{"version":3,"mappings":"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;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AA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A;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAA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AA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QA0ZrE5zC,GAA+B,uBAAuB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA,IAyC1D6zC,CAA8B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,0BAiBRxJ,EAA0B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA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EACM,CACE,eAAkB,sBAClB,OAAU,MACV,MAAS,GACT,MAAS,KACT,OAAU,KACV,gBAAmB,MACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,KACR,IAAO,KACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,mBAClB,OAAU,MACV,MAAS,GACT,MAAS,KACT,OAAU,KACV,gBAAmB,EACnB,QAAW,SACX,oBAAuB,CACrB,KAAQ,KACR,IAAO,KACP,KAAQ,EACR,MAAS,CACnB,CACA,CACA,CACA,EACE,CACE,GAAM,OACN,OAAU,uBACV,QAAW,YACX,MAAS,kDACT,SAAY,QACZ,UAAa,SACb,gBAAmB,IACnB,OAAU,CACR,CACE,eAAkB,wBAClB,OAAU,MACV,MAAS,GACT,MAAS,KACT,OAAU,KACV,gBAAmB,EACnB,QAAW,SACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,oBAClB,OAAU,MACV,MAAS,GACT,MAAS,IACT,OAAU,KACV,gBAAmB,IACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,sBAClB,OAAU,MACV,MAAS,GACT,MAAS,KACT,OAAU,KACV,gBAAmB,EACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,uBAClB,OAAU,MACV,MAAS,GACT,MAAS,KACT,OAAU,KACV,gBAAmB,EACnB,QAAW,SACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,sBAClB,OAAU,MACV,MAAS,GACT,MAAS,KACT,OAAU,KACV,gBAAmB,EACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,0BAClB,OAAU,KACV,MAAS,GACT,MAAS,KACT,OAAU,KACV,gBAAmB,EACnB,QAAW,SACX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AO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,sBAClB,OAAU,MACV,MAAS,IACT,MAAS,KACT,OAAU,KACV,gBAAmB,MACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,4BAClB,OAAU,MACV,MAAS,IACT,MAAS,KACT,OAAU,KACV,gBAAmB,KACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,eAClB,OAAU,MACV,MAAS,IACT,MAAS,IACT,OAAU,KACV,gBAAmB,KACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,CACA,CACA,EACE,CACE,GAAM,QACN,OAAU,wBACV,QAAW,QACX,MAAS,UACT,SAAY,QACZ,UAAa,QACb,gBAAmB,KACnB,OAAU,CACR,CACE,eAAkB,wBAClB,OAAU,MACV,MAAS,IACT,MAAS,IACT,OAAU,IACV,gBAAmB,MACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,KACR,IAAO,KACP,KAAQ,KACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,wBAClB,OAAU,KACV,MAAS,IACT,MAAS,KACT,OAAU,KACV,gBAAmB,MACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,KACR,IAAO,KACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,mBAClB,OAAU,MACV,MAAS,IACT,MAAS,IACT,OAAU,KACV,gBAAmB,MACnB,QAAW,SACX,oBAAuB,CACrB,KAAQ,IACR,IAAO,IACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,oBAClB,OAAU,KACV,MAAS,IACT,MAAS,KACT,OAAU,KACV,gBAAmB,MACnB,QAAW,SACX,oBAAuB,CACrB,KAAQ,KACR,IAAO,KACP,KAAQ,KACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,sBAClB,OAAU,MACV,MAAS,GACT,MAAS,KACT,OAAU,KACV,gBAAmB,MACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,IACR,IAAO,IACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,kBAClB,OAAU,MACV,MAAS,GACT,MAAS,IACT,OAAU,KACV,gBAAmB,EACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,KACR,IAAO,GACP,KAAQ,KACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,kBAClB,OAAU,MACV,MAAS,GACT,MAAS,KACT,OAAU,KACV,gBAAmB,KACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,KACR,IAAO,KACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,oBAClB,OAAU,MACV,MAAS,GACT,MAAS,KACT,OAAU,KACV,gBAAmB,KACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,CACA,CACA,EACE,CACE,GAAM,QACN,OAAU,qBACV,QAAW,SACX,MAAS,kDACT,SAAY,OACZ,UAAa,SACb,gBAAmB,KACnB,OAAU,CACR,CACE,eAAkB,yBAClB,OAAU,MACV,MAAS,IACT,MAAS,KACT,OAAU,KACV,gBAAmB,KACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,sBAClB,OAAU,MACV,MAAS,IACT,MAAS,KACT,OAAU,KACV,gBAAmB,MACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,qBAClB,OAAU,MACV,MAAS,IACT,MAAS,KACT,OAAU,KACV,gBAAmB,KACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,qBAClB,OAAU,MACV,MAAS,IACT,MAAS,KACT,OAAU,KACV,gBAAmB,MACnB,QAAW,SACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,2BAClB,OAAU,MACV,MAAS,IACT,MAAS,KACT,OAAU,KACV,gBAAmB,MACnB,QAAW,SACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,oBAClB,OAAU,MACV,MAAS,IACT,MAAS,KACT,OAAU,KACV,gBAAmB,MACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,uBAClB,OAAU,MACV,MAAS,IACT,MAAS,KACT,OAAU,KACV,gBAAmB,KACnB,QAAW,SACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,sBAClB,OAAU,MACV,MAAS,GACT,MAAS,IACT,OAAU,KACV,gBAAmB,EACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,CACA,CACA,EACE,CACE,GAAM,MACN,OAAU,iCACV,QAAW,WACX,MAAS,kDACT,SAAY,OACZ,UAAa,SACb,gBAAmB,KACnB,OAAU,CACR,CACE,eAAkB,mBAClB,OAAU,MACV,MAAS,IACT,MAAS,KACT,OAAU,KACV,gBAAmB,MACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,sBAClB,OAAU,KACV,MAAS,IACT,MAAS,KACT,OAAU,KACV,gBAAmB,KACnB,QAAW,SACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,uBAClB,OAAU,MACV,MAAS,IACT,MAAS,KACT,OAAU,KACV,gBAAmB,KACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,0BAClB,OAAU,KACV,MAAS,IACT,MAAS,KACT,OAAU,KACV,gBAAmB,MACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,sBAClB,OAAU,MACV,MAAS,GACT,MAAS,KACT,OAAU,KACV,gBAAmB,KACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,uBAClB,OAAU,MACV,MAAS,GACT,MAAS,KACT,OAAU,MACV,gBAAmB,KACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,yBAClB,OAAU,MACV,MAAS,GACT,MAAS,KACT,OAAU,KACV,gBAAmB,MACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,6BAClB,OAAU,MACV,MAAS,GACT,MAAS,KACT,OAAU,KACV,gBAAmB,KACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,CACA,CACA,EACE,CACE,GAAM,MACN,OAAU,cACV,QAAW,eACX,MAAS,gEACT,SAAY,QACZ,UAAa,QACb,gBAAmB,KACnB,OAAU,CACR,CACE,eAAkB,sBAClB,OAAU,MACV,MAAS,IACT,MAAS,KACT,OAAU,KACV,gBAAmB,MACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,sBAClB,OAAU,MACV,MAAS,IACT,MAAS,KACT,OAAU,KACV,gBAAmB,MACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,iBAClB,OAAU,MACV,MAAS,IACT,MAAS,KACT,OAAU,KACV,gBAAmB,KACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,uBAClB,OAAU,MACV,MAAS,IACT,MAAS,IACT,OAAU,KACV,gBAAmB,EACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,uBAClB,OAAU,MACV,MAAS,IACT,MAAS,IACT,OAAU,KACV,gBAAmB,KACnB,QAAW,SACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,qBAClB,OAAU,MACV,MAAS,IACT,MAAS,IACT,OAAU,IACV,gBAAmB,EACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,yBAClB,OAAU,MACV,MAAS,GACT,MAAS,KACT,OAAU,KACV,gBAAmB,MACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,yBAClB,OAAU,MACV,MAAS,GACT,MAAS,IACT,OAAU,KACV,gBAAmB,EACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,CACA,CACA,EACE,CACE,GAAM,OACN,OAAU,kCACV,QAAW,WACX,MAAS,gDACT,SAAY,OACZ,UAAa,SACb,gBAAmB,KACnB,OAAU,CACR,CACE,eAAkB,wBAClB,OAAU,KACV,MAAS,IACT,MAAS,KACT,OAAU,KACV,gBAAmB,KACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,wBAClB,OAAU,MACV,MAAS,IACT,MAAS,KACT,OAAU,KACV,gBAAmB,KACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,oBAClB,OAAU,MACV,MAAS,IACT,MAAS,KACT,OAAU,KACV,gBAAmB,MACnB,QAAW,SACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,0BAClB,OAAU,MACV,MAAS,IACT,MAAS,KACT,OAAU,KACV,gBAAmB,KACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,yBAClB,OAAU,MACV,MAAS,IACT,MAAS,IACT,OAAU,KACV,gBAAmB,KACnB,QAAW,SACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,iBAClB,OAAU,MACV,MAAS,IACT,MAAS,IACT,OAAU,IACV,gBAAmB,KACnB,QAAW,SACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,yBAClB,OAAU,MACV,MAAS,IACT,MAAS,KACT,OAAU,KACV,gBAAmB,KACnB,QAAW,SACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,wBAClB,OAAU,MACV,MAAS,IACT,MAAS,IACT,OAAU,KACV,gBAAmB,MACnB,QAAW,SACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,CACA,CACA,EACE,CACE,GAAM,MACN,OAAU,UACV,QAAW,QACX,MAAS,kDACT,SAAY,QACZ,UAAa,OACb,gBAAmB,KACnB,OAAU,CACR,CACE,eAAkB,qBAClB,OAAU,MACV,MAAS,IACT,MAAS,KACT,OAAU,KACV,gBAAmB,MACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,oBAClB,OAAU,MACV,MAAS,IACT,MAAS,KACT,OAAU,MACV,gBAAmB,KACnB,QAAW,SACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,gBAClB,OAAU,MACV,MAAS,IACT,MAAS,KACT,OAAU,KACV,gBAAmB,EACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,kBAClB,OAAU,MACV,MAAS,IACT,MAAS,KACT,OAAU,KACV,gBAAmB,MACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,cAClB,OAAU,KACV,MAAS,IACT,MAAS,KACT,OAAU,KACV,gBAAmB,MACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,qBAClB,OAAU,MACV,MAAS,IACT,MAAS,KACT,OAAU,KACV,gBAAmB,EACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,iBAClB,OAAU,MACV,MAAS,GACT,MAAS,KACT,OAAU,KACV,gBAAmB,KACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,uBAClB,OAAU,MACV,MAAS,GACT,MAAS,KACT,OAAU,KACV,gBAAmB,MACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,CACA,CACA,EACE,CACE,GAAM,KACN,OAAU,0BACV,QAAW,SACX,MAAS,sBACT,SAAY,QACZ,UAAa,QACb,gBAAmB,IACnB,OAAU,CACR,CACE,eAAkB,yBAClB,OAAU,MACV,MAAS,IACT,MAAS,KACT,OAAU,KACV,gBAAmB,MACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,oBAClB,OAAU,MACV,MAAS,IACT,MAAS,IACT,OAAU,KACV,gBAAmB,MACnB,QAAW,SACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,sBAClB,OAAU,MACV,MAAS,GACT,MAAS,IACT,OAAU,KACV,gBAAmB,KACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,qBAClB,OAAU,MACV,MAAS,GACT,MAAS,KACT,OAAU,KACV,gBAAmB,MACnB,QAAW,SACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,sBAClB,OAAU,MACV,MAAS,GACT,MAAS,KACT,OAAU,KACV,gBAAmB,KACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,qBAClB,OAAU,KACV,MAAS,GACT,MAAS,IACT,OAAU,KACV,gBAAmB,KACnB,QAAW,SACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,qBAClB,OAAU,MACV,MAAS,GACT,MAAS,KACT,OAAU,KACV,gBAAmB,GACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,sBAClB,OAAU,MACV,MAAS,GACT,MAAS,KACT,OAAU,KACV,gBAAmB,KACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,CACA,CACA,EACE,CACE,GAAM,MACN,OAAU,mBACV,QAAW,WACX,MAAS,uCACT,SAAY,QACZ,UAAa,QACb,gBAAmB,IACnB,OAAU,CACR,CACE,eAAkB,cAClB,OAAU,MACV,MAAS,IACT,MAAS,KACT,OAAU,KACV,gBAAmB,MACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,KACR,IAAO,EACP,KAAQ,EACR,MAAS,IACnB,CACA,EACM,CACE,eAAkB,oBAClB,OAAU,MACV,MAAS,IACT,MAAS,KACT,OAAU,KACV,gBAAmB,MA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S,CACnB,CACA,EACM,CACE,eAAkB,cAClB,OAAU,MACV,MAAS,GACT,MAAS,KACT,OAAU,KACV,gBAAmB,EACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,CACA,CACA,EACE,CACE,GAAM,QACN,OAAU,yBACV,QAAW,YACX,MAAS,kDACT,SAAY,QACZ,UAAa,SACb,gBAAmB,IACnB,OAAU,CACR,CACE,eAAkB,2BAClB,OAAU,MACV,MAAS,GACT,MAAS,KACT,OAAU,KACV,gBAAmB,EACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,sBAClB,OAAU,MACV,MAAS,GACT,MAAS,KACT,OAAU,KACV,gBAAmB,EACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,qBAClB,OAAU,MACV,MAAS,EACT,MAAS,IACT,OAAU,KACV,gBAAmB,EACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,qBAClB,OAAU,MACV,MAAS,EACT,MAAS,KACT,OAAU,KACV,gBAAmB,EACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,wBAClB,OAAU,MACV,MAAS,EACT,MAAS,KACT,OAAU,KACV,gBAAmB,EACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,wBAClB,OAAU,MACV,MAAS,EACT,MAAS,KACT,OAAU,KACV,gBAAmB,EACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,wBAClB,OAAU,MACV,MAAS,EACT,MAAS,KACT,OAAU,KACV,gBAAmB,EAC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ACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,qBAClB,OAAU,MACV,MAAS,IACT,MAAS,KACT,OAAU,KACV,gBAAmB,KACnB,QAAW,SACX,oBAAuB,CACrB,KAAQ,IACR,IAAO,EACP,KAAQ,IACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,qBAClB,OAAU,MACV,MAAS,IACT,MAAS,KACT,OAAU,KACV,gBAAmB,MACnB,QAAW,SACX,oBAAuB,CACrB,KAAQ,KACR,IAAO,EACP,KAAQ,KACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,oBAClB,OAAU,MACV,MAAS,GACT,MAAS,IACT,OAAU,KACV,gBAAmB,KACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,CACA,CACA,EACE,CACE,GAAM,OACN,OAAU,+BACV,QAAW,SACX,MAAS,kDACT,SAAY,QACZ,UAAa,SACb,gBAAmB,KACnB,OAAU,CACR,CACE,eAAkB,mBAClB,OAAU,MACV,MAAS,IACT,MAAS,KACT,OAAU,KACV,gBAAmB,MACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,sBAClB,OAAU,MACV,MAAS,IACT,MAAS,IACT,OAAU,IACV,gBAAmB,KACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,yBAClB,OAAU,MACV,MAAS,IACT,MAAS,KACT,OAAU,KACV,gBAAmB,MACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,oBAClB,OAAU,MACV,MAAS,IACT,MAAS,IACT,OAAU,KACV,gBAAmB,KACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,KACR,IAAO,EACP,KAAQ,EACR,MAAS,IACnB,CACA,EACM,CACE,eAAkB,yBAClB,OAAU,MACV,MAAS,IACT,MAAS,KACT,OAAU,KACV,gB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KACnB,OAAU,CACR,CACE,eAAkB,mBAClB,OAAU,MACV,MAAS,IACT,MAAS,KACT,OAAU,KACV,gBAAmB,MACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,mBAClB,OAAU,MACV,MAAS,IACT,MAAS,KACT,OAAU,KACV,gBAAmB,EACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,mBAClB,OAAU,MACV,MAAS,IACT,MAAS,KACT,OAAU,KACV,gBAAmB,KACnB,QAAW,SACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,iBAClB,OAAU,MACV,MAAS,IACT,MAAS,IACT,OAAU,KACV,gBAAmB,KACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,kBAClB,OAAU,MACV,MAAS,IACT,MAAS,IACT,OAAU,KACV,gBAAmB,MACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,sBAClB,OAAU,MACV,MAAS,IACT,MAAS,KACT,OAAU,KACV,gBAAmB,MACnB,QAAW,SACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,qBAClB,OAAU,MACV,MAAS,GACT,MAAS,KACT,OAAU,KACV,gBAAmB,KACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,wBAClB,OAAU,KACV,MAAS,GACT,MAAS,IACT,OAAU,KACV,gBAAmB,KACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,CACA,CACA,EACE,CACE,GAAM,OACN,OAAU,iCACV,QAAW,MACX,MAAS,uCACT,SAAY,QACZ,UAAa,SACb,gBAAmB,IACnB,OAAU,CACR,CACE,eAAkB,sBAClB,OAAU,MACV,MAAS,IACT,MAAS,IACT,OAAU,KACV,gBAAmB,MACnB,QAAW,SACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,kBAClB,OAAU,MACV,MAAS,GACT,MAAS,IACT,OAAU,KACV,gBAAmB,MACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,oBAClB,OAAU,MACV,MAAS,GACT,MAAS,IACT,OAAU,KACV,gBAAmB,MACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,kBAClB,OAAU,MACV,MAAS,GACT,MAAS,IACT,OAAU,KACV,gBAAmB,MACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,mBAClB,OAAU,MACV,MAAS,GACT,MAAS,IACT,OAAU,KACV,gBAAmB,MACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,kBAClB,OAAU,MACV,MAAS,GACT,MAAS,KACT,OAAU,KACV,gBAAmB,MACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,uBAClB,OAAU,MACV,MAAS,GACT,MAAS,KACT,OAAU,KACV,gBAAmB,KACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,oBAClB,OAAU,MACV,MAAS,GACT,MAAS,KACT,OAAU,KACV,gBAAmB,KACnB,QAAW,SACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,CACA,CACA,EACE,CACE,GAAM,SACN,OAAU,gCACV,QAAW,SACX,MAAS,+BACT,SAAY,QACZ,UAAa,QACb,gBAAmB,IACnB,OAAU,CACR,CACE,eAAkB,qBAClB,OAAU,MACV,MAAS,IACT,MAAS,IACT,OAAU,KACV,gBAAmB,KACnB,QAAW,SACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,wBAClB,OAAU,MACV,MAAS,IACT,MAAS,IACT,OAAU,KACV,gBAAmB,MACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,KACR,IAAO,KACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,sBAClB,OAAU,MACV,MAAS,IACT,MAAS,IACT,OAAU,KACV,gBAAmB,MACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,KACR,IAAO,KACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,iBAClB,OAAU,MACV,MAAS,GACT,MAAS,IACT,OAAU,KACV,gBAAmB,KACnB,QAAW,SACX,oBAAuB,CACrB,KAAQ,KACR,IAAO,KACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,wBAClB,OAAU,MACV,MAAS,GACT,MAAS,KACT,OAAU,KACV,gBAAmB,KACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,IACR,IAAO,IACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,sBAClB,OAAU,MACV,MAAS,GACT,MAAS,KACT,OAAU,KACV,gBAAmB,MACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,sBAClB,OAAU,MACV,MAAS,GACT,MAAS,IACT,OAAU,KACV,gBAAmB,MACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,KACR,IAAO,KACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,qBAClB,OAAU,MACV,MAAS,GACT,MAAS,KACT,OAAU,KACV,gBAAmB,KACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,CACA,CACA,EACE,CACE,GAAM,QACN,OAAU,4BACV,QAAW,QACX,MAAS,UACT,SAAY,QACZ,UAAa,OACb,gBAAmB,IACnB,OAAU,CACR,CACE,eAAkB,oBAClB,OAAU,MACV,MAAS,IACT,MAAS,KACT,OAAU,KACV,gBAAmB,MACnB,QAAW,SACX,oBAAuB,CACrB,KAAQ,KACR,IAAO,KACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,oBAClB,OAAU,MACV,MAAS,GACT,MAAS,KACT,OAAU,KACV,gBAAmB,MACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,KACR,IAAO,KACP,KAAQ,KACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,YAClB,OAAU,MACV,MAAS,GACT,MAAS,IACT,OAAU,KACV,gBAAmB,KACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,IACR,IAAO,IACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,wBAClB,OAAU,MACV,MAAS,GACT,MAAS,KACT,OAAU,KACV,gBAAmB,KACnB,QAAW,SACX,oBAAuB,CACrB,KAAQ,KACR,IAAO,KACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,cAClB,OAAU,MACV,MAAS,GACT,MAAS,KACT,OAAU,KACV,gBAAmB,KACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,eAClB,OAAU,MACV,MAAS,GACT,MAAS,KACT,OAAU,KACV,gBAAmB,MACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,KACR,IAAO,KACP,KAAQ,KACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,iBAClB,OAAU,MACV,MAAS,GACT,MAAS,KACT,OAAU,KACV,gBAAmB,MACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,KACR,IAAO,KACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,uBAClB,OAAU,MACV,MAAS,GACT,MAAS,KACT,OAAU,KACV,gBAAmB,KACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,KACR,IAAO,KACP,KAAQ,EACR,MAAS,CACnB,CACA,CACA,CACA,EACE,CACE,GAAM,SACN,OAAU,yBACV,QAAW,QACX,MAAS,UACT,SAAY,QACZ,UAAa,QACb,gBAAmB,IACnB,OAAU,CACR,CACE,eAAkB,oBAClB,OAAU,MACV,MAAS,GACT,MAAS,KACT,OAAU,KACV,gBAAmB,MACnB,QAAW,SACX,oBAAuB,CACrB,KAAQ,KACR,IAAO,KACP,KAAQ,KACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,kBAClB,OAAU,IACV,MAAS,GACT,MAAS,KACT,OAAU,KACV,gBAAmB,IACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,KACR,IAAO,KACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,mBAClB,OAAU,KACV,MAAS,GACT,MAAS,KACT,OAAU,KACV,gBAAmB,KACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,KACR,IAAO,KACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,yBAClB,OAAU,MACV,MAAS,EACT,MAAS,KACT,OAAU,KACV,gBAAmB,EACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,KACP,KAAQ,KACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,kBAClB,OAAU,MACV,MAAS,EACT,MAAS,KACT,OAAU,KACV,gBAAmB,KACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,YAClB,OAAU,MACV,MAAS,EACT,MAAS,IACT,OAAU,KACV,gBAAmB,KACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,IACR,IAAO,IACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,oBAClB,OAAU,MACV,MAAS,EACT,MAAS,KACT,OAAU,KACV,gBAAmB,EACnB,QAAW,QACX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AO,KACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,wBAClB,OAAU,MACV,MAAS,GACT,MAAS,KACT,OAAU,KACV,gBAAmB,MACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,KACR,IAAO,KACP,KAAQ,KACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,kBAClB,OAAU,MACV,MAAS,GACT,MAAS,IACT,OAAU,KACV,gBAAmB,MACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,KACR,IAAO,KACP,KAAQ,EACR,MAAS,CACnB,CACA,CACA,CACA,EACE,CACE,GAAM,MACN,OAAU,UACV,QAAW,QACX,MAAS,uCACT,SAAY,QACZ,UAAa,QACb,gBAAmB,KACnB,OAAU,CACR,CACE,eAAkB,oBAClB,OAAU,MACV,MAAS,IACT,MAAS,KACT,OAAU,KACV,gBAAmB,MACnB,QAAW,SACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,sBAClB,OAAU,MACV,MAAS,IACT,MAAS,KACT,OAAU,KACV,gBAAmB,MACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,qBAClB,OAAU,MACV,MAAS,IACT,MAAS,KACT,OAAU,KACV,gBAAmB,MACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,iBAClB,OAAU,MACV,MAAS,IACT,MAAS,KACT,OAAU,KACV,gBAAmB,MACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,cAClB,OAAU,MACV,MAAS,IACT,MAAS,KACT,OAAU,KACV,gBAAmB,KACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,wBAClB,OAAU,MACV,MAAS,GACT,MAAS,KACT,OAAU,KACV,gBAAmB,MACnB,QAAW,SACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,oBAClB,OAAU,MACV,MAAS,GACT,MAAS,KACT,OAAU,KACV,gBAAmB,MACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,oBAClB,OAAU,KACV,MAAS,GACT,MAAS,IACT,OAAU,MACV,gBAAmB,KACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,CACA,CACA,EACE,CACE,GAAM,KACN,OAAU,0BACV,QAAW,SACX,MAAS,sBACT,SAAY,OACZ,UAAa,QACb,gBAAmB,IACnB,OAAU,CACR,CACE,eAAkB,oBAClB,OAAU,MACV,MAAS,GACT,MAAS,KACT,OAAU,KACV,gBAAmB,MACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,yBAClB,OAAU,MACV,MAAS,GACT,MAAS,KACT,OAAU,KACV,gBAAmB,MACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,oBAClB,OAAU,MACV,MAAS,GACT,MAAS,KACT,OAAU,KACV,gBAAmB,MACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,qBAClB,OAAU,KACV,MAAS,GACT,MAAS,KACT,OAAU,KACV,gBAAmB,MACnB,QAAW,SACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,qBAClB,OAAU,MACV,MAAS,GACT,MAAS,KACT,OAAU,KACV,gBAAmB,MACnB,QAAW,SACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,sBAClB,OAAU,MACV,MAAS,GACT,MAAS,KACT,OAAU,KACV,gBAAmB,MACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,mBAClB,OAAU,MACV,MAAS,GACT,MAAS,KACT,OAAU,KACV,gBAAmB,MACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,iBAClB,OAAU,MACV,MAAS,GACT,MAAS,KACT,OAAU,KACV,gBAAmB,MACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,CACA,CACA,EACE,CACE,GAAM,OACN,OAAU,0BACV,QAAW,MACX,MAAS,8BACT,SAAY,QACZ,UAAa,UACb,gBAAmB,KACnB,OAAU,CACR,CACE,eAAkB,uBAClB,OAAU,KACV,MAAS,IACT,MAAS,KACT,OAAU,KACV,gBAAmB,KACnB,QAAW,SACX,oBAAuB,CACrB,KAAQ,KACR,IAAO,KACP,KAAQ,KACR,MAAS,IACnB,CACA,EACM,CACE,eAAkB,kBAClB,OAAU,MACV,MAAS,IACT,MAAS,KACT,OAAU,KACV,gBAAmB,MACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,KACR,IAAO,KACP,KAAQ,KACR,MAAS,IACnB,CACA,EACM,CACE,eAAkB,oBAClB,OAAU,KACV,MAAS,IACT,MAAS,KACT,OAAU,KACV,gBAAmB,KACnB,QAAW,SACX,oBAAuB,CACrB,KAAQ,KACR,IAAO,KACP,KAAQ,KACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,oBAClB,OAAU,MACV,MAAS,IACT,MAAS,KACT,OAAU,KACV,gBAAmB,KACnB,QAAW,SACX,oBAAuB,CACrB,KAAQ,IACR,IAAO,KACP,KAAQ,KACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,wBAClB,OAAU,MACV,MAAS,IACT,MAAS,KACT,OAAU,KACV,gBAAmB,EACnB,QA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,MAAS,CACnB,CACA,EACM,CACE,eAAkB,sBAClB,OAAU,MACV,MAAS,GACT,MAAS,KACT,OAAU,KACV,gBAAmB,KACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,KACR,IAAO,KACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,2BAClB,OAAU,IACV,MAAS,GACT,MAAS,IACT,OAAU,IACV,gBAAmB,EACnB,QAAW,SACX,oBAAuB,CACrB,KAAQ,KACR,IAAO,KACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,iCAClB,OAAU,MACV,MAAS,GACT,MAAS,KACT,OAAU,KACV,gBAAmB,KACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,KACR,IAAO,KACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,uBAClB,OAAU,MACV,MAAS,GACT,MAAS,IACT,OAAU,KACV,gBAAmB,MACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,IACR,IAAO,IACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,wBAClB,OAAU,MACV,MAAS,GACT,MAAS,KACT,OAAU,KACV,gBAAmB,MACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,GACR,IAAO,GACP,KAAQ,EACR,MAAS,CACnB,CACA,CACA,CACA,EACE,CACE,GAAM,OACN,OAAU,gCACV,QAAW,QACX,MAAS,kDACT,SAAY,QACZ,UAAa,QACb,gBAAmB,KACnB,OAAU,CACR,CACE,eAAkB,iBAClB,OAAU,MACV,MAAS,IACT,MAAS,KACT,OAAU,KACV,gBAAmB,MACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,IACR,IAAO,IACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,wBAClB,OAAU,MACV,MAAS,IACT,MAAS,KACT,OAAU,KACV,gBAAmB,MACnB,QAAW,SACX,oBAAuB,CACrB,KAAQ,KACR,IAAO,KACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,oBAClB,OAAU,MACV,MAAS,IACT,MAAS,KACT,OAAU,KACV,gBAAm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,MAAS,CACnB,CACA,CACA,CACA,EACE,CACE,GAAM,MACN,OAAU,oBACV,QAAW,SACX,MAAS,kDACT,SAAY,QACZ,UAAa,SACb,gBAAmB,IACnB,OAAU,CACR,CACE,eAAkB,cAClB,OAAU,MACV,MAAS,GACT,MAAS,KACT,OAAU,KACV,gBAAmB,KACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,oBAClB,OAAU,MACV,MAAS,GACT,MAAS,IACT,OAAU,KACV,gBAAmB,MACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,2BAClB,OAAU,MACV,MAAS,GACT,MAAS,IACT,OAAU,KACV,gBAAmB,MACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,uBAClB,OAAU,MACV,MAAS,GACT,MAAS,KACT,OAAU,KACV,gBAAmB,MACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,2BAClB,OAAU,MACV,MAAS,GACT,MAAS,KACT,OAAU,KACV,gBAAmB,KACnB,QAAW,SACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,wBAClB,OAAU,KACV,MAAS,GACT,MAAS,KACT,OAAU,KACV,gBAAmB,MACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,0BAClB,OAAU,MACV,MAAS,GACT,MAAS,KACT,OAAU,KACV,gBAAmB,KACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,uBAClB,OAAU,MACV,MAAS,EACT,MAAS,KACT,OAAU,KACV,gBAAmB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O,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,wBAClB,OAAU,MACV,MAAS,IACT,MAAS,KACT,OAAU,KACV,gBAAmB,MACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,KACR,IAAO,KACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,wBAClB,OAAU,KACV,MAAS,GACT,MAAS,IACT,OAAU,IACV,gBAAmB,KACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,KACR,IAAO,KACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,oBAClB,OAAU,KACV,MAAS,GACT,MAAS,KACT,OAAU,KACV,gBAAmB,MACnB,QAAW,SACX,oBAAuB,CACrB,KAAQ,KACR,IAAO,KACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,yBAClB,OAAU,KACV,MAAS,GACT,MAAS,KACT,OAAU,KACV,gBAAmB,MACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,KACR,IAAO,KACP,KAAQ,EACR,MAAS,CACnB,CACA,CACA,CACA,EACE,CACE,GAAM,MACN,OAAU,6BACV,QAAW,WACX,MAAS,gDACT,SAAY,OACZ,UAAa,SACb,gBAAmB,IACnB,OAAU,CACR,CACE,eAAkB,uBAClB,OAAU,KACV,MAAS,IACT,MAAS,KACT,OAAU,KACV,gBAAmB,MACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,kBAClB,OAAU,KACV,MAAS,IACT,MAAS,KACT,OAAU,MACV,gBAAmB,KACnB,QAAW,QACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,uBAClB,OAAU,MACV,MAAS,IACT,MAAS,KACT,OAAU,KACV,gBAAmB,KACnB,QAAW,SACX,oBAAuB,CACrB,KAAQ,EACR,IAAO,EACP,KAAQ,EACR,MAAS,CACnB,CACA,EACM,CACE,eAAkB,yBAClB,OAAU,MACV,MAAS,IACT,MAAS,KACT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AAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;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","names":["probe","prepare","setSceneOcclusionProbe","next","hasSceneOcclusionProbe","prepareSceneOcclusion","isSceneSegmentOccluded","fromWorld","toWorld","EventBus","eventName","handler","prefix","set","wrapper","payload","handlers","XR_EVENTS","KEY","PREF","finite","n","max","token","XR_METRICS","XR_TILE_METRICS","CPU_SECTIONS","NATIVE_TIMINGS","XR_CPU_METRICS","nullableBoolean","value","choice","v","values","fallback","cleanXRReport","k","_a","XRDiagnostics","scene","host","doc","nav","send","args","now","wall","storage","schedule","query","_b","_c","_d","raw","_e","saved","target","event","fn","capture","list","enabled","type","error","session","mode","time","dt","renderer","xr","ua","eyes","inputs","loader","tiles","lru","telemetry","sections","_f","nativeTiming","_j","_i","_h","_g","nativeClouds","_l","_k","modelCount","_n","_m","_p","_o","_q","_r","_t","_s","_v","_u","_x","_w","_z","_y","_B","_A","_D","_C","_F","_E","_H","_G","_J","_I","_L","_K","i","_M","_O","_N","key","section","_P","_Q","_R","_S","_T","_V","_U","_W","_Y","_X","_Z","_$","__","_aa","_ba","persist","supported","report","controller","timeout","response","resolveBackendApiUrl","retry","CAPACITY","WINDOW_MS","MAX_WINDOWS","FRAME_BUDGET_MS","MAX_REPORT_BYTES","QUALITY_KEYS","CPU_FIELDS","valid","rounded","average","stat","add","percentile","sorted","p","qualityValue","quality","XRProfileSampler","seconds","submitted","visible","cpu","contextLost","renderFailure","elapsed","index","window","timings","interval","elapsedMs","durationMs","sortedCPU","buckets","positions","count","windows","minWindowFps","duration","fps","summary","name","UUID","RELEASE","CAPABILITIES","record","keys","allowed","number","min","parseXRHarnessCommand","expiresAt","a","XRRemoteHarness","flush","fetch","sampler","loadRuntime","url","nativeBuild","id","reload","command","status","code","settings","result","acquireNativeXRComponentProfiler","epoch","abort","onAbort","interrupted","reject","bounded","work","text","manifest","pattern","entries","path","module","runtimeTransaction","wasXR","s","atmosphere","clouds","task","input","fraction","forwardMeters","rightMeters","yawDegrees","failed","gpu","lease","trace","object","original","harness","timed","start","restore","TARGET_HANDLE","DEFAULT_INTERVAL_MS","MAX_FRAME_SAMPLES","MAX_MODE_TRANSITIONS","PIPELINE_SECTIONS","integer","mean","sum","browserFamily","deviceClass","emptyNetwork","cleanReport","_key","item","BrowserPerformanceTelemetry","authService","getAuthService","perf","intervalMs","state","handle","shouldRun","identity","observer","callback","options","Observer","entry","dtSeconds","frameTimeMs","frameMs","wait","sectionName","sample","frame","reason","info","budget","labels","getLabelSystem","memory","sortedFrames","b","frameMean","longTaskTotal","connection","canvas","cameraMode","surface","mapMode","build","frameOwnership","cadence","control","body","retrySeconds","asMessage","CameraQuiescenceError","message","diagnostics","cause","runCameraQuiescenceBarrier","steps","timeoutMs","clock","startedAt","step","stepStartedAt","remainingMs","timer","_resolve","verified","detail","PerformanceMonitor","timestamp","sFrame","sInterval","sWait","frameAvg","cpuAvg","waitAvg","gpuEntries","cpuEntries","renderEntries","frameWaitEntry","avg","output","isLikelyThrottled","isLikelyGPUBound","label","e","panel","content","fpsEl","cpuLabel","waitLabel","html","pct","isHeavy","GraphicsStartupError","failures","createSceneRenderer","createCanvas","createRenderer","THREE.WebGLRenderer","profile","context","attributes","onError","THREE.HalfFloatType","initializeSceneGraphics","sleep","ms","resolve","onWaiting","onBlocked","attempts","failure","delay","METERS_PER_AU","KM_PER_AU","copyAstronomyVectorToEarthFixed","vector","CelestialEphemeris","THREE.Vector3","CelestialFrame","date","timeMs","instant","GeoVector","Body","LightingSystem","planetRadius","sunDistance","THREE.DirectionalLight","shadowExtent","shadowRange","THREE.AmbientLight","THREE.HemisphereLight","ephemeris","normalizedDirection","hours","minutes","lat","lng","getSunDirectionVector","speed","deltaTime","millisecondsElapsed","intensity","uvIndex","factor","THREE.MathUtils","angle","getEarthRotationAngleUTC","clamp","lo","hi","smooth","t","skyLimitingMagnitude","sunAltitudeDegrees","altitudeMeters","atmospheric","skyObjectVisibility","magnitude","limitingMagnitude","SKY_VISIBILITY_GLSL","normalizeCanonicalPath","candidate","resolveSceneRuntimeResource","canonicalPath","normalized","configured","resolved","pageOrigin","resolveSceneRuntimeBasePath","JRLL","JPLL","GAIA_G_ZERO_POINT","GAIA_ZERO_FLUX","healpixXYDirection","side","face","x","y","out","ring","nr","z","phi","r","nestedPixel","order","directionHealpix","direction","za","tt","jp","jm","fp","fm","nt","tp","tmp","healpixDirection","pixel","faceSize","bits","bit","shift","stellarViewTiles","forward","halfAngle","desiredOrder","maxTiles","scratch","required","previous","current","threshold","parent","child","validateStellarPacket","buffer","view","stride","data","validateStellarRecords","norm","stellarFlux","stellarExposureCompensation","exposure","readFluxPacket","STELLAR_LIMITS","STELLAR_BASE_URL","PC_METERS","AU_PC","StellarCatalogRenderer","group","radius","uniforms","fetchImpl","base","getBackendApiBase","baseDataUrl","onFlux","brightMatch","init","getNoclipGovernanceClient","THREE.Matrix4","THREE.Vector2","THREE.InterleavedBuffer","THREE.DynamicDrawUsage","THREE.BufferGeometry","size","offset","THREE.InterleavedBufferAttribute","THREE.ShaderMaterial","THREE.AdditiveBlending","THREE.Points","camera","nowMs","u","julianYearsSinceJ2000","earth","BaryState","half","tile","packet","owner","resident","c","bytes","readBoundedBytes","started","slots","ids","idView","first","last","row","slot","STELLAR_FLUX_URL","CDS_FLUX_DENSITY_CORRECTION","StellarFluxField","signal","radiance","indices","vertex","THREE.BufferAttribute","THREE.DoubleSide","THREE.Mesh","dy","dx","ix","iy","sign","cell","SKY_FOCUS_DEFAULTS","DEG","buildSkyLabelRecords","stars","motions","designations","constellations","conNames","starRecords","seen","proper","bayer","flamsteed","con","star","designation","equatorialDirection","properMotionVector","constellationRecords","abbr","ra","dec","angleBetween","dz","selectSkyLabels","focus","inView","visibility","halfFov","limit","o","span","focused","focusedScore","nearby","figuresVisible","rel","picks","q","scored","mag","member","score","starBudget","proximity","SKY_LABEL_FADE_MS","SKY_LANDMARKS","SkyFeatures","named","catalogOptions","w","h","scale","candidates","d","pin","kind","kinds","idle","years","up","ndc","pick","priority","coords","parts","opacity","position","FIRST_DRAW_GUARD_DEFAULTS","drawable","materialProgramKey","material","custom","f","FirstDrawGuard","props","version","drawnVersion","program","compiledFor","visit","materials","children","MotionBlurPass","Pass","damp","AfterimageShader","CopyMaterial","THREE.WebGLRenderTarget","THREE.NearestFilter","inputBuffer","outputBuffer","temp","width","height","LENS_DEFAULTS","LENS_LIMITS","clampTo","normalizeLensConfig","patch","ca","dof","grain","grade","WRAPPED_CLOUD_SAMPLING_GLSL","wrapCloudMapSampling","shader","samplers","changed","waterCoverageUniforms","source","uniform","WATER_GEOMETRY_GLSL","WATER_COVERAGE_GLSL","bathymetryTileWindow","latitude","longitude","altitude","zoom","waterTileWindow","left","top","tileSize","sampleWaterAtlas","atlas","WATER_REFLECTANCE_GLSL","WAVELENGTHS","PURE_WATER_ABSORPTION","PURE_WATER_SCATTERING","PHYTOPLANKTON_A","PHYTOPLANKTON_B","KD_WATER","KD_CHI","KD_EXPONENT","OCEAN_DEFAULT_CHLOROPHYLL","VISIBILITY_CONTRAST","clampChlorophyll","computeWaterOptics","chlorophyll","chl","absorption","scattering","attenuation","diffuseAttenuation","albedo","lambda","phytoplankton","cdom","WATER_INDEX","PARTICLE_BACKSCATTER_RATIO","oceanAirWaterFresnel","cosIncidence","cosI","sinT2","cosT","oceanSubsurfaceLight","optics","sunCosZenith","sunRadiance","cosZ","daylight","transmission","direct","irradiance","reflectance","sun","sky","bb","sinW","A","WGS84_SEMI_MAJOR_AXIS","B","WGS84_SEMI_MINOR_AXIS","E2","EP2","nightLightsGeodeticLatitude","horizontal","theta","NIGHT_LIGHTS_GEOGRAPHY_GLSL","bindings","THREE.Vector4","NIGHT_LIGHTS_EMISSION_DEFAULTS","THREE.Color","bindingEntries","bindNightCloudLighting","sourceName","THREE.Uniform","NIGHT_CLOUD_UNIFORMS_GLSL","NIGHT_CLOUD_FUNCTIONS_GLSL","NIGHT_CLOUD_LIGHTING_GLSL","NIGHT_LIGHTS_SOURCE_SIGNAL_GLSL","nightCloudLightingForExistingField","ORBITAL_CLOUD_VOLUME_DEFAULTS","orbitalCloudVolumeGlsl","mask","groundRadius","ORBITAL_CLOUD_VOLUME_GLSL","PI","DEFAULT_INTEGRATION_STEPS","CELESTIAL_IRRADIANCE_GLSL","ATMOSPHERIC_TRANSMITTANCE_GLSL","apparentAngularRadius","distance","circleOverlapArea","sourceRadius","occluderRadius","centerDistance","coveredRadius","aTerm","bTerm","radical","finiteDiscVisibility","sourceDirection","sourceAngularRadius","occluderDirection","occluderAngularRadius","sourceLength","occluderLength","cosine","separation","overlap","finiteSourceVisibility","observerPosition","sourceCenter","occluderCenter","sourceOffset","occluderOffset","sourceDistance","occluderDistance","raySphereInterval","origin","center","ox","oy","oz","discriminant","root","atmosphericTransmittance","lightDirection","planetCenter","PLANET_RADIUS","atmosphereHeight","ATMOSPHERE_HEIGHT_M","rayleighScaleHeight","RAYLEIGH_SCALE_HEIGHT_M","mieScaleHeight","MIE_SCALE_HEIGHT_M","betaRayleigh","BETA_RAYLEIGH","betaMie","BETA_MIE","integrationSteps","directionLength","groundInterval","topRadius","atmosphereInterval","length","stepLength","rayleighColumn","mieColumn","px","py","pz","createEarthMaterial","textures","sunLight","waterOptics","THREE.Matrix3","vertexShader","fragmentShader","NIGHT_LIGHTS_SURFACE_CARRIER_GLSL","THREE.BackSide","texture","clonedUniforms","clonedMaterial","createOrbitalEarthMaterial","sourceUniforms","shared","THREE.FrontSide","createAtmosphereMaterial","colors","ATMOSPHERE_RADIUS_M","MIE_G","THREE.NormalBlending","CELESTIAL_LENGTH_UNIT_PER_METER","CELESTIAL_OCCLUSION_UNIFORMS_GLSL","CELESTIAL_OCCLUSION_INTERSECTION_GLSL","enforceCelestialOpaqueDepthMaterial","THREE.LessEqualDepth","isObjectVisibleInHierarchy","ensureCelestialOcclusionUniforms","effect","ensure","ensureCelestialWorldOcclusionUniforms","syncOccluder","worldToECEFMatrix","scratchWorld","centerUniform","radiusUniform","radiusMeters","syncWorldOccluder","scratchScale","radiusScale","syncCelestialOcclusionUniforms","moonMesh","sunMesh","syncCelestialWorldOcclusionUniforms","geometryToBody","LunarFrame","celestialFrame","axis","RotationAxis","spin","lunarSurfacePoint","lon","MOON_RADIUS_M","l","lunarCoordinates","point","MOON_DISPLACEMENT_SCALE_M","MOON_DISPLACEMENT_BIAS_M","MOON_BUMP_SCALE","MOON_ATMOSPHERE_OCCLUSION_PADDING_M","MOON_BASE_COLOR","MOON_EARTHSHINE_INTENSITY","MOON_BASE_TEXTURE_SIZE","MOON_FULL_DETAIL_PX","whenIdle","loadMoonTexture","THREE.ImageBitmapLoader","THREE.TextureLoader","bitmap","THREE.Texture","dispose","MoonSystem","mobile","geom","THREE.SphereGeometry","mat","_scene","MOON_DISTANCE_M","THREE.MeshStandardMaterial","THREE.ShaderChunk","tier","celestialState","sunFromMoonDistance","SUN_RADIUS_M","seq","previousTier","old","err","queue","colorSize","heightSize","load","pending","results","color","displacement","THREE.SRGBColorSpace","THREE.NoColorSpace","OCEAN_WAVE_COUNT","TAU","oceanDispersion","depth","jonswapDensity","omega","peakOmega","gamma","alpha","sigma","peak","jonswapAlpha","windSpeed","logGamma","terms","oceanDirectionalSpread","frequencyRatio","spread","createOceanSpectrum","peakWavelength","windDirection","waves","low","high","j","tangent","derivative","OCEAN_WAVE_GLSL","wrapAngle","createOceanInitialSpectrum","minK","maxK","seed","spectrum","randomState","random","deltaK","kx","ky","density","phase","OCEAN_REPEAT_SECONDS","OCEAN_CASCADES","OCEAN_CHOP","coxMunkSlopeVariance","oceanPeakWavelength","PASS_VERTEX","COMPLEX","EVOLVE","BUTTERFLY","PACK","DERIVE","FOCUS","canRunOceanCascades","extensions","fieldTarget","mipmaps","THREE.RGBAFormat","THREE.LinearMipmapLinearFilter","THREE.LinearFilter","THREE.RepeatWrapping","OceanCascade","config","pass","mirror","THREE.DataTexture","THREE.FloatType","slopeVariance","k2","delta","run","OceanGPUCascades","sizes","THREE.Scene","THREE.OrthographicCamera","THREE.PlaneGeometry","cascade","savedTarget","OCEAN_OPTICS_GLSL","OCEAN_OPTICS_FRAGMENT","OCEAN_CAPILLARY_GLSL","OCEAN_VERTEX_DISPLACEMENT_GLSL","OCEAN_DEPTH_VERTEX_GLSL","CUBE","OceanParticulate","CLOUD_GUIDE_GLSL","patched","patchCloudDepthReconstruction","marker","Uniform","Vector2","Matrix4","repair","geometry","prepareCloudFrontDepth","FloatType","NearestFilter","decodeCloudShadowDepth","shadowStoragePatched","patchCloudShadowStorage","canonical","AerialPerspectiveEffect","copyrightStart","scatteringCopyright","declaration","match","open","functions","shadows","types","defines","namespace","suffix","rename","word","irradianceGLSL","shadowGLSL","ShaderChunk","OCEAN_CLOUD_LIGHTING_GLSL","createOceanCloudLightingUniforms","Vector3","Color","defaults","ownedUniformNames","syncOceanCloudLightingUniforms","resolution","map","get","has","ready","compile","flags","attachments","from","to","compactDevice","OceanSurface","environment","waterLevel","segments","wave","THREE.MeshPhysicalMaterial","THREE.NoBlending","wind","heading","total","localPosition","strength","THREE.PerspectiveCamera","aerial","sunCos","rendering","ellipsoidRadius","ellipsoidRadiusForLocalDir","level","datumReady","meanHeight","tide","gpuReady","extent","recentre","originX","originY","pointMeanHeight","latDeg","lonDeg","dirToLatLonLocal","DEFAULT_BYTES_PER_FRAME","worker","nextId","canStreamImageTextures","decode","channels","workerFactory","absolute","rowsPerBand","bytesPerFrame","streamTextureRows","nextFrame","band","rangeCount","end","loadStreamedImageTexture","configure","pixels","THREE.RedFormat","THREE.UnsignedByteType","StagedDataTexture","rowsPerFrame","onCommit","rowBytes","configureCoverage","configureBed","RegionalWaterMask","bed","generation","getMapTileApiBase","terrainBase","applyBed","sl","cl","heightRange","hasHeights","_listeners","SceneClockImpl","hidden","wallElapsedMs","epochMs","nextMode","modeChanged","_instance","getSceneClock","EARTH_RADIUS","MAX_STATIONS","TIDE_REACH_METERS","tideStationDistance","stationLat","stationLon","RegionalTides","createPredictor","cached","stations","station","support","weights","nearest","sources","minute","constituents","edge","weight","fade","OceanWaterLevel","getTime","loadGeoid","getEgm96GeoidRaster","loadTides","__vitePreload","grid","tides","bilinearEgm96Undulation","tideMeters","sharedWaterLevel","getOceanWaterLevel","OCEAN_TIERS","EXPIRY_MS","defaultStorage","readOceanTier","search","requested","demoteOceanTier","SOLAR_DISC_DEFAULTS","solarDiscRadianceScale","angularRadius","meanLimb","SOLAR_OPTICS_VISIBILITY_GLSL","LensFlareParams","debugLensFlare","LensFlareEffect","lensPosition","celestialOccluders","getEnvironment","ASTRONOMICAL_LENS_FLARE_DEFAULTS","lensDirtTexture","THREE.Clock","screenPosition","viewport","oldOpacity","internalOpacity","flarePosition","projectedPosition","raycaster","THREE.Raycaster","camWorld","sunDir","sunOffset","sunWorld","rayOrigin","rayDir","cameraQuaternion","THREE.Quaternion","lastCameraQuaternion","planetScale","celestialCenter","celestialScale","sunTransmittance","sourceVisibilityOffset","occluderVisibilityOffset","planetGroup","lastSourceOccluded","lastInView","hasLastCameraQuaternion","cameraMotion","lensFlareMaterial","elapsedTime","forceOpacity","instantaneousCameraMotion","lensFlareContainer","mouse","stateLabel","screenDistance","edgeWeight","sunAngularRadius","verticalHalfFov","cameraAspect","discRadiusY","ellipsoidR","ellipsoidRadiusForWorldDir","planetRadiusWorld","opticalOccluders","earthDistance","solarVisibility","celestialOccluder","bodyDistance","blocker","validHits","obj","planetOccluded","tileHit","overlayHit","hit","hitName","hitDist","checkTransparency","currentOpacity","responseRate","nextOpacity","intersects","forceOcclusion","maxTransmission","anyTransparent","maxOpacity","safeOpacity","SolarOpticsRenderer","flare","Scene","Mesh","Vector4","orbital","sourceScene","depthTest","autoClear","scissorTest","cloud","packing","HD_PROXY_LIMITS","materialVisible","nativeVisible","reachedFrame","node","buildHdProxyGeometry","maxTriangles","vertices","faces","attempt","clusters","remap","clusterOverflow","cluster","tooMany","edges","normals","masks","ab","ac","normal","prior","barycentric","edgeMask","corner","BufferGeometry","BufferAttribute","Sphere","proxyMaterial","FrontSide","darkUnderside","ShaderMaterial","colorMaterial","lighting","overview","terrain","alphaMap","uv","Matrix3","appearanceVersion","m","geometryVariant","sceneShell","HdSceneProxy","getSources","getSourceVersion","waitForRetirement","getSunPosition","getPlanetCenter","Frustum","stack","queued","visited","roots","variants","nextScene","triangles","sourceTriangles","completed","originals","materialVersion","unchanged","sourceGeometry","sourceVersion","built","bodyCenter","leases","retire","slice","deadline","retirement","frameRoot","relative","originalMaterial","mesh","bounds","revision","rootLimit","previousScene","updatedRoots","scissor","clearAlpha","toneMapping","shadowAutoUpdate","ratio","NoToneMapping","TerrainPathfinder","startDir","endDir","triTree","opts","sDir","eDir","pathRadius","weightUphill","weightDownhill","weightElevDelta","weightRough","weightLateral","weightHigh","smoothIterations","weightSlopeSq","weightDistance","collisionPenalty","clearance","stepsS","stepsT","startCol","goalCol","lateralMaxRad","dirs","elevs","radii","minElev","maxElev","sampleRadius","dir","dirAt","tNorm","angleS","baseDir","latAngle","idx","elev","elevRange","lateralPenalty","gScore","fScore","cameFrom","inOpen","startIdx","goalIdx","heuristic","sRem","distAlong","lateral","neighbors","bestIdx","bestF","ci","cj","cDir","cRad","cElev","di","dj","ni","nj","nIdx","nDir","nRad","nElev","horiz","elevDelta","slope","horizCost","cost","slopeAbs","heightNorm","midDir","midTerrainR","cPos","nPos","tentative","pathIdx","cur","rad","targetMin","smoothCount","prev","NIGHT_AIR_LIGHTING_GLSL","overlay","patchNightAirLighting","ground","patchPhotorealBackface","main","PhotorealBackfaceEffect","Effect","BlendFunction","AIRGLOW_EMISSION_DEFAULTS","NIGHT_LIMB_HAZE","haze","AIRGLOW_EMISSION_GLSL","SCALES","CloudResolutionPolicy","eligible","SHARED_UNIFORMS","NativeXRSkyMaterial","SkyMaterial","THREE.AgXToneMapping","THREE.LinearToneMapping","THREE.ReinhardToneMapping","THREE.CineonToneMapping","THREE.ACESFilmicToneMapping","THREE.NeutralToneMapping","getAltitudeCorrectionOffset","targetSpace","FRAGMENT","UnderwaterEffect","_camera","EffectAttribute","ocean","submerged","live","light","east","north","local","LOCAL_CLOUD_FIELD_DEFAULTS","localCloudGrid","gridSize","spanDeg","lats","lons","packLocalCloudField","records","precip","localCloudWeight","altitudeM","LocalCloudCoverField","json","ZOOM","TILE","REFRESH_MS","MRMS_BOUNDS","precipitationSourcesFor","toMercator","precipIntensityFromRgba","g","LocalPrecipitationField","active","x0","y0","spec","getMapLayer","resolveMapSource","ctx","drawn","tx","ty","rgba","HORIZON_BLUR_DEFAULTS","AtmosphericHorizonBlurEffect","getWorldToECEF","_renderer","worldToECEF","viewToECEF","OCEAN_SURFACE_LAYER","OceanSurfacePass","THREE.DepthTexture","THREE.UnsignedIntType","depthTexture","background","layerMask","waterMask","waterMaterial","lights","waterDepthWrite","copy","reflection","OceanDepthPass","PHOTO_DEFERRED_LIGHTING_LAYER","PHOTO_DEFERRED_ASSET_LAYER","PHOTO_MASK_OCCLUDER_LAYER","assertPhotorealDeferredLightingReady","meshCount","normalReadyCount","missingNormalCount","setPhotorealDeferredLighting","hasNormal","lightingEnabled","deferredMeshes","occluderMeshes","BLACK","isOpaque","isEmissive","toPhotorealAlbedoMaterial","MeshBasicMaterial","track","preparePhotorealAssetLighting","counts","converted","markPhotorealMaskOccluder","photorealAssetMaskCounts","createAssetMaskMaterial","DoubleSide","_geometry","contributes","PhotorealLightingMaskPass","selectionLayer","Selection","THREE.MeshBasicMaterial","RenderPass","clearPass","make","layer","frameBufferType","_inputBuffer","_outputBuffer","stencilTest","passes","PHOTO_SURFACE_HORIZON_GLSL","PHOTO_SURFACE_VISIBILITY_VERTEX_PARS","PHOTO_SURFACE_VISIBILITY_VERTEX_MAIN","PHOTO_SURFACE_VISIBILITY_FRAGMENT_PARS","PHOTO_SURFACE_VISIBILITY_FRAGMENT_MAIN","enforcePhotorealOpaqueDepthMaterial","preparePhotorealSurfaceVisibilityMaterial","previousOnBeforeCompile","previousProgramKey","preparePhotorealSurfaceVisibilityMaterials","preparedCount","GRID_Y","GRID_X","uniformValue","waterGeodeticPosition","waterGeodeticCoordinates","sampleReflectionWater","image","range","WaterReflectionView","PerspectiveCamera","Plane","horizonLimit","seaHeight","equatorial","polar","aa","qa","qb","qc","found","plane","clip","overscan","WaterReflectionAtlas","ShaderPass","extraWidth","extraHeight","cameraFar","aw","ah","bw","bh","cw","ch","rw","rh","kw","kh","rowsFit","columnsFit","rows","bx","by","cx","cy","WebGLRenderTarget","HalfFloatType","auto","reflectionAerialShader","prototype","helper","reflectionCloudShader","ray","CAMERA_UNIFORMS","AERIAL_OWNED","copyValue","copyUniforms","skip","sameDefines","ReflectedCloudPass","_input","_output","ReflectionResultPass","WaterReflectionCapturePass","system","kilometres","correction","constant","METER_TO_LENGTH_UNIT","own","EffectComposer","update","EffectPass","targets","jobs","cloudsRequested","cloudMaterial","cloudChanged","shadow","sunVisible","extra","RAIN_LAYER","RainPass","override","CloudColorPass","CustomBlending","OneFactor","OneMinusSrcAlphaFactor","AddEquation","AtmosphericEmissionPass","extras","drawMain","LIQUID_CODES","SHOWER_CODES","SNOW_CODES","finiteNonnegative","areWeatherCloudsEnabled","DEFAULT_LOCAL_CLOUD_LAYERS","DEFAULT_CLOUD_TERRAIN_CLEARANCE","CLOUD_LAYER_KEYS","cloudLayerTopRadius","layers","bottomRadius","configuredCloudTopRadius","terrainRadius","gap","deriveSceneWeatherState","maxAgeMs","maxDistanceKm","units","windUnit","windScale","gustUnit","gustScale","amountScale","unit","amount","rainScale","showerScale","totalScale","snowScale","liquid","solid","setWeatherBasis","planetQuaternion","south","EARTH_PRIME_MERIDIAN_OFFSET_RAD","weatherWindFrom","bearing","NightVisionEffect","tracks","SarEffect","planet","field","SKY_DEPTH","FOCUS_MIN_M","FOCUS_MAX_M","DEPTH_GLSL","OPTICS_UNIFORMS_GLSL","OPTICS_GLSL","PASS_HEADER_GLSL","PASS_VERTEX_GLSL","PASS_VERTEX_GLSL3","toGlsl3","MAX_SAMPLES","COMPOSITE_FRAGMENT","LAYER_FRAGMENT","DISK_FRAGMENT","FOCUS_FRAGMENT","RGBAFormat","LensDepthOfFieldEffect","LinearMipmapLinearFilter","LinearFilter","blur","GLSL3","OrthographicCamera","PlaneGeometry","log","depthPacking","hw","hh","rt","renderTarget","write","previousTarget","disk","FILM_GRAIN_SENSOR","FilmGrainEffect","chroma","ColorGradeEffect","contrast","brightness","saturation","CA_FRAGMENT","LensChromaticAberrationEffect","LensEffectsStage","composer","beforePass","wasDof","suspended","depthOfField","chromaticAberration","CloudAtmosphereAttachments","cascadeCount","replacements","DataTexture","UnsignedByteType","NoColorSpace","initial","DataArrayTexture","validateCompiledScenePrograms","gl","checked","prepared","programLog","shaderLogs","XRGpuTimer","ext","ns","age","dependencies","THREE","ToneMappingEffect","ToneMappingMode","SMAAEffect","SMAAPreset","NativeXRAtmosphereRenderer","createNativeXRRuntime","EARTH_RADIUS_M","xrTerrainRange","horizon","xrTerrainErrorScale","distanceM","XRTerrainDistancePolicy","descriptor","self","CAMERA_FIELDS","freezeCamera","patchNativeCloudReprojection","getPlanetMatrix","inverse","copyCamera","copyHistory","NativeXRClouds","empty","nativeCenter","BasicDepthPacking","layouts","eye","eyeCamera","leaf","OVATION_URL","GRID_W","GRID_H","RETRY_MS","TOP_ALT_M","GEOMAGNETIC_POLE","AURORA_VISIBILITY","geomagneticPoleLocal","MAG_POLE","AuroraSystem","THREE.ClampToEdgeWrapping","getFetchQueue","aurora","topAltitude","pathRef","depthBias","invProjectionMatrix","invViewMatrix","cameraWorld","planetCenterW","sunDirWorld","planetMatrixInverse","timeSec","depthSource","stale","retryPending","retryReady","targetRadius","FIRE_API_URL","FireSystem","features","splatR","feature","coordinates","frp","bright","gx","gy","yy","xx","d2","surfaceMode","MASK_WIDTH","MASK_HEIGHT","DEFAULT_TOP_ALTITUDE_M","densityByte","polygonsOf","unwrapRing","points","wrap","coordinate","SmokeSystem","metadata","ordered","polygons","byte","polygon","unwrapped","planetCenterWorld","sunDirectionWorld","timeSeconds","carrierRadius","MAX_LUT_ELEMENTS","BLOCK_ELEMENTS","throwIfAborted","convertHalfFloatLut","yieldTask","yieldToEventLoop","DataUtils","prepareAtmosphereLuts","disposeAtmosphereLuts","DEFAULT_BASE_PATH","DEFAULT_TONE_MAPPING_EXPOSURE","DEFAULT_ATMOSPHERE_BASE_OFFSET_M","DEFAULT_SURFACE_ATMOSPHERE_BASE_OFFSET_M","DEFAULT_ADAPTIVE_BASE_OFFSET","deriveRegionalAtmosphereBaseOffsets","minOffset","maxOffset","orbitClearance","surfaceClearance","localDepression","DEFAULT_AIRGLOW_DAY_STRENGTH","ORBIT_DAY_LIMB_RADIANCE_SCALE","ORBIT_DAY_LIMB_LOG_CURVE","DEFAULT_CLOUD_QUALITY_PRESET","DEFAULT_SKY_TUNING","CLOUD_DISTANCE_TUNING","ORBIT_CLOUD_DISTANCE_TUNING","DEFAULT_CLOUD_COMPOSER_CLOUD_MAX_ALTITUDE_M","DEFAULT_CLOUD_COMPOSER_CLOUD_HYSTERESIS_M","ENVIRONMENT_SURFACE_EFFECT_MAX_ALTITUDE_M","DEFAULT_CLOUD_SHADOW_TUNING","DEFAULT_NIGHT_IRRADIANCE_SUN_DOT_MIN","DEFAULT_NIGHT_IRRADIANCE_SUN_DOT_MAX","DEFAULT_NIGHT_MIN_IRRADIANCE","ORBIT_CLOUDS_BBOX","ORBIT_CLOUDS_RETRY_BASE_MS","ORBIT_CLOUDS_RETRY_MAX_MS","CLOUD_WARMUP_IDLE_TIMEOUT_MS","CLOUD_SURFACE_ACTIVATION_MAX_RAY_DISTANCE_M","CLOUD_SURFACE_ACTIVATION_MAX_ITERATIONS","CLOUD_SURFACE_ACTIVATION_MAX_SHADOW_LENGTH_ITERATIONS","CLOUD_SURFACE_ACTIVATION_SHADOW_ITERATIONS","CLOUD_SURFACE_ACTIVATION_HEADROOM_MS","CLOUD_SURFACE_ACTIVATION_PROGRESS_STEP","DEFAULT_ORBIT_CLOUDS","ORBIT_CLOUD_VERTEX_SHADER","ORBIT_CLOUD_FRAGMENT_SHADER","resolveOrbitCloudsBaseUrl","rawBaseUrl","trimmed","AtmosphereCloudsSystem","lightingSystem","basePath","useToneMapping","toneMappingMode","enableDithering","deferCloudWarmup","atmosphereBaseOffset","surfaceAtmosphereBaseOffset","MAX_SURFACE_LIGHT_EMITTERS","POSTPROCESS_BLOOM_EFFECT_DEFAULTS","LIGHT_POLLUTION_BLOOM_DEFAULTS","baseUrl","usesDefaultProxy","hasBackendOverride","settled","finish","stage","deferred","NativeRenderer","preset","nowSeconds","cameraDirection","snapshot","getSurfaceLightRegistry","starts","ends","params","endScratch","emitter","directionFromLatLon","detailTexture","sourceEnabled","syncScalar","targetName","sourceLightPollutionIntensity","simpleCloudTexture","cloudNightAirglowColor","detailBounds","auroraNeeds","fireNeeds","smokeNeeds","offsetMeters","force","numericKeys","maxStep","converge","nextOrbit","nextSurface","effectiveBefore","effectiveAfter","nextActive","surfaceCameraMode","nextOffset","physicalSunOwnsDisk","physicalMoonOwnsDisk","cameraDistance","atmosphereBottom","elevationMeters","terrainHeightAboveAtmosphereBottom","prevElevation","clearanceMeters","layerIndex","altitudeAboveTerrain","anyChanged","libraryAltitude","layerInfo","cfg","cloudPipelineReady","oceanMesh","waterVisible","submergedWater","airglowVisible","auroraMesh","auroraVisible","camRadius","hysteresis","exitAltitude","underwater","cloudWarmupWasScheduled","activePasses","composerOwnedEffects","atmosphereBottomRadius","atmosphereTopRadius","AtmosphereParameters","Ellipsoid","PHOTOREAL_ALBEDO_SCALE_DEFAULT","CloudsEffect","startupAltitude","lightingMaskMaterial","multisampling","gBufferDisabled","renderAerial","finalEffects","bloom","BloomEffect","smaa","dithering","DitheringEffect","register","complete","fail","requestedLutType","precomputedPromise","PrecomputedTexturesLoader","textureLoader","THREE.LinearMipMapLinearFilter","existing","loadData3DTexture","property","loadKey","THREE.Data3DTexture","CLOUD_SHAPE_TEXTURE_SIZE","CLOUD_SHAPE_DETAIL_TEXTURE_SIZE","STBNLoader","moonCenter","moonRadius","moonPhysicalRadius","baseAlt","coreAlt","fringeAlt","riseScale","tailScale","colHorizon","colCore","colUpper","colFringe","camDist","fringe","cameraAltitudeM","activationBlend","desiredMaxRayDistance","maxRayDistance","cameraRadius","disableAltitude","enableAltitude","baseMaxRayDistance","shellRadius","requiredDistance","cloudsParams","baseMaxStep","baseMinStep","iterations","idealStep","targetMaxStep","baseScale","targetScale","useLogDepth","applyDefine","updated","depthCompatible","skyPatched","orbitalGroundCompatible","celestialOcclusionCompatible","solarEclipseCompatible","surfaceCityLightingCompatible","PATCH_MARKER","ORBITAL_GROUND_MARKER","CELESTIAL_OCCLUSION_MARKER","SOLAR_ECLIPSE_MARKER","SURFACE_CITY_LIGHT_MARKER","SURFACE_OVERLAY_EMITTER_MARKER","DIRECT_LOG_DEPTH_MARKER","VISIBILITY_MARKER","lunarUniformNeedle","mainImageNeedle","solarIrradianceNeedle","solarIrradianceReplacement","uniformNeedle","uniformBlock","surfaceCityUniformNeedle","surfaceCityUniformBlock","legacyDepthTestNeedle","currentDepthPreludeNeedle","currentDepthPreludeReplacement","currentReconstructionNeedle","currentReconstructionReplacement","SKY_OPACITY","currentSkyBlockNeedle","currentSkyBlockReplacement","legacySkyBlockNeedle","legacySkyBlockReplacement","skyStart","skySnippet","surfaceCityLightingNeedle","surfaceCityLightingReplacement","NIGHT_MARKER","radianceNeedle","radianceReplacement","nightBlockRegex","cityAir","optimizeDryWaterReflectionShader","tuning","setValue","hadPatchedContract","hasLocal","hasOrbit","localPatched","orbitPatched","sceneDepthNeedle","cameraPosNeedle","signature","ok","callNeedle","declNeedle","factorNeedle","needle","geographic","solarLightingNeedle","lightingNeedle","celestialUniforms","mainPatched","_rotDelta","_invCurr","origCopyCameraSettings","THREE.BasicDepthPacking","cloudsMaterial","shadowMaterial","meridianOffset","offsetX","uvRegex","replacement","allPatched","forceBaseRefresh","coverageScale","scatteringScale","absorptionScale","turbulenceScale","coverage","turbulenceDisp","eased","simplify","baseIterations","targetIterations","applyCount","desired","bottomUniform","uBottom","uTop","THREE.NoToneMapping","baseOffsetMeters","surfaceBaseOffsetMeters","adaptiveBaseOffset","irradianceScale","shadowRadius","sunIrradiance","skyIrradiance","skyLight","transmittance","inscatter","moon","skyTuning","cloudLayers","cloudTerrainClearance","orbitClouds","airglow","lightPollution","lightPollutionBloom","fire","smoke","nightMinIrradiance","nightIrradianceSunDotMin","nightIrradianceSunDotMax","baseOffsetValue","surfaceBaseOffsetValue","adaptiveOwnsOffsets","nextScale","nextSunLight","nextSkyLight","dedicatedLightBloom","getLayerConfig","handleKey","idleFlagKey","waitForTask","effects","effectList","mapSize","completions","previousFace","previousMip","previousToneMapping","completion","leafPasses","skyScene","carrier","clear","orbit","keepClearReady","release","runWarmup","cloudResourcesPrepared","scheduled","canRender","apply","nextPass","renderToScreen","orbitRequested","warmed","surfaceWarmed","orbitWarmed","cloudsActive","orbitActive","needsRefresh","overrides","clamp01","setNumber","applyLayerConfig","applyLayerProperties","showRaw","sourceDate","stepMs","snappedMs","snapped","day","todayUtc","isRaw","jitter","nextRetry","snapshotDate","variant","timeParam","blob","img","objectUrl","snapshotKey","isNasa","rawCanvas","rawCtx","imageData","alphaScale","alphaBias","rn","gn","bn","isNoData","redDominant","srcAlpha","mx","mn","sat","neutral","adjusted","THREE.CanvasTexture","fadeStart","fadeEnd","refreshMs","rawStale","prevRadius","prevLayer","prevSize","prevBaseUrl","prevNasaSnapshot","sizeKey","DEFAULT_CONFIG","Flashlight","THREE.SpotLight","THREE.Object3D","THREE.Group","RENDER_FRAME_OWNER","RenderFrameCoordinator","rendered","nextOwner","NASA_NIGHT_LIGHTS_TILE_SOURCE","NIGHT_LIGHTS_GLOBAL_ZOOM","NIGHT_LIGHTS_DETAIL_TILE_SPAN","MAX_MERCATOR_LATITUDE_RAD","TWO_PI","modulo","divisor","nasaNightLightsTileUrl","template","planetLocalToWebMercator","mercatorLatitude","sinLatitude","nightLightsDetailZoomForAltitude","fov","metresPerPixel","createNightLightsTileWindow","tileSpan","tileCount","focusX","focusY","startX","startY","spanUv","windowContainsFocus","marginTiles","localX","localY","margin","NasaNightLightsTileField","tileUrl","maxNativeZoom","detailTileSpan","concurrency","onUpdate","promise","worldPerPixel","tileMetres","column","cursor","loaded","job","DEFAULT_HDR_URL","MATTEASON_LIVE_CLOUD_MAPS_BASE_URL","EARTH_SPECULAR_TEXTURE_URL","EARTH_SIMPLE_CLOUDS_TEXTURE_URL","EARTH_SIMPLE_CLOUDS_REFRESH_MS","EARTH_WATER_NORMALS_TEXTURE_URL","PUBLIC_LIGHT_POLLUTION_WMS_URL","PUBLIC_LIGHT_POLLUTION_LAYER","LEGACY_NIGHT_LIGHTS_IMAGE_SERVER","NIGHT_LIGHTS_IMAGE_SERVER","NIGHT_LIGHTS_RENDERING_RULE","ORBITAL_HDR_EXPOSURE_DEFAULTS","SURFACE_TONE_MAPPING_EXPOSURE","MAX_MERCATOR","WORLD_BBOX_MERCATOR","isPlainObject","mergeDeep","SceneInitializer","container","PHOTOREAL_OCEAN_DEFAULTS","POSTPROCESS_BLOOM_DEFAULTS","startup","renderWidth","renderHeight","CAMERA_NEAR","CAMERA_FAR","e2","OrbitControls","EARTH_ORBIT_MAX_DISTANCE_M","SUN_EARTH_DISTANCE_M","TileScheduler","getHudInfoStore","XRSurfaceRig","rigApplied","worldPos","yawRad","xrCamera","pos","RGBELoader","pmremGenerator","THREE.PMREMGenerator","envMap","THREE.DepthFormat","THREE.MeshDepthMaterial","THREE.Float32BufferAttribute","clearOnly","atmosphereClouds","initPromise","preserveFailureState","quiet","quad","sunGeometry","sunColor","sunMaterial","lensFlare","suppressed","hexMaterial","THREE.LineBasicMaterial","THREE.LineLoop","pathMaterial","THREE.Line","earthUniforms","sunUniforms","frameSeconds","targetExposure","cameraAngularSpeed","priorAngularSpeed","motionAlpha","halfVertical","halfHorizontal","frameRadius","inverseSmoothstep","inner","outer","observerDistance","planetViewAngle","planetAngularRadius","planetFullFrameAngle","planetOverlap","planetCoverage","earthFrameWeight","earthPhaseLuminance","lambertianSpherePhase","sunFrameWeight","earthVisibility","moonVisibility","transmissionLuminance","viewAngle","exposureTarget","resolveOrbitalHdrExposureTarget","responseSeconds","orbitalExposureResponseSeconds","flareUniforms","oceanState","geo","regionalWeather","waterGeo","geoid","lowFpsUpdateMs","moveSq","camQuat","camDot","angleDelta","planetAngle","planetQuat","planetDot","moveEps","rotateEps","planetRotateEps","camPos","prevOverride","prevTarget","hasPrevOverride","hasPrevTarget","excludedVisibility","excluded","insideAtmosphere","nextSide","targetSamples","targetSamplesLight","sampleScale","registrations","previousCameraMask","previousBackground","previousOverrideMaterial","previousAutoClear","coordinator","photo","accept","expected","proxy","PhotorealInteriorRenderer","finalFramebufferWritten","completeFrame","lateSolarOptics","orbitalSolarOptics","legacyVisible","renderMain","flareVisible","useLateOptics","shouldRenderAtmosphereCloudPipeline","handled","prevAtmosphereVisible","excludedObjects","excludedSeen","shouldUpdateDepth","updates","dirty","appliedUpdates","newValue","missingUniforms","applyUniform","clamped","legacyAllowed","disableError","delayMs","analyticDepth","warmupState","specular","simpleClouds","water","streamingEnabled","simpleCloudStreamingEnabled","plan","streamed","tileField","tileFieldGlobal","tileFieldDetail","loadSpecular","loadClouds","loadWater","cloudSlot","cloudPromise","cloudResult","overlayPromise","adopt","blendMode","lightPollutionStreaming","ou","ov","su","sv","imageServerCandidate","buildWmsUrl","wmsWidth","wmsHeight","imageServerMatch","exportUrl","bbox","bboxSR","imageSR","format","renderingRule","isLocalRuntime","disc","worldRoot","provider","gpuSuspended","focalLength","swap","renderPass","bloomPass","DepthOfFieldEffect","distanceHint","manualRange","hintDistance","autoRange","maxRange","fxaa","FXAAEffect","quat","blurSmooth","fovSmooth","baseFov","maxBoost","maxSpeed","dampMin","dampMax","stamp","materialIntensity","tint","applyMaterial","starIntensity","galaxyIntensity","multiplier","sunIntensity","pixelRatio","fetchCatalog","maxBytes","galaxies","starRadius","starPositions","starSizes","starColors","starAlphas","starTwinkles","starMotions","starMagnitudes","motionVector","coolR","coolG","coolB","midR","midG","midB","warmR","warmG","warmB","starIndex","raDeg","decDeg","DEG2RAD","cosDec","motion","magNorm","twinkleSeed","twinkleUnit","twinkleSecondary","bv","buildMaterial","softness","STAR_SCINTILLATION_DEFAULTS","starGeometry","starMaterial","galaxyPositions","galaxySizes","galaxyColors","galaxyAlphas","galaxyTwinkles","galaxy","sizeArcMin","galaxyGeometry","galaxyMaterial","_earthRotationAngle","limbRatio","turbulenceAttenuation","sunAltitude","onAtmosphereCreated","onMaterialsReady","earthMaterial","atmosphereGeometry","atmosphereMaterial","hexSelection","metricHex","val","cornerDirs","midDirs","mid","cornerDir","cornerRadius","midRadius","firstCorner","firstRadius","positionArray","camDir","pathPositions","pw","i3","controls","dist","altUnits","ALT_30K_UNITS","down","pitchAngle","ALT_10K_UNITS","lookDir","depthW","depthH","canRestore","component","presentationTextures","nodes","MapPresentationResources","budgetMs","maxItems","maxWeight","reference","iterator","operation","completePhase","done","DEFAULT_DIR_SMOOTH","DEFAULT_SPEED_SMOOTH","DEFAULT_MIN_SPEED_MPS","DEFAULT_EMIT_INTERVAL_MS","MotionTracker$1","eventBus","dirSmoothing","speedSmoothing","minSpeedMps","emitIntervalMs","surfaceController","invDt","surfaceVel","surfacePos","surfaceDir","radialAmount","hasMotion","dirAlpha","speedAlpha","latLon","TransportEvent","TransportStatus","TransportType","generateUUID","createMessage","sessionId","deviceId","BaseTransport","oldStatus","listener","unsub","timeoutId","startTime","CentralizedTransport","checkInterval","queryString","socket","intentionalClose","latency","headers","createCentralizedTransport","wsUrl","httpUrl","TransportManager","preferredTransport","getSharedNknTransport","nknErr","newTransport","transport","subscriptions","getSocialStore","SocialStore$1","store","notification","sub","localDeviceId","localSessionId","targetDeviceId","sessionIds","instance","getTransportManager","initTransport","manager","DB_NAME","DB_VERSION","ENVELOPE_STORE","ELEVATION_STORE","IMAGERY_TILE_STORE","IMAGERY_ATLAS_STORE","IMAGERY_META_STORE","ELEVATION_MAX_ENTRIES","ELEVATION_PRUNE_BATCH","IMAGERY_DEFAULT_MAX_BYTES","IMAGERY_DEFAULT_MAX_ENTRIES","IMAGERY_PRUNE_BATCH","DEFAULT_BUCKET_DEG","normalizeLon","parseLatLonFromKey","getBucketForLatLon","bucketDeg","clampedLat","normalizedLon","latIndex","lonIndex","decorateElevationEntry","bucket","SceneStateStore","db","request","migrateIfNeeded","envelope","elevationEntries","imgTiles","imgAtlases","imgMeta","dedupedElevationEntries","stores","txn","elStore","decorated","tStore","aStore","mStore","byKey","uniqueKeys","maxEntries","bucketRadius","latBucketCount","lonBucketCount","centerLat","centerLon","hardMax","dLat","dLon","remaining","bucketEntries","bucketKey","dedupedEntries","toDeleteByCount","overBytes","avgBytes","toDeleteByBytes","deleteTarget","deleted","storeName","maxDeletes","stored","tileBytes","atlasBytes","atlasCount","tileCandidates","atlasCandidates","deletedBytes","storeSet","storesByName","getSceneStateStore","OPEN_METEO_FALLBACK_URL","OPEN_METEO_MAX_POINTS","EPQS_FALLBACK_URL","GMRT_FALLBACK_URL","OPEN_TOPO_FALLBACK_ENV_KEY","OPEN_TOPO_FALLBACK_URL","__vite_import_meta_env__","OPEN_TOPO_MAX_POINTS","ElevationClient","MapzenElevationTileSource","MAPZEN_GEOTIFF_TEMPLATE","getElevationFallbackEnabled","MAX_TILE_LEVEL","mc","resolver","queryBucketRadius","queryMaxEntries","querySignature","imported","hardLimit","unique","chunkSize","loadedEntries","chunk","_store","startupImportCap","maxImportEntries","elevation","tileLevel","front","added","batch","relay","dataset","nearRaw","midRaw","farRaw","near","far","deficit","strides","clampStride","fallbackValue","ringBudgetWeights","ringStrideMultiplier","sampleStrideMultiplier","batchSize","maxConcurrent","minIntervalMs","maxKBPerMinute","maxChunkBytes","maxRequestBytes","backendTimeoutMs","angleLimitDeg","surfaceMinLevel","maxVertexRecords","pendingTimeoutMs","pendingRecoveryIntervalMs","pendingRecoveryMaxPerTick","fullFetchMinLevel","initialSampleStrideMultiplier","viewshedMinDeg","viewshedMarginDeg","ringNearMeters","ringMidMeters","ringBudgetNear","ringBudgetMid","ringLodCaps","cacheEnabled","strideMult","clampPercent","nearPct","midPct","farPct","clampLevel","nextNear","nextMid","nextFar","normalizedMid","normalizedFar","baseStride","lvl","fullFetch","nextEntries","tileMax","candidateMax","vertexIndex","ev","cutoff","fallbackTried","fallbackApplied","statusCode","minInterval","statusText","batchText","msg","diag","resultSize","hasElevationOverride","providerId","legacyId","exponent","windowMs","limits","minuteMs","hourMs","dayMs","waitMs","sinceLast","oldest","directUrl","proxyPath","hostname","port","protocol","devPorts","wsPort","getElevationWsUrl","getElevationApiBase","locations","elevations","loc","sourceLocations","location","rec","sourceZoom","fallbackBase","appliedAny","locSlice","batchSlice","latList","lonList","applied","maxConcurrency","resp","workers","mapped","pickElevation","num","locParam","providers","endpoints","ref","maxRecoveries","recovered","activeRecovered","pendingSince","resetThreshold","sourceConfigured","pressure","floor","scaled","sourceBase","boost","thisBatch","bytesIn","decoded","toResults","batchRec","hasLocation","appliedCount","elevStats","batchSamples","matchedIndices","isMapzenRasterResponse","applyRecord","resolvedZoom","latStr","lngStr","elevStr","dot","angleDeg","RAD2DEG","angleStr","keySet","retryInvalidRecord","toFiniteElevation","positionalToleranceDeg","resultMatchesBatchRecord","locationsPresent","kb","clearPending","surfaceR","arcDist","alt","effective","keepRecords","maxDistanceM","cleared","baseR","immediateReschedule","targetCount","toClear","lastUsed","toRemove","allowActiveClientTiles","clients","hasClientsPenalty","evictScore","removed","capKB","totalBytes","immediate","mapzenSourceZoom","resolveMapzenSourceZoomForTriangle","tileCache","cachedHeight","focusDirection","invQ","cameraMoveDistance","fd","overCapacity","targetFree","freed","lu","wx","wy","wz","maxRecords","baseline","nextCap","useBackend","allowFallback","effectiveMaxConcurrent","effectiveMinIntervalMs","cameraPos","viewDir","maxAngle","useActiveTiles","activeCandidates","activeCandidateCount","camDirLocal","viewshedLimitRad","computeViewshed","horizonRad","viewshedMinRad","viewshedMarginRad","minLevelToFetch","offView","ANGLE_LIMIT_DEG","filterInPlace","predicate","cache","baseMaxCandidates","candidateMap","activeTiles","activeTileCount","activeTileLimit","selectedActiveTiles","selectedActiveTileCount","desiredProbeCount","probeCount","headCount","overflowStart","overflowCount","desiredPerTileLimit","maxCandidates","perTileLimit","forcedSeedLimit","forcedScanLimit","scanTileKeys","scanLimit","forceTile","cap","cacheEntry","keyCount","scanned","canRetry","forcedTiles","normalTiles","nextCandidates","useActiveRecords","activePriority","maxLevel","entryMin","recMin","baseLevel","ringCap","allowForce","forceLevel","basePriority","levelWeight","distClamp","distPenalty","maxDist","distScore","ringFactor","dotCam","angleScore","lodScore","basePassLevel","hasBasePending","allowBase","computeSortKey","ringRank","tilePriority","forcedInView","normalInView","forcedOffView","normalOffView","forcedSort","ka","totalBudget","normalReserve","forcedBudget","picked","addFrom","forcedRemaining","inViewNear","inViewMid","inViewFar","nearBudget","midBudget","farBudget","sendBatch","buildBackendPayload","locs","backendPayload","payloadBytes","best","outboundEvent","fallbackError","retryAt","fallbackErr","errTime","sendViaBackend","bytesOut","lookupCount","lookupHits","persistentQueuePending","storeQueuePending","backendFailurePressure","pushRecord","latLonToLocalDir","images","imageBytes","acquireImage","releaseImage","ImageryTextureOwnership","released","uniqueImages","textureBytes","references","decodedBytes","stagingCanvasBytes","refs","ImageryManager","mapSource","DEFAULT_WAYBACK_VERSION","tex","holds","releases","cacheKey","tagged","targetCache","cacheHit","toBlob","releaseCanvas","atlasTileCount","atlasZoom","avoidedTiles","res","WAYBACK_WMTS_CAPABILITIES","xml","versions","title","versionMatch","sortKey","dateMatch","versionId","knownLatest","requestId","latest","keepTiles","snapshotTiles","maxAtlasKeys","minX","minY","preferVersionId","normalizedPreferred","maxTileKeys","atlasLimit","tileLimit","seenTile","seenAtlas","atlasKeys","tileKeys","versionPrefix","hardReset","maxQueue","dropped","itemRing","prevRing","strict","contextKey","matchIndex","staleMs","staleIndex","enqueuedAt","minTiles","yieldFrame","maxX","maxY","requests","drawQueue","failedEntries","xUnwrapped","nextIndex","workerLimit","req","parentByKey","parentList","maxParents","parentTexByKey","parentHolds","fallbackQueue","parentTex","parentImage","parentW","parentH","quadW","quadH","maxAtlasTiles","padTiles","maxTileCacheMB","maxAtlasCacheMB","textureAnisotropy","useMobileTiles","maxConcurrentAtlasBuilds","maxConcurrentTileLoads","contextBurstTileLoads","contextBurstAtlasBuilds","atlasDrawBudgetMs","atlasDrawMinTiles","tileRetryDelayMs","atlasRetryDelayMs","retryBypassPriority","maxAtlasTileFetches","atlasTileFetchConcurrency","atlasParentFallbackEnabled","atlasParentFallbackMaxParents","maxQueuedTileRequests","maxQueuedAtlasRequests","firstKey","evicted","refCount","WMTS_ROOT","onProgress","safeZoom","vId","aborter","workerCount","notify","runWorker","chunks","processed","exported","missing","header","pad","mtime","encoder","writeString","str","writeOctal","checksum","nx","ny","midX","midY","clampedMinY","clampedMaxY","rawX","rawY","regionKey","maxZoom","normalizedVersionId","shouldDropTileRequest","itemVersionId","shouldDropAtlasRequest","centerX","centerY","kept","regionZoom","regionX","regionY","newMaxZoom","wTiles","hTiles","normalizedMinY","normalizedMaxY","normalizedH","resourceGeneration","tileX","tileY","tileZ","failedAt","bypassRetryDelay","effectiveZoom","queuedKey","existingQueued","shouldRequeue","isCurrent","cachedTexture","fetchStatus","usedLoaderFallback","shouldUseLoaderFallback","queueKey","atlasTex","failAtlas","fallbackZoom","probes","probeResults","successfulProbes","failedProbes","probeFailureRatio","severeProbeFailure","collected","totalTiles","successfulTiles","failedTiles","includeOwnership","tileLookups","atlasLookups","pendingWrites","MERCATOR_LIMIT","tileCoordinate","tileLocation","sampleTerrarium","dem","fx","fy","decodeTerrarium","heights","globePosition","orthometric","terrainGeometry","heightAt","uv2","quadrants","skirt","surfaceIndices","u1","v1","setTerrainCoverage","buildingGeometry","vertexLimit","rings","vectors","roof","THREE.ShapeUtils","triangle","buildingGeometryAsync","batches","indexCount","keyOf","imageFromBytes","MapSourceGlobe","onSurfaceChange","THREE.Frustum","loadMapsourceTerrain","preferred","targetZoom","THREE.Sphere","leaves","wanted","retained","rasterError","nativeDem","ancestor","imageTile","u0","v0","nativeRaycast","hits","inherited","coveredByAncestor","nw","se","createTerrainSurfaceChangeRegion","offsets","VectorTile","Pbf","changes","OVERVIEW_IMAGE_URL","OVERVIEW_MAX_ENCODED_BYTES","OVERVIEW_BITMAP_OPTIONS","overviewJpegDimensions","components","decodeOverviewImage","createBitmap","createImage","urlApi","revoked","revoke","removeCancel","cancelled","OverviewImageSource","fetcher","resource","dimensions","chunkStore","pendingChunkedResponses","CHUNK_STALE_MS","textDecoder","isNknDebugEnabled","_decodeBase64ToBytes","b64","binary","_concatBytes","merged","_cleanupStaleChunks","_resolvePendingResponse","st","_decodePayload","_parsePayload","_tryAssembleChunks","byteChunks","handleIncoming","src","totalChunks","pendingResp","WeatherManager","updateIntervalMs","minDeltaDeg","minFetchIntervalMs","cacheTtlMs","maxCacheEntries","safeUpdateInterval","defaultMinFetchInterval","defaultCacheTtl","latChanged","lonChanged","earliestNext","requestLat","requestLon","requestEpoch","scoped","retryAfter","retryMs","oldestKey","days","forecast","maxDays","DEFAULT_UPDATE_INTERVAL_MS","DEFAULT_MIN_DELTA_DEG","DEFAULT_REGION_RADIUS_KM","DEFAULT_CLOUD_INFLUENCE","DEFAULT_MAP_WIDTH","DEFAULT_MAP_HEIGHT","AUTO_REGION_ID","WeatherSystem","autoTarget","regionRadiusKm","cloudInfluence","uvLightingEnabled","latEl","lonEl","shouldUpdate","radiusKm","useHover","desc","cloudCover","humidity","ageSuffix","tuneables","precipitation","precipNorm","windNorm","cloudFactor","humidityFactor","stormFactor","baseCoverage","baseScattering","baseAbsorption","baseTurbulence","scatteringCoefficient","absorptionCoefficient","turbulenceDisplacement","lightShafts","shapeDetail","turbulence","el","parsed","ageMs","hasData","tempVal","cloudsVal","humidityVal","windVal","precipVal","updatedLabel","region","radiusDeg","latRad","cosLat","lonRadiusDeg","radiusX","radiusY","drawAt","grad","collect","object3d","geometries","skeletons","disposeOwnedObject3D","preserve","owned","keep","skeleton","MAX_MODEL_BYTES","MAX_PENDING","grants","listeners","ModelAdmissionError","getModelLoadStats","onModelCapacityAvailable","nextEntryIndex","aged","selected","bestPriority","bestDistance","rank","pump","reserved","reserve","runModelLoad","prepareModelBundle","fetchResource","urls","parentSignal","parentAbort","closed","transferred","releaseTextures","createUrl","check","jsonBytes","getWorkerPool","resourceCount","tail","localize","loading","asset","parser","loadBuffer","loadImageSource","imageLoader","OVERLAY_PAGE_BYTES","OVERLAY_PAGE_WEIGHT","MAX_ACTIVE","MAX_WAITING","MAX_PAGE_ITEMS","TOKEN","waiting","OverlayPageClientError","retryAfterMs","invalid","checkId","checkToken","checkAbort","drain","acquire","waitForOverlayPage","parsePage","jsonRetentionWeight","OverlayPageClient","principal","parse","account","onStatus","collection","yielded","page","overlayId","metadataOnly","expectedRevision","manifestCursor","lastLayer","creator","layerIds","nextCursor","layerId","itemCursor","lastItem","itemLease","pages","overlayAccountId","OverlaySessionScope","auth","accountId","previousController","scope","bindOverlaySession","OVERLAY_ADMISSION_WINDOW","OVERLAY_ADMISSION_SLICE","OverlayAdmissionPlanner","anchor","forOverlayAdmission","planner","stats","exhausted","rankedVersion","operations","OVERLAY_DOCUMENT_WEIGHT","forOverlaySlice","forOverlayAsyncSlice","ingestOverlayPages","sessionScope","releaseSession","itemCount","layerCount","DEFAULT_DA3_ANCHOR_AGL_M","MODEL_FILE_ROLES","firstString","isDa3ScanItem","resolveDa3HeightMode","resolveDa3AnchorAglM","resolveItemModelUrl","propertyUrl","links","linked","mime","fileId","outputFileId","SURFACE_ANCHOR_STATE","SURFACE_ANCHOR_POLICY","VERIFIED_STATES","normalizeSurfaceAnchorPolicy","normalizeSurfaceAnchorSnapshot","radiusM","sampledAt","sampledTime","terrainRevision","isVerifiedSurfaceAnchor","resolveSurfaceAnchorState","requiresSurface","policy","sampledRadiusM","fallbackRadiusM","fallbackKind","providerAvailable","aglM","sampleSequence","authoredVersion","attemptedAt","resolvedPolicy","resolvedAglM","attemptedAtValue","pinned","MISSING_MODEL_RETRY_MS","OverlaySubsystem","parentGroup","registry","assets","access","splineSubsystem","sceneInitializer","proximityTriggerManager","physicsSystem","clickTriggerManager","debugLogs","GLTFLoader","GeoBoundaryService","wantedItem","modelStats","builds","change","scheduleRetry","tryInit","changeType","itemId","layerPayload","itemEntry","layerEntry","nextPolicy","proximityState","resolvedId","properties","incoming","backendItem","mediaPlayback","overlayDoc","keepLoad","keepBuild","replaceLayers","executionId","previewItem","captureSessionId","placement","ellipsoidAltitudeM","rotationDeg","modelOriginOffsetM","itemOrEntry","ingress","matches","overlayEntry","normalizedOverlayId","normalizedItemId","normalizedLayerId","assetMutation","createIfMissing","itemType","resolvedOverlayId","existingItem","requestedItemId","resolvedLayerId","firstLayerId","incomingPatch","itemPatch","nextItemEntry","pointcloud","positionData","pointsNode","modelUrl","objects","prevOverlayId","nextOverlayId","sequence","wakeKey","regional","terrainSurfaceChangesAffectLatLon","surfaceRelativeDa3","overlayGate","overlaySource","overlayFlag","overlayVisible","overlayOverrides","layerCurrent","layerGate","layerFlag","layerVisible","layerOverrides","itemCurrent","itemGate","itemVisible","itemOverrides","mergedOverrides","geoGate","rule","rules","matched","observerPos","nextAllowed","gatingVisible","itemPos","distSq","loadSq","unloadSq","shouldLoad","shouldUnload","toggleCooldownMs","lastToggle","canToggle","isModelAsset","visibleThresholdSq","shouldShow","pointsInterval","isDa3","overlayPolicy","layerPolicy","itemPolicy","loadDistanceM","unloadDistanceM","loadDist","unloadDist","startM","endM","minFraction","curve","defaultValue","itemData","baseRadius","pointsPolicy","minF","inv","positionCount","owners","mergedProps","hash","scanId","seedParts","reviewPreview","baseItem","effectiveItem","propertyVisible","nextVisible","renderSignature","updateHook","unloadMode","onRemove","proximityPolicy","deferModelLoad","layerGroup","items","documents","nextIds","runtime","layerData","layerType","hasSourceRef","rendererFactory","it","shape","line","nextItem","spline","refKey","refItem","description","objectRadius","maxDistance","labelColor","THREE.BoxGeometry","lightIntensity","lightDistance","lightDecay","THREE.PointLight","THREE.CylinderGeometry","audioAnchor","ownerRef","gltf","visitor","authenticated","fileBase","requestSignal","denial","bundle","THREE.LoadingManager","reasonCodes","placeholder","lockSprite","THREE.SpriteMaterial","sprite","THREE.Sprite","requirements","tokenType","display","nftType","tokenId","maybeId","existingRoot","box","THREE.Box3","da3SurfaceRelative","alignToSurface","placementOwnsHeight","anchoredRaw","anchoredElevation","authoredKey","pinnedSnapshot","heldRadius","localDir","worldDir","worldQuat","requireFreshPhotoHit","raycastR","vertexR","baseQuat","degQuat","rotation","euler","THREE.Euler","axisRaw","localQuat","alignMissingDa3Orientation","upAxis","alignQuat","flipQuat","transparent","rootOverride","targetSize","upAxisName","axisSize","originOffset","prevKey","nextKey","prevProps","nextProps","prevNum","nextNum","objectType","objectId","action","canEdit","canMove","layerDocs","layerMetadata","itemDocs","triggers","actions","trigger","triggerDistance","exitDistance","once","cooldown","mass","restitution","friction","physicsData","isEntering","playback","overlayIdFor","rangeM","authored","clickTriggers","conditions","clickConditions","cond","hoverEnabled","clickEnabled","retirements","API_BASE","OverlayApiError","errorCode","OverlayApiService","includePublic","includeOwnedEntries","client","pageSize","overlays","pageOverlays","method","idempotencyKey","includeArchived","pathId","definition","expectedRowVersion","publication","resourceId","after","commandLimit","telemetryLimit","grantSecret","ttlSeconds","leaseId","fleetId","missionId","expiresInSeconds","assignmentId","memberId","includeRevoked","delegationId","styleJson","inheritPolicies","dataSourceVersionId","elevationM","orientationQuat","sourceType","embedUrl","channelId","file","role","encrypt","formData","sensorMetadata","fileName","resolvedName","jobId","sceneData","sceneId","updateData","myScansOverlay","gatingPolicyId","bindingId","maxUses","shareKey","overlayApiServiceInstance","getOverlayApiService","createOverlaySceneApi","getSubsystem","getApi","subsystem","pageOptions","draft","MOVE_FLUSH_MS","MAX_PENDING_MOVES","MAX_TARGET_CACHE","textId","numberOrNull","normalizeTarget","objectUuid","mergeTarget","primary","head","hasTarget","parseJsonMaybe","decodeBase64ToUint8","normalizePointcloudPayload","HydraOverlayIngress","HYDRA_INTEROP_CONTRACT","meta","rawEnvelope","interopEnvelope","normalizeInteropEnvelope","INTEROP_ERROR_CODE","targetResolution","targetError","metering","readInt","readFloat","family","ticket","verification","billable","reservationMicros","estimatedMicros","messageId","mediaPayload","interopContract","normalizedType","normalizedEvent","mappedBySession","mappedByObject","mapRef","withInteropContractFields","errorDetail","contractStatus","requireItem","pose","livePosition","op","nextEnvelope","patchProps","explicitModelUrl","patchResult","glbBytes","streamIds","videoFramePayload","audioPayload","videoStream","audioStream","hlsUrl","OverlayRegistry","factory","DataSourceApiService","standardType","crs","bboxWgs84","sourceId","parentVersionId","transformChain","setActive","remoteUrl","assetType","contentType","dataSourceApiServiceInstance","getDataSourceApiService","DEFAULT_COLOR","DEFAULT_OPACITY","DEFAULT_POINT_SIZE","DEFAULT_OFFSET_M","DEFAULT_LIMIT","normalizeType","resolveStyle","VectorSourceLayer","geojson","style","typeSet","filter","filterLang","geoAsset","remote","useAuth","fetchOptions","pointColor","fillColor","fillOpacity","pointSize","offsetM","fillEnabled","labelField","labelMax","linePositions","pointPositions","fillPositions","maxFeatures","featureCount","handleCoords","cb","coord","pushPoint","labelValue","pushLine","lonA","latA","lonB","latB","pushPolygon","centroid","handleGeometry","poly","lines","THREE.LineSegments","THREE.PointsMaterial","sumLat","sumLon","minLat","maxLat","minLon","maxLon","centerDir","to2D","holes","hole","allPoints","tri","pt","fontSize","padding","metrics","aspect","raycast","sampled","DEFAULT_ZOOM","MAX_ZOOM","TileSourceLayer","createDataSurfaceGeometry","firstTile","mercatorCanvas","mercCtx","equirectCanvas","worldPosToLatLonLocal","updateDeg","detailZoom","maxLatLimit","lonLatToTileCoords","tileWidth","tileHeight","mercCanvas","mercWidth","mercHeight","mercData","spanLon","spanLat","outWidth","outHeight","outCanvas","outCtx","outImage","outData","mercY","my","mercX","srcIdx","dstIdx","uvs","dataSurfaceRadius","latLookup","VECTOR_ASSET_TYPES","TILE_ASSET_TYPES","COG_ASSET_TYPES","pickAssetByType","DataSourceLayerRenderer","nextLayer","details","nextDelegate","vectorAsset","tileAsset","cogAsset","standard","tileMode","StreamHub","EntitySystem","overlaySubsystem","accessController","entity","entityId","boundItemId","orientation","bound","AssetSubsystem","_fileDescriptors","_fileId","CLOCK_UNCERTAINTY_FLOOR_MS","MAX_SENSOR_AGE_MS","DEFAULT_ORIENTATION_ACCURACY_DEG","minimum","maximum","screenOrientationDegrees","diagonalCovariance","normalizeQuaternion","cameraToEnuQuaternion","sensors","hasLiveOrientation","sourceQuaternion","cameraToWorld","opencvToThreeCamera","matrix","quaternion","orientationRecord","cameraToEnu","headingConfidence","covarianceForOrientation","radians","BrowserGeoPoseProvider","gps","wallClockOriginMs","monotonicOriginMs","sampleIndex","monotonicMs","capturedAtMs","nowMonotonicMs","nowWallMs","hasPosition","horizontalAccuracyM","verticalAccuracyM","sensorTimeMs","sensorAgeMs","positionSigma","verticalSigma","angular","FIELD_PROOF_SCHEMA","FIELD_PROOF_MAX_GPS_AGE_MS","FIELD_PROOF_MAX_GPS_ACCURACY_M","FIELD_PROOF_MIN_PROXIMITY_M","FIELD_PROOF_MAX_PROXIMITY_M","cleanText","normalizeFieldContributor","contributor","displayName","geodesicDistanceMeters","lat1","lat2","isMobileFieldDevice","navigatorObject","windowObject","uaMobile","touch","coarsePointer","buildFieldPose","positionTimestampMs","evaluateFieldProof","reasons","rawAccuracyM","accuracyM","rawMeasuredAtMs","measuredAtMs","gpsAgeMs","targetPosition","distanceToTargetM","allowedDistanceM","buildFieldAssetProof","validation","note","hasPhoto","normalizedNote","finiteNumber","feedRecords","normalizeEvidence","proof","observation","contribution","remoteMedia","normalizePublicFieldAssetFeed","grouped","proofAsset","evidence","createdBy","areaRadiusM","FieldAssetApiService","apiBase","form","getFieldAssetApiService","_tmpWorldDir","_tmpWorldQuat","PUBLIC_REFRESH_MS","PUBLIC_REFRESH_MOVE_DEG","PUBLIC_RADIUS_M","contributorLabel","shortDate","mergeFieldAssetRecords","FieldAssetLayer","tagStore","getTagStore","api","activeIds","tags","tag","moved","labelSystem","createdAt","subText","clean","publicAttachmentUrl","AccountNoteApiError","normalizeAccountNote","normalizeAccountNoteActivationRadius","attachment","mutationPayload","activationRadiusM","ACCOUNT_NOTE_ACTIVATION_RADIUS_DEFAULT_M","ACCOUNT_NOTE_ACTIVATION_RADIUS_MIN_M","ACCOUNT_NOTE_ACTIVATION_RADIUS_MAX_M","AccountNoteApiService","noteId","attachmentId","getAccountNoteApiService","_worldDir","_worldQuat","shortText","AccountNoteLayer","ownerRequest","publicNotes","ownerNotes","notes","ellipsoid","requirePhoto","formatAccountNoteActivationRadius","MAX_ACCESS_EVALUATION_BATCH","buildApiError","fallbackMessage","GatingApiService","resetSeconds","cooldownMs","policyId","rootGroup","gatingApiServiceInstance","getGatingApiService","AccessEvents","AccessController","evaluationPromise","promises","decisionSet","allow","deny","warnNow","reasonCode","accessControllerInstance","getAccessController","PresenceClient","ws","peer","connected","SocialApiService","targetUserId","userId","includeDismissed","notificationId","socialApiServiceInstance","getSocialApiService","SocialEvents","SocialStore","outgoing","oldCount","friend","authState","accessToken","getBackendWsUrl","socialStoreInstance","AVATAR_MODEL_ID","DEFAULT_AVATAR_APPEARANCE","HEX_COLOR","clampNumber","numeric","normalizeAvatarAppearance","rawColor","baseColor","avatarAppearanceSignature","appearance","p2pModulePromise","nknIdentityStorePromise","loadP2PModule","loadNknIdentityStore","DEFAULT_SHARE_CONFIG","DEFAULT_PEER_SHARE","normalizeAvatarConfig","PUBLIC_PRESENCE_RADIUS_M","DEFAULT_PRESENCE_STREAM_HZ","MAX_PRESENCE_STREAM_HZ","normalizeNetworkAddress","address","network","TRANSPORT_ORDER","normalizeTransportLabel","endpointFromCandidate","candidateTimestampMs","fallbackMs","iso","normalizeEndpointCandidates","assign","transportKey","endpoint","selectTransportCandidate","selectedTransport","endpointCandidates","staleRejectionCount","transports","freshness","bestScore","ts","freshBonus","selectedBonus","stalePenalty","PresenceSystem","requestedUpdateHz","_dt","wallNow","peerId","filteredState","initialState","P2PDirectory","P2PRegistryClient","getStoredAddress","canonicalAddress","selfId","published","headingDeg","pitchDeg","contactRadius","nknAddress","candidateStamp","animState","viewHalfFov","viewRad","viewportWidth","viewportHeight","verticalFov","avatarHeight","pixelRangeM","deviceType","userLabel","exposeUsername","stableId","parentQuat","presenting","vFov","hFov","minRad","marginRadBase","maxRad","surfaceMarginRad","orbitMarginRad","isGrounded","isCrouching","isJumping","isSwimming","localPlayer","peerManager","friends","friendId","share","isFriend","publicState","discoverySource","selectedCandidate","providerFingerprint","marketplaceCatalog","friendState","friendUserId","localUserId","friendsEnabled","publicEnabled","staleCount","BIRDSONG_REGIONAL_PROFILES","ROAD_BANDS_HZ","DEFAULT_TEMPERATURE_C","DEFAULT_HUMIDITY_PERCENT","angularDistance","deltaLat","deltaLon","haversine","nearestBirdsongProfile","latitudeDeg","longitudeDeg","profiles","nearestAngle","solarDaylightHours","sceneTimeMs","declination","daylightHours","birdActivityForLocalHour","hour","sunrise","sunset","wrappedDistance","gaussian","dawn","dusk","daytime","nocturnalWildlifeActivity","localHour","temperatureC","humidityPercent","precipitationMm","biome","predawn","night","darkness","temperature","warmth","rain","habitat","wetHabitat","aridHabitat","birdSpectrogramCurves","voice","frequency","amplitude","contour","syllables","cycle","syllableWindow","phraseWindow","speedOfSoundMps","resolveLocalHour","utcOffsetSeconds","offsetSeconds","trafficActivityForLocalHour","x1","y1","atmosphericLowpassHz","distanceKm","dopplerFactor","sourcePosition","listenerPosition","sourceVelocity","listenerVelocity","soundSpeedMps","sourceRadial","listenerRadial","roadAcousticProfile","road","roadClass","classGain","flow","flowGain","speedGain","wet","bandGains","engine","tire","MEAN_EARTH_RADIUS_M","buildRoadPathMetrics","cumulativeM","sampleRoadPath","previousDistance","segmentLength","vehicleEngineState","speedMps","accelerationMps2","acceleration","gearThresholds","gear","gearRatios","wheelRpm","rpm","cylinders","habitatAcousticEligibility","observerIsOcean","greenDistanceM","waterDistanceM","hasGreenAnchor","hasWaterAnchor","coastalLand","seededNoiseBuffer","channel","stopNode","SpatialAmbientSoundscape","prepareAcousticGeometry","sampleSurfaceRadius","sampleAcousticPath","roads","soundSpeed","habitatEligibility","holder","heightM","spreadM","surfaceRadius","azimuth","localDirection","call","greenDistance","greenFactor","activity","intervalSeconds","eligibility","waterDistance","waterFactor","capacity","cricket","samples","pulse","pulsePhase","fundamental","harmonic","harmonicGain","fundamentalGain","roadCount","aircraftCount","refDistance","rolloff","reflectionHolder","audio","THREE.PositionalAudio","directFilter","directLevel","reflectionAudio","reflectionDelay","diffusionDelay","diffusionTap","reflectionFilter","reflectionLevel","audioNow","directGain","atmosphericCutoff","directCutoff","reflectionPoint","reflectionGain","diffusion","emitters","mix","bandIndex","gain","engineColor","engineMix","oscillator","engineLfo","engineLfoGain","lowpass","noise","noiseGain","vehicle","mainRoad","roadKey","frameDt","harmonicRatio","tireShare","audible","propagationDelay","baseFrequency","param","createRainAudioGraph","gains","master","limiter","pink","white","hp","lp","rateMmH","gustExcessMps","RainAudio","rate","excess","SPEED_OF_SOUND","airAbsorptionCutoff","coneGain","angleRad","outerGain","deg","distanceGain","estimateEmitterGain","facingAngleRad","occlusionGain","cone","air","sharedReverb","getSharedReverb","impulse","convolver","createAcousticEmitter","reverb","occlusionFilter","reverbSend","sourceWorld","listenerWorld","occluded","bounce","AudioSystem","streamHub","entitySystem","THREE.AudioLoader","sourceWorldPos","listenerWorldPos","worldDirection","pcmStream","handleId","osc","sound","volume","loop","onEnd","cleanup","snd","buf","hardness","velocity","roughness","decay","gainMul","freq","osc1","osc2","enableAudio","events","THREE.Audio","resolvedStream","masterGain","subscription","tryLoad","mediaEl","oscGain","harmonics","oscillators","addOscillator","gainValue","sampleRate","floatArray","int16Array","frameCount","audioBuffer","channelData","sr","len","f0","amHz","twoPI","env","am","stiffness","baseF","velBoost","f1","baseTau","tau1","tau2","tau3","modes","contactLen","phases","attack","tau","contact","micro","MPH_PER_MPS","DEFAULT_MAX_MPH","DEFAULT_MAX_MPS","lerp","setTarget","makeCurve","noiseWorklets","ensureNoiseWorklet","workletCode","createNoiseNode","sp","createBrownNoiseNode","createWindEngine","noiseMain","noiseGust","noiseTurb","noiseBrown","lowLP","midBP","highHP","hissBP","lowGain","midGain","highGain","hissGain","whistleBP","whistlePre","whistleGain","brownHP","brownLP","brownBP","brownGain","buffetGain","baseGain","gustGain","comp","gustLP","gustPre","gustShape","gustDepth","one","turbLP","turbToHiss","turbToWhistle","turbToBaseGain","speedMph","dirDeg","gustiness01","brown01","volume01","frontFactor","crossFactor","dirLoud","hiss","whistle","lowHz","midHz","highHz","hissHz","whistleHz","whistleQ","gustDepthVal","brownDir","brownCtl","brownLevel","buffetLevel","brownHz","buffetHz","WindAudio","gustiness","gustinessOverride","speedScale","minSpeed","massBed","mph","vol","modulation","RainSurfaceAtlas","infoReset","PRECIPITATION_SPAN_M","PRECIPITATION_HEIGHT_M","radicalInverse","precipitationSeed","precipitationProxyDensity","SPAN","vertexHeader","HEIGHT","rainVertex","rainFragment","snowVertex","snowFragment","splashVertex","splashFragment","period","makeGeometry","THREE.InstancedBufferGeometry","seeds","THREE.InstancedBufferAttribute","RainSystem","sunDirection","frameNowMs","cloudTopRadius","snowRate","fadeDt","snowDensity","composited","GlobeSpline","startLat","startLon","startElevation","endLat","endLon","endElevation","arcType","apexHeight","apexHeightMin","apexHeightMax","lineWidth","marchingAnts","marchingSpeed","flowDirection","normalizedDist","controlPoints","numControlPoints","heightOffset","heightDir","THREE.CatmullRomCurve3","lineDistances","v2","sinTheta","w1","w2","needsRebuild","hasChange","SplineSubsystem","splineOptions","asset1","asset2","relationshipKey","asset1Id","asset2Id","splineId","splineConfig","splines","PHOTO_PROTRUSION_CLASSIFIER","smoothstep","edge0","edge1","evaluatePhotorealProtrusion","radialNormalDot","heightWindowM","groundDeadbandM","agl","heightT","normalAvailable","upDot","roofZone","roofT","wallT","classifyPhotorealBuildingPresence","minimumHeightM","expectedHeightM","exteriorNoiseM","residuals","maximumResidual","roofThresholdM","raisedSamples","protrusionSamples","normalSamples","maximumStrength","requiredSamples","OVERPASS_URL","OVERPASS_FALLBACK_URLS","OSM_MAP_URL","DEFAULT_OVERPASS_TIMEOUT_MS","DEFAULT_OSM_MAP_TIMEOUT_MS","MAX_OSM_MAP_FALLBACK_RADIUS_M","DEFAULT_MAX_FEATURES","DEFAULT_REFRESH_DISTANCE_M","DEFAULT_LOD_DETAIL_RADIUS_M","DEFAULT_LOD_IMPOSTOR_RADIUS_M","DEFAULT_LOD_UPDATE_INTERVAL_MS","DEFAULT_LOD_BUDGET","DEFAULT_LOD_HYSTERESIS_M","DEFAULT_IMPOSTOR_MIN_SIZE_M","DEFAULT_IMPOSTOR_MIN_HEIGHT_M","DEFAULT_IMPOSTOR_REBUILD_BUDGET","DEFAULT_IMAGERY_UPDATE_INTERVAL_MS","DEFAULT_POLYP_MIN_POINT_SPACING_M","DEFAULT_POLYP_MAX_POINTS","DEFAULT_POLYP_MAX_ENTRIES_PER_TILE","DEFAULT_POLYP_HEIGHT_SCALE","DEFAULT_POLYP_MIN_HEIGHT_M","DEFAULT_MOTION_MIN_SPEED_MPS","DEFAULT_MOTION_SPEED_REF_MPS","DEFAULT_MOTION_AHEAD_FACTOR","DEFAULT_MOTION_BEHIND_FACTOR","DEFAULT_MOTION_QUERY_BIAS","DEFAULT_MOTION_RETENTION_FACTOR","MIN_RESNAP_TOLERANCE_M","DEFAULT_PHOTO_PROBE_RAYS_PER_FRAME","DEFAULT_PHOTO_PROBE_BUDGET_MS","DEFAULT_PHOTO_COVERAGE_MIN_HEIGHT_M","DEFAULT_PHOTO_EXTERIOR_MARGIN_M","angularDistanceDeg","destinationLatLon","bearingDeg","phi1","lambda1","sinPhi1","cosPhi1","sinAngular","cosAngular","phi2","lambda2","buildBuildingViewshed","horizontalFovDeg","nearRadiusM","farRadiusM","bearings","buildBuildingOverpassQuery","queryLat","queryLon","queryRadius","viewshed","metersPerDegLat","metersPerDegLon","fitAffinePlane","readValue","xy","xv","yv","sx","sy","col","pivot","evaluateAffinePlane","phiRad","lon1","lon2","geodesicDistanceWGS84","METERS_PER_LEVEL","parseLevels","parseExplicitHeight","parseHeight","explicitHeight","levels","formatAddress","full","streetParts","localityParts","formatBuildingName","BuildingOverlay","motionTracker","overpassUrl","overpassTimeoutMs","osmMapTimeoutMs","surfaceOffsetM","resnapIntervalMs","resnapBudget","resnapToleranceM","resnapFreezeFrames","tileDrivenResnap","fallbackResnapIntervalMs","maxSamplesPerBuilding","lodDetailRadiusM","lodImpostorRadiusM","lodUpdateIntervalMs","lodBudget","lodHysteresisM","impostorEnabled","impostorMinSizeM","impostorMinHeightM","impostorHeightScale","impostorRebuildBudget","polypEnabled","polypMinPointSpacingM","polypMaxPointsPerFootprint","polypMaxEntriesPerTile","polypHeightScale","polypMinHeightM","polypBakeToTiles","alignToTerrainNormal","motionEnabled","motionMinSpeedMps","motionSpeedRefMps","motionAheadFactor","motionBehindFactor","motionQueryBias","motionRetentionFactor","imageryEnabled","imageryUpdateIntervalMs","photorealFallbackEnabled","photoProbeRaysPerFrame","photoProbeBudgetMs","photoCoverageMinHeightM","photoExteriorMarginM","perfStart","perfEnd","perfRecord","applySliceMs","applyMinBatch","terrainMode","fill","hasFill","hasLine","reset","preserveResolved","retainStableResult","falloffStartM","nextViewshed","nextCenter","refreshDistance","headingThreshold","viewshedChanged","permanentChildren","meshInfo","relayAbort","getAsyncHarness","workerPool","document","elements","way","requestController","arr","primaryUrl","falloffRatio","speedRef","rawMotionDir","radialComponent","bias","biasDistance","shifted","shiftedLatLon","entryDir","motionDir","radial","centerLatRad","northM","eastM","dirRadius","falloffStart","falloff","maxR","sampleDirs","checkDirs","allowRaycast","centerSample","centerInfo","hasCenterRadius","lift","metersLat","metersLon","eastDir","northDir","eastSample","northSample","centerPos","eastPos","northPos","vEast","vNorth","bldgHeight","ls","motionWindow","footprint","nodeId","maxCount","limitedCandidates","cancel","sliceStart","sliceEntries","retention","removals","distances","latLonPairs","pairs","maxSamples","hasCenter","pushPair","minLatPair","maxLatPair","minLonPair","maxLonPair","pair","mLat","mLon","byTexture","textureSamples","uPlane","vPlane","insideSamples","outsideSamples","retainsStableResult","retries","revalidateAfterCommit","inside","outside","radiusReference","groundPlaneRelative","groundPlane","outsideResiduals","osmHeight","classification","roofThreshold","raised","minRadius","maxRadius","centerRadius","nextEmbed","rays","adjustedLon","upVec","shapePts","polypFootprint","boundsWidth","boundsDepth","primaryTile","fastSample","sampleResult","usingFallback","pendingVisibility","embed","impostorWidth","impostorDepth","impostorHeight","basis","outline","pickerMesh","THREE.Shape","THREE.ExtrudeGeometry","fillMaterial","THREE.EdgesGeometry","lineMaterial","explicitLevels","displayLevels","labelPrimary","labelRadius","minSpacing","maxPoints","minSpacingSq","epsilonSq","filtered","decimated","hull","orient","onSegment","o1","o2","o3","o4","a1","a2","jNext","b1","b2","pts","cross","lower","upper","area","allowSweep","tileBudget","tilesProcessed","entryBudget","tileKey","impostor","polyp","maxChecks","tileVersion","nextSurfaceRadius","tolerance","prevWasFallback","nextAt","fastMode","hasElevationSample","hasElevationForDir","raycastRadius","samplesToCheck","getRadius","terrainVariation","minEmbed","currentRadius","fallbackDir","nextPrimary","prevTile","prevImageryEnabled","resnapNeedsUpdate","lodNeedsUpdate","impostorNeedsUpdate","polypNeedsUpdate","rebuildSampleDirs","wasEnabled","refreshNeeded","prevAlign","refreshTiles","baseHeight","detailRadius","maxVisibleRadius","allowImpostor","nextLod","showDetail","needsVisibilitySync","lod","wantsVisible","impostorEntries","THREE.InstancedMesh","existingPolyp","polypEntries","clearPolypEntry","requiresImpostor","hasAppliedFootprints","tileCenter","buildings","basePosition","lodFactor","basePos","tileCx","tileCy","tileCz","gz","gax","gay","gaz","gbx","gby","gbz","tax","tay","taz","tbx","tby","tbz","ax","ay","az","bz","cz","imageryTile","atlasKey","imageryManager","atlasWidth","atlasHeight","halfPixelU","halfPixelV","positionAttr","uvArray","final","highlightGeom","anchorTop","anchorWorld","pointer","screenX","screenY","canvasRect","projected","pointerGap","clampedX","clampedY","toast","finalize","xi","yi","xj","yj","DEFAULT_RADIUS_M","DEFAULT_FALLOFF_M","DEFAULT_RING_COLOR","DEFAULT_FALLOFF_COLOR","resolveNumber","getLatLon","createBuildingOverlayItem","buildingOverlay","ringMaterial","falloffMaterial","ringGeometry","THREE.RingGeometry","falloffGeometry","ringMesh","falloffMesh","markerMaterial","applyVisuals","falloffM","ringColor","falloffColor","showMarker","applyConfig","resolveBool","removedItem","SOURCE_TYPE","DIRECT_VIDEO_EXTENSIONS","parseUrlLike","looksLikeHlsUrl","fmt","looksLikeDirectVideoUrl","looksLikeProviderEmbedUrl","extractIframeSrc","iframeMatch","resolveEmbedCandidateUrl","iframeSrc","resolveSourceType","createTheaterSourceManager","commsSystem","onMediaElement","_sourceType","_videoEl","_videoTexture","_hlsInstance","_embedUrl","_streamIdTexture","_currentProps","_createVideoElement","_createVideoTexture","videoEl","_setupHls","_disposeMedia","_startPlayback","Hls","__vite_default__","_setupDirectVideo","_setupStreamId","videoStreamId","_setupEmbed","nextType","typeChanged","nextUrl","prevUrl","_getActiveUrl","PLAYBACK_TRIGGERS","PLAYBACK_EXITS","PLAYBACK_SYNC_MODES","DEFAULT_PLAYBACK_RANGE_M","DRIFT_TOLERANCE_S","resolvePlaybackConfig","sharedTimelinePosition","anchorMs","createMediaPlaybackController","media","broadcaster","inRange","enteredOnce","personalPlaying","loadListeners","lastNotified","blocked","isActive","sharedAnchor","seekTo","play","pause","onTimeUpdate","onEnded","detachMedia","wasActive","LAYER_CLASS","MIN_SCREEN_PX","MASK_COLS","MASK_ROWS","MASK_RAYS_PER_FRAME","occlusionMaskState","cells","toEmbeddablePlayerUrl","autoplay","flag","second","part","adj","mulMM","mulMV","quadToCssMatrix","tl","tr","bl","br","ensureLayer","createTheaterIframePresenter","screen","onMount","onUnmount","interactive","lastSeen","hideTimer","corners","toCamera","hide","maskCursor","maskKey","maskState","maskCanvas","samplePoint","applyMask","prop","sampleOcclusion","mount","unmount","watch","isInteractive","rectW","rectH","xs","ys","spanX","spanY","theaterBadgeHint","embedded","getTheaterBadgeTexture","hint","hovered","accent","YT_ORIGIN","VIMEO_ORIGIN","PLAYER_STATE","bridgeProvider","youTubeVideoId","withBridgeParams","createEmbedPlayerBridge","iframe","onState","lastVolume","lastMuted","pinger","post","func","vimeo","emit","onMessage","ping","muted","videoId","startSeconds","MIN","MAX","clampAspect","aspectFromVideo","oEmbedEndpoint","ytId","guessAspect","fetchEmbedAspect","metaCache","fetchEmbedMeta","STYLE_ID","CSS","ensureStyle","shortLabel","createTheaterUpNextCard","onPlay","onResume","thumbnail","VOLUME_TICK_MS","createTheaterEmbedSession","hooks","bridge","card","wantActive","lastState","volumeTimer","syncCard","paused","ended","endedNow","presenter","createTheaterQueue","upNext","authoredIndex","history","authoredAt","playlist","nextLoop","authoredIdx","bvhCache","SKIP_NAME","MAX_RADIUS_M","RAYS_PER_FRAME","REBUILD_EVERY_MS","BVH_BUILDS_PER_PASS","BVH_MIN_TRIANGLES","DEFAULT_PROJECTOR","projectorFalloff","knee","inverseSquare","horizontalDeg","createTheaterProjector","ignoreRoot","bodyMaterial","stand","lensMaterial","lensMesh","lens","surfaceMaterial","frustum","projScreen","sphere","normalMatrix","tmpNormal","lensWorld","lastMatrix","centroidLocal","passStartedAt","hasSurface","sceneRoot","ignored","collectCandidates","bvh","MeshBVH","startPass","cols","localRay","THREE.Ray","firstHit","rc","castSome","shade","lambert","buildSurface","ks","lit","FOCUS_TTL_MS","DIRECT_MEDIA","theaters","focusedAt","installed","isRoutableMediaUrl","registerTheater","theater","focusTheater","pickTheater","routeMediaUrl","installMediaLinkRouter","win","onClick","originalOpen","patchedOpen","rest","createTheaterListenerAudio","audioSystem","lastCameraWorld","getProps","isProjector","defaultWidthM","facing","toViewer","acousticPath","occlusion","viewerPosition","audioReach","audioRef","viewer","applyTheaterStatus","baseProps","statusPayload","HOVER_FRAME_COLOR","SCREEN_CONE","PROJECTOR_HINT","noRaycast","authoredSourceUrl","DEFAULT_WIDTH_M","DEFAULT_HEIGHT_M","DEFAULT_FRAME_COLOR","DEFAULT_SCREEN_COLOR","deriveAudioStream","resolveIngressTarget","createTheaterOverlayItem","screenMaterial","frameMaterial","backMaterial","screenGeometry","THREE.Path","frameGeometry","THREE.ShapeGeometry","backGeometry","back","mediaAspect","aspectFor","projector","projectorLoop","blockedMediaUrl","baseFrameColor","baseScreenColor","latestProps","refreshScreen","watchedMedia","onMediaState","onMediaError","onMediaEnded","reloadSource","watchMedia","sourceManager","effectiveProps","embeddedUrl","iframeSize","projectorMode","videoTexture","hasFrames","showVideo","theaterApi","listenerGain","attachMediaAudio","updateAspectFor","playUrl","toQueue","broadcast","unregisterTheater","all","guess","_detachAudio","setScreenVisible","tickProjector","widthM","audioEl","applyStreams","ingressTarget","routedStreams","prevSource","derivedAudio","audioStreamId","TEXTURE_SLOTS","collectModelTextures","downscaleTarget","maxSize","downscaleTexture","prepareModelForFirstDraw","maxTextureSize","createProgramGate","compiling","before","AIRCRAFT_CORRECTION_SECONDS","aircraftIdentity","observationTime","aircraftScenePosition","positionAt","at","geodesicDestinationWGS84","aircraftStateAt","right","sampleAircraftFrame","t2","t3","u2","u3","TRACK_VERTICES","TRACK_SLOTS","fields","AircraftCatalogLayer","onNear","fetchHistory","createSatelliteTaskYield","modelIds","available","satelliteGeodetic","_ray","rect","readJson","FlightApiService","reader","flightApiServiceInstance","getFlightApiService","DEFAULT_MODEL_URL","DEFAULT_POLL_INTERVAL_MS","DEFAULT_STALE_MS","DEFAULT_PREDICT_MS","MAX_FUTURE_OBSERVATION_MS","DEFAULT_MODEL_SCALE","DEFAULT_HEADING_OFFSET_DEG","DEFAULT_TERRAIN_CLAMP_MAX_M","DEFAULT_TERRAIN_SAMPLE_INTERVAL_MS","DEFAULT_TERRAIN_CLEARANCE_M","DEFAULT_SMOOTH_MS","DEFAULT_ACCEL_MPS2","DEFAULT_VERTICAL_ACCEL_MPS2","DEFAULT_HEADING_ACCEL_DEG","DEFAULT_ACCEL_ESTIMATE_MAX_MPS2","DEFAULT_VERTICAL_ACCEL_ESTIMATE_MAX_MPS2","ACCEL_ESTIMATE_BLEND","DEFAULT_LOW_LOD_DISTANCE_M","DEFAULT_LOW_LOD_HYSTERESIS_M","DEFAULT_LOW_LOD_SCALE_MULTIPLIER","getDefaultLowLodColor","TOKENS","getPathColor","METERS_PER_NM","DEFAULT_CULL_HYSTERESIS_M","DEFAULT_PATH_HOURS","DEFAULT_PATH_MAX_POINTS","PATH_DASH_SIZE","PATH_GAP_SIZE","PATH_DASH_TAPER_POWER","PATH_DASH_TAPER_MIN_SCALE","PATH_GAP_TAPER_MAX_SCALE","PATH_SAMPLE_INTERVAL_MS","PATH_SUBDIVISIONS_PER_SEGMENT","PATH_ALT_MIN_M","PATH_ALT_MAX_M","PATH_ALT_RANGE_M","PATH_ALPHA_POWER","PATH_COLOR_LOW","PATH_COLOR_HIGH","PATH_MAX_GAP_MS","PATH_MAX_GROUND_SPEED_MPS","PATH_DISTANCE_BUFFER_M","PATH_MAX_VERTICAL_RATE_MPS","PATH_ALTITUDE_BUFFER_M","TERRAIN_CACHE_DISTANCE_M","FALLBACK_AIRCRAFT_GEOMETRY","FALLBACK_AIRCRAFT_MATERIAL","toNumber","buildSmoothedAircraftPathSamples","pathHistory","subdivisionsPerSegment","subdivisions","directions","segmentCount","sampleCount","isLast","segmentIndex","segmentT","curveT","p0","p1","p2","p3","interpolatedAltitude","normalizeAircraftType","degToRad","radToDeg","wrapAngleDeg","clampAbs","maxAbs","blendValue","approach","maxDelta","approachAngleDeg","parseTimeMs","numericValue","pathDistanceMeters","aDir","bDir","normalizeAircraftPathHistory","fallbackAltitudeM","deduplicated","carriedAltitude","latestSegment","deltaMs","deltaSec","maxAltitudeDelta","resolvePredictionWindowMs","predictionMaxMs","pollIntervalMs","staleAfterMs","requestedMs","pollMs","continuityMs","freshnessWindowMs","resolveObservationTimeMs","enableTaperedDashes","baseCacheKey","baseOnBeforeCompile","dashReplace","advanceLatLon","dest","sinLat1","cosLat1","sinAd","cosAd","integrateVelocity","accel","allowNegative","safeAccel","nextVelocity","tStop","AircraftOverlay","modelScale","maxAircraft","coneAngleDeg","radiusNm","queryMode","queryValue","headingOffsetDeg","altitudeOffsetM","terrainSampler","terrainClampMaxM","terrainSampleIntervalMs","terrainClearanceM","smoothingMs","accelMps2","verticalAccelMps2","headingAccelDeg","showPaths","pathHours","pathMaxPoints","lowLodEnabled","lowLodDistanceM","lowLodHysteresisM","lowLodScaleMultiplier","lowLodScale","lowLodColor","cullDistanceM","cullHysteresisM","photoTilesActive","fallbackCullDistanceM","THREE.LineDashedMaterial","resolveColor","states","aircraftType","previousLastContactMs","nextUpdatedAt","nextLastContactMs","isNewUpdate","previousLat","previousLon","previousAltitudeM","previousVelocityMps","previousHeadingDeg","sourceContactChanged","positionOrMotionChanged","sourcePositionAtMs","initialPredictionAtMs","targetLat","targetLon","targetAlt","deltaAlt","sampleTimeMs","maxAccel","maxVerticalAccel","dtSec","rawAccel","maxPredictMs","dirtyBuckets","lodEnabled","cullEnabled","lodOutSq","lodInSq","cullOutSq","cullInSq","observerLocal","switchOut","switchIn","lastSourceUpdate","trajectoryAlt","lastPredictedAt","dtMs","predictionStartedAtMs","predictionAgeMs","targetVelocity","isOnGround","targetHeading","targetVertical","dirForTerrain","baseRadiusForTerrain","minAlt","verticalRate","fadeStartMs","decayFactor","moveDt","altWithOffset","timeToGround","predictedDirForTerrain","predictedBaseRadiusForTerrain","pathAlt","renderAlt","instancedPos","renderHeading","distanceSq","prevCulled","nextCulled","prevLod","effectiveLod","lodChanged","labelSubText","labelMetadata","upDir","headingRad","clampMax","hasSampler","hasPhotogram","lastSample","cacheAngle","cacheDirectionMatches","photogramRadius","highAltitude","si","rootInv","offsetMat","localMat","baseMat","instanced","THREE.OctahedronGeometry","velocityMps","verticalRateMps","fallbackAltitude","seeded","altM","nextPoint","alphas","dashScales","gapScales","lowColor","highColor","lastIndex","sampleOffset","tailEase","altT","updateTrailAttributes","lineDistanceAttr","previousIndex","SkeletonUtils.clone","prevLowLodEnabled","lodConfigChanged","MaritimeApiService","maritimeApiServiceInstance","getMaritimeApiService","DEFAULT_RADIUS_NM","DEFAULT_CONE_ANGLE_DEG","DEFAULT_MAX_VESSELS","DEFAULT_LOOKBACK_MINUTES","DEFAULT_ALTITUDE_OFFSET_M","DEFAULT_SHOW_PATHS","MARKER_COLOR","PATH_COLOR","MaritimeOverlay","maxVessels","lookbackMinutes","THREE.ConeGeometry","altKm","logScale","scaledSize","vessels","nextLat","nextLon","updatedAtMs","speedKn","bow","MAX_FOOTPRINT_POINTS","DEFAULT_INCIDENT_SPIRE_HEIGHT_M","DEFAULT_EMBED_M","DEFAULT_FALLBACK_SIZE_M","DEFAULT_RESOLVING_RADIUS_M","DEFAULT_RESOLVING_SEGMENTS","DEFAULT_GROW_DURATION_MS","DEFAULT_MORPH_DURATION_MS","ACTIVE_SURFACE_MARKER_LIGHTS","unregisterSurfaceMarkerLights","ensureSurfaceMarkerLightProvider","releaseSurfaceMarkerLightProviderIfEmpty","samePoint","signedRingArea","sanitizeRing","normalizeSurfaceFootprint","createFallbackSurfaceFootprint","sizeM","createResolvingSurfaceFootprint","metersPerLatDeg","metersPerLonDeg","ringDistanceM","meanLat","resampleRing","lengths","perimeter","edgeStart","alignRingSamples","bestOffset","bestCost","averageRing","lonScale","_","animationNow","SurfaceFootprintMarker","presentation","embedM","outlineOpacity","renderOrder","lightChannel","lightPriority","lightRadiusM","lightIntensityScale","lightPulseHz","lightPhase","lightShadowStrength","surfaceDirection","surfaceElevationM","anchorRadius","anchorSource","exactRadius","growDurationMs","targetRing","morphCompleted","progress","finalCenter","photoRequired","extraM","wallPositions","wallHeights","wallIndices","baseOutlinePositions","topOutlinePositions","aBase","aTop","bBase","bTop","wallGeometry","outlineGeometry","topOutlineGeometry","computeBounds","wallAttr","baseAttr","topAttr","attribute","DEFAULT_MAX_INCIDENTS","DEFAULT_SPIRE_HEIGHT_M","DEFAULT_SPIRE_RADIUS_M","DEFAULT_SURFACE_OFFSET_M","DEFAULT_MARKER_OPACITY","DEFAULT_LABEL_ENABLED","DEFAULT_LABEL_OFFSET_M","DEFAULT_LABEL_MAX_CHARS","DEFAULT_LABEL_VIEW_CONE_DEG","SPIRE_RENDER_BIAS_M","DEFAULT_VISIBILITY_UPDATE_MS","SPIRE_HEIGHT_MIN_M","SPIRE_HEIGHT_MAX_M","SPIRE_RADIUS_MIN_M","SPIRE_RADIUS_MAX_M","PLACE_LOOKUP_RADIUS_M","PLACE_LOOKUP_CONCURRENCY","PLACE_LOOKUP_CACHE_TTL_MS","PLACE_LOOKUP_CACHE_LIMIT","PLACE_LOOKUP_QUEUE_LIMIT","FOOTPRINT_LOOKUP_RADIUS_M","FOOTPRINT_BATCH_DELAY_MS","DESKTOP_ACTIVE_FIRE_LIMIT","MOBILE_ACTIVE_FIRE_LIMIT","clampSpireHeight","clampSpireRadius","truncateLabel","maxChars","buildIncidentLabel","subheader","buildIncidentPresentation","secondary","placeLookupKey","normalizeAgencyIds","parseIncidentTimestamp","IncidentOverlay","buildingResolver","footprintResolver","footprintBatchDelayMs","maxIncidents","markerScaleM","spireHeightM","spireRadiusM","showLabels","labelScaleM","labelOffsetM","labelViewConeDeg","includeRecent","includeAlerts","publicOnly","hideMedical","agencyIds","nextHeight","nextRadius","getIncidentApiService","SurfaceFlameField","incidents","placeEnrichmentEntries","incident","placeChanged","nextColor","resolveIncidentColor","recencyPhaseForIdentity","baseHeightM","baseRadiusM","isActiveFireIncident","isVegetationFireIncident","place","resolvePlace","byId","placeName","nextText","markerOwned","formatIncidentTypeLabel","markerHeight","markerLocal","labelGroup","localLookupKey","building","stableR","outSq","inSq","recencyOpacity","eventRecencyBaseOpacity","vegetationFire","eventRecencyOpacity","recencySaturation","eventRecencySaturation","fireBoost","CACHE_TTL_MS","MAX_CACHE_ENTRIES","MAX_CAMERAS","discoveryCache","secureUrl","isFiniteCoordinate","normalizeProvider","normalizeCamera","discoveryMethod","normalizePayload","cameras","discoverTrafficCameras","includeFlock","maxCameras","DEFAULT_CULL_DISTANCE_M","DEFAULT_MAX_CAMERAS","DEFAULT_VISUAL_UPDATE_MS","CONTEXT_REFRESH_MS","CONTEXT_MOVE_METERS","CONTEXT_FAILURE_RETRY_MS","CLICK_SLOP_PX","VISUAL_ACTIVATION_DELAY_MS","VISUAL_ACTIVATION_BATCH_SIZE","CAMERA_PREVIEW_CENTER_RADIUS_NDC","CAMERA_PREVIEW_REFRESH_MS","COLORS","LABEL_COLOR","TRAFFIC_CAMERA_MARKER_VERTEX_SHADER","TRAFFIC_CAMERA_MARKER_FRAGMENT_SHADER","isAbortError","debugTraffic","distanceMeters","cameraPreviewUrl","selectCenteredTrafficCameraPreview","radiusSq","selectedDistanceSq","TrafficCameraViewer","styleId","titleBlock","close","notice","imageUrl","rawLabel","rawValue","dd","TrafficCameraOverlay","domElement","discoveryRadiusM","deferUntilInteractive","discoveryChanged","labelHandle","THREE.RawShaderMaterial","queuedCenter","discovery","sourceKey","verifiedProviderCount","oldIds","rankedItems","distanceA","distanceB","reuse","altitudeKm","cullSq","observerDirection","previewCandidates","sameHemisphere","refresh","previewUrl","MAX_SEGMENTS","MAX_EVENTS","MAX_COORDS_PER_LINE","finiteCoord","finiteOrNull","normalizeRoadTrafficRecord","rawGeometry","normalizeRoadTrafficPayload","normalizeList","fetchNearbyRoadTraffic","maxSegments","maxEvents","DEFAULT_MAX_SEGMENTS","DEFAULT_MAX_EVENTS","DEFAULT_LIFT_M","CONTEXT_MOVE_M","DRAPE_INTERVAL_MS","DRAPE_BUDGET","MAX_COORDS","MAX_LABELS","VERTEX_SHADER","FRAGMENT_SHADER","recordColor","recordSummary","RoadTrafficOverlay","surfaceLiftM","ribbonWidthM","previousLiftM","fetchChanged","liftDelta","_coords","_labelHandle","publicRecord","explicitBudget","vertexCount","triangleCount","along","halfWidth","cumulative","sideIndex","positionAttribute","readyAttribute","sideVertex","rawCoords","matching","RADIO_DATA_FEEDS","RADIO_DATA_BANDS","stableQuery","RadioDataApiService","ttlMs","feeds","country","selectedFeeds","feed","getRadioDataApiService","RADIO_LIGHT_SPEED_MPS","RADIO_REFERENCE_LOSS_DB","radioWavelengthMeters","frequencyHz","wireAmplitude","cosTheta","lengthWavelengths","describeRadioField","antenna","wavelengthM","lengthM","beamwidthDeg","azimuthDeg","elevationDeg","dipole","monopole","directional","electricalLength","assumptions","peakAmplitude","referenceRadiusM","displayRadiusM","receiverOnly","orientationKnown","MAX_FIELDS","SHELLS","patternIndex","RadioFieldVisualization","maxSignals","frequencyColor","model","EARTH_MEAN_RADIUS_M","RADIO_REFRACTION_EARTH_FACTOR","cleanNumber","RADIOSONDE_FREQUENCY_STYLES","UNKNOWN_FREQUENCY_STYLE","resolveRadiosondeFrequencyStyle","radiosondeRadioHorizonMeters","effectiveRadius","freeSpacePathLossDb","frequencyMhz","centralAngle","receiverFromItem","receiver","observedLinkQuality","snr","rssi","describeRadiosondeSignal","linkDistanceM","FEED_COLORS","TYPE_LABELS","AIRBORNE_TYPES","VHF_MIN_HZ","RADIO_SURFACE_MAX_QUERY_RADIUS_KM","RADIO_SURFACE_DISTANCE_LIMITS_M","radioDistanceMeters","toRadians","phiA","phiB","dPhi","dLambda","sinPhi","sinLambda","resolveSurfaceRadioDistanceLimitM","shouldDisplayRadioItem","configuredLimitM","limitM","formatFrequency","RadioDataOverlay","apiService","visualMoved","countryChanged","airborneSignal","GEOCACHE_TYPES","GEOCACHE_STATUSES","GEOCACHE_SIZES","allowlist","GeocacheApiService","statuses","difficultyMin","difficultyMax","terrainMin","terrainMax","getGeocacheApiService","TYPE_COLORS","RECORD_SIZES","rating","titleCase","href","normalizeGeocacheRecord","attributionNote","buildGeocacheMetadata","summaryText","providerState","GeocacheLayer","TARGET_COLOR","TARGET_COLOR_PINNED","TARGET_LEADER_COLOR","TARGET_LEADER_GROUND_OFFSET_M","TARGET_LABEL_MIN_OFFSET_M","TARGET_LABEL_MAX_OFFSET_M","TARGET_FOOTPRINT_EMBED_M","BUILDING_GEOMETRY_TYPES","resolveBuildingQualifiedGeoJson","category","deriveSelectionSpireHeight","baseWorld","cameraHeight","projectedUp","metersPerPixel","formatRouteDistance","meters","km","formatRouteDuration","mins","rem","AddressHoverOverlay","on","unsubscribe","geocodedFootprint","tLat","tLon","exactSurfaceRadius","hasExactPhotoAnchor","sameLeaderTarget","eta","drive","localSurfaceNormal","worldNormal","leaderHeight","labelOffset","posAttr","locationChanged","retainedExactAnchor","localFootprint","buildingFootprintContains","requireContaining","distLabel","getAddressHoverOverlay","MAX_EVENTS_PER_SOURCE","MAX_TOTAL_EVENTS","SensorEventStore","rawData","SENSOR_SOURCES","trim","idSet","evt","lastGeo","sumSin","sumCos","getSensorEventStore","ALT_HIGH_M","ALT_MED_M","ALT_LOW_M","ALT_SURFACE_M","SPIRE_BASE_HEIGHT_M","SPIRE_BASE_RADIUS_M","SPIRE_MIN_SCALE","SPIRE_MAX_SCALE","SURFACE_OFFSET_M","HEATMAP_RING_SEGMENTS","HEATMAP_BASE_RADIUS_M","HEATMAP_MIN_OPACITY","HEATMAP_MAX_OPACITY","HEATMAP_ALTITUDE_FADE_START","LABEL_FONT_SIZE","LABEL_MAX_CHARS","LABEL_BASE_SCALE_M","MAX_LABEL_COUNT","LABEL_FADE_ALT_START","LABEL_FADE_ALT_END","RECENT_WINDOW_MS","PULSE_SPEED","PULSE_SCALE_AMP","PULSE_BRIGHT_AMP","PULSE_RING_AMP","FADE_START_MS","FADE_END_MS","POLYGON_OFFSET_M","LINE_OPACITY","FILL_OPACITY_BASE","FILL_OPACITY_MAX","POINT_SIZE","SEVERITY_COLORS","CATEGORY_COLORS","HEATMAP_CATEGORIES","resolveSpireHeight","resolveHeatmapRadius","hashPhase","truncate","altitudeScale","logMin","logMax","altitudeLabelOpacity","altitudeHeatmapOpacity","SensorOverlay","sec","allEvents","THREE.UniformsUtils","grp","labelR","heatmapAlpha","ringPulse","ringScale","ageFade","paddingX","paddingY","lineHeight","catColor","labelAlpha","geoSources","altFill","MESSAGE_STORE","READ_STORE","META_STORE","MAX_LOCAL_MESSAGES_PER_THREAD","canonicalMeshtasticNodeId","fnv1a","requestResult","transactionDone","transaction","dbPromise","openDatabase","messages","getMeshtasticPeerId","localNodeId","buildMeshtasticThreadKey","peerNodeId","createMeshtasticMessageId","packetId","fingerprint","normalizeStoredMeshtasticMessage","updatedAt","deliveryStatus","canonicalId","mergeMeshtasticMessages","MeshtasticConversationStore","synced","previousId","oldId","repaired","threadKey","readAt","threadMessages","pendingOnly","maxMessages","remove","singleton","getMeshtasticConversationStore","SYNC_PAGE_SIZE","parseTimestamp","publicMessage","MeshtasticSyncService","pendingReads","pushed","pendingMessages","storageKey","savedCursor","pulled","newestUpdate","readStates","read","getMeshtasticSyncService","SERIAL_BAUD_RATE","SERIAL_HEARTBEAT_INTERVAL_MS","MAX_MESSAGE_HISTORY","SERIAL_AUTO_CONNECT_KEY","SERIAL_PORT_DESCRIPTOR_KEY","MAX_OWNER_LONG_NAME_BYTES","MAX_OWNER_SHORT_NAME_BYTES","LOCAL_SERVER_BASE","normalizeBaseUrl","readLocalStorage","writeLocalStorage","readStoredPortDescriptor","usbVendorId","usbProductId","describeSerialPort","sameSerialPortDescriptor","utf8ByteLength","normalizeAdvertisedNodeId","joinApiPath","cleanBase","getGlobalSerialCodec","codec","nodeIdFromNum","normalizeDestination","hex","dateToUnixSeconds","dateToUnixMilliseconds","asUint8Array","toStr","validLatitude","validLongitude","resolveMeshtasticPosition","addCandidate","latitudeI","longitudeI","normalizeMeshtasticNode","user","flatUserName","normalizeNode","normalizeMessage","rawFrom","rawTo","MESHTASTIC_NODE_CACHE_KEY","MESHTASTIC_NODE_CACHE_LIMIT","MeshtasticService","serialCodec","serialClientFactory","conversationStore","syncService","defaultApiBase","isBrowserRuntime","fallbackUrl","reportedLocalId","tick","requestPort","automatic","connect","activePort","serial","selectedPort","authorizedPorts","longName","shortName","normalizedLongName","normalizedShortName","normalizedId","device","Types","Protobuf","MeshDevice","TransportWebSerial","subscribe","applyPartialNode","deviceMetrics","bufLen","needed","grown","totalLen","clientId","usesRoutingAck","useFallback","destination","rawCache","nodeNum","sync","existingIndex","collisionIndex","candidateIndex","tid","getMeshtasticService","STALE_THRESHOLD_MS","LIVE_THRESHOLD_MS","STALE_CHECK_INTERVAL_MS","COLOR_LIVE","COLOR_STALE","COLOR_LIVE_CSS","COLOR_STALE_CSS","LABEL_TARGET_RADIUS_M","LABEL_OFFSET_M","MARKER_OPACITY","MARKER_OUTLINE_OPACITY","MeshtasticOverlay","service","nodeData","markers","nowS","_isLiveNode","meshtasticNodeIdsEqual","retainHover","_buildSubText","_buildMetadata","transition","allowFetch","meshtasticNodeIdFromLabelHover","normalizeMeshtasticNodeId","highlighted","footprintSource","WEATHER_FLOW_PLAYBACK","WEATHER_FLOW_PERIOD_SECONDS","focusUniforms","setWeatherVolumeFocus","createStreams","array","createWeatherVolumeMesh","setWeatherVolumeOpacity","disposeWeatherVolumeMesh","weatherRayBox","weatherRayConvex","planes","denominator","weatherEarthLimit","weatherPickCandidates","tree","WeatherVolumeInteraction","pixelAngle","screenScore","squared","WEATHER_PRODUCT_STYLES","readWeatherVolume","WeatherVolumeOverlay","WEATHER_VOLUME_DEFAULTS","WEATHER_VOLUME_LAYERS","C","ll","radar","SensorApiService","qs","overrideIntervalMs","poll","getAllSensorIds","getSensorApiService","SensorManager","sceneSettings","sensorSettings","sensorPatch","wsReconnects","getSensorManager","DEFAULT_RESNAP_INTERVAL_MS","DEFAULT_RESNAP_BUDGET","DEFAULT_DRAPE_BUDGET","DEFAULT_BUILD_SLICE_MS_DESKTOP","DEFAULT_BUILD_SLICE_MS_MOBILE","DEFAULT_ROAD_STEP_M","DEFAULT_RIBBON_THICKNESS_M","DEFAULT_ALIGN_FREEZE_FRAMES","DEFAULT_ALIGN_TOLERANCE_M","DEFAULT_ALIGN_SAMPLE_STEP_M","DEFAULT_ALIGN_MAX_SAMPLES","DEFAULT_PAINT_RESOLUTION","DEFAULT_PAINT_LINE_WIDTH_PX","DEFAULT_PAINT_OPACITY","DEFAULT_PAINT_REPAINT_ON_LOD","DEFAULT_PAINT_BUDGET","DEFAULT_PAUSE_WHEN_FAR","DEFAULT_PAUSE_DISTANCE_MULTIPLIER","getDeviceMemoryGb","getHardwareConcurrency","cores","scheduleIdle","cancelIdle","ROAD_WIDTHS","ROAD_COLORS","DEFAULT_INFRA_COLORS","INFRA_LINE_WIDTHS","UTILITY_RIBBON_KINDS","INFRA_RIBBON_KINDS","buildOverpassQuery","InfrastructureOverlay","refreshDistanceM","drapeBudget","roadWidthScale","roadStepM","bridgeHeightM","ribbonThicknessM","alignFreezeFrames","alignToleranceM","alignSampleStepM","alignMaxSamples","pauseWhenFar","pauseDistanceM","pauseDistanceMultiplier","roadsEnabled","bridgesEnabled","waterwaysEnabled","areasEnabled","railwaysEnabled","paint","backendUrl","resolveLayer","paintConfig","memoryGb","lowPower","needsDrape","newCenter","forceRefresh","wireframeActive","baseBudget","maxSlice","allowHidden","timeoutHandle","timedOut","terminal","obsolete","mPerDegLat","mPerDegLon","enabledLayers","osmId","styleKey","isClosed","renderMode","nodeMap","wayMap","embeddedGeometry","featureCenterLat","featureCenterLon","wayNodes","firstPoint","lastPoint","nodeHash","entryKey","expectsGeometryGroup","renderModeMatches","minPerSlice","idleMs","disposePending","localPoints","vertexLatLons","densifiedPoints","bridgeLift","uvAttr","minU","maxU","minV","maxV","spanU","spanV","paintInfo","uLocal","vLocal","colorHex","densified","prevKeys","nextKeys","shouldPause","waterwayType","highwayType","halfW","thickness","perpX","perpY","leftX","leftY","rightX","rightY","leftLat","leftLon","rightLat","rightLon","xyToLatLon","stepM","maxVertices","vertexDirs","groupPos","surfaceOffset","isVolumetricRibbon","endIdx","vertexDir","vertexRadius","terrainZ","newZ","isTopVertex","baseZ","oldZ","hasElevation","used","prevStamp","prevNormal","hasPhotorealSurface","fallbackRadius","normalChanged","stable","roadColor","colorAttr","nextHex","prevEnabled","prevSurfaceOffset","prevRoadWidthScale","prevRoadStepM","prevBridgeHeightM","prevRibbonThicknessM","prevAlignFreezeFrames","prevAlignToleranceM","prevAlignSampleStepM","prevAlignMaxSamples","prevDrapeBudget","prevMotionEnabled","prevMotionAhead","prevMotionBehind","prevMotionBias","prevPauseWhenFar","prevPauseDistanceM","prevPauseDistanceMultiplier","prevPaintEnabled","prevPaintResolution","prevPaintOpacity","prevPaintLineWidthPx","prevPaintRepaintOnLod","prevPaintBudget","prevColors","paintModeChanged","paintTuningChanged","layersChanged","prevLayerState","geometryChanged","motionChanged","LENS_SETTING_BOUNDS","SETTINGS_POLICY_VERSION","KNOWN_ROOTS","PRODUCTION_EXPOSURES","SYSTEM_META_DEFAULTS","clone","setPath","flattenSettingLeaves","pathMatches","classifyExposure","ownerFor","boundsFor","lensBounds","enumFor","LABEL_TEMPORAL_FILTER_MODE_IDS","schemaFor","enumValues","replacementPresetFor","exposureClass","policiesFor","productPreference","systemMetadata","descriptorFor","schemaTypes","schema","validateValue","canReadExposure","canMutateExposure","SettingDescriptorRegistry","unknownRoots","includeSystemMetadata","rejected","validationError","merge","CAPABILITY_PROFILES","CapabilityProfileService","facts","preference","mobileUserAgent","legacyMobileOverride","DEFAULT_STORAGE_KEY","PHOTO_SURFACE_LIGHTING_CONTRACT_VERSION","ORBITAL_SIMPLE_CLOUDS_CONTRACT_VERSION","ATMOSPHERE_BASE_OFFSET_CONTRACT_VERSION","NIGHT_VISIBILITY_CONTRACT_VERSION","BUILDING_REPAIR_CONTRACT_VERSION","LABEL_PRESENTATION_CONTRACT_VERSION","NIGHT_LIGHTS_EMISSION_CONTRACT_VERSION","MOBILE_ORBIT_NIGHT_CONTRACT_VERSION","deepClone","deepMerge","isMobileDevice","hasTouch","narrowViewport","SceneSettings","applyScene","normalizeScene","capabilityProfileService","policyContext","capabilityResolution","resolvedDefaults","sanitizedStored","normalizedScene","policyResult","nowIso","synchronized","synchronizeLabelCategorySourcePatch","persisted","boundary","retiredKeys","migrateLegacyLabelSettings","inheritedLegacyDefaults","LEGACY_NIGHT_LIGHTS_EMISSION_DEFAULTS","inheritedPreviousDefaults","PREVIOUS_NIGHT_LIGHTS_EMISSION_DEFAULTS","inheritedV2Defaults","V2_NIGHT_LIGHTS_EMISSION_DEFAULTS","flights","satellites","hasSurfaceOffset","legacyOffset","clonePlainObject","IMAGERY_MANAGER_CONFIG_NUMERIC_KEYS","IMAGERY_MANAGER_CONFIG_BOOLEAN_KEYS","IMAGERY_MANAGER_CONFIG_KEYS","ELEVATION_CLIENT_CONFIG_NUMERIC_KEYS","ELEVATION_CLIENT_CONFIG_BOOLEAN_KEYS","ELEVATION_CLIENT_CONFIG_OBJECT_KEYS","extractImageryManagerConfig","buildTerrainImagerySettings","imageryConfig","buildTriTreeImageryConfigPatch","imagery","currentImageryConfig","buildImageryManagerConfigPatch","hasImageryManagerConfigChanges","nextConfig","currentConfig","buildTerrainElevationSettings","elevationClient","ringBudget","buildElevationClientConfigPatch","RAPIER_MODULE_URL","createRapierModuleLoader","importModule","moduleUrl","initialization","importAttempts","loadRapierModule","TMP_TRANSLATION","TMP_ROTATION","TMP_LINEAR_VELOCITY","TMP_VELOCITY_DELTA","TMP_GRAVITY","TMP_WORLD_POSITION","TMP_WORLD_QUATERNION","TMP_WORLD_SCALE","_safeFinite","_scaledRadius","scaleVec","sz","maxScale","_geometryBoundingSphereRadius","createDynamicColliderDesc","RAPIER","radiusOverride","parameters","halfX","halfY","halfZ","halfHeight","PhysicsSystem","runtimeLoader","initializeOnConstruct","world","bodyDesc","colliderDesc","collider","indexAttr","colliderData","eyeHeight","gravityCenter","hasActiveDynamics","hasCharacterController","stepDt","translation","ops","physics","proposed","inwardSpeed","lv","deltaMag","speedDrop","verticalDelta","impactPos","baseFreq","ball","ProximityTrigger","debugName","triggerPos","shouldActivate","shouldDeactivate","audioControl","easing","startPos","targetPos","startScale","fadeIn","startOpacity","targetOpacity","continuous","targetRotation","deltaRotation","anim","easedT","ProximityTriggerManager","ClickTrigger","condition","minDistance","actual","enable","hook","ClickTriggerManager","intersectedObj","foundTrigger","deadzone","verticalDeadzone","XR_TAKEOFF_HOLD_SECONDS","XR_TURN_RATE","XR_TURN_RESPONSE_SECONDS","XRControllerInput","referenceSpace","airborne","dominantY","upStrength","downStrength","XR_LABEL_CAPACITY","ROW_HEIGHT","ATLAS_WIDTH","PANEL_SIZE","PAGE_LINES","ICON_DIAMETER","ICON_CENTRE_X","ICON_ONLY_WIDTH","FOCUS_INNER_COS","FOCUS_OUTER_COS","XRLabelLayer","XR_LABEL_LAYER","icon","alignment","cardWidth","uvWidth","angularWidth","maxWidth","markerIcon","textX","textLimit","titleWidth","subWidth","iconColor","colorCss","iconGlyph","fit","MAX_PALETTE_ELEMENT","enableMeshSpaceSkinning","updateRoot","meshes","THREE.DetachedBindMode","determinant","boneMatrix","boneInverse","ROOT","XRInputModels","fetchProfile","hand","MotionController","valueNode","minNode","maxNode","bone","joint","SIZE","CENTRE","INNER","WIDTH","GAP","pickRadialSector","XRRadialMenu","exitToBrowser","sector","radialSector","words","middle","XRVisionTools","THREE.MultiplyBlending","PANEL_WIDTH","PANEL_HEIGHT","positive","negative","weatherLines","weatherSystem","XRWristPanels","getLocation","getSceneTime","handedness","gradient","safeLat","xFloat","yFloat","tilePixels","offsetY","drawX","drawY","sceneTime","VR_ACCESS_REASONS","hasPositiveNoclipBalance","baseUnits","evaluateVrAccess","VrAccessGate","decision","XR_MENU_SECTOR_LIMIT","paginateXRMenuItems","VRManager","grip","listen","surfaceDistance","uiHit","hitDistance","contextCoords","createMapActions","adapt","buttons","pressed","minimap","quickSearches","labelSettings","layerItems","LABEL_CATEGORIES","getLabelCategorySourceBinding","getLabelCategoryControlValue","buildLabelCategoryControlPatch","Recognition","recognition","searchPlaces","menuText","globalEnabled","handlesByCategory","getLabelCategoryForType","categoryItem","handles","labelItems","visibleItems","groups","LABEL_CATEGORY_GROUPS","categories","getLabelCategoriesByGroup","essentialStates","buildLabelCategoryPresetPatch","sessionInit","endedSession","yaw","rig","smoothAlpha","ratePerSec","PRIMARY_STATE_KEYS","STATE_ALIASES","STATE_SPEED_REF","IDLE_SPEED_THRESHOLD","RUN_SPEED_THRESHOLD","DIRECTION_THRESHOLD","enforceOpaqueAvatarMaterial","Avatar","clips","footYOffset","groundContact","THREE.AnimationMixer","materialClones","cloneMaterial","registerAction","THREE.LoopOnce","THREE.LoopRepeat","getClipForState","alias","startState","considerBone","directChild","firstBoneChild","strafe","absForward","absStrafe","primaryForward","nextName","prevClip","nextClip","prevDur","nextDur","newY","horizontalSpeed","hasAngles","yawRaw","pitchRaw","rollRaw","pitch","roll","stateName","followingIndex","flightBlend","weightedOffset","totalWeight","airborneFlag","scaleSource","animation","headLook","jump","debug","hasProxyFlag","hasProxyRadius","hasProxyColor","useBall","MODEL_URL","TARGET_HEIGHT_M","GROUND_CONTACT_SAMPLE_COUNT","FOOT_SKIN_WEIGHT_MIN","GROUND_CONTACT_EPSILON_M","FOOT_BONE_PATTERN","GROUND_CONTACT_STATES","normalizeTemplateHeight","targetHeightM","rawHeight","scaledBounds","ANIMATION_URLS","ROOT_BONE_HINTS","CHARACTER_CLIP_SPECS","CHARACTER_CLIP_KEYS","stripRootMotionFromClip","rootNames","freeze","preserveY","shouldFreezeAxis","trackName","findClipInList","haystack","regexes","rx","buildClipMapFromList","deriveClipsFromAnimations","animations","collectFootVertexSets","minWeight","sets","skeletonUseCount","skinIndex","skinWeight","footBones","boneIndices","isFootVertex","captureLocalPose","restoreLocalPose","measureFootMinimumY","vertexSets","parentWorldInverse","meshToContact","baseVertex","weightedVertex","meshSpaceSkinning","bones","boneIndex","deriveGroundContactProfiles","epsilon","calibrationRoot","mixer","localPose","baseOffset","getSkinBundle","THREE.SkeletonHelper","THREE.Skeleton","loadExternalAnimations","targetModel","targetBundle","sourceBundle","retargeted","SkeletonUtils.retargetClip","buildFallbackTemplate","bodyMat","headMat","THREE.CapsuleGeometry","visor","armGeo","armL","armR","legGeo","legMat","legL","legR","_AvatarFactory","animationNames","nativeClips","externalClips","missingClips","emptyClips","__publicField","AvatarFactory","MEDITATE_ALTITUDE_THRESHOLD","LocalPlayer","avatarData","prevStand","prevCrouch","crouchRatio","surfaceSpeed","standHeight","heightAboveStand","pitchRad","surfaceState","surfaceUp","contactWorld","localPos","localUp","refUp","motionPose","nativeXR","PEER_LABEL_MAX_DISTANCE_M","PEER_STATIONARY_CONTACT_RADIUS_M","PEER_STATIONARY_CONTACT_DEADBAND_M","PEER_STATIONARY_SPEED_MPS","PEER_CONTACT_CONFIRM_MS","PEER_CONTACT_CANDIDATE_TOLERANCE_M","MOTION_STATE_KEYS","hasExplicitMotionState","remoteAvatarConfig","_localAppearance","_localIdentity","PeerManager","avatar","initialAppearance","labelText","shortId","presenceInstanceText","username","presenceLabelMetadata","hadSnapshot","motionStateKnown","isFloating","reportedContactMsl","canUseReportedContact","stableContactMsl","receivedAtMs","horizontalTravelM","stationary","contactDeltaM","avatarElevation","sentAtMs","remoteDt","reportedSpeed","continuityLimitM","hasAppearance","nextAppearanceSignature","worldUp","newLabelText","hoveredPeer","minDist","isHovered","snapshotAgeSec","posAlpha","rotAlpha","DEFAULT_IPD","IPD_STORAGE_KEY","MAX_IPD","MobileStereoRenderer","dispatchResize","cssW","cssH","eventManager","renderScale","renderW","renderH","fullW","fullH","restoreAspect","SceneBudgetGovernor","devMem","sys","bo","mgr","mem","heapMB","heapPressure","elevationStats","elevationCap","elevationRatio","elevationPressure","calls","overTriHard","overTriSoft","overDrawCalls","overGeometry","overTextures","trianglePressure","drawPressure","texturePressure","scenePressure","effectivePhotorealPressure","ATM_VERTEX_PARS","ATM_VERTEX_MAIN","ATM_FRAGMENT_PARS","ATM_FRAGMENT_MAIN","VOID_MAIN_RE","PhotoAtmosphereEffect","earthMaterialUniforms","mats","prevOBC","prevCacheKey","vsBefore","fsBefore","WARM_SESSION_PREFIX","WARM_SESSION_MAX_AGE_MS","WARM_SESSION_EXPIRY_MARGIN_MS","SNAPSHOT_MESSAGE_TYPE","PROFILE_MESSAGE_TYPE","MAX_SNAPSHOT_URLS_DESKTOP","MAX_SNAPSHOT_URLS_MOBILE","usedWarmSessionScopes","getStorage","sessionScopeKey","credentialId","normalizedProvider","parseExpiry","expiry","isExpectedProxyRoot","rootUrl","pathProvider","takeWarmPhotorealSession","storedAt","rememberWarmPhotorealSession","compactSession","reportPhotorealCacheProfile","reportVisiblePhotorealTiles","compact","LUNAR_LABEL_LIMIT","TYPE","validateLunarCatalog","scoreLunarFeature","localCamera","localToClip","pixelsPerRadian","heightColumn","LunarFeatureLabels","moonSystem","DEFAULT_MAX_BUILDINGS","DEFAULT_RAYCAST_BUDGET","MIN_FETCH_INTERVAL_MS","OVERPASS_FETCH_TIMEOUT_MS","_rayOrigin","_rayDir","_tmpDir","_tmpMatrix","_tmpQuat","_raycaster","PhotoBuildingLabels","tileGroup","localObs","fetchBuildingsForLabels","extractOsmContactFields","nodeLat","nodeLon","formatOsmBusinessCategory","roofRadius","startR","bestR","labelPos","hitPoint","localHit","parentInverse","bestEntry","bestDistSq","sampleBB","buildingResult","getPhotoBuildingLabels","DEFAULT_MIN_FETCH_INTERVAL_MS","DEFAULT_MAX_BUSINESSES","DEFAULT_RETENTION_MS","DEFAULT_MAX_RETAINED","DEFAULT_LABEL_MAX_DISTANCE_M","DEFAULT_SURFACE_HOVER_DISTANCE_M","MOBILE_RADIUS_M","MOBILE_REFRESH_DISTANCE_M","MOBILE_MIN_FETCH_INTERVAL_MS","MOBILE_MAX_BUSINESSES","MOBILE_RETENTION_MS","MOBILE_MAX_RETAINED","MOBILE_SURFACE_HOVER_DISTANCE_M","_tmpPos","geodesic","R","compactText","BusinessLabels","nextProfile","osm","clearEntries","businesses","prune","activeCamera","bestDist","fetchBusinessesAround","business","PLACE_CATEGORIES","classifyOsmPlace","formatOsmAddress","pruneDistanceM","distFromCenter","fadeSpan","radiusBased","maxRetained","ageA","ageB","distA","removeCount","getBusinessLabels","DEFAULT_MANUAL_INTERVAL_MS","DEFAULT_GPS_INTERVAL_MS","DEFAULT_FLUSH_INTERVAL_MS","DEFAULT_FLUSH_BATCH_SIZE","MIN_DISTANCE_M","haversineM","MotionTracker","sess","sessions","accuracy","sceneApi","unflushed","getMotionTracker","EARTH_R","OFF_ROUTE_THRESHOLD_M","RECOMPUTE_COOLDOWN_MS","toRad","toDeg","snapToPolyline","midLat","segLenSq","qx","qy","snappedLon","snappedLat","distM","buildCumulativeDistances","RouteProgressTracker","route","nextStep","slon","slat","clon","clat","snap","segLen","distanceAlong","totalDist","distanceRemaining","remainingFraction","durationRemaining","currentStepIdx","nextStepIndex","distanceToNextStep","nlon","nlat","lookahead","offRoute","shouldReroute","TILE_ZOOM","TILE_VERSION","MAX_MATCH_DISTANCE_M","MAX_ROAD_AUDIO_DISTANCE_M","UPDATE_INTERVAL_MS","EARTH_METERS_PER_DEGREE","decoderPromise","decoder","vectorModule","pbfModule","lonLatToTile","latitudeRad","wrappedLonDelta","segmentDistance","lengthSq","headingDifference","difference","profileAllows","subclass","featureLines","findNearestRoadContext","useHeading","segment","headingPenalty","unnamedPenalty","findNearbyRoadSoundSources","maxSources","simplifyCoordinatePath","sourceIndex","pointInRing","geometryLines","nearestPointOnFeature","closest","findNearbyHabitatContext","greenSpace","nearestWater","greenClasses","waterClasses","green","neighborTiles","tileWidthM","offsetsX","offsetsY","RoadContextService","onSoundscapeUpdate","nearbyRoads","habitatContext","vectorTile","DEFAULT_CAR_SPEED_MPS","MIN_SPEED_MPS","MAX_SPEED_MPS","MIN_TICK_MS","MAX_TICK_MS","finiteLatLon","sampleRouteAtDistance","startDistance","endDistance","ScenePuppetController","applyPose","routeStore","routeProgressTracker","getRoute","tickMs","stepSeconds","maxSteps","waypoints","routingService","RIBBON_WIDTH_M","SURFACE_LIFT_M","ELLIPSOID_LIFT_M","COLOR_AHEAD","COLOR_BEHIND","COLOR_DEST","DRAPE_BUDGET_PER_TICK","_tmpTangent","_tmpSide","_tmpCenterLocal","_tmpLeftLocal","_tmpRightLocal","_tmpPosA","_tmpPosB","RouteRibbonRenderer","sc","dir0","liftR","segCount","l0","r0","l1","r1","io","dirCur","rCur","nextIdx","dirNext","rNext","attr","lookupSeq","fetchBuildingFootprint","getRouteRibbonRenderer","PlaceSearchSurfaceLayer","getPlaceSearchStore","routes","getRouteStore","routeStopBadge","LOCAL_ROUTING_CLIENT_LIMITS","PATHS","MESSAGES","RoutingError","retryable","invalidRoutingRequest","invalidRoutingResponse","checkRoutingAbort","parseRoutingBytes","LocalRoutingClient","resolveUrl","validate","forwardAbort","savedBytes","attempted","serialized","until","getLocalRoutingClient","PROFILES","routingProfile","routingPoint","routingCoordinates","nonnegative","routingYield","validateLine","validateRoute","validateIsochrones","contours","validateMatching","inputCount","edgeCount","buildOsrmInstruction","modifier","streetPart","maneuverGlyph","mod","hydrateRouteSteps","fetchNearbyTransitStops","stops","CLASS_PEAK","WEEKDAY_HOURS","WEEKEND_HOURS","hourWeight","dow","table","h0","h1","getMultiplier","highway","hourLocal","lanes","shave","applyTrafficToRoute","freeFlow","withTraffic","newDur","trafficDelay","RouteStepHeights","estimate","RouteStepsWindow","element","renderRow","within","measured","RouteWaypointsEditor","onSearch","button","badge","MODES","STEP_ARROWS","arrowFor","glyph","escapeHtml","formatDistance","formatDuration","DirectionsPanel","getPlayerLatLon","routeLoader","transitLoader","placeSearch","removeBody","bindPlaceSearchList","off","btn","li","getPlaceSearchBias","player","lookupNotice","formatResultForDisplay","transitNote","lookup","stopLookup","originStops","destStops","delayStr","activeIdx","glyphToken","arrow","tone","getDirectionsPanel","PADDING_PX","FONT_SIZE_PX","FONT_FAMILY","LINE_HEIGHT_PX","MAX_WIDTH_PX","BG_FILL","BG_BORDER","TEXT_FILL","ANCHOR_OFFSET_M","SPRITE_WORLD_HEIGHT_M","FADE_IN_MS","FADE_OUT_MS","SpeechBubble","lineCount","blockWidth","onComplete","SATIN_BLACK_PARAMS","FOLLOW_TRIGGER_DIST_M","FOLLOW_SPEED_MPS","FOLLOW_STOP_DIST_M","NAV_STOP_DIST_M","EarthDaemon","latLonGetter","includeImage","rsp","stopDistanceM","clearOnArrive","here","fromDir","toDir","arcM","newDir","nextLatLon","newLat","newLon","prevXr","prevAutoClear","dst","ACTION_SPACE","WEB_TOOL_ACTIONS","DEFAULT_MAX_TOOL_CALLS_PER_MINUTE","DEFAULT_TOOL_RESULT_LIMIT","DEFAULT_TOOL_TIMEOUT_MS","KNOWN_DRIVERS","DEFAULT_TICK_MS","DEFAULT_MAX_ACTIONS_PER_MINUTE","DEFAULT_MAX_OFFSET_METERS","DEFAULT_REQUEST_TIMEOUT_MS","clampInt","normalizeDriverName","driver","normalizeAction","rawAction","compactError","getDaemonVisionActionSpace","DaemonVisionActionDriver","daemon","pov","offsetLatLonMeters","EarthDaemonManager","getPlayerPose","follow","forwardHeading","spawn","faceUser","getEarthDaemonManager","NavBanner","cameraYaw","getNavBanner","MANUAL_COLOR","GPS_COLOR","TRAIL_OPACITY","TRAIL_SEGMENTS","CAMERA_HELPER_SIZE","CAMERA_HELPER_EVERY","_helperGeo","getCameraHelperGeometry","verts","MotionTrailRenderer","curvePoints","lineGeo","lineMat","pointGeo","pointColors","pointMat","helpers","helperGeo","helperMat","surfaceQuat","surfaceNorth","surfaceMat","qz","qw","trail","unitFromLatLon","latLonFromUnit","slerpLatLon","sin","cardinalPoint","tension","h00","h10","h01","h11","catmullPosition","compiled","ecef","waypoint","binarySearchTime","sampleTrack","slerpQuaternion","aValue","bValue","lerpAngleDeg","sampleOrientation","sampleMotionPath","requestedTimeMs","waypointIndex","heldUntil","rawT","altitudeReference","MOTION_EXECUTION_STATE","MOTION_TERMINAL_STATES","TRANSITIONS","MotionRuntimeError","transitionMotionState","isMotionTerminal","MotionTimelineClock","monotonicNowMs","MotionTargetRegistry","adapter","MAX_EXECUTIONS","publicSnapshot","execution","MotionRuntime","targetRegistry","onEvent","adapterRecord","expectedGeneration","emitEvents","frameContext","frameNow","running","previousTime","fromTime","toTime","sampleWorldPosition","copyQuaternion","INPUT_EVENTS","CameraMotionTarget","inputTarget","isBlocked","overrideToken","settle","hpr","nextSample","LocalUserMotionTarget","previewPatch","mapping","cloneValue","OverlayItemMotionTarget","PhysicalDeviceMotionTarget","SimulatedDeviceMotionTarget","createSceneMotionRuntime","isCameraBlocked","simulated","ensureHudPanelStyles","HUD_PANELS_DEFAULT_ON","HUD_PANELS_ON_DEMAND","setAddressToastVisible","setLeftSidebarWidth","SPEEDS","HOUR_MS","RANGE_MIN_MS","RANGE_MAX_MS","injectTimelineStyles","getTimelinePanel","TimelinePanel","toggle","offsetMs","PERMISSIONS","_registry","registerIntent","normalised","unregisterIntent","getIntent","listIntents","dispatchIntent","intent","granted","handlerResult","generateToolSpec","intents","generateMarkdownDocs","md","ex","_clearRegistry","_registered","registerSceneClockIntents","seedBuiltinBasemaps","MAPSOURCE_STYLES","getBasemapPicker","BasemapPicker","Registry.subscribe","Registry.getActive","fragment","groupMapSources","Registry.list","Registry.setActive","registerBasemapIntents","LIFT_M","RENDER_ORDER","COLOR_COMMIT","COLOR_PREVIEW","COLOR_SELECTED","STEPS_PER_SEGMENT","CIRCLE_SAMPLES","POINT_RADIUS_M","_coordToWorld","_disposeObject","_basicLineMaterial","_basicMeshMaterial","_densifyGreatCircle","stepsPerSeg","arc","interpolateGreatCircle","_buildLineFromLatLon","radiusFor","_buildPointMarker","THREE.CircleGeometry","yUp","_buildCircleRing","_buildRectangleRing","_buildPolygonFill","verticesOrRings","sLat","sLon","cLat","cLon","centerRad","centerWorld","yWorld","projectRing","planarRings","planar","tris","DrawSurfaceLayer","getDrawSystem","preview","oldLabel","styledColor","geometryAnchor","measurement","preserved","dense","pointMarker","addLine","addPolygon","_layerInstance","getDrawSurfaceLayer","SceneCanvasCapture","download","downloadScenePng","aborted","hd","saveSceneCanvas","filename","SNAP_RADIUS_PX","SELECT_RADIUS_PX","FREEHAND_SAMPLE_PX","CONTEXT_DRAG_THRESHOLD_PX","CONTEXT_EVENT_SUPPRESSION_MS","interactionNow","DrawInteractionController","showActionMenu","showMapActionMenu","shouldOpen","drag","pointerId","clientX","clientY","exclusion","radiusPx","pointInPolygon","pointSegmentDistance","DrawingProjectApiService","projectId","clientMutationId","latColumn","lonColumn","wktColumn","polygonAsTrack","getDrawingProjectApiService","SNAPSHOTS","OUTBOX","requestValue","DrawingProjectStore","indexedDBImpl","getDrawingProjectStore","uuid","dispatch","DrawingProjectManager","project","parentGroupId","groupId","removedId","groupName","shapeIds","shapes","shapeId","bufferShape","combineShapes","geoJSONFeatureToShape","shapeToDrawingMutation","mutation","baseSnapshot","getDrawingProjectManager","TOOLS","FORMATS","stylesReady","ensureStyles","formatArea","getDrawToolbar","DrawToolbar","selector","formFocused","completionMessage","spatialRole","assetIds","assetMount","assetId","select","selectedValue","hasProject","inspector","assetAnchors","groupSelect","measurements","shapeMeasurements","getMeasurementReadout","MeasurementReadout","formatM","m2","sphericalPolygonArea","registerDrawingIntents","projects","POLYGON_LIFT_M","BOUNDARY_HALF_WIDTH_M","DEFAULT_FILL_OPACITY","MAX_FILL_OPACITY","_scratchVec","coordToWorld","upOut","parseColour","ringCentroid","buildRingFanGeometry","lon0","lat0","lonE","latE","vertCount","triCount","buildRingBoundaryGeometry","lonN","latN","IsochroneOverlay","fc","feat","colour","fanGeom","ringGeom","ringMat","getIsochroneOverlay","getIsochrones","denoise","generalize","_modCache","_load","pkg","_buffer","_union","_intersect","_difference","_booleanWithin","_booleanContains","_area","_length","_centroid","_simplify","_bbox","_bboxPolygon","_pointsWithinPolygon","_isFeatureLike","_safe","bufferGeom","unionGeom","intersectGeom","differenceGeom","withinGeom","containsGeom","areaGeom","lengthGeom","centroidGeom","simplifyGeom","highQuality","bboxGeom","bboxPolygonGeom","bboxArray","pointsWithin","applyOp","SPATIAL_OPS","emitDocumentEvent","activeIsochrone","registerIsochroneIntents","registerAddressingIntents","detected","sniff","getCollabDoc","CollabDoc","Y","YjsNknProvider","YjsWsProvider","registerCollabIntents","sid","comments","prefetchRegion","quotaStatus","usage","quota","_lonLatToTileXY","generateTileList","zooms","urlTemplate","west","registerOfflineIntents","getActiveBasemap","getIndoorOverlay","IndoorOverlay","registerIndoorIntents","_req","Marketplace","serviceId","orderId","listingId","receipt","registerMarketplaceIntents","STORE","_openDb","os","getCaptureStore","CaptureStore","put","getCaptureSystem","CaptureSystem","registerCaptureIntents","cs","_post","runBandMath","expression","runDiff","cogUrlA","cogUrlB","runClassify","cogUrl","training_pixels","algorithm","registerRasterIntents","registerBigDataIntents","getBigDataOverlay","RAINVIEWER_INDEX","FRAME_REFRESH_MS","getWeatherRadarOverlay","WeatherRadarOverlay","past","nowcast","registerWeatherIntents","getSatelliteImageryOverlay","SatelliteImageryOverlay","PRESETS","registerSatelliteIntents","_get","criteria","external","getItem","cid","iid","registerStacIntents","registerSunStudyIntents","getSunStudyPanel","getShadowPass","_readCameraLatLon","_readAltitude","_readHeadingDeg","_readMode","_readActiveBasemap","picker","registerSceneInfoIntents","wireframe","sceneClock","matchTrack","registerMapMatchingIntents","registerTrafficIntents","registerPhotogrammetryIntents","getPhotogrammetryPanel","registerARIntents","getARSession","registerStorefrontIntents","getCreatorStudio","getStorefrontPanel","unlockListing","planTransit","fromPlace","toPlace","its","normalizeItinerary","legs","leg","decodePolyline","dlat","dlon","registerTransitIntents","registerBlackSunIntents","_slots","registerEarthDaemonIntents","METAVERSE_SPHERE_RADIUS_KM","METAVERSE_SPHERE_RADIUS_M","STREET_WIDTH_M","STREET_HALF_WIDTH_M","TOTAL_LOCAL_PORTS","portToTheta","portIndex","BUILDING_BASE_SIDE_M","BUILDING_TOP_SIDE_M","BUILDING_HEIGHT_M","BUILDING_SETBACK_M","DOOR_WIDTH_M","DOOR_HEIGHT_M","HEMISPHERE_RADIUS_M","HEMISPHERE_CENTROID_HEIGHT_M","PROPERTY_LINE_OFFSET_M","BUILDING_NEAR_FACE_OFFSET_M","createSignTexture","caption","buildBlackSun","cos","buildingDir","nearFaceCenter","halfDepth","buildingCenter","hullGeom","hullMat","doorGeom","doorMat","door","hemiGeom","hemiMat","hemisphere","signGeom","signMat","distanceToPropertyLine","blackSunGroup","nearFace","CROWD_SIZE","CROWD_MIN_RADIUS","CROWD_MAX_RADIUS","CROWD_FAN_HALF_ANGLE_RAD","buildCrowd","bodyGeom","headGeom","mergeGeometries","dummy","doorAxis","leftAxis","geoms","posCount","idxCount","pOff","iOff","vertOff","ROSTER_URL_PROD","ROSTER_URL_DEV","ROSTER_CACHE_TTL_MS","PROPRIETOR_WALLET","PROPRIETOR_SIGNING_PUBLIC_KEY_B64","RosterClient","roster","wallet","invite","currentTier","lcWallet","verifyEd25519Json","getRosterClient","stableStringify","decodeBase64Bytes","padded","signatureB64","publicKeyB64","AUDIT_LOG_KEY","RECENT_DENIAL_BACKOFF_MS","AccessGate","getAccessGate","QUADRANT_TINTS","FLOOR_INSET_M","FLOOR_THICKNESS_M","QUADRANT_DIM","buildInterior","centerOnFloor","floorGeom","floorMat","quadrantSpec","inlayGeom","inlayMat","inlay","depthOffset","lateralOffset","barGeom","barMat","bar","barOffset","stageGeom","stageMat","stageOffset","ceilGeom","ceilMat","ceiling","runOpacityRamp","PYRE_FLAME_RADIUS_M","PYRE_FLAME_HEIGHT_M","buildPyre","flameGeom","flameMat","flame","coreGeom","coreMat","core","DEFAULT_LEASE_TTL_MS","CoordinatorService","taskType","targetId","daemonId","getCoordinator","_idCounter","POLICY_TRIGGERS","BouncerDaemon","targetWallet","audit","torsoGeom","torsoMat","torso","shirtGeom","shirtMat","shirt","GraveyardDaemon","dismemberedMesh","pyrePosition","hypercard","fromAnchor","toAnchor","BOUNCER_POOL_SIZE","GRAVEYARD_POOL_SIZE","DaemonRegistry","interiorCenter","bouncer","graveyard","getDaemonRegistry","EYE_HEIGHT_M","LOCAL_SEGMENT_LENGTH_M","STREETLIGHT_SPACING_M","MONORAIL_HEIGHT_M","portSpawnPose","MetaverseScene","MIN_OUTSIDE","pushBack","crowd","nf","interior","pyre","pyrePos","fallbackGround","pavementGeom","pavementMat","pavement","stripeGeom","stripeMat","stripe","lightCount","halfCount","across","monorailGeom","monorailMat","monorail","pylon","fixture","showGraphicsUnavailableNotice","getAddressToast","showGraphicsStartupRecovery","help","photorealisticTileLoaderModulePromise","satelliteOverlayClassPromise","commsSystemClassPromise","openInfraMapRendererClassPromise","normalizeUrlLon","isBootOriginUrlLatLon","parseUrlFloatParam","readUrlLatLonPair","latName","lonNames","lonName","resolveUrlLatLonParams","aliases","loadPhotorealisticTileLoaderModule","loadSatelliteOverlayClass","loadCommsSystemClass","loadOpenInfraMapRendererClass","DEFAULT_WIREFRAME_STYLE","hasPhotorealBuildingProbeSurface","resolveSurfaceBuildingViewshed","configuredRadiusM","verticalFovDeg","isMobile","hardMaxM","configuredMaxM","safeAspect","PlanetScene","requestedMapMode","restoreActiveBasemap","setActiveBasemap","tb","setTilesPendingNormals","initAsyncHarness","dolly","THREE.AudioListener","TriTreeManager","hudStore","reg","IntentRegistry","getARHud","geoJsonBorderColor","GeoJsonLayer","autoLevels","autoOpacity","geoJsonColor","liftMeters","SurfaceController","cameraWorldPos","labelWorldPos","EventManager","getPathTracker","presenceOptions","nknEnabled","bodyName","uiController","UIController","selection","focusDir","atmosphereMesh","_ca","_da","_ea","_fa","AnimationLoop","overlayObserver","_camAltKm","photorealSemanticLabelsReady","businessLabels","bootMapOwnsViewport","_ha","_ga","routeProfile","_ja","_ia","_la","_ka","_pa","_ma","_oa","_na","_ra","_qa","_ta","_sa","_va","_ua","_xa","_wa","tracker","_za","_ya","_Ba","_Aa","_Ca","_Da","_Fa","_Ea","_Ha","_Ga","_Ja","_Ia","_La","_Ka","_Na","_Ma","buildingOptions","flightOptions","maritimeOptions","incidentOptions","trafficCameraOptions","roadTrafficOptions","radioDataOptions","geocacheOptions","initialLabelSettings","meshtasticOptions","getLabelCategoryValue","EnvironmentalOverlay","GlobalSignalsOverlay","disposition","infrastructureOptions","infraBackendUrl","savedInfraLayers","SatelliteOverlay","satelliteOptions","initialConfig","CommsSystem","commsOptions","hasEnabledOpenInfraMapGroup","OpenInfraMapRenderer","getEnabledOpenInfraMapGroups","infrastructureSettings","infrastructureLayers","isObjectLike","assignIfDefined","restored","initializer","boundedTimeoutMs","photoLoader","photoCoverage","photoProviderBusy","allowWaitTimeout","governance","photoConfig","milliseconds","previousMode","photoRequested","partial","replayStats","comms","entities","listKey","callId","streamId","files","stream","soundPath","isReady","terrainColliders","pendingColliders","totalStaticColliders","dynamicObjects","actionName","peers","catalog","services","healthy","quote","credit","failureSignals","statusTone","acc","unlock","getInferenceManager","pushToTalkKey","cloudTop","rainActive","verticalScale","localFrom","inSurface","photorealActive","weather","maxFreq","phoneClass","hasMemorySignal","highTier","midTier","clampedImageryMaxZoom","clampedSurfaceImageryMax","nextImageryBudget","capInt","ringFarMeters","nearRingLod","ringMidDrop","ringFarDropRaw","ringFarDrop","ringMidLod","ringFarLod","ringMidImageryDrop","ringFarImageryDropRaw","ringFarImageryDrop","ringMidImageryCap","ringFarImageryCap","currentImagery","overlayProfile","currentBatch","currentConcurrent","currentInterval","buildingPatch","infrastructurePatch","currentScale","currentNormalsBudget","currentMorphBudget","currentFinalizeBudget","currentMorphMsBudget","currentFinalizeMsBudget","isLow","isMid","hardCap","mobileVertexCap","baseDelayMs","afterBuildingsDelayMs","mobileToggle","mobileModal","mobileClose","mobileContent","sidebar","overlaySidebar","wireframeCheckbox","rayEllipsoidIntersection","raySphereIntersection","withinInterval","withinDelta","needsSeed","includeDetails","maxItemsPerCategory","generatedAt","categoryFilter","resolveViewshedCategories","totalLimit","categoryLimit","labelsMasterEnabled","isGeoVisible","labelSnapshot","signals","namedPlaces","sourceLayers","sanitizeAgentValue","byCategory","dedupe","sourceVisibleCounts","appendItem","rawItem","hudCategoryMap","hudName","agentEntityId","observedAt","selectedByCategory","selectionCount","selectedThisPass","categoriesOut","summaries","visibleCount","returnedCount","truncated","allItems","categoryVisible","wantedId","categoryId","getLabelCategory","earthMatrix","tmpVec","formatAltitude","toWorldPosition","lonRad","sinLat","toWorldPositionFromRadius","resolveViewshedId","resolveViewshedSizeM","positionForEntry","labelForEntry","metaForEntry","limited","aircraftEntries","aircraftOffset","aircraft","satelliteEntries","satelliteOffset","maritimeEntries","maritimeOffset","maritime","buildingEntries","buildingOffset","hasAddress","namedPlaceEntries","businessEntries","naturalEntries","natural","infrastructureEntries","infrastructure","incidentEntries","incidentOffset","callType","emoji","resolveIncidentEmoji","blackMat","accentMat","earthPos","radiusValue","modelSize","maxDim","scaleMax","toTarget","radiusFromDistance","ringRadius","ringDistance","buildingInfo","countryInfoPromise","iso3","countryName","countryInfo","resolvedIso3","adminInfo","needsUpdate","previousHeading","waitedMs","buildingsConfig","configuredFalloff","requestKey","requestSeq","maxSatellites","due","contextChanged","infraConfig","overlayRadius","hierarchy","deepestAdmin","adminValue","bldgName","heightStr","levelsStr","labelRaycaster","businessLabelHit","hoverId","addrParts","photoBldg","hoverLL","businessNear","prevLat","prevLon","playerPos","camPosWorld","camPosLocal","altThreshold","bands","capLevel","adminLevel","preserveState","show","debugVisible","hasUrl","altitudeCap","effectiveMaxLevel","hierarchyChanged","needsReload","hasLevel","visibleLevels","parentLevel","parentKey","parentName","deepest","overlayLayer","newHierarchy","oldHierarchy","newName","oldName","rendererScale","autoRender","renderCadenceMs","frameDiscard","baseAtmosphereConfig","overlayAtmosphereConfig","atmosphereConfig","weatherConfig","terrainImagery","terrainElevation","geoJsonUrl","geoJsonBase","geoJsonSource","precision","applyToRaycaster","accentSoft","accentStrong","surfaceColor","lineColor","stylePatch","accentRgb","setWireframeStyle","currentIso","currentName","CONFLICT_BORDER_PALETTE","colorValue","nextDebug","nextAtmosphere","currentAtmosphere","nextTerrain","currentTerrain","effectiveAtmosphereEnabled","nextSimpleClouds","effectiveTileSource","hasTerrainProviderPatch","nextPhoto","hasExplicitTerrainMode","nextBuildings","resolveRegional","worldIndex","oceanCache","cacheLimit","quantize","keyFor","qLat","qLon","resolveOcean","lifecycle","getBasemap","attribution","lifecycleGeneration","lifecycleInvalidated","getPhotorealisticTileLoader","apiToken","authSvc","proxyFetchOpts","proxyFallbackFor","providerName","initCesiumSession","getFallbackCesiumIonToken","communitySession","fallbackKey","getFallbackGoogleTilesKey","currentPhotoConfig","warm","holdForTileCoverage","atmEffect","rs","stableXRContact","worldPosition","visibleState","focusedState","surfaceModeActive","walkingContactProbe","walkingPhotoContactActive","contactReleasedBeforeTraversal","contactWorldPosition","underfoot","terrainSurfaceChanges","modelSeq","photoGeometryChanged","bootContact","deferLocalVisualStreaming","terrainImageryEnabled","triTreeGroup","globe","stillWanted","destroyPhotorealisticTileLoader","rendererOpts","flashlightConfig","flashlight","getLabelCategoryPatch","maxVisible","nextWireframe","disableLensFlare","nextEnabled","_enabled","overlayConfig","nightSettings","nightStart","nightEnd","minZoomChanged","maxZoomChanged","photogrammetry","photoActive","scaleFactor","elevationConfigPatch","persistentEnabled","queueResetDistanceM","queueResetAngleDeg","urlState","hasUrlOverride","savedMode","pathfinding","costs","classicLayerKeys","classicLayers","applyLayers","meshtastic","radioData","_Oa","_Qa","_Pa","_Sa","_Ra","geocaches","_Ua","_Ta","nextAlt","_Wa","_Va","labelTuningDirty","hasAdminLevel","hasCountry","hasSource","nextLevel","nextCountry","viewState","imagerySnapshot","tileSource","hasUrlState","urlLatLon","resolvePreferredImageryVersionId","snapshotVersionId","configuredVersionId","prewarmImagerySnapshotTiles","prewarmImageryHotset","prewarmElevationForLatLon","sourceLatLon","prewarmElevationSnapshotKeys","focusWorldDir","keyCap","hasTiles","savedTileSource","triTreeConfigPatch","imageryManagerPatch","applyImagery","snapshotLatLon","latLonSource","worldQ","initialized","localReady","peerReady","previousXr","includeElevationCache","rawMode","lodMode","surfaceAltitude","surfaceTerrainRadius","surfaceLatLon","renderedSurfaceLatLon","activeCameraTransition","cameraTransition","orbitLatLon","orbitRadius","surfaceOrientation","vrState","updateUrl","applyElevationCache","allowPersistToggle","savedCamera","isSurfaceMode","btnLodOrbit","btnLodZoom","resolveWorldDirFromLatLon","surfaceVec","cameraVec","restoreLease","orbitDir","dollyPos","cfgStatePersist","metaverseParam","portRaw","hasLatLon","altitudeRaw","hasHeading","hasPitch","validBodies","ALT_URL_MIN","VIEW_ALTITUDE_MIN_M","ALT_URL_MAX","VIEW_ALTITUDE_MAX_M","stateOverride","hasOrientation","surfaceThreshold","hasAltitude","useSurface","terrainR","surfaceAlt","minSurfaceAlt","wantsSurface","bodyAnchor","inSurfaceMode","maxAlt","altitudeWriteable","writeLastStartupLocation","pollAltitude","initialUrlState","initialParams","hasShortEarthAliases","throttled","_reason","invalidate","keepLease","liveDirection","exactFocus","DEFAULT_FORWARDER","multiClient"],"ignoreList":[],"sources":["../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/render/SceneOcclusion.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/shared/EventBus.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/vr/XRDiagnostics.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/vr/XRProfileSampler.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/vr/XRRemoteHarness.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/diagnostics/BrowserPerformanceTelemetry.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/camera/CameraQuiescenceBarrier.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/modules/performance-monitor.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/render/SceneRendererStartup.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/modules/celestial-ephemeris.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/modules/lighting-system.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/modules/sky-visibility.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/scene/SceneRuntimeResources.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/modules/stellar-catalog-math.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/modules/stellar-catalog-renderer.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/modules/stellar-flux-field.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/modules/sky-label-focus.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/modules/sky-features.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/render/FirstDrawGuard.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/modules/motion-blur-pass.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/render/LensContract.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/modules/cloud-map-sampling.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/modules/water-coverage.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/modules/water-reflectance.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/modules/ocean-water-optics.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/imagery/NightLightsGeoreference.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/modules/night-cloud-lighting.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/modules/orbital-cloud-volume.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/render/CelestialIrradianceContract.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/modules/earth-material.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/render/CelestialOcclusionContract.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/lunar/LunarFrame.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/modules/moon-system.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/modules/ocean-wave-spectrum.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/modules/ocean-fft.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/modules/ocean-gpu-cascades.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/modules/ocean-optics.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/modules/ocean-capillary.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/modules/ocean-surface-depth.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/modules/ocean-particulate.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/render/CloudDepthReconstruction.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/modules/OceanCloudLighting.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/modules/ocean-surface.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/render/StreamedImageTexture.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/render/StagedDataTexture.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/imagery/RegionalWaterMask.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/scene/SceneClock.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/modules/ocean-water-level.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/modules/ocean-quality.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/render/SolarOpticsContract.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/modules/LenseFlare.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/render/SolarOpticsRenderer.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/render/HdSceneProxy.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/modules/terrain-pathfinder.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/render/NightAirLighting.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/render/PhotorealBackface.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/modules/airglow-emission.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/render/CloudResolutionPolicy.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/vr/NativeXRSkyMaterial.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/render/UnderwaterEffect.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/weather/LocalCloudCoverField.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/weather/LocalPrecipitationField.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/render/AtmosphericHorizonBlurEffect.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/render/OceanSurfacePass.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/render/OceanDepthPass.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/tiles/PhotorealLightingContract.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/render/PhotorealAssetLighting.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/render/PhotorealLightingMaskPass.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/tiles/PhotorealSurfaceVisibilityContract.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/render/WaterReflectionView.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/render/WaterReflectionAtlas.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/render/WaterReflectionShaders.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/render/WaterReflectionCapturePass.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/weather/RainPass.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/render/CloudColorPass.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/render/AtmosphericEmissionPass.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/weather/SceneWeatherState.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/render/NightVisionEffect.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/render/SarEffect.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/render/LensShaderChunks.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/render/LensDepthOfField.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/render/FilmGrainEffect.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/render/ColorGradeEffect.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/render/LensEffects.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/render/CloudAtmosphereAttachments.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/render/CloudShaderProgramValidation.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/vr/XRGpuTimer.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/vr/NativeXRRuntimeBindings.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/vr/XRTerrainRange.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/vr/NativeXRClouds.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/modules/aurora-system.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/modules/fire-system.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/modules/smoke-system.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/modules/atmosphere-lut-conversion.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/modules/atmosphere-clouds-system.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/modules/flashlight.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/render/RenderFrameCoordinator.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/imagery/NasaNightLightsTileField.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/modules/scene-initializer.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/render/MapPresentationResources.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/modules/motion-tracker.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/transport/types.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/transport/BaseTransport.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/transport/CentralizedTransport.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/transport/TransportManager.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/modules/scene-state-store.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/modules/elevation-client.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/modules/imagery-texture-ownership.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/modules/imagery-manager.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/imagery/MapSourceGlobeMath.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/imagery/MapSourceGlobe.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/imagery/OverviewImageSource.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/modules/nkn-client.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/modules/weather-manager.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/modules/weather-system.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/shared/disposeOwnedObject3D.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/shared/ModelLoadBudget.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/shared/ModelResourceBundle.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/creator/OverlayPageClient.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/overlays/OverlaySessionScope.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/overlays/OverlayAdmissionPlanner.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/overlays/OverlayPageIngestor.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/overlays/ScanAssetCompatibility.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/overlays/SurfaceAnchorState.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/overlays/OverlaySubsystem.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/creator/OverlayApiService.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/overlays/OverlaySceneApi.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/overlays/HydraOverlayIngress.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/overlays/OverlayRegistry.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/creator/DataSourceApiService.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/overlays/renderers/VectorSourceLayer.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/overlays/renderers/TileSourceLayer.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/overlays/renderers/DataSourceLayerRenderer.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/streams/StreamHub.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/entities/EntitySystem.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/assets/AssetSubsystem.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/camera/GeoPoseProvider.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/assets/FieldAssetProof.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/assets/FieldAssetApiService.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/assets/FieldAssetLayer.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/notes/AccountNoteApiService.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/notes/AccountNoteLayer.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/access/GatingApiService.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/access/AccessController.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/modules/presence-client.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/social/SocialApiService.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/social/SocialStore.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/avatar/AvatarAppearance.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/presence/PresenceSystem.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/audio/data/birdsong-regional-profiles.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/audio/SpatialAmbientSoundscape.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/audio/RainAudio.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/audio/AcousticEmitter.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/audio/AudioSystem.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/audio/WindAudio.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/weather/RainSurfaceAtlas.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/weather/PrecipitationContract.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/weather/PrecipitationShaders.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/weather/RainSystem.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/splines/GlobeSpline.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/splines/SplineSubsystem.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/tiles/PhotorealProtrusionClassifier.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/overlays/BuildingOverlay.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/overlays/BuildingOverlayItem.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/overlays/TheaterSourceManager.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/overlays/MediaPlaybackController.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/overlays/TheaterIframePresenter.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/overlays/TheaterScreenBadge.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/overlays/EmbedPlayerBridge.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/overlays/MediaAspect.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/overlays/TheaterUpNextCard.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/overlays/TheaterEmbedSession.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/overlays/TheaterQueue.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/overlays/TheaterProjector.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/overlays/TheaterMediaRouter.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/overlays/TheaterListenerAudio.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/overlays/TheaterStatusProps.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/overlays/TheaterOverlayItem.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/render/ModelFirstDrawPrep.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/flights/AircraftMotion.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/flights/AircraftCatalogLayer.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/flights/FlightApiService.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/overlays/AircraftOverlay.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/maritime/MaritimeApiService.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/overlays/MaritimeOverlay.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/overlays/SurfaceFootprintMarker.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/overlays/IncidentOverlay.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/traffic/TrafficCameraDiscoveryService.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/overlays/TrafficCameraOverlay.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/traffic/RoadTrafficApiService.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/overlays/RoadTrafficOverlay.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/radio/RadioDataApiService.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/radio/RadioFieldModel.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/radio/RadioFieldVisualization.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/overlays/RadioSignalVisualization.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/overlays/RadioDataOverlay.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/geocaches/GeocacheApiService.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/geocaches/GeocacheLayer.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/overlays/AddressHoverOverlay.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/sensors/SensorEventStore.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/sensors/SensorOverlay.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/meshtastic/MeshtasticConversationStore.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/meshtastic/MeshtasticSyncService.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/meshtastic/MeshtasticService.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/meshtastic/MeshtasticOverlay.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/weather/WeatherWindStreams.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/weather/WeatherVolumeMesh.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/weather/WeatherVolumePicking.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/weather/WeatherVolumeInteraction.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/weather/WeatherVolumeApi.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/weather/WeatherVolumeOverlay.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/sensors/SensorApiService.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/sensors/SensorManager.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/overlays/InfrastructureOverlay.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/settings/SettingDescriptorRegistry.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/settings/CapabilityProfileService.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/settings/SceneSettings.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/settings/tuneables-mapper.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/modules/rapier-runtime.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/modules/physics-system.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/audio/proximity-trigger.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/interaction/click-trigger.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/vr/XRControllerInput.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/vr/XRLabelLayer.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/avatar/MeshSpaceSkinning.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/vr/XRInputModels.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/vr/XRRadialMenu.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/vr/XRVisionTools.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/vr/XRWristPanels.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/vr/VrAccessGate.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/vr/VRManager.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/avatar/Avatar.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/avatar/AvatarFactory.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/avatar/LocalPlayer.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/avatar/PeerManager.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/modules/mobile-stereo-renderer.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/modules/scene-budget-governor.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/tiles/PhotoAtmosphereEffect.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/tiles/PhotorealWarmCache.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/lunar/LunarFeatureLabels.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/labels/PhotoBuildingLabels.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/labels/BusinessLabels.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/tracking/MotionTracker.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/routing/RouteProgressTracker.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/routing/RoadContextService.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/agent/ScenePuppetController.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/routing/RouteRibbonRenderer.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/overlays/PlaceSearchSurfaceLayer.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/async/fetch/LocalRoutingClient.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/routing/RoutingContracts.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/modules/routing-service.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/modules/osm-traffic-model.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/ui/RouteStepsWindow.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/ui/RouteWaypointsEditor.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/ui/DirectionsPanel.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/daemons/SpeechBubble.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/daemons/EarthDaemon.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/daemons/DaemonVisionActionDriver.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/daemons/EarthDaemonManager.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/ui/NavBanner.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/tracking/MotionTrailRenderer.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/motion/MotionPathEvaluator.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/motion/MotionExecutionState.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/motion/MotionTimelineClock.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/motion/MotionTargetRegistry.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/motion/MotionRuntime.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/motion/targets/MotionTargetGeo.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/motion/targets/CameraMotionTarget.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/motion/targets/LocalUserMotionTarget.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/motion/targets/OverlayItemMotionTarget.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/motion/targets/PhysicalDeviceMotionTarget.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/motion/targets/SimulatedDeviceMotionTarget.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/motion/createSceneMotionRuntime.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/ui/HudSlots.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/ui/TimelinePanel.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/agent/IntentRegistry.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/agent/intents/scene-clock-intents.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/imagery/builtin-basemaps.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/ui/BasemapPicker.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/agent/intents/basemap-intents.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/draw/DrawSurfaceLayer.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/capture/SceneCanvasCapture.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/draw/DrawInteractionController.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/draw/DrawingProjectApiService.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/draw/DrawingProjectStore.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/draw/DrawingProjectManager.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/ui/DrawToolbar.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/ui/MeasurementReadout.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/agent/intents/drawing-intents.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/overlays/IsochroneOverlay.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/modules/isochrone-service.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/modules/spatial-ops.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/agent/intents/isochrone-intents.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/agent/intents/addressing-intents.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/collab/CollabDoc.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/agent/intents/collab-intents.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/modules/offline/TileCache.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/modules/offline/tile-list.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/agent/intents/offline-intents.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/overlays/IndoorOverlay.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/agent/intents/indoor-intents.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/marketplace/MarketplaceClient.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/agent/intents/marketplace-intents.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/modules/storage/capture-store.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/capture/CaptureSystem.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/agent/intents/capture-intents.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/modules/raster-client.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/agent/intents/raster-intents.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/agent/intents/big-data-intents.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/overlays/WeatherRadarOverlay.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/agent/intents/weather-intents.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/overlays/SatelliteImageryOverlay.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/agent/intents/satellite-intents.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/modules/stac-client.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/agent/intents/stac-intents.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/agent/intents/sun-study-intents.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/agent/intents/scene-info-intents.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/modules/map-matching-service.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/agent/intents/map-matching-intents.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/agent/intents/traffic-intents.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/agent/intents/photogrammetry-intents.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/agent/intents/ar-intents.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/agent/intents/storefront-intents.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/modules/transit-service.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/agent/intents/transit-intents.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/agent/intents/blacksun-intents.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/agent/intents/earth-daemon-intents.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/blacksun/constants.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/blacksun/BlackSunBuilding.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/blacksun/CrowdRenderer.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/blacksun/RosterClient.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/blacksun/AccessGate.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/blacksun/Interior.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/blacksun/Pyre.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/blacksun/daemons/CoordinatorService.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/blacksun/daemons/BouncerDaemon.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/blacksun/daemons/GraveyardDaemon.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/blacksun/DaemonRegistry.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/scene/MetaverseScene.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/ui/GraphicsStartupRecovery.js","../../../../home/roko/Documents/Projects/Adjacent/noclip-unified/earth/refactor/scene/PlanetScene.js"],"sourcesContent":["/**\n * SceneOcclusion — one place to ask \"is rendered scene geometry between these\n * two world points?\" for things the depth buffer cannot hide (DOM overlays\n * pinned into the scene, such as theater iframes). PlanetScene registers the\n * photoreal probe; with none registered nothing is ever occluded.\n */\nlet probe = null;\nlet prepare = null;\n\n/** @param {{ isOccluded?: (from, to) => boolean, prepareFrame?: () => void } | null} next */\nexport function setSceneOcclusionProbe(next) {\n  probe = typeof next?.isOccluded === 'function' ? next.isOccluded : null;\n  prepare = typeof next?.prepareFrame === 'function' ? next.prepareFrame : null;\n}\n\nexport function hasSceneOcclusionProbe() { return !!probe; }\n\n/** Refresh any per-frame state the probe needs (matrices); cheap to repeat. */\nexport function prepareSceneOcclusion() {\n  try { prepare?.(); } catch { /* probe unavailable this frame */ }\n}\n\nexport function isSceneSegmentOccluded(fromWorld, toWorld) {\n  if (!probe) return false;\n  try { return probe(fromWorld, toWorld) === true; } catch { return false; }\n}\n","/**\n * EventBus\n *\n * Purpose:\n * - Minimal pub/sub utility for scene-wide events.\n *\n * API:\n * - on(eventName, handler)    — Subscribe to events\n * - off(eventName, handler)   — Unsubscribe\n * - once(eventName, handler)  — Single-fire subscription\n * - emit(eventName, payload)  — Broadcast event\n *\n * Wildcard support:\n * - on('config:*', handler)   — Matches all 'config:' prefixed events\n *\n * Relationships:\n * - Shared by all subsystems for decoupled notifications.\n */\nexport class EventBus {\n    constructor() {\n        this.listeners = new Map();\n        this._wildcards = new Map();\n    }\n\n    on(eventName, handler) {\n        if (typeof eventName !== 'string' || typeof handler !== 'function') return;\n        if (eventName.endsWith(':*') || eventName.endsWith('.*')) {\n            const prefix = eventName.slice(0, -1);\n            if (!this._wildcards.has(prefix)) {\n                this._wildcards.set(prefix, new Set());\n            }\n            this._wildcards.get(prefix).add(handler);\n            return;\n        }\n        if (!this.listeners.has(eventName)) {\n            this.listeners.set(eventName, new Set());\n        }\n        this.listeners.get(eventName).add(handler);\n    }\n\n    off(eventName, handler) {\n        if (typeof eventName !== 'string') return;\n        if (eventName.endsWith(':*') || eventName.endsWith('.*')) {\n            const prefix = eventName.slice(0, -1);\n            const set = this._wildcards.get(prefix);\n            if (set) {\n                set.delete(handler);\n                if (!set.size) this._wildcards.delete(prefix);\n            }\n            return;\n        }\n        const set = this.listeners.get(eventName);\n        if (set) {\n            set.delete(handler);\n            if (!set.size) this.listeners.delete(eventName);\n        }\n    }\n\n    once(eventName, handler) {\n        if (typeof handler !== 'function') return;\n        const wrapper = (payload) => {\n            this.off(eventName, wrapper);\n            handler(payload);\n        };\n        wrapper._original = handler;\n        this.on(eventName, wrapper);\n    }\n\n    emit(eventName, payload) {\n        // Exact match listeners\n        const set = this.listeners.get(eventName);\n        if (set) {\n            for (const handler of set) {\n                handler(payload);\n            }\n        }\n        // Wildcard listeners\n        if (this._wildcards.size > 0) {\n            for (const [prefix, handlers] of this._wildcards) {\n                if (eventName.startsWith(prefix)) {\n                    for (const handler of handlers) {\n                        handler(payload, eventName);\n                    }\n                }\n            }\n        }\n    }\n}\n","import { resolveBackendApiUrl } from '../shared/backend.js';\n\nexport const XR_EVENTS = new Set([\n  'native-enter', 'native-exit', 'phone-prompt', 'phone-exit', 'pending', 'unavailable',\n  'vr-blocked-ar', 'vr-request', 'vr-start', 'vr-end', 'ar-request', 'ar-start', 'ar-end',\n  'ar-magic-window', 'session-end', 'visibility-change', 'inputs-change',\n  'context-lost', 'context-restored', 'error-denied', 'error-unsupported',\n  'error-state', 'error-other',\n]);\nconst KEY = 'noclip:xr-diagnostics:v1';\nconst PREF = 'noclip:xr-diagnostics:enabled';\nconst finite = (n, max = 1e12) => Number.isFinite(n) && n >= 0 ? Math.min(max, Math.round(n * 100) / 100) : null;\nconst token = n => typeof n === 'string' && /^[a-zA-Z0-9_-]{1,40}$/.test(n) ? n : 'unknown';\nexport const XR_METRICS = ['frames', 'meanFrameMs', 'maxFrameMs', 'eyes', 'eyeWidth', 'eyeHeight',\n  'drawCalls', 'triangles', 'textures', 'geometries', 'programs', 'heapMB', 'exposure',\n  'toneMapping', 'controllers', 'hands', 'loadedModels', 'pendingTiles'];\nexport const XR_TILE_METRICS = ['visible', 'resident', 'preparing', 'visibleMaxDepth',\n  'dataBytes', 'maxBytes', 'minBytes', 'workingSetBytes', 'admissionFloorBytes', 'used',\n  'cacheItems', 'downloadRunning', 'downloadQueued', 'parseRunning', 'parseQueued',\n  'processRunning', 'processQueued', 'traversals', 'errorTarget', 'underfootError',\n  'underfootHalfWidth', 'modelAgeMs'];\nconst CPU_SECTIONS = Object.freeze({ frame: 'frame', onFrame: 'scene.onFrame', labels: 'labels.update',\n  interaction: 'xr.interaction', photoTiles: 'photo.tiles.update' });\nconst NATIVE_TIMINGS = ['nativeScene', 'nativeMask', 'nativeAerial', 'nativeAA', 'nativeBlit',\n  'nativeUI', 'nativeTotal', 'gpuMs', 'gpuAgeMs'];\nexport const XR_CPU_METRICS = [...Object.keys(CPU_SECTIONS), ...NATIVE_TIMINGS];\nconst nullableBoolean = value => typeof value === 'boolean' ? value : null;\nconst choice = (v, values, fallback = 'unknown') => values.includes(v) ? v : fallback;\n\n// Used again when reading local storage. Never forward arbitrary prior content.\nexport function cleanXRReport(value) {\n  return {\n    version: 1, run: token(value?.run), build: token(value?.build), at: finite(value?.at, 1e15),\n    browser: choice(value?.browser, ['quest', 'chromium', 'safari', 'firefox', 'other']),\n    mobileLayout: value?.mobileLayout === true,\n    nativeSupported: value?.nativeSupported === true,\n    mode: choice(value?.mode, ['immersive-vr', 'immersive-ar', 'none']),\n    visibility: choice(value?.visibility, ['visible', 'visible-blurred', 'hidden', 'none']),\n    owner: choice(value?.owner, ['xr', 'stereo', 'atmosphere-compositor', 'direct-basic', 'direct-atmosphere', 'direct-fallback']),\n    clouds: choice(value?.clouds, ['idle', 'pending', 'warming', 'ready', 'clear-ready', 'fallback', 'failed']),\n    phoneStereo: value?.phoneStereo === true, recovered: value?.recovered === true,\n    metrics: Object.fromEntries(XR_METRICS.map(k => [k, finite(value?.metrics?.[k])])),\n    ...(value?.cpu ? { cpu: Object.fromEntries(XR_CPU_METRICS.map(k => [k, finite(value.cpu[k])])) } : {}),\n    ...(value?.tiles ? { tiles: {\n      ...Object.fromEntries(XR_TILE_METRICS.map(k => [k, finite(value.tiles[k])])),\n      xrDemand: nullableBoolean(value.tiles.xrDemand),\n      bootFocus: nullableBoolean(value.tiles.bootFocus),\n      lruFull: nullableBoolean(value.tiles.lruFull),\n    } } : {}),\n    events: (Array.isArray(value?.events) ? value.events : []).slice(-16)\n      .filter(e => XR_EVENTS.has(e?.type)).map(e => ({ type: e.type, t: finite(e.t) })),\n  };\n}\n\nexport class XRDiagnostics {\n  constructor({ scene, host = window, doc = document, nav = navigator,\n    send = (...args) => fetch(...args), now = () => performance.now(), wall = () => Date.now(),\n    storage = null, schedule = true } = {}) {\n    this.scene = scene; this.host = host; this.doc = doc; this.nav = nav;\n    this.send = send; this.now = now; this.wall = wall;\n    this.schedule = schedule;\n    try { this.storage = storage || host.localStorage; } catch { this.storage = null; }\n    this.run = token(`${wall().toString(36)}-${Math.random().toString(36).slice(2, 10)}`);\n    this.events = []; this.session = null; this.mode = 'none'; this.lastFrame = null;\n    this.frames = 0; this.frameIntervals = 0; this.totalMs = 0; this.maxMs = 0;\n    this.nextSend = 0; this.failures = 0; this.inflight = null; this.disposed = false;\n    this.lastActivity = now(); this.active = false; this.optOut = false;\n    this.lastModelCount = null; this.lastModelAt = null;\n    this.bindings = []; this.sessionBindings = [];\n    try {\n      const query = new URLSearchParams(host.location?.search || '').get('xrDebug');\n      if (query === '0' || query === '1') this.storage?.setItem(PREF, query);\n      this.optOut = query === '0' || (query !== '1' && this.storage?.getItem(PREF) === '0');\n      this.active = query === '1' && !this.optOut;\n      if (this.optOut) this.storage?.removeItem(KEY);\n      const raw = this.storage?.getItem(KEY);\n      if (raw && raw.length <= 6144) {\n        const saved = cleanXRReport(JSON.parse(raw));\n        if (saved.at > wall() - 30 * 60_000 && saved.at <= wall()) this.recovered = { ...saved, recovered: true };\n      }\n    } catch { /* private browsing storage failure cannot block XR */ }\n    this.on(host, 'webglcontextlost', () => this.record('context-lost'), true);\n    this.on(host, 'webglcontextrestored', () => this.record('context-restored'), true);\n    this.on(host, 'pagehide', () => { this.persist(); });\n    this.timer = schedule ? setInterval(() => { void this.tick(); }, 10_000) : null;\n  }\n\n  on(target, event, fn, capture = false, list = this.bindings) {\n    target?.addEventListener?.(event, fn, capture); list.push([target, event, fn, capture]);\n  }\n  unbind(list) { for (const [target, event, fn, capture] of list) target?.removeEventListener?.(event, fn, capture); list.length = 0; }\n  setEnabled(enabled) {\n    this.optOut = !enabled; this.active = !!enabled; this.lastActivity = this.now();\n    try { this.storage?.setItem(PREF, enabled ? '1' : '0'); if (!enabled) this.storage?.removeItem(KEY); } catch {}\n    if (!enabled) { this.recovered = null; this.inflight?.abort(); }\n  }\n  record(type) {\n    if (this.disposed || this.optOut || !XR_EVENTS.has(type)) return;\n    this.active = true; this.lastActivity = this.now();\n    const t = Math.round(this.now());\n    if (this.events.at(-1)?.type === type && t - this.events.at(-1).t < 1000) return;\n    this.events.push({ type, t }); if (this.events.length > 16) this.events.shift();\n    // No synchronous storage writes on the rendering hot path.\n  }\n  error(error) {\n    this.record(({ NotAllowedError: 'error-denied', NotSupportedError: 'error-unsupported',\n      InvalidStateError: 'error-state' })[error?.name] || 'error-other');\n  }\n  bindSession(session, mode) {\n    if (this.session === session) return;\n    this.unbind(this.sessionBindings);\n    this.session = session; this.mode = mode; this.lastFrame = null;\n    this.record('visibility-change');\n    this.on(session, 'visibilitychange', () => this.record('visibility-change'), false, this.sessionBindings);\n    this.on(session, 'inputsourceschange', () => this.record('inputs-change'), false, this.sessionBindings);\n    this.on(session, 'end', () => {\n      if (this.session !== session) return;\n      this.record('session-end'); this.session = null; this.mode = 'none'; this.lastFrame = null;\n      this.unbind(this.sessionBindings);\n    }, false, this.sessionBindings);\n    // Start reporting at entry, even if immersive presentation suspends the\n    // window's interval before its next heartbeat.\n    this.nextSend = Math.min(this.nextSend, this.now());\n  }\n  frame(time) {\n    if (this.optOut || this.disposed || !this.session) return;\n    if (this.lastFrame !== null && time >= this.lastFrame) {\n      const dt = time - this.lastFrame;\n      this.totalMs += dt; this.maxMs = Math.max(this.maxMs, dt); this.frameIntervals++;\n    }\n    this.frames++; this.lastFrame = time;\n    // Use the existing native frame clock; no second RAF or per-frame storage.\n    // tick's shared deadline and in-flight slot also gate the window interval.\n    if (this.schedule && this.now() >= this.nextSend && !this.inflight) void this.tick(false);\n  }\n  snapshot() {\n    const scene = this.scene, renderer = scene?._renderer, xr = renderer?.xr;\n    const ua = this.nav?.userAgent || '';\n    const eyes = xr?.isPresenting ? xr.getCamera?.()?.cameras : null;\n    const inputs = this.session?.inputSources ? Array.from(this.session.inputSources) : [];\n    const loader = scene?._photoTileLoader, tiles = loader?._tiles, lru = tiles?.lruCache;\n    const telemetry = loader?.getTileTelemetry?.();\n    const sections = scene?._perf?.enabled === true ? scene._perf.sections : null;\n    const nativeTiming = xr?.isPresenting === true\n      ? scene?._sceneInitializer?.atmosphereClouds?._nativeXRRenderer?.getTimingStats?.() : null;\n    const nativeClouds = xr?.isPresenting === true ? scene?._sceneInitializer?.atmosphereClouds?._nativeXRClouds : null;\n    const modelCount = loader?._loadedModelCount;\n    const time = this.now();\n    if (Number.isFinite(modelCount) && modelCount !== this.lastModelCount) {\n      this.lastModelCount = modelCount; this.lastModelAt = time;\n    }\n    return cleanXRReport({\n      run: this.run, build: this.host.__noclipCrashTrace?.currentBuild?.(), at: this.wall(),\n      browser: /OculusBrowser|Quest/i.test(ua) ? 'quest' : /Firefox/i.test(ua) ? 'firefox'\n        : /Chrome|Chromium/i.test(ua) ? 'chromium' : /Safari/i.test(ua) ? 'safari' : 'other',\n      mobileLayout: scene?._isMobile, nativeSupported: scene?._vrManager?.isAvailable?.(),\n      mode: this.mode, visibility: this.session?.visibilityState || 'none',\n      owner: scene?._sceneInitializer?._lastRenderOwner,\n      clouds: nativeClouds ? (!nativeClouds.requested ? 'idle' : nativeClouds.state === 'cold' ? 'pending' : nativeClouds.state)\n        : scene?._sceneInitializer?.atmosphereClouds?._cloudWarmupState,\n      phoneStereo: scene?._mobileStereoRenderer?.isEnabled?.(), events: this.events,\n      metrics: {\n        frames: this.frames, meanFrameMs: this.frameIntervals ? this.totalMs / this.frameIntervals : null,\n        maxFrameMs: this.frameIntervals ? this.maxMs : null, eyes: eyes?.length,\n        eyeWidth: eyes?.[0]?.viewport?.z, eyeHeight: eyes?.[0]?.viewport?.w,\n        drawCalls: renderer?.info?.render?.calls, triangles: renderer?.info?.render?.triangles,\n        textures: renderer?.info?.memory?.textures, geometries: renderer?.info?.memory?.geometries,\n        programs: renderer?.info?.programs?.length, heapMB: this.host.performance?.memory?.usedJSHeapSize / 1048576,\n        exposure: renderer?.toneMappingExposure, toneMapping: renderer?.toneMapping,\n        controllers: inputs.filter(i => i.gamepad).length, hands: inputs.filter(i => i.hand).length,\n        loadedModels: scene?._photoTileLoader?._loadedModelCount,\n        pendingTiles: scene?._photoTileLoader?._getPendingTileCount?.(),\n      },\n      cpu: {\n        ...Object.fromEntries(Object.entries(CPU_SECTIONS).map(([key, section]) =>\n          [key, sections?.[section]?.samples > 0 ? sections[section].last : null])),\n        ...Object.fromEntries(NATIVE_TIMINGS.map(key => [key, nativeTiming?.[key]])),\n      },\n      tiles: {\n        visible: tiles?.visibleTiles?.size, resident: tiles?.stats?.loaded,\n        preparing: telemetry?.preparingModelCount, visibleMaxDepth: telemetry?.visibleTileMaxDepth,\n        dataBytes: lru?.cachedBytes, maxBytes: lru?.maxBytesSize, minBytes: lru?.minBytesSize,\n        workingSetBytes: telemetry?.cacheWorkingSetBytes,\n        admissionFloorBytes: telemetry?.cacheAdmissionFloorBytes,\n        used: lru?.usedSet?.size, cacheItems: lru?.itemSet?.size,\n        downloadRunning: tiles?.downloadQueue?.currJobs, downloadQueued: tiles?.downloadQueue?.items?.length,\n        parseRunning: tiles?.parseQueue?.currJobs, parseQueued: tiles?.parseQueue?.items?.length,\n        processRunning: tiles?.processNodeQueue?.currJobs, processQueued: tiles?.processNodeQueue?.items?.length,\n        traversals: loader?._tileUpdateTraversalCount, errorTarget: tiles?.errorTarget,\n        underfootError: loader?._bootUnderfootRegion?.errorTarget,\n        underfootHalfWidth: telemetry?.underfootHalfWidthM,\n        modelAgeMs: this.lastModelAt === null ? null : time - this.lastModelAt,\n        xrDemand: loader?._xrSurfaceDemandActive, bootFocus: loader?._bootUnderfootFocusActive,\n        lruFull: lru?.isFull?.(),\n      },\n    });\n  }\n  persist() {\n    if (!this.active || this.optOut || this.disposed) return;\n    try { this.storage?.setItem(KEY, JSON.stringify(this.snapshot())); } catch {}\n  }\n  async tick(persist = true) {\n    if (this.disposed || this.optOut || this.inflight) return;\n    const supported = this.scene?._vrManager?.isAvailable?.();\n    if (!this.active && (supported || this.recovered)) { this.active = true; this.lastActivity = this.now(); }\n    if (!this.active || (!this.session && this.now() - this.lastActivity > 60_000)) return;\n    if (this.now() < this.nextSend) return;\n    if (persist) this.persist();\n    this.nextSend = this.now() + 10_000;\n    const report = this.recovered || this.snapshot();\n    const controller = new AbortController(); this.inflight = controller;\n    const timeout = setTimeout(() => controller.abort(), 5000);\n    try {\n      const response = await this.send(resolveBackendApiUrl('/diagnostics/xr'), {\n        method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(report),\n        credentials: 'omit', referrerPolicy: 'no-referrer', redirect: 'error', signal: controller.signal,\n      });\n      if (!response.ok) {\n        const retry = Number(response.headers?.get?.('retry-after'));\n        if (Number.isFinite(retry) && retry > 0) this.nextSend = Math.max(this.nextSend, this.now() + Math.min(retry, 3600) * 1000);\n        throw new Error('diagnostics unavailable');\n      }\n      this.failures = 0; if (this.recovered === report) this.recovered = null;\n      this.frames = 0; this.frameIntervals = 0; this.totalMs = 0; this.maxMs = 0;\n    } catch {\n      this.failures = Math.min(this.failures + 1, 4);\n      this.nextSend = Math.max(this.nextSend, this.now() + Math.min(120_000, 10_000 * 2 ** this.failures));\n    } finally { clearTimeout(timeout); this.inflight = null; }\n  }\n  dispose() {\n    this.persist(); this.disposed = true; if (this.timer !== null) clearInterval(this.timer);\n    this.inflight?.abort(); this.unbind(this.bindings); this.unbind(this.sessionBindings);\n    this.scene = null; this.session = null;\n  }\n}\n","const CAPACITY = 32768, WINDOW_MS = 10000, MAX_WINDOWS = 18;\nconst FRAME_BUDGET_MS = 1000 / 30, MAX_REPORT_BYTES = 4096;\nconst QUALITY_KEYS = ['eyeWidth', 'eyeHeight', 'eyeWidthRight', 'eyeHeightRight',\n  'eyeCount', 'errorTarget', 'underfootError', 'anisotropy', 'cloudsRequested', 'cloudsStereo'];\nconst CPU_FIELDS = [\n  ['frameMeanMs', 'frame'], ['onFrameMeanMs', 'onFrame'], ['photoTilesMeanMs', 'photoTiles'],\n  ['nativeMeanMs', 'nativeTotal'], ['nativeSceneMeanMs', 'nativeScene'],\n  ['nativeMaskMeanMs', 'nativeMask'], ['nativeAerialMeanMs', 'nativeAerial'],\n  ['nativeAAMeanMs', 'nativeAA'], ['nativeUIMeanMs', 'nativeUI'], ['gpuMeanMs', 'gpuMs'],\n  ['controlsMeanMs', 'controls'], ['rigMeanMs', 'rig'], ['groundMeanMs', 'ground'],\n  ['placementMeanMs', 'placement'], ['onFrameOtherMeanMs', 'onFrameOther'],\n];\nconst valid = n => Number.isFinite(n) && n >= 0 && n <= 1e12;\nconst rounded = n => valid(n) ? Math.round(n * 100) / 100 : null;\nconst average = stat => stat.count ? rounded(stat.sum / stat.count) : null;\nconst stat = () => ({ sum: 0, count: 0 });\nconst add = (target, value) => { if (valid(value)) { target.sum += value; target.count++; } };\nconst percentile = (sorted, p) => sorted.length\n  ? rounded(sorted[Math.max(0, Math.ceil(sorted.length * p) - 1)]) : null;\nconst qualityValue = (quality, key) => key === 'cloudsRequested' || key === 'cloudsStereo'\n  ? quality?.[key] === true : valid(quality?.[key]) ? quality[key] : null;\n\n/** Bounded CPU-submission profile, driven only by the existing native frame owner.\n * No timers, RAF, GPU waits, DOM, storage, or raw location/input data. This cannot\n * observe whether the operating system presented or reprojected a submitted eye.\n */\nexport class XRProfileSampler {\n  constructor() {\n    this._intervals = new Float32Array(CAPACITY);\n    this._intervalWindows = new Uint8Array(CAPACITY);\n    this._cpuFrames = new Float32Array(CAPACITY);\n    this.active = false;\n    this._summary = null;\n  }\n\n  start({ seconds = 30, now, quality = {} } = {}) {\n    if (!valid(now)) throw new TypeError('XR profile start requires a monotonic timestamp');\n    this.startedAt = this.lastObservedAt = now;\n    this.requestedMs = Math.min(180, Math.max(1, Number.isFinite(seconds) ? seconds : 30)) * 1000;\n    this._quality = Object.fromEntries(QUALITY_KEYS.map(key => [key, qualityValue(quality, key)]));\n    this._cpu = Object.fromEntries(CPU_FIELDS.map(([, key]) => [key, stat()]));\n    this._windows = Array.from({ length: MAX_WINDOWS }, () => ({ frames: 0, intervals: stat(),\n      intervalCount: 0, cpu: stat(), native: stat(), photo: stat() }));\n    this.frames = this.slowFrames = this.renderFailures = this.contextLosses = this.visibilityInterruptions = 0;\n    this._intervalCount = this._cpuCount = this._intervalTotal = this._intervalSum = this._intervalMax = 0;\n    this._lastSubmissionAt = null;\n    this._lastVisible = null; this._contextLost = false;\n    this.qualityChanged = this.overflowed = false;\n    this._summary = null; this.active = true;\n    return this.status(now);\n  }\n\n  sample({ now, submitted = false, visible = false, quality, cpu = {},\n    contextLost = false, renderFailure = false } = {}) {\n    if (!this.active || !valid(now) || now < this.lastObservedAt) return this.status(this.lastObservedAt);\n    this.lastObservedAt = now;\n    if (quality) for (const key of QUALITY_KEYS) {\n      if (qualityValue(quality, key) !== this._quality[key]) this.qualityChanged = true;\n    }\n    if (visible !== true && this._lastVisible !== false) this.visibilityInterruptions++;\n    this._lastVisible = visible === true;\n    if (contextLost === true && !this._contextLost) this.contextLosses++;\n    this._contextLost = contextLost === true;\n    if (renderFailure === true) this.renderFailures++;\n    if (visible !== true) {\n      // A hidden period invalidates this capture. Never describe that pause as\n      // an interval between two visible submissions; full elapsed FPS retains it.\n      this._lastSubmissionAt = null;\n      return this.status(now);\n    }\n\n    const elapsed = now - this.startedAt;\n    const index = Math.min(MAX_WINDOWS - 1, Math.max(0, Math.ceil(elapsed / WINDOW_MS) - 1));\n    const window = this._windows[index];\n    if (submitted === true && contextLost !== true && renderFailure !== true\n      && this._lastSubmissionAt === now) return this.status(now);\n    if ((submitted === true || renderFailure === true) && contextLost !== true && elapsed > 0) {\n      const timings = cpu || {};\n      for (const [, key] of CPU_FIELDS) add(this._cpu[key], timings[key]);\n      add(window.cpu, timings.frame); add(window.native, timings.nativeTotal); add(window.photo, timings.photoTiles);\n      if (valid(timings.frame)) {\n        if (this._cpuCount < CAPACITY) this._cpuFrames[this._cpuCount++] = timings.frame;\n        else this.overflowed = true;\n      }\n    }\n    if (submitted !== true || contextLost === true || renderFailure === true) return this.status(now);\n    // The initial zero-time tick is a baseline, not a frame earned in no time.\n    // Likewise a repeated completion timestamp cannot inflate frame counts.\n    if (elapsed > 0) { this.frames++; window.frames++; }\n    if (this._lastSubmissionAt !== null && now > this._lastSubmissionAt) {\n      const interval = now - this._lastSubmissionAt;\n      this._intervalSum += interval; this._intervalTotal++;\n      this._intervalMax = Math.max(this._intervalMax, interval);\n      if (interval > FRAME_BUDGET_MS) this.slowFrames++;\n      add(window.intervals, interval);\n      if (this._intervalCount < CAPACITY) {\n        this._intervals[this._intervalCount] = interval;\n        this._intervalWindows[this._intervalCount++] = index;\n        window.intervalCount++;\n      } else this.overflowed = true;\n    }\n    this._lastSubmissionAt = now;\n    return this.status(now);\n  }\n\n  status(now) {\n    const elapsedMs = this._summary?.durationMs ?? (this.startedAt === undefined ? 0\n      : Math.max(0, (valid(now) ? Math.max(now, this.lastObservedAt) : this.lastObservedAt) - this.startedAt));\n    return { active: this.active, ready: this.startedAt !== undefined && elapsedMs >= this.requestedMs,\n      elapsedMs: rounded(elapsedMs), remainingMs: rounded(Math.max(0, (this.requestedMs || 0) - elapsedMs)),\n      frames: this.frames || 0 };\n  }\n\n  finish(now) {\n    if (this._summary) return this._summary;\n    if (!this.active) return null;\n    const durationMs = this.status(now).elapsedMs;\n    this.active = false;\n    const sorted = this._intervals.slice(0, this._intervalCount).sort();\n    const sortedCPU = this._cpuFrames.slice(0, this._cpuCount).sort();\n    const buckets = this._windows.map(window => new Float32Array(window.intervalCount));\n    const positions = new Uint32Array(MAX_WINDOWS);\n    for (let i = 0; i < this._intervalCount; i++) {\n      const window = this._intervalWindows[i]; buckets[window][positions[window]++] = this._intervals[i];\n    }\n    const count = Math.min(MAX_WINDOWS, Math.max(1, Math.ceil(durationMs / WINDOW_MS)));\n    const windows = [];\n    let minWindowFps = null;\n    for (let i = 0; i < count; i++) {\n      const window = this._windows[i];\n      // If completion arrives after a long visible stall, the final bounded\n      // bucket absorbs that tail instead of silently dropping elapsed time.\n      const duration = i === count - 1 ? Math.max(0, durationMs - i * WINDOW_MS) : WINDOW_MS;\n      const fps = duration > 0 ? window.frames * 1000 / duration : null;\n      if (duration >= 1000) minWindowFps = Math.min(minWindowFps ?? Infinity, fps);\n      windows.push({ durationMs: rounded(duration), frames: window.frames,\n        meanFrameMs: average(window.intervals), p95FrameMs: percentile(buckets[i].sort(), 0.95),\n        fps: rounded(fps), cpuMeanMs: average(window.cpu), nativeMeanMs: average(window.native),\n        photoTilesMeanMs: average(window.photo) });\n    }\n    const summary = {\n      durationMs, frames: this.frames, meanFrameMs: this._intervalTotal ? rounded(this._intervalSum / this._intervalTotal) : null,\n      p50FrameMs: percentile(sorted, 0.5), p95FrameMs: percentile(sorted, 0.95),\n      p99FrameMs: percentile(sorted, 0.99), maxFrameMs: this._intervalTotal ? rounded(this._intervalMax) : null,\n      fps: durationMs > 0 ? rounded(this.frames * 1000 / durationMs) : null,\n      minWindowFps: rounded(minWindowFps), slowFrames: this.slowFrames,\n      visibilityInterruptions: this.visibilityInterruptions, renderFailures: this.renderFailures,\n      contextLosses: this.contextLosses, eyeWidth: this._quality.eyeWidth, eyeHeight: this._quality.eyeHeight,\n      errorTarget: this._quality.errorTarget, underfootError: this._quality.underfootError,\n      qualityChanged: this.qualityChanged, cloudsRequested: this._quality.cloudsRequested,\n      cloudsStereo: this._quality.cloudsStereo, overflowed: this.overflowed,\n      windows, cpu: { ...Object.fromEntries(CPU_FIELDS.map(([name, key]) => [name, average(this._cpu[key])])),\n        frameP95Ms: percentile(sortedCPU, 0.95) },\n    };\n    // Pathological metric magnitudes must not overflow the strict envelope.\n    // Dropped window detail explicitly invalidates qualification; full-duration\n    // global counts, min-window rate and CPU totals remain represented.\n    while (JSON.stringify(summary).length > MAX_REPORT_BYTES && summary.windows.length) {\n      summary.overflowed = true; summary.windows.pop();\n    }\n    this._summary = summary;\n    return summary;\n  }\n}\n","import { XRProfileSampler } from './XRProfileSampler.js';\nimport { acquireNativeXRComponentProfiler } from './NativeXRComponentProfiler.js';\n\nconst KEY = 'noclip:xr-harness:v1';\nconst UUID = /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/i;\nconst RELEASE = /^[a-f0-9]{12}$/;\nconst CAPABILITIES = ['reload', 'clouds', 'profile', 'step', 'stop'];\nconst record = value => !!value && typeof value === 'object' && !Array.isArray(value);\nconst keys = (value, allowed) => record(value) && Object.keys(value).every(key => allowed.includes(key));\nconst number = (value, min, max) => Number.isFinite(value) && value >= min && value <= max;\n\nexport function parseXRHarnessCommand(value, wall = Date.now()) {\n  if (!keys(value, ['id', 'type', 'args', 'expiresAt']) || !UUID.test(value.id)\n    || !CAPABILITIES.includes(value.type) || !record(value.args)) return null;\n  const expiresAt = typeof value.expiresAt === 'string' ? Date.parse(value.expiresAt) : value.expiresAt;\n  if (!number(expiresAt, wall + 1, wall + 60_000)) return null;\n  const a = value.args;\n  if (value.type === 'reload' && (!keys(a, ['release', 'mode']) || !RELEASE.test(a.release)\n    || (a.mode !== undefined && !['document', 'native-runtime'].includes(a.mode)))) return null;\n  if (value.type === 'clouds' && (!keys(a, ['enabled']) || typeof a.enabled !== 'boolean')) return null;\n  if (value.type === 'profile' && (!keys(a, ['seconds', 'scenario']) || !number(a.seconds, 10, 180) || !Number.isInteger(a.seconds)\n    || (a.scenario !== undefined && !['stationary', 'walk-turn'].includes(a.scenario)))) return null;\n  if (value.type === 'step' && (!keys(a, ['forwardMeters', 'rightMeters', 'yawDegrees', 'durationMs'])\n    || !number(a.forwardMeters ?? 0, -10, 10) || !number(a.rightMeters ?? 0, -10, 10)\n    || Math.hypot(a.forwardMeters ?? 0, a.rightMeters ?? 0) > 10\n    || !number(a.yawDegrees ?? 0, -45, 45) || !number(a.durationMs, 100, 10_000) || !Number.isInteger(a.durationMs))) return null;\n  if (value.type === 'stop' && !keys(a, [])) return null;\n  return { id: value.id, type: value.type, args: { ...a }, expiresAt };\n}\n\n/** Typed host-operator control, carried only by the authenticated private stream. */\nexport class XRRemoteHarness {\n  constructor({ scene, host = globalThis, doc = globalThis.document, now = () => performance.now(),\n    wall = () => Date.now(), flush = async () => false, storage = null,\n    fetch = (...args) => globalThis.fetch(...args), sampler = new XRProfileSampler(),\n    loadRuntime = url => import(/* @vite-ignore */ url) } = {}) {\n    this.scene = scene; this.host = host; this.doc = doc; this.now = now; this.wall = wall;\n    this.flush = flush; this.fetch = fetch; this.sampler = sampler; this.loadRuntime = loadRuntime;\n    this.operationEpoch = 0;\n    const nativeBuild=scene?._sceneInitializer?.atmosphereClouds?._nativeXRRenderer?.runtimeBuild;\n    this.runtimeBuild = RELEASE.test(nativeBuild || '') ? nativeBuild : this.build();\n    this.active = null; this.ack = null; this.recent = []; this.traces = []; this.disposed = false;\n    this.nextPoll = 0; this.lastMotion = null; this.priorClouds = null;\n    try {\n      this.storage = storage || host.sessionStorage;\n      const raw = this.storage.getItem(KEY), saved = raw && raw.length <= 8192 ? JSON.parse(raw) : null;\n      this.id = UUID.test(saved?.id) ? saved.id : host.crypto.randomUUID();\n      this.recent = Array.isArray(saved?.recent) ? saved.recent.filter(id => UUID.test(id)).slice(-24) : [];\n      if (saved?.reload && UUID.test(saved.reload.id)) {\n        this.ack = { id: saved.reload.id, status: 'complete', code: saved.reload.wasXR ? 'gesture-required' : 'ok' };\n        if (this.build() !== saved.reload.release) this.ack = { id: saved.reload.id, status: 'failed', code: 'release-mismatch' };\n        this.recent.push(saved.reload.id);\n      }\n      this._persist();\n    } catch { this.id = null; }\n    this.onVisibility = () => this._visibility();\n    this.onContextLost = () => { if (this.active?.type === 'profile') this._finish('interrupted', true); };\n    this.doc?.addEventListener?.('visibilitychange', this.onVisibility);\n    this.scene?._renderer?.domElement?.addEventListener?.('webglcontextlost', this.onContextLost);\n  }\n\n  build() { return this.host.__noclipCrashTrace?.currentBuild?.() || 'unknown'; }\n  get enabled() { return !!this.id && !this.disposed; }\n  envelope() {\n    if (!this.enabled) return null;\n    return { version: 1, id: this.id, run: this.host.__noclipXRDiagnostics?.run || 'unknown', runtimeBuild: this.runtimeBuild,\n      capabilities: CAPABILITIES, ...(this.ack ? { ack: this.ack } : {}) };\n  }\n  _persist(reload = null) {\n    this.storage.setItem(KEY, JSON.stringify({ id: this.id, recent: this.recent.slice(-24), ...(reload ? { reload } : {}) }));\n  }\n  _ack(command, status, code, summary) {\n    this.ack = { id: command.id, status, code, ...(summary ? { summary } : {}) };\n    if (status !== 'running') {\n      if (!this.recent.includes(command.id)) this.recent.push(command.id);\n      this.recent = this.recent.slice(-24);\n      try { this._persist(); } catch { /* no automatic retry/reload */ }\n    }\n    this.nextPoll = 0;\n  }\n\n  receive(value) {\n    if (!this.enabled || !value?.harness?.command) return;\n    const command = parseXRHarnessCommand(value.harness.command, this.wall());\n    if (!command || this.recent.includes(command.id) || this.active?.id === command.id) return;\n    if (this.active && command.type !== 'stop') return;\n    // Run after the response's in-flight slot has settled. A reload ack may\n    // itself flush; awaiting that inside its own response would deadlock.\n    this.host.setTimeout(() => { if (!this.disposed) void this._execute(command); }, 0);\n  }\n\n  async _execute(command) {\n    if (!this.enabled || this.recent.includes(command.id)) return;\n    if (this.active && command.type !== 'stop') return;\n    if (this.wall() >= command.expiresAt) { this._ack(command, 'failed', 'expired'); return; }\n    try {\n      if (command.type === 'stop') {\n        this.operationEpoch++; this.reloadAbort?.abort();\n        this._finish('stopped'); this._restoreClouds(); this._ack(command, 'complete', 'stopped'); return;\n      }\n      if (command.type === 'reload') { await this._reload(command); return; }\n      if (command.type === 'clouds') {\n        const settings = this.scene?._sceneSettings;\n        if (!settings?.updateScene) { this._ack(command, 'failed', 'unavailable'); return; }\n        if (this.priorClouds === null) this.priorClouds = this._quality().cloudsRequested;\n        const result = settings.updateScene({ atmosphere: { clouds: { enabled: command.args.enabled } } }, { persist: false });\n        this._ack(command, result?.applied === false ? 'failed' : 'complete', result?.applied === false ? 'failed' : 'ok'); return;\n      }\n      if (!this.scene?._renderer?.xr?.isPresenting) { this._ack(command, 'failed', 'not-immersive'); return; }\n      if (!this._visible()) { this._ack(command, 'failed', 'not-visible'); return; }\n      this.active = { ...command, started: this.now(), progress: 0 };\n      this.lastMotion = this.now();\n      if (command.type === 'profile') {\n        this.lastGPUResult = null;\n        this.sampler.start({ seconds: command.args.seconds, now: this.now(), quality: this._quality() });\n        // A capture must not require replacing/compiling the native renderer.\n        // This lease observes only the exact receiver and existing frame clock.\n        if (this.scene?._browserPerformanceTelemetry?.harness === this) {\n          try { this.componentLease = acquireNativeXRComponentProfiler(this.scene, { now: this.now }); }\n          catch { /* unsupported optional probes do not prevent the core capture */ }\n        }\n        this._installTraces();\n        this.observedSession = this.scene?._renderer?.xr?.getSession?.();\n        this.observedSession?.addEventListener?.('visibilitychange', this.onVisibility);\n      }\n      this._ack(command, 'running', 'ok');\n    } catch { this._finish('failed'); this._ack(command, 'failed', 'failed'); }\n  }\n\n  async _reload(command) {\n    const epoch = ++this.operationEpoch;\n    const abort = new AbortController(), timeout = this.host.setTimeout(() => abort.abort(), 15000);\n    let onAbort;\n    const interrupted = new Promise((_, reject) => {\n      onAbort = () => reject(Error('reload-interrupted'));\n      abort.signal.addEventListener('abort', onAbort, { once: true });\n    });\n    const bounded = work => Promise.race([work, interrupted]);\n    this.reloadAbort = abort; this.active = command; this._ack(command, 'running', 'reloading');\n    try {\n      const url = new URL('/asset-release.json', this.host.location.href);\n      const response = await bounded(this.fetch(url.href, { cache: 'no-store', credentials: 'omit', redirect: 'error', signal: abort.signal }));\n      if (!response.ok) throw Error('unavailable');\n      const text = await bounded(response.text());\n      if (this.disposed || epoch !== this.operationEpoch) return;\n      const manifest = text.length <= 131072 ? JSON.parse(text) : null;\n      if (manifest?.release !== command.args.release) {\n        this.active = null;\n        this._ack(command, 'failed', 'release-mismatch'); return;\n      }\n      if (this.disposed || epoch !== this.operationEpoch) return;\n      if (command.args.mode === 'native-runtime') {\n        if (!this.scene?._renderer?.xr?.isPresenting) { this.active = null; this._ack(command, 'failed', 'not-immersive'); return; }\n        const pattern = new RegExp(`^assets/${command.args.release}/xr-runtime-[a-zA-Z0-9_-]+\\\\.js$`);\n        const entries = Array.isArray(manifest.assets) ? manifest.assets.filter(path => typeof path === 'string' && pattern.test(path)) : [];\n        if (entries.length !== 1) { this.active = null; this._ack(command, 'failed', 'unavailable'); return; }\n        // Imports cannot be cancelled. Bound our continuation and fence the\n        // transaction; a late module may finish downloading but cannot install.\n        const module = await bounded(this.loadRuntime(new URL('/' + entries[0] + '?nclp=' + command.args.release, this.host.location.href).href));\n        if (this.disposed || epoch !== this.operationEpoch) return;\n        if (module.XR_RUNTIME_ABI !== 1 || typeof module.installXRRuntime !== 'function') throw Error('unsupported');\n        const runtimeTransaction = module.installXRRuntime(this.scene);\n        if (runtimeTransaction?.abi !== 1 || typeof runtimeTransaction.commit !== 'function'\n          || typeof runtimeTransaction.rollback !== 'function') throw Error('unsupported');\n        this.active = { ...command, started: this.now(), hotFrames: 0,\n          runtimeTransaction, previousRuntimeBuild: this.runtimeBuild,\n          expectedEyes: this._quality(),\n          installedRenderer: this.scene?._sceneInitializer?.atmosphereClouds?._nativeXRRenderer };\n        return;\n      }\n      const wasXR = this.scene?._renderer?.xr?.isPresenting === true;\n      try { this._persist({ id: command.id, release: command.args.release, wasXR }); }\n      catch { this.active = null; this._ack(command, 'failed', 'storage-unavailable'); return; }\n      await bounded(this.flush());\n      if (this.disposed || epoch !== this.operationEpoch) return;\n      // Keep the original scene query/location and force a new navigation.\n      // Only the published same-origin entry is eligible, never an operator URL.\n      const next = new URL(this.host.location.href);\n      next.searchParams.set('xrHarnessRelease', command.args.release);\n      next.searchParams.set('xrHarnessReload', command.id);\n      this.host.location.replace(next.href);\n    } catch { if (epoch === this.operationEpoch && !this.disposed) { this._ack(command, 'failed', 'unavailable'); this.active = null; } }\n    finally {\n      this.host.clearTimeout(timeout); abort.signal.removeEventListener('abort', onAbort);\n      if (this.reloadAbort === abort) this.reloadAbort = null;\n    }\n  }\n\n  _visible() {\n    return this.doc?.visibilityState !== 'hidden'\n      && this.scene?._renderer?.xr?.getSession?.()?.visibilityState === 'visible';\n  }\n  _quality() {\n    const s = this.scene, xr = s?._renderer?.xr, eyes = xr?.getCamera?.()?.cameras || [];\n    const atmosphere = s?._sceneInitializer?.atmosphereClouds, loader = s?._photoTileLoader;\n    const clouds = s?._sceneSettings?.get?.()?.scene?.atmosphere?.clouds?.enabled;\n    return { eyeCount: eyes.length, eyeWidth: eyes[0]?.viewport?.z ?? null, eyeHeight: eyes[0]?.viewport?.w ?? null,\n      eyeWidthRight: eyes[1]?.viewport?.z ?? null, eyeHeightRight: eyes[1]?.viewport?.w ?? null,\n      errorTarget: loader?._tiles?.errorTarget ?? null, underfootError: loader?._bootUnderfootRegion?.errorTarget ?? null,\n      anisotropy: Math.min(s?._renderer?.capabilities?.getMaxAnisotropy?.() ?? 0, s?._isMobile ? 4 : 8) || null,\n      cloudsRequested: typeof clouds === 'boolean' ? clouds : atmosphere?._cloudsEnabled === true,\n      cloudsStereo: atmosphere?._nativeXRRenderer?.cloudsStereoReady === true };\n  }\n\n  beforeFrame(now) {\n    const task = this.active;\n    if (!task || !['step', 'profile'].includes(task.type)) return;\n    if (!this.scene?._renderer?.xr?.isPresenting || !this._visible()) return;\n    const controller = this.scene?._surfaceController;\n    const input = controller?._xrLocomotionInput;\n    if (input && [input.forward, input.right, input.turn, input.vertical].some(v => Math.abs(v || 0) > .05)) {\n      this._finish('stopped'); return;\n    }\n    const elapsed = now - task.started;\n    const dt = Math.max(0, Math.min(50, now - (this.lastMotion ?? now))); this.lastMotion = now;\n    if (task.type === 'step') {\n      const fraction = Math.min(dt / task.args.durationMs, Math.max(0, 1 - task.progress));\n      if (elapsed <= task.args.durationMs) {\n        this._move((task.args.forwardMeters || 0) * fraction, (task.args.rightMeters || 0) * fraction,\n          (task.args.yawDegrees || 0) * fraction); task.progress += fraction;\n      } else this._finish(task.progress >= .98 ? 'ok' : 'interrupted');\n    } else if (task.args.scenario === 'walk-turn') {\n      if (elapsed >= 5000 && elapsed < 9000) this._move(2 * dt / 4000, 0, 0);\n      if (elapsed >= 10000 && elapsed < 14000) this._move(-2 * dt / 4000, 0, 0);\n      if (elapsed >= 15000 && elapsed < 19000) this._move(0, 0, 30 * dt / 4000);\n      if (elapsed >= 20000 && elapsed < 24000) this._move(0, 0, -30 * dt / 4000);\n    }\n  }\n  _move(forwardMeters, rightMeters, yawDegrees) {\n    const controller = this.scene?._surfaceController;\n    if (!controller || controller.cameraMode !== 'surface') { this._finish('unsupported'); return; }\n    if (yawDegrees) controller.setXRLocomotionInput({ forward: 0, right: 0, vertical: 0,\n      turn: yawDegrees * Math.PI / 180, haltMove: true, haltVertical: true, jump: false, crouch: false });\n    if (forwardMeters || rightMeters) {\n      const result = controller.applyAgentCameraStep({ forwardMeters, rightMeters });\n      if (!result?.applied || !(result.appliedHorizontalMeters > 0)) this._finish('interrupted');\n    }\n  }\n\n  frameCompleted({ now = this.now(), submitted = false, failed = false } = {}) {\n    const task = this.active;\n    if (task?.type === 'reload' && task.hotFrames !== undefined) {\n      if (failed) this._finish('failed');\n      else if (submitted && this.scene?._renderer?.xr?.isPresenting\n        && task.installedRenderer === this.scene?._sceneInitializer?.atmosphereClouds?._nativeXRRenderer\n        && task.expectedEyes.eyeCount > 0 && task.installedRenderer?.lastCompletedEyes === task.expectedEyes.eyeCount\n        && ['eyeCount', 'eyeWidth', 'eyeHeight', 'eyeWidthRight', 'eyeHeightRight'].every(key => this._quality()[key] === task.expectedEyes[key])\n        && task.installedRenderer?.frames >= 2) this._finish('ok');\n    }\n    if (task?.type === 'profile') {\n      this.componentLease?.sync();\n      const s = this.scene, sections = s?._perf?.sections || {}, a = s?._sceneInitializer?.atmosphereClouds?._nativeXRRenderer;\n      const cpu = { frame: sections.frame?.last, controls: sections['controls.total']?.last,\n        onFrame: sections['scene.onFrame']?.last, photoTiles: sections['photo.tiles.update']?.last,\n        onFrameOther: Number.isFinite(sections['scene.onFrame']?.last) && Number.isFinite(sections['photo.tiles.update']?.last)\n          ? Math.max(0, sections['scene.onFrame'].last - sections['photo.tiles.update'].last) : null,\n        ...a?._timings };\n      const gpu = a?._gpuTimer;\n      cpu.gpuMs = gpu?.result && gpu.result !== this.lastGPUResult ? gpu.getStats()?.gpuMs : null;\n      this.lastGPUResult = gpu?.result || this.lastGPUResult;\n      for (const key of ['rig', 'ground', 'placement']) cpu[key] = this.traceKeys?.has(key) ? this.traceTotals?.[key] || 0 : null;\n      this.traceTotals = {};\n      this.sampler.sample({ now, submitted: submitted && s?._renderer?.xr?.isPresenting === true,\n        visible: this._visible(), quality: this._quality(), cpu,\n        contextLost: s?._renderer?.getContext?.()?.isContextLost?.() === true, renderFailure: failed });\n      if (this.sampler.status(now).ready) this._finish('ok');\n    }\n    this.poll(now);\n  }\n  poll(now = this.now()) {\n    if (!this.enabled) return;\n    this.checkDeadlines(now);\n    if (now >= this.nextPoll) { this.nextPoll = now + 5000; void this.flush(); }\n  }\n  checkDeadlines(now = this.now()) {\n    if (!this.enabled) return;\n    if (this.active?.type === 'profile') this.sampler.sample({ now, submitted: false, visible: this._visible(),\n      quality: this._quality(), contextLost: this.scene?._renderer?.getContext?.()?.isContextLost?.() === true });\n    if (this.active?.type === 'profile' && this.sampler.status(now).ready) this._finish('ok');\n    if (this.active?.type === 'step' && now - this.active.started > this.active.args.durationMs + 1000) this._finish('interrupted');\n    if (this.active?.type === 'reload' && this.active.hotFrames !== undefined\n      && now - this.active.started > 15000) this._finish('interrupted');\n  }\n  _visibility() {\n    if (this.active?.type === 'step' && !this._visible()) this._finish('interrupted');\n    if (this.active?.type === 'profile') this.sampler.sample({ now: this.now(), submitted: false,\n      visible: this._visible(), quality: this._quality() });\n  }\n  _finish(code, contextLost = false) {\n    const task = this.active; if (!task) return;\n    this.active = null;\n    let summary;\n    if (task.runtimeTransaction) {\n      try {\n        if (code === 'ok') { task.runtimeTransaction.commit(); this.runtimeBuild = task.args.release; }\n        else { task.runtimeTransaction.rollback(); this.runtimeBuild = task.previousRuntimeBuild; }\n      } catch {\n        try { task.runtimeTransaction.rollback(); } catch { /* retain the failed transaction outcome */ }\n        this.runtimeBuild = task.previousRuntimeBuild; code = 'failed';\n      }\n    }\n    try {\n      if (task.type === 'profile') {\n        if (contextLost) this.sampler.sample({ now: this.now(), submitted: false, visible: this._visible(),\n          quality: this._quality(), contextLost: true });\n        summary = this.sampler.finish(this.now());\n        if (code === 'ok' && (summary.visibilityInterruptions || summary.contextLosses || summary.renderFailures)) code = 'interrupted';\n        if (code === 'ok' && summary.qualityChanged) code = 'quality-changed';\n      }\n    } finally {\n      this.active = null;\n      try { this._removeTraces(); }\n      finally {\n        const lease = this.componentLease; this.componentLease = null;\n        try { lease?.release(); } catch { /* optional observation cannot retain the capture */ }\n        this.observedSession?.removeEventListener?.('visibilitychange', this.onVisibility); this.observedSession = null;\n      }\n    }\n    this._ack(task, ['ok', 'stopped'].includes(code) ? 'complete' : 'failed', code, summary);\n  }\n  _installTraces() {\n    this.traceTotals = {}; this.traceKeys = new Set();\n    const trace = (object, name, key) => {\n      const original = object?.[name]; if (typeof original !== 'function') return;\n      this.traceKeys.add(key);\n      const harness = this;\n      function timed(...args) { const start = harness.now();\n        try { return original.apply(this, args); }\n        finally { harness.traceTotals[key] = (harness.traceTotals[key] || 0) + harness.now() - start; }\n      }\n      object[name] = timed; this.traces.push(() => { if (object[name] === timed) object[name] = original; });\n    };\n    trace(this.scene?._sceneInitializer, 'syncXRCamera', 'rig');\n    trace(this.scene?._surfaceController, '_sampleGroundTruthRadius', 'ground');\n    trace(this.scene?._surfaceController, '_samplePhotoFlightGroundRadius', 'ground');\n    trace(this.scene?._surfaceController, 'applySurfaceCamera', 'placement');\n  }\n  _removeTraces() { for (const restore of this.traces.splice(0)) restore(); }\n  _restoreClouds() {\n    if (this.priorClouds === null) return;\n    this.scene?._sceneSettings?.updateScene?.({ atmosphere: { clouds: { enabled: this.priorClouds } } }, { persist: false });\n    this.priorClouds = null;\n  }\n  dispose() {\n    this.operationEpoch++; this.reloadAbort?.abort();\n    this._finish('stopped'); this._restoreClouds(); this.disposed = true;\n    this.doc?.removeEventListener?.('visibilitychange', this.onVisibility);\n    this.scene?._renderer?.domElement?.removeEventListener?.('webglcontextlost', this.onContextLost);\n    this._removeTraces(); this.scene = null;\n  }\n}\n","import { getAuthService } from '../auth/AuthService.js';\nimport { resolveBackendApiUrl } from '../shared/backend.js';\nimport { getLabelSystem } from '../labels/LabelSystem.js';\nimport { XRRemoteHarness } from '../vr/XRRemoteHarness.js';\n\nconst TARGET_HANDLE = 'robit';\nconst DEFAULT_INTERVAL_MS = 10_000;\nconst MAX_FRAME_SAMPLES = 1_200;\nconst MAX_REPORT_BYTES = 12 * 1024;\nconst MAX_MODE_TRANSITIONS = 16;\nconst PIPELINE_SECTIONS = Object.freeze({\n  controls: 'controls.total',\n  terrainLod: 'lod.total',\n  photoTiles: 'photo.tiles.update',\n  lighting: 'lighting',\n  atmosphere: 'atmosphere.clouds.total',\n  atmosphereComposer: 'atmosphere.clouds.composer',\n  cloudGpu: 'gpu.clouds.render',\n  sceneRender: 'render.total',\n});\n\nconst finite = (value, min = 0, max = 1e15) => {\n  if (value === null || value === undefined || value === '') return null;\n  const number = Number(value);\n  return Number.isFinite(number) ? Math.min(max, Math.max(min, number)) : null;\n};\n\nconst integer = (value, min = 0, max = 1e12) => {\n  const number = finite(value, min, max);\n  return number === null ? null : Math.round(number);\n};\n\nconst token = (value, fallback = 'unknown') => {\n  const cleaned = String(value || '').replace(/[^a-zA-Z0-9_-]/g, '').slice(0, 40);\n  return cleaned || fallback;\n};\n\nconst percentile = (sorted, p) => {\n  if (!sorted.length) return null;\n  const index = Math.min(sorted.length - 1, Math.max(0, Math.ceil(sorted.length * p) - 1));\n  return finite(sorted[index], 0, 60_000);\n};\n\nconst mean = (values) => values.length\n  ? finite(values.reduce((sum, value) => sum + value, 0) / values.length, 0, 60_000)\n  : null;\n\nconst browserFamily = (nav) => {\n  const ua = String(nav?.userAgent || '');\n  if (/OculusBrowser|Quest/i.test(ua)) return 'quest';\n  if (/Edg\\//i.test(ua)) return 'edge';\n  if (/CriOS|Chrome|Chromium/i.test(ua)) return 'chromium';\n  if (/FxiOS|Firefox/i.test(ua)) return 'firefox';\n  if (/Safari/i.test(ua) && !/Chrome|Chromium|CriOS/i.test(ua)) return 'safari';\n  return ua ? 'other' : 'unknown';\n};\n\nconst deviceClass = (scene, nav) => {\n  if (scene?._renderer?.xr?.isPresenting || /OculusBrowser|Quest|Vive|Pico/i.test(String(nav?.userAgent || ''))) return 'vr';\n  if (scene?._isMobile === true || /Mobile|Android|iPhone|iPad/i.test(String(nav?.userAgent || ''))) return 'mobile';\n  return 'desktop';\n};\n\nconst emptyNetwork = () => ({\n  resources: 0, transferBytes: 0, encodedBodyBytes: 0, decodedBodyBytes: 0,\n  durationMs: 0, maxDurationMs: 0, fetchCount: 0, xhrCount: 0,\n  imageCount: 0, scriptCount: 0, styleCount: 0, otherCount: 0,\n});\n\nconst cleanReport = (value) => JSON.parse(JSON.stringify(value, (_key, item) => (\n  typeof item === 'number' && !Number.isFinite(item) ? null : item\n)));\n\n/**\n * Private, short-lived performance stream for the signed-in robit account.\n * It deliberately reports aggregates only: never coordinates, URLs, UA text,\n * input/chat content, screenshots, poses, error prose, or bearer material.\n */\nexport class BrowserPerformanceTelemetry {\n  constructor({\n    scene,\n    authService = getAuthService(),\n    host = globalThis,\n    doc = globalThis.document,\n    nav = globalThis.navigator,\n    perf = globalThis.performance,\n    now = () => globalThis.performance?.now?.() ?? Date.now(),\n    wall = () => Date.now(),\n    intervalMs = DEFAULT_INTERVAL_MS,\n    schedule = true,\n  } = {}) {\n    this.scene = scene;\n    this.auth = authService;\n    this.host = host;\n    this.doc = doc;\n    this.nav = nav;\n    this.perf = perf;\n    this.now = now;\n    this.wall = wall;\n    this.intervalMs = Math.max(5_000, Math.min(60_000, intervalMs));\n    this.schedule = schedule;\n    this.clientSession = token(host?.crypto?.randomUUID?.() || `perf-${Math.random().toString(36).slice(2)}`);\n    this.sequence = 0;\n    this.active = false;\n    this.disposed = false;\n    this.inFlight = null;\n    this.nextAllowedAt = 0;\n    this.windowStartedAt = this.now();\n    this.lastFrameAt = null;\n    this.frameSamples = [];\n    this.cpuSamples = [];\n    this.waitSamples = [];\n    this.longTasks = [];\n    this.pipelineSamples = Object.fromEntries(Object.keys(PIPELINE_SECTIONS).map((key) => [key, []]));\n    this.modeTransitions = [];\n    this.lastCameraMode = null;\n    this.network = emptyNetwork();\n    this.events = { jsErrors: 0, unhandledRejections: 0, resourceErrors: 0, webglContextLost: 0, webglContextRestored: 0 };\n    this.vitals = { lcpMs: null, cls: 0, inpMs: null };\n    this.observers = [];\n    this.timer = null;\n    this.authUnsubscribe = this.auth?.subscribe?.((state) => this._syncAuth(state)) || null;\n    this._onVisibility = () => {\n      if (this.doc?.visibilityState === 'hidden') void this.flush('hidden');\n    };\n    this._onPageHide = () => { void this.flush('pagehide'); };\n    this._onError = (event) => {\n      if (event?.target && event.target !== this.host) this.events.resourceErrors++;\n      else this.events.jsErrors++;\n    };\n    this._onRejection = () => { this.events.unhandledRejections++; };\n    this._onContextLost = () => { this.events.webglContextLost++; };\n    this._onContextRestored = () => { this.events.webglContextRestored++; };\n    this.doc?.addEventListener?.('visibilitychange', this._onVisibility);\n    this.host?.addEventListener?.('pagehide', this._onPageHide);\n    this.host?.addEventListener?.('error', this._onError, true);\n    this.host?.addEventListener?.('unhandledrejection', this._onRejection);\n    this.scene?._renderer?.domElement?.addEventListener?.('webglcontextlost', this._onContextLost);\n    this.scene?._renderer?.domElement?.addEventListener?.('webglcontextrestored', this._onContextRestored);\n    this._syncAuth(this.auth?.getState?.());\n  }\n\n  _isTarget(state) {\n    const handle = state?.user?.handle || state?.user?.username || '';\n    return state?.isAuthenticated === true && String(handle).trim().toLowerCase() === TARGET_HANDLE;\n  }\n\n  _syncAuth(state) {\n    const shouldRun = !this.disposed && this._isTarget(state);\n    const identity = shouldRun ? JSON.stringify([state?.user?.userId || state?.user?.user_id || state?.user?.id\n      || state?.user?.handle || state?.user?.username || '', state?.device?.deviceId || state?.device?.device_id || '',\n    state?.session?.sessionId || state?.session?.session_id || '']) : null;\n    if (shouldRun === this.active && identity === this.authIdentity) return;\n    if (this.active) this._stop();\n    this.authIdentity = identity;\n    this.active = shouldRun;\n    if (shouldRun) this._start();\n    else this._stop();\n  }\n\n  _start() {\n    this.windowStartedAt = this.now();\n    this.lastFrameAt = null;\n    this.nextAllowedAt = 0;\n    this.scene?._perf?.enable?.();\n    this._ensureHarness();\n    this._installObservers();\n    if (!this.schedule) return;\n    this.timer = setTimeout(() => {\n      this.timer = null;\n      void this.flush('interval');\n      this._scheduleNext();\n    }, Math.min(3_000, this.intervalMs));\n  }\n\n  _ensureHarness() {\n    if (this.harness || !this.active) return;\n    if (deviceClass(this.scene, this.nav) === 'vr') {\n      this.harness = new XRRemoteHarness({ scene: this.scene, host: this.host, doc: this.doc,\n        now: this.now, wall: this.wall, flush: () => this.flush('manual') });\n    }\n  }\n\n  _scheduleNext() {\n    if (!this.active || this.disposed || !this.schedule || this.timer) return;\n    this.timer = setTimeout(() => {\n      this.timer = null;\n      void this.flush('interval');\n      this._scheduleNext();\n    }, this.intervalMs);\n  }\n\n  _stop() {\n    this.harness?.dispose(); this.harness = null;\n    if (this.timer) clearTimeout(this.timer);\n    this.timer = null;\n    this.lastFrameAt = null;\n    for (const observer of this.observers.splice(0)) observer.disconnect?.();\n    this._resetWindow();\n  }\n\n  _observe(type, callback, options = {}) {\n    const Observer = this.host?.PerformanceObserver;\n    if (typeof Observer !== 'function') return;\n    try {\n      const observer = new Observer((list) => callback(list.getEntries()));\n      observer.observe({ type, ...options });\n      this.observers.push(observer);\n    } catch { /* unsupported entry type */ }\n  }\n\n  _installObservers() {\n    if (this.observers.length) return;\n    this._observe('longtask', (entries) => {\n      for (const entry of entries) this.longTasks.push(finite(entry.duration, 0, 60_000) || 0);\n      if (this.longTasks.length > 1_000) this.longTasks.splice(0, this.longTasks.length - 1_000);\n    });\n    this._observe('resource', (entries) => {\n      for (const entry of entries) {\n        const type = String(entry.initiatorType || '').toLowerCase();\n        this.network.resources++;\n        this.network.transferBytes += integer(entry.transferSize) || 0;\n        this.network.encodedBodyBytes += integer(entry.encodedBodySize) || 0;\n        this.network.decodedBodyBytes += integer(entry.decodedBodySize) || 0;\n        this.network.durationMs += finite(entry.duration) || 0;\n        this.network.maxDurationMs = Math.max(this.network.maxDurationMs, finite(entry.duration) || 0);\n        if (type === 'fetch') this.network.fetchCount++;\n        else if (type === 'xmlhttprequest') this.network.xhrCount++;\n        else if (type === 'img' || type === 'image') this.network.imageCount++;\n        else if (type === 'script') this.network.scriptCount++;\n        else if (type === 'css' || type === 'link') this.network.styleCount++;\n        else this.network.otherCount++;\n      }\n    });\n    this._observe('largest-contentful-paint', (entries) => {\n      const entry = entries[entries.length - 1];\n      if (entry) this.vitals.lcpMs = finite(entry.startTime, 0, 600_000);\n    }, { buffered: true });\n    this._observe('layout-shift', (entries) => {\n      for (const entry of entries) if (!entry.hadRecentInput) this.vitals.cls += finite(entry.value, 0, 100) || 0;\n    }, { buffered: true });\n    this._observe('event', (entries) => {\n      for (const entry of entries) this.vitals.inpMs = Math.max(this.vitals.inpMs || 0, finite(entry.duration, 0, 60_000) || 0);\n    }, { durationThreshold: 40 });\n  }\n\n  frame(dtSeconds, frameTimeMs = null) {\n    if (!this.active) return;\n    // Simulation dt is deliberately capped during stalls. Measure callback\n    // delivery separately so a 140 ms VR frame is never reported as 100 ms.\n    // Keep the previous timestamp across report windows, but reset it when\n    // the account stream stops/starts. A clock handoff cannot fabricate a\n    // zero/negative interval or borrow the simulation clamp as a measurement.\n    let frameMs;\n    if (Number.isFinite(frameTimeMs)) {\n      frameMs = this.lastFrameAt !== null && frameTimeMs > this.lastFrameAt\n        ? finite(frameTimeMs - this.lastFrameAt, 0, 60_000) : null;\n      this.lastFrameAt = frameTimeMs;\n    } else frameMs = finite(Number(dtSeconds) * 1000, 0, 60_000);\n    if (frameMs !== null) {\n      this.frameSamples.push(frameMs);\n      if (this.frameSamples.length > MAX_FRAME_SAMPLES) this.frameSamples.shift();\n    }\n    const sections = this.scene?._perf?.sections;\n    const cpu = finite(sections?.frame?.last, 0, 60_000);\n    const wait = finite(sections?.frameWait?.last, 0, 60_000);\n    if (cpu !== null) this.cpuSamples.push(cpu);\n    if (wait !== null) this.waitSamples.push(wait);\n    if (this.cpuSamples.length > MAX_FRAME_SAMPLES) this.cpuSamples.shift();\n    if (this.waitSamples.length > MAX_FRAME_SAMPLES) this.waitSamples.shift();\n    for (const [key, sectionName] of Object.entries(PIPELINE_SECTIONS)) {\n      const sample = finite(sections?.[sectionName]?.last, 0, 60_000);\n      if (sample === null) continue;\n      const values = this.pipelineSamples[key];\n      values.push(sample);\n      if (values.length > MAX_FRAME_SAMPLES) values.shift();\n    }\n\n    const mode = this._cameraMode();\n    if (this.lastCameraMode && mode !== this.lastCameraMode) {\n      this.modeTransitions.push({\n        from: this.lastCameraMode,\n        to: mode,\n        atMs: finite(this.now() - this.windowStartedAt, 0, 60_000),\n        frameMs,\n        cpuMs: cpu,\n      });\n      if (this.modeTransitions.length > MAX_MODE_TRANSITIONS) this.modeTransitions.shift();\n    }\n    this.lastCameraMode = mode;\n  }\n\n  beforeFrame(now) { this.harness?.beforeFrame(now); }\n  frameCompleted(frame) { this._ensureHarness(); this.harness?.frameCompleted(frame); }\n\n  _cameraMode() {\n    const mode = this.scene?._surfaceController?.cameraMode;\n    return ['orbit', 'surface', 'toSurface', 'toOrbit'].includes(mode) ? mode : 'unknown';\n  }\n\n  _pipelineReport() {\n    return Object.fromEntries(Object.entries(this.pipelineSamples).map(([key, values]) => [key, {\n      meanMs: mean(values),\n      maxMs: values.length ? finite(Math.max(...values), 0, 60_000) : null,\n    }]));\n  }\n\n  _navigationVitals() {\n    let nav = null;\n    try { nav = this.perf?.getEntriesByType?.('navigation')?.[0] || null; } catch {}\n    return {\n      domContentLoadedMs: finite(nav?.domContentLoadedEventEnd, 0, 600_000),\n      loadMs: finite(nav?.loadEventEnd, 0, 600_000),\n      lcpMs: finite(this.vitals.lcpMs, 0, 600_000),\n      cls: finite(this.vitals.cls, 0, 100),\n      inpMs: finite(this.vitals.inpMs, 0, 60_000),\n    };\n  }\n\n  _buildReport(reason) {\n    const scene = this.scene || {};\n    const renderer = scene._renderer;\n    const info = renderer?.info;\n    const tiles = scene._photoTileLoader?.getTileTelemetry?.() || {};\n    const budget = scene._budgetGovernor?.getStats?.() || {};\n    let labels = {};\n    try { labels = getLabelSystem().getMemoryStats?.() || {}; } catch {}\n    let memory = null;\n    try { memory = this.perf?.memory || null; } catch {}\n    const sortedFrames = [...this.frameSamples].sort((a, b) => a - b);\n    const frameMean = mean(this.frameSamples);\n    const longTaskTotal = this.longTasks.reduce((sum, value) => sum + value, 0);\n    const connection = this.nav?.connection || this.nav?.mozConnection || this.nav?.webkitConnection;\n    const canvas = renderer?.domElement;\n    const intervalMs = finite(this.now() - this.windowStartedAt, 0, 60_000);\n    const xr = renderer?.xr?.isPresenting === true;\n    const cameraMode = scene._surfaceController?.cameraMode;\n    const surface = scene._surfaceController?.isInSurfaceMode?.() === true || cameraMode === 'toSurface';\n    const mapMode = scene._mapPresentationMode === '2d' ? '2d' : '3d';\n    const build = this.host?.__noclipCrashTrace?.currentBuild?.() || 'unknown';\n    const atmosphere = scene._sceneInitializer?.atmosphereClouds;\n    const frameOwnership = scene._sceneInitializer?.getRenderOwnershipState?.() || {};\n    const cadence = scene._animationLoop?.getRenderCadenceState?.() || {};\n    return cleanReport({\n      version: 1,\n      clientSession: this.clientSession,\n      sequence: ++this.sequence,\n      reason,\n      at: finite(this.wall(), 0, 1e15),\n      intervalMs,\n      build: token(build),\n      browser: browserFamily(this.nav),\n      deviceClass: deviceClass(scene, this.nav),\n      lifecycle: {\n        visibility: ['visible', 'hidden', 'prerender'].includes(this.doc?.visibilityState) ? this.doc.visibilityState : 'unknown',\n        online: typeof this.nav?.onLine === 'boolean' ? this.nav.onLine : null,\n        focused: typeof this.doc?.hasFocus === 'function' ? Boolean(this.doc.hasFocus()) : null,\n      },\n      display: {\n        viewportWidth: integer(this.host?.innerWidth, 0, 32_768),\n        viewportHeight: integer(this.host?.innerHeight, 0, 32_768),\n        devicePixelRatio: finite(this.host?.devicePixelRatio, 0, 16),\n        colorDepth: integer(this.host?.screen?.colorDepth, 0, 128),\n      },\n      capabilities: {\n        hardwareConcurrency: integer(this.nav?.hardwareConcurrency, 0, 1024),\n        deviceMemoryGB: finite(this.nav?.deviceMemory, 0, 1024),\n        maxTouchPoints: integer(this.nav?.maxTouchPoints, 0, 128),\n        webgl2: typeof renderer?.capabilities?.isWebGL2 === 'boolean' ? renderer.capabilities.isWebGL2 : null,\n        xrPresenting: xr,\n      },\n      connection: {\n        effectiveType: ['slow-2g', '2g', '3g', '4g'].includes(connection?.effectiveType) ? connection.effectiveType : 'unknown',\n        downlinkMbps: finite(connection?.downlink, 0, 100_000),\n        rttMs: finite(connection?.rtt, 0, 600_000),\n        saveData: typeof connection?.saveData === 'boolean' ? connection.saveData : null,\n      },\n      frames: {\n        count: integer(this.frameSamples.length), meanMs: frameMean,\n        p50Ms: percentile(sortedFrames, 0.5), p95Ms: percentile(sortedFrames, 0.95),\n        maxMs: sortedFrames.length ? finite(sortedFrames[sortedFrames.length - 1], 0, 60_000) : null,\n        fps: frameMean ? finite(1000 / frameMean, 0, 1000) : null,\n        jank50: integer(this.frameSamples.filter((value) => value >= 50).length),\n        jank100: integer(this.frameSamples.filter((value) => value >= 100).length),\n        cpuMeanMs: mean(this.cpuSamples), waitMeanMs: mean(this.waitSamples),\n        longTaskCount: integer(this.longTasks.length), longTaskTotalMs: finite(longTaskTotal, 0, 600_000),\n        longTaskMaxMs: this.longTasks.length ? finite(Math.max(...this.longTasks), 0, 60_000) : null,\n      },\n      memory: {\n        heapUsedBytes: integer(memory?.usedJSHeapSize), heapTotalBytes: integer(memory?.totalJSHeapSize),\n        heapLimitBytes: integer(memory?.jsHeapSizeLimit),\n      },\n      renderer: {\n        drawCalls: integer(info?.render?.calls), triangles: integer(info?.render?.triangles),\n        points: integer(info?.render?.points), lines: integer(info?.render?.lines),\n        geometries: integer(info?.memory?.geometries), textures: integer(info?.memory?.textures),\n        programs: integer(info?.programs?.length), pixelRatio: finite(renderer?.getPixelRatio?.(), 0, 16),\n        bufferWidth: integer(canvas?.width, 0, 32_768), bufferHeight: integer(canvas?.height, 0, 32_768),\n        maxTextureSize: integer(renderer?.capabilities?.maxTextureSize), maxSamples: integer(renderer?.capabilities?.maxSamples),\n      },\n      tiles: {\n        enabled: typeof scene._photoTileLoader?.enabled === 'boolean' ? scene._photoTileLoader.enabled : null,\n        active: integer(tiles.activeTileCount), pending: integer(tiles.pendingCount),\n        loadedModels: integer(tiles.loadedModelCount), residentModels: integer(tiles.residentModelCount),\n        preparingModels: integer(tiles.preparingModelCount), visibleMaxDepth: integer(tiles.visibleTileMaxDepth),\n        bytesUsed: integer(tiles.bytesUsed), dataBytes: integer(tiles.tileDataCacheBytes), gpuBytes: integer(tiles.tileGpuCacheBytes),\n        cacheTargetBytes: integer(tiles.cacheTargetBytes), errorTarget: finite(tiles.errorTarget),\n        effectivePixelRatio: finite(tiles.effectivePixelRatio, 0, 16),\n        cachePressure: ['none', 'soft', 'hard'].includes(tiles.cachePressure) ? tiles.cachePressure : 'unknown',\n        pressureDrainCount: integer(tiles.pressureDrainCount),\n        pressureDrainMs: finite(tiles.pressureDrainMs, 0, 60_000),\n        cacheMode: token(tiles.cacheMode),\n        queueMode: token(tiles.queueMode),\n      },\n      pipeline: this._pipelineReport(),\n      transitions: this.modeTransitions.map((entry) => ({ ...entry })),\n      atmosphere: {\n        enabled: typeof scene._sceneInitializer?.atmosphereEnabled === 'boolean'\n          ? scene._sceneInitializer.atmosphereEnabled : null,\n        streaming: typeof scene._sceneInitializer?._atmosphereCloudStreamingEnabled === 'boolean'\n          ? scene._sceneInitializer._atmosphereCloudStreamingEnabled : null,\n        ready: typeof atmosphere?.ready === 'boolean' ? atmosphere.ready : null,\n        failed: typeof scene._sceneInitializer?.atmosphereCloudsFailed === 'boolean'\n          ? scene._sceneInitializer.atmosphereCloudsFailed : null,\n        warmupState: token(atmosphere?._cloudWarmupState),\n        highOrbit: typeof atmosphere?._cloudComposerHighOrbitActive === 'boolean'\n          ? atmosphere._cloudComposerHighOrbitActive : null,\n        frameOwner: token(frameOwnership.owner),\n      },\n      network: Object.fromEntries(Object.entries(this.network).map(([key, value]) => [key, finite(value)])),\n      vitals: this._navigationVitals(),\n      scene: {\n        world: scene._sceneMode === 'metaverse' ? 'metaverse' : 'earth', mapMode,\n        cameraMode: ['orbit', 'surface', 'toSurface', 'toOrbit'].includes(cameraMode) ? cameraMode : 'unknown',\n        surface, xr, photoreal: scene._photoTileLoader?.enabled === true,\n        frameOwner: ['renderer', 'raf'].includes(scene._animationLoop?._frameOwner) ? scene._animationLoop._frameOwner : 'unknown',\n        cadenceMode: token(cadence.mode),\n        cadenceMs: finite(cadence.effectiveMs, 0, 10_000),\n        targetFps: finite(cadence.targetFps, 0, 1_000),\n        labelsRegistered: integer(labels.registered), labelsVisible: integer(labels.visible),\n        budgetPressure: finite(budget.scenePressure, 0, 1),\n        budgetThrottled: typeof budget.throttled === 'boolean' ? budget.throttled : null,\n        budgetEmergency: typeof budget.emergencyActive === 'boolean' ? budget.emergencyActive : null,\n      },\n      events: Object.fromEntries(Object.entries(this.events).map(([key, value]) => [key, integer(value)])),\n    });\n  }\n\n  _resetWindow() {\n    this.windowStartedAt = this.now();\n    this.frameSamples.length = 0;\n    this.cpuSamples.length = 0;\n    this.waitSamples.length = 0;\n    this.longTasks.length = 0;\n    for (const values of Object.values(this.pipelineSamples)) values.length = 0;\n    this.modeTransitions.length = 0;\n    this.network = emptyNetwork();\n    this.events = { jsErrors: 0, unhandledRejections: 0, resourceErrors: 0, webglContextLost: 0, webglContextRestored: 0 };\n  }\n\n  async flush(reason = 'manual') {\n    if (!this.active || this.disposed || this.inFlight || this.now() < this.nextAllowedAt) return false;\n    this.harness?.checkDeadlines();\n    const report = this._buildReport(['interval', 'hidden', 'pagehide', 'manual'].includes(reason) ? reason : 'manual');\n    const harness = this.harness;\n    const control = harness?.envelope();\n    if (control) report.harness = control;\n    const body = JSON.stringify(report);\n    if (body.length > MAX_REPORT_BYTES) return false;\n    // The window timer and native completion hook share one network deadline.\n    // Their overlap must not produce bursts or trigger backend backoff loops.\n    if (harness?.enabled) this.nextAllowedAt = this.now() + 5000;\n    this._resetWindow();\n    this.inFlight = this.auth.authenticatedFetch(resolveBackendApiUrl('/diagnostics/browser-performance'), {\n      method: 'POST',\n      governanceLane: 'control',\n      governanceRetry: false,\n      keepalive: reason === 'hidden' || reason === 'pagehide',\n      headers: { 'Content-Type': 'application/json' },\n      body,\n    }).then(async (response) => {\n      if (response?.status === 429) {\n        const retrySeconds = Number(response.headers?.get?.('retry-after'));\n        this.nextAllowedAt = this.now() + (Number.isFinite(retrySeconds) ? retrySeconds * 1000 : 30_000);\n      }\n      if (response?.status === 202 && harness?.enabled && harness === this.harness) {\n        const text = await response.text();\n        if (text.length <= 4096) harness.receive(JSON.parse(text));\n      }\n      return response?.ok === true || response?.status === 204;\n    }).catch(() => false).finally(() => { this.inFlight = null; });\n    return this.inFlight;\n  }\n\n  dispose() {\n    if (this.disposed) return;\n    if (this.active) void this.flush('pagehide');\n    this.disposed = true;\n    this.active = false;\n    this._stop();\n    this.authUnsubscribe?.();\n    this.authUnsubscribe = null;\n    this.doc?.removeEventListener?.('visibilitychange', this._onVisibility);\n    this.host?.removeEventListener?.('pagehide', this._onPageHide);\n    this.host?.removeEventListener?.('error', this._onError, true);\n    this.host?.removeEventListener?.('unhandledrejection', this._onRejection);\n    this.scene?._renderer?.domElement?.removeEventListener?.('webglcontextlost', this._onContextLost);\n    this.scene?._renderer?.domElement?.removeEventListener?.('webglcontextrestored', this._onContextRestored);\n  }\n}\n\nexport const browserPerformanceTelemetryInternals = Object.freeze({\n  browserFamily, cleanReport, deviceClass, finite, integer, percentile,\n});\n","const now = () => (\n  typeof performance !== 'undefined' && Number.isFinite(performance.now?.())\n    ? performance.now()\n    : Date.now()\n);\n\nconst asMessage = (error) => (\n  error instanceof Error ? error.message : String(error || 'Unknown quiescence failure')\n);\n\nexport class CameraQuiescenceError extends Error {\n  constructor(message, diagnostics, cause = null) {\n    super(message, cause ? { cause } : undefined);\n    this.name = 'CameraQuiescenceError';\n    this.diagnostics = diagnostics;\n  }\n}\n\n/**\n * Run named camera-handoff steps in order and retain privacy-safe timing data.\n * Each step must resolve only when its subsystem has stopped scheduling work.\n */\nexport async function runCameraQuiescenceBarrier(\n  steps,\n  { timeoutMs = 8000, clock = now } = {},\n) {\n  const startedAt = clock();\n  const diagnostics = {\n    schema: 'noclip.camera-quiescence/1.0',\n    status: 'quiescing',\n    timeoutMs,\n    durationMs: 0,\n    failedSubsystem: null,\n    steps: [],\n  };\n\n  for (const step of steps) {\n    const stepStartedAt = clock();\n    const record = {\n      subsystem: String(step?.name || 'unknown'),\n      status: 'pending',\n      durationMs: 0,\n    };\n    diagnostics.steps.push(record);\n    const remainingMs = Math.max(1, timeoutMs - (stepStartedAt - startedAt));\n    let timer = null;\n    const controller = new AbortController();\n    try {\n      const timeout = new Promise((_resolve, reject) => {\n        timer = setTimeout(() => {\n          controller.abort('camera-quiescence-timeout');\n          reject(new Error(`Timed out after ${Math.round(remainingMs)} ms`));\n        }, remainingMs);\n      });\n      const result = await Promise.race([\n        Promise.resolve().then(() => step.run?.(controller.signal)),\n        timeout,\n      ]);\n      const verified = step.verify ? await step.verify(result) : true;\n      if (verified !== true) {\n        throw new Error(typeof verified === 'string' ? verified : 'Subsystem did not acknowledge quiescence');\n      }\n      record.status = 'acknowledged';\n      const detail = step.describe?.(result);\n      if (detail && typeof detail === 'object') record.detail = detail;\n    } catch (error) {\n      record.status = 'failed';\n      record.error = asMessage(error);\n      record.durationMs = Math.max(0, Math.round(clock() - stepStartedAt));\n      diagnostics.status = 'failed';\n      diagnostics.failedSubsystem = record.subsystem;\n      diagnostics.durationMs = Math.max(0, Math.round(clock() - startedAt));\n      throw new CameraQuiescenceError(\n        `Camera handoff failed while quiescing ${record.subsystem}: ${record.error}`,\n        diagnostics,\n        error,\n      );\n    } finally {\n      if (timer !== null) clearTimeout(timer);\n    }\n    record.durationMs = Math.max(0, Math.round(clock() - stepStartedAt));\n  }\n\n  diagnostics.status = 'quiescent';\n  diagnostics.durationMs = Math.max(0, Math.round(clock() - startedAt));\n  return diagnostics;\n}\n\nexport const waitForCameraSubsystem = async (\n  predicate,\n  { timeoutMs = 3000, intervalMs = 16, signal = null } = {},\n) => {\n  const startedAt = now();\n  while (now() - startedAt < timeoutMs) {\n    if (signal?.aborted) throw new DOMException('Camera handoff cancelled', 'AbortError');\n    if (predicate()) return true;\n    await new Promise((resolve) => setTimeout(resolve, intervalMs));\n  }\n  return predicate() === true;\n};\n","/**\n * Performance instrumentation and debug panel visualization\n */\n\nexport class PerformanceMonitor {\n    constructor() {\n        this.sections = {};\n        this.enabled = false;\n        this.frameStart = 0;\n        this.lastPanelUpdate = 0;\n        this.logHeavyFrames = false;\n        this.logHeavyFrameThresholdMs = 30;\n        this.logHeavyFrameIntervalMs = 1000;\n    }\n\n    /**\n     * Start timing a named section\n     * @param {string} name - Section name\n     */\n    start(name) {\n        if (!this.enabled) return;\n        const s = this.sections[name] || (this.sections[name] = {\n            total: 0, samples: 0, last: 0, max: 0, ema: 0, _start: 0\n        });\n        s._start = performance.now();\n    }\n\n    /**\n     * End timing a named section\n     * @param {string} name - Section name\n     */\n    end(name) {\n        if (!this.enabled) return;\n        const s = this.sections[name];\n        if (!s || s._start == null) return;\n        const dt = performance.now() - s._start;\n        s.last = dt;\n        s.total += dt;\n        s.samples++;\n        s.ema = s.samples > 1 ? (s.ema * 0.9 + dt * 0.1) : dt;\n        if (dt > s.max) s.max = dt;\n        s._start = null;\n    }\n\n    record(name, dt) {\n        if (!this.enabled || !Number.isFinite(dt)) return;\n        const s = this.sections[name] || (this.sections[name] = {\n            total: 0, samples: 0, last: 0, max: 0, ema: 0, _start: null\n        });\n        s.last = dt;\n        s.total += dt;\n        s.samples++;\n        s.ema = s.samples > 1 ? (s.ema * 0.9 + dt * 0.1) : dt;\n        if (dt > s.max) s.max = dt;\n    }\n\n    /**\n     * Enable performance monitoring\n     */\n    enable() {\n        this.enabled = true;\n    }\n\n    /**\n     * Disable performance monitoring\n     */\n    disable() {\n        this.enabled = false;\n    }\n\n    /**\n     * Get current performance statistics\n     * @returns {Object} Performance stats\n     */\n    getStats() {\n        return {\n            sections: { ...this.sections },\n            enabled: this.enabled\n        };\n    }\n\n    /**\n     * Generate a clean, pasteable snapshot of current performance metrics\n     * @returns {string} Formatted performance snapshot\n     */\n    getSnapshot() {\n        const timestamp = new Date().toISOString();\n        const sFrame = this.sections.frame;\n        const sInterval = this.sections.frameInterval;\n        const sWait = this.sections.frameWait;\n\n        const frameAvg = sInterval && sInterval.samples\n            ? (sInterval.ema || (sInterval.total / sInterval.samples))\n            : (sFrame && sFrame.samples ? (sFrame.ema || (sFrame.total / sFrame.samples)) : null);\n        const cpuAvg = sFrame && sFrame.samples ? (sFrame.ema || (sFrame.total / sFrame.samples)) : null;\n        const waitAvg = sWait && sWait.samples ? (sWait.ema || (sWait.total / sWait.samples)) : null;\n        const fps = frameAvg ? (1000 / frameAvg).toFixed(1) : '—';\n\n        // Categorize entries\n        const gpuEntries = [];\n        const cpuEntries = [];\n        const renderEntries = [];\n        let frameWaitEntry = null;\n\n        for (const [name, s] of Object.entries(this.sections)) {\n            if (name === 'frame' || name === 'frameInterval') continue;\n            if (!s.samples) continue;\n            const avg = s.ema || (s.total / s.samples);\n            const entry = { name, avg: avg.toFixed(2), last: s.last.toFixed(2), max: s.max.toFixed(2) };\n\n            if (name === 'frameWait') {\n                frameWaitEntry = entry;\n            } else if (name.startsWith('gpu.')) {\n                gpuEntries.push(entry);\n            } else if (name.startsWith('cpu.')) {\n                cpuEntries.push(entry);\n            } else if (name.includes('render') || name.includes('atmosphere')) {\n                renderEntries.push(entry);\n            } else {\n                cpuEntries.push(entry);\n            }\n        }\n\n        gpuEntries.sort((a, b) => parseFloat(b.avg) - parseFloat(a.avg));\n        cpuEntries.sort((a, b) => parseFloat(b.avg) - parseFloat(a.avg));\n        renderEntries.sort((a, b) => parseFloat(b.avg) - parseFloat(a.avg));\n\n        // Build text output\n        let output = `Performance Snapshot - ${timestamp}\\n`;\n        output += `${'='.repeat(60)}\\n\\n`;\n        output += `SUMMARY:\\n`;\n        output += `  FPS: ${fps}\\n`;\n        output += `  Frame Interval: ${frameAvg ? frameAvg.toFixed(2) : '—'} ms\\n`;\n        output += `  Frame CPU: ${cpuAvg ? cpuAvg.toFixed(2) : '—'} ms\\n`;\n        output += `  Frame Wait: ${waitAvg ? waitAvg.toFixed(2) : '—'} ms\\n`;\n\n        // DIAGNOSTIC: Detect rAF throttling vs GPU blocking\n        const isLikelyThrottled = frameAvg > 100 && cpuAvg < 10;\n        const isLikelyGPUBound = frameAvg > 30 && frameAvg < 100 && cpuAvg < 20;\n\n        if (isLikelyThrottled) {\n            output += `  ⚠️  WARNING: rAF throttling detected!\\n`;\n            output += `      (tab backgrounded, DevTools throttling, or low refresh rate)\\n`;\n            output += `      frameWait is idle time, NOT GPU execution\\n`;\n        } else if (isLikelyGPUBound) {\n            output += `  ⚠️  WARNING: GPU-bound! Shaders taking ~${waitAvg.toFixed(0)}ms\\n`;\n            output += `      (complex terrain/cloud shaders blocking GPU)\\n`;\n            output += `      frameWait approximates GPU execution time\\n`;\n        }\n        output += '\\n';\n\n        if (frameWaitEntry) {\n            let label;\n            if (isLikelyThrottled) {\n                label = 'rAF THROTTLING (browser limiting FPS)';\n            } else if (isLikelyGPUBound) {\n                label = 'GPU EXECUTION TIME (shaders)';\n            } else {\n                label = 'GPU BLOCKING';\n            }\n            output += `${label}:\\n`;\n            output += `  ${frameWaitEntry.name.padEnd(30)} ${frameWaitEntry.avg.padStart(8)} ms avg  (last: ${frameWaitEntry.last}, max: ${frameWaitEntry.max})\\n\\n`;\n        }\n\n        if (gpuEntries.length > 0) {\n            output += `GPU OPERATIONS:\\n`;\n            for (const e of gpuEntries) {\n                output += `  ${e.name.padEnd(30)} ${e.avg.padStart(8)} ms avg  (last: ${e.last}, max: ${e.max})\\n`;\n            }\n            output += '\\n';\n        }\n\n        if (renderEntries.length > 0) {\n            output += `RENDER PIPELINE:\\n`;\n            for (const e of renderEntries) {\n                output += `  ${e.name.padEnd(30)} ${e.avg.padStart(8)} ms avg  (last: ${e.last}, max: ${e.max})\\n`;\n            }\n            output += '\\n';\n        }\n\n        if (cpuEntries.length > 0) {\n            output += `CPU OPERATIONS:\\n`;\n            for (const e of cpuEntries) {\n                output += `  ${e.name.padEnd(30)} ${e.avg.padStart(8)} ms avg  (last: ${e.last}, max: ${e.max})\\n`;\n            }\n            output += '\\n';\n        }\n\n        output += `${'='.repeat(60)}\\n`;\n        output += `Note: 'avg' = exponential moving average, 'last' = most recent frame, 'max' = peak value\\n`;\n\n        return output;\n    }\n\n    /**\n     * Update debug panel UI with current performance metrics\n     */\n    updateDebugPanel() {\n        if (!this.enabled) return;\n        const panel = document.getElementById('debug-panel');\n        const content = document.getElementById('debug-content');\n        const fpsEl = document.getElementById('debug-fps');\n        if (!panel || !content || !fpsEl) return;\n\n        const sFrame = this.sections.frame;\n        const sInterval = this.sections.frameInterval;\n        const sWait = this.sections.frameWait;\n        const frameAvg = sInterval && sInterval.samples\n            ? (sInterval.ema || (sInterval.total / sInterval.samples))\n            : (sFrame && sFrame.samples ? (sFrame.ema || (sFrame.total / sFrame.samples)) : null);\n        const cpuAvg = sFrame && sFrame.samples ? (sFrame.ema || (sFrame.total / sFrame.samples)) : null;\n        const waitAvg = sWait && sWait.samples ? (sWait.ema || (sWait.total / sWait.samples)) : null;\n        if (frameAvg) {\n            const fps = 1000 / frameAvg;\n            const cpuLabel = cpuAvg ? cpuAvg.toFixed(1) : '—';\n            const waitLabel = waitAvg ? waitAvg.toFixed(1) : '—';\n            fpsEl.textContent = `FPS: ${fps.toFixed(1)} (interval ~${frameAvg.toFixed(1)} ms, cpu ~${cpuLabel} ms, wait ~${waitLabel} ms)`;\n        } else {\n            fpsEl.textContent = 'FPS: —';\n        }\n\n        // Categorize entries\n        const gpuEntries = [];\n        const cpuEntries = [];\n        const renderEntries = [];\n        let frameWaitEntry = null;\n\n        for (const [name, s] of Object.entries(this.sections)) {\n            if (name === 'frame' || name === 'frameInterval') continue;\n            if (!s.samples) continue;\n            const avg = s.ema || (s.total / s.samples);\n            const entry = { name, avg, last: s.last, max: s.max };\n\n            if (name === 'frameWait') {\n                frameWaitEntry = entry;\n            } else if (name.startsWith('gpu.')) {\n                gpuEntries.push(entry);\n            } else if (name.startsWith('cpu.')) {\n                cpuEntries.push(entry);\n            } else if (name.includes('render') || name.includes('atmosphere')) {\n                renderEntries.push(entry);\n            } else {\n                cpuEntries.push(entry);\n            }\n        }\n\n        // Sort each category by average time\n        gpuEntries.sort((a, b) => b.avg - a.avg);\n        cpuEntries.sort((a, b) => b.avg - a.avg);\n        renderEntries.sort((a, b) => b.avg - a.avg);\n\n        // Build HTML with categories\n        let html = '';\n\n        // Frame wait (GPU blocking) - always show first if present\n        if (frameWaitEntry) {\n            const pct = frameAvg ? Math.min(100, (frameWaitEntry.avg / frameAvg) * 100) : 0;\n            const isHeavy = frameWaitEntry.avg > 30;\n            html += `\n        <div class=\"perf-row${isHeavy ? ' perf-row-heavy' : ''}\">\n          <div class=\"perf-row-header\">\n            <div class=\"perf-name\">⚠️ ${frameWaitEntry.name} (GPU blocking)</div>\n            <div class=\"perf-numbers\">\n              ${frameWaitEntry.avg.toFixed(2)} ms avg\n              &nbsp;·&nbsp;last ${frameWaitEntry.last.toFixed(2)}\n              &nbsp;·&nbsp;max ${frameWaitEntry.max.toFixed(2)}\n            </div>\n          </div>\n          <div class=\"perf-bar\"><span style=\"width:${pct.toFixed(1)}%\"></span></div>\n        </div>\n      `;\n        }\n\n        // GPU operations\n        if (gpuEntries.length > 0) {\n            html += '<div class=\"perf-category\">🎮 GPU Operations</div>';\n            for (const e of gpuEntries) {\n                const pct = frameAvg ? Math.min(100, (e.avg / frameAvg) * 100) : 0;\n                const isHeavy = e.avg > 10;\n                html += `\n        <div class=\"perf-row${isHeavy ? ' perf-row-heavy' : ''}\">\n          <div class=\"perf-row-header\">\n            <div class=\"perf-name\">${e.name}</div>\n            <div class=\"perf-numbers\">\n              ${e.avg.toFixed(2)} ms avg\n              &nbsp;·&nbsp;last ${e.last.toFixed(2)}\n              &nbsp;·&nbsp;max ${e.max.toFixed(2)}\n            </div>\n          </div>\n          <div class=\"perf-bar\"><span style=\"width:${pct.toFixed(1)}%\"></span></div>\n        </div>\n      `;\n            }\n        }\n\n        // Render operations (may include both CPU setup + GPU dispatch)\n        if (renderEntries.length > 0) {\n            html += '<div class=\"perf-category\">🎨 Render Pipeline</div>';\n            for (const e of renderEntries) {\n                const pct = frameAvg ? Math.min(100, (e.avg / frameAvg) * 100) : 0;\n                const isHeavy = e.avg > 10;\n                html += `\n        <div class=\"perf-row${isHeavy ? ' perf-row-heavy' : ''}\">\n          <div class=\"perf-row-header\">\n            <div class=\"perf-name\">${e.name}</div>\n            <div class=\"perf-numbers\">\n              ${e.avg.toFixed(2)} ms avg\n              &nbsp;·&nbsp;last ${e.last.toFixed(2)}\n              &nbsp;·&nbsp;max ${e.max.toFixed(2)}\n            </div>\n          </div>\n          <div class=\"perf-bar\"><span style=\"width:${pct.toFixed(1)}%\"></span></div>\n        </div>\n      `;\n            }\n        }\n\n        // CPU operations\n        if (cpuEntries.length > 0) {\n            html += '<div class=\"perf-category\">⚡ CPU Operations</div>';\n            for (const e of cpuEntries) {\n                const pct = frameAvg ? Math.min(100, (e.avg / frameAvg) * 100) : 0;\n                const isHeavy = e.avg > 5;\n                html += `\n        <div class=\"perf-row${isHeavy ? ' perf-row-heavy' : ''}\">\n          <div class=\"perf-row-header\">\n            <div class=\"perf-name\">${e.name}</div>\n            <div class=\"perf-numbers\">\n              ${e.avg.toFixed(2)} ms avg\n              &nbsp;·&nbsp;last ${e.last.toFixed(2)}\n              &nbsp;·&nbsp;max ${e.max.toFixed(2)}\n            </div>\n          </div>\n          <div class=\"perf-bar\"><span style=\"width:${pct.toFixed(1)}%\"></span></div>\n        </div>\n      `;\n            }\n        }\n\n        content.innerHTML = html;\n    }\n}\n","import * as THREE from 'three';\n\nexport class GraphicsStartupError extends Error {\n  constructor(failures) {\n    super('The browser could not start WebGL 2 graphics.');\n    this.name = 'GraphicsStartupError';\n    this.code = 'WEBGL_UNAVAILABLE';\n    this.failures = failures;\n  }\n}\n\n/** Admit the actual scene context; never allocate a separate capability probe. */\nexport function createSceneRenderer({\n  createCanvas = () => document.createElement('canvas'),\n  createRenderer = options => new THREE.WebGLRenderer(options),\n} = {}) {\n  const failures = [];\n  for (const profile of ['high-performance', 'compatible']) {\n    const canvas = createCanvas();\n    let context, reason = '';\n    const attributes = {\n      alpha: false, depth: true, stencil: false, premultipliedAlpha: true,\n      preserveDrawingBuffer: false, failIfMajorPerformanceCaveat: false,\n      antialias: profile === 'high-performance',\n      powerPreference: profile === 'high-performance' ? 'high-performance' : 'default',\n    };\n    const onError = event => { reason = String(event.statusMessage || '').slice(0, 512); };\n    canvas.addEventListener('webglcontextcreationerror', onError);\n    try {\n      context = canvas.getContext('webgl2', attributes);\n      if (!context || context.isContextLost()) throw new Error(reason || 'WebGL 2 context unavailable');\n      const renderer = createRenderer({\n        canvas, context, ...attributes, logarithmicDepthBuffer: true,\n        outputBufferType: THREE.HalfFloatType,\n      });\n      return { renderer, profile, attempts: failures.length + 1 };\n    } catch (error) {\n      failures.push({ profile, reason: reason || String(error.message || error).slice(0, 512) });\n      // A renderer that failed after context admission must not leave another\n      // live context behind when the compatible profile is attempted.\n      try { context?.getExtension('WEBGL_lose_context')?.loseContext(); } catch {}\n      canvas.width = canvas.height = 0;\n    } finally { canvas.removeEventListener('webglcontextcreationerror', onError); }\n  }\n  throw new GraphicsStartupError(failures);\n}\n\n/** Retry the real startup transaction, retaining an admitted context. The app\n * may hand persistent rejection to its CPU-rendered map without another probe. */\nexport async function initializeSceneGraphics(scene, { sleep = ms => new Promise(resolve => setTimeout(resolve, ms)),\n  onWaiting = () => {}, onBlocked } = {}) {\n  let attempts = 0;\n  for (;;) {\n    let failure;\n    for (const delay of [0, 1000, 3000]) {\n      if (delay) { onWaiting({ attempts, failures: failure.failures }); await sleep(delay); }\n      try { await scene.init(); return; }\n      catch (error) {\n        if (error?.code !== 'WEBGL_UNAVAILABLE') throw error;\n        attempts += error.failures?.length || 0; failure = error;\n      }\n    }\n    if (!onBlocked) throw failure;\n    // Embedded 3D-only consumers can still wait for an explicit Retry. The\n    // full app can instead continue with its existing 2D map and HUD.\n    if (await onBlocked({ attempts, failures: failure.failures }) === '2d') return { mode: '2d' };\n  }\n}\n","import * as THREE from 'three';\nimport {\n  Body,\n  GeoVector,\n  KM_PER_AU,\n} from 'astronomy-engine';\nimport { CelestialFrame } from './celestial-frame.js';\n\nconst METERS_PER_AU = KM_PER_AU * 1000;\nfunction copyAstronomyVectorToEarthFixed(vector, frame, result) {\n  // Astronomy Engine returns apparent geocentric vectors in its J2000\n  // equatorial frame. Rotate through equator-of-date before applying GAST so\n  // precession/nutation do not move a terrestrial eclipse track by tens of\n  // kilometres. NOCLIP's planet-local axes are +X east, +Y north, +Z at the\n  // prime meridian.\n  return result.set(vector.x, vector.y, vector.z)\n    .applyMatrix4(frame.eqjToEarthFixed).multiplyScalar(METERS_PER_AU);\n}\n\nexport class CelestialEphemeris {\n  constructor() {\n    this.timeMs = NaN;\n    this.sunPositionEarthFixed = new THREE.Vector3();\n    this.moonPositionEarthFixed = new THREE.Vector3();\n    this.sunPosition = new THREE.Vector3();\n    this.moonPosition = new THREE.Vector3();\n    this.sunDirection = new THREE.Vector3(0, 0, 1);\n    this.moonDirection = new THREE.Vector3(0, 0, 1);\n    this.sunDistance = 0;\n    this.moonDistance = 0;\n    this.frame = new CelestialFrame();\n  }\n\n  update(date = new Date()) {\n    const timeMs = date instanceof Date ? date.getTime() : Number(date);\n    if (!Number.isFinite(timeMs)) return this;\n    if (timeMs === this.timeMs) return this;\n    const instant = date instanceof Date ? date : new Date(timeMs);\n    this.frame.update(instant);\n    copyAstronomyVectorToEarthFixed(\n      GeoVector(Body.Sun, instant, true),\n      this.frame,\n      this.sunPositionEarthFixed,\n    );\n    copyAstronomyVectorToEarthFixed(\n      GeoVector(Body.Moon, instant, true),\n      this.frame,\n      this.moonPositionEarthFixed,\n    );\n    // Preserve the established Earth/camera transform exactly. Its legacy\n    // Euler composition is consumed throughout terrain, URL placement, and\n    // locomotion, so celestial coordinates project through that same frame\n    // instead of changing the planet transform underneath those systems.\n    this.sunPosition.copy(this.sunPositionEarthFixed).applyMatrix4(this.frame.earthFixedToWorld);\n    this.moonPosition.copy(this.moonPositionEarthFixed).applyMatrix4(this.frame.earthFixedToWorld);\n    this.sunDistance = this.sunPosition.length();\n    this.moonDistance = this.moonPosition.length();\n    this.sunDirection.copy(this.sunPosition).normalize();\n    this.moonDirection.copy(this.moonPosition).normalize();\n    this.timeMs = timeMs;\n    return this;\n  }\n}\n\nexport function computeCelestialEphemeris(date, result = new CelestialEphemeris()) {\n  return result.update(date);\n}\n","/**\n * Lighting System\n *\n * Dynamic lighting controller with real-time sun updates.\n * Replaces static multi-light rig with dynamic single-sun system.\n */\n\nimport * as THREE from 'three';\nimport { getSunDirectionVector, getEarthRotationAngleUTC } from './sun-calculator.js';\nimport { AXIAL_TILT_RAD } from './constants.js';\nimport { CelestialEphemeris } from './celestial-ephemeris.js';\n\nexport class LightingSystem {\n  /**\n   * @param {THREE.Scene} scene - Three.js scene\n   * @param {number} planetRadius - Radius of the planet in meters\n   * @param {number} sunDistance - Distance from Earth to Sun in meters (default: 1 AU)\n   */\n    constructor(scene, planetRadius = 6_371_000, sunDistance = 149_597_870_700) {\n        this.scene = scene;\n        this.planetRadius = planetRadius;\n        this.sunDistance = sunDistance;\n        this.celestialEphemeris = new CelestialEphemeris();\n\n    // Main directional light representing the sun at real astronomical distance.\n    // Base intensity is intentionally below the previous 4.0: under AgX at the\n    // pipeline's high exposure, an intensity-4 sun pushed lit surfaces into the\n    // tone-mapping shoulder, desaturating them to a milky \"UV burn\" washout.\n    // 3.4 keeps daylight bright but holds sun-lit ground out of that shoulder.\n    // The live UV-index modulation (applyUvIndex) rides on this as its base.\n    this.sun = new THREE.DirectionalLight('#ffffff', 3.4);\n    this._baseSunIntensity = 3.4;\n    this._uvSunFactor = 1.0;\n    this.sun.position.set(0, 0, sunDistance); // Real Earth-Sun distance\n    this.sun.target.position.set(0, 0, 0);\n    // This astronomical light supplies direction and illumination only.\n    // A global 1-AU shadow caster makes r185 add the shadow-map shader path to\n    // every scene material and caused the live first frame to freeze inside\n    // ANGLE program reflection. Takram owns normal cloud shadows and the\n    // dedicated sun-study ShadowPass enables local geometry shadows on demand.\n    // Keep this false unless that opt-in pass is active.\n    this.sun.castShadow = false;\n    this.sun.name = 'Sun';\n\n    const shadowExtent = this.planetRadius * 2;\n    const shadowRange = this.planetRadius * 4;\n    this.sun.shadow.mapSize.set(2048, 2048);\n    this.sun.shadow.camera.left = -shadowExtent;\n    this.sun.shadow.camera.right = shadowExtent;\n    this.sun.shadow.camera.top = shadowExtent;\n    this.sun.shadow.camera.bottom = -shadowExtent;\n    this.sun.shadow.camera.near = Math.max(1, this.sunDistance - shadowRange);\n    this.sun.shadow.camera.far = this.sunDistance + shadowRange;\n    this.sun.shadow.bias = -0.0001;\n    this.sun.shadow.normalBias = 0.0005;\n    this.sun.shadow.camera.updateProjectionMatrix();\n\n    this.scene.add(this.sun);\n    this.scene.add(this.sun.target);\n\n    // Time control\n    this.currentDate = new Date();\n    this.useSimplified = true; // Use simplified calculation by default\n    this.latitude = 0;\n    this.longitude = 0;\n    this.sunDirection = new THREE.Vector3(0, 0, -1);\n    this.timeSpeed = 0; // Multiplier for time progression (0 = paused)\n    this.lastUpdateTime = performance.now();\n    this.followSystemTime = false;\n\n    // Debug flags for testing sign flips\n    this.debugFlipRotation180 = false;\n    this.debugNegateSunX = false;\n    this.debugNegateSunZ = false;\n\n    // Optional: Add subtle ambient lights for nighttime visibility\n    this.ambient = new THREE.AmbientLight(0x404040, 0.3);\n    this.ambient.name = 'AmbientFill';\n    this.skyAmbient = new THREE.HemisphereLight(0x6b8dd6, 0x10152b, 0.2);\n    this.skyAmbient.name = 'SkyAmbient';\n    // Night-Side Visibility owns this fill color. Keep it truly neutral-black:\n    // geography and emissive light pollution remain visible through their own\n    // shader paths without a global blue-grey wash lifting every night pixel.\n    this.nightAmbient = new THREE.AmbientLight(0x000000, 0.08);\n    this.nightAmbient.name = 'NightAmbient';\n    this.scene.add(this.ambient);\n    this.scene.add(this.skyAmbient);\n    this.scene.add(this.nightAmbient);\n  }\n\n  /**\n   * Update sun position based on current date/time\n   *\n   * @param {Date} date - Optional date to use (if not provided, uses internal currentDate)\n   */\n  updateSunPosition(date = null) {\n    if (date) {\n      this.currentDate = date;\n    }\n\n    // One apparent geocentric ephemeris owns both physical bodies. Keeping the\n    // real Sun distance matters for total-versus-annular eclipse geometry, and\n    // keeping its frame shared with the Moon prevents arc-minute alignment\n    // drift between independently simplified orbits.\n    const ephemeris = this.celestialEphemeris.update(this.currentDate);\n    const normalizedDirection = ephemeris.sunDirection;\n    this.sunDistance = ephemeris.sunDistance;\n    this.sunDirection.copy(normalizedDirection);\n    this.sun.position.copy(ephemeris.sunPosition);\n\n    // Compute day factor from the ecliptic sun direction\n    // Note: ambient lighting should be constant, not sun-direction dependent\n    // for global realism (day/night is handled by shader based on local angles)\n    this.ambient.intensity = 0.02; // Much darker ambient for night-side contrast\n    this.skyAmbient.intensity = 0.03; // Reduce hemisphere lift on the dark side\n    this.nightAmbient.intensity = 0.01; // Keep a faint floor only\n  }\n\n  /**\n   * Set time of day manually (uses current date, UTC)\n   *\n   * @param {number} hours - Hours (0-23)\n   * @param {number} minutes - Minutes (0-59)\n   */\n  setTimeOfDay(hours, minutes = 0) {\n    this.followSystemTime = false;\n    this.currentDate.setUTCHours(hours, minutes, 0, 0);\n    this.updateSunPosition();\n  }\n\n  /**\n   * Set specific date\n   *\n   * @param {Date} date - Date to set\n   */\n  setDate(date) {\n    this.followSystemTime = false;\n    this.currentDate = new Date(date);\n    this.updateSunPosition();\n  }\n\n  /**\n   * Set location for astronomical calculations\n   * NOTE: Location does NOT affect global lighting (which uses geocentric sun direction).\n   * Location is stored for UI metrics and local sun angle calculations only.\n   *\n   * @param {number} lat - Latitude in degrees\n   * @param {number} lng - Longitude in degrees\n   */\n  setLocation(lat, lng) {\n    this.latitude = lat;\n    this.longitude = lng;\n    // Location doesn't change lighting - we always use ecliptic frame\n    // This is stored for EventManager to compute local sun metrics\n  }\n\n  /**\n   * Get local sun direction for a specific location (for UI metrics only)\n   * This is NOT used for global lighting.\n   *\n   * @param {number} lat - Latitude in degrees\n   * @param {number} lng - Longitude in degrees\n   * @returns {THREE.Vector3} Local sun direction vector\n   */\n  getLocalSunDirection(lat, lng) {\n    return getSunDirectionVector(this.currentDate, lat, lng);\n  }\n\n  /**\n   * Enable/disable simplified sun calculation\n   *\n   * @param {boolean} enabled - Whether to use simplified calculation\n   */\n  setSimplifiedMode(enabled) {\n    this.useSimplified = enabled;\n    this.updateSunPosition();\n  }\n\n  /**\n   * Follow system clock in real time (ignores timeSpeed).\n   *\n   * @param {boolean} enabled\n   */\n  setFollowSystemTime(enabled) {\n    this.followSystemTime = !!enabled;\n    if (this.followSystemTime) {\n      this.currentDate = new Date();\n      this.updateSunPosition();\n    }\n  }\n\n  /**\n   * Set time progression speed\n   *\n   * @param {number} speed - Time multiplier (1 = real-time, 60 = 1 minute per second, 0 = paused)\n   */\n  setTimeSpeed(speed) {\n    this.timeSpeed = speed;\n  }\n\n  /**\n   * Update time progression (call in animation loop)\n   *\n   * @param {number} deltaTime - Time elapsed in seconds\n   */\n  update(deltaTime) {\n    // Honour SceneClock as the canonical time source when available.\n    // Falls back to legacy followSystemTime / timeSpeed if SceneClock has\n    // not booted (very early boot frames, tests, or headless paths).\n    try {\n      const clock = (typeof globalThis !== 'undefined' && globalThis.window?.__noclipSceneClock)\n        || null;\n      if (clock?.getTime) {\n        this.currentDate = new Date(clock.getTime());\n        this.updateSunPosition();\n        return;\n      }\n    } catch { /* fall through to legacy */ }\n    if (this.followSystemTime) {\n      this.currentDate = new Date();\n      this.updateSunPosition();\n      return;\n    }\n    if (this.timeSpeed !== 0) {\n      // Progress simulated time (legacy path)\n      const millisecondsElapsed = deltaTime * 1000 * this.timeSpeed;\n      this.currentDate = new Date(this.currentDate.getTime() + millisecondsElapsed);\n      this.updateSunPosition();\n    }\n  }\n\n  /**\n   * Set sun intensity\n   *\n   * @param {number} intensity - Light intensity\n   */\n  setIntensity(intensity) {\n    this.sun.intensity = intensity;\n    // Treat an explicit set as the new base the UV modulation rides on, then\n    // re-apply the current UV factor so the two controls compose predictably.\n    this._baseSunIntensity = intensity;\n    if (Number.isFinite(this._uvSunFactor)) {\n      this.sun.intensity = intensity * this._uvSunFactor;\n    }\n  }\n\n  /**\n   * Modulate sun intensity by the real-world UV index.\n   *\n   * The high-exposure AgX pipeline pushes fully sun-lit surfaces into the\n   * desaturating shoulder, producing the milky \"UV burn\" washout on ground\n   * facing the sun. Tying the sun's diffuse strength to the live UV index makes\n   * that intensity physically meaningful instead of a fixed maximum: a hazy /\n   * low-sun-angle day (low UV) softens the sun and clears the washout, while an\n   * extreme clear-sky day (UV ~9+) keeps the full harsh look.\n   *\n   * The factor is capped at 1.0 so this can only TAME the washout relative to\n   * the current base, never brighten past it. When no UV data is available the\n   * base intensity is left untouched.\n   *\n   * @param {number}  uvIndex  Open-Meteo current UV index (0 … ~12).\n   * @param {Object} [opts]\n   * @param {boolean}[opts.enabled=true]  When false, restores the base sun.\n   */\n  applyUvIndex(uvIndex, { enabled = true } = {}) {\n    if (!Number.isFinite(this._baseSunIntensity)) {\n      this._baseSunIntensity = this.sun.intensity;\n    }\n    if (!enabled || !Number.isFinite(uvIndex)) {\n      this._uvSunFactor = 1.0;\n      this.sun.intensity = this._baseSunIntensity;\n      return;\n    }\n    // Map UV index → diffuse-sun factor. Anchored so a strong clear-sky day\n    // (UV 9) restores full intensity and a typical mid-day (UV ~6) is ~15%\n    // softer; floored so deep overcast still reads as daylight, not dusk.\n    const UV_REF = 9;       // UV that maps to full (1.0) intensity\n    const UV_FLOOR = 0.55;  // minimum factor (overcast / low sun)\n    const factor = THREE.MathUtils.clamp(0.55 + (0.45 / UV_REF) * uvIndex, UV_FLOOR, 1.0);\n    this._uvSunFactor = factor;\n    this.sun.intensity = this._baseSunIntensity * factor;\n  }\n\n  /**\n   * Set ambient light intensity\n   *\n   * @param {number} intensity - Ambient intensity\n   */\n  setAmbientIntensity(intensity) {\n    this.ambient.intensity = intensity;\n  }\n\n  /**\n   * Get current sun direction as normalized vector\n   *\n   * @returns {THREE.Vector3}\n   */\n  getSunDirection() {\n    return this.sunDirection.clone();\n  }\n\n  getCelestialEphemeris() {\n    return this.celestialEphemeris;\n  }\n\n  /**\n   * Get current time info\n   *\n   * @returns {Object} { date, hours, minutes, timeOfDay } (UTC)\n   */\n  getTimeInfo() {\n    return {\n      date: this.currentDate,\n      hours: this.currentDate.getUTCHours(),\n      minutes: this.currentDate.getUTCMinutes(),\n      timeOfDay: this.currentDate.getUTCHours() + this.currentDate.getUTCMinutes() / 60\n    };\n  }\n\n  /**\n   * Get Earth's rotation angle for current time\n   * Uses UTC-based time calculation to avoid circular dependency on sun direction.\n   * This should be applied to the planet/terrain group's rotation.y\n   *\n   * @returns {number} Rotation angle in radians\n   */\n  getEarthRotationAngle() {\n    // Use UTC-based rotation (no dependency on sun direction)\n    let angle = getEarthRotationAngleUTC(this.currentDate);\n\n    // Debug: Add 180° flip if enabled\n    if (this.debugFlipRotation180) {\n      angle += Math.PI;\n    }\n\n    return angle;\n  }\n\n  /**\n   * Clean up resources\n   */\n  dispose() {\n    this.scene.remove(this.sun);\n    this.scene.remove(this.sun.target);\n    this.scene.remove(this.ambient);\n  }\n}\n","const clamp = (v, lo, hi) => Math.min(hi, Math.max(lo, v));\nconst smooth = (lo, hi, v) => { const t = clamp((v-lo)/(hi-lo),0,1); return t*t*(3-2*t); };\n\n// A clear-sky visibility model, not a weather/light-pollution observation.\n// Bright stars emerge first; the faint catalog and diffuse Milky Way wait\n// until astronomical twilight. High orbit keeps its unobscured sky.\nexport function skyLimitingMagnitude(sunAltitudeDegrees, altitudeMeters = 0) {\n  const atmospheric = Math.exp(-Math.max(0, altitudeMeters)/8000);\n  const surface = -4 + 10.7*smooth(0,18,-sunAltitudeDegrees);\n  return 6.7 + (surface-6.7)*atmospheric;\n}\n\nexport function skyObjectVisibility(magnitude, limitingMagnitude) {\n  return 1-smooth(limitingMagnitude-0.65,limitingMagnitude+0.35,magnitude);\n}\n\nexport const SKY_VISIBILITY_GLSL = `\n  float skyObjectVisibility(float magnitude, float limitingMagnitude) {\n    return 1.0-smoothstep(limitingMagnitude-0.65, limitingMagnitude+0.35, magnitude);\n  }\n`;\n","const normalizeCanonicalPath = (value) => {\n    const candidate = String(value || '').trim();\n    if (!candidate.startsWith('/') || candidate.includes('\\\\') || candidate.includes('\\0')) return '';\n    return candidate;\n};\n\n/**\n * Resolve a reviewed scene resource to the immutable copy installed by a\n * release-pinned presentation frame. Normal app entry points intentionally\n * keep their existing root-relative resource contract.\n */\nexport function resolveSceneRuntimeResource(canonicalPath) {\n    const normalized = normalizeCanonicalPath(canonicalPath);\n    if (!normalized) throw new TypeError('Scene resource path must be root-relative');\n    const configured = globalThis.__NOCLIP_SCENE_RELEASE__?.resources?.[normalized];\n    if (typeof configured !== 'string' || !configured) return normalized;\n    try {\n        const resolved = new URL(configured, globalThis.location?.origin || 'https://app.noclip.org');\n        const pageOrigin = globalThis.location?.origin;\n        if (pageOrigin && resolved.origin !== pageOrigin) return normalized;\n        return resolved.href;\n    } catch {\n        return normalized;\n    }\n}\n\nexport function resolveSceneRuntimeBasePath() {\n    const configured = globalThis.__NOCLIP_SCENE_RELEASE__?.resourceBase;\n    if (typeof configured !== 'string' || !configured) return '/';\n    try {\n        const resolved = new URL(configured, globalThis.location?.origin || 'https://app.noclip.org');\n        const pageOrigin = globalThis.location?.origin;\n        if (pageOrigin && resolved.origin !== pageOrigin) return '/';\n        return resolved.href.endsWith('/') ? resolved.href : `${resolved.href}/`;\n    } catch {\n        return '/';\n    }\n}\n","// HEALPix NESTED cell centres, using the standard polar/equatorial ring equations.\n// Catalogue coordinates remain ICRS; HEALPix is acquisition addressing only.\nconst JRLL=[2,2,2,2,3,3,3,3,4,4,4,4], JPLL=[1,3,5,7,0,2,4,6,1,3,5,7];\nexport const GAIA_G_ZERO_POINT=25.6873668671;\nexport const GAIA_ZERO_FLUX=10**(0.4*GAIA_G_ZERO_POINT);\nexport function healpixXYDirection(side,face,x,y,out) {\n  const ring=JRLL[face]*side-x-y;\n  let nr,z;\n  if(ring<side){nr=ring;z=1-nr*nr/(3*side*side);}\n  else if(ring>3*side){nr=4*side-ring;z=-1+nr*nr/(3*side*side);}\n  else{nr=side;z=(2*side-ring)*2/(3*side);}\n  const phi=nr>1e-12?(JPLL[face]*nr+x-y)*Math.PI/(4*nr):JPLL[face]*Math.PI/4;\n  const r=Math.sqrt(Math.max(0,1-z*z));return out.set(r*Math.cos(phi),r*Math.sin(phi),z);\n}\nexport function nestedPixel(order,face,x,y){\n  let index=face*4**order;\n  for(let b=0;b<order;b++)index+=(Math.floor(x/2**b)%2+2*(Math.floor(y/2**b)%2))*4**b;\n  return index;\n}\nexport function directionHealpix(order,direction){\n  const side=2**order,z=direction.z/Math.hypot(direction.x,direction.y,direction.z),za=Math.abs(z);\n  const tt=((Math.atan2(direction.y,direction.x)/(Math.PI/2))%4+4)%4;\n  let face,x,y;\n  if(za<=2/3){\n    const jp=Math.floor(side*(0.5+tt-z*0.75)),jm=Math.floor(side*(0.5+tt+z*0.75));\n    const fp=Math.floor(jp/side),fm=Math.floor(jm/side);\n    face=fp===fm?(fp%4)+4:fp<fm?fp%4:(fm%4)+8;\n    x=jm%side;y=side-(jp%side)-1;\n  }else{\n    const nt=Math.min(3,Math.floor(tt)),tp=tt-nt,tmp=side*Math.sqrt(3*(1-za));\n    const jp=Math.min(side-1,Math.floor(tp*tmp)),jm=Math.min(side-1,Math.floor((1-tp)*tmp));\n    if(z>=0){face=nt;x=side-jm-1;y=side-jp-1;}else{face=nt+8;x=jp;y=jm;}\n  }\n  return nestedPixel(order,face,x,y);\n}\nexport function healpixDirection(order,pixel,out) {\n  const side=2**order, faceSize=4**order, face=Math.floor(pixel/faceSize);\n  let bits=pixel%faceSize,x=0,y=0;\n  for(let bit=0;bit<order;bit++) {x+=(bits%2)*2**bit;bits=Math.floor(bits/2);y+=(bits%2)*2**bit;bits=Math.floor(bits/2);}\n  const ring=JRLL[face]*side-x-y-1;\n  let nr,z,shift=0;\n  if(ring<side) {nr=ring;z=1-nr*nr/(3*side*side);}\n  else if(ring>3*side) {nr=4*side-ring;z=-1+nr*nr/(3*side*side);}\n  else {nr=side;z=(2*side-ring)*2/(3*side);shift=(ring-side)%2;}\n  const longitude=(JPLL[face]*nr+x-y+1+shift)/2;\n  const phi=(longitude-(shift+1)/2)*Math.PI/(2*nr),r=Math.sqrt(Math.max(0,1-z*z));\n  return out.set(r*Math.cos(phi),r*Math.sin(phi),z);\n}\n\n/** Complete intersecting levels, not a moving list of nearest individual stars.\n * Coarse levels remain required while deeper levels add catalogue sources.\n * Conservative angular margin plus quantized selection avoids orientation jitter.\n */\nexport function stellarViewTiles(forward,halfAngle,desiredOrder,{maxTiles=384,scratch}={}) {\n  const required=[];let previous=[];\n  for(let face=0;face<12;face++)previous.push(face);\n  for(let order=1;order<=Math.min(11,desiredOrder);order++) {\n    const current=[],threshold=Math.cos(Math.min(Math.PI,halfAngle+2/2**order));\n    for(const parent of previous)for(let child=0;child<4;child++) {\n      const pixel=parent*4+child;healpixDirection(order,pixel,scratch);\n      if(scratch.dot(forward)>=threshold) current.push(pixel);\n    }\n    if(required.length+current.length>maxTiles)break;\n    for(const pixel of current)required.push({order,pixel,key:`${order}/${pixel}`});\n    previous=current;\n  }\n  return required;\n}\n\nexport function validateStellarPacket(buffer) {\n  const view=new DataView(buffer);\n  if(buffer.byteLength<16 || view.getUint32(0,true)!==0x3147434e)throw new Error('Invalid stellar packet');\n  const count=view.getUint32(4,true),stride=view.getUint32(12,true);\n  if(count>4096 || stride!==48 || buffer.byteLength!==16+count*stride)throw new Error('Invalid stellar packet size');\n  const data=new Float32Array(buffer,16);\n  validateStellarRecords(data,count);\n  return {count,total:view.getUint32(8,true),data};\n}\nexport function validateStellarRecords(data,count){\n  for(let n=0;n<count;n++) {\n    const i=n*12, norm=data[i]**2+data[i+1]**2+data[i+2]**2;\n    if(!Number.isFinite(norm)||Math.abs(norm-1)>0.00001 || (!Number.isFinite(data[i+6])&&!Number.isNaN(data[i+6]))\n      || data[i+6]<-3 || data[i+6]>30 || !Number.isFinite(data[i+8]) || data[i+8]<0\n      || ![0,1,2].includes(data[i+9]) || ![3,4,5].every(k=>Number.isFinite(data[i+k])))throw new Error('Invalid stellar record');\n  }\n}\n\nexport const stellarFlux = magnitude => 10**(-0.4*magnitude);\nexport const stellarExposureCompensation = exposure => 1/Math.max(1,Number.isFinite(exposure)?exposure:1);\n\nexport function readFluxPacket(buffer){\n  const view=new DataView(buffer);\n  if(buffer.byteLength!==16+49152*4||view.getUint32(0,true)!==0x3146434e\n    ||view.getUint32(4,true)!==6||view.getUint32(8,true)!==49152)throw new Error('Invalid Gaia flux field');\n  const data=new Float32Array(buffer,16);\n  for(const value of data)if(!Number.isFinite(value)||value<0)throw new Error('Invalid Gaia flux value');\n  return data;\n}\n","import * as THREE from 'three';\nimport { resolveSceneRuntimeResource } from '../refactor/scene/SceneRuntimeResources.js';\nimport {BaryState,Body} from 'astronomy-engine';\nimport {getBackendApiBase} from '../refactor/shared/backend.js';\nimport {getNoclipGovernanceClient} from '../refactor/shared/NoclipGovernanceClient.js';\nimport {readBoundedBytes} from '../refactor/shared/readBoundedBytes.js';\nimport {julianYearsSinceJ2000} from './celestial-frame.js';\nimport {stellarViewTiles,validateStellarPacket,validateStellarRecords,stellarExposureCompensation} from './stellar-catalog-math.js';\n\nexport const STELLAR_LIMITS=Object.freeze({points:131072,basePoints:65536,tiles:384,cacheTiles:512,cacheBytes:8*1024*1024,active:2,packetBytes:16+4096*48});\nexport const STELLAR_BASE_URL=resolveSceneRuntimeResource('/refactor/data/space/stars/gaia-dr3-base.bin');\nconst PC_METERS=3.085677581491367e16,AU_PC=1/206264.80624709636;\n\n/** One points object, fixed-capacity buffers. No per-source Object3D, labels,\n * timers or sorting in the frame loop. HiPS ancestors are additive; exact IDs\n * prevent duplicates across tiles. Camera jitter doesn't change acquisition.\n */\nexport class StellarCatalogRenderer {\n  constructor({group,radius,uniforms,fetchImpl,base=getBackendApiBase(),baseDataUrl=STELLAR_BASE_URL,onFlux=()=>{},brightMatch=()=>false}){\n    Object.assign(this,{group,radius,onFlux,brightMatch});\n    this.request=fetchImpl||((url,init)=>getNoclipGovernanceClient().request(url,{...init,governanceLane:'scene',governanceProblemBodyLimit:8192}));\n    this.base=String(base||'').replace(/\\/+$/,'');\n    this.baseDataUrl=baseDataUrl;this.baseReady=!baseDataUrl;this.baseOffset=0;this.drawn=0;this.baseBatchSize=128;this.baseMaxSliceMs=0;\n    this.pending=new Map();this.cache=new Map();this.cacheBytes=0;this.required=[];this.requiredKeys=new Set();\n    this.resident=new Map();this.ids=new Set();this.free=[];this.used=0;this.drawEnd=0;\n    this.retryAt=0;this.lastSelect=-Infinity;this.lastAstrometry=-Infinity;this.epoch=0;this.uploads=0;this.requests=0;\n    this.direction=new THREE.Vector3();this.lastDirection=new THREE.Vector3();this.scratch=new THREE.Vector3();\n    this.observer=new THREE.Vector3();this.inverse=new THREE.Matrix4();this.drawingBuffer=new THREE.Vector2();\n    this.buffer=new THREE.InterleavedBuffer(new Float32Array(STELLAR_LIMITS.points*12),12).setUsage(THREE.DynamicDrawUsage);\n    this.geometry=new THREE.BufferGeometry();\n    for(const[name,size,offset]of[['position',3,0],['aMotion',3,3],['aMagnitude',1,6],['aColorIndex',1,7],['aDistance',1,8],['aActive',1,9]])\n      this.geometry.setAttribute(name,new THREE.InterleavedBufferAttribute(this.buffer,size,offset));\n    this.geometry.setDrawRange(0,0);\n    this.material=new THREE.ShaderMaterial({uniforms:{...uniforms,uLimbSin:uniforms?.uLimbSin||{value:-1},uRadius:{value:radius},uYears:{value:0},\n      uObserverPc:{value:new THREE.Vector3()},uPixelRatio:{value:1},uFocalPixels:{value:500}},\n      vertexShader:`\n        uniform float uRadius,uYears,uPixelRatio,uFocalPixels;\n        uniform vec3 uObserverPc,uObserverUp;\n        uniform float uAtmosphereWeight,uLimbSin;\n        attribute vec3 aMotion;\n        attribute float aMagnitude,aColorIndex,aDistance,aActive;\n        varying float vFlux,vSize,vHorizon;\n        varying vec3 vColor;\n        #include <common>\n        #include <logdepthbuf_pars_vertex>\n        void main(){\n          vec3 d=normalize(position+aMotion*uYears);\n          float distanceGain=1.0;\n          if(aDistance>0.0){vec3 relative=d*aDistance-uObserverPc;float r=max(length(relative),1e-9);d=relative/r;distanceGain=pow(aDistance/r,2.0);}\n          vec3 worldDirection=normalize((modelMatrix*vec4(d,0.0)).xyz);\n          float sinAlt=dot(worldDirection,uObserverUp);\n          vHorizon=mix(1.0,smoothstep(0.0,0.07,sinAlt),uAtmosphereWeight)*smoothstep(uLimbSin-0.003,uLimbSin+0.003,sinAlt);\n          // Colour is an explicitly approximate broad-band mapping, not a spectrum.\n          float ci=clamp(aColorIndex,-0.5,4.0);\n          vColor=mix(vec3(0.68,0.8,1.0),vec3(1.0,0.63,0.36),clamp((ci+0.5)/4.5,0.0,1.0));\n          vColor/=dot(vColor,vec3(0.2126,0.7152,0.0722));\n          vFlux=aActive>0.5?pow(10.0,-0.4*aMagnitude)*distanceGain:0.0;\n          // A fixed angular PSF, with a two-device-pixel minimum for stable sampling.\n          vSize=max(2.0*uPixelRatio,0.00058*uFocalPixels);\n          gl_PointSize=vSize;\n          vec4 mvPosition=modelViewMatrix*vec4(d*uRadius,1.0);\n          gl_Position=projectionMatrix*mvPosition;\n          if(aActive<0.5)gl_Position=vec4(2.0,2.0,2.0,1.0);\n          #include <logdepthbuf_vertex>\n        }`,\n      fragmentShader:`\n        uniform float uVisibility,uGain,uFocalPixels;\n        varying float vFlux,vSize,vHorizon;\n        varying vec3 vColor;\n        #include <logdepthbuf_pars_fragment>\n        void main(){\n          #include <logdepthbuf_fragment>\n          vec2 p=gl_PointCoord-0.5;float r2=dot(p,p);if(r2>0.25)discard;\n          // Unit-integral truncated Gaussian. Flux ratios are exactly Pogson,\n          // independent of sprite area; shared gain also applies to diffuse flux.\n          float psf=exp(-24.0*r2)*24.0/(3.14159265359*(1.0-exp(-6.0))*vSize*vSize);\n          gl_FragColor=vec4(vColor*vFlux*psf*uFocalPixels*uFocalPixels*uGain*uVisibility*vHorizon,1.0);\n          #include <tonemapping_fragment>\n          #include <colorspace_fragment>\n        }`,transparent:true,depthWrite:false,depthTest:true,blending:THREE.AdditiveBlending});\n    this.mesh=new THREE.Points(this.geometry,this.material);this.mesh.name='GaiaDR3Catalog';this.mesh.frustumCulled=false;\n    this.mesh.raycast=()=>{};this.mesh.userData.noEmissiveTuning=true;group.add(this.mesh);\n    this.visibilityListener=()=>{if(globalThis.document?.hidden)this.cancelPending();};\n    globalThis.document?.addEventListener?.('visibilitychange',this.visibilityListener);\n  }\n  snapshot(){return{catalogSources:1811709771,resolved:this.drawn,residentSources:this.used,baseReady:this.baseReady,residentTiles:this.resident.size,requiredTiles:this.required.length,\n    pending:this.pending.size,cacheBytes:this.cacheBytes,cacheTiles:this.cache.size,uploads:this.uploads,requests:this.requests,baseMaxSliceMs:this.baseMaxSliceMs,\n    status:this.disposed?'disposed':this.suspended?'suspended':Date.now()<this.retryAt?'unavailable':this.baseReady&&this.required.every(t=>this.resident.get(t.key)?.complete)?'ready':'partial'};}\n  update(camera,frame,timeMs,nowMs,renderer){\n    if(this.disposed||this.suspended||globalThis.document?.hidden)return;\n    const u=this.material.uniforms;u.uYears.value=julianYearsSinceJ2000(timeMs)-16;\n    u.uPixelRatio.value=renderer?.getPixelRatio?.()||1;\n    renderer?.getDrawingBufferSize?.(this.drawingBuffer);\n    u.uFocalPixels.value=(this.drawingBuffer.y||600)/(2*Math.tan((camera.fov||60)*Math.PI/360)/(camera.zoom||1));\n    // The night-sky display gain is not coupled to terrain auto-exposure.\n    u.uGain.value=0.00025*stellarExposureCompensation(renderer?.toneMappingExposure);\n    this.inverse.copy(frame.eqjToWorld).invert();\n    if(Math.abs(timeMs-this.lastAstrometry)>60000){\n      const earth=BaryState(Body.Earth,new Date(timeMs));this.observer.set(earth.x,earth.y,earth.z).multiplyScalar(AU_PC);\n      this.lastAstrometry=timeMs;\n    }\n    camera.getWorldPosition(this.scratch).applyMatrix4(this.inverse).multiplyScalar(1/PC_METERS);\n    u.uObserverPc.value.copy(this.observer).add(this.scratch);\n    if(u.uVisibility.value<0.001){this.cancelPending();return;}\n    if(!this.baseReady){\n      if(this.baseBuffer&&!this.basePublishing)this.publishBase();\n      else if(!this.baseBuffer&&!this.pending.has('_base')&&Date.now()>=this.retryAt)this.loadBase();\n      return;\n    }\n    if(nowMs-this.lastSelect<250)return;\n    this.lastSelect=nowMs;\n    camera.getWorldDirection(this.direction).transformDirection(this.inverse);\n    const half=Math.atan(Math.tan((camera.fov||60)*Math.PI/360)/(camera.zoom||1)*Math.hypot(1,camera.aspect||1));\n    if(this.direction.dot(this.lastDirection)<Math.cos(Math.PI/180)||Math.abs(half-(this.lastHalf||0))>0.002||!this.required.length){\n      this.lastDirection.copy(this.direction);this.lastHalf=half;\n      this.required=stellarViewTiles(this.direction,half+0.08,11,{maxTiles:STELLAR_LIMITS.tiles,scratch:this.scratch});\n      this.requiredKeys=new Set(this.required.map(t=>t.key));\n      for(const[key,controller]of this.pending)if(!this.requiredKeys.has(key))controller.abort();\n      for(const key of this.resident.keys())if(!key.startsWith('_base/')&&!this.requiredKeys.has(key))this.evict(key);\n    }\n    // At most one bounded packet publication per selection tick, never a burst\n    // of all completed pages in a render frame.\n    for(const tile of this.required)if(!this.resident.get(tile.key)?.complete&&this.cache.has(tile.key)&&!this.tilePublishing){\n      const packet=this.cache.get(tile.key);this.cache.delete(tile.key);this.cache.set(tile.key,packet);\n      if(this.used+packet.count-(this.resident.get(tile.key)?.offset||0)<=STELLAR_LIMITS.points)this.publishTile(tile.key,packet);break;\n    }\n    if(Date.now()<this.retryAt)return;\n    for(const tile of this.required){\n      if(this.pending.size>=STELLAR_LIMITS.active)break;\n      if(!this.cache.has(tile.key)&&!this.pending.has(tile.key)&&!this.resident.has(tile.key))this.load(tile);\n    }\n  }\n  async publishTile(key,packet){\n    this.tilePublishing=true;\n    try{\n      let owner=this.resident.get(key);\n      let offset=this.resident.get(key)?.offset||0;\n      while(offset<packet.count&&!this.disposed&&!this.suspended&&this.requiredKeys.has(key)){\n        await new Promise(resolve=>setTimeout(resolve,0));\n        if(this.disposed||this.suspended||!this.requiredKeys.has(key)||(owner&&this.resident.get(key)!==owner))return;\n        const count=Math.min(128,packet.count-offset),data=packet.data.subarray(offset*12,(offset+count)*12);\n        this.attach(key,{count,data});offset+=count;\n        const resident=this.resident.get(key);resident.offset=offset;resident.complete=offset===packet.count;owner=resident;\n      }\n      if(!packet.count&&!this.disposed&&!this.suspended&&this.requiredKeys.has(key))this.attach(key,packet);\n    }finally{this.tilePublishing=false;}\n  }\n  async publishBase(){\n    this.basePublishing=true;\n    try{\n      while(this.baseBuffer&&!this.disposed&&!this.suspended&&!globalThis.document?.hidden){\n        await new Promise(resolve=>setTimeout(resolve,0));\n        if(this.disposed||this.suspended||globalThis.document?.hidden)return;\n        this.processBase();\n      }\n    }finally{this.basePublishing=false;}\n  }\n  async loadBase(){\n    const c=new AbortController(),epoch=this.epoch;this.pending.set('_base',c);this.requests++;\n    const timer=setTimeout(()=>c.abort(),30000);\n    try{\n      // [ASYNC-HARNESS:exempt] One scene-owned <=3 MiB same-origin scientific base; bounded streaming, 30s deadline, disposal fence, 512-record incremental publication.\n      const response=await fetch(this.baseDataUrl,{signal:c.signal,credentials:'same-origin',redirect:'error'});\n      if(!response.ok){await response.body?.cancel();throw new Error('Gaia base unavailable');}\n      const bytes=await readBoundedBytes(response,{signal:c.signal,maxBytes:16+STELLAR_LIMITS.basePoints*48});\n      c.signal.throwIfAborted();if(this.disposed||epoch!==this.epoch)return;\n      const view=new DataView(bytes.buffer),count=view.getUint32(4,true);\n      if(view.getUint32(0,true)!==0x3147434e||count>STELLAR_LIMITS.basePoints||bytes.length!==16+count*48||view.getUint32(12,true)!==48)throw new Error('Invalid Gaia base');\n      this.baseBuffer=new Float32Array(bytes.buffer,16);this.baseCount=count;\n    }catch{if(!this.disposed&&!this.suspended&&epoch===this.epoch)this.retryAt=Date.now()+30000;}\n    finally{clearTimeout(timer);if(this.pending.get('_base')===c)this.pending.delete('_base');}\n  }\n  processBase(){\n    const started=performance.now(),count=Math.min(this.baseBatchSize,this.baseCount-this.baseOffset),data=this.baseBuffer.subarray(this.baseOffset*12,(this.baseOffset+count)*12);\n    try{validateStellarRecords(data,count);this.attach('_base/seed',{count,data});}\n    catch{this.retryAt=Date.now()+30000;this.baseBuffer=null;return;}\n    this.baseOffset+=count;\n    const elapsed=performance.now()-started;this.baseMaxSliceMs=Math.max(this.baseMaxSliceMs,elapsed);\n    if(elapsed>3)this.baseBatchSize=Math.max(32,Math.floor(this.baseBatchSize/2));\n    else if(elapsed<1)this.baseBatchSize=Math.min(512,this.baseBatchSize+32);\n    if(this.baseOffset===this.baseCount){this.baseReady=true;this.baseBuffer=null;}\n  }\n  async load(tile){\n    const c=new AbortController(),epoch=this.epoch;this.pending.set(tile.key,c);this.requests++;\n    const timer=setTimeout(()=>c.abort(),25000);\n    try{\n      const response=await this.request(`${this.base}/v1/sky/gaia-dr3/${tile.order}/${tile.pixel}.bin`,{signal:c.signal,credentials:'omit',redirect:'error',headers:{Accept:'application/octet-stream'}});\n      if(!response.ok){await response.body?.cancel();throw new Error(`Gaia HTTP ${response.status}`);}\n      const bytes=await readBoundedBytes(response,{signal:c.signal,maxBytes:STELLAR_LIMITS.packetBytes});\n      c.signal.throwIfAborted();if(this.disposed||epoch!==this.epoch)return;\n      const packet=response.status===204?{count:0,data:new Float32Array(),total:0}:validateStellarPacket(bytes.buffer);\n      while(this.cache.size>=STELLAR_LIMITS.cacheTiles||this.cacheBytes+packet.data.byteLength>STELLAR_LIMITS.cacheBytes){\n        const key=this.cache.keys().next().value;this.cacheBytes-=this.cache.get(key).data.byteLength;this.cache.delete(key);\n      }\n      this.cache.set(tile.key,packet);this.cacheBytes+=packet.data.byteLength;\n    }catch(error){if(!this.disposed&&!this.suspended&&epoch===this.epoch&&(!c.signal.aborted||this.requiredKeys.has(tile.key)))this.retryAt=Date.now()+30000;}\n    finally{clearTimeout(timer);if(this.pending.get(tile.key)===c)this.pending.delete(tile.key);}\n  }\n  attach(key,packet){\n    const resident=this.resident.get(key)||{slots:[],ids:[],complete:true,offset:0};\n    const {slots,ids}=resident,data=this.buffer.array,idView=new DataView(packet.data.buffer,packet.data.byteOffset,packet.data.byteLength);\n    let first=Infinity,last=-1;\n    for(let n=0;n<packet.count;n++){\n      const id=idView.getBigUint64(n*48+40,true).toString();if(this.ids.has(id))continue;\n      const row=packet.data.subarray(n*12,n*12+12);\n      const slot=this.free.length?this.free.pop():this.drawEnd++,offset=slot*12;\n      data.set(row,offset);data[offset+7]=Number.isFinite(row[7])?row[7]:0.8;data[offset+9]=!Number.isFinite(row[6])||this.brightMatch(row)?0:1;\n      this.drawn+=data[offset+9];\n      first=Math.min(first,slot);last=Math.max(last,slot);this.ids.add(id);ids.push(id);slots.push(slot);this.used++;\n      this.onFlux(row,-1);\n    }\n    if(last>=first){this.buffer.addUpdateRange(first*12,(last-first+1)*12);this.buffer.needsUpdate=true;this.uploads++;}\n    this.resident.set(key,resident);this.geometry.setDrawRange(0,this.drawEnd);\n  }\n  evict(key){\n    const tile=this.resident.get(key);if(!tile)return;\n    for(let n=0;n<tile.slots.length;n++){\n      const slot=tile.slots[n],offset=slot*12;this.onFlux(this.buffer.array.subarray(offset,offset+12),1);\n      this.drawn-=this.buffer.array[offset+9];\n      this.buffer.array[offset+9]=0;this.buffer.addUpdateRange(offset+9,1);this.free.push(slot);this.ids.delete(tile.ids[n]);this.used--;\n    }\n    this.resident.delete(key);if(tile.slots.length){this.buffer.needsUpdate=true;this.uploads++;}\n  }\n  cancelPending(){for(const controller of this.pending.values())controller.abort();}\n  setPresentationSuspended(value){\n    if(this.suspended===!!value)return;this.suspended=!!value;this.mesh.visible=!value;\n    if(value){this.epoch++;this.cancelPending();this.geometry.dispose();}else this.lastSelect=-Infinity;\n  }\n  dispose(){\n    if(this.disposed)return;this.disposed=true;this.epoch++;this.cancelPending();\n    this.mesh.removeFromParent();this.geometry.dispose();this.material.dispose();\n    globalThis.document?.removeEventListener?.('visibilitychange',this.visibilityListener);\n    this.cache.clear();this.cacheBytes=0;this.resident.clear();this.ids.clear();this.free.length=0;this.used=this.drawn=0;this.baseBuffer=null;\n  }\n}\n","import * as THREE from 'three';\nimport {readBoundedBytes} from '../refactor/shared/readBoundedBytes.js';\nimport {readFluxPacket,healpixXYDirection,nestedPixel,directionHealpix,GAIA_ZERO_FLUX,stellarFlux} from './stellar-catalog-math.js';\nimport { resolveSceneRuntimeResource } from '../refactor/scene/SceneRuntimeResources.js';\n\nexport const STELLAR_FLUX_URL=resolveSceneRuntimeResource('/refactor/data/space/stars/gaia-dr3-flux.bin');\n// Verified against independent DR3 SUM(phot_g_mean_flux) for NESTED order-6\n// cells 0,10000,30000. CDS order-0 FITS values are lower than their advertised\n// count.s-1.sr-1 by 512^2. Keep the original values and this explicit correction.\nexport const CDS_FLUX_DENSITY_CORRECTION=512*512;\nexport class StellarFluxField{\n  constructor({group,radius,uniforms,fetchImpl=globalThis.fetch}){\n    Object.assign(this,{group,radius,uniforms});this.controller=new AbortController();this.changed=new Set();\n    this.position=new THREE.Vector3();this.status='loading';this.ready=this.load(fetchImpl);\n  }\n  async load(fetchImpl){\n    const signal=this.controller.signal,timer=setTimeout(()=>this.controller.abort(),30000);\n    try{\n      // [ASYNC-HARNESS:exempt] One scene-owned 200 KiB bounded same-origin numerical data stream; 30s deadline and disposal fence, no image decode.\n      const response=await fetchImpl(STELLAR_FLUX_URL,{signal,credentials:'same-origin',redirect:'error'});\n      if(!response.ok){await response.body?.cancel();throw new Error('Gaia flux unavailable');}\n      const bytes=await readBoundedBytes(response,{signal,maxBytes:200*1024});\n      this.source=readFluxPacket(bytes.buffer);this.remaining=new Float64Array(this.source.length);\n      for(let i=0;i<this.source.length;i++)this.remaining[i]=this.source[i]*CDS_FLUX_DENSITY_CORRECTION/GAIA_ZERO_FLUX;\n      const positions=new Float32Array(12*65*65*3),radiance=new Float32Array(12*65*65),indices=new Uint32Array(12*64*64*6);\n      let k=0;\n      // Yield between faces; no 50K-vertex main-thread startup burst.\n      for(let face=0;face<12;face++){\n        await new Promise(resolve=>setTimeout(resolve,0));signal.throwIfAborted();\n        for(let y=0;y<=64;y++)for(let x=0;x<=64;x++){\n          const vertex=face*65*65+y*65+x;\n          healpixXYDirection(64,face,x,y,this.position).toArray(positions,vertex*3);\n          radiance[vertex]=this.vertexFlux(face,x,y);\n        }\n        for(let y=0;y<64;y++)for(let x=0;x<64;x++){\n          const v=face*65*65+y*65+x;indices[k++]=v;indices[k++]=v+1;indices[k++]=v+65;\n          indices[k++]=v+1;indices[k++]=v+66;indices[k++]=v+65;\n        }\n      }\n      signal.throwIfAborted();\n      this.geometry=new THREE.BufferGeometry();this.geometry.setIndex(new THREE.BufferAttribute(indices,1));\n      this.geometry.setAttribute('position',new THREE.BufferAttribute(positions,3));\n      this.attribute=new THREE.BufferAttribute(radiance,1).setUsage(THREE.DynamicDrawUsage);this.geometry.setAttribute('aRadiance',this.attribute);\n      this.material=new THREE.ShaderMaterial({uniforms:{...this.uniforms,uLimbSin:this.uniforms?.uLimbSin||{value:-1},uRadius:{value:this.radius}},\n        vertexShader:`uniform float uRadius;attribute float aRadiance;varying float vRadiance;varying vec3 vDirection;\n          #include <common>\n          #include <logdepthbuf_pars_vertex>\n          void main(){vRadiance=aRadiance;vDirection=(modelMatrix*vec4(position,0.0)).xyz;\n            vec4 mvPosition=modelViewMatrix*vec4(position*uRadius,1.0);gl_Position=projectionMatrix*mvPosition;\n            #include <logdepthbuf_vertex>\n          }`,\n        fragmentShader:`uniform float uGain,uVisibility,uAtmosphereWeight,uLimbSin;uniform vec3 uObserverUp;\n          varying float vRadiance;varying vec3 vDirection;\n          #include <logdepthbuf_pars_fragment>\n          void main(){\n            #include <logdepthbuf_fragment>\n            float sinAlt=dot(normalize(vDirection),uObserverUp);\n            float horizon=mix(1.0,smoothstep(0.0,0.07,sinAlt),uAtmosphereWeight)*smoothstep(uLimbSin-0.003,uLimbSin+0.003,sinAlt);\n            gl_FragColor=vec4(vec3(max(0.0,vRadiance)*uGain*uVisibility*horizon),1.0);\n            #include <tonemapping_fragment>\n            #include <colorspace_fragment>\n          }`,side:THREE.DoubleSide,transparent:true,depthWrite:false,depthTest:true,blending:THREE.AdditiveBlending});\n      this.mesh=new THREE.Mesh(this.geometry,this.material);this.mesh.name='GaiaDR3UnresolvedFlux';this.mesh.frustumCulled=false;\n      this.mesh.renderOrder=-20;this.mesh.raycast=()=>{};this.mesh.userData.noEmissiveTuning=true;\n      this.mesh.visible=!this.suspended;this.group.add(this.mesh);this.status='ready';\n    }catch(error){this.status=signal.aborted?'cancelled':'unavailable';if(!signal.aborted)console.warn('[StellarFluxField]',error.message);}\n    finally{clearTimeout(timer);}\n  }\n  vertexFlux(face,x,y){\n    let sum=0,count=0;\n    for(let dy=-1;dy<=0;dy++)for(let dx=-1;dx<=0;dx++){\n      const ix=x+dx,iy=y+dy;if(ix<0||iy<0||ix>=64||iy>=64)continue;\n      sum+=Math.max(0,this.remaining[nestedPixel(6,face,ix,iy)]);count++;\n    }\n    return count?sum/count:0;\n  }\n  async prime(){\n    this.seeding=true;this.changed.clear();\n    try{\n      for(let face=0;face<12;face++){\n        await new Promise(resolve=>setTimeout(resolve,0));this.controller.signal.throwIfAborted();\n        for(let y=0;y<=64;y++)for(let x=0;x<=64;x++)this.attribute.array[face*65*65+y*65+x]=this.vertexFlux(face,x,y);\n      }\n      this.attribute.clearUpdateRanges();this.attribute.needsUpdate=true;this.seedReady=true;\n    }catch{}finally{this.seeding=false;}\n  }\n  change(row,sign){\n    if(!this.remaining||!Number.isFinite(row[6]))return;\n    this.position.set(row[0],row[1],row[2]);const cell=directionHealpix(6,this.position);\n    this.remaining[cell]+=sign*stellarFlux(row[6])/(4*Math.PI/49152);this.changed.add(cell);\n  }\n  flush(){\n    if(!this.attribute||!this.changed.size)return;\n    for(const cell of this.changed){\n      const face=Math.floor(cell/4096);let bits=cell%4096,x=0,y=0;\n      for(let b=0;b<6;b++){x+=(bits%2)*2**b;bits=Math.floor(bits/2);y+=(bits%2)*2**b;bits=Math.floor(bits/2);}\n      for(let dy=0;dy<=1;dy++)for(let dx=0;dx<=1;dx++){\n        const vertex=face*65*65+(y+dy)*65+x+dx;this.attribute.array[vertex]=this.vertexFlux(face,x+dx,y+dy);\n      }\n    }\n    this.changed.clear();this.attribute.clearUpdateRanges();this.attribute.needsUpdate=true;\n  }\n  setPresentationSuspended(value){this.suspended=!!value;if(this.mesh)this.mesh.visible=!value;if(value)this.geometry?.dispose();}\n  dispose(){this.controller.abort();this.mesh?.removeFromParent();this.geometry?.dispose();this.material?.dispose();this.source=this.remaining=null;this.changed.clear();}\n}\n","/**\n * Focus-driven sky labels. The focus is where the user is looking: the mouse\n * ray on desktop, the centre of view on touch devices (or when the mouse has\n * been idle). The constellation under the focus gets its name and its member\n * stars labelled; elsewhere in view the brightest named stars are labelled,\n * thinning with angular distance from the focus. Opacity follows focus\n * proximity, so labels fade in as attention moves toward them.\n *\n * Data (sky-map.json, scripts/build-sky-catalog.mjs):\n *   designations: [starIndex, properName|null, bayer|null, flamsteed|null, con]\n *   constellations: [abbr, name, raDeg, decDeg, radiusDeg]\n */\nimport { equatorialDirection, properMotionVector } from './celestial-frame.js';\n\nexport const SKY_FOCUS_DEFAULTS = Object.freeze({\n  desktopLimit: 40,\n  mobileLimit: 22,\n  // Members of the focused constellation get this magnitude bonus.\n  focusBonusMag: 3.2,\n  // Magnitude penalty per (angle / half-FOV)²: farther from focus = fewer labels.\n  distancePenaltyMag: 4.5,\n  // Faintest magnitude labelled anywhere / inside the focused constellation.\n  maxMagnitude: 4.6,\n  maxFocusedMagnitude: 6.0,\n  // Extra constellation names shown near (not at) the focus.\n  nearbyConstellations: 3,\n  // Mouse idle before the focus returns to the centre of view.\n  mouseIdleMs: 4000,\n});\n\nconst DEG = Math.PI / 180;\n\n/** Static per-star and per-constellation label records (J2000 + motion). */\nexport function buildSkyLabelRecords({ stars = [], motions = [], designations = [], constellations = [] } = {}) {\n  const conNames = new Map(constellations.map((c) => [c[0], c[1]]));\n  const starRecords = [];\n  const seen = new Set(); // doubles share a designation: keep the brighter (listed first)\n  for (const row of designations) {\n    const [index, proper, bayer, flamsteed, con] = row;\n    const star = stars[index];\n    if (!star) continue;\n    const code = bayer || (flamsteed != null ? String(flamsteed) : null);\n    const designation = code && con ? `${code} ${con}` : null;\n    const name = proper || designation;\n    if (!name || seen.has(name)) continue;\n    seen.add(name);\n    starRecords.push({\n      key: `BSC ${index}`, kind: 'star', name, proper: proper || null, designation, con: con || null,\n      conName: conNames.get(con) || null, bayer: !!bayer, star,\n      direction: equatorialDirection(star[0], star[1]),\n      velocity: properMotionVector(star[0], star[1], ...(motions[index] || [0, 0])),\n    });\n  }\n  const constellationRecords = constellations.map(([abbr, name, ra, dec, radius]) => ({\n    key: `CON ${abbr}`, kind: 'constellation', abbr, name, radius: Math.max(3, radius) * DEG,\n    star: [ra, dec, 2.5], direction: equatorialDirection(ra, dec),\n  }));\n  return { stars: starRecords, constellations: constellationRecords };\n}\n\n/** Angle (radians) between two unit vectors, robust near 0. */\nexport function angleBetween(a, b) {\n  const dx = a.x - b.x, dy = a.y - b.y, dz = a.z - b.z;\n  return 2 * Math.asin(Math.min(1, Math.sqrt(dx * dx + dy * dy + dz * dz) / 2));\n}\n\n/**\n * Pick the labels for this view.\n * @param {object} o\n * @param {Array} o.stars        records with .world (unit, world frame) set\n * @param {Array} o.constellations  records with .world set\n * @param {{x,y,z}} o.focus      unit world focus direction\n * @param {(world) => boolean} o.inView\n * @param {(mag) => number} o.visibility  0..1 naked-eye visibility for a magnitude\n * @param {number} o.halfFov     radians\n * @param {number} o.limit\n * @returns {{ focused: object|null, picks: Array<{record, opacity, priority}> }}\n */\nexport function selectSkyLabels({ stars, constellations, focus, inView, visibility, halfFov, limit, options = SKY_FOCUS_DEFAULTS }) {\n  const o = { ...SKY_FOCUS_DEFAULTS, ...options };\n  const span = Math.max(halfFov, 5 * DEG);\n  // Focused constellation: focus inside its extent, nearest centre relative to size.\n  let focused = null, focusedScore = Infinity;\n  const nearby = [];\n  // Constellation figures need a dark enough sky to read (2nd-magnitude stars).\n  const figuresVisible = visibility(2.5) > 0.1;\n  for (const c of constellations) {\n    if (!c.world || !figuresVisible) continue;\n    const a = angleBetween(c.world, focus);\n    const rel = a / c.radius;\n    if (rel < 1.15 && rel < focusedScore) { focused = c; focusedScore = rel; }\n    if (inView(c.world) && a < span * 1.2) nearby.push({ c, rel, a });\n  }\n  const picks = [];\n  // detail: 1 = name in a column, 0 = icon only (the label system may still add text).\n  if (focused) picks.push({ record: focused, opacity: 1, priority: 9, detail: 1 });\n  nearby.sort((p, q) => p.rel - q.rel);\n  for (const { c, a } of nearby) {\n    if (c === focused) continue;\n    if (picks.length > o.nearbyConstellations) break;\n    picks.push({ record: c, opacity: Math.max(0.25, 0.75 * (1 - a / (span * 1.2))), priority: 6, detail: 1 });\n  }\n  const scored = [];\n  for (const s of stars) {\n    if (!s.world || !inView(s.world)) continue;\n    const mag = s.star[2];\n    const member = focused && s.con === focused.abbr;\n    if (mag > (member ? o.maxFocusedMagnitude : o.maxMagnitude)) continue;\n    if (!member && !s.proper && !s.bayer) continue; // Flamsteed-only: focused constellation only\n    if (visibility(mag) < 0.1) continue;\n    const a = angleBetween(s.world, focus);\n    const t = a / span;\n    const score = mag + o.distancePenaltyMag * t * t - (member ? o.focusBonusMag : 0) - (s.proper ? 0.8 : 0);\n    scored.push({ s, score, t, member });\n  }\n  scored.sort((p, q) => p.score - q.score);\n  const starBudget = Math.max(0, limit - picks.length);\n  for (let i = 0; i < scored.length && i < starBudget; i++) {\n    const { s, t, member } = scored[i];\n    const proximity = Math.max(0, 1 - t * 0.7);\n    // Text for the focused constellation's brighter members and for stars\n    // close to the focus; the rest stay as faint icons.\n    const detail = (member && s.star[2] <= 4.5) || t < 0.35 ? 1 : 0;\n    picks.push({ record: s, opacity: member ? 1 : Math.max(0.3, proximity), priority: member ? 8 : 7, detail });\n  }\n  return { focused, picks };\n}\n","import * as THREE from 'three';\nimport {equatorialDirection,properMotionVector,julianYearsSinceJ2000} from './celestial-frame.js';\nimport {skyObjectVisibility} from './sky-visibility.js';\nimport {StellarCatalogRenderer} from './stellar-catalog-renderer.js';\nimport {StellarFluxField} from './stellar-flux-field.js';\nimport {buildSkyLabelRecords,selectSkyLabels,SKY_FOCUS_DEFAULTS} from './sky-label-focus.js';\n\nexport const SKY_LABEL_LIMIT=SKY_FOCUS_DEFAULTS.desktopLimit;\nconst SKY_LABEL_FADE_MS=320;\nexport const SKY_LANDMARKS=Object.freeze([\n  {name:'Milky Way centre',kind:'galaxies',ra:266.4051,dec:-28.936175,detail:'Direction of Sagittarius A*; the black hole is not optically visible.'},\n  {name:'Large Magellanic Cloud',kind:'galaxies',ra:80.8942,dec:-69.7561,detail:'Satellite galaxy; Gaia catalog stellar distribution.'},\n  {name:'Small Magellanic Cloud',kind:'galaxies',ra:13.1867,dec:-72.8286,detail:'Satellite galaxy; Gaia catalog stellar distribution.'},\n  {name:'Pleiades · M45',kind:'clusters',ra:56.75,dec:24.1167,detail:'Open star cluster in Taurus.'},\n  {name:'Omega Centauri · NGC 5139',kind:'clusters',ra:201.697,dec:-47.4795,detail:'Globular cluster; Gaia catalog stellar distribution.'},\n]);\n\n/** Catalogue infill and numerical unresolved light. No sky images, textures,\n * procedural stars or per-star scene nodes. Shared labels remain bounded.\n */\nexport class SkyFeatures{\n  constructor({group,radius,labels,named=[],stars=[],motions=[],designations=[],constellations=[],uniforms,catalogOptions={}}){\n    Object.assign(this,{group,radius,labels,uniforms});\n    this.focusRecords=buildSkyLabelRecords({stars,motions,designations,constellations});\n    this._labelState=new Map();this._pins=new Map();this.labelKinds={constellations:true,stars:true,clusters:true,galaxies:true,nebulae:true};this._focusNdc={x:0,y:0,t:-Infinity};this._lastFadeMs=null;\n    this._coarse=typeof matchMedia==='function'&&matchMedia('(pointer: coarse)').matches;\n    this._onPointerMove=e=>{\n      if(e.pointerType&&e.pointerType!=='mouse')return;\n      const w=globalThis.innerWidth||1,h=globalThis.innerHeight||1;\n      this._focusNdc={x:(e.clientX/w)*2-1,y:-(e.clientY/h)*2+1,t:performance.now()};\n    };\n    globalThis.addEventListener?.('pointermove',this._onPointerMove,{passive:true});\n    uniforms.uGain={value:0.00025};\n    this.handles=new Map();this._selected=new Set();this.lastLabelsMs=-Infinity;\n    this._world=new THREE.Vector3();this._direction=new THREE.Vector3();this._forward=new THREE.Vector3();this._camera=new THREE.Vector3();\n    this._focus=new THREE.Vector3();this._ndc=new THREE.Vector3();this._labelPosition=new THREE.Vector3();\n    this.records=named.slice(0,80).map(n=>({...n,key:`HR ${n.hr}`,direction:equatorialDirection(n.star[0],n.star[1]),\n      velocity:properMotionVector(n.star[0],n.star[1],...(n.motion||[0,0]))}));\n    this.records.push(...SKY_LANDMARKS.map(n=>({...n,key:n.name,star:[n.ra,n.dec,5.5],direction:equatorialDirection(n.ra,n.dec),velocity:new THREE.Vector3()})));\n    // BSC5 owns bright-star names. Match Gaia at its 2016 epoch in a sparse\n    // Cartesian index, not by a different-band magnitude cut.\n    this.brightIndex=new Map();const scale=1000;\n    stars.forEach((star,i)=>{\n      const direction=equatorialDirection(star[0],star[1]).addScaledVector(properMotionVector(star[0],star[1],...(motions[i]||[0,0])),16).normalize();\n      const key=[direction.x,direction.y,direction.z].map(v=>Math.floor(v*scale)).join('/');\n      if(!this.brightIndex.has(key))this.brightIndex.set(key,[]);this.brightIndex.get(key).push(direction);\n    });\n    const brightMatch=row=>{\n      const x=Math.floor(row[0]*scale),y=Math.floor(row[1]*scale),z=Math.floor(row[2]*scale);\n      for(let dx=-1;dx<=1;dx++)for(let dy=-1;dy<=1;dy++)for(let dz=-1;dz<=1;dz++){\n        const candidates=this.brightIndex.get(`${x+dx}/${y+dy}/${z+dz}`);\n        // Chord distance avoids float32 dot-product errors exceeding the match radius.\n        if(candidates?.some(d=>(d.x-row[0])**2+(d.y-row[1])**2+(d.z-row[2])**2<(5*Math.PI/648000)**2))return true;\n      }\n      return false;\n    };\n    this.flux=new StellarFluxField({group,radius,uniforms,...catalogOptions.flux});\n    this.catalog=new StellarCatalogRenderer({group,radius,uniforms,brightMatch,onFlux:(row,sign)=>this.flux.change(row,sign),...catalogOptions});\n    this.ready=this.flux.ready;\n  }\n  get status(){return this.disposed?'cancelled':this.flux.status;}\n  get mesh(){return this.flux.mesh;}\n  update(camera,frame,timeMs,limitingMagnitude,nowMs,renderer){\n    if(this.disposed||this.suspended)return;\n    this.uniforms.uVisibility.value=skyObjectVisibility(6.1,limitingMagnitude);\n    if(this.flux.status==='ready')this.catalog.update(camera,frame,timeMs,nowMs,renderer);\n    if(this.catalog.baseReady&&!this.flux.seedReady&&!this.flux.seeding&&this.flux.status==='ready')this.flux.prime();\n    if(this.flux.mesh)this.flux.mesh.visible=!!this.flux.seedReady;\n    if(this.flux.seedReady)this.flux.flush();\n    this._fadeLabels(nowMs);\n    if(nowMs-this.lastLabelsMs<200)return;this.lastLabelsMs=nowMs;\n    const enabled=this.labels.isLabelProjectionEnabled({_projectionOnly:true,type:'celestial',metadata:{}});\n    for(const state of this._labelState.values())state.target=0;\n    if(enabled)this._selectLabels(camera,frame,timeMs,limitingMagnitude);\n    // Search picks stay labelled until their pin expires.\n    for(const[key,pin]of this._pins){\n      if(nowMs>pin.until||!enabled){this._pins.delete(key);continue;}\n      this._showLabel({record:pin.record,opacity:1,priority:10,detail:2});\n    }\n  }\n  /** Catalog objects (stars, constellations, landmarks) currently in view.\n   * Positions are from the last label pass (≤200 ms old). */\n  findInView(){\n    if(!this._inView)return[];\n    const out=[];\n    for(const r of[...this.focusRecords.stars,...this.focusRecords.constellations,...this.records.filter(r=>r.detail)]){\n      if(!r.world||!r.eq)continue;\n      const kind=r.kind==='star'?'stars':r.kind==='constellation'?'constellations':r.kind;\n      if(this.labelKinds[kind]===false)continue;\n      if(this._inView(r.world))out.push(r);\n    }\n    return out;\n  }\n  /** Label a catalog object (from search) and return its handle. */\n  pinLabel(record,ms=20000){\n    this._pins.set(record.key,{record,until:performance.now()+ms});\n    this._showLabel({record,opacity:1,priority:10,detail:2});\n    return this._labelState.get(record.key)?.handle||null;\n  }\n  /** Which celestial kinds may be labelled: constellations, stars, clusters, galaxies, nebulae. */\n  setLabelKinds(kinds={}){\n    for(const key of Object.keys(this.labelKinds))if(typeof kinds[key]==='boolean')this.labelKinds[key]=kinds[key];\n    this.lastLabelsMs=-Infinity;\n  }\n  /** Where attention is: the mouse ray, or the view centre on touch / idle mouse. */\n  _focusDirection(camera){\n    const idle=this._coarse||performance.now()-this._focusNdc.t>SKY_FOCUS_DEFAULTS.mouseIdleMs;\n    const x=idle?0:this._focusNdc.x,y=idle?0:this._focusNdc.y;\n    return this._focus.set(x,y,0.5).unproject(camera).sub(this._camera).normalize();\n  }\n  _selectLabels(camera,frame,timeMs,limitingMagnitude){\n    camera.getWorldDirection(this._forward);camera.getWorldPosition(this._camera);\n    camera.updateMatrixWorld?.();\n    const years=julianYearsSinceJ2000(timeMs),up=this.uniforms.uObserverUp.value,atmosphere=this.uniforms.uAtmosphereWeight.value>0.1;\n    const toWorld=(record)=>{\n      const d=this._direction.copy(record.direction);if(record.velocity)d.addScaledVector(record.velocity,years);\n      d.normalize();record.eq=record.eq||new THREE.Vector3();record.eq.copy(d);\n      record.world=record.world||new THREE.Vector3();return record.world.copy(d).applyMatrix4(frame.eqjToWorld).normalize();\n    };\n    const ndc=this._ndc;\n    const inView=this._inView=w=>{\n      if(w.dot(this._forward)<0.2)return false;\n      if(atmosphere&&w.dot(up)<0.02)return false;\n      if(w.dot(up)<(this.uniforms.uLimbSin?.value??-1))return false; // behind the Earth\n      ndc.copy(w).multiplyScalar(this.radius).add(this._camera).project(camera);\n      return Math.abs(ndc.x)<1.02&&Math.abs(ndc.y)<1.02;\n    };\n    const kinds=this.labelKinds;\n    const stars=kinds.stars?this.focusRecords.stars:[];\n    // Constellations always steer the focus; their names show only if enabled.\n    const constellations=this.focusRecords.constellations;\n    for(const r of stars)toWorld(r);for(const r of constellations)toWorld(r);\n    const halfFov=((camera.fov||60)*Math.PI/180)/2;\n    const limit=this._coarse?SKY_FOCUS_DEFAULTS.mobileLimit:SKY_FOCUS_DEFAULTS.desktopLimit;\n    let {picks}=selectSkyLabels({stars,constellations,focus:this._focusDirection(camera),inView,halfFov,limit,\n      visibility:mag=>skyObjectVisibility(mag,limitingMagnitude)});\n    if(!kinds.constellations)picks=picks.filter(p=>p.record.kind!=='constellation');\n    // Landmarks (galaxies, clusters) when in view.\n    for(const record of this.records){\n      if(!record.detail||kinds[record.kind]===false||skyObjectVisibility(record.star[2],limitingMagnitude)<0.1)continue;\n      if(inView(toWorld(record)))picks.push({record,opacity:0.85,priority:8});\n    }\n    for(const pick of picks)this._showLabel(pick);\n  }\n  _labelOptions(record,priority){\n    const base={type:'celestial',maxDistance:this.radius*100,objectRadius:1,labelPriority:priority,treeShyness:true};\n    const coords={raDegrees:record.star[0],decDegrees:record.star[1],coordinateFrame:'J2000.0'};\n    if(record.kind==='constellation')return{...base,subText:`Constellation · ${record.abbr}`,\n      metadata:{celestial:true,typeLabel:'Constellation',catalogId:record.abbr,...coords,magnitude:null,\n        source:'IAU constellation; centre of its Yale Bright Star Catalog members',sourceUrl:'https://cdsarc.cds.unistra.fr/ftp/cats/V/50/ReadMe',\n        semanticNotice:'Label sits at the brightness-weighted centre of the constellation\\'s catalogued stars.'}};\n    if(record.kind==='star'){\n      const parts=[record.proper&&record.designation?record.designation:null,record.conName,`magnitude ${record.star[2]}`].filter(Boolean);\n      return{...base,subText:parts.join(' · '),metadata:{celestial:true,typeLabel:'Catalog star',catalogId:record.designation||record.key,...coords,\n        magnitude:record.star[2],source:'Yale Bright Star Catalog, 5th Revised Edition',sourceUrl:'https://cdsarc.cds.unistra.fr/ftp/cats/V/50/ReadMe',\n        semanticNotice:'Catalog position advanced by proper motion, precession and nutation. Clear-sky visibility model; not observed weather.'}};\n    }\n    return{...base,subText:record.detail,metadata:{celestial:true,typeLabel:record.kind==='clusters'?'Star cluster':record.kind==='galaxies'?'Galaxy':'Sky landmark',catalogId:record.key,...coords,magnitude:null,\n      source:'ESA Gaia DR3 / CDS',sourceUrl:'https://www.cosmos.esa.int/web/gaia/dr3',semanticNotice:record.detail}};\n  }\n  _showLabel({record,opacity,priority,detail=0}){\n    let state=this._labelState.get(record.key);\n    const position=this._labelPosition.copy(record.eq).multiplyScalar(this.radius);\n    if(!state){\n      const handle=this.labels.createLabel(record.name,{...this._labelOptions(record,priority),position,opacity:0});\n      handle.opacity=0;this.group.add(handle.group);\n      state={handle,opacity:0,target:opacity};this._labelState.set(record.key,state);this.handles.set(record.key,handle);\n    }else{state.target=opacity;this.labels.updatePosition(state.handle,position);}\n    state.handle.focusDetail=detail;\n  }\n  /** Ease each label toward its target opacity; dispose once faded out. */\n  _fadeLabels(nowMs){\n    const dt=this._lastFadeMs==null?16:Math.min(250,Math.max(0,nowMs-this._lastFadeMs));this._lastFadeMs=nowMs;\n    const k=1-Math.exp(-dt/SKY_LABEL_FADE_MS*3);\n    for(const[key,state]of this._labelState){\n      state.opacity+=(state.target-state.opacity)*k;\n      if(state.target===0&&state.opacity<0.02){state.handle.dispose();this._labelState.delete(key);this.handles.delete(key);continue;}\n      state.handle.opacity=state.opacity;\n    }\n  }\n  setPresentationSuspended(value){\n    this.suspended=!!value;this.catalog.setPresentationSuspended(value);this.flux.setPresentationSuspended(value);\n    if(value){for(const handle of this.handles.values())handle.dispose();this.handles.clear();this._labelState.clear();}else this.lastLabelsMs=-Infinity;\n  }\n  dispose(){\n    this.disposed=true;this.catalog.dispose();this.flux.dispose();\n    globalThis.removeEventListener?.('pointermove',this._onPointerMove);this._labelState.clear();\n    for(const handle of this.handles.values())handle.dispose();this.handles.clear();this.brightIndex.clear();\n  }\n}\n","/**\n * FirstDrawGuard — keeps shader program linking out of the render loop.\n *\n * Turning a layer on adds objects whose materials have never been drawn.\n * WebGLRenderer compiles their programs inside render() and then blocks on\n * getProgramParameter(LINK_STATUS): measured 300-650 ms frames when toggling\n * layers. Before each frame this guard walks the visible scene; an object\n * whose program is not linked yet is hidden for that frame and its program is\n * compiled with renderer.compileAsync (parallel on drivers with\n * KHR_parallel_shader_compile). It appears once program.isReady() reports\n * true — a frame or a few later — instead of freezing the frame.\n *\n * Materials whose shader type already has a linked program (same class /\n * shader source / cache key) draw immediately: three reuses the cached\n * program, so new tiles and instances of known materials are never delayed.\n * A material still not ready after `maxWaitMs` is released so nothing can be\n * hidden indefinitely.\n *\n * Streaming terrain (photoreal tiles, Mapsource globe, TriTree tiles) opts\n * out with userData.firstDrawGuard = false on its root: a tile held back\n * while its parent has already been unloaded leaves a visible gap.\n */\nexport const FIRST_DRAW_GUARD_DEFAULTS = Object.freeze({ maxWaitMs: 4000 });\n\nconst drawable = (object) => object.isMesh || object.isPoints || object.isLine || object.isSprite;\n\n/** Program-family key: same key ⇒ three can reuse an already linked program. */\nexport function materialProgramKey(material) {\n  if (!material) return '';\n  const custom = typeof material.customProgramCacheKey === 'function' ? material.customProgramCacheKey() : '';\n  if (material.isShaderMaterial || material.isRawShaderMaterial) {\n    const v = material.vertexShader || '', f = material.fragmentShader || '';\n    return `${material.type}|${v.length}:${v.slice(-48)}|${f.length}:${f.slice(-48)}|${JSON.stringify(material.defines || {})}|${custom}`;\n  }\n  return `${material.type}|${!!material.map}|${!!material.envMap}|${material.vertexColors}|${custom}`;\n}\n\nexport class FirstDrawGuard {\n  constructor(renderer, options = {}) {\n    this.renderer = renderer;\n    this.o = { ...FIRST_DRAW_GUARD_DEFAULTS, ...options };\n    this.enabled = true;\n    this._ready = new WeakSet();\n    this._readyKeys = new Set();\n    this._pending = new WeakMap(); // material → start time (ms)\n    this._compiledVersion = new WeakMap(); // material → version we compiled\n    this._readyVersion = new WeakMap(); // material → version known linked\n    this._hidden = [];\n    this.stats = { hiddenLastFrame: 0, compilesStarted: 0, released: 0 };\n  }\n\n  _status(material, object, camera, scene, now) {\n    const props = this.renderer.properties?.get?.(material) || {};\n    const version = material.version;\n    // three stores the drawn version only in render(); needsUpdate (new\n    // defines / shader) bumps material.version and relinks on the next draw.\n    const drawnVersion = props.__version;\n    if (this._ready.has(material)) {\n      if (drawnVersion === undefined || drawnVersion === version || this._readyVersion.get(material) === version) return true;\n      this._ready.delete(material);\n    }\n    const program = props.currentProgram;\n    const compiledFor = this._compiledVersion.get(material);\n    if (program && (drawnVersion === version || compiledFor === version || (drawnVersion === undefined && compiledFor === undefined))) {\n      if (typeof program.isReady === 'function' && !program.isReady()) {\n        const started = this._pending.get(material) ?? now;\n        if (!this._pending.has(material)) this._pending.set(material, now);\n        if (now - started < this.o.maxWaitMs) return false;\n        this.stats.released += 1;\n      }\n      return this._markReady(material, version);\n    }\n    if (!program && this._readyKeys.has(materialProgramKey(material))) return this._markReady(material, version);\n    if (compiledFor !== version) {\n      this._compiledVersion.set(material, version);\n      this._pending.set(material, now);\n      this.stats.compilesStarted += 1;\n      try {\n        this.renderer.compileAsync(object, camera, scene)?.catch?.(() => this._markReady(material, version));\n      } catch {\n        return this._markReady(material, version);\n      }\n      return false;\n    }\n    if (now - (this._pending.get(material) ?? now) >= this.o.maxWaitMs) {\n      this.stats.released += 1;\n      return this._markReady(material, version);\n    }\n    return false;\n  }\n\n  _markReady(material, version) {\n    this._ready.add(material);\n    this._readyVersion.set(material, version);\n    this._readyKeys.add(materialProgramKey(material));\n    this._pending.delete(material);\n    return true;\n  }\n\n  /** Hide not-yet-linked objects for this frame. Call right before rendering. */\n  beforeRender(scene, camera) {\n    this._hidden.length = 0;\n    if (!this.enabled || !scene || !camera || typeof this.renderer?.compileAsync !== 'function') return;\n    const now = typeof performance !== 'undefined' ? performance.now() : Date.now();\n    const visit = (object) => {\n      // Opted-out subtrees (streaming terrain) are never held back.\n      if (object.visible === false || object.userData?.firstDrawGuard === false) return;\n      if (drawable(object)) {\n        const materials = Array.isArray(object.material) ? object.material : [object.material];\n        for (const material of materials) {\n          if (!material || this._status(material, object, camera, scene, now)) continue;\n          object.visible = false;\n          this._hidden.push(object);\n          break;\n        }\n      }\n      const children = object.children;\n      for (let i = 0; i < children.length; i++) visit(children[i]);\n    };\n    visit(scene);\n    this.stats.hiddenLastFrame = this._hidden.length;\n  }\n\n  /** Restore what beforeRender hid. Call right after rendering. */\n  afterRender() {\n    for (const object of this._hidden) if (object.visible === false) object.visible = true;\n    this._hidden.length = 0;\n  }\n}\n","import * as THREE from 'three';\nimport { AfterimageShader } from 'three/addons/shaders/AfterimageShader.js';\nimport { Pass, CopyMaterial } from 'postprocessing';\n\nexport class MotionBlurPass extends Pass {\n    constructor({ damp = 0.96 } = {}) {\n        super('MotionBlurPass');\n\n        this.uniforms = {\n            damp: { value: damp },\n            tOld: { value: null },\n            tNew: { value: null }\n        };\n\n        this._compMaterial = new THREE.ShaderMaterial({\n            name: 'MotionBlurComposite',\n            uniforms: this.uniforms,\n            vertexShader: `\n                varying vec2 vUv;\n                void main() {\n                    vUv = position.xy * 0.5 + 0.5;\n                    gl_Position = vec4(position.xy, 1.0, 1.0);\n                }\n            `,\n            fragmentShader: AfterimageShader.fragmentShader,\n            depthTest: false,\n            depthWrite: false,\n            toneMapped: false\n        });\n\n        this._copyMaterial = new CopyMaterial();\n\n        this._textureComp = new THREE.WebGLRenderTarget(1, 1, {\n            minFilter: THREE.NearestFilter,\n            magFilter: THREE.NearestFilter,\n            type: THREE.HalfFloatType,\n            depthBuffer: false,\n            stencilBuffer: false\n        });\n        this._textureOld = this._textureComp.clone();\n        this._needsReset = true;\n    }\n\n    get damp() {\n        return this.uniforms.damp.value;\n    }\n\n    set damp(value) {\n        this.uniforms.damp.value = value;\n    }\n\n    reset() {\n        this._needsReset = true;\n    }\n\n    render(renderer, inputBuffer, outputBuffer) {\n        if (this._needsReset) {\n            this._copyMaterial.inputBuffer = inputBuffer.texture;\n            this.fullscreenMaterial = this._copyMaterial;\n            renderer.setRenderTarget(this._textureOld);\n            renderer.render(this.scene, this.camera);\n            this._needsReset = false;\n        }\n\n        this.uniforms.tOld.value = this._textureOld.texture;\n        this.uniforms.tNew.value = inputBuffer.texture;\n        this.fullscreenMaterial = this._compMaterial;\n        renderer.setRenderTarget(this._textureComp);\n        renderer.render(this.scene, this.camera);\n\n        this._copyMaterial.inputBuffer = this._textureComp.texture;\n        this.fullscreenMaterial = this._copyMaterial;\n        renderer.setRenderTarget(this.renderToScreen ? null : outputBuffer);\n        if (this.clear) renderer.clear();\n        renderer.render(this.scene, this.camera);\n\n        const temp = this._textureOld;\n        this._textureOld = this._textureComp;\n        this._textureComp = temp;\n    }\n\n    setSize(width, height) {\n        this._textureComp.setSize(width, height);\n        this._textureOld.setSize(width, height);\n    }\n\n    dispose() {\n        this._textureComp.dispose();\n        this._textureOld.dispose();\n        this._compMaterial.dispose();\n        this._copyMaterial.dispose();\n    }\n}\n","/**\n * Lens modifier contract (scene.lens): defaults, tuneable limits and the\n * thin-lens circle of confusion. Dependency-free so the settings registry\n * and tests can import it without three.js or postprocessing.\n */\nexport const LENS_DEFAULTS = Object.freeze({\n  chromaticAberration: Object.freeze({ enabled: true, strength: 5.5 }),\n  depthOfField: Object.freeze({\n    enabled: true,\n    autofocus: true,\n    focusDistance: 50,\n    focalLength: 100,\n    fStop: 1.4,\n    maxBlur: 32,\n    samples: 40,\n    focusResponse: 4,\n  }),\n  // Sensor grain (FilmGrainEffect): strength × photon/read noise, chroma × mottling.\n  filmGrain: Object.freeze({ enabled: true, strength: 1, chroma: 1.1 }),\n  // Final grade (ColorGradeEffect): CSS contrast/brightness/saturate equivalents.\n  colorGrade: Object.freeze({ enabled: true, contrast: 1.1, brightness: 1.1, saturation: 1.1 }),\n});\n\nexport const LENS_LIMITS = Object.freeze({\n  'chromaticAberration.strength': [0, 14],\n  'depthOfField.focusDistance': [0.5, 100000],\n  'depthOfField.focalLength': [12, 400],\n  'depthOfField.fStop': [0.95, 22],\n  'depthOfField.maxBlur': [2, 64],\n  'depthOfField.samples': [8, 64],\n  'depthOfField.focusResponse': [0.5, 20],\n  'filmGrain.strength': [0, 2.5],\n  'filmGrain.chroma': [0, 3],\n  'colorGrade.contrast': [0.5, 2],\n  'colorGrade.brightness': [0.5, 2],\n  'colorGrade.saturation': [0, 2],\n});\n\nconst finite = (value, fallback) => (Number.isFinite(Number(value)) ? Number(value) : fallback);\nconst clampTo = (key, value, fallback) => {\n  const [lo, hi] = LENS_LIMITS[key];\n  return Math.min(hi, Math.max(lo, finite(value, fallback)));\n};\n\n/** Merge a (partial) scene.lens patch onto a complete, clamped config. */\nexport function normalizeLensConfig(patch = {}, base = LENS_DEFAULTS) {\n  const ca = { ...base.chromaticAberration, ...(patch?.chromaticAberration || {}) };\n  const dof = { ...base.depthOfField, ...(patch?.depthOfField || {}) };\n  const grain = { ...(base.filmGrain || LENS_DEFAULTS.filmGrain), ...(patch?.filmGrain || {}) };\n  const grade = { ...(base.colorGrade || LENS_DEFAULTS.colorGrade), ...(patch?.colorGrade || {}) };\n  return {\n    chromaticAberration: {\n      enabled: ca.enabled === true,\n      strength: clampTo('chromaticAberration.strength', ca.strength, LENS_DEFAULTS.chromaticAberration.strength),\n    },\n    depthOfField: {\n      enabled: dof.enabled === true,\n      autofocus: dof.autofocus !== false,\n      focusDistance: clampTo('depthOfField.focusDistance', dof.focusDistance, LENS_DEFAULTS.depthOfField.focusDistance),\n      focalLength: clampTo('depthOfField.focalLength', dof.focalLength, LENS_DEFAULTS.depthOfField.focalLength),\n      fStop: clampTo('depthOfField.fStop', dof.fStop, LENS_DEFAULTS.depthOfField.fStop),\n      maxBlur: clampTo('depthOfField.maxBlur', dof.maxBlur, LENS_DEFAULTS.depthOfField.maxBlur),\n      samples: Math.round(clampTo('depthOfField.samples', dof.samples, LENS_DEFAULTS.depthOfField.samples)),\n      focusResponse: clampTo('depthOfField.focusResponse', dof.focusResponse, LENS_DEFAULTS.depthOfField.focusResponse),\n    },\n    filmGrain: {\n      enabled: grain.enabled === true,\n      strength: clampTo('filmGrain.strength', grain.strength, LENS_DEFAULTS.filmGrain.strength),\n      chroma: clampTo('filmGrain.chroma', grain.chroma, LENS_DEFAULTS.filmGrain.chroma),\n    },\n    colorGrade: {\n      enabled: grade.enabled !== false,\n      contrast: clampTo('colorGrade.contrast', grade.contrast, LENS_DEFAULTS.colorGrade.contrast),\n      brightness: clampTo('colorGrade.brightness', grade.brightness, LENS_DEFAULTS.colorGrade.brightness),\n      saturation: clampTo('colorGrade.saturation', grade.saturation, LENS_DEFAULTS.colorGrade.saturation),\n    },\n  };\n}\n\n/** Signed thin-lens CoC diameter in pixels (CPU mirror of the shader). */\nexport function thinLensCocPixels({ depth, focus, focalLength, fStop, pixelFocal }) {\n  const f = focalLength / 1000;\n  const aperture = f / fStop;\n  return aperture * pixelFocal * (depth - focus) / (depth * Math.max(focus - f, 1e-3));\n}\n","// Equirectangular longitude is periodic. Implicit derivatives of fract(atan2)\n// jump by almost an entire texture at the dateline, selecting the coarsest mip\n// for just the fragment quad crossing it. RepeatWrapping cannot fix that LOD.\n// Keep the original footprint everywhere else, with one ordinary filtered fetch.\nexport const WRAPPED_CLOUD_SAMPLING_GLSL = `\nvec4 ncaSampleWrappedClouds(sampler2D cloudMap, vec2 uv) {\n  vec2 dx = dFdx(uv);\n  vec2 dy = dFdy(uv);\n  dx.x -= floor(dx.x + 0.5);\n  dy.x -= floor(dy.x + 0.5);\n  return textureGrad(cloudMap, uv, dx, dy);\n}\n// Biased variant (texture2D's third argument): scale the footprint by 2^bias.\nvec4 ncaSampleWrappedClouds(sampler2D cloudMap, vec2 uv, float bias) {\n  vec2 dx = dFdx(uv);\n  vec2 dy = dFdy(uv);\n  dx.x -= floor(dx.x + 0.5);\n  dy.x -= floor(dy.x + 0.5);\n  float scale = exp2(bias);\n  return textureGrad(cloudMap, uv, dx * scale, dy * scale);\n}\n`;\n\n// Run after the dry-water adapter so its exact signatures and derivative/helper\n// lane placement remain intact. Only known periodic cloud samplers are changed.\nexport function wrapCloudMapSampling(shader, samplers) {\n  let changed = false;\n  for (const sampler of samplers) {\n    if (!/^[A-Za-z_]\\w*$/.test(sampler)) throw new TypeError('Invalid cloud sampler');\n    shader = shader.replace(new RegExp(`\\\\btexture2D\\\\(\\\\s*${sampler}\\\\s*,`, 'g'), () => {\n      changed = true;\n      return `ncaSampleWrappedClouds(${sampler},`;\n    });\n  }\n  return changed && !shader.includes('vec4 ncaSampleWrappedClouds(')\n    ? WRAPPED_CLOUD_SAMPLING_GLSL + shader : shader;\n}\n","// Shared geographic classification. R = all mapped water, G = valid tile,\n// B = ocean. Inland water can reflect at its native terrain height; it must\n// never acquire the sea-level ocean mesh or the ocean's navigation floor.\nexport function waterCoverageUniforms(source) {\n    return Object.fromEntries(Object.entries({\n        ncaWaterGlobalMask: source.specularTexture,\n        ncaWaterGlobalEnabled: source.waterMaskEnabled || source.specularEnabled,\n        ncaWaterRegionalMask: source.regionalWaterMask,\n        ncaWaterRegionalBounds: source.regionalWaterBounds,\n        ncaWaterRegionalEnabled: source.regionalWaterEnabled,\n        ncaWaterLocalFrame: source.waterLocalFrame,\n        ncaWaterLocalLatitude: source.waterLocalLatitude,\n        ncaWaterGeoid: source.waterSurfaceGeoid,\n        ncaWaterSeaHeight: source.waterSurfaceSeaHeight,\n        ncaWaterDatumReady: source.waterSurfaceDatumReady,\n        ncaWaterSurfaceHeightRange: source.waterSurfaceHeightRange,\n        ncaWaterSurfaceHeightEnabled: source.waterSurfaceHeightEnabled,\n        ncaWaterBed: source.waterBedTexture,\n        ncaWaterBedBounds: source.waterBedBounds,\n        ncaWaterBedEnabled: source.waterBedEnabled,\n        ncaWaterKd: source.waterDiffuseAttenuation,\n    }).filter(([, uniform]) => uniform));\n}\n\nexport const WATER_GEOMETRY_GLSL = /* glsl */`\nvec3 ncaWaterGeodeticNormal(vec3 direction) {\n  if (dot(direction,direction) > 1e12) {\n    // Bowring latitude for actual WGS84 positions, including elevated lakes.\n    // The surface-only y/(1-e²) shortcut drifts metres at kilometre heights.\n    // Use normalized pairs instead of subtracting absolute atan results.\n    float horizontal = length(direction.xz);\n    vec2 theta = normalize(vec2(horizontal * 6356752.314245, direction.y * 6378137.0));\n    vec2 latitude = normalize(vec2(horizontal - 42697.672707 * theta.x*theta.x*theta.x,\n      direction.y + 42841.311513 * theta.y*theta.y*theta.y));\n    return vec3(direction.x / max(horizontal,1e-6) * latitude.x,\n      latitude.y, direction.z / max(horizontal,1e-6) * latitude.x);\n  }\n  return normalize(vec3(direction.x, direction.y / 0.9933056200098587, direction.z));\n}\nfloat ncaWaterReferenceRadius(vec3 direction) {\n  vec3 d = normalize(direction);\n  return 6378137.0 * inversesqrt(1.0 + 0.006739496742276434 * d.y * d.y);\n}\nfloat ncaOrbitalWaterBlend(float altitude) {\n  return smoothstep(20000.0, 120000.0, altitude);\n}\n`;\n\nexport const WATER_COVERAGE_GLSL = /* glsl */`\n${WATER_GEOMETRY_GLSL}\nuniform sampler2D ncaWaterGlobalMask, ncaWaterRegionalMask;\nuniform float ncaWaterGlobalEnabled, ncaWaterRegionalEnabled;\nuniform vec4 ncaWaterRegionalBounds;\nuniform mat3 ncaWaterLocalFrame;\nuniform vec2 ncaWaterLocalLatitude;\nuniform float ncaWaterGeoid, ncaWaterSeaHeight, ncaWaterDatumReady;\nuniform vec2 ncaWaterSurfaceHeightRange;\nuniform float ncaWaterSurfaceHeightEnabled;\nuniform sampler2D ncaWaterBed;\nuniform vec4 ncaWaterBedBounds;\nuniform float ncaWaterBedEnabled;\nuniform vec3 ncaWaterKd;\nvec2 ncaWaterUv(vec3 direction) {\n  vec3 d = normalize(direction);\n  return vec2(fract(atan(d.x, d.z) / 6.28318530718 + 0.5),\n    0.5 - atan(d.y / 0.9933056200098587, length(d.xz)) / 3.14159265359);\n}\nvec2 ncaWaterMercatorUv(vec3 direction) {\n  float s = clamp(ncaWaterGeodeticNormal(direction).y, -0.99627207622, 0.99627207622);\n  return vec2(ncaWaterUv(direction).x, 0.5 - log((1.0+s)/(1.0-s)) / 12.56637061436);\n}\nvec2 ncaWaterGlobalUv(vec3 direction) {\n  vec2 uv = ncaWaterUv(direction);\n  // The bundled mask's final PNG row is a white export gutter. Clamp within\n  // its genuine polar interior, rather than turning the South Pole to ocean.\n  float height = float(textureSize(ncaWaterGlobalMask, 0).y);\n  float inset = height >= 1024.0 ? 3.5 / height : 0.5 / max(height, 1.0);\n  uv.y = clamp(uv.y, inset, 1.0-inset); return uv;\n}\n// Work near the atlas centre instead of subtracting absolute float32 world\n// UVs. Small-angle longitude and Mercator differences retain metre-scale edges.\nvec2 ncaWaterAtlasUv(vec3 direction, vec4 bounds) {\n  if (ncaWaterRegionalEnabled < 0.5) {\n    vec2 mercator = ncaWaterMercatorUv(direction);\n    mercator.x += floor(bounds.x + bounds.z * 0.5 - mercator.x + 0.5);\n    return (mercator - bounds.xy) / bounds.zw;\n  }\n  vec3 local = ncaWaterLocalFrame * ncaWaterGeodeticNormal(direction);\n  float s = ncaWaterLocalLatitude.x, c = ncaWaterLocalLatitude.y;\n  float longitude = atan(local.x, local.z * c - local.y * s);\n  float ds = local.y * c + (local.z - 1.0) * s;\n  float t = clamp(ds / max(1.0 - (s + ds) * s, 1e-5), -0.999999, 0.999999);\n  vec2 delta = vec2(longitude, -0.5 * log((1.0+t)/(1.0-t))) / 6.28318530718;\n  vec2 origin = ncaWaterRegionalBounds.xy - bounds.xy;\n  origin.x -= floor(origin.x + 0.5);\n  return (origin + ncaWaterRegionalBounds.zw * 0.5 + delta) / bounds.zw;\n}\n// Orthometric terrain/water-surface elevation plus independent source validity.\nvec2 ncaWaterTerrainElevation(vec3 direction) {\n  if (ncaWaterBedEnabled < 0.5) return vec2(0.0);\n  vec2 uv = ncaWaterAtlasUv(direction, ncaWaterBedBounds);\n  if (any(lessThan(uv,vec2(0.0))) || any(greaterThanEqual(uv,vec2(1.0)))) return vec2(0.0);\n  vec4 value = texture2D(ncaWaterBed,uv);\n  float elevation = dot(value.rgb * 255.0,vec3(256.0,1.0,1.0/256.0))-32768.0;\n  return vec2(elevation,step(0.99,value.a));\n}\n// Depth below MSL, and independently valid source coverage. Never invent a\n// shallow bed from missing DEM pixels or a photographed sea-surface cap.\nvec2 ncaWaterBedDepth(vec3 direction) {\n  vec2 terrain = ncaWaterTerrainElevation(direction);\n  return vec2(max(0.0,-terrain.x),terrain.y*float(terrain.x<0.0));\n}\nvec3 ncaWaterCoverage(vec3 direction) {\n  vec2 uv = ncaWaterUv(direction);\n  float globalWater = ncaWaterGlobalEnabled > 0.5\n    ? texture2D(ncaWaterGlobalMask, ncaWaterGlobalUv(direction)).r : 0.0;\n  if (ncaWaterRegionalEnabled > 0.5) {\n    vec2 regionalUv = ncaWaterAtlasUv(direction, ncaWaterRegionalBounds);\n    if (all(greaterThanEqual(regionalUv, vec2(0.0))) && all(lessThan(regionalUv, vec2(1.0)))) {\n      vec3 mapped = texture2D(ncaWaterRegionalMask, regionalUv).rgb;\n      if (mapped.g > 0.99) return vec3(mapped.r, mapped.b, 1.0);\n    }\n  }\n  return vec3(globalWater, globalWater, 0.0);\n}\n// Geographic water is necessary but insufficient: a bridge is still above a\n// river in plan view. Only near-horizontal geometry at the datum-corrected\n// water elevation receives local water albedo/reflection. Unknown local height\n// support stays dry; orbital coverage retains its independent geographic LOD.\nfloat ncaWaterSurfaceFactor(vec3 position, vec3 geometricNormal, float cameraAltitude) {\n  vec3 mapped = ncaWaterCoverage(position);\n  float orbital = ncaOrbitalWaterBlend(cameraAltitude);\n  if (orbital >= 1.0) return mapped.x;\n  // Existing regional alpha contains numeric DEM height. Keep the full cloud\n  // compositor inside its 16-sampler budget; bathymetry is not another active\n  // sampler for specular. Nearest alpha preserves explicit unknown pixels.\n  vec2 atlasUv=ncaWaterAtlasUv(position,ncaWaterRegionalBounds);\n  float heightCode=0.0;\n  if(ncaWaterRegionalEnabled>0.5 && ncaWaterSurfaceHeightEnabled>0.5\n    && all(greaterThanEqual(atlasUv,vec2(0.0))) && all(lessThan(atlasUv,vec2(1.0)))){\n    ivec2 size=textureSize(ncaWaterRegionalMask,0);\n    heightCode=texelFetch(ncaWaterRegionalMask,ivec2(atlasUv*vec2(size)),0).a*255.0;\n  }\n  vec2 terrain=vec2(ncaWaterSurfaceHeightRange.x+heightCode*ncaWaterSurfaceHeightRange.y,step(0.5,heightCode));\n  vec3 up = ncaWaterGeodeticNormal(position);\n  float expected = mapped.y > 0.5 ? ncaWaterSeaHeight : terrain.x + ncaWaterGeoid;\n  float valid = ncaWaterDatumReady * mapped.z * (mapped.y > 0.5 ? 1.0 : terrain.y);\n  float height = length(position) - ncaWaterReferenceRadius(position);\n  float difference=height-expected;\n  float plane = 1.0 - smoothstep(1.0, 3.0, abs(difference));\n  // Inland DEMs and photogrammetry can capture different river stages. Permit\n  // a modest lower stage, while retaining the strict upper bound for decks\n  // and banks. Ocean geometry continues to use its shared physical sea level.\n  if(mapped.y<0.5)plane=(1.0-smoothstep(1.0,3.0,difference))*smoothstep(-5.0,-3.5,difference);\n  float level = smoothstep(0.990268, 0.998630, dot(geometricNormal,up));\n  // Centre the local polygon edge at half coverage; weak bilinear/AA fringe\n  // must not turn adjacent bank pixels into visibly reflective water.\n  float localCoverage = smoothstep(0.45,0.55,mapped.x);\n  return mix(localCoverage * valid * plane * level, mapped.x, orbital);\n}\n`;\n\nexport function bathymetryTileWindow(latitude, longitude, altitude) {\n    const zoom = Math.max(2, Math.min(14, Math.floor(Math.log2(120225050 / Math.max(500, altitude * 2)))));\n    const window = waterTileWindow(latitude, longitude, 0, 256);\n    if (!window) return null;\n    const count = 2 ** zoom, x = (((longitude+180)/360)%1+1)%1;\n    const y = (1-Math.asinh(Math.tan(latitude*Math.PI/180))/Math.PI)/2;\n    // At z0/z1 a world-sized atlas is sufficient; repeated X tiles wrap.\n    const left = Math.floor(x*count)-1, top = Math.max(0,Math.min(Math.max(0,count-3),Math.floor(y*count)-1));\n    return { key:`${zoom}/${left}/${top}`,zoom,left,top,count,tileSize:256,\n        bounds:[left/count,top/count,3/count,3/count] };\n}\n\nexport function waterTileWindow(latitude, longitude, altitude = 0, tileSize = 512) {\n    if (![latitude, longitude, altitude].every(Number.isFinite) || Math.abs(latitude) > 85.05112878) return null;\n    const zoom = Math.max(5, Math.min(14, Math.floor(14 - Math.log2(Math.max(1, altitude / 150)) / 2)));\n    const count = 2 ** zoom;\n    const x = (((longitude + 180) / 360) % 1 + 1) % 1;\n    const y = (1 - Math.asinh(Math.tan(latitude * Math.PI / 180)) / Math.PI) / 2;\n    const left = Math.floor(x * count) - 1, top = Math.max(0, Math.min(count - 3, Math.floor(y * count) - 1));\n    return { key: `${zoom}/${left}/${top}`, zoom, left, top, count, tileSize,\n        bounds: [left / count, top / count, 3 / count, 3 / count] };\n}\n\nexport function sampleWaterAtlas(atlas, latitude, longitude) {\n    if (!atlas || ![latitude, longitude].every(Number.isFinite) || Math.abs(latitude) > 85.05112878) return null;\n    const [left, top, width, height] = atlas.bounds;\n    let x = (((longitude + 180) / 360) % 1 + 1) % 1;\n    x += Math.floor(left + width * 0.5 - x + 0.5);\n    const y = (1 - Math.asinh(Math.tan(latitude * Math.PI / 180)) / Math.PI) / 2;\n    const u = (x - left) / width, v = (y - top) / height;\n    if (u < 0 || u >= 1 || v < 0 || v >= 1) return null;\n    const offset = (Math.floor(v * atlas.size) * atlas.size + Math.floor(u * atlas.size)) * 4;\n    if (atlas.pixels[offset + 1] < 254) return null;\n    return { isOcean: atlas.pixels[offset + 2] >= 128, waterMask: atlas.pixels[offset] / 255,\n        source: 'mapsource-water' };\n}\n","// Beckmann ocean-slope distribution + Smith masking + unpolarized dielectric\n// Fresnel (IOR 1.333). Wind sets Cox–Munk mean-square slope, not an arbitrary\n// Phong exponent. Shared by terrain, the orbital globe and deferred photoreal.\nexport const WATER_REFLECTANCE_GLSL = /* glsl */`\nfloat ncaWaterFresnel(float cosine) {\n  float ct = sqrt(max(0.0, 1.0 - (1.0 - cosine*cosine) / (1.333*1.333)));\n  float rs = (cosine - 1.333*ct) / max(cosine + 1.333*ct, 1e-5);\n  float rp = (1.333*cosine - ct) / max(1.333*cosine + ct, 1e-5);\n  return 0.5 * (rs*rs + rp*rp);\n}\nvec3 ncaWaterBottomTransmission(vec3 direction, vec3 normal, vec3 view, vec3 sun) {\n  vec2 bed = ncaWaterBedDepth(direction);\n  float nv = clamp(dot(normal,view),0.0,1.0), nl = clamp(dot(normal,sun),0.0,1.0);\n  if (bed.y < 0.5 || nl <= 0.0) return vec3(0.0);\n  float muView = sqrt(1.0-(1.0-nv*nv)/(1.333*1.333));\n  float muSun = sqrt(1.0-(1.0-nl*nl)/(1.333*1.333));\n  // Two-way diffuse bottom radiance crosses downwelling and outgoing\n  // refracted paths. Unknown bathymetry never fabricates a visible bed.\n  return exp(-bed.x * ncaWaterKd * (1.0/muSun + 1.0/muView))\n    * (1.0-ncaWaterFresnel(nv)) * (1.0-ncaWaterFresnel(nl));\n}\nfloat ncaWaterSmith(float cosine, float alpha) {\n  float a = cosine / max(alpha * sqrt(max(0.0, 1.0-cosine*cosine)), 1e-5);\n  if (a >= 1.6) return 1.0;\n  return (3.535*a + 2.181*a*a) / max(1.0 + 2.276*a + 2.577*a*a, 1e-5);\n}\n// The lighting owner supplies direct sun and sky independently. Cloud optical\n// transmission attenuates direct irradiance, never the whole Fresnel reflection.\nvec3 ncaWaterCloudSky(vec3 sky, float transmission) {\n  float luminance = dot(max(sky, vec3(0.0)), vec3(0.2126, 0.7152, 0.0722));\n  return mix(vec3(luminance), sky, clamp(transmission, 0.0, 1.0));\n}\nvec3 ncaWaterReflection(vec3 n, vec3 view, vec3 sun, float windSpeed, vec3 sunRadiance, vec3 skyRadiance) {\n  float nv = dot(n, view), nl = dot(n, sun);\n  if (nv <= 0.0) return vec3(0.0);\n  vec3 reflectedSky = max(skyRadiance, vec3(0.0)) * ncaWaterFresnel(nv);\n  if (nl <= 0.0) return reflectedSky;\n  vec3 h = normalize(view + sun);\n  float nh = max(dot(n,h), 1e-4), hv = max(dot(h,view), 0.0);\n  // Include the finite solar disc and the pixel's unresolved normal range.\n  float alpha2 = max(0.003 + 0.00512 * clamp(windSpeed, 0.0, 25.0), 0.003);\n  alpha2 += 0.004675*0.004675 + max(dot(dFdx(n),dFdx(n)), dot(dFdy(n),dFdy(n)));\n  float d = exp((nh*nh - 1.0) / (alpha2*nh*nh)) / (3.14159265359*alpha2*nh*nh*nh*nh);\n  float g = ncaWaterSmith(nv, sqrt(alpha2)) * ncaWaterSmith(nl, sqrt(alpha2));\n  float specular = ncaWaterFresnel(hv) * d * g / max(4.0*nv, 1e-4);\n  return max(sunRadiance, vec3(0.0)) * specular + reflectedSky;\n}\n`;\n","// Inherent and apparent optical properties of sea water for three display\n// channels, from chlorophyll concentration (mg/m³). See docs/OCEAN_MATH.md.\n//\n// Channels are represented by 600, 540 and 460 nm. The functional forms are\n// the standard Case-1 bio-optical ones: pure-water absorption (Pope & Fry\n// 1997 magnitudes), phytoplankton absorption A·Chl^(1-B) (Bricaud et al. form),\n// CDOM covarying with Chl and decaying exponentially with wavelength,\n// scattering b = 0.30·Chl^0.62·(550/λ) (Gordon & Morel form) and diffuse\n// downwelling attenuation Kd = Kw + χ·Chl^e (Morel & Maritorena form).\n// Coefficients are rounded, channel-representative approximations, not a\n// per-wavelength reproduction of the published tables.\nconst WAVELENGTHS = Object.freeze([600, 540, 460]);\nconst PURE_WATER_ABSORPTION = Object.freeze([0.2224, 0.0409, 0.0098]);\nconst PURE_WATER_SCATTERING = Object.freeze([0.0012, 0.0017, 0.0029]);\nconst PHYTOPLANKTON_A = Object.freeze([0.0072, 0.0151, 0.0346]);\nconst PHYTOPLANKTON_B = Object.freeze([0.077, 0.155, 0.316]);\nconst KD_WATER = Object.freeze([0.2440, 0.0590, 0.0182]);\nconst KD_CHI = Object.freeze([0.0350, 0.0567, 0.0937]);\nconst KD_EXPONENT = Object.freeze([0.62, 0.64, 0.68]);\n\nexport const OCEAN_DEFAULT_CHLOROPHYLL = 0.15;\n// Contrast threshold for a large dark target against the water background:\n// visibility = ln(1/0.02) / c (Duntley; Zaneveld & Pegau 2003).\nconst VISIBILITY_CONTRAST = Math.log(1 / 0.02);\n\nconst clampChlorophyll = value => Math.min(30, Math.max(0.01, Number.isFinite(value) ? value : OCEAN_DEFAULT_CHLOROPHYLL));\n\nexport function computeWaterOptics(chlorophyll = OCEAN_DEFAULT_CHLOROPHYLL) {\n    const chl = clampChlorophyll(chlorophyll);\n    const absorption = [], scattering = [], attenuation = [], diffuseAttenuation = [], albedo = [];\n    for (let i = 0; i < 3; i++) {\n        const lambda = WAVELENGTHS[i];\n        const phytoplankton = PHYTOPLANKTON_A[i] * chl ** (1 - PHYTOPLANKTON_B[i]);\n        const cdom = 0.2 * 0.06 * chl ** 0.65 * Math.exp(-0.014 * (lambda - 440));\n        const a = PURE_WATER_ABSORPTION[i] + phytoplankton + cdom;\n        const b = PURE_WATER_SCATTERING[i] + 0.30 * chl ** 0.62 * (550 / lambda);\n        absorption.push(a); scattering.push(b); attenuation.push(a + b);\n        diffuseAttenuation.push(KD_WATER[i] + KD_CHI[i] * chl ** KD_EXPONENT[i]);\n        albedo.push(b / (a + b));\n    }\n    return {\n        chlorophyll: chl, wavelengths: WAVELENGTHS,\n        absorption, scattering, attenuation, diffuseAttenuation, singleScatteringAlbedo: albedo,\n        // Visibility is limited by the clearest (minimum-attenuation) channel.\n        visibilityMeters: VISIBILITY_CONTRAST / Math.min(...attenuation),\n        // Depth of the 1% downwelling light level (euphotic depth), green channel.\n        euphoticDepthMeters: Math.log(100) / diffuseAttenuation[1],\n    };\n}\n\nconst WATER_INDEX = 1.333;\n// Particle backscattering ratio (≈1.9% for oceanic particles); pure water\n// backscatters half its scattering.\nconst PARTICLE_BACKSCATTER_RATIO = 0.019;\n\n/** Unpolarized Fresnel reflectance for light entering water from air. */\nexport function oceanAirWaterFresnel(cosIncidence) {\n    const cosI = Math.min(1, Math.max(0, cosIncidence));\n    const sinT2 = (1 - cosI * cosI) / (WATER_INDEX * WATER_INDEX);\n    const cosT = Math.sqrt(Math.max(0, 1 - sinT2));\n    const s = (cosI - WATER_INDEX * cosT) / (cosI + WATER_INDEX * cosT);\n    const p = (WATER_INDEX * cosI - cosT) / (WATER_INDEX * cosI + cosT);\n    return 0.5 * (s * s + p * p);\n}\n\n/**\n * Light field just below the surface, in scene radiance units.\n * sunRadiance: the scene's directional light colour × intensity (RGB).\n * Returns downwelling irradiance Ed(0⁻), the direct-beam share, the in-water\n * cosine of the refracted sun, and the remote-sensing reflectance\n * Rrs ≈ 0.0949u + 0.0794u², u = bb/(a+bb) (Gordon et al. 1988).\n */\nexport function oceanSubsurfaceLight(optics, { sunCosZenith = 1, sunRadiance = [3.4, 3.4, 3.4] } = {}) {\n    const cosZ = Math.max(0, sunCosZenith);\n    const daylight = Math.min(1, Math.max(0, (sunCosZenith + 0.1) / 0.25));\n    const transmission = 1 - oceanAirWaterFresnel(cosZ);\n    // Clear-sky diffuse irradiance is roughly 15% of direct at moderate\n    // elevations; it remains through twilight after the direct beam is gone.\n    const direct = [], irradiance = [], reflectance = [];\n    for (let i = 0; i < 3; i++) {\n        const sun = sunRadiance[i] * cosZ * transmission;\n        const sky = sunRadiance[i] * 0.15 * daylight * 0.94 + 0.0015;\n        direct.push(sun); irradiance.push(sun + sky);\n        const bb = PARTICLE_BACKSCATTER_RATIO * (optics.scattering[i] - 0.0017) + 0.5 * 0.0017;\n        const u = bb / (optics.absorption[i] + bb);\n        reflectance.push(0.0949 * u + 0.0794 * u * u);\n    }\n    const sinW = Math.sqrt(Math.max(0, 1 - cosZ * cosZ)) / WATER_INDEX;\n    return { irradiance, direct, reflectance, daylight,\n        sunCosInWater: Math.sqrt(Math.max(0, 1 - sinW * sinW)),\n        directFraction: irradiance[1] > 0 ? direct[1] / irradiance[1] : 0 };\n}\n","import { WGS84_SEMI_MAJOR_AXIS, WGS84_SEMI_MINOR_AXIS } from '../../modules/constants.js';\n\nconst A = WGS84_SEMI_MAJOR_AXIS, B = WGS84_SEMI_MINOR_AXIS;\nconst E2 = 1 - (B * B) / (A * A);\nconst EP2 = (A * A) / (B * B) - 1;\n\n/** WGS84 latitude of an actual planet-fixed position, including elevation. */\nexport function nightLightsGeodeticLatitude(position) {\n  const x = position?.x || 0, y = position?.y || 0, z = position?.z || 0;\n  const horizontal = Math.hypot(x, z);\n  if (Math.hypot(horizontal, y) < 1e6) {\n    return Math.atan2(y / (1 - E2), horizontal);\n  }\n  const theta = Math.atan2(y * A, horizontal * B);\n  return Math.atan2(y + EP2 * B * Math.sin(theta) ** 3,\n    horizontal - E2 * A * Math.cos(theta) ** 3);\n}\n\n// Geographic imagery uses geodetic latitude, not a normalized radial vector.\n// Keep the source position in metres, before the atmosphere's sphere correction.\nexport const NIGHT_LIGHTS_GEOGRAPHY_GLSL = /* glsl */`\nvec2 ncaNightLightsGeographicUv(vec3 position) {\n  float horizontal = length(position.xz);\n  vec2 theta = normalize(vec2(horizontal * ${B.toFixed(6)}, position.y * ${A.toFixed(1)}));\n  float latitude = atan(\n    position.y + ${(EP2 * B).toFixed(6)} * theta.y * theta.y * theta.y,\n    horizontal - ${(E2 * A).toFixed(6)} * theta.x * theta.x * theta.x\n  );\n  return vec2(fract(atan(position.x, position.z) / 6.28318530718 + 0.5),\n    clamp(0.5 - latitude / 3.14159265359, 0.0, 1.0));\n}\n`;\n","import * as THREE from 'three';\nimport { NIGHT_LIGHTS_EMISSION_DEFAULTS, NIGHT_LIGHTS_SOURCE_SIGNAL_GLSL } from '../refactor/render/NightLightsEmissionContract.js';\nimport { NIGHT_LIGHTS_GEOGRAPHY_GLSL } from '../refactor/imagery/NightLightsGeoreference.js';\n\n// Borrow the authoritative NASA emission field. No new download, render target,\n// timer or source classification: the same blue-relief rejection is mandatory.\nconst bindings = {\n    ncaCityTexture: ['lightPollutionTexture', null],\n    ncaCityDetailTexture: ['lightPollutionDetailTexture', null],\n    ncaCityDetailEnabled: ['lightPollutionDetailEnabled', 0],\n    ncaCityDetailBounds: ['lightPollutionDetailBounds', new THREE.Vector4(.5,0,1,1)],\n    ncaCityEnabled: ['lightPollutionEnabled', 0],\n    ncaCityIntensity: ['lightPollutionIntensity', NIGHT_LIGHTS_EMISSION_DEFAULTS.intensity],\n    ncaCityMapGain: ['lightPollutionMapGain', NIGHT_LIGHTS_EMISSION_DEFAULTS.mapGain],\n    ncaCityThreshold: ['lightPollutionEmissionThreshold', NIGHT_LIGHTS_EMISSION_DEFAULTS.emissionThreshold],\n    ncaCitySoftness: ['lightPollutionEmissionSoftness', NIGHT_LIGHTS_EMISSION_DEFAULTS.emissionSoftness],\n    ncaCityPower: ['lightPollutionEmissionPower', NIGHT_LIGHTS_EMISSION_DEFAULTS.emissionPower],\n    ncaCityBlueSuppression: ['lightPollutionEmissionBlueSuppression', NIGHT_LIGHTS_EMISSION_DEFAULTS.emissionBlueSuppression],\n    ncaCityTint: ['lightPollutionColor', new THREE.Color(0xffb57a)],\n    ncaCityMercator: ['lightPollutionMercator', 0],\n    ncaCityUvOffset: ['lightPollutionUvOffset', new THREE.Vector2()],\n    ncaCityUvScale: ['lightPollutionUvScale', new THREE.Vector2(1, 1)],\n};\nconst bindingEntries = Object.entries(bindings);\nexport function bindNightCloudLighting(uniforms, source) {\n    if (!uniforms) return;\n    for (const [name, [sourceName, fallback]] of bindingEntries) {\n        if (source?.[sourceName]) uniforms[name] = source[sourceName];\n        else if (!uniforms[name]) uniforms[name] = new THREE.Uniform(fallback);\n    }\n}\nexport const NIGHT_CLOUD_UNIFORMS_GLSL = `\nuniform sampler2D ncaCityTexture,ncaCityDetailTexture;\nuniform float ncaCityDetailEnabled;\nuniform vec4 ncaCityDetailBounds;\nuniform float ncaCityEnabled, ncaCityIntensity, ncaCityMapGain, ncaCityThreshold;\nuniform float ncaCitySoftness, ncaCityPower, ncaCityBlueSuppression, ncaCityMercator;\nuniform vec3 ncaCityTint;\nuniform vec2 ncaCityUvOffset, ncaCityUvScale;\n`;\nexport const NIGHT_CLOUD_FUNCTIONS_GLSL = `\nvec3 ncaCitySource(vec2 uv, float lod) {\n    uv.x = fract(uv.x); uv.y = clamp(uv.y, 0.0, 1.0);\n    if (ncaCityMercator > .5) {\n        float latitude = clamp((.5 - uv.y) * PI, -1.48442223, 1.48442223);\n        float s = sin(latitude);\n        uv.y = .5 - .25 * log((1.0 + s) / (1.0 - s)) / PI;\n    }\n    uv = (uv - .5) * ncaCityUvScale + .5 + ncaCityUvOffset;\n    uv = vec2(fract(uv.x), clamp(uv.y, 0.0, 1.0));\n    vec4 sampleValue = textureLod(ncaCityTexture, uv, max(lod,0.0));\n    /* CITY_DETAIL_BEGIN */\n    if(ncaCityDetailEnabled>.5){\n        float wrapped=fract(uv.x-ncaCityDetailBounds.x+.5)-.5;\n        vec2 detailUv=vec2(wrapped/ncaCityDetailBounds.z+.5,(uv.y-ncaCityDetailBounds.y)/ncaCityDetailBounds.w);\n        if(all(greaterThanEqual(detailUv,vec2(0.0)))&&all(lessThanEqual(detailUv,vec2(1.0)))){\n            vec2 ratio=vec2(textureSize(ncaCityDetailTexture,0))/(vec2(textureSize(ncaCityTexture,0))*ncaCityDetailBounds.zw);\n            float detailLod=max(0.0,lod+log2(max(ratio.x,ratio.y)));\n            vec4 detail=textureLod(ncaCityDetailTexture,detailUv,detailLod);\n            sampleValue=mix(sampleValue,detail,detail.a);\n        }\n    }\n    /* CITY_DETAIL_END */\n    vec3 rgb = max(sampleValue.rgb, vec3(0.0));\n    float peak = max(max(rgb.r, rgb.g), max(rgb.b, 1e-4));\n    float signalValue = resolveNightLightsSourceSignal(rgb, ncaCityBlueSuppression);\n    float threshold = clamp(ncaCityThreshold, 0.0, .95);\n    float normalizedSignal = clamp((signalValue - threshold) / (1.0 - threshold), 0.0, 1.0);\n    float gate = smoothstep(threshold, min(1.0, threshold + max(ncaCitySoftness, 1e-4)), signalValue);\n    return rgb / peak * ncaCityTint * ncaCityIntensity * ncaCityMapGain\n        * pow(normalizedSignal, max(ncaCityPower, .1)) * gate * sampleValue.a;\n}\n// Approximate the upward Lambertian irradiance integral at the cloud altitude.\n// Its ground-space kernel broadens with height, rather than blurring in screen\n// pixels (which swims as the camera moves). Source mipmaps filter each lobe.\nvec3 ncaNightCloudRadiance(vec3 actualPlanetPosition, float cloudHeight) {\n    if (ncaCityEnabled < .5) return vec3(0.0);\n    vec2 uv = ncaNightLightsGeographicUv(actualPlanetPosition);\n    float latitude = (.5 - uv.y) * PI;\n    float width = max(cloudHeight, 250.0);\n    vec2 footprint = vec2(width / max(cos(latitude), .05), width * 2.0) / 40075016.686;\n    vec2 sourceSize = vec2(textureSize(ncaCityTexture, 0));\n    vec2 fieldFootprint=footprint;\n    if(ncaCityMercator>.5)fieldFootprint.y=width/max(cos(latitude),.05)/40075016.686;\n    float lod = log2(max(1e-6, max(fieldFootprint.x * sourceSize.x,\n        fieldFootprint.y * sourceSize.y) * .5));\n    vec3 energy = ncaCitySource(uv, lod) * .5;\n    energy += ncaCitySource(uv + vec2(footprint.x, 0.0), lod) * .125;\n    energy += ncaCitySource(uv - vec2(footprint.x, 0.0), lod) * .125;\n    energy += ncaCitySource(uv + vec2(0.0, footprint.y), lod) * .125;\n    energy += ncaCitySource(uv - vec2(0.0, footprint.y), lod) * .125;\n    // Isotropic single scattering: upward hemispherical irradiance PI * L,\n    // phase 1/(4*PI). Native extinction/multiple scattering still owns transport.\n    return energy * .25;\n}\n// Light transmitted diffusely up through a cloud deck, as seen from orbit. In\n// a thick deck multiple scattering spreads city light over tens of\n// kilometres; the direct beam is gone. The kernel widens with coverage\n// (optical depth), and diffuse transmittance falls from ~0.55 for thin cover\n// to ~0.36 for thick cover. Twelve golden-spiral taps sample a mip level that\n// matches their spacing, so the glow is smooth and geographically anchored.\nvec3 ncaNightCloudDiffuse(vec3 actualPlanetPosition, float cloudHeight, float coverage) {\n    if (ncaCityEnabled < .5 || coverage <= 0.0) return vec3(0.0);\n    float c = clamp(coverage, 0.0, 1.0);\n    vec2 uv = ncaNightLightsGeographicUv(actualPlanetPosition);\n    float latitude = (.5 - uv.y) * PI;\n    float radiusM = max(cloudHeight * .5, 2000.0) + 60000.0 * c;\n    vec2 footprint = vec2(radiusM / (40075016.686 * max(cos(latitude), .05)), radiusM / 20037508.34);\n    vec2 fieldFootprint = footprint;\n    if (ncaCityMercator > .5) fieldFootprint.y = footprint.x;\n    vec2 sourceSize = vec2(textureSize(ncaCityTexture, 0));\n    float lod = log2(max(1e-6, max(fieldFootprint.x * sourceSize.x, fieldFootprint.y * sourceSize.y) * .35));\n    vec3 energy = ncaCitySource(uv, lod) * .2;\n    for (int i = 0; i < 12; i++) {\n        float fi = float(i) + .5;\n        float r = sqrt(fi / 12.0);\n        float a = fi * 2.399963229728653;\n        energy += ncaCitySource(uv + vec2(cos(a), sin(a)) * r * footprint, lod) * (.8 / 12.0);\n    }\n    // Brighter than the bare diffuse-transmittance estimate: the deck also\n    // reflects light back down and re-scatters it (ISS night photography shows\n    // city glows through cloud far larger and brighter than the cities).\n    return energy * mix(.55, .36, c) * 2.0;\n}\n// City light scattered by the air between the ground and the viewer: a wide,\n// soft glow whose strength follows the slant path (airmass), so it grows\n// toward the limb. tau ~0.14 combines aerosol and Rayleigh optical depth for\n// orange sodium/LED light at night.\nvec3 ncaNightAirGlow(vec3 actualPlanetPosition, float viewMu) {\n    if (ncaCityEnabled < .5) return vec3(0.0);\n    float mu = clamp(viewMu, .04, 1.0);\n    float airmass = min(1.0 / mu, 12.0);\n    float scatter = 1.0 - exp(-.14 * airmass);\n    vec2 uv = ncaNightLightsGeographicUv(actualPlanetPosition);\n    float latitude = (.5 - uv.y) * PI;\n    float radiusM = 15000.0 + 20000.0 * min(airmass, 8.0);\n    vec2 footprint = vec2(radiusM / (40075016.686 * max(cos(latitude), .05)), radiusM / 20037508.34);\n    vec2 fieldFootprint = footprint;\n    if (ncaCityMercator > .5) fieldFootprint.y = footprint.x;\n    vec2 sourceSize = vec2(textureSize(ncaCityTexture, 0));\n    float lod = log2(max(1e-6, max(fieldFootprint.x * sourceSize.x, fieldFootprint.y * sourceSize.y) * .35));\n    vec3 energy = ncaCitySource(uv, lod) * .25;\n    for (int i = 0; i < 8; i++) {\n        float fi = float(i) + .5;\n        float a = fi * 2.399963229728653;\n        energy += ncaCitySource(uv + vec2(cos(a), sin(a)) * sqrt(fi / 8.0) * footprint, lod) * (.75 / 8.0);\n    }\n    return energy * scatter * .9;\n}\n`;\nexport const NIGHT_CLOUD_LIGHTING_GLSL = NIGHT_CLOUD_UNIFORMS_GLSL\n    + NIGHT_LIGHTS_GEOGRAPHY_GLSL + NIGHT_LIGHTS_SOURCE_SIGNAL_GLSL + NIGHT_CLOUD_FUNCTIONS_GLSL;\n// Other Earth shaders already own these samplers/uniforms/functions. Alias\n// names at compile time, avoiding additional sampler units or duplicate fields.\nexport function nightCloudLightingForExistingField(prefix = 'lightPollution', detail = false) {\n    let shader = NIGHT_CLOUD_FUNCTIONS_GLSL;\n    if(!detail)shader=shader.replace(/\\/\\* CITY_DETAIL_BEGIN \\*\\/[\\s\\S]*?\\/\\* CITY_DETAIL_END \\*\\//,'');\n    for (const [name, [sourceName]] of bindingEntries) {\n        const target = prefix + sourceName.slice('lightPollution'.length);\n        shader = shader.replaceAll(name, target);\n    }\n    return shader;\n}\n","/**\n * Orbital presentation of the daily simple-cloud map and of the night limb.\n * Shared by the overview Earth material and the deferred aerial-perspective\n * surface compositor (the live photoreal path). Each instantiates the GLSL\n * with its own sampler, mask function and ground radius (any length unit).\n *\n * Cloud volume: the map is a 2D coverage field, so the deck is modelled as a\n * slab between 35% and 100% of the cloud-top height. Dense cores reach the\n * top and wisps stay low. The view ray is intersected with three levels of\n * the slab (top, middle, base), so clouds show parallax at their real\n * altitude, and oblique rays near the limb cross more of the deck and read\n * thicker. Treating coverage as a height field gives each cloud a relief\n * normal, so sunward faces brighten and lee faces darken.\n *\n * Night limb: light leaving the dark night ground at a grazing angle crosses\n * a long air path (airmass ≈ 1/μ). It is attenuated by the night-time optical\n * depth, so the night disc fades at the edge. The glow that replaces it is\n * the airglow pass's integrated night haze (airglow-emission.js), which\n * spans both sides of the limb.\n */\nexport const ORBITAL_CLOUD_VOLUME_DEFAULTS = Object.freeze({\n  baseFraction: 0.35,\n  extinctionPerLevel: 0.65,\n  reliefStrength: 2.5,\n  // Effective night-time extinction, sized so the fade reads at orbital range\n  // (μ < ~0.45) rather than collapsing into the outermost pixel.\n  nightLimbOpticalDepth: 0.35,\n});\n\nconst d = ORBITAL_CLOUD_VOLUME_DEFAULTS;\nconst f = (value) => Number(value).toFixed(6);\n\n/**\n * @param {{name: string, sampler: string, mask: string, groundRadius: string}} options\n *   name: function name for the cloud view (struct is `<Name>Result`).\n */\nexport function orbitalCloudVolumeGlsl({ name, sampler, mask, groundRadius }) {\n  const result = `${name.charAt(0).toUpperCase()}${name.slice(1)}Result`;\n  return /* glsl */`\nstruct ${result} { float alpha; float shade; vec2 uv; vec4 sampleValue; };\n\nfloat ${name}RayHit(vec3 origin, vec3 dir, float radius) {\n  float b = dot(origin, dir);\n  float c = dot(origin, origin) - radius * radius;\n  float h = b * b - c;\n  if (h < 0.0) return -1.0;\n  float s = sqrt(h);\n  float tNear = -b - s;\n  float tFar = -b + s;\n  return tNear > 0.0 ? tNear : (tFar > 0.0 ? tFar : -1.0);\n}\n\n// Geodetic equirect UV (north at v = 0), matching the surface UVs the cloud\n// map is drawn with; geocentric latitude would shift clouds by up to ~0.19°.\n// Fetches go through wrapCloudMapSampling(), so the dateline leaves no seam.\nvec2 ${name}Uv(vec3 p) {\n  float lon = atan(p.x, p.z);\n  float lat = atan(p.y / 0.99330562, length(p.xz));\n  return vec2(fract(lon / (2.0 * PI) + 1.5), clamp(0.5 - lat / PI, 0.0, 1.0));\n}\n\n${result} ${name}(vec3 surfacePos, vec3 toCamera, vec3 sunDir, float cloudTop) {\n  ${result} view;\n  vec3 rd = normalize(toCamera);\n  float top = max(cloudTop, 1e-6);\n  float ground = ${groundRadius};\n  float transmittance = 1.0;\n  view.uv = ${name}Uv(surfacePos);\n  view.sampleValue = texture2D(${sampler}, view.uv);\n  float topMask = 0.0;\n  vec3 topPos = surfacePos;\n  for (int i = 0; i < 3; i++) {\n    float level = 1.0 - (float(i) + 0.5) / 3.0;\n    float height = mix(top * ${f(d.baseFraction)}, top, level);\n    float t = ${name}RayHit(surfacePos, rd, ground + height);\n    vec3 p = t > 0.0 ? surfacePos + rd * t : surfacePos;\n    vec2 uv = ${name}Uv(p);\n    vec4 s = texture2D(${sampler}, uv);\n    float m = ${mask}(s);\n    if (i == 0) { view.uv = uv; view.sampleValue = s; topMask = m; topPos = p; }\n    // Dense cores are tall; thin cover only fills the lower levels.\n    float density = m * smoothstep(level - 0.35, level + 0.05, m * 1.15);\n    transmittance *= 1.0 - clamp(density, 0.0, 1.0) * ${f(d.extinctionPerLevel)};\n  }\n  view.alpha = 1.0 - transmittance;\n  // Relief normal from the coverage height field at the top intersection.\n  vec2 texel = 2.0 / vec2(textureSize(${sampler}, 0));\n  float mEast = ${mask}(texture2D(${sampler}, view.uv + vec2(texel.x, 0.0)));\n  float mNorth = ${mask}(texture2D(${sampler}, view.uv - vec2(0.0, texel.y)));\n  vec3 up = normalize(topPos);\n  vec3 east = vec3(up.z, 0.0, -up.x);\n  east = dot(east, east) > 1e-8 ? normalize(east) : vec3(1.0, 0.0, 0.0);\n  vec3 north = cross(up, east);\n  vec3 normal = normalize(up - ${f(d.reliefStrength)} * ((mEast - topMask) * east + (mNorth - topMask) * north));\n  view.shade = clamp(1.0 + dot(normal - up, normalize(sunDir)) * 4.0, 0.65, 1.25);\n  return view;\n}\n\nvec3 ${name}NightLimb(vec3 radiance, vec3 surfacePos, vec3 toCamera, float nightness) {\n  if (nightness <= 0.0) return radiance;\n  float mu = clamp(dot(normalize(toCamera), normalize(surfacePos)), 0.0, 1.0);\n  float airmass = 1.0 / max(mu + 0.025, 0.025);\n  float transmittance = exp(-${f(d.nightLimbOpticalDepth)} * (airmass - 1.0));\n  // The glow itself comes from the airglow pass's integrated night haze.\n  return mix(radiance, radiance * transmittance, nightness);\n}\n`;\n}\n\n/** Overview Earth material instance (metres, its own mask resolver). */\nexport const ORBITAL_CLOUD_VOLUME_GLSL = orbitalCloudVolumeGlsl({\n  name: 'ncaSimpleCloudView',\n  sampler: 'simpleCloudsTexture',\n  mask: 'resolveSimpleCloudMask',\n  groundRadius: 'planetRadius',\n});\n","import * as THREE from 'three';\n\nimport {\n  ATMOSPHERE_HEIGHT_M,\n  BETA_MIE,\n  BETA_RAYLEIGH,\n  MIE_SCALE_HEIGHT_M,\n  PLANET_RADIUS,\n  RAYLEIGH_SCALE_HEIGHT_M,\n} from '../../modules/constants.js';\n\nconst PI = Math.PI;\nconst DEFAULT_INTEGRATION_STEPS = 32;\n\nexport const CELESTIAL_IRRADIANCE_GLSL = `\nfloat ncaCircleOverlapArea(\n  const float sourceRadius,\n  const float occluderRadius,\n  const float centerDistance\n) {\n  float a = max(sourceRadius, 1e-7);\n  float b = max(occluderRadius, 0.0);\n  float d = max(centerDistance, 0.0);\n  if (b <= 0.0 || d >= a + b) return 0.0;\n  if (d <= abs(a - b)) {\n    float coveredRadius = min(a, b);\n    return PI * coveredRadius * coveredRadius;\n  }\n  float dSafe = max(d, 1e-7);\n  float aTerm = clamp(\n    (dSafe * dSafe + a * a - b * b) / (2.0 * dSafe * a),\n    -1.0,\n    1.0\n  );\n  float bTerm = clamp(\n    (dSafe * dSafe + b * b - a * a) / (2.0 * dSafe * b),\n    -1.0,\n    1.0\n  );\n  float radical = max(\n    0.0,\n    (-dSafe + a + b)\n      * (dSafe + a - b)\n      * (dSafe - a + b)\n      * (dSafe + a + b)\n  );\n  return a * a * acos(aTerm)\n    + b * b * acos(bTerm)\n    - 0.5 * sqrt(radical);\n}\n\nfloat ncaFiniteDiscVisibility(\n  const vec3 sourceDirection,\n  const float sourceAngularRadius,\n  const vec3 occluderDirection,\n  const float occluderAngularRadius\n) {\n  float sourceRadius = max(sourceAngularRadius, 1e-7);\n  float separation = acos(clamp(\n    dot(normalize(sourceDirection), normalize(occluderDirection)),\n    -1.0,\n    1.0\n  ));\n  float overlap = ncaCircleOverlapArea(\n    sourceRadius,\n    max(occluderAngularRadius, 0.0),\n    separation\n  );\n  return clamp(1.0 - overlap / (PI * sourceRadius * sourceRadius), 0.0, 1.0);\n}\n`;\n\nexport const ATMOSPHERIC_TRANSMITTANCE_GLSL = `\nvec2 ncaRaySphereInterval(\n  const vec3 rayOrigin,\n  const vec3 rayDirection,\n  const vec3 sphereCenter,\n  const float sphereRadius\n) {\n  vec3 offset = rayOrigin - sphereCenter;\n  float b = dot(offset, rayDirection);\n  float c = dot(offset, offset) - sphereRadius * sphereRadius;\n  float discriminant = b * b - c;\n  if (discriminant < 0.0) return vec2(1.0, -1.0);\n  float root = sqrt(discriminant);\n  return vec2(-b - root, -b + root);\n}\n\nvec3 ncaAtmosphericTransmittance(\n  const vec3 observer,\n  const vec3 lightDirection,\n  const vec3 planetCenter,\n  const float planetRadius,\n  const float atmosphereHeight,\n  const vec3 betaRayleigh,\n  const vec3 betaMie,\n  const float rayleighScaleHeight,\n  const float mieScaleHeight\n) {\n  vec3 direction = normalize(lightDirection);\n  vec2 ground = ncaRaySphereInterval(\n    observer,\n    direction,\n    planetCenter,\n    planetRadius\n  );\n  if (ground.y > 1e-3 && ground.x > 1e-3) return vec3(0.0);\n  vec2 atmosphere = ncaRaySphereInterval(\n    observer,\n    direction,\n    planetCenter,\n    planetRadius + atmosphereHeight\n  );\n  if (atmosphere.y <= 0.0 || atmosphere.y < atmosphere.x) return vec3(1.0);\n  float startDistance = max(0.0, atmosphere.x);\n  float pathLength = max(0.0, atmosphere.y - startDistance);\n  if (pathLength <= 1e-3) return vec3(1.0);\n  const int NCA_ATMOSPHERE_STEPS = 24;\n  float stepLength = pathLength / float(NCA_ATMOSPHERE_STEPS);\n  float rayleighColumn = 0.0;\n  float mieColumn = 0.0;\n  for (int index = 0; index < NCA_ATMOSPHERE_STEPS; ++index) {\n    float distance = startDistance + (float(index) + 0.5) * stepLength;\n    vec3 samplePosition = observer + direction * distance;\n    float altitude = max(\n      0.0,\n      length(samplePosition - planetCenter) - planetRadius\n    );\n    rayleighColumn += exp(-altitude / rayleighScaleHeight) * stepLength;\n    mieColumn += exp(-altitude / mieScaleHeight) * stepLength;\n  }\n  return exp(-(\n    betaRayleigh * rayleighColumn\n      + betaMie * mieColumn\n  ));\n}\n`;\n\nexport function apparentAngularRadius(radius, distance) {\n  if (!(radius > 0) || !(distance > 0)) return 0;\n  return Math.asin(THREE.MathUtils.clamp(radius / distance, 0, 1));\n}\n\nexport function circleOverlapArea(sourceRadius, occluderRadius, centerDistance) {\n  const a = Math.max(Number(sourceRadius) || 0, 1e-12);\n  const b = Math.max(Number(occluderRadius) || 0, 0);\n  const d = Math.max(Number(centerDistance) || 0, 0);\n  if (b <= 0 || d >= a + b) return 0;\n  if (d <= Math.abs(a - b)) {\n    const coveredRadius = Math.min(a, b);\n    return PI * coveredRadius * coveredRadius;\n  }\n  const aTerm = THREE.MathUtils.clamp(\n    (d * d + a * a - b * b) / (2 * d * a),\n    -1,\n    1,\n  );\n  const bTerm = THREE.MathUtils.clamp(\n    (d * d + b * b - a * a) / (2 * d * b),\n    -1,\n    1,\n  );\n  const radical = Math.max(\n    0,\n    (-d + a + b) * (d + a - b) * (d - a + b) * (d + a + b),\n  );\n  return a * a * Math.acos(aTerm)\n    + b * b * Math.acos(bTerm)\n    - 0.5 * Math.sqrt(radical);\n}\n\nexport function finiteDiscVisibility({\n  sourceDirection,\n  sourceAngularRadius,\n  occluderDirection,\n  occluderAngularRadius,\n} = {}) {\n  if (!sourceDirection || !occluderDirection || !(sourceAngularRadius > 0)) return 1;\n  const sourceLength = sourceDirection.length?.() ?? 0;\n  const occluderLength = occluderDirection.length?.() ?? 0;\n  if (!(sourceLength > 0) || !(occluderLength > 0) || !(occluderAngularRadius > 0)) {\n    return 1;\n  }\n  const cosine = THREE.MathUtils.clamp(\n    sourceDirection.dot(occluderDirection) / (sourceLength * occluderLength),\n    -1,\n    1,\n  );\n  const separation = Math.acos(cosine);\n  const overlap = circleOverlapArea(\n    sourceAngularRadius,\n    occluderAngularRadius,\n    separation,\n  );\n  return THREE.MathUtils.clamp(\n    1 - overlap / (PI * sourceAngularRadius * sourceAngularRadius),\n    0,\n    1,\n  );\n}\n\nexport function finiteSourceVisibility({\n  observerPosition,\n  sourceCenter,\n  sourceRadius,\n  occluderCenter,\n  occluderRadius,\n  sourceOffset = new THREE.Vector3(),\n  occluderOffset = new THREE.Vector3(),\n} = {}) {\n  if (!observerPosition || !sourceCenter || !(sourceRadius > 0)) return 1;\n  sourceOffset.subVectors(sourceCenter, observerPosition);\n  const sourceDistance = sourceOffset.length();\n  if (!(sourceDistance > sourceRadius)) return 1;\n  if (!occluderCenter || !(occluderRadius > 0)) return 1;\n  occluderOffset.subVectors(occluderCenter, observerPosition);\n  const occluderDistance = occluderOffset.length();\n  if (!(occluderDistance > occluderRadius) || occluderDistance >= sourceDistance) return 1;\n  return finiteDiscVisibility({\n    sourceDirection: sourceOffset,\n    sourceAngularRadius: apparentAngularRadius(sourceRadius, sourceDistance),\n    occluderDirection: occluderOffset,\n    occluderAngularRadius: apparentAngularRadius(occluderRadius, occluderDistance),\n  });\n}\n\nfunction raySphereInterval(origin, direction, center, radius) {\n  const ox = origin.x - center.x;\n  const oy = origin.y - center.y;\n  const oz = origin.z - center.z;\n  const b = ox * direction.x + oy * direction.y + oz * direction.z;\n  const c = ox * ox + oy * oy + oz * oz - radius * radius;\n  const discriminant = b * b - c;\n  if (discriminant < 0) return null;\n  const root = Math.sqrt(discriminant);\n  return [-b - root, -b + root];\n}\n\n/**\n * Direct Beer-Lambert transmission along an observer-to-Sun ray. All work is\n * performed in JS doubles; the astronomical source position never enters a\n * shader subtraction. The bounded midpoint integration runs once per frame,\n * not once per scene fragment.\n */\nexport function atmosphericTransmittance({\n  observerPosition,\n  lightDirection,\n  planetCenter = new THREE.Vector3(),\n  planetRadius = PLANET_RADIUS,\n  atmosphereHeight = ATMOSPHERE_HEIGHT_M,\n  rayleighScaleHeight = RAYLEIGH_SCALE_HEIGHT_M,\n  mieScaleHeight = MIE_SCALE_HEIGHT_M,\n  betaRayleigh = BETA_RAYLEIGH,\n  betaMie = BETA_MIE,\n  integrationSteps = DEFAULT_INTEGRATION_STEPS,\n  result = new THREE.Vector3(1, 1, 1),\n} = {}) {\n  if (!observerPosition || !lightDirection || !(planetRadius > 0)) {\n    return result.set(1, 1, 1);\n  }\n  const directionLength = lightDirection.length?.() ?? 0;\n  if (!(directionLength > 0)) return result.set(1, 1, 1);\n  const dx = lightDirection.x / directionLength;\n  const dy = lightDirection.y / directionLength;\n  const dz = lightDirection.z / directionLength;\n  const direction = { x: dx, y: dy, z: dz };\n\n  const groundInterval = raySphereInterval(\n    observerPosition,\n    direction,\n    planetCenter,\n    planetRadius,\n  );\n  if (groundInterval && groundInterval[1] > 1e-3 && groundInterval[0] > 1e-3) {\n    return result.set(0, 0, 0);\n  }\n\n  const topRadius = planetRadius + Math.max(0, atmosphereHeight);\n  const atmosphereInterval = raySphereInterval(\n    observerPosition,\n    direction,\n    planetCenter,\n    topRadius,\n  );\n  if (!atmosphereInterval || atmosphereInterval[1] <= 0) {\n    return result.set(1, 1, 1);\n  }\n  const start = Math.max(0, atmosphereInterval[0]);\n  const end = Math.max(start, atmosphereInterval[1]);\n  const length = end - start;\n  if (!(length > 1e-3)) return result.set(1, 1, 1);\n\n  const steps = THREE.MathUtils.clamp(\n    Math.round(integrationSteps) || DEFAULT_INTEGRATION_STEPS,\n    8,\n    96,\n  );\n  const stepLength = length / steps;\n  let rayleighColumn = 0;\n  let mieColumn = 0;\n  for (let index = 0; index < steps; index += 1) {\n    const distance = start + (index + 0.5) * stepLength;\n    const px = observerPosition.x + dx * distance - planetCenter.x;\n    const py = observerPosition.y + dy * distance - planetCenter.y;\n    const pz = observerPosition.z + dz * distance - planetCenter.z;\n    const altitude = Math.max(0, Math.hypot(px, py, pz) - planetRadius);\n    rayleighColumn += Math.exp(-altitude / rayleighScaleHeight) * stepLength;\n    mieColumn += Math.exp(-altitude / mieScaleHeight) * stepLength;\n  }\n  result.set(\n    Math.exp(-(betaRayleigh[0] * rayleighColumn + betaMie[0] * mieColumn)),\n    Math.exp(-(betaRayleigh[1] * rayleighColumn + betaMie[1] * mieColumn)),\n    Math.exp(-(betaRayleigh[2] * rayleighColumn + betaMie[2] * mieColumn)),\n  );\n  return result;\n}\n","/**\n * Earth Material Factory\n *\n * Terrain material that outputs pure albedo (diffuse color).\n * All lighting (sun, sky) is handled by @takram/three-atmosphere\n * AerialPerspectiveEffect post-process via sunLight/skyLight. The scene\n * settings retain sunIrradiance/skyIrradiance as compatibility aliases.\n *\n * The NormalPass renders geometry normals using MeshNormalMaterial override,\n * which the atmosphere system uses for physically-correct lighting.\n *\n * References:\n * - https://github.com/takram-design-engineering/three-geospatial\n */\n\nimport * as THREE from 'three';\nimport { wrapCloudMapSampling } from './cloud-map-sampling.js';\nimport { WATER_COVERAGE_GLSL, WATER_GEOMETRY_GLSL, waterCoverageUniforms } from './water-coverage.js';\nimport { WATER_REFLECTANCE_GLSL } from './water-reflectance.js';\nimport { computeWaterOptics } from './ocean-water-optics.js';\nimport { NIGHT_LIGHTS_GEOGRAPHY_GLSL } from '../refactor/imagery/NightLightsGeoreference.js';\nimport { nightCloudLightingForExistingField } from './night-cloud-lighting.js';\nimport { ORBITAL_CLOUD_VOLUME_GLSL } from './orbital-cloud-volume.js';\nimport {\n  NIGHT_LIGHTS_EMISSION_DEFAULTS,\n  NIGHT_LIGHTS_SOURCE_SIGNAL_GLSL,\n  NIGHT_LIGHTS_SURFACE_CARRIER_GLSL,\n} from '../refactor/render/NightLightsEmissionContract.js';\nimport {\n  CELESTIAL_IRRADIANCE_GLSL,\n} from '../refactor/render/CelestialIrradianceContract.js';\nimport {\n  PLANET_RADIUS,\n  ATMOSPHERE_RADIUS_M,\n  RAYLEIGH_SCALE_HEIGHT_M,\n  MIE_SCALE_HEIGHT_M,\n  BETA_RAYLEIGH,\n  BETA_MIE,\n  MIE_G\n} from './constants.js';\n\n/**\n * Create Earth terrain material for WMTS tiles\n *\n * This material outputs PURE ALBEDO only. No lighting calculations.\n * ALL lighting is handled by the atmosphere system's sunLight/skyLight path,\n * which uses the normal buffer from NormalPass for physically-correct lighting.\n *\n * This matches the reference geospatial implementation which uses MeshBasicMaterial\n * to output pure color, letting the atmosphere post-process handle all lighting.\n *\n * @param {Object} textures - Unused, kept for API compatibility\n * @param {THREE.DirectionalLight} sunLight - Unused, kept for API compatibility\n * @param {Object} options - Unused, kept for API compatibility\n * @returns {THREE.ShaderMaterial}\n */\nexport function createEarthMaterial(textures, sunLight, options = {}) {\n  const waterOptics = computeWaterOptics();\n  const uniforms = {\n    // WMTS imagery texture - each tile gets its own texture\n    imageryTexture: { value: null },\n    // Optional orbit overlays\n    specularTexture: { value: null },\n    specularEnabled: { value: 0.0 },\n    specularStrength: { value: 0.9 },\n    waterMaskEnabled: { value: 0 },\n    regionalWaterMask: { value: null },\n    regionalWaterBounds: { value: new THREE.Vector4(0, 0, 1, 1) },\n    regionalWaterEnabled: { value: 0 },\n    waterLocalFrame: { value: new THREE.Matrix3() },\n    waterLocalLatitude: { value: new THREE.Vector2(0,1) },\n    waterSurfaceGeoid: { value: 0 },\n    waterSurfaceSeaHeight: { value: 0 },\n    waterSurfaceDatumReady: { value: 0 },\n    waterSurfaceHeightRange: { value: new THREE.Vector2(0,1) },\n    waterSurfaceHeightEnabled: { value: 0 },\n    waterBedTexture: { value: null },\n    waterBedBounds: { value: new THREE.Vector4(0,0,1,1) },\n    waterBedEnabled: { value: 0 },\n    waterDiffuseAttenuation: { value: new THREE.Vector3(...waterOptics.diffuseAttenuation) },\n    waterWindSpeed: { value: 8 },\n    simpleCloudsTexture: { value: null },\n    simpleCloudsEnabled: { value: 0.0 },\n    simpleCloudsOpacity: { value: 0.6 },\n    simpleCloudsShadowStrength: { value: 0.25 },\n    simpleCloudsShadowHeight: { value: 12000.0 },\n    simpleCloudsBlendMode: { value: 0.0 }, // 0=overlay, 1=additive, 2=screen, 3=multiply\n    simpleCloudsAlphaThreshold: { value: 0.0 },\n    simpleCloudsAlphaSoftness: { value: 0.0 },\n    // Deep-night clouds are dark occluders. This deliberately tiny cool term\n    // represents airglow scattered through their tops without restoring a\n    // white ambient floor under the tone mapper.\n    simpleCloudsNightAirglowColor: { value: new THREE.Color('#9fb3c2') },\n    simpleCloudsNightAirglowStrength: { value: 0.006 },\n    orbitCloudsTexture: { value: null },\n    orbitCloudsEnabled: { value: 0.0 },\n    orbitCloudsShadowStrength: { value: 0.3 },\n    orbitCloudsShadowHeight: { value: 12000.0 },\n    lightPollutionTexture: { value: null },\n    lightPollutionDetailTexture: { value: null },\n    lightPollutionDetailEnabled: { value: 0.0 },\n    // centerU, minV, spanU, spanV in canonical Web-Mercator UV space.\n    lightPollutionDetailBounds: { value: new THREE.Vector4(0.5, 0.0, 1.0, 1.0) },\n    lightPollutionEnabled: { value: 0.0 },\n    lightPollutionIntensity: { value: NIGHT_LIGHTS_EMISSION_DEFAULTS.intensity },\n    lightPollutionMapGain: { value: NIGHT_LIGHTS_EMISSION_DEFAULTS.mapGain },\n    lightPollutionSurfaceIntensityScale: {\n      value: NIGHT_LIGHTS_EMISSION_DEFAULTS.surfaceIntensityScale,\n    },\n    // Reject Black Marble's blue/purple relief before the lower source-light\n    // knee preserves faint neutral/warm corridors between city cores.\n    lightPollutionEmissionThreshold: { value: NIGHT_LIGHTS_EMISSION_DEFAULTS.emissionThreshold },\n    lightPollutionEmissionSoftness: { value: NIGHT_LIGHTS_EMISSION_DEFAULTS.emissionSoftness },\n    lightPollutionEmissionPower: { value: NIGHT_LIGHTS_EMISSION_DEFAULTS.emissionPower },\n    lightPollutionEmissionBlueSuppression: {\n      value: NIGHT_LIGHTS_EMISSION_DEFAULTS.emissionBlueSuppression,\n    },\n    lightPollutionColor: { value: new THREE.Color(0xffb57a) },\n    // Manual alignment of the light-pollution texture over the surface.\n    // mercator: 0 = sample as equirectangular (matches an EPSG:4326 source),\n    // 1 = apply the Web-Mercator latitude warp. offset/scale shift + size the\n    // sampled UV (scale is about the 0.5 center) so the overlay can be nudged\n    // onto its true position.\n    lightPollutionMercator: { value: 0.0 },\n    lightPollutionUvOffset: { value: new THREE.Vector2(0.0, 0.0) },\n    lightPollutionUvScale: { value: new THREE.Vector2(1.0, 1.0) },\n    // Water shading\n    waterNormalsTexture: { value: null },\n    waterNormalsEnabled: { value: 0.0 },\n    waterEnabled: { value: 0.0 },\n    // Written by OceanSurface while its GPU sea surface is drawn nearby.\n    seaSurfaceActive: { value: 0.0 },\n    seaLevelRadius: { value: 6378137.0 },\n    // Sea confirmed by the vector ocean resolver around the observer, where\n    // the coarse global mask may misclassify atolls and narrow coasts.\n    seaConfirmedCenter: { value: new THREE.Vector3() },\n    seaConfirmedRadius: { value: 0.0 },\n    waterOpacity: { value: 0.75 },\n    waterColor: { value: new THREE.Color(0x031e32) },\n    waterNormalScale: { value: 0.7 },\n    waterDistortion: { value: 0.35 },\n    waterSpecularStrength: { value: 1.1 },\n    waterSpecularPower: { value: 64.0 },\n    waterFresnelStrength: { value: 0.6 },\n    waterFresnelPower: { value: 5.0 },\n    waterUvScale: { value: 1.2 },\n    waterTime: { value: 0.0 },\n    infraPaintTexture: { value: null },\n    infraPaintEnabled: { value: 0.0 },\n    infraPaintOpacity: { value: 0.9 },\n    infraPaintUvOffset: { value: new THREE.Vector2(0, 0) },\n    infraPaintUvScale: { value: new THREE.Vector2(1, 1) },\n    // Imagery loading indicator (per-tile overrides in cloned uniforms)\n    loadingTime: { value: 0.0 }, // ms (shared)\n    loadingDuration: { value: 1000.0 }, // ms per wave\n    loadingEnabled: { value: 0.0 },\n    loadingStartTime: { value: 0.0 },\n    loadingCenterDir: { value: new THREE.Vector3(0, 0, 1) },\n    loadingAngularRadius: { value: 1.0 },\n    loadingIntensity: { value: 0.85 },\n    loadingPulseWidth: { value: 0.18 },\n    loadingFillStrength: { value: 0.35 },\n    loadingNoiseStrength: { value: 0.2 },\n    // Planet radius for horizon culling\n    planetRadius: { value: PLANET_RADIUS },\n    // Sun direction in world space for night-side darkening\n    sunDirection: { value: new THREE.Vector3(0, 0, 1) },\n    moonCenterWorld: { value: new THREE.Vector3(0, 0, 384_400_000) },\n    moonRadius: { value: 1_737_400 },\n    sunAngularRadius: { value: 0.004675 },\n    sunDistance: { value: 149_597_870_700 },\n    // Camera position in world space - used for RTE precision enhancement\n    cameraWorldPosition: { value: new THREE.Vector3(0, 0, 0) },\n    // Night-side visibility tuneables\n    nightMinBrightness: { value: 0.002 },  // Minimum brightness multiplier on night side (0.002 = 0.2%)\n    nightVision: { value: 0 },\n    nightAmbientColor: { value: new THREE.Vector3(0, 0, 0) },  // No ambient tint; night geography/emissives remain independent\n    nightAmbientStrength: { value: 0.2 },  // How much ambient color is mixed in (0-1)\n    nightTransitionStart: { value: 0.0 },  // Sun dot value where night begins\n    nightTransitionEnd: { value: 0.5 },  // Sun dot value where day begins\n    nightPower: { value: 1.6 }  // Exponential falloff for night mask\n  };\n\n/**\n * RTE (Relative-To-Eye) Enhanced Vertex Shader\n *\n * PRECISION STRATEGY:\n * At planetary scale (~6.4M meters from origin), Float32 has only ~1 meter precision.\n * We improve this by:\n * 1. Passing camera position as a uniform (computed in Float64 on CPU)\n * 2. Computing world position relative to camera in the shader\n * 3. Using the relative position for view transformation\n *\n * This keeps the intermediate math values small (meters from camera) rather than\n * large (millions of meters from origin), preserving GPU Float32 precision.\n */\nconst vertexShader = `\n  #include <common>\n  #include <logdepthbuf_pars_vertex>\n\n  uniform vec3 cameraWorldPosition;\n  uniform vec3 sunDirection;\n\n  attribute float aWaterMask;\n\n  varying vec2 vUv;\n  varying vec2 vUvImagery;\n  varying vec3 vWorldPosition;\n  varying vec3 vPlanetSurfacePosition;\n  varying vec3 vLocalSunDirection;\n  varying vec3 vSurfaceDir;\n  varying vec3 vToCamera;\n  varying vec3 vLocalToCamera;\n  varying vec3 vWaterWorldNormal;\n  varying float vWaterCameraAltitude;\n  varying float vWaterMask;\n\n  void main() {\n    vUv = uv;\n    #ifdef USE_UV2\n      vUvImagery = uv2;\n    #else\n      vUvImagery = uv;\n    #endif\n\n    // Transform vertex to world space\n    vec4 worldPosition = modelMatrix * vec4(position, 1.0);\n    vWorldPosition = worldPosition.xyz;\n    vPlanetSurfacePosition = inverseTransformDirection(worldPosition.xyz, modelMatrix) * length(worldPosition.xyz);\n    vWaterWorldNormal = transformDirection(ncaWaterGeodeticNormal(vPlanetSurfacePosition), modelMatrix);\n    vec3 waterLocalCamera = inverseTransformDirection(cameraPosition, modelMatrix) * length(cameraPosition);\n    vWaterCameraAltitude = length(waterLocalCamera) - ncaWaterReferenceRadius(waterLocalCamera);\n    vLocalSunDirection = inverseTransformDirection(normalize(sunDirection), modelMatrix);\n    vWaterMask = aWaterMask;\n\n    // HIGH PRECISION FIX: Compute direction vectors in vertex shader\n    // At planetary scale (~6.4M meters), float32 subtraction loses precision.\n    // Computing these in vertex shader preserves precision from modelMatrix math.\n    // The normalized direction is stable (unit vector), and vToCamera computed\n    // here avoids large float32 subtraction in fragment shader.\n    vSurfaceDir = normalize(worldPosition.xyz);\n    vToCamera = cameraWorldPosition - worldPosition.xyz;\n    vLocalToCamera = inverseTransformDirection(vToCamera, modelMatrix);\n\n    // Standard MVP transform - Three.js handles view matrix construction\n    // The modelViewMatrix already incorporates camera position\n    gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n\n    #include <logdepthbuf_vertex>\n  }\n`;\n\n  const fragmentShader = `\n    #include <common>\n    #include <logdepthbuf_pars_fragment>\n\n    uniform sampler2D imageryTexture;\n    uniform sampler2D specularTexture;\n    uniform float specularEnabled;\n    uniform float specularStrength;\n    uniform sampler2D simpleCloudsTexture;\n    uniform float simpleCloudsEnabled;\n    uniform float simpleCloudsOpacity;\n    uniform float simpleCloudsShadowStrength;\n    uniform float simpleCloudsShadowHeight;\n    uniform float simpleCloudsBlendMode;\n    uniform float simpleCloudsAlphaThreshold;\n    uniform float simpleCloudsAlphaSoftness;\n    uniform vec3 simpleCloudsNightAirglowColor;\n    uniform float simpleCloudsNightAirglowStrength;\n    uniform sampler2D orbitCloudsTexture;\n    uniform float orbitCloudsEnabled;\n    uniform float orbitCloudsShadowStrength;\n    uniform float orbitCloudsShadowHeight;\n    uniform sampler2D lightPollutionTexture;\n    uniform sampler2D lightPollutionDetailTexture;\n    uniform float lightPollutionDetailEnabled;\n    uniform vec4 lightPollutionDetailBounds;\n    uniform float lightPollutionEnabled;\n    uniform float lightPollutionIntensity;\n    uniform float lightPollutionMapGain;\n    uniform float lightPollutionSurfaceIntensityScale;\n    uniform float lightPollutionEmissionThreshold;\n    uniform float lightPollutionEmissionSoftness;\n    uniform float lightPollutionEmissionPower;\n    uniform float lightPollutionEmissionBlueSuppression;\n    uniform vec3 lightPollutionColor;\n    uniform float lightPollutionMercator;\n    uniform vec2 lightPollutionUvOffset;\n    uniform vec2 lightPollutionUvScale;\n    uniform sampler2D waterNormalsTexture;\n    uniform float waterNormalsEnabled;\n    uniform float waterEnabled;\n    uniform float waterOpacity;\n    uniform vec3 waterColor;\n    uniform float waterNormalScale;\n    uniform float waterDistortion;\n    uniform float waterSpecularStrength;\n    uniform float waterSpecularPower;\n    uniform float waterFresnelStrength;\n    uniform float waterFresnelPower;\n    uniform float waterUvScale;\n    uniform float waterTime;\n    uniform sampler2D infraPaintTexture;\n    uniform float infraPaintEnabled;\n    uniform float infraPaintOpacity;\n    uniform vec2 infraPaintUvOffset;\n    uniform vec2 infraPaintUvScale;\n    uniform float loadingTime;\n    uniform float loadingDuration;\n    uniform float loadingEnabled;\n    uniform float loadingStartTime;\n    uniform vec3 loadingCenterDir;\n    uniform float loadingAngularRadius;\n    uniform float loadingIntensity;\n    uniform float loadingPulseWidth;\n    uniform float loadingFillStrength;\n    uniform float loadingNoiseStrength;\n    uniform float planetRadius;\n    uniform vec3 sunDirection;\n    uniform vec3 moonCenterWorld;\n    uniform float moonRadius;\n    uniform float sunAngularRadius;\n    uniform float sunDistance;\n    // Night-side visibility tuneables\n    uniform float nightMinBrightness;\n    uniform float nightVision;\n    uniform vec3 nightAmbientColor;\n    uniform float nightAmbientStrength;\n    uniform float nightTransitionStart;\n    uniform float nightTransitionEnd;\n    uniform float nightPower;\n\n    varying vec2 vUv;\n    varying vec2 vUvImagery;\n    varying vec3 vWorldPosition;\n  varying vec3 vPlanetSurfacePosition;\n  varying vec3 vLocalSunDirection;\n    varying vec3 vSurfaceDir;\n    varying vec3 vToCamera;\n    varying vec3 vLocalToCamera;\n  varying vec3 vWaterWorldNormal;\n  varying float vWaterCameraAltitude;\n    varying float vWaterMask;\n\n    float resolveSimpleCloudMask(vec4 cloudSample) {\n      // The cloud map (clouds-alpha.png) is luminance+alpha: the ALPHA channel is the\n      // cloud coverage (clear sky reads low alpha), while luminance stays bright almost\n      // everywhere and must NOT drive the mask. The map also has a high, fairly uniform\n      // haze \"backing\": showing the raw alpha (low threshold) blends backing + clouds\n      // into a white sheet. So: subtract the backing with a black point (threshold),\n      // then EXPAND CONTRAST with a gamma curve (softness). The gamma keeps the backing\n      // pushed toward transparent while the cloud gradient is preserved monotonically,\n      // so detail stays maximal even as the threshold approaches 0 — no white sheet.\n      float coverage = clamp(cloudSample.a, 0.0, 1.0);\n      float black = clamp(simpleCloudsAlphaThreshold, 0.0, 0.95);\n      float contrast = 1.0 + clamp(simpleCloudsAlphaSoftness, 0.0, 1.0) * 6.0;\n      float t = clamp((coverage - black) / (1.0 - black + 1e-4), 0.0, 1.0);\n      return pow(t, contrast);\n    }\n\n    float raySphereFirstHit(vec3 rayOrigin, vec3 rayDir, float radius) {\n      float b = dot(rayOrigin, rayDir);\n      float c = dot(rayOrigin, rayOrigin) - radius * radius;\n      float h = b * b - c;\n      if (h < 0.0) return -1.0;\n      float s = sqrt(h);\n      float tNear = -b - s;\n      float tFar = -b + s;\n      if (tNear > 0.0) return tNear;\n      if (tFar > 0.0) return tFar;\n      return -1.0;\n    }\n\n    vec2 directionToEquirectUv(vec3 dir) {\n      vec3 n = normalize(dir);\n      float lon = atan(n.x, n.z);\n      float lat = asin(clamp(n.y, -1.0, 1.0));\n      float u = lon / (2.0 * PI) + 0.5;\n      float v = 0.5 - (lat / PI);\n      return vec2(fract(u + 1.0), clamp(v, 0.0, 1.0));\n    }\n\n    vec2 lightPollutionSourceUv(vec2 equirectUv) {\n      vec2 sourceUv = equirectUv;\n      if (lightPollutionMercator > 0.5) {\n        float latitude = (0.5 - equirectUv.y) * PI;\n        latitude = clamp(latitude, -1.4844222297, 1.4844222297);\n        float sinLatitude = sin(latitude);\n        sourceUv.y = clamp(\n          0.5 - 0.25 * log((1.0 + sinLatitude) / (1.0 - sinLatitude)) / PI,\n          0.0,\n          1.0\n        );\n      }\n      sourceUv = (sourceUv - 0.5) * lightPollutionUvScale\n        + 0.5\n        + lightPollutionUvOffset;\n      sourceUv.x = fract(sourceUv.x + 1.0);\n      sourceUv.y = clamp(sourceUv.y, 0.0, 1.0);\n      return sourceUv;\n    }\n\n    vec4 sampleLightPollutionField(vec2 equirectUv) {\n      vec2 sourceUv = lightPollutionSourceUv(equirectUv);\n      vec4 globalSample = texture2D(lightPollutionTexture, sourceUv);\n      if (lightPollutionDetailEnabled < 0.5) return globalSample;\n\n      float wrappedDeltaU = fract(\n        sourceUv.x - lightPollutionDetailBounds.x + 0.5\n      ) - 0.5;\n      vec2 detailUv = vec2(\n        wrappedDeltaU / max(lightPollutionDetailBounds.z, 1e-6) + 0.5,\n        (sourceUv.y - lightPollutionDetailBounds.y)\n          / max(lightPollutionDetailBounds.w, 1e-6)\n      );\n      float detailInside = step(0.0, detailUv.x)\n        * step(detailUv.x, 1.0)\n        * step(0.0, detailUv.y)\n        * step(detailUv.y, 1.0);\n      vec4 detailSample = texture2D(\n        lightPollutionDetailTexture,\n        clamp(detailUv, vec2(0.0), vec2(1.0))\n      );\n      return mix(globalSample, detailSample, detailInside);\n    }\n\n    ${NIGHT_LIGHTS_SOURCE_SIGNAL_GLSL}\n    ${NIGHT_LIGHTS_SURFACE_CARRIER_GLSL}\n    ${NIGHT_LIGHTS_GEOGRAPHY_GLSL}\n    ${nightCloudLightingForExistingField('lightPollution', true)}\n    ${ORBITAL_CLOUD_VOLUME_GLSL}\n    ${CELESTIAL_IRRADIANCE_GLSL}\n\n    float resolveSolarEclipseVisibility(vec3 worldPosition) {\n      vec3 moonOffset = moonCenterWorld - worldPosition;\n      float moonDistance = length(moonOffset);\n      if (moonDistance <= moonRadius) return 1.0;\n      vec3 centerSunDirection = normalize(sunDirection);\n      vec3 observerPerpendicular = worldPosition\n        - centerSunDirection * dot(worldPosition, centerSunDirection);\n      vec3 localSunDirection = normalize(\n        centerSunDirection\n          - observerPerpendicular / max(sunDistance, 1.0)\n      );\n      float moonAngularRadius = asin(clamp(\n        moonRadius / moonDistance,\n        0.0,\n        1.0\n      ));\n      return ncaFiniteDiscVisibility(\n        localSunDirection,\n        sunAngularRadius,\n        moonOffset,\n        moonAngularRadius\n      );\n    }\n\n    float resolveLightPollutionEmission(float sourceSignal) {\n      float threshold = clamp(lightPollutionEmissionThreshold, 0.0, 0.95);\n      float softness = max(lightPollutionEmissionSoftness, 1e-4);\n      float normalizedSignal = clamp(\n        (sourceSignal - threshold) / max(1.0 - threshold, 1e-4),\n        0.0,\n        1.0\n      );\n      float emissionGate = smoothstep(\n        threshold,\n        min(1.0, threshold + softness),\n        sourceSignal\n      );\n      return pow(\n        normalizedSignal,\n        max(lightPollutionEmissionPower, 0.1)\n      ) * emissionGate;\n    }\n\n    void main() {\n      #include <logdepthbuf_fragment>\n\n      // Sample current WMTS imagery texture\n      vec3 albedo = texture2D(imageryTexture, vUvImagery).rgb;\n\n      // Orbit blend (avoid map overlays in surface mode)\n      float camDist = length(cameraPosition);\n      float orbitBlend = ncaOrbitalWaterBlend(vWaterCameraAltitude);\n\n      // HIGH PRECISION: Use pre-computed surface direction from vertex shader\n      // This avoids normalizing large world positions in fragment shader\n      vec3 surfaceDir = normalize(vSurfaceDir);\n      float sunDot = dot(surfaceDir, sunDirection);\n      float dayToNight = smoothstep(nightTransitionStart, nightTransitionEnd, sunDot);\n      float solarEclipseVisibility = resolveSolarEclipseVisibility(vWorldPosition);\n      float eclipseDayIrradiance = mix(0.075, 1.0, solarEclipseVisibility);\n      float waterSunTransmission = 1.0;\n      float waterViewTransmission = 1.0;\n      float nightMask = 1.0 - dayToNight;\n      nightMask = pow(nightMask, nightPower);\n      // Geographic masks use north-at-v=0 independently of mesh UVs (standard\n      // SphereGeometry uses the opposite vertical convention). Sampling vUv\n      // here mirrors specular coverage across the equator on those meshes.\n      float geojsonWater = clamp(vWaterMask, 0.0, 1.0);\n      vec3 mappedWater = ncaWaterCoverage(vPlanetSurfacePosition);\n      float specularWater = ncaWaterGlobalEnabled > 0.5 ? mappedWater.x\n        : (specularEnabled > 0.5 ? texture2D(specularTexture, ncaWaterGlobalUv(vPlanetSurfacePosition)).r : 0.0);\n      float waterMask = mappedWater.z > 0.5 ? mappedWater.x : max(geojsonWater, specularWater);\n\n      // Water shading (hybrid mask from geojson + specular)\n      if (waterEnabled > 0.5 && waterMask > 0.001) {\n        vec2 waterUv = vUv * waterUvScale;\n        float t = waterTime;\n        vec2 flowA = vec2(t * 0.02, t * 0.015);\n        vec2 flowB = vec2(-t * 0.015, t * 0.02);\n        vec3 n = vec3(0.0, 0.0, 1.0);\n        if (waterNormalsEnabled > 0.5) {\n          vec3 n1 = texture2D(waterNormalsTexture, waterUv + flowA).xyz * 2.0 - 1.0;\n          vec3 n2 = texture2D(waterNormalsTexture, waterUv * 1.9 + flowB).xyz * 2.0 - 1.0;\n          n = normalize(mix(n1, n2, 0.5));\n        }\n        float detailBlend = 1.0 - orbitBlend;\n        n.xy *= waterNormalScale * waterDistortion * detailBlend;\n        n = normalize(n);\n\n        vec3 up = vec3(0.0, 1.0, 0.0);\n        vec3 waterSurfaceNormal = normalize(vWaterWorldNormal);\n        vec3 tangent = cross(up, waterSurfaceNormal);\n        if (dot(tangent, tangent) < 1e-10) {\n          tangent = cross(vec3(1.0, 0.0, 0.0), waterSurfaceNormal);\n        }\n        tangent = normalize(tangent);\n        vec3 bitangent = normalize(cross(waterSurfaceNormal, tangent));\n        vec3 waterNormal = normalize(tangent * n.x + bitangent * n.y + waterSurfaceNormal * n.z);\n\n        // HIGH PRECISION: Use pre-computed camera direction from vertex shader\n        vec3 viewDir = normalize(vToCamera);\n        vec3 sunDir = sunDirection;\n        float specAngle = max(dot(reflect(-sunDir, waterNormal), viewDir), 0.0);\n        float spec = pow(specAngle, waterSpecularPower) * waterSpecularStrength;\n        spec *= dayToNight * solarEclipseVisibility;\n\n        float fresnel = pow(1.0 - max(dot(viewDir, waterNormal), 0.0), waterFresnelPower);\n        fresnel *= waterFresnelStrength;\n\n        // Realistic deep-ocean body: a uniform deep blue that absorbs (darkens)\n        // when viewed straight down and lifts toward a lighter blue at grazing\n        // angles (sky reflection), so the sea reads as real water rather than\n        // cheap specular over the photoreal tiles. Sun glint + fresnel rim ride\n        // on top, and a little tile detail survives for coastal/sediment variation.\n        float oceanView = pow(1.0 - clamp(dot(viewDir, waterNormal), 0.0, 1.0), 2.0);\n        float openOcean = smoothstep(0.35, 0.85, waterMask);\n        vec3 deepColor = waterColor;\n        vec3 shallowColor = clamp(waterColor * 1.35, 0.0, 1.0);\n        vec3 oceanBody = mix(deepColor, shallowColor, oceanView * 0.45);\n        float oceanOpacity = mix(waterOpacity, 0.92, openOcean);\n        vec3 waterBase = mix(albedo, oceanBody, oceanOpacity);\n        vec3 waterLit = waterBase + shallowColor * fresnel;\n        vec3 bottomTransmission = ncaWaterBottomTransmission(vPlanetSurfacePosition,\n          waterSurfaceNormal, viewDir, normalize(sunDirection));\n        vec3 orbitalWater = mix(waterColor, albedo, bottomTransmission);\n        waterLit = mix(waterLit, orbitalWater, orbitBlend);\n        albedo = mix(albedo, waterLit, waterMask);\n      }\n\n      if (infraPaintEnabled > 0.5) {\n        vec2 paintUv = (vUvImagery - infraPaintUvOffset) * infraPaintUvScale;\n        if (paintUv.x >= 0.0 && paintUv.x <= 1.0 && paintUv.y >= 0.0 && paintUv.y <= 1.0) {\n          vec4 paintSample = texture2D(infraPaintTexture, paintUv);\n          float paintAlpha = paintSample.a * infraPaintOpacity;\n          albedo = mix(albedo, paintSample.rgb, paintAlpha);\n        }\n      }\n\n      // Simple orbit clouds overlay (equirect texture). From orbit the deck is\n      // a slab at its real altitude: parallax, thickness and relief shading.\n      float viewCloudAlpha = 0.0;\n      if (simpleCloudsEnabled > 0.5) {\n        vec4 cloudSample = texture2D(simpleCloudsTexture, vUv);\n        float cloudMask = resolveSimpleCloudMask(cloudSample);\n        float cloudRelief = 1.0;\n        if (orbitBlend > 0.0) {\n          NcaSimpleCloudViewResult cloudView = ncaSimpleCloudView(vPlanetSurfacePosition, vLocalToCamera,\n            vLocalSunDirection, max(simpleCloudsShadowHeight, 1.0));\n          cloudMask = mix(cloudMask, cloudView.alpha, orbitBlend);\n          cloudSample = mix(cloudSample, cloudView.sampleValue, orbitBlend);\n          cloudRelief = mix(1.0, cloudView.shade, orbitBlend * dayToNight);\n        }\n\n        // Project cloud shadows along sunlight direction onto the terrain/ocean shell.\n        float shadowMask = cloudMask;\n        if (simpleCloudsShadowStrength > 0.0\n            && dayToNight > 0.0\n            && solarEclipseVisibility > 0.001) {\n          float cloudShellRadius = max(planetRadius + 1.0, planetRadius + max(simpleCloudsShadowHeight, 0.0));\n          float hitT = raySphereFirstHit(vPlanetSurfacePosition, normalize(vLocalSunDirection), cloudShellRadius);\n          if (hitT > 0.0) {\n            vec3 cloudHitPos = vPlanetSurfacePosition + normalize(vLocalSunDirection) * hitT;\n            vec2 shadowUv = directionToEquirectUv(cloudHitPos);\n            // Mip-biased: the penumbra widens with the deck's height.\n            shadowMask = resolveSimpleCloudMask(texture2D(simpleCloudsTexture, shadowUv, 1.5));\n          }\n        }\n\n        // Keep cloud shadows sun-driven (day-side only).\n        float cloudShadow = shadowMask\n          * simpleCloudsShadowStrength\n          * dayToNight;\n        cloudShadow = clamp(cloudShadow, 0.0, 0.85);\n        waterSunTransmission *= 1.0 - cloudShadow;\n        albedo *= (1.0 - cloudShadow);\n        // Clouds exist on both sides, but the night side is unlit: fade cloud\n        // brightness to near-black across the terminator so night clouds read as\n        // dark occluders over the city lights instead of glowing gray blobs.\n        float cloudAlpha = cloudMask * simpleCloudsOpacity * orbitBlend;\n        viewCloudAlpha = clamp(cloudAlpha, 0.0, 1.0);\n        waterViewTransmission *= 1.0 - clamp(cloudAlpha, 0.0, 1.0);\n        // Use the texture luminance for internal cloud shading so dense cores read\n        // brighter than wisps — keeps high-frequency detail instead of a flat fill.\n        float cloudShade = clamp(max(cloudSample.r, max(cloudSample.g, cloudSample.b)), 0.0, 1.0);\n        vec3 nightCloudAirglow = simpleCloudsNightAirglowColor\n          * simpleCloudsNightAirglowStrength;\n        vec3 eclipsedCloudDayColor = vec3(eclipseDayIrradiance);\n        vec3 cloudColor = mix(nightCloudAirglow, eclipsedCloudDayColor, dayToNight)\n          * mix(0.7, 1.0, cloudShade) * cloudRelief;\n        if (simpleCloudsBlendMode < 0.5) {\n          // Overlay: blend toward cloud tops tinted by solar lighting.\n          albedo = mix(albedo, cloudColor, cloudAlpha);\n        } else if (simpleCloudsBlendMode < 1.5) {\n          // Additive: brighten without hard replacement.\n          albedo = clamp(albedo + cloudColor * cloudAlpha, 0.0, 1.0);\n        } else if (simpleCloudsBlendMode < 2.5) {\n          // Screen: softer brightening than additive.\n          vec3 screenColor = cloudColor * cloudAlpha;\n          albedo = 1.0 - (1.0 - albedo) * (1.0 - screenColor);\n        } else {\n          // Multiply: darken clouded areas.\n          albedo *= (1.0 - cloudAlpha);\n        }\n      }\n\n      // Orbit clouds shadow (satellite-derived coverage at higher altitude)\n      if (orbitCloudsEnabled > 0.5 && orbitCloudsShadowStrength > 0.0 && dayToNight > 0.0) {\n        float orbitCloudShellRadius = max(planetRadius + 1.0, planetRadius + max(orbitCloudsShadowHeight, 0.0));\n        float hitT = raySphereFirstHit(vPlanetSurfacePosition, normalize(vLocalSunDirection), orbitCloudShellRadius);\n        if (hitT > 0.0) {\n          vec3 cloudHitPos = vPlanetSurfacePosition + normalize(vLocalSunDirection) * hitT;\n          vec2 shadowUv = directionToEquirectUv(cloudHitPos);\n          float mask = resolveSimpleCloudMask(texture2D(orbitCloudsTexture, shadowUv));\n          float shadow = mask\n            * orbitCloudsShadowStrength\n            * dayToNight;\n          shadow = clamp(shadow, 0.0, 0.85);\n          waterSunTransmission *= 1.0 - shadow;\n          albedo *= (1.0 - shadow);\n        }\n      }\n\n      // Retain the authoritative local surface colour before astronomical\n      // attenuation. At street level the coarse NASA texel controls energy,\n      // while this imagery controls the visible structure and chroma.\n      vec3 surfaceProviderAlbedo = max(albedo, vec3(0.0));\n      float nightDarken = mix(1.0, nightMinBrightness, nightMask);\n      albedo *= nightDarken * mix(1.0, eclipseDayIrradiance, dayToNight);\n      albedo = mix(albedo, nightAmbientColor, nightMask * nightAmbientStrength);\n      albedo = mix(albedo, max(albedo, surfaceProviderAlbedo * 0.8), nightVision);\n\n      // NASA Black Marble pixels are light-source radiance on the actual\n      // terrain fragment. Add that radiance directly after night attenuation;\n      // never blend the source map into albedo and never draw a globe skin.\n      if (lightPollutionEnabled > 0.5) {\n        vec4 lightSample = sampleLightPollutionField(vUv);\n        vec3 lightRgb = max(lightSample.rgb, vec3(0.0));\n        float sourceLuminance = max(max(lightRgb.r, lightRgb.g), lightRgb.b);\n        float sourceSignal = resolveNightLightsSourceSignal(\n          lightRgb,\n          lightPollutionEmissionBlueSuppression\n        );\n        float sourceRadiance = resolveLightPollutionEmission(sourceSignal)\n          * lightPollutionMapGain;\n        vec3 sourceChroma = lightRgb / max(sourceLuminance, 1e-4);\n\n        float fadeStart = nightTransitionStart - 0.05;\n        float fadeEnd = nightTransitionEnd + 0.02;\n        float nightFactor = 1.0 - smoothstep(fadeStart, fadeEnd, sunDot);\n        nightFactor = pow(nightFactor, 1.5);\n\n        vec3 geometricNormal = normalize(cross(dFdx(vWorldPosition), dFdy(vWorldPosition)));\n        float outwardEmission = 0.65\n          + 0.35 * clamp(abs(dot(geometricNormal, surfaceDir)), 0.0, 1.0);\n        float cloudOcclusion = 1.0;\n        if (simpleCloudsEnabled > 0.5 && orbitBlend > 0.0) {\n          // The cloud actually seen along the view ray hides the direct beam.\n          cloudOcclusion = 1.0 - clamp(viewCloudAlpha, 0.0, 0.95);\n        }\n\n        vec3 surfaceEmissionCarrier = resolveNightLightsSurfaceCarrier(\n          surfaceProviderAlbedo,\n          sourceChroma,\n          lightPollutionColor,\n          ${NIGHT_LIGHTS_EMISSION_DEFAULTS.surfaceProviderColorMix}\n        );\n        vec3 orbitalEmissionCarrier = sourceChroma * lightPollutionColor;\n        vec3 emissionCarrier = mix(\n          surfaceEmissionCarrier,\n          orbitalEmissionCarrier,\n          orbitBlend\n        );\n        float altitudeScale = mix(\n          lightPollutionSurfaceIntensityScale,\n          1.0,\n          orbitBlend\n        );\n        vec3 emittedRadiance = emissionCarrier\n          * lightPollutionIntensity\n          * sourceRadiance;\n        albedo += emittedRadiance\n          * lightSample.a\n          * nightFactor\n          * outwardEmission\n          * cloudOcclusion\n          * altitudeScale;\n        if (cloudOcclusion < .999 && nightFactor > .001) {\n          // Light diffused up through the deck: a broad soft glow, not dots.\n          float coveredFraction = 1.0 - cloudOcclusion;\n          albedo += ncaNightCloudDiffuse(vPlanetSurfacePosition, simpleCloudsShadowHeight, coveredFraction)\n            * coveredFraction * nightFactor * orbitBlend * outwardEmission;\n        }\n        if (nightFactor > .001) {\n          // City light scattered by the atmosphere toward the viewer.\n          float airViewMu = dot(normalize(vToCamera), normalize(vPlanetSurfacePosition));\n          albedo += ncaNightAirGlow(vPlanetSurfacePosition, airViewMu) * nightFactor * orbitBlend;\n        }\n      }\n\n      // Specular highlight using global specular mask (ocean shine)\n      if (specularEnabled > 0.5) {\n        float specMask = waterMask;\n        // HIGH PRECISION: Use pre-computed camera direction from vertex shader\n        vec3 viewDir = normalize(vToCamera);\n        vec3 sunDir = sunDirection;\n        vec3 reflectedSky = vec3(0.035, 0.065, 0.11) * dayToNight;\n        vec3 reflectionRay = reflect(-normalize(vLocalToCamera), ncaWaterGeodeticNormal(vPlanetSurfacePosition));\n        if (simpleCloudsEnabled > 0.5) {\n          float hitT = raySphereFirstHit(vPlanetSurfacePosition, reflectionRay,\n            planetRadius + max(simpleCloudsShadowHeight, 1.0));\n          if (hitT > 0.0) {\n            vec4 reflectedCloud = texture2D(simpleCloudsTexture,\n              directionToEquirectUv(vPlanetSurfacePosition + reflectionRay * hitT));\n            float coverage = resolveSimpleCloudMask(reflectedCloud) * simpleCloudsOpacity;\n            vec3 cloudSky = mix(simpleCloudsNightAirglowColor * simpleCloudsNightAirglowStrength,\n              vec3(eclipseDayIrradiance), dayToNight) * mix(0.7, 1.0, max(reflectedCloud.r, max(reflectedCloud.g, reflectedCloud.b)));\n            reflectedSky = mix(reflectedSky, cloudSky, clamp(coverage, 0.0, 1.0));\n          }\n        }\n        if (orbitCloudsEnabled > 0.5) {\n          float hitT = raySphereFirstHit(vPlanetSurfacePosition, reflectionRay,\n            planetRadius + max(orbitCloudsShadowHeight, 1.0));\n          if (hitT > 0.0) {\n            vec4 reflectedCloud = texture2D(orbitCloudsTexture,\n              directionToEquirectUv(vPlanetSurfacePosition + reflectionRay * hitT));\n            reflectedSky = mix(reflectedSky, vec3(eclipseDayIrradiance * dayToNight)\n              * max(reflectedCloud.r, max(reflectedCloud.g, reflectedCloud.b)), resolveSimpleCloudMask(reflectedCloud));\n          }\n        }\n        albedo += ncaWaterReflection(normalize(vWaterWorldNormal), viewDir, normalize(sunDir), waterWindSpeed,\n          vec3(3.4) * solarEclipseVisibility * waterSunTransmission, reflectedSky)\n          * specMask * specularStrength * waterViewTransmission;\n      }\n\n      // Back-face culling for horizon (prevents tiles behind Earth from rendering)\n      vec3 C = cameraPosition;\n      if (camDist > planetRadius + 1.0) {\n        vec3 camDir = C / camDist;\n        // HIGH PRECISION: Use pre-computed surface direction from vertex shader\n        vec3 posDir = normalize(vSurfaceDir);\n        float horizonCos = planetRadius / camDist;\n        float dotCam = dot(posDir, camDir);\n        if (dotCam < horizonCos - 1e-4) discard;\n      }\n\n      // Imagery loading animation: radial wave from tile center (only for blank tiles)\n      if (loadingEnabled > 0.5) {\n        vec3 centerDir = normalize(loadingCenterDir);\n        float angle = acos(clamp(dot(normalize(vSurfaceDir), centerDir), -1.0, 1.0));\n        float denom = max(loadingAngularRadius, 1e-6);\n        float r = clamp(angle / denom, 0.0, 1.0);\n\n        float t = max(0.0, (loadingTime - loadingStartTime) / max(loadingDuration, 1.0));\n        float progress = fract(t);\n        float w = clamp(loadingPulseWidth, 0.02, 0.5);\n\n        // Expanding fill with a soft leading edge\n        float fill = 1.0 - smoothstep(progress, progress + w, r);\n        // Thin ring at the leading edge for a ripple effect\n        float ring = smoothstep(progress - w, progress, r) * (1.0 - smoothstep(progress, progress + w, r));\n\n        float alpha = max(fill * loadingFillStrength, ring);\n\n        // Subtle tessellated shimmer\n        float noise = fract(sin(dot(vWorldPosition.xyz, vec3(12.9898, 78.233, 37.719))) * 43758.5453);\n        alpha *= mix(1.0 - loadingNoiseStrength, 1.0, noise);\n\n        albedo = mix(albedo, vec3(1.0), clamp(alpha * loadingIntensity, 0.0, 1.0));\n      }\n\n      // Night limb: grazing light leaves through a long air path and fades\n      // into nightglow haze instead of ending in a hard silhouette.\n      albedo = ncaSimpleCloudViewNightLimb(albedo, vPlanetSurfacePosition, vLocalToCamera,\n        (1.0 - dayToNight) * orbitBlend);\n\n      gl_FragColor = vec4(albedo, 1.0);\n    }\n  `;\n\n\n\n  Object.assign(uniforms, waterCoverageUniforms(uniforms));\n  const material = new THREE.ShaderMaterial({\n    uniforms,\n    vertexShader: WATER_GEOMETRY_GLSL + vertexShader,\n    fragmentShader: wrapCloudMapSampling(WATER_COVERAGE_GLSL + WATER_REFLECTANCE_GLSL\n      + '\\nuniform float waterWindSpeed;\\n' + fragmentShader, ['simpleCloudsTexture', 'orbitCloudsTexture']),\n    side: THREE.BackSide,  // Render backfaces (terrain viewed from inside planet)\n    defines: {\n      USE_UV2: ''\n    }\n  });\n\n  // No per-frame updates needed - lighting handled by atmosphere system\n\n  // Intercept .map setter to handle WMTS imagery textures\n  Object.defineProperty(material, 'map', {\n    get: function() {\n      return uniforms.imageryTexture.value;\n    },\n    set: function(texture) {\n      uniforms.imageryTexture.value = texture;\n    }\n  });\n\n  material.userData.uniforms = uniforms;\n\n  // Custom clone method that deep-copies uniforms for per-tile imagery\n  material.clone = function() {\n    const clonedUniforms = {\n      // Scene-wide cloud, celestial and sensor contracts stay shared. Only\n      // the explicitly overridden imagery/placement fields are tile-local.\n      ...uniforms,\n      imageryTexture: { value: null }, // Each tile gets independent imagery\n      imageryTexturePrev: { value: null }, // Previous imagery for crossfade\n      imageryBlend: { value: 1.0 }, // Crossfade factor (0=prev, 1=current)\n      imageryPrevUvOffset: { value: new THREE.Vector2(0, 0) },\n      imageryPrevUvScale: { value: new THREE.Vector2(1, 1) },\n      specularTexture: uniforms.specularTexture,\n      specularEnabled: uniforms.specularEnabled,\n      specularStrength: uniforms.specularStrength,\n      simpleCloudsTexture: uniforms.simpleCloudsTexture,\n      simpleCloudsEnabled: uniforms.simpleCloudsEnabled,\n      simpleCloudsOpacity: uniforms.simpleCloudsOpacity,\n      simpleCloudsShadowStrength: uniforms.simpleCloudsShadowStrength,\n      simpleCloudsShadowHeight: uniforms.simpleCloudsShadowHeight,\n      simpleCloudsBlendMode: uniforms.simpleCloudsBlendMode,\n      simpleCloudsAlphaThreshold: uniforms.simpleCloudsAlphaThreshold,\n      simpleCloudsAlphaSoftness: uniforms.simpleCloudsAlphaSoftness,\n      simpleCloudsNightAirglowColor: uniforms.simpleCloudsNightAirglowColor,\n      simpleCloudsNightAirglowStrength: uniforms.simpleCloudsNightAirglowStrength,\n      lightPollutionTexture: uniforms.lightPollutionTexture,\n      lightPollutionDetailTexture: uniforms.lightPollutionDetailTexture,\n      lightPollutionDetailEnabled: uniforms.lightPollutionDetailEnabled,\n      lightPollutionDetailBounds: uniforms.lightPollutionDetailBounds,\n      lightPollutionEnabled: uniforms.lightPollutionEnabled,\n      lightPollutionIntensity: uniforms.lightPollutionIntensity,\n      lightPollutionMapGain: uniforms.lightPollutionMapGain,\n      lightPollutionSurfaceIntensityScale: uniforms.lightPollutionSurfaceIntensityScale,\n      lightPollutionEmissionThreshold: uniforms.lightPollutionEmissionThreshold,\n      lightPollutionEmissionSoftness: uniforms.lightPollutionEmissionSoftness,\n      lightPollutionEmissionPower: uniforms.lightPollutionEmissionPower,\n      lightPollutionEmissionBlueSuppression: uniforms.lightPollutionEmissionBlueSuppression,\n      lightPollutionColor: uniforms.lightPollutionColor,\n      lightPollutionMercator: uniforms.lightPollutionMercator,\n      lightPollutionUvOffset: uniforms.lightPollutionUvOffset,\n      lightPollutionUvScale: uniforms.lightPollutionUvScale,\n      waterNormalsTexture: uniforms.waterNormalsTexture,\n      waterEnabled: uniforms.waterEnabled,\n      waterOpacity: uniforms.waterOpacity,\n      waterColor: uniforms.waterColor,\n      waterNormalScale: uniforms.waterNormalScale,\n      waterDistortion: uniforms.waterDistortion,\n      waterSpecularStrength: uniforms.waterSpecularStrength,\n      waterSpecularPower: uniforms.waterSpecularPower,\n      waterFresnelStrength: uniforms.waterFresnelStrength,\n      waterFresnelPower: uniforms.waterFresnelPower,\n      waterUvScale: uniforms.waterUvScale,\n      waterTime: uniforms.waterTime,\n      infraPaintTexture: { value: null },\n      infraPaintEnabled: { value: uniforms.infraPaintEnabled.value },\n      infraPaintOpacity: { value: uniforms.infraPaintOpacity.value },\n      infraPaintUvOffset: { value: new THREE.Vector2(0, 0) },\n      infraPaintUvScale: { value: new THREE.Vector2(1, 1) },\n      loadingTime: uniforms.loadingTime,\n      loadingDuration: uniforms.loadingDuration,\n      loadingEnabled: { value: 0.0 },\n      loadingStartTime: { value: 0.0 },\n      loadingCenterDir: { value: new THREE.Vector3(0, 0, 1) },\n      loadingAngularRadius: { value: 1.0 },\n      loadingIntensity: uniforms.loadingIntensity,\n      loadingPulseWidth: uniforms.loadingPulseWidth,\n      loadingFillStrength: uniforms.loadingFillStrength,\n      loadingNoiseStrength: uniforms.loadingNoiseStrength,\n      planetRadius: { value: uniforms.planetRadius.value },\n      sunDirection: { value: uniforms.sunDirection.value.clone() },\n      cameraWorldPosition: { value: new THREE.Vector3(0, 0, 0) },\n      // Night-side visibility tuneables - share references to allow global updates\n      nightMinBrightness: uniforms.nightMinBrightness,\n      nightVision: uniforms.nightVision,\n      nightAmbientColor: uniforms.nightAmbientColor,\n      nightAmbientStrength: uniforms.nightAmbientStrength,\n      nightTransitionStart: uniforms.nightTransitionStart,\n      nightTransitionEnd: uniforms.nightTransitionEnd,\n      nightPower: uniforms.nightPower\n    };\n\n    const clonedMaterial = new THREE.ShaderMaterial({\n      uniforms: clonedUniforms,\n      vertexShader: this.vertexShader,\n      fragmentShader: this.fragmentShader,\n      side: this.side,\n      transparent: this.transparent,\n      blending: this.blending,\n      depthWrite: this.depthWrite,\n      depthTest: this.depthTest,\n      defines: this.defines ? { ...this.defines } : undefined\n    });\n\n    // Redefine map property for cloned material\n    Object.defineProperty(clonedMaterial, 'map', {\n      get: function() {\n        return clonedUniforms.imageryTexture.value;\n      },\n      set: function(texture) {\n        clonedUniforms.imageryTexture.value = texture;\n      }\n    });\n\n    clonedMaterial.userData.uniforms = clonedUniforms;\n\n    // Preserve the clone method itself\n    clonedMaterial.clone = material.clone;\n\n    return clonedMaterial;\n  };\n\n  return material;\n}\n\n/**\n * Create the lightweight globe used while photorealistic tiles are deferred.\n * It shares canonical sunlight, mapped water reflections, live simple clouds\n * and NASA night emission, without surface imagery or local wave allocations.\n *\n * @param {Object} sourceUniforms - Uniforms from the canonical earth material.\n * @returns {THREE.ShaderMaterial}\n */\nexport function createOrbitalEarthMaterial(sourceUniforms = {}) {\n  // RENDERER OWNERSHIP INVARIANT: this material belongs only to the standalone\n  // orbital overview sphere. It is not a hidden TriTree underlay and must be\n  // retired before photoreal surface tiles own the scene. Night-light pixels\n  // may emit from this opaque depth-writing surface, never a second globe.\n  const shared = (name, fallback) => sourceUniforms[name] || { value: fallback };\n  const uniforms = {\n    sunDirection: shared('sunDirection', new THREE.Vector3(0, 0, 1)),\n    moonCenterWorld: shared('moonCenterWorld', new THREE.Vector3(0, 0, 384_400_000)),\n    moonRadius: shared('moonRadius', 1_737_400),\n    sunAngularRadius: shared('sunAngularRadius', 0.004675),\n    sunDistance: shared('sunDistance', 149_597_870_700),\n    orbitalDayTexture: shared('orbitalDayTexture', null),\n    orbitalDayTextureEnabled: shared('orbitalDayTextureEnabled', 0.0),\n    specularTexture: shared('specularTexture', null),\n    waterMaskEnabled: shared('waterMaskEnabled', 0),\n    regionalWaterMask: shared('regionalWaterMask', null),\n    regionalWaterBounds: shared('regionalWaterBounds', new THREE.Vector4(0, 0, 1, 1)),\n    regionalWaterEnabled: shared('regionalWaterEnabled', 0),\n    specularEnabled: shared('specularEnabled', 0),\n    specularStrength: shared('specularStrength', 0.9),\n    waterWindSpeed: shared('waterWindSpeed', 8),\n    waterEnabled: shared('waterEnabled', 0),\n    waterColor: shared('waterColor', new THREE.Color(0x031e32)),\n    waterBedTexture: shared('waterBedTexture', null),\n    waterBedBounds: shared('waterBedBounds', new THREE.Vector4(0,0,1,1)),\n    waterBedEnabled: shared('waterBedEnabled', 0),\n    waterLocalFrame: shared('waterLocalFrame', new THREE.Matrix3()),\n    waterLocalLatitude: shared('waterLocalLatitude', new THREE.Vector2(0,1)),\n    waterSurfaceGeoid: shared('waterSurfaceGeoid', 0),\n    waterSurfaceSeaHeight: shared('waterSurfaceSeaHeight', 0),\n    waterSurfaceDatumReady: shared('waterSurfaceDatumReady', 0),\n    waterSurfaceHeightRange: shared('waterSurfaceHeightRange', new THREE.Vector2(0,1)),\n    waterSurfaceHeightEnabled: shared('waterSurfaceHeightEnabled', 0),\n    waterDiffuseAttenuation: shared('waterDiffuseAttenuation', new THREE.Vector3(...computeWaterOptics().diffuseAttenuation)),\n    planetRadius: shared('planetRadius', 6371000.0),\n    simpleCloudsTexture: shared('simpleCloudsTexture', null),\n    simpleCloudsEnabled: shared('simpleCloudsEnabled', 0.0),\n    simpleCloudsOpacity: shared('simpleCloudsOpacity', 0.6),\n    simpleCloudsShadowStrength: shared('simpleCloudsShadowStrength', 0.25),\n    simpleCloudsShadowHeight: shared('simpleCloudsShadowHeight', 12000.0),\n    simpleCloudsBlendMode: shared('simpleCloudsBlendMode', 0.0),\n    simpleCloudsAlphaThreshold: shared('simpleCloudsAlphaThreshold', 0.0),\n    simpleCloudsAlphaSoftness: shared('simpleCloudsAlphaSoftness', 0.0),\n    simpleCloudsNightAirglowColor: shared(\n      'simpleCloudsNightAirglowColor',\n      new THREE.Color('#9fb3c2')\n    ),\n    simpleCloudsNightAirglowStrength: shared('simpleCloudsNightAirglowStrength', 0.006),\n    lightPollutionTexture: shared('lightPollutionTexture', null),\n    lightPollutionEnabled: shared('lightPollutionEnabled', 0.0),\n    lightPollutionIntensity: shared(\n      'lightPollutionIntensity',\n      NIGHT_LIGHTS_EMISSION_DEFAULTS.intensity\n    ),\n    lightPollutionMapGain: shared(\n      'lightPollutionMapGain',\n      NIGHT_LIGHTS_EMISSION_DEFAULTS.mapGain\n    ),\n    lightPollutionEmissionThreshold: shared(\n      'lightPollutionEmissionThreshold',\n      NIGHT_LIGHTS_EMISSION_DEFAULTS.emissionThreshold\n    ),\n    lightPollutionEmissionSoftness: shared(\n      'lightPollutionEmissionSoftness',\n      NIGHT_LIGHTS_EMISSION_DEFAULTS.emissionSoftness\n    ),\n    lightPollutionEmissionPower: shared(\n      'lightPollutionEmissionPower',\n      NIGHT_LIGHTS_EMISSION_DEFAULTS.emissionPower\n    ),\n    lightPollutionEmissionBlueSuppression: shared(\n      'lightPollutionEmissionBlueSuppression',\n      NIGHT_LIGHTS_EMISSION_DEFAULTS.emissionBlueSuppression\n    ),\n    lightPollutionColor: shared('lightPollutionColor', new THREE.Color(0xffb57a)),\n    lightPollutionMercator: shared('lightPollutionMercator', 0.0),\n    lightPollutionUvOffset: shared('lightPollutionUvOffset', new THREE.Vector2()),\n    lightPollutionUvScale: shared('lightPollutionUvScale', new THREE.Vector2(1, 1)),\n    nightTransitionStart: shared('nightTransitionStart', 0.0),\n    nightTransitionEnd: shared('nightTransitionEnd', 0.5),\n    nightPower: shared('nightPower', 1.6),\n    nightAmbientColor: shared('nightAmbientColor', new THREE.Vector3(0, 0, 0)),\n  };\n\n  const vertexShader = `\n    ${WATER_GEOMETRY_GLSL}\n    #include <common>\n    #include <logdepthbuf_pars_vertex>\n\n    varying vec2 vUv;\n    varying vec3 vWorldSurfaceDir;\n    varying vec3 vWorldSurfacePosition;\n    varying vec3 vLocalSurfaceDir;\n    varying vec3 vLocalSunDirection;\n    varying vec3 vLocalToCamera;\n    varying vec3 vWaterWorldNormal;\n    uniform vec3 sunDirection;\n\n    void main() {\n      vec4 worldPosition = modelMatrix * vec4(position, 1.0);\n      vUv = uv;\n      vWorldSurfaceDir = normalize(worldPosition.xyz);\n      vWorldSurfacePosition = worldPosition.xyz;\n      vLocalSurfaceDir = normalize(position);\n      vWaterWorldNormal = transformDirection(ncaWaterGeodeticNormal(position), modelMatrix);\n      vLocalSunDirection = inverseTransformDirection(normalize(sunDirection), modelMatrix);\n      vLocalToCamera = inverseTransformDirection(cameraPosition - worldPosition.xyz, modelMatrix);\n      gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n      #include <logdepthbuf_vertex>\n    }\n  `;\n\n  const fragmentShader = `\n    #include <common>\n    #include <logdepthbuf_pars_fragment>\n\n    varying vec2 vUv;\n    varying vec3 vWorldSurfaceDir;\n    varying vec3 vWorldSurfacePosition;\n    varying vec3 vLocalSurfaceDir;\n    varying vec3 vLocalSunDirection;\n    varying vec3 vLocalToCamera;\n    varying vec3 vWaterWorldNormal;\n    uniform vec3 sunDirection;\n    uniform vec3 moonCenterWorld;\n    uniform float moonRadius;\n    uniform float sunAngularRadius;\n    uniform float sunDistance;\n    uniform sampler2D orbitalDayTexture;\n    uniform float orbitalDayTextureEnabled;\n    uniform float waterEnabled;\n    uniform vec3 waterColor;\n    uniform float planetRadius;\n    uniform sampler2D simpleCloudsTexture;\n    uniform float simpleCloudsEnabled;\n    uniform float simpleCloudsOpacity;\n    uniform float simpleCloudsShadowStrength;\n    uniform float simpleCloudsShadowHeight;\n    uniform float simpleCloudsBlendMode;\n    uniform float simpleCloudsAlphaThreshold;\n    uniform float simpleCloudsAlphaSoftness;\n    uniform vec3 simpleCloudsNightAirglowColor;\n    uniform float simpleCloudsNightAirglowStrength;\n    uniform sampler2D lightPollutionTexture;\n    uniform float lightPollutionEnabled;\n    uniform float lightPollutionIntensity;\n    uniform float lightPollutionMapGain;\n    uniform float lightPollutionEmissionThreshold;\n    uniform float lightPollutionEmissionSoftness;\n    uniform float lightPollutionEmissionPower;\n    uniform float lightPollutionEmissionBlueSuppression;\n    uniform vec3 lightPollutionColor;\n    uniform float lightPollutionMercator;\n    uniform vec2 lightPollutionUvOffset;\n    uniform vec2 lightPollutionUvScale;\n    uniform float nightTransitionStart;\n    uniform float nightTransitionEnd;\n    uniform float nightPower;\n    uniform vec3 nightAmbientColor;\n\n    float resolveOverviewCloudMask(vec4 cloudSample) {\n      float coverage = clamp(cloudSample.a, 0.0, 1.0);\n      float black = clamp(simpleCloudsAlphaThreshold, 0.0, 0.95);\n      float contrast = 1.0 + clamp(simpleCloudsAlphaSoftness, 0.0, 1.0) * 6.0;\n      float t = clamp((coverage - black) / (1.0 - black + 1e-4), 0.0, 1.0);\n      return pow(t, contrast);\n    }\n\n    float overviewRaySphereFirstHit(vec3 rayOrigin, vec3 rayDir, float radius) {\n      float b = dot(rayOrigin, rayDir);\n      float c = dot(rayOrigin, rayOrigin) - radius * radius;\n      float h = b * b - c;\n      if (h < 0.0) return -1.0;\n      float s = sqrt(h);\n      float tNear = -b - s;\n      float tFar = -b + s;\n      if (tNear > 0.0) return tNear;\n      if (tFar > 0.0) return tFar;\n      return -1.0;\n    }\n\n    vec2 overviewDirectionToCloudUv(vec3 direction) {\n      vec3 n = normalize(direction);\n      float u = atan(n.x, n.z) / (2.0 * PI) + 0.5;\n      float v = 0.5 - asin(clamp(n.y, -1.0, 1.0)) / PI;\n      return vec2(fract(u + 1.0), clamp(v, 0.0, 1.0));\n    }\n\n    ${NIGHT_LIGHTS_SOURCE_SIGNAL_GLSL}\n    ${NIGHT_LIGHTS_GEOGRAPHY_GLSL}\n    ${nightCloudLightingForExistingField()}\n    ${CELESTIAL_IRRADIANCE_GLSL}\n\n    float resolveOverviewSolarEclipseVisibility(vec3 worldPosition) {\n      vec3 moonOffset = moonCenterWorld - worldPosition;\n      float moonDistance = length(moonOffset);\n      if (moonDistance <= moonRadius) return 1.0;\n      vec3 centerSunDirection = normalize(sunDirection);\n      vec3 observerPerpendicular = worldPosition\n        - centerSunDirection * dot(worldPosition, centerSunDirection);\n      vec3 localSunDirection = normalize(\n        centerSunDirection\n          - observerPerpendicular / max(sunDistance, 1.0)\n      );\n      float moonAngularRadius = asin(clamp(\n        moonRadius / moonDistance,\n        0.0,\n        1.0\n      ));\n      return ncaFiniteDiscVisibility(\n        localSunDirection,\n        sunAngularRadius,\n        moonOffset,\n        moonAngularRadius\n      );\n    }\n\n    float resolveOverviewLightEmission(float sourceSignal) {\n      float threshold = clamp(lightPollutionEmissionThreshold, 0.0, 0.95);\n      float softness = max(lightPollutionEmissionSoftness, 1e-4);\n      float normalizedSignal = clamp(\n        (sourceSignal - threshold) / max(1.0 - threshold, 1e-4),\n        0.0,\n        1.0\n      );\n      float emissionGate = smoothstep(\n        threshold,\n        min(1.0, threshold + softness),\n        sourceSignal\n      );\n      return pow(\n        normalizedSignal,\n        max(lightPollutionEmissionPower, 0.1)\n      ) * emissionGate;\n    }\n\n    void main() {\n      #include <logdepthbuf_fragment>\n\n      vec3 worldSurfaceDir = normalize(vWorldSurfaceDir);\n      float sunDot = dot(worldSurfaceDir, normalize(sunDirection));\n      float dayFactor = smoothstep(nightTransitionStart, nightTransitionEnd, sunDot);\n      float solarEclipseVisibility = resolveOverviewSolarEclipseVisibility(\n        vWorldSurfacePosition\n      );\n      float eclipseDayIrradiance = mix(0.075, 1.0, solarEclipseVisibility);\n      float nightFactor = pow(clamp(1.0 - dayFactor, 0.0, 1.0), max(nightPower, 0.1));\n\n      // SphereGeometry's seam starts at local -X, while every NOCLIP\n      // geospatial conversion defines Greenwich at local +Z. Shift the\n      // conventional EPSG:4326 texture by one quarter turn so the requested\n      // latitude/longitude remains directly under the orbital camera. The\n      // day-texture loader keeps its normal vertical upload flip; vUv.y already\n      // runs south-to-north for SphereGeometry. Do not flip either day-map axis.\n      vec2 geographicUv = ncaWaterUv(vLocalSurfaceDir);\n      vec2 orbitalMapUv = vec2(geographicUv.x, 1.0 - geographicUv.y);\n\n      // Keep a non-black procedural floor while the compact overview texture\n      // streams, then use the real planet-fixed geography. This texture is\n      // independent from TriTree and photoreal surface ownership.\n      float latitude = abs(orbitalMapUv.y * 2.0 - 1.0);\n      vec3 dayAlbedo = mix(vec3(0.018, 0.075, 0.115), vec3(0.045, 0.12, 0.14), latitude);\n      if (orbitalDayTextureEnabled > 0.5) {\n        dayAlbedo = texture2D(orbitalDayTexture, orbitalMapUv).rgb;\n      }\n      if (waterEnabled > 0.5) {\n        vec3 transmission = ncaWaterBottomTransmission(vLocalSurfaceDir,\n          normalize(vWaterWorldNormal), normalize(cameraPosition-vWorldSurfacePosition), normalize(sunDirection));\n        dayAlbedo = mix(dayAlbedo, mix(waterColor,dayAlbedo,transmission), ncaWaterCoverage(vLocalSurfaceDir).x);\n      }\n\n      // The live Matteason map follows TriTree's north-at-v=0 convention\n      // (TextureLoader.flipY=false), while SphereGeometry puts north at v=1.\n      // Compensate in this material just as the shared night texture does.\n      vec2 cloudUv = vec2(orbitalMapUv.x, 1.0 - orbitalMapUv.y);\n      vec4 cloudSample = vec4(0.0);\n      float cloudMask = 0.0;\n      float waterSunTransmission = 1.0;\n      if (simpleCloudsEnabled > 0.5) {\n        cloudSample = texture2D(simpleCloudsTexture, cloudUv);\n        cloudMask = resolveOverviewCloudMask(cloudSample);\n\n        // Project the displaced cloud coverage toward the terrain along the\n        // current ECEF sun direction. Work in planet-local coordinates so the\n        // shadow stays registered while the Earth group rotates.\n        float shadowMask = cloudMask;\n        if (simpleCloudsShadowStrength > 0.0 && dayFactor > 0.0) {\n          float shellRadius = max(planetRadius + 1.0, planetRadius + max(simpleCloudsShadowHeight, 0.0));\n          vec3 localSurfacePosition = normalize(vLocalSurfaceDir) * planetRadius;\n          vec3 localSunDirection = normalize(vLocalSunDirection);\n          float hitT = overviewRaySphereFirstHit(localSurfacePosition, localSunDirection, shellRadius);\n          if (hitT > 0.0) {\n            vec3 cloudHitPosition = localSurfacePosition + localSunDirection * hitT;\n            vec2 shadowUv = overviewDirectionToCloudUv(cloudHitPosition);\n            shadowMask = resolveOverviewCloudMask(texture2D(simpleCloudsTexture, shadowUv));\n          }\n        }\n        float cloudShadow = clamp(\n          shadowMask\n            * simpleCloudsShadowStrength\n            * dayFactor,\n          0.0,\n          0.85\n        );\n        dayAlbedo *= 1.0 - cloudShadow;\n        waterSunTransmission = 1.0 - cloudShadow;\n      }\n\n      vec3 nightGeography = dayAlbedo * 0.025 + vec3(0.001, 0.002, 0.005);\n      vec3 nightBase = max(nightAmbientColor, nightGeography);\n      vec3 color = mix(\n        nightBase,\n        dayAlbedo * eclipseDayIrradiance,\n        dayFactor\n      );\n\n      if (specularEnabled > 0.5) {\n        float water = ncaWaterCoverage(vLocalSurfaceDir).x;\n        vec3 reflectedSky = vec3(0.035, 0.065, 0.11) * dayFactor;\n        if (simpleCloudsEnabled > 0.5) {\n          vec3 localPosition = normalize(vLocalSurfaceDir) * planetRadius;\n          vec3 reflectionRay = reflect(-normalize(vLocalToCamera), ncaWaterGeodeticNormal(vLocalSurfaceDir));\n          float hitT = overviewRaySphereFirstHit(localPosition, reflectionRay,\n            planetRadius + max(simpleCloudsShadowHeight, 1.0));\n          if (hitT > 0.0) {\n            vec4 reflectedCloud = texture2D(simpleCloudsTexture,\n              overviewDirectionToCloudUv(localPosition + reflectionRay * hitT));\n            vec3 cloudSky = mix(simpleCloudsNightAirglowColor * simpleCloudsNightAirglowStrength,\n              vec3(eclipseDayIrradiance), dayFactor) * mix(0.7, 1.0, max(reflectedCloud.r, max(reflectedCloud.g, reflectedCloud.b)));\n            reflectedSky = mix(reflectedSky, cloudSky,\n              clamp(resolveOverviewCloudMask(reflectedCloud) * simpleCloudsOpacity, 0.0, 1.0));\n          }\n        }\n        vec3 reflected = ncaWaterReflection(normalize(vWaterWorldNormal),\n          normalize(cameraPosition - vWorldSurfacePosition), normalize(sunDirection), waterWindSpeed,\n          vec3(3.4) * solarEclipseVisibility * waterSunTransmission, reflectedSky);\n        color += reflected * water * specularStrength\n          * (1.0 - clamp(cloudMask * simpleCloudsOpacity, 0.0, 1.0));\n      }\n\n      // Emit NASA source radiance from this opaque fallback surface while its\n      // bounded global atlas is resident. This is not replacement imagery or\n      // a translucent shell; the day geography remains authoritative and the\n      // source pixels contribute only on the live astronomical night side.\n      if (lightPollutionEnabled > 0.5) {\n        vec2 lightUv = cloudUv;\n        if (lightPollutionMercator > 0.5) {\n          float lightLatitude = (0.5 - cloudUv.y) * PI;\n          lightLatitude = clamp(lightLatitude, -1.4844222297, 1.4844222297);\n          float lightSinLatitude = sin(lightLatitude);\n          lightUv.y = clamp(\n            0.5\n              - 0.25\n                * log((1.0 + lightSinLatitude) / (1.0 - lightSinLatitude))\n                / PI,\n            0.0,\n            1.0\n          );\n        }\n        lightUv = (lightUv - 0.5) * lightPollutionUvScale\n          + 0.5\n          + lightPollutionUvOffset;\n        lightUv.x = fract(lightUv.x + 1.0);\n        lightUv.y = clamp(lightUv.y, 0.0, 1.0);\n        vec4 lightSample = texture2D(lightPollutionTexture, lightUv);\n        vec3 lightRgb = max(lightSample.rgb, vec3(0.0));\n        float sourceLuminance = max(max(lightRgb.r, lightRgb.g), lightRgb.b);\n        float sourceSignal = resolveNightLightsSourceSignal(\n          lightRgb,\n          lightPollutionEmissionBlueSuppression\n        );\n        float sourceRadiance = resolveOverviewLightEmission(sourceSignal)\n          * lightPollutionMapGain;\n        vec3 sourceChroma = lightRgb / max(sourceLuminance, 1e-4);\n        float cloudOcclusion = 1.0 - clamp(\n          cloudMask * simpleCloudsOpacity,\n          0.0,\n          0.95\n        );\n        vec3 emittedRadiance = sourceChroma\n          * lightPollutionColor\n          * lightPollutionIntensity\n          * sourceRadiance;\n        color += emittedRadiance\n          * lightSample.a\n          * nightFactor\n          * cloudOcclusion;\n      }\n\n      if (simpleCloudsEnabled > 0.5) {\n        float cloudAlpha = cloudMask * simpleCloudsOpacity;\n        float cloudShade = clamp(max(cloudSample.r, max(cloudSample.g, cloudSample.b)), 0.0, 1.0);\n        vec3 nightCloudAirglow = simpleCloudsNightAirglowColor\n          * simpleCloudsNightAirglowStrength\n          + (dayFactor < .999 ? ncaNightCloudRadiance(normalize(vLocalSurfaceDir) * planetRadius,\n              simpleCloudsShadowHeight) : vec3(0.0));\n        vec3 cloudColor = mix(\n          nightCloudAirglow,\n          vec3(eclipseDayIrradiance),\n          dayFactor\n        )\n          * mix(0.7, 1.0, cloudShade);\n        if (simpleCloudsBlendMode < 0.5) {\n          color = mix(color, cloudColor, cloudAlpha);\n        } else if (simpleCloudsBlendMode < 1.5) {\n          color = clamp(color + cloudColor * cloudAlpha, 0.0, 1.0);\n        } else if (simpleCloudsBlendMode < 2.5) {\n          vec3 screenColor = cloudColor * cloudAlpha;\n          color = 1.0 - (1.0 - color) * (1.0 - screenColor);\n        } else {\n          color *= 1.0 - cloudAlpha;\n        }\n      }\n\n      gl_FragColor = vec4(color, 1.0);\n    }\n  `;\n\n  Object.assign(uniforms, waterCoverageUniforms(uniforms));\n  const material = new THREE.ShaderMaterial({\n    name: 'OrbitalEarthMaterial',\n    uniforms,\n    vertexShader,\n    fragmentShader: wrapCloudMapSampling(WATER_COVERAGE_GLSL + WATER_REFLECTANCE_GLSL\n      + '\\nuniform float specularEnabled, specularStrength, waterWindSpeed;\\n' + fragmentShader, ['simpleCloudsTexture']),\n    side: THREE.FrontSide,\n    depthWrite: true,\n    depthTest: true,\n    toneMapped: true,\n  });\n  material.userData.orbitalEarth = true;\n  return material;\n}\n\n/**\n * Create atmosphere shell material with physically-based scattering\n *\n * Implements accurate Rayleigh and Mie scattering based on Earth's atmospheric composition.\n * Uses real atmospheric parameters for authentic sky color, sunset/sunrise gradients,\n * and altitude-dependent density falloff.\n *\n * Physical constants based on:\n * - Bruneton & Neyret 2008: \"Precomputed Atmospheric Scattering\"\n * - Nishita et al. 1993: \"Display of the Earth Taking into Account Atmospheric Scattering\"\n *\n * @param {Object} colors - Not used (kept for API compatibility)\n * @param {THREE.DirectionalLight} sunLight - Sun directional light\n * @returns {THREE.ShaderMaterial}\n */\nexport function createAtmosphereMaterial(colors, sunLight) {\n  const uniforms = {\n    sunDirection: { value: new THREE.Vector3() },\n\n    // Physical atmosphere parameters (real Earth values in meters)\n    planetRadius: { value: PLANET_RADIUS },           // Earth radius: 6,371 km\n    atmosphereRadius: { value: ATMOSPHERE_RADIUS_M }, // Atmosphere top\n\n    // Rayleigh scattering (molecules) - causes blue sky\n    rayleighScaleHeight: { value: RAYLEIGH_SCALE_HEIGHT_M }, // Scale height: 8 km\n    rayleighCoeff: { value: new THREE.Vector3(...BETA_RAYLEIGH) },\n\n    // Mie scattering (aerosols/particles) - causes haze and sunset colors\n    mieScaleHeight: { value: MIE_SCALE_HEIGHT_M }, // Scale height: 1.2 km\n    mieCoeff: { value: BETA_MIE[0] },              // Mie scattering coefficient\n    mieG: { value: MIE_G },                        // Asymmetry factor (forward scattering)\n\n    // Sun intensity\n    sunIntensity: { value: 22.0 },                // Sun brightness factor\n\n    // Rendering parameters (reduced for better performance)\n    numSamples: { value: 8 },                     // Ray marching samples (reduced from 16)\n    numSamplesLight: { value: 4 },                // Light ray samples (reduced from 8)\n\n    // Depth-aware clamp inputs\n    depthTexture: { value: null },\n    resolution: { value: new THREE.Vector2(1, 1) },\n    invProjectionMatrix: { value: new THREE.Matrix4() },\n    invViewMatrix: { value: new THREE.Matrix4() },\n\n    // Aerial perspective / distance fog parameters\n    aerialPerspectiveDensity: { value: 0.00004 },   // Extinction coefficient β (increased for visibility)\n    aerialPerspectiveHeightFalloff: { value: 5000.0 }, // Height falloff in meters (denser ground fog)\n    aerialPerspectiveStrength: { value: 1.0 },      // Overall strength (0-1) - full strength\n\n    // Atmosphere visibility controls (how atmosphere covers terrain)\n    minAtmospherePathLength: { value: 1000.0 },     // Min path length (m) to render atmosphere (lower = more coverage)\n    atmosphereAlphaScale: { value: 2.0 },           // Alpha intensity multiplier (higher = more opaque atmosphere)\n    atmosphereDepthClamp: { value: 1.0 },           // Depth clamp strength (0 = ignore terrain, 1 = full clamp)\n    // The orbital overview is an exact analytic sphere. Its huge log-depth\n    // range must not shorten the scattering segment with reconstructed depth;\n    // local photoreal terrain keeps the normal depth-aware path instead.\n    analyticPlanetDepth: { value: 0.0 }\n  };\n\n\n  const vertexShader = `\n    #include <common>\n    #include <logdepthbuf_pars_vertex>\n\n    varying vec3 vWorldPosition;\n    varying vec3 vPosition;\n\n    void main() {\n      vec4 worldPos = modelMatrix * vec4(position, 1.0);\n      vWorldPosition = worldPos.xyz;\n      vPosition = position;\n\n      gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n      #include <logdepthbuf_vertex>\n    }\n  `;\n\n  const fragmentShader = `\n    #include <common>\n    #include <logdepthbuf_pars_fragment>\n\n    uniform vec3 sunDirection;\n    uniform float planetRadius;\n    uniform float atmosphereRadius;\n    uniform float rayleighScaleHeight;\n    uniform vec3 rayleighCoeff;\n    uniform float mieScaleHeight;\n    uniform float mieCoeff;\n    uniform float mieG;\n    uniform float sunIntensity;\n    uniform int numSamples;\n    uniform int numSamplesLight;\n    uniform sampler2D depthTexture;\n    uniform vec2 resolution;\n    uniform mat4 invProjectionMatrix;\n    uniform mat4 invViewMatrix;\n    uniform float aerialPerspectiveDensity;\n    uniform float aerialPerspectiveHeightFalloff;\n    uniform float aerialPerspectiveStrength;\n    uniform float minAtmospherePathLength;\n    uniform float atmosphereAlphaScale;\n    uniform float atmosphereDepthClamp;\n    uniform float analyticPlanetDepth;\n\n    varying vec3 vWorldPosition;\n    varying vec3 vPosition;\n\n    // PI is already defined in <common> include\n\n    // Ray-sphere intersection\n    // Returns vec2(t_near, t_far) or vec2(-1.0) if no intersection\n    vec2 raySphereIntersect(vec3 ro, vec3 rd, float r) {\n      float b = dot(ro, rd);\n      float c = dot(ro, ro) - r * r;\n      float delta = b * b - c;\n      if (delta < 0.0) return vec2(-1.0);\n      float sqrtDelta = sqrt(delta);\n      float t1 = -b - sqrtDelta;\n      float t2 = -b + sqrtDelta;\n      return vec2(t1, t2);\n    }\n\n    // Atmospheric density at altitude h\n    float rayleighDensity(float h) {\n      return exp(-max(h, 0.0) / rayleighScaleHeight);\n    }\n\n    float mieDensity(float h) {\n      return exp(-max(h, 0.0) / mieScaleHeight);\n    }\n\n    // Rayleigh phase function (molecules scatter light symmetrically)\n    float phaseRayleigh(float cosTheta) {\n      return (3.0 / (16.0 * PI)) * (1.0 + cosTheta * cosTheta);\n    }\n\n    // Mie phase function (Henyey-Greenstein approximation)\n    // Forward-scattering for aerosols/particles\n    float phaseMie(float cosTheta, float g) {\n      float g2 = g * g;\n      float num = (1.0 - g2);\n      float denom = (1.0 + g2 - 2.0 * g * cosTheta);\n      return (1.0 / (4.0 * PI)) * num / pow(denom, 1.5);\n    }\n\n    // Approximate optical depth to the sun with a midpoint density sample.\n    vec3 lightOpticalDepth(vec3 start, vec3 dir, float lightDistance) {\n      vec3 mid = start + dir * (lightDistance * 0.5);\n      float h = length(mid) - planetRadius;\n      float densityR = rayleighDensity(h);\n      float densityM = mieDensity(h);\n      return (rayleighCoeff * densityR + mieCoeff * densityM) * lightDistance;\n    }\n\n    void main() {\n      #include <logdepthbuf_fragment>\n\n      vec3 camPos = cameraPosition;\n      vec3 rayDir = normalize(vWorldPosition - camPos);\n      vec3 sunDir = sunDirection;\n\n      // Depth clamp: limit scattering to actual surface depth when terrain is visible\n      float tDepth = 1e20;\n      vec2 uv = gl_FragCoord.xy / resolution;\n      float depthSample = texture2D(depthTexture, uv).x;\n\n      // DEBUG: Output depth sample value to see if depth texture is working\n      // Uncomment to debug: gl_FragColor = vec4(vec3(depthSample), 1.0); return;\n\n      if (depthSample < 0.9999) {\n        #if defined(USE_LOGDEPTHBUF) || defined(USE_LOGARITHMIC_DEPTH_BUFFER)\n          // Log-depth buffer stores log2(1 + viewZ); reconstruct view-space depth.\n          float viewZ = exp2(depthSample * 2.0 / logDepthBufFC) - 1.0;\n          vec4 viewRay = invProjectionMatrix * vec4(uv * 2.0 - 1.0, 1.0, 1.0);\n          vec3 rayDirView = normalize(viewRay.xyz / max(viewRay.w, 1e-6));\n          float denom = max(-rayDirView.z, 1e-6);\n          tDepth = viewZ / denom;\n        #else\n          vec4 clip = vec4(uv * 2.0 - 1.0, depthSample * 2.0 - 1.0, 1.0);\n          vec4 viewPos = invProjectionMatrix * clip;\n          viewPos /= max(viewPos.w, 1e-6);\n          vec4 worldPos = invViewMatrix * viewPos;\n          tDepth = length(worldPos.xyz - camPos);\n        #endif\n      }\n\n      // ═══════════════════════════════════════════════════════════════\n      // VOLUMETRIC RAY MARCHING SETUP\n      // Smooth, continuous - no hard boundaries based on camera position\n      // ═══════════════════════════════════════════════════════════════\n\n      // Find intersection with atmosphere sphere\n      vec2 tAtmos = raySphereIntersect(camPos, rayDir, atmosphereRadius);\n      if (tAtmos.y < 0.0) {\n        discard; // Ray doesn't intersect atmosphere at all\n        return;\n      }\n\n      // Find intersection with planet surface\n      vec2 tPlanet = raySphereIntersect(camPos, rayDir, planetRadius);\n\n      // Ray start: smoothly handle inside/outside atmosphere\n      // No conditionals - just use max(0, entry point)\n      // If inside atmosphere, tAtmos.x is negative, so max(0, negative) = 0\n      // If outside atmosphere, tAtmos.x is positive entry distance\n      float tStart = max(0.0, tAtmos.x);\n\n      // Ray end: use closest of planet surface, atmosphere exit, or terrain depth\n      // Start with atmosphere far bound\n      float tEnd = tAtmos.y;\n\n      // Clamp to planet surface if ray hits it (smooth, continuous)\n      // Use smooth blend based on whether planet was hit\n      float planetHitFactor = step(0.0, tPlanet.x); // 1.0 if hit, 0.0 if not\n      tEnd = mix(tEnd, min(tEnd, tPlanet.x), planetHitFactor);\n\n      // Apply depth clamp with tuneable strength (smooth blend, not hard switch)\n      // Only apply if valid depth exists (tDepth < large threshold)\n      float depthValidFactor = 1.0 - step(1e19, tDepth); // 1.0 if valid, 0.0 if not\n      // A standalone orbital globe already has an exact tPlanet intersection.\n      // Reconstructed logarithmic depth loses precision several megameters\n      // away and can collapse this segment to zero, exposing a raw surface.\n      float depthClampStrength = atmosphereDepthClamp * depthValidFactor * (1.0 - analyticPlanetDepth);\n      tEnd = mix(tEnd, min(tEnd, tDepth), depthClampStrength);\n\n      // Validate ray segment\n      if (tEnd <= tStart || tEnd <= 0.0) {\n        discard;\n        return;\n      }\n\n      // Calculate path length through atmosphere\n      float pathLength = tEnd - tStart;\n\n      // Soft fade instead of hard cutoff for performance optimization\n      // Short paths just contribute less, not zero\n      float pathFade = smoothstep(minAtmospherePathLength * 0.5, minAtmospherePathLength, pathLength);\n      if (pathFade < 0.001) {\n        discard; // Only discard if essentially zero contribution\n        return;\n      }\n\n      // Ray march through atmosphere\n      float segmentLength = pathLength / float(numSamples);\n      vec3 rayStep = rayDir * segmentLength;\n      vec3 pos = camPos + rayDir * (tStart + segmentLength * 0.5);\n\n      vec3 totalRayleigh = vec3(0.0);\n      vec3 totalMie = vec3(0.0);\n\n      // Optical depth from camera to current position\n      vec3 opticalDepthCam = vec3(0.0);\n\n      // Performance optimization: reduced max iterations\n      for (int i = 0; i < 16; i++) {\n        if (i >= numSamples) break;\n\n        float h = length(pos) - planetRadius;\n        float densityR = rayleighDensity(h);\n        float densityM = mieDensity(h);\n\n        // Accumulate optical depth from camera\n        opticalDepthCam += (rayleighCoeff * densityR + mieCoeff * densityM) * segmentLength;\n\n        // Find intersection of light ray with atmosphere\n        vec2 tLight = raySphereIntersect(pos, sunDir, atmosphereRadius);\n        if (tLight.y > 0.0) {\n          // Total optical depth (camera to sample + sample to sun)\n          vec3 tau = opticalDepthCam + lightOpticalDepth(pos, sunDir, tLight.y);\n\n          // Transmittance (Beer-Lambert law)\n          vec3 attenuation = exp(-tau);\n\n          // Accumulate scattered light\n          totalRayleigh += attenuation * densityR * segmentLength;\n          totalMie += attenuation * densityM * segmentLength;\n        }\n\n        pos += rayStep;\n      }\n\n      // Phase functions\n      float cosTheta = dot(rayDir, sunDir);\n      float phaseR = phaseRayleigh(cosTheta);\n      float phaseM = phaseMie(cosTheta, mieG);\n\n      // Final scattered light\n      vec3 scatteredLight = sunIntensity * (\n        totalRayleigh * rayleighCoeff * phaseR +\n        totalMie * mieCoeff * phaseM\n      );\n\n      // Tone mapping to prevent oversaturation\n      scatteredLight = 1.0 - exp(-scatteredLight * 0.5);\n\n      // Apply path fade to scattered light as well (smooth brightness transition)\n      // Short paths through atmosphere scatter less light\n      scatteredLight = scatteredLight * pathFade;\n\n      // ═══════════════════════════════════════════════════════════════\n      // VOLUMETRIC ATMOSPHERE OPACITY\n      // Truly volumetric - no hard cutoffs, just physics\n      // ═══════════════════════════════════════════════════════════════\n\n      // Base opacity from accumulated optical depth (Beer-Lambert law)\n      // This already accounts for exponential density falloff naturally\n      float pathOpticalDepth = length(opticalDepthCam);\n      float alpha = 1.0 - exp(-pathOpticalDepth * atmosphereAlphaScale);\n\n      // Enhanced opacity for long tangential paths through atmosphere\n      // This creates the natural limb brightening effect at horizon\n      // Works EVERYWHERE - not just inside atmosphere (no hard boundaries!)\n      float camAltitude = length(camPos) - planetRadius;\n      float camDistNormalized = camAltitude / (atmosphereRadius - planetRadius);\n\n      // Calculate viewing angle relative to local \"up\" direction\n      // Works smoothly whether inside or outside atmosphere\n      vec3 upDir = normalize(camPos);\n      float horizonDot = abs(dot(rayDir, upDir));\n\n      // horizonDot near 1.0 = looking straight up/down (short path)\n      // horizonDot near 0.0 = looking at horizon (long tangential path)\n      float tangentialFactor = 1.0 - horizonDot;  // 0 when vertical, 1 at horizon\n\n      // Path length factor - longer paths naturally have more scattering\n      float pathKm = pathLength / 1000.0;\n      float pathFactor = smoothstep(0.0, 500.0, pathKm);  // Smooth ramp 0-500km\n\n      // Combine tangential viewing angle with actual path length\n      // Both contribute to limb brightening effect\n      float limbEnhancement = tangentialFactor * tangentialFactor * pathFactor;\n\n      // Smoothly boost alpha for grazing angles - no conditionals, just smooth math\n      // The enhancement naturally fades out for short paths or vertical views\n      alpha = alpha * (1.0 + limbEnhancement * 2.5);\n\n      // Match the compact NOAA GeoColor orbital rim. The former response left\n      // the outer day-side edge looking like a linear cyan band. Preserve the\n      // dense inner limb, then use a logarithmic remaining-height curve so the\n      // last part of the physical shell falls rapidly into black space.\n      float closestDistance = max(-dot(camPos, rayDir), 0.0);\n      vec3 closestPoint = camPos + rayDir * closestDistance;\n      float impactRadius = length(closestPoint);\n      float atmosphereSpan = max(atmosphereRadius - planetRadius, 1.0);\n      float remainingHeight = clamp(\n        (atmosphereRadius - impactRadius) / atmosphereSpan,\n        0.0,\n        1.0\n      );\n      float logarithmicEdgeFalloff = log2(\n        1.0 + 15.0 * remainingHeight\n      ) / log2(16.0);\n      float atmosphereOnlyRay = step(planetRadius, impactRadius)\n        * (1.0 - step(atmosphereRadius, impactRadius));\n      float orbitalView = smoothstep(\n        atmosphereRadius + 20000.0,\n        atmosphereRadius + 400000.0,\n        length(camPos)\n      );\n      float dayLimb = smoothstep(\n        -0.12,\n        0.28,\n        dot(\n          closestPoint / max(impactRadius, 1.0),\n          normalize(sunDir)\n        )\n      );\n      float dayEdgeWeight = atmosphereOnlyRay * orbitalView * dayLimb;\n      float dayEdgeResponse = 0.42 * logarithmicEdgeFalloff;\n      scatteredLight *= mix(1.0, dayEdgeResponse, dayEdgeWeight);\n      alpha *= mix(1.0, logarithmicEdgeFalloff, dayEdgeWeight);\n\n      // Apply path fade for short atmosphere segments (smooth, not hard cutoff)\n      // This makes very short paths through atmosphere contribute less\n      alpha = alpha * pathFade;\n\n      alpha = clamp(alpha, 0.0, 0.98);\n\n      // ═══════════════════════════════════════════════════════════════\n      // AERIAL PERSPECTIVE: Removed from atmosphere shader\n      // Now handled by terrain shader for correct fog blending\n      // ═══════════════════════════════════════════════════════════════\n      // The terrain shader now applies fog to itself before this atmosphere\n      // layer blends over it. This ensures distant terrain fades properly.\n      //\n      // Atmosphere shader continues to handle:\n      // - Rayleigh scattering (blue sky)\n      // - Mie scattering (sunset colors, haze)\n      // - Limb glow (horizon brightening)\n      // ═══════════════════════════════════════════════════════════════\n\n      // Dithering to reduce banding artifacts from low sample count\n      // This adds subtle noise to hide stepping in gradients\n      float dither = fract(sin(dot(gl_FragCoord.xy, vec2(12.9898, 78.233))) * 43758.5453);\n      alpha += (dither - 0.5) * 0.02;  // ±1% noise\n      alpha = clamp(alpha, 0.0, 0.98);\n\n      // TEMPORARY DEBUG: Make atmosphere VERY visible to test if it's rendering at all\n      // Uncomment these lines to test:\n      // scatteredLight = vec3(0.3, 0.6, 1.0);  // Bright blue\n      // alpha = 0.8;  // Very opaque\n\n      gl_FragColor = vec4(scatteredLight, alpha);\n    }\n  `;\n\n\n  const material = new THREE.ShaderMaterial({\n    uniforms,\n    vertexShader,\n    fragmentShader,\n    side: THREE.FrontSide,\n    transparent: true,\n    blending: THREE.NormalBlending,\n    depthWrite: false\n  });\n\n  // Update sun direction uniform\n  material.onBeforeRender = function() {\n    uniforms.sunDirection.value.copy(sunLight.position).normalize();\n  };\n\n  material.userData.uniforms = uniforms;\n\n  return material;\n}\n\n/**\n * Update material uniforms (for GUI/runtime tweaking)\n *\n * @param {THREE.ShaderMaterial} material - Earth material\n * @param {Object} updates - { atmosphereDayColor?, atmosphereTwilightColor?, roughnessLow?, roughnessHigh? }\n */\nexport function updateEarthMaterialUniforms(material, updates) {\n  const uniforms = material.userData.uniforms;\n\n  if (!uniforms) {\n    console.warn('Material does not have exposed uniforms');\n    return;\n  }\n\n  if (updates.atmosphereDayColor !== undefined) {\n    uniforms.atmosphereDayColor.value.set(updates.atmosphereDayColor);\n  }\n\n  if (updates.atmosphereTwilightColor !== undefined) {\n    uniforms.atmosphereTwilightColor.value.set(updates.atmosphereTwilightColor);\n  }\n\n  if (updates.roughnessLow !== undefined) {\n    uniforms.roughnessLow.value = updates.roughnessLow;\n  }\n\n  if (updates.roughnessHigh !== undefined) {\n    uniforms.roughnessHigh.value = updates.roughnessHigh;\n  }\n\n  // NEW haze controls\n  if (updates.atmosphereScale !== undefined) {\n    uniforms.atmosphereScale.value = updates.atmosphereScale;\n  }\n  if (updates.hazeStrength !== undefined) {\n    uniforms.hazeStrength.value = updates.hazeStrength;\n  }\n  if (updates.hazeFalloff !== undefined) {\n    uniforms.hazeFalloff.value = updates.hazeFalloff;\n  }\n  if (updates.hazeMax !== undefined) {\n    uniforms.hazeMax.value = updates.hazeMax;\n  }\n}\n\n/**\n * Update atmosphere aerial perspective parameters (for GUI/runtime tweaking)\n *\n * @param {THREE.ShaderMaterial} atmosphereMaterial - Atmosphere material\n * @param {Object} updates - { aerialPerspectiveDensity?, aerialPerspectiveHeightFalloff?, aerialPerspectiveStrength? }\n */\nexport function updateAtmosphereAerialPerspective(atmosphereMaterial, updates) {\n  if (!atmosphereMaterial || !atmosphereMaterial.uniforms) {\n    console.warn('Invalid atmosphere material');\n    return;\n  }\n\n  const uniforms = atmosphereMaterial.uniforms;\n\n  if (updates.aerialPerspectiveDensity !== undefined) {\n    uniforms.aerialPerspectiveDensity.value = updates.aerialPerspectiveDensity;\n  }\n\n  if (updates.aerialPerspectiveHeightFalloff !== undefined) {\n    uniforms.aerialPerspectiveHeightFalloff.value = updates.aerialPerspectiveHeightFalloff;\n  }\n\n  if (updates.aerialPerspectiveStrength !== undefined) {\n    uniforms.aerialPerspectiveStrength.value = updates.aerialPerspectiveStrength;\n  }\n}\n\n\n/**\n * Create simple fallback material (if textures fail to load)\n *\n * @returns {THREE.MeshStandardMaterial}\n */\nexport function createFallbackMaterial() {\n  return new THREE.MeshStandardMaterial({\n    color: 0x4b5563,\n    metalness: 0.0,\n    roughness: 0.95,\n    flatShading: false,\n    side: THREE.BackSide  // Render backfaces (terrain viewed from inside planet)\n  });\n}\n","import * as THREE from 'three';\n\nexport const CELESTIAL_LENGTH_UNIT_PER_METER = 1 / 1000;\n\nexport const CELESTIAL_OCCLUSION_UNIFORMS_GLSL = `\nuniform vec3 ncaMoonCenterECEF;\nuniform float ncaMoonRadius;\nuniform vec3 ncaSunCenterECEF;\nuniform float ncaSunRadius;`;\n\nexport const CELESTIAL_OCCLUSION_INTERSECTION_GLSL = `\nfloat ncaRaySphereFirstIntersection(\n  const vec3 rayOrigin,\n  const vec3 rayDirection,\n  const vec3 sphereCenter,\n  const float sphereRadius\n) {\n  if (sphereRadius <= 0.0) {\n    return -1.0;\n  }\n  vec3 offset = rayOrigin - sphereCenter;\n  float b = dot(offset, rayDirection);\n  float c = dot(offset, offset) - sphereRadius * sphereRadius;\n  float discriminant = b * b - c;\n  if (discriminant < 0.0) {\n    return -1.0;\n  }\n  float root = sqrt(discriminant);\n  float nearDistance = -b - root;\n  float farDistance = -b + root;\n  return nearDistance > 0.0\n    ? nearDistance\n    : (farDistance > 0.0 ? farDistance : -1.0);\n}\n`;\n\n/**\n * Celestial spheres are real opaque geometry in the primary scene. They must\n * participate in ordinary mutual depth occlusion even though the atmosphere\n * effect classifies their pixels as sky radiance rather than Earth terrain.\n */\nexport function enforceCelestialOpaqueDepthMaterial(material) {\n    if (!material) return material;\n    material.transparent = false;\n    material.opacity = 1;\n    material.alphaTest = 0;\n    material.alphaHash = false;\n    material.alphaToCoverage = false;\n    material.depthTest = true;\n    material.depthWrite = true;\n    material.colorWrite = true;\n    material.depthFunc = THREE.LessEqualDepth;\n    material.side = THREE.FrontSide;\n    material.blending = THREE.NormalBlending;\n    material.premultipliedAlpha = false;\n    return material;\n}\n\nexport function isObjectVisibleInHierarchy(object) {\n    let current = object;\n    while (current) {\n        if (current.visible === false) return false;\n        current = current.parent;\n    }\n    return !!object;\n}\n\nexport function ensureCelestialOcclusionUniforms(effect) {\n    const uniforms = effect?.uniforms;\n    if (!uniforms?.get || !uniforms?.set) return false;\n    const ensure = (name, value) => {\n        if (!uniforms.get(name)) {\n            uniforms.set(name, new THREE.Uniform(value));\n        }\n    };\n    ensure('ncaMoonCenterECEF', new THREE.Vector3());\n    ensure('ncaMoonRadius', 0);\n    ensure('ncaSunCenterECEF', new THREE.Vector3());\n    ensure('ncaSunRadius', 0);\n    return true;\n}\n\nexport function ensureCelestialWorldOcclusionUniforms(material) {\n    const uniforms = material?.uniforms;\n    if (!uniforms) return false;\n    const ensure = (name, value) => {\n        if (!uniforms[name]) uniforms[name] = new THREE.Uniform(value);\n    };\n    ensure('ncaMoonCenterWorld', new THREE.Vector3());\n    ensure('ncaMoonRadiusWorld', 0);\n    ensure('ncaSunCenterWorld', new THREE.Vector3());\n    ensure('ncaSunRadiusWorld', 0);\n    return true;\n}\n\nfunction syncOccluder(effect, prefix, object, worldToECEFMatrix, scratchWorld) {\n    const uniforms = effect?.uniforms;\n    const centerUniform = uniforms?.get?.(`nca${prefix}CenterECEF`);\n    const radiusUniform = uniforms?.get?.(`nca${prefix}Radius`);\n    if (!centerUniform || !radiusUniform) return;\n\n    const radiusMeters = Number(object?.userData?.celestialOccluderRadiusM);\n    if (!object || !isObjectVisibleInHierarchy(object) || !(radiusMeters > 0)) {\n        radiusUniform.value = 0;\n        return;\n    }\n\n    object.getWorldPosition(scratchWorld);\n    scratchWorld.applyMatrix4(worldToECEFMatrix);\n    centerUniform.value.copy(scratchWorld).multiplyScalar(CELESTIAL_LENGTH_UNIT_PER_METER);\n    radiusUniform.value = radiusMeters * CELESTIAL_LENGTH_UNIT_PER_METER;\n}\n\nfunction syncWorldOccluder(\n    material,\n    prefix,\n    object,\n    scratchScale\n) {\n    const uniforms = material?.uniforms;\n    const centerUniform = uniforms?.[`nca${prefix}CenterWorld`];\n    const radiusUniform = uniforms?.[`nca${prefix}RadiusWorld`];\n    if (!centerUniform || !radiusUniform) return;\n\n    const radiusMeters = Number(object?.userData?.celestialOccluderRadiusM);\n    if (!object || !isObjectVisibleInHierarchy(object) || !(radiusMeters > 0)) {\n        radiusUniform.value = 0;\n        return;\n    }\n\n    object.getWorldPosition(centerUniform.value);\n    let radiusScale = 1;\n    if (scratchScale && object.getWorldScale) {\n        object.getWorldScale(scratchScale);\n        radiusScale = Math.max(\n            Math.abs(scratchScale.x),\n            Math.abs(scratchScale.y),\n            Math.abs(scratchScale.z)\n        );\n    }\n    radiusUniform.value = radiusMeters * radiusScale;\n}\n\n/**\n * Synchronize physical celestial geometry into Takram's rotating ECEF,\n * kilometre-scaled shader frame without allocating in the render loop.\n */\nexport function syncCelestialOcclusionUniforms(effect, {\n    moonMesh = null,\n    sunMesh = null,\n    worldToECEFMatrix,\n    scratchWorld,\n} = {}) {\n    if (!ensureCelestialOcclusionUniforms(effect)\n        || !worldToECEFMatrix\n        || !scratchWorld) return false;\n    syncOccluder(effect, 'Moon', moonMesh, worldToECEFMatrix, scratchWorld);\n    syncOccluder(effect, 'Sun', sunMesh, worldToECEFMatrix, scratchWorld);\n    return true;\n}\n\n/**\n * Synchronize the same physical celestial spheres into a world-space material.\n * This is used by transparent scene shells which render before the Takram\n * aerial pass and therefore cannot rely on the compositor to remove emission\n * that was already additively blended into inputColor.\n */\nexport function syncCelestialWorldOcclusionUniforms(material, {\n    moonMesh = null,\n    sunMesh = null,\n    scratchScale = null,\n} = {}) {\n    if (!ensureCelestialWorldOcclusionUniforms(material)) return false;\n    syncWorldOccluder(material, 'Moon', moonMesh, scratchScale);\n    syncWorldOccluder(material, 'Sun', sunMesh, scratchScale);\n    return true;\n}\n\n/**\n * Pure CPU analogue used by regression tests and diagnostics.\n */\nexport function raySphereFirstHitDistance(rayOrigin, rayDirection, center, radius) {\n    if (!rayOrigin || !rayDirection || !center || !(radius > 0)) return -1;\n    const ox = rayOrigin.x - center.x;\n    const oy = rayOrigin.y - center.y;\n    const oz = rayOrigin.z - center.z;\n    const b = ox * rayDirection.x + oy * rayDirection.y + oz * rayDirection.z;\n    const c = ox * ox + oy * oy + oz * oz - radius * radius;\n    const discriminant = b * b - c;\n    if (discriminant < 0) return -1;\n    const root = Math.sqrt(discriminant);\n    const nearDistance = -b - root;\n    if (nearDistance > 0) return nearDistance;\n    const farDistance = -b + root;\n    return farDistance > 0 ? farDistance : -1;\n}\n\nexport function resolveCelestialOcclusion({\n    rayOrigin,\n    rayDirection,\n    earthCenter,\n    earthRadius,\n    moonCenter,\n    moonRadius,\n    sunCenter,\n    sunRadius,\n} = {}) {\n    const earthDistance = raySphereFirstHitDistance(\n        rayOrigin, rayDirection, earthCenter, earthRadius\n    );\n    const moonDistance = raySphereFirstHitDistance(\n        rayOrigin, rayDirection, moonCenter, moonRadius\n    );\n    const sunDistance = raySphereFirstHitDistance(\n        rayOrigin, rayDirection, sunCenter, sunRadius\n    );\n    let celestial = null;\n    let celestialDistance = -1;\n    if (moonDistance >= 0) {\n        celestial = 'moon';\n        celestialDistance = moonDistance;\n    }\n    if (sunDistance >= 0\n        && (celestialDistance < 0 || sunDistance < celestialDistance)) {\n        celestial = 'sun';\n        celestialDistance = sunDistance;\n    }\n    return {\n        earthDistance,\n        celestial,\n        celestialDistance,\n        celestialOccludesEarth: celestialDistance >= 0\n            && (earthDistance < 0 || celestialDistance < earthDistance),\n    };\n}\n","import * as THREE from 'three';\nimport { Body, RotationAxis } from 'astronomy-engine';\nimport { MOON_RADIUS_M } from '../../modules/constants.js';\n\nconst geometryToBody = new THREE.Matrix4().makeRotationX(Math.PI / 2);\n/** IAU lunar body rotation through the scene's sole EQJ/world authority. */\nexport class LunarFrame {\n  constructor() {\n    this.matrix = new THREE.Matrix4();\n    this._north = new THREE.Vector3(); this._reference = new THREE.Vector3();\n    this._east = new THREE.Vector3(); this._x = new THREE.Vector3(); this._y = new THREE.Vector3();\n    this.timeMs = NaN;\n  }\n  update(date, celestialFrame) {\n    const ms = date.getTime();\n    if (!celestialFrame?.eqjToWorld || ms === this.timeMs) return this;\n    const axis = RotationAxis(Body.Moon, date), spin = axis.spin * Math.PI / 180;\n    this._north.set(axis.north.x, axis.north.y, axis.north.z).normalize();\n    this._reference.set(-this._north.y, this._north.x, 0).normalize();\n    this._east.crossVectors(this._north, this._reference);\n    this._x.copy(this._reference).multiplyScalar(Math.cos(spin)).addScaledVector(this._east, Math.sin(spin));\n    this._y.crossVectors(this._north, this._x);\n    this.matrix.makeBasis(this._x, this._y, this._north).premultiply(celestialFrame.eqjToWorld).multiply(geometryToBody);\n    this.timeMs = ms;\n    return this;\n  }\n}\n\n/** Stock lunar SphereGeometry axes: +X at 0E; -Z at 90E; +Y north. */\nexport function lunarSurfacePoint(lat, lon, radius = MOON_RADIUS_M, out = new THREE.Vector3()) {\n  const p = lat * Math.PI / 180, l = lon * Math.PI / 180;\n  return out.set(Math.cos(p) * Math.cos(l), Math.sin(p), -Math.cos(p) * Math.sin(l)).multiplyScalar(radius);\n}\n\nexport function lunarCoordinates(point, out = {}) {\n  out.rangeM = point.length();\n  out.lat = Math.atan2(point.y, Math.hypot(point.x, point.z)) * 180 / Math.PI;\n  out.lon = Math.atan2(-point.z, point.x) * 180 / Math.PI;\n  out.altitudeM = out.rangeM - MOON_RADIUS_M;\n  return out;\n}\n","/**\n * Simple Moon System\n *\n * Positions a Moon mesh at physical scale and apparent geocentric distance from\n * the shared Astronomy Engine ephemeris.\n *\n * IMPORTANT: Moon and Sun use the same apparent Earth-fixed-to-world frame.\n * Eclipse alignment must never mix this position with the retired circular\n * orbit or an independently simplified solar direction.\n */\n\nimport * as THREE from 'three';\nimport { resolveSceneRuntimeResource } from '../refactor/scene/SceneRuntimeResources.js';\nimport {\n    PLANET_RADIUS,\n    MOON_RADIUS_M,\n    MOON_DISTANCE_M,\n    SUN_RADIUS_M,\n} from './constants.js';\nimport { enforceCelestialOpaqueDepthMaterial } from '../refactor/render/CelestialOcclusionContract.js';\nimport { CelestialEphemeris } from './celestial-ephemeris.js';\nimport { LunarFrame } from '../refactor/lunar/LunarFrame.js';\nimport {\n    apparentAngularRadius,\n    CELESTIAL_IRRADIANCE_GLSL,\n} from '../refactor/render/CelestialIrradianceContract.js';\nconst MOON_DISPLACEMENT_SCALE_M = 32_767.5;\nconst MOON_DISPLACEMENT_BIAS_M = -10_000;\nconst MOON_BUMP_SCALE = 4;\n// Transparent and post-process atmosphere passes classify the lunar disk from\n// an analytic sphere after raster antialiasing. A sub-percent guard band keeps\n// their samples behind the opaque limb instead of creating a one-pixel blue or\n// green ring; it does not alter the rendered lunar geometry or apparent phase.\nconst MOON_ATMOSPHERE_OCCLUSION_PADDING_M = 12_000;\nconst MOON_BASE_COLOR = '#b0b3b8';\n// The scene's global Earth ambient lights are not a lunar irradiance model.\n// Lunar phase is direct finite-Sun illumination only; the unlit hemisphere\n// therefore stays black instead of inheriting an artificial grey fill.\nconst MOON_EARTHSHINE_INTENSITY = 0;\nconst MOON_BASE_TEXTURE_SIZE = 2048;\n// Projected lunar diameter (drawing-buffer px) at which full detail is loaded.\nconst MOON_FULL_DETAIL_PX = 900;\nconst whenIdle = (fn) => (typeof requestIdleCallback === 'function'\n    ? requestIdleCallback(fn, { timeout: 1500 })\n    : setTimeout(fn, 16));\n\n/**\n * Decode off the main thread (createImageBitmap) where available. A plain\n * <img> texture is decoded inside texImage/texSubImage on first draw, which\n * is what stalled frames. Raw channels are kept for the RG16 height map.\n */\nfunction loadMoonTexture(url) {\n    if (typeof createImageBitmap !== 'function' || !THREE.ImageBitmapLoader) {\n        return new THREE.TextureLoader().loadAsync(url);\n    }\n    const loader = new THREE.ImageBitmapLoader();\n    loader.setOptions({ imageOrientation: 'flipY', premultiplyAlpha: 'none', colorSpaceConversion: 'none' });\n    return loader.loadAsync(url).then((bitmap) => {\n        const texture = new THREE.Texture(bitmap);\n        texture.flipY = false; // already flipped during decode\n        texture.needsUpdate = true;\n        const dispose = texture.dispose.bind(texture);\n        texture.dispose = () => { dispose(); bitmap.close?.(); };\n        return texture;\n    });\n}\n\nexport class MoonSystem {\n    constructor(scene, planetRadius = PLANET_RADIUS, { renderer, mobile = false, camera = null } = {}) {\n        this.scene = scene;\n        this.planetRadius = planetRadius;\n        this._renderer = renderer || null;\n        this._camera = camera || null;\n        const limit = renderer?.capabilities?.maxTextureSize || 8192;\n        // Full-detail sizes, used only once the Moon is large on screen. Until\n        // then a 2048 base set is shown: an 8192 JPEG decoded + uploaded on the\n        // main thread froze the render loop for ~0.5-0.9 s the first time the\n        // Moon entered the view, even from Earth where it spans a few pixels.\n        this._fullColorSize = Math.min(mobile ? 4096 : 8192, limit) >= 8192 ? 8192 : limit >= 4096 ? 4096 : 2048;\n        this._fullHeightSize = this._fullColorSize >= 8192 ? 4096 : 2048;\n        this._colorSize = MOON_BASE_TEXTURE_SIZE;\n        this._heightSize = MOON_BASE_TEXTURE_SIZE; // size of the height map on the Moon now\n        this._anisotropy = Math.min(8, renderer?.capabilities?.getMaxAnisotropy?.() || 1);\n\n        // Basic moon mesh (higher tessellation for displacement)\n        const geom = new THREE.SphereGeometry(MOON_RADIUS_M, 256, 128);\n        const mat = this._createMoonMaterial();\n        this.moonMesh = new THREE.Mesh(geom, mat);\n        this.moonMesh.name = 'Moon';\n        this.moonMesh.userData.celestialOccluder = 'moon';\n        this.moonMesh.userData.celestialOccluderRadiusM =\n            MOON_RADIUS_M\n            + Math.max(0, MOON_DISPLACEMENT_SCALE_M + MOON_DISPLACEMENT_BIAS_M)\n            + MOON_ATMOSPHERE_OCCLUSION_PADDING_M;\n        // Runs only when the Moon is actually drawn: request full detail once\n        // it spans enough pixels for 8192 texels to matter.\n        this._drawSize = new THREE.Vector2();\n        this._moonWorld = new THREE.Vector3();\n        this._cameraWorld = new THREE.Vector3();\n        this.moonMesh.onBeforeRender = (renderer, _scene, camera) => this._observeScreenSize(renderer, camera);\n        this.scene.add(this.moonMesh);\n\n        this.position = new THREE.Vector3(0, 0, MOON_DISTANCE_M);\n        this.direction = new THREE.Vector3(0, 0, 1);\n        this._baseMaterial = mat;\n        this._moonMaterial = mat;\n        this._imageryEnabled = false;\n        this._tier = 'base';\n        this._texturesByTier = new Map();   // tier → { color, displacement }\n        this._loadsByTier = new Map();      // tier → Promise\n        this._applySeq = 0;\n        this._loadTexture = loadMoonTexture; // url → Promise<Texture>; replaceable in tests\n        this._fallbackEphemeris = new CelestialEphemeris();\n        this._sunFromMoon = new THREE.Vector3();\n        this.bodyFrame = new LunarFrame();\n    }\n\n    _createMoonMaterial() {\n        const mat = enforceCelestialOpaqueDepthMaterial(new THREE.MeshStandardMaterial({\n            color: MOON_BASE_COLOR,\n            roughness: 0.9,\n            metalness: 0.0,\n            emissive: MOON_BASE_COLOR,\n            emissiveIntensity: MOON_EARTHSHINE_INTENSITY,\n        }));\n        // MeshStandardMaterial computes the direct lunar phase from the shared\n        // astronomical DirectionalLight. The shader below rejects Earth-only\n        // ambient/hemisphere lights from the lunar material, then applies the\n        // finite-disc Earth eclipse only to direct solar irradiance.\n        this._eclipseUniforms = {\n            ncaSunFromMoonDirection: { value: new THREE.Vector3(0, 0, 1) },\n            ncaSunAngularRadiusAtMoon: { value: 0.004675 },\n            ncaEarthCenterWorld: { value: new THREE.Vector3() },\n            ncaEarthRadius: { value: PLANET_RADIUS },\n            ncaLunarUmbraColor: { value: new THREE.Color('#b52b12') },\n            ncaLunarUmbraStrength: { value: 0.012 },\n        };\n        mat.onBeforeCompile = (shader) => {\n            Object.assign(shader.uniforms, this._eclipseUniforms);\n            shader.vertexShader = shader.vertexShader\n                .replace(\n                    '#include <common>',\n                    '#include <common>\\nvarying vec3 vNcaMoonWorldPosition;',\n                )\n                .replace(\n                    '#include <worldpos_vertex>',\n                    '#include <worldpos_vertex>\\n  vNcaMoonWorldPosition = (modelMatrix * vec4(transformed, 1.0)).xyz;',\n                )\n                .replace('#include <displacementmap_vertex>', THREE.ShaderChunk.displacementmap_vertex\n                    .replace('texture2D( displacementMap, vDisplacementMapUv ).x',\n                        'dot(texture2D(displacementMap, vDisplacementMapUv).rg, vec2(256.0, 1.0)) / 257.0'));\n            shader.fragmentShader = shader.fragmentShader\n                .replace(\n                    '#include <common>',\n                    `#include <common>\nvarying vec3 vNcaMoonWorldPosition;\nuniform vec3 ncaSunFromMoonDirection;\nuniform float ncaSunAngularRadiusAtMoon;\nuniform vec3 ncaEarthCenterWorld;\nuniform float ncaEarthRadius;\nuniform vec3 ncaLunarUmbraColor;\nuniform float ncaLunarUmbraStrength;\n${CELESTIAL_IRRADIANCE_GLSL}`,\n                )\n                .replace(\n                    '#include <lights_fragment_end>',\n                    `#include <lights_fragment_end>\n  reflectedLight.indirectDiffuse = vec3(0.0);\n  reflectedLight.indirectSpecular = vec3(0.0);\n  vec3 ncaMoonToEarth = ncaEarthCenterWorld - vNcaMoonWorldPosition;\n  float ncaMoonEarthDistance = max(length(ncaMoonToEarth), ncaEarthRadius + 1.0);\n  float ncaEarthAngularRadius = asin(clamp(\n    ncaEarthRadius / ncaMoonEarthDistance,\n    0.0,\n    1.0\n  ));\n  float ncaLunarSolarVisibility = ncaFiniteDiscVisibility(\n    ncaSunFromMoonDirection,\n    ncaSunAngularRadiusAtMoon,\n    ncaMoonToEarth,\n    ncaEarthAngularRadius\n  );\n  reflectedLight.directDiffuse *= ncaLunarSolarVisibility;\n  reflectedLight.directSpecular *= ncaLunarSolarVisibility;\n  float ncaUmbraAmount = pow(1.0 - ncaLunarSolarVisibility, 2.0);\n  totalEmissiveRadiance += ncaLunarUmbraColor\n    * ncaLunarUmbraStrength\n    * ncaUmbraAmount;`,\n                )\n                .replace('#include <bumpmap_pars_fragment>', THREE.ShaderChunk.bumpmap_pars_fragment\n                    .replace(/texture2D\\( bumpMap, ([^)]*) \\)\\.x/g,\n                        '(dot(texture2D(bumpMap, $1).rg, vec2(256.0, 1.0)) / 257.0)'));\n            this._moonShader = shader;\n        };\n        mat.customProgramCacheKey = () => 'nca-lunar-direct-topography-rg16-v3';\n        return mat;\n    }\n\n    _observeScreenSize(renderer, camera) {\n        if (camera?.isPerspectiveCamera) this._camera = camera;\n        if (this._tier === 'full' || !this._imageryEnabled || this._fullColorSize <= MOON_BASE_TEXTURE_SIZE) return;\n        const distance = this.moonMesh.getWorldPosition(this._moonWorld).distanceTo(camera.getWorldPosition(this._cameraWorld));\n        if (!(distance > MOON_RADIUS_M)) return this._requestTier('full');\n        renderer.getDrawingBufferSize(this._drawSize);\n        const angular = 2 * Math.asin(Math.min(1, MOON_RADIUS_M / distance));\n        const pixels = angular / THREE.MathUtils.degToRad(camera.fov || 60) * this._drawSize.y;\n        if (pixels >= MOON_FULL_DETAIL_PX) this._requestTier('full');\n    }\n\n    _requestTier(tier) {\n        if (this._tier === tier || this._requestedTier === tier) return;\n        this._requestedTier = tier;\n        // Leave the render callback before any work starts.\n        Promise.resolve().then(() => this._applyMoonTextures(tier));\n    }\n\n    /**\n     * Update from the shared apparent geocentric ephemeris.\n     *\n     * @param {Date} date\n     */\n    update(date = new Date(), celestialState = null) {\n        const ephemeris = celestialState?.moonPosition\n            ? celestialState\n            : this._fallbackEphemeris.update(date);\n\n        // Update state\n        this.position.copy(ephemeris.moonPosition);\n        this.direction.copy(ephemeris.moonDirection);\n        this._sunFromMoon.subVectors(\n            ephemeris.sunPosition,\n            ephemeris.moonPosition,\n        );\n        const sunFromMoonDistance = this._sunFromMoon.length();\n        if (sunFromMoonDistance > 0) {\n            this._eclipseUniforms.ncaSunFromMoonDirection.value\n                .copy(this._sunFromMoon)\n                .divideScalar(sunFromMoonDistance);\n            this._eclipseUniforms.ncaSunAngularRadiusAtMoon.value =\n                apparentAngularRadius(SUN_RADIUS_M, sunFromMoonDistance);\n        }\n\n        if (this.moonMesh) {\n            this.moonMesh.position.copy(this.position);\n            this.bodyFrame.update(date, ephemeris.frame);\n            this.moonMesh.quaternion.setFromRotationMatrix(this.bodyFrame.matrix);\n        }\n    }\n\n    getDirection() {\n        return this.direction.clone();\n    }\n\n    setImageryEnabled(enabled) {\n        const next = !!enabled;\n        if (this._imageryEnabled === next) return;\n        this._imageryEnabled = next;\n        if (next) {\n            this._applyMoonTextures();\n        } else {\n            this._clearMoonTextures();\n        }\n    }\n\n    _clearMoonTextures() {\n        this._applySeq += 1;\n        if (!this.moonMesh) return;\n        if (this.moonMesh.material !== this._baseMaterial) {\n            this.moonMesh.material.dispose();\n            this.moonMesh.material = this._baseMaterial;\n        }\n        this._moonMaterial = this._baseMaterial;\n    }\n\n    /**\n     * Load a tier's textures (decoded off the main thread), upload them to\n     * the GPU in idle time, compile the textured shader ahead of use, then\n     * swap materials — so neither upload nor shader link lands in a frame.\n     */\n    async _applyMoonTextures(tier = this._tier) {\n        if (!this.moonMesh) return;\n        const seq = ++this._applySeq;\n        try {\n            const textures = await this._loadMoonTextures(tier);\n            if (seq !== this._applySeq || this._disposed || !this._imageryEnabled || !textures) return;\n            await this._uploadInIdle(textures);\n            const mat = this._createMoonMaterial();\n            mat.map = textures.color;\n            mat.emissiveMap = null;\n            mat.displacementMap = textures.displacement;\n            // The source is the same registered LRO DEM used for vertex\n            // displacement. Three's height-derived bump path evaluates its\n            // local gradients per fragment, providing crater-wall normals\n            // between the finite topology samples without inventing a\n            // separately aligned texture.\n            mat.bumpMap = textures.displacement;\n            mat.displacementScale = MOON_DISPLACEMENT_SCALE_M;\n            mat.displacementBias = MOON_DISPLACEMENT_BIAS_M;\n            mat.bumpScale = MOON_BUMP_SCALE;\n            mat.color.set(0xffffff);\n            mat.emissive.set(0xffffff);\n            mat.emissiveIntensity = MOON_EARTHSHINE_INTENSITY;\n            await this._precompile(mat);\n            if (seq !== this._applySeq || this._disposed || !this._imageryEnabled) { mat.dispose(); return; }\n            const previous = this.moonMesh.material;\n            this.moonMesh.material = mat;\n            this._moonMaterial = mat;\n            if (previous !== this._baseMaterial) previous.dispose();\n            const previousTier = this._tier;\n            this._tier = tier;\n            this._colorSize = textures.colorSize;\n            this._heightSize = textures.heightSize;\n            if (previousTier !== tier && this._texturesByTier.has(previousTier) && previousTier !== 'full') {\n                const old = this._texturesByTier.get(previousTier);\n                old.color.dispose(); old.displacement.dispose();\n                this._texturesByTier.delete(previousTier);\n                this._loadsByTier.delete(previousTier);\n            }\n        } catch (err) {\n            console.warn('[MoonSystem] Failed to load moon textures:', err);\n            if (this._requestedTier === tier) this._requestedTier = null;\n            if (!this._disposed && tier === 'base') this._clearMoonTextures();\n        }\n    }\n\n    _uploadInIdle(textures) {\n        const renderer = this._renderer;\n        if (!renderer?.initTexture) return Promise.resolve();\n        const queue = [textures.color, textures.displacement];\n        return new Promise((resolve) => {\n            const next = () => {\n                const texture = queue.shift();\n                if (!texture) return resolve();\n                try { renderer.initTexture(texture); } catch { /* uploaded on first draw instead */ }\n                whenIdle(next);\n            };\n            whenIdle(next);\n        });\n    }\n\n    async _precompile(material) {\n        const renderer = this._renderer;\n        if (!renderer?.compileAsync || !this._camera) return;\n        const probe = new THREE.Mesh(this.moonMesh.geometry, material);\n        probe.matrixWorld.copy(this.moonMesh.matrixWorld);\n        try { await renderer.compileAsync(probe, this._camera, this.scene); } catch { /* compiles on first draw */ }\n    }\n\n    _loadMoonTextures(tier = 'base') {\n        if (this._texturesByTier.has(tier)) return Promise.resolve(this._texturesByTier.get(tier));\n        if (this._loadsByTier.has(tier)) return this._loadsByTier.get(tier);\n        const colorSize = tier === 'full' ? this._fullColorSize : MOON_BASE_TEXTURE_SIZE;\n        const heightSize = tier === 'full' ? this._fullHeightSize : MOON_BASE_TEXTURE_SIZE;\n        const load = (url) => this._loadTexture(url);\n        const pending = Promise.allSettled([\n            load(resolveSceneRuntimeResource(`/textures/moon/lroc-2025-${colorSize}.jpg`))\n                .catch(error => {\n                    if (colorSize === MOON_BASE_TEXTURE_SIZE) throw error;\n                    return load(resolveSceneRuntimeResource(`/textures/moon/lroc-2025-${MOON_BASE_TEXTURE_SIZE}.jpg`));\n                }),\n            load(resolveSceneRuntimeResource(`/textures/moon/lola-height-rg16-${heightSize}.png`))\n        ]).then(results => {\n            if (this._disposed || results.some(result => result.status === 'rejected')) {\n                for (const result of results) if (result.status === 'fulfilled') result.value.dispose();\n                if (this._disposed) return null;\n                throw results.find(result => result.status === 'rejected').reason;\n            }\n            const [color, displacement] = results.map(result => result.value);\n            color.colorSpace = THREE.SRGBColorSpace;\n            displacement.colorSpace = THREE.NoColorSpace;\n            color.anisotropy = displacement.anisotropy = this._anisotropy;\n            color.needsUpdate = true;\n            displacement.needsUpdate = true;\n            const textures = { color, displacement, colorSize: color.image?.width || colorSize, heightSize };\n            this._texturesByTier.set(tier, textures);\n            return textures;\n        }).catch((err) => {\n            this._loadsByTier.delete(tier);\n            throw err;\n        });\n        this._loadsByTier.set(tier, pending);\n        return pending;\n    }\n\n    dispose() {\n        this._disposed = true;\n        for (const textures of this._texturesByTier.values()) {\n            textures.color?.dispose?.();\n            textures.displacement?.dispose?.();\n        }\n        this._texturesByTier.clear();\n        if (this.moonMesh && this.moonMesh.material !== this._baseMaterial) this._baseMaterial.dispose();\n        if (this.moonMesh) {\n            this.scene.remove(this.moonMesh);\n            this.moonMesh.geometry.dispose();\n            this.moonMesh.material.dispose();\n            this.moonMesh = null;\n        }\n    }\n}\n","// Independent implementation of published wave equations; see docs/OCEAN_MATH.md.\nexport const OCEAN_WAVE_COUNT = 16;\nconst TAU = 2 * Math.PI;\nexport const OCEAN_ABSORPTION = Object.freeze([0.12, 0.045, 0.025]);\n\nexport function oceanDispersion(k, depth = 5000) {\n    return Math.sqrt((9.81 * k + 0.000074 * k ** 3) * Math.tanh(k * Math.max(0.1, depth)));\n}\n\n/** JONSWAP density in angular-frequency space, in m²/(rad/s). */\nexport function jonswapDensity(omega, peakOmega, gamma = 3.3, alpha = 0.0081) {\n    if (!(omega > 0) || !(peakOmega > 0)) return 0;\n    const sigma = omega <= peakOmega ? 0.07 : 0.09;\n    const peak = Math.exp(-0.5 * ((omega / peakOmega - 1) / sigma) ** 2);\n    return alpha * 9.81 ** 2 * omega ** -5\n        * Math.exp(-1.25 * (peakOmega / omega) ** 4) * gamma ** peak;\n}\n\nexport function jonswapAlpha(windSpeed, peakOmega) {\n    return windSpeed > 0 ? 0.076 * (windSpeed * peakOmega / (22 * 9.81)) ** 0.66 : 0;\n}\n\n// Lanczos log-gamma gives the exact normalization for cos^(2s)(theta/2).\nfunction logGamma(z) {\n    const terms = [676.5203681218851, -1259.1392167224028, 771.3234287776531,\n        -176.6150291621406, 12.507343278686905, -0.13857109526572012,\n        9.984369578019572e-6, 1.5056327351493116e-7];\n    z -= 1;\n    let sum = 0.9999999999998099;\n    for (let i = 0; i < terms.length; i++) sum += terms[i] / (z + i + 1);\n    const t = z + 7.5;\n    return 0.5 * Math.log(2 * Math.PI) + (z + 0.5) * Math.log(t) - t + Math.log(sum);\n}\n\nexport function oceanDirectionalSpread(angle, frequencyRatio) {\n    const spread = Math.max(0.5, 9.77 * frequencyRatio ** (frequencyRatio <= 1 ? 5 : -2.5));\n    const normalization = Math.exp(logGamma(spread + 1) - logGamma(spread + 0.5)) / (2 * Math.sqrt(Math.PI));\n    return normalization * Math.max(0, Math.cos(angle / 2)) ** (2 * spread);\n}\n\n/** Bounded Fourier quadrature, not an FFT or a measured wave forecast. */\nexport function createOceanSpectrum({ windSpeed = 8, peakWavelength = 70, windDirection = 0.5, depth = 5000 } = {}) {\n    const peakOmega = oceanDispersion(TAU / Math.max(10, peakWavelength), depth);\n    const waves = [];\n    for (let i = 0; i < OCEAN_WAVE_COUNT; i++) {\n        const low = peakOmega * 0.55 * (8 / 0.55) ** (i / OCEAN_WAVE_COUNT);\n        const high = peakOmega * 0.55 * (8 / 0.55) ** ((i + 1) / OCEAN_WAVE_COUNT);\n        const omega = Math.sqrt(low * high);\n        // Solve the finite-depth dispersion relation; phase speed follows k.\n        let k = omega ** 2 / 9.81;\n        for (let j = 0; j < 12; j++) {\n            const tangent = Math.tanh(k * Math.max(0.1, depth));\n            const f = (9.81 * k + 0.000074 * k ** 3) * tangent - omega ** 2;\n            const derivative = (9.81 + 0.000222 * k ** 2) * tangent\n                + (9.81 * k + 0.000074 * k ** 3) * Math.max(0.1, depth) * (1 - tangent ** 2);\n            k = Math.max(1e-6, k - f / Math.max(1e-8, derivative));\n        }\n        // Long waves align with wind; shorter waves spread more widely.\n        const spread = Math.min(1.4, 0.18 + 0.28 * omega / peakOmega);\n        const angle = windDirection + Math.sin(i * 2.399963) * spread;\n        waves.push({ kx: Math.cos(angle) * k, ky: Math.sin(angle) * k, k, omega,\n            amplitude: Math.sqrt(2 * jonswapDensity(omega, peakOmega, 3.3, jonswapAlpha(windSpeed, peakOmega)) * (high - low)),\n            phase: (i * 2.399963) % TAU });\n    }\n    return waves;\n}\n\n/** CPU counterpart for sampling and validation, with analytic derivatives. */\nexport function sampleOceanSpectrum(waves, x, y, seconds, scale = 1) {\n    let height = 0, dx = 0, dy = 0, compression = 0;\n    for (const wave of waves) {\n        const phase = wave.kx * x + wave.ky * y - wave.omega * seconds + wave.phase;\n        const amplitude = wave.amplitude * scale;\n        height += amplitude * Math.sin(phase);\n        dx += amplitude * wave.kx * Math.cos(phase);\n        dy += amplitude * wave.ky * Math.cos(phase);\n        compression += amplitude * wave.k * Math.sin(phase);\n    }\n    return { height, dx, dy, compression };\n}\n\n// Both stages evaluate the same spectrum. Wavelength filtering keeps geometry\n// below its spatial Nyquist limit and fragment normals below their pixel limit.\n// With GPU cascades ready, fields come from three spectral tiles (see\n// ocean-gpu-cascades.js); otherwise sixteen analytic components remain.\nexport const OCEAN_WAVE_GLSL = `\nuniform vec4 ncaOceanWaves[16];\nuniform vec2 ncaOceanWavePhases[16];\nuniform float ncaOceanTime;\nuniform float ncaOceanWaveScale;\nuniform vec4 ncaOceanRipples[8];\nuniform float ncaOceanGPUReady;\nuniform sampler2D ncaOceanDisp0, ncaOceanDisp1, ncaOceanDisp2;\nuniform sampler2D ncaOceanSlope0, ncaOceanSlope1, ncaOceanSlope2;\nuniform vec3 ncaOceanCascadeLength, ncaOceanCascadeSize;\nuniform vec2 ncaOceanCascadeOrigin[3];\nuniform vec4 ncaOceanFFTMatrix;\nvec2 oceanFixed(vec2 p) { return vec2(dot(p, ncaOceanFFTMatrix.xy), dot(p, ncaOceanFFTMatrix.zw)); }\nvec2 oceanPatchVector(vec2 v) {\n  return vec2(v.x * ncaOceanFFTMatrix.x + v.y * ncaOceanFFTMatrix.z, v.x * ncaOceanFFTMatrix.y + v.y * ncaOceanFFTMatrix.w);\n}\nvec2 oceanCascadeUv(vec2 fixedP, int i) {\n  float length_ = i == 0 ? ncaOceanCascadeLength.x : (i == 1 ? ncaOceanCascadeLength.y : ncaOceanCascadeLength.z);\n  return fixedP / length_ + ncaOceanCascadeOrigin[i];\n}\nvec3 oceanCascadeLod(float footprint) {\n  return max(vec3(0.0), log2(max(vec3(0.001), footprint * ncaOceanCascadeSize / ncaOceanCascadeLength)));\n}\n// (Dx, h, Dz) in the patch frame: x east, y up, z north.\nvec3 oceanDisplacement(vec2 p, float footprint) {\n  vec2 fixedP = oceanFixed(p);\n  vec3 lod = oceanCascadeLod(footprint);\n  vec3 d = textureLod(ncaOceanDisp0, oceanCascadeUv(fixedP, 0), lod.x).xyz\n    + textureLod(ncaOceanDisp1, oceanCascadeUv(fixedP, 1), lod.y).xyz\n    + textureLod(ncaOceanDisp2, oceanCascadeUv(fixedP, 2), lod.z).xyz;\n  vec2 horizontal = oceanPatchVector(d.xz);\n  return vec3(horizontal.x, d.y, horizontal.y);\n}\n// Summed cascade slopes (patch frame), foam and unresolved slope variance.\nvec4 oceanSlopeFoam(vec2 p, float footprint, out float variance) {\n  vec2 fixedP = oceanFixed(p);\n  vec3 lod = oceanCascadeLod(footprint);\n  vec4 s0 = textureLod(ncaOceanSlope0, oceanCascadeUv(fixedP, 0), lod.x);\n  vec4 s1 = textureLod(ncaOceanSlope1, oceanCascadeUv(fixedP, 1), lod.y);\n  vec4 s2 = textureLod(ncaOceanSlope2, oceanCascadeUv(fixedP, 2), lod.z);\n  variance = max(0.0, s0.a - dot(s0.xy, s0.xy)) + max(0.0, s1.a - dot(s1.xy, s1.xy)) + max(0.0, s2.a - dot(s2.xy, s2.xy));\n  return vec4(oceanPatchVector(s0.xy + s1.xy + s2.xy), clamp(s0.b * 0.5 + s1.b + s2.b * 0.35, 0.0, 1.0), 0.0);\n}\n// Surface Laplacian (slope divergence), filtered to a lateral blur radius.\nfloat oceanFocusDivergence(vec2 p, float blurMeters) {\n  vec2 fixedP = oceanFixed(p);\n  vec3 lod = oceanCascadeLod(blurMeters);\n  return textureLod(ncaOceanDisp1, oceanCascadeUv(fixedP, 1), lod.y).a\n    + textureLod(ncaOceanDisp2, oceanCascadeUv(fixedP, 2), lod.z).a;\n}\nvec2 oceanDrift(vec2 p, float footprint) {\n  if (ncaOceanGPUReady < 0.5) return vec2(0.0);\n  return oceanDisplacement(p, footprint).xz;\n}\nvec4 oceanField(vec2 p, float footprint) {\n  vec4 field = vec4(0.0);\n  float seconds = ncaOceanTime * 4.0;\n  if (ncaOceanGPUReady > 0.5) {\n    float variance;\n    vec4 slopeFoam = oceanSlopeFoam(p, footprint, variance);\n    field = vec4(oceanDisplacement(p, footprint).y, slopeFoam.xy, slopeFoam.z);\n  } else for (int i = 0; i < 16; i++) {\n    vec4 wave = ncaOceanWaves[i];\n    float k = length(wave.xy);\n    float wavelength = 6.28318530718 / k;\n    float amplitude = wave.z * clamp(ncaOceanWaveScale, 0.0, 2.0)\n      * smoothstep(2.0 * footprint, 4.0 * footprint, wavelength);\n    float phase = dot(p, wave.xy) - seconds * wave.w + ncaOceanWavePhases[i].x;\n    float s = sin(phase), c = cos(phase);\n    field += vec4(amplitude * s, amplitude * wave.xy * c, amplitude * k * s);\n  }\n  for (int i = 0; i < 8; i++) {\n    float age = max(0.0, ncaOceanTime - ncaOceanRipples[i].z) * 4.0;\n    vec2 delta = p - ncaOceanRipples[i].xy;\n    float distance = length(delta), front = distance - age * 1.4;\n    float envelope = exp(-abs(front) * 0.7 - age * 0.8) * ncaOceanRipples[i].w;\n    float phase = distance * 2.5 - age * 5.0;\n    field.x += sin(phase) * envelope;\n    field.yz += delta / max(distance, 0.001) * envelope\n      * (2.5 * cos(phase) - 0.7 * sign(front) * sin(phase));\n  }\n  return field;\n}`;\n","import { oceanDispersion, jonswapDensity, jonswapAlpha, oceanDirectionalSpread } from './ocean-wave-spectrum.js';\n\n/** In-place radix-2 complex FFT. Inverse is an unnormalized Fourier sum. */\nexport function oceanFFT(real, imaginary, inverse = false) {\n    const size = real.length;\n    if (size < 2 || (size & (size - 1)) !== 0 || imaginary.length !== size) throw new Error('FFT requires matching power-of-two arrays');\n    for (let i = 1, j = 0; i < size; i++) {\n        let bit = size >> 1;\n        for (; j & bit; bit >>= 1) j ^= bit;\n        j ^= bit;\n        if (i < j) {\n            [real[i], real[j]] = [real[j], real[i]];\n            [imaginary[i], imaginary[j]] = [imaginary[j], imaginary[i]];\n        }\n    }\n    for (let length = 2; length <= size; length *= 2) {\n        const angle = (inverse ? 2 : -2) * Math.PI / length;\n        const stepReal = Math.cos(angle), stepImaginary = Math.sin(angle);\n        for (let start = 0; start < size; start += length) {\n            let wr = 1, wi = 0;\n            for (let offset = 0; offset < length / 2; offset++) {\n                const a = start + offset, b = a + length / 2;\n                const br = wr * real[b] - wi * imaginary[b];\n                const bi = wr * imaginary[b] + wi * real[b];\n                real[b] = real[a] - br; imaginary[b] = imaginary[a] - bi;\n                real[a] += br; imaginary[a] += bi;\n                const next = wr * stepReal - wi * stepImaginary;\n                wi = wr * stepImaginary + wi * stepReal; wr = next;\n            }\n        }\n    }\n}\n\nexport function oceanFFT2D(real, imaginary, size, scratchReal = new Float64Array(size), scratchImaginary = new Float64Array(size)) {\n    for (let row = 0; row < size; row++) {\n        oceanFFT(real.subarray(row * size, (row + 1) * size), imaginary.subarray(row * size, (row + 1) * size), true);\n    }\n    for (let column = 0; column < size; column++) {\n        for (let row = 0; row < size; row++) {\n            scratchReal[row] = real[row * size + column]; scratchImaginary[row] = imaginary[row * size + column];\n        }\n        oceanFFT(scratchReal, scratchImaginary, true);\n        for (let row = 0; row < size; row++) {\n            real[row * size + column] = scratchReal[row]; imaginary[row * size + column] = scratchImaginary[row];\n        }\n    }\n}\n\nconst wrapAngle = angle => Math.atan2(Math.sin(angle), Math.cos(angle));\n\n/**\n * Initial Hermitian coefficients h0(k), shared by the CPU reference cascade and\n * the GPU cascades. Wavenumbers outside [minK, maxK) are zero so cascades with\n * different tile lengths partition the spectrum without double-counting energy.\n */\nexport function createOceanInitialSpectrum({ size = 128, length = 1024, minK = 0, maxK = Infinity, windSpeed = 8,\n    peakWavelength = 70, windDirection = 0.5, depth = 5000, seed = 947 } = {}) {\n    if (size < 8 || size > 512 || (size & (size - 1))) throw new Error('Unsupported ocean FFT resolution');\n    const count = size * size;\n    const spectrum = { size, length, initialReal: new Float64Array(count), initialImaginary: new Float64Array(count),\n        kx: new Float64Array(count), ky: new Float64Array(count), omega: new Float64Array(count) };\n    let randomState = seed >>> 0;\n    const random = () => {\n        randomState = (Math.imul(randomState, 1664525) + 1013904223) >>> 0;\n        return (randomState + 0.5) / 4294967296;\n    };\n    const peakOmega = oceanDispersion(2 * Math.PI / peakWavelength, depth);\n    const alpha = jonswapAlpha(windSpeed, peakOmega), deltaK = 2 * Math.PI / length;\n    for (let y = 0; y < size; y++) for (let x = 0; x < size; x++) {\n        const i = y * size + x;\n        // Zero Nyquist lines: odd derivatives must retain Hermitian symmetry.\n        if (x === size / 2 || y === size / 2) continue;\n        const kx = (x < size / 2 ? x : x - size) * deltaK;\n        const ky = (y < size / 2 ? y : y - size) * deltaK;\n        const k = Math.hypot(kx, ky);\n        spectrum.kx[i] = kx; spectrum.ky[i] = ky;\n        if (k < Math.max(1e-6, minK) || k >= maxK) continue;\n        const omega = oceanDispersion(k, depth); spectrum.omega[i] = omega;\n        const tangent = Math.tanh(k * depth);\n        const derivative = ((9.81 + 0.000222 * k * k) * tangent\n            + (9.81 * k + 0.000074 * k ** 3) * depth * (1 - tangent * tangent)) / (2 * omega);\n        const density = jonswapDensity(omega, peakOmega, 3.3, alpha)\n            * oceanDirectionalSpread(wrapAngle(Math.atan2(ky, kx) - windDirection), omega / peakOmega) * derivative / k;\n        // Each pair h0(k), conjugate(h0(-k)) supplies the full real variance.\n        const sigma = Math.sqrt(Math.max(0, density) * deltaK * deltaK) * 0.5;\n        const radius = Math.sqrt(-2 * Math.log(random())), phase = 2 * Math.PI * random();\n        spectrum.initialReal[i] = sigma * radius * Math.cos(phase);\n        spectrum.initialImaginary[i] = sigma * radius * Math.sin(phase);\n    }\n    return spectrum;\n}\n\n/** Hermitian spectral evolution with analytic slopes and choppy horizontal displacement. */\nexport class OceanFFTCascade {\n    constructor(options = {}) {\n        const size = options.size ?? 128;\n        if (size > 256) throw new Error('Unsupported ocean FFT resolution');\n        const spectrum = createOceanInitialSpectrum(options);\n        Object.assign(this, spectrum);\n        const count = size * size;\n        this.fields = Array.from({ length: 5 }, () => ({ real: new Float64Array(count), imaginary: new Float64Array(count) }));\n        this.scratchReal = new Float64Array(size); this.scratchImaginary = new Float64Array(size);\n        this.output = new Float32Array(count * 4);\n        this.displacement = new Float32Array(count * 4); this.foam = new Float32Array(count);\n    }\n\n    evaluate(seconds, output = this.output, scale = 1) {\n        const n = this.size;\n        for (let y = 0; y < n; y++) for (let x = 0; x < n; x++) {\n            const i = y * n + x, mirror = ((n - y) % n) * n + (n - x) % n;\n            const phase = this.omega[i] * seconds, c = Math.cos(phase), s = Math.sin(phase);\n            const ar = this.initialReal[i], ai = this.initialImaginary[i];\n            const br = this.initialReal[mirror], bi = this.initialImaginary[mirror];\n            const real = ((ar + br) * c + (ai + bi) * s) * scale;\n            const imaginary = ((ai - bi) * c + (br - ar) * s) * scale;\n            const k = Math.hypot(this.kx[i], this.ky[i]);\n            this.fields[0].real[i] = real; this.fields[0].imaginary[i] = imaginary;\n            for (let channel = 1; channel <= 2; channel++) {\n                const derivative = channel === 1 ? this.kx[i] : this.ky[i];\n                this.fields[channel].real[i] = -imaginary * derivative;\n                this.fields[channel].imaginary[i] = real * derivative;\n            }\n            for (let channel = 3; channel <= 4; channel++) {\n                const direction = (channel === 3 ? this.kx[i] : this.ky[i]) / Math.max(k, 1e-8);\n                this.fields[channel].real[i] = -imaginary * direction * 0.8;\n                this.fields[channel].imaginary[i] = real * direction * 0.8;\n            }\n        }\n        for (const field of this.fields) oceanFFT2D(field.real, field.imaginary, n, this.scratchReal, this.scratchImaginary);\n        const decay = Math.exp(-Math.min(1, Math.max(0, seconds - (this.previousSeconds ?? seconds - 0.1))) / 0.5);\n        const derivativeScale = n / (2 * this.length);\n        for (let y = 0; y < n; y++) for (let x = 0; x < n; x++) {\n            const i = y * n + x, l = y * n + (x + n - 1) % n, r = y * n + (x + 1) % n;\n            const b = ((y + n - 1) % n) * n + x, t = ((y + 1) % n) * n + x;\n            const horizontalX = this.fields[3].real, horizontalY = this.fields[4].real;\n            const xx = 1 + (horizontalX[r] - horizontalX[l]) * derivativeScale;\n            const xy = (horizontalX[t] - horizontalX[b]) * derivativeScale;\n            const yx = (horizontalY[r] - horizontalY[l]) * derivativeScale;\n            const yy = 1 + (horizontalY[t] - horizontalY[b]) * derivativeScale;\n            const determinant = xx * yy - xy * yx;\n            const source = Math.min(1, Math.max(0, (0.85 - determinant) / 0.4));\n            this.foam[i] = Math.min(1, this.foam[i] * decay + 2.5 * source * (1 - decay));\n            const gx = this.fields[1].real[i], gy = this.fields[2].real[i];\n            output[i * 4] = this.fields[0].real[i];\n            output[i * 4 + 1] = (yy * gx - yx * gy) / Math.max(0.2, determinant);\n            output[i * 4 + 2] = (xx * gy - xy * gx) / Math.max(0.2, determinant);\n            output[i * 4 + 3] = this.foam[i];\n            this.displacement[i * 4] = horizontalX[i]; this.displacement[i * 4 + 1] = horizontalY[i];\n            this.displacement[i * 4 + 2] = determinant; this.displacement[i * 4 + 3] = 0;\n        }\n        this.previousSeconds = seconds;\n        return output;\n    }\n}\n","import * as THREE from 'three';\nimport { createOceanInitialSpectrum } from './ocean-fft.js';\n\n// GPU spectral ocean: Hermitian evolution, a radix-2 Stockham inverse FFT and\n// derived slope/foam/focus fields, per cascade, entirely in render targets.\n// The pass structure (evolve → log2(N) horizontal + vertical butterflies →\n// pack → derive) follows the MIT-licensed iamtechartist/ocean-simulation; the\n// spectrum is NOCLIP's normalized JONSWAP (createOceanInitialSpectrum).\n// See docs/OCEAN_MATH.md.\n\nconst TAU = Math.PI * 2;\n// Dispersion is quantized to a 400 s repeat so time can be reduced in double\n// precision on the CPU; float32 phase at large uptimes would otherwise jitter.\nexport const OCEAN_REPEAT_SECONDS = 400;\n// Non-overlapping wavelength bands. Tile lengths are mutually incommensurate\n// so the repeats of the three periodic tiles do not align visibly.\nexport const OCEAN_CASCADES = Object.freeze([\n    Object.freeze({ length: 1792, minWavelength: 30, maxWavelength: Infinity, seed: 947 }),\n    Object.freeze({ length: 211, minWavelength: 3.5, maxWavelength: 30, seed: 1597 }),\n    Object.freeze({ length: 27.3, minWavelength: 0, maxWavelength: 3.5, seed: 2711 }),\n]);\nexport const OCEAN_CHOP = 0.8;\n\n/** Cox–Munk (1954) total mean square slope of the wind-roughened sea. */\nexport function coxMunkSlopeVariance(windSpeed) {\n    return 0.003 + 0.00512 * Math.max(0, windSpeed);\n}\n\n/** Fully developed (Pierson–Moskowitz) peak wavelength, metres: 2πU²/(0.877² g). */\nexport function oceanPeakWavelength(windSpeed) {\n    const u = Math.max(0, windSpeed);\n    return THREE.MathUtils.clamp(TAU * u * u / (0.877 * 0.877 * 9.81), 6, 450);\n}\n\nconst PASS_VERTEX = 'void main() { gl_Position = vec4(position.xy, 0.0, 1.0); }';\nconst COMPLEX = 'vec2 cmul(vec2 a, vec2 b) { return vec2(a.x * b.x - a.y * b.y, a.x * b.y + a.y * b.x); }';\n\nconst EVOLVE = `\nuniform sampler2D uInitial;\nuniform float uTime, uLength, uSize, uScale, uChop, uQuantum;\n${COMPLEX}\nvoid main() {\n  ivec2 cell = ivec2(gl_FragCoord.xy);\n  vec2 k = vec2(cell);\n  if (k.x >= uSize * 0.5) k.x -= uSize;\n  if (k.y >= uSize * 0.5) k.y -= uSize;\n  k *= 6.283185307 / uLength;\n  float magnitude = length(k);\n  if (magnitude < 1e-6) { gl_FragColor = vec4(0.0); return; }\n  // Deep-water gravity–capillary dispersion, quantized to the repeat period.\n  float omega = floor(sqrt(9.81 * magnitude + 0.000074 * magnitude * magnitude * magnitude) / uQuantum) * uQuantum;\n  float phase = mod(omega * uTime, 6.283185307);\n  vec2 rotation = vec2(cos(phase), sin(phase));\n  vec4 h0 = texelFetch(uInitial, cell, 0);\n  vec2 h = (cmul(h0.xy, vec2(rotation.x, -rotation.y)) + cmul(vec2(h0.z, -h0.w), rotation)) * uScale;\n  // Horizontal displacement i(k/|k|)H, both real fields packed as Dx + iDz.\n  vec2 d = k / magnitude * uChop;\n  vec2 ih = vec2(-h.y, h.x);\n  gl_FragColor = vec4(h, ih * d.x - h * d.y);\n}`;\n\nconst BUTTERFLY = `\nuniform sampler2D uInput;\nuniform float uStep, uSize, uHorizontal;\n${COMPLEX}\nvoid main() {\n  vec2 cell = gl_FragCoord.xy - 0.5;\n  float index = uHorizontal > 0.5 ? cell.x : cell.y;\n  float evenIndex = floor(index / uStep) * uStep * 0.5 + mod(index, uStep * 0.5);\n  vec2 evenCell = uHorizontal > 0.5 ? vec2(evenIndex, cell.y) : vec2(cell.x, evenIndex);\n  vec2 oddCell = evenCell + (uHorizontal > 0.5 ? vec2(uSize * 0.5, 0.0) : vec2(0.0, uSize * 0.5));\n  vec4 evenValue = texelFetch(uInput, ivec2(evenCell + 0.5), 0);\n  vec4 oddValue = texelFetch(uInput, ivec2(oddCell + 0.5), 0);\n  float angle = 6.283185307 * index / uStep;\n  vec2 twiddle = vec2(cos(angle), sin(angle));\n  gl_FragColor = evenValue + vec4(cmul(twiddle, oddValue.xy), cmul(twiddle, oddValue.zw));\n}`;\n\n// (Dx, h, Dz): x east, y up, z north in the planet-fixed wave frame.\nconst PACK = `\nuniform sampler2D uInput;\nvoid main() {\n  vec4 field = texelFetch(uInput, ivec2(gl_FragCoord.xy), 0);\n  gl_FragColor = vec4(field.z, field.x, field.w, 1.0);\n}`;\n\n// Slopes of the displaced (choppy) surface, Jacobian whitecap foam with\n// persistence, and the squared slope for filtered-variance roughness.\nconst DERIVE = `\nuniform sampler2D uDisplacement, uPrevious;\nuniform float uSize, uLength, uDecay;\nivec2 wrapCell(ivec2 c) { int n = int(uSize); return ivec2((c.x + n) % n, (c.y + n) % n); }\nvoid main() {\n  ivec2 cell = ivec2(gl_FragCoord.xy);\n  float scale = uSize / (2.0 * uLength);\n  vec3 dx = (texelFetch(uDisplacement, wrapCell(cell + ivec2(1, 0)), 0).xyz - texelFetch(uDisplacement, wrapCell(cell - ivec2(1, 0)), 0).xyz) * scale;\n  vec3 dz = (texelFetch(uDisplacement, wrapCell(cell + ivec2(0, 1)), 0).xyz - texelFetch(uDisplacement, wrapCell(cell - ivec2(0, 1)), 0).xyz) * scale;\n  vec3 n = cross(vec3(dz.x, dz.y, 1.0 + dz.z), vec3(1.0 + dx.x, dx.y, dx.z));\n  n *= inversesqrt(max(dot(n, n), 1e-12));\n  vec2 slope = clamp(-n.xz / max(0.25, n.y), vec2(-4.0), vec2(4.0));\n  float jacobian = (1.0 + dx.x) * (1.0 + dz.z) - dx.z * dz.x;\n  float breaking = smoothstep(0.22, 0.48, 1.0 - jacobian);\n  float foam = max(texelFetch(uPrevious, cell, 0).b * uDecay, breaking);\n  gl_FragColor = vec4(slope, foam, dot(slope, slope));\n}`;\n\n// Displacement RGB plus slope divergence A. Reuse the already scheduled\n// focus draw/target so vertex waves and fragment caustics share one sampler,\n// with identical resolution, half-float pixels and generated mip chains.\nconst FOCUS = `\nuniform sampler2D uSlope, uDisplacement;\nuniform float uSize, uLength;\nivec2 wrapCell(ivec2 c) { int n = int(uSize); return ivec2((c.x + n) % n, (c.y + n) % n); }\nvoid main() {\n  ivec2 cell = ivec2(gl_FragCoord.xy);\n  float scale = uSize / (2.0 * uLength);\n  float sx = texelFetch(uSlope, wrapCell(cell + ivec2(1, 0)), 0).x - texelFetch(uSlope, wrapCell(cell - ivec2(1, 0)), 0).x;\n  float sz = texelFetch(uSlope, wrapCell(cell + ivec2(0, 1)), 0).y - texelFetch(uSlope, wrapCell(cell - ivec2(0, 1)), 0).y;\n  gl_FragColor = vec4(texelFetch(uDisplacement, cell, 0).xyz, (sx + sz) * scale);\n}`;\n\nexport function canRunOceanCascades(renderer) {\n    const extensions = renderer?.extensions;\n    return !!(renderer?.capabilities?.isWebGL2 !== false && extensions\n        && (extensions.has('EXT_color_buffer_float') || extensions.has('EXT_color_buffer_half_float')));\n}\n\nfunction fieldTarget(size, mipmaps) {\n    const target = new THREE.WebGLRenderTarget(size, size, { type: THREE.HalfFloatType, format: THREE.RGBAFormat,\n        depthBuffer: false, stencilBuffer: false, generateMipmaps: mipmaps,\n        minFilter: mipmaps ? THREE.LinearMipmapLinearFilter : THREE.NearestFilter,\n        magFilter: mipmaps ? THREE.LinearFilter : THREE.NearestFilter,\n        wrapS: THREE.RepeatWrapping, wrapT: THREE.RepeatWrapping });\n    target.texture.name = 'Ocean.SpectralField';\n    return target;\n}\n\nclass OceanCascade {\n    constructor(owner, config, size) {\n        Object.assign(this, { owner, config, size, length: config.length, foamIndex: 0 });\n        this.ping = [fieldTarget(size, false), fieldTarget(size, false)];\n        this.displacement = fieldTarget(size, true);\n        this.slopes = [fieldTarget(size, true), fieldTarget(size, true)];\n        this.focus = fieldTarget(size, true);\n        const pass = (shader, uniforms) => owner.material(shader, uniforms);\n        this.evolve = pass(EVOLVE, { uInitial: { value: null }, uTime: { value: 0 }, uLength: { value: this.length },\n            uSize: { value: size }, uScale: { value: 1 }, uChop: { value: OCEAN_CHOP }, uQuantum: { value: TAU / OCEAN_REPEAT_SECONDS } });\n        this.butterfly = pass(BUTTERFLY, { uInput: { value: null }, uStep: { value: 2 }, uSize: { value: size }, uHorizontal: { value: 1 } });\n        this.pack = pass(PACK, { uInput: { value: null } });\n        this.derive = pass(DERIVE, { uDisplacement: { value: this.displacement.texture }, uPrevious: { value: null },\n            uSize: { value: size }, uLength: { value: this.length }, uDecay: { value: 1 } });\n        this.focusPass = pass(FOCUS, { uSlope: { value: null }, uDisplacement: { value: this.displacement.texture },\n            uSize: { value: size }, uLength: { value: this.length } });\n    }\n    setSpectrum(windSpeed, windDirection) {\n        const { config, size } = this;\n        const spectrum = createOceanInitialSpectrum({ size, length: config.length, seed: config.seed,\n            minK: Number.isFinite(config.maxWavelength) ? TAU / config.maxWavelength : 0,\n            maxK: config.minWavelength > 0 ? TAU / config.minWavelength : Infinity,\n            windSpeed, windDirection, peakWavelength: oceanPeakWavelength(windSpeed) });\n        const data = new Float32Array(size * size * 4);\n        for (let y = 0; y < size; y++) for (let x = 0; x < size; x++) {\n            const i = y * size + x, mirror = ((size - y) % size) * size + (size - x) % size;\n            data[i * 4] = spectrum.initialReal[i]; data[i * 4 + 1] = spectrum.initialImaginary[i];\n            data[i * 4 + 2] = spectrum.initialReal[mirror]; data[i * 4 + 3] = spectrum.initialImaginary[mirror];\n        }\n        this.initial?.dispose();\n        this.initial = new THREE.DataTexture(data, size, size, THREE.RGBAFormat, THREE.FloatType);\n        this.initial.needsUpdate = true;\n        this.evolve.uniforms.uInitial.value = this.initial;\n        this.spectrum = spectrum;\n        // Resolved slope variance Σ k²|H(k)|², for the unresolved remainder.\n        let slopeVariance = 0;\n        for (let i = 0; i < size * size; i++) {\n            const k2 = spectrum.kx[i] ** 2 + spectrum.ky[i] ** 2;\n            slopeVariance += k2 * (data[i * 4] ** 2 + data[i * 4 + 1] ** 2 + data[i * 4 + 2] ** 2 + data[i * 4 + 3] ** 2);\n        }\n        this.slopeVariance = slopeVariance;\n    }\n    update(time, delta, scale) {\n        const run = this.owner.run.bind(this.owner);\n        this.evolve.uniforms.uTime.value = time;\n        this.evolve.uniforms.uScale.value = scale;\n        run(this.evolve, this.ping[0]);\n        let index = 0;\n        for (let axis = 0; axis < 2; axis++) {\n            this.butterfly.uniforms.uHorizontal.value = axis === 0 ? 1 : 0;\n            for (let step = 2; step <= this.size; step *= 2) {\n                this.butterfly.uniforms.uInput.value = this.ping[index].texture;\n                this.butterfly.uniforms.uStep.value = step;\n                index = 1 - index;\n                run(this.butterfly, this.ping[index]);\n            }\n        }\n        this.pack.uniforms.uInput.value = this.ping[index].texture;\n        run(this.pack, this.displacement);\n        this.derive.uniforms.uPrevious.value = this.slopes[this.foamIndex].texture;\n        // Whitecap persistence: e-folding time 1.6 s, as in the reference.\n        this.derive.uniforms.uDecay.value = Math.exp(-Math.min(1, Math.max(0, delta)) / 1.6);\n        this.foamIndex = 1 - this.foamIndex;\n        run(this.derive, this.slopes[this.foamIndex]);\n        this.focusPass.uniforms.uSlope.value = this.slopes[this.foamIndex].texture;\n        run(this.focusPass, this.focus);\n    }\n    get slope() { return this.slopes[this.foamIndex]; }\n    dispose() {\n        for (const target of [...this.ping, this.displacement, ...this.slopes, this.focus]) target.dispose();\n        for (const material of [this.evolve, this.butterfly, this.pack, this.derive, this.focusPass]) material.dispose();\n        this.initial?.dispose();\n    }\n}\n\n/** Three spectral cascades evaluated on the GPU once per rendered frame. */\nexport class OceanGPUCascades {\n    constructor(renderer, { sizes = [256, 256, 128], windSpeed = 8, windDirection = 0.5 } = {}) {\n        this.renderer = renderer;\n        this.scene = new THREE.Scene();\n        this.camera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0, 1);\n        this.quad = new THREE.Mesh(new THREE.PlaneGeometry(2, 2));\n        this.quad.frustumCulled = false;\n        this.scene.add(this.quad);\n        this.materials = [];\n        this.cascades = OCEAN_CASCADES.map((config, i) => new OceanCascade(this, config, sizes[i] ?? 128));\n        this.setSeaState({ windSpeed, windDirection });\n        this.ready = false;\n        // Link the five pass programs off the render loop: running them cold\n        // linked each synchronously (measured a 3.6 s frame descending from\n        // orbit). Until linked the ocean keeps its analytic wave field.\n        this.programsReady = false;\n        this._warm = this._prewarmPrograms();\n    }\n    async _prewarmPrograms() {\n        const renderer = this.renderer;\n        if (typeof renderer?.compileAsync !== 'function') { this.programsReady = true; return; }\n        try {\n            await Promise.all(this.materials.map((material) => {\n                const probe = new THREE.Mesh(this.quad.geometry, material);\n                probe.frustumCulled = false;\n                return renderer.compileAsync(probe, this.camera, this.scene);\n            }));\n        } catch { /* compile on first run instead */ }\n        this.programsReady = true;\n    }\n    material(fragmentShader, uniforms) {\n        const material = new THREE.ShaderMaterial({ uniforms, vertexShader: PASS_VERTEX, fragmentShader,\n            depthTest: false, depthWrite: false, toneMapped: false });\n        this.materials.push(material);\n        return material;\n    }\n    run(material, target) {\n        this.quad.material = material;\n        this.renderer.setRenderTarget(target);\n        this.renderer.render(this.scene, this.camera);\n    }\n    setSeaState({ windSpeed = this.windSpeed ?? 8, windDirection = this.windDirection ?? 0.5 } = {}) {\n        if (windSpeed === this.windSpeed && windDirection === this.windDirection) return false;\n        this.windSpeed = windSpeed; this.windDirection = windDirection;\n        for (const cascade of this.cascades) cascade.setSpectrum(windSpeed, windDirection);\n        this.slopeVariance = this.cascades.reduce((sum, cascade) => sum + cascade.slopeVariance, 0);\n        return true;\n    }\n    /** seconds: physical simulation time; reduced modulo the repeat in double precision. */\n    update(seconds, scale = 1) {\n        if (!Number.isFinite(seconds) || !this.programsReady) return;\n        const delta = Number.isFinite(this.lastSeconds) ? seconds - this.lastSeconds : 0;\n        if (this.ready && delta === 0 && scale === this.lastScale) return;\n        this.lastSeconds = seconds; this.lastScale = scale;\n        const time = ((seconds % OCEAN_REPEAT_SECONDS) + OCEAN_REPEAT_SECONDS) % OCEAN_REPEAT_SECONDS;\n        const renderer = this.renderer;\n        const savedTarget = renderer.getRenderTarget(), xr = renderer.xr?.enabled;\n        // An XR session would replace the simulation camera with the headset rig.\n        if (renderer.xr) renderer.xr.enabled = false;\n        try {\n            for (const cascade of this.cascades) cascade.update(time, delta, scale);\n            this.ready = true;\n        } finally {\n            if (renderer.xr) renderer.xr.enabled = xr;\n            renderer.setRenderTarget(savedTarget);\n        }\n    }\n    dispose() {\n        for (const cascade of this.cascades) cascade.dispose();\n        for (const material of this.materials) material.dispose();\n        this.quad.geometry.dispose();\n        this.ready = false;\n    }\n}\n","// Independently authored dielectric water optics. Metres, linear HDR radiance,\n// and the renderer's logarithmic depth convention; see docs/OCEAN_MATH.md.\nexport const OCEAN_OPTICS_GLSL = `\nuniform sampler2D ncaOceanSceneColor, ncaOceanSceneDepth;\nuniform float ncaOceanOpticsReady, ncaOceanCameraFar;\nuniform vec2 ncaOceanViewport;\nuniform mat4 ncaOceanProjection;\nuniform float ncaOceanReflectionReady;\nuniform vec4 ncaOceanSceneRegion,ncaOceanReflectionRegion;\nuniform mat4 ncaOceanReflectionFromView,ncaOceanReflectionViewFromView;\nuniform vec3 ncaOceanSunView, ncaOceanUpView;\nuniform float ncaOceanSubmerged;\nuniform vec3 ncaOceanWaterC, ncaOceanWaterKd, ncaOceanWaterBody, ncaOceanWaterDirectBody, ncaOceanWaterReflectance, ncaOceanSunRadiance;\nvec3 oceanWaterBodyRadiance(float sunTransmission, vec3 sunRadiance, vec3 skyRadiance) {\n  #ifdef NCA_OCEAN_CLOUD_READY\n  return ncaOceanWaterDirectBody * sunRadiance / max(ncaOceanSunRadiance, vec3(1e-5)) * sunTransmission\n    + ncaOceanWaterReflectance * skyRadiance * 3.14159265 * 0.94;\n  #endif\n  return max(vec3(0.0), ncaOceanWaterBody - ncaOceanWaterDirectBody * (1.0 - sunTransmission));\n}\nfloat oceanSceneZ(vec2 uv) {\n  // The optics snapshot is half resolution. Nearest depth steps alternated\n  // between bed and foreground on adjacent full-resolution rows at altitude.\n  // Reciprocal view Z is affine across a projected plane; interpolate that,\n  // not log depth or metre Z. Keep genuine depth discontinuities sharp.\n  vec2 size=vec2(textureSize(ncaOceanSceneDepth,0));\n  vec2 pixel=clamp(uv*size-.5,vec2(0.0),size-1.0);\n  vec2 base=floor(pixel),fraction=fract(pixel);\n  vec4 z;\n  for(int y=0;y<2;y++)for(int x=0;x<2;x++){\n    float d=texture2D(ncaOceanSceneDepth,(min(base+vec2(x,y),size-1.0)+.5)/size).r;\n    z[y*2+x]=max(.001,exp2(d*log2(ncaOceanCameraFar+1.0))-1.0);\n  }\n  float minimum=min(min(z.x,z.y),min(z.z,z.w));\n  float maximum=max(max(z.x,z.y),max(z.z,z.w));\n  if(maximum-minimum>max(2.0,minimum*.1)){\n    return z[(fraction.y<.5?0:2)+(fraction.x<.5?0:1)];\n  }\n  vec2 inverseRows=mix(vec2(1.0/z.x,1.0/z.z),vec2(1.0/z.y,1.0/z.w),fraction.x);\n  return 1.0/mix(inverseRows.x,inverseRows.y,fraction.y);\n}\nvec2 oceanProject(vec3 p) {\n  vec4 clip = ncaOceanProjection * vec4(p, 1.0);\n  return clip.xy / max(clip.w, 0.0001) * 0.5 + 0.5;\n}\nvec2 oceanRegionUv(vec2 uv,vec4 region) {\n  vec2 halfTexel=0.5/vec2(textureSize(ncaOceanSceneColor,0));\n  return clamp(uv*region.xy+region.zw,region.zw+halfTexel,region.zw+region.xy-halfTexel);\n}\nvec4 oceanSceneColor(vec2 uv) {\n  return texture2D(ncaOceanSceneColor,oceanRegionUv(uv,ncaOceanSceneRegion));\n}\nvec4 oceanPlanarReflection(vec3 origin,vec3 direction) {\n  if(ncaOceanReflectionReady<0.5)return vec4(0.0);\n  vec3 reflectedOrigin=(ncaOceanReflectionViewFromView*vec4(origin,1.0)).xyz;\n  vec3 reflectedDirection=(ncaOceanReflectionViewFromView*vec4(direction,0.0)).xyz;\n  vec4 clip=ncaOceanReflectionFromView*vec4(origin,1.0),sampled=vec4(0.0);\n  // Resolve wave-normal parallax against reciprocal view-depth. Sky has\n  // no finite intersection: project its direction rather than a fake plane.\n  bool valid=false;\n  for(int refine=0;refine<3;refine++){\n    if(clip.w<=0.0)break;\n    vec2 uv=clip.xy/clip.w*0.5+0.5;\n    if(any(lessThan(uv,vec2(0.0)))||any(greaterThan(uv,vec2(1.0))))break;\n    sampled=texture2D(ncaOceanSceneColor,oceanRegionUv(uv,ncaOceanReflectionRegion));valid=true;\n    if(sampled.a<=1e-7){\n      vec4 skyClip=ncaOceanReflectionFromView*vec4(direction,0.0);\n      if(skyClip.w>0.0){\n        vec2 skyUv=skyClip.xy/skyClip.w*.5+.5;\n        if(all(greaterThanEqual(skyUv,vec2(0.0)))&&all(lessThanEqual(skyUv,vec2(1.0))))\n          sampled=texture2D(ncaOceanSceneColor,oceanRegionUv(skyUv,ncaOceanReflectionRegion));\n      }\n      break;\n    }\n    float depth=min(1e7,1000.0/sampled.a);\n    if(abs(reflectedDirection.z)<1e-6)break;\n    float distanceAlong=(-depth-reflectedOrigin.z)/reflectedDirection.z;\n    if(distanceAlong<=0.0)break;\n    clip=ncaOceanReflectionFromView*vec4(origin+direction*distanceAlong,1.0);\n  }\n  // Keep the last supported sample when refinement reaches the capture\n  // boundary; do not alternate valid geometry with a bright diffuse fallback.\n  return valid?vec4(sampled.rgb,1.0):vec4(0.0);\n}\n\nfloat oceanScreenFade(vec2 uv) {\n  vec2 edge = min(uv, 1.0 - uv);\n  return smoothstep(0.0, 0.08, min(edge.x, edge.y));\n}\n// Trace in view space, then bisect the first front-to-back depth crossing.\n// This bounded screen-space lane never reads its own water draw target.\nvec4 oceanReflection(vec3 origin, vec3 direction) {\n#ifdef OCEAN_BASIC\n  return vec4(0.0);\n#endif\n  float previous = 0.08;\n  float previousGap = -0.2;\n  for (int stepIndex = 0; stepIndex < 28; stepIndex++) {\n    float distanceAlong = 0.12 * pow(1.32, float(stepIndex));\n    vec3 point = origin + direction * distanceAlong;\n    if (point.z > -0.1) break;\n    vec2 uv = oceanProject(point);\n    if (any(lessThanEqual(uv, vec2(0.0))) || any(greaterThanEqual(uv, vec2(1.0)))) break;\n    float sceneZ = oceanSceneZ(uv);\n    float gap = -point.z - sceneZ;\n    float thickness = 0.2 + distanceAlong * 0.035;\n    if (gap > 0.0 && previousGap <= 0.0) {\n      float low = previous, high = distanceAlong;\n      for (int refine = 0; refine < 5; refine++) {\n        float middle = (low + high) * 0.5;\n        vec3 testPoint = origin + direction * middle;\n        vec2 testUv = oceanProject(testPoint);\n        if (-testPoint.z > oceanSceneZ(testUv)) high = middle; else low = middle;\n      }\n      uv = oceanProject(origin + direction * ((low + high) * 0.5));\n      float refinedGap = -(origin + direction * high).z - oceanSceneZ(uv);\n      if (refinedGap < thickness) {\n        return vec4(oceanSceneColor(uv).rgb, oceanScreenFade(uv));\n      }\n    }\n    previous = distanceAlong; previousGap = gap;\n  }\n  return vec4(0.0);\n}\nvec2 oceanHash(vec2 cell) {\n  vec2 seed = vec2(dot(cell,vec2(137.3,279.1)),dot(cell,vec2(313.7,127.9)));\n  return fract(sin(seed) * 41753.47);\n}\nvec2 oceanCells(vec2 p) {\n  vec2 cell = floor(p), offset = fract(p);\n  vec2 nearest = vec2(8.0);\n  for (int y=-1;y<=1;y++) for (int x=-1;x<=1;x++) {\n    vec2 neighbor = vec2(float(x),float(y));\n    vec2 center = neighbor + oceanHash(cell + neighbor) - offset;\n    float distanceSquared = dot(center,center);\n    if (distanceSquared < nearest.x) nearest = vec2(distanceSquared,nearest.x);\n    else nearest.y = min(nearest.y,distanceSquared);\n  }\n  return sqrt(nearest);\n}\nfloat oceanFoamPattern(vec2 p) {\n  vec2 q = p * 3.5 + 0.1 * ncaOceanTime;\n  q += 0.3 * sin(q.yx * 0.7);\n  vec2 cells = oceanCells(q);\n  float bubbles = 1.0 - smoothstep(0.025,0.12,cells.y-cells.x);\n  float patches = smoothstep(0.1,0.75,oceanHash(floor(p*0.7)).x);\n  return mix(0.35,bubbles,0.8) * patches;\n}\n// Refractive focusing by the actual wave surface: a ray bundle crossing the\n// surface converges with J = 1 + s(1 - 1/n)∇²h at path length s below it.\nfloat oceanFocusIntensity(vec2 p, float pathLength) {\n  if (ncaOceanGPUReady < 0.5 || pathLength <= 0.0) return 1.0;\n  float blur = 0.05 + pathLength * 0.02;\n  float jacobian = 1.0 + pathLength * 0.24981 * oceanFocusDivergence(p, blur);\n  return clamp(1.0 / max(jacobian, 0.2), 0.0, 5.0);\n}\n// Sky seen through Snell's window: the captured sky where the exit direction\n// is on screen, otherwise a sun-driven hemisphere, plus the refracted sun disc.\nvec3 oceanSkyRadiance(vec3 origin, vec3 direction, float daylight, float lobe, float sunTransmission,\n    vec3 sunRadiance, vec3 skyRadiance) {\n  float height = clamp(dot(direction, ncaOceanUpView), 0.0, 1.0);\n  vec3 sky = mix(vec3(0.42, 0.58, 0.69), vec3(0.075, 0.24, 0.46), height) * (0.015 + daylight * 0.985);\n  #ifdef NCA_OCEAN_CLOUD_READY\n  sky = skyRadiance;\n  #endif\n  vec2 uv = oceanProject(origin + direction * 1.0e5);\n  if (all(greaterThan(uv, vec2(0.0))) && all(lessThan(uv, vec2(1.0)))\n      && oceanSceneZ(uv) > 5.0e4) {\n    // Fade the captured sky out well before the screen edge so the window\n    // shows no seam where it meets the analytic hemisphere.\n    vec2 edge = min(uv, 1.0 - uv);\n    sky = mix(sky, oceanSceneColor(uv).rgb, smoothstep(0.0, 0.35, min(edge.x, edge.y)));\n  }\n  float sunCosine = max(dot(direction, ncaOceanSunView), 0.0);\n  // The sun's irradiance spread over the angular lobe of unresolved\n  // capillary slopes (energy-conserving Gaussian, ∫L dΩ = E): resolved slopes\n  // then break it into moving glints.\n  float angle = acos(clamp(dot(direction, ncaOceanSunView), -1.0, 1.0));\n  float width = max(0.0047, lobe);\n  return sky + sunRadiance * sunTransmission * exp(-angle * angle / (width * width)) / (3.14159265 * width * width);\n}\n// Unpolarized Fresnel, including the critical angle from inside water.\nfloat oceanFresnel(float cosine, bool inside) {\n  float eta = inside ? 1.333 : (1.0 / 1.333);\n  float sinSquared = eta * eta * (1.0 - cosine * cosine);\n  if (sinSquared >= 1.0) return 1.0;\n  float transmittedCosine = sqrt(max(0.0, 1.0 - sinSquared));\n  float s = (eta * cosine - transmittedCosine) / (eta * cosine + transmittedCosine);\n  float p = (cosine - eta * transmittedCosine) / (cosine + eta * transmittedCosine);\n  return clamp(0.5 * (s*s + p*p), 0.0, 1.0);\n}\n`;\n\nexport const OCEAN_OPTICS_FRAGMENT = `\nif (ncaOceanOpticsReady > 0.5) {\n  vec3 surfaceView = -vViewPosition;\n  vec3 incident = normalize(surfaceView);\n  vec3 waterNormal = faceforward(normal, incident, normal);\n  bool inside = ncaOceanSubmerged > 0.5;\n  float fresnel = oceanFresnel(clamp(dot(-incident, waterNormal), 0.0, 1.0), inside);\n  float daylight = smoothstep(-0.08, 0.15, dot(ncaOceanSunView, ncaOceanUpView));\n  vec2 screenUv = gl_FragCoord.xy / ncaOceanViewport;\n  if (inside) {\n    // From below: rays inside the 48.6° critical cone leave the water and see\n    // the sky/world above (radiance gains n² entering the denser medium);\n    // beyond it total internal reflection mirrors the water body below.\n    vec3 exitRay = refract(incident, waterNormal, 1.333);\n    vec3 window = vec3(0.0);\n    if (dot(exitRay, exitRay) > 0.0) {\n      vec4 above = oceanReflection(surfaceView + exitRay * 0.05, exitRay);\n      // Refraction scales slope deviations by about (n−1)/1 on exit.\n      window = mix(oceanSkyRadiance(surfaceView, exitRay, daylight, oceanAlpha * 0.333, ncaOceanSunTransmission,\n        ncaOceanDirectSunRadiance, ncaOceanDiffuseSkyRadiance), above.rgb, above.a) * 1.777;\n    }\n    // The mirrored water column is dominated by its own scattered light; a\n    // screen-space trace of distant bed geometry only adds unstable speckle.\n    // Radiance of the water column rises from nadir toward the horizontal.\n    float mirrorDown = clamp(-dot(reflect(incident, waterNormal), ncaOceanUpView), 0.0, 1.0);\n    vec3 mirrored = oceanWaterBodyRadiance(ncaOceanSunTransmission, ncaOceanDirectSunRadiance,\n      ncaOceanDiffuseSkyRadiance) * mix(2.2, 1.0, mirrorDown);\n    vec3 fromBelow = mix(window, mirrored, fresnel);\n    // Foam and bubbles are bright diffusers lit through the surface.\n    float bubbles = clamp(foam, 0.0, 1.0) * oceanFoamPattern(waveP);\n    vec3 bubbleLight = ncaOceanDirectSunRadiance * ncaOceanSunTransmission * 0.08 * (0.03 + daylight * 0.97);\n    #ifdef NCA_OCEAN_CLOUD_READY\n    bubbleLight += ncaOceanDiffuseSkyRadiance * 0.08;\n    #endif\n    outgoingLight = mix(fromBelow, bubbleLight, bubbles * 0.7);\n  } else {\n  float rawDepth = max(0.0, oceanSceneZ(screenUv) + surfaceView.z);\n  // Snell's law projects a short refracted ray, with depth rejection to keep\n  // foreground objects from bleeding into the water at silhouettes.\n  vec3 transmissionRay = refract(incident, waterNormal, 1.0/1.333);\n  float rayLength = min(rawDepth / max(0.15, -transmissionRay.z), 12.0);\n  vec2 refractUv = oceanProject(surfaceView + transmissionRay * rayLength);\n  refractUv = clamp(refractUv, vec2(0.001), vec2(0.999));\n  if (oceanSceneZ(refractUv) < -surfaceView.z + 0.05) refractUv = screenUv;\n  float thickness = min(180.0, max(0.0, oceanSceneZ(refractUv) + surfaceView.z)\n    / max(0.2, -transmissionRay.z));\n  // Path to the bed attenuates by beam attenuation c; the light reaching it\n  // has already crossed that depth, attenuated by Kd, and is focused by waves.\n  float bedDepth = thickness * clamp(-dot(transmissionRay, ncaOceanUpView), 0.0, 1.0);\n  vec3 transmission = exp(-ncaOceanWaterC * thickness);\n  vec3 below = oceanSceneColor(refractUv).rgb * exp(-ncaOceanWaterKd * bedDepth);\n  below *= mix(1.0, oceanFocusIntensity(waveP, bedDepth), daylight * 0.8);\n  vec3 scatter = oceanWaterBodyRadiance(ncaOceanSunTransmission, ncaOceanDirectSunRadiance, ncaOceanDiffuseSkyRadiance);\n  vec3 transmitted = below * transmission + scatter * (1.0 - transmission);\n  vec3 reflectionRay = reflect(incident, waterNormal);\n  vec4 planarReflection=oceanPlanarReflection(surfaceView,reflectionRay);\n  vec4 reflected = planarReflection.a>0.0?planarReflection:oceanReflection(surfaceView + waterNormal * 0.05, reflectionRay);\n  // Offscreen reflection falls back to the physical material/environment,\n  // plus a sun-driven sky hemisphere; no stale planar-camera texture.\n  float skyHeight = clamp(dot(reflectionRay, ncaOceanUpView), 0.0, 1.0);\n  vec3 skyReflection = mix(vec3(0.42,0.58,0.69), vec3(0.075,0.24,0.46), skyHeight)\n    * (0.015 + daylight * 0.985);\n  #ifdef NCA_OCEAN_CLOUD_READY\n  skyReflection = ncaOceanDiffuseSkyRadiance;\n  #endif\n  vec3 environmentReflection = max(outgoingLight, skyReflection);\n  // During cold/unsupported capture, preserve the lit water column instead\n  // of pretending hemispherical diffuse irradiance is a directional mirror.\n  // Real SSR hits remain eligible. No primary-FOV cloud image is fabricated.\n  if(ncaOceanReflectionReady<.5&&reflected.a<=0.0)environmentReflection=transmitted;\n  vec3 reflectedColor = mix(environmentReflection, reflected.rgb, reflected.a);\n  // Thin backlit crests transmit sunlight through the wave (green-blue glow).\n  float crestLight = pow(max(0.0, dot(-incident, ncaOceanSunView)), 4.0)\n    * smoothstep(0.1, 0.6, oceanCrestSteepness) * max(0.0, field.x) * 0.12 * daylight * ncaOceanSunTransmission;\n  float crestSunScale = clamp(dot(ncaOceanDirectSunRadiance, vec3(0.2126, 0.7152, 0.0722))\n    / max(dot(ncaOceanSunRadiance, vec3(0.2126, 0.7152, 0.0722)), 1e-5), 0.0, 4.0);\n  crestLight *= crestSunScale;\n  transmitted += vec3(0.08,0.42,0.32) * crestLight;\n  float shoreline = (1.0 - smoothstep(0.12, 1.5, rawDepth))\n    * smoothstep(0.015, 0.12, rawDepth);\n  float shorePulse = 0.5 + 0.5 * sin(rawDepth * 8.0 - ncaOceanTime * 4.0 + field.x * 3.0);\n  float opticalFoam = clamp(foam + shoreline * shorePulse * 0.85, 0.0, 1.0)\n    * oceanFoamPattern(waveP);\n  vec3 foamLight = vec3(0.72,0.79,0.79) * (0.03 + daylight * 0.97);\n  #ifdef NCA_OCEAN_CLOUD_READY\n  foamLight = vec3(0.72,0.79,0.79) * (ncaOceanDirectSunRadiance * ncaOceanSunTransmission\n    * max(dot(ncaOceanSunView, ncaOceanUpView), 0.0) * 0.31830988618 + ncaOceanDiffuseSkyRadiance);\n  #endif\n  vec3 planarDirect=planarReflection.a>0.0?reflectedLight.directSpecular:vec3(0.0);\n  outgoingLight = mix(mix(transmitted, reflectedColor, fresnel)+planarDirect, foamLight, opticalFoam);\n  }\n}\n`;\n","// Capillary and short gravity–capillary slopes below the finest spectral\n// cascade (λ < ~0.4 m). Three octaves of analytic-derivative gradient noise\n// carry the share of the unresolved Cox–Munk slope variance that the pixel\n// footprint can resolve; the remainder stays in the specular lobe.\n// Returns (slopeEast, slopeNorth, resolvedVariance, value).\nexport const OCEAN_CAPILLARY_GLSL = `\nvec2 oceanCapGradient(vec2 cell) {\n  float h = fract(sin(dot(cell, vec2(127.1, 311.7))) * 43758.5453) * 6.2831853;\n  return vec2(cos(h), sin(h));\n}\nvec3 oceanCapNoise(vec2 p) {\n  vec2 i = floor(p), f = fract(p);\n  vec2 u = f * f * f * (f * (f * 6.0 - 15.0) + 10.0);\n  vec2 du = 30.0 * f * f * (f * (f - 2.0) + 1.0);\n  vec2 ga = oceanCapGradient(i), gb = oceanCapGradient(i + vec2(1.0, 0.0));\n  vec2 gc = oceanCapGradient(i + vec2(0.0, 1.0)), gd = oceanCapGradient(i + vec2(1.0, 1.0));\n  float va = dot(ga, f), vb = dot(gb, f - vec2(1.0, 0.0));\n  float vc = dot(gc, f - vec2(0.0, 1.0)), vd = dot(gd, f - vec2(1.0, 1.0));\n  float k = va - vb - vc + vd;\n  return vec3(va + u.x * (vb - va) + u.y * (vc - va) + u.x * u.y * k,\n    ga + u.x * (gb - ga) + u.y * (gc - ga) + u.x * u.y * (ga - gb - gc + gd) + du * (u.yx * k + vec2(vb, vc) - va));\n}\nvec4 oceanCapillary(vec2 p, float footprint, float seconds, vec2 wind, float unresolvedVariance) {\n  vec2 direction = normalize(wind + vec2(1e-4, 0.0));\n  vec2 across = vec2(-direction.y, direction.x);\n  vec2 slope = vec2(0.0); float resolved = 0.0, value = 0.0;\n  // Gradient-noise derivative RMS is ~0.62 per axis at unit frequency.\n  float perOctave = sqrt(unresolvedVariance * 0.8 / 3.0 / 2.0) / 0.62;\n  for (int octave = 0; octave < 3; octave++) {\n    float wavelength = 0.4 / pow(2.6, float(octave));\n    float visible = 1.0 - smoothstep(wavelength / 6.0, wavelength / 2.0, footprint);\n    if (visible <= 0.0) continue;\n    // Capillary–gravity phase speed is ~0.23 m/s near its minimum.\n    float speed = 0.23 * (1.0 + float(octave) * 0.35);\n    vec2 q = vec2(dot(p, direction), dot(p, across)) / wavelength;\n    vec3 a = oceanCapNoise(q - vec2(seconds * speed / wavelength, 0.0) + float(octave) * 17.3);\n    vec3 b = oceanCapNoise(q * 1.37 + vec2(0.0, seconds * speed * 0.6 / wavelength) + float(octave) * 41.1);\n    vec2 d = (a.yz + b.yz * 0.7) * 0.82;\n    slope += (direction * d.x + across * d.y) * perOctave * visible;\n    resolved += unresolvedVariance * 0.8 / 3.0 * visible * visible;\n    value += (a.x + b.x) * visible;\n  }\n  return vec4(slope, resolved, value);\n}\n`;\n","import { OCEAN_WAVE_GLSL } from './ocean-wave-spectrum.js';\n\nexport const OCEAN_VERTEX_DISPLACEMENT_GLSL = `\n  vec2 waveXZ = vec2(dot(position, ncaOceanEast), dot(position, ncaOceanNorth));\n  // Geometry carries resolvable waves near the observer; beyond it the\n  // filtered fragment slopes alone describe the surface.\n  float waveLod = 1.0 - smoothstep(1500.0, 4000.0, length(waveXZ));\n  float spacing = aOceanSpacing * 1.3;\n  vec4 field = oceanField(waveXZ, spacing);\n  vec2 drift = oceanDrift(waveXZ, spacing) * waveLod;\n  vOceanHeight = field.x * waveLod;\n  transformed += (ncaOceanUp * vOceanHeight + ncaOceanEast * drift.x + ncaOceanNorth * drift.y);\n`;\n\nexport const OCEAN_DEPTH_VERTEX_GLSL = `\n#include <common>\n#include <logdepthbuf_pars_vertex>\ninvariant gl_Position;\n#ifdef USE_LOGARITHMIC_DEPTH_BUFFER\ninvariant vFragDepth;\n#endif\n${OCEAN_WAVE_GLSL}\nuniform vec3 ncaOceanUp,ncaOceanEast,ncaOceanNorth,ncaOceanCenter;\nattribute float aOceanSpacing;\nvarying vec3 vViewPosition,vOceanLocal;\nvoid main(){\n  vec3 transformed=position;\n  float vOceanHeight;\n  ${OCEAN_VERTEX_DISPLACEMENT_GLSL}\n  vOceanLocal=ncaOceanCenter+transformed;\n  vec4 mvPosition=modelViewMatrix*vec4(transformed,1.0);\n  vViewPosition=-mvPosition.xyz;\n  gl_Position=projectionMatrix*mvPosition;\n  #include <logdepthbuf_vertex>\n}`;\n\n","import * as THREE from 'three';\n\n// Suspended particulate (\"marine snow\") around a submerged camera: a fixed\n// pool of points wrapped in a 24 m cube that follows the observer, lit by the\n// in-water light field. Idea after wave-three-js (MIT); shader is our own.\nconst CUBE = 24;\n\nexport class OceanParticulate {\n    constructor({ parent, uniforms, count = 900 }) {\n        this.parent = parent;\n        const positions = new Float32Array(count * 3);\n        let seed = 7919;\n        const random = () => ((seed = (Math.imul(seed, 1664525) + 1013904223) >>> 0) + 0.5) / 4294967296;\n        for (let i = 0; i < positions.length; i++) positions[i] = random() * CUBE;\n        this.geometry = new THREE.BufferGeometry();\n        this.geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));\n        this.uniforms = {\n            uOffset: { value: new THREE.Vector3() }, uTime: { value: 0 }, uDepth: { value: 0 },\n            uWaterBody: uniforms.ncaOceanWaterBody, uWaterKd: uniforms.ncaOceanWaterKd,\n            uSunRadiance: uniforms.ncaOceanSunRadiance,\n        };\n        this.material = new THREE.ShaderMaterial({ uniforms: this.uniforms, transparent: true, depthWrite: false,\n            vertexShader: `\n#include <common>\n#include <logdepthbuf_pars_vertex>\nuniform vec3 uOffset; uniform float uTime;\nvarying float vFade;\nvoid main() {\n  // Wrap each particle into the cube centred on the camera, with slow sinking.\n  vec3 p = mod(position - uOffset + vec3(0.0, uTime * 0.02, 0.0), ${CUBE.toFixed(1)}) - ${(CUBE / 2).toFixed(1)};\n  vec4 mvPosition = modelViewMatrix * vec4(p, 1.0);\n  float distance = -mvPosition.z;\n  vFade = (1.0 - smoothstep(${(CUBE * 0.3).toFixed(1)}, ${(CUBE * 0.5).toFixed(1)}, length(p))) * smoothstep(0.2, 0.8, distance);\n  gl_PointSize = clamp(18.0 / max(distance, 0.1), 1.0, 6.0);\n  gl_Position = projectionMatrix * mvPosition;\n  #include <logdepthbuf_vertex>\n}`,\n            fragmentShader: `\n#include <common>\n#include <logdepthbuf_pars_fragment>\nuniform vec3 uWaterBody, uWaterKd, uSunRadiance; uniform float uDepth;\nvarying float vFade;\nvoid main() {\n  #include <logdepthbuf_fragment>\n  float r = length(gl_PointCoord - 0.5);\n  if (r > 0.5) discard;\n  vec3 light = uSunRadiance * 0.05 * exp(-uWaterKd * uDepth) + uWaterBody * 4.0;\n  gl_FragColor = vec4(light, (1.0 - r * 2.0) * vFade * 0.55);\n}`,\n        });\n        this.points = new THREE.Points(this.geometry, this.material);\n        this.points.frustumCulled = false; this.points.visible = false;\n        this.points.name = 'OceanParticulate';\n        this.points.raycast = () => {};\n        this.basis = new THREE.Matrix4(); this.east = new THREE.Vector3(); this.north = new THREE.Vector3();\n        parent.add(this.points);\n    }\n    /** state: { cameraLocal, up, depth, time } while submerged, otherwise null. */\n    update(state) {\n        this.points.visible = !!state;\n        if (!state) return;\n        // Orient the cube to local up so sinking is vertical; offset wraps in metres.\n        this.east.crossVectors(new THREE.Vector3(0, 1, 0), state.up);\n        if (this.east.lengthSq() < 1e-8) this.east.set(1, 0, 0); else this.east.normalize();\n        this.north.crossVectors(state.up, this.east).normalize();\n        this.points.position.copy(state.cameraLocal);\n        this.points.quaternion.setFromRotationMatrix(this.basis.makeBasis(this.east, this.north.clone().negate(), state.up));\n        this.uniforms.uOffset.value.set(state.cameraLocal.dot(this.east) % CUBE, state.cameraLocal.dot(this.north) % CUBE, state.cameraLocal.dot(state.up) % CUBE);\n        this.uniforms.uTime.value = state.time; this.uniforms.uDepth.value = state.depth;\n    }\n    dispose() { this.points.removeFromParent(); this.geometry.dispose(); this.material.dispose(); }\n}\n","import { Matrix4, Uniform, Vector2, FloatType, NearestFilter } from 'three';\n\n// Compare view-space metres directly. Perspective-depth round trips lose the\n// skyline at NOCLIP's astronomical far plane. Sky and geometry beyond the\n// marched volume share the same guide depth.\nexport const CLOUD_GUIDE_GLSL = /* glsl */`\nfloat ncaCloudGuideDepth(float depth, float nearZ, float farZ, vec2 mode, float limitZ, float rayCosine) {\n  if (depth >= 1.0 - 1e-7) return limitZ;\n  float distanceZ;\n  if (mode.x > 0.5 && mode.y > 0.5) distanceZ = exp2(depth * log2(farZ + 1.0)) - 1.0;\n  else if (mode.y > 0.5) distanceZ = nearZ * farZ / max(farZ - depth * (farZ - nearZ), 1e-6);\n  else distanceZ = mix(nearZ, farZ, depth);\n  return min(limitZ, max(0.0, distanceZ) / max(1e-6, rayCosine));\n}\nfloat ncaCloudDepthWeight(float sourceZ, float targetZ) {\n  return 1.0 - smoothstep(0.025, 0.08, abs(sourceZ - targetZ) / max(1.0, min(sourceZ, targetZ)));\n}\n`;\n\nconst patched = new WeakSet();\n/** Repair only silhouette reconstruction; retain native raymarch dimensions,\n * volumes, targets, temporal storage and all interior-history filtering. */\nexport function patchCloudDepthReconstruction(clouds) {\n  const current = clouds?.cloudsPass?.currentMaterial;\n  const resolve = clouds?.cloudsPass?.resolveMaterial;\n  if (!current || !resolve || patched.has(resolve)) return;\n  const marker = '  #if defined(SHADOW_LENGTH) && defined(DEBUG_SHOW_SHADOW_LENGTH)';\n  if (!resolve.fragmentShader.includes(marker)) throw new Error('Cloud resolve depth contract changed');\n  Object.assign(resolve.uniforms, {\n    ncaSceneDepth: current.uniforms.depthBuffer,\n    ncaCameraNear: current.uniforms.cameraNear,\n    ncaCameraFar: current.uniforms.cameraFar,\n    ncaMarchLimit: current.uniforms.maxRayDistance,\n    ncaSourceUvScale: current.uniforms.targetUvScale,\n    ncaSourceJitter: current.uniforms.temporalJitter,\n    ncaDepthMode: new Uniform(new Vector2()),\n    ncaDepthPacking: new Uniform(0),\n    ncaInverseProjection: new Uniform(new Matrix4()),\n  });\n  resolve.fragmentShader = /* glsl */`\n    precision highp float;\n    precision highp sampler2D;\n    uniform sampler2D ncaSceneDepth;\n    uniform mat4 ncaInverseProjection;\n    uniform float ncaCameraNear, ncaCameraFar, ncaMarchLimit, ncaDepthPacking;\n    uniform vec2 ncaSourceUvScale, ncaSourceJitter, ncaDepthMode;\n    ${CLOUD_GUIDE_GLSL}\n    float ncaGuideAt(vec2 uv) {\n      vec4 sampleDepth = texture(ncaSceneDepth, clamp(uv, vec2(0.0), vec2(1.0)));\n      float depth = ncaDepthPacking > 0.5\n        ? dot(sampleDepth, vec4(1.0/16777216.0, 1.0/65536.0, 1.0/256.0, 1.0)) * (255.0/256.0)\n        : sampleDepth.r;\n      vec3 ray = normalize((ncaInverseProjection * vec4(uv*2.0-1.0,0.0,1.0)).xyz);\n      return ncaCloudGuideDepth(depth, ncaCameraNear, ncaCameraFar, ncaDepthMode, ncaMarchLimit,\n        ncaDepthMode.y>0.5 ? -ray.z : 1.0);\n    }\n  ` + resolve.fragmentShader;\n  const repair = /* glsl */`\n  // The native march depth sample belongs to its actual jittered coarse ray,\n  // not the centre of the enlarged 4x4 block. Reject cross-silhouette history.\n  ivec2 ncaSize = textureSize(colorBuffer, 0);\n  vec2 ncaSourcePixel = vUv * vec2(ncaSize) - 0.5;\n  ivec2 ncaCenter = ivec2(floor(ncaSourcePixel + 0.5));\n  float ncaTargetZ = ncaGuideAt(vUv);\n  bool ncaEdge = false;\n  for (int y = -1; y <= 1; y += 2) for (int x = -1; x <= 1; x += 2) {\n    vec2 probeUv = (vec2(clamp(ncaCenter + ivec2(x,y), ivec2(0), ncaSize-1)) + 0.5)\n      / vec2(ncaSize) * ncaSourceUvScale + ncaSourceJitter;\n    if (ncaCloudDepthWeight(ncaGuideAt(probeUv), ncaTargetZ) < 0.99) ncaEdge = true;\n  }\n  if (ncaEdge) {\n    vec4 sumColor = vec4(0.0); float sumWeight = 0.0, sumLength = 0.0;\n    for (int y = -2; y <= 2; ++y) for (int x = -2; x <= 2; ++x) {\n      ivec2 sampleCoord = clamp(ncaCenter + ivec2(x,y), ivec2(0), ncaSize-1);\n      vec2 sampleUv = (vec2(sampleCoord) + 0.5) / vec2(ncaSize) * ncaSourceUvScale + ncaSourceJitter;\n      float weight = ncaCloudDepthWeight(ncaGuideAt(sampleUv), ncaTargetZ);\n      vec2 offset = vec2(sampleCoord) - ncaSourcePixel;\n      weight *= exp2(-0.7 * dot(offset, offset));\n      sumColor += texelFetch(colorBuffer, sampleCoord, 0) * weight;\n      #ifdef SHADOW_LENGTH\n      sumLength += texelFetch(shadowLengthBuffer, sampleCoord, 0).r * weight;\n      #endif\n      sumWeight += weight;\n    }\n    // An unrepresented thin foreground must not inherit a background cloud.\n    outputColor = sumWeight > 1e-5 ? sumColor / sumWeight : vec4(0.0);\n    outputShadowLength = sumWeight > 1e-5 ? sumLength / sumWeight : 0.0;\n  }\n`;\n  resolve.fragmentShader = resolve.fragmentShader.replace(marker, repair + marker);\n  const original = resolve.onBeforeRender;\n  resolve.onBeforeRender = function(renderer, scene, camera, geometry, object, group) {\n    original.call(this, renderer, scene, camera, geometry, object, group);\n    this.uniforms.ncaDepthMode.value.set(renderer.capabilities.logarithmicDepthBuffer ? 1 : 0,\n      current.defines.PERSPECTIVE_CAMERA != null ? 1 : 0);\n    this.uniforms.ncaDepthPacking.value = current.depthPacking === 3201 ? 1 : 0;\n    this.uniforms.ncaInverseProjection.value.copy(clouds.cloudsPass.mainCamera.projectionMatrixInverse);\n  };\n  resolve.needsUpdate = true;\n  patched.add(resolve);\n}\n\n/** Native front depth is stored in metres: float16 overflows at 65,504 m. */\nexport function prepareCloudFrontDepth(pass) {\n  const target=pass?.currentRenderTarget,depth=target?.depthVelocity;\n  if(!depth || depth.type===FloatType)return;\n  target.dispose();depth.type=FloatType;\n  depth.minFilter=depth.magFilter=NearestFilter;depth.needsUpdate=true;\n}\n\n// Shadow MRTs carry metre distances in float16, including a 1,000 km empty\n// ray. Keep the native targets/history/filtering, but pack only the distance\n// channels in km; extinction remains per metre and consumers decode once.\nexport function decodeCloudShadowDepth(shader) {\n  if(shader.includes('/* NCA_SHADOW_DISTANCE_KM */'))return shader;\n  return shader.replace(/vec4 shadow = texture\\(shadowBuffer, ([^;\\n]+)\\);/g,\n    '$&\\n  /* NCA_SHADOW_DISTANCE_KM */\\n  shadow.r *= 1000.0;');\n}\nconst shadowStoragePatched=new WeakSet();\nexport function patchCloudShadowStorage(effect) {\n  const material=effect?.shadowPass?.currentMaterial;\n  if(!material?.fragmentShader || shadowStoragePatched.has(material))return;\n  if(material.fragmentShader.includes('/* NCA_SHADOW_PACK_KM */')){shadowStoragePatched.add(material);return;}\n  if(!material.fragmentShader.includes('outputColor = color;')\n    || !material.fragmentShader.includes('outputDepthVelocity = vec3(color.x, velocity);')) {\n    throw new Error('Native cloud shadow distance contract changed');\n  }\n  material.fragmentShader=material.fragmentShader\n    .replace('outputColor = color;', '/* NCA_SHADOW_PACK_KM */\\n  outputColor = vec4(min(color.r * .001, 65504.0), color.gba);')\n    .replace('outputDepthVelocity = vec3(color.x, velocity);',\n      'outputDepthVelocity = vec3(min(color.x * .001, 65504.0), velocity);');\n  material.needsUpdate=true;shadowStoragePatched.add(material);\n  const clouds=effect.cloudsPass?.currentMaterial;\n  if(clouds){clouds.fragmentShader=decodeCloudShadowDepth(clouds.fragmentShader);clouds.needsUpdate=true;}\n}\n","import { Color, Matrix4, ShaderChunk, Uniform, Vector2, Vector3 } from 'three';\nimport { decodeCloudShadowDepth } from '../refactor/render/CloudDepthReconstruction.js';\nimport { AerialPerspectiveEffect } from '@takram/three-atmosphere';\nimport { CELESTIAL_IRRADIANCE_GLSL } from '../refactor/render/CelestialIrradianceContract.js';\n\n// Extract the pinned SDK's functions, rather than maintaining a second shadow\n// filter or scattering approximation. Constructing this Effect allocates no\n// render targets/textures, starts no work, and acquires no renderer/context.\nconst canonical = new AerialPerspectiveEffect().fragmentShader;\nconst copyrightStart = canonical.lastIndexOf('/**', canonical.indexOf('Copyright (c) 2008 INRIA'));\nconst scatteringCopyright = canonical.slice(copyrightStart, canonical.indexOf('*/', copyrightStart) + 2);\nfunction declaration(source, name, kind = 'function') {\n    const expression = kind === 'struct' ? new RegExp(`\\\\bstruct\\\\s+${name}\\\\s*\\\\{`)\n        : new RegExp(`^[ \\\\t]*(?:float|int|vec[234]|Length|Number|Area|DimensionlessSpectrum|IrradianceSpectrum|Illuminance3)\\\\s+${name}\\\\s*\\\\(`, 'm');\n    const match = expression.exec(source);\n    if (!match) throw new Error(`Pinned ocean lighting declaration changed: ${name}`);\n    const start = match.index, open = source.indexOf('{', start);\n    let depth = 1, index = open + 1;\n    for (; index < source.length && depth; index++) {\n        if (source[index] === '{') depth++;\n        else if (source[index] === '}') depth--;\n    }\n    if (depth) throw new Error('Pinned ocean lighting declaration is incomplete');\n    return source.slice(start, index + (kind === 'struct' ? 1 : 0));\n}\nconst functions = ['ClampDistance', 'SafeSqrt', 'DistanceToTopAtmosphereBoundary',\n    'GetTextureCoordFromUnitRange', 'GetTransmittanceTextureUvFromRMu',\n    'GetTransmittanceToTopAtmosphereBoundary', 'GetTransmittanceToSun',\n    'GetIrradianceTextureUvFromRMuS', 'GetIrradiance', 'GetSunAndSkyIrradiance', 'GetSunAndSkyIlluminance'];\nconst shadows = ['raySphereFirstIntersection', 'raySphereSecondIntersection', 'remapClamped',\n    'interleavedGradientNoise', 'vogelDisk', 'viewZToOrthographicDepth', 'getFadedCascadeIndex', 'getSTBN', 'getShadowUv',\n    'getDistanceToShadowTop', 'readShadowOpticalDepth', 'sampleShadowOpticalDepthPCF',\n    'sampleShadowOpticalDepth', 'getShadowRadius'];\nconst types = ['DensityProfileLayer', 'DensityProfile', 'AtmosphereParameters'];\nconst bindings = {\n    ATMOSPHERE: 'Atmosphere', SUN_SPECTRAL_RADIANCE_TO_LUMINANCE: 'SunLuminance',\n    SKY_SPECTRAL_RADIANCE_TO_LUMINANCE: 'SkyLuminance', transmittance_texture: 'Transmittance',\n    irradiance_texture: 'Irradiance', worldToECEFMatrix: 'WorldToECEF', altitudeCorrection: 'AltitudeCorrection',\n    sunDirection: 'SunDirection', bottomRadius: 'BottomRadius', projectionMatrix: 'Projection',\n    viewMatrix: 'View', shadowBuffer: 'Shadow', shadowIntervals: 'Intervals', shadowMatrices: 'Matrices',\n    inverseShadowMatrices: 'InverseMatrices', shadowFar: 'ShadowFar', shadowTopHeight: 'ShadowTopHeight',\n    shadowRadius: 'ShadowRadius', stbnTexture: 'STBN', frame: 'Frame', cameraNear: 'CameraNear', resolution: 'Resolution',\n    ncaSunCenterECEF: 'SunCenter', ncaSunRadius: 'SunRadius', ncaMoonCenterECEF: 'MoonCenter', ncaMoonPhysicalRadius: 'MoonRadius',\n    ncaSimpleCloudsTexture: 'SimpleTexture', ncaSimpleCloudsOpacity: 'SimpleOpacity',\n    ncaSimpleCloudsShadowStrength: 'SimpleStrength', ncaSimpleCloudsShadowHeight: 'SimpleHeight',\n    ncaSimpleCloudsAlphaThreshold: 'SimpleThreshold', ncaSimpleCloudsAlphaSoftness: 'SimpleSoftness',\n    ncaSimpleCloudsNightAirglowColor: 'NightColor', ncaSimpleCloudsNightAirglowStrength: 'NightStrength',\n    ncaNightTransitionStart: 'NightStart', ncaNightTransitionEnd: 'NightEnd',\n};\nconst defines = {\n    SHADOW_CASCADE_COUNT: 'NCA_OCEAN_CLOUD_CASCADE_COUNT', SHADOW_SAMPLE_COUNT: 'NCA_OCEAN_CLOUD_SAMPLE_COUNT',\n    TRANSMITTANCE_TEXTURE_WIDTH: 'NCA_OCEAN_CLOUD_TRANSMITTANCE_WIDTH',\n    TRANSMITTANCE_TEXTURE_HEIGHT: 'NCA_OCEAN_CLOUD_TRANSMITTANCE_HEIGHT',\n    IRRADIANCE_TEXTURE_WIDTH: 'NCA_OCEAN_CLOUD_IRRADIANCE_WIDTH',\n    IRRADIANCE_TEXTURE_HEIGHT: 'NCA_OCEAN_CLOUD_IRRADIANCE_HEIGHT',\n    TRANSMITTANCE_PRECISION_LOG: 'NCA_OCEAN_CLOUD_TRANSMITTANCE_LOG',\n    METER_TO_LENGTH_UNIT: 'NCA_OCEAN_CLOUD_METER_SCALE',\n};\nconst namespace = Object.fromEntries([...functions, ...shadows, ...types,\n    'ncaFiniteDiscVisibility', 'ncaCircleOverlapArea'].map(name => [name, `ncaOceanCanonical_${name}`]));\nfor (const [name, suffix] of Object.entries(bindings)) namespace[name] = `ncaOceanCloud${suffix}`;\nObject.assign(namespace, defines);\nfor (const name of ['Length', 'Number', 'Area', 'Angle', 'InverseLength']) namespace[name] = 'float';\nfor (const name of ['IrradianceSpectrum', 'DimensionlessSpectrum', 'ScatteringSpectrum', 'Position', 'Direction', 'Illuminance3']) namespace[name] = 'vec3';\nnamespace.TransmittanceTexture = namespace.IrradianceTexture = 'sampler2D';\nnamespace.m = namespace.m2 = namespace.rad = '1.0'; namespace.assert = 'ncaOceanCloudAssert';\nconst rename = source => source.replace(/\\b[A-Za-z_]\\w*\\b/g, word => namespace[word] || word);\nconst irradianceGLSL = rename(types.map(name => declaration(canonical, name, 'struct')).join('\\n')\n    + '\\n' + functions.map(name => declaration(canonical, name)).join('\\n'));\nconst shadowGLSL = rename(decodeCloudShadowDepth(shadows.map(name => declaration(\n    name === 'viewZToOrthographicDepth' ? ShaderChunk.packing : canonical, name)).join('\\n')));\n\nexport const OCEAN_CLOUD_LIGHTING_GLSL = /* glsl */`\n${scatteringCopyright}\nuniform float ncaOceanCloudReady;\n#ifdef NCA_OCEAN_CLOUD_READY\n#define ncaOceanCloudAssert(x)\n${irradianceGLSL.slice(0, irradianceGLSL.indexOf('float ncaOceanCanonical_ClampDistance'))}\nuniform ncaOceanCanonical_AtmosphereParameters ncaOceanCloudAtmosphere;\nuniform vec3 ncaOceanCloudSunLuminance, ncaOceanCloudSkyLuminance;\nuniform sampler2D ncaOceanCloudTransmittance, ncaOceanCloudIrradiance;\nuniform mat4 ncaOceanCloudWorldToECEF;\nuniform vec3 ncaOceanCloudAltitudeCorrection, ncaOceanCloudSunDirection;\nuniform vec3 ncaOceanCloudSunCenter, ncaOceanCloudMoonCenter;\nuniform float ncaOceanCloudSunRadius, ncaOceanCloudMoonRadius, ncaOceanCloudBottomRadius;\nuniform float ncaOceanCloudGeometricCorrection;\n${irradianceGLSL.slice(irradianceGLSL.indexOf('float ncaOceanCanonical_ClampDistance'))}\n${rename(CELESTIAL_IRRADIANCE_GLSL)}\n#ifdef NCA_OCEAN_CLOUD_SHADOW\nuniform sampler2DArray ncaOceanCloudShadow;\nuniform sampler3D ncaOceanCloudSTBN;\nuniform vec2 ncaOceanCloudIntervals[NCA_OCEAN_CLOUD_CASCADE_COUNT];\nuniform mat4 ncaOceanCloudMatrices[NCA_OCEAN_CLOUD_CASCADE_COUNT];\nuniform mat4 ncaOceanCloudInverseMatrices[NCA_OCEAN_CLOUD_CASCADE_COUNT];\nuniform mat4 ncaOceanCloudProjection, ncaOceanCloudView;\nuniform float ncaOceanCloudShadowFar, ncaOceanCloudShadowTopHeight, ncaOceanCloudShadowRadius, ncaOceanCloudCameraNear;\nuniform vec2 ncaOceanCloudResolution;\nuniform int ncaOceanCloudFrame;\nuniform float ncaOceanCloudShadowEnabled;\n${shadowGLSL}\n#endif\n#ifdef NCA_OCEAN_CLOUD_SIMPLE\nuniform sampler2D ncaOceanCloudSimpleTexture;\nuniform float ncaOceanCloudSimpleOpacity, ncaOceanCloudSimpleStrength, ncaOceanCloudSimpleHeight;\nuniform float ncaOceanCloudSimpleThreshold, ncaOceanCloudSimpleSoftness;\nuniform vec3 ncaOceanCloudNightColor;\nuniform float ncaOceanCloudNightStrength, ncaOceanCloudNightStart, ncaOceanCloudNightEnd;\nuniform float ncaOceanCloudSimpleEnabled;\nfloat ncaOceanCloudMask(vec4 sample_) {\n    float black = clamp(ncaOceanCloudSimpleThreshold, 0.0, 0.95);\n    return pow(clamp((sample_.a - black) / (1.0 - black + 1e-4), 0.0, 1.0),\n        1.0 + clamp(ncaOceanCloudSimpleSoftness, 0.0, 1.0) * 6.0);\n}\nvec2 ncaOceanCloudUv(vec3 direction) {\n    vec3 d = normalize(direction);\n    return vec2(fract(atan(d.x, d.z) / PI2 + 0.5), 0.5 - asin(clamp(d.y, -1.0, 1.0)) / PI);\n}\nfloat ncaOceanCloudShellHit(vec3 origin, vec3 direction, float radius) {\n    float b = dot(origin, direction), c = dot(origin, origin) - radius * radius;\n    float h = b*b-c; if (h < 0.0) return -1.0;\n    float near_ = -b-sqrt(h), far_ = -b+sqrt(h);\n    return near_ > 0.0 ? near_ : far_;\n}\n#endif\n#endif\nvoid ncaOceanCloudLighting(vec3 worldPosition, vec3 normalWorld,\n    out vec3 sunRadiance, out vec3 skyRadiance, out float sunTransmission) {\n    sunRadiance = vec3(0.0); skyRadiance = vec3(0.0); sunTransmission = 1.0;\n    #ifdef NCA_OCEAN_CLOUD_READY\n    if (ncaOceanCloudReady < 0.5) return;\n    vec3 meters = (ncaOceanCloudWorldToECEF * vec4(worldPosition,1.0)).xyz;\n    vec3 p = (meters + ncaOceanCloudAltitudeCorrection * (1.0 - ncaOceanCloudGeometricCorrection)) * NCA_OCEAN_CLOUD_METER_SCALE;\n    vec3 n = normalize(mat3(ncaOceanCloudWorldToECEF) * normalWorld);\n    vec3 sun = normalize(ncaOceanCloudSunDirection);\n    vec3 sky;\n    vec3 irradiance = ncaOceanCanonical_GetSunAndSkyIlluminance(p,n,sun,sky);\n    #ifdef NCA_OCEAN_CLOUD_SUN\n    vec3 sunOffset = ncaOceanCloudSunCenter-p, moonOffset = ncaOceanCloudMoonCenter-p;\n    float eclipse = ncaOceanCloudMoonRadius > 0.0 ? ncaOceanCanonical_ncaFiniteDiscVisibility(sunOffset,\n        asin(clamp(ncaOceanCloudSunRadius/max(length(sunOffset),ncaOceanCloudSunRadius),0.0,1.0)), moonOffset,\n        asin(clamp(ncaOceanCloudMoonRadius/max(length(moonOffset),ncaOceanCloudMoonRadius),0.0,1.0))) : 1.0;\n    sunRadiance = irradiance * eclipse / max(dot(n,sun),1e-4);\n    #endif\n    #ifdef NCA_OCEAN_CLOUD_SKY\n    skyRadiance = sky * RECIPROCAL_PI;\n    #endif\n    #ifdef NCA_OCEAN_CLOUD_SHADOW\n    float opticalDepth = ncaOceanCloudShadowEnabled > 0.5 ? ncaOceanCanonical_sampleShadowOpticalDepth(worldPosition,p,\n        ncaOceanCanonical_getShadowRadius(worldPosition),ncaOceanCanonical_getSTBN()) : 0.0;\n    sunTransmission = exp(-opticalDepth);\n    #endif\n    #ifdef NCA_OCEAN_CLOUD_SIMPLE\n    if (ncaOceanCloudSimpleEnabled > 0.5) {\n    float day = smoothstep(ncaOceanCloudNightStart,ncaOceanCloudNightEnd,dot(normalize(p),sun));\n    float hit = ncaOceanCloudShellHit(p,sun,ncaOceanCloudAtmosphere.bottom_radius\n        + max(ncaOceanCloudSimpleHeight,0.0)*NCA_OCEAN_CLOUD_METER_SCALE);\n    float coverage = ncaOceanCloudMask(texture2D(ncaOceanCloudSimpleTexture,\n        ncaOceanCloudUv(hit > 0.0 ? p+sun*hit : p)));\n    sunTransmission *= 1.0-clamp(coverage*ncaOceanCloudSimpleStrength*day,0.0,0.85);\n    #ifdef NCA_OCEAN_CLOUD_SKY\n    vec3 eyeMeters = (ncaOceanCloudWorldToECEF * vec4(cameraPosition,1.0)).xyz;\n    vec3 reflected = reflect(-normalize(eyeMeters-meters),n);\n    float reflectedHit = ncaOceanCloudShellHit(p,reflected,ncaOceanCloudAtmosphere.bottom_radius\n        + max(ncaOceanCloudSimpleHeight,1.0)*NCA_OCEAN_CLOUD_METER_SCALE);\n    if (reflectedHit > 0.0) {\n        vec4 cloud = texture2D(ncaOceanCloudSimpleTexture,ncaOceanCloudUv(p+reflected*reflectedHit));\n        vec3 cloudSky = mix(ncaOceanCloudNightColor*ncaOceanCloudNightStrength,vec3(1.0),day)\n            * mix(0.7,1.0,max(cloud.r,max(cloud.g,cloud.b)));\n        skyRadiance = mix(skyRadiance,cloudSky,clamp(ncaOceanCloudMask(cloud)*ncaOceanCloudSimpleOpacity,0.0,1.0));\n    }\n    #endif\n    }\n    #endif\n    #ifdef NCA_OCEAN_CLOUD_SKY\n    // Overcast redistributes sky radiance; it does not remove the environment.\n    float luminance = dot(max(skyRadiance,vec3(0.0)),vec3(0.2126,0.7152,0.0722));\n    skyRadiance = mix(vec3(luminance),skyRadiance,clamp(sunTransmission,0.0,1.0));\n    #endif\n    #endif\n}\n// Aerial perspective for the sea, which draws after the atmosphere pass:\n// transmittance from the water point to the camera (ratio of top-of-\n// atmosphere transmittances along the upward point→camera ray) and horizon\n// sky light scattered in front of it, so distant water fades into the sky\n// like terrain does instead of staying dark and saturated to the horizon.\nvec3 ncaOceanAerial(vec3 worldPosition, vec3 color, vec3 skyRadiance) {\n    #ifdef NCA_OCEAN_CLOUD_READY\n    if (ncaOceanCloudReady < 0.5) return color;\n    vec3 correction = ncaOceanCloudAltitudeCorrection * (1.0 - ncaOceanCloudGeometricCorrection);\n    vec3 p = ((ncaOceanCloudWorldToECEF * vec4(worldPosition, 1.0)).xyz + correction) * NCA_OCEAN_CLOUD_METER_SCALE;\n    vec3 c = ((ncaOceanCloudWorldToECEF * vec4(cameraPosition, 1.0)).xyz + correction) * NCA_OCEAN_CLOUD_METER_SCALE;\n    vec3 d = c - p;\n    if (dot(d, d) < 1e-12) return color;\n    d = normalize(d);\n    float rp = length(p), rc = length(c);\n    float top = ncaOceanCloudAtmosphere.top_radius;\n    rp = clamp(rp, ncaOceanCloudAtmosphere.bottom_radius, top);\n    rc = clamp(rc, ncaOceanCloudAtmosphere.bottom_radius, top);\n    vec3 tP = ncaOceanCanonical_GetTransmittanceToTopAtmosphereBoundary(ncaOceanCloudAtmosphere,\n        ncaOceanCloudTransmittance, rp, clamp(dot(p, d) / length(p), -1.0, 1.0));\n    vec3 tC = ncaOceanCanonical_GetTransmittanceToTopAtmosphereBoundary(ncaOceanCloudAtmosphere,\n        ncaOceanCloudTransmittance, rc, clamp(dot(c, d) / length(c), -1.0, 1.0));\n    vec3 transmittance = clamp(tP / max(tC, vec3(1e-6)), 0.0, 1.0);\n    // Sky radiance near the horizon is brighter than the hemispherical mean.\n    return color * transmittance + skyRadiance * 1.6 * (1.0 - transmittance);\n    #else\n    return color;\n    #endif\n}\n`;\n\nexport function createOceanCloudLightingUniforms() {\n    const result = { ncaOceanCloudReady: new Uniform(0), ncaOceanCloudCameraNear: new Uniform(0.1),\n        ncaOceanCloudResolution: new Uniform(new Vector2(1,1)), ncaOceanCloudGeometricCorrection: new Uniform(0) };\n    for (const suffix of Object.values(bindings)) result[`ncaOceanCloud${suffix}`] = new Uniform(null);\n    result.ncaOceanCloudCameraNear.value = 0.1;\n    result.ncaOceanCloudResolution.value = new Vector2(1,1);\n    result.ncaOceanCloudWorldToECEF.value = new Matrix4();\n    result.ncaOceanCloudAltitudeCorrection.value = new Vector3();\n    result.ncaOceanCloudSunDirection.value = new Vector3(0,1,0);\n    result.ncaOceanCloudSunCenter.value = new Vector3(0,1e12,0);\n    result.ncaOceanCloudSunRadius.value = 1;\n    result.ncaOceanCloudMoonCenter.value = new Vector3();\n    result.ncaOceanCloudMoonRadius.value = 0;\n    result.ncaOceanCloudSunLuminance.value = new Vector3(1,1,1);\n    result.ncaOceanCloudSkyLuminance.value = new Vector3(1,1,1);\n    result.ncaOceanCloudProjection.value = new Matrix4();\n    result.ncaOceanCloudView.value = new Matrix4();\n    result.ncaOceanCloudFrame.value = 0;\n    result.ncaOceanCloudSimpleOpacity.value = 1;\n    result.ncaOceanCloudSimpleStrength.value = 1;\n    result.ncaOceanCloudSimpleHeight.value = 12600;\n    result.ncaOceanCloudSimpleThreshold.value = 0;\n    result.ncaOceanCloudSimpleSoftness.value = 1;\n    result.ncaOceanCloudNightColor.value = new Color('#9fb3c2');\n    result.ncaOceanCloudNightStrength.value = 0.006;\n    result.ncaOceanCloudNightStart.value = 0;\n    result.ncaOceanCloudNightEnd.value = 0.5;\n    result.ncaOceanCloudShadowEnabled = new Uniform(0);\n    result.ncaOceanCloudSimpleEnabled = new Uniform(0);\n    for (const uniform of Object.values(result)) defaults.set(uniform, uniform.value);\n    return result;\n}\nconst defaults = new WeakMap();\nconst ownedUniformNames = ['ncaOceanCloudReady', 'ncaOceanCloudGeometricCorrection',\n    'ncaOceanCloudShadowEnabled', 'ncaOceanCloudSimpleEnabled',\n    ...Object.values(bindings).map(suffix => `ncaOceanCloud${suffix}`)];\n\n/** Stable wrappers borrow SDK values only. No texture acquisition or disposal. */\nexport function syncOceanCloudLightingUniforms(uniforms, source, { resolution } = {}) {\n    const map = source?.uniforms;\n    const get = key => map?.get?.(key)?.value;\n    const has = key => source?.defines?.has?.(key) === true;\n    const ready = !!(get('ATMOSPHERE') && get('transmittance_texture') && get('irradiance_texture') && get('worldToECEFMatrix'));\n    uniforms.ncaOceanCloudReady.value = ready ? 1 : 0;\n    const compile = {}, flags = { ready, hasShadow: false, hasSimple: false, shadowEnabled: false,\n        simpleEnabled: false, cascadeCount: 1, sampleCount: 8 };\n    if (ready) {\n        for (const [name,suffix] of Object.entries(bindings)) {\n            const value = get(name);\n            const uniform = uniforms[`ncaOceanCloud${suffix}`];\n            uniform.value = value !== undefined ? value : defaults.get(uniform);\n        }\n        const attachments = get('ncaCloudAttachments');\n        flags.hasShadow = has('HAS_SHADOW') && !!get('shadowBuffer') && !!get('stbnTexture');\n        flags.hasSimple = !!get('ncaSimpleCloudsTexture');\n        flags.shadowEnabled = flags.hasShadow && (!attachments || attachments.y > 0.5);\n        flags.simpleEnabled = flags.hasSimple && get('ncaSimpleCloudsEnabled') > 0.5;\n        uniforms.ncaOceanCloudShadowEnabled.value = flags.shadowEnabled ? 1 : 0;\n        uniforms.ncaOceanCloudSimpleEnabled.value = flags.simpleEnabled ? 1 : 0;\n        const integer = (value,min,max,fallback) => Number.isFinite(Number(value)) ? Math.min(max,Math.max(min,Math.round(Number(value)))) : fallback;\n        flags.cascadeCount = integer(source.defines.get('SHADOW_CASCADE_COUNT'),1,4,1);\n        flags.sampleCount = integer(source.defines.get('SHADOW_SAMPLE_COUNT'),1,16,8);\n        compile.NCA_OCEAN_CLOUD_READY = '1';\n        if (flags.hasShadow) compile.NCA_OCEAN_CLOUD_SHADOW = '1';\n        if (flags.hasSimple) compile.NCA_OCEAN_CLOUD_SIMPLE = '1';\n        if (has('SUN_LIGHT')) compile.NCA_OCEAN_CLOUD_SUN = '1';\n        if (has('SKY_LIGHT')) compile.NCA_OCEAN_CLOUD_SKY = '1';\n        compile.NCA_OCEAN_CLOUD_CASCADE_COUNT = `${flags.cascadeCount}`;\n        compile.NCA_OCEAN_CLOUD_SAMPLE_COUNT = `${flags.sampleCount}`;\n        for (const [from,to] of Object.entries(defines)) {\n            if (['SHADOW_CASCADE_COUNT','SHADOW_SAMPLE_COUNT'].includes(from)) continue;\n            const value = source.defines.get(from); if (value !== undefined) compile[to] = value;\n        }\n        uniforms.ncaOceanCloudCameraNear.value = source.mainCamera?.near ?? 0.1;\n        uniforms.ncaOceanCloudGeometricCorrection.value = has('CORRECT_GEOMETRIC_ERROR') ? get('geometricErrorCorrectionAmount') || 0 : 0;\n        if (resolution) uniforms.ncaOceanCloudResolution.value = resolution;\n    } else {\n        for (const name of ownedUniformNames) {\n            const uniform = uniforms[name];\n            uniform.value = defaults.get(uniform);\n        }\n    }\n    return { ...flags, defines: compile, key: JSON.stringify(compile) };\n}\n","import * as THREE from 'three';\nimport { ellipsoidRadiusForLocalDir, dirToLatLonLocal } from './geometry-utils.js';\nimport { createOceanSpectrum, OCEAN_WAVE_GLSL } from './ocean-wave-spectrum.js';\nimport { OceanGPUCascades, OCEAN_CASCADES, canRunOceanCascades, coxMunkSlopeVariance } from './ocean-gpu-cascades.js';\nimport { OCEAN_OPTICS_GLSL, OCEAN_OPTICS_FRAGMENT } from './ocean-optics.js';\nimport { OCEAN_CAPILLARY_GLSL } from './ocean-capillary.js';\nimport { OCEAN_DEPTH_VERTEX_GLSL, OCEAN_VERTEX_DISPLACEMENT_GLSL } from './ocean-surface-depth.js';\nimport { computeWaterOptics, oceanSubsurfaceLight, OCEAN_DEFAULT_CHLOROPHYLL } from './ocean-water-optics.js';\nimport { OceanParticulate } from './ocean-particulate.js';\nimport { WATER_COVERAGE_GLSL, waterCoverageUniforms } from './water-coverage.js';\nimport { OCEAN_CLOUD_LIGHTING_GLSL, createOceanCloudLightingUniforms,\n    syncOceanCloudLightingUniforms } from './OceanCloudLighting.js';\n\nconst compactDevice = () => typeof matchMedia === 'function' && matchMedia('(max-width: 700px), (pointer: coarse)').matches;\n\n// A camera-centred, curved sea-level surface. Terrain retains bathymetry;\n// this bounded mesh supplies GPU spectral waves and dielectric optics.\n// Uses WebGL MeshPhysicalMaterial, compatible with the existing atmosphere.\nexport class OceanSurface {\n    /** tier: 'full' or 'basic' (analytic waves, no reflection trace or particulate); see ocean-quality.js. */\n    constructor({ parent, camera, uniforms, renderer = null, environment = null, sunLight = null, waterLevel = null, tier = 'full',\n        segments = tier === 'basic' ? 64 : 128 }) {\n        Object.assign(this, { parent, camera, uniforms, renderer, sunLight, waterLevel, tier });\n        this.gpuUnavailable = tier !== 'full';\n        this.center = new THREE.Vector3(); this.up = new THREE.Vector3();\n        this.east = new THREE.Vector3(); this.north = new THREE.Vector3();\n        this.point = new THREE.Vector3(); this.cameraLocal = new THREE.Vector3();\n        this.geo = {};\n        this.previousCenter = new THREE.Vector3(Infinity, 0, 0);\n        this.patchMeanCenter = new THREE.Vector3();\n        this.patchUp = new THREE.Vector3();\n        this.lastSwimmer = new THREE.Vector3(Infinity, 0, 0);\n        this.ripples = Array.from({ length: 8 }, () => new THREE.Vector4(0, 0, -1e6, 0));\n        this.rippleIndex = 0;\n        this.rippleWorlds = Array.from({ length: 8 }, () => new THREE.Vector3());\n        this.spectrum = createOceanSpectrum();\n        this.wavePhases = this.spectrum.map(wave => new THREE.Vector2(wave.phase, 0));\n        this.waveFrameEast = new THREE.Vector3(); this.waveFrameNorth = new THREE.Vector3();\n        this.sunWorld = new THREE.Vector3();\n        this.setWaterClarity(OCEAN_DEFAULT_CHLOROPHYLL);\n        this.uniformsLocal = {\n            ncaOceanSceneColor: { value: null }, ncaOceanSceneDepth: { value: null },\n            ncaOceanOpticsReady: { value: 0 }, ncaOceanCameraFar: { value: camera.far },\n            ncaOceanViewport: { value: new THREE.Vector2(1, 1) },\n            ncaOceanProjection: { value: new THREE.Matrix4() },\n            ncaOceanSceneRegion: { value: new THREE.Vector4(1,1,0,0) },\n            ncaOceanReflectionReady: { value: 0 },\n            ncaOceanReflectionRegion: { value: new THREE.Vector4() },\n            ncaOceanReflectionFromView: { value: new THREE.Matrix4() },\n            ncaOceanReflectionViewFromView: { value: new THREE.Matrix4() },\n            ncaOceanSunView: { value: new THREE.Vector3(0,1,0) },\n            ncaOceanUpView: { value: new THREE.Vector3(0,1,0) },\n            ncaOceanSubmerged: { value: 0 },\n            ncaOceanWaterC: { value: new THREE.Vector3() }, ncaOceanWaterKd: { value: new THREE.Vector3() },\n            ncaOceanWaterBody: { value: new THREE.Vector3() }, ncaOceanSunRadiance: { value: new THREE.Vector3(3.4, 3.4, 3.4) },\n            ncaOceanWaterDirectBody: { value: new THREE.Vector3() },\n            ncaOceanWaterReflectance: { value: new THREE.Vector3() },\n            ncaOceanGPUReady: { value: 0 },\n            ncaOceanDisp0: { value: null }, ncaOceanDisp1: { value: null }, ncaOceanDisp2: { value: null },\n            ncaOceanSlope0: { value: null }, ncaOceanSlope1: { value: null }, ncaOceanSlope2: { value: null },\n            ncaOceanCascadeLength: { value: new THREE.Vector3(...OCEAN_CASCADES.map(c => c.length)) },\n            ncaOceanCascadeSize: { value: new THREE.Vector3(256, 256, 128) },\n            ncaOceanCascadeOrigin: { value: OCEAN_CASCADES.map(() => new THREE.Vector2()) },\n            ncaOceanFFTMatrix: { value: new THREE.Vector4(1, 0, 0, 1) },\n            ncaOceanBaseRoughness: { value: 0.02 }, ncaOceanWindVector: { value: new THREE.Vector2(Math.cos(0.5), Math.sin(0.5)) },\n            ncaOceanTime: uniforms.waterTime,\n            ncaOceanWaves: { value: this.spectrum.map(wave => new THREE.Vector4(wave.kx, wave.ky, wave.amplitude, wave.omega)) },\n            ncaOceanWavePhases: { value: this.wavePhases },\n            ncaOceanMask: uniforms.specularTexture,\n            ncaOceanMaskEnabled: { value: 0 },\n            ncaOceanCenter: { value: this.center },\n            ncaOceanUp: { value: this.up },\n            ncaOceanEast: { value: this.east },\n            ncaOceanNorth: { value: this.north },\n            ncaOceanWaveScale: uniforms.waterDistortion,\n            ncaOceanNormals: uniforms.waterNormalsTexture,\n            ncaOceanRipples: { value: this.ripples },\n            ...waterCoverageUniforms(uniforms),\n            ...createOceanCloudLightingUniforms(),\n        };\n        this.geometry = new THREE.PlaneGeometry(2, 2, segments, segments);\n        this.grid = new Float32Array(this.geometry.attributes.position.array);\n        this.spacing = new THREE.BufferAttribute(new Float32Array(this.geometry.attributes.position.count), 1);\n        this.geometry.setAttribute('aOceanSpacing', this.spacing);\n        this.segments = segments;\n        this.material = new THREE.MeshPhysicalMaterial({ color: 0x063e4b,\n            roughness: 0.16, metalness: 0, ior: 1.333, specularIntensity: 1,\n            clearcoat: 0.25, clearcoatRoughness: 0.08, side: THREE.DoubleSide,\n            envMap: environment, envMapIntensity: 0.8 });\n        if (tier !== 'full') this.material.defines = { ...this.material.defines, OCEAN_BASIC: '' };\n        this.material.onBeforeCompile = shader => {\n            Object.assign(shader.uniforms, this.uniformsLocal);\n            shader.vertexShader = shader.vertexShader.replace('#include <logdepthbuf_pars_vertex>', '#include <logdepthbuf_pars_vertex>\\n#ifdef USE_LOGARITHMIC_DEPTH_BUFFER\\ninvariant vFragDepth;\\n#endif').replace('#include <common>', `#include <common>\ninvariant gl_Position;\n${OCEAN_WAVE_GLSL}\nuniform vec3 ncaOceanCenter, ncaOceanUp, ncaOceanEast, ncaOceanNorth;\nattribute float aOceanSpacing;\nvarying vec3 vOceanLocal;\nvarying vec3 vOceanWorld;\nvarying vec2 vOceanWaveXZ;\nvarying float vOceanHeight;`)\n                .replace('#include <begin_vertex>', `#include <begin_vertex>\n${OCEAN_VERTEX_DISPLACEMENT_GLSL}\n  vOceanWaveXZ = waveXZ;\n  vOceanLocal = ncaOceanCenter + transformed;\n  vOceanWorld = (modelMatrix * vec4(transformed, 1.0)).xyz;`);\n            shader.fragmentShader = shader.fragmentShader.replace('#include <common>', `#include <common>\nuniform sampler2D ncaOceanMask;\nuniform sampler2D ncaOceanNormals;\nuniform float ncaOceanMaskEnabled, ncaOceanBaseRoughness;\nuniform vec2 ncaOceanWindVector;\n${OCEAN_WAVE_GLSL}\n${OCEAN_CAPILLARY_GLSL}\n${OCEAN_OPTICS_GLSL}\n${WATER_COVERAGE_GLSL}\nvarying vec3 vOceanLocal;\nvarying vec3 vOceanWorld;\nvarying vec2 vOceanWaveXZ;\nvarying float vOceanHeight;`)\n                .replace('#include <color_fragment>', `#include <color_fragment>\n  vec3 oceanDir = normalize(vOceanLocal);\n  vec2 oceanUv = vec2(fract(atan(oceanDir.x, oceanDir.z) / (2.0 * PI) + 0.5),\n    0.5 - asin(clamp(oceanDir.y, -1.0, 1.0)) / PI);\n  if (ncaWaterCoverage(vOceanLocal).y < 0.5) discard;`)\n                .replace('#include <roughnessmap_fragment>', `#include <roughnessmap_fragment>\n  vec2 waveP = vOceanWaveXZ;\n  float footprint = max(length(dFdx(waveP)), length(dFdy(waveP)));\n  float waveVariance = 0.0;\n  vec4 field;\n  if (ncaOceanGPUReady > 0.5) {\n    vec4 slopeFoam = oceanSlopeFoam(waveP, footprint, waveVariance);\n    field = vec4(vOceanHeight, slopeFoam.xyz);\n  } else {\n    field = oceanField(waveP, footprint);\n    field.w = smoothstep(0.25, 0.65, field.w);\n  }\n  // Capillary slopes the pixel resolves become geometry; the remainder of\n  // the Cox–Munk variance and unresolved cascade variance widen the lobe.\n  vec4 capillary = oceanCapillary(waveP, footprint, ncaOceanTime * 4.0, ncaOceanWindVector,\n    ncaOceanBaseRoughness * ncaOceanBaseRoughness);\n  float oceanAlpha = clamp(sqrt(max(0.0, ncaOceanBaseRoughness * ncaOceanBaseRoughness - capillary.z) + waveVariance), 0.009, 0.5);\n  roughnessFactor = sqrt(oceanAlpha);`)\n                .replace('#include <normal_fragment_maps>', `#include <normal_fragment_maps>\n  vec3 q0 = dFdx(-vViewPosition), q1 = dFdy(-vViewPosition);\n  vec2 st0 = dFdx(waveP), st1 = dFdy(waveP);\n  vec3 tangent = normalize(q0 * st1.y - q1 * st0.y);\n  vec3 bitangent = normalize(-q0 * st1.x + q1 * st0.x);\n  vec2 slope = field.yz;\n  if (ncaOceanGPUReady < 0.5) slope *= 1.0 - smoothstep(800.0, 2500.0, length(waveP));\n  float oceanCrestSteepness = length(slope);\n  slope += capillary.xy;\n  // Back faces carry the flipped geometric normal; flip the slope term too.\n  float oceanFace = gl_FrontFacing ? 1.0 : -1.0;\n  normal = normalize(normal - oceanFace * (tangent * slope.x + bitangent * slope.y));\n  // Breaking crests (Jacobian folds), shaded by the same lights.\n  float foam = clamp(field.w, 0.0, 1.0) * smoothstep(-0.6, 0.7, capillary.w);\n  diffuseColor.rgb = mix(diffuseColor.rgb, vec3(0.65), foam);\n  roughnessFactor = mix(roughnessFactor, 0.8, foam);\n  float ncaOceanSunTransmission = 1.0;\n  vec3 ncaOceanDirectSunRadiance = ncaOceanSunRadiance;\n  vec3 ncaOceanDiffuseSkyRadiance = vec3(0.0);\n  #ifdef NCA_OCEAN_CLOUD_READY\n  // Query downwelling illumination with the above-water normal even while\n  // shading the underside; Snell's window must retain the actual Sun.\n  ncaOceanCloudLighting(vOceanWorld, inverseTransformDirection(normal * oceanFace, viewMatrix),\n    ncaOceanDirectSunRadiance, ncaOceanDiffuseSkyRadiance, ncaOceanSunTransmission);\n  #endif`)\n                .replace('#include <lights_physical_pars_fragment>', `#include <lights_physical_pars_fragment>\\n${OCEAN_CLOUD_LIGHTING_GLSL}`)\n                .replace('#include <lights_fragment_begin>', THREE.ShaderChunk.lights_fragment_begin.replace(\n                    'getDirectionalLightInfo( directionalLight, directLight );',\n                    `getDirectionalLightInfo( directionalLight, directLight );\n  #ifdef NCA_OCEAN_CLOUD_READY\n  // Only the solar directional lane shares this Sun-ray cloud query. Keep\n  // unrelated authored directional lights on their original lighting path.\n  if (dot(directLight.direction, normalize(ncaOceanSunView)) > 0.99999) {\n    directLight.color = ncaOceanDirectSunRadiance * ncaOceanSunTransmission;\n  }\n  #endif`))\n                .replace('#include <lights_fragment_maps>', `#ifdef NCA_OCEAN_CLOUD_READY\n  // Keep Three's full dielectric/clearcoat BRDF. Its environment input now\n  // comes from current sky irradiance and the reflected cloud field.\n  iblIrradiance = ncaOceanDiffuseSkyRadiance * PI;\n  radiance = ncaOceanDiffuseSkyRadiance;\n  clearcoatRadiance = ncaOceanDiffuseSkyRadiance;\n  #else\n  #include <lights_fragment_maps>\n  #endif`)\n                .replace('#include <opaque_fragment>', OCEAN_OPTICS_FRAGMENT + `\n#ifdef NCA_OCEAN_CLOUD_READY\n// The sea composites after the atmosphere pass: apply its own aerial perspective.\nif (ncaOceanSubmerged < 0.5) outgoingLight = ncaOceanAerial(vOceanWorld, outgoingLight, ncaOceanDiffuseSkyRadiance);\n#endif\n#include <opaque_fragment>`);\n            // The fragment GPU branch uses the displaced vertex height plus\n            // slope/foam maps and displacement-alpha focus. Constant readiness\n            // removes the unused analytic wave branch; all vertex waves remain.\n            shader.fragmentShader = shader.fragmentShader.replace('uniform float ncaOceanGPUReady;', '')\n                .replaceAll('ncaOceanGPUReady', this._gpuFragmentReady ? '1.0' : '0.0');\n        };\n        this.material.customProgramCacheKey = () => `nca-curved-sea-level-gpu-optics-v15-reciprocal-reflection-depth-${tier}-${this._gpuFragmentReady ? 'gpu' : 'analytic'}-${this._cloudLightingKey || 'none'}`;\n        this.depthMaterial = new THREE.ShaderMaterial({\n            name: 'Ocean.CloudSceneDepth', uniforms: this.uniformsLocal,\n            vertexShader: OCEAN_DEPTH_VERTEX_GLSL,\n            fragmentShader: `#include <common>\n#include <logdepthbuf_pars_fragment>\nvarying vec3 vOceanLocal;\n${WATER_COVERAGE_GLSL}\nvoid main(){\n  if(ncaWaterCoverage(vOceanLocal).y<.5)discard;\n  #include <logdepthbuf_fragment>\n  gl_FragColor=vec4(0.0);\n}`,\n            colorWrite:false, depthWrite:true, depthTest:true, side:THREE.DoubleSide,\n            toneMapped:false, blending:THREE.NoBlending,\n        });\n        this.mesh = new THREE.Mesh(this.geometry, this.material);\n        this.mesh.name = 'SeaLevelOcean'; this.mesh.frustumCulled = false;\n        // Selecting/moving follows the terrain and entities below/above water.\n        this.mesh.userData.noOcclusion = true;\n        this.mesh.userData.lensflare = 'no-occlusion';\n        this.mesh.raycast = () => {};\n        parent.add(this.mesh); this.mesh.visible = false;\n        this.particulate = tier === 'full' ? new OceanParticulate({ parent, uniforms: this.uniformsLocal }) : null;\n    }\n    /** Chlorophyll (mg/m³) sets absorption, scattering and visibility; see ocean-water-optics.js. */\n    setWaterClarity(chlorophyll) {\n        this.optics = computeWaterOptics(chlorophyll);\n    }\n    setSeaState({ windSpeed = this.windSpeed ?? 8, windDirection } = {}) {\n        if (!Number.isFinite(windSpeed)) return;\n        const wind = Math.round(THREE.MathUtils.clamp(windSpeed, 0, 25) * 2) / 2;\n        // Meteorological direction is where wind comes FROM, clockwise from\n        // north; waves travel downwind, measured counter-clockwise from east.\n        const heading = Number.isFinite(windDirection)\n            ? Math.round(THREE.MathUtils.euclideanModulo(Math.PI / 2 - THREE.MathUtils.degToRad(windDirection + 180), Math.PI * 2) * 36 / Math.PI) * Math.PI / 36\n            : (this.windHeading ?? 0.5);\n        if (this.windSpeed === wind && this.windHeading === heading) return;\n        this.windSpeed = wind; this.windHeading = heading;\n        this.spectrum = createOceanSpectrum({ windSpeed: wind, windDirection: heading });\n        this.gpu?.setSeaState({ windSpeed: wind, windDirection: heading });\n        this.uniformsLocal.ncaOceanWindVector.value.set(Math.cos(heading), Math.sin(heading)).multiplyScalar(Math.max(0.5, wind));\n        this.updateBaseRoughness();\n        // Force one bounded patch update, retaining the planet-fixed phase frame.\n        this.previousCenter.set(Infinity, 0, 0);\n    }\n    // Slopes finer than the smallest cascade wavelength widen the specular\n    // lobe: Beckmann α² = Cox–Munk variance minus the explicitly resolved part.\n    updateBaseRoughness() {\n        const total = coxMunkSlopeVariance(this.windSpeed ?? 8);\n        const resolved = this.gpu?.slopeVariance ?? 0;\n        this.uniformsLocal.ncaOceanBaseRoughness.value = Math.sqrt(Math.max(0.0004, total - resolved));\n    }\n    disturb(localPosition, strength = 0.08) {\n        if (!this.mesh.visible || !localPosition) return;\n        this.point.copy(localPosition).sub(this.center);\n        const index = this.rippleIndex++ % this.ripples.length;\n        this.rippleWorlds[index].copy(localPosition);\n        this.ripples[index].set(\n            this.point.dot(this.east), this.point.dot(this.north),\n            this.uniforms.waterTime.value, THREE.MathUtils.clamp(strength, 0, 0.4));\n    }\n    ensureGPU() {\n        if (this.gpu || this.gpuUnavailable) return;\n        if (!canRunOceanCascades(this.renderer)) { this.gpuUnavailable = true; return; }\n        try {\n            const sizes = compactDevice() ? [128, 128, 64] : [256, 256, 128];\n            this.gpu = new OceanGPUCascades(this.renderer, { sizes, windSpeed: this.windSpeed ?? 8, windDirection: this.windHeading ?? 0.5 });\n            const u = this.uniformsLocal;\n            u.ncaOceanCascadeSize.value.set(...sizes);\n            this.gpu.cascades.forEach((cascade, i) => { u[`ncaOceanDisp${i}`].value = cascade.focus.texture; });\n            this.updateBaseRoughness();\n        } catch { this.gpuUnavailable = true; this.gpu = null; } // Analytic field remains available.\n    }\n    releaseGPU() {\n        this.gpu?.dispose(); this.gpu = null;\n        this.uniformsLocal.ncaOceanGPUReady.value = 0;\n        this._setGPUFragmentReady(false);\n        this._gpuVariantProbe?.material?.dispose();\n        this._gpuVariantProbe = null;\n        this._gpuVariantWarm = false;\n    }\n    /**\n     * The GPU-ready fragment variant is a separate program (constant\n     * readiness removes the analytic branch). Compile it asynchronously on a\n     * probe clone that shares the program cache key, so flipping the real\n     * material reuses an already linked program instead of linking mid-frame.\n     */\n    _warmGPUVariant() {\n        if (this._gpuVariantWarm) return true;\n        if (this._gpuVariantPending || typeof this.renderer?.compileAsync !== 'function') {\n            if (typeof this.renderer?.compileAsync !== 'function') this._gpuVariantWarm = true;\n            return this._gpuVariantWarm === true;\n        }\n        const probe = new THREE.Mesh(this.geometry, this.material.clone());\n        probe.frustumCulled = false;\n        const previous = this._gpuFragmentReady;\n        let pending;\n        // compileAsync builds programs synchronously before it returns, so the\n        // flag only needs to read \"gpu\" for this call.\n        this._gpuFragmentReady = true;\n        try { pending = this.renderer.compileAsync(probe, this._warmCamera ||= new THREE.PerspectiveCamera()); }\n        catch { pending = null; }\n        finally { this._gpuFragmentReady = previous; }\n        this._gpuVariantPending = true;\n        // Keep the probe alive: three frees a program once no material uses\n        // it, which would discard the linked variant before the switch.\n        this._gpuVariantProbe = probe;\n        Promise.resolve(pending).catch(() => {}).finally(() => {\n            this._gpuVariantWarm = true;\n            this._gpuVariantPending = false;\n        });\n        return false;\n    }\n    _setGPUFragmentReady(ready) {\n        if (this._gpuFragmentReady === (ready === true)) return;\n        this._gpuFragmentReady = ready === true;\n        this.material.needsUpdate = true;\n    }\n    setAtmosphereLighting(aerial, resolution) {\n        const state = syncOceanCloudLightingUniforms(this.uniformsLocal, aerial, { resolution });\n        if (state.key !== this._cloudLightingKey) {\n            this._cloudLightingKey = state.key;\n            this.material.defines = { ...(this.tier === 'full' ? {} : { OCEAN_BASIC: '' }), ...state.defines };\n            this.material.needsUpdate = true;\n        }\n    }\n    updateLight(state) {\n        const u = this.uniformsLocal, optics = this.optics;\n        // sunDirection is world-space; compare with the world-space local up.\n        this.sunWorld.copy(this.uniforms.sunDirection?.value || this.up).normalize();\n        const sunCos = this.sunWorld.dot(this.point.copy(this.up).transformDirection(this.parent.matrixWorld));\n        const sun = this.sunLight;\n        const radiance = sun ? [sun.color.r * sun.intensity, sun.color.g * sun.intensity, sun.color.b * sun.intensity] : [3.4, 3.4, 3.4];\n        this.light = oceanSubsurfaceLight(optics, { sunCosZenith: sunCos, sunRadiance: radiance });\n        this.light.sunCosZenith = sunCos;\n        u.ncaOceanSunRadiance.value.set(...radiance);\n        u.ncaOceanWaterC.value.set(...optics.attenuation);\n        u.ncaOceanWaterKd.value.set(...optics.diffuseAttenuation);\n        // Upwelling radiance of the water body just below the surface: Rrs·Ed.\n        u.ncaOceanWaterBody.value.set(...this.light.irradiance.map((e, i) => e * this.light.reflectance[i]));\n        u.ncaOceanWaterDirectBody.value.set(...this.light.direct.map((e, i) => e * this.light.reflectance[i]));\n        u.ncaOceanWaterReflectance.value.set(...this.light.reflectance);\n        u.ncaOceanSubmerged.value = state?.underwater === true ? 1 : 0;\n    }\n    update(state, { rendering = true } = {}) {\n        this.parent.updateWorldMatrix(true, false);\n        this.camera.getWorldPosition(this.cameraLocal);\n        this.parent.worldToLocal(this.cameraLocal);\n        this.up.copy(this.cameraLocal).normalize();\n        const ellipsoidRadius = ellipsoidRadiusForLocalDir(this.up);\n        // Geometry and terrain use WGS84 heights, not an ellipsoid mistaken\n        // for mean sea level. Keep the sea hidden until the shared datum is\n        // known; otherwise a loading frame can flood tens of metres of land.\n        if (this.waterLevel) this.waterLevel.load();\n        const level = this.waterLevel?.sampleDirection(this.up);\n        const datumReady = !this.waterLevel || !!level;\n        this.level = level;\n        const meanHeight = level?.meanSeaLevelEllipsoidMeters || 0;\n        const tide = level?.tideMeters || 0;\n        const radius = ellipsoidRadius + meanHeight + tide;\n        const altitude = this.cameraLocal.length() - radius;\n        if (this.uniforms.waterMaskEnabled) this.uniforms.waterMaskEnabled.value = this.uniforms.specularTexture.value ? 1 : 0;\n        this.mesh.visible = this.uniforms.waterEnabled.value > 0.5\n            && (!!this.uniforms.specularTexture.value || this.uniforms.regionalWaterEnabled.value > 0.5)\n            && altitude < 15000 && datumReady;\n        if (this.uniforms.seaLevelRadius) this.uniforms.seaLevelRadius.value = radius;\n        if (!this.mesh.visible) {\n            if (this.uniforms.seaSurfaceActive) this.uniforms.seaSurfaceActive.value = 0;\n            this.releaseGPU(); this.particulate?.update(null); return;\n        }\n        // Structural HD has a different final-frame owner. Keep the physical\n        // clock, tide, navigation and CPU wave anchor live, while retaining the\n        // exact native FFT resources for the next native draw.\n        if (rendering) this.ensureGPU();\n        if (rendering && this.gpu) {\n            this.gpu.update(this.uniforms.waterTime.value * 4, THREE.MathUtils.clamp(this.uniforms.waterDistortion.value, 0, 2));\n            const u = this.uniformsLocal;\n            this.gpu.cascades.forEach((cascade, i) => {\n                u[`ncaOceanSlope${i}`].value = cascade.slope.texture;\n            });\n            // Switch to the GPU variant only once its program is linked.\n            const gpuReady = this.gpu.ready && this._warmGPUVariant();\n            u.ncaOceanGPUReady.value = gpuReady ? 1 : 0;\n            this._setGPUFragmentReady(gpuReady);\n        }\n        if (this.uniforms.seaSurfaceActive) this.uniforms.seaSurfaceActive.value = this.uniformsLocal.ncaOceanGPUReady.value;\n        if (this.extent && state?.swimming && this.cameraLocal.distanceToSquared(this.lastSwimmer) > 0.8 ** 2\n            && this.uniforms.waterTime.value - (this.lastRippleAt || -1) > 0.05) {\n            this.disturb(this.cameraLocal); this.lastRippleAt = this.uniforms.waterTime.value;\n            this.lastSwimmer.copy(this.cameraLocal);\n        }\n        this.uniformsLocal.ncaOceanMaskEnabled.value = this.uniforms.specularTexture.value ? 1 : 0;\n        // An ocean verdict at one point says nothing about neighbouring dry\n        // land. Never promote a 6 km circle through the geographic mask.\n        if (this.uniforms.seaConfirmedRadius) this.uniforms.seaConfirmedRadius.value = 0;\n        this.updateLight(state);\n        this.particulate?.update(state?.underwater ? { cameraLocal: this.cameraLocal, up: this.up, depth: Math.max(0, -altitude), time: this.uniforms.waterTime.value * 4 } : null);\n        this.center.copy(this.up).multiplyScalar(ellipsoidRadius + meanHeight);\n        const extent = THREE.MathUtils.clamp(Math.sqrt(2 * radius * Math.max(Math.abs(altitude), 2)) * 1.2, 12000, 450000);\n        // Recentre often enough that the dense rings stay under a swimmer.\n        const recentre = THREE.MathUtils.clamp(Math.abs(altitude) * 0.25, 3, 100);\n        if (this.previousCenter.distanceToSquared(this.center) < recentre * recentre\n            && Math.abs((this.extent || 0) - extent) < extent * 0.05) {\n            // Retain the mesh's basis as well as its origin while idle.\n            this.up.copy(this.patchUp);\n            this.center.copy(this.patchMeanCenter).addScaledVector(this.up, tide);\n            this.mesh.position.copy(this.center);\n            return;\n        }\n        this.extent = extent; this.previousCenter.copy(this.center);\n        this.patchMeanCenter.copy(this.center); this.patchUp.copy(this.up);\n        this.center.addScaledVector(this.up, tide);\n        this.east.crossVectors(new THREE.Vector3(0, 1, 0), this.up);\n        if (this.east.lengthSq() < 1e-8) this.east.set(1, 0, 0); else this.east.normalize();\n        this.north.crossVectors(this.up, this.east).normalize();\n        // Fix the wave field in the planet frame, rather than scrolling it\n        // with the patch. Reduce phase in CPU double precision for the GPU.\n        if (!this.waveFrameReady) {\n            this.waveFrameEast.copy(this.east); this.waveFrameNorth.copy(this.north);\n            this.waveFrameReady = true;\n        }\n        const originX = this.center.dot(this.waveFrameEast), originY = this.center.dot(this.waveFrameNorth);\n        OCEAN_CASCADES.forEach((cascade, i) => this.uniformsLocal.ncaOceanCascadeOrigin.value[i].set(\n            (originX % cascade.length) / cascade.length, (originY % cascade.length) / cascade.length));\n        this.uniformsLocal.ncaOceanFFTMatrix.value.set(this.east.dot(this.waveFrameEast), this.north.dot(this.waveFrameEast),\n            this.east.dot(this.waveFrameNorth), this.north.dot(this.waveFrameNorth));\n        for (let i = 0; i < this.spectrum.length; i++) {\n            const wave = this.spectrum[i];\n            this.point.copy(this.waveFrameEast).multiplyScalar(wave.kx).addScaledVector(this.waveFrameNorth, wave.ky);\n            const phase = wave.phase + this.point.dot(this.center);\n            this.uniformsLocal.ncaOceanWaves.value[i].set(this.point.dot(this.east), this.point.dot(this.north), wave.amplitude, wave.omega);\n            this.wavePhases[i].x = phase % (2 * Math.PI);\n        }\n        for (let i = 0; i < this.ripples.length; i++) {\n            this.point.copy(this.rippleWorlds[i]).sub(this.center);\n            this.ripples[i].x = this.point.dot(this.east); this.ripples[i].y = this.point.dot(this.north);\n        }\n        const positions = this.geometry.attributes.position;\n        for (let i = 0; i < positions.count; i++) {\n            // Concentrate topology at the observer; metre-scale waves should\n            // not alias against a uniformly spaced kilometre-scale grid.\n            const x = Math.pow(this.grid[i * 3], 3) * extent;\n            const y = Math.pow(this.grid[i * 3 + 1], 3) * extent;\n            this.point.copy(this.center).addScaledVector(this.east, x).addScaledVector(this.north, y).normalize();\n            let pointMeanHeight = meanHeight;\n            if (this.waterLevel) {\n                const { latDeg, lonDeg } = dirToLatLonLocal(this.point, this.geo);\n                pointMeanHeight = this.waterLevel.meanHeight(latDeg, lonDeg) ?? meanHeight;\n            }\n            this.point.multiplyScalar(ellipsoidRadiusForLocalDir(this.point) + pointMeanHeight + tide).sub(this.center);\n            positions.setXYZ(i, this.point.x, this.point.y, this.point.z);\n            this.spacing.setX(i, Math.max(0.1, 3 * Math.max(this.grid[i * 3] ** 2,\n                this.grid[i * 3 + 1] ** 2) * extent * 2 / this.segments));\n        }\n        this.spacing.needsUpdate = true;\n        positions.needsUpdate = true; this.geometry.computeVertexNormals();\n        this.mesh.position.copy(this.center);\n    }\n    dispose() {\n        this.releaseGPU(); this.particulate?.dispose();\n        this.mesh.removeFromParent(); this.geometry.dispose(); this.material.dispose(); this.depthMaterial.dispose();\n    }\n}\n","/**\n * StreamedImageTexture — load a large image texture with no main-thread\n * stall: decode to raw pixels in a worker, then upload a band of rows per\n * frame (Three's DataTexture update ranges; on the texStorage path even the\n * first allocation uploads only the ranges given). Resolves with the texture\n * once every row is on the GPU, so it is never drawn half-filled.\n *\n * An 8192×4096 <img> texture otherwise decodes + uploads inside the first\n * frame that draws it: 200-730 ms for the Earth specular and live cloud maps.\n */\nimport * as THREE from 'three';\n\nconst DEFAULT_BYTES_PER_FRAME = 2 * 1024 * 1024;\nlet worker = null;\nlet nextId = 1;\nconst pending = new Map();\n\nexport function canStreamImageTextures() {\n  return typeof Worker === 'function' && typeof OffscreenCanvas === 'function' && typeof createImageBitmap === 'function';\n}\n\nfunction decode(url, channels, workerFactory) {\n  if (!worker) {\n    worker = workerFactory ? workerFactory() : new Worker(new URL('./image-decode.worker.js', import.meta.url), { type: 'module' });\n    worker.onmessage = (event) => {\n      const { id } = event.data || {};\n      const entry = pending.get(id);\n      if (!entry) return;\n      pending.delete(id);\n      if (event.data.error) entry.reject(new Error(event.data.error));\n      else entry.resolve(event.data);\n    };\n    worker.onerror = (event) => {\n      for (const entry of pending.values()) entry.reject(new Error(event?.message || 'image decode worker failed'));\n      pending.clear();\n      worker?.terminate?.();\n      worker = null;\n    };\n  }\n  const id = nextId++;\n  const absolute = new URL(url, globalThis.location?.href || 'http://localhost/').href;\n  return new Promise((resolve, reject) => {\n    pending.set(id, { resolve, reject });\n    worker.postMessage({ id, url: absolute, channels });\n  });\n}\n\n/** Rows per frame for a byte budget (at least one). */\nexport function rowsPerBand(width, channels, bytesPerFrame = DEFAULT_BYTES_PER_FRAME) {\n  return Math.max(1, Math.floor(bytesPerFrame / Math.max(1, width * channels)));\n}\n\n/**\n * Upload `texture` (a DataTexture whose data is complete) in row bands.\n * @returns {Promise<THREE.DataTexture>}\n */\nexport function streamTextureRows(texture, { renderer, channels = 4, bytesPerFrame = DEFAULT_BYTES_PER_FRAME, nextFrame = (fn) => requestAnimationFrame(fn) } = {}) {\n  const { width, height } = texture.image;\n  const band = rowsPerBand(width, channels, bytesPerFrame);\n  // Update ranges are counted in RGBA components (×4 per texel) regardless\n  // of format; Three converts them back to texel rows.\n  const rangeCount = width * 4;\n  // Never change generateMipmaps / filters / format between bands: they are\n  // part of Three's texture cache key, and a changed key allocates a fresh\n  // GPU texture, discarding the rows already uploaded (the streamed cloud\n  // map ended up holding only its first band).\n  let row = 0;\n  return new Promise((resolve, reject) => {\n    const step = () => {\n      try {\n        const end = Math.min(height, row + band);\n        for (let r = row; r < end; r++) texture.addUpdateRange(r * width * 4, rangeCount);\n        texture.needsUpdate = true;\n        renderer.initTexture(texture);\n        row = end;\n        if (row >= height) { resolve(texture); return; }\n        nextFrame(step);\n      } catch (error) { reject(error); }\n    };\n    nextFrame(step);\n  });\n}\n\n/**\n * @param {string} url\n * @param {{ renderer: THREE.WebGLRenderer, channels?: 1|4, configure?: (t) => void,\n *           bytesPerFrame?: number, workerFactory?: () => Worker }} o\n * @returns {Promise<THREE.DataTexture>}\n */\nexport async function loadStreamedImageTexture(url, { renderer, channels = 4, configure = null, bytesPerFrame, workerFactory } = {}) {\n  const { width, height, data } = await decode(url, channels, workerFactory);\n  const pixels = new Uint8Array(data);\n  const texture = new THREE.DataTexture(pixels, width, height, channels === 1 ? THREE.RedFormat : THREE.RGBAFormat, THREE.UnsignedByteType);\n  if (channels === 1) texture.internalFormat = 'R8';\n  texture.flipY = false;\n  texture.generateMipmaps = true;\n  texture.minFilter = THREE.LinearMipmapLinearFilter;\n  texture.magFilter = THREE.LinearFilter;\n  configure?.(texture);\n  texture.userData.streamed = true;\n  return streamTextureRows(texture, { renderer, channels, bytesPerFrame });\n}\n","/**\n * StagedDataTexture — replace a large RGBA DataTexture without a frame stall.\n *\n * Creating a new DataTexture for each update makes the next frame that draws\n * it allocate GPU storage and upload every byte at once (a 1536² atlas is\n * 9.4 MB: 30-220 ms on the main thread). Instead two persistent textures are\n * kept: new pixels are written into the hidden one and uploaded a band of\n * rows per frame through Three's row update ranges, then it is swapped in\n * whole — consumers switch to the new content (and its bounds) atomically.\n * Each texture's very first upload still allocates once, at its first use.\n */\nimport * as THREE from 'three';\n\nexport class StagedDataTexture {\n  /**\n   * @param {object} o\n   * @param {THREE.WebGLRenderer} o.renderer\n   * @param {number} o.size                 width = height, texels\n   * @param {(t: THREE.DataTexture) => void} [o.configure]  filters / colour space / name\n   * @param {number} [o.rowsPerFrame=128]\n   */\n  constructor({ renderer, size, configure = null, rowsPerFrame = 128 }) {\n    this.renderer = renderer;\n    this.size = size;\n    this.rowsPerFrame = Math.max(1, rowsPerFrame);\n    this.textures = [0, 1].map(() => {\n      const texture = new THREE.DataTexture(new Uint8Array(size * size * 4), size, size, THREE.RGBAFormat);\n      texture.generateMipmaps = false;\n      texture.flipY = false;\n      configure?.(texture);\n      return texture;\n    });\n    this.allocated = [false, false];\n    this.frontIndex = -1;\n    this.pending = null; // { index, row, onCommit }\n  }\n\n  /** The texture currently shown (null before the first commit). */\n  get front() { return this.frontIndex >= 0 ? this.textures[this.frontIndex] : null; }\n\n  get staging() { return !!this.pending; }\n\n  /** Begin replacing the content; `onCommit(texture)` runs when it is live. */\n  stage(pixels, onCommit) {\n    if (!(pixels?.length === this.size * this.size * 4)) return false;\n    const index = this.frontIndex === 0 ? 1 : 0;\n    const texture = this.textures[index];\n    texture.image.data.set(pixels);\n    texture.clearUpdateRanges();\n    this.pending = { index, row: 0, onCommit };\n    return true;\n  }\n\n  /** Upload the next band of rows; call once per frame. */\n  pump() {\n    const pending = this.pending;\n    if (!pending) return;\n    const texture = this.textures[pending.index];\n    if (!this.allocated[pending.index]) {\n      // First use of this buffer: allocate + upload once, then it is ready.\n      texture.needsUpdate = true;\n      this._upload(texture);\n      this.allocated[pending.index] = true;\n      this._commit();\n      return;\n    }\n    const rowBytes = this.size * 4;\n    const end = Math.min(this.size, pending.row + this.rowsPerFrame);\n    for (let row = pending.row; row < end; row++) texture.addUpdateRange(row * rowBytes, rowBytes);\n    pending.row = end;\n    texture.needsUpdate = true;\n    this._upload(texture);\n    if (pending.row >= this.size) this._commit();\n  }\n\n  _upload(texture) {\n    try { this.renderer?.initTexture?.(texture); } catch { /* uploads on first draw instead */ }\n  }\n\n  _commit() {\n    const { index, onCommit } = this.pending;\n    this.pending = null;\n    this.frontIndex = index;\n    onCommit?.(this.textures[index]);\n  }\n\n  cancel() { this.pending = null; }\n\n  dispose() {\n    this.pending = null;\n    for (const texture of this.textures) texture.dispose();\n    this.frontIndex = -1;\n  }\n}\n","import * as THREE from 'three';\nimport { getMapTileApiBase } from '../shared/backend.js';\nimport { waterTileWindow, bathymetryTileWindow, sampleWaterAtlas } from '../../modules/water-coverage.js';\nimport { StagedDataTexture } from '../render/StagedDataTexture.js';\n\nconst configureCoverage = (texture) => {\n    texture.name = 'Mapsource.WaterCoverage'; texture.colorSpace = THREE.NoColorSpace;\n    texture.minFilter = THREE.LinearFilter; texture.magFilter = THREE.LinearFilter;\n};\nconst configureBed = (texture) => {\n    texture.name = 'Mapsource.Bathymetry'; texture.colorSpace = THREE.NoColorSpace;\n    texture.minFilter = texture.magFilter = THREE.LinearFilter;\n};\n\n/** Shared coastal/inland geography: one worker and one bounded 3×3 water atlas. */\nexport class RegionalWaterMask {\n    /**\n     * With `renderer`, atlas replacements stream into persistent textures a\n     * band of rows per frame and swap in whole (StagedDataTexture). A fresh\n     * 1536² DataTexture per window otherwise uploads 9.4 MB in one frame —\n     * the recurring 30-220 ms render-loop freeze while moving.\n     */\n    constructor(uniforms, { tileSize = 512, renderer = null, workerFactory = () => new Worker(\n        new URL('./regional-water.worker.js', import.meta.url), { type: 'module' }),\n    } = {}) {\n        Object.assign(this, { uniforms, tileSize, workerFactory });\n        this.staged = renderer ? {\n            coverage: new StagedDataTexture({ renderer, size: tileSize * 3, configure: configureCoverage }),\n            bed: new StagedDataTexture({ renderer, size: 768, configure: configureBed }),\n        } : null;\n        this.generation = 0; this.requested = null; this.disposed = false;\n        this.stats = { requested: 0, admitted: 0, failed: 0 };\n    }\n    update(latitude, longitude, altitude) {\n        if (this.disposed) return;\n        this.staged?.coverage.pump();\n        this.staged?.bed.pump();\n        if (typeof location === 'undefined' || altitude > 1e7) return;\n        const window = waterTileWindow(latitude, longitude, altitude, this.tileSize);\n        const bed = bathymetryTileWindow(latitude, longitude, altitude);\n        const key = window && bed ? `${window.key}|bed:${bed.key}` : null;\n        if (!key || key === this.requested || performance.now() < (this.retryAt || 0)) return;\n        try {\n            if (!this.worker) {\n                this.worker = this.workerFactory();\n                this.worker.onmessage = event => this.admit(event.data);\n                this.worker.onerror = () => {\n                    this.stats.failed++; this.worker?.terminate(); this.worker = null;\n                    this.requested = null; this.retryAt = performance.now() + 30000;\n                };\n            }\n            this.requested = key;\n            const generation = ++this.generation;\n            const base = new URL(`${getMapTileApiBase()}/tiles/vector/`, location.href).href;\n            const terrainBase = new URL(`${getMapTileApiBase()}/v1/maps/terrain/`, location.href).href;\n            this.worker.postMessage({ ...window, generation, base, bed, terrainBase }); this.stats.requested++;\n        } catch { this.requested = null; this.retryAt = performance.now() + 30000; }\n    }\n    admit(result) {\n        if (this.disposed || result.generation !== this.generation) return;\n        if (result.kind === 'bathymetry') {\n            const pixels = result.pixels && new Uint8Array(result.pixels), size = 768;\n            if (!result.loaded || result.size !== size || pixels?.byteLength !== size*size*4\n                || result.bounds?.length !== 4 || !result.bounds.every(Number.isFinite)) {\n                this.stats.depthFailed = (this.stats.depthFailed || 0)+1;\n                this.requested = null; this.retryAt = performance.now()+30000; return;\n            }\n            const applyBed = (texture) => {\n                this.uniforms.waterBedTexture.value=texture;\n                this.uniforms.waterBedBounds.value.fromArray(result.bounds); this.uniforms.waterBedEnabled.value=1;\n                this.stats.depthLoadedTiles=result.loaded;\n            };\n            if (this.staged) { this.staged.bed.stage(pixels, (texture) => { this.bedTexture = texture; applyBed(texture); }); return; }\n            const texture = new THREE.DataTexture(pixels,size,size,THREE.RGBAFormat);\n            configureBed(texture);\n            texture.generateMipmaps=false; texture.flipY=false; texture.needsUpdate=true;\n            this.bedTexture?.dispose(); this.bedTexture=texture;\n            applyBed(texture); return;\n        }\n        if (result.error || !result.loaded) {\n            this.stats.failed++; this.requested = null; this.retryAt = performance.now() + 30000; return;\n        }\n        const size = this.tileSize * 3, pixels = new Uint8Array(result.pixels);\n        if (result.size !== size || pixels.byteLength !== size * size * 4\n            || result.bounds?.length !== 4 || !result.bounds.every(Number.isFinite)) return;\n        // Retain the last paired geography/heights until its replacement is\n        // complete. A vector-first arrival must not blink existing glint off.\n        if(this.texture && this.uniforms.waterSurfaceHeightEnabled.value>0.5\n            && !Object.hasOwn(result,'surfaceHeightRange'))return;\n        // Retry scheduling follows arrival, as before; uniforms follow commit.\n        if (this.staged && result.loaded < 9) { this.requested = null; this.retryAt = performance.now() + 30000; }\n        if (this.staged) {\n            const window = this.requested;\n            this.staged.coverage.stage(pixels, (texture) => this._applyCoverage(texture, pixels, result, null, window));\n            return;\n        }\n        const texture = new THREE.DataTexture(pixels, size, size, THREE.RGBAFormat);\n        configureCoverage(texture);\n        texture.generateMipmaps = false; texture.flipY = false; texture.needsUpdate = true;\n        this._applyCoverage(texture, pixels, result, this.texture, this.requested);\n        if (result.loaded < 9) { this.requested = null; this.retryAt = performance.now() + 30000; }\n    }\n    _applyCoverage(texture, pixels, result, previous, window) {\n        const size = this.tileSize * 3;\n        this.texture = texture; this.atlas = { pixels, bounds: result.bounds, size };\n        this.uniforms.regionalWaterMask.value = texture;\n        this.uniforms.regionalWaterBounds.value.fromArray(result.bounds);\n        // Binary slippy-map bounds give an exact atlas-centre UV. Keep the\n        // geographic basis in CPU double precision, then project small local\n        // differences on the GPU instead of cancelling large world UVs.\n        const longitude = (result.bounds[0] + result.bounds[2] * 0.5 - 0.5) * Math.PI * 2;\n        const latitude = Math.atan(Math.sinh(Math.PI * (1 - 2 * (result.bounds[1] + result.bounds[3] * 0.5))));\n        const sl = Math.sin(longitude), cl = Math.cos(longitude), s = Math.sin(latitude), c = Math.cos(latitude);\n        this.uniforms.waterLocalFrame.value.set(cl,0,-sl, -s*sl,c,-s*cl, c*sl,s,c*cl);\n        this.uniforms.waterLocalLatitude.value.set(s,c);\n        const heightRange=result.surfaceHeightRange;\n        const hasHeights=heightRange?.length===2 && heightRange.every(Number.isFinite) && heightRange[1]>0 && heightRange[1]<=1;\n        this.uniforms.waterSurfaceHeightEnabled.value=hasHeights?1:0;\n        if(hasHeights)this.uniforms.waterSurfaceHeightRange.value.fromArray(heightRange);\n        this.stats.surfaceHeightStepMeters=hasHeights?heightRange[1]:null;\n        this.uniforms.regionalWaterEnabled.value = 1;\n        if (previous && previous !== texture) previous.dispose();\n        this.stats.admitted++;\n        this.stats.loadedTiles = result.loaded; this.stats.window = window;\n    }\n    sample(latitude, longitude) { return sampleWaterAtlas(this.atlas, latitude, longitude); }\n    suspend() {\n        this.generation++; this.worker?.terminate(); this.worker = null; this.requested = null;\n        this.staged?.coverage.cancel(); this.staged?.bed.cancel();\n    }\n    dispose() {\n        this.disposed = true; this.suspend();\n        this.uniforms.regionalWaterEnabled.value = 0; this.uniforms.regionalWaterMask.value = null;\n        this.uniforms.waterSurfaceHeightEnabled.value=0;\n        if (this.staged) { this.staged.coverage.dispose(); this.staged.bed.dispose(); }\n        else { this.texture?.dispose(); this.bedTexture?.dispose(); }\n        this.texture = null; this.atlas = null; this.bedTexture=null;\n        this.uniforms.waterBedEnabled.value=0; this.uniforms.waterBedTexture.value=null;\n    }\n}\n","/**\n * SceneClock — single canonical timeline driving every temporal subsystem\n * in the scene. Modes:\n *   - 'live'  → tracks wall clock (real time)\n *   - 'fixed' → frozen at a specific epoch\n *   - 'play'  → advances at speed × wall-clock\n *\n * Subscribers receive `clock:tick` events at the current rAF cadence\n * with the latest scene-time. Mode/seek transitions emit dedicated\n * events. Used by:\n *   - lighting-system  (sun position)\n *   - imagery-manager  (Wayback historical scrubbing)\n *   - AircraftOverlay  (ADS-B history replay)\n *   - SatelliteOverlay (TLE propagation at scene-time)\n *   - IncidentOverlay  (temporal filter)\n *   - WeatherRadarOverlay (radar replay — WO-025)\n *   - SatelliteImageryOverlay (time-series — WO-026)\n *\n * Visibility-handler integration: in 'live' mode the clock advances at\n * wall-clock pace even while the tab is hidden (so on resume the time\n * matches reality). In 'fixed' or 'play' mode the clock is frozen\n * during tab-hidden so playback resumes from the same scene-time.\n */\n\nconst _listeners = new Set();\nconst _emitters = new Set();\n\nclass SceneClockImpl {\n  constructor() {\n    // Scene time in milliseconds since epoch.\n    this._sceneTimeMs = Date.now();\n    // Wall-clock anchor for 'play' / 'live' mode integration.\n    this._wallAnchorMs = performance.now();\n    this._sceneAnchorMs = this._sceneTimeMs;\n    this._mode = 'live';\n    this._speed = 1;\n    this._tabHidden = false;\n\n    if (typeof document !== 'undefined' && document.addEventListener) {\n      document.addEventListener('visibilitychange', () => {\n        const hidden = document.visibilityState === 'hidden';\n        // When transitioning from hidden→visible while in fixed/play mode,\n        // re-anchor so the next tick sees a normal delta. In live mode we\n        // simply re-sync to wall clock.\n        if (this._tabHidden && !hidden) {\n          if (this._mode === 'live') {\n            this._sceneTimeMs = Date.now();\n            this._sceneAnchorMs = this._sceneTimeMs;\n            this._wallAnchorMs = performance.now();\n          } else {\n            // Re-anchor: don't advance during the hidden period.\n            this._wallAnchorMs = performance.now();\n            this._sceneAnchorMs = this._sceneTimeMs;\n          }\n        }\n        this._tabHidden = hidden;\n      });\n    }\n  }\n\n  /** Current scene-time in ms-since-epoch. */\n  getTime() {\n    if (this._mode === 'live') {\n      return Date.now();\n    }\n    if (this._mode === 'play') {\n      const wallElapsedMs = performance.now() - this._wallAnchorMs;\n      return this._sceneAnchorMs + wallElapsedMs * this._speed;\n    }\n    // fixed\n    return this._sceneTimeMs;\n  }\n\n  /** Current scene-time as a JS Date. */\n  getDate() {\n    return new Date(this.getTime());\n  }\n\n  /** Mode: 'live' | 'fixed' | 'play'. */\n  getMode() {\n    return this._mode;\n  }\n\n  /** Playback speed multiplier (only meaningful in 'play' mode). */\n  getSpeed() {\n    return this._speed;\n  }\n\n  /**\n   * Set absolute scene-time. Switches mode to 'fixed' unless a mode is\n   * explicitly provided.\n   */\n  setTime(epochMs, mode) {\n    const t = Number(epochMs);\n    if (!Number.isFinite(t)) return false;\n    const nextMode = mode || 'fixed';\n    if (!['live', 'fixed', 'play'].includes(nextMode)) return false;\n    const modeChanged = this._mode !== nextMode;\n    // Publish mode and epoch atomically. setMode() intentionally preserves\n    // the OLD mode's current time, so calling it after a seek loses that seek.\n    this._mode = nextMode;\n    this._sceneTimeMs = t;\n    this._sceneAnchorMs = t;\n    this._wallAnchorMs = performance.now();\n    if (modeChanged) this._emit('clock:mode-change', { mode: nextMode });\n    this._emit('clock:seek', { time: t, mode: this._mode });\n    return true;\n  }\n\n  /** Switch mode. Re-anchors as needed. */\n  setMode(mode) {\n    if (mode !== 'live' && mode !== 'fixed' && mode !== 'play') return false;\n    if (this._mode === mode) return true;\n    // Capture current scene time before switching anchors.\n    const t = this.getTime();\n    this._mode = mode;\n    this._sceneTimeMs = t;\n    this._sceneAnchorMs = t;\n    this._wallAnchorMs = performance.now();\n    this._emit('clock:mode-change', { mode });\n    return true;\n  }\n\n  /** Set playback speed multiplier. */\n  setSpeed(speed) {\n    const s = Number(speed);\n    if (!Number.isFinite(s) || s === 0) return false;\n    // Re-anchor so current time stays put before the rate changes.\n    const t = this.getTime();\n    this._speed = s;\n    this._sceneAnchorMs = t;\n    this._wallAnchorMs = performance.now();\n    if (this._mode !== 'play') this.setMode('play');\n    this._emit('clock:speed-change', { speed: s });\n    return true;\n  }\n\n  /** Resume play mode at current speed. */\n  play() { return this.setMode('play'); }\n\n  /** Pause: switch to fixed at current time. */\n  pause() { return this.setMode('fixed'); }\n\n  /** Subscribe to clock events. Returns an unsubscribe function. */\n  subscribe(handler) {\n    if (typeof handler !== 'function') return () => {};\n    _listeners.add(handler);\n    return () => _listeners.delete(handler);\n  }\n\n  /** Per-frame tick — called by the animation loop. */\n  tick() {\n    const t = this.getTime();\n    for (const fn of _listeners) {\n      try { fn({ type: 'clock:tick', time: t, mode: this._mode, speed: this._speed }); }\n      catch (err) { console.warn('[SceneClock] listener threw', err); }\n    }\n    if (typeof document !== 'undefined' && typeof CustomEvent !== 'undefined') {\n      try {\n        document.dispatchEvent(new CustomEvent('noclip:clock:tick', {\n          detail: { time: t, mode: this._mode, speed: this._speed },\n        }));\n      } catch {}\n    }\n  }\n\n  _emit(type, detail) {\n    for (const fn of _listeners) {\n      try { fn({ type, ...detail }); } catch {}\n    }\n    try {\n      if (typeof document !== 'undefined' && typeof CustomEvent !== 'undefined') {\n        document.dispatchEvent(new CustomEvent(`noclip:${type}`, { detail }));\n      }\n    } catch {}\n  }\n}\n\nlet _instance = null;\n\nexport function getSceneClock() {\n  if (!_instance) _instance = new SceneClockImpl();\n  return _instance;\n}\n\nexport default getSceneClock;\n","import { bilinearEgm96Undulation, getEgm96GeoidRaster } from '../refactor/imagery/MapzenElevationTileSource.js';\nimport { resolveSceneRuntimeResource } from '../refactor/scene/SceneRuntimeResources.js';\nimport { getSceneClock } from '../refactor/scene/SceneClock.js';\nimport { dirToLatLonLocal } from './geometry-utils.js';\nimport { readBoundedBytes } from '../refactor/shared/readBoundedBytes.js';\n\nconst DEG = Math.PI / 180;\nconst EARTH_RADIUS = 6371008.8;\nconst MAX_STATIONS = 4;\nexport const TIDE_REACH_METERS = 100000;\n\nexport function tideStationDistance(lat, lon, stationLat, stationLon) {\n    const y = Math.sin((lat - stationLat) * DEG / 2);\n    const x = Math.sin((lon - stationLon) * DEG / 2);\n    return 2 * EARTH_RADIUS * Math.asin(Math.sqrt(Math.min(1,\n        y * y + Math.cos(lat * DEG) * Math.cos(stationLat * DEG) * x * x)));\n}\n\n/** Regional astronomical anomalies, separate from the mean-sea-level datum.\n * Bounded interpolation of nearby measured harmonic stations, not a global\n * hydrodynamic forecast. Outside coverage the anomaly is zero, explicitly.\n */\nexport class RegionalTides {\n    constructor(data, createPredictor) {\n        if (data?.version !== 1 || !Array.isArray(data.stations) || data.stations.length > 5000\n            || !Array.isArray(data.constituents) || data.constituents.length > 512) {\n            throw new Error('Invalid regional tide catalogue');\n        }\n        this.data = data;\n        this.createPredictor = createPredictor;\n        this.predictors = new Map();\n        this.cache = null;\n    }\n    sample(latitude, longitude, epochMs) {\n        if (![latitude, longitude, epochMs].every(Number.isFinite)) return { meters: 0, sources: [], status: 'unavailable' };\n        const cached = this.cache;\n        if (cached && cached.latitude === latitude && cached.longitude === longitude\n            && cached.epochMs === epochMs) return cached.result;\n        // Station search only after 500 m of travel; time changes never scan\n        // the world catalogue. Retain a margin so the 100 km edge stays smooth.\n        if (!this.region || tideStationDistance(latitude, longitude, this.region.latitude, this.region.longitude) > 500) {\n            const stations = this.data.stations\n                .map(station => ({ station, distance: tideStationDistance(latitude, longitude, station[2], station[3]) }))\n                .filter(entry => entry.distance < TIDE_REACH_METERS + 1000)\n                .sort((a, b) => a.distance - b.distance);\n            // Keep every candidate that could enter the nearest five before\n            // the next search (triangle inequality, 500 m of travel).\n            const support = stations[MAX_STATIONS]?.distance ?? TIDE_REACH_METERS;\n            this.region = { latitude, longitude,\n                stations: stations.filter(entry => entry.distance <= support + 1000) };\n        }\n        for (const entry of this.region.stations) entry.distance = tideStationDistance(latitude, longitude, entry.station[2], entry.station[3]);\n        this.region.stations.sort((a, b) => a.distance - b.distance);\n        const support = Math.min(TIDE_REACH_METERS, this.region.stations[MAX_STATIONS]?.distance ?? TIDE_REACH_METERS);\n        let sum = 0, weights = 0, nearest = Infinity;\n        const sources = [];\n        const minute = Math.floor(epochMs / 60000) * 60000;\n        for (const { station, distance } of this.region.stations.slice(0, MAX_STATIONS)) {\n            if (distance >= TIDE_REACH_METERS) continue;\n            let entry = this.predictors.get(station[0]);\n            if (!entry) {\n                const constituents = [];\n                for (let i = 0; i < station[4].length; i += 3) constituents.push({\n                    name: this.data.constituents[station[4][i]], amplitude: station[4][i + 1], phase: station[4][i + 2],\n                });\n                entry = { predictor: this.createPredictor(constituents) };\n                this.predictors.set(station[0], entry);\n                if (this.predictors.size > 16) this.predictors.delete(this.predictors.keys().next().value);\n            }\n            if (entry.minute !== minute) {\n                entry.start = entry.predictor.getWaterLevelAtTime({ time: new Date(minute) }).level;\n                entry.end = entry.predictor.getWaterLevelAtTime({ time: new Date(minute + 60000) }).level;\n                entry.minute = minute;\n            }\n            const level = entry.start + (entry.end - entry.start) * (epochMs - minute) / 60000;\n            if (!Number.isFinite(level)) continue;\n            // Zero value and zero derivative at the coverage edge. Exact\n            // station samples dominate; no hard nearest-station height jump.\n            // The departing fourth neighbour has zero weight at the fifth\n            // neighbour's distance, preventing a visible regional step.\n            const edge = Math.max(0, 1 - distance / Math.max(1, support));\n            const weight = edge * edge / Math.max(1, distance * distance);\n            if (weight === 0) continue;\n            sum += level * weight; weights += weight; nearest = Math.min(nearest, distance);\n            sources.push({ id: station[0], name: station[1], distanceMeters: distance });\n        }\n        const t = Math.max(0, Math.min(1, (TIDE_REACH_METERS - nearest) / 25000));\n        const fade = t * t * (3 - 2 * t);\n        const result = { meters: weights > 0 ? sum / weights * fade : 0,\n            sources, status: weights > 0 ? 'regional-harmonics' : 'outside-coverage' };\n        this.cache = { latitude, longitude, epochMs, result };\n        return result;\n    }\n}\n\n/** One sea-level reference shared by geometry, swimming and underwater optics.\n * h(WGS84) = N(EGM96) + tidal anomaly. Wind waves are a separate displacement.\n */\nexport class OceanWaterLevel {\n    constructor({ getTime = () => getSceneClock().getTime(), loadGeoid = getEgm96GeoidRaster,\n        loadTides = async () => {\n            const [module, response] = await Promise.all([import('@neaps/tide-predictor'),\n                fetch(resolveSceneRuntimeResource('/assets/ocean/tides.json'), { signal: AbortSignal.timeout(20000) })]);\n            if (!response.ok) throw new Error(`Tidal harmonics unavailable (${response.status})`);\n            const bytes = await readBoundedBytes(response, { maxBytes: 4 * 1024 * 1024 });\n            return new RegionalTides(JSON.parse(new TextDecoder().decode(bytes)), module.createTidePredictor);\n        } } = {}) {\n        Object.assign(this, { getTime, loadGeoid, loadTides });\n        this.geoid = null; this.tides = null; this.ready = false;\n    }\n    load() {\n        if (this.promise || (this.ready && this.tides) || this.attempts >= 3 || Date.now() < (this.retryAt || 0)) {\n            return this.promise || Promise.resolve(this.ready);\n        }\n        this.attempts = (this.attempts || 0) + 1;\n        this.promise = Promise.allSettled([\n            this.ready ? Promise.resolve() : Promise.resolve().then(() => this.loadGeoid()).then(grid => { this.geoid = grid; this.ready = !!grid; }),\n            this.tides ? Promise.resolve() : Promise.resolve().then(() => this.loadTides()).then(tides => { this.tides = tides; }),\n        ]).then(results => {\n            this.errors = results.filter(result => result.status === 'rejected').map(result => result.reason?.message);\n            return this.ready;\n        }).finally(() => {\n            this.promise = null;\n            this.retryAt = Date.now() + 60000;\n        });\n        return this.promise;\n    }\n    meanHeight(latitude, longitude) {\n        return bilinearEgm96Undulation(this.geoid, latitude, longitude);\n    }\n    sample(latitude, longitude, epochMs = this.getTime()) {\n        const mean = this.meanHeight(latitude, longitude);\n        if (!Number.isFinite(mean)) return null;\n        const tide = this.tides?.sample(latitude, longitude, epochMs);\n        const tideMeters = tide?.meters ?? 0;\n        return { meanSeaLevelEllipsoidMeters: mean, tideMeters,\n            seaLevelEllipsoidMeters: mean + tideMeters,\n            tideStatus: tide?.status || 'unavailable', tideSources: tide?.sources || [] };\n    }\n    sampleDirection(direction, epochMs = this.getTime()) {\n        const { latDeg, lonDeg } = dirToLatLonLocal(direction);\n        return this.sample(latDeg, lonDeg, epochMs);\n    }\n}\n\nlet sharedWaterLevel;\nexport const getOceanWaterLevel = () => (sharedWaterLevel ||= new OceanWaterLevel());\n","// Ocean render tier. A failure in the sea surface must only cost the sea,\n// never the 3D world, so the ocean steps down one tier at a time:\n//   full   GPU FFT cascades, screen-space reflections, godrays, particulate\n//   basic  analytic Gerstner waves on the same surface, no reflection trace\n//   off    no sea-surface mesh; the planet shader's own water remains\n// A demotion persists, so a browser that lost its context to the ocean\n// reloads straight into the cheaper tier. It expires after a week, and\n// `?ocean=full|basic|off` overrides it for testing.\nexport const OCEAN_TIERS = ['full', 'basic', 'off'];\nconst KEY = 'noclip.ocean.tier';\nconst EXPIRY_MS = 7 * 24 * 3600 * 1000;\n\nfunction defaultStorage() {\n    try { return globalThis.localStorage ?? null; } catch { return null; }\n}\n\n/** The tier to start with: URL override, else an unexpired demotion, else full. */\nexport function readOceanTier({ storage = defaultStorage(), search = globalThis.location?.search ?? '', now = Date.now() } = {}) {\n    try {\n        const requested = new URLSearchParams(search).get('ocean');\n        if (OCEAN_TIERS.includes(requested)) return requested;\n    } catch { /* malformed query */ }\n    try {\n        const saved = JSON.parse(storage?.getItem(KEY) || 'null');\n        if (OCEAN_TIERS.includes(saved?.tier) && now - saved.at < EXPIRY_MS) return saved.tier;\n    } catch { /* unreadable or blocked storage */ }\n    return 'full';\n}\n\n/** Step down one tier, persist it, and return the new tier. */\nexport function demoteOceanTier(current, reason, { storage = defaultStorage(), now = Date.now() } = {}) {\n    const index = Math.max(0, OCEAN_TIERS.indexOf(current));\n    const tier = OCEAN_TIERS[Math.min(OCEAN_TIERS.length - 1, index + 1)];\n    try { storage?.setItem(KEY, JSON.stringify({ tier, reason: String(reason || '').slice(0, 200), at: now })); } catch { /* storage optional */ }\n    return tier;\n}\n","// Match the Bruneton atmosphere's radiometric reference. Visible solar radiance\n// is irradiance divided by projected source solid angle, not a unit albedo.\nexport const SOLAR_DISC_DEFAULTS = Object.freeze({\n  irradiance: Object.freeze([1.474, 1.8504, 1.91198]),\n  referenceAngularRadius: 0.004675,\n  limbLinear: 0.47,\n  limbQuadratic: 0.23,\n  halfFloatMaximum: 60000,\n});\n\nexport function solarDiscRadianceScale(angularRadius = SOLAR_DISC_DEFAULTS.referenceAngularRadius) {\n  const radius = Math.max(1e-6, Number(angularRadius) || SOLAR_DISC_DEFAULTS.referenceAngularRadius);\n  const meanLimb = 1 - SOLAR_DISC_DEFAULTS.limbLinear / 3 - SOLAR_DISC_DEFAULTS.limbQuadratic / 6;\n  return 1 / (Math.PI * Math.sin(radius) ** 2 * meanLimb);\n}\n\n// The same original flare is drawn once, after cloud/atmosphere composition.\n// These vertex samplers belong to that small independent program, not the\n// 16-sampler aerial program. All inputs are borrowed; no target, readback or clock.\nexport const SOLAR_OPTICS_VISIBILITY_GLSL = /* glsl */`\nuniform sampler2D ncaOpticsDepth, ncaOpticsClouds;\nuniform vec4 ncaOpticsFlags;\nuniform vec2 ncaSolarDiscRadius;\nuniform float ncaSolarFrontDepth;\nuniform mat4 ncaOpticsInverseProjection;\nuniform vec4 ncaOpticsOccluders[2];\n\nfloat ncaSolarOpticsVisibility() {\n  if (ncaOpticsFlags.x < 0.5) return 1.0;\n  float visible = 0.0, eligible = 0.0;\n  for (int i = 0; i < 13; ++i) {\n    float radius = i == 0 ? 0.0 : sqrt((float(i) - 0.5) / 12.0);\n    float angle = float(i) * 2.39996322973;\n    vec2 offset = radius * vec2(cos(angle), sin(angle));\n    vec2 point = lensPosition * 0.5 + 0.5 + offset * ncaSolarDiscRadius;\n    if (any(lessThan(point, vec2(0.0))) || any(greaterThan(point, vec2(1.0)))) continue;\n    vec3 ray = normalize((ncaOpticsInverseProjection * vec4(point * 2.0 - 1.0, 0.0, 1.0)).xyz);\n    float clearBody = 1.0;\n    for (int body = 0; body < 2; ++body) {\n      vec4 occluder = ncaOpticsOccluders[body];\n      if (occluder.w < 1.0 && dot(ray, occluder.xyz) > occluder.w) clearBody = 0.0;\n    }\n    // Analytic Earth/Moon visibility already controls opacity. Normalize over\n    // its clear samples so a partial eclipse is never attenuated twice.\n    float oneMinusMu = 1.0 - sqrt(max(0.0, 1.0 - radius * radius));\n    float weight = clearBody * (1.0 - 0.47 * oneMinusMu - 0.23 * oneMinusMu * oneMinusMu);\n    eligible += weight;\n    vec4 depthSample = texture2D(ncaOpticsDepth, point);\n    float depth = ncaOpticsFlags.z > 0.5 ? unpackRGBAToDepth(depthSample) : depthSample.r;\n    float terrain = step(ncaSolarFrontDepth - 0.0000004, depth);\n    float cloud = ncaOpticsFlags.y > 0.5 ? 1.0 - texture2D(ncaOpticsClouds, point).a : 1.0;\n    visible += weight * terrain * clamp(cloud, 0.0, 1.0);\n  }\n  return eligible > 0.0 ? visible / eligible : 0.0;\n}\n`;\n","/**\n * Lens Flare by Anderson Mancini\n * Based on: https://github.com/ektogamat/R3F-Ultimate-Lens-Flare\n */\nimport * as THREE from 'three'\nimport {\n  PLANET_RADIUS,\n  SUN_RADIUS_M,\n} from './constants.js'\nimport { ellipsoidRadiusForWorldDir } from './geometry-utils.js'\nimport { isObjectVisibleInHierarchy } from '../refactor/render/CelestialOcclusionContract.js'\nimport { ASTRONOMICAL_LENS_FLARE_DEFAULTS } from '../refactor/render/PostProcessingContract.js'\nimport { SOLAR_OPTICS_VISIBILITY_GLSL } from '../refactor/render/SolarOpticsContract.js'\nimport {\n  atmosphericTransmittance,\n  finiteSourceVisibility,\n} from '../refactor/render/CelestialIrradianceContract.js'\n/**\n * @param {THREE.Vector3 | undefined} lensPosition The date\n * @param {Boolean} debug The string\n * @param {Number | undefined} opacity The string\n */\n\nexport let LensFlareParams = {}\n\nconst debugLensFlare = (...args) => {\n  if (globalThis.__noclipDebugLensFlare === true) console.debug(...args)\n}\n\nexport function LensFlareEffect(\n  lensPosition,\n  opacity,\n  { celestialOccluders = [], getEnvironment = () => null } = {},\n) {\n  LensFlareParams = {\n    lensPosition: lensPosition ? lensPosition : new THREE.Vector3(25, 2, -80),\n    opacity: THREE.MathUtils.clamp(\n      Number.isFinite(opacity)\n        ? opacity\n        : ASTRONOMICAL_LENS_FLARE_DEFAULTS.opacity,\n      0,\n      1,\n    ),\n  }\n\n  const lensDirtTexture = new THREE.DataTexture(new Uint8Array([255, 255, 255, 255]), 1, 1, THREE.RGBAFormat)\n  lensDirtTexture.minFilter = THREE.LinearFilter\n  lensDirtTexture.magFilter = THREE.LinearFilter\n  lensDirtTexture.generateMipmaps = false\n  lensDirtTexture.needsUpdate = true\n\n  const clock = new THREE.Clock()\n  const screenPosition = LensFlareParams.lensPosition\n  const viewport = new THREE.Vector4()\n  const oldOpacity = LensFlareParams.opacity\n\n  let internalOpacity = oldOpacity\n  let flarePosition = new THREE.Vector3()\n  const projectedPosition = new THREE.Vector3()\n  const raycaster = new THREE.Raycaster()\n  const camWorld = new THREE.Vector3()\n  const sunDir = new THREE.Vector3()\n  const sunOffset = new THREE.Vector3()\n  const sunWorld = new THREE.Vector3()\n  const rayOrigin = new THREE.Vector3()\n  const rayDir = new THREE.Vector3()\n  const cameraQuaternion = new THREE.Quaternion()\n  const lastCameraQuaternion = new THREE.Quaternion()\n  const planetCenter = new THREE.Vector3()\n  const planetScale = new THREE.Vector3()\n  const celestialCenter = new THREE.Vector3()\n  const celestialScale = new THREE.Vector3()\n  const sunTransmittance = new THREE.Vector3(1, 1, 1)\n  const sourceVisibilityOffset = new THREE.Vector3()\n  const occluderVisibilityOffset = new THREE.Vector3()\n  let planetGroup = null\n  let lastSourceOccluded = null\n  let lastInView = null\n  let hasLastCameraQuaternion = false\n  let cameraMotion = 0\n\n  const lensFlareMaterial = new THREE.ShaderMaterial({\n    uniforms: {\n      iTime: { value: 0 },\n      iResolution: { value: new THREE.Vector2(window.innerWidth, window.innerHeight) },\n      lensPosition: { value: new THREE.Vector2(0, 0) },\n      enabled: { value: true },\n      colorGain: {\n        value: new THREE.Color().fromArray(\n          ASTRONOMICAL_LENS_FLARE_DEFAULTS.colorGain,\n        ),\n      },\n      flareEnergy: { value: ASTRONOMICAL_LENS_FLARE_DEFAULTS.energy },\n      coronaStrength: { value: ASTRONOMICAL_LENS_FLARE_DEFAULTS.coronaStrength },\n      veilStrength: { value: ASTRONOMICAL_LENS_FLARE_DEFAULTS.veilStrength },\n      diffractionStrength: { value: ASTRONOMICAL_LENS_FLARE_DEFAULTS.diffractionStrength },\n      starPoints: { value: 5.0 },\n      glareSize: { value: ASTRONOMICAL_LENS_FLARE_DEFAULTS.glareSize },\n      flareSize: { value: ASTRONOMICAL_LENS_FLARE_DEFAULTS.flareSize },\n      flareSpeed: { value: 0.0 },\n      flareShape: { value: 1.05 },\n      haloScale: { value: 0.4 },\n      opacity: { value: internalOpacity },\n      flareDesaturate: { value: ASTRONOMICAL_LENS_FLARE_DEFAULTS.desaturate },\n      sunTransmittance: { value: sunTransmittance.clone() },\n      animated: { value: false },\n      anamorphic: { value: false },\n      lensDirtTexture: { value: lensDirtTexture },\n      secondaryGhosts: { value: true },\n      starBurst: { value: false },\n      ghostScale: { value: ASTRONOMICAL_LENS_FLARE_DEFAULTS.ghostScale },\n      sourceRadius: { value: 0.0056 },\n      viewCentrality: { value: 0 },\n      exposureCompensation: { value: 1 },\n      cameraMotion: { value: 0 },\n      sourceViewDepth: { value: 1 },\n      surfaceGain: { value: 1 },\n      ncaOpticsDepth: { value: lensDirtTexture },\n      ncaOpticsClouds: { value: lensDirtTexture },\n      ncaOpticsFlags: { value: new THREE.Vector4() },\n      ncaSolarDiscRadius: { value: new THREE.Vector2() },\n      ncaSolarFrontDepth: { value: 1 },\n      ncaOpticsInverseProjection: { value: new THREE.Matrix4() },\n      ncaOpticsOccluders: { value: [new THREE.Vector4(0,0,0,1),new THREE.Vector4(0,0,0,1)] },\n      aditionalStreaks: { value: false },\n      followMouse: { value: false },\n    },\n    /*GLSL */\n    fragmentShader: `\n    #include <logdepthbuf_pars_fragment>\n\n    // Based on https://www.shadertoy.com/view/4sX3Rs\n    uniform float iTime;\n    uniform vec2 lensPosition;\n    uniform vec2 iResolution;\n    uniform vec3 colorGain;\n    uniform float flareEnergy;\n    uniform float coronaStrength;\n    uniform float veilStrength;\n    uniform float diffractionStrength;\n    uniform float starPoints;\n    uniform float glareSize;\n    uniform float flareSize;\n    uniform float flareSpeed;\n    uniform float flareShape;\n    uniform float haloScale;\n    uniform float opacity;\n    uniform float flareDesaturate;\n    uniform vec3 sunTransmittance;\n    uniform bool animated;\n    uniform bool anamorphic;\n    uniform bool enabled;\n    uniform bool secondaryGhosts;\n    uniform bool starBurst;\n    uniform float ghostScale;\n    uniform float sourceRadius;\n    uniform float viewCentrality;\n    uniform float exposureCompensation;\n    uniform float cameraMotion;\n    uniform float surfaceGain;\n    uniform bool aditionalStreaks;\n    uniform sampler2D lensDirtTexture;\n    varying vec2 vUv;\n    varying float vSolarVisibility;\n\n    float uDispersal = 0.2;\n    float uHaloWidth = 0.45;\n    float uDistortion = 0.6;\n    float uBrightDark = 0.35;\n    vec2 vTexCoord;\n    \n\n    float rand(float n){return fract(sin(n) * 43758.5453123);}\n\n    float noise(float p){\n        float fl = floor(p);\n        float fc = fract(p);\n        return mix(rand(fl),rand(fl + 1.0), fc);\n    }\n\n    vec3 hsv2rgb(vec3 c)\n    {\n        vec4 k = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n        vec3 p = abs(fract(c.xxx + k.xyz) * 6.0 - k.www);\n        return c.z * mix(k.xxx, clamp(p - k.xxx, 0.0, 1.0), c.y);\n    }\n\n    float saturate2(float x)\n    {\n        return clamp(x, 0.,1.);\n    }\n\n\n    vec2 rotateUV(vec2 uv, float rotation)\n    {\n        return vec2(\n            cos(rotation) * uv.x + sin(rotation) * uv.y,\n            cos(rotation) * uv.y - sin(rotation) * uv.x\n        );\n    }\n\n    // Based on https://www.shadertoy.com/view/XtKfRV\n    vec3 drawflare(vec2 p, float intensity, float rnd, float speed, int id)\n    {\n        float flarehueoffset = (1. / 32.) * float(id) * 0.1;\n        float lingrad = distance(vec2(0.), p);\n        float expgrad = 1. / exp(lingrad * (fract(rnd) * 0.66 + 0.33));\n        vec3 colgrad = hsv2rgb(vec3( fract( (expgrad * 8.) + speed * flareSpeed + flarehueoffset), pow(1.-abs(expgrad*2.-1.), 0.45), 20.0 * expgrad * intensity)); //rainbow spectrum effect\n\n        float internalStarPoints;\n\n        if(anamorphic){\n            internalStarPoints = 1.0;\n        } else{\n            internalStarPoints = starPoints;\n        }\n        \n        float blades = length(p * flareShape * sin(internalStarPoints * atan(p.x, p.y))); //draw 6 blades\n        \n        float comp = pow(1.-saturate2(blades), ( anamorphic ? 100. : 12.));\n        comp += saturate2(expgrad-0.9) * 3.;\n        comp = pow(comp * expgrad, 8. + (1.-intensity) * 5.);\n        \n        if(flareSpeed > 0.0){\n            return vec3(comp) * colgrad;\n        } else{\n            return vec3(comp) * flareSize * 15.;\n        }\n    }\n\n    float dist(vec3 a, vec3 b) { return abs(a.x - b.x) + abs(a.y - b.y) + abs(a.z - b.z); }\n\n    float glare(vec2 uv, vec2 pos, float size)\n    {\n        vec2 main;\n\n        if(animated){\n        main = rotateUV(uv-pos, iTime * 0.1);      \n        } else{\n        main = uv-pos;     \n        }\n        \n        float ang = atan(main.y, main.x) * (anamorphic ? 1.0 : starPoints);\n        float dist = length(main); \n        dist = pow(dist, .9);\n        \n        float f0 = 1.0/(length(uv-pos)*(1.0/size*16.0)+.2);\n\n        return f0+f0*(sin((ang))*.2 +.3);\n    }\n\n    //https://www.shadertoy.com/view/Xd2GR3\n    float sdHex(vec2 p){\n        p = abs(p);\n        vec2 q = vec2(p.x*2.0*0.5773503, p.y + p.x*0.5773503);\n        return dot(step(q.xy,q.yx), 1.0-q.yx);\n    }\n\n    //fakes x^n for specular effects (k is 0-1)\n    float fpow(float x, float k){\n        return x > k ? pow((x-k)/(1.0-k),2.0) : 0.0;\n    }\n\n    vec3 renderhex(vec2 uv, vec2 p, float s, vec3 col){\n        uv -= p;\n        if (abs(uv.x) < 0.2*s && abs(uv.y) < 0.2*s){\n            return mix(vec3(0),mix(vec3(0),col,0.1 + fpow(length(uv/s),0.1)*10.0),smoothstep(0.0,0.1,sdHex(uv*20.0/s)));\n        }\n        return vec3(0);\n    }\n\n    vec3 LensFlare(vec2 uv, vec2 pos)\n    {\n        vec2 main = uv-pos;\n        vec2 uvd = uv*(length(uv));\n        \n        float ang = atan(main.x,main.y);\n        \n        float f0 = .3/(length(uv-pos)*16.0+1.0);\n        \n        f0 = f0*(sin(noise(sin(ang*3.9-(animated ? iTime : 0.0) * 0.3) * starPoints))*.2 );\n        \n        float f1 = max(0.01-pow(length(uv+1.2*pos),1.9),.0)*7.0;\n\n        float f2 = max(.9/(10.0+32.0*pow(length(uvd+0.99*pos),2.0)),.0)*0.35;\n        float f22 = max(.9/(11.0+32.0*pow(length(uvd+0.85*pos),2.0)),.0)*0.23;\n        float f23 = max(.9/(12.0+32.0*pow(length(uvd+0.95*pos),2.0)),.0)*0.6;\n        \n        vec2 uvx = mix(uv,uvd, 0.1);\n        \n        float f4 = max(0.01-pow(length(uvx+0.4*pos),2.9),.0)*4.02;\n        float f42 = max(0.0-pow(length(uvx+0.45*pos),2.9),.0)*4.1;\n        float f43 = max(0.01-pow(length(uvx+0.5*pos),2.9),.0)*4.6;\n        \n        uvx = mix(uv,uvd,-.4);\n        \n        float f5 = max(0.01-pow(length(uvx+0.1*pos),5.5),.0)*2.0;\n        float f52 = max(0.01-pow(length(uvx+0.2*pos),5.5),.0)*2.0;\n        float f53 = max(0.01-pow(length(uvx+0.1*pos),5.5),.0)*2.0;\n        \n        uvx = mix(uv,uvd, 2.1);\n        \n        float f6 = max(0.01-pow(length(uvx-0.3*pos),1.61),.0)*3.159;\n        float f62 = max(0.01-pow(length(uvx-0.325*pos),1.614),.0)*3.14;\n        float f63 = max(0.01-pow(length(uvx-0.389*pos),1.623),.0)*3.12;\n        \n        vec3 c = vec3(glare(uv,pos, glareSize));\n\n        vec2 prot;\n\n        if(animated){\n            prot = rotateUV(uv - pos, (iTime * 0.1));  \n        } else if(anamorphic){\n            prot = rotateUV(uv - pos, 1.570796);     \n        } else {\n            prot = uv - pos;\n        }\n\n        c += drawflare(prot, (anamorphic ? flareSize * 10. : flareSize), 0.1, iTime, 1);\n        \n        c.r+=f1+f2+f4+f5+f6; c.g+=f1+f22+f42+f52+f62; c.b+=f1+f23+f43+f53+f63;\n        c = c*1.3 * vec3(length(uvd)+.09); // Vignette\n        c+=vec3(f0);\n        \n        return c;\n    }\n\n    vec3 cc(vec3 color, float factor,float factor2)\n    {\n        float w = color.x+color.y+color.z;\n        return mix(color,vec3(w)*factor,w*factor2);\n    }    \n\n    float rnd(vec2 p)\n    {\n        float f = fract(sin(dot(p, vec2(12.1234, 72.8392) )*45123.2));\n        return f;   \n    }\n\n    float rnd(float w)\n    {\n        float f = fract(sin(w)*1000.);\n        return f;   \n    }\n\n    vec2 ghostJitter(float seed)\n    {\n        float jx = rnd(seed * 17.13);\n        float jy = rnd(seed * 31.77);\n        return (vec2(jx, jy) - 0.5) * 0.25;\n    }\n\n    float regShape(vec2 p, int N)\n    {\n        float f;\n        \n        float a=atan(p.x,p.y)+.2;\n        float b=6.28319/float(N);\n        f=smoothstep(.5,.51, cos(floor(.5+a/b)*b-a)*length(p.xy)* 2.0  -ghostScale);\n            \n        return f;\n    }\n\n    vec3 renderDisc(vec2 uv, vec2 p, float s, vec3 col)\n    {\n        vec2 d = (uv - p) / max(1e-4, s);\n        float r = length(d);\n        float a = smoothstep(1.0, 0.0, r);\n        a *= a;\n        return col * a;\n    }\n\n    // Based on https://www.shadertoy.com/view/Xlc3D2\n    vec3 circle(vec2 p, float size, float decay, vec3 color, vec3 color2, float dist, vec2 mouse)\n    {\n        float l = length(p + mouse*(dist*2.))+size/2.;\n        float l2 = length(p + mouse*(dist*4.))+size/3.;\n        \n        float c = max(0.04-pow(length(p + mouse*dist), size*ghostScale), 0.0)*10.;\n        float c1 = max(0.001-pow(l-0.3, 1./40.)+sin(l*20.), 0.0)*3.;\n        float c2 =  max(0.09/pow(length(p-mouse*dist/.5)*1., .95), 0.0)/20.;\n        float s = max(0.02-pow(regShape(p*5. + mouse*dist*5. + decay, 6) , 1.), 0.0)*1.5;\n        \n        color = cos(vec3(colorGain)*16. + dist/8.)*0.5+.5;\n        vec3 f = c*color;\n        f += c1*color;\n        f += c2*color;  \n        f +=  s*color;\n        return f;\n    }\n\n    vec4 getLensColor(float x){\n        return vec4(vec3(mix(mix(mix(mix(mix(mix(mix(mix(mix(mix(mix(mix(mix(mix(mix(vec3(0., 0., 0.),\n        vec3(0., 0., 0.), smoothstep(0.0, 0.063, x)),\n        vec3(0., 0., 0.), smoothstep(0.063, 0.125, x)),\n        vec3(0.0, 0., 0.), smoothstep(0.125, 0.188, x)),\n        vec3(0.188, 0.131, 0.116), smoothstep(0.188, 0.227, x)),\n        vec3(0.31, 0.204, 0.537), smoothstep(0.227, 0.251, x)),\n        vec3(0.192, 0.106, 0.286), smoothstep(0.251, 0.314, x)),\n        vec3(0.102, 0.008, 0.341), smoothstep(0.314, 0.392, x)),\n        vec3(0.086, 0.0, 0.141), smoothstep(0.392, 0.502, x)),\n        vec3(1.0, 0.31, 0.0), smoothstep(0.502, 0.604, x)),\n        vec3(.1, 0.1, 0.1), smoothstep(0.604, 0.643, x)),\n        vec3(1.0, 0.929, 0.0), smoothstep(0.643, 0.761, x)),\n        vec3(1.0, 0.086, 0.424), smoothstep(0.761, 0.847, x)),\n        vec3(1.0, 0.49, 0.0), smoothstep(0.847, 0.89, x)),\n        vec3(0.945, 0.275, 0.475), smoothstep(0.89, 0.941, x)),\n        vec3(0.251, 0.275, 0.796), smoothstep(0.941, 1.0, x))),\n        1.0);\n    }\n\n    float dirtNoise(vec2 p){\n        vec2 f = fract(p);\n        f = (f * f) * (3.0 - (2.0 * f));    \n        float n = dot(floor(p), vec2(1.0, 157.0));\n        vec4 a = fract(sin(vec4(n + 0.0, n + 1.0, n + 157.0, n + 158.0)) * 43758.5453123);\n        return mix(mix(a.x, a.y, f.x), mix(a.z, a.w, f.x), f.y);\n    } \n\n    float fbm(vec2 p){\n        const mat2 m = mat2(0.80, -0.60, 0.60, 0.80);\n        float f = 0.0;\n        f += 0.5000*dirtNoise(p); p = m*p*2.02;\n        f += 0.2500*dirtNoise(p); p = m*p*2.03;\n        f += 0.1250*dirtNoise(p); p = m*p*2.01;\n        f += 0.0625*dirtNoise(p);\n        return f/0.9375;\n    } \n    vec4 getLensStar(vec2 p){\n        vec2 pp = (p - vec2(0.5)) * 2.0;\n        float a = atan(pp.y, pp.x);\n        vec4 cp = vec4(sin(a * 1.0), length(pp), sin(a * 13.0), sin(a * 53.0));\n        float d = sin(clamp(pow(length(vec2(0.5) - p) * 0.5 + haloScale /2., 5.0), 0.0, 1.0) * 3.14159);\n        vec3 c = vec3(d) * vec3(fbm(cp.xy * 16.0) * fbm(cp.zw * 9.0) * max(max(max(max(0.5, sin(a * 1.0)), sin(a * 3.0) * 0.8), sin(a * 7.0) * 0.8), sin(a * 9.0) * 10.6));\n        c *= vec3(mix(2.0, (sin(length(pp.xy) * 256.0) * 0.5) + 0.5, sin((clamp((length(pp.xy) - 0.875) / 0.1, 0.0, 1.0) + 0.0) * 2.0 * 3.14159) * 1.5) + 0.5) * 0.3275;\n        return vec4(vec3(c * 1.0), d);\t\n    }\n\n    vec4 getLensDirt(vec2 p){\n        p.xy += vec2(fbm(p.yx * 3.0), fbm(p.yx * 2.0)) * 0.0825;\n        vec3 o = vec3(mix(0.125, 0.25, max(max(smoothstep(0.1, 0.0, length(p - vec2(0.25))),\n                                            smoothstep(0.4, 0.0, length(p - vec2(0.75)))),\n                                            smoothstep(0.8, 0.0, length(p - vec2(0.875, 0.125))))));\n        o += vec3(max(fbm(p * 1.0) - 0.5, 0.0)) * 0.5;\n        o += vec3(max(fbm(p * 2.0) - 0.5, 0.0)) * 0.5;\n        o += vec3(max(fbm(p * 4.0) - 0.5, 0.0)) * 0.25;\n        o += vec3(max(fbm(p * 8.0) - 0.75, 0.0)) * 1.0;\n        o += vec3(max(fbm(p * 16.0) - 0.75, 0.0)) * 0.75;\n        o += vec3(max(fbm(p * 64.0) - 0.75, 0.0)) * 0.5;\n        return vec4(clamp(o, vec3(0.15), vec3(1.0)), 1.0);\t\n    }\n\n    vec4 textureLimited(sampler2D tex, vec2 texCoord){\n        if(((texCoord.x < 0.) || (texCoord.y < 0.)) || ((texCoord.x > 1.) || (texCoord.y > 1.))){\n        return vec4(0.0);\n        }else{\n        return texture(tex, texCoord); \n        }\n    }\n\n    vec4 textureDistorted(sampler2D tex, vec2 texCoord, vec2 direction, vec3 distortion) {\n        return vec4(textureLimited(tex, (texCoord + (direction * distortion.r))).r,\n                    textureLimited(tex, (texCoord + (direction * distortion.g))).g,\n                    textureLimited(tex, (texCoord + (direction * distortion.b))).b,\n                    1.0);\n    }\n\n    vec4 getStartBurst(){\n        vec2 aspectTexCoord = vec2(1.0) - (((vTexCoord - vec2(0.5)) * vec2(1.0)) + vec2(0.5)); \n        vec2 texCoord = vec2(1.0) - vTexCoord; \n        vec2 ghostVec = (vec2(0.5) - texCoord) * uDispersal - lensPosition;\n        vec2 ghostVecAspectNormalized = normalize(ghostVec * vec2(1.0)) * vec2(1.0);\n        vec2 haloVec = normalize(ghostVec) * uHaloWidth;\n        vec2 haloVecAspectNormalized = ghostVecAspectNormalized * uHaloWidth;\n        vec2 texelSize = vec2(1.0) / vec2(iResolution.xy);\n        vec3 distortion = vec3(-(texelSize.x * uDistortion), 0.2, texelSize.x * uDistortion);\n        vec4 c = vec4(0.0);\n        for (int i = 0; i < 8; i++) {\n        vec2 offset = texCoord + (ghostVec * float(i));\n        c += textureDistorted(lensDirtTexture, offset, ghostVecAspectNormalized, distortion) * pow(max(0.0, 1.0 - (length(vec2(0.5) - offset) / length(vec2(0.5)))), 10.0);\n        }                       \n        vec2 haloOffset = texCoord + haloVecAspectNormalized; \n        return (c * getLensColor((length(vec2(0.5) - aspectTexCoord) / length(vec2(haloScale))))) + \n            (textureDistorted(lensDirtTexture, haloOffset, ghostVecAspectNormalized, distortion) * pow(max(0.0, 1.0 - (length(vec2(0.5) - haloOffset) / length(vec2(0.5)))), 10.0));\n    } \n\n    void main()\n    {\n        vec2 uv = vUv;\n        vec2 myUV = uv -0.5;\n        myUV.y *= iResolution.y/iResolution.x;\n        vec2 mouse = lensPosition * 0.5;\n        mouse.y *= iResolution.y/iResolution.x;\n        \n        //First LensFlarePass\n        vec3 finalColor = LensFlare(myUV, mouse) * flareEnergy * colorGain / 256.;\n\n        // A finite astronomical disc drives a much broader optical response in\n        // an exposed camera. Keep the dominant corona and veiling glare nearly\n        // white; the smaller chromatic ghosts below remain secondary.\n        vec2 sourceDelta = myUV - mouse;\n        float sourceDistance = length(sourceDelta);\n        float calibratedRadius = max(sourceRadius, 0.0015);\n        float sensorCore = (calibratedRadius * calibratedRadius)\n            / (sourceDistance * sourceDistance + calibratedRadius * calibratedRadius);\n        float corona = exp(-sourceDistance / (calibratedRadius * 18.0 + 0.022));\n        float broadVeil = exp(-sourceDistance * 4.5)\n            * (1.0 - smoothstep(0.15, 1.35, sourceDistance));\n        float sourceAngle = atan(sourceDelta.y, sourceDelta.x);\n        float diffraction = pow(abs(cos(sourceAngle * 4.0)), 56.0)\n            * exp(-sourceDistance * 6.5);\n        float sensorStreak = exp(\n            -abs(sourceDelta.y) / (calibratedRadius * 0.7 + 0.0015)\n        ) * exp(-abs(sourceDelta.x) * 2.2);\n        vec3 solarWhite = vec3(1.0, 0.94, 0.82);\n        float fieldGain = mix(0.72, 1.18, clamp(viewCentrality, 0.0, 1.0));\n        float motionGain = mix(1.0, 1.24, clamp(cameraMotion, 0.0, 1.0));\n        vec3 opticalGlare = solarWhite * (\n            sensorCore * coronaStrength * 2.7\n            + corona * coronaStrength * 0.72\n            + broadVeil * veilStrength * 0.34\n            + diffraction * diffractionStrength * 0.62\n            + sensorStreak * diffractionStrength * 0.18\n        );\n        finalColor += opticalGlare * exposureCompensation * fieldGain * motionGain;\n\n        //Aditional Streaks\n        if(aditionalStreaks){\n            vec3 circColor = vec3(0.9, 0.2, 0.1);\n            vec3 circColor2 = vec3(0.3, 0.1, 0.9);\n\n            for(float i=0.;i<10.;i++){\n            finalColor += circle(myUV, pow(rnd(i*2000.)*2.8, .1)+1.41, 0.0, circColor+i , circColor2+i, rnd(i*20.)*3.+0.2-.5, lensPosition);\n            }\n        }\n\n        //Alternative Ghosts\n        if(secondaryGhosts){\n            vec3 altGhosts = vec3(0.0);\n            vec2 g0 = lensPosition * -0.38 + ghostJitter(1.3);\n            vec2 g1 = lensPosition * 0.18 + ghostJitter(2.7);\n            vec2 g2 = lensPosition * 0.52 + ghostJitter(4.2);\n            vec2 g3 = lensPosition * 0.95 + ghostJitter(6.1);\n            vec2 g4 = lensPosition * 1.35 + ghostJitter(8.9);\n            vec2 g5 = lensPosition * -1.05 + ghostJitter(11.4);\n            float s0 = ghostScale * mix(0.7, 1.4, rnd(3.7));\n            float s1 = ghostScale * mix(0.6, 1.2, rnd(6.2));\n            float s2 = ghostScale * mix(0.7, 1.5, rnd(9.8));\n            float s3 = ghostScale * mix(0.5, 1.1, rnd(12.9));\n            float s4 = ghostScale * mix(0.6, 1.0, rnd(15.4));\n            float s5 = ghostScale * mix(0.7, 1.3, rnd(18.1));\n            \n            altGhosts += renderDisc(myUV, g0, s0, vec3(0.032) * colorGain);\n            altGhosts += renderDisc(myUV, g1, s1, vec3(0.028) * colorGain);\n            altGhosts += renderDisc(myUV, g2, s2, vec3(0.025) * colorGain);\n            altGhosts += renderDisc(myUV, g3, s3, vec3(0.02) * colorGain);\n            altGhosts += renderDisc(myUV, g4, s4, vec3(0.018) * colorGain);\n            altGhosts += renderDisc(myUV, g5, s5, vec3(0.022) * colorGain);\n            \n            finalColor += altGhosts * 0.55;\n        }\n        \n\n        //Starburst                     \n        if(starBurst){\n            vTexCoord = myUV + 0.5;\n            vec4 lensMod = getLensDirt(myUV);\n            float tooBright = 1.0 - (clamp(uBrightDark, 0.0, 0.5) * 2.0); \n            float tooDark = clamp(uBrightDark - 0.5, 0.0, 0.5) * 2.0;\n            lensMod += mix(lensMod, pow(lensMod * 2.0, vec4(2.0)) * 0.5, tooBright);\n            float lensStarRotationAngle = ((myUV.x + myUV.y)) * (1.0 / 6.0);\n            vec2 lensStarTexCoord = (mat2(cos(lensStarRotationAngle), -sin(lensStarRotationAngle), sin(lensStarRotationAngle), cos(lensStarRotationAngle)) * vTexCoord);\n            lensMod += getLensStar(lensStarTexCoord) * 2.;\n            \n            finalColor += clamp((lensMod.rgb * getStartBurst().rgb ), 0.01, 1.0);\n        }\n\n        //Final composed output\n        if (!enabled) discard;\n        float flareLuma = dot(finalColor, vec3(0.299, 0.587, 0.114));\n        finalColor = mix(finalColor, vec3(flareLuma), flareDesaturate);\n        finalColor *= sunTransmittance * surfaceGain;\n\n        // Attenuate radiance before the fixed-point framebuffer clamps it.\n        // SRC_ALPHA additive blending clamps an HDR white source to 1 first,\n        // then multiplies by opacity: against black space it can only be gray.\n        // ONE/ONE blending carries the already attenuated optical energy;\n        // zero alpha preserves the opaque scene framebuffer's alpha.\n        gl_FragColor = vec4(finalColor * clamp(opacity, 0.0, 1.0) * vSolarVisibility, 0.0);\n        #include <logdepthbuf_fragment>\n\n        #include <tonemapping_fragment>\n        #include <colorspace_fragment>\n    }\n    `,\n\n    /* GLSL */\n    vertexShader: `\n    #include <logdepthbuf_pars_vertex>\n    #include <packing>\n    uniform float sourceViewDepth;\n    uniform vec2 lensPosition;\n    varying vec2 vUv;\n    varying float vSolarVisibility;\n    ${SOLAR_OPTICS_VISIBILITY_GLSL}\n    void main() {\n      vUv = uv;\n      // All four carrier vertices evaluate the same finite source. Keep these\n      // texture reads out of the full-screen fragment shader.\n      vSolarVisibility = ncaSolarOpticsVisibility();\n\n      gl_Position = vec4(position, 1.0);\n      #ifdef USE_LOGARITHMIC_DEPTH_BUFFER\n        vFragDepth = 1.0 + max(sourceViewDepth, 0.0);\n        vIsPerspective = 1.0;\n      #endif\n      \n    }`,\n    transparent: true,\n    depthWrite: false,\n    depthTest: true,\n    blending: THREE.AdditiveBlending,\n    premultipliedAlpha: true,\n    name: 'LensFlareShader',\n    toneMapped: false,\n  })\n\n  const damp = (current, target, lambda, delta) => {\n    if (!Number.isFinite(current)) return target\n    const t = 1 - Math.exp(-lambda * Math.max(0, delta))\n    return current + (target - current) * t\n  }\n\n  lensFlareMaterial.onBeforeRender = function (renderer, scene, camera) {\n    // Read the clock exactly once. Calling getElapsedTime() and then\n    // getDelta() made the second read effectively zero, so the old flare took\n    // minutes to respond despite being framed as a temporal adaptation.\n    const deltaTime = THREE.MathUtils.clamp(clock.getDelta() || 1 / 60, 1 / 240, 0.1)\n    const elapsedTime = clock.elapsedTime\n    let forceOpacity = null\n\n    renderer.getCurrentViewport(viewport)\n    camWorld.setFromMatrixPosition(camera.matrixWorld)\n    cameraQuaternion.setFromRotationMatrix(camera.matrixWorld)\n    let instantaneousCameraMotion = 0\n    if (hasLastCameraQuaternion) {\n      instantaneousCameraMotion = lastCameraQuaternion.angleTo(cameraQuaternion) / deltaTime\n    }\n    lastCameraQuaternion.copy(cameraQuaternion)\n    hasLastCameraQuaternion = true\n    cameraMotion = damp(\n      cameraMotion,\n      THREE.MathUtils.clamp(instantaneousCameraMotion / (Math.PI * 0.75), 0, 1),\n      10,\n      deltaTime,\n    )\n    lensFlareMaterial.uniforms.cameraMotion.value = cameraMotion\n    raycaster.camera = camera\n    lensFlareContainer.lookAt(camWorld)\n\n    lensFlareMaterial.uniforms.iResolution.value.set(viewport.z, viewport.w)\n\n    if (lensFlareMaterial.uniforms.followMouse.value === true) {\n      lensFlareMaterial.uniforms.lensPosition.value.set(mouse.x, mouse.y)\n    } else {\n      sunWorld.copy(screenPosition)\n      projectedPosition.copy(sunWorld).applyMatrix4(camera.matrixWorldInverse)\n      lensFlareMaterial.uniforms.sourceViewDepth.value = Math.max(0, -projectedPosition.z)\n      projectedPosition.copy(sunWorld).project(camera)\n      const environment = getEnvironment() || {}\n      lensFlareMaterial.uniforms.surfaceGain.value = environment.surface\n        ? 0.85 : 1\n\n      flarePosition.x = projectedPosition.x\n      flarePosition.y = projectedPosition.y\n      flarePosition.z = projectedPosition.z\n\n      const inView = Number.isFinite(flarePosition.x)\n        && Number.isFinite(flarePosition.y)\n        && Number.isFinite(flarePosition.z)\n        && flarePosition.z >= -1 && flarePosition.z <= 1\n        && flarePosition.x >= -1 && flarePosition.x <= 1\n        && flarePosition.y >= -1 && flarePosition.y <= 1\n      if (inView !== lastInView) {\n        const stateLabel = inView ? 'entered' : 'exited'\n        const x = Number.isFinite(flarePosition.x) ? flarePosition.x.toFixed(4) : 'n/a'\n        const y = Number.isFinite(flarePosition.y) ? flarePosition.y.toFixed(4) : 'n/a'\n        const z = Number.isFinite(flarePosition.z) ? flarePosition.z.toFixed(4) : 'n/a'\n        debugLensFlare(`[LensFlare] screenspace ${stateLabel} (x=${x} y=${y} z=${z})`)\n        lastInView = inView\n      }\n      if (inView) {\n        lensFlareMaterial.uniforms.lensPosition.value.set(flarePosition.x, flarePosition.y)\n        const screenDistance = Math.hypot(flarePosition.x, flarePosition.y)\n        const edgeWeight = THREE.MathUtils.clamp((screenDistance - 0.15) / 1.15, 0, 1)\n        lensFlareMaterial.uniforms.viewCentrality.value = 1\n          - edgeWeight * edgeWeight * (3 - 2 * edgeWeight)\n      } else {\n        internalOpacity = 0\n        forceOpacity = 0\n        lensFlareMaterial.uniforms.viewCentrality.value = 0\n      }\n\n      if (inView) {\n        sunOffset.copy(sunWorld).sub(camWorld)\n        const sunDistance = sunOffset.length()\n        if (sunDistance <= 1e-4) {\n          internalOpacity = oldOpacity\n          sunTransmittance.set(1, 1, 1)\n          lensFlareMaterial.uniforms.sunTransmittance.value.copy(sunTransmittance)\n        } else {\n          sunDir.copy(sunOffset).normalize()\n          const sunAngularRadius = Math.asin(THREE.MathUtils.clamp(\n            SUN_RADIUS_M / sunDistance,\n            0,\n            1,\n          ))\n          const verticalHalfFov = THREE.MathUtils.degToRad(camera.fov * 0.5)\n          const cameraAspect = Math.max(1e-4, Number(camera.aspect) || 1)\n          const discRadiusY = 0.5 * Math.tan(sunAngularRadius) / Math.max(1e-4, Math.tan(verticalHalfFov))\n          lensFlareMaterial.uniforms.ncaSolarDiscRadius.value.set(discRadiusY / cameraAspect, discRadiusY)\n          lensFlareMaterial.uniforms.ncaSolarFrontDepth.value = Math.log2(1 + Math.max(1,\n            lensFlareMaterial.uniforms.sourceViewDepth.value - SUN_RADIUS_M)) / Math.log2(camera.far + 1)\n          lensFlareMaterial.uniforms.sourceRadius.value = THREE.MathUtils.clamp(\n            0.5 * Math.tan(sunAngularRadius)\n              / (Math.max(1e-4, Math.tan(verticalHalfFov)) * cameraAspect),\n            0.0015,\n            0.08,\n          )\n          rayOrigin.copy(camWorld)\n          rayDir.copy(sunDir)\n          if (!planetGroup && scene) {\n            planetGroup = scene.getObjectByName('PlanetGroup')\n          }\n          const ellipsoidR = ellipsoidRadiusForWorldDir(camWorld, planetGroup)\n          if (planetGroup) {\n            planetGroup.getWorldPosition(planetCenter)\n            planetGroup.getWorldScale(planetScale)\n          } else {\n            planetCenter.set(0, 0, 0)\n            planetScale.set(1, 1, 1)\n          }\n          const planetRadiusWorld = ellipsoidR || PLANET_RADIUS\n          const opticalOccluders = lensFlareMaterial.uniforms.ncaOpticsOccluders.value\n          opticalOccluders[0].set(0,0,0,1);opticalOccluders[1].set(0,0,0,1)\n          const earthDistance = sourceVisibilityOffset.subVectors(planetCenter,camWorld).length()\n          if (earthDistance > planetRadiusWorld && earthDistance < sunDistance) {\n            sourceVisibilityOffset.transformDirection(camera.matrixWorldInverse)\n            opticalOccluders[0].set(sourceVisibilityOffset.x,sourceVisibilityOffset.y,sourceVisibilityOffset.z,\n              Math.sqrt(Math.max(0,1-(planetRadiusWorld/earthDistance)**2)))\n          }\n          atmosphericTransmittance({\n            observerPosition: camWorld,\n            lightDirection: sunDir,\n            planetCenter,\n            planetRadius: planetRadiusWorld,\n            result: sunTransmittance,\n          })\n          lensFlareMaterial.uniforms.sunTransmittance.value.copy(sunTransmittance)\n\n          let solarVisibility = finiteSourceVisibility({\n            observerPosition: camWorld,\n            sourceCenter: sunWorld,\n            sourceRadius: SUN_RADIUS_M,\n            occluderCenter: planetCenter,\n            occluderRadius: planetRadiusWorld,\n            sourceOffset: sourceVisibilityOffset,\n            occluderOffset: occluderVisibilityOffset,\n          })\n          let celestialOccluder = null\n          for (const object of celestialOccluders) {\n            const radiusMeters = Number(\n              object?.geometry?.parameters?.radius\n                ?? object?.userData?.celestialOccluderRadiusM\n            )\n            if (!object\n              || !isObjectVisibleInHierarchy(object)\n              || !(radiusMeters > 0)\n              || !object.getWorldPosition) continue\n            object.getWorldPosition(celestialCenter)\n            object.getWorldScale?.(celestialScale)\n            const radiusScale = object.getWorldScale\n              ? Math.max(\n                  Math.abs(celestialScale.x),\n                  Math.abs(celestialScale.y),\n                  Math.abs(celestialScale.z),\n                )\n              : 1\n            const visibility = finiteSourceVisibility({\n              observerPosition: camWorld,\n              sourceCenter: sunWorld,\n              sourceRadius: SUN_RADIUS_M,\n              occluderCenter: celestialCenter,\n              occluderRadius: radiusMeters * radiusScale,\n              sourceOffset: sourceVisibilityOffset,\n              occluderOffset: occluderVisibilityOffset,\n            })\n            solarVisibility *= visibility\n            const bodyDistance = sourceVisibilityOffset.subVectors(celestialCenter,camWorld).length()\n            if(bodyDistance > radiusMeters*radiusScale && bodyDistance < sunDistance){\n              sourceVisibilityOffset.transformDirection(camera.matrixWorldInverse)\n              opticalOccluders[1].set(sourceVisibilityOffset.x,sourceVisibilityOffset.y,sourceVisibilityOffset.z,\n                Math.sqrt(Math.max(0,1-(radiusMeters*radiusScale/bodyDistance)**2)))\n            }\n            if (visibility < 1) {\n              celestialOccluder = object\n            }\n          }\n          solarVisibility = THREE.MathUtils.clamp(solarVisibility, 0, 1)\n          const analyticOccluded = solarVisibility <= 1e-4\n\n          // Fast path: Earth or a nearer physical celestial sphere already\n          // confirms full source occlusion. The Moon lives outside PlanetGroup,\n          // so relying on the terrain raycast alone can never detect an eclipse.\n          if (analyticOccluded) {\n            if (lastSourceOccluded !== true) {\n              const blocker = celestialOccluder?.name || 'Earth'\n              debugLensFlare(`[LensFlare] source occlusion=true blocker=${blocker} visibleFraction=${solarVisibility.toFixed(5)} sunDistance=${sunDistance.toFixed(2)}`)\n              lastSourceOccluded = true\n            }\n            internalOpacity = 0\n            forceOpacity = 0\n          } else if (planetGroup && !environment.surface && solarVisibility >= 1 - 1e-5\n            && lensFlareMaterial.uniforms.ncaOpticsFlags.value.x < 0.5) {\n            raycaster.layers.enableAll()\n            raycaster.set(rayOrigin, rayDir)\n            raycaster.near = 0\n            raycaster.far = sunDistance\n            const intersects = raycaster.intersectObject(planetGroup, true)\n\n            // Filter out objects marked as non-occluding\n            const validHits = intersects.filter((entry) => {\n              const obj = entry?.object\n              if (!obj) return false\n              if (obj.userData?.lensflare === 'no-occlusion') return false\n              if (obj.userData?.noOcclusion || obj.userData === 'no-occlusion') return false\n              return true\n            })\n\n            const anyHit = validHits.length > 0\n            const planetOccluded = anyHit\n\n            if (planetOccluded !== lastSourceOccluded) {\n              const tileHit = validHits.find((entry) => entry?.object?.userData?.tile)\n              const overlayHit = validHits.find((entry) => !entry?.object?.userData?.tile)\n              const hit = tileHit || overlayHit || validHits[0]\n              const hitName = hit?.object?.name || '(unnamed)'\n              const hitDist = Number.isFinite(hit?.distance) ? hit.distance.toFixed(2) : 'n/a'\n              const hitType = tileHit ? 'tile' : 'overlay'\n              debugLensFlare(`[LensFlare] planet occlusion=${planetOccluded} type=${hitType} hit=${hitName} dist=${hitDist} sunDistance=${sunDistance.toFixed(2)}`)\n              lastSourceOccluded = planetOccluded\n            }\n            if (planetOccluded) {\n              // Occluded by overlays/tiles — check transparency\n              const shouldForceOcclusion = checkTransparency(validHits, true)\n              if (shouldForceOcclusion) {\n                internalOpacity = 0\n              }\n            } else {\n              internalOpacity = oldOpacity * solarVisibility\n            }\n          } else {\n            // Finite solar crescents must remain visible. A center-ray hit is\n            // not full occlusion when part of the physical disc clears the\n            // Earth or Moon limb.\n            if (lastSourceOccluded !== false) {\n              debugLensFlare(`[LensFlare] source visibleFraction=${solarVisibility.toFixed(5)}`)\n              lastSourceOccluded = false\n            }\n            internalOpacity = oldOpacity * solarVisibility\n          }\n        }\n      }\n      \n    }\n\n    lensFlareMaterial.uniforms.iTime.value = elapsedTime\n    if (forceOpacity !== null) {\n      lensFlareMaterial.uniforms.opacity.value = forceOpacity\n    } else {\n      const currentOpacity = lensFlareMaterial.uniforms.opacity.value\n      // Optical glare rises over a handful of frames instead of popping on\n      // screen entry. It disappears even faster behind a solid body so no\n      // post-process afterimage leaks through Earth, Moon, or terrain.\n      const responseRate = internalOpacity < currentOpacity ? 42 : 18\n      const nextOpacity = damp(\n        currentOpacity,\n        internalOpacity,\n        responseRate,\n        deltaTime,\n      )\n      lensFlareMaterial.uniforms.opacity.value = nextOpacity\n    }\n  }\n\n  /**\n   * Transparency check\n   * @param {Array} intersects - Array of raycast hits\n   * @param {boolean} forceOcclusion - If true, assume occlusion even if no valid hit found (for pre-filtered hits)\n   * @returns {boolean} - True if object is solid/opaque and should force immediate occlusion\n   */\n  function checkTransparency(intersects, forceOcclusion = false){\n    const hit = intersects?.find((entry) => {\n      const obj = entry?.object\n      if (!obj) return false\n      if (obj.userData?.lensflare === 'no-occlusion') return false\n      if (obj.userData?.noOcclusion || obj.userData === 'no-occlusion') return false\n      return true\n    })\n\n    if (!hit || !hit.object) {\n      // If forceOcclusion is true, we know there's an occluding object even if we can't analyze it\n      internalOpacity = forceOcclusion ? 0 : oldOpacity\n      return forceOcclusion // Return true if we're forcing occlusion\n    }\n\n    const mat = hit.object.material\n    const materials = Array.isArray(mat) ? mat : [mat]\n    let maxTransmission = null\n    let anyTransparent = false\n    let maxOpacity = 0\n\n    for (const material of materials) {\n      if (!material) continue\n      if (Number.isFinite(material.transmission)) {\n        maxTransmission = Math.max(maxTransmission ?? 0, material.transmission)\n      }\n      if (material.transparent) {\n        anyTransparent = true\n        const opacity = Number.isFinite(material.opacity) ? material.opacity : 1\n        if (opacity > maxOpacity) maxOpacity = opacity\n      }\n    }\n\n    if (maxTransmission !== null) {\n      internalOpacity = maxTransmission > 0.2\n        ? oldOpacity * (maxTransmission * 0.5)\n        : 0\n      return maxTransmission <= 0.2 // Force occlusion if transmission is very low\n    }\n\n    if (anyTransparent) {\n      if (maxOpacity >= 0.98) {\n        internalOpacity = 0\n        return true // Force occlusion for nearly opaque transparent materials\n      } else {\n        const safeOpacity = Math.max(0.01, maxOpacity)\n        internalOpacity = Math.min(oldOpacity, oldOpacity / (safeOpacity * 10))\n        return false // Don't force occlusion for semi-transparent materials\n      }\n    }\n\n    // Solid opaque material\n    internalOpacity = 0\n    return true // Force immediate occlusion\n  }\n\n  /**\n   * Mouse\n   */\n  const mouse = new THREE.Vector2()\n\n  window.addEventListener('mousemove', (event) => {\n    mouse.x = (event.clientX / window.innerWidth) * 2 - 1\n    mouse.y = -(event.clientY / window.innerHeight) * 2 + 1\n  })\n\n  const lensFlareContainer = new THREE.Mesh(new THREE.PlaneGeometry(2, 2, 1, 1), lensFlareMaterial)\n  lensFlareContainer.frustumCulled = false\n  lensFlareContainer.userData.noOcclusion = true\n  lensFlareContainer.raycast = () => {}\n\n  return lensFlareContainer\n}\n","import { Mesh, Scene, Vector4 } from 'three';\n\n/** Reuses the original scene flare geometry/material after cloud composition.\n * No duplicate optical effect, retained image, texture allocation or scene-tree\n * scan. Direct/native XR keep the original draw and its hardware log depth.\n */\nexport class SolarOpticsRenderer {\n  constructor(flare) {\n    this.flare = flare;\n    this.scene = new Scene();\n    this.carrier = new Mesh(flare.geometry, flare.material);\n    this.carrier.frustumCulled = false;\n    this.scene.add(this.carrier);\n    this._viewport = new Vector4();this._scissor = new Vector4();\n  }\n\n  canRender(renderer, atmosphere, { orbital = false } = {}) {\n    return !this.failed && !renderer?.xr?.isPresenting && !!this.flare?.visible\n      && (orbital || !!atmosphere?._aerialEffectPass?.getDepthTexture?.());\n  }\n\n  render(renderer, sourceScene, camera, atmosphere, options = {}) {\n    if (!this.canRender(renderer, atmosphere, options)) return false;\n    const material = this.flare.material, u = material.uniforms;\n    const callback = material.onBeforeRender;\n    const depthTest = material.depthTest, autoClear = renderer.autoClear;\n    const target = renderer.getRenderTarget();\n    renderer.getViewport(this._viewport);renderer.getScissor(this._scissor);\n    const scissorTest = renderer.getScissorTest();\n    try {\n      const depth = atmosphere?._aerialEffectPass?.getDepthTexture?.() || null;\n      const cloud = atmosphere?._cloudAtmosphereAttachments?.enabled\n        ? atmosphere.clouds?.atmosphereOverlay?.map : null;\n      u.ncaOpticsDepth.value = depth;\n      u.ncaOpticsClouds.value = cloud || depth;\n      const packing = atmosphere?.aerialPerspective?.defines?.get('DEPTH_PACKING');\n      // Orbital direct/bloom frames retain the flare's existing analytic\n      // finite-disc Earth/Moon and native geometry occlusion. Never sample\n      // a parked surface compositor's stale depth/cloud textures there.\n      u.ncaOpticsFlags.value.set(depth ? 1 : 0, cloud ? 1 : 0, Number(packing) === 3201 ? 1 : 0, 0);\n      u.ncaOpticsInverseProjection.value.copy(camera.projectionMatrixInverse);\n      // Compute source projection, finite-disc occlusion and air transmission\n      // using the actual observer once; the carrier's automatic hook is muted.\n      callback?.call(material, renderer, sourceScene, camera);\n      material.onBeforeRender = () => {};\n      material.depthTest = false;\n      renderer.autoClear = false;\n      renderer.setRenderTarget(null);\n      renderer.render(this.scene, camera);\n      return true;\n    } finally {\n      material.onBeforeRender = callback;\n      material.depthTest = depthTest;renderer.autoClear = autoClear;\n      u.ncaOpticsFlags.value.set(0,0,0,0);\n      u.ncaOpticsDepth.value = u.ncaOpticsClouds.value = null;\n      renderer.setRenderTarget(target);\n      renderer.setViewport(this._viewport);renderer.setScissor(this._scissor);renderer.setScissorTest(scissorTest);\n    }\n  }\n\n  dispose() { this.scene.clear();this.flare = this.carrier = null; }\n}\n","import {\n    BufferAttribute, BufferGeometry, Color, FrontSide, Frustum, Matrix3, Matrix4, Mesh, NoToneMapping,\n    Scene, ShaderMaterial, Sphere, Vector3, Vector4,\n} from 'three';\n\nexport const HD_PROXY_LIMITS = Object.freeze({\n    meshes: 256, sourceRoots: 512, sourceVertices: 1_000_000, trianglesPerMesh: 8192,\n    triangles: 131072, nodes: 16384, colorMaterials: 4096, liveColorMaterials: 8192,\n    materialSlots: 65536, materialSlotsPerMesh: 4096, taskMs: 2, taskOperations: 128,\n});\n\nconst clock = () => globalThis.performance?.now?.() ?? Date.now();\nconst materialVisible = (material) => (Array.isArray(material) ? material : [material])\n    .some((item) => item && item.visible !== false);\nconst nativeVisible = (entry, camera) => {\n    if (entry.retiredFlag || entry.geometryLease?.retired || !materialVisible(entry.object.material) || (camera && !camera.layers.test(entry.object.layers))) return false;\n    let reachedFrame = false;\n    for (let node = entry.object; node; node = node.parent) {\n        if (node.visible === false) return false;\n        if (node === entry.frameRoot) reachedFrame = true;\n    }\n    return reachedFrame;\n};\n\n/** Vertex clustering is a structural approximation, never source geometry.\n * Work yields between small input batches; no normal/texture/image acquisition.\n * Positions are recentered before upload so planetary translations remain in\n * Three's double-precision CPU modelView subtraction, including ECEF sources.\n */\nexport function* buildHdProxyGeometry(geometry, { maxTriangles = HD_PROXY_LIMITS.trianglesPerMesh } = {}) {\n    const position = geometry?.getAttribute?.('position');\n    if (!position || position.itemSize !== 3 || position.count < 3 || position.count > HD_PROXY_LIMITS.sourceVertices) {\n        throw new Error('HD proxy source geometry exceeds its supported vertex bound');\n    }\n    if (geometry.getAttribute('positionHigh') || geometry.getAttribute('positionLow')) {\n        throw new Error('HD proxy requires resolved local positions, not high/low encoded vertices');\n    }\n    const index = geometry.index;\n    const count = index?.count ?? position.count;\n    const min = new Vector3(Infinity, Infinity, Infinity), max = new Vector3(-Infinity, -Infinity, -Infinity);\n    for (let i = 0; i < position.count; i++) {\n        const x = position.getX(i), y = position.getY(i), z = position.getZ(i);\n        if (![x, y, z].every(Number.isFinite)) throw new Error('HD proxy source has non-finite positions');\n        min.x = Math.min(min.x, x); min.y = Math.min(min.y, y); min.z = Math.min(min.z, z);\n        max.x = Math.max(max.x, x); max.y = Math.max(max.y, y); max.z = Math.max(max.z, z);\n        if (i % 128 === 127) yield;\n    }\n    const origin = new Vector3().addVectors(min, max).multiplyScalar(.5);\n    const span = Math.max(max.x - min.x, max.y - min.y, max.z - min.z, .01);\n    let vertices, faces;\n    // Retrying a coarser grid bounds the final topology without dropping an\n    // arbitrary triangle prefix or inventing bounding-box buildings.\n    for (let attempt = 0; attempt < 12; attempt++) {\n        const cell = span / (128 / 2 ** attempt);\n        const clusters = new Map(), remap = new Uint32Array(position.count);\n        vertices = []; let clusterOverflow = false;\n        for (let i = 0; i < position.count; i++) {\n            const x = position.getX(i) - origin.x, y = position.getY(i) - origin.y, z = position.getZ(i) - origin.z;\n            const key = `${Math.round(x / cell)},${Math.round(y / cell)},${Math.round(z / cell)}`;\n            let cluster = clusters.get(key);\n            if (cluster === undefined) {\n                if (vertices.length === 131072) { clusterOverflow = true; break; }\n                cluster = vertices.length; clusters.set(key, cluster); vertices.push([x, y, z, 1]);\n            } else {\n                const v = vertices[cluster]; v[0] += x; v[1] += y; v[2] += z; v[3]++;\n            }\n            remap[i] = cluster;\n            if (i % 128 === 127) yield;\n        }\n        if (clusterOverflow) { yield; continue; }\n        for (let i = 0; i < vertices.length; i++) {\n            const v = vertices[i]; v[0] /= v[3]; v[1] /= v[3]; v[2] /= v[3];\n            if (i % 128 === 127) yield;\n        }\n        faces = []; const seen = new Set(); let tooMany = false;\n        const start = Math.max(0, geometry.drawRange.start || 0);\n        const end = Math.min(count, start + geometry.drawRange.count);\n        for (let i = start; i + 2 < end; i += 3) {\n            const a = remap[index ? index.getX(i) : i], b = remap[index ? index.getX(i + 1) : i + 1], c = remap[index ? index.getX(i + 2) : i + 2];\n            if (a !== b && b !== c && c !== a) {\n                const key = [a, b, c].sort((x, y) => x - y).join(',');\n                if (!seen.has(key)) { seen.add(key); faces.push([a, b, c]); }\n                if (faces.length > maxTriangles) { tooMany = true; break; }\n            }\n            if (i % 384 === 0) yield;\n        }\n        if (!tooMany) break;\n    }\n    if (faces.length > maxTriangles) throw new Error('HD proxy topology exceeds its triangle bound');\n    const edges = new Map(), normals = [], masks = faces.map(() => [1, 1, 1]);\n    const a = new Vector3(), b = new Vector3(), c = new Vector3(), ab = new Vector3(), ac = new Vector3();\n    for (let i = 0; i < faces.length; i++) {\n        const face = faces[i]; a.fromArray(vertices[face[0]]); b.fromArray(vertices[face[1]]); c.fromArray(vertices[face[2]]);\n        const normal = ab.subVectors(b, a).cross(ac.subVectors(c, a)).normalize(); normals.push(normal.clone());\n        // Barycentric component 0 is the edge opposite vertex 0, etc.\n        for (let e = 0; e < 3; e++) {\n            const x = face[(e + 1) % 3], y = face[(e + 2) % 3], key = x < y ? `${x},${y}` : `${y},${x}`;\n            const prior = edges.get(key);\n            if (prior) {\n                if (normal.dot(normals[prior.face]) > .75) { masks[i][e] = 0; masks[prior.face][prior.edge] = 0; }\n            } else edges.set(key, { face: i, edge: e });\n        }\n        if (i % 128 === 127) yield;\n    }\n    const positions = new Float32Array(faces.length * 9), barycentric = new Float32Array(positions.length), edgeMask = new Float32Array(positions.length);\n    for (let i = 0; i < faces.length; i++) {\n        for (let corner = 0; corner < 3; corner++) {\n            const offset = i * 9 + corner * 3;\n            positions.set(vertices[faces[i][corner]].slice(0, 3), offset);\n            barycentric[offset + corner] = 1; edgeMask.set(masks[i], offset);\n        }\n        if (i % 128 === 127) yield;\n    }\n    const result = new BufferGeometry();\n    result.setAttribute('position', new BufferAttribute(positions, 3));\n    result.setAttribute('hdBarycentric', new BufferAttribute(barycentric, 3));\n    result.setAttribute('hdEdgeMask', new BufferAttribute(edgeMask, 3));\n    // Bounds are measured incrementally above. The conservative original box\n    // avoids an unbounded computeBoundingSphere pass at task completion.\n    const radius = max.distanceTo(min) * .5;\n    result.boundingSphere = new Sphere(new Vector3(), radius);\n    return { geometry: result, origin, min, max, triangles: faces.length, sourceTriangles: Math.floor(count / 3) };\n}\n\nfunction proxyMaterial(side = FrontSide, darkUnderside = false) {\n    const material = new ShaderMaterial({\n        name: 'MatrixStructuralProxy', toneMapped: false, side,\n        uniforms: { hdColor: { value: new Color(.42, .55, .68) }, hdUp: { value: new Vector3(0, 1, 0) }, hdFloor: { value: 0 } },\n        vertexShader: `#include <common>\n#include <logdepthbuf_pars_vertex>\nattribute vec3 hdBarycentric; attribute vec3 hdEdgeMask;\nuniform vec3 hdUp; uniform float hdFloor;\nvarying vec3 vHdBarycentric; varying vec3 vHdEdgeMask; varying vec3 vHdView;\nvarying vec3 vHdWorldUp; varying vec3 vHdChecker; varying float vHdHeight;\nvoid main(){\n vec4 world=modelMatrix*vec4(position,1.0);\n vec4 view=modelViewMatrix*vec4(position,1.0);\n vHdBarycentric=hdBarycentric; vHdEdgeMask=hdEdgeMask;\n vHdView=view.xyz; vHdWorldUp=mat3(viewMatrix)*normalize(world.xyz);\n vHdChecker=world.xyz*(1.0/16.0); vHdHeight=dot(position,hdUp)-hdFloor;\n gl_Position=projectionMatrix*view;\n #include <logdepthbuf_vertex>\n}`,\n        fragmentShader: `#include <common>\n#include <logdepthbuf_pars_fragment>\nuniform vec3 hdColor;\nvarying vec3 vHdBarycentric; varying vec3 vHdEdgeMask; varying vec3 vHdView;\nvarying vec3 vHdWorldUp; varying vec3 vHdChecker; varying float vHdHeight;\nvoid main(){\n #include <logdepthbuf_fragment>\n vec3 n=normalize(cross(dFdx(vHdView),dFdy(vHdView)));\n bool ground=vHdHeight<2.0&&abs(dot(n,normalize(vHdWorldUp)))>.72;\n float checker=mod(floor(vHdChecker.x)+floor(vHdChecker.y)+floor(vHdChecker.z),2.0);\n vec3 color=ground?mix(vec3(.28),vec3(.52),checker):hdColor;\n ${darkUnderside ? 'if(!gl_FrontFacing)color=vec3(0.0);' : ''}\n vec3 edge=smoothstep(vec3(0.0),fwidth(vHdBarycentric)*1.2,vHdBarycentric);\n edge=mix(vec3(1.0),edge,vHdEdgeMask);\n gl_FragColor=vec4(color*min(min(edge.x,edge.y),edge.z),1.0);\n #include <colorspace_fragment>\n}`,\n    });\n    // During the first bounded fit, native static positions can already supply\n    // a cheap texture-free draw. Missing proxy edge attributes have constants;\n    // source BufferGeometry attributes and buffers are never edited or disposed.\n    material.defaultAttributeValues.hdBarycentric = [1, 1, 1];\n    material.defaultAttributeValues.hdEdgeMask = [0, 0, 0];\n    return material;\n}\n\nfunction colorMaterial(source, geometry, lighting, kind = null) {\n    const overview = source.userData?.orbitalEarth === true;\n    const terrain = kind === 'terrain' && !!source.userData?.uniforms?.imageryTexture;\n    if ((source.isShaderMaterial || source.isRawShaderMaterial) && !overview && !terrain) throw new Error('HD color control requires a resolved native basic material');\n    const map = overview ? source.uniforms.orbitalDayTexture?.value : source.map, alphaMap = source.alphaMap;\n    const displacement = kind === 'moon' ? source.displacementMap : null;\n    if (source.displacementMap && !displacement) throw new Error('HD color control has an unsupported displacement contract');\n    const color = source.vertexColors && geometry.attributes.color;\n    const uv = (texture) => texture.channel ? `uv${texture.channel}` : 'uv';\n    const defines = {};\n    for (const texture of [map, alphaMap, displacement].filter(Boolean)) {\n        if (!Number.isInteger(texture.channel) || texture.channel < 0 || texture.channel > 3) throw new Error('HD color control has an unsupported source UV channel');\n        if (texture.channel) defines[`USE_UV${texture.channel}`] = '';\n    }\n    if (terrain && geometry.attributes.uv2) defines.USE_UV2 = '';\n    if (color) defines[color.itemSize === 4 ? 'USE_COLOR_ALPHA' : 'USE_COLOR'] = '';\n    return new ShaderMaterial({\n        name: 'MatrixColorControl', side: source.side, toneMapped: false, defines,\n        visible: source.visible !== false, transparent: source.transparent === true,\n        depthWrite: source.depthWrite !== false, depthTest: source.depthTest !== false, blending: source.blending,\n        uniforms: { ...lighting, hdDiffuse: { value: source.color?.clone() || new Color(1, 1, 1) },\n            hdOpacity: { value: source.opacity ?? 1 }, hdMap: { value: map || null }, hdAlphaMap: { value: alphaMap || null },\n            hdDisplacement: { value: displacement }, hdDisplacementScale: { value: source.displacementScale || 0 }, hdDisplacementBias: { value: source.displacementBias || 0 },\n            hdDisplacementTransform: { value: displacement?.matrix || new Matrix3() },\n            hdMapTransform: { value: map?.matrix || new Matrix3() }, hdAlphaTransform: { value: alphaMap?.matrix || new Matrix3() },\n            hdAlphaTest: { value: source.alphaTest || 0 } },\n        vertexShader: `#include <common>\n#include <logdepthbuf_pars_vertex>\nuniform mat3 hdMapTransform; uniform mat3 hdAlphaTransform; uniform mat3 hdDisplacementTransform;\nuniform sampler2D hdDisplacement; uniform float hdDisplacementScale; uniform float hdDisplacementBias;\nvarying vec2 vHdUv; varying vec2 vHdAlphaUv; varying vec4 vHdColor; varying vec3 vHdWorld;\nvoid main(){\n vHdUv=${overview ? 'uv' : terrain ? geometry.attributes.uv2 ? 'uv2' : 'uv' : map ? `(hdMapTransform*vec3(${uv(map)},1.0)).xy` : 'vec2(0.0)'};\n vHdAlphaUv=${alphaMap ? `(hdAlphaTransform*vec3(${uv(alphaMap)},1.0)).xy` : 'vec2(0.0)'};\n vHdColor=${color ? color.itemSize === 4 ? 'color' : 'vec4(color,1.0)' : 'vec4(1.0)'};\n vec3 transformed=position;\n ${displacement ? `float hdHeight=dot(texture2D(hdDisplacement,(hdDisplacementTransform*vec3(${uv(displacement)},1.0)).xy).rg,vec2(256.0,1.0))/257.0;\n transformed+=normalize(normal)*(hdHeight*hdDisplacementScale+hdDisplacementBias);` : ''}\n vHdWorld=(modelMatrix*vec4(transformed,1.0)).xyz;\n #include <project_vertex>\n #include <logdepthbuf_vertex>\n}`,\n        fragmentShader: `#include <common>\n#include <logdepthbuf_pars_fragment>\nuniform vec3 hdDiffuse; uniform vec3 hdSunPosition; uniform vec3 hdPlanetCenter;\nuniform float hdOpacity; uniform float hdAlphaTest;\nuniform sampler2D hdMap; uniform sampler2D hdAlphaMap;\nvarying vec2 vHdUv; varying vec2 vHdAlphaUv; varying vec4 vHdColor; varying vec3 vHdWorld;\nvoid main(){\n #include <logdepthbuf_fragment>\n vec4 color=vec4(hdDiffuse,hdOpacity)*vHdColor;\n ${map ? overview ? 'color*=textureGrad(hdMap,vec2(fract(vHdUv.x+.25),vHdUv.y),dFdx(vHdUv),dFdy(vHdUv));' : 'color*=texture2D(hdMap,vHdUv);' : ''}\n ${alphaMap ? 'color.a*=texture2D(hdAlphaMap,vHdAlphaUv).g;' : ''}\n if(color.a<hdAlphaTest)discard;\n float sunCos=dot(normalize(vHdWorld-hdPlanetCenter),normalize(hdSunPosition-vHdWorld));\n // Styled source radiance only: physical day/night gates a bounded unlit\n // source, without claiming calibrated irradiance or inventing night lights.\n float daylight=${kind === 'moon' ? 'max(0.0,sunCos)' : 'mix(.04,1.0,smoothstep(-.12,.18,sunCos))'};\n gl_FragColor=vec4(${source.userData?.photoDarkUnderside ? 'gl_FrontFacing?color.rgb*daylight:vec3(0.0)' : 'color.rgb*daylight'},${source.transparent ? 'color.a' : '1.0'});\n #include <colorspace_fragment>\n}`,\n    });\n}\n\nconst appearanceVersion = (m) => `${m?.id}:${m?.version}:${m?.side}:${m?.transparent}:${m?.depthWrite}:${m?.depthTest}:${m?.blending}:${m?.vertexColors}:${m?.alphaTest}:${m?.userData?.photoDarkUnderside}:${m?.map?.id ?? 0}:${m?.map?.channel ?? 0}:${m?.alphaMap?.id ?? 0}:${m?.alphaMap?.channel ?? 0}:${m?.displacementMap?.id ?? 0}:${m?.displacementMap?.channel ?? 0}:${m?.displacementScale}:${m?.displacementBias}:${m?.uniforms?.orbitalDayTexture?.value?.id ?? 0}`;\nconst geometryVariant = (geometry) => `${geometry.attributes.color?.itemSize ?? 0}:${!!geometry.attributes.uv2}`;\nconst sceneShell = () => { const scene = new Scene(); scene.background = new Color(0); return scene; };\n\n/** Optional final-frame owner. It borrows only transforms/CPU source positions;\n * original geometry, materials, visibility, renderer sizing and quality remain\n * owned by the native scene. All preparation runs on the existing frame clock.\n */\nexport class HdSceneProxy {\n    constructor({ getSources, getSourceVersion, waitForRetirement, getSunPosition, getPlanetCenter, mode = 'structure', width, height, now = clock } = {}) {\n        if (!['structure', 'color'].includes(mode)) throw new Error('Unknown HD proxy control mode');\n        if (mode === 'color' && typeof getSunPosition !== 'function') throw new Error('HD color control requires the physical sun source');\n        this.mode = mode; this.getSunPosition = getSunPosition; this.getPlanetCenter = getPlanetCenter;\n        this.lighting = { hdSunPosition: { value: new Vector3() }, hdPlanetCenter: { value: new Vector3() } };\n        this.getSources = getSources; this.getSourceVersion = getSourceVersion; this.now = now; this.setSize(width, height);\n        this.materialCache = new Map(); this.geometryCache = new Map(); this.bodyCenters = new WeakMap(); this.rootFrames = new WeakMap(); this.updateSequence = 0;\n        this.waiting = !!waitForRetirement;\n        if (waitForRetirement) Promise.resolve(waitForRetirement).then(() => { this.waiting = false; }, () => { this.waiting = false; });\n        this.scene = sceneShell();\n        this.entries = []; this.pending = null; this.frame = 0; this.disposed = false;\n        this.stats = { mode, ready: false, preparing: true, meshes: 0, triangles: 0, sourceTriangles: 0, error: null };\n        this._viewport = new Vector4(); this._scissor = new Vector4(); this._clearColor = new Color();\n        this._frustum = new Frustum(); this._viewProjection = new Matrix4(); this._sphere = new Sphere();\n        this._lastCamera = new Matrix4(); this._lastProjection = new Matrix4();\n        this.nextInventoryAt = 0;\n    }\n    setSize(width, height) {\n        if (!Number.isInteger(width) || !Number.isInteger(height) || width < 1 || height < 1 || width * height > 864 * 480) throw new Error('Invalid HD proxy dimensions');\n        this.width = width; this.height = height;\n    }\n    *_prepare(sources) {\n        const entries = [], candidates = [], stack = [], queued = new Set(), visited = new Set(), roots = new Set(), variants = new Set(), nextScene = sceneShell();\n        let triangles = 0, sourceTriangles = 0, completed = false, slots = 0;\n        try {\n            for (const source of sources) {\n                if (!source.object || roots.has(source.object)) { yield; continue; }\n                roots.add(source.object); queued.add(source.object); stack.push({ object: source.object, source }); yield;\n            }\n            while (stack.length) {\n                const { object, source } = stack.pop(); queued.delete(object);\n                if (!object || visited.has(object)) { yield; continue; }\n                visited.add(object);\n                if (visited.size > HD_PROXY_LIMITS.nodes) throw new Error('HD proxy source inventory exceeds its unique node bound');\n                if (object.visible === false) { yield; continue; }\n                for (const child of object.children) {\n                    if (!visited.has(child) && !queued.has(child)) {\n                        if (visited.size + queued.size >= HD_PROXY_LIMITS.nodes) throw new Error('HD proxy source inventory exceeds its node bound');\n                        queued.add(child); stack.push({ object: child, source });\n                    }\n                    yield;\n                }\n                if (!object.isMesh || (source.accept && !source.accept(object))) { yield; continue; }\n                const originals = Array.isArray(object.material) ? object.material : [object.material];\n                if (originals.length > HD_PROXY_LIMITS.materialSlotsPerMesh) throw new Error('HD proxy material slots exceed their per-mesh bound');\n                if (!materialVisible(object.material) || (this.camera && !this.camera.layers.test(object.layers))) { yield; continue; }\n                if (object.isSkinnedMesh || object.isInstancedMesh || object.isBatchedMesh || object.geometry?.morphAttributes?.position?.length) throw new Error('HD proxy source has unsupported dynamic vertex transforms');\n                const position = object.geometry?.getAttribute?.('position');\n                if (!position || position.itemSize !== 3 || !Number.isSafeInteger(position.count) || position.count < 3 || (this.mode !== 'color' && position.count > HD_PROXY_LIMITS.sourceVertices)) throw new Error('HD proxy source geometry exceeds its supported vertex bound');\n                if (object.geometry.getAttribute('positionHigh') || object.geometry.getAttribute('positionLow')) throw new Error('HD proxy requires resolved local positions, not high/low encoded vertices');\n                if (this.camera && object.frustumCulled !== false && object.geometry.boundingSphere) {\n                    object.updateWorldMatrix(true, false);\n                    this._sphere.copy(object.geometry.boundingSphere).applyMatrix4(object.matrixWorld);\n                    if (!this._frustum.intersectsSphere(this._sphere)) { yield; continue; }\n                }\n                if (this.mode !== 'color' && candidates.length === HD_PROXY_LIMITS.meshes) throw new Error('HD proxy visible mesh capacity exceeded');\n                if ((slots += originals.length) > HD_PROXY_LIMITS.materialSlots) throw new Error('HD proxy material reference capacity exceeded');\n                let materialVersion = '';\n                for (const material of originals) { materialVersion += appearanceVersion(material) + '|'; yield; }\n                candidates.push({ object, source, materialVersion, geometryVariant: geometryVariant(object.geometry) }); yield;\n            }\n            let unchanged = candidates.length === this.entries.length;\n            for (let i = 0; unchanged && i < candidates.length; i++) {\n                const candidate = candidates[i], entry = this.entries[i];\n                unchanged = entry.object === candidate.object && entry.source.object === candidate.source.object\n                    && entry.frameRoot === (candidate.source.frameRoot || candidate.source.object)\n                    && entry.geometry === candidate.object.geometry && entry.version === candidate.object.geometry.attributes.position.version\n                    && !entry.geometryLease?.retired && entry.materialVersion === candidate.materialVersion && entry.geometryVariant === candidate.geometryVariant\n                    && (entry.owned || this.mode === 'color');\n                yield;\n            }\n            if (unchanged) { completed = true; return { unchanged: true }; }\n            if (this.mode === 'color') {\n                for (const candidate of candidates) {\n                    const { object, source } = candidate;\n                    const count = object.geometry.index?.count ?? object.geometry.attributes.position.count;\n                    triangles += Math.floor(Math.max(0, Math.min(count - (object.geometry.drawRange.start || 0), object.geometry.drawRange.count)) / 3);\n                    const entry = yield* this._colorEntry(candidate, variants);\n                    entries.push(entry); nextScene.add(entry.mesh); yield;\n                }\n                completed = true; return { entries, scene: nextScene, triangles, sourceTriangles: triangles };\n            }\n            if (!this.entries.length && candidates.length) {\n                for (const candidate of candidates) {\n                    const entry = this._entry(candidate.object, candidate.source, null, null, candidate);\n                    this.entries.push(entry); this.scene.add(entry.mesh); yield;\n                }\n                Object.assign(this.stats, { ready: true, meshes: this.entries.length, fitting: true,\n                    sourceTriangles: candidates.reduce((sum, { object }) => sum + Math.floor((object.geometry.index?.count ?? object.geometry.attributes.position.count) / 3), 0) });\n            }\n            const maxTriangles = Math.min(HD_PROXY_LIMITS.trianglesPerMesh, Math.floor(HD_PROXY_LIMITS.triangles / Math.max(1, candidates.length)));\n            for (const candidate of candidates) {\n                const { object, source } = candidate, sourceGeometry = object.geometry, sourceVersion = sourceGeometry.attributes.position.version;\n                const built = yield* buildHdProxyGeometry(sourceGeometry, { maxTriangles });\n                if (object.geometry !== sourceGeometry || sourceGeometry.attributes.position.version !== sourceVersion) { built.geometry.dispose(); return { retry: true }; }\n                triangles += built.triangles; sourceTriangles += built.sourceTriangles;\n                if (triangles > HD_PROXY_LIMITS.triangles) { built.geometry.dispose(); throw new Error('HD proxy visible triangle capacity exceeded'); }\n                const entry = this._entry(object, source, built, null, candidate);\n                entries.push(entry); nextScene.add(entry.mesh); yield;\n            }\n            completed = true; return { entries, scene: nextScene, triangles, sourceTriangles };\n        } finally {\n            if (!completed) this._retire(nextScene, entries);\n        }\n    }\n    *_colorEntry(candidate, variants) {\n        const { object, source } = candidate, kind = source.kind || (object.userData.tile || object.userData.isTriTreeSkirt ? 'terrain' : null);\n        let bodyCenter = null;\n        if (kind === 'moon') {\n            bodyCenter = this.bodyCenters.get(object);\n            if (!bodyCenter) this.bodyCenters.set(object, bodyCenter = { value: new Vector3() });\n        }\n        const lighting = bodyCenter ? { ...this.lighting, hdPlanetCenter: bodyCenter } : this.lighting;\n        const originals = Array.isArray(object.material) ? object.material : [object.material], leases = [];\n        let completed = false;\n        try {\n            for (const original of originals) {\n                const key = `${appearanceVersion(original)}:${candidate.geometryVariant}:${kind}:${bodyCenter ? object.id : ''}`;\n                variants.add(key);\n                if (variants.size > HD_PROXY_LIMITS.colorMaterials) throw new Error('HD color material variant capacity exceeded');\n                let lease = this.materialCache.get(key);\n                if (!lease) {\n                    if (this.materialCache.size >= HD_PROXY_LIMITS.liveColorMaterials) throw new Error('HD live color material capacity exceeded');\n                    const material = colorMaterial(original, object.geometry, lighting, kind);\n                    this.materialCache.set(key, lease = { key, material, original, refs: 0, version: appearanceVersion(original) });\n                }\n                lease.refs++; leases.push(lease); yield;\n            }\n            const entry = this._entry(object, source, null, { material: Array.isArray(object.material) ? leases.map(x => x.material) : leases[0].material, bodyCenter, leases }, candidate);\n            completed = true; return entry;\n        } finally { if (!completed) this._retire(null, [], leases); }\n    }\n    _releaseMaterial(lease) {\n        if (--lease.refs === 0) { this.materialCache.delete(lease.key); lease.material.dispose(); }\n    }\n    _retire(scene, entries, leases = []) {\n        if (!entries.length && !leases.length) return this.retirement || Promise.resolve();\n        // Detached scene graphs are emptied from the end: Three.remove searches\n        // its children, so removing an authored prefix would become quadratic.\n        const retire = function* (owner) {\n            for (let index = entries.length - 1; index >= 0; index--) {\n                const entry = entries[index];\n                if (scene) { scene.children.pop(); entry.mesh.parent = null; }\n                yield* owner._disposeEntry(entry); yield;\n            }\n            for (let index = leases.length - 1; index >= 0; index--) { owner._releaseMaterial(leases[index]); yield; }\n            entries.length = 0; leases.length = 0;\n        }(this);\n        const run = () => new Promise(resolve => {\n            const slice = () => {\n                const deadline = clock() + HD_PROXY_LIMITS.taskMs;\n                for (let count = 0; count < HD_PROXY_LIMITS.taskOperations; count++) {\n                    if (retire.next().done) { resolve(); return; }\n                    if (clock() >= deadline) break;\n                }\n                setTimeout(slice, 0);\n            };\n            slice();\n        });\n        const prior = this.retirement;\n        const retirement = prior ? prior.then(run) : run();\n        this.retiring = true;\n        this.retirement = retirement;\n        retirement.then(() => { if (this.retirement === retirement) this.retiring = false; });\n        return retirement;\n    }\n    _entry(object, source, built = null, color = null, candidate = null) {\n        const frameRoot = source.frameRoot || source.object;\n        object.updateWorldMatrix(true, false); frameRoot.updateWorldMatrix(true, false);\n        const origin = built?.origin || new Vector3();\n        const relative = new Matrix4().copy(frameRoot.matrixWorld).invert().multiply(object.matrixWorld)\n            .multiply(new Matrix4().makeTranslation(origin.x, origin.y, origin.z));\n        const originalMaterial = Array.isArray(object.material) ? object.material[0] : object.material;\n        const kind = source.kind || (object.userData.tile || object.userData.isTriTreeSkirt ? 'terrain' : null);\n        const bodyCenter = color?.bodyCenter || null;\n        const material = this.mode === 'color'\n            ? color.material\n            : proxyMaterial(originalMaterial.side, originalMaterial.userData?.photoDarkUnderside === true);\n        const mesh = new Mesh(built?.geometry || object.geometry, material);\n        const centre = built?.origin || object.geometry.boundingSphere?.center || new Vector3();\n        const up = centre.clone().applyMatrix4(object.matrixWorld).normalize().transformDirection(new Matrix4().copy(object.matrixWorld).invert());\n        if (this.mode === 'structure') material.uniforms.hdUp.value.copy(up);\n        const bounds = built || object.geometry.boundingBox;\n        if (this.mode === 'structure' && bounds?.min && bounds?.max) {\n            const lo = bounds.min.clone().sub(origin), hi = bounds.max.clone().sub(origin);\n            material.uniforms.hdFloor.value = Math.min(lo.x * up.x, hi.x * up.x) + Math.min(lo.y * up.y, hi.y * up.y) + Math.min(lo.z * up.z, hi.z * up.z);\n        }\n        if (this.mode === 'structure') material.uniforms.hdColor.value.setHSL(((object.id * .61803398875) % 1), .22, .48);\n        mesh.matrixAutoUpdate = mesh.matrixWorldAutoUpdate = false;\n        mesh.name = 'HdProxy:' + object.name; mesh.frustumCulled = object.frustumCulled; mesh.layers.mask = object.layers.mask; mesh.renderOrder = object.renderOrder;\n        const entry = { source, frameRoot, mesh, relative, object, kind, bodyCenter, owned: !!built, geometry: object.geometry,\n            version: object.geometry.attributes.position.version, materialVersion: candidate?.materialVersion, geometryVariant: candidate?.geometryVariant, leases: color?.leases };\n        if (!built) {\n            let lease = this.geometryCache.get(object.geometry);\n            if (!lease) {\n                lease = { geometry: object.geometry, refs: 0, retired: false };\n                lease.listener = () => { lease.retired = true; this.nextInventoryAt = 0; };\n                this.geometryCache.set(object.geometry, lease); object.geometry.addEventListener('dispose', lease.listener);\n            }\n            lease.refs++; entry.geometryLease = lease;\n        }\n        return entry;\n    }\n    *_disposeEntry(entry) {\n        const geometry = entry.geometryLease;\n        if (geometry && --geometry.refs === 0) {\n            geometry.geometry.removeEventListener('dispose', geometry.listener); this.geometryCache.delete(geometry.geometry);\n        }\n        if (entry.owned) entry.mesh.geometry.dispose();\n        if (entry.leases) for (const lease of entry.leases) { this._releaseMaterial(lease); yield; }\n        else for (const material of Array.isArray(entry.mesh.material) ? entry.mesh.material : [entry.mesh.material]) { material.dispose(); yield; }\n    }\n    update() {\n        if (this.disposed) return;\n        if (this.mode === 'color') {\n            const sun = this.getSunPosition();\n            if (!sun || ![sun.x, sun.y, sun.z].every(Number.isFinite) || sun.lengthSq() < 1) {\n                this.stats.ready = false; this.stats.error = 'HD color control has no physical sun position'; return;\n            }\n            this.lighting.hdSunPosition.value.copy(sun);\n            const center = this.getPlanetCenter?.();\n            if (center) this.lighting.hdPlanetCenter.value.copy(center);\n        }\n        const now = this.now();\n        if (this.waiting) return;\n        const revision = this.getSourceVersion?.();\n        if (revision !== this.sourceVersion) { this.sourceVersion = revision; this.nextInventoryAt = 0; }\n        if (!this.pending && !this.retiring && now >= this.nextInventoryAt) {\n            const sources = this.getSources?.() || [];\n            const rootLimit = this.mode === 'color' ? HD_PROXY_LIMITS.nodes : HD_PROXY_LIMITS.sourceRoots;\n            if (sources.length > rootLimit) throw new Error('HD proxy source root capacity exceeded');\n            this.nextInventoryAt = now + 1000;\n            this.pending = this._prepare(sources); this.stats.preparing = true;\n        }\n        if (this.pending) {\n            const deadline = this.now() + HD_PROXY_LIMITS.taskMs;\n            try {\n                for (let i = 0; i < HD_PROXY_LIMITS.taskOperations; i++) {\n                    const value = this.pending.next();\n                    if (value.done) {\n                        if (value.value.retry) { this.nextInventoryAt = 0; this.pending = null; break; }\n                        if (value.value.unchanged) { this.stats.preparing = false; this.pending = null; break; }\n                        const previous = this.entries, previousScene = this.scene;\n                        this.entries = value.value.entries; this.scene = value.value.scene;\n                        this._retire(previousScene, previous);\n                        Object.assign(this.stats, { ready: this.entries.length > 0, preparing: false, fitting: false, error: null, meshes: this.entries.length, triangles: value.value.triangles, sourceTriangles: value.value.sourceTriangles });\n                        this.pending = null; break;\n                    }\n                    if (this.now() >= deadline) break;\n                }\n            } catch (error) {\n                this.pending = null; Object.assign(this.stats, { preparing: false, error: error.message });\n            }\n        }\n        this.updateSequence++;\n        const updatedRoots = new Set();\n        for (const entry of this.entries) {\n            if (!updatedRoots.has(entry.frameRoot)) { entry.frameRoot.updateWorldMatrix(true, false); updatedRoots.add(entry.frameRoot); }\n            entry.mesh.matrixWorld.multiplyMatrices(entry.frameRoot.matrixWorld, entry.relative);\n            entry.mesh.visible = nativeVisible(entry, this.camera);\n            if (entry.leases) for (const lease of entry.leases) {\n                if (lease.updatedAt === this.updateSequence) continue;\n                lease.updatedAt = this.updateSequence;\n                const original = lease.original, material = lease.material;\n                material.visible = original.visible !== false; material.uniforms.hdOpacity.value = original.opacity ?? 1;\n                material.uniforms.hdAlphaTest.value = original.alphaTest || 0;\n                if (original.color) material.uniforms.hdDiffuse.value.copy(original.color);\n                if (appearanceVersion(original) !== lease.version) this.nextInventoryAt = 0;\n            }\n            if (entry.bodyCenter) entry.bodyCenter.value.setFromMatrixPosition(entry.object.matrixWorld);\n        }\n    }\n    render(renderer, camera) {\n        this.camera = camera;\n        camera.updateWorldMatrix(true, false);\n        if (!this._lastCamera.equals(camera.matrixWorld) || !this._lastProjection.equals(camera.projectionMatrix)) {\n            this.nextInventoryAt = Math.min(this.nextInventoryAt, this.now() + 100);\n            this._lastCamera.copy(camera.matrixWorld); this._lastProjection.copy(camera.projectionMatrix);\n        }\n        this._viewProjection.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse);\n        this._frustum.setFromProjectionMatrix(this._viewProjection, camera.coordinateSystem);\n        this.update();\n        if (!this.stats.ready || this.disposed) return false;\n        const target = renderer.getRenderTarget(), viewport = renderer.getViewport(this._viewport), scissor = renderer.getScissor(this._scissor);\n        renderer.getClearColor(this._clearColor);\n        const clearAlpha = renderer.getClearAlpha(), scissorTest = renderer.getScissorTest(), autoClear = renderer.autoClear;\n        const toneMapping = renderer.toneMapping, shadowAutoUpdate = renderer.shadowMap?.autoUpdate;\n        try {\n            const scale = Math.min(1, renderer.domElement.width / this.width, renderer.domElement.height / this.height);\n            this.captureWidth = Math.max(1, Math.floor(this.width * scale)); this.captureHeight = Math.max(1, Math.floor(this.height * scale));\n            const ratio = renderer.getPixelRatio();\n            renderer.setRenderTarget(null); renderer.setViewport(0, 0, this.captureWidth / ratio, this.captureHeight / ratio);\n            renderer.setScissor(0, 0, this.captureWidth / ratio, this.captureHeight / ratio); renderer.setScissorTest(true);\n            renderer.setClearColor(0, 1); renderer.autoClear = true; renderer.toneMapping = NoToneMapping;\n            if (renderer.shadowMap) renderer.shadowMap.autoUpdate = false;\n            renderer.render(this.scene, camera); this.frame++; this.lastRenderedAt = this.now();\n            this.renderedCanvasWidth = renderer.domElement.width; this.renderedCanvasHeight = renderer.domElement.height;\n            return true;\n        } finally {\n            renderer.toneMapping = toneMapping; renderer.autoClear = autoClear;\n            if (renderer.shadowMap) renderer.shadowMap.autoUpdate = shadowAutoUpdate;\n            renderer.setClearColor(this._clearColor, clearAlpha); renderer.setRenderTarget(target);\n            renderer.setViewport(viewport); renderer.setScissor(scissor); renderer.setScissorTest(scissorTest);\n        }\n    }\n    status() { return { ...this.stats, frame: this.frame, width: this.width, height: this.height,\n        sourceWidth: this.captureWidth ?? null, sourceHeight: this.captureHeight ?? null, lastRenderedAt: this.lastRenderedAt ?? null }; }\n    captureSource(renderer) {\n        if (!this.frame || this.disposed || this.renderedCanvasWidth !== renderer.domElement.width || this.renderedCanvasHeight !== renderer.domElement.height) return null;\n        return { source: renderer.domElement, sx: 0, sy: renderer.domElement.height - this.captureHeight, sw: this.captureWidth, sh: this.captureHeight, ...this.status() };\n    }\n    dispose() {\n        if (this.disposed) return this.retirement || Promise.resolve();\n        this.disposed = true; this.pending?.return(); this.pending = null;\n        const entries = this.entries, scene = this.scene;\n        this.entries = []; this.scene = sceneShell(); this.getSources = null; this.getSourceVersion = null;\n        this._retire(scene, entries);\n        return this.retirement || Promise.resolve();\n    }\n}\n","/**\n * TerrainPathfinder\n *\n * Computes a low-cost surface path between two directions on the globe by\n * sampling terrain, building a small grid in a corridor, and running A* with\n * a slope-aware cost. Designed for short paths (camera to hover hex).\n */\n\nimport * as THREE from 'three';\nimport { PLANET_RADIUS } from './constants.js';\nimport { ellipsoidRadiusForLocalDir } from './geometry-utils.js';\n\nexport class TerrainPathfinder {\n    constructor(options = {}) {\n        this.maxStepsS = options.maxStepsS ?? 64;   // along-path resolution\n        this.maxStepsT = options.maxStepsT ?? 17;   // lateral resolution (odd preferred)\n        this.lateralMaxDeg = options.lateralMaxDeg ?? 5; // corridor half-width in degrees\n\n        // Cost weights\n        this.weightUphill = options.weightUphill ?? 8;\n        this.weightDownhill = options.weightDownhill ?? 1.5;\n        this.weightElevDelta = options.weightElevDelta ?? 0.5;\n        this.weightRough = options.weightRough ?? 0.25;\n        this.weightLateral = options.weightLateral ?? 1.0;\n        this.weightHigh = options.weightHigh ?? 0.5;\n        this.weightSlopeSq = options.weightSlopeSq ?? 0.0;\n        this.weightDistance = options.weightDistance ?? 1.0;\n\n        // Smoothing\n        this.smoothIterations = options.smoothIterations ?? 2;\n    }\n\n    /**\n     * Compute a terrain-aware path between two directions.\n     * @param {THREE.Vector3} startDir\n     * @param {THREE.Vector3} endDir\n     * @param {TriTreeManager} triTree\n     * @param {Object} opts\n     * @returns {THREE.Vector3[]|null}\n     */\n    computePath(startDir, endDir, triTree, opts = {}) {\n        if (!triTree || !startDir || !endDir) return null;\n        const sDir = startDir.clone().normalize();\n        const eDir = endDir.clone().normalize();\n        const theta = sDir.angleTo(eDir);\n        if (!Number.isFinite(theta) || theta < 1e-5) return null;\n        const pathRadius = (ellipsoidRadiusForLocalDir(sDir) + ellipsoidRadiusForLocalDir(eDir)) * 0.5;\n\n        const weightUphill = opts.weightUphill ?? this.weightUphill;\n        const weightDownhill = opts.weightDownhill ?? this.weightDownhill;\n        const weightElevDelta = opts.weightElevDelta ?? this.weightElevDelta;\n        const weightRough = opts.weightRough ?? this.weightRough;\n        const weightLateral = opts.weightLateral ?? this.weightLateral;\n        const weightHigh = opts.weightHigh ?? this.weightHigh;\n        const smoothIterations = opts.smoothIterations ?? this.smoothIterations;\n        const weightSlopeSq = opts.weightSlopeSq ?? this.weightSlopeSq;\n        const weightDistance = opts.weightDistance ?? this.weightDistance;\n        const collisionPenalty = opts.collisionPenalty ?? 5e6;\n        const clearance = opts.clearance ?? 0.35;\n\n        const axis = new THREE.Vector3().crossVectors(sDir, eDir).normalize();\n        if (!Number.isFinite(axis.lengthSq()) || axis.lengthSq() < 1e-12) return null;\n\n        const stepsS = Math.max(4, Math.min(this.maxStepsS, opts.stepsS ?? this.maxStepsS));\n        const stepsT = Math.max(3, Math.min(this.maxStepsT, opts.stepsT ?? this.maxStepsT));\n        const startCol = Math.floor(stepsT / 2);\n        const goalCol = startCol;\n        const lateralMaxRad = THREE.MathUtils.degToRad(opts.lateralMaxDeg ?? this.lateralMaxDeg);\n\n        // Precompute directions and elevations\n        const dirs = new Array(stepsS * stepsT);\n        const elevs = new Float32Array(stepsS * stepsT);\n        const radii = new Float32Array(stepsS * stepsT);\n        let minElev = Infinity;\n        let maxElev = -Infinity;\n\n        const sampleRadius = (dir) => {\n            if (triTree && typeof triTree.sampleTerrainRadiusForDir === 'function') {\n                const r = triTree.sampleTerrainRadiusForDir(dir);\n                if (Number.isFinite(r)) return r;\n            }\n            if (triTree && typeof triTree.getSurfaceRadiusAtDir === 'function') {\n                const r = triTree.getSurfaceRadiusAtDir(dir);\n                if (Number.isFinite(r)) return r;\n            }\n            return PLANET_RADIUS;\n        };\n\n        const dirAt = (i, j) => {\n            const tNorm = stepsT <= 1 ? 0 : (j / (stepsT - 1)) * 2 - 1; // [-1,1]\n            const s = stepsS <= 1 ? 0 : i / (stepsS - 1); // [0,1]\n            const angleS = theta * s;\n            const baseDir = sDir.clone().applyAxisAngle(axis, angleS).normalize();\n\n            // Tangent along path = axis x baseDir\n            const tangent = new THREE.Vector3().crossVectors(axis, baseDir).normalize();\n            const latAngle = tNorm * lateralMaxRad;\n            if (Math.abs(latAngle) < 1e-6 || tangent.lengthSq() < 1e-12) {\n                return baseDir;\n            }\n            return baseDir.clone().applyAxisAngle(tangent, latAngle).normalize();\n        };\n\n        for (let i = 0; i < stepsS; i++) {\n            for (let j = 0; j < stepsT; j++) {\n                const idx = i * stepsT + j;\n                let dir = dirAt(i, j);\n                // Force exact endpoints in the center column\n                if (i === 0 && j === startCol) dir = sDir.clone();\n                if (i === stepsS - 1 && j === goalCol) dir = eDir.clone();\n                dirs[idx] = dir;\n                const radius = sampleRadius(dir);\n                radii[idx] = radius;\n                const elev = radius - ellipsoidRadiusForLocalDir(dir);\n                elevs[idx] = elev;\n                if (elev < minElev) minElev = elev;\n                if (elev > maxElev) maxElev = elev;\n            }\n        }\n\n        const elevRange = Math.max(1, maxElev - minElev);\n        const lateralPenalty = (j) => {\n            const tNorm = stepsT <= 1 ? 0 : (j / (stepsT - 1)) * 2 - 1;\n            return Math.abs(tNorm);\n        };\n\n        // A* on grid\n        const total = stepsS * stepsT;\n        const gScore = new Float64Array(total).fill(Infinity);\n        const fScore = new Float64Array(total).fill(Infinity);\n        const cameFrom = new Int32Array(total).fill(-1);\n        const open = [];\n        const inOpen = new Uint8Array(total);\n\n        const startIdx = startCol;\n        const goalIdx = (stepsS - 1) * stepsT + goalCol;\n\n        const heuristic = (idx) => {\n            const i = Math.floor(idx / stepsT);\n            const j = idx % stepsT;\n            const sRem = (stepsS - 1 - i) / Math.max(1, stepsS - 1);\n            const distAlong = theta * sRem * pathRadius;\n            const lateral = lateralPenalty(j) * lateralMaxRad * pathRadius;\n            return distAlong + lateral;\n        };\n\n        gScore[startIdx] = 0;\n        fScore[startIdx] = heuristic(startIdx);\n        open.push(startIdx);\n        inOpen[startIdx] = 1;\n\n        const neighbors = [\n            [1, 0], [0, 1], [0, -1], [-1, 0],\n            [1, 1], [1, -1], [-1, 1], [-1, -1]\n        ];\n\n        while (open.length) {\n            // Extract node with lowest fScore (small heap not necessary for small grids)\n            let bestIdx = 0;\n            let bestF = fScore[open[0]];\n            for (let k = 1; k < open.length; k++) {\n                const idx = open[k];\n                if (fScore[idx] < bestF) {\n                    bestF = fScore[idx];\n                    bestIdx = k;\n                }\n            }\n            const current = open.splice(bestIdx, 1)[0];\n            inOpen[current] = 0;\n            if (current === goalIdx) break;\n\n            const ci = Math.floor(current / stepsT);\n            const cj = current % stepsT;\n            const cDir = dirs[current];\n            const cRad = radii[current];\n            const cElev = elevs[current];\n\n            for (const [di, dj] of neighbors) {\n                const ni = ci + di;\n                const nj = cj + dj;\n                if (ni < 0 || ni >= stepsS || nj < 0 || nj >= stepsT) continue;\n                const nIdx = ni * stepsT + nj;\n                const nDir = dirs[nIdx];\n                const nRad = radii[nIdx];\n                const nElev = elevs[nIdx];\n\n                // Horizontal distance along sphere\n                const angle = Math.acos(THREE.MathUtils.clamp(cDir.dot(nDir), -1, 1));\n                const horiz = angle * ((cRad + nRad) * 0.5);\n                const elevDelta = nElev - cElev;\n                const slope = horiz > 0 ? elevDelta / horiz : 0;\n\n                const horizCost = horiz * weightDistance;\n                let cost = horizCost;\n                if (slope > 0) cost += weightUphill * slope * horizCost;\n                else cost += weightDownhill * Math.abs(slope) * horizCost;\n                const slopeAbs = Math.abs(slope);\n                cost += weightSlopeSq * slopeAbs * slopeAbs * horizCost;\n                cost += weightElevDelta * Math.abs(elevDelta);\n                // roughness approximated by local gradient using lateral penalty\n                cost += weightRough * lateralPenalty(nj) * horizCost;\n                const heightNorm = (nElev - minElev) / elevRange;\n                cost += weightHigh * heightNorm * horizCost;\n                cost += weightLateral * lateralPenalty(nj) * horizCost;\n\n                // Collision check: if straight segment dips below terrain at midpoint, heavily penalize\n                const midDir = new THREE.Vector3().addVectors(cDir, nDir).normalize();\n                const midTerrainR = sampleRadius(midDir);\n                const cPos = cDir.clone().multiplyScalar(cRad + clearance);\n                const nPos = nDir.clone().multiplyScalar(nRad + clearance);\n                const midPos = new THREE.Vector3().addVectors(cPos, nPos).multiplyScalar(0.5);\n                if (midPos.length() < midTerrainR - 0.01) {\n                    cost += collisionPenalty;\n                }\n\n                const tentative = gScore[current] + cost;\n                if (tentative < gScore[nIdx]) {\n                    cameFrom[nIdx] = current;\n                    gScore[nIdx] = tentative;\n                    fScore[nIdx] = tentative + heuristic(nIdx);\n                    if (!inOpen[nIdx]) {\n                        open.push(nIdx);\n                        inOpen[nIdx] = 1;\n                    }\n                }\n            }\n        }\n\n        // Reconstruct path\n        const pathIdx = [];\n        let cur = goalIdx;\n        if (!Number.isFinite(gScore[cur]) || gScore[cur] === Infinity) return null;\n        pathIdx.push(cur);\n        while (cameFrom[cur] !== -1 && pathIdx.length < total + 2) {\n            cur = cameFrom[cur];\n            pathIdx.push(cur);\n        }\n        pathIdx.reverse();\n\n        const path = [];\n        for (const idx of pathIdx) {\n            const dir = dirs[idx];\n            let rad = radii[idx] + clearance;\n            // Nudge above terrain if sample says we're below\n            const terrainR = sampleRadius(dir);\n            const targetMin = terrainR + clearance;\n            if (rad < targetMin) {\n                rad = targetMin;\n            }\n            path.push(dir.clone().multiplyScalar(rad));\n        }\n\n        // Smooth path (simple Laplacian, preserve endpoints)\n        const smoothCount = Math.max(0, smoothIterations);\n        for (let s = 0; s < smoothCount; s++) {\n            for (let i = 1; i < path.length - 1; i++) {\n                const prev = path[i - 1];\n                const next = path[i + 1];\n                path[i].lerpVectors(prev, next, 0.5);\n            }\n        }\n\n        return path;\n    }\n}\n","// Finite single scattering of the existing upward city-radiance field.\n// Reuses the custom Bruneton density/phase/extinction parameters and samplers.\n// Four quadrature points; no target, light objects, frame owner or clock.\nexport const NIGHT_AIR_LIGHTING_GLSL = `\nvec2 ncaCityAirInterval(vec3 origin,vec3 direction,vec3 axes){\n  vec3 o=origin/axes,d=direction/axes;\n  float a=dot(d,d),b=dot(o,d),c=dot(o,o)-1.0,h=b*b-a*c;\n  if(h<0.0)return vec2(-1.0);\n  float root=sqrt(h);return vec2((-b-root)/a,(-b+root)/a);\n}\nfloat ncaCityAirLayer(DensityProfileLayer layer,float height){\n  return clamp(layer.exp_term*exp(layer.exp_scale*height)+layer.linear_term*height+layer.constant_term,0.0,1.0);\n}\nfloat ncaCityAirDensity(DensityProfile profile,float height){\n  if(height<profile.layers[0].width)return ncaCityAirLayer(profile.layers[0],height);\n  return ncaCityAirLayer(profile.layers[1],height);\n}\nfloat ncaCityAirRayLimit(vec2 uv){\n  float raw=readDepthValue(depthBuffer,uv);\n  if(raw>=1.0-1e-7)return 1e12;\n  #if defined(PERSPECTIVE_CAMERA) && (defined(USE_LOGDEPTHBUF) || defined(USE_LOGARITHMIC_DEPTH_BUFFER))\n  float z=1.0-exp2(raw*log2(cameraFar+1.0));\n  vec3 ray=(inverseProjectionMatrix*vec4(uv*2.0-1.0,0.0,1.0)).xyz;\n  return length(ray*(z/ray.z));\n  #else\n  float depth=reverseLogDepth(raw,cameraNear,cameraFar);\n  return length(screenToView(uv,depth,getViewZ(depth),projectionMatrix,inverseProjectionMatrix));\n  #endif\n}\nvec3 ncaCityAirRadiance(vec3 origin,vec3 direction,float maximumDistance){\n  if(ncaLightPollutionEnabled<.5)return vec3(0.0);\n  vec2 outer=ncaCityAirInterval(origin,direction,vec3(6408137.0,6386752.314245,6408137.0));\n  float start=max(0.0,outer.x),end=min(outer.y,maximumDistance);\n  vec2 solid=ncaCityAirInterval(origin,direction,vec3(6378137.0,6356752.314245,6378137.0));\n  if(solid.x>start)end=min(end,solid.x);\n  else if(solid.y>start)start=solid.y;\n  if(end<=start)return vec3(0.0);\n  vec3 midpoint=origin+direction*((start+end)*.5);\n  float night=1.0-smoothstep(ncaNightTransitionStart,ncaNightTransitionEnd,dot(normalize(midpoint),sunDirection));\n  if(night<.001)return vec3(0.0);\n  vec3 radiance=vec3(0.0),transmission=vec3(1.0);\n  const vec4 nodes=vec4(.0694318442,.3300094782,.6699905218,.9305681558);\n  const vec4 weights=vec4(.1739274226,.3260725774,.3260725774,.1739274226);\n  for(int i=0;i<4;i++){\n    float distanceAlong=mix(start,end,nodes[i]);vec3 point=origin+direction*distanceAlong;\n    float height=max(0.0,length(point)-ncaWaterReferenceRadius(point));\n    float h=height*METER_TO_LENGTH_UNIT;\n    float rayleigh=ncaCityAirDensity(ATMOSPHERE.rayleigh_density,h);\n    float mie=ncaCityAirDensity(ATMOSPHERE.mie_density,h);\n    float absorption=ncaCityAirDensity(ATMOSPHERE.absorption_density,h);\n    vec3 betaR=ATMOSPHERE.rayleigh_scattering*rayleigh*METER_TO_LENGTH_UNIT;\n    vec3 betaM=ATMOSPHERE.mie_scattering*mie*METER_TO_LENGTH_UNIT;\n    vec3 extinction=betaR+ATMOSPHERE.mie_extinction*mie*METER_TO_LENGTH_UNIT\n      +ATMOSPHERE.absorption_extinction*absorption*METER_TO_LENGTH_UNIT;\n    float cosine=dot(normalize(point),-direction);\n    vec3 scattering=betaR*(4.0*PI*RayleighPhaseFunction(cosine))\n      +betaM*(4.0*PI*MiePhaseFunction(ATMOSPHERE.mie_phase_function_g,cosine));\n    vec3 attenuation=exp(-extinction*((end-start)*weights[i]));\n    vec3 source=ncaNightCloudRadiance(point,height)*night;\n    radiance+=transmission*source*scattering/max(extinction,vec3(1e-9))*(1.0-attenuation);\n    transmission*=attenuation;\n  }\n  return radiance;\n}\n`;\nconst overlay = 'outputColor.rgb = outputColor.rgb * (1.0 - overlay.a) + overlay.rgb;';\nexport function patchNightAirLighting(shader){\n  if(shader.includes('/* CITY_AIR_SCATTERING */'))return {shader,compatible:true};\n  const sky=`    #ifdef HAS_OVERLAY\\n    ${overlay}`;\n  const ground=`  #ifdef HAS_OVERLAY\\n  ${overlay}`;\n  if(!shader.includes(sky)||!shader.includes(ground)||!shader.includes('void mainImage('))return {shader,compatible:false};\n  const origin='(worldToECEFMatrix * inverseViewMatrix * vec4(0.0,0.0,0.0,1.0)).xyz';\n  shader=shader.replace('void mainImage(',NIGHT_AIR_LIGHTING_GLSL+'\\nvoid mainImage(')\n    .replace(sky,`    /* CITY_AIR_SCATTERING */\\n    outputColor.rgb += ncaCityAirRadiance(${origin},rayDirection,ncaCityAirRayLimit(uv));\\n${sky}`)\n    .replace(ground,`  outputColor.rgb += ncaCityAirRadiance(${origin},rayDirection,ncaCityAirRayLimit(uv));\\n${ground}`);\n  return {shader,compatible:true};\n}\n","import { Effect, BlendFunction } from 'postprocessing';\nimport { Uniform } from 'three';\n\n/** Existing R8 lighting mask: zero = background, one = front, half = back.\n * Keep opaque hardware depth and reuse the already allocated target/sampler.\n */\nexport function patchPhotorealBackface(shader) {\n    if (shader.includes('/* PHOTO_ABSORBING_BACKFACE */')) return shader;\n    const main = 'void mainImage(const vec4 inputColor, const vec2 uv, out vec4 outputColor)';\n    if (!shader.includes(main)) throw new Error('Photoreal back-face compositor signature changed');\n    return 'uniform float ncaPhotoBackfaceEnabled;\\n' + shader.replace(main, main.replace('mainImage', 'ncaPhotorealMainImage')) + `\n/* PHOTO_ABSORBING_BACKFACE */\n${main} {\n    ncaPhotorealMainImage(inputColor, uv, outputColor);\n    #ifdef HAS_LIGHTING_MASK\n    float ncaFace = texture(lightingMaskBuffer, uv).LIGHTING_MASK_CHANNEL_;\n    if (ncaPhotoBackfaceEnabled > 0.5 && ncaFace > 0.25 && ncaFace < 0.75) outputColor = vec4(0.0, 0.0, 0.0, 1.0);\n    #endif\n}\n`;\n}\n\n/** Last operation in the existing display EffectPass, after water/cloud color,\n * bloom, assisted vision and SAR. One existing R8 target, no extra scene pass.\n */\nexport class PhotorealBackfaceEffect extends Effect {\n    constructor(mask, enabled = true) {\n        super('PhotorealBackfaceEffect', `\nuniform sampler2D photoFaceMask;\nuniform float photoFaceMaskEnabled;\nvoid mainImage(const in vec4 inputColor, const in vec2 uv, out vec4 outputColor) {\n    float face = texture2D(photoFaceMask, uv).r;\n    outputColor = photoFaceMaskEnabled > 0.5 && face > 0.25 && face < 0.75\n        ? vec4(0.0, 0.0, 0.0, 1.0) : inputColor;\n}`, { blendFunction: BlendFunction.NORMAL, uniforms: new Map([\n            ['photoFaceMask', new Uniform(mask)], ['photoFaceMaskEnabled', new Uniform(enabled ? 1 : 0)],\n        ]) });\n    }\n}\n","// Generic visible nightglow layers, not a live chemistry/space-weather product.\n// NASA Earth Observatory: Na/OH 85–90 km, OI 557.7 nm 95–100 km;\n// NASA NTRS 19670010932: OI 630.0 nm primarily 200–300 km.\nexport const AIRGLOW_EMISSION_DEFAULTS = Object.freeze({\n  strength:.005,baseAltitudeMeters:80000,coreAltitudeMeters:97000,fringeAltitudeMeters:330000,\n  riseScaleMeters:4500,tailScaleMeters:35000,\n});\n\n// Night limb haze: faint light scattered in the lower atmosphere (nightglow,\n// city glow, starlight). Integrated along the line of sight like the emission\n// layers, it brightens rays that graze the night limb (long air paths) and\n// fades inward over the disc and outward with tangent height, so the dark\n// disc meets the sky through a soft band. Night side only; daytime\n// scattering belongs to the physical sky pass.\nexport const NIGHT_LIMB_HAZE = Object.freeze({\n  topMeters: 60000, scaleHeightMeters: 14000, emissivity: 3.0, color: Object.freeze([0.55, 0.75, 0.65]),\n});\nconst haze = NIGHT_LIMB_HAZE;\n\nexport const AIRGLOW_EMISSION_GLSL = /* glsl */`\nvec3 airglowNightHaze(vec3 p,vec3 sunDir){\n  float altitude=airglowAltitude(p);\n  if(altitude>${haze.topMeters.toFixed(1)})return vec3(0.0);\n  float night=1.0-smoothstep(-.12,.08,dot(normalize(p),sunDir));\n  return vec3(${haze.color.map((v) => v.toFixed(3)).join(',')})*${haze.emissivity.toFixed(3)}\n    *exp(-max(altitude,0.0)/${haze.scaleHeightMeters.toFixed(1)})*night;\n}\nfloat airglowGaussian(float altitude,float mean,float sigma){\n  float q=(altitude-mean)/max(1000.0,sigma);return exp(-.5*q*q);\n}\nvec3 airglowEmission(vec3 p,vec3 rd,vec3 sunDir){\n  vec3 nightHaze=airglowNightHaze(p,sunDir);\n  float altitude=airglowAltitude(p);\n  if(altitude<uBaseAlt||altitude>uFringeAlt)return nightHaze;\n  float sodium=airglowGaussian(altitude,uCoreAlt-9500.0,2500.0)*.35;\n  float hydroxyl=airglowGaussian(altitude,uCoreAlt-10000.0,4500.0)*.12;\n  float green=airglowGaussian(altitude,uCoreAlt,uRiseScale);\n  float red=airglowGaussian(altitude,uCoreAlt+148000.0,uTailScale)*.06;\n  // Preserve the existing exposure control while concentrating its emitting\n  // column into the actual separated layers. UV has no visible RGB term.\n  vec3 emission=uColHorizon*sodium+uColFringe*hydroxyl+uColCore*green+uColUpper*red;\n  // Optically thin emission. Dayglow exists, but at a daylight exposure it is\n  // far below the sunlit disc and limb; above ~100 km there is no Rayleigh\n  // sky to hide it, so unattenuated it drew a brown/red ring around the whole\n  // day-side limb that orbital photography never shows. Fade it on the\n  // sunlit side (to 8%) while the night side and terminator keep full glow.\n  float nightSide=1.0-smoothstep(-.12,.10,dot(normalize(p),sunDir));\n  return 5.0*emission*mix(.08,1.0,nightSide)+nightHaze;\n}\nvoid integrateAirglowSegment(vec3 origin,vec3 rd,vec3 sunDir,float start,float finish,\n  inout vec3 emission,inout float firstEmissionDistance){\n  if(finish<=start)return;\n  // Gauss–Legendre integration per physical layer interval, not uniform\n  // samples over a 330 km carrier that can entirely skip a thin green line.\n  const float nodes[8]=float[8](-.960289856,-.796666477,-.525532410,-.183434642,\n    .183434642,.525532410,.796666477,.960289856);\n  const float weights[8]=float[8](.101228536,.222381034,.313706646,.362683783,\n    .362683783,.313706646,.222381034,.101228536);\n  float halfLength=(finish-start)*.5,midpoint=(finish+start)*.5;\n  for(int i=0;i<8;i++){\n    float t=midpoint+halfLength*nodes[i];vec3 value=airglowEmission(origin+rd*t,rd,sunDir);\n    if(max(max(value.r,value.g),value.b)>1e-5\n      &&(firstEmissionDistance<0.0||t<firstEmissionDistance))firstEmissionDistance=t;\n    emission+=value*weights[i]*halfLength;\n  }\n}\nvoid integrateAirglowLayer(vec3 origin,vec3 rd,vec3 sunDir,float lower,float upper,\n  float clipStart,float clipEnd,inout vec3 emission,inout float firstEmissionDistance){\n  vec2 outer=airglowIntersection(origin,rd,upper),inner=airglowIntersection(origin,rd,lower);\n  float start=max(clipStart,outer.x),finish=min(clipEnd,outer.y);\n  if(finish<=start)return;\n  if(inner.y<=start||inner.x>=finish||inner.y<0.0){\n    integrateAirglowSegment(origin,rd,sunDir,start,finish,emission,firstEmissionDistance);\n  }else{\n    integrateAirglowSegment(origin,rd,sunDir,start,min(finish,inner.x),emission,firstEmissionDistance);\n    integrateAirglowSegment(origin,rd,sunDir,max(start,inner.y),finish,emission,firstEmissionDistance);\n  }\n}\n`;\n","// One small state machine fed by the existing frame clock. Ordinary FPS dips,\n// camera altitude and boot work are not reasons to reduce cloud resolution.\nconst SCALES = [1, .85, .7, .5];\nexport class CloudResolutionPolicy {\n  constructor() { this.level=0; this.hardFrames=0; this.deepMs=0; this.stableMs=0; this.lastChange=-Infinity; }\n  get scale() { return SCALES[this.level]; }\n  update({ now, frameMs, eligible=true }) {\n    if (!eligible || !Number.isFinite(frameMs) || frameMs<=0) {\n      this.hardFrames=0;this.deepMs=0;this.stableMs=0;return null;\n    }\n    const elapsed=Math.min(frameMs,250);\n    this.hardFrames=frameMs>=250?this.hardFrames+1:0;\n    this.deepMs=frameMs>=100?this.deepMs+elapsed:0;\n    this.stableMs=frameMs<80?this.stableMs+elapsed:0;\n    let level=this.level;\n    if (now-this.lastChange>=6000 && (this.hardFrames>=3 || this.deepMs>=2500)) level=Math.min(SCALES.length-1,level+1);\n    else if (now-this.lastChange>=15000 && this.stableMs>=15000) level=Math.max(0,level-1);\n    if (level===this.level) return null;\n    this.level=level;this.lastChange=now;this.hardFrames=0;this.deepMs=0;this.stableMs=0;\n    return this.scale;\n  }\n}\n","import * as THREE from 'three';\nimport { SkyMaterial, getAltitudeCorrectionOffset } from '@takram/three-atmosphere';\n\nconst SHARED_UNIFORMS = ['ATMOSPHERE', 'SUN_SPECTRAL_RADIANCE_TO_LUMINANCE', 'SKY_SPECTRAL_RADIANCE_TO_LUMINANCE',\n  'irradiance_texture', 'scattering_texture', 'transmittance_texture', 'single_mie_scattering_texture', 'higher_order_scattering_texture',\n  'worldToECEFMatrix', 'sunDirection', 'moonDirection', 'cosSunAngularRadius', 'moonAngularRadius', 'lunarRadianceScale', 'groundAlbedo'];\n\n/** Physical Bruneton sky, sharing the desktop LUTs, drawn directly per XR eye. */\nexport class NativeXRSkyMaterial extends SkyMaterial {\n  constructor(source) {\n    super({ sun: false, moon: false, renderTargetCount: 1 });\n    this.name = 'NativeXRSkyMaterial';\n    this._ecefPosition = new THREE.Vector3();\n    this.uniforms.toneMappingExposure = new THREE.Uniform(1);\n    this.uniforms.ncaOutputToneMapping = new THREE.Uniform(THREE.AgXToneMapping);\n    this.uniforms.ncaOutputSRGB = new THREE.Uniform(true);\n    // SkyMaterial is raw GLSL: Three cannot inject output transforms for it.\n    // Do not feed unexposed linear radiance directly to the XR display target.\n    const marker = 'outputColor.a = 1.0;';\n    if (!this.fragmentShader.includes(marker)) throw new Error('Unsupported Takram sky output contract');\n    this.fragmentShader = this.fragmentShader.replace('void main() {', `\n      ${THREE.ShaderChunk.tonemapping_pars_fragment}\n      ${THREE.ShaderChunk.colorspace_pars_fragment}\n      uniform int ncaOutputToneMapping;\n      uniform bool ncaOutputSRGB;\n      vec3 ncaToneMap(vec3 color) {\n        if (ncaOutputToneMapping == ${THREE.LinearToneMapping}) return LinearToneMapping(color);\n        if (ncaOutputToneMapping == ${THREE.ReinhardToneMapping}) return ReinhardToneMapping(color);\n        if (ncaOutputToneMapping == ${THREE.CineonToneMapping}) return CineonToneMapping(color);\n        if (ncaOutputToneMapping == ${THREE.ACESFilmicToneMapping}) return ACESFilmicToneMapping(color);\n        if (ncaOutputToneMapping == ${THREE.AgXToneMapping}) return AgXToneMapping(color);\n        if (ncaOutputToneMapping == ${THREE.NeutralToneMapping}) return NeutralToneMapping(color);\n        return color;\n      }\n      void main() {`).replace(marker, `${marker}\n        outputColor.rgb = ncaToneMap(max(vec3(0.0), outputColor.rgb));\n        if (ncaOutputSRGB) outputColor = sRGBTransferOETF(outputColor);`);\n    this.syncFrom(source);\n  }\n\n  syncFrom(source) {\n    this.ellipsoid = source.ellipsoid; this.atmosphere = source.atmosphere; this.correctAltitude = source.correctAltitude;\n    for (const name of SHARED_UNIFORMS) {\n      this.uniforms[name] = source.uniforms[name];\n    }\n    this.singleMieScatteringTexture = source.singleMieScatteringTexture;\n    this.higherOrderScatteringTexture = source.higherOrderScatteringTexture;\n    this.ground = source.ground;\n    // Never reuse mono screen-space cloud shadow/temporal buffers in stereo.\n    this.shadowLength = null;\n  }\n\n  copyCameraSettings(camera) {\n    // XR eye cameras have authoritative world matrices computed by WebXRManager\n    // but no Earth-rig parent. getWorldPosition() recomputes them from local\n    // room-space transforms, putting the atmosphere ray inside Earth's centre.\n    const u = this.uniforms;\n    u.cameraPosition.value.setFromMatrixPosition(camera.matrixWorld);\n    this._ecefPosition.copy(u.cameraPosition.value).applyMatrix4(u.worldToECEFMatrix.value);\n    if (this.correctAltitude) getAltitudeCorrectionOffset(this._ecefPosition, this.atmosphere.bottomRadius,\n      this.ellipsoid, u.altitudeCorrection.value);\n    else u.altitudeCorrection.value.setScalar(0);\n  }\n\n  onBeforeRender(renderer, scene, camera, geometry, object, group) {\n    super.onBeforeRender(renderer, scene, camera, geometry, object, group);\n    this.uniforms.toneMappingExposure.value = renderer.toneMappingExposure;\n    this.uniforms.ncaOutputToneMapping.value = renderer.toneMapping;\n    const targetSpace = renderer.getRenderTarget()?.texture?.colorSpace || renderer.outputColorSpace;\n    this.uniforms.ncaOutputSRGB.value = targetSpace === THREE.SRGBColorSpace;\n    this.uniformsNeedUpdate = true;\n  }\n}\n","import { Effect, EffectAttribute, BlendFunction } from 'postprocessing';\nimport { Uniform, Vector2, Vector3, Vector4, Matrix4 } from 'three';\nimport { computeWaterOptics, oceanSubsurfaceLight } from '../../modules/ocean-water-optics.js';\n\n// Submerged view in the existing final pass, without extra render targets.\n// Per pixel, along the view ray of length d from camera depth z0:\n//   object  L·exp(−Kd z_end)·focus · exp(−c d)          (light reaching it, then the path)\n//   veil    c·L∞(z0)·(1 − e^{−(c+Kd μ)d})/(c+Kd μ),  L∞ = Ed(z0)·Rrs·g(μ)\n//   shafts  Σ b·p_HG(θ)·E_sun·exp(−Kd s)·focus(Q,s)·exp(−c t)·Δt   (ray-marched)\n// where μ is the downward component of the view ray and focus is refractive\n// convergence by the simulated waves at the surface point Q on the sun's path.\n// See docs/OCEAN_MATH.md.\nconst FRAGMENT = `\nuniform float underwater, focusReady, directFraction, sunCosInWater;\nuniform mat4 inverseProjection, viewToPatch;\nuniform vec3 waterC, waterKd, waterB, surfaceIrradiance, reflectance, sunDirect, sunInWater;\nuniform sampler2D focus1, focus2;\nuniform vec3 cascadeLength, cascadeSize;\nuniform vec2 origin1, origin2;\nuniform vec4 waveMatrix;\n\nfloat focusDivergence(vec2 p, float blur) {\n  vec2 fixedP = vec2(dot(p, waveMatrix.xy), dot(p, waveMatrix.zw));\n  vec2 lod = max(vec2(0.0), log2(max(vec2(0.001), blur * cascadeSize.yz / cascadeLength.yz)));\n  return textureLod(focus1, fixedP / cascadeLength.y + origin1, lod.x).a\n    + textureLod(focus2, fixedP / cascadeLength.z + origin2, lod.y).a;\n}\n// J = 1 + s(1 − 1/n)∇²h for a bundle s metres below the surface point.\nfloat focusAt(vec2 surfaceP, float path) {\n  if (focusReady < 0.5 || path <= 0.0) return 1.0;\n  float jacobian = 1.0 + path * 0.24981 * focusDivergence(surfaceP, 0.03 + path * 0.008);\n  return clamp(1.0 / max(jacobian, 0.2), 0.0, 5.0);\n}\nfloat henyeyGreenstein(float cosine, float g) {\n  float d = 1.0 + g * g - 2.0 * g * cosine;\n  return (1.0 - g * g) / (12.5663706 * d * sqrt(d));\n}\nvoid mainImage(const in vec4 inputColor, const in vec2 uv, out vec4 outputColor) {\n  if (underwater < 0.5) { outputColor = inputColor; return; }\n  // EffectPass readDepth() already converts logarithmic depth to perspective\n  // depth; invert the perspective mapping for metres along -z.\n  float depth = readDepth(uv);\n  float viewZ = depth >= 1.0 ? 1.0e7 : cameraNear * cameraFar / (cameraFar * (1.0 - depth) + cameraNear * depth);\n  vec4 ray = inverseProjection * vec4(uv * 2.0 - 1.0, -1.0, 1.0);\n  vec3 viewDir = normalize(ray.xyz / ray.w);\n  float d = min(viewZ / max(0.001, -viewDir.z), 4000.0);\n  vec3 camP = (viewToPatch * vec4(0.0, 0.0, 0.0, 1.0)).xyz;\n  vec3 dirP = normalize((viewToPatch * vec4(viewDir, 0.0)).xyz);\n  float z0 = max(0.0, -camP.z), mu = -dirP.z;\n  vec3 endP = camP + dirP * d;\n  float zEnd = max(0.0, -endP.z);\n  // Light that reached the visible surface had crossed zEnd of water.\n  float pathToEnd = zEnd / max(0.2, sunCosInWater);\n  vec3 objectLight = exp(-waterKd * zEnd)\n    * mix(1.0, focusAt(endP.xy - sunInWater.xy * pathToEnd, pathToEnd), directFraction);\n  vec3 transmittance = exp(-waterC * d);\n  // Diffuse light field: brighter looking toward the surface, darker down.\n  float angular = mu >= 0.0 ? mix(2.0, 1.0, mu) : mix(2.0, 8.0, -mu);\n  vec3 asymptote = surfaceIrradiance * exp(-waterKd * z0) * reflectance * angular;\n  vec3 rate = max(waterC + waterKd * mu, vec3(0.001));\n  vec3 veil = waterC * asymptote * (1.0 - exp(-rate * d)) / rate;\n  // Single-scattered sunlight with forward-peaked particle phase: shafts.\n  vec3 shafts = vec3(0.0);\n  if (directFraction > 0.001) {\n    float marchLength = min(d, 2.5 / min(waterC.y, waterC.z));\n    float dt = marchLength / 32.0;\n    float jitter = fract(52.9829189 * fract(dot(gl_FragCoord.xy, vec2(0.06711056, 0.00583715))));\n    float phase = henyeyGreenstein(dot(sunInWater, -dirP), 0.85);\n    for (int i = 0; i < 32; i++) {\n      float t = (float(i) + jitter) * dt;\n      vec3 p = camP + dirP * t;\n      float s = max(0.0, -p.z) / max(0.2, sunCosInWater);\n      shafts += exp(-waterKd * s - waterC * t) * focusAt(p.xy - sunInWater.xy * s, s);\n    }\n    shafts *= waterB * phase * sunDirect * dt;\n  }\n  outputColor = vec4(inputColor.rgb * objectLight * transmittance + veil + shafts, inputColor.a);\n}`;\n\n/** Beer–Lambert transmission, depth-dimmed light field and godrays underwater. */\nexport class UnderwaterEffect extends Effect {\n    constructor(_camera) {\n        super('UnderwaterEffect', FRAGMENT, { blendFunction: BlendFunction.NORMAL, attributes: EffectAttribute.DEPTH,\n            uniforms: new Map([\n                ['underwater', new Uniform(0)],\n                ['focusReady', new Uniform(0)], ['directFraction', new Uniform(0)], ['sunCosInWater', new Uniform(1)],\n                ['inverseProjection', new Uniform(new Matrix4())], ['viewToPatch', new Uniform(new Matrix4())],\n                ['waterC', new Uniform(new Vector3(0.31, 0.14, 0.13))], ['waterKd', new Uniform(new Vector3(0.255, 0.076, 0.044))],\n                ['waterB', new Uniform(new Vector3(0.1, 0.11, 0.13))],\n                ['surfaceIrradiance', new Uniform(new Vector3())], ['reflectance', new Uniform(new Vector3())],\n                ['sunDirect', new Uniform(new Vector3())], ['sunInWater', new Uniform(new Vector3(0, 0, -1))],\n                ['focus1', new Uniform(null)], ['focus2', new Uniform(null)],\n                ['cascadeLength', new Uniform(new Vector3(1, 1, 1))], ['cascadeSize', new Uniform(new Vector3(1, 1, 1))],\n                ['origin1', new Uniform(new Vector2())], ['origin2', new Uniform(new Vector2())],\n                ['waveMatrix', new Uniform(new Vector4(1, 0, 0, 1))],\n            ]) });\n        this._frame = new Matrix4(); this._inverse = new Matrix4(); this._sun = new Vector3(); this._up = new Vector3();\n    }\n    /** ocean: the OceanSurface supplying optics, light, wave frame and focus fields. */\n    setState(state, camera, ocean = null) {\n        const u = name => this.uniforms.get(name);\n        const submerged = state?.underwater === true && !!camera;\n        u('underwater').value = submerged ? 1 : 0;\n        if (!submerged) return;\n        camera.updateMatrixWorld();\n        u('inverseProjection').value.copy(camera.projectionMatrixInverse);\n        const live = !!(ocean?.light && ocean.mesh?.visible);\n        live ? this._setOceanFrame(ocean, camera) : this._setFallbackFrame(state, camera);\n        const optics = live ? ocean.optics : (this._fallbackOptics ||= computeWaterOptics());\n        const light = live ? ocean.light : (this._fallbackLight ||= oceanSubsurfaceLight(optics, { sunCosZenith: 1 }));\n        u('waterC').value.set(...optics.attenuation);\n        u('waterKd').value.set(...optics.diffuseAttenuation);\n        u('waterB').value.set(...optics.scattering);\n        u('surfaceIrradiance').value.set(...light.irradiance);\n        u('reflectance').value.set(...light.reflectance);\n        u('sunDirect').value.set(...light.direct);\n        // The shaft march needs the full-tier focus fields; cheaper tiers skip it.\n        u('directFraction').value = live && ocean.tier === 'full' ? light.directFraction : 0;\n        u('sunCosInWater').value = light.sunCosInWater;\n    }\n    // View space → patch frame (x east, y north, z up, origin at sea level).\n    _setOceanFrame(ocean, camera) {\n        const u = name => this.uniforms.get(name);\n        ocean.parent.updateWorldMatrix(true, false);\n        this._frame.makeBasis(ocean.east, ocean.north, ocean.up).setPosition(ocean.center)\n            .premultiply(ocean.parent.matrixWorld).invert().multiply(camera.matrixWorld);\n        u('viewToPatch').value.copy(this._frame);\n        const light = ocean.light;\n        // Refracted sun propagation direction in the patch frame (pointing down).\n        this._up.copy(ocean.up).transformDirection(ocean.parent.matrixWorld);\n        this._sun.copy(ocean.sunWorld).addScaledVector(this._up, -ocean.sunWorld.dot(this._up))\n            .transformDirection(this._inverse.copy(ocean.parent.matrixWorld).invert());\n        const horizontal = Math.sqrt(Math.max(0, 1 - light.sunCosInWater ** 2));\n        const east = this._sun.dot(ocean.east), north = this._sun.dot(ocean.north), length = Math.hypot(east, north) || 1;\n        u('sunInWater').value.set(-east / length * horizontal, -north / length * horizontal, -light.sunCosInWater);\n        const local = ocean.uniformsLocal;\n        u('focusReady').value = local.ncaOceanGPUReady.value;\n        u('focus1').value = local.ncaOceanDisp1.value; u('focus2').value = local.ncaOceanDisp2.value;\n        u('cascadeLength').value.copy(local.ncaOceanCascadeLength.value);\n        u('cascadeSize').value.copy(local.ncaOceanCascadeSize.value);\n        u('origin1').value.copy(local.ncaOceanCascadeOrigin.value[1]);\n        u('origin2').value.copy(local.ncaOceanCascadeOrigin.value[2]);\n        u('waveMatrix').value.copy(local.ncaOceanFFTMatrix.value);\n    }\n    // Without a sea surface: planet-centred up at the camera, default clear water, no focusing.\n    _setFallbackFrame(state, camera) {\n        const u = name => this.uniforms.get(name);\n        const position = camera.getWorldPosition(this._sun);\n        this._up.copy(position).normalize();\n        const east = new Vector3(0, 1, 0).cross(this._up);\n        if (east.lengthSq() < 1e-8) east.set(1, 0, 0); else east.normalize();\n        const north = new Vector3().crossVectors(this._up, east);\n        const depth = Number.isFinite(state?.depthMeters) ? state.depthMeters : 2;\n        this._frame.makeBasis(east, north, this._up).setPosition(position.addScaledVector(this._up, depth))\n            .invert().multiply(camera.matrixWorld);\n        u('viewToPatch').value.copy(this._frame);\n        u('focusReady').value = 0;\n        u('sunInWater').value.set(0, 0, -1);\n    }\n}\n","/**\n * LocalCloudCoverField — real current cloud cover and precipitation on a\n * small geographic grid around the viewer, for the near-ground volumetric\n * clouds. The global live cloud map is a ~3-hourly satellite composite; close\n * to the surface, current regional-model fields (Open-Meteo \"best match\":\n * ICON-D2 / HRRR / AROME … where available) are fresher and finer, so the\n * cloud shader fuses the two: global mask from altitude, this field near the\n * ground. Refreshes every 15 min or when the viewer leaves the grid centre.\n *\n * Texture texel (i, j): R = total cloud cover, G = low cloud cover,\n * B = precipitation (mm/h × 40, capped), A = 255. Bounds are degrees:\n * (west, south, spanLon, spanLat). Texel centres sit on grid points.\n */\nimport * as THREE from 'three';\n\nexport const LOCAL_CLOUD_FIELD_DEFAULTS = Object.freeze({\n  gridSize: 9,\n  spanDeg: 1.6,\n  refreshMs: 15 * 60 * 1000,\n  activeBelowM: 60_000,\n  fullWeightBelowM: 20_000,\n  endpoint: 'https://api.open-meteo.com/v1/forecast',\n});\n\n/** Grid point coordinates (row-major, south→north, west→east). */\nexport function localCloudGrid(latDeg, lonDeg, { gridSize = 9, spanDeg = 1.6 } = {}) {\n  const lats = [];\n  const lons = [];\n  const half = spanDeg / 2;\n  for (let j = 0; j < gridSize; j++) {\n    for (let i = 0; i < gridSize; i++) {\n      lats.push(Math.max(-89.9, Math.min(89.9, latDeg - half + (spanDeg * j) / (gridSize - 1))));\n      lons.push(((lonDeg - half + (spanDeg * i) / (gridSize - 1) + 540) % 360) - 180);\n    }\n  }\n  return { lats, lons, west: lonDeg - half, south: latDeg - half };\n}\n\n/** Pack Open-Meteo multi-point \"current\" records into RGBA bytes. */\nexport function packLocalCloudField(records, gridSize) {\n  const data = new Uint8Array(gridSize * gridSize * 4);\n  for (let k = 0; k < gridSize * gridSize; k++) {\n    const c = records[k]?.current || {};\n    const total = Number.isFinite(c.cloud_cover) ? c.cloud_cover : 0;\n    const low = Number.isFinite(c.cloud_cover_low) ? c.cloud_cover_low : total;\n    const precip = Number.isFinite(c.precipitation) ? c.precipitation : 0;\n    data[k * 4] = Math.round(Math.max(0, Math.min(100, total)) * 2.55);\n    data[k * 4 + 1] = Math.round(Math.max(0, Math.min(100, low)) * 2.55);\n    data[k * 4 + 2] = Math.round(Math.max(0, Math.min(255, precip * 40)));\n    data[k * 4 + 3] = 255;\n  }\n  return data;\n}\n\n/** 0..1 influence of the local field for a camera altitude. */\nexport function localCloudWeight(altitudeM, o = LOCAL_CLOUD_FIELD_DEFAULTS) {\n  if (!Number.isFinite(altitudeM) || altitudeM >= o.activeBelowM) return 0;\n  if (altitudeM <= o.fullWeightBelowM) return 1;\n  return 1 - (altitudeM - o.fullWeightBelowM) / (o.activeBelowM - o.fullWeightBelowM);\n}\n\nexport class LocalCloudCoverField {\n  constructor({ fetchImpl = globalThis.fetch?.bind(globalThis), options = {} } = {}) {\n    this.o = { ...LOCAL_CLOUD_FIELD_DEFAULTS, ...options };\n    this.fetchImpl = fetchImpl;\n    const n = this.o.gridSize;\n    this.texture = new THREE.DataTexture(new Uint8Array(n * n * 4), n, n, THREE.RGBAFormat);\n    this.texture.minFilter = this.texture.magFilter = THREE.LinearFilter;\n    this.texture.generateMipmaps = false;\n    this.texture.colorSpace = THREE.NoColorSpace;\n    this.texture.name = 'Weather.LocalCloudCover';\n    this.uniforms = {\n      ncaLocalCloudMap: new THREE.Uniform(this.texture),\n      // Texel-centre aligned bounds (degrees): west, south, spanLon, spanLat.\n      ncaLocalCloudBounds: new THREE.Uniform(new THREE.Vector4(0, 0, 1, 1)),\n      ncaLocalCloudWeight: new THREE.Uniform(0),\n    };\n    this.center = null;\n    this.fetchedAt = 0;\n    this.pending = null;\n    this.ready = false;\n  }\n\n  /** Call each frame (cheap); fetches only when needed. */\n  update(latDeg, lonDeg, altitudeM, nowMs = Date.now()) {\n    const weight = localCloudWeight(altitudeM, this.o);\n    this.uniforms.ncaLocalCloudWeight.value = this.ready ? weight : 0;\n    if (weight <= 0 || !Number.isFinite(latDeg) || !Number.isFinite(lonDeg) || this.pending || !this.fetchImpl) return;\n    const moved = this.center\n      ? Math.max(Math.abs(latDeg - this.center.lat), Math.abs(((lonDeg - this.center.lon + 540) % 360) - 180))\n      : Infinity;\n    if (moved < this.o.spanDeg / 4 && nowMs - this.fetchedAt < this.o.refreshMs) return;\n    this.pending = this._fetch(latDeg, lonDeg, nowMs).finally(() => { this.pending = null; });\n  }\n\n  async _fetch(latDeg, lonDeg, nowMs) {\n    const n = this.o.gridSize;\n    const grid = localCloudGrid(latDeg, lonDeg, this.o);\n    const url = `${this.o.endpoint}?latitude=${grid.lats.map((v) => v.toFixed(3)).join(',')}`\n      + `&longitude=${grid.lons.map((v) => v.toFixed(3)).join(',')}`\n      + '&current=cloud_cover,cloud_cover_low,precipitation&timezone=UTC';\n    try {\n      const response = await this.fetchImpl(url);\n      if (!response.ok) throw new Error(`HTTP ${response.status}`);\n      const json = await response.json();\n      const records = Array.isArray(json) ? json : [json];\n      if (records.length !== n * n) throw new Error('unexpected grid size');\n      this.texture.image.data.set(packLocalCloudField(records, n));\n      this.texture.needsUpdate = true;\n      // Map so texel centres land on grid points.\n      const cell = this.o.spanDeg / (n - 1);\n      this.uniforms.ncaLocalCloudBounds.value.set(grid.west - cell / 2, grid.south - cell / 2, cell * n, cell * n);\n      this.center = { lat: latDeg, lon: lonDeg };\n      this.fetchedAt = nowMs;\n      this.ready = true;\n    } catch {\n      // Keep the previous field; retry after the normal interval.\n      this.fetchedAt = nowMs;\n      this.center = this.center || { lat: latDeg, lon: lonDeg };\n    }\n  }\n\n  dispose() { this.texture.dispose(); }\n}\n","/**\n * LocalPrecipitationField — real precipitation around the viewer, read from\n * the same map-layer sources the Map panel uses (resolveMapSource: backend\n * relay, CORS-safe): NOAA MRMS radar over the contiguous US, RainViewer\n * global radar elsewhere, NOAA CPC CMORPH daily global precipitation as the\n * fallback. A 2×2 Web Mercator tile mosaic at zoom 7 is decoded to intensity\n * (radar palettes run green → yellow → red → magenta) and kept in Mercator\n * with tile-exact bounds; the cloud shader converts latitude to Mercator, so\n * the field lands exactly where the map layer draws it.\n *\n * Texture: R = precipitation intensity 0..1. Bounds: (mx0, my0, mx1, my1) in\n * normalised Web Mercator (x east, y south; tile row 0 at my0).\n */\nimport * as THREE from 'three';\nimport { get as getMapLayer } from '../imagery/BasemapRegistry.js';\nimport { resolveMapSource } from '../imagery/MapSourceResolver.js';\n\nconst ZOOM = 7;\nconst TILE = 256;\nconst REFRESH_MS = 10 * 60 * 1000;\n\nexport const MRMS_BOUNDS = Object.freeze({ south: 20, north: 55, west: -130, east: -60 });\n\n/** Which map layers to try, best first, for a location. */\nexport function precipitationSourcesFor(latDeg, lonDeg) {\n  const inMrms = latDeg >= MRMS_BOUNDS.south && latDeg <= MRMS_BOUNDS.north\n    && lonDeg >= MRMS_BOUNDS.west && lonDeg <= MRMS_BOUNDS.east;\n  return inMrms\n    ? ['noaa-mrms-radar', 'rainviewer-radar', 'noaa-cmorph-precipitation']\n    : ['rainviewer-radar', 'noaa-cmorph-precipitation'];\n}\n\n/** Normalised Web Mercator (x east, y south) for a geographic point. */\nexport function toMercator(latDeg, lonDeg) {\n  const lat = Math.max(-85.0511, Math.min(85.0511, latDeg)) * Math.PI / 180;\n  return { x: (lonDeg + 180) / 360, y: (1 - Math.log(Math.tan(Math.PI / 4 + lat / 2)) / Math.PI) / 2 };\n}\n\n/** Radar/precip palette colour → intensity 0..1 (transparent = none). */\nexport function precipIntensityFromRgba(r, g, b, a) {\n  if (a < 24) return 0;\n  const max = Math.max(r, g, b); const min = Math.min(r, g, b);\n  if (max - min < 24) return Math.min(1, 0.2 + (max / 255) * 0.3); // grey/white overlays: light\n  let h;\n  if (max === r) h = ((g - b) / (max - min)) * 60;\n  else if (max === g) h = (2 + (b - r) / (max - min)) * 60;\n  else h = (4 + (r - g) / (max - min)) * 60;\n  if (h < 0) h += 360;\n  // Blue/teal (drizzle) 240..150 → 0.1..0.25, green 150..90 → 0.25..0.4,\n  // yellow/orange 90..20 → 0.4..0.75, red 20..0 / magenta 360..270 → 0.75..1.\n  if (h > 260) return 0.85 + Math.min(1, (360 - h) / 90) * 0.15; // magenta / violet: extreme\n  if (h >= 150) return 0.1 + (260 - h) / 110 * 0.15;\n  if (h >= 90) return 0.25 + (150 - h) / 60 * 0.15;\n  if (h >= 20) return 0.4 + (90 - h) / 70 * 0.35;\n  return 0.75 + (20 - h) / 20 * 0.1;\n}\n\nexport class LocalPrecipitationField {\n  constructor({ fetchImpl = globalThis.fetch?.bind(globalThis) } = {}) {\n    this.fetchImpl = fetchImpl;\n    const size = TILE * 2;\n    this.texture = new THREE.DataTexture(new Uint8Array(size * size * 4), size, size, THREE.RGBAFormat);\n    this.texture.minFilter = this.texture.magFilter = THREE.LinearFilter;\n    this.texture.generateMipmaps = false;\n    this.texture.colorSpace = THREE.NoColorSpace;\n    this.texture.name = 'Weather.LocalPrecipitation';\n    this.uniforms = {\n      ncaLocalPrecipMap: new THREE.Uniform(this.texture),\n      ncaLocalPrecipBounds: new THREE.Uniform(new THREE.Vector4(0, 0, 1, 1)),\n      ncaLocalPrecipEnabled: new THREE.Uniform(0),\n    };\n    this.tileOrigin = null;\n    this.fetchedAt = 0;\n    this.pending = null;\n    this.source = null;\n  }\n\n  update(latDeg, lonDeg, active, nowMs = Date.now()) {\n    if (!active || !Number.isFinite(latDeg) || !Number.isFinite(lonDeg) || this.pending || !this.fetchImpl\n      || typeof document === 'undefined') return;\n    const n = 2 ** ZOOM;\n    const m = toMercator(latDeg, lonDeg);\n    // 2×2 tiles whose shared corner is nearest the viewer.\n    const x0 = Math.floor(m.x * n - 0.5);\n    const y0 = Math.floor(m.y * n - 0.5);\n    const same = this.tileOrigin && this.tileOrigin.x === x0 && this.tileOrigin.y === y0;\n    if (same && nowMs - this.fetchedAt < REFRESH_MS) return;\n    this.pending = this._load(latDeg, lonDeg, x0, y0, nowMs).finally(() => { this.pending = null; });\n  }\n\n  async _load(latDeg, lonDeg, x0, y0, nowMs) {\n    this.fetchedAt = nowMs;\n    const n = 2 ** ZOOM;\n    for (const id of precipitationSourcesFor(latDeg, lonDeg)) {\n      const spec = getMapLayer(id);\n      if (!spec) continue;\n      try {\n        const resolved = await resolveMapSource(spec);\n        if (!resolved?.url?.includes('{z}')) continue;\n        const canvas = document.createElement('canvas');\n        canvas.width = canvas.height = TILE * 2;\n        const ctx = canvas.getContext('2d', { willReadFrequently: true });\n        let drawn = 0;\n        await Promise.all([[0, 0], [1, 0], [0, 1], [1, 1]].map(async ([dx, dy]) => {\n          const tx = ((x0 + dx) % n + n) % n; const ty = Math.max(0, Math.min(n - 1, y0 + dy));\n          const url = resolved.url.replace('{z}', ZOOM).replace('{x}', tx).replace('{y}', ty);\n          const response = await this.fetchImpl(url, { mode: 'cors', credentials: 'omit' });\n          if (!response.ok) return;\n          const bitmap = await createImageBitmap(await response.blob());\n          ctx.drawImage(bitmap, dx * TILE, dy * TILE, TILE, TILE);\n          bitmap.close?.();\n          drawn++;\n        }));\n        if (!drawn) continue;\n        const rgba = ctx.getImageData(0, 0, TILE * 2, TILE * 2).data;\n        const out = this.texture.image.data;\n        for (let i = 0; i < rgba.length; i += 4) {\n          out[i] = Math.round(precipIntensityFromRgba(rgba[i], rgba[i + 1], rgba[i + 2], rgba[i + 3]) * 255);\n          out[i + 1] = out[i + 2] = 0; out[i + 3] = 255;\n        }\n        this.texture.needsUpdate = true;\n        this.uniforms.ncaLocalPrecipBounds.value.set(x0 / n, y0 / n, (x0 + 2) / n, (y0 + 2) / n);\n        this.uniforms.ncaLocalPrecipEnabled.value = 1;\n        this.tileOrigin = { x: x0, y: y0 };\n        this.source = id;\n        return;\n      } catch {\n        // Try the next layer (provider down, CORS, outside coverage).\n      }\n    }\n  }\n\n  dispose() { this.texture.dispose(); }\n}\n","/**\n * AtmosphericHorizonBlurEffect — softens detail seen through a lot of air.\n *\n * Turbulence and forward scattering soften what is seen through a great\n * deal of air. Per pixel the view ray's sea-level-equivalent air column is\n * integrated (exponential atmosphere, scale height H) out to the visible\n * surface, and the HDR image is blurred with a small disc:\n *\n * - From orbit (camera above ~100-122 km) only the limb softens: rays whose\n *   column approaches the full tangent column √(2πRH) ≈ 565 km (the absolute\n *   horizon), up to `maxRadiusPx`. Looking down (≈ 8 km / cos θ) stays sharp.\n * - On or near the surface real seeing is arcseconds to ~1 arcminute even\n *   at the horizon — below a pixel at normal fields of view — so the blur is\n *   sub-pixel and appears only on the very longest sightlines.\n */\nimport { Effect, EffectAttribute } from 'postprocessing';\nimport { Uniform, Matrix4, Vector2 } from 'three';\n\nexport const HORIZON_BLUR_DEFAULTS = Object.freeze({\n  planetRadiusM: 6_371_000,\n  scaleHeightM: 8_000,\n  atmosphereTopM: 100_000,\n  // Limb (orbit): blur ramps in from this fraction of the tangent column.\n  limbStartFraction: 0.45,\n  maxRadiusPx: 4,\n  // Altitude band where the limb blur takes over from the surface model.\n  orbitStartM: 100_000,\n  orbitFullM: 122_000,\n  // Surface: sub-pixel seeing; ~0.5 px at a 565 km horizon column.\n  surfaceMaxRadiusPx: 1.2,\n  surfaceReferenceColumnM: 1_200_000,\n});\n\nconst FRAGMENT = /* glsl */`\nuniform mat4 inverseProjection, viewToECEF;\nuniform float planetRadius, scaleHeight, atmosphereTop, limbStartFraction, maxRadiusPx, enabledBlur;\nuniform float orbitStart, orbitFull, surfaceMaxRadiusPx, surfaceReferenceColumn;\nuniform vec2 texel;\n\n// Sea-level-equivalent air column along a ray (8-sample midpoint rule),\n// ending at the visible surface (maxT) so nearby objects stay sharp.\nfloat airColumn(vec3 origin, vec3 dir, float maxT) {\n  float top = planetRadius + atmosphereTop;\n  float b = dot(origin, dir);\n  float c = dot(origin, origin) - top * top;\n  float disc = b * b - c;\n  if (disc <= 0.0) return 0.0;\n  float tEnter = max(0.0, -b - sqrt(disc));\n  float tExit = -b + sqrt(disc);\n  float cg = dot(origin, origin) - planetRadius * planetRadius;\n  float dg = b * b - cg;\n  if (dg > 0.0) { float tg = -b - sqrt(dg); if (tg > 0.0) tExit = min(tExit, tg); }\n  tExit = min(tExit, maxT);\n  if (tExit <= tEnter) return 0.0;\n  float dt = (tExit - tEnter) / 8.0;\n  float column = 0.0;\n  for (int i = 0; i < 8; i++) {\n    vec3 p = origin + dir * (tEnter + (float(i) + 0.5) * dt);\n    column += exp(-max(0.0, length(p) - planetRadius) / scaleHeight);\n  }\n  return column * dt;\n}\n\nvoid mainImage(const in vec4 inputColor, const in vec2 uv, out vec4 outputColor) {\n  outputColor = inputColor;\n  if (enabledBlur < 0.5) return;\n  vec4 ray = inverseProjection * vec4(uv * 2.0 - 1.0, -1.0, 1.0);\n  vec3 viewDir = normalize(ray.xyz / ray.w);\n  vec3 camE = (viewToECEF * vec4(0.0, 0.0, 0.0, 1.0)).xyz;\n  vec3 dirE = normalize((viewToECEF * vec4(viewDir, 0.0)).xyz);\n  // EffectPass readDepth() returns perspective depth (log depth converted).\n  float depth = readDepth(uv);\n  float maxT = 1.0e12;\n  if (depth < 1.0) {\n    float viewZ = cameraNear * cameraFar / (cameraFar * (1.0 - depth) + cameraNear * depth);\n    maxT = viewZ / max(1e-4, -viewDir.z);\n  }\n  float column = airColumn(camE, dirE, maxT);\n  float orbitWeight = smoothstep(orbitStart, orbitFull, length(camE) - planetRadius);\n  // Full grazing column through the atmosphere at sea level: sqrt(2*pi*R*H).\n  float tangentColumn = sqrt(6.283185307 * planetRadius * scaleHeight);\n  float limb = smoothstep(limbStartFraction, 1.0, column / tangentColumn);\n  float surface = 1.0 - exp(-column / surfaceReferenceColumn);\n  float radius = mix(surfaceMaxRadiusPx * surface, maxRadiusPx * limb, orbitWeight);\n  if (radius < 0.35) return;\n  vec3 sum = inputColor.rgb * 0.2;\n  for (int i = 0; i < 12; i++) {\n    float fi = float(i) + 0.5;\n    float a = fi * 2.399963229728653;\n    vec2 offset = vec2(cos(a), sin(a)) * sqrt(fi / 12.0) * radius * texel;\n    sum += texture2D(inputBuffer, uv + offset).rgb * (0.8 / 12.0);\n  }\n  outputColor = vec4(sum, inputColor.a);\n}`;\n\nexport class AtmosphericHorizonBlurEffect extends Effect {\n  /**\n   * @param {THREE.Camera} camera\n   * @param {() => THREE.Matrix4} getWorldToECEF  world → Earth-centred frame\n   */\n  constructor(camera, getWorldToECEF, options = {}) {\n    const o = { ...HORIZON_BLUR_DEFAULTS, ...options };\n    super('AtmosphericHorizonBlurEffect', FRAGMENT, {\n      attributes: EffectAttribute.CONVOLUTION | EffectAttribute.DEPTH,\n      uniforms: new Map([\n        ['inverseProjection', new Uniform(new Matrix4())],\n        ['viewToECEF', new Uniform(new Matrix4())],\n        ['planetRadius', new Uniform(o.planetRadiusM)],\n        ['scaleHeight', new Uniform(o.scaleHeightM)],\n        ['atmosphereTop', new Uniform(o.atmosphereTopM)],\n        ['limbStartFraction', new Uniform(o.limbStartFraction)],\n        ['maxRadiusPx', new Uniform(o.maxRadiusPx)],\n        ['orbitStart', new Uniform(o.orbitStartM)],\n        ['orbitFull', new Uniform(o.orbitFullM)],\n        ['surfaceMaxRadiusPx', new Uniform(o.surfaceMaxRadiusPx)],\n        ['surfaceReferenceColumn', new Uniform(o.surfaceReferenceColumnM)],\n        ['enabledBlur', new Uniform(1)],\n        ['texel', new Uniform(new Vector2(1, 1))],\n      ]),\n    });\n    this.camera = camera;\n    this.getWorldToECEF = getWorldToECEF;\n  }\n\n  setEnabled(enabled) { this.uniforms.get('enabledBlur').value = enabled ? 1 : 0; }\n\n  update(_renderer, inputBuffer) {\n    const camera = this.camera;\n    if (!camera) return;\n    this.uniforms.get('inverseProjection').value.copy(camera.projectionMatrixInverse);\n    const worldToECEF = this.getWorldToECEF?.();\n    const viewToECEF = this.uniforms.get('viewToECEF').value;\n    if (worldToECEF) viewToECEF.multiplyMatrices(worldToECEF, camera.matrixWorld);\n    else viewToECEF.copy(camera.matrixWorld);\n    if (inputBuffer?.width) this.uniforms.get('texel').value.set(1 / inputBuffer.width, 1 / inputBuffer.height);\n  }\n}\n","import * as THREE from 'three';\nimport { Pass, CopyMaterial } from 'postprocessing';\n\n// The sea draws after atmospheric scattering. Layer 29 belongs to photoreal\n// albedo: selecting it here redraws terrain over its already-composited haze.\nexport const OCEAN_SURFACE_LAYER = 27;\n\n// A capture of the existing lit scene, not a second scene/composer or frame\n// owner. One half-resolution HDR+depth snapshot, capped at 1024 on either axis.\nexport class OceanSurfacePass extends Pass {\n    constructor(scene, camera) {\n        super('OceanSurfacePass');\n        this.waterScene = scene; this.waterCamera = camera;\n        this.needsSwap = false; this.needsDepthTexture = true;\n        this.fullscreenMaterial = new CopyMaterial();\n        this.fullscreenMaterial.colorSpaceConversion = false;\n        this.viewport = new THREE.Vector2(1, 1);\n        this.sunView = new THREE.Vector3(); this.upView = new THREE.Vector3();\n    }\n    setDepthTexture(texture) { this.depthTexture = texture; }\n    getDepthTexture() { return this.depthTexture; }\n    setSize(width, height) {\n        this.viewport.set(width, height);\n        this.target?.setSize(Math.max(1, Math.min(1024, Math.ceil(width / 2))),\n            Math.max(1, Math.min(1024, Math.ceil(height / 2))));\n    }\n    release() {\n        this.target?.dispose(); this.target = null; this.opaqueDepthCaptured=false;\n        if (this.ocean) this.ocean.uniformsLocal.ncaOceanOpticsReady.value = 0;\n    }\n    ensureTarget() {\n        if (!this.target) {\n            this.target = new THREE.WebGLRenderTarget(1, 1, { type: THREE.HalfFloatType,\n                depthBuffer: true, depthTexture: new THREE.DepthTexture(1, 1, THREE.UnsignedIntType) });\n            this.target.texture.name = 'Ocean.OpaqueScene';\n            this.setSize(this.viewport.x, this.viewport.y);\n        }\n    }\n    captureOpaqueDepth(renderer,inputBuffer,depthTexture) {\n        this.ensureTarget();\n        const target=renderer.getRenderTarget(),autoClear=renderer.autoClear;\n        try {\n            renderer.autoClear=false;\n            this.fullscreenMaterial.inputBuffer=inputBuffer.texture;\n            this.fullscreenMaterial.depthBuffer=depthTexture;\n            renderer.setRenderTarget(this.target);\n            renderer.render(this.scene,this.camera);\n            this.opaqueDepthCaptured=true;\n        } finally {\n            renderer.autoClear=autoClear;renderer.setRenderTarget(target);\n        }\n    }\n    render(renderer, inputBuffer) {\n        const ocean = this.ocean;\n        this.needsDepthBlit = false;\n        if (!ocean || !this.waterVisible || !this.depthTexture) { this.release(); return; }\n        ocean.setAtmosphereLighting?.(this.atmosphereSource, this.viewport);\n        this.ensureTarget();\n        const savedTarget = renderer.getRenderTarget(), autoClear = renderer.autoClear;\n        const background = this.waterScene.background, camera = this.waterCamera;\n        const layerMask = camera.layers.mask, waterMask = ocean.mesh.layers.mask, waterMaterial=ocean.mesh.material;\n        const lights = [], waterDepthWrite=waterMaterial.depthWrite;\n        try {\n            renderer.autoClear = false;\n            const copy = this.fullscreenMaterial;\n            copy.inputBuffer = inputBuffer.texture;\n            copy.depthBuffer = this.opaqueDepthCaptured ? null : this.depthTexture;\n            renderer.setRenderTarget(this.target);\n            renderer.render(this.scene, this.camera);\n            // Aerial/cloud passes may have swapped color targets. Restore the\n            // opaque hardware depth there before the water's depth-tested draw.\n            copy.inputBuffer = null; copy.depthBuffer = this.depthTexture;\n            renderer.setRenderTarget(inputBuffer);\n            renderer.render(this.scene, this.camera);\n            const u = ocean.uniformsLocal;\n            u.ncaOceanSceneColor.value = this.target.texture;\n            u.ncaOceanSceneRegion.value.set(1,1,0,0);\n            u.ncaOceanReflectionReady.value=0;\n            const reflection=this.reflectionCapture;\n            if(this.atmosphereSource?.uniforms.get('ncaWaterReflectionReady')?.value>0.5\n                && reflection?.atlas.copyExtra(renderer,this.target.texture)){\n                u.ncaOceanSceneColor.value=reflection.atlas.target.texture;\n                u.ncaOceanSceneRegion.value.copy(reflection.atlas.extraRegion);\n                u.ncaOceanReflectionRegion.value.copy(reflection.atlas.reflectionRegion);\n                u.ncaOceanReflectionFromView.value.copy(reflection.view.fromView);\n                u.ncaOceanReflectionViewFromView.value.copy(reflection.view.viewFromView);\n                u.ncaOceanReflectionReady.value=1;\n            }\n            u.ncaOceanSceneDepth.value = this.target.depthTexture;\n            u.ncaOceanOpticsReady.value = 1;\n            u.ncaOceanCameraFar.value = camera.far;\n            u.ncaOceanViewport.value.copy(this.viewport);\n            u.ncaOceanProjection.value.copy(camera.projectionMatrix);\n            this.upView.copy(ocean.up).transformDirection(ocean.parent.matrixWorld)\n                .transformDirection(camera.matrixWorldInverse);\n            u.ncaOceanUpView.value.copy(this.upView);\n            u.ncaOceanSunView.value.copy(ocean.uniforms.sunDirection?.value || this.sunView.set(0,1,0))\n                .transformDirection(camera.matrixWorldInverse);\n            this.waterScene.traverseVisible(object => {\n                if (object.isLight) { lights.push([object, object.layers.mask]); object.layers.enable(OCEAN_SURFACE_LAYER); }\n            });\n            camera.layers.set(OCEAN_SURFACE_LAYER); ocean.mesh.layers.set(OCEAN_SURFACE_LAYER); ocean.mesh.visible = true;\n            this.waterScene.background = null;\n            waterMaterial.depthWrite=false;\n            renderer.render(this.waterScene, camera);\n            this.needsDepthBlit = true;\n        } finally {\n            this.opaqueDepthCaptured=false;\n            waterMaterial.depthWrite=waterDepthWrite;\n            ocean.mesh.material=waterMaterial;\n            ocean.mesh.visible = false; ocean.mesh.layers.mask = waterMask;\n            camera.layers.mask = layerMask;\n            for (const [light, mask] of lights) light.layers.mask = mask;\n            this.waterScene.background = background;\n            renderer.autoClear = autoClear; renderer.setRenderTarget(savedTarget);\n        }\n    }\n    dispose() { this.release(); super.dispose(); }\n}\n","import { Pass } from 'postprocessing';\n\n/** Publish the displaced sea into the existing opaque depth before cloud\n * marching. Preserve the original bed in the ocean's existing optics target.\n */\nexport class OceanDepthPass extends Pass {\n    constructor(camera) { super('OceanDepthPass');this.waterCamera=camera;this.needsSwap=false;this.needsDepthTexture=true; }\n    setDepthTexture(texture) { this.depthTexture=texture; }\n    getDepthTexture() { return this.depthTexture; }\n    render(renderer,inputBuffer) {\n        this.needsDepthBlit=false;\n        const ocean=this.ocean,owner=this.surfacePass;\n        if(!this.waterVisible || !ocean?.depthMaterial || !this.depthTexture || !owner)return;\n        owner.captureOpaqueDepth(renderer,inputBuffer,this.depthTexture);\n        const mesh=ocean.mesh,material=mesh.material,visible=mesh.visible;\n        const target=renderer.getRenderTarget(),autoClear=renderer.autoClear;\n        try {\n            renderer.autoClear=false;renderer.setRenderTarget(inputBuffer);\n            mesh.visible=true;mesh.material=ocean.depthMaterial;\n            renderer.render(mesh,this.waterCamera);\n            this.needsDepthBlit=true;\n        } finally {\n            mesh.material=material;mesh.visible=visible;\n            renderer.autoClear=autoClear;renderer.setRenderTarget(target);\n        }\n    }\n}\n","/**\n * Mixed deferred-lighting contract for photoreal 3D Tiles.\n *\n * The atmosphere compositor renders the whole scene, but Takram's physical\n * sun/sky irradiance must only reinterpret Google/Cesium's baked unlit\n * photogrammetry as albedo. A dedicated render layer lets the photoreal mask\n * pass select those meshes without retaining tile-model references or allowing\n * GeoJSON/labels/overview assets into the lighting mask. The mask uses its own\n * hardware depth attachment: packed depth comparisons are unstable across\n * NOCLIP's astronomical logarithmic camera range. Surface direction comes from\n * Takram's stable ellipsoid normal, not streaming mesh topology.\n */\nexport const PHOTO_DEFERRED_LIGHTING_LAYER = 29;\n\n/**\n * Imported scene assets (see render/PhotorealAssetLighting.js). Layer 25:\n * unlit-albedo asset meshes that the mask marks as lit photoreal surface.\n * Layer 24: opaque forward-lit asset meshes that only occlude the mask.\n * Neither ever joins layer 29.\n */\nexport const PHOTO_DEFERRED_ASSET_LAYER = 25;\nexport const PHOTO_MASK_OCCLUDER_LAYER = 24;\n\n/**\n * Verify that every renderable photoreal mesh is ready for the shared provider\n * material contract before the native tile parser exposes it.\n *\n * Google photoreal geometry does not consistently ship normals. The upstream\n * Three.js example therefore treats TileCreasedNormalsPlugin as required model\n * preparation, and NOCLIP's provider/wireframe material paths share that\n * contract. Irradiance itself deliberately does not consume these normals:\n * tile boundary faces and retained coarse parents are valid geometry but\n * produce unstable lighting during continuous refinement.\n *\n * @param {import('three').Object3D|null|undefined} root\n * @returns {{meshCount:number, normalReadyCount:number, missingNormalCount:number}}\n * @throws {Error} When a renderable mesh has no usable normal attribute.\n */\nexport function assertPhotorealDeferredLightingReady(root) {\n    let meshCount = 0;\n    let normalReadyCount = 0;\n    let missingNormalCount = 0;\n\n    root?.traverse?.((object) => {\n        if (!object?.isMesh || !object.geometry?.getAttribute?.('position')) return;\n        meshCount++;\n        if (object.geometry.getAttribute('normal')) {\n            normalReadyCount++;\n        } else {\n            missingNormalCount++;\n        }\n    });\n\n    if (missingNormalCount > 0) {\n        const error = new Error(\n            `Photoreal tile preparation produced ${missingNormalCount} mesh(es) without required normals`\n        );\n        error.name = 'PhotorealTilePreparationError';\n        error.meshCount = meshCount;\n        error.missingNormalCount = missingNormalCount;\n        throw error;\n    }\n\n    return { meshCount, normalReadyCount, missingNormalCount };\n}\n\n/**\n * Mark or unmark every mesh below a tile model for deferred surface lighting.\n * Layer 0 remains enabled, so this never changes ordinary scene visibility.\n *\n * @param {import('three').Object3D|null|undefined} root\n * @param {boolean} enabled\n * @returns {number} Number of meshes updated.\n */\nexport function setPhotorealDeferredLighting(root, enabled = true) {\n    let count = 0;\n    root?.traverse?.((object) => {\n        if (!object?.isMesh) return;\n        // A selected pixel without a usable normal falls back to baked input\n        // radiance inside Takram. It must not enter the mask, because that\n        // would also bypass the legacy night multiplier before the surface\n        // normal has arrived.\n        const hasNormal = !!object.geometry?.getAttribute?.('normal');\n        const lightingEnabled = enabled === true && hasNormal;\n        if (lightingEnabled) {\n            object.layers.enable(PHOTO_DEFERRED_LIGHTING_LAYER);\n        } else {\n            object.layers.disable(PHOTO_DEFERRED_LIGHTING_LAYER);\n        }\n        object.userData.photoDeferredLighting = lightingEnabled;\n        count++;\n    });\n    return count;\n}\n","/**\n * Imported scene assets (Content Studio glTF scans and models) inside the\n * photoreal lighting contract.\n *\n * Photoreal tiles are unlit albedo. Takram's deferred surface path lights\n * them with physical sun/sky irradiance, but only on pixels selected by the\n * hardware-depth lighting mask (layer 29). An asset that is not in that mask\n * inherits whatever the mask holds behind it:\n *   - over terrain it is relit as if it were that distant terrain, and a\n *     photoreal back face behind it paints it black;\n *   - against the sky it receives no surface lighting at all.\n * Both happen on one model, so a tall asset is split by the horizon.\n *\n * Opaque, non-emissive asset meshes therefore become unlit albedo (same\n * textures and colour) and enter the mask through their own pass (layer 25),\n * which marks every visible face as front. They are lit exactly like a\n * photoreal tile and never twice. Opaque meshes that cannot be relit, because\n * they are emissive, stay forward-lit but occlude the mask (layer 24), so\n * terrain behind them never shows through. Transparent or alpha-cut meshes\n * stay untouched. Layer 0 stays enabled, so ordinary visibility is unchanged.\n */\nimport { MeshBasicMaterial, Color, DoubleSide, FrontSide } from 'three';\nimport {\n  PHOTO_DEFERRED_ASSET_LAYER,\n  PHOTO_MASK_OCCLUDER_LAYER,\n} from '../tiles/PhotorealLightingContract.js';\n\nconst deferredMeshes = new Set();\nconst occluderMeshes = new Set();\n\nconst BLACK = new Color(0, 0, 0);\n\nconst isOpaque = (material) => material\n  && material.transparent !== true\n  && !(material.opacity < 1)\n  && !(material.alphaTest > 0)\n  && !material.alphaMap\n  && !(material.transmission > 0)\n  && material.visible !== false;\n\nconst isEmissive = (material) => !!material?.emissiveMap\n  || (material?.emissive instanceof Color\n    && !material.emissive.equals(BLACK)\n    && (material.emissiveIntensity ?? 1) > 0);\n\n/** Unlit albedo carrying the source material's base colour inputs. */\nexport function toPhotorealAlbedoMaterial(source) {\n  const material = new MeshBasicMaterial({\n    name: source.name ? `${source.name}:albedo` : 'photoreal-asset-albedo',\n    color: source.color instanceof Color ? source.color.clone() : new Color(1, 1, 1),\n    map: source.map || null,\n    vertexColors: source.vertexColors === true,\n    side: source.side ?? FrontSide,\n    fog: source.fog !== false,\n    toneMapped: source.toneMapped !== false,\n  });\n  material.userData.photorealAssetAlbedo = true;\n  return material;\n}\n\nconst track = (set, mesh) => {\n  if (set.has(mesh)) return;\n  set.add(mesh);\n  mesh.geometry?.addEventListener?.('dispose', () => {\n    deferredMeshes.delete(mesh);\n    occluderMeshes.delete(mesh);\n  });\n};\n\n/**\n * Prepare a freshly loaded asset subtree. Call before opacity/appearance\n * caches read its materials. Returns the classification counts.\n */\nexport function preparePhotorealAssetLighting(root) {\n  const counts = { deferred: 0, occluder: 0, forward: 0 };\n  root?.traverse?.((object) => {\n    if (!object?.isMesh || object.isInstancedMesh && !object.count) return;\n    if (object.userData?.photorealAssetLighting) return;\n    const materials = [object.material].flat().filter(Boolean);\n    if (!materials.length || !materials.every(isOpaque)) {\n      object.userData.photorealAssetLighting = 'forward';\n      counts.forward++;\n      return;\n    }\n    if (materials.some(isEmissive)) {\n      object.layers.enable(PHOTO_MASK_OCCLUDER_LAYER);\n      object.userData.photorealAssetLighting = 'occluder';\n      track(occluderMeshes, object);\n      counts.occluder++;\n      return;\n    }\n    const converted = materials.map(toPhotorealAlbedoMaterial);\n    for (const material of materials) material.dispose?.();\n    object.material = Array.isArray(object.material) ? converted : converted[0];\n    object.layers.enable(PHOTO_DEFERRED_ASSET_LAYER);\n    object.userData.photorealAssetLighting = 'deferred';\n    track(deferredMeshes, object);\n    counts.deferred++;\n  });\n  return counts;\n}\n\n/**\n * Keep a forward-lit opaque mesh (e.g. a theater screen showing video) out of\n * photoreal relighting while still occluding the mask, so the terrain and sky\n * composited behind it never bleed through.\n */\nexport function markPhotorealMaskOccluder(root) {\n  root?.traverse?.((object) => {\n    if (!object?.isMesh || object.userData?.photorealAssetLighting) return;\n    object.layers.enable(PHOTO_MASK_OCCLUDER_LAYER);\n    object.userData.photorealAssetLighting = 'occluder';\n    track(occluderMeshes, object);\n  });\n}\n\n/** Whether either asset mask pass has anything to draw. */\nexport function photorealAssetMaskCounts() {\n  return { deferred: deferredMeshes.size, occluder: occluderMeshes.size };\n}\n\n/**\n * Override material for an asset mask pass. Writes `value` (1 = lit like a\n * photoreal front face, 0 = not photoreal) with its own depth, on every face\n * the source draws. A source that became transparent at runtime (overlay\n * opacity) contributes nothing.\n */\nexport function createAssetMaskMaterial(value) {\n  const material = new MeshBasicMaterial({\n    color: new Color(value, 0, 0),\n    depthTest: true,\n    depthWrite: true,\n    side: DoubleSide,\n    toneMapped: false,\n    fog: false,\n  });\n  material.customProgramCacheKey = () => 'nca-photo-asset-mask-v1';\n  material.onBeforeRender = (_renderer, _scene, _camera, _geometry, object, group) => {\n    const source = Array.isArray(object.material) ? object.material[group?.materialIndex || 0] : object.material;\n    const contributes = isOpaque(source);\n    material.side = source?.side ?? FrontSide;\n    material.colorWrite = contributes;\n    material.depthWrite = contributes;\n  };\n  return material;\n}\n\n/** Test seam. */\nexport function _resetPhotorealAssetRegistry() {\n  deferredMeshes.clear();\n  occluderMeshes.clear();\n}\n","import * as THREE from 'three';\nimport {\n    Pass,\n    RenderPass,\n    Selection,\n} from 'postprocessing';\nimport {\n    PHOTO_DEFERRED_ASSET_LAYER,\n    PHOTO_MASK_OCCLUDER_LAYER,\n} from '../tiles/PhotorealLightingContract.js';\nimport { createAssetMaskMaterial, photorealAssetMaskCounts } from './PhotorealAssetLighting.js';\n\n/**\n * Renders the photoreal lighting layer directly into a single-channel mask.\n *\n * Takram's LightingMaskPass copies two logarithmic depth textures, packs them\n * to RGBA, reconstructs perspective depth, and compares the results. That is\n * reliable for ordinary camera ranges, but a 0.1 m → astronomical NOCLIP\n * camera turns tiny round-trip errors into a full-frame salt-and-pepper mask.\n *\n * This pass uses the selected layer's own hardware depth test instead. It\n * preserves front-most photoreal surfaces and exact raster coverage without\n * converting depth to or from a color texture. Non-photoreal foreground\n * objects are intentionally not part of this auxiliary depth buffer; that\n * small mixed-geometry limitation is preferable to relighting every surface\n * through a noisy screen-space comparison.\n *\n * Imported scene assets are the exception: they are depth-tested into the\n * same attachment after the photoreal layer. Albedo assets (layer 25) write 1\n * on every visible face, and opaque forward assets (layer 24) write 0, so the\n * terrain behind an asset never decides how the asset is lit.\n */\nexport class PhotorealLightingMaskPass extends Pass {\n    constructor(scene, camera, selectionLayer) {\n        super('PhotorealLightingMaskPass');\n        this.needsSwap = false;\n\n        this.selection = new Selection();\n        this.selection.layer = selectionLayer;\n\n        const material = new THREE.MeshBasicMaterial({\n            color: 0xffffff,\n            depthTest: true,\n            depthWrite: true,\n            side: THREE.DoubleSide,\n            toneMapped: false,\n        });\n        material.userData.photoDarkUnderside = true;\n        material.onBeforeCompile = shader => {\n            shader.fragmentShader = shader.fragmentShader.replace('#include <tonemapping_fragment>',\n                'if (!gl_FrontFacing) gl_FragColor = vec4(0.5, 0.0, 0.0, 1.0);\\n#include <tonemapping_fragment>');\n        };\n        material.customProgramCacheKey = () => 'nca-photo-face-mask-v1';\n        // An override must not admit faces that the source color pass culls.\n        // Standard/front-only provider parents otherwise paint a false black\n        // silhouette across genuine sky when the camera is inside their shell.\n        material.onBeforeRender = (_renderer, _scene, _camera, _geometry, object, group) => {\n            const source = Array.isArray(object.material) ? object.material[group?.materialIndex || 0] : object.material;\n            material.side = material.userData.photoBackfaceMaskDisabled ? THREE.FrontSide : (source?.side ?? THREE.FrontSide);\n        };\n        this.renderPass = new RenderPass(scene, camera, material);\n        this.renderPass.ignoreBackground = true;\n        this.renderPass.skipShadowMapUpdate = true;\n        this.renderPass.selection = this.selection;\n        const clearPass = this.renderPass.getClearPass?.();\n        if (clearPass) {\n            clearPass.overrideClearColor = new THREE.Color(0x000000);\n            clearPass.overrideClearAlpha = 1;\n        }\n\n        this.renderTarget = new THREE.WebGLRenderTarget(1, 1, {\n            format: THREE.RedFormat,\n            type: THREE.UnsignedByteType,\n            minFilter: THREE.NearestFilter,\n            magFilter: THREE.NearestFilter,\n            depthBuffer: true,\n            stencilBuffer: false,\n        });\n        this.renderTarget.texture.name = 'NOCLIP.PhotorealLightingMask';\n        this._scene = scene;\n        this._camera = camera;\n        this._assetPasses = null;\n    }\n\n    _ensureAssetPasses() {\n        if (this._assetPasses) return this._assetPasses;\n        const make = (layer, value) => {\n            const pass = new RenderPass(this._scene, this._camera, createAssetMaskMaterial(value));\n            pass.ignoreBackground = true;\n            pass.skipShadowMapUpdate = true;\n            pass.clear = false;\n            pass.selection = new Selection();\n            pass.selection.layer = layer;\n            return pass;\n        };\n        this._assetPasses = {\n            deferred: make(PHOTO_DEFERRED_ASSET_LAYER, 1),\n            occluder: make(PHOTO_MASK_OCCLUDER_LAYER, 0),\n        };\n        return this._assetPasses;\n    }\n\n    initialize(renderer, alpha, frameBufferType) {\n        this.renderPass.initialize(renderer, alpha, frameBufferType);\n        this._assetPasses?.deferred.initialize(renderer, alpha, frameBufferType);\n        this._assetPasses?.occluder.initialize(renderer, alpha, frameBufferType);\n    }\n\n    render(renderer, _inputBuffer, _outputBuffer, deltaTime, stencilTest) {\n        const autoClear = renderer.autoClear;\n        renderer.autoClear = false;\n        this.renderPass.render(\n            renderer,\n            this.renderTarget,\n            null,\n            deltaTime,\n            stencilTest,\n        );\n        // Scene traversal is not free: only run an asset pass that has meshes.\n        const counts = photorealAssetMaskCounts();\n        if (counts.deferred || counts.occluder) {\n            const passes = this._ensureAssetPasses();\n            if (counts.deferred) passes.deferred.render(renderer, this.renderTarget, null, deltaTime, stencilTest);\n            if (counts.occluder) passes.occluder.render(renderer, this.renderTarget, null, deltaTime, stencilTest);\n        }\n        renderer.autoClear = autoClear;\n    }\n\n    setSize(width, height) {\n        this.renderTarget.setSize(width, height);\n    }\n\n    dispose() {\n        for (const pass of Object.values(this._assetPasses || {})) {\n            pass.overrideMaterial?.dispose?.();\n            pass.dispose?.();\n        }\n        this._assetPasses = null;\n        this.renderPass.dispose?.();\n        this.renderTarget.dispose();\n    }\n\n    get texture() {\n        return this.renderTarget.texture;\n    }\n\n    get selectionLayer() {\n        return this.selection.layer;\n    }\n\n    set selectionLayer(value) {\n        this.selection.layer = value;\n    }\n}\n","import * as THREE from 'three';\n\n// Coarse global parents must not draw through a temporary near-side coverage\n// gap, but the horizon guard must also preserve terrain above the camera. A\n// one-sided tangent test against the fragment radius treats every hilltop as\n// part of a sphere larger than a valley camera and clips that sphere cleanly\n// out of the skyline.\n//\n// Model the camera and fragment as two elevated endpoints above a conservative\n// inner sphere instead. Test the closest point on their finite line segment\n// rather than subtracting two cosines that are both nearly 1.0 at street\n// height. The cosine form loses the very altitude precision this guard needs\n// and produces a razor-straight screen-space cut through overlapping LODs.\n// The segment form is the same two-endpoint line-of-sight condition, remains\n// invariant under daily rotation, preserves elevated skyline terrain, and\n// still rejects remote/opposite-side parents. The occluder is a fixed\n// conservative inner sphere: WGS84 semi-minor radius minus 12 km of global\n// relief/bathymetry clearance. Deriving it from min(fragment, camera) creates\n// an artificial street-height sphere and visibly slices distant mountains\n// into a detached cap above a ruler-flat horizon.\nexport const PHOTO_SURFACE_HORIZON_GLSL = /* glsl */`\nbool photoSurfaceOccluded( const in vec3 photoPosition, const in vec3 photoCameraPosition ) {\n    const float photoOccluderRadius = 6344752.314245;\n    vec3 photoSegment = photoPosition - photoCameraPosition;\n    float photoSegmentLengthSq = dot( photoSegment, photoSegment );\n    if ( photoSegmentLengthSq <= 1.0 ) return false;\n\n    float photoClosestT = clamp(\n        -dot( photoCameraPosition, photoSegment ) / photoSegmentLengthSq,\n        0.0,\n        1.0\n    );\n    if ( photoClosestT <= 0.0 || photoClosestT >= 1.0 ) return false;\n\n    vec3 photoClosestPoint =\n        photoCameraPosition + photoClosestT * photoSegment;\n    return length( photoClosestPoint ) < photoOccluderRadius;\n}\n`;\n\nconst PHOTO_SURFACE_VISIBILITY_VERTEX_PARS = /* glsl */`\n#define NCA_PHOTO_SURFACE_VISIBILITY_R185\nvarying vec3 vPhotoWorldPosition;\n`;\n\nconst PHOTO_SURFACE_VISIBILITY_VERTEX_MAIN = /* glsl */`\nvec4 photoVisibilityWorldPosition = vec4( transformed, 1.0 );\n#ifdef USE_BATCHING\n    photoVisibilityWorldPosition = batchingMatrix * photoVisibilityWorldPosition;\n#endif\n#ifdef USE_INSTANCING\n    photoVisibilityWorldPosition = instanceMatrix * photoVisibilityWorldPosition;\n#endif\nvPhotoWorldPosition = ( modelMatrix * photoVisibilityWorldPosition ).xyz;\n`;\n\nconst PHOTO_SURFACE_VISIBILITY_FRAGMENT_PARS = /* glsl */`\n#define NCA_PHOTO_SURFACE_VISIBILITY_R185\n${PHOTO_SURFACE_HORIZON_GLSL}\nvarying vec3 vPhotoWorldPosition;\n`;\n\nconst PHOTO_SURFACE_VISIBILITY_FRAGMENT_MAIN = /* glsl */`\nif ( photoSurfaceOccluded( vPhotoWorldPosition, cameraPosition ) ) discard;\n`;\n\n/**\n * Photoreal terrain is an opaque depth surface. Provider coarse parents and\n * child LODs must not disagree about blending, depth writes, or sidedness:\n * doing so lets retained parent skirts show through until a later child\n * happens to arrive with an opaque material.\n */\nexport function enforcePhotorealOpaqueDepthMaterial(material) {\n    if (!material?.isMaterial) return false;\n    const side = material.userData?.photoDarkUnderside ? THREE.DoubleSide : THREE.FrontSide;\n    const changed = material.transparent !== false\n        || material.opacity !== 1\n        || material.blending !== THREE.NormalBlending\n        || material.alphaTest !== 0\n        || material.alphaHash !== false\n        || material.alphaToCoverage !== false\n        || material.depthTest !== true\n        || material.depthWrite !== true\n        || material.depthFunc !== THREE.LessEqualDepth\n        || material.colorWrite !== true\n        || material.side !== side\n        || material.premultipliedAlpha !== false;\n    material.transparent = false;\n    material.opacity = 1;\n    material.blending = THREE.NormalBlending;\n    material.alphaTest = 0;\n    material.alphaHash = false;\n    material.alphaToCoverage = false;\n    material.depthTest = true;\n    material.depthWrite = true;\n    material.depthFunc = THREE.LessEqualDepth;\n    material.colorWrite = true;\n    material.side = side;\n    material.premultipliedAlpha = false;\n    if (changed) material.needsUpdate = true;\n    return changed;\n}\n\n/**\n * Patch one arbitrary provider or override material with the shared\n * photoreal horizon guard. This is also used by the deferred normal and\n * lighting-mask passes so their G-buffers cannot see a back-side parent that\n * the main colour/depth pass rejected.\n */\nexport function preparePhotorealSurfaceVisibilityMaterial(material) {\n    if (!material?.isMaterial) return false;\n    // Even a provider-specific shader that cannot accept the generic chunk\n    // injection still represents opaque terrain and must agree with the color\n    // and depth ownership of its parent/child LODs.\n    enforcePhotorealOpaqueDepthMaterial(material);\n    if (material.isShaderMaterial\n        || material.isRawShaderMaterial\n        || material.userData?.photoLeanR185\n        || material.userData?.photoSurfaceVisibilityR185) {\n        return false;\n    }\n\n    const previousOnBeforeCompile = material.onBeforeCompile;\n    const previousProgramKey = material.customProgramCacheKey?.() || '';\n    material.userData = {\n        ...material.userData,\n        photoSurfaceVisibilityR185: true,\n    };\n    material.onBeforeCompile = function onBeforeCompilePhotoSurfaceVisibility(shader, renderer) {\n        previousOnBeforeCompile?.call(this, shader, renderer);\n        if (!shader.vertexShader.includes('#include <project_vertex>')\n            || !shader.vertexShader.match(/void\\s+main\\s*\\(\\s*\\)\\s*\\{/)\n            || !shader.fragmentShader.match(/void\\s+main\\s*\\(\\s*\\)\\s*\\{/)) {\n            return;\n        }\n        shader.vertexShader = shader.vertexShader\n            .replace(\n                /(?=void\\s+main\\s*\\(\\s*\\)\\s*\\{)/,\n                `${PHOTO_SURFACE_VISIBILITY_VERTEX_PARS}\\n`\n            )\n            .replace(\n                '#include <project_vertex>',\n                `${PHOTO_SURFACE_VISIBILITY_VERTEX_MAIN}\\n#include <project_vertex>`\n            );\n        shader.fragmentShader = shader.fragmentShader\n            .replace(\n                /(?=void\\s+main\\s*\\(\\s*\\)\\s*\\{)/,\n                `${PHOTO_SURFACE_VISIBILITY_FRAGMENT_PARS}\\n`\n            )\n            .replace(\n                /void\\s+main\\s*\\(\\s*\\)\\s*\\{/,\n                (main) => `${main}\\n${PHOTO_SURFACE_VISIBILITY_FRAGMENT_MAIN}`\n            );\n    };\n    material.customProgramCacheKey = () => (\n        `${previousProgramKey}|nca-photo-surface-visibility-r185-v4`\n    );\n    material.needsUpdate = true;\n    return true;\n}\n\n/**\n * Apply the physical horizon guard to every non-unlit provider material in a\n * tile model. Cesium and provider sub-assets can contain standard or physical\n * materials even though Google currently ships mostly unlit tiles.\n */\nexport function preparePhotorealSurfaceVisibilityMaterials(scene) {\n    let preparedCount = 0;\n    scene?.traverse?.((child) => {\n        if (!child?.isMesh || !child.material) return;\n        const materials = Array.isArray(child.material) ? child.material : [child.material];\n        for (const material of materials) {\n            if (preparePhotorealSurfaceVisibilityMaterial(material)) preparedCount++;\n        }\n    });\n    return preparedCount;\n}\n","import { Matrix4, PerspectiveCamera, Plane, Vector3, Vector4 } from 'three';\n\nconst A=6378137, B=6356752.314245, E2=1-(B*B)/(A*A);\nconst GRID_Y=[-.8,-.4,0,.4,.8], GRID_X=[0,-.4,.4,-.8,.8];\nconst uniformValue=(uniforms,name)=>uniforms.get(name)?.value;\nexport function waterGeodeticPosition(latitude, longitude, height, target) {\n  const s=Math.sin(latitude), c=Math.cos(latitude), n=A/Math.sqrt(1-E2*s*s);\n  return target.set((n+height)*c*Math.sin(longitude), (n*(1-E2)+height)*s, (n+height)*c*Math.cos(longitude));\n}\nexport function waterGeodeticCoordinates(position, target) {\n  const h=Math.hypot(position.x,position.z), theta=Math.atan2(position.y*A,h*B);\n  target.x=Math.atan2(position.y+(A*A-B*B)/B*Math.sin(theta)**3,h-E2*A*Math.cos(theta)**3);\n  target.y=Math.atan2(position.x,position.z);\n  return target;\n}\n\n/** One bounded, numeric water lookup. No terrain rays, readback, or new data. */\nexport function sampleReflectionWater(uniforms, position, result, scratch) {\n  const image=uniformValue(uniforms,'ncaWaterRegionalMask')?.image, bounds=uniformValue(uniforms,'ncaWaterRegionalBounds');\n  if(!image?.data || !bounds || uniformValue(uniforms,'ncaWaterRegionalEnabled')<0.5 || uniformValue(uniforms,'ncaWaterDatumReady')<0.5)return false;\n  waterGeodeticCoordinates(position,scratch);\n  const latitude=scratch.x, longitude=scratch.y;\n  let x=longitude/(Math.PI*2)+.5; x+=Math.floor(bounds.x+bounds.z*.5-x+.5);\n  const y=.5-Math.asinh(Math.tan(latitude))/(Math.PI*2),u=(x-bounds.x)/bounds.z,v=(y-bounds.y)/bounds.w;\n  if(!(u>=0&&u<1&&v>=0&&v<1))return false;\n  const i=(Math.floor(v*image.height)*image.width+Math.floor(u*image.width))*4, p=image.data;\n  if(p[i]<192 || p[i+1]<254)return false;\n  let height;\n  if(p[i+2]>=128)height=uniformValue(uniforms,'ncaWaterSeaHeight');\n  else {\n    if(uniformValue(uniforms,'ncaWaterSurfaceHeightEnabled')<.5 || p[i+3]===0)return false;\n    const range=uniformValue(uniforms,'ncaWaterSurfaceHeightRange');height=range.x+p[i+3]*range.y+uniformValue(uniforms,'ncaWaterGeoid');\n  }\n  if(!Number.isFinite(height))return false;\n  waterGeodeticPosition(latitude,longitude,height,result.point);\n  result.normal.set(Math.cos(latitude)*Math.sin(longitude),Math.sin(latitude),Math.cos(latitude)*Math.cos(longitude));\n  result.height=height;return true;\n}\n\n/** Mirror geometry in CPU double precision; never move the original camera. */\nexport class WaterReflectionView {\n  constructor(){\n    this.camera=new PerspectiveCamera(); this.plane=new Plane(); this.ecefPlane=new Plane();\n    this.fromView=new Matrix4();this.viewFromView=new Matrix4();this._inverse=new Matrix4();this._local=new Plane();this._clip=new Vector4();this._q=new Vector4();\n    this._position=new Vector3();this._target=new Vector3();this._up=new Vector3();this._point=new Vector3();this._ray=new Vector3();\n    this._ecefCamera=new Vector3();this._geo=new Vector3();this._normal=new Vector3();this._ground=new Vector3();\n    this.water={point:new Vector3(),normal:new Vector3(),height:0,support:null};this.valid=false;\n    this._nearestWaterPoint=new Vector3();this._nearestWaterNormal=new Vector3();\n  }\n  findWater(camera,uniforms,worldToECEF){\n    this._inverse.copy(worldToECEF).invert();this._ecefCamera.setFromMatrixPosition(camera.matrixWorld).applyMatrix4(worldToECEF);\n    waterGeodeticCoordinates(this._ecefCamera,this._geo);\n    waterGeodeticPosition(this._geo.x,this._geo.y,uniforms.get('ncaWaterSeaHeight')?.value||0,this._ground);\n    this._normal.set(Math.cos(this._geo.x)*Math.sin(this._geo.y),Math.sin(this._geo.x),Math.cos(this._geo.x)*Math.cos(this._geo.y));\n    const altitude=this._ecefCamera.distanceTo(this._ground);\n    if(altitude>20000 || this._ecefCamera.dot(this._normal)<this._ground.dot(this._normal)+.2)return false;\n    const horizonLimit=Math.min(500000,Math.max(15000,Math.sqrt(altitude*(2*A+altitude))*1.1));\n    const seaHeight=uniformValue(uniforms,'ncaWaterSeaHeight')||0;\n    const equatorial=A+seaHeight,polar=B+seaHeight;\n    // A fixed 5x5 image grid includes the horizon and nadir. Work is independent\n    // of provider mesh count; unsupported/dry samples never invent a plane.\n    for(const y of GRID_Y)for(const x of GRID_X){\n      this._ray.set(x,y,1).applyMatrix4(camera.projectionMatrixInverse).normalize()\n        .transformDirection(camera.matrixWorld).transformDirection(worldToECEF);\n      // Actual WGS84 intersection, not a tangent-plane estimate or a fixed\n      // 15 km range gate that excludes water visible below the horizon aloft.\n      const o=this._ecefCamera,d=this._ray,aa=equatorial*equatorial,bb=polar*polar;\n      const qa=(d.x*d.x+d.z*d.z)/aa+d.y*d.y/bb;\n      const qb=(o.x*d.x+o.z*d.z)/aa+o.y*d.y/bb;\n      const qc=(o.x*o.x+o.z*o.z)/aa+o.y*o.y/bb-1;\n      const discriminant=qb*qb-qa*qc;\n      if(discriminant<0)continue;\n      const distance=(-qb-Math.sqrt(discriminant))/qa;\n      if(distance<0 || distance>horizonLimit)continue;\n      this._point.copy(this._ecefCamera).addScaledVector(this._ray,distance);\n      if(sampleReflectionWater(uniforms,this._point,this.water,this._geo)){\n        this.water.support='visible-regional';\n        this.ecefPlane.setFromNormalAndCoplanarPoint(this.water.normal,this.water.point);\n        this.plane.copy(this.ecefPlane).applyMatrix4(this._inverse);return true;\n      }\n    }\n    // A land observer can see sea beyond the small regional atlas while\n    // every view ray misses its supported water. The same verified atlas can\n    // still provide a nearby datum/normal outside the primary FOV. That is a\n    // reflection reference, never new water coverage or provider tile demand.\n    const image=uniformValue(uniforms,'ncaWaterRegionalMask')?.image;\n    const bounds=uniformValue(uniforms,'ncaWaterRegionalBounds');\n    if(!image?.data||!bounds||bounds.z<=0||bounds.w<=0)return false;\n    let nearest=Math.min(50000,horizonLimit)**2,found=false,height=0;\n    for(let y=0;y<5;y++)for(let x=0;x<5;x++){\n      const longitude=(bounds.x+bounds.z*(x+.5)/5-.5)*Math.PI*2;\n      const latitude=Math.atan(Math.sinh(Math.PI*(1-2*(bounds.y+bounds.w*(y+.5)/5))));\n      waterGeodeticPosition(latitude,longitude,0,this._point);\n      if(!sampleReflectionWater(uniforms,this._point,this.water,this._geo))continue;\n      const distance=this.water.point.distanceToSquared(this._ecefCamera);\n      if(distance>=nearest||this._point.copy(this._ecefCamera).sub(this.water.point).dot(this.water.normal)<=.2)continue;\n      nearest=distance;found=true;height=this.water.height;\n      this._nearestWaterPoint.copy(this.water.point);this._nearestWaterNormal.copy(this.water.normal);\n    }\n    if(!found){this.water.support=null;return false;}\n    this.water.point.copy(this._nearestWaterPoint);this.water.normal.copy(this._nearestWaterNormal);this.water.height=height;\n    this.water.support='nearby-regional';\n    this.ecefPlane.setFromNormalAndCoplanarPoint(this.water.normal,this.water.point);\n    this.plane.copy(this.ecefPlane).applyMatrix4(this._inverse);return true;\n  }\n  update(camera,plane=this.plane,options=null){\n    const clip=options?.clip??true,overscan=options?.overscan??1.08;\n    this.plane.copy(plane);const mirror=this.camera,normal=this.plane.normal;\n    this._position.setFromMatrixPosition(camera.matrixWorld);\n    if(this.plane.distanceToPoint(this._position)<=.1){this.valid=false;return false;}\n    mirror.position.copy(this._position).addScaledVector(normal,-2*this.plane.distanceToPoint(this._position));\n    this._ray.set(0,0,-1).transformDirection(camera.matrixWorld).reflect(normal);\n    this._target.copy(mirror.position).add(this._ray);\n    this._up.set(0,1,0).transformDirection(camera.matrixWorld).reflect(normal);\n    mirror.up.copy(this._up);mirror.lookAt(this._target);mirror.near=camera.near;mirror.far=camera.far;\n    mirror.layers.mask=camera.layers.mask;mirror.updateMatrixWorld(true);\n    mirror.projectionMatrix.copy(camera.projectionMatrix);\n    mirror.projectionMatrix.elements[0]/=overscan;mirror.projectionMatrix.elements[5]/=overscan;\n    // Project from small primary-view coordinates, avoiding cancellation of\n    // float32 Earth-radius translations in the water fragment shader.\n    this.viewFromView.multiplyMatrices(mirror.matrixWorldInverse,camera.matrixWorld);\n    this.fromView.multiplyMatrices(mirror.projectionMatrix,this.viewFromView);\n    if(clip){\n      this._local.copy(this.plane).applyMatrix4(mirror.matrixWorldInverse);\n      const p=mirror.projectionMatrix.elements,c=this._clip.set(this._local.normal.x,this._local.normal.y,this._local.normal.z,this._local.constant);\n      this._q.set((Math.sign(c.x)+p[8])/p[0],(Math.sign(c.y)+p[9])/p[5],-1,(1+p[10])/p[14]);\n      c.multiplyScalar(2/c.dot(this._q));p[2]=c.x;p[6]=c.y;p[10]=c.z+1;p[14]=c.w;\n    }\n    mirror.projectionMatrixInverse.copy(mirror.projectionMatrix).invert();this.valid=true;return true;\n  }\n}\n","import { WebGLRenderTarget, HalfFloatType, Vector4, ShaderMaterial, Uniform } from 'three';\nimport { ShaderPass } from 'postprocessing';\n\n/** Main clouds, reflected HDR/depth, and optional finished ocean background\n * share one sampler. Preserve every primary cloud pixel and the 16-unit limit.\n */\nexport class WaterReflectionAtlas {\n  constructor(){\n    this.mainRegion=new Vector4(1,1,0,0);this.reflectionRegion=new Vector4();this.extraRegion=new Vector4();\n    const material=new ShaderMaterial({toneMapped:false,depthTest:false,depthWrite:false,\n      uniforms:{inputBuffer:new Uniform(null),reflectionDepth:new Uniform(null),packReflectionDepth:new Uniform(0),reflectionCameraFar:new Uniform(2e12)},\n      vertexShader:'varying vec2 vUv;void main(){vUv=position.xy*0.5+0.5;gl_Position=vec4(position.xy,0.0,1.0);}',\n      fragmentShader:`uniform sampler2D inputBuffer,reflectionDepth;\nuniform float packReflectionDepth,reflectionCameraFar;varying vec2 vUv;\nvoid main(){\n  gl_FragColor=texture2D(inputBuffer,vUv);\n  if(packReflectionDepth>.5){\n    float depth=texture2D(reflectionDepth,vUv).r;\n    // Reciprocal view kilometres retain far geometry in float16 and are\n    // affine over projected planes. Zero denotes sky, never a finite wall.\n    float z=exp2(depth*log2(reflectionCameraFar+1.0))-1.0;\n    gl_FragColor.a=depth>=1.0-1e-7?0.0:1000.0/max(.02,z);\n  }\n}`\n    });\n    this.copy=new ShaderPass(material);\n    this.input={texture:null};this.extraPixels={x:0,y:0,width:0,height:0};\n  }\n  render(renderer,main,reflection,depth=null,extraWidth=0,extraHeight=0,cameraFar=2e12){\n    const a=main.image||{},b=reflection.image||{},aw=a.width||1,ah=a.height||1,bw=b.width||1,bh=b.height||1;\n    const cw=extraWidth,ch=extraHeight,max=renderer.capabilities.maxTextureSize;\n    // Two guillotine arrangements retain exact, unscaled source rectangles.\n    const rw=Math.max(aw,bw+cw),rh=ah+Math.max(bh,ch);\n    const kw=aw+Math.max(bw,cw),kh=Math.max(ah,bh+ch);\n    const rowsFit=rw<=max&&rh<=max,columnsFit=kw<=max&&kh<=max;\n    if(!rowsFit&&!columnsFit)return null;\n    const rows=rowsFit&&(!columnsFit||rw*rh<=kw*kh);\n    const width=rows?rw:kw,height=rows?rh:kh,bx=rows?0:aw,by=rows?ah:0,cx=rows?bw:aw,cy=rows?ah:bh;\n    if(!this.target)this.target=new WebGLRenderTarget(width,height,{type:HalfFloatType,depthBuffer:false});\n    else if(this.target.width!==width||this.target.height!==height)this.target.setSize(width,height);\n    this.target.texture.name='Water.ReflectionAndMainClouds';\n    this.mainRegion.set(aw/width,ah/height,0,0);this.reflectionRegion.set(bw/width,bh/height,bx/width,by/height);\n    this.extraRegion.set(cw/width,ch/height,cx/width,cy/height);this.extraPixels.x=cx;this.extraPixels.y=cy;this.extraPixels.width=cw;this.extraPixels.height=ch;\n    const target=renderer.getRenderTarget(),auto=renderer.autoClear;\n    try{\n      renderer.autoClear=false;\n      const u=this.copy.fullscreenMaterial.uniforms;u.packReflectionDepth.value=0;u.reflectionCameraFar.value=cameraFar;\n      this.target.viewport.set(0,0,aw,ah);this.input.texture=main;this.copy.render(renderer,this.input,this.target);\n      u.packReflectionDepth.value=depth?1:0;u.reflectionDepth.value=depth;\n      this.target.viewport.set(bx,by,bw,bh);this.input.texture=reflection;this.copy.render(renderer,this.input,this.target);\n    }finally{this.target.viewport.set(0,0,width,height);renderer.autoClear=auto;renderer.setRenderTarget(target);}\n    return this.target.texture;\n  }\n  copyExtra(renderer,texture){\n    const r=this.extraPixels;if(!r?.width||!r.height)return false;\n    const target=renderer.getRenderTarget(),auto=renderer.autoClear;\n    try{renderer.autoClear=false;this.copy.fullscreenMaterial.uniforms.packReflectionDepth.value=0;\n      this.target.viewport.set(r.x,r.y,r.width,r.height);this.input.texture=texture;this.copy.render(renderer,this.input,this.target);\n    }finally{this.target.viewport.set(0,0,this.target.width,this.target.height);renderer.autoClear=auto;renderer.setRenderTarget(target);}\n    return true;\n  }\n  dispose(){this.target?.dispose();this.copy.dispose();}\n}\n","// View-independent capture adapters for the pinned native atmosphere shaders.\n// Geometry/sky radiance starts at the physical water plane; the primary aerial\n// pass subsequently applies the water-to-eye segment exactly once.\nexport function reflectionAerialShader(source) {\n  const start=source.indexOf('  if (ncaWaterReflectionEnabled > 0.5 && ncaPhotoSurfaceMask > 0.0) {');\n  if(start<0)throw Error('Water reflection aerial contract changed');\n  const open=source.indexOf('{',start);let end=open+1,depth=1;\n  while(depth&&end<source.length){if(source[end]==='{')depth++;if(source[end]==='}')depth--;end++;}\n  if(depth)throw Error('Water reflection aerial block is incomplete');\n  let shader=source.slice(0,start)+source.slice(end);\n  shader=shader.replace('void mainImage(const vec4 inputColor, const vec2 uv, out vec4 outputColor) {',`uniform vec4 ncaReflectionPlane;\nvec3 ncaReflectionOrigin(vec3 direction) {\n  float denominator=dot(ncaReflectionPlane.xyz,direction);\n  float distanceAlong=abs(denominator)>1e-6 ? -dot(ncaReflectionPlane,vec4(vCameraPosition,1.0))/denominator : 0.0;\n  return vCameraPosition+direction*max(0.0,distanceAlong);\n}\nvoid mainImage(const vec4 inputColor, const vec2 uv, out vec4 outputColor) {`);\n  // Helpers occur before mainImage: put the declaration before the helper\n  // that references it as well, with a single matching forward declaration.\n  const prototype='vec3 ncaReflectionOrigin(vec3 direction);\\n';\n  const helper='void applyTransmittanceInscatter(';\n  if(!shader.includes(helper))throw Error('Water reflection transmittance contract changed');\n  shader=shader.replace(helper,prototype+helper);\n  shader=shader.replace('    vCameraPosition,\\n    positionECEF,','    ncaReflectionOrigin(normalize(positionECEF-vCameraPosition)),\\n    positionECEF,');\n  shader=shader.replace(/getSkyRadiance\\(\\s*vCameraPosition,/g,'getSkyRadiance(ncaReflectionOrigin(normalize(vRayDirection)),');\n  return shader;\n}\nexport function reflectionCloudShader(source) {\n  const ray='  vec3 rayDirection = normalize(vRayDirection);';\n  const distance='  float rayDistanceToScene = getRayDistanceToScene(rayDirection, sceneViewZ);';\n  if(!source.includes(ray)||!source.includes(distance))throw Error('Water reflection cloud contract changed');\n  return source.replace('uniform float cameraNear;','uniform vec4 ncaReflectionPlane;\\nuniform float cameraNear;').replace(ray,`${ray}\n  float ncaReflectionDenominator=dot(ncaReflectionPlane.xyz,rayDirection);\n  float ncaReflectionStart=abs(ncaReflectionDenominator)>1e-6\n    ? max(0.0,-dot(ncaReflectionPlane,vec4(cameraPosition,1.0))/ncaReflectionDenominator) : 0.0;\n  cameraPosition+=rayDirection*ncaReflectionStart;`)\n    .replace(distance,`${distance}\n  if(rayDistanceToScene>0.0)rayDistanceToScene=max(0.001,rayDistanceToScene-ncaReflectionStart);`)\n    .replace('depthVelocity = vec3(frontDepth, velocity);','depthVelocity = vec3(frontDepth+ncaReflectionStart, velocity);');\n}\n","import { patchCloudDepthReconstruction, prepareCloudFrontDepth } from './CloudDepthReconstruction.js';\nimport { HalfFloatType, Matrix4, Uniform, Vector2, Vector3, Vector4 } from 'three';\nimport { EffectComposer, EffectPass, Pass, RenderPass } from 'postprocessing';\nimport { AerialPerspectiveEffect, METER_TO_LENGTH_UNIT } from '@takram/three-atmosphere';\nimport { PhotorealLightingMaskPass } from './PhotorealLightingMaskPass.js';\nimport { PHOTO_DEFERRED_LIGHTING_LAYER } from '../tiles/PhotorealLightingContract.js';\nimport { preparePhotorealSurfaceVisibilityMaterial } from '../tiles/PhotorealSurfaceVisibilityContract.js';\nimport { WaterReflectionView } from './WaterReflectionView.js';\nimport { WaterReflectionAtlas } from './WaterReflectionAtlas.js';\nimport { reflectionAerialShader, reflectionCloudShader } from './WaterReflectionShaders.js';\n\nconst CAMERA_UNIFORMS=new Set(['projectionMatrix','viewMatrix','inverseProjectionMatrix','inverseViewMatrix',\n  'cameraPosition','cameraNear','cameraFar','cameraHeight','depthBuffer','reprojectionMatrix','viewReprojectionMatrix',\n  'temporalJitter','targetUvScale','resolution','mipLevelScale','frame']);\nconst AERIAL_OWNED=new Set([...CAMERA_UNIFORMS,'altitudeCorrection','geometricErrorCorrectionAmount','overlayBuffer',\n  'normalBuffer','lightingMaskBuffer','ncaCloudAttachments','ncaCloudOverlayRegion','ncaWaterReflectionReady',\n  'ncaWaterReflectionFromView','ncaWaterReflectionRegion','ncaReflectionPlane']);\nfunction copyValue(target,value){\n  if(value?.isTexture || value===null || typeof value!=='object')return value;\n  if(Array.isArray(value)){\n    const out=Array.isArray(target)?target:[];out.length=value.length;\n    for(let i=0;i<value.length;i++)out[i]=copyValue(out[i],value[i]);return out;\n  }\n  if(target?.copy && target.constructor===value.constructor)return target.copy(value);\n  return value.clone?.()||value;\n}\nfunction copyUniforms(target,source,skip){\n  for(const [name,u]of source){if(skip.has(name))continue;const t=target.get(name);if(t)t.value=copyValue(t.value,u.value);}\n}\nfunction sameDefines(a,b){if(a.size!==b.size)return false;for(const [key,value]of a)if(b.get(key)!==value)return false;return true;}\n\nclass ReflectedCloudPass extends Pass {\n  constructor(owner){super('Water.ReflectedClouds');this.owner=owner;this.needsSwap=false;this.needsDepthTexture=true;}\n  setDepthTexture(texture,packing){this.owner.cloudPass?.setDepthTexture(texture,packing);}\n  render(renderer,_input,_output,delta){\n    const o=this.owner;if(!o.cloudPass || !o.captureClouds)return;\n    const source=o.system.clouds.cloudsPass, material=o.cloudPass.currentMaterial;\n    o.syncCloudUniforms();\n    o.syncPlane(material.uniforms.ncaReflectionPlane.value,false,material.uniforms.altitudeCorrection.value);\n    o.cloudPass.shadowBuffer=source.shadowBuffer;\n    o.cloudPass.update(renderer,source.currentMaterial.uniforms.frame.value,delta);\n    o.cloudOverlay.map=o.cloudPass.outputBuffer;o.effect.overlay=o.cloudOverlay;\n  }\n  dispose(){} // Native pass/resources have exactly one disposal owner below.\n}\n\nclass ReflectionResultPass extends Pass {\n  constructor(owner){super('Water.ReflectionResult');this.owner=owner;this.needsSwap=false;}\n  render(_renderer,input){this.owner.resultTarget=input;}\n  dispose(){}\n}\n\n/** Auxiliary HDR mirrored view, never a final-frame owner or navigation camera.\n * Native clouds have independent camera/history targets but borrow the current\n * weather, noise, physical light and shadow inputs. No second weather clock.\n */\nexport class WaterReflectionCapturePass extends Pass {\n  constructor(system){\n    super('WaterReflectionCapturePass');this.system=system;this.needsSwap=false;\n    this.view=new WaterReflectionView();this.atlas=new WaterReflectionAtlas();this.size=new Vector2(1,1);\n    this.stats={state:'cold',frames:0,failures:0};this._epoch=0;this._plane=new Vector4();this._normal=new Vector3();\n    this._viewport=new Vector4();this._scissor=new Vector4();this._worldToECEF=new Matrix4();\n    this.overlay={map:null};this.cloudOverlay={map:null};this.captureClouds=false;this._hidden=[];\n  }\n  setSize(width,height){\n    const scale=Math.min(.5,1024/Math.max(width,1),1024/Math.max(height,1));\n    this.size.set(Math.max(1,Math.ceil(width*scale)),Math.max(1,Math.ceil(height*scale)));\n    this._sizeCapture();\n  }\n  _sizeCapture(){\n    // EffectComposer.setSize also resizes the shared renderer/canvas. Only the\n    // primary composer owns that; resize auxiliary storage and passes directly.\n    if(!this.capture)return;\n    for(const target of [this.capture.inputBuffer,this.capture.outputBuffer,this.capture.depthRenderTarget])target?.setSize(this.size.x,this.size.y);\n    for(const pass of this.capture.passes)pass.setSize(this.size.x,this.size.y);\n    this.cloudPass?.setSize(this.size.x,this.size.y);\n  }\n  resetBindings(){\n    const source=this.system.aerialPerspective;\n    source?.uniforms.get('ncaWaterReflectionReady')&&(source.uniforms.get('ncaWaterReflectionReady').value=0);\n    this.system._cloudAtmosphereAttachments?.set(this.system._cloudAtmosphereAttachments.enabled,this.system.clouds);\n  }\n  syncPlane(target,kilometres,correction=this.effect?.uniforms.get('altitudeCorrection')?.value){\n    this._normal.copy(this.view.ecefPlane.normal);\n    const constant=this.view.ecefPlane.constant-(correction?this._normal.dot(correction):0);\n    target.set(this._normal.x,this._normal.y,this._normal.z,constant*(kilometres?METER_TO_LENGTH_UNIT:1));\n  }\n  syncCloudUniforms(){\n    const original=this.system.clouds.cloudsPass.currentMaterial.uniforms,own=this.cloudPass.currentMaterial.uniforms;\n    for(const name in original){if(CAMERA_UNIFORMS.has(name))continue;let target=own[name];if(!target)target=own[name]=new Uniform(null);target.value=copyValue(target.value,original[name].value);}\n  }\n  _syncAerial(){\n    const source=this.system.aerialPerspective,effect=this.effect;\n    copyUniforms(effect.uniforms,source.uniforms,AERIAL_OWNED);\n    effect.correctAltitude=source.correctAltitude;effect.ellipsoid=source.ellipsoid;effect.atmosphere=source.atmosphere;\n    effect.shadow=source.shadow;effect.shadowLength=this.system._cloudAtmosphereAttachments.emptyLength;\n    this.cloudOverlay.map=this.cloudPass?.outputBuffer||null;\n    effect.overlay=this.captureClouds?this.cloudOverlay:this.system._cloudAtmosphereAttachments.emptyOverlay;\n    effect.lightingMask=this.mask;\n    effect.uniforms.get('ncaCloudAttachments').value.set(this.captureClouds?1:0,source.uniforms.get('ncaCloudAttachments').value.y,0);\n    effect.uniforms.get('ncaCloudOverlayRegion').value.set(1,1,0,0);\n    effect.uniforms.get('ncaWaterReflectionReady').value=0;\n    // Native camera/correction update runs in EffectPass immediately before\n    // shading. The plane must use that reflected camera's correction as well.\n  }\n  _create(renderer){\n    const system=this.system,source=system.aerialPerspective;\n    this.capture=new EffectComposer(renderer,{frameBufferType:HalfFloatType,multisampling:0});\n    this.capture.autoRenderToScreen=false;\n    this.capture.addPass(new RenderPass(system.scene,this.view.camera));\n    this.maskPass=new PhotorealLightingMaskPass(system.scene,this.view.camera,PHOTO_DEFERRED_LIGHTING_LAYER);\n    const material=this.maskPass.renderPass.overrideMaterial;\n    if(material)preparePhotorealSurfaceVisibilityMaterial(material);\n    this.capture.addPass(this.maskPass);this.mask={map:this.maskPass.texture,channel:'r'};\n    if(system._cloudWarmupState==='ready'&&system._cloudAtmosphereAttachments.enabled)this._createClouds(renderer);\n    this.capture.addPass(new ReflectedCloudPass(this));\n    const effect=new AerialPerspectiveEffect(this.view.camera,{},system._atmosphereParams);this.effect=effect;\n    // Clone wrappers/math, borrow textures; never clone or dispose scene inputs.\n    for(const [key,u]of source.uniforms)if(!effect.uniforms.has(key))effect.uniforms.set(key,new Uniform(copyValue(null,u.value)));\n    effect.defines.clear();for(const [key,value]of source.defines)effect.defines.set(key,value);\n    effect.fragmentShader=reflectionAerialShader(source.fragmentShader);\n    effect.uniforms.set('ncaReflectionPlane',new Uniform(new Vector4()));\n    this._syncAerial();\n    const update=effect.update.bind(effect);\n    effect.update=(...args)=>{update(...args);this.syncPlane(effect.uniforms.get('ncaReflectionPlane').value,true);};\n    this.aerialPass=new EffectPass(this.view.camera,effect);this.capture.addPass(this.aerialPass);\n    this.capture.addPass(new ReflectionResultPass(this));\n    this._sizeCapture();\n    this._shader=source.fragmentShader;this._defines=new Map(source.defines);\n  }\n  _createClouds(renderer){\n      const system=this.system;\n      const clouds=system.clouds,original=clouds.cloudsPass;\n      this.cloudPass=new original.constructor({shadow:original.shadow,parameterUniforms:clouds.parameterUniforms,\n        layerUniforms:clouds.layerUniforms,atmosphereUniforms:clouds.atmosphereUniforms},system._atmosphereParams);\n      this.cloudPass.mainCamera=this.view.camera;this.cloudPass.lightShafts=false;\n      prepareCloudFrontDepth(this.cloudPass);\n      patchCloudDepthReconstruction({cloudsPass:this.cloudPass});\n      this.cloudPass.temporalUpscale=original.temporalUpscale;\n      const own=this.cloudPass.currentMaterial,base=original.currentMaterial;\n      own.vertexShader=base.vertexShader;own.fragmentShader=reflectionCloudShader(base.fragmentShader);\n      own.defines={...base.defines};delete own.defines.SHADOW_LENGTH;\n      own.uniforms.ncaReflectionPlane=new Uniform(new Vector4());\n      this.syncCloudUniforms();\n      own.onBeforeRender(renderer);\n      this._cloudMaterial=base;this._cloudVersion=base.version;\n      this.system._patchCloudsReprojectionForEffect?.({cloudsPass:this.cloudPass});\n      this.cloudPass.setShadowSize(clouds.shadow.mapSize.x,clouds.shadow.mapSize.y,clouds.shadow.cascadeCount);\n  }\n  _requestWarm(renderer){\n    if(this._warming || this._disposed)return;\n    const epoch=++this._epoch;this._warming=true;this.stats.state='warming';\n    const idle=task=>this.system._runCloudWarmupIdleTask(()=>{if(!this._disposed&&epoch===this._epoch)return task();});\n    void (async()=>{\n      await idle(()=>{this._disposeCapture();this._create(renderer);});\n      if(this._disposed||epoch!==this._epoch)return;\n      if(this.cloudPass)await idle(()=>this.cloudPass.initialize(renderer,false,HalfFloatType));\n      const targets=[this.capture.inputBuffer,this.capture.outputBuffer,this.maskPass.renderTarget,\n        this.cloudPass?.currentRenderTarget,this.cloudPass?.resolveRenderTarget,this.cloudPass?.historyRenderTarget].filter(Boolean);\n      for(const target of targets){await idle(()=>renderer.initRenderTarget(target));if(this._disposed||epoch!==this._epoch)return;}\n      const jobs=[[this.aerialPass.scene,this.aerialPass.camera]];\n      if(this.cloudPass)jobs.push([this.cloudPass.currentPass.scene,this.cloudPass.currentPass.camera],\n        [this.cloudPass.resolvePass.scene,this.cloudPass.resolvePass.camera]);\n      await this.system._compileCloudScenesInIdleSlices(jobs);\n      if(this._disposed||epoch!==this._epoch)return;\n      this._cloudReady=!!this.cloudPass;\n      this.stats.state='ready';\n    })().catch(error=>{if(!this._disposed){this.stats.state='failed';this.stats.failures++;this.stats.error=String(error?.message||error).slice(0,300);console.warn('[WaterReflection] Capture warm-up failed',error);}})\n      .finally(()=>{this._warming=false;});\n  }\n  _requestCloudWarm(renderer){\n    if(this._cloudWarming||this._disposed||this.stats.cloudState==='failed')return;\n    const epoch=this._epoch;this._cloudWarming=true;this._cloudReady=false;this.stats.cloudState='warming';\n    const idle=task=>this.system._runCloudWarmupIdleTask(()=>{if(!this._disposed&&epoch===this._epoch)return task();});\n    void(async()=>{\n      await idle(()=>{\n        if(!this.cloudPass){\n          this._createClouds(renderer);this.cloudPass.initialize(renderer,false,HalfFloatType);\n          this.cloudPass.setSize(this.size.x,this.size.y);\n          this.cloudPass.setDepthTexture(this.aerialPass.getDepthTexture());\n        }\n        const source=this.system.clouds.cloudsPass.currentMaterial,own=this.cloudPass.currentMaterial;\n        own.vertexShader=source.vertexShader;own.fragmentShader=reflectionCloudShader(source.fragmentShader);\n        own.defines={...source.defines};delete own.defines.SHADOW_LENGTH;\n        this.syncCloudUniforms();own.onBeforeRender(renderer);own.needsUpdate=true;\n        this._cloudMaterial=source;this._cloudVersion=source.version;\n      });\n      if(this._disposed||epoch!==this._epoch)return;\n      for(const target of [this.cloudPass.currentRenderTarget,this.cloudPass.resolveRenderTarget,this.cloudPass.historyRenderTarget]){\n        await idle(()=>renderer.initRenderTarget(target));\n        if(this._disposed||epoch!==this._epoch)return;\n      }\n      await this.system._compileCloudScenesInIdleSlices([[this.cloudPass.currentPass.scene,this.cloudPass.currentPass.camera],\n        [this.cloudPass.resolvePass.scene,this.cloudPass.resolvePass.camera]]);\n      if(this._disposed||epoch!==this._epoch)return;\n      this._cloudReady=true;this.stats.cloudState='ready';\n    })().catch(error=>{if(!this._disposed){this.stats.cloudState='failed';this.stats.error=String(error?.message||error).slice(0,300);}})\n      .finally(()=>{this._cloudWarming=false;});\n  }\n  render(renderer,_input,_output,delta){\n    const system=this.system,source=system.aerialPerspective;\n    if(!source || source.uniforms.get('ncaWaterReflectionEnabled')?.value<.5 || renderer.xr.isPresenting){return;}\n    this._worldToECEF.copy(source.worldToECEFMatrix);\n    if(!this.view.findWater(system.camera,source.uniforms,this._worldToECEF)||!this.view.update(system.camera)){\n      return;\n    }\n    if(this.stats.state==='failed')return;\n    const cloudsRequested=system._cloudAtmosphereAttachments?.enabled===true&&system._cloudWarmupState==='ready';\n    const cloudMaterial=system.clouds?.cloudsPass?.currentMaterial;\n    const cloudChanged=cloudsRequested&&(cloudMaterial!==this._cloudMaterial||cloudMaterial?.version!==this._cloudVersion);\n    if(this.stats.state!=='ready'||source.fragmentShader!==this._shader||!sameDefines(source.defines,this._defines)){\n      this._requestWarm(renderer);return;\n    }\n    if(cloudChanged)this._requestCloudWarm(renderer);\n    this.captureClouds=!!this.cloudPass&&cloudsRequested&&this._cloudReady===true;\n    this._syncAerial();\n    const target=renderer.getRenderTarget(),autoClear=renderer.autoClear,xr=renderer.xr.enabled,shadow=renderer.shadowMap.autoUpdate;\n    renderer.getViewport(this._viewport);renderer.getScissor(this._scissor);const scissorTest=renderer.getScissorTest();\n    try{\n      renderer.xr.enabled=false;renderer.shadowMap.autoUpdate=false;\n      // Consume only native retained siblings/fallbacks. Reflection never changes\n      // traversal, tile demand, cache usage, or the selected primary hierarchy.\n      const tiles=system.getPhotorealTileLoader?.()?._tiles;\n      if(tiles)for(const tile of tiles.visibleTiles){const root=tile.engineData?.scene;if(root&&!root.visible){this._hidden.push(root);root.visible=true;}}\n      const sun=system._sunMesh;const sunVisible=sun?.visible;\n      if(sun)sun.visible=false;\n      try{this.capture.render(delta);}finally{if(sun)sun.visible=sunVisible;}\n      const main=system._cloudAtmosphereAttachments.enabled?system.clouds?.atmosphereOverlay?.map:null;\n      const ocean=system._oceanSurfacePass;const extra=ocean?.waterVisible===true;\n      const texture=this.atlas.render(renderer,main||system._cloudAtmosphereAttachments.zero,this.resultTarget.texture,\n        this.aerialPass.getDepthTexture(),extra?Math.min(1024,Math.ceil(ocean.viewport.x/2)):0,extra?Math.min(1024,Math.ceil(ocean.viewport.y/2)):0,this.view.camera.far);\n      if(!texture)return;\n      this.overlay.map=texture;source.overlay=this.overlay;\n      source.uniforms.get('ncaCloudOverlayRegion').value.copy(this.atlas.mainRegion);\n      source.uniforms.get('ncaWaterReflectionRegion').value.copy(this.atlas.reflectionRegion);\n      source.uniforms.get('ncaWaterReflectionFromView').value.copy(this.view.fromView);\n      source.uniforms.get('ncaWaterReflectionReady').value=1;\n      this.stats.support=this.view.water.support;this.stats.frames++;this.stats.width=this.size.x;this.stats.height=this.size.y;this.stats.clouds=this.captureClouds;\n    }catch(error){this.stats.failures++;this.stats.state='failed';this.stats.error=String(error?.message||error).slice(0,300);this.resetBindings();}\n    finally{\n      for(const root of this._hidden)root.visible=false;this._hidden.length=0;\n      renderer.autoClear=autoClear;renderer.xr.enabled=xr;renderer.shadowMap.autoUpdate=shadow;\n      renderer.setRenderTarget(target);renderer.setViewport(this._viewport);renderer.setScissor(this._scissor);renderer.setScissorTest(scissorTest);\n    }\n  }\n  _disposeCapture(){\n    // EffectComposer.dispose() disposes the library-wide fullscreen triangle.\n    // This auxiliary owner must never retire the primary composer's geometry.\n    if(this.capture){for(const pass of this.capture.passes)pass.dispose();this.capture.passes=[];\n      this.capture.inputBuffer.dispose();this.capture.outputBuffer.dispose();this.capture.deleteDepthTexture();\n      this.capture.copyPass.dispose();this.capture.timer.dispose();}\n    this.cloudPass?.dispose();this.capture=this.cloudPass=this.effect=this.aerialPass=this.maskPass=null;}\n  dispose(){this._disposed=true;this._epoch++;this.resetBindings();this._disposeCapture();this.atlas.dispose();}\n}\n","import { Pass, CopyMaterial } from 'postprocessing';\n\nexport const RAIN_LAYER = 26;\n\n/** Draw local weather after aerial/cloud scattering, before final tone mapping.\n * Reuse the composer's authoritative opaque depth; no additional render target.\n */\nexport class RainPass extends Pass {\n    constructor(scene, camera) {\n        super('RainPass');\n        this.weatherScene = scene; this.weatherCamera = camera;\n        this.rainSystem = null;\n        this.needsSwap = false; this.needsDepthTexture = true;\n        this.fullscreenMaterial = new CopyMaterial();\n        this.fullscreenMaterial.colorSpaceConversion = false;\n        this.fullscreenMaterial.inputBuffer = null;\n    }\n    setDepthTexture(texture) { this.depthTexture = texture; }\n    getDepthTexture() { return this.depthTexture; }\n    render(renderer, inputBuffer) {\n        if (!this.rainSystem?.group.visible || !this.depthTexture) return;\n        const target = renderer.getRenderTarget(), autoClear = renderer.autoClear;\n        const camera = this.weatherCamera, scene = this.weatherScene;\n        const mask = camera.layers.mask, background = scene.background, override = scene.overrideMaterial;\n        try {\n            renderer.autoClear = false;\n            renderer.setRenderTarget(inputBuffer);\n            // The atmospheric effects can swap color targets. Copy depth only\n            // into the current target before depth-tested transparent weather.\n            this.fullscreenMaterial.depthBuffer = this.depthTexture;\n            renderer.render(this.scene, this.camera);\n            camera.layers.set(RAIN_LAYER); scene.background = null; scene.overrideMaterial = null;\n            renderer.render(scene, camera);\n        } finally {\n            camera.layers.mask = mask; scene.background = background; scene.overrideMaterial = override;\n            renderer.autoClear = autoClear; renderer.setRenderTarget(target);\n        }\n    }\n}\n","import { Pass } from 'postprocessing';\nimport { ShaderMaterial, CustomBlending, OneFactor, OneMinusSrcAlphaFactor, AddEquation, Matrix4, Vector2 } from 'three';\nimport { CLOUD_GUIDE_GLSL } from './CloudDepthReconstruction.js';\n\n/** Native cloud radiance is already premultiplied and atmosphere-lit. Composite\n * it once after opaque lighting/water optics, never feed it back as albedo or\n * a refractive/reflective geometry source. Borrow all native buffers/scene depth.\n */\nexport class CloudColorPass extends Pass {\n  constructor(camera) {\n    super('CloudColorPass'); this.viewCamera=camera; this.effects=[];\n    this.needsSwap=false;this.needsDepthTexture=true;\n    this.fullscreenMaterial=new ShaderMaterial({name:'CloudColorComposite',toneMapped:false,\n      transparent:true,depthTest:false,depthWrite:false,blending:CustomBlending,\n      blendSrc:OneFactor,blendDst:OneMinusSrcAlphaFactor,blendEquation:AddEquation,\n      uniforms:{cloudColor:{value:null},sceneDepth:{value:null},\n        inverseProjection:{value:new Matrix4()},depthMode:{value:new Vector2()},\n        viewport:{value:new Vector2(1,1)},\n        nearZ:{value:.1},farZ:{value:2e12},marchLimit:{value:1e6}},\n      vertexShader:'void main(){gl_Position=vec4(position.xy,0.0,1.0);}',\n      fragmentShader:`precision highp float;\nuniform sampler2D cloudColor,sceneDepth;\nuniform mat4 inverseProjection;\nuniform vec2 viewport,depthMode;\nuniform float nearZ,farZ,marchLimit;\n${CLOUD_GUIDE_GLSL}\nfloat guide(vec2 uv,float limitZ){\n  vec3 ray=normalize((inverseProjection*vec4(uv*2.0-1.0,0.0,1.0)).xyz);\n  return ncaCloudGuideDepth(texture2D(sceneDepth,uv).r,nearZ,farZ,depthMode,limitZ,\n    depthMode.y>.5?-ray.z:1.0);\n}\nvoid main(){\n  vec2 uv=gl_FragCoord.xy/viewport;\n  vec2 size=vec2(textureSize(cloudColor,0)),position=uv*size-.5;\n  vec2 base=floor(position),fraction=fract(position);\n  float target=guide(uv,marchLimit),weight=0.0;vec4 color=vec4(0.0);\n  for(int y=0;y<2;y++)for(int x=0;x<2;x++){\n    vec2 point=clamp((base+vec2(x,y)+.5)/size,.5/size,1.0-.5/size);\n    float w=ncaCloudDepthWeight(guide(point,marchLimit),target)\n      *(x==0?1.0-fraction.x:fraction.x)*(y==0?1.0-fraction.y:fraction.y);\n    color+=texture2D(cloudColor,point)*w;weight+=w;\n  }\n  if(weight<=1e-5)discard;\n  gl_FragColor=color/weight;\n}`});\n  }\n  setDepthTexture(texture){this.depthTexture=texture;}\n  getDepthTexture(){return this.depthTexture;}\n  setSize(width,height){this.fullscreenMaterial.uniforms.viewport.value.set(width,height);}\n  render(renderer,inputBuffer){\n    if(!this.depthTexture||!this.effects.length)return;\n    const target=renderer.getRenderTarget(),autoClear=renderer.autoClear,u=this.fullscreenMaterial.uniforms,camera=this.viewCamera;\n    try{\n      renderer.autoClear=false;renderer.setRenderTarget(inputBuffer);\n      u.sceneDepth.value=this.depthTexture;u.inverseProjection.value.copy(camera.projectionMatrixInverse);\n      u.nearZ.value=camera.near;u.farZ.value=camera.far;\n      u.depthMode.value.set(renderer.capabilities.logarithmicDepthBuffer?1:0,camera.isPerspectiveCamera?1:0);\n      for(const effect of this.effects){\n        const pass=effect.cloudsPass,source=pass?.currentMaterial?.uniforms;\n        if(!pass?.outputBuffer)continue;\n        u.cloudColor.value=pass.outputBuffer;\n        u.marchLimit.value=source.maxRayDistance?.value||1e6;\n        renderer.render(this.scene,this.camera);\n      }\n    }finally{renderer.autoClear=autoClear;renderer.setRenderTarget(target);}\n  }\n}\n","import { Pass, CopyMaterial } from 'postprocessing';\n\n/** Upper-atmosphere emission is radiance, not sunlit ground albedo. Draw the\n * existing shell after surface/cloud lighting so nighttime attenuation cannot\n * extinguish it a second time. Borrow the canonical opaque depth, no new target.\n */\nexport class AtmosphericEmissionPass extends Pass {\n    constructor(camera) {\n        super('AtmosphericEmissionPass');\n        this.emissionCamera = camera;\n        this.mesh = null;\n        // Further emission shells (aurora) drawn the same way; each entry is\n        // { mesh, visible, bindDepth? } captured before the scene pass hides\n        // it. bindDepth(depthTexture) receives the canonical opaque depth\n        // (photoreal tiles included) so the shell's ray stops at the ground.\n        this.extraMeshes = [];\n        this.needsSwap = false;\n        this.needsDepthTexture = true;\n        this.fullscreenMaterial = new CopyMaterial();\n        this.fullscreenMaterial.inputBuffer = null;\n        this.fullscreenMaterial.colorSpaceConversion = false;\n    }\n    setDepthTexture(texture) { this.depthTexture = texture; }\n    getDepthTexture() { return this.depthTexture; }\n    render(renderer, inputBuffer) {\n        const extras = this.extraMeshes.filter((entry) => entry?.visible && entry.mesh);\n        const drawMain = this.emissionVisible && !!this.mesh;\n        if ((!drawMain && !extras.length) || !this.depthTexture) return;\n        const target = renderer.getRenderTarget(), autoClear = renderer.autoClear;\n        const visible = this.mesh?.visible;\n        try {\n            renderer.autoClear = false;\n            renderer.setRenderTarget(inputBuffer);\n            this.fullscreenMaterial.depthBuffer = this.depthTexture;\n            renderer.render(this.scene, this.camera);\n            if (drawMain) {\n                this.mesh.visible = true;\n                renderer.render(this.mesh, this.emissionCamera);\n            }\n            for (const entry of extras) {\n                entry.bindDepth?.(this.depthTexture);\n                entry.mesh.visible = true;\n                renderer.render(entry.mesh, this.emissionCamera);\n                entry.mesh.visible = false;\n            }\n        } finally {\n            if (this.mesh) this.mesh.visible = visible;\n            renderer.autoClear = autoClear;\n            renderer.setRenderTarget(target);\n        }\n    }\n}\n","import { EARTH_PRIME_MERIDIAN_OFFSET_RAD } from '../../modules/constants.js';\n\nconst LIQUID_CODES = new Set([51, 53, 55, 56, 57, 61, 63, 65, 66, 67, 80, 81, 82, 95]);\nconst SHOWER_CODES = new Set([80, 81, 82, 95]);\nconst SNOW_CODES = new Set([71, 73, 75, 77, 85, 86]);\nconst finiteNonnegative = value => Number.isFinite(value) && value >= 0;\n\nexport function areWeatherCloudsEnabled(settings) {\n    return ['clouds', 'orbitClouds', 'simpleClouds'].some(layer =>\n        settings?.getSection?.(`scene.atmosphere.${layer}.enabled`) === true);\n}\n\nexport const DEFAULT_LOCAL_CLOUD_LAYERS = Object.freeze([\n    Object.freeze({ altitude: 2750, height: 650 }),\n    Object.freeze({ altitude: 3000, height: 1200 }),\n    Object.freeze({ altitude: 9500, height: 500 }),\n    null,\n]);\nexport const DEFAULT_CLOUD_TERRAIN_CLEARANCE = 200;\nconst CLOUD_LAYER_KEYS = ['low', 'mid', 'high', 'upper'];\n\n/** Actual rendered layer bounds, in metres from the planet centre. */\nexport function cloudLayerTopRadius(layers, bottomRadius) {\n    if (!layers || !Number.isFinite(bottomRadius) || bottomRadius <= 0) return null;\n    let top = null;\n    for (const layer of layers) {\n        if (!Number.isFinite(layer?.altitude) || !(layer.height > 0) || !Number.isFinite(layer.height)\n            || layer.densityScale === 0) continue;\n        top = Math.max(top ?? -Infinity, bottomRadius + layer.altitude + layer.height);\n    }\n    // An initialized but empty cloud deck cannot supply local precipitation.\n    return top ?? bottomRadius;\n}\n\n/** Lazy/cold-cloud equivalent, using the same terrain-relative settings as the renderer. */\nexport function configuredCloudTopRadius(layers, terrainRadius, clearance = DEFAULT_CLOUD_TERRAIN_CLEARANCE) {\n    if (!Number.isFinite(terrainRadius) || terrainRadius <= 0) return null;\n    let top = terrainRadius;\n    const gap = Number.isFinite(clearance) ? Math.max(0, clearance) : DEFAULT_CLOUD_TERRAIN_CLEARANCE;\n    for (let i = 0; i < CLOUD_LAYER_KEYS.length; i++) {\n        const layer = Array.isArray(layers) ? layers[i] : layers?.[CLOUD_LAYER_KEYS[i]];\n        const fallback = DEFAULT_LOCAL_CLOUD_LAYERS[i];\n        if ((!layer && !fallback) || layer?.densityScale === 0) continue;\n        const altitude = Number.isFinite(layer?.altitude) ? Math.max(0, layer.altitude) : fallback?.altitude;\n        const height = Number.isFinite(layer?.height) ? Math.max(100, layer.height) : fallback?.height;\n        if (Number.isFinite(altitude) && Number.isFinite(height)) top = Math.max(top, terrainRadius + gap + altitude + height);\n    }\n    return top;\n}\n\n/** Pure, allocation-free presentation contract. Never infer rain from cloud cover or a WMO code. */\nexport function deriveSceneWeatherState(data, { enabled = true, latitude, longitude, now = Date.now(),\n    maxAgeMs = 30 * 60_000, maxDistanceKm = 15 } = {}, out = {}) {\n    const current = data?.current;\n    out.available = false;\n    out.rainRateMmH = null;\n    out.snowWaterEquivalentMmH = null;\n    out.snowfallCmH = null;\n    out.precipitationPhase = null;\n    out.windSpeedMps = null;\n    out.windFromDegrees = null;\n    out.windGustMps = null;\n    out.weatherCode = Number.isFinite(current?.weather_code) ? current.weather_code : null;\n    out.observedAt = current?.time ?? null;\n    out.updatedAt = data?.lastUpdate ?? null;\n    out.latitude = data?.location?.lat ?? null;\n    out.longitude = data?.location?.lon ?? null;\n    out.status = !enabled ? 'disabled' : 'unavailable';\n    if (!enabled || !current) return out;\n    if (!Number.isFinite(data.lastUpdate) || now - data.lastUpdate > maxAgeMs || now < data.lastUpdate - 60_000) {\n        out.status = 'stale'; return out;\n    }\n    if (!Number.isFinite(latitude) || !Number.isFinite(longitude)\n        || !Number.isFinite(out.latitude) || !Number.isFinite(out.longitude)) {\n        out.status = 'location-unavailable'; return out;\n    }\n    const rad = Math.PI / 180;\n    const a = Math.sin((latitude - out.latitude) * rad / 2) ** 2\n        + Math.cos(latitude * rad) * Math.cos(out.latitude * rad)\n        * Math.sin((longitude - out.longitude) * rad / 2) ** 2;\n    if (12742 * Math.asin(Math.sqrt(Math.min(1, a))) > maxDistanceKm) {\n        out.status = 'outside-weather-scope'; return out;\n    }\n    out.available = true;\n    out.status = 'current';\n    const units = data.currentUnits || {};\n    const windUnit = units.wind_speed_10m;\n    const windScale = windUnit === 'm/s' ? 1 : windUnit === 'mp/h' || windUnit === 'mph' ? 0.44704\n        : windUnit === 'kn' ? 0.514444 : !windUnit || windUnit === 'km/h' ? 1 / 3.6 : null;\n    if (windScale !== null && finiteNonnegative(current.wind_speed_10m)) {\n        out.windSpeedMps = current.wind_speed_10m * windScale;\n    }\n    if ((!units.wind_direction_10m || units.wind_direction_10m === '°') && Number.isFinite(current.wind_direction_10m)) {\n        out.windFromDegrees = ((current.wind_direction_10m % 360) + 360) % 360;\n    }\n    const gustUnit = units.wind_gusts_10m;\n    const gustScale = !gustUnit || gustUnit === windUnit ? windScale : gustUnit === 'm/s' ? 1\n        : gustUnit === 'km/h' ? 1 / 3.6 : gustUnit === 'mp/h' || gustUnit === 'mph' ? 0.44704 : gustUnit === 'kn' ? 0.514444 : null;\n    if (gustScale !== null && finiteNonnegative(current.wind_gusts_10m)) out.windGustMps = current.wind_gusts_10m * gustScale;\n    // Current accumulation is over current.interval seconds, NOT necessarily an hour.\n    // The canonical backend currently supplies total precipitation + WMO phase.\n    const interval = current.interval;\n    if (!(Number.isFinite(interval) && interval > 0)) return out;\n    const amountScale = unit => !unit || unit === 'mm' ? 1 : unit === 'inch' ? 25.4 : null;\n    let amount = null;\n    if (finiteNonnegative(current.rain) && finiteNonnegative(current.showers)) {\n        const rainScale = amountScale(units.rain), showerScale = amountScale(units.showers);\n        if (rainScale !== null && showerScale !== null) amount = current.rain * rainScale + current.showers * showerScale;\n    } else if (finiteNonnegative(current.rain) && !SHOWER_CODES.has(out.weatherCode)) {\n        const scale = amountScale(units.rain);\n        if (scale !== null) amount = current.rain * scale;\n    } else if (SNOW_CODES.has(out.weatherCode)) amount = 0;\n    else if (LIQUID_CODES.has(out.weatherCode) && finiteNonnegative(current.precipitation)) {\n        const scale = amountScale(units.precipitation);\n        if (scale !== null) amount = current.precipitation * scale;\n    } else if (finiteNonnegative(current.rain)) {\n        const scale = amountScale(units.rain);\n        if (scale !== null) amount = current.rain * scale;\n    } else if (current.precipitation === 0) amount = 0;\n    out.rainRateMmH = amount === null ? null : amount * 3600 / interval;\n    // Total precipitation is liquid-water equivalent; snowfall is snow depth.\n    // Never silently impose a snow/water density ratio or infer an amount\n    // from a WMO code. Explicit liquid and solid fields may coexist.\n    const totalScale = amountScale(units.precipitation);\n    const total = finiteNonnegative(current.precipitation) && totalScale !== null\n        ? current.precipitation * totalScale * 3600 / interval : null;\n    if (SNOW_CODES.has(out.weatherCode) && total !== null) {\n        out.snowWaterEquivalentMmH = Math.max(0, total - (out.rainRateMmH || 0));\n    } else if (out.rainRateMmH !== null && total !== null && finiteNonnegative(current.snowfall)) {\n        out.snowWaterEquivalentMmH = Math.max(0, total - out.rainRateMmH);\n    } else if (total === 0 || (LIQUID_CODES.has(out.weatherCode) && !current.snowfall)) {\n        out.snowWaterEquivalentMmH = 0;\n    }\n    const snowScale = !units.snowfall || units.snowfall === 'cm' ? 1\n        : units.snowfall === 'inch' ? 2.54 : units.snowfall === 'mm' ? 0.1 : null;\n    if (finiteNonnegative(current.snowfall) && snowScale !== null) {\n        out.snowfallCmH = current.snowfall * snowScale * 3600 / interval;\n    }\n    const liquid = out.rainRateMmH > 0, solid = out.snowWaterEquivalentMmH > 0 || out.snowfallCmH > 0;\n    out.precipitationPhase = liquid && solid ? 'mixed' : solid ? 'snow' : liquid ? 'rain'\n        : total === 0 ? 'dry' : null;\n    return out;\n}\n\n/** East/up/south basis in the project's rotating TriTree ECEF frame. */\nexport function setWeatherBasis(latitude, longitude, planetQuaternion, east, up, south) {\n    const lat = latitude * Math.PI / 180;\n    const lon = longitude * Math.PI / 180 - EARTH_PRIME_MERIDIAN_OFFSET_RAD;\n    east.set(Math.cos(lon), 0, -Math.sin(lon));\n    up.set(Math.cos(lat) * Math.sin(lon), Math.sin(lat), Math.cos(lat) * Math.cos(lon));\n    south.crossVectors(east, up).normalize();\n    if (planetQuaternion) {\n        east.applyQuaternion(planetQuaternion);\n        up.applyQuaternion(planetQuaternion);\n        south.applyQuaternion(planetQuaternion);\n    }\n}\n\n/** WMO bearings describe where air comes FROM; rain travels in the opposite direction. */\nexport function weatherWindFrom(state, east, south, out) {\n    if (!Number.isFinite(state?.windSpeedMps) || !Number.isFinite(state?.windFromDegrees)) return out.set(0, 0, 0);\n    const bearing = state.windFromDegrees * Math.PI / 180;\n    return out.copy(east).multiplyScalar(Math.sin(bearing) * state.windSpeedMps)\n        .addScaledVector(south, -Math.cos(bearing) * state.windSpeedMps);\n}\n","import { Effect, BlendFunction } from 'postprocessing';\nimport { Uniform, Vector4 } from 'three';\n\n/** Scene-derived sensor styles in the existing final pass, without history targets. */\nexport class NightVisionEffect extends Effect {\n  constructor() {\n    super('NightVisionEffect', `\nuniform float visionEnabled;\nuniform float visionMode;\nuniform float visionGain;\nuniform float visionEdges;\nuniform float visionMotionOnly;\nuniform int visionTrackCount;\nuniform vec4 visionTracks[16];\nfloat visionLuma(vec3 color) { return dot(max(color, vec3(0.0)), vec3(0.2126, 0.7152, 0.0722)); }\nvoid mainImage(const in vec4 inputColor, const in vec2 uv, out vec4 outputColor) {\n  if (visionEnabled < 0.5) { outputColor = inputColor; return; }\n  // RGB has no infrared measurements. NIR-style weights red reflectance;\n  // FIR-style is a white/black-hot luminance proxy, never a temperature map.\n  float signal = visionMode < 0.5 ? dot(max(inputColor.rgb, vec3(0.0)), vec3(0.65, 0.30, 0.05)) : visionLuma(inputColor.rgb);\n  float gray = clamp(signal * visionGain, 0.0, 1.0);\n  if (visionMode > 1.5) gray = 1.0 - gray;\n  float mask = visionMotionOnly < 0.5 ? 1.0 : 0.0;\n  if (visionMotionOnly > 0.5 && visionEdges > 0.0) {\n    for (int i = 0; i < 16; i++) {\n      if (i >= visionTrackCount) break;\n      vec4 track = visionTracks[i];\n      mask = max(mask, 1.0 - smoothstep(0.75, 1.0, length((uv - track.xy) / track.zw)));\n    }\n  }\n  if (visionEdges > 0.0 && mask > 0.0) {\n    float l = visionLuma(texture2D(inputBuffer, uv - vec2(texelSize.x, 0.0)).rgb);\n    float r = visionLuma(texture2D(inputBuffer, uv + vec2(texelSize.x, 0.0)).rgb);\n    float b = visionLuma(texture2D(inputBuffer, uv - vec2(0.0, texelSize.y)).rgb);\n    float t = visionLuma(texture2D(inputBuffer, uv + vec2(0.0, texelSize.y)).rgb);\n    float edge = clamp(length(vec2(r-l, t-b)) / (0.08 + max(max(l,r),max(b,t))), 0.0, 1.0);\n    gray = mix(gray, visionMode > 1.5 ? 0.0 : 1.0, clamp(edge * visionEdges * mask, 0.0, 1.0));\n  }\n  outputColor = vec4(vec3(gray), inputColor.a);\n}`, { blendFunction: BlendFunction.NORMAL, uniforms: new Map([\n      ['visionEnabled', new Uniform(0)], ['visionMode', new Uniform(0)],\n      ['visionGain', new Uniform(1)], ['visionEdges', new Uniform(0)],\n      ['visionMotionOnly', new Uniform(1)], ['visionTrackCount', new Uniform(0)],\n      ['visionTracks', new Uniform(Array.from({ length: 16 }, () => new Vector4(0, 0, 1, 1)))],\n    ]) });\n  }\n  setState(enabled, settings = {}, tracks = []) {\n    const set = (key, value) => { this.uniforms.get(key).value = value; };\n    set('visionEnabled', enabled ? 1 : 0);\n    set('visionMode', settings.mode === 'fir-black' ? 2 : settings.mode === 'fir-white' ? 1 : 0);\n    set('visionGain', Math.min(4, Math.max(0.5, Number(settings.gain) || 1)));\n    set('visionEdges', Math.min(2, Math.max(0, Number(settings.edges) || 0)));\n    set('visionMotionOnly', settings.motionOnly === false ? 0 : 1);\n    set('visionTrackCount', Math.min(16, tracks.length));\n    const target = this.uniforms.get('visionTracks').value;\n    for (let i = 0; i < Math.min(16, tracks.length); i++) target[i].copy(tracks[i]);\n  }\n}\n","import { Effect, BlendFunction } from 'postprocessing';\nimport { Uniform, Matrix4, Vector3, Vector4 } from 'three';\n\n/** Actual source-amplitude pixels on the analytic WGS84 surface, after lighting. */\nexport class SarEffect extends Effect {\n  constructor() {\n    super('SarEffect', `\nuniform float sarEnabled, sarGlobalReady, sarDetailReady;\nuniform sampler2D sarGlobal, sarDetail;\nuniform vec4 sarBounds;\nuniform mat4 sarInverseProjection, sarViewToPlanet;\nvec4 sarSample(vec2 uv) {\n  vec4 value=sarGlobalReady>.5?texture2D(sarGlobal,uv):vec4(0.0);\n  vec2 local=uv; local.x+=floor(sarBounds.x+sarBounds.z*.5-local.x+.5);\n  local=(local-sarBounds.xy)/sarBounds.zw;\n  if(sarDetailReady>.5&&all(greaterThanEqual(local,vec2(0.0)))&&all(lessThan(local,vec2(1.0)))) {\n    vec4 detail=texture2D(sarDetail,local); if(detail.a>.99)value=detail;\n  }\n  return value;\n}\nvoid mainImage(const in vec4 inputColor,const in vec2 uv,out vec4 outputColor) {\n  outputColor=inputColor; if(sarEnabled<.5)return;\n  vec4 ray=sarInverseProjection*vec4(uv*2.0-1.0,-1.0,1.0);\n  vec3 origin=(sarViewToPlanet*vec4(0.0,0.0,0.0,1.0)).xyz;\n  vec3 direction=normalize((sarViewToPlanet*vec4(ray.xyz/ray.w,0.0)).xyz);\n  vec3 axes=vec3(6378137.0,6356752.314245,6378137.0);\n  vec3 o=origin/axes,d=direction/axes;\n  float a=dot(d,d),b=dot(o,d),c=dot(o,o)-1.0,disc=b*b-a*c;\n  if(disc<0.0)return;\n  float t=(-b-sqrt(disc))/a;if(t<=0.0)return;\n  vec3 p=origin+t*direction,normal=normalize(p/(axes*axes));\n  float longitude=fract(atan(p.x,p.z)/6.28318530718+.5);\n  float latitude=asin(clamp(normal.y,-1.0,1.0));\n  float s=clamp(normal.y,-.99627207622,.99627207622);\n  vec2 sourceUv=vec2(longitude,.5-log((1.0+s)/(1.0-s))/12.56637061436);\n  vec4 sampleValue=abs(latitude)<1.48442223?sarSample(sourceUv):vec4(0.0);\n  // Unobserved pixels retain the normal Earth context. These pixels are\n  // explicitly labelled as gaps, never invented or recoloured into fake SAR.\n  if(sampleValue.a<=.99)return;\n  float gray=sampleValue.r;\n  // The PNG stretch is display encoded; EffectPass applies output encoding.\n  float linearGray=gray<=.04045?gray/12.92:pow((gray+.055)/1.055,2.4);\n  outputColor=vec4(vec3(linearGray),inputColor.a);\n}`, {blendFunction:BlendFunction.NORMAL,uniforms:new Map([\n      ['sarEnabled',new Uniform(0)],['sarGlobalReady',new Uniform(0)],['sarDetailReady',new Uniform(0)],\n      ['sarGlobal',new Uniform(null)],['sarDetail',new Uniform(null)],['sarBounds',new Uniform(new Vector4(0,0,1,1))],\n      ['sarInverseProjection',new Uniform(new Matrix4())],['sarViewToPlanet',new Uniform(new Matrix4())],\n    ])});\n    this.inverse=new Matrix4(); this.position=new Vector3();\n  }\n  update(){if(this.state?.[0])this.setState(...this.state);}\n  setState(enabled,camera,planet,field){\n    this.state=[enabled,camera,planet,field];\n    const u=name=>this.uniforms.get(name);\n    u('sarEnabled').value=enabled?1:0;\n    if(!enabled||!camera||!planet)return;\n    camera.updateMatrixWorld();planet.updateWorldMatrix(true,false);\n    u('sarInverseProjection').value.copy(camera.projectionMatrixInverse);\n    u('sarViewToPlanet').value.multiplyMatrices(this.inverse.copy(planet.matrixWorld).invert(),camera.matrixWorld);\n    u('sarGlobal').value=field?.global;u('sarDetail').value=field?.detail;\n    u('sarGlobalReady').value=field?.global?1:0;u('sarDetailReady').value=field?.detail?1:0;\n    if(field?.bounds)u('sarBounds').value.copy(field.bounds);\n  }\n}\n","/**\n * GLSL shared by the lens passes: depth decoding, the thin-lens circle of\n * confusion and the autofocus read. Written GLSL1-style (texture2D); use\n * toGlsl3() for GLSL3 materials.\n */\nexport const SKY_DEPTH = 0.9999999;\nexport const FOCUS_MIN_M = 0.25;\nexport const FOCUS_MAX_M = 1.0e7;\n\n// View distance (metres along -z) from the composer depth buffer. Log depth\n// stores log2(1 + w) / log2(far + 1); decoding it directly keeps full\n// precision at planetary ranges, where re-projecting to perspective would not.\nexport const DEPTH_GLSL = `\nfloat lensDistance(const in vec2 uv) {\n#if DEPTH_PACKING == 3201\n  float d = unpackRGBAToDepth(texture2D(depthBuffer, uv));\n#else\n  float d = texture2D(depthBuffer, uv).r;\n#endif\n  if (d >= ${SKY_DEPTH}) return 1.0e9;\n#ifdef NCA_LENS_LOG_DEPTH\n  return exp2(d * log2(cameraFar + 1.0)) - 1.0;\n#else\n  return -perspectiveDepthToViewZ(d, cameraNear, cameraFar);\n#endif\n}`;\n\n/** Uniforms an Effect does not already provide (it owns depthBuffer/camera*). */\nexport const OPTICS_UNIFORMS_GLSL = `\nuniform sampler2D lensFocusBuffer;\nuniform float lensAperture;\nuniform float lensFocalLength;\nuniform float lensPixelFocal;\nuniform float lensMaxBlur;`;\n\n// Signed CoC RADIUS in full-resolution pixels: c(z) = A·P·(z − s)/(z·(s − f)) / 2.\nexport const OPTICS_GLSL = `\nfloat lensFocus() { return exp(texture2D(lensFocusBuffer, vec2(0.5)).r); }\nfloat lensCoc(const in float z, const in float s) {\n  float diameter = lensAperture * lensPixelFocal * (z - s) / (z * max(s - lensFocalLength, 1.0e-3));\n  return clamp(0.5 * diameter, -lensMaxBlur, lensMaxBlur);\n}`;\n\n/** Header for a standalone ShaderMaterial pass (not an Effect). */\nexport const PASS_HEADER_GLSL = `\n#include <packing>\nuniform highp sampler2D depthBuffer;\nuniform float cameraNear;\nuniform float cameraFar;\nuniform vec2 lensResolution;\n${OPTICS_UNIFORMS_GLSL}\n${DEPTH_GLSL}\n${OPTICS_GLSL}`;\n\nexport const PASS_VERTEX_GLSL = 'varying vec2 vUv; void main() { vUv = uv; gl_Position = vec4(position.xy, 0.0, 1.0); }';\nexport const PASS_VERTEX_GLSL3 = 'out vec2 vUv; void main() { vUv = uv; gl_Position = vec4(position.xy, 0.0, 1.0); }';\n\nexport const toGlsl3 = (source) => source.replaceAll('texture2D(', 'texture(');\n","/**\n * Thin-lens depth of field as an area integral (four passes plus a composite).\n *\n *  1. Layers: a 3×3-prefiltered, premultiplied HDR image is split by the sign\n *     of the CoC into a near (in front of focus) and a far (behind focus)\n *     layer, at half resolution and mipmapped. In-focus pixels stay out of\n *     both, so neither near objects nor a sharp subject leak into far blur.\n *  2. Disk gathers: each layer is integrated over its own aperture disk. Each\n *     sample reads the mip level that matches the spacing between samples,\n *     so a few dozen taps integrate area instead of stamping repeated copies\n *     (ghost contours), and the Vogel disk is rotated per pixel. Far samples\n *     use a soft depth weight, so a sharp occluder never bleeds backward;\n *     a behind-focus sample whose own disk reaches the pixel still spreads.\n *     The near gather takes the largest neighbouring foreground CoC that\n *     reaches the pixel, so foreground blur scatters past its silhouette.\n *  3. Composite: the sharp image yields to the far blur behind focus, and\n *     the premultiplied near blur covers it: near + back·(1 − near.a).\n *\n * Autofocus reads depth at the centre of the view on the GPU, averages\n * centre-weighted taps in log space and smooths them over time in a 1×1\n * ping-pong target, so there is no CPU readback.\n */\nimport { BlendFunction, Effect, EffectAttribute } from 'postprocessing';\nimport {\n  GLSL3, HalfFloatType, LinearFilter, LinearMipmapLinearFilter, Mesh, NearestFilter,\n  OrthographicCamera, PlaneGeometry, RGBAFormat, Scene, ShaderMaterial, Uniform, Vector2,\n  WebGLRenderTarget,\n} from 'three';\nimport { LENS_DEFAULTS } from './LensContract.js';\nimport {\n  DEPTH_GLSL, FOCUS_MAX_M, FOCUS_MIN_M, OPTICS_GLSL, OPTICS_UNIFORMS_GLSL, PASS_HEADER_GLSL,\n  PASS_VERTEX_GLSL, PASS_VERTEX_GLSL3, toGlsl3,\n} from './LensShaderChunks.js';\n\nconst MAX_SAMPLES = 64;\n\nconst COMPOSITE_FRAGMENT = `\n${OPTICS_UNIFORMS_GLSL}\nuniform sampler2D lensFarBlur;\nuniform sampler2D lensNearBlur;\n${DEPTH_GLSL}\n${OPTICS_GLSL}\nvoid mainImage(const in vec4 inputColor, const in vec2 uv, out vec4 outputColor) {\n  float c = lensCoc(lensDistance(uv), lensFocus());\n  vec4 far = texture2D(lensFarBlur, uv);\n  vec4 near = texture2D(lensNearBlur, uv);\n  // The sharp image keeps every detail at the focal plane and yields to\n  // depth-isolated defocus behind it.\n  vec3 back = mix(inputColor.rgb, far.rgb, smoothstep(0.8, 2.0, c) * smoothstep(0.01, 0.35, far.a));\n  // Foreground blur is a premultiplied translucent disk over the scene.\n  outputColor = vec4(near.rgb + back * (1.0 - near.a), inputColor.a);\n}`;\n\nconst LAYER_FRAGMENT = `\n${PASS_HEADER_GLSL}\nuniform sampler2D tColor;\nuniform int uLayer;\nvarying vec2 vUv;\nvoid main() {\n  // 3×3 area prefilter. Premultiplied RGB with coverage keeps a correct\n  // translucent silhouette for the foreground.\n  float s = lensFocus();\n  vec3 rgb = vec3(0.0);\n  float cov = 0.0;\n  vec2 px = 1.0 / lensResolution;\n  for (int y = -1; y <= 1; y++) for (int x = -1; x <= 1; x++) {\n    vec2 uv = clamp(vUv + vec2(float(x), float(y)) * px * 0.65, px * 0.5, 1.0 - px * 0.5);\n    float c = lensCoc(lensDistance(uv), s);\n    // In-focus pixels belong to neither layer: the composite keeps them sharp,\n    // and keeping them out of the far mips stops a sharp object haloing into\n    // the background blur behind it.\n    float a = uLayer == 1 ? smoothstep(0.75, 2.0, -c) : smoothstep(0.5, 1.0, c);\n    float w = (x == 0 && y == 0) ? 2.0 : 1.0;\n    rgb += texture2D(tColor, uv).rgb * a * w;\n    cov += a * w;\n  }\n  gl_FragColor = vec4(rgb / 10.0, cov / 10.0);\n}`;\n\nconst DISK_FRAGMENT = toGlsl3(`\nprecision highp float;\n${PASS_HEADER_GLSL}\nuniform sampler2D uLayerTexture;\nuniform vec2 uHalfResolution;\nuniform int uSamples;\nuniform int uIsNear;\nin vec2 vUv;\nout vec4 fragColor;\nconst float GOLDEN_ANGLE = 2.399963229728653;\nconst float TWO_PI = 6.283185307179586;\nfloat cocAt(vec2 p, float s) { return lensCoc(lensDistance(clamp(p, vec2(0.0), vec2(1.0))), s); }\nvoid main() {\n  vec2 halfTexel = 1.0 / uHalfResolution;\n  float s = lensFocus();\n  float c0 = cocAt(vUv, s);\n  float z0 = lensDistance(vUv);\n  float radius;\n  if (uIsNear == 0) {\n    radius = max(c0, 0.0) * 0.5;\n    if (radius < 0.5) { fragColor = vec4(0.0); return; }\n  } else {\n    // Foreground blur must scatter outside its sharp silhouette: take the\n    // largest neighbouring foreground CoC whose disk reaches this pixel.\n    radius = max(-c0 * 0.5, 0.0);\n    float search = lensMaxBlur * 0.5;\n    for (int i = 0; i < 32; i++) {\n      float a = float(i % 8) * TWO_PI / 8.0 + float(i / 8) * 0.3926991;\n      float r = search * (0.125 + float(i / 8) * 0.25);\n      float nr = max(-cocAt(vUv + vec2(cos(a), sin(a)) * r * halfTexel, s) * 0.5, 0.0);\n      if (nr >= r - 0.75) radius = max(radius, nr);\n    }\n    if (radius < 0.45) { fragColor = vec4(0.0); return; }\n  }\n  radius = min(radius, lensMaxBlur * 0.5);\n  // Mip level ≈ spacing between disk samples: each tap integrates its area.\n  float spacing = radius * sqrt(3.14159265 / float(uSamples));\n  float lod = clamp(log2(max(1.0, spacing * 1.65)), 0.0, 5.0);\n  float rotation = fract(sin(dot(floor(gl_FragCoord.xy), vec2(12.9898, 78.233))) * 43758.5453) * TWO_PI;\n  vec3 accumulated = vec3(0.0);\n  float alphaSum = 0.0;\n  float weightSum = 0.0;\n  for (int i = 0; i < ${MAX_SAMPLES}; i++) {\n    if (i >= uSamples) break;\n    float q = (float(i) + 0.5) / float(uSamples);\n    float a = float(i) * GOLDEN_ANGLE + rotation;\n    vec2 delta = sqrt(q) * radius * vec2(cos(a), sin(a));\n    vec2 uv = clamp(vUv + delta * halfTexel, halfTexel * 0.5, 1.0 - halfTexel * 0.5);\n    vec4 sampleColor = textureLod(uLayerTexture, uv, lod);\n    float c = cocAt(uv, s);\n    float weight;\n    if (uIsNear == 1) {\n      // Solid foreground integrates to full coverage; only its rim feathers.\n      float sourceRadius = max(-c * 0.5, 0.0);\n      weight = (1.0 - smoothstep(sourceRadius - 0.6, sourceRadius + 0.6, length(delta))) * smoothstep(0.6, 1.8, -c);\n    } else {\n      // Reject nearer occluders and keep same-depth continuity; a nearer\n      // behind-focus sample whose own disk reaches here still contributes.\n      float sz = lensDistance(uv);\n      weight = clamp(1.0 + (sz - z0) / max(z0 * 0.08, 0.1), 0.0, 1.0);\n      if (c * 0.5 + 0.5 >= length(delta)) weight = 1.0;\n      weightSum += weight;\n    }\n    accumulated += sampleColor.rgb * weight;\n    alphaSum += sampleColor.a * weight;\n  }\n  if (uIsNear == 1) {\n    float inv = 1.0 / float(uSamples);\n    fragColor = vec4(accumulated * inv, clamp(alphaSum * inv, 0.0, 1.0));\n  } else {\n    // Normalize by valid coverage to avoid dark rims at foreground edges.\n    fragColor = vec4(accumulated / max(alphaSum, 1.0e-4), clamp(alphaSum / max(weightSum, 1.0e-4), 0.0, 1.0));\n  }\n}`);\n\nconst FOCUS_FRAGMENT = `\n#include <packing>\nuniform highp sampler2D depthBuffer;\nuniform sampler2D previousFocus;\nuniform float cameraNear, cameraFar, cameraAspect, blend, initialized, manualFocus, tapRadius;\n${DEPTH_GLSL}\nvoid main() {\n  float acc = 0.0, weight = 0.0;\n  for (int i = 0; i < 13; i++) {\n    float ring = i == 0 ? 0.0 : (i < 7 ? 1.0 : 2.0);\n    float a = float(i) * 1.0471976 + (i < 7 ? 0.0 : 0.5235988);\n    vec2 uv = vec2(0.5) + vec2(cos(a), sin(a)) * ring * tapRadius * vec2(1.0, cameraAspect);\n    float z = lensDistance(uv);\n    if (z >= 1.0e9) continue;\n    float w = i == 0 ? 3.0 : (i < 7 ? 0.5 : 0.1);\n    acc += w * log(clamp(z, ${FOCUS_MIN_M.toFixed(2)}, ${FOCUS_MAX_M.toExponential(1)}));\n    weight += w;\n  }\n  float target = weight > 0.0 ? acc / weight : log(${FOCUS_MAX_M.toExponential(1)});\n  if (manualFocus > 0.0) target = log(manualFocus);\n  float previous = texture2D(previousFocus, vec2(0.5)).r;\n  gl_FragColor = vec4(initialized > 0.5 ? mix(previous, target, blend) : target, 0.0, 0.0, 1.0);\n}`;\n\nconst target = (options) => new WebGLRenderTarget(1, 1, {\n  type: HalfFloatType, format: RGBAFormat, depthBuffer: false, stencilBuffer: false, ...options,\n});\n\nexport class LensDepthOfFieldEffect extends Effect {\n  constructor(camera) {\n    super('LensDepthOfFieldEffect', COMPOSITE_FRAGMENT, {\n      blendFunction: BlendFunction.NORMAL,\n      attributes: EffectAttribute.DEPTH,\n      uniforms: new Map([\n        ['lensFocusBuffer', new Uniform(null)],\n        ['lensAperture', new Uniform(0.1 / 1.4)],\n        ['lensFocalLength', new Uniform(0.1)],\n        ['lensPixelFocal', new Uniform(1000)],\n        ['lensMaxBlur', new Uniform(32)],\n        ['lensFarBlur', new Uniform(null)],\n        ['lensNearBlur', new Uniform(null)],\n      ]),\n    });\n    this.camera = camera;\n    this._width = 1;\n    this._height = 1;\n    this._settings = { ...LENS_DEFAULTS.depthOfField };\n\n    const nearest = { minFilter: NearestFilter, magFilter: NearestFilter, generateMipmaps: false };\n    this._focusTargets = [target(nearest), target(nearest)];\n    this._focusIndex = 0;\n    this._focusInitialized = false;\n    const layer = { minFilter: LinearMipmapLinearFilter, magFilter: LinearFilter, generateMipmaps: true };\n    const blur = { minFilter: LinearFilter, magFilter: LinearFilter, generateMipmaps: false };\n    this._layers = { near: target(layer), far: target(layer) };\n    this._blurs = { near: target(blur), far: target(blur) };\n    this.uniforms.get('lensFarBlur').value = this._blurs.far.texture;\n    this.uniforms.get('lensNearBlur').value = this._blurs.near.texture;\n\n    // Uniform objects shared by every internal pass.\n    const u = (name) => this.uniforms.get(name);\n    this._shared = {\n      depthBuffer: { value: null },\n      cameraNear: { value: 0.1 },\n      cameraFar: { value: 1000 },\n      lensResolution: { value: new Vector2(1, 1) },\n      lensFocusBuffer: u('lensFocusBuffer'),\n      lensAperture: u('lensAperture'),\n      lensFocalLength: u('lensFocalLength'),\n      lensPixelFocal: u('lensPixelFocal'),\n      lensMaxBlur: u('lensMaxBlur'),\n    };\n    const defines = () => ({ DEPTH_PACKING: '3200' });\n    const s = this._shared;\n    this._focusMaterial = new ShaderMaterial({\n      vertexShader: PASS_VERTEX_GLSL, fragmentShader: FOCUS_FRAGMENT, defines: defines(),\n      uniforms: {\n        depthBuffer: s.depthBuffer, cameraNear: s.cameraNear, cameraFar: s.cameraFar,\n        previousFocus: { value: this._focusTargets[1].texture }, cameraAspect: { value: 1 },\n        blend: { value: 1 }, initialized: { value: 0 }, manualFocus: { value: 0 }, tapRadius: { value: 0.012 },\n      },\n      depthTest: false, depthWrite: false,\n    });\n    this._layerMaterial = new ShaderMaterial({\n      vertexShader: PASS_VERTEX_GLSL, fragmentShader: LAYER_FRAGMENT, defines: defines(),\n      uniforms: { ...s, tColor: { value: null }, uLayer: { value: 0 } },\n      depthTest: false, depthWrite: false,\n    });\n    this._diskMaterial = new ShaderMaterial({\n      glslVersion: GLSL3, vertexShader: PASS_VERTEX_GLSL3, fragmentShader: DISK_FRAGMENT, defines: defines(),\n      uniforms: {\n        ...s, uLayerTexture: { value: null }, uHalfResolution: { value: new Vector2(1, 1) },\n        uSamples: { value: 40 }, uIsNear: { value: 0 },\n      },\n      depthTest: false, depthWrite: false,\n    });\n    this._materials = [this._focusMaterial, this._layerMaterial, this._diskMaterial];\n    this._passScene = new Scene();\n    this._passCamera = new OrthographicCamera(-1, 1, 1, -1, 0, 1);\n    this._quad = new Mesh(new PlaneGeometry(2, 2), this._focusMaterial);\n    this._quad.frustumCulled = false;\n    this._passScene.add(this._quad);\n    u('lensFocusBuffer').value = this._focusTargets[0].texture;\n  }\n\n  _setPassDefine(name, value) {\n    for (const material of this._materials) {\n      if (value === null) delete material.defines[name];\n      else material.defines[name] = value;\n      material.needsUpdate = true;\n    }\n  }\n\n  initialize(renderer, alpha, frameBufferType) {\n    super.initialize?.(renderer, alpha, frameBufferType);\n    const log = renderer?.capabilities?.logarithmicDepthBuffer === true;\n    if (log) this.defines.set('NCA_LENS_LOG_DEPTH', '1');\n    else this.defines.delete('NCA_LENS_LOG_DEPTH');\n    this._setPassDefine('NCA_LENS_LOG_DEPTH', log ? '1' : null);\n  }\n\n  setDepthTexture(depthTexture, depthPacking) {\n    super.setDepthTexture?.(depthTexture, depthPacking);\n    this._shared.depthBuffer.value = depthTexture || null;\n    this._setPassDefine('DEPTH_PACKING', String(depthPacking ?? 3200));\n  }\n\n  setSize(width, height) {\n    super.setSize?.(width, height);\n    this._width = Math.max(1, width);\n    this._height = Math.max(1, height);\n    const hw = Math.max(2, Math.ceil(this._width / 2));\n    const hh = Math.max(2, Math.ceil(this._height / 2));\n    for (const rt of [this._layers.near, this._layers.far, this._blurs.near, this._blurs.far]) rt.setSize(hw, hh);\n    this._shared.lensResolution.value.set(this._width, this._height);\n    this._diskMaterial.uniforms.uHalfResolution.value.set(hw, hh);\n  }\n\n  setSettings(settings) {\n    this._settings = { ...settings };\n    const f = settings.focalLength / 1000;\n    this.uniforms.get('lensFocalLength').value = f;\n    this.uniforms.get('lensAperture').value = f / settings.fStop;\n    this.uniforms.get('lensMaxBlur').value = settings.maxBlur;\n    this._diskMaterial.uniforms.uSamples.value = settings.samples;\n  }\n\n  /** Next enable starts from the current view rather than a stale focus. */\n  resetFocus() {\n    this._focusInitialized = false;\n  }\n\n  _draw(renderer, material, renderTarget) {\n    this._quad.material = material;\n    renderer.setRenderTarget(renderTarget);\n    renderer.render(this._passScene, this._passCamera);\n  }\n\n  update(renderer, inputBuffer, deltaTime = 0) {\n    const camera = this.camera;\n    if (camera?.projectionMatrix) {\n      this.uniforms.get('lensPixelFocal').value = camera.projectionMatrix.elements[0] * this._width * 0.5;\n    }\n    if (!this._shared.depthBuffer.value || !renderer) return;\n    this._shared.cameraNear.value = camera?.near ?? 0.1;\n    this._shared.cameraFar.value = camera?.far ?? 1000;\n\n    const f = this._focusMaterial.uniforms;\n    f.cameraAspect.value = Number.isFinite(camera?.aspect) && camera.aspect > 0 ? camera.aspect : 1;\n    const dt = Math.min(0.25, Math.max(0, Number(deltaTime) || 0));\n    f.blend.value = 1 - Math.exp(-dt * this._settings.focusResponse);\n    f.initialized.value = this._focusInitialized ? 1 : 0;\n    f.manualFocus.value = this._settings.autofocus ? 0 : this._settings.focusDistance;\n    const write = this._focusTargets[this._focusIndex ^ 1];\n    f.previousFocus.value = this._focusTargets[this._focusIndex].texture;\n\n    const previousTarget = renderer.getRenderTarget();\n    this._draw(renderer, this._focusMaterial, write);\n    this._focusIndex ^= 1;\n    this._focusInitialized = true;\n    this.uniforms.get('lensFocusBuffer').value = write.texture;\n\n    if (inputBuffer?.texture) {\n      const layer = this._layerMaterial.uniforms;\n      layer.tColor.value = inputBuffer.texture;\n      layer.uLayer.value = 0;\n      this._draw(renderer, this._layerMaterial, this._layers.far);\n      layer.uLayer.value = 1;\n      this._draw(renderer, this._layerMaterial, this._layers.near);\n      const disk = this._diskMaterial.uniforms;\n      disk.uIsNear.value = 0;\n      disk.uLayerTexture.value = this._layers.far.texture;\n      this._draw(renderer, this._diskMaterial, this._blurs.far);\n      disk.uIsNear.value = 1;\n      disk.uLayerTexture.value = this._layers.near.texture;\n      this._draw(renderer, this._diskMaterial, this._blurs.near);\n    }\n    renderer.setRenderTarget(previousTarget);\n  }\n\n  dispose() {\n    super.dispose?.();\n    for (const rt of [...this._focusTargets, this._layers.near, this._layers.far, this._blurs.near, this._blurs.far]) rt.dispose();\n    for (const material of this._materials) material.dispose();\n    this._quad.geometry.dispose();\n  }\n}\n","/**\n * Natural sensor grain for the final image (scene.lens.filmGrain).\n *\n * Statistics follow a photon-counting sensor: per pixel the signal in\n * electrons N = Y · E (E = electrons per unit linear signal, calibrated so\n * 18 % grey holds `signal18` electrons) has variance σ² = N + read², so\n * grain is relatively strongest in the shadows and fades in highlights.\n * Most fine grain is shared between channels (demosaic / luma processing,\n * correlation 0.82); the remainder is per channel. Low-frequency chroma\n * mottling (3–5 px, interpolated) appears chiefly in dark areas. Noise is\n * anchored to screen pixels and re-drawn at 24 Hz, like a video sensor.\n *\n * It runs in the final pass after tone mapping and SMAA, on display-linear\n * values, and stays compiled when off: toggling flips a uniform and never\n * rebuilds the pass.\n */\nimport { BlendFunction, Effect } from 'postprocessing';\nimport { Uniform } from 'three';\nimport { LENS_DEFAULTS } from './LensContract.js';\n\nexport const FILM_GRAIN_SENSOR = Object.freeze({\n  signal18: 550, // electrons at 18 % grey\n  readNoise: 4.5, // electrons RMS\n  frameHz: 24,\n});\n\nconst FRAGMENT = /* glsl */`\nuniform float grainEnabled, grainStrength, grainChroma, grainSignal18, grainReadNoise, grainFrame;\n\nfloat grainHash(vec2 p) {\n  vec3 q = fract(vec3(p.xyx) * 0.1031);\n  q += dot(q, q.yzx + 33.33);\n  return fract((q.x + q.y) * q.z);\n}\n// Box–Muller: one unit Gaussian sample per seed.\nfloat grainGauss(vec2 p) {\n  float a = max(grainHash(p), 1.0e-6);\n  float b = grainHash(p + vec2(47.321, 123.741));\n  return sqrt(-2.0 * log(a)) * cos(6.28318530718 * b);\n}\n// Interpolated value noise in [-1, 1]; seed animates values, not positions.\nfloat grainValue(vec2 p, float seed) {\n  vec2 i = floor(p), f = fract(p);\n  f = f * f * (3.0 - 2.0 * f);\n  i += vec2(seed * 41.73, seed * 93.47);\n  float a = grainHash(i), b = grainHash(i + vec2(1.0, 0.0));\n  float c = grainHash(i + vec2(0.0, 1.0)), d = grainHash(i + vec2(1.0, 1.0));\n  return 2.0 * mix(mix(a, b, f.x), mix(c, d, f.x), f.y) - 1.0;\n}\n\nvoid mainImage(const in vec4 inputColor, const in vec2 uv, out vec4 outputColor) {\n  outputColor = inputColor;\n  if (grainEnabled < 0.5 || grainStrength <= 0.0) return;\n  vec3 rgb = max(inputColor.rgb, vec3(0.0));\n  vec2 pixel = floor(gl_FragCoord.xy);\n  vec2 seed = vec2(grainFrame * 3.11, grainFrame * 7.39);\n  // Shot + read noise in electrons.\n  float electronsPerUnit = grainSignal18 / 0.18;\n  vec3 photons = rgb * electronsPerUnit;\n  vec3 sigma = sqrt(photons + vec3(grainReadNoise * grainReadNoise));\n  float shared = grainGauss(pixel + seed + vec2(11.3, 43.7));\n  vec3 z = vec3(\n    0.82 * shared + 0.572 * grainGauss(pixel + seed + vec2(91.1, 83.1)),\n    0.82 * shared + 0.572 * grainGauss(pixel + seed + vec2(169.9, 173.7)),\n    0.82 * shared + 0.572 * grainGauss(pixel + seed + vec2(283.7, 41.3)));\n  rgb = max(rgb + sigma * z * grainStrength / electronsPerUnit, vec3(0.0));\n  // Chroma mottling, strongest in shadows (display-referred amplitude).\n  if (grainChroma > 0.0) {\n    vec3 display = pow(rgb, vec3(1.0 / 2.2));\n    float luma = dot(display, vec3(0.2126, 0.7152, 0.0722));\n    float shadow = 1.0 - smoothstep(0.045, 0.52, luma);\n    float amp = (0.007 + 0.5 / sqrt(max(grainSignal18, 80.0))) * grainStrength * grainChroma * (0.08 + 0.92 * shadow);\n    vec2 p = gl_FragCoord.xy;\n    float a = grainValue(p / 3.2 + vec2(73.6, 17.3), grainFrame + 11.0);\n    float b = grainValue(p / 4.8 + vec2(21.8, 119.4), grainFrame + 101.0);\n    float fixedPattern = grainValue(p / 5.1 + vec2(211.4, 39.7), -73.2) * 0.1;\n    a += fixedPattern; b -= fixedPattern * 0.6;\n    display += vec3(0.8 * a + 0.12 * b, -0.42 * a - 0.29 * b, 0.81 * b - 0.14 * a) * amp;\n    rgb = pow(max(display, vec3(0.0)), vec3(2.2));\n  }\n  outputColor = vec4(rgb, inputColor.a);\n}`;\n\nexport class FilmGrainEffect extends Effect {\n  constructor() {\n    const d = LENS_DEFAULTS.filmGrain;\n    super('FilmGrainEffect', FRAGMENT, {\n      blendFunction: BlendFunction.NORMAL,\n      uniforms: new Map([\n        ['grainEnabled', new Uniform(d.enabled ? 1 : 0)],\n        ['grainStrength', new Uniform(d.strength)],\n        ['grainChroma', new Uniform(d.chroma)],\n        ['grainSignal18', new Uniform(FILM_GRAIN_SENSOR.signal18)],\n        ['grainReadNoise', new Uniform(FILM_GRAIN_SENSOR.readNoise)],\n        ['grainFrame', new Uniform(0)],\n      ]),\n    });\n    this._clockMs = 0;\n  }\n\n  setSettings({ enabled, strength, chroma } = {}) {\n    this.uniforms.get('grainEnabled').value = enabled ? 1 : 0;\n    if (Number.isFinite(strength)) this.uniforms.get('grainStrength').value = strength;\n    if (Number.isFinite(chroma)) this.uniforms.get('grainChroma').value = chroma;\n  }\n\n  update(_renderer, _inputBuffer, deltaTime = 0) {\n    if (this.uniforms.get('grainEnabled').value < 0.5) return;\n    this._clockMs += Math.max(0, Number(deltaTime) || 0) * 1000;\n    // A new noise realisation at the sensor frame rate (24 Hz).\n    this.uniforms.get('grainFrame').value = Math.floor(this._clockMs * FILM_GRAIN_SENSOR.frameHz / 1000) % 4096;\n  }\n}\n","/**\n * Final colour grade in the three.js compositor (scene.lens.colorGrade),\n * replacing a CSS `filter: contrast() brightness() saturate()` on the canvas.\n *\n * It reproduces the CSS Filter Effects functions exactly, in that order, on\n * sRGB-encoded values (CSS filters act on the encoded image):\n *   contrast(k):   c' = (c − 0.5)·k + 0.5\n *   brightness(b): c' = c·b\n *   saturate(s):   the spec's 3×3 matrix built on 0.2126/0.7152/0.0722\n * Values are clamped to [0, 1] after each step, as the CSS pipeline does.\n *\n * It runs in the final pass after tone mapping (display-linear input),\n * encodes to sRGB, grades, and decodes back so the pass's own output\n * encoding is unchanged.\n */\nimport { BlendFunction, Effect } from 'postprocessing';\nimport { Uniform } from 'three';\nimport { LENS_DEFAULTS } from './LensContract.js';\n\nconst FRAGMENT = /* glsl */`\nuniform float gradeEnabled, gradeContrast, gradeBrightness, gradeSaturation;\n\nvec3 gradeToSrgb(vec3 c) {\n  c = clamp(c, 0.0, 1.0);\n  return mix(c * 12.92, 1.055 * pow(c, vec3(1.0 / 2.4)) - 0.055, step(vec3(0.0031308), c));\n}\nvec3 gradeToLinear(vec3 c) {\n  return mix(c / 12.92, pow((c + 0.055) / 1.055, vec3(2.4)), step(vec3(0.04045), c));\n}\n\nvoid mainImage(const in vec4 inputColor, const in vec2 uv, out vec4 outputColor) {\n  outputColor = inputColor;\n  if (gradeEnabled < 0.5) return;\n  vec3 c = gradeToSrgb(inputColor.rgb);\n  c = clamp((c - 0.5) * gradeContrast + 0.5, 0.0, 1.0);\n  c = clamp(c * gradeBrightness, 0.0, 1.0);\n  float s = gradeSaturation;\n  mat3 saturate = mat3(\n    0.2126 + 0.7874 * s, 0.2126 - 0.2126 * s, 0.2126 - 0.2126 * s,\n    0.7152 - 0.7152 * s, 0.7152 + 0.2848 * s, 0.7152 - 0.7152 * s,\n    0.0722 - 0.0722 * s, 0.0722 - 0.0722 * s, 0.0722 + 0.9278 * s);\n  c = clamp(saturate * c, 0.0, 1.0);\n  outputColor = vec4(gradeToLinear(c), inputColor.a);\n}`;\n\n/** CPU mirror of the shader for one sRGB-encoded colour (tests, tooling). */\nexport function gradeSrgb([r, g, b], { contrast = 1, brightness = 1, saturation = 1 } = {}) {\n  const clamp = (v) => Math.min(1, Math.max(0, v));\n  let c = [r, g, b].map((v) => clamp(clamp((v - 0.5) * contrast + 0.5) * brightness));\n  const s = saturation;\n  c = [\n    (0.2126 + 0.7874 * s) * c[0] + (0.7152 - 0.7152 * s) * c[1] + (0.0722 - 0.0722 * s) * c[2],\n    (0.2126 - 0.2126 * s) * c[0] + (0.7152 + 0.2848 * s) * c[1] + (0.0722 - 0.0722 * s) * c[2],\n    (0.2126 - 0.2126 * s) * c[0] + (0.7152 - 0.7152 * s) * c[1] + (0.0722 + 0.9278 * s) * c[2],\n  ];\n  return c.map(clamp);\n}\n\nexport class ColorGradeEffect extends Effect {\n  constructor() {\n    const d = LENS_DEFAULTS.colorGrade;\n    super('ColorGradeEffect', FRAGMENT, {\n      blendFunction: BlendFunction.NORMAL,\n      uniforms: new Map([\n        ['gradeEnabled', new Uniform(d.enabled ? 1 : 0)],\n        ['gradeContrast', new Uniform(d.contrast)],\n        ['gradeBrightness', new Uniform(d.brightness)],\n        ['gradeSaturation', new Uniform(d.saturation)],\n      ]),\n    });\n  }\n\n  setSettings({ enabled, contrast, brightness, saturation } = {}) {\n    this.uniforms.get('gradeEnabled').value = enabled ? 1 : 0;\n    if (Number.isFinite(contrast)) this.uniforms.get('gradeContrast').value = contrast;\n    if (Number.isFinite(brightness)) this.uniforms.get('gradeBrightness').value = brightness;\n    if (Number.isFinite(saturation)) this.uniforms.get('gradeSaturation').value = saturation;\n  }\n}\n","/**\n * Physical camera-lens modifiers for the atmosphere compositor.\n *\n * Depth of field (LensDepthOfField.js) is a thin-lens area integral on the\n * real logarithmic depth buffer, with GPU centre-of-view autofocus.\n *\n * Chromatic aberration is radial lateral colour (transverse colour). Lens\n * magnification depends on wavelength, so red and blue are misregistered\n * along the radius from the optical axis. Green stays fixed, red and blue\n * shift unequally (0.85 and 1.15), and the fringe follows\n * smoothstep(0.15, 0.9, r)·r³: zero near the centre, strongest at the corners.\n * Both effects run on the HDR image before bloom and tone mapping.\n */\nimport { BlendFunction, Effect, EffectAttribute, EffectPass } from 'postprocessing';\nimport { Uniform } from 'three';\nimport { LENS_DEFAULTS, normalizeLensConfig } from './LensContract.js';\nimport { LensDepthOfFieldEffect } from './LensDepthOfField.js';\nimport { FilmGrainEffect } from './FilmGrainEffect.js';\nimport { ColorGradeEffect } from './ColorGradeEffect.js';\n\nexport { LENS_DEFAULTS, LENS_LIMITS, normalizeLensConfig, thinLensCocPixels } from './LensContract.js';\nexport { LensDepthOfFieldEffect } from './LensDepthOfField.js';\n\nconst CA_FRAGMENT = `\nuniform float lensDispersion;\nvoid mainImage(const in vec4 inputColor, const in vec2 uv, out vec4 outputColor) {\n  vec2 fromAxis = (uv - 0.5) * resolution;\n  float len = length(fromAxis);\n  float field = clamp(len / (0.5 * length(resolution)), 0.0, 1.0);\n  vec2 radial = fromAxis / max(len, 1.0e-5);\n  // Edge-weighted profile: no fringe near the axis and no hard boundary.\n  float fieldColor = smoothstep(0.15, 0.9, field) * field * field * field;\n  // Strength is authored in pixels at 1080 lines and scales with resolution.\n  float fringe = lensDispersion * (resolution.y / 1080.0) * fieldColor;\n  vec2 redUv = clamp(uv + radial * (fringe * 0.85) * texelSize, vec2(0.0), vec2(1.0));\n  vec2 blueUv = clamp(uv - radial * (fringe * 1.15) * texelSize, vec2(0.0), vec2(1.0));\n  outputColor = vec4(texture2D(inputBuffer, redUv).r, inputColor.g, texture2D(inputBuffer, blueUv).b, inputColor.a);\n}`;\n\n/** Radial lateral chromatic aberration (zero on the optical axis). */\nexport class LensChromaticAberrationEffect extends Effect {\n  constructor() {\n    super('LensChromaticAberrationEffect', CA_FRAGMENT, {\n      blendFunction: BlendFunction.NORMAL,\n      attributes: EffectAttribute.CONVOLUTION,\n      uniforms: new Map([['lensDispersion', new Uniform(LENS_DEFAULTS.chromaticAberration.strength)]]),\n    });\n  }\n\n  setStrength(strength) {\n    this.uniforms.get('lensDispersion').value = strength;\n  }\n}\n\n/**\n * Owns the DOF and CA passes inside an EffectComposer. Both are separate\n * passes because the pmndrs EffectPass cannot merge two convolution effects.\n * A disabled modifier costs nothing: its pass is skipped by the composer.\n */\nexport class LensEffectsStage {\n  constructor({ camera }) {\n    this.camera = camera;\n    this.config = normalizeLensConfig();\n    this.dof = new LensDepthOfFieldEffect(camera);\n    this.ca = new LensChromaticAberrationEffect();\n    // Grain lives in the compositor's final pass (after tone mapping); the\n    // stage owns its settings so all lens modifiers share one config path.\n    this.grain = new FilmGrainEffect();\n    this.grade = new ColorGradeEffect();\n    this.dofPass = new EffectPass(camera, this.dof);\n    this.caPass = new EffectPass(camera, this.ca);\n    this.composer = null;\n    this.suspended = false;\n    this.applyConfig(this.config);\n  }\n\n  /** Insert both passes immediately before `beforePass` (HDR, pre-tone-map). */\n  attach(composer, beforePass = null) {\n    if (!composer || this.composer === composer) return;\n    this.detach();\n    const index = beforePass ? composer.passes.indexOf(beforePass) : -1;\n    if (index >= 0) {\n      composer.addPass(this.caPass, index);\n      composer.addPass(this.dofPass, index);\n    } else {\n      composer.addPass(this.dofPass);\n      composer.addPass(this.caPass);\n    }\n    this.composer = composer;\n    this._syncEnabled();\n  }\n\n  detach() {\n    if (!this.composer) return;\n    this.composer.removePass(this.dofPass);\n    this.composer.removePass(this.caPass);\n    this.composer = null;\n  }\n\n  applyConfig(patch = {}) {\n    const wasDof = this.config.depthOfField.enabled;\n    this.config = normalizeLensConfig(patch, this.config);\n    this.dof.setSettings(this.config.depthOfField);\n    this.ca.setStrength(this.config.chromaticAberration.strength);\n    this._syncGrain();\n    if (this.config.depthOfField.enabled && !wasDof) this.dof.resetFocus();\n    this._syncEnabled();\n    return this.config;\n  }\n\n  /** XR and other presentation modes that must not receive screen-space optics. */\n  setSuspended(suspended) {\n    this.suspended = suspended === true;\n    this._syncEnabled();\n    this._syncGrain();\n  }\n\n  _syncGrain() {\n    const grain = this.config.filmGrain;\n    this.grain.setSettings({ ...grain, enabled: !this.suspended && grain.enabled });\n    this.grade.setSettings(this.config.colorGrade);\n  }\n\n  _syncEnabled() {\n    const { depthOfField, chromaticAberration } = this.config;\n    this.dofPass.enabled = !this.suspended && depthOfField.enabled;\n    this.caPass.enabled = !this.suspended && chromaticAberration.enabled && chromaticAberration.strength > 0;\n  }\n\n  dispose() {\n    this.detach();\n    this.dofPass.dispose?.();\n    this.caPass.dispose?.();\n    this.dof.dispose();\n    this.ca.dispose?.();\n    this.grain.dispose?.();\n    this.grade.dispose?.();\n  }\n}\n","import { DataTexture, DataArrayTexture, RGBAFormat, UnsignedByteType, NearestFilter, NoColorSpace, Uniform, Vector2, Vector3, Vector4, Matrix4 } from 'three';\nimport { CLOUD_GUIDE_GLSL } from './CloudDepthReconstruction.js';\n\n/** Keep native aerial shader structure stable while cloud attachments change.\n * Takram toggles HAS_OVERLAY/HAS_SHADOW/HAS_SHADOW_LENGTH from nullness during\n * update(); each change recompiles every cached EffectPass on a render frame.\n * Neutral, typed attachments plus uniform gates preserve exact enabled optics\n * without compiling cloud on/off states or sampling shadow maps while off.\n */\nexport class CloudAtmosphereAttachments {\n  constructor(effect, cascadeCount = 3, clouds = null) {\n    this.effect=effect; this.enabled=false;\n    this.flags=new Uniform(new Vector3()); effect.uniforms.set('ncaCloudAttachments',this.flags);\n    effect.uniforms.set('ncaCloudOverlayDeferred',new Uniform(0));\n    effect.uniforms.set('ncaCloudGuideLimit', clouds?.cloudsPass?.currentMaterial?.uniforms.maxRayDistance || new Uniform(200000));\n    this.overlayRegion=new Uniform(new Vector4(1,1,0,0));effect.uniforms.set('ncaCloudOverlayRegion',this.overlayRegion);\n    const replacements=[\n      ['vec4 overlay = texture(overlayBuffer, uv);','vec4 overlay = ncaCloudAttachments.x > 0.5 && ncaCloudOverlayDeferred < 0.5 ? ncaReconstructCloudOverlay(uv) : vec4(0.0);'],\n      ['shadowLength = texture(shadowLengthBuffer, uv).r;','shadowLength = ncaCloudAttachments.z > 0.5 ? texture(shadowLengthBuffer, uv).r : 0.0;'],\n      ['float opticalDepth = sampleShadowOpticalDepth(worldPosition, positionECEF, radius, stbn);','float opticalDepth = ncaCloudAttachments.y > 0.5 ? sampleShadowOpticalDepth(worldPosition, positionECEF, radius, stbn) : 0.0;'],\n    ];\n    let shader=effect.fragmentShader;\n    for(const [from,to]of replacements){if(!shader.includes(from))throw new Error('Aerial cloud attachment shader contract changed');shader=shader.replace(from,to);}\n    const helper = /* glsl */`\n      ${CLOUD_GUIDE_GLSL}\n      float ncaCloudSceneGuide(vec2 uv) {\n        vec2 mode = vec2(0.0);\n        #ifdef USE_LOGDEPTHBUF\n        mode.x = 1.0;\n        #endif\n        #ifdef PERSPECTIVE_CAMERA\n        mode.y = 1.0;\n        #endif\n        vec3 ray = normalize((inverseProjectionMatrix * vec4(uv*2.0-1.0,0.0,1.0)).xyz);\n        return ncaCloudGuideDepth(readDepthValue(depthBuffer, uv), cameraNear, cameraFar, mode, ncaCloudGuideLimit,\n          mode.y>0.5 ? -ray.z : 1.0);\n      }\n      vec4 ncaReconstructCloudOverlay(vec2 uv) {\n        vec2 size = vec2(textureSize(overlayBuffer,0)) * ncaCloudOverlayRegion.xy;\n        vec2 position = uv * size - 0.5;\n        vec2 base = floor(position), fraction = fract(position);\n        float targetZ = ncaCloudSceneGuide(uv);\n        vec4 sumColor = vec4(0.0); float sumWeight = 0.0;\n        for (int y=0; y<2; ++y) for (int x=0; x<2; ++x) {\n          vec2 point = clamp((base+vec2(x,y)+0.5)/size, 0.5/size, 1.0-0.5/size);\n          float weight = ncaCloudDepthWeight(ncaCloudSceneGuide(point), targetZ);\n          weight *= (x==0 ? 1.0-fraction.x : fraction.x) * (y==0 ? 1.0-fraction.y : fraction.y);\n          vec2 mapUv = point*ncaCloudOverlayRegion.xy+ncaCloudOverlayRegion.zw;\n          sumColor += texture(overlayBuffer,mapUv)*weight; sumWeight += weight;\n        }\n        return sumWeight>1e-5 ? sumColor/sumWeight : vec4(0.0);\n      }\n    `;\n    if (!shader.includes('void mainImage(')) throw new Error('Aerial cloud reconstruction signature changed');\n    shader = shader.replace('void mainImage(', helper+'\\nvoid mainImage(');\n    effect.fragmentShader='uniform float ncaCloudOverlayDeferred;\\nuniform vec3 ncaCloudAttachments;\\nuniform vec4 ncaCloudOverlayRegion;\\nuniform float ncaCloudGuideLimit;\\n'+shader;\n    const texture=new DataTexture(new Uint8Array(4),1,1,RGBAFormat,UnsignedByteType);\n    texture.name='CloudAttachments.Neutral';texture.minFilter=texture.magFilter=NearestFilter;\n    texture.colorSpace=NoColorSpace;texture.generateMipmaps=false;texture.needsUpdate=true;\n    this.zero=texture;this.emptyOverlay={map:texture};this.emptyLength={map:texture};\n    this._setCascadeCount(cascadeCount);\n    for(const name of ['HAS_OVERLAY','HAS_SHADOW','HAS_SHADOW_LENGTH'])effect.defines.set(name,'1');\n    this.set(false);\n  }\n  _setCascadeCount(value){\n    const count=Math.max(1,Math.min(8,Math.round(value)||3));if(count===this.count)return;\n    const initial=this.count===undefined;this.count=count;this.shadowZero?.dispose();\n    const map=new DataArrayTexture(new Uint8Array(4*count),1,1,count);\n    map.name='CloudAttachments.NeutralShadow';map.format=RGBAFormat;map.type=UnsignedByteType;\n    map.minFilter=map.magFilter=NearestFilter;map.colorSpace=NoColorSpace;map.generateMipmaps=false;map.needsUpdate=true;\n    this.shadowZero=map;this.emptyShadow={map,mapSize:new Vector2(1,1),cascadeCount:count,\n      intervals:Array.from({length:count},()=>new Vector2(0,1)),matrices:Array.from({length:count},()=>new Matrix4()),\n      inverseMatrices:Array.from({length:count},()=>new Matrix4()),far:1,topHeight:0};\n    // Prime the initial shader only. A deliberate cascade-count setting change\n    // must remain visible to native updateShadow(), which invalidates programs\n    // for the new array size. Ordinary visibility toggles never change it.\n    if(initial)this.effect.defines.set('SHADOW_CASCADE_COUNT',String(count));\n  }\n  set(enabled,clouds){\n    this.overlayRegion.value.set(1,1,0,0);\n    this.enabled=enabled===true;\n    const overlay=this.enabled?clouds?.atmosphereOverlay:null;\n    const shadow=this.enabled?clouds?.atmosphereShadow:null;\n    const length=this.enabled?clouds?.atmosphereShadowLength:null;\n    const count=shadow?.cascadeCount??clouds?.shadow?.cascadeCount??this.count;this._setCascadeCount(count);\n    this.effect.overlay=overlay?.map?overlay:this.emptyOverlay;\n    this.effect.shadow=shadow?.map?shadow:this.emptyShadow;\n    this.effect.shadowLength=length?.map?length:this.emptyLength;\n    this.flags.value.set(overlay?.map?1:0,shadow?.map?1:0,length?.map?1:0);\n  }\n  dispose(){this.zero.dispose();this.shadowZero.dispose();}\n}\n","/** Three r185 compileAsync waits for completion, including failed links.\n * Check only the small cloud/sky scenes after that wait, never the terrain\n * scene or the animation loop. Keep production-wide shader diagnostics off.\n */\nexport function validateCompiledScenePrograms(renderer, scene) {\n  const gl = renderer.getContext?.();\n  if (!gl || !renderer.properties?.get || !scene.traverse) return;\n  if (gl.isContextLost()) throw new Error('Cloud shader preparation lost its WebGL context');\n  const checked = new Set();\n  scene.traverse(object => {\n    if (!(object.isMesh || object.isPoints || object.isLine || object.isSprite)) return;\n    const materials = Array.isArray(object.material) ? object.material : [object.material];\n    for (const material of materials) {\n      if (!material) continue;\n      const prepared = renderer.properties.get(material).currentProgram;\n      const program = prepared?.program;\n      if (checked.has(program)) continue;\n      checked.add(program);\n      if (program && gl.isProgram(program) && gl.getProgramParameter(program, gl.LINK_STATUS)) {\n        // Three defers reflection until first use, even after compileAsync.\n        // Settle it here after native completion, outside the visible draw.\n        prepared.getUniforms?.();\n        prepared.getAttributes?.();\n        continue;\n      }\n      const valid = program && gl.isProgram(program);\n      const programLog = valid ? gl.getProgramInfoLog(program) || '' : 'Program was not compiled or was retired';\n      const shaderLogs = valid ? (gl.getAttachedShaders(program) || [])\n        .map(shader => gl.getShaderInfoLog(shader) || '').filter(Boolean) : [];\n      const error = new Error(`Cloud shader link failed (${material.name || material.type}): ${[programLog, ...shaderLogs].join('\\n').replaceAll('\\0', '').slice(0, 8192)}`);\n      error.code = 'CLOUD_SHADER_LINK_FAILED';\n      throw error;\n    }\n  });\n}\n","/** Optional, nonblocking native compositor timing. Uses the admitted GL context. */\nexport class XRGpuTimer {\n  constructor(renderer, now = () => performance.now()) {\n    this.gl = renderer.getContext(); this.canvas = renderer.domElement; this.now = now;\n    this.pending = []; this.active = null; this.nextSample = 0; this.result = null;\n    this.onLost = () => { this.pending.length = 0; this.active = null; this.result = null; this.ext = null; };\n    this.onRestored = () => { this.ext = this.gl.getExtension('EXT_disjoint_timer_query_webgl2'); this.nextSample = 0; };\n    this.onRestored();\n    this.canvas?.addEventListener('webglcontextlost', this.onLost);\n    this.canvas?.addEventListener('webglcontextrestored', this.onRestored);\n  }\n  begin() {\n    const gl = this.gl, ext = this.ext, now = this.now();\n    if (!ext || gl.isContextLost()) return;\n    try {\n      if (gl.getParameter(ext.GPU_DISJOINT_EXT)) {\n        this.clear(); this.nextSample = now + 1000; return;\n      }\n      while (this.pending.length && gl.getQueryParameter(this.pending[0], gl.QUERY_RESULT_AVAILABLE)) {\n        const query = this.pending.shift(), ns = gl.getQueryParameter(query, gl.QUERY_RESULT);\n        gl.deleteQuery(query);\n        this.result = Number.isFinite(ns) && ns >= 0 ? { ms: ns / 1e6, at: now } : null;\n      }\n      if (this.active || now < this.nextSample || this.pending.length >= 2\n        || gl.getQuery(ext.TIME_ELAPSED_EXT, gl.CURRENT_QUERY)) return;\n      this.active = gl.createQuery(); this.nextSample = now + 1000;\n      if (this.active) gl.beginQuery(ext.TIME_ELAPSED_EXT, this.active);\n    } catch { this.disable(); }\n  }\n  end(valid = true) {\n    if (!this.active) return;\n    try {\n      this.gl.endQuery(this.ext.TIME_ELAPSED_EXT);\n      if (valid) this.pending.push(this.active); else this.gl.deleteQuery(this.active);\n      this.active = null;\n    } catch { this.disable(); }\n  }\n  getStats() {\n    const age = this.result ? this.now() - this.result.at : null;\n    return { gpuMs: age !== null && age <= 5000 ? this.result.ms : null, gpuAgeMs: age };\n  }\n  clear() {\n    for (const query of this.pending) this.gl.deleteQuery(query);\n    this.pending.length = 0; this.result = null;\n  }\n  disable() {\n    // Instrumentation failure must never fail a frame or retry every frame.\n    try { if (this.active) { this.gl.endQuery(this.ext.TIME_ELAPSED_EXT); this.gl.deleteQuery(this.active); } this.clear(); } catch {}\n    this.active = null; this.ext = null;\n  }\n  dispose() {\n    if (!this.gl.isContextLost()) this.disable(); else this.onLost();\n    this.canvas?.removeEventListener('webglcontextlost', this.onLost);\n    this.canvas?.removeEventListener('webglcontextrestored', this.onRestored);\n  }\n}\n","import * as THREE from 'three';\nimport { AerialPerspectiveEffect } from '@takram/three-atmosphere';\nimport { EffectPass, ToneMappingEffect, ToneMappingMode, SMAAEffect, SMAAPreset } from 'postprocessing';\nimport { PhotorealLightingMaskPass } from '../render/PhotorealLightingMaskPass.js';\nimport { PHOTO_DEFERRED_LIGHTING_LAYER } from '../tiles/PhotorealLightingContract.js';\nimport { preparePhotorealSurfaceVisibilityMaterial } from '../tiles/PhotorealSurfaceVisibilityContract.js';\nimport { XRGpuTimer } from './XRGpuTimer.js';\nimport { createNativeXRRuntime } from './NativeXRRuntimeFactory.js';\n\nconst dependencies = Object.freeze({ THREE, AerialPerspectiveEffect, EffectPass, ToneMappingEffect,\n  ToneMappingMode, SMAAEffect, SMAAPreset, PhotorealLightingMaskPass, PHOTO_DEFERRED_LIGHTING_LAYER,\n  preparePhotorealSurfaceVisibilityMaterial, XRGpuTimer });\nexport const { NativeXRAtmosphereRenderer, NativeXRLightingMask, NativeXRFinalPass } = createNativeXRRuntime(dependencies);\n","const EARTH_RADIUS_M = 6378137;\nconst smooth = value => { const t = Math.max(0, Math.min(1, value)); return t * t * (3 - 2 * t); };\n\n/** Native-only distance budget. It never changes render pixels or nearby SSE. */\nexport function xrTerrainRange(altitudeM, out = {}) {\n  const altitude = Math.max(0, Number.isFinite(altitudeM) ? altitudeM : 0);\n  const horizon = Math.sqrt(Math.max(3, altitude) * (2 * EARTH_RADIUS_M + altitude));\n  out.altitudeM = altitude;\n  out.nearDetailM = Math.min(25000, 120 + Math.sqrt(altitude) * 10);\n  // Add relief/context beyond the mathematical sea-level horizon. At height,\n  // the visible hemisphere remains eligible, with much coarser distant SSE.\n  out.farM = Math.max(10000, horizon * 1.15 + 3000 + altitude * 0.05);\n  out.fogStartM = out.farM * 0.45;\n  out.fogEndM = out.farM * 0.9;\n  out.fogStrength = 1 - smooth((altitude - 6000) / 34000);\n  return out;\n}\n\nexport function xrTerrainErrorScale(distanceM, profile) {\n  if (!Number.isFinite(distanceM) || distanceM <= profile.nearDetailM) return 1;\n  const fraction = (distanceM - profile.nearDetailM)\n    / Math.max(1, profile.farM * 0.5 - profile.nearDetailM);\n  return 1 + 31 * smooth(fraction);\n}\n\n/** Wrap only native camera SSE, before additive underfoot regions are merged.\n * Native ancestors/fade/cache and exact underfoot error-zero demand stay owned\n * by TilesRenderer. No visibility scan, camera, timer or extra tile requests.\n */\nexport class XRTerrainDistancePolicy {\n  constructor(tiles) {\n    this.tiles = tiles; this.active = false; this.profile = xrTerrainRange(0);\n    const descriptor = Object.getOwnPropertyDescriptor(tiles, 'calculateTileViewError');\n    this.descriptor = descriptor; this.original = tiles.calculateTileViewError;\n    const self = this;\n    this.wrapper = function(tile, target) {\n      self.original.call(this, tile, target);\n      if (self.active) target.error /= xrTerrainErrorScale(target.distanceFromCamera, self.profile);\n    };\n    tiles.calculateTileViewError = this.wrapper;\n  }\n  update(active, altitudeM) { this.active = active === true; xrTerrainRange(altitudeM, this.profile); }\n  dispose() {\n    if (this.tiles.calculateTileViewError === this.wrapper) {\n      if (this.descriptor) Object.defineProperty(this.tiles, 'calculateTileViewError', this.descriptor);\n      else delete this.tiles.calculateTileViewError;\n    }\n    this.active = false;\n  }\n}\n","import { BasicDepthPacking, HalfFloatType, Matrix4, PerspectiveCamera, Uniform, Vector3 } from 'three';\nimport { patchCloudDepthReconstruction, prepareCloudFrontDepth } from '../render/CloudDepthReconstruction.js';\nimport { xrTerrainRange } from './XRTerrainRange.js';\n\nconst CAMERA_FIELDS = new Set(['projectionMatrix', 'viewMatrix', 'inverseProjectionMatrix', 'inverseViewMatrix',\n  'cameraPosition', 'cameraNear', 'cameraFar', 'cameraHeight', 'depthBuffer', 'reprojectionMatrix',\n  'viewReprojectionMatrix', 'temporalJitter', 'targetUvScale', 'resolution', 'mipLevelScale', 'frame',\n  'inverseShadowMatrices', 'reprojectionMatrices', 'shadowIntervals', 'shadowMatrices', 'shadowFar']);\nfunction copyUniforms(to, from) {\n  for (const name in from) {\n    if (CAMERA_FIELDS.has(name)) continue;\n    if (!to[name]) to[name] = new Uniform(from[name].value);\n    else to[name].value = from[name].value;\n  }\n}\nfunction freezeCamera(target, source) {\n  target.matrix.copy(source.matrixWorld); target.matrixWorld.copy(source.matrixWorld);\n  target.matrixWorldInverse.copy(source.matrixWorldInverse);\n  target.matrix.decompose(target.position, target.quaternion, target.scale);\n  target.projectionMatrix.copy(source.projectionMatrix);\n  target.projectionMatrixInverse.copy(source.projectionMatrixInverse);\n  target.near = source.near; target.far = source.far;\n}\n\n/** Planet motion belongs to the same accepted history as that eye's view.\n * A parked desktop history or a disabled eye must not advance on other draws.\n */\nexport function patchNativeCloudReprojection(pass, getPlanetMatrix) {\n  const material = pass.currentMaterial, previous = new Matrix4(), inverse = new Matrix4(), delta = new Matrix4();\n  const copyCamera = material.copyCameraSettings.bind(material);\n  const copyHistory = material.copyReprojectionMatrix.bind(material);\n  let valid = false;\n  material.copyCameraSettings = function(camera) {\n    copyCamera(camera);\n    if (valid) {\n      delta.copy(previous).multiply(inverse.copy(getPlanetMatrix()).invert());\n      this.uniforms.reprojectionMatrix.value.multiply(delta);\n      this.uniforms.viewReprojectionMatrix.value.copy(this.uniforms.reprojectionMatrix.value)\n        .multiply(this.uniforms.inverseViewMatrix.value);\n    }\n  };\n  material.copyReprojectionMatrix = function(camera) {\n    copyHistory(camera); previous.copy(getPlanetMatrix()); valid = true;\n  };\n}\n\n/** Native radiance/depth histories belong to each eye. Only the world-space\n * density inputs and native centre-view shadow field are shared. No mono draw,\n * scene clone, second weather clock or density/resolution reduction.\n * AtmosphereCloudsSystem owns this bridge across renderer hot handoffs.\n */\nexport class NativeXRClouds {\n  constructor(system) {\n    this.system = system; this.eyes = []; this.frame = 0; this.ready = false;\n    this.center = new PerspectiveCamera(); this.center.matrixAutoUpdate = this.center.matrixWorldAutoUpdate = false;\n    this.profile = xrTerrainRange(0); this.fog = new Vector3();\n    this.state = 'cold'; this.failures = 0; this.completedEyes = 0;\n  }\n\n  configureAerial(effect) {\n    const empty = this.system._cloudAtmosphereAttachments;\n    effect.overlay = empty.emptyOverlay; effect.shadow = empty.emptyShadow; effect.shadowLength = empty.emptyLength;\n    effect.uniforms.set('ncaCloudAttachments', new Uniform(new Vector3()));\n    effect.uniforms.set('ncaXRTerrainFog', new Uniform(this.fog));\n    for (const key of ['HAS_OVERLAY', 'HAS_SHADOW', 'HAS_SHADOW_LENGTH']) effect.defines.set(key, '1');\n  }\n\n  get requested() { return this.system._cloudsEnabled === true; }\n\n  beginFrame(renderer, eyes, deltaTime) {\n    this.completedEyes = 0;\n    const system = this.system, source = system.clouds;\n    const requested = this.requested;\n    if (requested && this.wasRequested === false && this.state === 'failed') this.state = 'cold';\n    this.wasRequested = requested;\n    xrTerrainRange(system._getCameraAltitudeMeters?.() ?? 0, this.profile);\n    this.fog.set(this.profile.fogStartM, this.profile.fogEndM, this.profile.fogStrength);\n    this.active = requested && system.ready === true && eyes.length > 0;\n    if (!this.active) return;\n    const nativeCenter = renderer.xr.getCamera();\n    freezeCamera(this.center, nativeCenter);\n    // getWorldPosition is safe on this frozen standalone camera, never on a\n    // native eye whose published matrix must not be rebuilt from room space.\n    const previous = source.camera;\n    source.camera = this.center;\n    try { source.updateSharedUniforms(deltaTime); source.updateWeatherTextureChannels(); }\n    finally { source.camera = previous; }\n    system._updateCloudDistanceTuning?.(deltaTime);\n    this.frame++;\n    if (!this.ready) return;\n    try {\n      copyUniforms(this.shadow.currentMaterial.uniforms, source.shadowPass.currentMaterial.uniforms);\n      this.shadow.mainCamera = this.center;\n      this.shadow.update(renderer, this.frame, deltaTime);\n    } catch (error) { this._fail(error); }\n  }\n\n  _clear(effect) {\n    const empty = this.system._cloudAtmosphereAttachments;\n    effect.overlay = empty.emptyOverlay; effect.shadow = empty.emptyShadow; effect.shadowLength = empty.emptyLength;\n    effect.uniforms.get('ncaCloudAttachments').value.set(0, 0, 0);\n    effect.uniforms.get('ncaCloudOverlayRegion').value.set(1, 1, 0, 0);\n  }\n\n  renderEye(renderer, camera, depth, index, width, height, deltaTime, effect) {\n    this._clear(effect);\n    if (!this.active || this.disposed || this.state === 'failed') return false;\n    const source = this.system.clouds, scale = source.resolutionScale;\n    const w = Math.max(1, Math.round(width * scale)), h = Math.max(1, Math.round(height * scale));\n    const entry = this.eyes[index];\n    if (!this.ready || entry?.width !== w || entry?.height !== h || this.sourceVersion !== source.cloudsPass.currentMaterial.version\n      || this.cascadeCount !== source.shadow.cascadeCount || this.shadowWidth !== source.shadow.mapSize.x\n      || this.shadowHeight !== source.shadow.mapSize.y) {\n      this._requestWarm(renderer, depth, camera);\n      return false;\n    }\n    if (!entry) return false;\n    try {\n      freezeCamera(entry.camera, camera);\n      const pass = entry.pass;\n      copyUniforms(pass.currentMaterial.uniforms, source.cloudsPass.currentMaterial.uniforms);\n      pass.setDepthTexture(depth, BasicDepthPacking);\n      pass.shadowBuffer = this.shadow.outputBuffer;\n      pass.update(renderer, this.frame, deltaTime);\n      entry.overlay.map = pass.outputBuffer; entry.length.map = pass.shadowLengthBuffer;\n      effect.overlay = entry.overlay; effect.shadowLength = entry.length.map ? entry.length : this.system._cloudAtmosphereAttachments.emptyLength;\n      const shadow = entry.shadow;\n      shadow.map = this.shadow.outputBuffer; shadow.far = source.shadowMaps.far;\n      shadow.topHeight = pass.currentMaterial.uniforms.shadowTopHeight.value;\n      effect.shadow = shadow;\n      effect.uniforms.get('ncaCloudAttachments').value.set(1, 1, entry.length.map ? 1 : 0);\n      this.completedEyes++;\n      return true;\n    } catch (error) { this._fail(error); this._clear(effect); return false; }\n  }\n\n  _fail(error) {\n    this.state = 'failed'; this.ready = false; this.failures++;\n    console.warn('[NativeXRClouds] Optional cloud preparation failed; physical atmosphere remains active', error);\n  }\n\n  _requestWarm(renderer, depth, camera) {\n    if (this.warming || this.disposed || this.state === 'failed') return;\n    const system = this.system, source = system.clouds;\n    const layouts = renderer.xr.getCamera().cameras.slice(0, 2).map(eye => ({\n      width: Math.max(1, Math.round(eye.viewport.z * source.resolutionScale)),\n      height: Math.max(1, Math.round(eye.viewport.w * source.resolutionScale)),\n    }));\n    this.state = 'warming'; this.ready = false;\n    const work = async task => {\n      let failure;\n      await system._runCloudWarmupIdleTask(async () => {\n        if (this.disposed) return;\n        try { await task(); } catch (error) { failure = error; }\n      });\n      if (failure) throw failure;\n      if (this.disposed) throw new Error('Native cloud preparation retired');\n    };\n    this.warming = (async () => {\n      await work(() => {\n        this._disposePasses();\n        system._patchCloudsCameraHeight(); system._patchCloudsNightLighting();\n        const original = source.cloudsPass;\n        const options = {shadow: source.shadowMaps, parameterUniforms: source.parameterUniforms,\n          layerUniforms: source.layerUniforms, atmosphereUniforms: source.atmosphereUniforms};\n        this.shadow = new source.shadowPass.constructor(options);\n        this.shadow.temporalPass = source.shadowPass.temporalPass;\n        this.shadow.mainCamera = this.center;\n        this.shadow.currentMaterial.vertexShader = source.shadowPass.currentMaterial.vertexShader;\n        this.shadow.currentMaterial.fragmentShader = source.shadowPass.currentMaterial.fragmentShader;\n        this.shadow.currentMaterial.defines = {...source.shadowPass.currentMaterial.defines};\n        this.shadow.setSize(source.shadow.mapSize.x, source.shadow.mapSize.y, source.shadow.cascadeCount);\n        for (const {width, height} of layouts) {\n          const eyeCamera = new PerspectiveCamera(); eyeCamera.matrixAutoUpdate = eyeCamera.matrixWorldAutoUpdate = false;\n          freezeCamera(eyeCamera, camera);\n          const pass = new original.constructor(options, system._atmosphereParams);\n          pass.mainCamera = eyeCamera; pass.lightShafts = original.lightShafts; pass.temporalUpscale = original.temporalUpscale;\n          pass.currentMaterial.vertexShader = original.currentMaterial.vertexShader;\n          pass.currentMaterial.fragmentShader = original.currentMaterial.fragmentShader;\n          pass.currentMaterial.defines = {...original.currentMaterial.defines};\n          copyUniforms(pass.currentMaterial.uniforms, original.currentMaterial.uniforms);\n          pass.setDepthTexture(depth, BasicDepthPacking);\n          pass.setShadowSize(source.shadow.mapSize.x, source.shadow.mapSize.y, source.shadow.cascadeCount);\n          pass.setSize(width, height);\n          prepareCloudFrontDepth(pass);\n          patchCloudDepthReconstruction({cloudsPass: pass});\n          patchNativeCloudReprojection(pass, () => system._planetMatrix);\n          this.eyes.push({pass, width, height, camera: eyeCamera, overlay: {map: null}, length: {map: null}, shadow: {\n            map: null, mapSize: source.shadow.mapSize, cascadeCount: source.shadow.cascadeCount,\n            intervals: pass.currentMaterial.uniforms.shadowIntervals.value,\n            matrices: pass.currentMaterial.uniforms.shadowMatrices.value,\n            inverseMatrices: this.shadow.currentMaterial.uniforms.inverseShadowMatrices.value, far: 1, topHeight: 0,\n          }});\n        }\n        this.sourceVersion = original.currentMaterial.version;\n        this.cascadeCount = source.shadow.cascadeCount;\n        this.shadowWidth = source.shadow.mapSize.x; this.shadowHeight = source.shadow.mapSize.y;\n      });\n      for (const texture of system._cloudEffectTextures(source)) await work(() => renderer.initTexture(texture));\n      const passes = [this.shadow, ...this.eyes.map(e => e.pass)];\n      for (const pass of passes) {\n        for (const leaf of [pass.currentPass, pass.resolvePass]) await work(() => leaf.initialize(renderer, false, HalfFloatType));\n        for (const target of [pass.currentRenderTarget, pass.resolveRenderTarget, pass.historyRenderTarget]) {\n          if (target) await work(() => renderer.initRenderTarget(target));\n        }\n        pass.currentMaterial.onBeforeRender(renderer);\n        pass.copyCameraSettings?.(pass.mainCamera);\n        await system._compileCloudScenesInIdleSlices([\n          [pass.currentPass.scene, pass.currentPass.camera], [pass.resolvePass.scene, pass.resolvePass.camera],\n        ]);\n        if (this.disposed) return;\n      }\n      this.ready = true; this.state = 'ready';\n    })().catch(error => { if (!this.disposed) this._fail(error); }).finally(() => { this.warming = null; });\n  }\n\n  _disposePasses() {\n    this.shadow?.dispose(); this.shadow = null;\n    for (const eye of this.eyes) eye.pass.dispose();\n    this.eyes.length = 0;\n  }\n  dispose() { this.disposed = true; this.ready = false; this._disposePasses(); }\n}\n","/**\n * Aurora system — renders a physically-motivated auroral oval driven by live\n * NOAA SWPC OVATION nowcast data.\n *\n * Data: https://services.swpc.noaa.gov/json/ovation_aurora_latest.json\n *   A 1°x1° global grid of aurora probability (0-100). The auroral oval shape,\n *   its offset from the geographic pole, and night-side enhancement are all baked\n *   into the data, so we just sample it by geographic lon/lat.\n *\n * Render: a world-space shell scaled each frame to enclose the camera, ray-marched\n * like the airglow/atmosphere inscatter. Per sample we read the OVATION probability\n * (location + prominence), apply a vertical curtain profile and animated fbm noise\n * (the fluid/spire structure), and tint by altitude using real emission lines:\n *   ~90-110 km  N2+ blue/purple (427.8 nm)\n *   ~110-180 km O green (557.7 nm) — the dominant band\n *   ~180-400 km O red (630.0 nm)\n * Gated to the night side, where aurora is visible against the dark sky.\n */\n\nimport * as THREE from 'three';\nimport { PLANET_RADIUS } from './constants.js';\nimport { getFetchQueue } from '../refactor/async/fetch/FetchQueue.js';\n\nconst OVATION_URL = 'https://services.swpc.noaa.gov/json/ovation_aurora_latest.json';\nconst GRID_W = 360;\nconst GRID_H = 181;\nconst REFRESH_MS = 5 * 60 * 1000;\nconst RETRY_MS = 60 * 1000;\nconst TOP_ALT_M = 400000; // top of the visible auroral column\n// Centred-dipole geomagnetic north pole (IGRF-14 epoch 2025: ~80.8°N 72.7°W).\n// Auroral arcs run along geomagnetic latitude circles around it.\nexport const GEOMAGNETIC_POLE = Object.freeze({ latDeg: 80.8, lonDeg: -72.7 });\n// OVATION probability (0-1) below which no aurora is drawn: the nowcast\n// carries ~1-10 % noise at the equator and polar caps; SWPC's own maps start\n// at ~10 %. Storm-time expansion shows up as genuinely high probabilities.\nexport const AURORA_VISIBILITY = Object.freeze({ start: 0.10, full: 0.35 });\n\n/**\n * Texture coordinates of the OVATION grid for a planet-local direction, in\n * the engine's convention (geometry-utils latLonToLocalDir: lon = atan2(x, z)\n * with Greenwich at +Z, geodetic latitude). The shader mirrors this exactly.\n */\nexport function auroraGridUv(dir) {\n    const rxz = Math.hypot(dir.x, dir.z);\n    const lat = Math.atan2(dir.y / 0.99330562, rxz);\n    const lon = Math.atan2(dir.x, dir.z);\n    const u = ((lon / (2 * Math.PI) + 0.5) % 1 + 1) % 1;\n    return { u, v: Math.min(1, Math.max(0, 0.5 - lat / Math.PI)), latDeg: lat * 180 / Math.PI, lonDeg: lon * 180 / Math.PI };\n}\n\nfunction geomagneticPoleLocal() {\n    const lat = GEOMAGNETIC_POLE.latDeg * Math.PI / 180;\n    const lon = GEOMAGNETIC_POLE.lonDeg * Math.PI / 180;\n    return [Math.cos(lat) * Math.sin(lon), Math.sin(lat), Math.cos(lat) * Math.cos(lon)];\n}\nconst MAG_POLE = geomagneticPoleLocal().map((v) => v.toFixed(6)).join(', ');\n\nexport class AuroraSystem {\n    constructor({ planetRadius = PLANET_RADIUS } = {}) {\n        this.enabled = true;\n        this.planetRadius = planetRadius;\n        this.strength = 0.9;\n        this.topAltitudeMeters = TOP_ALT_M;\n        // Emission column (m) for ~63 % brightness. Saturating, so a straight-\n        // down view through the ~100-300 km band reads clearly from above\n        // while long grazing paths at the horizon still saturate.\n        this.pathRefMeters = 30000;\n        this.depthBiasMeters = 4;\n\n        this._gridData = new Uint8Array(GRID_W * GRID_H);\n        this._dataTexture = new THREE.DataTexture(this._gridData, GRID_W, GRID_H, THREE.RedFormat, THREE.UnsignedByteType);\n        this._dataTexture.minFilter = THREE.LinearFilter;\n        this._dataTexture.magFilter = THREE.LinearFilter;\n        this._dataTexture.wrapS = THREE.RepeatWrapping;\n        this._dataTexture.wrapT = THREE.ClampToEdgeWrapping;\n        this._dataTexture.needsUpdate = true;\n\n        this._material = this._buildMaterial();\n        this.mesh = new THREE.Mesh(new THREE.SphereGeometry(planetRadius, 64, 32), this._material);\n        this.mesh.name = 'Aurora';\n        // Ray-marched atmospheric emission must tint, never geometrically\n        // eclipse, the scene-owned astronomical lens flare.\n        this.mesh.userData.lensflare = 'no-occlusion';\n        this.mesh.renderOrder = 12;\n        this.mesh.frustumCulled = false;\n        this.mesh.visible = false;\n\n        this._worldToLocal = new THREE.Matrix3();\n        this._lastFetchMs = 0;\n        this._nextRetryMs = 0;\n        this._fetchInFlight = false;\n        this._fetchData();\n    }\n\n    _buildMaterial() {\n        return new THREE.ShaderMaterial({\n            uniforms: {\n                uAuroraTex: { value: this._dataTexture },\n                uCameraWorld: { value: new THREE.Vector3() },\n                uPlanetCenterW: { value: new THREE.Vector3() },\n                uSunDirWorld: { value: new THREE.Vector3(0, 0, 1) },\n                uWorldToLocal: { value: new THREE.Matrix3() },\n                uPlanetRadius: { value: this.planetRadius },\n                uTopAlt: { value: this.topAltitudeMeters },\n                uTime: { value: 0 },\n                uStrength: { value: this.strength },\n                uPathRef: { value: this.pathRefMeters },\n                uDepthTexture: { value: null },\n                uDepthResolution: { value: new THREE.Vector2(1, 1) },\n                uInvProjectionMatrix: { value: new THREE.Matrix4() },\n                uInvViewMatrix: { value: new THREE.Matrix4() },\n                uDepthEnabled: { value: 0 },\n                uDepthBias: { value: this.depthBiasMeters }\n            },\n            vertexShader: /* glsl */`\n                #include <common>\n                #include <logdepthbuf_pars_vertex>\n\n                varying vec3 vPosW;\n                void main() {\n                    vec4 wp = modelMatrix * vec4(position, 1.0);\n                    vPosW = wp.xyz;\n                    gl_Position = projectionMatrix * viewMatrix * wp;\n                    #include <logdepthbuf_vertex>\n                }\n            `,\n            fragmentShader: /* glsl */`\n                precision highp float;\n                #include <logdepthbuf_pars_fragment>\n\n                uniform sampler2D uAuroraTex;\n                uniform vec3 uCameraWorld;\n                uniform vec3 uPlanetCenterW;\n                uniform vec3 uSunDirWorld;\n                uniform mat3 uWorldToLocal;\n                uniform float uPlanetRadius;\n                uniform float uTopAlt;\n                uniform float uTime;\n                uniform float uStrength;\n                uniform float uPathRef;\n                uniform sampler2D uDepthTexture;\n                uniform vec2 uDepthResolution;\n                uniform mat4 uInvProjectionMatrix;\n                uniform mat4 uInvViewMatrix;\n                uniform float uDepthEnabled;\n                uniform float uDepthBias;\n                varying vec3 vPosW;\n\n                #define PI 3.141592653589793\n\n                float hash(vec3 p) {\n                    p = fract(p * 0.3183099 + 0.1);\n                    p *= 17.0;\n                    return fract(p.x * p.y * p.z * (p.x + p.y + p.z));\n                }\n                float vnoise(vec3 x) {\n                    vec3 i = floor(x); vec3 f = fract(x);\n                    f = f * f * (3.0 - 2.0 * f);\n                    return mix(mix(mix(hash(i + vec3(0,0,0)), hash(i + vec3(1,0,0)), f.x),\n                                   mix(hash(i + vec3(0,1,0)), hash(i + vec3(1,1,0)), f.x), f.y),\n                               mix(mix(hash(i + vec3(0,0,1)), hash(i + vec3(1,0,1)), f.x),\n                                   mix(hash(i + vec3(0,1,1)), hash(i + vec3(1,1,1)), f.x), f.y), f.z);\n                }\n                float fbm(vec3 p) {\n                    float a = 0.5; float s = 0.0;\n                    for (int i = 0; i < 3; i++) { s += a * vnoise(p); p *= 2.02; a *= 0.5; }\n                    return s;\n                }\n\n                // OVATION probability at a planet-local direction, matching the engine's\n                // equirect convention (y = north, lon = atan(z,x), v = 0.5 - lat/PI).\n                // Engine convention (latLonToLocalDir): lon = atan(x, z) with\n                // Greenwich at +Z, geodetic latitude. Mirrors auroraGridUv().\n                float auroraProb(vec3 dirLocal, out float lat) {\n                    vec3 n = normalize(dirLocal);\n                    lat = atan(n.y / 0.99330562, length(n.xz));\n                    float lon = atan(n.x, n.z);\n                    float u = lon / (2.0 * PI) + 0.5;\n                    float v = 0.5 - (lat / PI);\n                    return texture2D(uAuroraTex, vec2(fract(u + 1.0), clamp(v, 0.0, 1.0))).r;\n                }\n                const vec3 MAG_POLE = vec3(${MAG_POLE});\n                // Geomagnetic latitude / longitude: arcs follow mlat circles.\n                vec2 geomagnetic(vec3 n) {\n                    vec3 e1 = normalize(cross(vec3(0.0, 1.0, 0.0), MAG_POLE));\n                    vec3 e2 = cross(MAG_POLE, e1);\n                    return vec2(atan(dot(n, e2), dot(n, e1)), asin(clamp(dot(n, MAG_POLE), -1.0, 1.0)));\n                }\n\n                // Spectral tint by altitude, smoothly blended across wide bands:\n                // N2+ violet base (~100 km), O green (~110-190 km), O red (~200 km+).\n                vec3 auroraColor(float alt) {\n                    vec3 violet = vec3(0.45, 0.28, 1.00);\n                    vec3 green = vec3(0.20, 1.00, 0.45);\n                    vec3 red = vec3(1.00, 0.30, 0.42);\n                    // Blue/violet N2+ only at the lower fringe; 557.7 nm green\n                    // dominates ~105-180 km; 630.0 nm red above ~200 km.\n                    vec3 c = mix(violet, green, smoothstep(96000.0, 112000.0, alt));\n                    c = mix(c, red, smoothstep(180000.0, 260000.0, alt));\n                    return c;\n                }\n\n                float terrainDepthDistance(vec2 uv) {\n                    if (uDepthEnabled < 0.5) return 1.0e20;\n                    if (uv.x < 0.0 || uv.y < 0.0 || uv.x > 1.0 || uv.y > 1.0) return 1.0e20;\n\n                    float depthSample = texture2D(uDepthTexture, uv).x;\n                    if (depthSample >= 0.999999) return 1.0e20;\n\n                    #if defined(USE_LOGDEPTHBUF) || defined(USE_LOGARITHMIC_DEPTH_BUFFER)\n                        float viewZ = exp2(depthSample * 2.0 / logDepthBufFC) - 1.0;\n                        vec4 viewRay = uInvProjectionMatrix * vec4(uv * 2.0 - 1.0, 1.0, 1.0);\n                        vec3 rayDirView = normalize(viewRay.xyz / max(abs(viewRay.w), 1.0e-6));\n                        float denom = max(-rayDirView.z, 1.0e-6);\n                        return viewZ / denom;\n                    #else\n                        vec4 clip = vec4(uv * 2.0 - 1.0, depthSample * 2.0 - 1.0, 1.0);\n                        vec4 viewPos = uInvProjectionMatrix * clip;\n                        viewPos /= max(abs(viewPos.w), 1.0e-6);\n                        vec4 worldPos = uInvViewMatrix * viewPos;\n                        return length(worldPos.xyz - uCameraWorld);\n                    #endif\n                }\n\n                void main() {\n                    vec3 rd = normalize(vPosW - uCameraWorld);\n                    vec3 oc = uCameraWorld - uPlanetCenterW;\n                    float bdot = dot(oc, rd);\n                    float oc2 = dot(oc, oc);\n                    float R = uPlanetRadius;\n                    float Ro = R + uTopAlt;\n\n                    float discO = bdot * bdot - (oc2 - Ro * Ro);\n                    if (discO <= 0.0) discard;\n                    float sq = sqrt(discO);\n                    float tEnter = max(-bdot - sq, 0.0);\n                    float tExit = -bdot + sq;\n                    if (tExit <= tEnter) discard;\n\n                    // Stop at the near ground hit so the far-side oval stays occluded.\n                    float discG = bdot * bdot - (oc2 - R * R);\n                    if (discG > 0.0) {\n                        float tg = -bdot - sqrt(discG);\n                        if (tg > 0.0) tExit = min(tExit, tg);\n                    }\n\n                    vec2 depthUv = gl_FragCoord.xy / max(uDepthResolution, vec2(1.0));\n                    float tDepth = terrainDepthDistance(depthUv);\n                    if (tDepth < 1.0e19) {\n                        tExit = min(tExit, max(0.0, tDepth - uDepthBias));\n                    }\n                    if (tExit <= tEnter) discard;\n\n                    const int STEPS = 28;\n                    float dt = (tExit - tEnter) / float(STEPS);\n                    // The sun in the planet-fixed frame used for all samples.\n                    vec3 sunLocal = normalize(uWorldToLocal * normalize(uSunDirWorld));\n                    vec3 colAccum = vec3(0.0);\n                    float densAccum = 0.0;\n\n                    for (int i = 0; i < STEPS; i++) {\n                        float t = tEnter + (float(i) + 0.5) * dt;\n                        vec3 p = oc + rd * t;            // relative to planet centre (world)\n                        float alt = length(p) - R;\n                        if (alt < 80000.0 || alt > uTopAlt) continue;\n\n                        vec3 pLocal = uWorldToLocal * p;\n                        float lat;\n                        float prob = auroraProb(pLocal, lat);\n                        if (prob < ${AURORA_VISIBILITY.start.toFixed(3)}) continue; // below visibility: nowcast noise\n                        float visible = smoothstep(${AURORA_VISIBILITY.start.toFixed(3)}, ${AURORA_VISIBILITY.full.toFixed(3)}, prob);\n\n                        // Floating altitude band: crisp lower edge ~100 km (aurora has a\n                        // sharp base) with a soft tail upward — the curtains sit clearly\n                        // above the surface, the way the cloud layers do, and the wide\n                        // smoothstep keeps the layers blended rather than stepped.\n                        // Sharp lower border ~95-108 km (electron penetration\n                        // depth), green peak just above ~110-120 km, emission\n                        // decaying upward with a ~90 km scale toward the red top.\n                        float base = smoothstep(95000.0, 108000.0, alt);\n                        float top = exp(-max(alt - 120000.0, 0.0) / 90000.0);\n                        float vert = base * top;\n                        if (vert <= 0.001) continue;\n\n                        // Oval-aligned structure: stretched along the oval (longitude),\n                        // thin across it (latitude). A domain warp plus a slow longitudinal\n                        // drift makes the curtains undulate and flow realistically, while a\n                        // higher-frequency term scintillates the vertical rays/spires.\n                        vec3 nd = normalize(pLocal);\n                        vec2 mag = geomagnetic(nd);\n                        vec2 h = vec2(mag.x * 7.0, mag.y * 34.0);\n                        vec2 warp = vec2(\n                            fbm(vec3(h * 0.5, uTime * 0.025)),\n                            fbm(vec3(h * 0.5 + 11.3, uTime * 0.025))\n                        ) - 0.5;\n                        h += warp * 2.2;\n                        h.x += uTime * 0.05;             // slow drift along the oval\n                        float curtain = fbm(vec3(h, uTime * 0.04));\n                        curtain = smoothstep(0.30, 0.80, curtain);\n                        float rays = 0.55 + 0.45 * fbm(vec3(h.x * 2.6, alt * 0.000018, uTime * 0.18));\n\n                        // Night gating: aurora is seen against the dark side.\n                        // Visible once the emitting point (~100 km up) is dark:\n                        // sun from ~-1° to ~-13° below the local horizon.\n                        float night = 1.0 - smoothstep(-0.22, -0.02, dot(nd, sunLocal));\n\n                        float w = prob * visible * vert * curtain * rays * night;\n                        if (w <= 0.0) continue;\n                        colAccum += auroraColor(alt) * w;\n                        densAccum += w;\n                    }\n                    if (densAccum <= 0.0) discard;\n                    // Optically thin emission seen through a sensor: saturate\n                    // instead of clipping, so brightness no longer scales ~10x\n                    // between nadir (short column) and horizon (long column).\n                    float intensity = 1.0 - exp(-uStrength * (densAccum * dt) / uPathRef);\n                    if (intensity <= 0.0) discard;\n                    vec3 color = colAccum / densAccum;\n                    gl_FragColor = vec4(color * intensity, intensity);\n                }\n            `,\n            transparent: true,\n            blending: THREE.AdditiveBlending,\n            depthWrite: false,\n            depthTest: false,\n            side: THREE.BackSide,\n            toneMapped: false\n        });\n    }\n\n    async _fetchData() {\n        if (this._fetchInFlight || typeof fetch !== 'function') return;\n        this._fetchInFlight = true;\n        try {\n            const response = await getFetchQueue().fetchJSON(OVATION_URL, { mode: 'cors' });\n            if (!response.ok || !response.data) {\n                throw response.error || new Error(`OVATION fetch failed: ${response.status}`);\n            }\n            const json = response.data;\n            const coords = Array.isArray(json?.coordinates) ? json.coordinates : null;\n            if (!coords) throw new Error('OVATION payload missing coordinates');\n            this._gridData.fill(0);\n            for (let i = 0; i < coords.length; i++) {\n                const entry = coords[i];\n                const lon = entry[0];\n                const lat = entry[1];\n                const aurora = entry[2];\n                if (!Number.isFinite(lon) || !Number.isFinite(lat)) continue;\n                // Equirect layout: x = 0 -> lon -180; OVATION lon is 0..359.\n                const x = ((Math.round(lon) + 180) % 360 + 360) % 360;\n                const y = THREE.MathUtils.clamp(90 - Math.round(lat), 0, GRID_H - 1);\n                this._gridData[y * GRID_W + x] = THREE.MathUtils.clamp(Math.round(aurora * 2.55), 0, 255);\n            }\n            this._dataTexture.needsUpdate = true;\n            this._lastFetchMs = Date.now();\n            this._nextRetryMs = 0;\n        } catch (error) {\n            console.warn('[Aurora] OVATION fetch failed', error);\n            this._nextRetryMs = Date.now() + RETRY_MS;\n        } finally {\n            this._fetchInFlight = false;\n        }\n    }\n\n    setEnabled(enabled) {\n        this.enabled = !!enabled;\n        if (!this.enabled && this.mesh) this.mesh.visible = false;\n    }\n\n    setStrength(value) {\n        if (!Number.isFinite(value)) return;\n        this.strength = THREE.MathUtils.clamp(value, 0, 3);\n        if (this._material?.uniforms?.uStrength) {\n            this._material.uniforms.uStrength.value = this.strength;\n        }\n    }\n\n    applyConfig(config = {}) {\n        if (!config || typeof config !== 'object') return;\n        if (typeof config.enabled === 'boolean') this.setEnabled(config.enabled);\n        if (Number.isFinite(config.strength) || Number.isFinite(config.intensity)) {\n            this.setStrength(Number.isFinite(config.strength) ? config.strength : config.intensity);\n        }\n        const topAltitude = Number(config.topAltitudeMeters ?? config.topAltMeters ?? config.topAlt);\n        if (Number.isFinite(topAltitude)) {\n            this.topAltitudeMeters = THREE.MathUtils.clamp(topAltitude, 120000, 900000);\n            this._material.uniforms.uTopAlt.value = this.topAltitudeMeters;\n        }\n        const pathRef = Number(config.pathRefMeters ?? config.pathRef);\n        if (Number.isFinite(pathRef)) {\n            this.pathRefMeters = THREE.MathUtils.clamp(pathRef, 20000, 1000000);\n            this._material.uniforms.uPathRef.value = this.pathRefMeters;\n        }\n        const depthBias = Number(config.depthBiasMeters ?? config.depthBias);\n        if (Number.isFinite(depthBias)) {\n            this.depthBiasMeters = THREE.MathUtils.clamp(depthBias, 0, 200);\n            this._material.uniforms.uDepthBias.value = this.depthBiasMeters;\n        }\n    }\n\n    getConfig() {\n        return {\n            enabled: this.enabled,\n            strength: this.strength,\n            topAltitudeMeters: this.topAltitudeMeters,\n            pathRefMeters: this.pathRefMeters,\n            depthBiasMeters: this.depthBiasMeters\n        };\n    }\n\n    getStatus() {\n        return {\n            enabled: this.enabled,\n            ready: this._lastFetchMs > 0,\n            loading: this._fetchInFlight,\n            stale: this._lastFetchMs > 0 && Date.now() - this._lastFetchMs > REFRESH_MS,\n            lastUpdatedAt: this._lastFetchMs > 0\n                ? new Date(this._lastFetchMs).toISOString()\n                : null,\n            retryAt: this._nextRetryMs > 0\n                ? new Date(this._nextRetryMs).toISOString()\n                : null,\n            source: 'NOAA SWPC OVATION',\n            ...this.getConfig(),\n        };\n    }\n\n    setDepthSource({\n        depthTexture = null,\n        resolution = null,\n        invProjectionMatrix = null,\n        invViewMatrix = null,\n        enabled = false\n    } = {}) {\n        if (!this._material?.uniforms) return;\n        const u = this._material.uniforms;\n        u.uDepthTexture.value = depthTexture || null;\n        u.uDepthEnabled.value = enabled && depthTexture ? 1 : 0;\n        if (resolution) {\n            if (Number.isFinite(resolution.x) && Number.isFinite(resolution.y)) {\n                u.uDepthResolution.value.set(Math.max(1, resolution.x), Math.max(1, resolution.y));\n            } else if (Number.isFinite(resolution.width) && Number.isFinite(resolution.height)) {\n                u.uDepthResolution.value.set(Math.max(1, resolution.width), Math.max(1, resolution.height));\n            }\n        }\n        if (invProjectionMatrix) u.uInvProjectionMatrix.value.copy(invProjectionMatrix);\n        if (invViewMatrix) u.uInvViewMatrix.value.copy(invViewMatrix);\n    }\n\n    /**\n     * @param {THREE.Vector3} cameraWorld\n     * @param {THREE.Vector3} planetCenterW\n     * @param {THREE.Vector3} sunDirWorld\n     * @param {THREE.Matrix4} planetMatrixInverse - world -> planet-local (rotation used)\n     * @param {number} timeSec\n     */\n    update(cameraWorld, planetCenterW, sunDirWorld, planetMatrixInverse, timeSec, depthSource = null) {\n        if (!this.enabled || !this.mesh) return;\n\n        const now = Date.now();\n        const stale = now - this._lastFetchMs > REFRESH_MS;\n        const retryPending = this._nextRetryMs > now;\n        const retryReady = this._nextRetryMs > 0 && now >= this._nextRetryMs;\n        if (!retryPending && (stale || retryReady) && !this._fetchInFlight) this._fetchData();\n\n        this.mesh.visible = true;\n        const u = this._material.uniforms;\n        u.uCameraWorld.value.copy(cameraWorld);\n        u.uPlanetCenterW.value.copy(planetCenterW);\n        u.uSunDirWorld.value.copy(sunDirWorld).normalize();\n        if (planetMatrixInverse) {\n            this._worldToLocal.setFromMatrix4(planetMatrixInverse);\n            u.uWorldToLocal.value.copy(this._worldToLocal);\n        }\n        u.uTime.value = timeSec || 0;\n        if (depthSource) {\n            this.setDepthSource(depthSource);\n        } else {\n            u.uDepthEnabled.value = 0;\n        }\n\n        // Scale the carrier shell to always enclose the camera.\n        const camDist = cameraWorld.distanceTo(planetCenterW);\n        const targetRadius = camDist + this.planetRadius + this.topAltitudeMeters;\n        this.mesh.scale.setScalar(targetRadius / this.planetRadius);\n    }\n\n    dispose() {\n        this.mesh?.parent?.remove?.(this.mesh);\n        this.mesh?.geometry?.dispose?.();\n        this._material?.dispose?.();\n        this._dataTexture?.dispose?.();\n        this.mesh = null;\n    }\n}\n","/**\n * Fire system — renders live active-fire hotspots driven by NASA FIRMS\n * (VIIRS / MODIS) active fire data, proxied through the noclip backend.\n *\n * Data: /v1/fire/detections (canonical FIRMS GeoJSON preserving platform,\n * observation time, FRP, confidence, quality flags, and provenance)\n *   Sparse point hotspots (not a smooth grid), so we splat each hotspot into an\n *   equirect accumulation grid (like OVATION for aurora) and ray-march a thin\n *   near-surface shell sampling that grid.\n *\n * This coarse accumulation shell is orbit-only. At the surface,\n * EnvironmentalOverlay owns bounded FIRMS detections as terrain-mated layered\n * flames, buoyant smoke lobes, and embers. Keeping the 0.5-degree shell out of\n * the surface view prevents a point detection from becoming a tens-of-km haze.\n *\n * Render: world-space shell scaled each frame to enclose the camera, ray-marched\n * like the aurora inscatter. Per sample we read the accumulated fire grid\n * (location + intensity), apply a surface-weighted vertical profile and animated\n * fbm flicker, and tint with a black-body ramp (deep red → orange → yellow → white).\n * Fire is visible day and night (additive), unlike the night-gated aurora.\n */\n\nimport * as THREE from 'three';\nimport { PLANET_RADIUS } from './constants.js';\nimport { getFetchQueue } from '../refactor/async/fetch/FetchQueue.js';\n\n// Backend-proxied FIRMS feed (CSV). Served by the same origin in dev (vite proxy)\n// and by the API in prod, so a relative path avoids CORS / API-key exposure.\nimport { getBackendApiBase } from '../refactor/shared/backend.js';\n\nconst FIRE_API_URL = `${getBackendApiBase()}/v1/fire/detections?min_confidence=nominal&limit=10000`;\nconst GRID_W = 720; // 0.5° longitude resolution for crisp hotspots\nconst GRID_H = 361; // -90..90 at 0.5°\nconst REFRESH_MS = 5 * 60 * 1000;\nconst RETRY_MS = 60 * 1000;\nconst TOP_ALT_M = 9000; // top of the visible fire column (near-surface)\n\nexport class FireSystem {\n    constructor({ planetRadius = PLANET_RADIUS } = {}) {\n        this.enabled = true;\n        this.planetRadius = planetRadius;\n        this.strength = 1.0;\n        this.topAltitudeMeters = TOP_ALT_M;\n        this.pathRefMeters = 60000;\n        this.depthBiasMeters = 4;\n        this.surfaceMode = false;\n\n        this._gridData = new Float32Array(GRID_W * GRID_H); // accumulated intensity 0..~1\n        this._dataTexture = new THREE.DataTexture(this._gridData, GRID_W, GRID_H, THREE.RedFormat, THREE.FloatType);\n        this._dataTexture.minFilter = THREE.LinearFilter;\n        this._dataTexture.magFilter = THREE.LinearFilter;\n        this._dataTexture.wrapS = THREE.RepeatWrapping;\n        this._dataTexture.wrapT = THREE.ClampToEdgeWrapping;\n        this._dataTexture.needsUpdate = true;\n\n        this._material = this._buildMaterial();\n        this.mesh = new THREE.Mesh(new THREE.SphereGeometry(planetRadius, 64, 32), this._material);\n        this.mesh.name = 'Fire';\n        // This is a transparent radiance carrier, not solid foreground\n        // geometry. The astronomical flare already applies physical\n        // atmosphere transmittance and must remain visible through the fire\n        // shell whenever the analytic Earth-horizon test says the sun is up.\n        this.mesh.userData.lensflare = 'no-occlusion';\n        this.mesh.renderOrder = 13;\n        this.mesh.frustumCulled = false;\n        this.mesh.visible = false;\n\n        this._worldToLocal = new THREE.Matrix3();\n        this._lastFetchMs = 0;\n        this._nextRetryMs = 0;\n        this._fetchInFlight = false;\n        this._fetchData();\n    }\n\n    _buildMaterial() {\n        return new THREE.ShaderMaterial({\n            uniforms: {\n                uFireTex: { value: this._dataTexture },\n                uCameraWorld: { value: new THREE.Vector3() },\n                uPlanetCenterW: { value: new THREE.Vector3() },\n                uSunDirWorld: { value: new THREE.Vector3(0, 0, 1) },\n                uWorldToLocal: { value: new THREE.Matrix3() },\n                uPlanetRadius: { value: this.planetRadius },\n                uTopAlt: { value: this.topAltitudeMeters },\n                uTime: { value: 0 },\n                uStrength: { value: this.strength },\n                uPathRef: { value: this.pathRefMeters },\n                uDepthTexture: { value: null },\n                uDepthResolution: { value: new THREE.Vector2(1, 1) },\n                uInvProjectionMatrix: { value: new THREE.Matrix4() },\n                uInvViewMatrix: { value: new THREE.Matrix4() },\n                uDepthEnabled: { value: 0 },\n                uDepthBias: { value: this.depthBiasMeters },\n                uSurfaceMode: { value: 0 },\n                uSurfaceFullRange: { value: 180000.0 },\n                uSurfaceMaximumRange: { value: 420000.0 }\n            },\n            vertexShader: /* glsl */`\n                #include <common>\n                #include <logdepthbuf_pars_vertex>\n\n                varying vec3 vPosW;\n                void main() {\n                    vec4 wp = modelMatrix * vec4(position, 1.0);\n                    vPosW = wp.xyz;\n                    gl_Position = projectionMatrix * viewMatrix * wp;\n                    #include <logdepthbuf_vertex>\n                }\n            `,\n            fragmentShader: /* glsl */`\n                precision highp float;\n                #include <logdepthbuf_pars_fragment>\n\n                uniform sampler2D uFireTex;\n                uniform vec3 uCameraWorld;\n                uniform vec3 uPlanetCenterW;\n                uniform vec3 uSunDirWorld;\n                uniform mat3 uWorldToLocal;\n                uniform float uPlanetRadius;\n                uniform float uTopAlt;\n                uniform float uTime;\n                uniform float uStrength;\n                uniform float uPathRef;\n                uniform sampler2D uDepthTexture;\n                uniform vec2 uDepthResolution;\n                uniform mat4 uInvProjectionMatrix;\n                uniform mat4 uInvViewMatrix;\n                uniform float uDepthEnabled;\n                uniform float uDepthBias;\n                uniform float uSurfaceMode;\n                uniform float uSurfaceFullRange;\n                uniform float uSurfaceMaximumRange;\n                varying vec3 vPosW;\n\n                #define PI 3.141592653589793\n\n                float hash(vec3 p) {\n                    p = fract(p * 0.3183099 + 0.1);\n                    p *= 17.0;\n                    return fract(p.x * p.y * p.z * (p.x + p.y + p.z));\n                }\n                float vnoise(vec3 x) {\n                    vec3 i = floor(x); vec3 f = fract(x);\n                    f = f * f * (3.0 - 2.0 * f);\n                    return mix(mix(mix(hash(i + vec3(0,0,0)), hash(i + vec3(1,0,0)), f.x),\n                                   mix(hash(i + vec3(0,1,0)), hash(i + vec3(1,1,0)), f.x), f.y),\n                               mix(mix(hash(i + vec3(0,0,1)), hash(i + vec3(1,0,1)), f.x),\n                                   mix(hash(i + vec3(0,1,1)), hash(i + vec3(1,1,1)), f.x), f.y), f.z);\n                }\n                float fbm(vec3 p) {\n                    float a = 0.5; float s = 0.0;\n                    for (int i = 0; i < 3; i++) { s += a * vnoise(p); p *= 2.02; a *= 0.5; }\n                    return s;\n                }\n\n                // Accumulated fire intensity at a planet-local direction, matching the\n                // engine's equirect convention (y = north, lon = atan(z,x), v = 0.5 - lat/PI).\n                float fireProb(vec3 dirLocal, out float lat) {\n                    vec3 n = normalize(dirLocal);\n                    lat = asin(clamp(n.y, -1.0, 1.0));\n                    float lon = atan(n.z, n.x);\n                    float u = lon / (2.0 * PI) + 0.5;\n                    float v = 0.5 - (lat / PI);\n                    return texture2D(uFireTex, vec2(fract(u + 1.0), clamp(v, 0.0, 1.0))).r;\n                }\n\n                // Black-body-ish ramp: deep red (cool/low) → orange → yellow → white-hot.\n                vec3 fireColor(float intensity, float alt) {\n                    vec3 deepRed = vec3(0.55, 0.04, 0.01);\n                    vec3 orange  = vec3(1.00, 0.35, 0.05);\n                    vec3 yellow  = vec3(1.00, 0.80, 0.25);\n                    vec3 white   = vec3(1.00, 0.95, 0.80);\n                    vec3 c = mix(deepRed, orange, smoothstep(0.05, 0.35, intensity));\n                    c = mix(c, yellow, smoothstep(0.35, 0.70, intensity));\n                    c = mix(c, white, smoothstep(0.70, 1.0, intensity));\n                    // hotter cores sit slightly lower; cooler smoke-tinged tops fade red\n                    c = mix(c, deepRed * 0.6, smoothstep(uTopAlt * 0.6, uTopAlt, alt) * 0.4);\n                    return c;\n                }\n\n                float terrainDepthDistance(vec2 uv) {\n                    if (uDepthEnabled < 0.5) return 1.0e20;\n                    if (uv.x < 0.0 || uv.y < 0.0 || uv.x > 1.0 || uv.y > 1.0) return 1.0e20;\n\n                    float depthSample = texture2D(uDepthTexture, uv).x;\n                    if (depthSample >= 0.999999) return 1.0e20;\n\n                    #if defined(USE_LOGDEPTHBUF) || defined(USE_LOGARITHMIC_DEPTH_BUFFER)\n                        float viewZ = exp2(depthSample * 2.0 / logDepthBufFC) - 1.0;\n                        vec4 viewRay = uInvProjectionMatrix * vec4(uv * 2.0 - 1.0, 1.0, 1.0);\n                        vec3 rayDirView = normalize(viewRay.xyz / max(abs(viewRay.w), 1.0e-6));\n                        float denom = max(-rayDirView.z, 1.0e-6);\n                        return viewZ / denom;\n                    #else\n                        vec4 clip = vec4(uv * 2.0 - 1.0, depthSample * 2.0 - 1.0, 1.0);\n                        vec4 viewPos = uInvProjectionMatrix * clip;\n                        viewPos /= max(abs(viewPos.w), 1.0e-6);\n                        vec4 worldPos = uInvViewMatrix * viewPos;\n                        return length(worldPos.xyz - uCameraWorld);\n                    #endif\n                }\n\n                void main() {\n                    vec3 rd = normalize(vPosW - uCameraWorld);\n                    vec3 oc = uCameraWorld - uPlanetCenterW;\n                    float bdot = dot(oc, rd);\n                    float oc2 = dot(oc, oc);\n                    float R = uPlanetRadius;\n                    float Ro = R + uTopAlt;\n\n                    float discO = bdot * bdot - (oc2 - Ro * Ro);\n                    if (discO <= 0.0) discard;\n                    float sq = sqrt(discO);\n                    float tEnter = max(-bdot - sq, 0.0);\n                    float tExit = -bdot + sq;\n                    if (tExit <= tEnter) discard;\n\n                    // Stop at the near ground hit so the far-side hotspots stay occluded.\n                    float discG = bdot * bdot - (oc2 - R * R);\n                    if (discG > 0.0) {\n                        float tg = -bdot - sqrt(discG);\n                        if (tg > 0.0) tExit = min(tExit, tg);\n                    }\n\n                    vec2 depthUv = gl_FragCoord.xy / max(uDepthResolution, vec2(1.0));\n                    float tDepth = terrainDepthDistance(depthUv);\n                    if (tDepth < 1.0e19) {\n                        // Occlude fire behind terrain (orbital + surface).\n                        tExit = min(tExit, max(0.0, tDepth - uDepthBias));\n                        // Surface mode: fire rises FROM the terrain surface, engulfing the\n                        // topology boundary instead of starting at sea level.\n                        if (uSurfaceMode > 0.5) {\n                            tEnter = max(tEnter, max(0.0, tDepth - uDepthBias));\n                        }\n                    }\n                    if (tExit <= tEnter) discard;\n\n                    const int STEPS = 24;\n                    float dt = (tExit - tEnter) / float(STEPS);\n                    vec3 colAccum = vec3(0.0);\n                    float densAccum = 0.0;\n\n                    for (int i = 0; i < STEPS; i++) {\n                        float t = tEnter + (float(i) + 0.5) * dt;\n                        vec3 p = oc + rd * t;            // relative to planet centre (world)\n                        float alt = length(p) - R;\n                        if (alt < 0.0 || alt > uTopAlt) continue;\n                        float regionalAlpha = 1.0;\n                        if (uSurfaceMode > 0.5) {\n                            float centralAngle = acos(clamp(dot(\n                                normalize(oc),\n                                normalize(p)\n                            ), -1.0, 1.0));\n                            regionalAlpha = 1.0 - smoothstep(\n                                uSurfaceFullRange,\n                                uSurfaceMaximumRange,\n                                centralAngle * R\n                            );\n                            if (regionalAlpha <= 0.001) continue;\n                        }\n\n                        vec3 pLocal = uWorldToLocal * p;\n                        float lat;\n                        float prob = fireProb(pLocal, lat);\n                        if (prob < 0.01) continue;       // outside any hotspot — skip noise\n\n                        // Vertical profile: fire is densest at the surface and falls off\n                        // with altitude (buoyant plume). Surface mode keeps it hugging terrain.\n                        float vert = exp(-alt / max(uTopAlt * 0.35, 1.0));\n                        if (vert <= 0.001) continue;\n\n                        // Animated flicker: domain-warped fbm driven by time + hotspot seed.\n                        vec3 nd = normalize(pLocal);\n                        float lon = atan(nd.z, nd.x);\n                        float seed = prob * 6.2831;\n                        float flick = 0.55 + 0.45 * fbm(vec3(lon * 9.0, lat * 22.0, uTime * 0.6 + seed));\n                        flick *= 0.7 + 0.3 * fbm(vec3(lon * 30.0, lat * 60.0, uTime * 1.3 + seed));\n\n                        float w = prob * vert * flick * regionalAlpha;\n                        if (w <= 0.0) continue;\n                        colAccum += fireColor(prob, alt) * w;\n                        densAccum += w;\n                    }\n                    if (densAccum <= 0.0) discard;\n                    float intensity = clamp(uStrength * (densAccum * dt) / uPathRef, 0.0, 1.0);\n                    if (intensity <= 0.0) discard;\n                    vec3 color = colAccum / densAccum;\n                    gl_FragColor = vec4(color * intensity, intensity);\n                }\n            `,\n            transparent: true,\n            blending: THREE.AdditiveBlending,\n            depthWrite: false,\n            depthTest: false,\n            side: THREE.BackSide,\n            toneMapped: false\n        });\n    }\n\n    /** Parse canonical FIRMS GeoJSON into the equirect accumulation grid. */\n    async _fetchData() {\n        if (this._fetchInFlight || typeof fetch !== 'function') return;\n        this._fetchInFlight = true;\n        try {\n            const response = await getFetchQueue().fetchText(FIRE_API_URL, { mode: 'cors' });\n            if (!response.ok) {\n                throw response.error || new Error(`FIRMS fetch failed: ${response.status}`);\n            }\n            const payload = JSON.parse(response.text);\n            const features = Array.isArray(payload?.features) ? payload.features : [];\n            if (!features.length) throw new Error('FIRMS payload has no detections');\n\n            this._gridData.fill(0);\n            const splatR = 2; // cells\n            for (const feature of features) {\n                const coordinates = feature?.geometry?.coordinates;\n                const lon = Number(coordinates?.[0]);\n                const lat = Number(coordinates?.[1]);\n                if (!Number.isFinite(lat) || !Number.isFinite(lon)) continue;\n                const frp = Number(feature?.properties?.frp_mw);\n                const bright = Number(feature?.properties?.brightness_kelvin);\n                // Intensity: prefer FRP (fire radiative power, MW), fall back to brightness (K).\n                let intensity = 0;\n                if (Number.isFinite(frp) && frp > 0) intensity = Math.min(frp / 120, 1.0);\n                else if (Number.isFinite(bright) && bright > 0) intensity = Math.min((bright - 300) / 200, 1.0);\n                if (intensity <= 0) continue;\n\n                const gx = Math.round((lon + 180) * (GRID_W / 360));\n                const gy = Math.round((90 - lat) * (GRID_H / 181));\n                const cx = ((gx % GRID_W) + GRID_W) % GRID_W;\n                const cy = THREE.MathUtils.clamp(gy, 0, GRID_H - 1);\n                for (let dy = -splatR; dy <= splatR; dy++) {\n                    const yy = cy + dy;\n                    if (yy < 0 || yy >= GRID_H) continue;\n                    for (let dx = -splatR; dx <= splatR; dx++) {\n                        const xx = ((cx + dx) % GRID_W + GRID_W) % GRID_W;\n                        const d2 = dx * dx + dy * dy;\n                        const w = Math.exp(-d2 / (splatR * splatR * 0.6));\n                        const idx = yy * GRID_W + xx;\n                        this._gridData[idx] = Math.min(1.0, this._gridData[idx] + intensity * w);\n                    }\n                }\n            }\n            this._dataTexture.needsUpdate = true;\n            this._lastFetchMs = Date.now();\n            this._nextRetryMs = 0;\n        } catch (error) {\n            console.warn('[Fire] FIRMS fetch failed', error);\n            this._nextRetryMs = Date.now() + RETRY_MS;\n        } finally {\n            this._fetchInFlight = false;\n        }\n    }\n\n    setEnabled(enabled) {\n        this.enabled = !!enabled;\n        if (!this.enabled && this.mesh) this.mesh.visible = false;\n    }\n\n    setStrength(value) {\n        if (!Number.isFinite(value)) return;\n        this.strength = THREE.MathUtils.clamp(value, 0, 3);\n        if (this._material?.uniforms?.uStrength) {\n            this._material.uniforms.uStrength.value = this.strength;\n        }\n    }\n\n    setSurfaceMode(enabled) {\n        this.surfaceMode = !!enabled;\n        if (this._material?.uniforms?.uSurfaceMode) {\n            this._material.uniforms.uSurfaceMode.value = this.surfaceMode ? 1 : 0;\n        }\n    }\n\n    applyConfig(config = {}) {\n        if (!config || typeof config !== 'object') return;\n        if (typeof config.enabled === 'boolean') this.setEnabled(config.enabled);\n        if (Number.isFinite(config.strength) || Number.isFinite(config.intensity)) {\n            this.setStrength(Number.isFinite(config.strength) ? config.strength : config.intensity);\n        }\n        const topAltitude = Number(config.topAltitudeMeters ?? config.topAltMeters ?? config.topAlt);\n        if (Number.isFinite(topAltitude)) {\n            this.topAltitudeMeters = THREE.MathUtils.clamp(topAltitude, 1000, 60000);\n            this._material.uniforms.uTopAlt.value = this.topAltitudeMeters;\n        }\n        const pathRef = Number(config.pathRefMeters ?? config.pathRef);\n        if (Number.isFinite(pathRef)) {\n            this.pathRefMeters = THREE.MathUtils.clamp(pathRef, 10000, 500000);\n            this._material.uniforms.uPathRef.value = this.pathRefMeters;\n        }\n        const depthBias = Number(config.depthBiasMeters ?? config.depthBias);\n        if (Number.isFinite(depthBias)) {\n            this.depthBiasMeters = THREE.MathUtils.clamp(depthBias, 0, 200);\n            this._material.uniforms.uDepthBias.value = this.depthBiasMeters;\n        }\n        if (typeof config.surfaceMode === 'boolean') this.setSurfaceMode(config.surfaceMode);\n    }\n\n    getConfig() {\n        return {\n            enabled: this.enabled,\n            strength: this.strength,\n            topAltitudeMeters: this.topAltitudeMeters,\n            pathRefMeters: this.pathRefMeters,\n            depthBiasMeters: this.depthBiasMeters,\n            surfaceMode: this.surfaceMode\n        };\n    }\n\n    setDepthSource({\n        depthTexture = null,\n        resolution = null,\n        invProjectionMatrix = null,\n        invViewMatrix = null,\n        enabled = false\n    } = {}) {\n        if (!this._material?.uniforms) return;\n        const u = this._material.uniforms;\n        u.uDepthTexture.value = depthTexture || null;\n        u.uDepthEnabled.value = enabled && depthTexture ? 1 : 0;\n        if (resolution) {\n            if (Number.isFinite(resolution.x) && Number.isFinite(resolution.y)) {\n                u.uDepthResolution.value.set(Math.max(1, resolution.x), Math.max(1, resolution.y));\n            } else if (Number.isFinite(resolution.width) && Number.isFinite(resolution.height)) {\n                u.uDepthResolution.value.set(Math.max(1, resolution.width), Math.max(1, resolution.height));\n            }\n        }\n        if (invProjectionMatrix) u.uInvProjectionMatrix.value.copy(invProjectionMatrix);\n        if (invViewMatrix) u.uInvViewMatrix.value.copy(invViewMatrix);\n    }\n\n    /**\n     * @param {THREE.Vector3} cameraWorld\n     * @param {THREE.Vector3} planetCenterW\n     * @param {THREE.Vector3} sunDirWorld\n     * @param {THREE.Matrix4} planetMatrixInverse - world -> planet-local (rotation used)\n     * @param {number} timeSec\n     * @param {object|null} depthSource\n     * @param {boolean} surfaceMode\n     */\n    update(cameraWorld, planetCenterW, sunDirWorld, planetMatrixInverse, timeSec, depthSource = null, surfaceMode = false) {\n        if (!this.enabled || !this.mesh) return;\n\n        const now = Date.now();\n        const stale = now - this._lastFetchMs > REFRESH_MS;\n        const retryPending = this._nextRetryMs > now;\n        const retryReady = this._nextRetryMs > 0 && now >= this._nextRetryMs;\n        if (!retryPending && (stale || retryReady) && !this._fetchInFlight) this._fetchData();\n\n        this.setSurfaceMode(surfaceMode);\n        if (surfaceMode) {\n            // Surface fire is rendered from the exact bounded FIRMS features by\n            // EnvironmentalOverlay and hardware-depth-tested against the live\n            // photoreal tiles. The coarse global grid is an orbital context\n            // product and must not impersonate local fire extent.\n            this.mesh.visible = false;\n            return;\n        }\n        this.mesh.visible = true;\n        const u = this._material.uniforms;\n        u.uCameraWorld.value.copy(cameraWorld);\n        u.uPlanetCenterW.value.copy(planetCenterW);\n        u.uSunDirWorld.value.copy(sunDirWorld).normalize();\n        if (planetMatrixInverse) {\n            this._worldToLocal.setFromMatrix4(planetMatrixInverse);\n            u.uWorldToLocal.value.copy(this._worldToLocal);\n        }\n        u.uTime.value = timeSec || 0;\n        if (depthSource) {\n            this.setDepthSource(depthSource);\n        } else {\n            u.uDepthEnabled.value = 0;\n        }\n\n        // Scale the carrier shell to always enclose the camera.\n        const camDist = cameraWorld.distanceTo(planetCenterW);\n        const targetRadius = camDist + this.planetRadius + this.topAltitudeMeters;\n        this.mesh.scale.setScalar(targetRadius / this.planetRadius);\n    }\n\n    dispose() {\n        this.mesh?.parent?.remove?.(this.mesh);\n        this.mesh?.geometry?.dispose?.();\n        this._material?.dispose?.();\n        this._dataTexture?.dispose?.();\n        this.mesh = null;\n    }\n}\n","/**\n * NOAA HMS smoke-volume renderer.\n *\n * HMS polygons are analyst-interpreted 2D plume extent with qualitative\n * light/medium/heavy density. This system preserves that meaning: polygons are\n * rasterized into a planet-fixed mask, then ray-marched through a configurable\n * atmospheric column. The vertical structure is a visual volume, never exposed\n * as measured PM2.5 or an observed plume altitude.\n */\n\nimport * as THREE from 'three';\nimport {\n  EARTH_PRIME_MERIDIAN_OFFSET_RAD,\n  PLANET_RADIUS,\n} from './constants.js';\n\nconst MASK_WIDTH = 2048;\nconst MASK_HEIGHT = 1024;\nconst DEFAULT_TOP_ALTITUDE_M = 14_000;\n\nfunction densityByte(value) {\n  if (value === 'heavy') return 255;\n  if (value === 'medium') return 172;\n  if (value === 'light') return 88;\n  return 56;\n}\n\nfunction polygonsOf(geometry) {\n  if (geometry?.type === 'Polygon') return [geometry.coordinates];\n  if (geometry?.type === 'MultiPolygon') return geometry.coordinates;\n  return [];\n}\n\nfunction unwrapRing(ring, width) {\n  const points = [];\n  let previous = null;\n  let wrap = 0;\n  for (const coordinate of ring || []) {\n    const lon = Number(coordinate?.[0]);\n    const lat = Number(coordinate?.[1]);\n    if (!Number.isFinite(lon) || !Number.isFinite(lat)) continue;\n    let x = ((lon + 180) / 360) * width;\n    if (previous !== null) {\n      const delta = x + wrap - previous;\n      if (delta > width / 2) wrap -= width;\n      else if (delta < -width / 2) wrap += width;\n    }\n    x += wrap;\n    previous = x;\n    points.push([x, ((90 - lat) / 180) * MASK_HEIGHT]);\n  }\n  return points;\n}\n\nexport class SmokeSystem {\n  constructor({ planetRadius = PLANET_RADIUS } = {}) {\n    this.planetRadius = planetRadius;\n    this.enabled = false;\n    this.strength = 0.82;\n    this.topAltitudeMeters = DEFAULT_TOP_ALTITUDE_M;\n    this.depthBiasMeters = 8;\n    this.surfaceMode = false;\n    this.observationTime = null;\n    this.featureCount = 0;\n\n    this._mask = new Uint8Array(MASK_WIDTH * MASK_HEIGHT);\n    this._maskTexture = new THREE.DataTexture(\n      this._mask,\n      MASK_WIDTH,\n      MASK_HEIGHT,\n      THREE.RedFormat,\n      THREE.UnsignedByteType,\n    );\n    this._maskTexture.minFilter = THREE.LinearFilter;\n    this._maskTexture.magFilter = THREE.LinearFilter;\n    this._maskTexture.wrapS = THREE.RepeatWrapping;\n    this._maskTexture.wrapT = THREE.ClampToEdgeWrapping;\n    this._maskTexture.needsUpdate = true;\n\n    this._material = this._buildMaterial();\n    this.mesh = new THREE.Mesh(\n      new THREE.SphereGeometry(planetRadius, 64, 32),\n      this._material,\n    );\n    this.mesh.name = 'HMS Smoke Volume';\n    this.mesh.renderOrder = 12;\n    this.mesh.frustumCulled = false;\n    this.mesh.visible = false;\n\n    this._worldToLocal = new THREE.Matrix3();\n  }\n\n  _buildMaterial() {\n    return new THREE.ShaderMaterial({\n      uniforms: {\n        uSmokeMask: { value: this._maskTexture },\n        uCameraWorld: { value: new THREE.Vector3() },\n        uPlanetCenterW: { value: new THREE.Vector3() },\n        uSunDirWorld: { value: new THREE.Vector3(0, 0, 1) },\n        uWorldToLocal: { value: new THREE.Matrix3() },\n        uPlanetRadius: { value: this.planetRadius },\n        uTopAltitude: { value: this.topAltitudeMeters },\n        uPrimeOffset: { value: EARTH_PRIME_MERIDIAN_OFFSET_RAD || 0 },\n        uTime: { value: 0 },\n        uStrength: { value: this.strength },\n        uDepthTexture: { value: null },\n        uDepthResolution: { value: new THREE.Vector2(1, 1) },\n        uInvProjectionMatrix: { value: new THREE.Matrix4() },\n        uInvViewMatrix: { value: new THREE.Matrix4() },\n        uDepthEnabled: { value: 0 },\n        uDepthBias: { value: this.depthBiasMeters },\n        uSurfaceMode: { value: 0 },\n        uSurfaceFullRange: { value: 350_000 },\n        uSurfaceMaximumRange: { value: 700_000 },\n      },\n      vertexShader: /* glsl */`\n        #include <common>\n        #include <logdepthbuf_pars_vertex>\n        varying vec3 vPositionWorld;\n        void main() {\n          vec4 world = modelMatrix * vec4(position, 1.0);\n          vPositionWorld = world.xyz;\n          gl_Position = projectionMatrix * viewMatrix * world;\n          #include <logdepthbuf_vertex>\n        }\n      `,\n      fragmentShader: /* glsl */`\n        precision highp float;\n        #include <logdepthbuf_pars_fragment>\n        uniform sampler2D uSmokeMask;\n        uniform vec3 uCameraWorld;\n        uniform vec3 uPlanetCenterW;\n        uniform vec3 uSunDirWorld;\n        uniform mat3 uWorldToLocal;\n        uniform float uPlanetRadius;\n        uniform float uTopAltitude;\n        uniform float uPrimeOffset;\n        uniform float uTime;\n        uniform float uStrength;\n        uniform sampler2D uDepthTexture;\n        uniform vec2 uDepthResolution;\n        uniform mat4 uInvProjectionMatrix;\n        uniform mat4 uInvViewMatrix;\n        uniform float uDepthEnabled;\n        uniform float uDepthBias;\n        uniform float uSurfaceMode;\n        uniform float uSurfaceFullRange;\n        uniform float uSurfaceMaximumRange;\n        varying vec3 vPositionWorld;\n\n        #define PI 3.141592653589793\n\n        float hash31(vec3 p) {\n          p = fract(p * 0.1031);\n          p += dot(p, p.yzx + 33.33);\n          return fract((p.x + p.y) * p.z);\n        }\n        float noise3(vec3 p) {\n          vec3 i = floor(p);\n          vec3 f = fract(p);\n          f = f * f * (3.0 - 2.0 * f);\n          return mix(\n            mix(mix(hash31(i), hash31(i + vec3(1,0,0)), f.x),\n                mix(hash31(i + vec3(0,1,0)), hash31(i + vec3(1,1,0)), f.x), f.y),\n            mix(mix(hash31(i + vec3(0,0,1)), hash31(i + vec3(1,0,1)), f.x),\n                mix(hash31(i + vec3(0,1,1)), hash31(i + vec3(1,1,1)), f.x), f.y),\n            f.z\n          );\n        }\n        float fbm(vec3 p) {\n          float value = 0.0;\n          float amplitude = 0.5;\n          for (int i = 0; i < 4; i++) {\n            value += amplitude * noise3(p);\n            p = p * 2.03 + vec3(11.7, 3.4, 7.9);\n            amplitude *= 0.5;\n          }\n          return value;\n        }\n        float smokeMask(vec3 localDirection) {\n          vec3 n = normalize(localDirection);\n          float longitude = atan(n.x, n.z) + uPrimeOffset;\n          float latitude = asin(clamp(n.y, -1.0, 1.0));\n          vec2 uv = vec2(fract(longitude / (2.0 * PI) + 1.5), 0.5 - latitude / PI);\n          return texture2D(uSmokeMask, uv).r;\n        }\n        float terrainDepthDistance(vec2 uv) {\n          if (uDepthEnabled < 0.5) return 1.0e20;\n          float depth = texture2D(uDepthTexture, uv).x;\n          if (depth >= 0.999999) return 1.0e20;\n          #if defined(USE_LOGDEPTHBUF) || defined(USE_LOGARITHMIC_DEPTH_BUFFER)\n            float viewZ = exp2(depth * 2.0 / logDepthBufFC) - 1.0;\n            vec4 viewRay = uInvProjectionMatrix * vec4(uv * 2.0 - 1.0, 1.0, 1.0);\n            vec3 directionView = normalize(viewRay.xyz / max(abs(viewRay.w), 1.0e-6));\n            return viewZ / max(-directionView.z, 1.0e-6);\n          #else\n            vec4 clip = vec4(uv * 2.0 - 1.0, depth * 2.0 - 1.0, 1.0);\n            vec4 viewPosition = uInvProjectionMatrix * clip;\n            viewPosition /= max(abs(viewPosition.w), 1.0e-6);\n            vec4 worldPosition = uInvViewMatrix * viewPosition;\n            return length(worldPosition.xyz - uCameraWorld);\n          #endif\n        }\n        void main() {\n          vec3 rayDirection = normalize(vPositionWorld - uCameraWorld);\n          vec3 origin = uCameraWorld - uPlanetCenterW;\n          float projection = dot(origin, rayDirection);\n          float outerRadius = uPlanetRadius + uTopAltitude;\n          float outerDisc = projection * projection\n            - (dot(origin, origin) - outerRadius * outerRadius);\n          if (outerDisc <= 0.0) discard;\n          float outerRoot = sqrt(outerDisc);\n          float t0 = max(0.0, -projection - outerRoot);\n          float t1 = -projection + outerRoot;\n\n          float innerDisc = projection * projection\n            - (dot(origin, origin) - uPlanetRadius * uPlanetRadius);\n          if (innerDisc > 0.0) {\n            float terrainSphere = -projection - sqrt(innerDisc);\n            if (terrainSphere > 0.0) t1 = min(t1, terrainSphere);\n          }\n          float terrainDepth = terrainDepthDistance(\n            gl_FragCoord.xy / max(uDepthResolution, vec2(1.0))\n          );\n          if (terrainDepth < 1.0e19) t1 = min(t1, max(0.0, terrainDepth - uDepthBias));\n          if (t1 <= t0) discard;\n\n          const int STEPS = 40;\n          float stepLength = (t1 - t0) / float(STEPS);\n          vec3 accumulatedColor = vec3(0.0);\n          float accumulatedAlpha = 0.0;\n          for (int i = 0; i < STEPS; i++) {\n            float t = t0 + (float(i) + 0.5) * stepLength;\n            vec3 worldPosition = uCameraWorld + rayDirection * t;\n            vec3 planetPosition = worldPosition - uPlanetCenterW;\n            float altitude = length(planetPosition) - uPlanetRadius;\n            if (altitude < 0.0 || altitude > uTopAltitude) continue;\n            float regionalAlpha = 1.0;\n            if (uSurfaceMode > 0.5) {\n              float centralAngle = acos(clamp(dot(\n                normalize(origin),\n                normalize(planetPosition)\n              ), -1.0, 1.0));\n              regionalAlpha = 1.0 - smoothstep(\n                uSurfaceFullRange,\n                uSurfaceMaximumRange,\n                centralAngle * uPlanetRadius\n              );\n              if (regionalAlpha <= 0.001) continue;\n            }\n            vec3 localPosition = uWorldToLocal * planetPosition;\n            float classMask = smokeMask(localPosition);\n            if (classMask < 0.015) continue;\n\n            float normalizedAltitude = altitude / max(uTopAltitude, 1.0);\n            float vertical = smoothstep(1.0, 0.58, normalizedAltitude)\n              * smoothstep(0.0, 0.045, normalizedAltitude + 0.02);\n            vec3 domain = normalize(localPosition) * 86.0\n              + vec3(0.018 * uTime, 0.006 * uTime, -0.012 * uTime)\n              + vec3(0.0, normalizedAltitude * 9.0, 0.0);\n            float structure = smoothstep(0.27, 0.82, fbm(domain));\n            float density = classMask * vertical * mix(0.3, 1.0, structure);\n            density *= uStrength * regionalAlpha;\n\n            vec3 normalWorld = normalize(planetPosition);\n            float daylight = smoothstep(-0.22, 0.36, dot(normalWorld, normalize(uSunDirWorld)));\n            vec3 lightSmoke = mix(vec3(0.18, 0.17, 0.16), vec3(0.73, 0.76, 0.77), daylight);\n            vec3 heavySmoke = mix(vec3(0.08, 0.075, 0.07), vec3(0.31, 0.30, 0.28), daylight);\n            vec3 sampleColor = mix(lightSmoke, heavySmoke, smoothstep(0.55, 0.9, classMask));\n            float sampleAlpha = 1.0 - exp(-density * stepLength / 5200.0);\n            sampleAlpha *= (1.0 - accumulatedAlpha);\n            accumulatedColor += sampleColor * sampleAlpha;\n            accumulatedAlpha += sampleAlpha;\n            if (accumulatedAlpha > 0.985) break;\n          }\n          if (accumulatedAlpha < 0.004) discard;\n          gl_FragColor = vec4(accumulatedColor / max(accumulatedAlpha, 1.0e-4), accumulatedAlpha);\n          #include <logdepthbuf_fragment>\n        }\n      `,\n      transparent: true,\n      depthWrite: false,\n      depthTest: false,\n      side: THREE.BackSide,\n      blending: THREE.NormalBlending,\n      toneMapped: true,\n    });\n  }\n\n  setFeatures(features = [], metadata = {}) {\n    this._mask.fill(0);\n    this.featureCount = 0;\n    this.observationTime = metadata.observation_time || metadata.observationTime || null;\n    if (typeof document === 'undefined') {\n      this._maskTexture.needsUpdate = true;\n      return;\n    }\n    const canvas = document.createElement('canvas');\n    canvas.width = MASK_WIDTH;\n    canvas.height = MASK_HEIGHT;\n    const context = canvas.getContext('2d', { willReadFrequently: true });\n    if (!context) return;\n    context.clearRect(0, 0, MASK_WIDTH, MASK_HEIGHT);\n\n    const ordered = [...features].sort((a, b) => (\n      densityByte(a?.properties?.smoke_density) - densityByte(b?.properties?.smoke_density)\n    ));\n    for (const feature of ordered) {\n      const polygons = polygonsOf(feature?.geometry);\n      if (!polygons.length) continue;\n      const byte = densityByte(feature?.properties?.smoke_density);\n      context.fillStyle = `rgb(${byte},0,0)`;\n      for (const polygon of polygons) {\n        const unwrapped = polygon.map((ring) => unwrapRing(ring, MASK_WIDTH));\n        for (const shift of [-MASK_WIDTH, 0, MASK_WIDTH]) {\n          context.beginPath();\n          for (const ring of unwrapped) {\n            if (ring.length < 3) continue;\n            context.moveTo(ring[0][0] + shift, ring[0][1]);\n            for (let i = 1; i < ring.length; i += 1) {\n              context.lineTo(ring[i][0] + shift, ring[i][1]);\n            }\n            context.closePath();\n          }\n          context.fill('evenodd');\n        }\n      }\n      this.featureCount += 1;\n    }\n    const rgba = context.getImageData(0, 0, MASK_WIDTH, MASK_HEIGHT).data;\n    for (let i = 0, p = 0; i < this._mask.length; i += 1, p += 4) {\n      this._mask[i] = rgba[p];\n    }\n    this._maskTexture.needsUpdate = true;\n    this.mesh.visible = this.enabled && this.featureCount > 0;\n  }\n\n  setEnabled(enabled) {\n    this.enabled = !!enabled;\n    this.mesh.visible = this.enabled && this.featureCount > 0;\n  }\n\n  applyConfig(config = {}) {\n    if (typeof config.enabled === 'boolean') this.setEnabled(config.enabled);\n    if (Number.isFinite(config.strength)) {\n      this.strength = THREE.MathUtils.clamp(config.strength, 0, 2);\n      this._material.uniforms.uStrength.value = this.strength;\n    }\n    if (Number.isFinite(config.topAltitudeMeters)) {\n      this.topAltitudeMeters = THREE.MathUtils.clamp(config.topAltitudeMeters, 1000, 40_000);\n      this._material.uniforms.uTopAltitude.value = this.topAltitudeMeters;\n    }\n    if (Number.isFinite(config.depthBiasMeters)) {\n      this.depthBiasMeters = THREE.MathUtils.clamp(config.depthBiasMeters, 0, 200);\n      this._material.uniforms.uDepthBias.value = this.depthBiasMeters;\n    }\n  }\n\n  setDepthSource(source = null) {\n    const uniforms = this._material.uniforms;\n    if (!source?.depthTexture || source.enabled === false) {\n      uniforms.uDepthEnabled.value = 0;\n      return;\n    }\n    uniforms.uDepthTexture.value = source.depthTexture;\n    uniforms.uDepthEnabled.value = 1;\n    const resolution = source.resolution;\n    if (resolution) {\n      uniforms.uDepthResolution.value.set(\n        Math.max(1, resolution.x ?? resolution.width ?? 1),\n        Math.max(1, resolution.y ?? resolution.height ?? 1),\n      );\n    }\n    if (source.invProjectionMatrix) uniforms.uInvProjectionMatrix.value.copy(source.invProjectionMatrix);\n    if (source.invViewMatrix) uniforms.uInvViewMatrix.value.copy(source.invViewMatrix);\n  }\n\n  update(\n    cameraWorld,\n    planetCenterWorld,\n    sunDirectionWorld,\n    planetMatrixInverse,\n    timeSeconds,\n    depthSource = null,\n    surfaceMode = false,\n  ) {\n    if (!this.enabled || !this.featureCount || !this.mesh) {\n      if (this.mesh) this.mesh.visible = false;\n      return;\n    }\n    const uniforms = this._material.uniforms;\n    this.mesh.visible = true;\n    uniforms.uCameraWorld.value.copy(cameraWorld);\n    uniforms.uPlanetCenterW.value.copy(planetCenterWorld);\n    uniforms.uSunDirWorld.value.copy(sunDirectionWorld).normalize();\n    uniforms.uTime.value = timeSeconds;\n    uniforms.uSurfaceMode.value = surfaceMode ? 1 : 0;\n    if (planetMatrixInverse) {\n      this._worldToLocal.setFromMatrix4(planetMatrixInverse);\n      uniforms.uWorldToLocal.value.copy(this._worldToLocal);\n    }\n    this.setDepthSource(depthSource);\n    const cameraDistance = cameraWorld.distanceTo(planetCenterWorld);\n    const carrierRadius = cameraDistance + this.planetRadius + this.topAltitudeMeters;\n    this.mesh.scale.setScalar(carrierRadius / this.planetRadius);\n  }\n\n  dispose() {\n    this.mesh?.parent?.remove?.(this.mesh);\n    this.mesh?.geometry?.dispose?.();\n    this._material?.dispose?.();\n    this._maskTexture?.dispose?.();\n    this.mesh = null;\n  }\n}\n","import { DataUtils, FloatType } from 'three';\nimport { yieldToEventLoop } from '../refactor/async/scheduler/BudgetScheduler.js';\n\nconst MAX_LUT_ELEMENTS = 256 * 128 * 32 * 4;\nconst BLOCK_ELEMENTS = 16_384;\nconst throwIfAborted = signal => {\n    if (signal?.aborted) throw new DOMException('Atmosphere LUT conversion aborted', 'AbortError');\n};\n\n/** Exact half→float conversion with one output allocation and small task slices.\n * Never feed the Float16Array polyfill into a native typed-array constructor:\n * its iterable path builds a multi-million-element temporary JS list.\n */\nexport async function convertHalfFloatLut(input, {\n    signal,\n    now = () => performance.now(),\n    yieldTask = () => yieldToEventLoop('user-visible'),\n} = {}) {\n    throwIfAborted(signal);\n    if (!(input instanceof Uint16Array) || input.length > MAX_LUT_ELEMENTS) {\n        throw new RangeError('Atmosphere LUT must be a bounded Uint16Array');\n    }\n    // Leave the network/decoder callback before beginning conversion.\n    await yieldTask();\n    throwIfAborted(signal);\n    const output = new Float32Array(input.length);\n    let offset = 0;\n    while (offset < input.length) {\n        const started = now();\n        do {\n            const end = Math.min(input.length, offset + BLOCK_ELEMENTS);\n            for (; offset < end; offset++) output[offset] = DataUtils.fromHalfFloat(input[offset]);\n        } while (offset < input.length && now() - started < 2);\n        if (offset < input.length) {\n            await yieldTask();\n            throwIfAborted(signal);\n        }\n    }\n    return output;\n}\n\n/** Textures are still private to the loader until every conversion completes. */\nexport async function prepareAtmosphereLuts(textures, type, options = {}) {\n    throwIfAborted(options.signal);\n    if (type !== FloatType) return textures;\n    for (const texture of new Set(Object.values(textures).filter(value => value?.isTexture))) {\n        const data = await convertHalfFloatLut(texture.image.data, options);\n        throwIfAborted(options.signal);\n        texture.image.data = data;\n        texture.type = type;\n        texture.needsUpdate = true;\n    }\n    return textures;\n}\n\nexport function disposeAtmosphereLuts(textures) {\n    for (const texture of new Set(Object.values(textures || {}).filter(value => value?.isTexture))) {\n        texture.dispose();\n        // These are exclusively owned binary LUTs, never shared ImageBitmaps.\n        if (texture.image) texture.image.data = null;\n    }\n}\n","import {patchNightAirLighting} from '../refactor/render/NightAirLighting.js';\nimport { patchPhotorealBackface, PhotorealBackfaceEffect } from '../refactor/render/PhotorealBackface.js';\nimport { wrapCloudMapSampling } from './cloud-map-sampling.js';\nimport { AIRGLOW_EMISSION_DEFAULTS, AIRGLOW_EMISSION_GLSL, NIGHT_LIMB_HAZE } from './airglow-emission.js';\nimport { CloudResolutionPolicy } from '../refactor/render/CloudResolutionPolicy.js';\nimport * as THREE from 'three';\nimport { WATER_COVERAGE_GLSL, waterCoverageUniforms } from './water-coverage.js';\nimport { WATER_REFLECTANCE_GLSL } from './water-reflectance.js';\nimport { optimizeDryWaterReflectionShader } from '../refactor/render/WaterReflectionWork.js';\nimport { NativeXRSkyMaterial } from '../refactor/vr/NativeXRSkyMaterial.js';\nimport { UnderwaterEffect } from '../refactor/render/UnderwaterEffect.js';\nimport { LocalCloudCoverField, localCloudWeight } from '../refactor/weather/LocalCloudCoverField.js';\nimport { LocalPrecipitationField } from '../refactor/weather/LocalPrecipitationField.js';\nimport { AtmosphericHorizonBlurEffect } from '../refactor/render/AtmosphericHorizonBlurEffect.js';\nimport { OceanSurfacePass } from '../refactor/render/OceanSurfacePass.js';\nimport { OceanDepthPass } from '../refactor/render/OceanDepthPass.js';\nimport { WaterReflectionCapturePass } from '../refactor/render/WaterReflectionCapturePass.js';\nimport { RainPass } from '../refactor/weather/RainPass.js';\nimport { CloudColorPass } from '../refactor/render/CloudColorPass.js';\nimport { AtmosphericEmissionPass } from '../refactor/render/AtmosphericEmissionPass.js';\nimport { DEFAULT_LOCAL_CLOUD_LAYERS, DEFAULT_CLOUD_TERRAIN_CLEARANCE, cloudLayerTopRadius } from '../refactor/weather/SceneWeatherState.js';\nimport { NightVisionEffect } from '../refactor/render/NightVisionEffect.js';\nimport { SarEffect } from '../refactor/render/SarEffect.js';\nimport { LensEffectsStage } from '../refactor/render/LensEffects.js';\nimport { CloudAtmosphereAttachments } from '../refactor/render/CloudAtmosphereAttachments.js';\nimport { patchCloudDepthReconstruction, prepareCloudFrontDepth, patchCloudShadowStorage, decodeCloudShadowDepth } from '../refactor/render/CloudDepthReconstruction.js';\nimport { validateCompiledScenePrograms } from '../refactor/render/CloudShaderProgramValidation.js';\nimport { NativeXRAtmosphereRenderer } from '../refactor/vr/NativeXRAtmosphereRenderer.js';\nimport { NativeXRClouds } from '../refactor/vr/NativeXRClouds.js';\nimport {\n    BlendFunction,\n    EffectComposer,\n    EffectPass,\n    RenderPass,\n    BloomEffect,\n    SMAAEffect,\n    SMAAPreset,\n    ToneMappingEffect,\n    ToneMappingMode,\n    MaskPass,\n    ClearMaskPass\n} from 'postprocessing';\nimport {\n    AerialPerspectiveEffect,\n    AtmosphereParameters,\n    METER_TO_LENGTH_UNIT,\n    PrecomputedTexturesLoader,\n    SkyMaterial\n} from '@takram/three-atmosphere';\nimport {\n    CLOUD_SHAPE_DETAIL_TEXTURE_SIZE,\n    CLOUD_SHAPE_TEXTURE_SIZE,\n    CloudsEffect\n} from '@takram/three-clouds';\nimport {\n    Ellipsoid,\n    STBNLoader\n} from '@takram/three-geospatial';\nimport { DitheringEffect } from '@takram/three-geospatial-effects';\nimport {\n    PLANET_RADIUS,\n    ATMOSPHERE_HEIGHT_M,\n    EARTH_PRIME_MERIDIAN_OFFSET_RAD,\n    MOON_RADIUS_M,\n} from './constants.js';\nimport { AuroraSystem } from './aurora-system.js';\nimport { FireSystem } from './fire-system.js';\nimport { SmokeSystem } from './smoke-system.js';\nimport { ellipsoidRadiusForWorldDir } from './geometry-utils.js';\nimport { resolveBackendApiUrl, hasBackendOverride } from '../refactor/shared/backend.js';\nimport { getFetchQueue } from '../refactor/async/fetch/FetchQueue.js';\nimport { prepareAtmosphereLuts, disposeAtmosphereLuts } from './atmosphere-lut-conversion.js';\nimport { getNoclipGovernanceClient } from '../refactor/shared/NoclipGovernanceClient.js';\nimport { PHOTO_DEFERRED_LIGHTING_LAYER } from '../refactor/tiles/PhotorealLightingContract.js';\nimport { preparePhotorealSurfaceVisibilityMaterial } from '../refactor/tiles/PhotorealSurfaceVisibilityContract.js';\nimport {\n    CELESTIAL_OCCLUSION_INTERSECTION_GLSL,\n    CELESTIAL_OCCLUSION_UNIFORMS_GLSL,\n    ensureCelestialOcclusionUniforms,\n    syncCelestialOcclusionUniforms,\n    syncCelestialWorldOcclusionUniforms,\n} from '../refactor/render/CelestialOcclusionContract.js';\nimport {\n    CELESTIAL_IRRADIANCE_GLSL,\n} from '../refactor/render/CelestialIrradianceContract.js';\nimport {\n    LIGHT_POLLUTION_BLOOM_DEFAULTS,\n    POSTPROCESS_BLOOM_EFFECT_DEFAULTS,\n} from '../refactor/render/PostProcessingContract.js';\nimport {\n    NIGHT_LIGHTS_EMISSION_DEFAULTS,\n    NIGHT_LIGHTS_SOURCE_SIGNAL_GLSL,\n    NIGHT_LIGHTS_SURFACE_CARRIER_GLSL,\n} from '../refactor/render/NightLightsEmissionContract.js';\nimport { NIGHT_LIGHTS_GEOGRAPHY_GLSL } from '../refactor/imagery/NightLightsGeoreference.js';\nimport { bindNightCloudLighting, NIGHT_CLOUD_LIGHTING_GLSL, nightCloudLightingForExistingField } from './night-cloud-lighting.js';\nimport { orbitalCloudVolumeGlsl } from './orbital-cloud-volume.js';\nimport {\n    PhotorealLightingMaskPass,\n} from '../refactor/render/PhotorealLightingMaskPass.js';\nimport {\n    MAX_SURFACE_LIGHT_EMITTERS,\n    directionFromLatLon,\n    getSurfaceLightRegistry,\n} from '../refactor/render/SurfaceLightRegistry.js';\nimport {\n    PHOTOREAL_ALBEDO_SCALE_DEFAULT,\n} from '../refactor/tiles/PhotorealAppearanceContract.js';\nimport { resolveSceneRuntimeBasePath } from '../refactor/scene/SceneRuntimeResources.js';\n\nconst DEFAULT_BASE_PATH = resolveSceneRuntimeBasePath();\nconst DEFAULT_TONE_MAPPING_EXPOSURE = 10;\nconst DEFAULT_ATMOSPHERE_BASE_OFFSET_M = 0;\nconst DEFAULT_SURFACE_ATMOSPHERE_BASE_OFFSET_M = 13000;\nconst DEFAULT_ADAPTIVE_BASE_OFFSET = Object.freeze({\n    enabled: true,\n    orbitClearanceMeters: 4800,\n    surfaceClearanceMeters: 5900,\n    minOffsetMeters: 0,\n    maxOffsetMeters: 32000,\n    updateThresholdMeters: 100,\n    maxStepMeters: 1500,\n});\n\n/**\n * Keep the spherical Takram floor a stable clearance below the actual local\n * terrain radius. This automatically accounts for WGS84 latitude depression\n * and real terrain elevation without decoding display-raster grayscale.\n */\nexport function deriveRegionalAtmosphereBaseOffsets(\n    terrainRadius,\n    config = DEFAULT_ADAPTIVE_BASE_OFFSET,\n) {\n    if (!Number.isFinite(terrainRadius) || terrainRadius <= 0) return null;\n    const minOffset = Number.isFinite(config?.minOffsetMeters)\n        ? Math.max(0, config.minOffsetMeters)\n        : DEFAULT_ADAPTIVE_BASE_OFFSET.minOffsetMeters;\n    const maxOffset = Number.isFinite(config?.maxOffsetMeters)\n        ? Math.max(minOffset, config.maxOffsetMeters)\n        : DEFAULT_ADAPTIVE_BASE_OFFSET.maxOffsetMeters;\n    const orbitClearance = Number.isFinite(config?.orbitClearanceMeters)\n        ? Math.max(0, config.orbitClearanceMeters)\n        : DEFAULT_ADAPTIVE_BASE_OFFSET.orbitClearanceMeters;\n    const surfaceClearance = Number.isFinite(config?.surfaceClearanceMeters)\n        ? Math.max(0, config.surfaceClearanceMeters)\n        : DEFAULT_ADAPTIVE_BASE_OFFSET.surfaceClearanceMeters;\n    const localDepression = PLANET_RADIUS - terrainRadius;\n    return {\n        orbit: THREE.MathUtils.clamp(localDepression + orbitClearance, minOffset, maxOffset),\n        surface: THREE.MathUtils.clamp(localDepression + surfaceClearance, minOffset, maxOffset),\n        localDepression,\n    };\n}\nconst DEFAULT_AIRGLOW_DAY_STRENGTH = 0.015;\nconst ORBIT_DAY_LIMB_RADIANCE_SCALE = 0.42;\nconst ORBIT_DAY_LIMB_LOG_CURVE = 15;\nconst DEFAULT_CLOUD_QUALITY_PRESET = 'ultra';\nconst DEFAULT_SKY_TUNING = {\n    alphaScale: 1,\n    alphaClamp: 0.85,          // Reduced from 0.95 to allow terrain to show through\n    limbBoost: 2.5,\n    pathShort: 0.25,\n    limbMax: 6,\n    densityScale: 2,\n    scaleHeight: 0.08,\n    verticalFadeStart: 0.05,\n    verticalFadeEnd: 0.4,\n    altitudeFadeStart: 0.5,    // Start fading at 50% of atmosphere height (~50km)\n    altitudeFadeEnd: 1.0,      // Fully faded at atmosphere top (~100km)\n    outsideFadeStart: 0.0,     // Continue fading immediately outside atmosphere\n    outsideFadeEnd: 0.1,       // Fully faded by 10% of atmosphere radius above (~650km)\n    depthThreshold: 0.9999999\n};\n\n// Distance tuning optimized for surface-level cloud rendering.\n// nearAltitude=0 means clouds render at full quality at ground level,\n// transitioning to orbit-optimized settings as camera climbs.\n// nearMaxRayDistance is reduced for surface (ground-to-cloud < 30km)\n// versus the orbit view where we need to see cloud edges at the limb.\nconst CLOUD_DISTANCE_TUNING = {\n    nearAltitude: 0,\n    farAltitude: 1200000,\n    nearMaxRayDistance: 60000,\n    farMaxRayDistance: 250000,\n    nearResolutionScale: 1,\n    farResolutionScale: 1,\n    cullAltitude: 1600000,\n    cullHysteresis: 150000\n};\nconst ORBIT_CLOUD_DISTANCE_TUNING = {\n    nearAltitude: 150000,\n    farAltitude: 3000000,\n    nearMaxRayDistance: 240000,\n    farMaxRayDistance: 420000,\n    nearResolutionScale: 1,\n    farResolutionScale: 1,\n    cullAltitude: 7000000,\n    cullHysteresis: 300000\n};\n// Above this camera altitude the aerial-perspective/sky effect also drops the\n// photoreal lighting mask. Surface irradiance always uses Takram's stable\n// ellipsoid normal rather than a topology-sensitive geometry/depth G-buffer.\nconst DEFAULT_CLOUD_COMPOSER_CLOUD_MAX_ALTITUDE_M = CLOUD_DISTANCE_TUNING.cullAltitude;\nconst DEFAULT_CLOUD_COMPOSER_CLOUD_HYSTERESIS_M = 100000;\n// Matches the environmental orbit-coverage enter threshold without coupling\n// the low-level atmosphere owner back to the UI/refactor package.\nconst ENVIRONMENT_SURFACE_EFFECT_MAX_ALTITUDE_M = 90_000;\nconst DEFAULT_CLOUD_SHADOW_TUNING = {\n    farScale: 0.25,\n    maxFar: 100000,\n    cascadeCount: 2,\n    mapSize: 512,\n    splitMode: 'practical',\n    splitLambda: 0.71\n};\n// Night irradiance transition range (configurable via nightIrradianceSunDotMin/Max)\nconst DEFAULT_NIGHT_IRRADIANCE_SUN_DOT_MIN = -0.2;\nconst DEFAULT_NIGHT_IRRADIANCE_SUN_DOT_MAX = 0.006;\nconst DEFAULT_NIGHT_MIN_IRRADIANCE = 0.0;  // Minimum irradiance floor at night (0 = completely dark)\nconst ORBIT_CLOUDS_BBOX = '-90,-180,90,180';\nconst ORBIT_CLOUDS_RETRY_BASE_MS = 15000;\nconst ORBIT_CLOUDS_RETRY_MAX_MS = 5 * 60 * 1000;\n// Cloud textures, 3D volumes, render targets, and shader variants are all\n// expensive on first use. Keep that work out of the animation frame that\n// crosses the orbit/surface threshold.\n// Upper bound on how long any single warm-up slice may wait for an idle\n// window. Warm-up is dozens of sequential slices, so an unbounded wait\n// multiplies into minutes under sustained photoreal streaming.\nconst CLOUD_WARMUP_IDLE_TIMEOUT_MS = 200;\n// A volumetric raymarch cannot execute off-thread in WebGL. Bound its initial\n// uniform-controlled work, then admit more while frames have headroom. Target\n// resolution is NOT an activation control: native setSize discards current,\n// resolve and temporal-history storage, creating a resize/frame-time loop.\nconst CLOUD_SURFACE_ACTIVATION_MAX_RAY_DISTANCE_M = 30_000;\nconst CLOUD_SURFACE_ACTIVATION_MAX_ITERATIONS = 64;\nconst CLOUD_SURFACE_ACTIVATION_MAX_SHADOW_LENGTH_ITERATIONS = 48;\nconst CLOUD_SURFACE_ACTIVATION_SHADOW_ITERATIONS = 12;\nconst CLOUD_SURFACE_ACTIVATION_HEADROOM_MS = 80;\nconst CLOUD_SURFACE_ACTIVATION_PROGRESS_STEP = 0.025;\nconst DEFAULT_ORBIT_CLOUDS = {\n    enabled: true,\n    opacity: 0.4,\n    radiusOffsetM: 12000,\n    fadeStartM: 150000,\n    fadeEndM: 800000,\n    refreshMinutes: 30,\n    timeStepMinutes: 1440,\n    width: 2048,\n    height: 1024,\n    layer: 'MODIS_Terra_Cloud_Fraction_Day',\n    format: 'image/png',\n    baseUrl: '/api/orbit-clouds',\n    nasaSnapshot: null,\n    alphaScale: 0.85,\n    alphaBias: 0,\n    flipY: false,\n    dateOnly: true,\n    rawOverlay: false,\n    debugOverlay: false,\n    volumetricEnabled: true,\n    qualityPreset: 'ultra',\n    resolutionScale: 1,\n    coverageScale: 0.85,\n    scatteringScale: 0.85,\n    absorptionScale: 0.9,\n    turbulenceScale: 0.6,\n    maxRayDistance: 220000,\n    cullAltitude: 7000000,\n    cullHysteresis: 300000\n};\n\n// Do not put the stock MeshBasicMaterial shader back on the orbital cloud\n// sphere. In Three r185 it includes unused normal, environment, light-map,\n// clipping, morph, skinning, fog, and dithering paths. The live ANGLE / GT 1030\n// renderer reported KHR completion and then blocked ACTIVE_UNIFORMS for 15 s on\n// that mapless program. This exact shader retains the cloud texture transform,\n// opacity, terminator fade, logarithmic depth, and output colour conversion.\nconst ORBIT_CLOUD_VERTEX_SHADER = /* glsl */`\n#define NCA_ORBIT_CLOUDS_R185\n#include <common>\n#include <logdepthbuf_pars_vertex>\nuniform mat3 mapTransform;\nvarying vec2 vOrbitCloudUv;\nvarying vec3 vOrbitNormalL;\nvoid main() {\n    vOrbitCloudUv = ( mapTransform * vec3( uv, 1.0 ) ).xy;\n    vOrbitNormalL = normalize( position );\n    #include <begin_vertex>\n    #include <project_vertex>\n    #include <logdepthbuf_vertex>\n}\n`;\n\nconst ORBIT_CLOUD_FRAGMENT_SHADER = /* glsl */`\n#define NCA_ORBIT_CLOUDS_R185\n#include <common>\n#include <logdepthbuf_pars_fragment>\nuniform sampler2D map;\nuniform vec3 diffuse;\nuniform float opacity;\nuniform vec3 uOrbitSunDir;\nuniform vec3 uOrbitNightAirglowColor;\nuniform float uOrbitNightAirglowStrength;\nuniform float uOrbitCloudHeight;\nuniform float uOrbitNightTransitionStart;\nuniform float uOrbitNightTransitionEnd;\nvarying vec2 vOrbitCloudUv;\nvarying vec3 vOrbitNormalL;\n${NIGHT_CLOUD_LIGHTING_GLSL}\nvoid main() {\n    #include <logdepthbuf_fragment>\n    vec4 cloud = texture2D( map, vOrbitCloudUv ) * vec4( diffuse, opacity );\n    float orbitDay = smoothstep(\n        uOrbitNightTransitionStart,\n        uOrbitNightTransitionEnd,\n        dot( normalize( vOrbitNormalL ), normalize( uOrbitSunDir ) )\n    );\n    vec3 orbitNightAirglow = uOrbitNightAirglowColor\n      * uOrbitNightAirglowStrength\n      + (orbitDay < .999 ? ncaNightCloudRadiance(normalize(vOrbitNormalL) * 6378137.0, uOrbitCloudHeight) : vec3(0.0));\n    float orbitCloudShade = clamp(\n      max( cloud.r, max( cloud.g, cloud.b ) ),\n      0.0,\n      1.0\n    );\n    cloud.rgb = mix(\n      orbitNightAirglow * mix( 0.7, 1.0, orbitCloudShade ),\n      cloud.rgb,\n      orbitDay\n    );\n    // Preserve the cloud's ability to occlude surface emission at night. Its\n    // visible radiance is dark; its physical coverage does not disappear.\n    cloud.a *= mix( 0.85, 1.0, orbitDay );\n    gl_FragColor = cloud;\n    #include <colorspace_fragment>\n    #include <premultiplied_alpha_fragment>\n}\n`;\n\nconst resolveOrbitCloudsBaseUrl = (rawBaseUrl) => {\n    const trimmed = (rawBaseUrl || '').trim();\n    if (!trimmed) {\n        return resolveBackendApiUrl('/api/orbit-clouds');\n    }\n    return resolveBackendApiUrl(trimmed);\n};\n\nexport class AtmosphereCloudsSystem {\n    constructor({\n        renderer,\n        scene,\n        camera,\n        lightingSystem,\n        planetGroup = null,\n        basePath = DEFAULT_BASE_PATH,\n        useToneMapping = true,\n        toneMappingMode = ToneMappingMode.AGX,\n        enableDithering = true,\n        deferCloudWarmup = false,\n        atmosphereBaseOffset = DEFAULT_ATMOSPHERE_BASE_OFFSET_M,\n        surfaceAtmosphereBaseOffset = DEFAULT_SURFACE_ATMOSPHERE_BASE_OFFSET_M\n    } = {}) {\n        if (!renderer || !scene || !camera) {\n            throw new Error('AtmosphereCloudsSystem requires renderer, scene, and camera');\n        }\n\n        this.renderer = renderer;\n        this.scene = scene;\n        this.camera = camera;\n        this.lightingSystem = lightingSystem || null;\n        this.planetGroup = planetGroup;\n        this.basePath = basePath;\n        this.useToneMapping = useToneMapping;\n        this.toneMappingMode = toneMappingMode;\n        this.enableDithering = enableDithering;\n        this.orbitAtmosphereBaseOffset = Number.isFinite(atmosphereBaseOffset)\n            ? atmosphereBaseOffset\n            : DEFAULT_ATMOSPHERE_BASE_OFFSET_M;\n        this.surfaceAtmosphereBaseOffset = Number.isFinite(surfaceAtmosphereBaseOffset)\n            ? surfaceAtmosphereBaseOffset\n            : DEFAULT_SURFACE_ATMOSPHERE_BASE_OFFSET_M;\n        this._surfaceCameraModeActive = false;\n        this.atmosphereBaseOffset = this.orbitAtmosphereBaseOffset;\n        this._adaptiveBaseOffset = { ...DEFAULT_ADAPTIVE_BASE_OFFSET };\n        this._regionalTerrainRadius = null;\n        this._regionalBaseOffsetInitialized = false;\n\n        this.enabled = true;\n        this.ready = false;\n        this._cloudWarmupDeferred = deferCloudWarmup === true;\n        this._directPhysicalSkyPrepared = false;\n\n        this.aerialPerspective = null;\n        this.clouds = null;\n        this.normalPass = null;\n        this._photoLightingMaskPass = null;\n        this._disabledPhotoGBufferTexture = null;\n        this._activePhotoLightingMask = null;\n        this._disabledPhotoLightingMask = null;\n        this.composer = null;\n        this.skyMaterial = null;\n        this.skyMesh = null;\n        this._atmosphereParams = null;\n        this._atmosphereEllipsoid = null;\n\n        this._pendingLoads = new Set();\n        this._sunDirection = new THREE.Vector3();\n        this._moonDirection = new THREE.Vector3();\n        this._cameraWorldPosition = new THREE.Vector3();\n        this._planetMatrix = new THREE.Matrix4();\n        this._planetMatrixInverse = new THREE.Matrix4();\n        this._planetCenterECEF = new THREE.Vector3();\n        this._surfaceEmitterCameraDirection = new THREE.Vector3(0, 1, 0);\n        this._surfaceEmitterScratchDirection = new THREE.Vector3();\n        this._surfaceEmitterScratchEndDirection = new THREE.Vector3();\n        this._surfaceEmitterStarts = Array.from(\n            { length: MAX_SURFACE_LIGHT_EMITTERS },\n            () => new THREE.Vector4(),\n        );\n        this._surfaceEmitterEnds = Array.from(\n            { length: MAX_SURFACE_LIGHT_EMITTERS },\n            () => new THREE.Vector4(),\n        );\n        this._surfaceEmitterColors = Array.from(\n            { length: MAX_SURFACE_LIGHT_EMITTERS },\n            () => new THREE.Vector4(),\n        );\n        this._surfaceEmitterParams = Array.from(\n            { length: MAX_SURFACE_LIGHT_EMITTERS },\n            () => new THREE.Vector4(),\n        );\n        this._surfaceEmitterCount = 0;\n        this._celestialScratchWorld = new THREE.Vector3();\n        this._celestialScratchScale = new THREE.Vector3(1, 1, 1);\n        this._moonMesh = null;\n        this._sunMesh = null;\n        this._tmpSize = new THREE.Vector2();\n        this._terrainDepthSource = {\n            depthTexture: null,\n            resolution: new THREE.Vector2(1, 1),\n            invProjectionMatrix: new THREE.Matrix4(),\n            invViewMatrix: new THREE.Matrix4(),\n            enabled: false\n        };\n        this._lastCloudMaxRayDistance = null;\n        this._lastCloudResolutionScale = null;\n        this._cloudBaseSettings = null;\n        this._cloudQualityPreset = DEFAULT_CLOUD_QUALITY_PRESET;\n        this._cloudShadowTuning = { ...DEFAULT_CLOUD_SHADOW_TUNING };\n        this._cloudLodState = { simplified: false, disabled: false };\n        this._surfaceCloudActivation = { active: false, progress: 1 };\n        this._cloudBlendFunction = BlendFunction.NORMAL;\n        this._cloudsEnabled = true;\n        this._cloudsEffectPass = null;\n        this._cloudsEffectSignature = null;\n        this._cloudEffectPassVariants = new Map();\n        this._cloudEffectPassBuilds = new Map();\n        this._cloudEffectsInitialized = false;\n        // cold / scheduled / warming / clear-ready / ready / fallback / failed\n        this._cloudWarmupState = 'cold';\n        this._cloudWarmupPromise = null;\n        this._cloudWarmupResolve = null;\n        this._cloudWarmupIdleHandle = null;\n        this._cloudWarmupIdleUsesRequestIdleCallback = false;\n        this._disposed = false;\n        this._lutConversionController = new AbortController();\n        this._precomputedTextures = null;\n        this._skyDepthPatched = false;\n        this._cloudsCameraHeightPatched = false;\n        this._cloudsCameraHeightPatchedMaterials = new WeakSet();\n        this._cloudsNightLightingPatched = false;\n        this._cloudsNightLightingPatchedMaterials = new WeakSet();\n        this._cloudsReprojectionPatched = false;\n        this._cloudsReprojectionPatchedMaterials = new WeakSet();\n        this._previousEllipsoidMatrix = new THREE.Matrix4();\n        this._lowFpsMode = false;\n        this._bloomEnabled = false;\n        this._bloomSettings = { ...POSTPROCESS_BLOOM_EFFECT_DEFAULTS };\n        this._bloomEffect = null;\n        this._lightPollutionBloomSettings = {\n            ...LIGHT_POLLUTION_BLOOM_DEFAULTS,\n        };\n        this._lightPollutionBloomEffect = null;\n        this._postEffectsPass = null;\n        this._toneMappingEffect = null;\n        this._smaaEffect = null;\n        this._ditheringEffect = null;\n        this._composerSamples = 0;\n        this._cloudRenderCadenceMs = 0;\n        this._cloudRenderCadenceBase = 0;\n        this._lastCloudRenderMs = 0;\n        // `render()` can retain ownership while deliberately reusing the\n        // previous composer output. Consumers that draw after the composer\n        // must distinguish that cadence skip from a newly written framebuffer\n        // or transparent overlays will accumulate into the retained image.\n        this._finalFrameWritten = false;\n        this._cloudComposerCloudMaxAltitudeM = DEFAULT_CLOUD_COMPOSER_CLOUD_MAX_ALTITUDE_M;\n        this._cloudComposerCloudHysteresisM = DEFAULT_CLOUD_COMPOSER_CLOUD_HYSTERESIS_M;\n        this._cloudComposerHighOrbitActive = false;\n        this._orbitalOverviewActive = false;\n        this._lastCameraAltitudeM = null;\n        this._cloudResolutionScaleBase = null;\n        this._orbitCloudResolutionScaleBase = null;\n        this._toneMappingOverridden = false;\n        this._toneMappingSnapshot = {\n            toneMapping: renderer.toneMapping,\n            exposure: renderer.toneMappingExposure\n        };\n        this._toneMappingExposureTarget = Number.isFinite(renderer.toneMappingExposure)\n            ? renderer.toneMappingExposure\n            : DEFAULT_TONE_MAPPING_EXPOSURE;\n        this._perf = null;\n        this._perfStart = () => {};\n        this._perfEnd = () => {};\n        this._defaultLocalWeatherTexture = null;\n        this._currentIrradianceScale = 1.0;\n        this._irradianceScaleBase = null;\n        this._sunIrradianceBase = null;\n        this._skyIrradianceBase = null;\n        this._baseOffsetInitialized = false;\n        this._skyTuning = { ...DEFAULT_SKY_TUNING };\n        this._tmpUpDir = new THREE.Vector3();\n\n        // Night irradiance tuning\n        this._nightIrradianceSunDotMin = DEFAULT_NIGHT_IRRADIANCE_SUN_DOT_MIN;\n        this._nightIrradianceSunDotMax = DEFAULT_NIGHT_IRRADIANCE_SUN_DOT_MAX;\n        this._nightMinIrradiance = DEFAULT_NIGHT_MIN_IRRADIANCE;\n\n        // Sky tuning\n        this._skyEnabled = true;\n        // The scene owns physical Sun and Moon meshes at astronomical scale.\n        // Takram can also synthesize both disks in getSkyRadiance(), but\n        // enabling that path alongside the meshes renders duplicate celestial\n        // bodies. Keep the saved visibility state here while one ownership\n        // method below selects exactly one disk renderer.\n        this._sunDiskEnabled = true;\n        this._moonDiskEnabled = true;\n\n        // Night airglow and aurora are dependent atmosphere systems. The\n        // master atmosphere toggle owns their visibility so they cannot remain\n        // visible after the atmospheric render path is disabled.\n        this._airglowEnabled = true;\n        this._airglowBaseAlt = AIRGLOW_EMISSION_DEFAULTS.baseAltitudeMeters;\n        this._airglowCoreAlt = AIRGLOW_EMISSION_DEFAULTS.coreAltitudeMeters;\n        this._airglowFringeAlt = AIRGLOW_EMISSION_DEFAULTS.fringeAltitudeMeters;\n        this._airglowRiseScale = AIRGLOW_EMISSION_DEFAULTS.riseScaleMeters;\n        this._airglowTailScale = AIRGLOW_EMISSION_DEFAULTS.tailScaleMeters;\n        this._airglowStrength = AIRGLOW_EMISSION_DEFAULTS.strength;\n        this._airglowDayStrength = DEFAULT_AIRGLOW_DAY_STRENGTH;\n        this._airglowPathRef = 900000;\n        this._airglowInsideMin = 0.05;\n        this._airglowInsideMax = 0.48;\n        this._airglowGrazingPower = 1.7;\n        this._airglowColHorizon = new THREE.Color(0.88, 0.80, 0.45);\n        this._airglowColCore = new THREE.Color(0.38, 1.0, 0.55);\n        this._airglowColUpper = new THREE.Color(0.85, 0.38, 0.35);\n        this._airglowColFringe = new THREE.Color(0.72, 0.52, 0.55);\n        this._auroraEnabled = true;\n        this._auroraStrength = 0.9;\n        this._auroraTopAltitudeMeters = 400000;\n        this._auroraPathRefMeters = 140000;\n        this._auroraDepthBiasMeters = 4;\n\n        // Active-fire hotspots (NASA FIRMS, proxied through the backend).\n        this._fireEnabled = true;\n        this._fireStrength = 1.0;\n        this._fireTopAltitudeMeters = 9000;\n        this._firePathRefMeters = 60000;\n        this._fireDepthBiasMeters = 4;\n        this._fireSystem = null;\n\n        // NOAA HMS analyst polygons drive this qualitative volume. It remains\n        // dormant until the environmental control plane supplies features.\n        this._smokeEnabled = false;\n        this._smokeStrength = 0.82;\n        this._smokeTopAltitudeMeters = 14000;\n        this._smokeDepthBiasMeters = 8;\n        this._smokeSystem = null;\n        this._pendingSmokeFeatures = [];\n        this._pendingSmokeMetadata = {};\n\n        // Orbit cloud overlay (global low-res coverage)\n        this._orbitClouds = { ...DEFAULT_ORBIT_CLOUDS };\n        if (typeof this._orbitClouds.nasaSnapshot !== 'boolean') {\n            const baseUrl = (this._orbitClouds.baseUrl || '').trim();\n            const usesDefaultProxy = !baseUrl || baseUrl === '/api/orbit-clouds';\n            this._orbitClouds.nasaSnapshot = baseUrl.includes('wvs.earthdata.nasa.gov')\n                || (usesDefaultProxy && !hasBackendOverride());\n        }\n        this._orbitCloudsMesh = null;\n        this._orbitCloudsMaterial = null;\n        this._orbitCloudsRawMesh = null;\n        this._orbitCloudsRawMaterial = null;\n        this._orbitCloudsGeometry = null;\n        this._orbitCloudsTexture = null;\n        this._orbitCloudsRawTexture = null;\n        this._orbitCloudsCanvas = null;\n        this._orbitCloudsRawCanvas = null;\n        this._orbitCloudsCtx = null;\n        this._orbitCloudsRawCtx = null;\n        this._orbitCloudsLastKey = null;\n        this._orbitCloudsLastFetchMs = 0;\n        this._orbitCloudsInFlight = false;\n        this._orbitCloudsRawLastKey = null;\n        this._orbitCloudsRawLastFetchMs = 0;\n        this._orbitCloudsRawInFlight = false;\n        this._orbitCloudsFailureCount = 0;\n        this._orbitCloudsNextRetryMs = 0;\n        this._orbitCloudsRawFailureCount = 0;\n        this._orbitCloudsRawNextRetryMs = 0;\n        this._orbitCloudsDirty = false;\n        this._orbitCloudsEffect = null;\n        this._orbitCloudsBaseSettings = null;\n        this._orbitCloudsLodState = { disabled: false, simplified: false };\n        this._orbitCloudsEffectPreset = null;\n        this._orbitCloudRenderEnabled = false;\n        this._pendingOrbitCloudRenderEnabled = null;\n        this._orbitCloudVisibilityIdleHandle = null;\n        this._orbitCloudVisibilityIdleUsesRequestIdleCallback = false;\n        this._orbitCloudsUvPatched = false;\n        this._lastOrbitCloudMaxRayDistance = null;\n        this._lastOrbitCloudResolutionScale = null;\n        this._earthMaterial = null;\n\n        // Terrain-aware cloud adjustment\n        // Cloud altitudes are specified as heights ABOVE LOCAL TERRAIN (0 = terrain surface)\n        // These are the user-facing values that get converted to library coordinates.\n        // Surface-optimized defaults: low clouds at ~3km, mid at ~5km, high at ~10km.\n        this._cloudLayerHeightsAboveTerrain = DEFAULT_LOCAL_CLOUD_LAYERS.map(layer => layer ? { ...layer } : null);\n        // Current terrain elevation above atmosphere bottomRadius\n        this._terrainElevation = 0;\n        // Minimum additional clearance above terrain (meters)\n        this._cloudTerrainClearance = DEFAULT_CLOUD_TERRAIN_CLEARANCE;\n    }\n\n    async init() {\n        // An async function executes synchronously until its first await. The\n        // old implementation built the entire compositor here before yielding,\n        // which put effect construction directly on the orbit -> surface\n        // transition task. Each independent construction stage now starts only\n        // after the browser has had an opportunity to present another frame.\n        // The shared physical direct sky covers clear-compositor preparation;\n        // the old shell remains only until required LUTs/sky are admitted.\n        if (!await this._runAsyncSetupStage(() => this._setupAtmosphereCore())) return;\n        if (!await this._runAsyncSetupStage(() => this._setupCloudEffects())) return;\n        if (!await this._runAsyncSetupStage(() => this._setupOrbitCloudsEffect())) return;\n        if (!await this._runAsyncSetupStage(() => this._setupComposerCore())) return;\n        if (!await this._runAsyncSetupStage(() => this._setupSkyAndAerialPass())) return;\n        if (!await this._runAsyncSetupStage(() => this._setupPostEffects())) return;\n        await this._loadTextures();\n    }\n\n    _waitForAnimationFrame() {\n        return new Promise((resolve) => {\n            // Window rAF can stop while immersive XR owns presentation. A\n            // bounded timer also settles waits queued immediately before entry.\n            let settled = false;\n            let frame = null;\n            const finish = () => {\n                if (settled) return;\n                settled = true; clearTimeout(timer);\n                if (frame !== null) window.cancelAnimationFrame?.(frame);\n                resolve();\n            };\n            const timer = setTimeout(finish, 50);\n            if (typeof window !== 'undefined' && typeof window.requestAnimationFrame === 'function') {\n                frame = window.requestAnimationFrame(() => setTimeout(finish, 0));\n                return;\n            }\n            setTimeout(finish, 0);\n        });\n    }\n\n    async _runAsyncSetupStage(stage) {\n        await this._waitForAnimationFrame();\n        if (this._disposed) return false;\n        stage();\n        return !this._disposed;\n    }\n\n    setEnabled(enabled) {\n        const next = !!enabled;\n        if (this.enabled === next) {\n            this._syncToneMappingForRenderPath();\n            return;\n        }\n        this.enabled = next;\n        this._syncToneMappingForRenderPath();\n        if (!this.enabled) {\n            this._hideAtmosphereDependents();\n        }\n        this._applySkyMeshVisibility();\n    }\n\n    setOrbitalOverviewActive(active) {\n        const next = active === true;\n        if (this._orbitalOverviewActive === next) return;\n        this._orbitalOverviewActive = next;\n        // Match the r182 renderer contract: scene content may change the\n        // composer's G-buffer budget, but it never changes frame ownership.\n        // Keeping the warmed compositor continuous is what preserves the\n        // atmosphere blend while local terrain hands off to the overview globe.\n        this._syncComposerGBufferMode();\n    }\n\n    /**\n     * Toggle the standalone sky-background quad (SkyMaterial fullscreen\n     * plane at renderOrder=-1000). Independent of the takram aerial-\n     * perspective post-process. When this is OFF and atmosphere is ON,\n     * the scene reads as \"stars / space behind the planet, no sky\" —\n     * useful for orbital views without horizon haze.\n     *\n     * Effective visibility = master atmosphere enabled AND _skyEnabled.\n     */\n    setSkyEnabled(enabled) {\n        const next = !!enabled;\n        if (this._skyEnabled === next) return;\n        this._skyEnabled = next;\n        this._applySkyMeshVisibility();\n    }\n\n    isSkyEnabled() {\n        return !!this._skyEnabled;\n    }\n\n    _applySkyMeshVisibility() {\n        if (!this.skyMesh) return;\n        // The r182 pipeline kept the sky/compositor relationship independent\n        // from scene content. At high orbit aerial perspective still supplies\n        // the limb while this background quad retires with the cloud budget.\n        this.skyMesh.visible = !!(\n            this.enabled\n            && this._skyEnabled\n            && !this._cloudComposerHighOrbitActive\n            && (this._cloudWarmupState === 'ready' || this._cloudWarmupState === 'clear-ready')\n        );\n    }\n\n    shouldUseLegacyFallback() {\n        return this._cloudWarmupState === 'fallback'\n            || this._cloudWarmupState === 'failed';\n    }\n\n    /**\n     * Explicitly yield final-frame ownership to SceneInitializer's direct\n     * renderer. Readiness remains intact so the same warmed compositor can\n     * reclaim the next healthy frame without an altitude/content handoff.\n     */\n    releaseFrameOwnership() {\n        if (this._oceanSurface) this._oceanSurface.uniformsLocal.ncaOceanOpticsReady.value = 0;\n        this._restoreToneMapping();\n    }\n\n    /** Direct frames still draw these scene-owned carriers. Their camera,\n     * Earth transform and depth source must follow the frame that draws them,\n     * even after an optional compositor/cloud preparation failure.\n     */\n    prepareDirectFrame({ enabled = this.enabled } = {}) {\n        this.releaseFrameOwnership();\n        this._oceanSurface?.setAtmosphereLighting?.(null);\n        if (!enabled || !this.camera || (!this.ready && !this._directPhysicalSkyPrepared)) {\n            this._hideAtmosphereDependents();\n            return;\n        }\n        this._updateEllipsoidTransform();\n        this._updateSunDirection();\n        this._updateOrbitClouds();\n        this._updateAirglowShell();\n        this._updateAuroraSystem();\n        this._updateFireSystem();\n        this._updateSmokeSystem();\n        if (this.hasDirectPhysicalSky()) {\n            this._nativeXRSkyMaterial.syncFrom(this.skyMaterial);\n            this.skyMesh.material = this._nativeXRSkyMaterial;\n            this.skyMesh.visible = true;\n        }\n    }\n\n    hasDirectPhysicalSky() {\n        return this._directPhysicalSkyPrepared === true && this.enabled && this._skyEnabled\n            && !this._cloudComposerHighOrbitActive && !!this.skyMesh;\n    }\n\n    setCloudWarmupDeferred(deferred) {\n        const next = deferred === true;\n        if (this._cloudWarmupDeferred === next) return;\n        this._cloudWarmupDeferred = next;\n        if (!next) void this._scheduleCloudWarmup();\n    }\n\n    /** Update physical sky without executing any desktop composer passes. */\n    prepareNativeXRFrame({ enabled = this.enabled } = {}) {\n        this._waterReflectionPass?.resetBindings();\n        this.releaseFrameOwnership();\n        // A desktop shadow field is not an eye-local/native lighting source.\n        // The hero retains its independent clear fallback during this handoff.\n        this._oceanSurface?.setAtmosphereLighting?.(null);\n        if (!this.skyMesh || !this.skyMaterial) return false;\n        if (!this._nativeXRSkyMaterial) this._nativeXRSkyMaterial = new NativeXRSkyMaterial(this.skyMaterial);\n        this._updateEllipsoidTransform();\n        this._updateSunDirection();\n        this._nativeXRSkyMaterial.syncFrom(this.skyMaterial);\n        this.skyMesh.material = this._nativeXRSkyMaterial;\n        // LUT readiness is independent of mono volumetric-cloud compilation,\n        // failed desktop postprocessing and the previous orbital cloud budget.\n        this.skyMesh.visible = !!(enabled && this._skyEnabled\n            && this.skyMaterial.scatteringTexture && this.skyMaterial.transmittanceTexture\n            && this.skyMaterial.irradianceTexture);\n        return this.skyMesh.visible;\n    }\n\n    restoreDesktopSky() {\n        if (this._nativeXRRenderer) {\n            this._nativeXRRenderer.dispose(); this._nativeXRRenderer = null;\n        }\n        if (this._nativeXRClouds) {\n            this._nativeXRClouds.dispose(); this._nativeXRClouds = null;\n            if (this.aerialPerspective) delete this.aerialPerspective.ncaNativeClouds;\n            if (!this._disposed) void this._scheduleCloudWarmup();\n        }\n        if (this.skyMesh && this.skyMesh.material !== this.skyMaterial) {\n            this.skyMesh.material = this.skyMaterial;\n            this._applySkyMeshVisibility();\n        }\n    }\n\n    renderNativeXRFrame(deltaTime, { enabled = this.enabled } = {}) {\n        // `this.enabled` also quarantines failed DESKTOP cloud rendering. The\n        // XR owner supplies the actual user preference, not that failure flag.\n        if (!enabled || !this.skyMaterial || !this.aerialPerspective?.scatteringTexture\n            || !this.aerialPerspective.transmittanceTexture || !this.aerialPerspective.irradianceTexture) return false;\n        this.releaseFrameOwnership();\n        this._updateEllipsoidTransform(); this._updateSunDirection();\n        this._syncLightPollutionBloomEffect();\n        this._syncSurfaceEmitterUniforms(performance.now() / 1000);\n        if (!this._patchSkyDepthRule()) return false;\n        this._nativeXRClouds ??= new NativeXRClouds(this);\n        this.aerialPerspective.ncaNativeClouds = this._nativeXRClouds;\n        const NativeRenderer = this._nativeXRRendererClass || NativeXRAtmosphereRenderer;\n        this._nativeXRRenderer ??= new NativeRenderer(this.renderer, this.scene, this.aerialPerspective);\n        this._nativeXRRenderer.sync(this.aerialPerspective);\n        // The per-eye aerial pass owns sky scattering and physical terrain\n        // lighting together. Do not blend a second sky over the resulting sky.\n        const visible = this.skyMesh.visible;\n        this.skyMesh.visible = false;\n        try { this._nativeXRRenderer.render(this.renderer, this.scene, deltaTime); }\n        finally { this.skyMesh.visible = visible; }\n        return true;\n    }\n\n    _hideAtmosphereDependents() {\n        if (this._orbitCloudsMesh) this._orbitCloudsMesh.visible = false;\n        if (this._orbitCloudsRawMesh) this._orbitCloudsRawMesh.visible = false;\n        if (this._airglowMesh) this._airglowMesh.visible = false;\n        if (this._auroraSystem?.mesh) this._auroraSystem.mesh.visible = false;\n        if (this._fireSystem?.mesh) this._fireSystem.mesh.visible = false;\n        if (this._smokeSystem?.mesh) this._smokeSystem.mesh.visible = false;\n    }\n\n    setCloudsEnabled(enabled) {\n        const next = !!enabled;\n        if (this._cloudsEnabled === next) return;\n        this._cloudsEnabled = next;\n        if (next) this._cloudWarmupError = null;\n        this._applyCloudsEnabled();\n    }\n\n    updateQualityPressure(frameMs, visible = true) {\n        this._cloudResolutionPolicy ||= new CloudResolutionPolicy();\n        const scale = this._cloudResolutionPolicy.update({now:performance.now(),frameMs,\n            eligible:visible && this._cloudWarmupState==='ready' && this._cloudsEffectPass?.enabled\n                && !this.renderer?.xr?.isPresenting});\n        if (scale !== null) this.setLowFpsMode(scale<1,scale);\n    }\n\n    setLowFpsMode(active, scale = active ? .85 : 1) {\n        scale=THREE.MathUtils.clamp(scale,.5,1);\n        if (this._lowFpsMode===(active===true) && this._qualityResolutionScale===scale) return;\n        this._lowFpsMode = active===true;\n        this._qualityResolutionScale = THREE.MathUtils.clamp(scale,.5,1);\n        this._lastCloudResolutionScale = null;\n        this._lastOrbitCloudResolutionScale = null;\n        this._cloudRenderCadenceMs = 0;\n        this._cloudRenderCadenceBase = 0;\n    }\n\n    setCloudQualityPreset(preset) {\n        const next = this._normalizeCloudQualityPreset(preset);\n        if (!next || this._cloudQualityPreset === next) return;\n        this._cloudQualityPreset = next;\n        this._applyCloudQualityPreset();\n    }\n\n    setPerformanceMonitor(perf) {\n        this._perf = perf || null;\n        if (perf && typeof perf.start === 'function' && typeof perf.end === 'function') {\n            this._perfStart = (name) => perf.start(name);\n            this._perfEnd = (name) => perf.end(name);\n        } else {\n            this._perfStart = () => {};\n            this._perfEnd = () => {};\n        }\n    }\n\n    setEarthMaterial(material) {\n        this._earthMaterial = material;\n        this._syncSurfaceLightPollutionUniforms();\n        if (this._earthMaterial?.uniforms?.orbitCloudsTexture && this._orbitCloudsTexture) {\n            this._earthMaterial.uniforms.orbitCloudsTexture.value = this._orbitCloudsTexture;\n            this._earthMaterial.uniforms.orbitCloudsEnabled.value = this._orbitClouds.enabled ? 1.0 : 0.0;\n            if (this._earthMaterial.uniforms.orbitCloudsShadowHeight) {\n                this._earthMaterial.uniforms.orbitCloudsShadowHeight.value = Math.max(0, this._orbitClouds.radiusOffsetM || 12000);\n            }\n        }\n    }\n\n    /** scene.lens patch: depth of field and chromatic aberration. */\n    setLensEffects(config) {\n        this._lensConfig = config;\n        this._lensStage?.applyConfig(config);\n    }\n\n    setNightVision(enabled, settings = {}, tracks = []) {\n        this._nightVisionSettings = settings;\n        this._nightVisionEffect?.setState(enabled, settings, tracks);\n        this._nightVisionEnabled = enabled === true;\n        const uniform = this.aerialPerspective?.uniforms?.get('ncaNightVision');\n        if (uniform) uniform.value = this._nightVisionEnabled ? 1 : 0;\n    }\n\n    _ensureSurfaceLightPollutionUniforms() {\n        const uniforms = this.aerialPerspective?.uniforms;\n        if (!uniforms) return;\n        const ensure = (name, value) => {\n            if (!uniforms.has(name)) {\n                uniforms.set(name, new THREE.Uniform(value));\n            }\n        };\n        ensure('ncaLightPollutionTexture', null);\n        ensure('ncaLightPollutionDetailTexture', null);\n        ensure('ncaLightPollutionDetailEnabled', 0);\n        ensure('ncaLightPollutionDetailBounds', new THREE.Vector4(0.5, 0, 1, 1));\n        ensure('ncaLightPollutionEnabled', 0);\n        ensure(\n            'ncaLightPollutionIntensity',\n            NIGHT_LIGHTS_EMISSION_DEFAULTS.intensity\n        );\n        ensure('ncaLightPollutionMapGain', 0.05);\n        ensure(\n            'ncaLightPollutionSurfaceIntensityScale',\n            NIGHT_LIGHTS_EMISSION_DEFAULTS.surfaceIntensityScale\n        );\n        ensure(\n            'ncaLightPollutionEmissionThreshold',\n            NIGHT_LIGHTS_EMISSION_DEFAULTS.emissionThreshold\n        );\n        ensure(\n            'ncaLightPollutionEmissionSoftness',\n            NIGHT_LIGHTS_EMISSION_DEFAULTS.emissionSoftness\n        );\n        ensure(\n            'ncaLightPollutionEmissionPower',\n            NIGHT_LIGHTS_EMISSION_DEFAULTS.emissionPower\n        );\n        ensure(\n            'ncaLightPollutionEmissionBlueSuppression',\n            NIGHT_LIGHTS_EMISSION_DEFAULTS.emissionBlueSuppression\n        );\n        ensure('ncaLightPollutionColor', new THREE.Color(0xffb57a));\n        ensure('ncaLightPollutionMercator', 0);\n        ensure('ncaLightPollutionUvOffset', new THREE.Vector2());\n        ensure('ncaLightPollutionUvScale', new THREE.Vector2(1, 1));\n        ensure('ncaNightTransitionStart', 0);\n        ensure('ncaNightTransitionEnd', 0.5);\n        ensure('ncaNightPower', 1.6);\n        ensure('ncaNightMinBrightness', 0.002);\n        ensure('ncaNightVision', this._nightVisionEnabled ? 1 : 0);\n        ensure('ncaSimpleCloudsTexture', null);\n        ensure('ncaSimpleCloudsEnabled', 0);\n        ensure('ncaSimpleCloudsOpacity', 1);\n        ensure('ncaSimpleCloudsShadowStrength', 1);\n        ensure('ncaSimpleCloudsShadowHeight', 12600);\n        ensure('ncaSimpleCloudsBlendMode', 0);\n        ensure('ncaSimpleCloudsAlphaThreshold', 0);\n        ensure('ncaSimpleCloudsAlphaSoftness', 1);\n        ensure('ncaSimpleCloudsNightAirglowColor', new THREE.Color('#9fb3c2'));\n        ensure('ncaSimpleCloudsNightAirglowStrength', 0.006);\n        ensure('ncaWaterGlobalMask', null); ensure('ncaWaterGlobalEnabled', 0);\n        ensure('ncaWaterRegionalMask', null); ensure('ncaWaterRegionalEnabled', 0);\n        ensure('ncaWaterRegionalBounds', new THREE.Vector4(0, 0, 1, 1));\n        ensure('ncaWaterLocalFrame', new THREE.Matrix3());\n        ensure('ncaWaterLocalLatitude', new THREE.Vector2(0,1));\n        ensure('ncaWaterGeoid', 0); ensure('ncaWaterSeaHeight', 0); ensure('ncaWaterDatumReady', 0);\n        ensure('ncaWaterSurfaceHeightRange', new THREE.Vector2(0,1)); ensure('ncaWaterSurfaceHeightEnabled', 0);\n        ensure('ncaWaterReflectionEnabled', 0); ensure('ncaWaterReflectionStrength', 0.9);\n        ensure('ncaWaterWindSpeed', 8);\n        ensure('ncaWaterReflectionReady',0);\n        ensure('ncaWaterReflectionFromView',new THREE.Matrix4());\n        ensure('ncaWaterReflectionRegion',new THREE.Vector4());\n        ensure('ncaWaterBed', null); ensure('ncaWaterBedEnabled', 0);\n        ensure('ncaWaterBedBounds', new THREE.Vector4(0,0,1,1));\n        ensure('ncaWaterKd', new THREE.Vector3());\n        this._ensureSurfaceEmitterUniforms();\n    }\n\n    _ensureSurfaceEmitterUniforms() {\n        const uniforms = this.aerialPerspective?.uniforms;\n        if (!uniforms) return;\n        const ensure = (name, value) => {\n            if (!uniforms.has(name)) uniforms.set(name, new THREE.Uniform(value));\n        };\n        if (!Array.isArray(this._surfaceEmitterStarts)) {\n            this._surfaceEmitterStarts = Array.from(\n                { length: MAX_SURFACE_LIGHT_EMITTERS },\n                () => new THREE.Vector4(),\n            );\n            this._surfaceEmitterEnds = Array.from(\n                { length: MAX_SURFACE_LIGHT_EMITTERS },\n                () => new THREE.Vector4(),\n            );\n            this._surfaceEmitterColors = Array.from(\n                { length: MAX_SURFACE_LIGHT_EMITTERS },\n                () => new THREE.Vector4(),\n            );\n            this._surfaceEmitterParams = Array.from(\n                { length: MAX_SURFACE_LIGHT_EMITTERS },\n                () => new THREE.Vector4(),\n            );\n        }\n        ensure('ncaSurfaceEmitterCount', 0);\n        ensure('ncaSurfaceEmitterTime', 0);\n        ensure('ncaSurfaceEmitterECEFToWorld', new THREE.Matrix4());\n        ensure('ncaSurfaceEmitterStarts', this._surfaceEmitterStarts);\n        ensure('ncaSurfaceEmitterEnds', this._surfaceEmitterEnds);\n        ensure('ncaSurfaceEmitterColors', this._surfaceEmitterColors);\n        ensure('ncaSurfaceEmitterParams', this._surfaceEmitterParams);\n    }\n\n    _syncSurfaceEmitterUniforms(nowSeconds = 0) {\n        const uniforms = this.aerialPerspective?.uniforms;\n        if (!uniforms) return;\n        this._ensureSurfaceEmitterUniforms();\n\n        const cameraDirection = this._surfaceEmitterCameraDirection\n            || (this._surfaceEmitterCameraDirection = new THREE.Vector3());\n        this.camera?.getWorldPosition?.(cameraDirection);\n        cameraDirection.applyMatrix4(this._planetMatrixInverse).normalize();\n        const snapshot = getSurfaceLightRegistry().snapshot({ cameraDirection });\n        const starts = this._surfaceEmitterStarts;\n        const ends = this._surfaceEmitterEnds;\n        const colors = this._surfaceEmitterColors;\n        const params = this._surfaceEmitterParams;\n        const count = Math.min(snapshot.emitters.length, MAX_SURFACE_LIGHT_EMITTERS);\n        const scratch = this._surfaceEmitterScratchDirection\n            || (this._surfaceEmitterScratchDirection = new THREE.Vector3());\n        const endScratch = this._surfaceEmitterScratchEndDirection\n            || (this._surfaceEmitterScratchEndDirection = new THREE.Vector3());\n        for (let index = 0; index < MAX_SURFACE_LIGHT_EMITTERS; index += 1) {\n            const emitter = snapshot.emitters[index];\n            if (!emitter) {\n                starts[index].set(0, 1, 0, 0);\n                ends[index].set(0, 1, 0, 0);\n                colors[index].set(0, 0, 0, 0);\n                params[index].set(0, 0, 0, 0);\n                continue;\n            }\n            directionFromLatLon(emitter.lat, emitter.lon, scratch);\n            directionFromLatLon(emitter.endLat, emitter.endLon, endScratch);\n            starts[index].set(\n                scratch.x,\n                scratch.y,\n                scratch.z,\n                emitter.radiusM * METER_TO_LENGTH_UNIT,\n            );\n            ends[index].set(\n                endScratch.x,\n                endScratch.y,\n                endScratch.z,\n                emitter.altitudeM * METER_TO_LENGTH_UNIT,\n            );\n            colors[index].set(\n                emitter.color.r,\n                emitter.color.g,\n                emitter.color.b,\n                emitter.intensity,\n            );\n            params[index].set(\n                emitter.pulseHz,\n                emitter.phase,\n                emitter.shadowStrength,\n                emitter.lat === emitter.endLat && emitter.lon === emitter.endLon ? 0 : 1,\n            );\n        }\n        this._surfaceEmitterCount = count;\n        uniforms.get('ncaSurfaceEmitterCount').value = count;\n        uniforms.get('ncaSurfaceEmitterTime').value = Number(nowSeconds) || 0;\n        uniforms.get('ncaSurfaceEmitterECEFToWorld').value.copy(this._planetMatrix);\n        uniforms.get('ncaSurfaceEmitterStarts').value = starts;\n        uniforms.get('ncaSurfaceEmitterEnds').value = ends;\n        uniforms.get('ncaSurfaceEmitterColors').value = colors;\n        uniforms.get('ncaSurfaceEmitterParams').value = params;\n    }\n\n    _syncSurfaceLightPollutionUniforms() {\n        const uniforms = this.aerialPerspective?.uniforms;\n        if (!uniforms) return;\n        this._ensureSurfaceLightPollutionUniforms();\n\n        const source = this._earthMaterial?.uniforms;\n        for (const effect of [this.clouds, this._orbitCloudsEffect]) {\n            bindNightCloudLighting(effect?.cloudsPass?.currentMaterial?.uniforms, source);\n        }\n        bindNightCloudLighting(this._orbitCloudsShader?.uniforms, source);\n        if(this._orbitCloudsShader?.uniforms.uOrbitCloudHeight) {\n            this._orbitCloudsShader.uniforms.uOrbitCloudHeight.value = Math.max(0, this._orbitClouds.radiusOffsetM || 0);\n        }\n        if (source) for (const [name, uniform] of Object.entries(waterCoverageUniforms(source))) {\n            if (uniform) uniforms.get(name).value = uniform.value;\n        }\n        uniforms.get('ncaWaterReflectionEnabled').value = source?.specularEnabled?.value || 0;\n        uniforms.get('ncaWaterReflectionStrength').value = source?.specularStrength?.value ?? 0.9;\n        uniforms.get('ncaWaterWindSpeed').value = source?.waterWindSpeed?.value ?? 8;\n        const texture = source?.lightPollutionTexture?.value ?? null;\n        const detailTexture = source?.lightPollutionDetailTexture?.value ?? null;\n        const sourceEnabled = source?.lightPollutionEnabled?.value > 0.5;\n        uniforms.get('ncaLightPollutionTexture').value = texture;\n        uniforms.get('ncaLightPollutionDetailTexture').value = detailTexture;\n        uniforms.get('ncaLightPollutionDetailEnabled').value = (\n            source?.lightPollutionDetailEnabled?.value > 0.5 && detailTexture\n        ) ? 1 : 0;\n        uniforms.get('ncaLightPollutionEnabled').value = (\n            sourceEnabled && texture\n        ) ? 1 : 0;\n\n        const syncScalar = (targetName, sourceName, fallback) => {\n            const value = source?.[sourceName]?.value;\n            uniforms.get(targetName).value = Number.isFinite(value)\n                ? value\n                : fallback;\n        };\n        const sourceLightPollutionIntensity = source?.lightPollutionIntensity?.value;\n        uniforms.get('ncaLightPollutionIntensity').value = (\n            Number.isFinite(sourceLightPollutionIntensity)\n                ? sourceLightPollutionIntensity\n                : NIGHT_LIGHTS_EMISSION_DEFAULTS.intensity\n        );\n        syncScalar(\n            'ncaLightPollutionMapGain',\n            'lightPollutionMapGain',\n            NIGHT_LIGHTS_EMISSION_DEFAULTS.mapGain\n        );\n        syncScalar(\n            'ncaLightPollutionSurfaceIntensityScale',\n            'lightPollutionSurfaceIntensityScale',\n            NIGHT_LIGHTS_EMISSION_DEFAULTS.surfaceIntensityScale\n        );\n        syncScalar(\n            'ncaLightPollutionEmissionThreshold',\n            'lightPollutionEmissionThreshold',\n            NIGHT_LIGHTS_EMISSION_DEFAULTS.emissionThreshold\n        );\n        syncScalar(\n            'ncaLightPollutionEmissionSoftness',\n            'lightPollutionEmissionSoftness',\n            NIGHT_LIGHTS_EMISSION_DEFAULTS.emissionSoftness\n        );\n        syncScalar(\n            'ncaLightPollutionEmissionPower',\n            'lightPollutionEmissionPower',\n            NIGHT_LIGHTS_EMISSION_DEFAULTS.emissionPower\n        );\n        syncScalar(\n            'ncaLightPollutionEmissionBlueSuppression',\n            'lightPollutionEmissionBlueSuppression',\n            NIGHT_LIGHTS_EMISSION_DEFAULTS.emissionBlueSuppression\n        );\n        syncScalar('ncaLightPollutionMercator', 'lightPollutionMercator', 0);\n        syncScalar('ncaNightTransitionStart', 'nightTransitionStart', 0);\n        syncScalar('ncaNightTransitionEnd', 'nightTransitionEnd', 0.5);\n        syncScalar('ncaNightPower', 'nightPower', 1.6);\n        syncScalar('ncaNightMinBrightness', 'nightMinBrightness', 0.002);\n        syncScalar('ncaSimpleCloudsOpacity', 'simpleCloudsOpacity', 1);\n        syncScalar('ncaSimpleCloudsShadowStrength', 'simpleCloudsShadowStrength', 1);\n        syncScalar('ncaSimpleCloudsShadowHeight', 'simpleCloudsShadowHeight', 12600);\n        syncScalar('ncaSimpleCloudsBlendMode', 'simpleCloudsBlendMode', 0);\n        syncScalar('ncaSimpleCloudsAlphaThreshold', 'simpleCloudsAlphaThreshold', 0);\n        syncScalar('ncaSimpleCloudsAlphaSoftness', 'simpleCloudsAlphaSoftness', 1);\n        syncScalar(\n            'ncaSimpleCloudsNightAirglowStrength',\n            'simpleCloudsNightAirglowStrength',\n            0.006\n        );\n\n        const simpleCloudTexture = source?.simpleCloudsTexture?.value ?? null;\n        uniforms.get('ncaSimpleCloudsTexture').value = simpleCloudTexture;\n        uniforms.get('ncaSimpleCloudsEnabled').value = (\n            source?.simpleCloudsEnabled?.value > 0.5 && simpleCloudTexture\n        ) ? 1 : 0;\n\n        const color = source?.lightPollutionColor?.value;\n        if (color) {\n            uniforms.get('ncaLightPollutionColor').value.copy(color);\n        }\n        const cloudNightAirglowColor = source?.simpleCloudsNightAirglowColor?.value;\n        if (cloudNightAirglowColor) {\n            uniforms.get('ncaSimpleCloudsNightAirglowColor').value.copy(\n                cloudNightAirglowColor\n            );\n        }\n        const offset = source?.lightPollutionUvOffset?.value;\n        if (offset) {\n            uniforms.get('ncaLightPollutionUvOffset').value.copy(offset);\n        }\n        const scale = source?.lightPollutionUvScale?.value;\n        if (scale) {\n            uniforms.get('ncaLightPollutionUvScale').value.copy(scale);\n        }\n        const detailBounds = source?.lightPollutionDetailBounds?.value;\n        if (detailBounds) {\n            uniforms.get('ncaLightPollutionDetailBounds').value.copy(detailBounds);\n        }\n    }\n\n    setTerrainDepthSource(source = null) {\n        const state = this._terrainDepthSource;\n        if (!source || !source.depthTexture) {\n            state.depthTexture = null;\n            state.enabled = false;\n            return;\n        }\n\n        state.depthTexture = source.depthTexture;\n        state.enabled = source.enabled !== false;\n        const resolution = source.resolution;\n        if (resolution) {\n            if (Number.isFinite(resolution.x) && Number.isFinite(resolution.y)) {\n                state.resolution.set(Math.max(1, resolution.x), Math.max(1, resolution.y));\n            } else if (Number.isFinite(resolution.width) && Number.isFinite(resolution.height)) {\n                state.resolution.set(Math.max(1, resolution.width), Math.max(1, resolution.height));\n            }\n        }\n        if (source.invProjectionMatrix) state.invProjectionMatrix.copy(source.invProjectionMatrix);\n        if (source.invViewMatrix) state.invViewMatrix.copy(source.invViewMatrix);\n    }\n\n    needsTerrainDepth() {\n        // Aurora needs the depth prepass for its night-side terrain occlusion, and\n        // the fire system needs it in surface mode to engulf the photorealistic\n        // tile topology. Either system being active must keep the prepass alive.\n        const auroraNeeds = this._auroraEnabled !== false && (this._auroraStrength ?? 0) > 0;\n        const fireNeeds = this._fireEnabled !== false && (this._fireStrength ?? 0) > 0;\n        const smokeNeeds = this._smokeEnabled === true\n            && (this._smokeStrength ?? 0) > 0\n            && (this._smokeSystem?.featureCount ?? this._pendingSmokeFeatures.length) > 0;\n        return this.enabled !== false && (auroraNeeds || fireNeeds || smokeNeeds);\n    }\n\n    getDepthPassExcludeObjects() {\n        return [\n            this.skyMesh,\n            this._orbitCloudsMesh,\n            this._orbitCloudsRawMesh,\n            this._airglowMesh,\n            this._auroraSystem?.mesh,\n            this._fireSystem?.mesh,\n            this._smokeSystem?.mesh\n        ].filter(Boolean);\n    }\n\n    setPlanetGroup(group) {\n        this.planetGroup = group || null;\n        this._updateEllipsoidTransform();\n        if (this._orbitCloudsMesh) {\n            const parent = this._getOrbitCloudsParent();\n            if (parent && this._orbitCloudsMesh.parent !== parent) {\n                this._orbitCloudsMesh.parent?.remove?.(this._orbitCloudsMesh);\n                parent.add(this._orbitCloudsMesh);\n            }\n        }\n    }\n\n    setLocalWeatherTexture(texture) {\n        if (!this.clouds || !texture) return;\n        this.clouds.localWeatherTexture = texture;\n    }\n\n    restoreLocalWeatherTexture() {\n        if (!this.clouds || !this._defaultLocalWeatherTexture) return;\n        this.clouds.localWeatherTexture = this._defaultLocalWeatherTexture;\n    }\n\n    getDefaultLocalWeatherTexture() {\n        return this._defaultLocalWeatherTexture || null;\n    }\n\n    setAtmosphereBaseOffset(offsetMeters, { force = false } = {}) {\n        if (!Number.isFinite(offsetMeters)) return;\n        const next = Math.max(0, offsetMeters);\n        if (!force && Math.abs(this.atmosphereBaseOffset - next) < 1e-3) return;\n        const delta = next - this.atmosphereBaseOffset;\n        this.atmosphereBaseOffset = next;\n        this._baseOffsetInitialized = true;\n        if (this.clouds?.cloudLayers && Math.abs(delta) > 1e-3) {\n            this.clouds.cloudLayers.forEach((layer) => {\n                if (!layer || !Number.isFinite(layer.altitude)) return;\n                layer.altitude = Math.max(0, layer.altitude + delta);\n            });\n        }\n        if (this._atmosphereParams) {\n            this._rebuildAtmosphereParameters();\n        }\n    }\n\n    setAdaptiveBaseOffsetConfig(config = {}) {\n        if (!config || typeof config !== 'object') return;\n        const next = { ...this._adaptiveBaseOffset };\n        if (typeof config.enabled === 'boolean') next.enabled = config.enabled;\n        const numericKeys = [\n            'orbitClearanceMeters',\n            'surfaceClearanceMeters',\n            'minOffsetMeters',\n            'maxOffsetMeters',\n            'updateThresholdMeters',\n            'maxStepMeters',\n        ];\n        for (const key of numericKeys) {\n            const value = Number(config[key]);\n            if (Number.isFinite(value)) next[key] = Math.max(0, value);\n        }\n        next.maxOffsetMeters = Math.max(next.minOffsetMeters, next.maxOffsetMeters);\n        this._adaptiveBaseOffset = next;\n        if (next.enabled && Number.isFinite(this._regionalTerrainRadius)) {\n            this.setRegionalTerrainRadius(this._regionalTerrainRadius, { force: true });\n        } else if (!next.enabled) {\n            this._regionalBaseOffsetInitialized = false;\n        }\n    }\n\n    setRegionalTerrainRadius(terrainRadius, { force = false } = {}) {\n        if (!Number.isFinite(terrainRadius) || terrainRadius <= 0) return false;\n        this._regionalTerrainRadius = terrainRadius;\n        if (this._adaptiveBaseOffset?.enabled !== true) return false;\n\n        const targets = deriveRegionalAtmosphereBaseOffsets(\n            terrainRadius,\n            this._adaptiveBaseOffset,\n        );\n        if (!targets) return false;\n\n        const threshold = Math.max(0, Number(this._adaptiveBaseOffset.updateThresholdMeters) || 0);\n        const maxStep = Math.max(1, Number(this._adaptiveBaseOffset.maxStepMeters) || 1500);\n        const first = !this._regionalBaseOffsetInitialized;\n        const converge = (current, target) => {\n            if (first || force || !Number.isFinite(current)) return target;\n            const delta = target - current;\n            if (Math.abs(delta) < threshold) return current;\n            return current + THREE.MathUtils.clamp(delta, -maxStep, maxStep);\n        };\n\n        const nextOrbit = converge(this.orbitAtmosphereBaseOffset, targets.orbit);\n        const nextSurface = converge(this.surfaceAtmosphereBaseOffset, targets.surface);\n        const effectiveBefore = this._surfaceCameraModeActive\n            ? this.surfaceAtmosphereBaseOffset\n            : this.orbitAtmosphereBaseOffset;\n        this.orbitAtmosphereBaseOffset = nextOrbit;\n        this.surfaceAtmosphereBaseOffset = nextSurface;\n        this._regionalBaseOffsetInitialized = true;\n        const effectiveAfter = this._surfaceCameraModeActive ? nextSurface : nextOrbit;\n        if (Math.abs(effectiveAfter - effectiveBefore) >= 1e-3) {\n            this.setSurfaceCameraModeActive(this._surfaceCameraModeActive, { force: true });\n            return true;\n        }\n        return false;\n    }\n\n    /**\n     * Select the regional orbit/surface clearance appropriate to the active\n     * camera contract. Both values are derived from the same local terrain\n     * radius when adaptive offsets are enabled.\n     */\n    setSurfaceCameraModeActive(active, { force = false } = {}) {\n        const nextActive = active === true;\n        if (!force && nextActive === this._surfaceCameraModeActive) return;\n        this._surfaceCameraModeActive = nextActive;\n        const surfaceCameraMode = this.aerialPerspective?.uniforms?.get?.(\n            'ncaSurfaceCameraMode'\n        );\n        if (surfaceCameraMode) {\n            surfaceCameraMode.value = nextActive ? 1 : 0;\n        }\n        const nextOffset = nextActive\n            ? this.surfaceAtmosphereBaseOffset\n            : this.orbitAtmosphereBaseOffset;\n        this.setAtmosphereBaseOffset(nextOffset, { force });\n    }\n\n    setSunDirection(vector) {\n        if (!vector || !this.aerialPerspective || !this.clouds) return;\n        this.aerialPerspective.sunDirection.copy(vector).normalize();\n        this.clouds.sunDirection.copy(vector).normalize();\n        if (this.skyMaterial) {\n            this.skyMaterial.sunDirection.copy(vector).normalize();\n        }\n    }\n\n    setMoonDirection(vector) {\n        if (!vector) return;\n        this._moonDirection.copy(vector).normalize();\n        if (this.aerialPerspective) {\n            this.aerialPerspective.moonDirection.copy(this._moonDirection);\n        }\n        if (this.skyMaterial) {\n            this.skyMaterial.moonDirection.copy(this._moonDirection);\n        }\n    }\n\n    setCelestialOccluders({ moonMesh = null, sunMesh = null } = {}) {\n        this._moonMesh = moonMesh;\n        this._sunMesh = sunMesh;\n        this._syncCelestialDiskOwnership();\n        this._syncCelestialOccluders();\n    }\n\n    _syncCelestialDiskOwnership() {\n        const physicalSunOwnsDisk = !!this._sunMesh;\n        const physicalMoonOwnsDisk = !!this._moonMesh;\n\n        if (this._sunMesh) {\n            this._sunMesh.visible = this._sunDiskEnabled;\n        }\n        if (this._moonMesh) {\n            this._moonMesh.visible = this._moonDiskEnabled;\n        }\n\n        // The aerial pass is the sole procedural fallback when a physical\n        // body is unavailable. SkyMaterial remains scattering-only; allowing\n        // both Takram passes to synthesize disks would duplicate them even\n        // without the scene meshes.\n        if (this.aerialPerspective) {\n            this.aerialPerspective.sun =\n                this._sunDiskEnabled && !physicalSunOwnsDisk;\n            this.aerialPerspective.moon =\n                this._moonDiskEnabled && !physicalMoonOwnsDisk;\n        }\n        if (this.skyMaterial) {\n            this.skyMaterial.sun = false;\n            this.skyMaterial.moon = false;\n        }\n    }\n\n    getIrradianceScale() {\n        return this._currentIrradianceScale;\n    }\n\n    getCameraAltitude() {\n        this.camera.getWorldPosition(this._cameraWorldPosition);\n        const cameraDistance = this._cameraWorldPosition.length();\n        const atmosphereBottom = this._atmosphereParams?.bottomRadius ?? PLANET_RADIUS;\n        return Math.max(0, cameraDistance - atmosphereBottom);\n    }\n\n    /**\n     * Set the local terrain radius (distance from planet center to terrain surface).\n     * This adjusts cloud layer altitudes to ensure they render above terrain.\n     *\n     * The key issue is that clouds use a spherical bottomRadius, but terrain uses\n     * WGS84 ellipsoid. At poles, the ellipsoid surface is ~21km closer to center\n     * than at equator, so clouds set at \"4000m altitude\" would be underground at poles.\n     *\n     * @param {number} elevationMeters - Terrain elevation above spherical PLANET_RADIUS\n     */\n    setTerrainElevationMeters(elevationMeters) {\n        if (!Number.isFinite(elevationMeters)) return;\n\n        // The elevation passed in is (actual_terrain_radius - PLANET_RADIUS)\n        // This can be negative at poles since WGS84_SEMI_MINOR_AXIS < PLANET_RADIUS\n        //\n        // We need to compute how high terrain is above the atmosphere's bottomRadius\n        // bottomRadius = PLANET_RADIUS - atmosphereBaseOffset\n        //\n        // terrainHeightAboveBottom = (PLANET_RADIUS + elevationMeters) - bottomRadius\n        //                          = (PLANET_RADIUS + elevationMeters) - (PLANET_RADIUS - atmosphereBaseOffset)\n        //                          = elevationMeters + atmosphereBaseOffset\n\n        const terrainHeightAboveAtmosphereBottom = elevationMeters + this.atmosphereBaseOffset;\n\n        // Only update if changed significantly (within 50m to reduce jitter)\n        if (Math.abs(this._terrainElevation - terrainHeightAboveAtmosphereBottom) < 50) return;\n\n        const prevElevation = this._terrainElevation;\n        this._terrainElevation = terrainHeightAboveAtmosphereBottom;\n\n        // Log significant changes for debugging\n        if (Math.abs(prevElevation - terrainHeightAboveAtmosphereBottom) > 1000) {\n            console.log(`[AtmosphereClouds] Terrain elevation changed: ` +\n                `input=${elevationMeters.toFixed(0)}m, ` +\n                `aboveBottom=${terrainHeightAboveAtmosphereBottom.toFixed(0)}m`);\n        }\n\n        this._updateCloudLayersForTerrain();\n    }\n\n    /**\n     * Set the minimum clearance above terrain for cloud layers.\n     * @param {number} clearanceMeters - Minimum distance above terrain (default 200m)\n     */\n    setCloudTerrainClearance(clearanceMeters) {\n        if (!Number.isFinite(clearanceMeters)) return;\n        this._cloudTerrainClearance = Math.max(0, clearanceMeters);\n        this._updateCloudLayersForTerrain();\n    }\n\n    /**\n     * Set cloud layer altitude above terrain.\n     * @param {number} layerIndex - Layer index (0=low, 1=mid, 2=high)\n     * @param {number} altitudeAboveTerrain - Height above local terrain in meters\n     * @param {number} [height] - Optional layer thickness in meters\n     */\n    setCloudLayerAltitude(layerIndex, altitudeAboveTerrain, height) {\n        if (layerIndex < 0 || layerIndex >= this._cloudLayerHeightsAboveTerrain.length) return;\n        if (!Number.isFinite(altitudeAboveTerrain)) return;\n\n        const config = this._cloudLayerHeightsAboveTerrain[layerIndex] || {};\n        config.altitude = Math.max(0, altitudeAboveTerrain);\n        if (Number.isFinite(height)) {\n            config.height = Math.max(100, height);\n        }\n        this._cloudLayerHeightsAboveTerrain[layerIndex] = config;\n        this._updateCloudLayersForTerrain();\n    }\n\n    /**\n     * Get cloud layer altitude above terrain.\n     * @param {number} layerIndex - Layer index (0=low, 1=mid, 2=high)\n     * @returns {{ altitude: number, height: number } | null}\n     */\n    getCloudLayerAltitude(layerIndex) {\n        if (layerIndex < 0 || layerIndex >= this._cloudLayerHeightsAboveTerrain.length) return null;\n        return this._cloudLayerHeightsAboveTerrain[layerIndex];\n    }\n\n    /** Read live geometry even when cloud rendering is hidden or warming up. */\n    getLocalCloudTopRadius() {\n        return cloudLayerTopRadius(this.clouds?.cloudLayers, this._atmosphereParams?.bottomRadius);\n    }\n\n    /**\n     * Update cloud layer altitudes based on current terrain elevation.\n     *\n     * Cloud altitudes in _cloudLayerHeightsAboveTerrain are specified as heights\n     * ABOVE LOCAL TERRAIN (where 0 = terrain surface). This method converts them\n     * to the library's coordinate system (altitude above bottomRadius).\n     *\n     * Library coordinate: layer.altitude = terrainElevation + heightAboveTerrain\n     */\n    _updateCloudLayersForTerrain() {\n        if (!this.clouds?.cloudLayers) return;\n\n        const layers = this.clouds.cloudLayers;\n        let anyChanged = false;\n\n        layers.forEach((layer, i) => {\n            if (!layer) return;\n\n            const config = this._cloudLayerHeightsAboveTerrain[i];\n            if (!config) return;\n\n            // Convert terrain-relative altitude to library altitude (above bottomRadius)\n            // terrainElevation is already the height of terrain above bottomRadius\n            const libraryAltitude = this._terrainElevation + config.altitude + this._cloudTerrainClearance;\n\n            // Only update if changed significantly (reduce frequent updates)\n            if (Math.abs(layer.altitude - libraryAltitude) > 50) {\n                layer.altitude = libraryAltitude;\n                layer.height = config.height;\n                anyChanged = true;\n            }\n        });\n\n        // Log updates occasionally for debugging\n        if (anyChanged && Math.random() < 0.02) {\n            const layerInfo = layers.map((l, i) => {\n                const cfg = this._cloudLayerHeightsAboveTerrain[i];\n                return cfg ? `L${i}:${cfg.altitude}m→${l?.altitude?.toFixed(0) || '?'}m` : null;\n            }).filter(Boolean).join(', ');\n            console.log(`[AtmosphereClouds] Cloud layers updated: terrain=${this._terrainElevation.toFixed(0)}m, ${layerInfo}`);\n        }\n    }\n\n    setRainSystem(system) {\n        this._rainSystem = system || null;\n        if (this._rainPass) this._rainPass.rainSystem = this._rainSystem;\n    }\n\n    render(deltaTime) {\n        this._finalFrameWritten = false;\n        this._waterReflectionPass?.resetBindings();\n        // A yielded/direct/XR frame must never sample a previous compositor's\n        // screen capture with a different camera or viewport.\n        if (this._oceanSurface) this._oceanSurface.uniformsLocal.ncaOceanOpticsReady.value = 0;\n        // The composer owns tone mapping only after its exact shader chain is\n        // ready. Direct fallback frames must keep the renderer's AGX/exposure\n        // state or orbital radiance (globe, airglow, stars) is nearly black.\n        this._syncToneMappingForRenderPath();\n        if (!this.enabled) {\n            this._hideAtmosphereDependents();\n            return false;\n        }\n        // Texture readiness is independent from optional cloud compilation.\n        // We still update airglow and high-orbit state below when compilation\n        // falls back, then hand the actual frame to the proven direct renderer.\n        if (!this.ready) return false;\n        this._updateOrbitClouds();\n        if (!this.composer || !this.aerialPerspective || !this.clouds) {\n            return false;\n        }\n\n        const now = (typeof performance !== 'undefined' && performance.now)\n            ? performance.now()\n            : Date.now();\n        const cloudPipelineReady = this._cloudWarmupState === 'ready';\n\n        this._perfStart('atmosphere.clouds.ellipsoid');\n        this._updateEllipsoidTransform();\n        this._perfEnd('atmosphere.clouds.ellipsoid');\n\n        this._perfStart('atmosphere.clouds.sun');\n        this._updateSunDirection();\n        this._updateAirglowShell();\n        this._updateAuroraSystem();\n        this._updateFireSystem();\n        this._updateSmokeSystem();\n        this._perfEnd('atmosphere.clouds.sun');\n\n        this._perfStart('atmosphere.clouds.lod');\n        if (this._cloudsEnabled) {\n            this._updateCloudDistanceTuning(deltaTime);\n        }\n        this._perfEnd('atmosphere.clouds.lod');\n\n        const altitude = this._getCameraAltitudeMeters();\n        this._updateHighOrbitComposerMode(altitude);\n        this._syncLightPollutionBloomEffect();\n        this._syncSurfaceEmitterUniforms(now / 1000);\n\n        // Patch sky depth handling if not yet done (shader may only be available after first render)\n        if (!this._skyDepthPatched) {\n            if (!this._patchSkyDepthRule()) {\n                // Never let a dependency shader change promote an unpatched\n                // compositor to frame owner. The direct renderer is already\n                // tone-mapped and keeps orbital content visible.\n                this._cloudWarmupState = 'fallback';\n                this._syncToneMappingForRenderPath();\n                this._applySkyMeshVisibility();\n                this._applyCloudsEnabled();\n                return false;\n            }\n        }\n\n        if (cloudPipelineReady) {\n            // CloudsEffect selects a different raymarch material as the camera\n            // crosses cloud-layer boundaries. Validate those optional\n            // materials only once their variants have warmed. The clear\n            // aerial/irradiance pass can own stable scene-entry frames before\n            // volumetric clouds finish compiling.\n            if (!this._patchCloudsCameraHeight()\n                || !this._patchCloudsNightLighting()) {\n                this._cloudWarmupState = 'fallback';\n                this._syncToneMappingForRenderPath();\n                this._applySkyMeshVisibility();\n                this._applyCloudsEnabled();\n                return false;\n            }\n\n            // Patch temporal reprojection for planet rotation once per active cloud material.\n            this._patchCloudsReprojection();\n            this._patchCloudsLiveCoverage();\n        }\n\n        // Sync camera settings to effect materials\n        this._syncEffectMaterialsWithCamera();\n\n        this._perfStart('atmosphere.clouds.composer');\n        const oceanMesh = this._oceanSurface?.mesh;\n        const waterVisible = oceanMesh?.visible === true;\n        // A submerged observer needs clouds in the refracted sky snapshot\n        // (Snell's window), not clipped at the intervening sea before capture.\n        const submergedWater = waterVisible\n            && this._oceanSurface.uniformsLocal.ncaOceanSubmerged.value > .5;\n        this._deferMainCloudOverlay = !submergedWater;\n        if (this._oceanDepthPass) {\n            this._oceanDepthPass.ocean = this._oceanSurface;\n            this._oceanDepthPass.waterVisible = waterVisible && !submergedWater;\n            this._oceanDepthPass.surfacePass = this._oceanSurfacePass;\n        }\n        if (this._oceanSurfacePass) {\n            this._oceanSurfacePass.ocean = this._oceanSurface;\n            this._oceanSurfacePass.atmosphereSource = this.aerialPerspective;\n            this._oceanSurfacePass.reflectionCapture = this._waterReflectionPass;\n            this._oceanSurfacePass.waterVisible = waterVisible;\n        }\n        if(this._cloudColorPass){\n            this._cloudColorPass.effects=!submergedWater && this._cloudsEffectPass?.enabled\n                ? this._cloudsEffectPass.effects.filter(effect=>effect.cloudsPass) : [];\n        }\n        if (waterVisible) oceanMesh.visible = false;\n        const airglowVisible = this._airglowMesh?.visible === true;\n        // Aurora is upper-atmosphere emission too: drawn after surface lighting,\n        // otherwise over photoreal ground the deferred pass relit it as albedo\n        // under night irradiance and it vanished when looking down at it.\n        const auroraMesh = this._auroraSystem?.mesh || null;\n        const auroraVisible = auroraMesh?.visible === true;\n        if (this._atmosphericEmissionPass) {\n            this._atmosphericEmissionPass.mesh = this._airglowMesh;\n            this._atmosphericEmissionPass.emissionVisible = airglowVisible;\n            this._atmosphericEmissionPass.extraMeshes = auroraMesh ? [{\n                mesh: auroraMesh,\n                visible: auroraVisible,\n                // Occlude against the full opaque depth (photoreal tiles\n                // included), not the terrain-only depth target.\n                bindDepth: (depthTexture) => this._bindAuroraSceneDepth(depthTexture),\n            }] : [];\n            if (airglowVisible) this._airglowMesh.visible = false;\n            if (auroraVisible) auroraMesh.visible = false;\n        }\n        this._rainSystem?.setCompositionMode(true);\n        this._lensStage?.setSuspended(this.renderer.xr?.isPresenting === true);\n        // (The frame-wide first-draw guard wraps this in SceneInitializer.)\n        try { this.composer.render(deltaTime); }\n        finally {\n            this._rainSystem?.setCompositionMode(false);\n            if (oceanMesh) oceanMesh.visible = waterVisible;\n            if (this._airglowMesh) this._airglowMesh.visible = airglowVisible;\n            if (auroraMesh && this._atmosphericEmissionPass) auroraMesh.visible = auroraVisible;\n        }\n        this._perfEnd('atmosphere.clouds.composer');\n        this._finalFrameWritten = true;\n\n        // Store current ellipsoid matrix for next frame's reprojection correction\n        this._previousEllipsoidMatrix.copy(this._planetMatrix);\n\n        this._lastCloudRenderMs = now;\n        return true;\n    }\n\n    didWriteFinalFrame() {\n        return this._finalFrameWritten === true;\n    }\n\n    _getCameraAltitudeMeters() {\n        if (!this.camera) return null;\n        this.camera.getWorldPosition(this._cameraWorldPosition);\n        if (this._cameraWorldPosition.lengthSq() < 1e-6) return null;\n        const camRadius = this._cameraWorldPosition.length();\n        const ellipsoidR = ellipsoidRadiusForWorldDir(this._cameraWorldPosition, this.planetGroup);\n        const altitude = Math.max(0, camRadius - ellipsoidR);\n        this._lastCameraAltitudeM = altitude;\n        return altitude;\n    }\n\n    _updateHighOrbitComposerMode(altitude) {\n        const limit = this._cloudComposerCloudMaxAltitudeM;\n        if (!Number.isFinite(limit) || limit <= 0) return;\n        if (!Number.isFinite(altitude)) return;\n        const hysteresis = Number.isFinite(this._cloudComposerCloudHysteresisM)\n            ? Math.max(0, this._cloudComposerCloudHysteresisM)\n            : 0;\n        const exitAltitude = Math.max(0, limit - hysteresis);\n        const next = this._cloudComposerHighOrbitActive\n            ? altitude > exitAltitude\n            : altitude >= limit;\n        if (next === this._cloudComposerHighOrbitActive) return;\n\n        this._cloudComposerHighOrbitActive = next;\n        // Cloud altitude does not change the scene G-buffer. The former call\n        // into _syncComposerGBufferMode rebuilt the unrelated post-effects\n        // material synchronously at this exact boundary.\n        this._applySkyMeshVisibility();\n        this._applyCloudsEnabled();\n    }\n\n    /**\n     * Select the composer's photoreal lighting-mask budget from scene content\n     * and altitude. Surface irradiance deliberately uses Takram's stable\n     * ellipsoid normal instead of a second geometry raster. Google terrain\n     * streams retained parents and vertical boundary/skirt faces whose creased\n     * normals otherwise become black seams under both sun and sky irradiance.\n     * The overview path disables the photoreal mask without changing the\n     * compositor's ownership of the frame.\n     */\n    _syncComposerGBufferMode() {\n        // High orbit retires volumetric cloud work, but it does not imply a\n        // scene-content handoff. A surface-started ascent keeps photoreal\n        // tiles as Earth's rendered surface at every altitude, so their\n        // lighting mask must remain active for sun, sky, terminator, and night\n        // emission. Only the standalone overview globe owns an independent\n        // orbital material and therefore disables the photoreal mask.\n        this._applyHighOrbitComposerBudget(this._orbitalOverviewActive);\n    }\n\n    _applyHighOrbitComposerBudget(active) {\n        if (this.normalPass) {\n            this.normalPass.enabled = false;\n        }\n        if (this._photoLightingMaskPass) {\n            this._photoLightingMaskPass.enabled = !active;\n        }\n        if (this._photorealBackfaceEffect) this._photorealBackfaceEffect.uniforms.get('photoFaceMaskEnabled').value = active || this._photorealUnderwater ? 0 : 1;\n        if (this.aerialPerspective) {\n            // Null with reconstruction disabled selects Takram's radial\n            // ellipsoid normal. Do not substitute a black normal texture:\n            // that marks every pixel degenerate and silently disables\n            // irradiance instead of applying the seam-free surface light.\n            this.aerialPerspective.normalBuffer = null;\n            this.aerialPerspective.reconstructNormal = false;\n            this.aerialPerspective.lightingMask = active\n                ? (this._disabledPhotoLightingMask ?? null)\n                : (this._activePhotoLightingMask ?? null);\n        }\n        this._refreshPostEffectsPass();\n    }\n\n    setPhotorealUnderwater(underwater) {\n        this._photorealUnderwater = underwater === true;\n        const enabled = this._photorealUnderwater ? 0 : 1;\n        const uniform = this.aerialPerspective?.uniforms?.get('ncaPhotoBackfaceEnabled');\n        if (uniform) uniform.value = enabled;\n        const material = this._photoLightingMaskPass?.renderPass?.overrideMaterial;\n        if (material) material.userData.photoBackfaceMaskDisabled = this._photorealUnderwater;\n        if (this._photorealBackfaceEffect) this._photorealBackfaceEffect.uniforms.get('photoFaceMaskEnabled').value = this._orbitalOverviewActive ? 0 : enabled;\n    }\n\n    resize() {\n        if (!this.composer) return;\n        this.renderer.getDrawingBufferSize(this._tmpSize);\n        this.composer.setSize(this._tmpSize.x, this._tmpSize.y);\n    }\n\n    dispose() {\n        this._nativeXRRenderer?.dispose(); this._nativeXRRenderer = null;\n        this._nativeXRClouds?.dispose(); this._nativeXRClouds = null;\n        if (this._disposed) return;\n        this._disposed = true;\n        this._lensStage?.dispose(); this._lensStage = null;\n        this.setPresentationSuspended(false);\n        this._lutConversionController?.abort();\n        disposeAtmosphereLuts(this._precomputedTextures);\n        this._precomputedTextures = null;\n        const cloudWarmupWasScheduled = this._cloudWarmupIdleHandle !== null;\n        this._cancelIdleTask('_cloudWarmupIdleHandle', '_cloudWarmupIdleUsesRequestIdleCallback');\n        if (cloudWarmupWasScheduled) {\n            this._cloudWarmupState = 'cold';\n            this._cloudWarmupResolve?.(false);\n        }\n        this._cancelIdleTask('_orbitCloudVisibilityIdleHandle', '_orbitCloudVisibilityIdleUsesRequestIdleCallback');\n        const activePasses = new Set(this.composer?.passes || []);\n        const composerOwnedEffects = new Set([...activePasses].flatMap((pass) => pass.effects || []));\n        for (const pass of new Set(this._cloudEffectPassVariants.values())) {\n            if (!pass || activePasses.has(pass)) continue;\n            // EffectPass.dispose() also disposes its shared effects. Detached\n            // variants own only their compound material, not the cloud/aerial\n            // effects that may still be used by the active composer pass.\n            pass.setEffects?.([]);\n            pass.fullscreenMaterial?.dispose?.();\n        }\n        this._cloudEffectPassVariants.clear();\n        this._cloudEffectPassBuilds.clear();\n        this._restoreToneMapping();\n        if (this.skyMesh) {\n            this.scene.remove(this.skyMesh);\n            this.skyMesh.geometry?.dispose();\n            this.skyMaterial?.dispose();\n            this._nativeXRSkyMaterial?.dispose();\n            this._nativeXRSkyMaterial = null;\n        }\n        if (this._orbitCloudsMesh) {\n            this._orbitCloudsMesh.parent?.remove?.(this._orbitCloudsMesh);\n            this._orbitCloudsMesh.geometry?.dispose();\n            this._orbitCloudsMaterial?.dispose();\n            this._orbitCloudsMesh = null;\n            this._orbitCloudsMaterial = null;\n            this._orbitCloudsShader = null;\n        }\n        if (this._orbitCloudsRawMesh) {\n            this._orbitCloudsRawMesh.parent?.remove?.(this._orbitCloudsRawMesh);\n            this._orbitCloudsRawMesh.geometry?.dispose();\n            this._orbitCloudsRawMaterial?.dispose();\n            this._orbitCloudsRawMesh = null;\n            this._orbitCloudsRawMaterial = null;\n        }\n        if (this._orbitCloudsGeometry) {\n            this._orbitCloudsGeometry.dispose();\n            this._orbitCloudsGeometry = null;\n        }\n        if (this._airglowMesh) {\n            this._airglowMesh.parent?.remove?.(this._airglowMesh);\n            this._airglowMesh.geometry?.dispose();\n            this._airglowMaterial?.dispose();\n            this._airglowMesh = null;\n            this._airglowMaterial = null;\n        }\n        if (this._auroraSystem) {\n            this._auroraSystem.dispose();\n            this._auroraSystem = null;\n        }\n        if (this._fireSystem) {\n            this._fireSystem.dispose();\n            this._fireSystem = null;\n        }\n        if (this._smokeSystem) {\n            this._smokeSystem.dispose();\n            this._smokeSystem = null;\n        }\n        this._orbitCloudsTexture?.dispose?.();\n        this._orbitCloudsRawTexture?.dispose?.();\n        this._disabledPhotoGBufferTexture?.dispose?.();\n        this._disabledPhotoGBufferTexture = null;\n        this._activePhotoLightingMask = null;\n        this._disabledPhotoLightingMask = null;\n        this.composer?.dispose?.();\n        this._cloudAtmosphereAttachments?.dispose();\n        this._cloudAtmosphereAttachments = null;\n        // Detached variants deliberately do not dispose shared effects. When\n        // the active pass is clear (or only one cloud effect is selected), the\n        // composer therefore does not own those other native target families.\n        // Retire every remaining scene-owned effect once, including early init.\n        for (const effect of new Set([this.clouds, this._orbitCloudsEffect, this.aerialPerspective])) {\n            if (effect && !composerOwnedEffects.has(effect)) effect.dispose?.();\n        }\n        this.normalPass?.dispose?.();\n    }\n\n    _setupAtmosphereCore() {\n        // Bottom radius slightly below planet surface for better ground contact\n        const atmosphereBottomRadius = Math.max(1, PLANET_RADIUS - this.atmosphereBaseOffset);\n        const atmosphereTopRadius = atmosphereBottomRadius + ATMOSPHERE_HEIGHT_M;\n\n        this._atmosphereParams = new AtmosphereParameters({\n            bottomRadius: atmosphereBottomRadius,\n            topRadius: atmosphereTopRadius\n        });\n        this._atmosphereEllipsoid = new Ellipsoid(\n            atmosphereBottomRadius,\n            atmosphereBottomRadius,\n            atmosphereBottomRadius\n        );\n\n        console.log('[AtmosphereClouds] Radius alignment check:');\n        console.log(`  PLANET_RADIUS: ${PLANET_RADIUS.toLocaleString()}m`);\n        console.log(`  atmosphereBaseOffset: ${this.atmosphereBaseOffset.toLocaleString()}m`);\n        console.log(`  bottomRadius: ${atmosphereBottomRadius.toLocaleString()}m`);\n        console.log(`  topRadius: ${atmosphereTopRadius.toLocaleString()}m`);\n\n        this.aerialPerspective = new AerialPerspectiveEffect(this.camera, {\n            ellipsoid: this._atmosphereEllipsoid,\n            correctGeometricError: true,\n            correctAltitude: true,\n            inscatter: true,\n            transmittance: true,\n            // The current Three.js 3D Tiles reference treats the provider's\n            // baked unlit imagery as albedo and applies physical sun + sky\n            // irradiance here. The hardware-depth photoreal mask confines this\n            // reinterpretation to tile pixels so the r182 overview/orbit\n            // materials are never multiplied a second time.\n            sunLight: true,\n            skyLight: true,\n            albedoScale: PHOTOREAL_ALBEDO_SCALE_DEFAULT,\n            sky: true,\n            // SceneInitializer supplies physical astronomical meshes. These\n            // start disabled and _syncCelestialDiskOwnership() enables a\n            // procedural fallback only if one of those meshes is absent.\n            sun: false,\n            moon: false\n        }, this._atmosphereParams);\n        this.aerialPerspective.sky = true;\n        this.aerialPerspective.uniforms.set('ncaPhotoBackfaceEnabled', new THREE.Uniform(this._photorealUnderwater ? 0 : 1));\n        this._syncCelestialDiskOwnership();\n        ensureCelestialOcclusionUniforms(this.aerialPerspective);\n        // Preserve public setting names for saved-scene compatibility while\n        // binding them to Takram 0.19's real API.\n        this._irradianceScaleBase = this.aerialPerspective.albedoScale;\n        this._sunIrradianceBase = this.aerialPerspective.sunLight;\n        this._skyIrradianceBase = this.aerialPerspective.skyLight;\n        this._currentIrradianceScale = this.aerialPerspective.albedoScale;\n        this._applySkyTuning();\n    }\n\n    _setupCloudEffects() {\n        this.clouds = new CloudsEffect(this.camera, undefined, this._atmosphereParams);\n        patchCloudDepthReconstruction(this.clouds);\n        this._applyCloudQualityPreset();\n        this._applyCloudShadowTuning();\n        this._applyCloudDepthPacking(this.clouds);\n        this.clouds.ellipsoid = this._atmosphereEllipsoid;\n        this.clouds.atmosphere = this._atmosphereParams;\n        this.clouds.coverage = 0.3;\n        this.clouds.localWeatherVelocity.set(0.001, 0);\n        this.clouds.shapeVelocity.set(0, 0, 0);\n        this.clouds.shapeDetailVelocity.set(0, 0, 0);\n\n        // Configure cloud layer properties (altitudes will be set by _updateCloudLayersForTerrain)\n        if (this.clouds.cloudLayers) {\n            const layers = this.clouds.cloudLayers;\n            if (layers[0]) {\n                layers[0].shadow = true;\n            }\n            if (layers[1]) {\n                layers[1].shadow = true;\n            }\n            if (layers[2]) {\n                layers[2].shadow = true;  // High clouds cast broad ground shadows visible from altitude\n            }\n        }\n\n        // Initialize with default terrain elevation (will be updated when terrain data arrives)\n        // Default assumes sea level terrain, so initial altitude = atmosphereBaseOffset\n        this._terrainElevation = this.atmosphereBaseOffset;\n        this._updateCloudLayersForTerrain();\n\n        this.clouds.events.addEventListener('change', (event) => {\n            if (event?.property) {\n                this._onCloudsChange(event.property);\n            }\n        });\n        this._captureCloudBaseSettings();\n        this._cloudBlendFunction = this.clouds?.blendMode?.blendFunction ?? BlendFunction.NORMAL;\n\n        const startupAltitude = this._getCameraAltitudeMeters();\n        if (Number.isFinite(startupAltitude)\n            && startupAltitude >= CLOUD_DISTANCE_TUNING.cullAltitude) {\n            this._cloudComposerHighOrbitActive = true;\n            this._cloudLodState.disabled = true;\n            this._applyDormantSurfaceCloudBudget();\n        } else {\n            this._beginSurfaceCloudActivation();\n        }\n    }\n\n    _setupComposerCore() {\n        // The current Three example uses a geometry NormalPass in its\n        // single-tile-scene demonstration. At eye height in a continuously\n        // refining globe, that pass also rasterizes retained coarse parents\n        // and vertical tile skirts. Their discontinuous creased normals turn\n        // into black interference under either irradiance term. Takram's\n        // no-buffer/no-reconstruction path uses the ellipsoid normal, which\n        // keeps physical day/night irradiance without relighting streaming\n        // topology. The photoreal layer mask still confines that light to tiles.\n        this.normalPass = null;\n        this._photoLightingMaskPass = new PhotorealLightingMaskPass(\n            this.scene,\n            this.camera,\n            PHOTO_DEFERRED_LIGHTING_LAYER\n        );\n        this._photoLightingMaskPass.selectionLayer = PHOTO_DEFERRED_LIGHTING_LAYER;\n        // Render the selected layer directly. Takram's general mixed-lighting\n        // pass round-trips two depth buffers through packed RGBA before\n        // comparing them; with NOCLIP's 0.1 m → astronomical logarithmic depth\n        // range that comparison becomes a salt-and-pepper mask. Hardware depth\n        // testing within the photoreal layer keeps the mask stable.\n        const lightingMaskMaterial = this._photoLightingMaskPass.renderPass?.overrideMaterial;\n        if (lightingMaskMaterial) {\n            preparePhotorealSurfaceVisibilityMaterial(lightingMaskMaterial);\n            this._photoLightingMaskPass.renderPass.overrideMaterial = lightingMaskMaterial;\n        }\n        this.aerialPerspective.normalBuffer = null;\n        this.aerialPerspective.reconstructNormal = false;\n        this._disabledPhotoGBufferTexture = new THREE.DataTexture(\n            new Uint8Array([0, 0, 0, 0]),\n            1,\n            1,\n            THREE.RGBAFormat,\n            THREE.UnsignedByteType\n        );\n        this._disabledPhotoGBufferTexture.name = 'PhotorealDeferredLighting.Disabled';\n        this._disabledPhotoGBufferTexture.minFilter = THREE.NearestFilter;\n        this._disabledPhotoGBufferTexture.magFilter = THREE.NearestFilter;\n        this._disabledPhotoGBufferTexture.generateMipmaps = false;\n        this._disabledPhotoGBufferTexture.colorSpace = THREE.NoColorSpace;\n        this._disabledPhotoGBufferTexture.needsUpdate = true;\n        this._activePhotoLightingMask = {\n            map: this._photoLightingMaskPass.texture,\n            channel: 'r',\n        };\n        this._disabledPhotoLightingMask = {\n            map: this._disabledPhotoGBufferTexture,\n            channel: 'r',\n        };\n        this.aerialPerspective.lightingMask = this._activePhotoLightingMask;\n\n        // Keep the color/depth buffer on the same single-sample raster grid as\n        // the photoreal layer mask. Multisampling only the main half-float\n        // targets resolves partial triangle coverage without a matching mask\n        // sample. SMAA antialiases the completed image instead.\n        const multisampling = 0;\n        this._composerSamples = multisampling;\n        this.composer = new EffectComposer(this.renderer, {\n            frameBufferType: THREE.HalfFloatType,\n            multisampling\n        });\n\n        this.composer.addPass(new RenderPass(this.scene, this.camera));\n        this._oceanDepthPass = new OceanDepthPass(this.camera);\n        this.composer.addPass(this._oceanDepthPass);\n        this.composer.addPass(this._photoLightingMaskPass);\n        const gBufferDisabled = this._orbitalOverviewActive;\n        this._photoLightingMaskPass.enabled = !gBufferDisabled;\n        if (gBufferDisabled) {\n            this.aerialPerspective.lightingMask = this._disabledPhotoLightingMask;\n        }\n    }\n\n    _setupSkyAndAerialPass() {\n        this.aerialPerspective.fragmentShader = decodeCloudShadowDepth(this.aerialPerspective.fragmentShader);\n        this._cloudAtmosphereAttachments = new CloudAtmosphereAttachments(\n            this.aerialPerspective, this.clouds?.shadow?.cascadeCount ?? 3, this.clouds);\n        // Prime native camera/lighting-mask uniforms before any pass listens\n        // for structural changes. Cloud on/off is uniform-only afterwards.\n        this.aerialPerspective.update(this.renderer, undefined, 0);\n        // Sky material for background\n        this.skyMaterial = new SkyMaterial();\n        this.skyMaterial.ellipsoid = this._atmosphereEllipsoid;\n        this.skyMaterial.atmosphere = this._atmosphereParams;\n        // SkyMaterial does not expose AtmosphereParameters as a constructor\n        // argument in Takram 0.19. Keep its Bruneton struct on the same custom\n        // 100 km atmosphere contract as the aerial and cloud effects.\n        this._syncAtmosphereParameterStruct(this.skyMaterial);\n        this._syncCelestialDiskOwnership();\n        this.skyMesh = new THREE.Mesh(new THREE.PlaneGeometry(2, 2), this.skyMaterial);\n        this.skyMesh.frustumCulled = false;\n        this.skyMesh.renderOrder = -1000;\n        this.skyMesh.userData.lensflare = 'no-occlusion';\n        this.scene.add(this.skyMesh);\n        this._applySkyMeshVisibility();\n\n        // Cloud effects are activated only after their shader variants and\n        // render resources have been warmed in an idle task. This avoids a\n        // synchronous GPU setup when the camera crosses into surface range.\n        // Aerial perspective alone uses up to 16 fragment samplers. Merging\n        // CloudsEffect into the same shader adds one sampler per cloud family\n        // and fails on WebGL 2 devices with the guaranteed 16-unit limit.\n        // Native composer ping-pong keeps the same HDR pixels/depth and effect\n        // order without another target or any loss of cloud/atmosphere quality.\n        this._cloudsEffectPass = new EffectPass(this.camera);\n        this._cloudsEffectPass.enabled = false;\n        this.composer.addPass(this._cloudsEffectPass);\n        this._aerialEffectPass = new EffectPass(this.camera, this.aerialPerspective);\n        this._waterReflectionPass = new WaterReflectionCapturePass(this);\n        this.composer.addPass(this._waterReflectionPass);\n        const renderAerial=this._aerialEffectPass.render.bind(this._aerialEffectPass);\n        this._aerialEffectPass.render=(...args)=>{\n            const deferred=this.aerialPerspective.uniforms.get('ncaCloudOverlayDeferred');\n            const previous=deferred.value;deferred.value=this._deferMainCloudOverlay===false?0:1;\n            try{return renderAerial(...args);}finally{deferred.value=previous;}\n        };\n        this.composer.addPass(this._aerialEffectPass);\n        this._cloudEffectPassVariants.set('clear:clear', this._cloudsEffectPass);\n        this._applyCloudsEnabled();\n    }\n\n    _setupPostEffects() {\n        this._oceanSurfacePass = new OceanSurfacePass(this.scene, this.camera);\n        this.composer.addPass(this._oceanSurfacePass);\n        this._cloudColorPass = new CloudColorPass(this.camera);\n        this.composer.addPass(this._cloudColorPass);\n        this._atmosphericEmissionPass = new AtmosphericEmissionPass(this.camera);\n        this.composer.addPass(this._atmosphericEmissionPass);\n        this._rainPass = new RainPass(this.scene, this.camera);\n        this._rainPass.rainSystem = this._rainSystem || null;\n        this.composer.addPass(this._rainPass);\n        // Distance through dense air softens detail (horizon / limb); its own\n        // pass because SMAA already owns the final pass's convolution slot.\n        this._horizonBlurEffect = new AtmosphericHorizonBlurEffect(this.camera, () => this._planetMatrixInverse);\n        this._horizonBlurPass = new EffectPass(this.camera, this._horizonBlurEffect);\n        this.composer.addPass(this._horizonBlurPass);\n        this._underwaterEffect = new UnderwaterEffect(this.camera);\n        this._nightVisionEffect = new NightVisionEffect();\n        this._nightVisionEffect.setState(this._nightVisionEnabled, this._nightVisionSettings);\n        const finalEffects = [this._underwaterEffect];\n        if (this._bloomEnabled) {\n            const bloom = new BloomEffect({ ...this._bloomSettings });\n            this._bloomEffect = bloom;\n            finalEffects.push(bloom);\n        }\n        // Do not project the night-light field as an independent post effect.\n        // NASA source pixels emit only at real provider/fallback surface depth\n        // in the terrain or deferred photoreal path.\n        this._lightPollutionBloomEffect = null;\n        // COMPOSITOR INVARIANT: this pass intentionally contains no\n        // LensFlareEffect. The scene already owns its astronomical lens flare,\n        // and the convolution effect was absent from the last known-good\n        // orbital compositor. Keep the working morning chain: bloom (optional),\n        // tone mapping, SMAA, dithering.\n        if (this.useToneMapping) {\n            const toneMapping = new ToneMappingEffect({ mode: this.toneMappingMode });\n            this._toneMappingEffect = toneMapping;\n            finalEffects.push(toneMapping);\n        }\n        if (this._composerSamples === 0) {\n            const smaa = new SMAAEffect({ preset: SMAAPreset.MEDIUM });\n            this._smaaEffect = smaa;\n            finalEffects.push(smaa);\n        }\n        // Sensor grain on the finished (tone-mapped, antialiased) image; always\n        // compiled in, switched by a uniform so toggling never rebuilds the pass.\n        this._lensStage ||= new LensEffectsStage({ camera: this.camera });\n        // Grade (CSS-equivalent contrast/brightness/saturate), then grain.\n        finalEffects.push(this._lensStage.grade, this._lensStage.grain);\n        if (this.enableDithering) {\n            const dithering = new DitheringEffect();\n            this._ditheringEffect = dithering;\n            finalEffects.push(dithering);\n        }\n        this._sarEffect ||= new SarEffect();\n        finalEffects.push(this._nightVisionEffect, this._sarEffect);\n        this._photorealBackfaceEffect ||= new PhotorealBackfaceEffect(this._photoLightingMaskPass.texture, !this._orbitalOverviewActive && !this._photorealUnderwater);\n        finalEffects.push(this._photorealBackfaceEffect);\n        if (finalEffects.length > 0) {\n            this._postEffectsPass = new EffectPass(this.camera, ...finalEffects);\n            this.composer.addPass(this._postEffectsPass);\n        }\n        // Lens modifiers (DOF, chromatic aberration) act on HDR scene light,\n        // before bloom and tone mapping in the final pass.\n        this._lensStage ||= new LensEffectsStage({ camera: this.camera });\n        if (this._lensConfig) this._lensStage.applyConfig(this._lensConfig);\n        this._lensStage.attach(this.composer, this._postEffectsPass);\n\n        this._syncToneMappingForRenderPath();\n        this._syncLogDepthDefines();\n        this._patchCloudsCameraHeight();\n        this._patchCloudsNightLighting();\n        this._patchCloudsLiveCoverage();\n        this.resize();\n    }\n\n    _normalizeBasePath() {\n        if (!this.basePath) return DEFAULT_BASE_PATH;\n        return this.basePath.endsWith('/') ? this.basePath : `${this.basePath}/`;\n    }\n\n    async _loadTextures() {\n        const basePath = this._normalizeBasePath();\n        const register = (key) => {\n            this._pendingLoads.add(key);\n        };\n        const complete = (key) => {\n            if (this._disposed) return;\n            this._pendingLoads.delete(key);\n            if (this._pendingLoads.size === 0) {\n                this.ready = true;\n                console.log('[AtmosphereClouds] All textures loaded, system ready');\n                // Texture decoding finishes off the render path. GPU upload,\n                // render-target allocation, and shader compilation are warmed\n                // in a follow-up idle task instead of the first surface frame.\n                void this._scheduleCloudWarmup();\n            }\n        };\n        const fail = (key, error) => {\n            console.warn(`[AtmosphereCloudsSystem] Failed to load ${key}`, error);\n            complete(key);\n        };\n\n        register('precomputed');\n        register('localWeather');\n        register('shape');\n        register('shapeDetail');\n        register('turbulence');\n        register('stbn');\n\n        // The shipped Bruneton LUTs are the only runtime source. Generating a\n        // recovery set executes a long chain of WebGL renders synchronously;\n        // doing that while the user is navigating can stop RAF entirely. A\n        // missing/corrupt LUT therefore fails closed to the direct atmosphere\n        // shell and can be retried by the existing recovery lifecycle.\n        let requestedLutType;\n        const precomputedPromise = new Promise((resolve, reject) => {\n            const loader = new PrecomputedTexturesLoader({\n                format: 'binary',\n                higherOrderScattering: false,\n            });\n            // 0.12 (the r182 reference renderer) exposes setTypeFromRenderer;\n            // newer releases renamed it to setType. Assigning format explicitly\n            // is required because 0.12's inherited constructor ignores the\n            // options object and otherwise defaults to EXR.\n            loader.format = 'binary';\n            if (typeof loader.setType === 'function') {\n                loader.setType(this.renderer);\n            } else {\n                loader.setTypeFromRenderer?.(this.renderer);\n            }\n            requestedLutType = loader.type;\n            // Keep the shipped half-float bytes through the upstream decoder.\n            // Float-capable renderers still receive exact Float32 output, but\n            // conversion is bounded/task-sliced rather than a giant iterable.\n            loader.type = THREE.HalfFloatType;\n            loader.load(`${basePath}assets/atmosphere`, resolve, undefined, reject);\n        }).then(async (textures) => {\n            try {\n                await prepareAtmosphereLuts(textures, requestedLutType, {\n                    signal: this._lutConversionController.signal,\n                });\n                if (this._disposed || this._lutConversionController.signal.aborted) {\n                    throw new DOMException('Atmosphere disposed during LUT preparation', 'AbortError');\n                }\n                this._precomputedTextures = textures;\n                return textures;\n            } catch (error) {\n                // Includes raw loader completion after this system was disposed.\n                disposeAtmosphereLuts(textures);\n                throw error;\n            }\n        });\n\n        precomputedPromise\n            .then((textures) => {\n                if (this._disposed) return;\n                if (this.aerialPerspective) {\n                    Object.assign(this.aerialPerspective, textures);\n                }\n                if (this.clouds) {\n                    Object.assign(this.clouds, textures);\n                }\n                if (this._orbitCloudsEffect) {\n                    Object.assign(this._orbitCloudsEffect, textures);\n                }\n                if (this.skyMaterial) {\n                    Object.assign(this.skyMaterial, textures);\n                }\n                // Patch sky depth handling after textures are loaded\n                // (fragmentShader is available after first render/setup)\n                this._waitForAnimationFrame().then(() => {\n                    if (!this._disposed) this._patchSkyDepthRule();\n                });\n                void this._warmDirectPhysicalSky().catch(error => {\n                    if (!this._disposed) console.warn('[AtmosphereClouds] Physical sky preparation failed', error);\n                });\n                complete('precomputed');\n            })\n            .catch((error) => {\n                // Do not mark this required resource complete. init() rejects\n                // below, SceneInitializer retains the direct shell, and no\n                // cloud GPU warm-up is allowed to start with incomplete LUTs.\n                console.warn('[AtmosphereCloudsSystem] Failed to load precomputed atmosphere LUTs', error);\n            });\n\n        const textureLoader = new THREE.TextureLoader();\n        textureLoader.load(\n            `${basePath}assets/clouds/local_weather.png`,\n            (texture) => {\n                if (this.clouds) {\n                    texture.minFilter = THREE.LinearMipMapLinearFilter;\n                    texture.magFilter = THREE.LinearFilter;\n                    texture.wrapS = THREE.RepeatWrapping;\n                    texture.wrapT = THREE.RepeatWrapping;\n                    texture.colorSpace = THREE.NoColorSpace;\n                    texture.needsUpdate = true;\n                    const existing = this.clouds.localWeatherTexture;\n                    this._defaultLocalWeatherTexture = texture;\n                    if (!existing || existing === texture) {\n                        this.clouds.localWeatherTexture = texture;\n                    }\n                }\n                complete('localWeather');\n            },\n            undefined,\n            (error) => fail('localWeather', error)\n        );\n\n        // The reference constructs Data3DTexture directly from the cloud\n        // volume bytes. Keeping this explicit also makes the volume layout\n        // independent of removed geospatial loader-factory APIs.\n        const loadData3DTexture = async (url, size, property, loadKey) => {\n            try {\n                const response = await getFetchQueue().fetchBinary(url);\n                if (!response.ok || !response.buffer) {\n                    throw response.error || new Error(`Cloud volume fetch failed: ${response.status}`);\n                }\n                const buffer = response.buffer;\n                const texture = new THREE.Data3DTexture(\n                    new Uint8Array(buffer),\n                    size,\n                    size,\n                    size\n                );\n                texture.format = THREE.RedFormat;\n                texture.minFilter = THREE.LinearFilter;\n                texture.magFilter = THREE.LinearFilter;\n                texture.wrapS = THREE.RepeatWrapping;\n                texture.wrapT = THREE.RepeatWrapping;\n                texture.wrapR = THREE.RepeatWrapping;\n                texture.colorSpace = THREE.NoColorSpace;\n                texture.needsUpdate = true;\n                if (this.clouds) this.clouds[property] = texture;\n                if (this._orbitCloudsEffect) this._orbitCloudsEffect[property] = texture;\n                complete(loadKey);\n            } catch (error) {\n                fail(loadKey, error);\n            }\n        };\n        loadData3DTexture(\n            `${basePath}assets/clouds/shape.bin`,\n            CLOUD_SHAPE_TEXTURE_SIZE,\n            'shapeTexture',\n            'shape'\n        );\n        loadData3DTexture(\n            `${basePath}assets/clouds/shape_detail.bin`,\n            CLOUD_SHAPE_DETAIL_TEXTURE_SIZE,\n            'shapeDetailTexture',\n            'shapeDetail'\n        );\n\n        textureLoader.load(\n            `${basePath}assets/clouds/turbulence.png`,\n            (texture) => {\n                if (this.clouds) {\n                    texture.minFilter = THREE.LinearMipMapLinearFilter;\n                    texture.magFilter = THREE.LinearFilter;\n                    texture.wrapS = THREE.RepeatWrapping;\n                    texture.wrapT = THREE.RepeatWrapping;\n                    texture.colorSpace = THREE.NoColorSpace;\n                    texture.needsUpdate = true;\n                    this.clouds.turbulenceTexture = texture;\n                }\n                if (this._orbitCloudsEffect) {\n                    this._orbitCloudsEffect.turbulenceTexture = texture;\n                }\n                complete('turbulence');\n            },\n            undefined,\n            (error) => fail('turbulence', error)\n        );\n\n        new STBNLoader().load(\n            `${basePath}assets/core/stbn.bin`,\n            (texture) => {\n                if (this.aerialPerspective) {\n                    this.aerialPerspective.stbnTexture = texture;\n                }\n                if (this.clouds) {\n                    this.clouds.stbnTexture = texture;\n                }\n                if (this._orbitCloudsEffect) {\n                    this._orbitCloudsEffect.stbnTexture = texture;\n                }\n                complete('stbn');\n            },\n            undefined,\n            (error) => fail('stbn', error)\n        );\n\n        await precomputedPromise;\n    }\n\n    _updateEllipsoidTransform() {\n        if (!this.planetGroup || !this.aerialPerspective || !this.clouds) return;\n        // Only the Earth frame is read here. Updating descendants visits every\n        // retained provider mesh twice during native sky/aerial preparation.\n        // Their own sampling/render owners publish descendant matrices.\n        this.planetGroup.updateWorldMatrix(true, false);\n        this._planetMatrix.copy(this.planetGroup.matrixWorld);\n        this._planetMatrix.setPosition(0, 0, 0);\n\n        this._planetMatrixInverse.copy(this._planetMatrix).invert();\n        this.planetGroup.getWorldPosition(this._planetCenterECEF);\n        this._planetCenterECEF.applyMatrix4(this._planetMatrixInverse);\n\n        this._syncEffectEllipsoidFrame(this.aerialPerspective);\n        this._syncCelestialOccluders();\n        this._syncEffectEllipsoidFrame(this.clouds);\n        if (this._orbitCloudsEffect) {\n            this._syncEffectEllipsoidFrame(this._orbitCloudsEffect);\n        }\n        // Update skyMaterial with Earth rotation (extends AtmosphereMaterialBase which has these properties)\n        if (this.skyMaterial) {\n            this._syncEffectEllipsoidFrame(this.skyMaterial);\n        }\n    }\n\n    _syncEffectEllipsoidFrame(target) {\n        if (!target) return;\n\n        if (target.worldToECEFMatrix?.copy) {\n            target.worldToECEFMatrix.copy(this._planetMatrixInverse);\n        } else if (target.uniforms?.get?.('worldToECEFMatrix')?.value?.copy) {\n            target.uniforms.get('worldToECEFMatrix').value.copy(this._planetMatrixInverse);\n        } else if (target.uniforms?.worldToECEFMatrix?.value?.copy) {\n            target.uniforms.worldToECEFMatrix.value.copy(this._planetMatrixInverse);\n        }\n\n        if (target.ellipsoidMatrix?.copy) {\n            target.ellipsoidMatrix.copy(this._planetMatrix);\n        }\n        if (target.ellipsoidCenter?.copy) {\n            target.ellipsoidCenter.copy(this._planetCenterECEF);\n        }\n    }\n\n    _updateSunDirection() {\n        if (!this.lightingSystem || !this.aerialPerspective || !this.clouds) return;\n        this._sunDirection.copy(this.lightingSystem.sun.position).normalize();\n        if (this.planetGroup) {\n            this._sunDirection.applyMatrix4(this._planetMatrixInverse).normalize();\n        }\n        this.aerialPerspective.sunDirection.copy(this._sunDirection);\n        this.clouds.sunDirection.copy(this._sunDirection);\n        if (this._orbitCloudsEffect) {\n            this._orbitCloudsEffect.sunDirection.copy(this._sunDirection);\n        }\n        if (this.skyMaterial) {\n            this.skyMaterial.sunDirection.copy(this._sunDirection);\n        }\n    }\n\n    _syncCelestialOccluders() {\n        if (!this.aerialPerspective) return;\n        syncCelestialOcclusionUniforms(this.aerialPerspective, {\n            moonMesh: this._moonMesh,\n            sunMesh: this._sunMesh,\n            worldToECEFMatrix: this._planetMatrixInverse,\n            scratchWorld: this._celestialScratchWorld,\n        });\n        const moonCenter = this.aerialPerspective.uniforms?.get?.('ncaMoonCenterECEF');\n        const moonRadius = this.aerialPerspective.uniforms?.get?.('ncaMoonRadius');\n        const moonPhysicalRadius = this.aerialPerspective.uniforms\n            ?.get?.('ncaMoonPhysicalRadius');\n        if (moonPhysicalRadius) {\n            moonPhysicalRadius.value = moonCenter?.value && (moonRadius?.value ?? 0) > 0\n                ? MOON_RADIUS_M / 1000\n                : 0;\n        }\n        if (moonCenter?.value && (moonRadius?.value ?? 0) > 0) {\n            this._moonDirection.copy(moonCenter.value).normalize();\n            this.aerialPerspective.moonDirection.copy(this._moonDirection);\n            if (this.skyMaterial) {\n                this.skyMaterial.moonDirection.copy(this._moonDirection);\n            }\n        }\n    }\n\n    // Shared high-atmosphere emission carrier. The night side renders the\n    // green/red airglow profile, while the day side renders a blue grazing limb\n    // through the SAME uFringeAlt boundary. Do not enlarge Takram's physical\n    // scattering top radius to achieve this: the shipped Bruneton LUTs are\n    // precomputed for that physical radius. This analytic carrier is what lets\n    // the visible daylight boundary reach the configured airglow height without\n    // invalidating those LUT coordinates.\n    _ensureAirglowShell(parent) {\n        if (this._airglowMesh) {\n            if (this._airglowMesh.parent !== parent) {\n                this._airglowMesh.parent?.remove?.(this._airglowMesh);\n                parent.add(this._airglowMesh);\n            }\n            return;\n        }\n        // Airglow vertical structure (meters above the surface). Unlike a single thin\n        // layer, the visible band spans from just above the horizon up through a pale\n        // fringe: a dense core hugging the limb, then a soft exponential tail to space.\n        const baseAlt = this._airglowBaseAlt;\n        const coreAlt = this._airglowCoreAlt;\n        const fringeAlt = this._airglowFringeAlt;\n        const riseScale = this._airglowRiseScale;\n        const tailScale = this._airglowTailScale;\n        // The shell is drawn from the inside (BackSide) and scaled each frame to always\n        // enclose the camera, so the band renders at any view distance — the previous\n        // fixed FrontSide shell vanished whenever the camera dropped inside it. The band\n        // itself comes from the per-ray altitude math, not the shell radius.\n        this._airglowFringeAlt = fringeAlt;\n        const strength = Number.isFinite(this._airglowStrength) ? this._airglowStrength : AIRGLOW_EMISSION_DEFAULTS.strength;\n        const pathRef = Number.isFinite(this._airglowPathRef) ? this._airglowPathRef : 900000;\n        // Aurora/airglow colors low->high (per NASA SVS 12963 / ISS imagery, where\n        // green sits below red): gentle sodium-yellow just above the horizon, the\n        // bright atomic-oxygen green core (~557 nm), the fainter oxygen red layer\n        // (~630 nm) higher up, fading to a pale red fringe at space.\n        const colHorizon = this._airglowColHorizon || new THREE.Color(0.88, 0.80, 0.45);\n        const colCore = this._airglowColCore || new THREE.Color(0.38, 1.0, 0.55);\n        const colUpper = this._airglowColUpper || new THREE.Color(0.85, 0.38, 0.35);\n        const colFringe = this._airglowColFringe || new THREE.Color(0.72, 0.52, 0.55);\n        this._airglowMaterial = new THREE.ShaderMaterial({\n            uniforms: {\n                uSunDirWorld: { value: new THREE.Vector3(0, 0, 1) },\n                uCameraWorld: { value: new THREE.Vector3() },\n                uPlanetCenterW: { value: new THREE.Vector3() },\n                ncaMoonCenterWorld: { value: new THREE.Vector3() },\n                ncaMoonRadiusWorld: { value: 0 },\n                ncaSunCenterWorld: { value: new THREE.Vector3() },\n                ncaSunRadiusWorld: { value: 0 },\n                uPlanetRadius: { value: PLANET_RADIUS },\n                uWorldToPlanet: { value: new THREE.Matrix4() },\n                uAirglowView: { value: new THREE.Matrix4() },\n                uAirglowProjection: { value: new THREE.Matrix4() },\n                uBaseAlt: { value: baseAlt },\n                uCoreAlt: { value: coreAlt },\n                uFringeAlt: { value: fringeAlt },\n                uRiseScale: { value: riseScale },\n                uTailScale: { value: tailScale },\n                uColHorizon: { value: colHorizon },\n                uColCore: { value: colCore },\n                uColUpper: { value: colUpper },\n                uColFringe: { value: colFringe },\n                uStrength: { value: strength },\n                uDayStrength: {\n                    value: Number.isFinite(this._airglowDayStrength)\n                        ? this._airglowDayStrength\n                        : DEFAULT_AIRGLOW_DAY_STRENGTH\n                },\n                uPathRef: { value: pathRef },\n                uInsideMin: { value: this._airglowInsideMin },\n                uInsideMax: { value: this._airglowInsideMax },\n                uGrazingPower: { value: this._airglowGrazingPower }\n            },\n            vertexShader: `\n                #include <common>\n                #include <logdepthbuf_pars_vertex>\n                varying vec3 vPosW;\n                void main() {\n                    vec4 wp = modelMatrix * vec4(position, 1.0);\n                    vPosW = wp.xyz;\n                    gl_Position = projectionMatrix * viewMatrix * wp;\n                    #include <logdepthbuf_vertex>\n                }\n            `,\n            fragmentShader: `\n                precision highp float;\n                #include <common>\n                #include <logdepthbuf_pars_fragment>\n                uniform vec3 uSunDirWorld;\n                uniform vec3 uCameraWorld;\n                uniform vec3 uPlanetCenterW;\n                uniform vec3 ncaMoonCenterWorld;\n                uniform float ncaMoonRadiusWorld;\n                uniform vec3 ncaSunCenterWorld;\n                uniform float ncaSunRadiusWorld;\n                uniform float uPlanetRadius;\n                uniform mat4 uWorldToPlanet, uAirglowView, uAirglowProjection;\n                uniform float uBaseAlt;\n                uniform float uCoreAlt;\n                uniform float uFringeAlt;\n                uniform float uRiseScale;\n                uniform float uTailScale;\n                uniform vec3 uColHorizon;\n                uniform vec3 uColCore;\n                uniform vec3 uColUpper;\n                uniform vec3 uColFringe;\n                uniform float uStrength;\n                uniform float uDayStrength;\n                uniform float uPathRef;\n                uniform float uInsideMin;\n                uniform float uInsideMax;\n                uniform float uGrazingPower;\n                varying vec3 vPosW;\n\n                ${CELESTIAL_OCCLUSION_INTERSECTION_GLSL}\n\n                vec3 dayAltTint(float alt) {\n                    // The physical scattering pass supplies the dense lower\n                    // atmosphere. This is only its tall, luminous blue limb,\n                    // fading through the exact same outer height as airglow.\n                    float upper = smoothstep(uBaseAlt, uFringeAlt, alt);\n                    return mix(vec3(0.16, 0.43, 0.95), vec3(0.48, 0.72, 1.0), upper);\n                }\n\n                // Expanded WGS84 ellipsoids retain the same altitude at the\n                // poles and equator; a sphere is 21 km wrong near the poles.\n                vec3 airglowAxes(float altitude) {\n                    return vec3(6378137.0, 6356752.314245, 6378137.0) + altitude;\n                }\n                vec2 airglowIntersection(vec3 origin, vec3 direction, float altitude) {\n                    vec3 axes = airglowAxes(altitude);\n                    vec3 o = origin / axes, d = direction / axes;\n                    float a = dot(d, d), b = dot(o, d), c = dot(o, o) - 1.0;\n                    float discriminant = b * b - a * c;\n                    if (discriminant <= 0.0) return vec2(-1.0);\n                    float root = sqrt(discriminant);\n                    return vec2(-b - root, -b + root) / a;\n                }\n                float airglowAltitude(vec3 p) {\n                    vec3 direction = normalize(p);\n                    return length(p) - 1.0 / length(direction / airglowAxes(0.0));\n                }\n                ${AIRGLOW_EMISSION_GLSL}\n                void main() {\n                    // Integrate emission along the view ray through the airglow layer,\n                    // like the day-side atmosphere's inscatter. Limb rays traverse a long\n                    // path (bright band); rays onto the night disk traverse only the thin\n                    // near-side layer before the surface (the faint glow seen \"behind\" the\n                    // horizon). Works at any view distance.\n                    vec3 rdWorld = normalize(vPosW - uCameraWorld);\n                    vec3 rd = normalize(mat3(uWorldToPlanet) * rdWorld);\n                    vec3 oc = (uWorldToPlanet * vec4(uCameraWorld, 1.0)).xyz;\n                    vec2 outerHit = airglowIntersection(oc, rd, uFringeAlt);\n                    float tEnter = max(outerHit.x, 0.0), tExit = outerHit.y;\n                    if (tExit <= tEnter) discard;\n                    // Only the near-side emitting column is visible over Earth.\n                    vec2 groundHit = airglowIntersection(oc, rd, 0.0);\n                    float groundDistance = groundHit.x;\n                    if (groundDistance > 0.0) tExit = min(tExit, groundDistance);\n                    if (tExit <= tEnter) discard;\n\n                    // Airglow is an additive transparent carrier rendered\n                    // after opaque scene geometry. Depth testing cannot make\n                    // it respect the Moon because the carrier sphere encloses\n                    // the camera. Reject the exact physical celestial disk\n                    // analytically before adding any emission, while retaining\n                    // normal Earth-before-Moon occlusion.\n                    float moonDistance = ncaRaySphereFirstIntersection(\n                        uCameraWorld,\n                        rdWorld,\n                        ncaMoonCenterWorld,\n                        ncaMoonRadiusWorld\n                    );\n                    float sunDistance = ncaRaySphereFirstIntersection(\n                        uCameraWorld,\n                        rdWorld,\n                        ncaSunCenterWorld,\n                        ncaSunRadiusWorld\n                    );\n                    float celestialDistance = moonDistance;\n                    if (sunDistance >= 0.0\n                        && (celestialDistance < 0.0 || sunDistance < celestialDistance)) {\n                        celestialDistance = sunDistance;\n                    }\n                    if (celestialDistance >= 0.0\n                        && (groundDistance < 0.0 || celestialDistance < groundDistance)) {\n                        discard;\n                    }\n\n                    vec3 colAccum=vec3(0.0);\n                    vec3 sunDir=normalize(mat3(uWorldToPlanet)*uSunDirWorld);\n                    float firstEmissionDistance=-1.0;\n                    integrateAirglowLayer(oc,rd,sunDir,0.0,${NIGHT_LIMB_HAZE.topMeters.toFixed(1)},\n                      tEnter,tExit,colAccum,firstEmissionDistance);\n                    integrateAirglowLayer(oc,rd,sunDir,uBaseAlt,min(uCoreAlt+5.0*uRiseScale,uCoreAlt+50000.0),\n                      tEnter,tExit,colAccum,firstEmissionDistance);\n                    integrateAirglowLayer(oc,rd,sunDir,uCoreAlt+50000.0,uFringeAlt,\n                      tEnter,tExit,colAccum,firstEmissionDistance);\n                    if(firstEmissionDistance<0.0)discard;\n                    // Clear-air extinction below the layer limits horizon\n                    // brightening for ground observers. No camera-angle mask\n                    // suppresses overhead emission; the column integral owns it.\n                    float cameraAltitude=max(0.0,airglowAltitude(oc));\n                    float airmass=1.0/max(.04,abs(dot(rd,normalize(oc))));\n                    vec3 transmission=exp(-vec3(.25,.12,.06)*airmass*exp(-cameraAltitude/8000.0));\n                    vec3 emitted=colAccum*(uStrength/max(1.0,uPathRef))*transmission;\n                    if(max(max(emitted.r,emitted.g),emitted.b)<=0.0)discard;\n                    // Depth belongs to the emitting gas, never the enclosing\n                    // carrier behind Earth. Preserve ordinary opaque occlusion,\n                    // including nearby mountains when viewed from the ground.\n                    vec4 emissionView = uAirglowView * vec4(\n                        uCameraWorld + rdWorld * firstEmissionDistance, 1.0);\n                    #ifdef USE_LOGARITHMIC_DEPTH_BUFFER\n                    gl_FragDepth = log2(max(1e-6, 1.0 - emissionView.z)) * logDepthBufFC * 0.5;\n                    #else\n                    vec4 emissionClip = uAirglowProjection * emissionView;\n                    gl_FragDepth = emissionClip.z / emissionClip.w * 0.5 + 0.5;\n                    #endif\n                    gl_FragColor = vec4(emitted, 0.0);\n                    #include <colorspace_fragment>\n                }\n            `,\n            transparent: true,\n            blending: THREE.AdditiveBlending,\n            // RGB already contains integrated emission; do not multiply it by\n            // alpha a second time (which suppresses faint nadir glow quadratically).\n            premultipliedAlpha: true,\n            depthWrite: false,\n            // The fragment supplies the near emitting layer's depth. Both\n            // orbital nadir and limb columns therefore obey physical occlusion.\n            depthTest: true,\n            side: THREE.BackSide,\n            toneMapped: false\n        });\n        // Base radius = planet radius; scaled each frame to enclose the camera.\n        this._airglowMesh = new THREE.Mesh(new THREE.SphereGeometry(PLANET_RADIUS, 64, 32), this._airglowMaterial);\n        this._airglowMesh.name = 'NightAirglow';\n        this._airglowMesh.userData.lensflare = 'no-occlusion';\n        this._airglowMesh.renderOrder = 11;\n        this._airglowMesh.frustumCulled = false;\n        parent.add(this._airglowMesh);\n    }\n\n    _updateAirglowShell() {\n        if (this.enabled === false || this._airglowEnabled === false || (this._airglowStrength ?? 0) <= 0) {\n            if (this._airglowMesh) this._airglowMesh.visible = false;\n            return;\n        }\n        const parent = this._getOrbitCloudsParent();\n        if (!parent) return;\n        this._ensureAirglowShell(parent);\n        this._syncAirglowUniforms();\n        if (!this._airglowMesh) return;\n        this._airglowMesh.visible = true;\n        const u = this._airglowMaterial.uniforms;\n\n        // Camera + planet centre in world space.\n        this.camera.getWorldPosition(this._cameraWorldPosition);\n        u.uCameraWorld.value.copy(this._cameraWorldPosition);\n        this._airglowCenterW = this._airglowCenterW || new THREE.Vector3();\n        if (this.planetGroup) {\n            this.planetGroup.getWorldPosition(this._airglowCenterW);\n        } else {\n            this._airglowCenterW.set(0, 0, 0);\n        }\n        u.uPlanetCenterW.value.copy(this._airglowCenterW);\n        parent.updateWorldMatrix(true, false);\n        u.uWorldToPlanet.value.copy(parent.matrixWorld).invert();\n        u.uAirglowView.value.copy(this.camera.matrixWorldInverse);\n        u.uAirglowProjection.value.copy(this.camera.projectionMatrix);\n        syncCelestialWorldOcclusionUniforms(this._airglowMaterial, {\n            moonMesh: this._moonMesh,\n            sunMesh: this._sunMesh,\n            scratchScale: this._celestialScratchScale,\n        });\n\n        // Sun direction in world space (night gating is purely geometric, so no need\n        // for the planet-local frame here).\n        if (this.lightingSystem?.sun) {\n            u.uSunDirWorld.value.copy(this.lightingSystem.sun.position).normalize();\n        }\n\n        // Scale the shell so it always encloses the camera — the band itself comes\n        // from the per-ray march, the shell is just a full-screen carrier.\n        const camDist = this._cameraWorldPosition.distanceTo(this._airglowCenterW);\n        const fringe = Number.isFinite(this._airglowFringeAlt) ? this._airglowFringeAlt : 320000;\n        const targetRadius = camDist + PLANET_RADIUS + fringe;\n        this._airglowMesh.scale.setScalar(targetRadius / PLANET_RADIUS);\n    }\n\n    _updateAuroraSystem() {\n        if (this.enabled === false || this._auroraEnabled === false || (this._auroraStrength ?? 0) <= 0) {\n            if (this._auroraSystem?.mesh) this._auroraSystem.mesh.visible = false;\n            return;\n        }\n        const parent = this._getOrbitCloudsParent();\n        if (!parent) return;\n        if (!this._auroraSystem) {\n            this._auroraSystem = new AuroraSystem({ planetRadius: PLANET_RADIUS });\n            parent.add(this._auroraSystem.mesh);\n        } else if (this._auroraSystem.mesh && this._auroraSystem.mesh.parent !== parent) {\n            parent.add(this._auroraSystem.mesh);\n        }\n        this._syncAuroraConfig();\n\n        this.camera.getWorldPosition(this._cameraWorldPosition);\n        this._airglowCenterW = this._airglowCenterW || new THREE.Vector3();\n        if (this.planetGroup) {\n            this.planetGroup.getWorldPosition(this._airglowCenterW);\n        } else {\n            this._airglowCenterW.set(0, 0, 0);\n        }\n        this._auroraSunW = this._auroraSunW || new THREE.Vector3();\n        if (this.lightingSystem?.sun) {\n            this._auroraSunW.copy(this.lightingSystem.sun.position);\n        }\n        const timeSec = ((typeof performance !== 'undefined' && performance.now)\n            ? performance.now() : Date.now()) / 1000;\n        const depthSource = this._terrainDepthSource?.enabled\n            ? this._terrainDepthSource\n            : null;\n        this._auroraSystem.update(\n            this._cameraWorldPosition,\n            this._airglowCenterW,\n            this._auroraSunW,\n            this._planetMatrixInverse,\n            timeSec,\n            depthSource\n        );\n    }\n\n    _bindAuroraSceneDepth(depthTexture) {\n        const aurora = this._auroraSystem;\n        if (!aurora || !depthTexture) return;\n        const image = depthTexture.image || {};\n        this.camera.updateMatrixWorld?.();\n        this._auroraInvProjection ||= new THREE.Matrix4();\n        this._auroraInvProjection.copy(this.camera.projectionMatrixInverse);\n        aurora.setDepthSource({\n            depthTexture,\n            resolution: { width: image.width || this.renderer.domElement?.width || 1, height: image.height || this.renderer.domElement?.height || 1 },\n            invProjectionMatrix: this._auroraInvProjection,\n            invViewMatrix: this.camera.matrixWorld,\n            enabled: true,\n        });\n    }\n\n    _updateFireSystem() {\n        if (this.enabled === false || this._fireEnabled === false || (this._fireStrength ?? 0) <= 0) {\n            if (this._fireSystem?.mesh) this._fireSystem.mesh.visible = false;\n            return;\n        }\n        const parent = this._getOrbitCloudsParent();\n        if (!parent) return;\n        if (!this._fireSystem) {\n            this._fireSystem = new FireSystem({ planetRadius: PLANET_RADIUS });\n            parent.add(this._fireSystem.mesh);\n        } else if (this._fireSystem.mesh && this._fireSystem.mesh.parent !== parent) {\n            parent.add(this._fireSystem.mesh);\n        }\n        this._syncFireConfig();\n\n        this.camera.getWorldPosition(this._cameraWorldPosition);\n        this._airglowCenterW = this._airglowCenterW || new THREE.Vector3();\n        if (this.planetGroup) {\n            this.planetGroup.getWorldPosition(this._airglowCenterW);\n        } else {\n            this._airglowCenterW.set(0, 0, 0);\n        }\n        this._auroraSunW = this._auroraSunW || new THREE.Vector3();\n        if (this.lightingSystem?.sun) {\n            this._auroraSunW.copy(this.lightingSystem.sun.position);\n        }\n        const timeSec = ((typeof performance !== 'undefined' && performance.now)\n            ? performance.now() : Date.now()) / 1000;\n        const depthSource = this._terrainDepthSource?.enabled\n            ? this._terrainDepthSource\n            : null;\n        // Depth remains available after leaving the surface, so it cannot own\n        // the mode handoff. Physical altitude keeps the orbital FIRMS shell\n        // alive while still allowing the depth texture to occlude terrain.\n        const cameraAltitudeM = Math.max(\n            0,\n            this._cameraWorldPosition.distanceTo(this._airglowCenterW) - PLANET_RADIUS\n        );\n        const surfaceMode = !!depthSource\n            && cameraAltitudeM < ENVIRONMENT_SURFACE_EFFECT_MAX_ALTITUDE_M;\n        this._fireSystem.update(\n            this._cameraWorldPosition,\n            this._airglowCenterW,\n            this._auroraSunW,\n            this._planetMatrixInverse,\n            timeSec,\n            depthSource,\n            surfaceMode\n        );\n    }\n\n    _updateSmokeSystem() {\n        if (this.enabled === false\n            || this._smokeEnabled !== true\n            || (this._smokeStrength ?? 0) <= 0) {\n            if (this._smokeSystem?.mesh) this._smokeSystem.mesh.visible = false;\n            return;\n        }\n        const parent = this._getOrbitCloudsParent();\n        if (!parent) return;\n        if (!this._smokeSystem) {\n            this._smokeSystem = new SmokeSystem({ planetRadius: PLANET_RADIUS });\n            this._smokeSystem.setFeatures(\n                this._pendingSmokeFeatures,\n                this._pendingSmokeMetadata\n            );\n            parent.add(this._smokeSystem.mesh);\n        } else if (this._smokeSystem.mesh && this._smokeSystem.mesh.parent !== parent) {\n            parent.add(this._smokeSystem.mesh);\n        }\n        this._syncSmokeConfig();\n\n        this.camera.getWorldPosition(this._cameraWorldPosition);\n        this._airglowCenterW = this._airglowCenterW || new THREE.Vector3();\n        if (this.planetGroup) {\n            this.planetGroup.getWorldPosition(this._airglowCenterW);\n        } else {\n            this._airglowCenterW.set(0, 0, 0);\n        }\n        this._auroraSunW = this._auroraSunW || new THREE.Vector3();\n        if (this.lightingSystem?.sun) {\n            this._auroraSunW.copy(this.lightingSystem.sun.position);\n        }\n        const timeSec = ((typeof performance !== 'undefined' && performance.now)\n            ? performance.now() : Date.now()) / 1000;\n        const depthSource = this._terrainDepthSource?.enabled\n            ? this._terrainDepthSource\n            : null;\n        const cameraAltitudeM = Math.max(\n            0,\n            this._cameraWorldPosition.distanceTo(this._airglowCenterW) - PLANET_RADIUS\n        );\n        this._smokeSystem.update(\n            this._cameraWorldPosition,\n            this._airglowCenterW,\n            this._auroraSunW,\n            this._planetMatrixInverse,\n            timeSec,\n            depthSource,\n            !!depthSource && cameraAltitudeM < ENVIRONMENT_SURFACE_EFFECT_MAX_ALTITUDE_M\n        );\n    }\n\n    _updateCloudDistanceTuning(deltaTime = 0) {\n        if (!this.clouds?.clouds) return;\n        this.camera.getWorldPosition(this._cameraWorldPosition);\n        const camRadius = this._cameraWorldPosition.length();\n        const ellipsoidR = ellipsoidRadiusForWorldDir(this._cameraWorldPosition, this.planetGroup);\n        const altitude = Math.max(0, camRadius - ellipsoidR);\n        this._updateCloudCullState(altitude);\n        if (this._cloudLodState.disabled) {\n            this._applyDormantSurfaceCloudBudget();\n            return;\n        }\n        const activationBlend = this._advanceSurfaceCloudActivation(deltaTime);\n        const span = CLOUD_DISTANCE_TUNING.farAltitude - CLOUD_DISTANCE_TUNING.nearAltitude;\n        const t = span > 0\n            ? THREE.MathUtils.clamp((altitude - CLOUD_DISTANCE_TUNING.nearAltitude) / span, 0, 1)\n            : 0;\n        const desiredMaxRayDistance = THREE.MathUtils.lerp(\n            CLOUD_DISTANCE_TUNING.nearMaxRayDistance,\n            CLOUD_DISTANCE_TUNING.farMaxRayDistance,\n            t\n        );\n        const maxRayDistance = THREE.MathUtils.lerp(\n            CLOUD_SURFACE_ACTIVATION_MAX_RAY_DISTANCE_M,\n            desiredMaxRayDistance,\n            activationBlend\n        );\n        if (this._lastCloudMaxRayDistance === null || Math.abs(this._lastCloudMaxRayDistance - maxRayDistance) > 1) {\n            this._lastCloudMaxRayDistance = maxRayDistance;\n            this.clouds.clouds.maxRayDistance = maxRayDistance;\n            this.clouds.clouds.maxShadowLengthRayDistance = maxRayDistance;\n        }\n        this._applyCloudDistanceLod(t);\n        this._applyCloudResolutionLod(t);\n        this._applyCloudIterationLod(activationBlend);\n    }\n\n    _updateOrbitCloudDistanceTuning(altitude, cameraRadius = null) {\n        if (!this._orbitCloudsEffect?.clouds) return;\n        const disableAltitude = Number.isFinite(this._orbitClouds.cullAltitude)\n            ? this._orbitClouds.cullAltitude\n            : (ORBIT_CLOUD_DISTANCE_TUNING.cullAltitude ?? Infinity);\n        const hysteresis = Number.isFinite(this._orbitClouds.cullHysteresis)\n            ? this._orbitClouds.cullHysteresis\n            : (ORBIT_CLOUD_DISTANCE_TUNING.cullHysteresis ?? 0);\n        const enableAltitude = disableAltitude - hysteresis;\n        if (!this._orbitCloudsLodState.disabled && altitude >= disableAltitude) {\n            this._orbitCloudsLodState.disabled = true;\n            this._applyCloudsEnabled();\n        } else if (this._orbitCloudsLodState.disabled && altitude <= enableAltitude) {\n            this._orbitCloudsLodState.disabled = false;\n            this._applyCloudsEnabled();\n        }\n\n        const span = ORBIT_CLOUD_DISTANCE_TUNING.farAltitude - ORBIT_CLOUD_DISTANCE_TUNING.nearAltitude;\n        const t = span > 0\n            ? THREE.MathUtils.clamp((altitude - ORBIT_CLOUD_DISTANCE_TUNING.nearAltitude) / span, 0, 1)\n            : 0;\n        const baseMaxRayDistance = Number.isFinite(this._orbitClouds.maxRayDistance)\n            ? Math.max(1, this._orbitClouds.maxRayDistance)\n            : THREE.MathUtils.lerp(\n                ORBIT_CLOUD_DISTANCE_TUNING.nearMaxRayDistance,\n                ORBIT_CLOUD_DISTANCE_TUNING.farMaxRayDistance,\n                t\n            );\n        const camRadius = Number.isFinite(cameraRadius) ? cameraRadius : (PLANET_RADIUS + altitude);\n        const shellRadius = this._getOrbitCloudShellRadius();\n        let requiredDistance = 0;\n        if (camRadius > shellRadius) {\n            requiredDistance = Math.sqrt(Math.max(camRadius * camRadius - shellRadius * shellRadius, 0));\n        }\n        const maxRayDistance = Math.max(baseMaxRayDistance, requiredDistance * 1.05);\n        if (this._lastOrbitCloudMaxRayDistance === null || Math.abs(this._lastOrbitCloudMaxRayDistance - maxRayDistance) > 1) {\n            this._lastOrbitCloudMaxRayDistance = maxRayDistance;\n            this._orbitCloudsEffect.clouds.maxRayDistance = maxRayDistance;\n            this._orbitCloudsEffect.clouds.maxShadowLengthRayDistance = maxRayDistance;\n        }\n        const cloudsParams = this._orbitCloudsEffect.clouds;\n        if (cloudsParams) {\n            const baseMaxStep = Number.isFinite(this._orbitCloudsBaseSettings?.maxStepSize)\n                ? this._orbitCloudsBaseSettings.maxStepSize\n                : cloudsParams.maxStepSize;\n            const baseMinStep = Number.isFinite(this._orbitCloudsBaseSettings?.minStepSize)\n                ? this._orbitCloudsBaseSettings.minStepSize\n                : cloudsParams.minStepSize;\n            const iterations = Math.max(1, Math.round(\n                this._orbitCloudsBaseSettings?.maxIterationCount ?? cloudsParams.maxIterationCount ?? 1\n            ));\n            const idealStep = maxRayDistance / iterations;\n            const targetMaxStep = Math.max(baseMaxStep || 0, idealStep);\n            if (Number.isFinite(targetMaxStep) && Math.abs(cloudsParams.maxStepSize - targetMaxStep) > 1) {\n                cloudsParams.maxStepSize = targetMaxStep;\n            }\n            if (Number.isFinite(baseMinStep) && baseMinStep > 0 && cloudsParams.minStepSize !== baseMinStep) {\n                cloudsParams.minStepSize = baseMinStep;\n            }\n        }\n\n        const baseScale = Number.isFinite(this._orbitClouds.resolutionScale)\n            ? this._orbitClouds.resolutionScale\n            : 1;\n        const targetScale = THREE.MathUtils.clamp(baseScale * (this._qualityResolutionScale ?? 1), 0.1, 1);\n        if (this._lastOrbitCloudResolutionScale === null || Math.abs(this._lastOrbitCloudResolutionScale - targetScale) > 0.02) {\n            this._lastOrbitCloudResolutionScale = targetScale;\n            this._orbitCloudsEffect.resolutionScale = targetScale;\n        }\n        this._applyOrbitCloudLod(t);\n    }\n\n    _syncEffectMaterialsWithCamera() {\n        prepareCloudFrontDepth(this.clouds?.cloudsPass);\n        prepareCloudFrontDepth(this._orbitCloudsEffect?.cloudsPass);\n        if (!this.composer?.passes) return;\n        for (const pass of this.composer.passes) {\n            if (pass.fullscreenMaterial?.adoptCameraSettings) {\n                pass.fullscreenMaterial.adoptCameraSettings(this.camera);\n            }\n        }\n    }\n\n    _rebuildAtmosphereParameters() {\n        const atmosphereBottomRadius = Math.max(1, PLANET_RADIUS - this.atmosphereBaseOffset);\n        const atmosphereTopRadius = atmosphereBottomRadius + ATMOSPHERE_HEIGHT_M;\n        this._atmosphereParams = new AtmosphereParameters({\n            bottomRadius: atmosphereBottomRadius,\n            topRadius: atmosphereTopRadius\n        });\n        this._atmosphereEllipsoid = new Ellipsoid(\n            atmosphereBottomRadius,\n            atmosphereBottomRadius,\n            atmosphereBottomRadius\n        );\n\n        if (this.aerialPerspective) {\n            this.aerialPerspective.atmosphere = this._atmosphereParams;\n            this.aerialPerspective.ellipsoid = this._atmosphereEllipsoid;\n            this._syncAerialPerspectiveAtmosphereUniforms(atmosphereBottomRadius, atmosphereTopRadius);\n            this._syncAtmosphereParameterStruct(this.aerialPerspective);\n        }\n\n        if (this.clouds) {\n            this.clouds.atmosphere = this._atmosphereParams;\n            this.clouds.ellipsoid = this._atmosphereEllipsoid;\n            const uniforms = this.clouds.atmosphereUniforms;\n            if (uniforms?.bottomRadius) uniforms.bottomRadius.value = atmosphereBottomRadius;\n            if (uniforms?.topRadius) uniforms.topRadius.value = atmosphereTopRadius;\n            this._syncAtmosphereParameterStruct(this.clouds.cloudsPass?.currentMaterial);\n        }\n        if (this._orbitCloudsEffect) {\n            this._orbitCloudsEffect.atmosphere = this._atmosphereParams;\n            this._orbitCloudsEffect.ellipsoid = this._atmosphereEllipsoid;\n            const uniforms = this._orbitCloudsEffect.atmosphereUniforms;\n            if (uniforms?.bottomRadius) uniforms.bottomRadius.value = atmosphereBottomRadius;\n            if (uniforms?.topRadius) uniforms.topRadius.value = atmosphereTopRadius;\n            this._syncAtmosphereParameterStruct(\n                this._orbitCloudsEffect.cloudsPass?.currentMaterial\n            );\n        }\n\n        if (this.skyMaterial) {\n            this.skyMaterial.ellipsoid = this._atmosphereEllipsoid;\n            this.skyMaterial.atmosphere = this._atmosphereParams;\n            this._syncAtmosphereParameterStruct(this.skyMaterial);\n        }\n\n        this._updateEllipsoidTransform();\n    }\n\n    _syncLogDepthDefines() {\n        const useLogDepth = !!this.renderer?.capabilities?.logarithmicDepthBuffer;\n        const applyDefine = (effect) => {\n            if (!effect?.defines) return;\n            if (useLogDepth) {\n                effect.defines.set('USE_LOGARITHMIC_DEPTH_BUFFER', '1');\n                effect.defines.set('USE_LOGDEPTHBUF', '1');\n            } else {\n                effect.defines.delete('USE_LOGARITHMIC_DEPTH_BUFFER');\n                effect.defines.delete('USE_LOGDEPTHBUF');\n            }\n            effect.setChanged?.();\n        };\n        applyDefine(this.aerialPerspective);\n        applyDefine(this.clouds);\n    }\n\n    _patchSkyDepthRule() {\n        if (!this.aerialPerspective?.fragmentShader) return false;\n\n        let shader = this.aerialPerspective.fragmentShader;\n        let updated = false;\n        let depthCompatible = false;\n        let skyPatched = false;\n        let orbitalGroundCompatible = false;\n        let celestialOcclusionCompatible = false;\n        let solarEclipseCompatible = false;\n        let surfaceCityLightingCompatible = false;\n\n        // Marker so we can detect if a recompile wiped our patch.\n        const PATCH_MARKER = '/* AtmosphereClouds: SKY_OPACITY_PATCH */';\n        const ORBITAL_GROUND_MARKER = '/* AtmosphereClouds: ORBITAL_ANALYTIC_GROUND */';\n        const CELESTIAL_OCCLUSION_MARKER = '/* AtmosphereClouds: CELESTIAL_OCCLUSION */';\n        const SOLAR_ECLIPSE_MARKER = '/* AtmosphereClouds: SOLAR_ECLIPSE_IRRADIANCE */';\n        const SURFACE_CITY_LIGHT_MARKER = '/* AtmosphereClouds: SURFACE_CITY_IRRADIANCE */';\n        const SURFACE_OVERLAY_EMITTER_MARKER = '/* AtmosphereClouds: SURFACE_OVERLAY_EMITTERS */';\n        const DIRECT_LOG_DEPTH_MARKER = '/* AtmosphereClouds: DIRECT_LOG_DEPTH */';\n        const VISIBILITY_MARKER = '/* AtmosphereClouds: GLOBAL_CELESTIAL_VISIBILITY */';\n        if (this._skyDepthPatched\n            && shader.includes(PATCH_MARKER)\n            && shader.includes(ORBITAL_GROUND_MARKER)\n            && shader.includes(CELESTIAL_OCCLUSION_MARKER)\n            && shader.includes(SOLAR_ECLIPSE_MARKER)\n            && shader.includes(SURFACE_CITY_LIGHT_MARKER)\n            && shader.includes(SURFACE_OVERLAY_EMITTER_MARKER)\n            && shader.includes(DIRECT_LOG_DEPTH_MARKER)\n            && shader.includes(VISIBILITY_MARKER)\n            && shader.includes('if (orbitalAnalyticGround)')) return true;\n        // If shader was recompiled and lost the marker, allow re-patching.\n        this._skyDepthPatched = false;\n\n        this._ensureSkyTuningUniforms();\n        ensureCelestialOcclusionUniforms(this.aerialPerspective);\n        this._syncSurfaceLightPollutionUniforms();\n\n        const lunarUniformNeedle = 'uniform float lunarRadianceScale;';\n        if (!shader.includes('uniform vec3 ncaMoonCenterECEF;')\n            && shader.includes(lunarUniformNeedle)) {\n            shader = shader.replace(\n                lunarUniformNeedle,\n                `${lunarUniformNeedle}\\n${CELESTIAL_OCCLUSION_UNIFORMS_GLSL}`\n            );\n            updated = true;\n        }\n        if (!shader.includes('uniform float ncaMoonPhysicalRadius;')\n            && shader.includes(lunarUniformNeedle)) {\n            shader = shader.replace(\n                lunarUniformNeedle,\n                `${lunarUniformNeedle}\\nuniform float ncaMoonPhysicalRadius;`\n            );\n            updated = true;\n        }\n        const mainImageNeedle = 'void mainImage(const vec4 inputColor, const vec2 uv, out vec4 outputColor) {';\n        if (!shader.includes('vec3 ncaWaterReflection(') && shader.includes(mainImageNeedle)) {\n            shader = shader.replace(mainImageNeedle, `${WATER_COVERAGE_GLSL}\\n${WATER_REFLECTANCE_GLSL}\nuniform float ncaWaterReflectionEnabled, ncaWaterReflectionStrength, ncaWaterWindSpeed;\nuniform float ncaWaterReflectionReady;\nuniform mat4 ncaWaterReflectionFromView;\nuniform vec4 ncaWaterReflectionRegion;\n${mainImageNeedle}`);\n            updated = true;\n        }\n        if (!shader.includes('float ncaRaySphereFirstIntersection(')\n            && shader.includes(mainImageNeedle)) {\n            shader = shader.replace(\n                mainImageNeedle,\n                `${CELESTIAL_OCCLUSION_INTERSECTION_GLSL}\\n${mainImageNeedle}`\n            );\n            updated = true;\n        }\n        // Water reflection needs eclipse visibility even with both aerial\n        // light flags off. getSunSkyIrradiance lives inside Takram's\n        // SUN_LIGHT || SKY_LIGHT branch: injecting the helper there leaves\n        // the water call undefined and the entire compositor unlinked.\n        if (!shader.includes(VISIBILITY_MARKER) && shader.includes(lunarUniformNeedle)) {\n            shader = shader.replace(CELESTIAL_IRRADIANCE_GLSL, '');\n            shader = shader.replace(\n                lunarUniformNeedle,\n                `${lunarUniformNeedle}\\n${VISIBILITY_MARKER}\\n${CELESTIAL_IRRADIANCE_GLSL}`\n            );\n            updated = true;\n        }\n        if (!shader.includes('uniform float ncaSurfaceCameraMode;')\n            && shader.includes(lunarUniformNeedle)) {\n            shader = shader.replace(\n                lunarUniformNeedle,\n                `${lunarUniformNeedle}\\nuniform float ncaSurfaceCameraMode;`\n            );\n            updated = true;\n        }\n        celestialOcclusionCompatible = shader.includes('uniform vec3 ncaMoonCenterECEF;')\n            && shader.includes('float ncaRaySphereFirstIntersection(')\n            && shader.includes('uniform float ncaSurfaceCameraMode;');\n\n        const solarIrradianceNeedle = `  vec3 skyIrradiance;\n  vec3 sunIrradiance = GetSunAndSkyIrradiance(positionECEF, normal, sunDirection, skyIrradiance);`;\n        const solarIrradianceReplacement = `  vec3 skyIrradiance;\n  vec3 sunIrradiance = GetSunAndSkyIrradiance(positionECEF, normal, sunDirection, skyIrradiance);\n  ${SOLAR_ECLIPSE_MARKER}\n  vec3 ncaLocalSunOffset = ncaSunCenterECEF - positionECEF;\n  vec3 ncaLocalMoonOffset = ncaMoonCenterECEF - positionECEF;\n  float ncaLocalSunDistance = length(ncaLocalSunOffset);\n  float ncaLocalMoonDistance = length(ncaLocalMoonOffset);\n  if (ncaLocalSunDistance > ncaSunRadius\n      && ncaLocalMoonDistance > ncaMoonPhysicalRadius\n      && ncaMoonPhysicalRadius > 0.0) {\n    float ncaLocalSunAngularRadius = asin(clamp(\n      ncaSunRadius / ncaLocalSunDistance,\n      0.0,\n      1.0\n    ));\n    float ncaLocalMoonAngularRadius = asin(clamp(\n      ncaMoonPhysicalRadius / ncaLocalMoonDistance,\n      0.0,\n      1.0\n    ));\n    sunIrradiance *= ncaFiniteDiscVisibility(\n      ncaLocalSunOffset,\n      ncaLocalSunAngularRadius,\n      ncaLocalMoonOffset,\n      ncaLocalMoonAngularRadius\n    );\n  }`;\n        if (shader.includes(SOLAR_ECLIPSE_MARKER)) {\n            solarEclipseCompatible = true;\n        } else if (shader.includes(solarIrradianceNeedle)) {\n            shader = shader.replace(\n                solarIrradianceNeedle,\n                solarIrradianceReplacement\n            );\n            updated = true;\n            solarEclipseCompatible = true;\n        } else {\n            console.error('[AtmosphereClouds] Required direct solar irradiance signature changed');\n        }\n\n        // --- Keep/insert tuning uniforms (harmless even if not used) ---\n        const uniformNeedle = 'uniform float idealSphereAlpha;';\n        if (!shader.includes('uniform float skyAlphaScale;') && shader.includes(uniformNeedle)) {\n            const uniformBlock = [\n                'uniform float idealSphereAlpha;',\n                'uniform float skyAlphaScale;',\n                'uniform float skyAlphaClamp;',\n                'uniform float skyLimbBoost;',\n                'uniform float skyPathShort;',\n                'uniform float skyLimbMax;',\n                'uniform float skyDensityScale;',\n                'uniform float skyScaleHeight;',\n                'uniform float skyVerticalFadeStart;',\n                'uniform float skyVerticalFadeEnd;',\n                'uniform float skyAltitudeFadeStart;',\n                'uniform float skyAltitudeFadeEnd;',\n                'uniform float skyOutsideFadeStart;',\n                'uniform float skyOutsideFadeEnd;',\n                'uniform float skyDepthThreshold;'\n            ].join('\\n');\n\n            shader = shader.replace(uniformNeedle, uniformBlock);\n            updated = true;\n        }\n        const surfaceCityUniformNeedle = 'uniform float albedoScale;';\n        if (!shader.includes('uniform sampler2D ncaLightPollutionTexture;')\n            && shader.includes(surfaceCityUniformNeedle)) {\n            const surfaceCityUniformBlock = [\n                surfaceCityUniformNeedle,\n                'uniform sampler2D ncaLightPollutionTexture;',\n                'uniform sampler2D ncaLightPollutionDetailTexture;',\n                'uniform float ncaLightPollutionDetailEnabled;',\n                'uniform vec4 ncaLightPollutionDetailBounds;',\n                'uniform float ncaLightPollutionEnabled;',\n                'uniform float ncaLightPollutionIntensity;',\n                'uniform float ncaLightPollutionMapGain;',\n                'uniform float ncaLightPollutionSurfaceIntensityScale;',\n                'uniform float ncaLightPollutionEmissionThreshold;',\n                'uniform float ncaLightPollutionEmissionSoftness;',\n                'uniform float ncaLightPollutionEmissionPower;',\n                'uniform float ncaLightPollutionEmissionBlueSuppression;',\n                'uniform vec3 ncaLightPollutionColor;',\n                'uniform float ncaLightPollutionMercator;',\n                'uniform vec2 ncaLightPollutionUvOffset;',\n                'uniform vec2 ncaLightPollutionUvScale;',\n                'uniform float ncaNightTransitionStart;',\n                'uniform float ncaNightTransitionEnd;',\n                'uniform float ncaNightPower;',\n                'uniform float ncaNightMinBrightness;',\n                'uniform float ncaNightVision;',\n                'uniform sampler2D ncaSimpleCloudsTexture;',\n                'uniform float ncaSimpleCloudsEnabled;',\n                'uniform float ncaSimpleCloudsOpacity;',\n                'uniform float ncaSimpleCloudsShadowStrength;',\n                'uniform float ncaSimpleCloudsShadowHeight;',\n                'uniform float ncaSimpleCloudsBlendMode;',\n                'uniform float ncaSimpleCloudsAlphaThreshold;',\n                'uniform float ncaSimpleCloudsAlphaSoftness;',\n                'uniform vec3 ncaSimpleCloudsNightAirglowColor;',\n                'uniform float ncaSimpleCloudsNightAirglowStrength;',\n                'uniform float ncaSurfaceEmitterCount;',\n                'uniform float ncaSurfaceEmitterTime;',\n                'uniform mat4 ncaSurfaceEmitterECEFToWorld;',\n                `uniform vec4 ncaSurfaceEmitterStarts[${MAX_SURFACE_LIGHT_EMITTERS}];`,\n                `uniform vec4 ncaSurfaceEmitterEnds[${MAX_SURFACE_LIGHT_EMITTERS}];`,\n                `uniform vec4 ncaSurfaceEmitterColors[${MAX_SURFACE_LIGHT_EMITTERS}];`,\n                `uniform vec4 ncaSurfaceEmitterParams[${MAX_SURFACE_LIGHT_EMITTERS}];`,\n                NIGHT_LIGHTS_SOURCE_SIGNAL_GLSL,\n                NIGHT_LIGHTS_SURFACE_CARRIER_GLSL,\n                NIGHT_LIGHTS_GEOGRAPHY_GLSL,\n                nightCloudLightingForExistingField('ncaLightPollution', true),\n                `float ncaAerialCloudMask(vec4 s) {\n  float black = clamp(ncaSimpleCloudsAlphaThreshold, 0.0, 0.95);\n  float contrast = 1.0 + clamp(ncaSimpleCloudsAlphaSoftness, 0.0, 1.0) * 6.0;\n  return pow(clamp((clamp(s.a, 0.0, 1.0) - black) / (1.0 - black + 1e-4), 0.0, 1.0), contrast);\n}`,\n                orbitalCloudVolumeGlsl({\n                    name: 'ncaAerialCloudView',\n                    sampler: 'ncaSimpleCloudsTexture',\n                    mask: 'ncaAerialCloudMask',\n                    groundRadius: 'ATMOSPHERE.bottom_radius',\n                }),\n            ].join('\\n');\n            shader = shader.replace(\n                surfaceCityUniformNeedle,\n                surfaceCityUniformBlock\n            );\n            updated = true;\n        }\n\n        // Takram 0.19 reads packed/logarithmic depth first. At orbital range on\n        // r185, that value is no longer authoritative for the surface: it can\n        // read clear or reconstruct an astronomical-range point even though\n        // RenderPass still produced valid photoreal colour. Either case drives\n        // transmittance to black near 3.52 Mm. Once Takram's own geometric-\n        // error correction reaches 1, the r182 strategy treats Earth as an\n        // ideal sphere anyway, so classify it from the exact camera ray before\n        // consulting depth. The legacy 0.12 signature remains unchanged.\n        const currentDepthTestNeedle = '  if (depth >= 1.0 - 1e-8) {';\n        const legacyDepthTestNeedle = '  if (depth >= 1.0 - 1e-7) {';\n        const currentDepthPreludeNeedle = `  float depth = readDepthValue(depthBuffer, uv);\n  if (depth >= 1.0 - 1e-8) {`;\n        const currentDepthPreludeReplacement = `  float depth = readDepthValue(depthBuffer, uv);\n  ${ORBITAL_GROUND_MARKER}\n  ${CELESTIAL_OCCLUSION_MARKER}\n  float orbitalGroundDistance = -1.0;\n  float orbitalB = dot(vCameraPosition, rayDirection);\n  float orbitalC = dot(vCameraPosition, vCameraPosition)\n    - ATMOSPHERE.bottom_radius * ATMOSPHERE.bottom_radius;\n  float orbitalDiscriminant = orbitalB * orbitalB - orbitalC;\n  if (orbitalDiscriminant >= 0.0) {\n    float candidateGroundDistance = -orbitalB - sqrt(orbitalDiscriminant);\n    if (candidateGroundDistance > 0.0) {\n      orbitalGroundDistance = candidateGroundDistance;\n    }\n  }\n\n  float ncaMoonDistance = ncaRaySphereFirstIntersection(\n    vCameraPosition,\n    rayDirection,\n    ncaMoonCenterECEF,\n    ncaMoonRadius\n  );\n  float ncaSunDistance = ncaRaySphereFirstIntersection(\n    vCameraPosition,\n    rayDirection,\n    ncaSunCenterECEF,\n    ncaSunRadius\n  );\n  float ncaCelestialDistance = ncaMoonDistance;\n  if (ncaSunDistance >= 0.0\n      && (ncaCelestialDistance < 0.0 || ncaSunDistance < ncaCelestialDistance)) {\n    ncaCelestialDistance = ncaSunDistance;\n  }\n  bool ncaCelestialInFrontOfGround = ncaCelestialDistance >= 0.0\n    && (orbitalGroundDistance < 0.0\n      || ncaCelestialDistance < orbitalGroundDistance);\n  // At orbital range the analytic nearest-body test avoids precision loss in\n  // astronomical packed depth. Surface rays need one additional distinction:\n  // the ray can intersect a physical Sun/Moon even when a much nearer\n  // photoreal tile won the hardware depth test. Classify ownership by a broad\n  // logarithmic-depth floor, not an equality tolerance. Any surface or\n  // building depth is orders of magnitude nearer than one quarter of the\n  // Moon/Sun distance, while a rendered physical celestial fragment is well\n  // beyond that floor. This preserves the real disk through atmosphere but\n  // cannot resurrect it over a nearer photoreal pixel.\n  bool ncaSurfaceCelestialOwnsDepth = ncaCelestialInFrontOfGround;\n  #ifdef USE_LOGDEPTHBUF\n    float ncaCelestialDistanceMeters =\n      ncaCelestialDistance / METER_TO_LENGTH_UNIT;\n    float ncaCelestialDepthFloor = log2(max(\n      2.0,\n      1.0 + ncaCelestialDistanceMeters * 0.25\n    )) / log2(cameraFar + 1.0);\n    ncaSurfaceCelestialOwnsDepth = ncaCelestialInFrontOfGround\n      && depth >= ncaCelestialDepthFloor\n      && depth < 1.0 - 1e-8;\n  #endif\n  bool ncaCelestialSkyOccluder = ncaCelestialInFrontOfGround\n    && (ncaSurfaceCameraMode < 0.5 || ncaSurfaceCelestialOwnsDepth);\n  bool ncaMoonSkyOccluder = ncaCelestialSkyOccluder\n    && ncaMoonDistance >= 0.0\n    && (ncaSunDistance < 0.0 || ncaMoonDistance <= ncaSunDistance);\n  bool orbitalAnalyticGround = geometricErrorCorrectionAmount >= 0.999\n    && orbitalGroundDistance >= 0.0\n    && !ncaCelestialSkyOccluder;\n  if ((depth >= 1.0 - 1e-8 && !orbitalAnalyticGround)\n      || ncaCelestialSkyOccluder) {`;\n        const depthTestReplacement = `  float skyDepth = depth;\n  float skyThreshold = 1.0 - 1e-7;\n  #ifdef USE_LOGDEPTHBUF\n    skyDepth = reverseLogDepth(depth, cameraNear, cameraFar);\n  #endif\n  if (depth >= skyThreshold || skyDepth >= skyThreshold) {`;\n\n        if (shader.includes(currentDepthPreludeNeedle)) {\n            shader = shader.replace(currentDepthPreludeNeedle, currentDepthPreludeReplacement);\n            updated = true;\n            depthCompatible = true;\n            orbitalGroundCompatible = true;\n        } else if (shader.includes(legacyDepthTestNeedle)) {\n            shader = shader.replace(legacyDepthTestNeedle, depthTestReplacement);\n            updated = true;\n            depthCompatible = true;\n        } else if (shader.includes('skyThreshold')) {\n            depthCompatible = true;\n        }\n\n        // Preserve the analytic ground fallback at extreme orbital correction.\n        // For actual geometry decode log depth directly to view-space metres.\n        // Converting it to perspective depth first rounds distant surfaces\n        // into a few float32 bins (or 1.0), creating broad bands of scattering\n        // and bad reconstructed normals during surface-to-orbit ascent.\n        const currentReconstructionNeedle = `  depth = reverseLogDepth(depth, cameraNear, cameraFar);\n\n  // Reconstruct position and normal in world space.\n  vec3 viewPosition = screenToView(\n    uv,\n    depth,\n    getViewZ(depth),\n    projectionMatrix,\n    inverseProjectionMatrix\n  );\n  vec3 worldPosition = (inverseViewMatrix * vec4(viewPosition, 1.0)).xyz;\n  vec3 positionECEF = (worldToECEFMatrix * vec4(worldPosition, 1.0)).xyz;\n  positionECEF = positionECEF * METER_TO_LENGTH_UNIT + vGeometryAltitudeCorrection;`;\n        const currentReconstructionReplacement = `  vec3 viewPosition = vec3(0.0);\n  vec3 worldPosition = vec3(0.0);\n  vec3 positionECEF;\n  if (orbitalAnalyticGround) {\n    positionECEF = vCameraPosition + rayDirection * orbitalGroundDistance;\n  } else {\n    ${DIRECT_LOG_DEPTH_MARKER}\n    #if defined(PERSPECTIVE_CAMERA) && (defined(USE_LOGDEPTHBUF) || defined(USE_LOGARITHMIC_DEPTH_BUFFER))\n    float ncaViewZ = 1.0 - exp2(depth * log2(cameraFar + 1.0));\n    // Unproject a point inside the frustum, avoiding its astronomical far\n    // plane. Dividing by ray.z preserves view depth for off-axis pixels too.\n    vec3 ncaViewRay = (inverseProjectionMatrix * vec4(uv * 2.0 - 1.0, 0.0, 1.0)).xyz;\n    viewPosition = ncaViewRay * (ncaViewZ / ncaViewRay.z);\n    #else\n    // Three stores ordinary linear depth for orthographic cameras even when\n    // the renderer enables logarithmic depth for perspective cameras.\n    viewPosition = screenToView(\n      uv,\n      depth,\n      getViewZ(depth),\n      projectionMatrix,\n      inverseProjectionMatrix\n    );\n    #endif\n    worldPosition = (inverseViewMatrix * vec4(viewPosition, 1.0)).xyz;\n    positionECEF = (worldToECEFMatrix * vec4(worldPosition, 1.0)).xyz;\n    positionECEF = positionECEF * METER_TO_LENGTH_UNIT + vGeometryAltitudeCorrection;\n  }`;\n\n        if (shader.includes(currentReconstructionNeedle) && orbitalGroundCompatible) {\n            shader = shader.replace(currentReconstructionNeedle, currentReconstructionReplacement);\n            updated = true;\n        } else if (shader.includes(ORBITAL_GROUND_MARKER)\n            && shader.includes('if (orbitalAnalyticGround)')) {\n            orbitalGroundCompatible = true;\n        } else if (shader.includes(legacyDepthTestNeedle) || shader.includes('skyThreshold')) {\n            orbitalGroundCompatible = true;\n        }\n\n        // d5dd567 / r182 contract: getSkyRadiance() is never allowed to replace\n        // the already-rendered frame. Its fixed 90% cross-blend is deliberate:\n        // it retains the planet, stars, airglow, and night emission when depth\n        // resolves as sky while keeping the same visible atmosphere response\n        // from surface distance through high orbit. Port the input names and\n        // call signature for r185, but do not change this blend equation.\n        const SKY_OPACITY = .90; // <- change to 0.30–0.40 for a more Earth-like look\n\n        const currentSkyBlockNeedle = `    #ifdef SKY\n    outputColor.rgb = getSkyRadiance(\n      vCameraPosition,\n      rayDirection,\n      shadowLength,\n      sunDirection,\n      moonDirection,\n      moonAngularRadius,\n      lunarRadianceScale,\n      fragmentAngle\n    );\n    outputColor.a = 1.0;\n    #else // SKY\n    outputColor = inputColor;\n    #endif // SKY`;\n        const currentSkyBlockReplacement = `    ${PATCH_MARKER}\n    #ifdef SKY\n    if (ncaCelestialSkyOccluder) {\n      // The primary RenderPass already shaded an opaque physical body. Keep\n      // its hardware depth and albedo authoritative. A surface observer sees\n      // that radiance transmitted through the atmosphere PLUS the same sky\n      // scattering as the neighbouring ray. A cross-fade would incorrectly\n      // leave the unlit hemisphere as a dark silhouette in the daytime sky.\n      if (ncaSurfaceCameraMode > 0.5 && ncaMoonSkyOccluder) {\n        vec3 ncaMoonTransmittance;\n        vec3 ncaMoonSkyRadiance = GetSkyRadiance(\n          vCameraPosition,\n          rayDirection,\n          shadowLength,\n          sunDirection,\n          ncaMoonTransmittance\n        );\n        // Match the normal sky carrier's scattering gain, keeping the lunar\n        // reflection additive. No analytic Moon disk is evaluated here.\n        outputColor.rgb = inputColor.rgb * ncaMoonTransmittance\n          + ncaMoonSkyRadiance * ${SKY_OPACITY.toFixed(2)};\n        outputColor.a = 1.0;\n      } else {\n        outputColor = inputColor;\n      }\n    } else {\n      vec3 skyRadiance = getSkyRadiance(\n        vCameraPosition,\n        rayDirection,\n        shadowLength,\n        sunDirection,\n        moonDirection,\n        moonAngularRadius,\n        lunarRadianceScale,\n        fragmentAngle\n      );\n      // NOAA GeoColor shows a restrained, thin daylight rim rather than a\n      // uniformly bright cyan shell. Shape only orbital sky rays that graze\n      // the physical atmosphere: the logarithmic remaining-height curve holds\n      // a compact inner rim, then falls rapidly to black at top_radius.\n      float ncaClosestDistance = max(\n        -dot(vCameraPosition, rayDirection),\n        0.0\n      );\n      vec3 ncaClosestPoint = vCameraPosition\n        + rayDirection * ncaClosestDistance;\n      float ncaImpactRadius = length(ncaClosestPoint);\n      float ncaAtmosphereSpan = max(\n        ATMOSPHERE.top_radius - ATMOSPHERE.bottom_radius,\n        1e-4\n      );\n      float ncaRemainingHeight = clamp(\n        (ATMOSPHERE.top_radius - ncaImpactRadius) / ncaAtmosphereSpan,\n        0.0,\n        1.0\n      );\n      float ncaLogarithmicEdgeFalloff = log2(\n        1.0 + ${ORBIT_DAY_LIMB_LOG_CURVE.toFixed(1)} * ncaRemainingHeight\n      ) / log2(1.0 + ${ORBIT_DAY_LIMB_LOG_CURVE.toFixed(1)});\n      float ncaAtmosphereOnlyRay = step(\n        ATMOSPHERE.bottom_radius,\n        ncaImpactRadius\n      ) * (1.0 - step(ATMOSPHERE.top_radius, ncaImpactRadius));\n      float ncaOrbitalView = smoothstep(\n        ATMOSPHERE.top_radius + 20.0,\n        ATMOSPHERE.top_radius + 400.0,\n        length(vCameraPosition)\n      );\n      float ncaDayLimb = smoothstep(\n        -0.12,\n        0.28,\n        dot(\n          ncaClosestPoint / max(ncaImpactRadius, 1e-4),\n          sunDirection\n        )\n      );\n      float ncaDayEdgeWeight = ncaAtmosphereOnlyRay\n        * ncaOrbitalView\n        * ncaDayLimb;\n      skyRadiance *= mix(\n        1.0,\n        ${ORBIT_DAY_LIMB_RADIANCE_SCALE.toFixed(2)}\n          * ncaLogarithmicEdgeFalloff,\n        ncaDayEdgeWeight\n      );\n      float skyAlpha = ${SKY_OPACITY.toFixed(2)};\n      outputColor.rgb = mix(inputColor.rgb, skyRadiance, skyAlpha);\n      outputColor.a = 1.0;\n    }\n    #else // SKY\n    outputColor = inputColor;\n    #endif // SKY`;\n\n        const legacySkyBlockNeedle = `    #ifdef SKY\n    vec3 rayDirection = normalize(vRayDirection);\n    outputColor.rgb = getSkyRadiance(\n      vCameraPosition - vEllipsoidCenter,\n      rayDirection,\n      shadowLength,\n      sunDirection,\n      moonDirection,\n      moonAngularRadius,\n      lunarRadianceScale\n    );\n    outputColor.a = 1.0;\n    #else // SKY\n    outputColor = inputColor;\n    #endif // SKY`;\n\n        const legacySkyBlockReplacement = `    ${PATCH_MARKER}\n    #ifdef SKY\n    vec3 rayDirection = normalize(vRayDirection);\n    vec3 cameraPosition = vCameraPosition - vEllipsoidCenter;\n    vec3 skyRadiance = getSkyRadiance(\n      cameraPosition,\n      rayDirection,\n      shadowLength,\n      sunDirection,\n      moonDirection,\n      moonAngularRadius,\n      lunarRadianceScale\n    );\n    float ncaClosestDistance = max(\n      -dot(cameraPosition, rayDirection),\n      0.0\n    );\n    vec3 ncaClosestPoint = cameraPosition\n      + rayDirection * ncaClosestDistance;\n    float ncaImpactRadius = length(ncaClosestPoint);\n    float ncaAtmosphereSpan = max(\n      ATMOSPHERE.top_radius - ATMOSPHERE.bottom_radius,\n      1e-4\n    );\n    float ncaRemainingHeight = clamp(\n      (ATMOSPHERE.top_radius - ncaImpactRadius) / ncaAtmosphereSpan,\n      0.0,\n      1.0\n    );\n    float ncaLogarithmicEdgeFalloff = log2(\n      1.0 + ${ORBIT_DAY_LIMB_LOG_CURVE.toFixed(1)} * ncaRemainingHeight\n    ) / log2(1.0 + ${ORBIT_DAY_LIMB_LOG_CURVE.toFixed(1)});\n    float ncaAtmosphereOnlyRay = step(\n      ATMOSPHERE.bottom_radius,\n      ncaImpactRadius\n    ) * (1.0 - step(ATMOSPHERE.top_radius, ncaImpactRadius));\n    float ncaOrbitalView = smoothstep(\n      ATMOSPHERE.top_radius + 20.0,\n      ATMOSPHERE.top_radius + 400.0,\n      length(cameraPosition)\n    );\n    float ncaDayLimb = smoothstep(\n      -0.12,\n      0.28,\n      dot(\n        ncaClosestPoint / max(ncaImpactRadius, 1e-4),\n        sunDirection\n      )\n    );\n    float ncaDayEdgeWeight = ncaAtmosphereOnlyRay\n      * ncaOrbitalView\n      * ncaDayLimb;\n    skyRadiance *= mix(\n      1.0,\n      ${ORBIT_DAY_LIMB_RADIANCE_SCALE.toFixed(2)}\n        * ncaLogarithmicEdgeFalloff,\n      ncaDayEdgeWeight\n    );\n    float skyAlpha = ${SKY_OPACITY.toFixed(2)};\n    outputColor.rgb = mix(inputColor.rgb, skyRadiance, skyAlpha);\n    outputColor.a = 1.0;\n    #else // SKY\n    outputColor = inputColor;\n    #endif // SKY`;\n\n        if (shader.includes(currentSkyBlockNeedle)) {\n            shader = shader.replace(currentSkyBlockNeedle, currentSkyBlockReplacement);\n            updated = true;\n            skyPatched = true;\n        } else if (shader.includes(legacySkyBlockNeedle)) {\n            shader = shader.replace(legacySkyBlockNeedle, legacySkyBlockReplacement);\n            updated = true;\n            skyPatched = true;\n        } else if (shader.includes(PATCH_MARKER)) {\n            skyPatched = true;\n        } else {\n            const skyStart = shader.indexOf('#ifdef SKY');\n            if (skyStart !== -1) {\n                const skySnippet = shader.slice(skyStart, skyStart + 200);\n                console.error('[AtmosphereClouds] Required orbital sky blend signature changed:', JSON.stringify(skySnippet));\n            } else {\n                console.error('[AtmosphereClouds] Required orbital SKY block is absent');\n            }\n        }\n\n        const surfaceCityLightingNeedle = `  #if defined(TRANSMITTANCE) || defined(INSCATTER)\n  applyTransmittanceInscatter(positionECEF, shadowLength, radiance);\n  #endif // defined(TRANSMITTANCE) || defined(INSCATTER)`;\n        const surfaceCityLightingReplacement = `  ${SURFACE_CITY_LIGHT_MARKER}\n  // Keep the lightweight live cloud map and bounded NASA WMTS field attached\n  // to hardware-masked photoreal surface pixels across the loading-globe\n  // handoff. Clouds cast a sun-projected shadow before their visible body is\n  // composited; city pixels then emit from that same reconstructed depth.\n  #ifdef HAS_LIGHTING_MASK\n  float ncaPhotoSurfaceMask =\n    texture(lightingMaskBuffer, uv).LIGHTING_MASK_CHANNEL_;\n  vec3 ncaSurfaceDirection = normalize(positionECEF);\n  vec2 ncaSurfaceUv = vec2(\n    fract(atan(ncaSurfaceDirection.x, ncaSurfaceDirection.z) / (2.0 * PI) + 0.5),\n    clamp(\n      0.5 - asin(clamp(ncaSurfaceDirection.y, -1.0, 1.0)) / PI,\n      0.0,\n      1.0\n    )\n  );\n  float ncaDayFactor = smoothstep(\n    ncaNightTransitionStart,\n    ncaNightTransitionEnd,\n    dot(ncaSurfaceDirection, sunDirection)\n  );\n  float ncaNightFactor = pow(\n    clamp(1.0 - ncaDayFactor, 0.0, 1.0),\n    max(ncaNightPower, 0.1)\n  );\n  // Provider imagery is display-referred albedo, not emitted radiance. Apply\n  // the same authored terminator and black night floor as the direct Earth\n  // material before adding clouds, Black Marble, or local light emitters.\n  // Keeping this attenuation here lets genuine emission remain luminous.\n  float ncaPhotorealNightVisibility = mix(\n    1.0,\n    clamp(ncaNightMinBrightness, 0.0, 1.0),\n    ncaNightFactor\n  );\n  radiance *= mix(\n    1.0,\n    ncaPhotorealNightVisibility,\n    ncaPhotoSurfaceMask\n  );\n  // Physical night irradiance can already be exactly zero, so multiplication\n  // alone cannot retain any terrain detail. Add a very small display-referred\n  // provider-albedo floor beneath all true emission. This keeps blackout areas\n  // barely navigable without flattening the brighter Black Marble hotspots.\n  radiance += inputColor.rgb\n    * clamp(ncaNightMinBrightness, 0.0, 1.0)\n    * ncaNightFactor\n    * ncaPhotoSurfaceMask;\n  // Assisted surface illumination must recover provider texture even where\n  // physical night radiance is zero. It shares the existing hardware mask and\n  // compositor; the scene canvas supplies monochrome presentation only.\n  radiance = mix(radiance, max(radiance, inputColor.rgb * 0.8),\n    ncaNightVision * ncaPhotoSurfaceMask);\n  float ncaOrbitSurfaceBlend = smoothstep(\n    ATMOSPHERE.bottom_radius + 20.0,\n    ATMOSPHERE.bottom_radius + 120.0,\n    length(vCameraPosition)\n  );\n  float ncaSimpleCloudOcclusion = 1.0;\n  // Water geography and geometry stay in the actual Earth frame, independent\n  // of the osculating-sphere correction used only for atmospheric scattering.\n  vec3 ncaWaterPosition = orbitalAnalyticGround ? positionECEF / METER_TO_LENGTH_UNIT\n    : (worldToECEFMatrix * vec4(worldPosition, 1.0)).xyz;\n  vec3 ncaWaterViewNormal = cross(dFdx(viewPosition),dFdy(viewPosition));\n  vec3 ncaWaterGeometryNormal = dot(ncaWaterViewNormal,ncaWaterViewNormal) > 1e-12\n    ? normalize(mat3(worldToECEFMatrix) * mat3(inverseViewMatrix) * ncaWaterViewNormal)\n    : ncaWaterGeodeticNormal(ncaWaterPosition);\n\n  // Reflected radiance belongs after diffuse irradiance and before aerial\n  // transmission/cloud compositing. Never turn specular light into albedo.\n  vec3 ncaWaterReflectedSky = vec3(0.0);\n  // Deep-ocean body (and far-orbit glint), kept outside the reflection block\n  // below, which WaterReflectionWork matches byte-for-byte. The global water\n  // mask is sampled by geographic position, like the simple clouds, so\n  // provider imagery's baked seafloor relief never shows from orbit; it fades\n  // in with the orbital water blend so near-surface water/waves own the look.\n  // Above ~7000 km the photoreal mask is dropped but the analytic ground is\n  // still surface, so ocean and glint show at any distance.\n  if (ncaWaterReflectionEnabled > 0.5 && (ncaPhotoSurfaceMask > 0.0 || orbitalAnalyticGround)) {\n    float ncaOceanSurfaceMask = orbitalAnalyticGround ? 1.0 : ncaPhotoSurfaceMask;\n    vec3 ncaOceanObserver = (worldToECEFMatrix * inverseViewMatrix * vec4(0.0,0.0,0.0,1.0)).xyz;\n    float ncaOceanObserverAltitude = length(ncaOceanObserver) - ncaWaterReferenceRadius(ncaOceanObserver);\n    float ncaOceanWater = ncaWaterSurfaceFactor(ncaWaterPosition,ncaWaterGeometryNormal,ncaOceanObserverAltitude);\n    float ncaOceanBody = ncaOceanWater * ncaOrbitalWaterBlend(ncaOceanObserverAltitude) * ncaOceanSurfaceMask;\n    if (ncaOceanBody > 0.0) {\n      vec3 ncaOceanNormal = ncaWaterGeodeticNormal(ncaSurfaceDirection);\n      vec3 ncaOceanSun = normalize(ncaSunCenterECEF - positionECEF);\n      vec3 ncaOceanSky;\n      vec3 ncaOceanSunIrradiance = GetSunAndSkyIrradiance(positionECEF, ncaOceanNormal, ncaOceanSun, ncaOceanSky);\n      vec3 ncaOceanIrradiance = ncaOceanSky;\n      vec3 ncaOceanDirect = vec3(0.0);\n      #ifdef SUN_LIGHT\n      ncaOceanIrradiance += ncaOceanSunIrradiance * sunTransmittance;\n      ncaOceanDirect = ncaOceanSunIrradiance * sunTransmittance / max(dot(ncaOceanNormal, ncaOceanSun), 1e-4);\n      #endif\n      // #031e32 deep water (linear), Lambertian body under sun + sky.\n      radiance = mix(radiance, vec3(0.00137, 0.0123, 0.0319) * ncaOceanIrradiance * RECIPROCAL_PI, ncaOceanBody);\n      if (ncaPhotoSurfaceMask <= 0.0) {\n        // The reflection block below needs the photoreal mask; supply the\n        // glint where only the analytic ground exists.\n        radiance += ncaWaterReflection(ncaOceanNormal, normalize(vCameraPosition - positionECEF), ncaOceanSun,\n          ncaWaterWindSpeed, ncaOceanDirect, vec3(0.0)) * ncaOceanWater * ncaWaterReflectionStrength;\n      }\n    }\n  }\n  if (ncaWaterReflectionEnabled > 0.5 && ncaPhotoSurfaceMask > 0.0) {\n    vec3 ncaWaterObserver = (worldToECEFMatrix * inverseViewMatrix * vec4(0.0,0.0,0.0,1.0)).xyz;\n    float ncaWaterObserverAltitude = length(ncaWaterObserver) - ncaWaterReferenceRadius(ncaWaterObserver);\n    float ncaMappedWater = ncaWaterSurfaceFactor(ncaWaterPosition,ncaWaterGeometryNormal,ncaWaterObserverAltitude);\n    vec3 ncaWaterSunOffset = ncaSunCenterECEF - positionECEF;\n    vec3 ncaWaterMoonOffset = ncaMoonCenterECEF - positionECEF;\n    float ncaWaterSolarVisibility = ncaFiniteDiscVisibility(ncaWaterSunOffset,\n      asin(clamp(ncaSunRadius / max(length(ncaWaterSunOffset), ncaSunRadius), 0.0, 1.0)),\n      ncaWaterMoonOffset,\n      asin(clamp(ncaMoonPhysicalRadius / max(length(ncaWaterMoonOffset), ncaMoonPhysicalRadius), 0.0, 1.0)));\n    vec3 ncaWaterNormal = ncaWaterGeodeticNormal(ncaSurfaceDirection);\n    vec3 ncaWaterView = normalize(vCameraPosition - positionECEF);\n    vec3 ncaWaterSun = normalize(ncaWaterSunOffset);\n    vec3 ncaWaterSkyIrradiance;\n    vec3 ncaWaterSunIrradiance = GetSunAndSkyIrradiance(positionECEF,\n      ncaWaterNormal, ncaWaterSun, ncaWaterSkyIrradiance);\n    vec3 ncaWaterDirect = vec3(0.0), ncaWaterEnvironment = vec3(0.0);\n    #ifdef SUN_LIGHT\n    // Use the exact cloud optical depth already sampled for diffuse lighting.\n    // GetSunAndSkyIrradiance contains cosine irradiance; this BRDF's direct\n    // expression already includes the incident cosine, so remove it once.\n    ncaWaterDirect = ncaWaterSunIrradiance * sunTransmittance * ncaWaterSolarVisibility\n      / max(dot(ncaWaterNormal, ncaWaterSun), 1e-4);\n    #endif\n    #ifdef SKY_LIGHT\n    ncaWaterEnvironment = ncaWaterCloudSky(ncaWaterSkyIrradiance * RECIPROCAL_PI, sunTransmittance);\n    vec3 ncaReflectionRay = reflect(-ncaWaterView, ncaWaterNormal);\n    if (ncaSimpleCloudsEnabled > 0.5) {\n      float ncaReflectionHit = ncaRaySphereFirstIntersection(positionECEF, ncaReflectionRay,\n        vec3(0.0), ATMOSPHERE.bottom_radius + max(ncaSimpleCloudsShadowHeight, 1.0) * METER_TO_LENGTH_UNIT);\n      if (ncaReflectionHit > 0.0) {\n        vec3 direction = normalize(positionECEF + ncaReflectionRay * ncaReflectionHit);\n        vec2 cloudUv = vec2(fract(atan(direction.x, direction.z) / (2.0 * PI) + 0.5),\n          0.5 - asin(clamp(direction.y, -1.0, 1.0)) / PI);\n        vec4 reflectedCloud = texture2D(ncaSimpleCloudsTexture, cloudUv);\n        float black = clamp(ncaSimpleCloudsAlphaThreshold, 0.0, 0.95);\n        float coverage = pow(clamp((reflectedCloud.a - black) / (1.0 - black + 1e-4), 0.0, 1.0),\n          1.0 + clamp(ncaSimpleCloudsAlphaSoftness, 0.0, 1.0) * 6.0);\n        vec3 cloudRadiance = mix(ncaSimpleCloudsNightAirglowColor * ncaSimpleCloudsNightAirglowStrength,\n          vec3(1.0), ncaDayFactor) * mix(0.7, 1.0, max(reflectedCloud.r, max(reflectedCloud.g, reflectedCloud.b)));\n        ncaWaterEnvironment = mix(ncaWaterEnvironment, cloudRadiance,\n          clamp(coverage * ncaSimpleCloudsOpacity, 0.0, 1.0));\n      }\n    }\n    #ifdef HAS_OVERLAY\n    // A separate reflected viewshed includes geometry and clouds outside the\n    // primary FOV. It shares the overlay sampler via disjoint atlas rectangles.\n    vec4 ncaReflectionClip = ncaWaterReflectionFromView * vec4(viewPosition, 1.0);\n    vec2 ncaReflectionUnitUv = ncaReflectionClip.xy / max(ncaReflectionClip.w, 1e-5) * 0.5 + 0.5;\n    vec2 ncaReflectionUv = ncaReflectionUnitUv * ncaWaterReflectionRegion.xy + ncaWaterReflectionRegion.zw;\n    vec2 ncaReflectionTexel = 0.5 / vec2(textureSize(overlayBuffer, 0));\n    ncaReflectionUv = clamp(ncaReflectionUv, ncaWaterReflectionRegion.zw + ncaReflectionTexel,\n      ncaWaterReflectionRegion.zw + ncaWaterReflectionRegion.xy - ncaReflectionTexel);\n    if (ncaReflectionClip.w > 0.0 && ncaWaterReflectionReady > 0.5\n        && all(greaterThan(ncaReflectionUnitUv, vec2(0.0))) && all(lessThan(ncaReflectionUnitUv, vec2(1.0)))) {\n      vec4 ncaReflectedClouds = texture2D(overlayBuffer, ncaReflectionUv);\n      ncaWaterEnvironment = ncaReflectedClouds.rgb;\n    }\n    #endif\n    #endif\n    float ncaReflectionWeight = ncaMappedWater * ncaPhotoSurfaceMask * ncaWaterReflectionStrength;\n    radiance += ncaWaterReflection(ncaWaterNormal, ncaWaterView, ncaWaterSun,\n      ncaWaterWindSpeed, ncaWaterDirect, vec3(0.0)) * ncaReflectionWeight;\n    ncaWaterReflectedSky = ncaWaterEnvironment * ncaWaterFresnel(max(dot(ncaWaterNormal,ncaWaterView),0.0))\n      * ncaReflectionWeight;\n  }\n\n  if (ncaSimpleCloudsEnabled > 0.5\n      && ncaPhotoSurfaceMask > 0.0) {\n    vec4 ncaCloudSample = texture2D(\n      ncaSimpleCloudsTexture,\n      ncaSurfaceUv\n    );\n    float ncaCloudCoverage = clamp(ncaCloudSample.a, 0.0, 1.0);\n    float ncaCloudBlack = clamp(ncaSimpleCloudsAlphaThreshold, 0.0, 0.95);\n    float ncaCloudContrast = 1.0\n      + clamp(ncaSimpleCloudsAlphaSoftness, 0.0, 1.0) * 6.0;\n    float ncaCloudNormalized = clamp(\n      (ncaCloudCoverage - ncaCloudBlack)\n        / (1.0 - ncaCloudBlack + 1e-4),\n      0.0,\n      1.0\n    );\n    float ncaCloudMask = pow(ncaCloudNormalized, ncaCloudContrast);\n    // From orbit the deck is a slab at its real altitude: parallax, thickness\n    // toward the limb, and relief shading (orbital-cloud-volume.js).\n    float ncaCloudRelief = 1.0;\n    if (ncaOrbitSurfaceBlend > 0.0) {\n      NcaAerialCloudViewResult ncaCloudView = ncaAerialCloudView(positionECEF,\n        vCameraPosition - positionECEF, sunDirection,\n        max(ncaSimpleCloudsShadowHeight, 1.0) * METER_TO_LENGTH_UNIT);\n      ncaCloudMask = mix(ncaCloudMask, ncaCloudView.alpha, ncaOrbitSurfaceBlend);\n      ncaCloudSample = mix(ncaCloudSample, ncaCloudView.sampleValue, ncaOrbitSurfaceBlend);\n      ncaCloudRelief = mix(1.0, ncaCloudView.shade, ncaOrbitSurfaceBlend * ncaDayFactor);\n    }\n\n    float ncaCloudShadowMask = ncaCloudMask;\n    if (ncaSimpleCloudsShadowStrength > 0.0 && ncaDayFactor > 0.0) {\n      float ncaCloudShellRadius = max(\n        ATMOSPHERE.bottom_radius + 0.001,\n        ATMOSPHERE.bottom_radius\n          + max(ncaSimpleCloudsShadowHeight, 0.0) * METER_TO_LENGTH_UNIT\n      );\n      float ncaCloudHitDistance = ncaRaySphereFirstIntersection(\n        positionECEF,\n        normalize(sunDirection),\n        vec3(0.0),\n        ncaCloudShellRadius\n      );\n      if (ncaCloudHitDistance > 0.0) {\n        vec3 ncaCloudHitDirection = normalize(\n          positionECEF + normalize(sunDirection) * ncaCloudHitDistance\n        );\n        vec2 ncaCloudShadowUv = vec2(\n          fract(atan(ncaCloudHitDirection.x, ncaCloudHitDirection.z)\n            / (2.0 * PI) + 0.5),\n          clamp(\n            0.5 - asin(clamp(ncaCloudHitDirection.y, -1.0, 1.0)) / PI,\n            0.0,\n            1.0\n          )\n        );\n        float ncaCloudShadowCoverage = clamp(\n          texture2D(ncaSimpleCloudsTexture, ncaCloudShadowUv, 1.5).a,\n          0.0,\n          1.0\n        );\n        float ncaCloudShadowNormalized = clamp(\n          (ncaCloudShadowCoverage - ncaCloudBlack)\n            / (1.0 - ncaCloudBlack + 1e-4),\n          0.0,\n          1.0\n        );\n        ncaCloudShadowMask = pow(\n          ncaCloudShadowNormalized,\n          ncaCloudContrast\n        );\n      }\n    }\n\n    float ncaCloudShadow = clamp(\n      ncaCloudShadowMask\n        * ncaSimpleCloudsShadowStrength\n        * ncaDayFactor\n        * ncaPhotoSurfaceMask,\n      0.0,\n      0.85\n    );\n    radiance *= 1.0 - ncaCloudShadow;\n    // The projected simple-cloud field also shadows the direct glint above.\n    // Add diffuse sky reflection after this direct attenuation, before the\n    // camera-facing cloud overlay, so overcast does not erase all reflection.\n    radiance += ncaWaterReflectedSky;\n\n    float ncaCloudAlpha = clamp(\n      ncaCloudMask\n        * ncaSimpleCloudsOpacity\n        * ncaOrbitSurfaceBlend\n        * ncaPhotoSurfaceMask,\n      0.0,\n      1.0\n    );\n    float ncaCloudShade = clamp(\n      max(ncaCloudSample.r, max(ncaCloudSample.g, ncaCloudSample.b)),\n      0.0,\n      1.0\n    );\n    vec3 ncaNightCloudAirglow = ncaSimpleCloudsNightAirglowColor\n      * ncaSimpleCloudsNightAirglowStrength;\n    vec3 ncaCloudColor = mix(\n      ncaNightCloudAirglow,\n      vec3(1.0),\n      ncaDayFactor\n    )\n      * mix(0.7, 1.0, ncaCloudShade) * ncaCloudRelief;\n    if (ncaSimpleCloudsBlendMode < 0.5) {\n      radiance = mix(radiance, ncaCloudColor, ncaCloudAlpha);\n    } else if (ncaSimpleCloudsBlendMode < 1.5) {\n      radiance += ncaCloudColor * ncaCloudAlpha;\n    } else if (ncaSimpleCloudsBlendMode < 2.5) {\n      vec3 ncaCloudScreen = ncaCloudColor * ncaCloudAlpha;\n      radiance = 1.0 - (1.0 - radiance) * (1.0 - ncaCloudScreen);\n    } else {\n      radiance *= 1.0 - ncaCloudAlpha;\n    }\n    ncaSimpleCloudOcclusion = 1.0 - clamp(\n      ncaCloudMask\n        * ncaSimpleCloudsOpacity\n        * ncaOrbitSurfaceBlend,\n      0.0,\n      0.95\n    );\n  } else {\n    radiance += ncaWaterReflectedSky;\n  }\n\n  if (ncaLightPollutionEnabled > 0.5 && ncaPhotoSurfaceMask > 0.0) {\n    // The scattering position is shifted onto Takram's osculating sphere.\n    // Sample geography at the actual WGS84 terrain position instead.\n    vec3 ncaLightPosition = ncaWaterPosition;\n    if (orbitalAnalyticGround) {\n      // The high-orbit scattering fallback deliberately skips real terrain\n      // reconstruction. Its sphere intersection is not an imagery coordinate.\n      // A nonzero hardware mask proves that this depth belongs to real geometry.\n      vec3 ncaLightViewPosition;\n      #if defined(PERSPECTIVE_CAMERA) && (defined(USE_LOGDEPTHBUF) || defined(USE_LOGARITHMIC_DEPTH_BUFFER))\n        float ncaLightViewZ = 1.0 - exp2(depth * log2(cameraFar + 1.0));\n        vec3 ncaLightViewRay = (inverseProjectionMatrix * vec4(uv * 2.0 - 1.0, 0.0, 1.0)).xyz;\n        ncaLightViewPosition = ncaLightViewRay * (ncaLightViewZ / ncaLightViewRay.z);\n      #else\n        ncaLightViewPosition = screenToView(uv, depth, getViewZ(depth),\n          projectionMatrix, inverseProjectionMatrix);\n      #endif\n      ncaLightPosition = (worldToECEFMatrix * inverseViewMatrix\n        * vec4(ncaLightViewPosition, 1.0)).xyz;\n    }\n    vec2 ncaLightUv = ncaNightLightsGeographicUv(ncaLightPosition);\n    if (ncaLightPollutionMercator > 0.5) {\n      float ncaLatitude = (0.5 - ncaLightUv.y) * PI;\n      ncaLatitude = clamp(ncaLatitude, -1.4844222297, 1.4844222297);\n      float ncaSinLatitude = sin(ncaLatitude);\n      ncaLightUv.y = clamp(\n        0.5\n          - 0.25\n            * log((1.0 + ncaSinLatitude) / (1.0 - ncaSinLatitude))\n            / PI,\n        0.0,\n        1.0\n      );\n    }\n    ncaLightUv = (ncaLightUv - 0.5) * ncaLightPollutionUvScale\n      + 0.5\n      + ncaLightPollutionUvOffset;\n    ncaLightUv.x = fract(ncaLightUv.x + 1.0);\n    ncaLightUv.y = clamp(ncaLightUv.y, 0.0, 1.0);\n\n    vec4 ncaLightSample = texture2D(\n      ncaLightPollutionTexture,\n      ncaLightUv\n    );\n    if (ncaLightPollutionDetailEnabled > 0.5) {\n      float ncaWrappedDeltaU = fract(\n        ncaLightUv.x - ncaLightPollutionDetailBounds.x + 0.5\n      ) - 0.5;\n      vec2 ncaDetailUv = vec2(\n        ncaWrappedDeltaU / max(ncaLightPollutionDetailBounds.z, 1e-6) + 0.5,\n        (ncaLightUv.y - ncaLightPollutionDetailBounds.y)\n          / max(ncaLightPollutionDetailBounds.w, 1e-6)\n      );\n      float ncaDetailInside = step(0.0, ncaDetailUv.x)\n        * step(ncaDetailUv.x, 1.0)\n        * step(0.0, ncaDetailUv.y)\n        * step(ncaDetailUv.y, 1.0);\n      vec4 ncaDetailSample = texture2D(\n        ncaLightPollutionDetailTexture,\n        clamp(ncaDetailUv, vec2(0.0), vec2(1.0))\n      );\n      ncaLightSample = mix(\n        ncaLightSample,\n        ncaDetailSample,\n        ncaDetailInside\n      );\n    }\n    vec3 ncaLightRgb = max(ncaLightSample.rgb, vec3(0.0));\n    float ncaSourceLuminance = max(\n      max(ncaLightRgb.r, ncaLightRgb.g),\n      ncaLightRgb.b\n    );\n    float ncaSourceSignal = resolveNightLightsSourceSignal(\n      ncaLightRgb,\n      ncaLightPollutionEmissionBlueSuppression\n    );\n    float ncaEmissionThreshold = clamp(\n      ncaLightPollutionEmissionThreshold,\n      0.0,\n      0.95\n    );\n    float ncaEmissionSoftness = max(\n      ncaLightPollutionEmissionSoftness,\n      1e-4\n    );\n    float ncaNormalizedEmission = clamp(\n      (ncaSourceSignal - ncaEmissionThreshold)\n        / max(1.0 - ncaEmissionThreshold, 1e-4),\n      0.0,\n      1.0\n    );\n    float ncaEmissionGate = smoothstep(\n      ncaEmissionThreshold,\n      min(1.0, ncaEmissionThreshold + ncaEmissionSoftness),\n      ncaSourceSignal\n    );\n    float ncaMapRadiance = pow(\n      ncaNormalizedEmission,\n      max(ncaLightPollutionEmissionPower, 0.1)\n    ) * ncaEmissionGate * ncaLightPollutionMapGain;\n    vec3 ncaSourceChroma =\n      ncaLightRgb / max(ncaSourceLuminance, 1e-4);\n    // The NASA field is a regional energy envelope near the ground. Preserve\n    // photoreal texture/chroma at street level, then progressively recover the\n    // authored source-pixel emission for regional and orbital views.\n    vec3 ncaSurfaceEmissionCarrier = resolveNightLightsSurfaceCarrier(\n      inputColor.rgb,\n      ncaSourceChroma,\n      ncaLightPollutionColor,\n      ${NIGHT_LIGHTS_EMISSION_DEFAULTS.surfaceProviderColorMix}\n    );\n    vec3 ncaOrbitalEmissionCarrier =\n      ncaSourceChroma * ncaLightPollutionColor;\n    vec3 ncaEmissionCarrier = mix(\n      ncaSurfaceEmissionCarrier,\n      ncaOrbitalEmissionCarrier,\n      ncaOrbitSurfaceBlend\n    );\n    float ncaAltitudeEmissionScale = mix(\n      ncaLightPollutionSurfaceIntensityScale,\n      1.0,\n      ncaOrbitSurfaceBlend\n    );\n    vec3 ncaEmittedRadiance =\n      ncaEmissionCarrier\n      * ncaLightPollutionIntensity\n      * ncaMapRadiance\n      * ncaAltitudeEmissionScale;\n    radiance += ncaEmittedRadiance\n      * ncaLightSample.a\n      * ncaNightFactor\n      * ncaSimpleCloudOcclusion\n      * ncaPhotoSurfaceMask;\n    if (ncaSimpleCloudOcclusion < .999 && ncaNightFactor > .001) {\n      // Light diffused up through the deck: a broad soft glow, not dots.\n      float ncaCoveredFraction = 1.0 - ncaSimpleCloudOcclusion;\n      radiance += ncaNightCloudDiffuse(ncaLightPosition, ncaSimpleCloudsShadowHeight, ncaCoveredFraction)\n        * ncaCoveredFraction * ncaNightFactor * ncaPhotoSurfaceMask * ncaOrbitSurfaceBlend;\n      radiance += ncaNightCloudRadiance(ncaLightPosition, ncaSimpleCloudsShadowHeight)\n        * ncaCoveredFraction * ncaNightFactor * ncaPhotoSurfaceMask * (1.0 - ncaOrbitSurfaceBlend);\n    }\n    if (ncaNightFactor > .001 && ncaOrbitSurfaceBlend > .001) {\n      // City light scattered by the atmosphere toward the viewer.\n      vec3 ncaViewerECEF = (worldToECEFMatrix * inverseViewMatrix * vec4(0.0, 0.0, 0.0, 1.0)).xyz;\n      float ncaViewMu = dot(normalize(ncaViewerECEF - ncaLightPosition), normalize(ncaLightPosition));\n      radiance += ncaNightAirGlow(ncaLightPosition, ncaViewMu)\n        * ncaNightFactor * ncaPhotoSurfaceMask * ncaOrbitSurfaceBlend;\n    }\n  }\n\n  ${SURFACE_OVERLAY_EMITTER_MARKER}\n  // Overlay-owned emitters illuminate the reconstructed photoreal surface\n  // rather than merely drawing a screen-space halo.  A compact source list is\n  // shared by utility corridors and incident spires.  Relief normals come\n  // from the actual front-most depth surface, while a midpoint depth probe\n  // removes illumination behind intervening tile geometry.  This supplies\n  // local cast-shadow contrast without enabling Three's global shadow-map\n  // define on every astronomical-scale scene material.\n  if (ncaSurfaceEmitterCount > 0.5 && ncaPhotoSurfaceMask > 0.0) {\n    vec3 ncaSurfaceReliefNormal = normalize(cross(\n      dFdx(positionECEF),\n      dFdy(positionECEF)\n    ));\n    if (dot(ncaSurfaceReliefNormal, ncaSurfaceDirection) < 0.0) {\n      ncaSurfaceReliefNormal *= -1.0;\n    }\n    for (int ncaEmitterIndex = 0;\n      ncaEmitterIndex < ${MAX_SURFACE_LIGHT_EMITTERS};\n      ncaEmitterIndex += 1) {\n      if (float(ncaEmitterIndex) >= ncaSurfaceEmitterCount) break;\n      vec4 ncaEmitterStart = ncaSurfaceEmitterStarts[ncaEmitterIndex];\n      vec4 ncaEmitterEnd = ncaSurfaceEmitterEnds[ncaEmitterIndex];\n      vec4 ncaEmitterColor = ncaSurfaceEmitterColors[ncaEmitterIndex];\n      vec4 ncaEmitterParams = ncaSurfaceEmitterParams[ncaEmitterIndex];\n      vec3 ncaEmitterChord = ncaEmitterEnd.xyz - ncaEmitterStart.xyz;\n      float ncaEmitterChordLength2 = max(\n        dot(ncaEmitterChord, ncaEmitterChord),\n        1e-9\n      );\n      float ncaEmitterSegmentT = clamp(\n        dot(ncaSurfaceDirection - ncaEmitterStart.xyz, ncaEmitterChord)\n          / ncaEmitterChordLength2,\n        0.0,\n        1.0\n      );\n      vec3 ncaEmitterDirection = normalize(mix(\n        ncaEmitterStart.xyz,\n        ncaEmitterEnd.xyz,\n        ncaEmitterParams.w > 0.5 ? ncaEmitterSegmentT : 0.0\n      ));\n      float ncaEmitterDistance = length(\n        ncaSurfaceDirection - ncaEmitterDirection\n      ) * ATMOSPHERE.bottom_radius;\n      float ncaEmitterRadius = max(ncaEmitterStart.w, 1e-4);\n      float ncaEmitterFalloff = 1.0 - smoothstep(\n        ncaEmitterRadius * 0.06,\n        ncaEmitterRadius,\n        ncaEmitterDistance\n      );\n      ncaEmitterFalloff *= ncaEmitterFalloff;\n      if (ncaEmitterFalloff <= 0.0005) continue;\n\n      float ncaEmitterPulse = 1.0;\n      if (ncaEmitterParams.x > 0.0) {\n        ncaEmitterPulse = mix(\n          0.76,\n          1.0,\n          0.5 + 0.5 * sin(\n            2.0 * PI * (\n              ncaSurfaceEmitterTime * ncaEmitterParams.x\n              + ncaEmitterParams.y\n            )\n          )\n        );\n      }\n      vec3 ncaEmitterPosition = ncaEmitterDirection * (\n        ATMOSPHERE.bottom_radius + ncaEmitterEnd.w\n      );\n      vec3 ncaEmitterLightDirection = normalize(\n        ncaEmitterPosition - positionECEF\n      );\n      float ncaEmitterRelief = mix(\n        0.24,\n        1.0,\n        max(dot(ncaSurfaceReliefNormal, ncaEmitterLightDirection), 0.0)\n      );\n      float ncaEmitterVisibility = 1.0;\n\n      // One bounded screen-depth probe halfway to the emitter detects the\n      // high-value case: a building or ridge between the receiver and source.\n      // Most fragments leave before this branch because their falloff is zero.\n      if (ncaEmitterParams.z > 0.001) {\n        vec3 ncaProbeECEF = mix(positionECEF, ncaEmitterPosition, 0.52);\n        vec3 ncaProbeWorld = (\n          ncaSurfaceEmitterECEFToWorld\n            * vec4(ncaProbeECEF / METER_TO_LENGTH_UNIT, 1.0)\n        ).xyz;\n        vec4 ncaProbeClip = projectionMatrix\n          * viewMatrix\n          * vec4(ncaProbeWorld, 1.0);\n        if (ncaProbeClip.w > 0.0) {\n          vec2 ncaProbeUv = ncaProbeClip.xy / ncaProbeClip.w * 0.5 + 0.5;\n          if (all(greaterThanEqual(ncaProbeUv, vec2(0.0)))\n              && all(lessThanEqual(ncaProbeUv, vec2(1.0)))) {\n            float ncaProbeDepth = readDepthValue(depthBuffer, ncaProbeUv);\n            if (ncaProbeDepth < 1.0 - 1e-8) {\n              #ifdef USE_LOGDEPTHBUF\n                ncaProbeDepth = reverseLogDepth(\n                  ncaProbeDepth,\n                  cameraNear,\n                  cameraFar\n                );\n              #endif\n              float ncaSceneViewZ = getViewZ(ncaProbeDepth);\n              float ncaProbeViewZ = (\n                viewMatrix * vec4(ncaProbeWorld, 1.0)\n              ).z;\n              float ncaBlocked = step(\n                ncaProbeViewZ + 1.5,\n                ncaSceneViewZ\n              );\n              ncaEmitterVisibility = mix(\n                1.0,\n                1.0 - ncaEmitterParams.z,\n                ncaBlocked\n              );\n            }\n          }\n        }\n      }\n\n      vec3 ncaLocalEmitterRadiance = ncaEmitterColor.rgb\n        * ncaEmitterColor.a\n        * ncaEmitterFalloff\n        * ncaEmitterPulse\n        * ncaEmitterRelief\n        * ncaEmitterVisibility\n        * mix(0.34, 1.0, ncaNightFactor)\n        * ncaPhotoSurfaceMask;\n      radiance += ncaLocalEmitterRadiance;\n    }\n  }\n  // Night limb: grazing light leaves through a long air path and fades into\n  // nightglow haze instead of ending in a hard silhouette.\n  radiance = mix(radiance, ncaAerialCloudViewNightLimb(radiance, positionECEF,\n    vCameraPosition - positionECEF, (1.0 - ncaDayFactor) * ncaOrbitSurfaceBlend), ncaPhotoSurfaceMask);\n  #endif // HAS_LIGHTING_MASK\n\n${surfaceCityLightingNeedle}`;\n        if (shader.includes(SURFACE_CITY_LIGHT_MARKER)) {\n            surfaceCityLightingCompatible = true;\n        } else if (shader.includes(surfaceCityLightingNeedle)) {\n            shader = shader.replace(\n                surfaceCityLightingNeedle,\n                surfaceCityLightingReplacement\n            );\n            updated = true;\n            surfaceCityLightingCompatible = true;\n        } else {\n            console.error('[AtmosphereClouds] Required surface-city irradiance insertion point changed');\n        }\n\n        if (!depthCompatible\n            || !skyPatched\n            || !orbitalGroundCompatible\n            || !celestialOcclusionCompatible\n            || !solarEclipseCompatible\n            || !surfaceCityLightingCompatible) {\n            console.error('[AtmosphereClouds] Refusing unsafe compositor; direct renderer will retain the globe and stars');\n            return false;\n        }\n\n        // --- Night-side darkening on surface pixels ---\n        // Reduced effect: the sky alpha reduction above already handles most of the night transition.\n        // This just applies subtle darkening to inscattered atmospheric light, NOT a uniform tint.\n        const NIGHT_MARKER = '/* AtmosphereClouds: NIGHT_SHADE */';\n        const radianceNeedle = 'outputColor = vec4(radiance, inputColor.a);';\n        const radianceReplacement = `  ${NIGHT_MARKER}\n  vec3 surfaceDir = normalize(positionECEF);\n  float sunDot = dot(surfaceDir, sunDirection);\n  float dayToNight = smoothstep(-0.1, 0.05, sunDot);\n  float nightMask = 1.0 - dayToNight;\n  // Gentler darkening curve - don't crush to near-zero\n  float nightDarken = mix(1.0, 0.02, nightMask);\n  // Photoreal base radiance was already attenuated before clouds and emitted\n  // light were added. Do not darken those later emission terms a second time.\n  #ifdef HAS_LIGHTING_MASK\n  // Takram only declares its local lightingMask variable inside the\n  // SUN_LIGHT/SKY_LIGHT branch. Sample the texture here so the supported\n  // mask-on/light-off shader permutation remains valid.\n  float photoLightingMask =\n    texture(lightingMaskBuffer, uv).LIGHTING_MASK_CHANNEL_;\n  nightDarken = mix(nightDarken, 1.0, photoLightingMask);\n  #endif\n  nightDarken = mix(nightDarken, 1.0, ncaNightVision);\n  radiance *= nightDarken;\n  // No tint mixing - let the surface colors show through naturally\n  outputColor = vec4(radiance, 1.0);`;\n\n        const nightBlockRegex = /\\/\\* AtmosphereClouds: NIGHT_SHADE \\*\\/[\\s\\S]*?outputColor\\s*=\\s*vec4\\(radiance[^;]*?;/;\n        if (shader.includes(NIGHT_MARKER)) {\n            shader = shader.replace(nightBlockRegex, radianceReplacement);\n            updated = true;\n        } else if (shader.includes(radianceNeedle)) {\n            shader = shader.replace(radianceNeedle, radianceReplacement);\n            updated = true;\n        }\n\n        if (!updated) {\n            console.warn('[AtmosphereClouds] Sky patch: no changes applied (needles not found).');\n            return false;\n        }\n\n        const cityAir=patchNightAirLighting(shader);\n        if(!cityAir.compatible){console.error('[AtmosphereClouds] City air-scattering signature changed');return false;}\n        shader = optimizeDryWaterReflectionShader(cityAir.shader).shader;\n        this.aerialPerspective.fragmentShader = patchPhotorealBackface(wrapCloudMapSampling(shader, ['ncaSimpleCloudsTexture']));\n        this.aerialPerspective.setChanged?.();\n        this._applySkyTuning();\n\n        this._skyDepthPatched = true;\n        console.log('[AtmosphereClouds] Sky patched: morning orbital frame blend + recompile-safe marker');\n        return true;\n    }\n\n\n    _ensureSkyTuningUniforms() {\n        if (!this.aerialPerspective?.uniforms) return;\n        const uniforms = this.aerialPerspective.uniforms;\n        const tuning = this._skyTuning;\n        const ensure = (key, value) => {\n            const uniform = uniforms.get(key);\n            if (uniform) {\n                uniform.value = value;\n                return;\n            }\n            uniforms.set(key, new THREE.Uniform(value));\n        };\n        ensure('skyAlphaScale', tuning.alphaScale);\n        ensure('skyAlphaClamp', tuning.alphaClamp);\n        ensure('skyLimbBoost', tuning.limbBoost);\n        ensure('skyPathShort', tuning.pathShort);\n        ensure('skyLimbMax', tuning.limbMax);\n        ensure('skyDensityScale', tuning.densityScale);\n        ensure('skyScaleHeight', tuning.scaleHeight);\n        ensure('skyVerticalFadeStart', tuning.verticalFadeStart);\n        ensure('skyVerticalFadeEnd', tuning.verticalFadeEnd);\n        ensure('skyAltitudeFadeStart', tuning.altitudeFadeStart);\n        ensure('skyAltitudeFadeEnd', tuning.altitudeFadeEnd);\n        ensure('skyOutsideFadeStart', tuning.outsideFadeStart);\n        ensure('skyOutsideFadeEnd', tuning.outsideFadeEnd);\n        ensure('skyDepthThreshold', tuning.depthThreshold);\n        ensure(\n            'ncaSurfaceCameraMode',\n            this._surfaceCameraModeActive ? 1 : 0\n        );\n        ensure('ncaMoonPhysicalRadius', MOON_RADIUS_M / 1000);\n    }\n\n    _applySkyTuning() {\n        this._ensureSkyTuningUniforms();\n        if (!this.aerialPerspective?.uniforms) return;\n        const uniforms = this.aerialPerspective.uniforms;\n        const tuning = this._skyTuning;\n        const setValue = (key, value) => {\n            const uniform = uniforms.get(key);\n            if (uniform) uniform.value = value;\n        };\n        setValue('skyAlphaScale', tuning.alphaScale);\n        setValue('skyAlphaClamp', tuning.alphaClamp);\n        setValue('skyLimbBoost', tuning.limbBoost);\n        setValue('skyPathShort', tuning.pathShort);\n        setValue('skyLimbMax', tuning.limbMax);\n        setValue('skyDensityScale', tuning.densityScale);\n        setValue('skyScaleHeight', tuning.scaleHeight);\n        setValue('skyVerticalFadeStart', tuning.verticalFadeStart);\n        setValue('skyVerticalFadeEnd', tuning.verticalFadeEnd);\n        setValue('skyAltitudeFadeStart', tuning.altitudeFadeStart);\n        setValue('skyAltitudeFadeEnd', tuning.altitudeFadeEnd);\n        setValue('skyOutsideFadeStart', tuning.outsideFadeStart);\n        setValue('skyOutsideFadeEnd', tuning.outsideFadeEnd);\n        setValue('skyDepthThreshold', tuning.depthThreshold);\n    }\n\n    /**\n     * Patch the clouds shader to compute cameraHeight locally from the actual\n     * ray origin position rather than using the uniform value. This fixes the\n     * issue where clouds disappear when the camera enters a cloud layer because\n     * Takram's uniform is measured against its default WGS84 ellipsoid while\n     * this effect's cloud layers use our spherical atmosphere bottom radius.\n     *\n     * The pinned r182 matrix uses the vEllipsoidCenter signature. Keep support\n     * for the later altitudeCorrection signature only as an explicit adapter,\n     * never as authority for the active dependency contract.\n     */\n    _patchCloudsCameraHeight() {\n        const hadPatchedContract = this._cloudsCameraHeightPatched;\n        const hasLocal = !!this.clouds;\n        const hasOrbit = !!this._orbitCloudsEffect;\n        if (!hasLocal && !hasOrbit) return false;\n        const localPatched = !hasLocal || this._patchCloudsCameraHeightForEffect(this.clouds);\n        const orbitPatched = !hasOrbit || this._patchCloudsCameraHeightForEffect(this._orbitCloudsEffect);\n        const patched = localPatched && orbitPatched;\n        this._cloudsCameraHeightPatched = patched;\n        if (patched && !hadPatchedContract) {\n            console.log('[AtmosphereClouds] Cloud camera heights patched for continuous layer traversal');\n        }\n        return patched;\n    }\n\n    _patchCloudsCameraHeightForEffect(effect) {\n        patchCloudShadowStorage(effect);\n        const material = effect?.cloudsPass?.currentMaterial;\n        if (!material?.fragmentShader) return false;\n        if (this._cloudsCameraHeightPatchedMaterials?.has(material)) return true;\n\n        // The SDK's log -> perspective -> view-depth round trip collapses\n        // distant ground into float32 bins. Cloud clipping must consume the\n        // scene's logarithmic metres directly, just like aerial perspective.\n        const sceneDepthNeedle = '    depth = reverseLogDepth(depth, cameraNear, cameraFar);\\n    viewZ = getViewZ(depth);';\n        if (material.fragmentShader.includes(sceneDepthNeedle)) {\n            material.fragmentShader = material.fragmentShader.replace(sceneDepthNeedle, `\n    /* AtmosphereClouds: CLOUD_DIRECT_LOG_DEPTH */\n    #if defined(USE_LOGDEPTHBUF) || defined(USE_LOGARITHMIC_DEPTH_BUFFER)\n    viewZ = 1.0 - exp2(depth * log2(cameraFar + 1.0));\n    #else\n    viewZ = getViewZ(depth);\n    #endif`);\n        }\n        const marker = '/* AtmosphereClouds: LOCAL_CAMERA_HEIGHT */';\n        if (material.fragmentShader.includes(marker)) {\n            this._cloudsCameraHeightPatchedMaterials?.add(material);\n            return true;\n        }\n\n        const uniformNeedle = 'uniform float cameraHeight;';\n        const cameraPositionSignatures = [\n            // @takram/three-clouds 0.7.x / @takram/three-atmosphere 0.19.x.\n            'vec3 cameraPosition = vCameraPosition + altitudeCorrection;',\n            // Legacy three-clouds 0.3.x / three-atmosphere 0.12.x.\n            'vec3 cameraPosition = vCameraPosition - vEllipsoidCenter;'\n        ];\n        const cameraPosNeedle = cameraPositionSignatures.find((signature) =>\n            material.fragmentShader.includes(signature)\n        );\n        if (!material.fragmentShader.includes(uniformNeedle) || !cameraPosNeedle) {\n            console.error('[AtmosphereClouds] Required cloud camera-height signature changed; refusing unpatched layer traversal');\n            return false;\n        }\n\n        let shader = material.fragmentShader.replace(\n            uniformNeedle,\n            `${uniformNeedle}\\n${marker}\\nfloat cameraHeightLocal;`\n        );\n        shader = shader.replace(\n            cameraPosNeedle,\n            `${cameraPosNeedle}\\n  cameraHeightLocal = length(cameraPosition) - bottomRadius;`\n        );\n        shader = shader.replace(/\\bcameraHeight\\b/g, 'cameraHeightLocal');\n        // Preserve the library uniform declaration/API even though all shader\n        // decisions now consume the locally consistent value.\n        shader = shader.replace('uniform float cameraHeightLocal;', uniformNeedle);\n\n        material.fragmentShader = shader;\n        material.needsUpdate = true;\n        this._cloudsCameraHeightPatchedMaterials?.add(material);\n        return true;\n    }\n\n    /**\n     * Takram correctly removes direct sunlight below the horizon, but its sky\n     * irradiance approximation can retain a daytime-white ambient contribution\n     * over the astronomical night side. Make the local surface-to-Sun factor\n     * authoritative for every volumetric sample, apply the Moon's finite disc\n     * to direct solar irradiance at each sample, and retain only the same tiny\n     * cool airglow term used by the lightweight cloud-map renderers.\n     */\n    /**\n     * Bound the volumetric clouds by the real daily cover. Takram's local\n     * weather is a tiling procedural field, so close to the surface clouds,\n     * their shadows and sparkle were spread uniformly regardless of where the\n     * live simple-cloud map has cloud. Every weather sample's density is\n     * multiplied by the live coverage at that sample's geographic position\n     * (same lookup and contrast curve as the deferred simple-cloud pass), in\n     * the cloud march and in the shadow-map march.\n     */\n    _patchCloudsLiveCoverage() {\n        let ok = true;\n        for (const effect of [this.clouds, this._orbitCloudsEffect]) {\n            if (!effect) continue;\n            for (const material of [effect.cloudsPass?.currentMaterial, effect.shadowPass?.currentMaterial]) {\n                if (material) ok = this._patchMaterialLiveCoverage(material) && ok;\n            }\n        }\n        return ok;\n    }\n\n    _patchMaterialLiveCoverage(material) {\n        if (!material?.fragmentShader || !material?.uniforms) return false;\n        const marker = '/* AtmosphereClouds: LIVE_CLOUD_COVERAGE */';\n        if (material.fragmentShader.includes(marker)) return true;\n        const callNeedle = 'WeatherSample weather = sampleWeather(uv, height, mipLevel);';\n        const declNeedle = 'WeatherSample sampleWeather(';\n        const factorNeedle = 'vec4 factor = 1.0 - coverage * heightScale;';\n        if (![callNeedle, declNeedle, factorNeedle].every((needle) => material.fragmentShader.includes(needle))) return false;\n        const source = this._earthMaterial?.uniforms;\n        material.uniforms.ncaLiveCloudMap = source?.simpleCloudsTexture ?? new THREE.Uniform(null);\n        material.uniforms.ncaLiveCloudEnabled = source?.simpleCloudsEnabled ?? new THREE.Uniform(0);\n        material.uniforms.ncaLiveCloudThreshold = source?.simpleCloudsAlphaThreshold ?? new THREE.Uniform(0);\n        material.uniforms.ncaLiveCloudSoftness = source?.simpleCloudsAlphaSoftness ?? new THREE.Uniform(0);\n        this._localCloudField ||= new LocalCloudCoverField();\n        this._localPrecipField ||= new LocalPrecipitationField();\n        Object.assign(material.uniforms, this._localCloudField.uniforms, this._localPrecipField.uniforms);\n        // Remove the SDK's osculating-sphere correction when it is present.\n        const geographic = /uniform vec3 altitudeCorrection;/.test(material.fragmentShader)\n            ? 'p - altitudeCorrection' : 'p';\n        let shader = material.fragmentShader.replace(declNeedle, `${marker}\nuniform sampler2D ncaLiveCloudMap, ncaLocalCloudMap;\nuniform float ncaLiveCloudEnabled, ncaLiveCloudThreshold, ncaLiveCloudSoftness, ncaLocalCloudWeight;\nuniform vec4 ncaLocalCloudBounds;\nuniform sampler2D ncaLocalPrecipMap;\nuniform vec4 ncaLocalPrecipBounds;\nuniform float ncaLocalPrecipEnabled;\n// Precipitation from the Map-layer radar / NOAA precipitation mosaic, kept in\n// Web Mercator with tile-exact bounds so it lands where the map draws it.\nfloat ncaLocalPrecip(float latDeg, float lonDeg) {\n  if (ncaLocalPrecipEnabled <= 0.0) return 0.0;\n  float lat = radians(clamp(latDeg, -85.0511, 85.0511));\n  float mx = (lonDeg + 180.0) / 360.0;\n  float my = (1.0 - log(tan(PI * 0.25 + lat * 0.5)) / PI) * 0.5;\n  float cx = (ncaLocalPrecipBounds.x + ncaLocalPrecipBounds.z) * 0.5;\n  mx -= floor(mx - cx + 0.5);\n  vec2 uv = (vec2(mx, my) - ncaLocalPrecipBounds.xy) / (ncaLocalPrecipBounds.zw - ncaLocalPrecipBounds.xy);\n  if (any(lessThan(uv, vec2(0.0))) || any(greaterThan(uv, vec2(1.0)))) return 0.0;\n  return textureLod(ncaLocalPrecipMap, uv, 0.0).r * ncaLocalPrecipEnabled;\n}\n// Per-sample multiplier on the SDK coverage parameter (set before sampleWeather).\nfloat ncaCoverageScale = 1.0;\nfloat ncaGlobalCloudMask(const vec3 d) {\n  vec2 uv = vec2(fract(atan(d.x, d.z) / (2.0 * PI) + 0.5), 0.5 - asin(clamp(d.y, -1.0, 1.0)) / PI);\n  float a = textureLod(ncaLiveCloudMap, uv, 0.0).a;\n  float black = clamp(ncaLiveCloudThreshold, 0.0, 0.95);\n  float t = clamp((a - black) / (1.0 - black + 1e-4), 0.0, 1.0);\n  return smoothstep(0.02, 0.35, pow(t, 1.0 + clamp(ncaLiveCloudSoftness, 0.0, 1.0) * 6.0));\n}\n// Real cover at this geographic position: the global live mask from altitude,\n// fused near the ground with the current regional-model cloud cover and\n// precipitation grid (LocalCloudCoverField). The local value sets the\n// effective coverage to the real fraction, so 27 % cover is ~27 % of the sky\n// in procedural cloud shapes, and rain pushes toward overcast.\nfloat ncaFusedCoverageScale(const vec3 p) {\n  vec3 d = normalize(${geographic});\n  float g = ncaLiveCloudEnabled > 0.5 ? ncaGlobalCloudMask(d) : 1.0;\n  float latDeg = degrees(asin(clamp(d.y, -1.0, 1.0)));\n  float lonDeg = degrees(atan(d.x, d.z));\n  // Where the radar shows rain there is cloud: push toward overcast.\n  float rain = clamp(ncaLocalPrecip(latDeg, lonDeg) * 2.5, 0.0, 1.0);\n  float overcast = 0.95 / max(coverage, 0.05);\n  if (ncaLocalCloudWeight <= 0.0) return max(g, mix(g, overcast, rain));\n  vec2 center = ncaLocalCloudBounds.xy + ncaLocalCloudBounds.zw * 0.5;\n  float dl = lonDeg - center.x; dl -= 360.0 * floor((dl + 180.0) / 360.0);\n  vec2 luv = vec2(dl, latDeg - center.y) / ncaLocalCloudBounds.zw + 0.5;\n  vec2 edge = smoothstep(vec2(0.0), vec2(0.12), luv) * smoothstep(vec2(0.0), vec2(0.12), 1.0 - luv);\n  float w = ncaLocalCloudWeight * edge.x * edge.y;\n  float scale = g;\n  if (w > 0.0) {\n    vec4 field = textureLod(ncaLocalCloudMap, clamp(luv, 0.0, 1.0), 0.0);\n    float precip = clamp(field.b * 255.0 / 160.0, 0.0, 1.0); // 4 mm/h → full\n    float cover = mix(max(field.r, field.g), 0.95, precip);\n    scale = mix(g, cover / max(coverage, 0.05), w);\n  }\n  return max(scale, mix(scale, overcast, rain));\n}\n${declNeedle}`);\n        shader = shader.replace(factorNeedle, 'vec4 factor = 1.0 - clamp(coverage * ncaCoverageScale, 0.0, 1.0) * heightScale;');\n        shader = shader.split(callNeedle).join(`ncaCoverageScale = ncaFusedCoverageScale(position);\n    ${callNeedle}`);\n        material.fragmentShader = shader;\n        material.needsUpdate = true;\n        return true;\n    }\n\n    /** Feed the near-ground local cloud field (call per frame). */\n    updateLocalCloudField(latDeg, lonDeg, altitudeM) {\n        const weight = localCloudWeight(altitudeM);\n        this._localCloudField?.update(latDeg, lonDeg, altitudeM);\n        if (this._localPrecipField) {\n            this._localPrecipField.update(latDeg, lonDeg, weight > 0);\n            this._localPrecipField.uniforms.ncaLocalPrecipEnabled.value = this._localPrecipField.source ? weight : 0;\n        }\n    }\n\n    _patchCloudsNightLighting() {\n        const hasLocal = !!this.clouds;\n        const hasOrbit = !!this._orbitCloudsEffect;\n        if (!hasLocal && !hasOrbit) return false;\n        const localPatched = !hasLocal\n            || this._patchCloudsNightLightingForEffect(this.clouds);\n        const orbitPatched = !hasOrbit\n            || this._patchCloudsNightLightingForEffect(this._orbitCloudsEffect);\n        const patched = localPatched && orbitPatched;\n        this._cloudsNightLightingPatched = patched;\n        return patched;\n    }\n\n    _patchCloudsNightLightingForEffect(effect) {\n        const material = effect?.cloudsPass?.currentMaterial;\n        if (!material?.fragmentShader || !material?.uniforms) return false;\n        if (this._cloudsNightLightingPatchedMaterials?.has(material)) return true;\n\n        const marker = '/* AtmosphereClouds: NIGHT_CLOUD_AIRGLOW */';\n        if (material.fragmentShader.includes(marker)) {\n            this._cloudsNightLightingPatchedMaterials?.add(material);\n            return true;\n        }\n\n        const uniformNeedle = 'uniform float cameraHeight;';\n        const solarLightingNeedle =\n            '      vec3 radiance = sunIrradiance * approximateMultipleScattering(opticalDepth, cosTheta);';\n        const lightingNeedle = '      // Finally multiply by scattering.\\n      radiance *= media.scattering;';\n        if (!material.fragmentShader.includes(uniformNeedle)\n            || !material.fragmentShader.includes(solarLightingNeedle)\n            || !material.fragmentShader.includes(lightingNeedle)) {\n            console.error('[AtmosphereClouds] Required cloud solar/night-lighting signature changed; refusing unoccluded cloud lighting');\n            return false;\n        }\n\n        const sourceUniforms = this._earthMaterial?.uniforms;\n        bindNightCloudLighting(material.uniforms, sourceUniforms);\n        material.uniforms.ncaCloudNightAirglowColor = sourceUniforms\n            ?.simpleCloudsNightAirglowColor\n            ?? new THREE.Uniform(new THREE.Color('#9fb3c2'));\n        material.uniforms.ncaCloudNightAirglowStrength = sourceUniforms\n            ?.simpleCloudsNightAirglowStrength\n            ?? new THREE.Uniform(0.006);\n        material.uniforms.ncaCloudNightTransitionStart = sourceUniforms\n            ?.nightTransitionStart\n            ?? new THREE.Uniform(0);\n        material.uniforms.ncaCloudNightTransitionEnd = sourceUniforms\n            ?.nightTransitionEnd\n            ?? new THREE.Uniform(0.5);\n        const celestialUniforms = this.aerialPerspective?.uniforms;\n        material.uniforms.ncaCloudMoonCenterECEF = celestialUniforms\n            ?.get?.('ncaMoonCenterECEF')\n            ?? new THREE.Uniform(new THREE.Vector3());\n        material.uniforms.ncaCloudMoonPhysicalRadius = celestialUniforms\n            ?.get?.('ncaMoonPhysicalRadius')\n            ?? new THREE.Uniform(0);\n        material.uniforms.ncaCloudSunCenterECEF = celestialUniforms\n            ?.get?.('ncaSunCenterECEF')\n            ?? new THREE.Uniform(new THREE.Vector3());\n        material.uniforms.ncaCloudSunRadius = celestialUniforms\n            ?.get?.('ncaSunRadius')\n            ?? new THREE.Uniform(0);\n\n        let shader = material.fragmentShader.replace(\n            uniformNeedle,\n            `${uniformNeedle}\nuniform vec3 ncaCloudNightAirglowColor;\nuniform float ncaCloudNightAirglowStrength;\nuniform float ncaCloudNightTransitionStart;\nuniform float ncaCloudNightTransitionEnd;\nuniform vec3 ncaCloudMoonCenterECEF;\nuniform float ncaCloudMoonPhysicalRadius;\nuniform vec3 ncaCloudSunCenterECEF;\nuniform float ncaCloudSunRadius;\n${NIGHT_CLOUD_LIGHTING_GLSL}\n${CELESTIAL_IRRADIANCE_GLSL}\nfloat ncaCloudSolarVisibilityAt(const vec3 positionMeters) {\n  vec3 positionKm = positionMeters * 0.001;\n  vec3 sunOffset = ncaCloudSunCenterECEF - positionKm;\n  vec3 moonOffset = ncaCloudMoonCenterECEF - positionKm;\n  float sunDistance = length(sunOffset);\n  float moonDistance = length(moonOffset);\n  if (ncaCloudSunRadius <= 0.0\n      || ncaCloudMoonPhysicalRadius <= 0.0\n      || sunDistance <= ncaCloudSunRadius\n      || moonDistance <= ncaCloudMoonPhysicalRadius\n      || moonDistance >= sunDistance) return 1.0;\n  return ncaFiniteDiscVisibility(\n    sunOffset,\n    asin(clamp(ncaCloudSunRadius / sunDistance, 0.0, 1.0)),\n    moonOffset,\n    asin(clamp(ncaCloudMoonPhysicalRadius / moonDistance, 0.0, 1.0))\n  );\n}`\n        );\n        shader = shader.replace(\n            solarLightingNeedle,\n            `      /* AtmosphereClouds: CLOUD_SOLAR_ECLIPSE */\n      float ncaCloudSolarVisibility = ncaCloudSolarVisibilityAt(position);\n      vec3 radiance = sunIrradiance\n        * ncaCloudSolarVisibility\n        * approximateMultipleScattering(opticalDepth, cosTheta);`\n        );\n        shader = shader.replace(\n            lightingNeedle,\n            `      ${marker}\n      float ncaCloudDayFactor = smoothstep(\n        ncaCloudNightTransitionStart,\n        ncaCloudNightTransitionEnd,\n        dot(surfaceNormal, normalize(sunDirection))\n      );\n      float ncaCloudAirglowExposure = 0.35 + 0.65 * skyGradient;\n      vec3 ncaCloudNightRadiance = ncaCloudNightAirglowColor\n        * ncaCloudNightAirglowStrength\n        * ncaCloudAirglowExposure;\n      if (ncaCloudDayFactor < .999) {\n        // Remove the SDK's osculating-sphere correction before sampling the\n        // actual geographic source. Raymarch extinction scatters this upward\n        // city radiance through the real cloud, including opaque cores.\n        ncaCloudNightRadiance += ncaNightCloudRadiance(position - altitudeCorrection, height);\n      }\n      radiance = mix(\n        ncaCloudNightRadiance,\n        radiance,\n        ncaCloudDayFactor\n      );\n\n      // Finally multiply by scattering.\n      radiance *= media.scattering;`\n        );\n\n        material.fragmentShader = shader;\n        material.needsUpdate = true;\n        this._cloudsNightLightingPatchedMaterials?.add(material);\n        return true;\n    }\n\n    /**\n     * Patch cloud temporal reprojection to account for planet rotation.\n     *\n     * The three-clouds library computes reprojection velocity as:\n     *   worldPos = ECEFToWorld(ecefPos)           // uses CURRENT ellipsoidMatrix\n     *   prevClip = reprojectionMatrix * worldPos  // uses PREVIOUS VP\n     *\n     * This is wrong when the planet rotates between frames because ECEFToWorld\n     * maps the ECEF point to its CURRENT world position, but the reprojection\n     * matrix expects the PREVIOUS frame's world position. The mismatch causes\n     * temporal accumulation to blend misaligned samples, producing undulation.\n     *\n     * Fix: after the library builds reprojectionMatrix = PrevProj * PrevView,\n     * post-multiply by (ellipsoidMatrix_prev * inverse(ellipsoidMatrix_curr))\n     * so the combined transform correctly maps current-ECEFToWorld output\n     * back to the previous frame's clip space.\n     */\n    _patchCloudsReprojection() {\n        const mainPatched = this._patchCloudsReprojectionForEffect(this.clouds);\n        const orbitPatched = !this._orbitCloudsEffect\n            || this._patchCloudsReprojectionForEffect(this._orbitCloudsEffect);\n        this._cloudsReprojectionPatched = mainPatched && orbitPatched;\n    }\n\n    _patchCloudsReprojectionForEffect(effect) {\n        const material = effect?.cloudsPass?.currentMaterial;\n        if (!material?.uniforms?.reprojectionMatrix) return;\n        if (this._cloudsReprojectionPatchedMaterials.has(material)) return true;\n\n        const self = this;\n        const _rotDelta = new THREE.Matrix4();\n        const _invCurr = new THREE.Matrix4();\n        const origCopyCameraSettings = material.copyCameraSettings.bind(material);\n\n        material.copyCameraSettings = function (camera) {\n            origCopyCameraSettings(camera);\n            // Apply rotation delta correction to the reprojection matrix.\n            // reprojectionMatrix' = PrevProj * PrevView * planetMatrix_prev * inv(planetMatrix_curr)\n            if (self._previousEllipsoidMatrix && self.planetGroup) {\n                _invCurr.copy(self._planetMatrix).invert();\n                _rotDelta.copy(self._previousEllipsoidMatrix).multiply(_invCurr);\n                material.uniforms.reprojectionMatrix.value.multiply(_rotDelta);\n            }\n        };\n\n        this._cloudsReprojectionPatchedMaterials.add(material);\n        if (globalThis.__noclipDebugClouds === true) {\n            console.debug('[AtmosphereClouds] Temporal reprojection patched for planet rotation');\n        }\n        return true;\n    }\n\n    _captureCloudBaseSettings() {\n        if (!this.clouds) return;\n        const clouds = this.clouds.clouds;\n        const shadow = this.clouds.shadow;\n        this._cloudBaseSettings = {\n            coverage: this.clouds.coverage,\n            scatteringCoefficient: this.clouds.scatteringCoefficient,\n            absorptionCoefficient: this.clouds.absorptionCoefficient,\n            turbulenceDisplacement: this.clouds.turbulenceDisplacement,\n            lightShafts: this.clouds.lightShafts,\n            shapeDetail: this.clouds.shapeDetail,\n            turbulence: this.clouds.turbulence,\n            haze: this.clouds.haze,\n            maxIterationCount: clouds?.maxIterationCount,\n            maxShadowLengthIterationCount: clouds?.maxShadowLengthIterationCount,\n            shadowMaxIterationCount: shadow?.maxIterationCount,\n        };\n    }\n\n    _setupOrbitCloudsEffect() {\n        if (this._orbitCloudsEffect) return;\n        this._orbitCloudsEffect = new CloudsEffect(\n            this.camera,\n            undefined,\n            this._atmosphereParams\n        );\n        patchCloudDepthReconstruction(this._orbitCloudsEffect);\n        this._applyCloudDepthPacking(this._orbitCloudsEffect);\n        this._orbitCloudsEffect.ellipsoid = this._atmosphereEllipsoid;\n        this._orbitCloudsEffect.atmosphere = this._atmosphereParams;\n        this._orbitCloudsEffect.localWeatherRepeat.set(1, 1);\n        this._orbitCloudsEffect.localWeatherOffset.set(0, 0);\n        this._orbitCloudsEffect.localWeatherVelocity.set(0, 0);\n        this._orbitCloudsEffect.skipRendering = true;\n        this._applyCloudShadowTuning();\n        this._patchOrbitCloudsUvMapping();\n        this._applyOrbitCloudEffectSettings(true);\n    }\n\n    _captureOrbitCloudBaseSettings() {\n        if (!this._orbitCloudsEffect) return;\n        this._orbitCloudsBaseSettings = {\n            coverage: this._orbitCloudsEffect.coverage,\n            scatteringCoefficient: this._orbitCloudsEffect.scatteringCoefficient,\n            absorptionCoefficient: this._orbitCloudsEffect.absorptionCoefficient,\n            turbulenceDisplacement: this._orbitCloudsEffect.turbulenceDisplacement,\n            lightShafts: this._orbitCloudsEffect.lightShafts,\n            shapeDetail: this._orbitCloudsEffect.shapeDetail,\n            turbulence: this._orbitCloudsEffect.turbulence,\n            haze: this._orbitCloudsEffect.haze,\n            maxStepSize: this._orbitCloudsEffect.clouds?.maxStepSize,\n            minStepSize: this._orbitCloudsEffect.clouds?.minStepSize,\n            maxIterationCount: this._orbitCloudsEffect.clouds?.maxIterationCount\n        };\n    }\n\n    _applyCloudDepthPacking(effect) {\n        if (!effect) return;\n        const depthPacking = Number.isFinite(THREE.BasicDepthPacking) ? THREE.BasicDepthPacking : 0;\n        const cloudsMaterial = effect.cloudsPass?.currentMaterial;\n        if (cloudsMaterial && Number.isFinite(depthPacking)) {\n            cloudsMaterial.depthPacking = depthPacking;\n        }\n        const shadowMaterial = effect.shadowPass?.currentMaterial;\n        if (shadowMaterial && Number.isFinite(depthPacking)) {\n            shadowMaterial.depthPacking = depthPacking;\n        }\n    }\n\n    _getOrbitCloudShellRadius() {\n        const bottomRadius = this._atmosphereParams?.bottomRadius ?? PLANET_RADIUS;\n        const layers = this._orbitCloudsEffect?.cloudLayers;\n        let top = 10000;\n        if (layers) {\n            layers.forEach((layer) => {\n                if (!layer) return;\n                const altitude = Number.isFinite(layer.altitude) ? layer.altitude : 0;\n                const height = Number.isFinite(layer.height) ? layer.height : 0;\n                top = Math.max(top, altitude + height);\n            });\n        }\n        return bottomRadius + top;\n    }\n\n    _applyOrbitCloudOverlayMapping(texture) {\n        if (!texture) return;\n        texture.wrapS = THREE.RepeatWrapping;\n        texture.wrapT = THREE.ClampToEdgeWrapping;\n        texture.repeat.set(1, 1);\n        texture.center.set(0.5, 0.5);\n        const meridianOffset = (EARTH_PRIME_MERIDIAN_OFFSET_RAD || 0) / (Math.PI * 2);\n        const offsetX = THREE.MathUtils.euclideanModulo(0.25 + meridianOffset, 1);\n        texture.offset.set(offsetX, 0);\n        texture.needsUpdate = true;\n    }\n\n    _patchOrbitCloudsUvMapping() {\n        if (!this._orbitCloudsEffect) return;\n        const marker = '/* OrbitClouds: EQUIRECT_UV */';\n        const uvRegex = /vec2 getGlobeUv\\s*\\\\(const vec3 position\\\\)[\\\\s\\\\S]*?\\\\}/;\n        const meridianOffset = Number(EARTH_PRIME_MERIDIAN_OFFSET_RAD || 0);\n        const replacement = `${marker}\nvec2 getGlobeUv(const vec3 position) {\n  vec3 n = normalize(position);\n  float lat = asin(clamp(n.y, -1.0, 1.0));\n  float lon = atan(n.x, n.z) + ${meridianOffset.toFixed(8)};\n  float u = lon * (1.0 / (2.0 * PI)) + 0.5;\n  float v = lat * (1.0 / PI) + 0.5;\n  return vec2(u, v);\n}\n`;\n\n        const materials = [\n            this._orbitCloudsEffect.cloudsPass?.currentMaterial,\n            this._orbitCloudsEffect.shadowPass?.currentMaterial\n        ].filter(Boolean);\n\n        let allPatched = materials.length > 0;\n        materials.forEach((material) => {\n            if (!material?.fragmentShader) {\n                allPatched = false;\n                return;\n            }\n            if (material.fragmentShader.includes(marker)) {\n                return;\n            }\n            if (!uvRegex.test(material.fragmentShader)) {\n                allPatched = false;\n                return;\n            }\n            material.fragmentShader = material.fragmentShader.replace(uvRegex, replacement);\n            material.needsUpdate = true;\n        });\n\n        this._orbitCloudsUvPatched = allPatched;\n    }\n\n    _applyOrbitCloudEffectSettings(forceBaseRefresh = false) {\n        if (!this._orbitCloudsEffect) return;\n        const preset = this._normalizeCloudQualityPreset(this._orbitClouds.qualityPreset);\n        if (preset && preset !== this._orbitCloudsEffectPreset) {\n            this._orbitCloudsEffect.qualityPreset = preset;\n            this._orbitCloudsEffectPreset = preset;\n            forceBaseRefresh = true;\n        }\n        if (forceBaseRefresh || !this._orbitCloudsBaseSettings) {\n            this._captureOrbitCloudBaseSettings();\n        }\n        const baseScale = Number.isFinite(this._orbitClouds.resolutionScale)\n            ? THREE.MathUtils.clamp(this._orbitClouds.resolutionScale, 0.1, 1)\n            : 1;\n        if (Math.abs((this._orbitCloudsEffect.resolutionScale ?? 1) - baseScale) > 0.01) {\n            this._orbitCloudsEffect.resolutionScale = baseScale;\n            this._lastOrbitCloudResolutionScale = baseScale;\n        }\n        this._applyOrbitCloudIntensity(1);\n    }\n\n    _applyOrbitCloudIntensity(intensity) {\n        if (!this._orbitCloudsEffect || !this._orbitCloudsBaseSettings) return;\n        const t = THREE.MathUtils.clamp(intensity, 0, 1);\n        const coverageScale = Number.isFinite(this._orbitClouds.coverageScale)\n            ? this._orbitClouds.coverageScale\n            : 1;\n        const scatteringScale = Number.isFinite(this._orbitClouds.scatteringScale)\n            ? this._orbitClouds.scatteringScale\n            : 1;\n        const absorptionScale = Number.isFinite(this._orbitClouds.absorptionScale)\n            ? this._orbitClouds.absorptionScale\n            : 1;\n        const turbulenceScale = Number.isFinite(this._orbitClouds.turbulenceScale)\n            ? this._orbitClouds.turbulenceScale\n            : 1;\n        const base = this._orbitCloudsBaseSettings;\n        const coverage = base.coverage * coverageScale * t;\n        const scattering = base.scatteringCoefficient * scatteringScale * t;\n        const absorption = base.absorptionCoefficient * absorptionScale * t;\n        const turbulenceDisp = base.turbulenceDisplacement * turbulenceScale;\n\n        if (Math.abs(this._orbitCloudsEffect.coverage - coverage) > 1e-4) {\n            this._orbitCloudsEffect.coverage = coverage;\n        }\n        if (Math.abs(this._orbitCloudsEffect.scatteringCoefficient - scattering) > 1e-4) {\n            this._orbitCloudsEffect.scatteringCoefficient = scattering;\n        }\n        if (Math.abs(this._orbitCloudsEffect.absorptionCoefficient - absorption) > 1e-4) {\n            this._orbitCloudsEffect.absorptionCoefficient = absorption;\n        }\n        if (Math.abs(this._orbitCloudsEffect.turbulenceDisplacement - turbulenceDisp) > 1) {\n            this._orbitCloudsEffect.turbulenceDisplacement = turbulenceDisp;\n        }\n    }\n\n    _applyOrbitCloudLod(t) {\n        if (!this._orbitCloudsEffect || !this._orbitCloudsBaseSettings) return;\n        const eased = THREE.MathUtils.smootherstep(t, 0, 1);\n        const simplify = eased > 0.35;\n        if (simplify !== this._orbitCloudsLodState.simplified) {\n            this._orbitCloudsLodState.simplified = simplify;\n            // shapeDetail/turbulence/haze/lightShafts are shader defines in\n            // Takram CloudsEffect: flipping them here rebuilt the volumetric\n            // program (a 0.5 s link) every time the camera crossed this\n            // altitude. As with surface clouds, LOD stays on uniforms\n            // (iterations below, coverage, resolution); structural quality\n            // only changes through explicit settings.\n        }\n\n        const cloudsParams = this._orbitCloudsEffect.clouds;\n        if (!cloudsParams) return;\n        const baseIterations = Number.isFinite(this._orbitCloudsBaseSettings.maxIterationCount)\n            ? Math.max(1, Math.round(this._orbitCloudsBaseSettings.maxIterationCount))\n            : (Number.isFinite(cloudsParams.maxIterationCount)\n                ? Math.max(1, Math.round(cloudsParams.maxIterationCount))\n                : null);\n        if (!baseIterations) return;\n        const targetIterations = Math.max(4, Math.round(baseIterations * (1 - 0.5 * eased)));\n        if (cloudsParams.maxIterationCount !== targetIterations) {\n            cloudsParams.maxIterationCount = targetIterations;\n        }\n    }\n\n    _applyCloudDistanceLod(t) {\n        if (!this.clouds || !this._cloudBaseSettings) return;\n        const eased = THREE.MathUtils.smootherstep(t, 0, 1);\n        const coverage = this._cloudBaseSettings.coverage * (1 - 0.35 * eased);\n        const scattering = this._cloudBaseSettings.scatteringCoefficient * (1 - 0.25 * eased);\n        const absorption = this._cloudBaseSettings.absorptionCoefficient * (1 - 0.2 * eased);\n        const turbulenceDisp = this._cloudBaseSettings.turbulenceDisplacement * (1 - 0.6 * eased);\n\n        if (Math.abs(this.clouds.coverage - coverage) > 1e-4) this.clouds.coverage = coverage;\n        if (Math.abs(this.clouds.scatteringCoefficient - scattering) > 1e-4) {\n            this.clouds.scatteringCoefficient = scattering;\n        }\n        if (Math.abs(this.clouds.absorptionCoefficient - absorption) > 1e-4) {\n            this.clouds.absorptionCoefficient = absorption;\n        }\n        if (Math.abs(this.clouds.turbulenceDisplacement - turbulenceDisp) > 1) {\n            this.clouds.turbulenceDisplacement = turbulenceDisp;\n        }\n\n        const simplify = eased > 0.6;\n        if (simplify !== this._cloudLodState.simplified) {\n            this._cloudLodState.simplified = simplify;\n            // shapeDetail/turbulence/haze/lightShafts are shader defines in\n            // Takram CloudsEffect. Flipping them at an altitude boundary makes\n            // EffectPass rebuild a volumetric shader from the camera update\n            // task. Resolution, distance, coverage, and scattering remain\n            // continuous uniform/target LOD controls; structural quality is\n            // selected only while background variants are prepared.\n        }\n    }\n\n    _beginSurfaceCloudActivation() {\n        const state = this._surfaceCloudActivation || (this._surfaceCloudActivation = {\n            active: false,\n            progress: 1,\n        });\n        state.active = true;\n        state.progress = 0;\n        this._applyDormantSurfaceCloudBudget();\n    }\n\n    _advanceSurfaceCloudActivation(deltaTime = 0) {\n        const state = this._surfaceCloudActivation || (this._surfaceCloudActivation = {\n            active: false,\n            progress: 1,\n        });\n        if (!state.active) return 1;\n        // Compilation/resource warm-up does not imply that a full raymarch has\n        // ever met the frame budget. Do not consume the ramp while the clear\n        // aerial pass is still the active variant.\n        if (this._cloudWarmupState !== 'ready') return 0;\n\n        const frameMs = Number.isFinite(deltaTime) && deltaTime > 0\n            ? deltaTime * 1000\n            : CLOUD_SURFACE_ACTIVATION_HEADROOM_MS;\n        // Hold admitted work on a slow frame. Backtracking made valid mixed\n        // timings (three fast / one slow) oscillate indefinitely. The existing\n        // low-FPS mode remains the separate owner of sustained workload caps.\n        if (frameMs <= CLOUD_SURFACE_ACTIVATION_HEADROOM_MS) {\n            state.progress = Math.min(\n                1,\n                state.progress + CLOUD_SURFACE_ACTIVATION_PROGRESS_STEP\n            );\n        }\n        if (state.progress >= 1) state.active = false;\n        return THREE.MathUtils.smootherstep(state.progress, 0, 1);\n    }\n\n    _applyDormantSurfaceCloudBudget() {\n        if (!this.clouds) return;\n        // Keep prewarmed current/resolve/history dimensions and native temporal\n        // ownership intact across activation and same-view surface re-entry.\n        this._lastCloudMaxRayDistance = CLOUD_SURFACE_ACTIVATION_MAX_RAY_DISTANCE_M;\n        const clouds = this.clouds.clouds;\n        if (clouds) {\n            clouds.maxRayDistance = CLOUD_SURFACE_ACTIVATION_MAX_RAY_DISTANCE_M;\n            clouds.maxShadowLengthRayDistance = CLOUD_SURFACE_ACTIVATION_MAX_RAY_DISTANCE_M;\n            clouds.maxIterationCount = CLOUD_SURFACE_ACTIVATION_MAX_ITERATIONS;\n            clouds.maxShadowLengthIterationCount = CLOUD_SURFACE_ACTIVATION_MAX_SHADOW_LENGTH_ITERATIONS;\n        }\n        if (this.clouds.shadow) {\n            this.clouds.shadow.maxIterationCount = CLOUD_SURFACE_ACTIVATION_SHADOW_ITERATIONS;\n        }\n    }\n\n    _primeCloudResolutionForCamera() {\n        const altitude = this._getCameraAltitudeMeters() ?? 0;\n        const span = CLOUD_DISTANCE_TUNING.farAltitude - CLOUD_DISTANCE_TUNING.nearAltitude;\n        const t = span > 0\n            ? THREE.MathUtils.clamp((altitude - CLOUD_DISTANCE_TUNING.nearAltitude) / span, 0, 1)\n            : 0;\n        // A preset can reset the native Resolution independently of our last\n        // LOD value. A warm-up boundary must establish actual storage, not rely\n        // on that cached value to decide the profile is already applied.\n        this._lastCloudResolutionScale = null;\n        this._applyCloudResolutionLod(t);\n    }\n\n    _applyCloudResolutionLod(t) {\n        if (!this.clouds) return;\n        const eased = THREE.MathUtils.smootherstep(t, 0, 1);\n        const desired = THREE.MathUtils.clamp(\n            THREE.MathUtils.lerp(\n                CLOUD_DISTANCE_TUNING.nearResolutionScale,\n                CLOUD_DISTANCE_TUNING.farResolutionScale,\n                eased\n            ),\n            0.25,\n            1.0\n        );\n        // Full output resolution is independent of altitude and ordinary FPS.\n        // Only sustained severe pressure may reduce it, never activation. Uniform iteration/distance limits\n        // preserve progressive first use without destroying three GPU targets.\n        const target = desired * (this._qualityResolutionScale ?? 1);\n        if (this._lastCloudResolutionScale === null || Math.abs(this._lastCloudResolutionScale - target) > 0.02) {\n            this._lastCloudResolutionScale = target;\n            this.clouds.resolutionScale = target;\n        }\n    }\n\n    _applyCloudIterationLod(activationBlend = 1) {\n        const clouds = this.clouds?.clouds;\n        const shadow = this.clouds?.shadow;\n        const base = this._cloudBaseSettings;\n        if (!clouds || !base) return;\n        const applyCount = (object, key, start, desired) => {\n            if (!object || !Number.isFinite(desired)) return;\n            const next = Math.max(1, Math.round(THREE.MathUtils.lerp(start, desired, activationBlend)));\n            if (object[key] !== next) object[key] = next;\n        };\n        applyCount(\n            clouds,\n            'maxIterationCount',\n            CLOUD_SURFACE_ACTIVATION_MAX_ITERATIONS,\n            base.maxIterationCount\n        );\n        applyCount(\n            clouds,\n            'maxShadowLengthIterationCount',\n            CLOUD_SURFACE_ACTIVATION_MAX_SHADOW_LENGTH_ITERATIONS,\n            base.maxShadowLengthIterationCount\n        );\n        applyCount(\n            shadow,\n            'maxIterationCount',\n            CLOUD_SURFACE_ACTIVATION_SHADOW_ITERATIONS,\n            base.shadowMaxIterationCount\n        );\n    }\n\n    _updateCloudCullState(altitude) {\n        if (!Number.isFinite(altitude)) return;\n        const disableAltitude = CLOUD_DISTANCE_TUNING.cullAltitude ?? Infinity;\n        const hysteresis = CLOUD_DISTANCE_TUNING.cullHysteresis ?? 0;\n        const enableAltitude = disableAltitude - hysteresis;\n        if (!this._cloudLodState.disabled && altitude >= disableAltitude) {\n            this._cloudLodState.disabled = true;\n            if (this._surfaceCloudActivation) {\n                this._surfaceCloudActivation.active = false;\n                this._surfaceCloudActivation.progress = 0;\n            }\n            this._applyDormantSurfaceCloudBudget();\n            this._applyCloudsEnabled();\n        } else if (this._cloudLodState.disabled && altitude <= enableAltitude) {\n            this._cloudLodState.disabled = false;\n            this._beginSurfaceCloudActivation();\n            this._applyCloudsEnabled();\n        }\n    }\n\n    _syncAerialPerspectiveAtmosphereUniforms(bottomRadius, topRadius) {\n        const uniforms = this.aerialPerspective?.uniforms;\n        if (!uniforms) return;\n        const bottomUniform = uniforms.get('bottomRadius');\n        if (bottomUniform) bottomUniform.value = bottomRadius;\n        const uBottom = uniforms.get('u_bottom_radius');\n        if (uBottom) uBottom.value = bottomRadius * METER_TO_LENGTH_UNIT;\n        const uTop = uniforms.get('u_top_radius');\n        if (uTop) uTop.value = topRadius * METER_TO_LENGTH_UNIT;\n    }\n\n    _syncLightPollutionBloomEffect() {\n        this._syncSurfaceLightPollutionUniforms();\n        this._lightPollutionBloomEffect?.sync({\n            camera: this.camera,\n            worldToECEFMatrix: this._planetMatrixInverse,\n            sunDirectionECEF: this._sunDirection,\n            earthUniforms: this._earthMaterial?.uniforms,\n            planetRadius: PLANET_RADIUS,\n        });\n    }\n\n    _syncAtmosphereParameterStruct(target) {\n        const next = this._atmosphereParams?.toUniform?.().value;\n        if (!next || !target?.uniforms) return;\n        const uniform = target.uniforms.get?.('ATMOSPHERE')\n            ?? target.uniforms.ATMOSPHERE;\n        if (uniform) uniform.value = next;\n    }\n\n    _onCloudsChange(property) {\n        if (this._cloudAtmosphereAttachments) {\n            this._cloudAtmosphereAttachments.set(this._cloudAtmosphereAttachments.enabled, this.clouds);\n            return;\n        }\n        if (!this.aerialPerspective || !this.clouds) return;\n        switch (property) {\n            case 'atmosphereOverlay':\n                this.aerialPerspective.overlay = this.clouds.atmosphereOverlay;\n                break;\n            case 'atmosphereShadow':\n                this.aerialPerspective.shadow = this.clouds.atmosphereShadow;\n                break;\n            case 'atmosphereShadowLength':\n                this.aerialPerspective.shadowLength = this.clouds.atmosphereShadowLength;\n                break;\n        }\n    }\n\n    _applyToneMappingOverride() {\n        if (this._toneMappingOverridden) return;\n        const exposure = Number.isFinite(this._toneMappingExposureTarget)\n            ? this._toneMappingExposureTarget\n            : (Number.isFinite(this._toneMappingSnapshot.exposure)\n                ? this._toneMappingSnapshot.exposure\n                : DEFAULT_TONE_MAPPING_EXPOSURE);\n        this._toneMappingExposureTarget = exposure;\n        this._toneMappingSnapshot.toneMapping = this.renderer.toneMapping;\n        this._toneMappingSnapshot.exposure = exposure;\n        this.renderer.toneMapping = THREE.NoToneMapping;\n        this.renderer.toneMappingExposure = exposure;\n        this._toneMappingOverridden = true;\n    }\n\n    _restoreToneMapping() {\n        if (!this._toneMappingOverridden) return;\n        const exposure = Number.isFinite(this._toneMappingExposureTarget)\n            ? this._toneMappingExposureTarget\n            : (Number.isFinite(this._toneMappingSnapshot.exposure)\n                ? this._toneMappingSnapshot.exposure\n                : DEFAULT_TONE_MAPPING_EXPOSURE);\n        this._toneMappingExposureTarget = exposure;\n        this.renderer.toneMapping = this._toneMappingSnapshot.toneMapping;\n        this.renderer.toneMappingExposure = exposure;\n        this._toneMappingOverridden = false;\n    }\n\n    /**\n     * The final-frame owner shares one exposure value. The direct renderer\n     * applies it through AGX; the compositor temporarily selects NoToneMapping\n     * on the renderer and its final ToneMappingEffect consumes the same Three\n     * renderer exposure uniform. Keeping the saved direct value synchronized\n     * prevents a render-path transition from producing an exposure flash.\n     */\n    setToneMappingExposure(exposure) {\n        if (!Number.isFinite(exposure)) return;\n        const next = THREE.MathUtils.clamp(exposure, 0.05, 32);\n        this._toneMappingExposureTarget = next;\n        this._toneMappingSnapshot.exposure = next;\n        this.renderer.toneMappingExposure = next;\n    }\n\n    _syncToneMappingForRenderPath() {\n        // FRAME OWNERSHIP INVARIANT — DO NOT REMOVE OR \"SIMPLIFY\":\n        // EffectComposer includes its own ToneMappingEffect and therefore owns\n        // NoToneMapping only while it returns the final frame. Every cold,\n        // failed, or unsupported cloud path yields to SceneInitializer's direct\n        // renderer, which requires the saved AGX/exposure state. Leaving the\n        // composer override active on a yielded frame makes Earth, airglow,\n        // light pollution, and stars appear black. The regression test is\n        // tests/atmosphere-cloud-streaming.test.mjs.\n        if (!this.useToneMapping) return;\n        const composerOwnsFrame = this.enabled === true\n            && this.ready === true\n            && this.shouldUseLegacyFallback() !== true;\n        if (composerOwnsFrame) {\n            this._applyToneMappingOverride();\n        } else {\n            this._restoreToneMapping();\n        }\n    }\n\n    // Configuration methods\n    applyConfig(config = {}) {\n        if (!config || typeof config !== 'object') return;\n        const {\n            baseOffsetMeters,\n            surfaceBaseOffsetMeters,\n            adaptiveBaseOffset,\n            irradianceScale,\n            shadowRadius,\n            sunIrradiance,\n            skyIrradiance,\n            sunLight,\n            skyLight,\n            transmittance,\n            inscatter,\n            sky,\n            sun,\n            moon,\n            skyTuning,\n            clouds,\n            cloudLayers,\n            cloudTerrainClearance,\n            orbitClouds,\n            airglow,\n            aurora,\n            bloom,\n            lightPollution,\n            lightPollutionBloom,\n            fire,\n            smoke,\n            // Night-side visibility tuneables\n            nightMinIrradiance,\n            nightIrradianceSunDotMin,\n            nightIrradianceSunDotMax\n        } = config;\n\n        if (typeof sun === 'boolean') this._sunDiskEnabled = sun;\n        if (typeof moon === 'boolean') this._moonDiskEnabled = moon;\n        this._syncCelestialDiskOwnership();\n\n        if (adaptiveBaseOffset && typeof adaptiveBaseOffset === 'object') {\n            this.setAdaptiveBaseOffsetConfig(adaptiveBaseOffset);\n        }\n\n        const baseOffsetValue = Number(baseOffsetMeters);\n        const surfaceBaseOffsetValue = Number(surfaceBaseOffsetMeters);\n        const adaptiveOwnsOffsets = this._adaptiveBaseOffset?.enabled === true &&\n            Number.isFinite(this._regionalTerrainRadius);\n        if (!adaptiveOwnsOffsets && Number.isFinite(baseOffsetValue)) {\n            this.orbitAtmosphereBaseOffset = Math.max(0, baseOffsetValue);\n        }\n        if (!adaptiveOwnsOffsets && Number.isFinite(surfaceBaseOffsetValue)) {\n            this.surfaceAtmosphereBaseOffset = Math.max(0, surfaceBaseOffsetValue);\n        }\n        if (adaptiveOwnsOffsets) {\n            this.setRegionalTerrainRadius(this._regionalTerrainRadius, { force: true });\n        } else if (Number.isFinite(baseOffsetValue) || Number.isFinite(surfaceBaseOffsetValue)) {\n            this.setSurfaceCameraModeActive(this._surfaceCameraModeActive, {\n                force: !this._baseOffsetInitialized\n                    || (this._surfaceCameraModeActive\n                        ? Number.isFinite(surfaceBaseOffsetValue)\n                        : Number.isFinite(baseOffsetValue))\n            });\n        }\n\n        if (this.aerialPerspective) {\n            if (Number.isFinite(irradianceScale)) {\n                const nextScale = Math.max(0, irradianceScale);\n                this.aerialPerspective.albedoScale = nextScale;\n                this._irradianceScaleBase = nextScale;\n                this._currentIrradianceScale = nextScale;\n            }\n            if (Number.isFinite(shadowRadius)) {\n                this.aerialPerspective.shadowRadius = shadowRadius;\n            }\n            const nextSunLight = typeof sunLight === 'boolean' ? sunLight : sunIrradiance;\n            const nextSkyLight = typeof skyLight === 'boolean' ? skyLight : skyIrradiance;\n            if (typeof nextSunLight === 'boolean') {\n                this.aerialPerspective.sunLight = nextSunLight;\n                this._sunIrradianceBase = nextSunLight;\n            }\n            if (typeof nextSkyLight === 'boolean') {\n                this.aerialPerspective.skyLight = nextSkyLight;\n                this._skyIrradianceBase = nextSkyLight;\n            }\n            if (typeof transmittance === 'boolean') this.aerialPerspective.transmittance = transmittance;\n            if (typeof inscatter === 'boolean') this.aerialPerspective.inscatter = inscatter;\n            if (typeof sky === 'boolean') {\n                this.aerialPerspective.sky = sky;\n                // Also retire the standalone SkyMaterial fullscreen quad\n                // — it's the one painting the persistent purple→orange\n                // horizon haze independent of the post-process pass.\n                this.setSkyEnabled(sky);\n            }\n        }\n\n        this._applySkyTuningConfig(skyTuning);\n\n        if (clouds && typeof clouds === 'object') {\n            if (typeof clouds.qualityPreset === 'string') {\n                this.setCloudQualityPreset(clouds.qualityPreset);\n            }\n            if (clouds.shadow && typeof clouds.shadow === 'object') {\n                this._applyCloudShadowTuning(clouds.shadow);\n            }\n        }\n\n        if (clouds && typeof clouds === 'object' && typeof clouds.enabled === 'boolean') {\n            this.setCloudsEnabled(clouds.enabled);\n        }\n\n        if (this.clouds && clouds && typeof clouds === 'object') {\n            this._applyCloudSettings(clouds);\n        }\n\n        if (this.clouds && cloudLayers && typeof cloudLayers === 'object') {\n            this._applyCloudLayerSettings(cloudLayers);\n        }\n\n        if (Number.isFinite(cloudTerrainClearance)) {\n            this.setCloudTerrainClearance(cloudTerrainClearance);\n        }\n\n        if (orbitClouds && typeof orbitClouds === 'object') {\n            this._applyOrbitCloudsConfig(orbitClouds);\n        }\n\n        if (airglow && typeof airglow === 'object') {\n            this._applyAirglowConfig(airglow);\n        }\n\n        if (aurora && typeof aurora === 'object') {\n            this._applyAuroraConfig(aurora);\n        }\n\n        if (fire && typeof fire === 'object') {\n            this._applyFireConfig(fire);\n        }\n        if (smoke && typeof smoke === 'object') {\n            this._applySmokeConfig(smoke);\n        }\n\n        if (bloom && typeof bloom === 'object') {\n            this._applyBloomConfig(bloom);\n        }\n        const dedicatedLightBloom = lightPollutionBloom ?? lightPollution?.bloom;\n        if (dedicatedLightBloom && typeof dedicatedLightBloom === 'object') {\n            this._applyLightPollutionBloomConfig(dedicatedLightBloom);\n        }\n\n        // Night-side visibility tuneables\n        if (Number.isFinite(nightMinIrradiance)) {\n            this._nightMinIrradiance = Math.max(0, Math.min(1, nightMinIrradiance));\n        }\n        if (Number.isFinite(nightIrradianceSunDotMin)) {\n            this._nightIrradianceSunDotMin = Math.max(-1, Math.min(1, nightIrradianceSunDotMin));\n        }\n        if (Number.isFinite(nightIrradianceSunDotMax)) {\n            this._nightIrradianceSunDotMax = Math.max(-1, Math.min(1, nightIrradianceSunDotMax));\n        }\n    }\n\n    getConfig() {\n        const aerial = this.aerialPerspective;\n        const clouds = this.clouds;\n\n        // Return terrain-relative altitudes (user-facing values)\n        const getLayerConfig = (i) => {\n            const config = this._cloudLayerHeightsAboveTerrain[i];\n            return config ? { altitude: config.altitude, height: config.height } : null;\n        };\n\n        return {\n            baseOffsetMeters: this.orbitAtmosphereBaseOffset,\n            surfaceBaseOffsetMeters: this.surfaceAtmosphereBaseOffset,\n            effectiveBaseOffsetMeters: this.atmosphereBaseOffset,\n            adaptiveBaseOffset: { ...this._adaptiveBaseOffset },\n            regionalTerrainRadius: this._regionalTerrainRadius,\n            irradianceScale: Number.isFinite(this._irradianceScaleBase)\n                ? this._irradianceScaleBase\n                : (aerial?.albedoScale ?? PHOTOREAL_ALBEDO_SCALE_DEFAULT),\n            shadowRadius: aerial?.shadowRadius ?? 3,\n            sunIrradiance: typeof this._sunIrradianceBase === 'boolean'\n                ? this._sunIrradianceBase\n                : (aerial?.sunLight ?? true),\n            skyIrradiance: typeof this._skyIrradianceBase === 'boolean'\n                ? this._skyIrradianceBase\n                : (aerial?.skyLight ?? true),\n            transmittance: aerial?.transmittance ?? true,\n            inscatter: aerial?.inscatter ?? true,\n            sky: aerial?.sky ?? true,\n            sun: this._sunDiskEnabled,\n            moon: this._moonDiskEnabled,\n            skyTuning: { ...this._skyTuning },\n            clouds: {\n                enabled: this._cloudsEnabled,\n                qualityPreset: this._cloudQualityPreset,\n                coverage: clouds?.coverage ?? 0.4,\n                scatteringCoefficient: clouds?.scatteringCoefficient ?? 1,\n                absorptionCoefficient: clouds?.absorptionCoefficient ?? 0,\n                turbulenceDisplacement: clouds?.turbulenceDisplacement ?? 350,\n                lightShafts: clouds?.lightShafts ?? true,\n                shapeDetail: clouds?.shapeDetail ?? true,\n                turbulence: clouds?.turbulence ?? true,\n                haze: clouds?.haze ?? true,\n                shadow: { ...this._cloudShadowTuning }\n            },\n            // Cloud layer altitudes are heights ABOVE LOCAL TERRAIN (0 = terrain surface)\n            cloudLayers: {\n                low: getLayerConfig(0) ?? { altitude: 1500, height: 1000 },\n                mid: getLayerConfig(1) ?? { altitude: 3000, height: 2000 },\n                high: getLayerConfig(2) ?? { altitude: 8000, height: 2000 }\n            },\n            cloudTerrainClearance: this._cloudTerrainClearance,\n            orbitClouds: { ...this._orbitClouds },\n            bloom: {\n                enabled: this._bloomEnabled,\n                intensity: this._bloomSettings?.intensity ?? 0,\n                threshold: this._bloomSettings?.luminanceThreshold ?? 1,\n                smoothing: this._bloomSettings?.luminanceSmoothing ?? 0,\n                radius: this._bloomSettings?.radius ?? 0,\n                levels: this._bloomSettings?.levels ?? 5,\n                mipmapBlur: !!this._bloomSettings?.mipmapBlur\n            },\n            lightPollutionBloom: {\n                ...this._lightPollutionBloomSettings,\n            },\n            airglow: {\n                enabled: this._airglowEnabled !== false,\n                strength: this._airglowStrength,\n                dayStrength: this._airglowDayStrength,\n                baseAltitudeMeters: this._airglowBaseAlt,\n                coreAltitudeMeters: this._airglowCoreAlt,\n                fringeAltitudeMeters: this._airglowFringeAlt,\n                riseScaleMeters: this._airglowRiseScale,\n                tailScaleMeters: this._airglowTailScale,\n                pathRefMeters: this._airglowPathRef,\n                insideMin: this._airglowInsideMin,\n                insideMax: this._airglowInsideMax,\n                grazingPower: this._airglowGrazingPower\n            },\n            aurora: {\n                enabled: this._auroraEnabled !== false,\n                strength: this._auroraStrength,\n                topAltitudeMeters: this._auroraTopAltitudeMeters,\n                pathRefMeters: this._auroraPathRefMeters,\n                depthBiasMeters: this._auroraDepthBiasMeters\n            },\n            fire: {\n                enabled: this._fireEnabled !== false,\n                strength: this._fireStrength,\n                topAltitudeMeters: this._fireTopAltitudeMeters,\n                pathRefMeters: this._firePathRefMeters,\n                depthBiasMeters: this._fireDepthBiasMeters\n            },\n            smoke: {\n                enabled: this._smokeEnabled === true,\n                strength: this._smokeStrength,\n                topAltitudeMeters: this._smokeTopAltitudeMeters,\n                depthBiasMeters: this._smokeDepthBiasMeters\n            },\n            // Night-side visibility tuneables\n            nightMinIrradiance: this._nightMinIrradiance,\n            nightIrradianceSunDotMin: this._nightIrradianceSunDotMin,\n            nightIrradianceSunDotMax: this._nightIrradianceSunDotMax\n        };\n    }\n\n    _scheduleIdleTask(callback, timeout = CLOUD_WARMUP_IDLE_TIMEOUT_MS) {\n        if (typeof window !== 'undefined' && typeof window.requestIdleCallback === 'function') {\n            return {\n                // The timeout is REQUIRED, not a convenience. Warm-up is a long\n                // chain of sequential idle slices (leaf pass init, per-texture\n                // and per-render-target uploads, per-variant compiles). An\n                // untimed requestIdleCallback never fires while photoreal tile\n                // streaming saturates the main thread, so each hop stalled and\n                // clouds took minutes to appear instead of seconds. Each slice\n                // is a single bounded GPU operation, so running one on a busy\n                // frame costs far less than starving the whole pipeline.\n                handle: window.requestIdleCallback(callback, { timeout }),\n                usesRequestIdleCallback: true\n            };\n        }\n        return {\n            handle: setTimeout(callback, Math.min(timeout, 32)),\n            usesRequestIdleCallback: false\n        };\n    }\n\n    _supportsAsyncCloudCompilation() {\n        // Explicit cloud choices use the same one-resource/one-leaf idle\n        // admission on every WebGL 2 browser. KHR improves driver scheduling;\n        // it is not a capability requirement for Three's compileAsync API.\n        // Validate each link before admission and retain the physical clear\n        // frame on failure. Never substitute synchronous whole-scene compile.\n        return globalThis.__noclipDisableVolumetricCloudWarmup !== true\n            && typeof this.renderer?.compileAsync === 'function';\n    }\n\n    _cancelIdleTask(handleKey, idleFlagKey) {\n        const handle = this[handleKey];\n        if (handle === null || handle === undefined) return;\n        if (this[idleFlagKey] && typeof window !== 'undefined' && typeof window.cancelIdleCallback === 'function') {\n            window.cancelIdleCallback(handle);\n        } else {\n            clearTimeout(handle);\n        }\n        this[handleKey] = null;\n        this[idleFlagKey] = false;\n    }\n\n    _cloudEffectTexture(value) {\n        if (value?.isTexture) return value;\n        if (value?.texture?.isTexture) return value.texture;\n        return null;\n    }\n\n    _cloudEffectTextures(effect) {\n        if (!effect) return [];\n        const textures = [\n            effect.localWeatherTexture,\n            effect.shapeTexture,\n            effect.shapeDetailTexture,\n            effect.turbulenceTexture,\n            effect.stbnTexture,\n            effect.irradianceTexture,\n            effect.scatteringTexture,\n            effect.transmittanceTexture\n        ];\n        return [...new Set(textures.map((value) => this._cloudEffectTexture(value)).filter(Boolean))];\n    }\n\n    _warmCloudTexture(texture) {\n        if (!texture || typeof this.renderer?.initTexture !== 'function') return;\n        this.renderer.initTexture(texture);\n    }\n\n    _cloudEffectRenderTargets(effect) {\n        if (!effect) return [];\n        const passes = [effect.shadowPass, effect.cloudsPass];\n        return passes.flatMap((pass) => [\n            pass?.currentRenderTarget,\n            pass?.resolveRenderTarget,\n            pass?.historyRenderTarget\n        ]).filter(Boolean);\n    }\n\n    _warmCloudRenderTarget(target) {\n        if (!target || typeof this.renderer?.initRenderTarget !== 'function') return;\n        this.renderer.initRenderTarget(target);\n    }\n\n    setPresentationSuspended(suspended) {\n        if (suspended) {\n            this._waterReflectionPass?.resetBindings();\n        }\n        if (suspended && !this._presentationResumePromise) {\n            this._presentationResumePromise = new Promise(resolve => { this._presentationResume = resolve; });\n        } else if (!suspended) {\n            this._presentationResume?.();\n            this._presentationResume = this._presentationResumePromise = null;\n        }\n    }\n\n    _runCloudWarmupIdleTask(task, { waitForTask = true } = {}) {\n        return new Promise((resolve) => {\n            const run = async () => {\n                // Do not let late cloud decoding/warm-up refill parked GPU\n                // textures beneath the full-screen map. Disposal unblocks this\n                // waiter too, then the ordinary disposed guard owns cleanup.\n                while (this._presentationResumePromise && !this._disposed) await this._presentationResumePromise;\n                if (this._disposed) {\n                    resolve();\n                    return;\n                }\n                try {\n                    const result = task();\n                    if (waitForTask) {\n                        await result;\n                    } else {\n                        Promise.resolve(result).catch((error) => {\n                            console.warn('[AtmosphereClouds] Idle cloud compile failed', error);\n                        });\n                    }\n                } catch (error) {\n                    // Individual GPU warm-up tasks are isolated so one bad\n                    // optional asset cannot strand the full atmosphere pass.\n                    console.warn('[AtmosphereClouds] Idle cloud warm-up task failed', error);\n                }\n                resolve();\n            };\n            this._scheduleIdleTask(run);\n        });\n    }\n\n    async _warmCloudResourcesInIdleSlices(effects) {\n        const effectList = (Array.isArray(effects) ? effects : [effects]).filter(Boolean);\n        for (const effect of effectList) {\n            if (this._disposed) return;\n            await this._runCloudWarmupIdleTask(() => {\n                // Prime the same profile used by the first visible update.\n                // Warming a dormant/activation size only moves its replacement\n                // allocations onto that first frame instead of eliminating them.\n                if (effect === this.clouds) this._primeCloudResolutionForCamera();\n                // CloudsEffect.setSize only sizes radiance targets. Its native\n                // update normally sizes shadow arrays on the first visible\n                // frame, which would throw away our 1x1 warm-up allocations\n                // and change cascade shader defines after compilation. Use\n                // those same pass sizing methods before warming/compiling.\n                this.renderer.getDrawingBufferSize(this._tmpSize);\n                effect.setSize(this._tmpSize.x, this._tmpSize.y);\n                const { mapSize, cascadeCount } = effect.shadow;\n                effect.shadowPass.setSize(mapSize.x, mapSize.y, cascadeCount);\n                effect.cloudsPass.setShadowSize(mapSize.x, mapSize.y, cascadeCount);\n                // compileAsync does not invoke material.onBeforeRender.\n                // Prime the native perspective/depth/powder/ground variants\n                // here so first presentation uses the program we validated.\n                const material = effect.cloudsPass.currentMaterial;\n                material.copyCameraSettings?.(this.camera);\n                if (this.renderer.capabilities) {\n                    material.onBeforeRender?.(this.renderer);\n                }\n            });\n        }\n        const textures = [...new Set(effectList.flatMap((effect) => this._cloudEffectTextures(effect)))];\n        // A 2D LUT or temporal target can also be large. Keep every unique GPU\n        // initialization in its own real task; the scheduler's finite timeout\n        // still guarantees progress when tile streaming leaves no idle time.\n        for (const texture of textures) {\n            if (this._disposed) return;\n            await this._runCloudWarmupIdleTask(() => this._warmCloudTexture(texture));\n        }\n\n        const targets = [...new Set(effectList.flatMap((effect) => this._cloudEffectRenderTargets(effect)))];\n        for (const target of targets) {\n            if (this._disposed) return;\n            await this._runCloudWarmupIdleTask(() => this._warmCloudRenderTarget(target));\n        }\n    }\n\n    async _compileCloudScenesInIdleSlices(jobs) {\n        const completions = [];\n        for (const [scene, camera, target = this.composer?.inputBuffer ?? null] of jobs) {\n            await this._runCloudWarmupIdleTask(() => {\n                // Observe rejection immediately, while later requests are\n                // still admitted in separate tasks. Hold all actual native\n                // completions before reporting success or failure.\n                completions.push(Promise.resolve(this._compileCloudScene(scene, camera, target)).then(\n                    (value) => value === false\n                        ? { ok: false, error: new Error('Asynchronous cloud compilation is unavailable') }\n                        : { ok: true },\n                    (error) => ({ ok: false, error }),\n                ));\n            }, { waitForTask: false });\n        }\n        const results = await Promise.all(completions);\n        const failed = results.find((result) => !result.ok);\n        if (failed) throw failed.error;\n    }\n\n    _cloudEffectCompileJobs(effect) {\n        if (!effect) return [];\n        const passes = [effect.shadowPass, effect.cloudsPass];\n        const jobs = [];\n        for (const pass of passes) {\n            jobs.push([pass?.currentPass?.scene, pass?.currentPass?.camera]);\n            jobs.push([pass?.resolvePass?.scene, pass?.resolvePass?.camera]);\n        }\n        return jobs;\n    }\n\n    async _compileCloudScene(scene, camera, target = this.composer?.inputBuffer ?? null) {\n        if (!scene || !camera || !this.renderer) return Promise.resolve();\n        try {\n            // Never fall through to renderer.compile(). It is synchronous and\n            // can monopolize RAF for seconds on volumetric shader variants.\n            if (typeof this.renderer.compileAsync !== 'function') return Promise.resolve(false);\n            const renderer = this.renderer;\n            const previousTarget = renderer.getRenderTarget?.() ?? null;\n            const previousFace = renderer.getActiveCubeFace?.() ?? 0;\n            const previousMip = renderer.getActiveMipmapLevel?.() ?? 0;\n            const previousToneMapping = renderer.toneMapping;\n            let completion;\n            try {\n                // r185 includes the render target's output colour space in its\n                // program key. Idle normally runs with the screen bound: that\n                // warmed sRGB while the first HDR draw compiled again on RAF.\n                // Bind only during the synchronous compile submission; never\n                // leave renderer state changed while awaiting native completion.\n                renderer.setRenderTarget?.(target);\n                if (target) renderer.toneMapping = THREE.NoToneMapping;\n                completion = renderer.compileAsync(scene, camera);\n            } finally {\n                renderer.toneMapping = previousToneMapping;\n                renderer.setRenderTarget?.(previousTarget, previousFace, previousMip);\n            }\n            const result = await completion;\n            if (!this._disposed) validateCompiledScenePrograms(this.renderer, scene);\n            return result;\n        } catch (error) {\n            return Promise.reject(error);\n        }\n    }\n\n    async _initializeCloudEffectsInIdleSlices(effects) {\n        this._initializedCloudEffects ||= new WeakSet();\n        const context = this.renderer?.getContext?.();\n        const alpha = context?.getContextAttributes?.()?.alpha ?? false;\n        for (const effect of effects.filter(Boolean)) {\n            if (this._initializedCloudEffects.has(effect)) continue;\n            // CloudsEffect.initialize() initializes both temporal halves of\n            // both the shadow and radiance pipelines in one call. Invoke the\n            // exact same leaf initializers separately so a driver allocation\n            // cannot accumulate four resources in one main-thread task.\n            const leafPasses = [\n                effect.shadowPass?.currentPass,\n                effect.shadowPass?.resolvePass,\n                effect.cloudsPass?.currentPass,\n                effect.cloudsPass?.resolvePass\n            ].filter(Boolean);\n            if (leafPasses.length === 0) {\n                await this._runCloudWarmupIdleTask(() => {\n                    effect.initialize?.(this.renderer, alpha, THREE.HalfFloatType);\n                });\n                this._initializedCloudEffects.add(effect);\n                continue;\n            }\n            for (const pass of leafPasses) {\n                await this._runCloudWarmupIdleTask(() => {\n                    pass.initialize?.(this.renderer, alpha, THREE.HalfFloatType);\n                });\n            }\n            this._initializedCloudEffects.add(effect);\n        }\n        this._cloudEffectsInitialized = true;\n    }\n\n    _detachCloudShaderChangeListeners(pass) {\n        // These compound materials are deliberately immutable. Cloud LOD and\n        // weather updates use uniforms/render-target state; allowing a cloud\n        // define change to reach EffectPass.handleEvent would call recompile()\n        // in whichever task happened to update the camera. New structural\n        // variants must instead be built by _ensureCloudEffectPassVariant().\n        for (const effect of [this.clouds, this._orbitCloudsEffect]) {\n            effect?.removeEventListener?.('change', pass.listener);\n        }\n    }\n\n    _ensureCloudEffectPassVariant(signature, effects) {\n        const existing = this._cloudEffectPassVariants.get(signature);\n        if (existing) return Promise.resolve(existing);\n        const pending = this._cloudEffectPassBuilds.get(signature);\n        if (pending) return pending;\n        if (this._disposed || !this._supportsAsyncCloudCompilation()) return Promise.resolve(null);\n\n        const build = (async () => {\n            let pass = null;\n            await this._runCloudWarmupIdleTask(() => {\n                pass = new EffectPass(this.camera, ...effects.filter(effect => effect !== this.aerialPerspective));\n                pass.renderer = this.renderer;\n                this.renderer.getDrawingBufferSize(this._tmpSize);\n                pass.setSize(this._tmpSize.x, this._tmpSize.y);\n                const depthTexture = (this._aerialEffectPass || this._cloudEffectPassVariants\n                    .get('clear:clear'))?.getDepthTexture?.();\n                if (depthTexture) pass.setDepthTexture(depthTexture);\n                pass.fullscreenMaterial.defines.FRAMEBUFFER_PRECISION_HIGH = '1';\n                pass.fullscreenMaterial.adoptCameraSettings(this.camera);\n                pass.recompile();\n                this._detachCloudShaderChangeListeners(pass);\n            });\n            if (!pass || this._disposed) {\n                pass?.setEffects?.([]);\n                pass?.fullscreenMaterial?.dispose?.();\n                return null;\n            }\n            try {\n                await this._compileCloudScenesInIdleSlices([[pass.scene, pass.camera]]);\n            } catch (error) {\n                // Detached candidates share native effects with the live\n                // compositor; retire only their own failed material.\n                pass.setEffects([]);\n                pass.fullscreenMaterial?.dispose?.();\n                throw error;\n            }\n            if (this._disposed) {\n                pass.setEffects([]);\n                pass.fullscreenMaterial?.dispose?.();\n                return null;\n            }\n            this._cloudEffectPassVariants.set(signature, pass);\n            return pass;\n        })().finally(() => {\n            this._cloudEffectPassBuilds.delete(signature);\n        });\n        this._cloudEffectPassBuilds.set(signature, build);\n        return build;\n    }\n\n    _hasConfiguredVolumetricClouds() {\n        // Configuration, not instantaneous altitude/visibility, owns cold\n        // admission. Once requested, keep the full prewarmed temporal family\n        // through ordinary culling and rapid toggles; never cycle its storage.\n        return this.renderer?.xr?.isPresenting !== true && this._cloudWarmupDeferred !== true && !!(this._cloudsEnabled\n            || (this._orbitClouds?.enabled && this._orbitClouds?.volumetricEnabled));\n    }\n\n    _warmDirectPhysicalSky() {\n        if (this._directPhysicalSkyPrepared) return Promise.resolve(true);\n        if (this._directPhysicalSkyPromise) return this._directPhysicalSkyPromise;\n        if (!this.skyMaterial?.scatteringTexture || !this.skyMesh || !this.renderer) return Promise.resolve(false);\n        this._directPhysicalSkyPromise = (async () => {\n            // The direct output wrapper uses the SAME Bruneton LUTs and Earth\n            // frame. This prepares only a sky quad, never cloud targets or the\n            // live photoreal tree; output conversion belongs to its material.\n            this._nativeXRSkyMaterial ||= new NativeXRSkyMaterial(this.skyMaterial);\n            const skyScene = new THREE.Scene();\n            const carrier = new THREE.Mesh(this.skyMesh.geometry, this._nativeXRSkyMaterial);\n            carrier.frustumCulled = false; skyScene.add(carrier);\n            try {\n                for (const texture of new Set(this._cloudEffectTextures(this.skyMaterial))) {\n                    if (this._disposed) return false;\n                    await this._runCloudWarmupIdleTask(() => this._warmCloudTexture(texture));\n                }\n                if (this._disposed) return false;\n                await this._compileCloudScenesInIdleSlices([[skyScene, this.camera, null]]);\n                if (this._disposed) return false;\n                this._directPhysicalSkyPrepared = true;\n                return true;\n            } finally { skyScene.clear(); }\n        })().finally(() => { this._directPhysicalSkyPromise = null; });\n        return this._directPhysicalSkyPromise;\n    }\n\n    async _warmClearAtmosphereInIdleSlices() {\n        const textures = [...new Set([\n            ...this._cloudEffectTextures(this.aerialPerspective),\n            ...this._cloudEffectTextures(this.skyMaterial),\n        ])];\n        for (const texture of textures) {\n            if (this._disposed) return;\n            await this._runCloudWarmupIdleTask(() => this._warmCloudTexture(texture));\n        }\n        if (this._disposed) return;\n        // Compile only the clear compositor and one shared-material sky quad,\n        // never the entire live terrain scene. No cloud target or noise upload\n        // is needed to make the atmospheric sky/lighting ready.\n        const clear = this._aerialEffectPass || this._cloudEffectPassVariants.get('clear:clear');\n        const skyScene = new THREE.Scene();\n        if (this.skyMesh) skyScene.add(new THREE.Mesh(this.skyMesh.geometry, this.skyMaterial));\n        await this._compileCloudScenesInIdleSlices([\n            [clear?.scene, clear?.camera],\n            [skyScene, this.camera],\n        ]);\n        skyScene.clear();\n        if (!this._disposed) this._clearAtmospherePrepared = true;\n    }\n\n    async _warmCloudPipeline() {\n        if (!this.renderer || !this.camera || !this.clouds || !this.aerialPerspective) return;\n\n        // Mobile/user configuration can disable both effects while retaining\n        // atmospheric sky and physical lighting. Do not initialize two unused\n        // GPU target families merely because their input downloads completed.\n        // A subsequent explicit enable reuses this scheduler to prepare every\n        // original cloud resource before allowing cloud presentation.\n        if (!this._hasConfiguredVolumetricClouds()) {\n            if (!this._patchSkyDepthRule()) {\n                throw new Error('Atmosphere SKY shader signature is incompatible with the required orbital frame blend');\n            }\n            await this._warmClearAtmosphereInIdleSlices();\n            return false;\n        }\n\n        // Patch both the local and orbital CloudEffects before any compound\n        // material is compiled. Applying this after warm-up would force an\n        // unbounded shader recompile on the first frame inside a cloud layer.\n        if (!this._patchCloudsCameraHeight()\n            || !this._patchCloudsNightLighting()) {\n            throw new Error('Cloud camera-height shader signature is incompatible with continuous layer traversal');\n        }\n\n        // Compile only the patched composite. Takram upgrades have changed the\n        // SKY function signature before; compiling the default assignment can\n        // silently erase Earth and the inertial background at orbital range.\n        if (!this._patchSkyDepthRule()) {\n            throw new Error('Atmosphere SKY shader signature is incompatible with the required orbital frame blend');\n        }\n\n        // Validate a usable clear frame before preparing optional clouds.\n        // An optional link failure must not retire the already-working sky.\n        await this._warmClearAtmosphereInIdleSlices();\n\n        // The optional orbital volumetric family has its own full-resolution\n        // temporal storage. Ordinary surface clouds must not allocate a second\n        // unused family. Prepare it once on explicit volumetric opt-in, then\n        // retain that exact native family through every later toggle.\n        if (this.renderer?.xr?.isPresenting === true) return false;\n        const orbit = this._orbitClouds?.enabled && this._orbitClouds?.volumetricEnabled\n            ? this._orbitCloudsEffect : null;\n        await this._runCloudWarmupIdleTask(() => {\n            // Retain the original full-resolution density sources. The old\n            // 32-cubed warm-up substitute was never restored, so it silently\n            // became permanent visible cloud quality. Uploads already have\n            // one-resource idle admission below; no resampling is required.\n            // SKIP_RENDERING is a shader define. Set it exactly once before any\n            // cloud compound material exists; runtime visibility is expressed\n            // by selecting a precompiled pass, never by changing this define.\n            this.clouds.skipRendering = true;\n            if (orbit) orbit.skipRendering = true;\n        });\n        await this._initializeCloudEffectsInIdleSlices([this.clouds, orbit]);\n        if (this.renderer?.xr?.isPresenting === true) return false;\n\n        // Do exactly one GPU allocation/upload/compile request per idle slice.\n        // A continuous camera animation therefore never receives a multi-\n        // resource cloud initialization on a render frame.\n        await this._warmCloudResourcesInIdleSlices([this.clouds, orbit]);\n        await this._compileCloudScenesInIdleSlices([\n            ...this._cloudEffectCompileJobs(this.clouds),\n            ...this._cloudEffectCompileJobs(orbit),\n            ...(this._cloudColorPass ? [[this._cloudColorPass.scene,this._cloudColorPass.camera]] : [])\n        ]);\n\n        // Build every visibility combination before declaring clouds ready.\n        // The animation loop will only exchange one already-compiled pass\n        // reference as altitude/weather changes.\n        await this._ensureCloudEffectPassVariant(\n            'clouds:clear',\n            [this.clouds, this.aerialPerspective]\n        );\n        this._surfaceCloudPipelinePrepared = true;\n        if (orbit) {\n            await this._ensureCloudEffectPassVariant(\n                'clear:orbit',\n                [orbit, this.aerialPerspective]\n            );\n            await this._ensureCloudEffectPassVariant(\n                'clouds:orbit',\n                [this.clouds, orbit, this.aerialPerspective]\n            );\n            this._orbitCloudPipelinePrepared = true;\n        }\n    }\n\n    _scheduleCloudWarmup() {\n        if (this._cloudWarmupError) return Promise.resolve(false);\n        if (this._cloudWarmupState === 'ready') {\n            if (!(this._orbitClouds?.enabled && this._orbitClouds?.volumetricEnabled)\n                || this._orbitCloudPipelinePrepared) return Promise.resolve(true);\n            this._cloudWarmupState = 'clear-ready';\n        }\n        if (this._cloudWarmupState === 'clear-ready'\n            && (!this._hasConfiguredVolumetricClouds() || !this._supportsAsyncCloudCompilation())) return Promise.resolve(true);\n        if (this._cloudWarmupState === 'fallback') return Promise.resolve(false);\n        if (this._cloudWarmupPromise) return this._cloudWarmupPromise;\n        if (!this.ready || this._disposed || !this.clouds || !this.aerialPerspective) return Promise.resolve(false);\n\n        if (!this._supportsAsyncCloudCompilation()) {\n            // Do not trade all interaction responsiveness for a cloud effect\n            // on renderers that can only compile synchronously. The already\n            // constructed clear aerial/irradiance pass still owns physical\n            // day/night lighting and emitted NASA night lights; only optional\n            // volumetric cloud variants remain unavailable. Treating this as\n            // a whole-compositor fallback left mobile provider imagery as\n            // bright, unlit albedo through the astronomical night hemisphere.\n            this._cloudWarmupState = 'clear-ready';\n            this._syncToneMappingForRenderPath();\n            this._applySkyMeshVisibility();\n            this._applyCloudsEnabled();\n            return Promise.resolve(true);\n        }\n\n        const keepClearReady = this._cloudWarmupState === 'clear-ready';\n        if (!keepClearReady) this._cloudWarmupState = 'scheduled';\n        this._cloudWarmupPromise = new Promise((resolve) => {\n            const release = () => {\n                if (this._cloudWarmupResolve === finish) {\n                    this._cloudWarmupResolve = null;\n                    this._cloudWarmupPromise = null;\n                }\n            };\n            const finish = (result) => {\n                release();\n                resolve(result);\n            };\n            this._cloudWarmupResolve = finish;\n            const runWarmup = async () => {\n                this._cloudWarmupIdleHandle = null;\n                this._cloudWarmupIdleUsesRequestIdleCallback = false;\n                if (this._disposed) {\n                    this._cloudWarmupState = 'cold';\n                    finish(false);\n                    return;\n                }\n                if (!keepClearReady) this._cloudWarmupState = 'warming';\n                try {\n                    const cloudResourcesPrepared = await this._warmCloudPipeline();\n                    if (this._disposed) {\n                        this._cloudWarmupState = 'cold';\n                        finish(false);\n                        return;\n                    }\n                    this._cloudWarmupState = cloudResourcesPrepared === false ? 'clear-ready' : 'ready';\n                    release();\n                    this._syncToneMappingForRenderPath();\n                    this._applySkyMeshVisibility();\n                    this._applyCloudsEnabled();\n                    this._queueOrbitCloudVisibility(this._pendingOrbitCloudRenderEnabled);\n                    finish(true);\n                } catch (error) {\n                    if (this._disposed) {\n                        this._cloudWarmupState = 'cold';\n                        finish(false);\n                        return;\n                    }\n                    console.warn('[AtmosphereClouds] Idle cloud warm-up failed', error);\n                    this._retainClearFrameAfterCloudFailure(error);\n                    finish(false);\n                }\n            };\n            const scheduled = this._scheduleIdleTask(runWarmup);\n            this._cloudWarmupIdleHandle = scheduled.handle;\n            this._cloudWarmupIdleUsesRequestIdleCallback = scheduled.usesRequestIdleCallback;\n        });\n        return this._cloudWarmupPromise;\n    }\n\n    _queueOrbitCloudVisibility(canRender) {\n        if (typeof canRender !== 'boolean' || !this._orbitCloudsEffect) return;\n        if (canRender === this._orbitCloudRenderEnabled\n            && this._pendingOrbitCloudRenderEnabled === null) return;\n        if (this._pendingOrbitCloudRenderEnabled === canRender\n            && (this._orbitCloudVisibilityIdleHandle !== null\n                || (canRender && this._cloudWarmupState !== 'ready'))) return;\n        this._pendingOrbitCloudRenderEnabled = canRender;\n        if (this._orbitCloudVisibilityIdleHandle !== null) return;\n        const apply = () => {\n            this._orbitCloudVisibilityIdleHandle = null;\n            this._orbitCloudVisibilityIdleUsesRequestIdleCallback = false;\n            if (this._disposed || !this._orbitCloudsEffect) return;\n            const next = this._pendingOrbitCloudRenderEnabled;\n            if (typeof next !== 'boolean') return;\n            if (next && this._cloudWarmupState !== 'ready') {\n                void this._scheduleCloudWarmup();\n                return;\n            }\n            this._pendingOrbitCloudRenderEnabled = null;\n            if (this._orbitCloudRenderEnabled === next) return;\n            this._orbitCloudRenderEnabled = next;\n            this._applyCloudsEnabled();\n        };\n        const scheduled = this._scheduleIdleTask(apply);\n        this._orbitCloudVisibilityIdleHandle = scheduled.handle;\n        this._orbitCloudVisibilityIdleUsesRequestIdleCallback = scheduled.usesRequestIdleCallback;\n    }\n\n    _activateCloudEffectPassVariant(signature) {\n        const nextPass = this._cloudEffectPassVariants.get(signature);\n        if (!nextPass || !this.composer) return false;\n        nextPass.enabled = signature !== 'clear:clear';\n        if (this._cloudsEffectPass === nextPass) {\n            this._cloudsEffectSignature = signature;\n            return true;\n        }\n        const index = this.composer.passes.indexOf(this._cloudsEffectPass);\n        if (index < 0) return false;\n        const renderToScreen = this._cloudsEffectPass?.renderToScreen === true;\n        if (this._cloudsEffectPass) this._cloudsEffectPass.renderToScreen = false;\n        nextPass.renderToScreen = renderToScreen;\n        this.composer.passes[index] = nextPass;\n        this._cloudsEffectPass = nextPass;\n        this._cloudsEffectSignature = signature;\n        return true;\n    }\n\n    _applyCloudsEnabled() {\n        if (!this._cloudsEffectPass || !this.aerialPerspective) return;\n        const cloudsRequested = this._cloudsEnabled\n            && !this._cloudComposerHighOrbitActive\n            && !this._cloudLodState.disabled;\n        const orbitRequested = !!this._orbitCloudsEffect\n            && !!this._orbitClouds.enabled\n            && !!this._orbitClouds.volumetricEnabled\n            && !this._cloudComposerHighOrbitActive\n            && !this._orbitCloudsLodState.disabled;\n        const warmed = this._cloudWarmupState === 'ready';\n        const surfaceWarmed = warmed || this._surfaceCloudPipelinePrepared === true;\n        const orbitWarmed = warmed && this._orbitCloudPipelinePrepared;\n        if ((cloudsRequested && !surfaceWarmed || orbitRequested && !orbitWarmed) && this._cloudWarmupState !== 'fallback') {\n            void this._scheduleCloudWarmup();\n        }\n\n        const cloudsActive = cloudsRequested && surfaceWarmed && !!this.clouds;\n        const orbitActive = orbitRequested && orbitWarmed && this._orbitCloudRenderEnabled;\n        if (cloudsActive) {\n            this._syncCloudAtmosphereAttachments();\n        } else {\n            this._clearCloudAtmosphereAttachments();\n        }\n\n        const signature = `${cloudsActive ? 'clouds' : 'clear'}:${orbitActive ? 'orbit' : 'clear'}`;\n        if (signature === this._cloudsEffectSignature) return;\n        if (this._activateCloudEffectPassVariant(signature)) return;\n\n        // Never compile or allocate from this camera/update call. It is valid\n        // for the previous pass (normally clear aerial perspective) to remain\n        // active until an optional variant has finished in background slices.\n        const effects = [];\n        if (cloudsActive) effects.push(this.clouds);\n        if (orbitActive) effects.push(this._orbitCloudsEffect);\n        effects.push(this.aerialPerspective);\n        void this._ensureCloudEffectPassVariant(signature, effects)\n            .then((pass) => {\n                if (pass && !this._disposed) this._applyCloudsEnabled();\n            })\n            .catch((error) => {\n                if (this._disposed) return;\n                console.warn('[AtmosphereClouds] Cloud variant preparation failed', error);\n                this._retainClearFrameAfterCloudFailure(error);\n            });\n    }\n\n    _retainClearFrameAfterCloudFailure(error) {\n        this._cloudWarmupError = error;\n        this._surfaceCloudPipelinePrepared = false;\n        this._orbitCloudPipelinePrepared = false;\n        this._cloudWarmupState = this._clearAtmospherePrepared ? 'clear-ready' : 'failed';\n        this._clearCloudAtmosphereAttachments();\n        this._activateCloudEffectPassVariant('clear:clear');\n        this._syncToneMappingForRenderPath();\n        this._applySkyMeshVisibility();\n    }\n\n    _readFiniteConfig(config, keys, fallback) {\n        for (const key of keys) {\n            const value = Number(config?.[key]);\n            if (Number.isFinite(value)) return value;\n        }\n        return fallback;\n    }\n\n    _applyAirglowConfig(config = {}) {\n        if (!config || typeof config !== 'object') return;\n        const clamp = THREE.MathUtils.clamp;\n        if (typeof config.enabled === 'boolean') {\n            this._airglowEnabled = config.enabled;\n        }\n        this._airglowStrength = clamp(this._readFiniteConfig(config, ['strength', 'intensity'], this._airglowStrength), 0, 2);\n        this._airglowDayStrength = clamp(\n            this._readFiniteConfig(\n                config,\n                ['dayStrength', 'dayIntensity'],\n                this._airglowDayStrength\n            ),\n            0,\n            0.2\n        );\n        this._airglowBaseAlt = clamp(this._readFiniteConfig(config, ['baseAltitudeMeters', 'baseAltMeters', 'baseAlt'], this._airglowBaseAlt), 30000, 180000);\n        this._airglowCoreAlt = clamp(this._readFiniteConfig(config, ['coreAltitudeMeters', 'coreAltMeters', 'coreAlt'], this._airglowCoreAlt), 60000, 260000);\n        this._airglowFringeAlt = clamp(this._readFiniteConfig(config, ['fringeAltitudeMeters', 'fringeAltMeters', 'fringeAlt'], this._airglowFringeAlt), 90000, 600000);\n        this._airglowRiseScale = clamp(this._readFiniteConfig(config, ['riseScaleMeters', 'riseScale'], this._airglowRiseScale), 1000, 150000);\n        this._airglowTailScale = clamp(this._readFiniteConfig(config, ['tailScaleMeters', 'tailScale'], this._airglowTailScale), 1000, 250000);\n        this._airglowPathRef = clamp(this._readFiniteConfig(config, ['pathRefMeters', 'pathRef'], this._airglowPathRef), 50000, 3000000);\n        this._airglowInsideMin = clamp(this._readFiniteConfig(config, ['insideMin'], this._airglowInsideMin), 0, 1);\n        this._airglowInsideMax = clamp(this._readFiniteConfig(config, ['insideMax'], this._airglowInsideMax), 0, 1);\n        this._airglowGrazingPower = clamp(this._readFiniteConfig(config, ['grazingPower'], this._airglowGrazingPower), 0.2, 8);\n        if (this._airglowInsideMax < this._airglowInsideMin) {\n            this._airglowInsideMax = this._airglowInsideMin;\n        }\n        const colors = config.colors && typeof config.colors === 'object' ? config.colors : {};\n        if (colors.horizon) this._airglowColHorizon.set(colors.horizon);\n        if (colors.core) this._airglowColCore.set(colors.core);\n        if (colors.upper) this._airglowColUpper.set(colors.upper);\n        if (colors.fringe) this._airglowColFringe.set(colors.fringe);\n        this._syncAirglowUniforms();\n        if (!this._airglowEnabled && this._airglowMesh) this._airglowMesh.visible = false;\n    }\n\n    _syncAirglowUniforms() {\n        const u = this._airglowMaterial?.uniforms;\n        if (!u) return;\n        u.uBaseAlt.value = this._airglowBaseAlt;\n        u.uCoreAlt.value = this._airglowCoreAlt;\n        u.uFringeAlt.value = this._airglowFringeAlt;\n        u.uRiseScale.value = this._airglowRiseScale;\n        u.uTailScale.value = this._airglowTailScale;\n        u.uStrength.value = this._airglowStrength;\n        u.uDayStrength.value = this._airglowDayStrength;\n        u.uPathRef.value = this._airglowPathRef;\n        u.uInsideMin.value = this._airglowInsideMin;\n        u.uInsideMax.value = this._airglowInsideMax;\n        u.uGrazingPower.value = this._airglowGrazingPower;\n        u.uColHorizon.value.copy(this._airglowColHorizon);\n        u.uColCore.value.copy(this._airglowColCore);\n        u.uColUpper.value.copy(this._airglowColUpper);\n        u.uColFringe.value.copy(this._airglowColFringe);\n    }\n\n    _getAuroraConfig() {\n        return {\n            enabled: this._auroraEnabled !== false,\n            strength: this._auroraStrength,\n            topAltitudeMeters: this._auroraTopAltitudeMeters,\n            pathRefMeters: this._auroraPathRefMeters,\n            depthBiasMeters: this._auroraDepthBiasMeters\n        };\n    }\n\n    _applyAuroraConfig(config = {}) {\n        if (!config || typeof config !== 'object') return;\n        const clamp = THREE.MathUtils.clamp;\n        if (typeof config.enabled === 'boolean') {\n            this._auroraEnabled = config.enabled;\n        }\n        this._auroraStrength = clamp(this._readFiniteConfig(config, ['strength', 'intensity'], this._auroraStrength), 0, 3);\n        this._auroraTopAltitudeMeters = clamp(this._readFiniteConfig(config, ['topAltitudeMeters', 'topAltMeters', 'topAlt'], this._auroraTopAltitudeMeters), 120000, 900000);\n        this._auroraPathRefMeters = clamp(this._readFiniteConfig(config, ['pathRefMeters', 'pathRef'], this._auroraPathRefMeters), 20000, 1000000);\n        this._auroraDepthBiasMeters = clamp(this._readFiniteConfig(config, ['depthBiasMeters', 'depthBias'], this._auroraDepthBiasMeters), 0, 200);\n        this._syncAuroraConfig();\n        if (!this._auroraEnabled && this._auroraSystem?.mesh) this._auroraSystem.mesh.visible = false;\n    }\n\n    _syncAuroraConfig() {\n        this._auroraSystem?.applyConfig?.(this._getAuroraConfig());\n    }\n\n    _getFireConfig() {\n        return {\n            enabled: this._fireEnabled !== false,\n            strength: this._fireStrength,\n            topAltitudeMeters: this._fireTopAltitudeMeters,\n            pathRefMeters: this._firePathRefMeters,\n            depthBiasMeters: this._fireDepthBiasMeters\n        };\n    }\n\n    _applyFireConfig(config = {}) {\n        if (!config || typeof config !== 'object') return;\n        const clamp = THREE.MathUtils.clamp;\n        if (typeof config.enabled === 'boolean') {\n            this._fireEnabled = config.enabled;\n        }\n        this._fireStrength = clamp(this._readFiniteConfig(config, ['strength', 'intensity'], this._fireStrength), 0, 3);\n        this._fireTopAltitudeMeters = clamp(this._readFiniteConfig(config, ['topAltitudeMeters', 'topAltMeters', 'topAlt'], this._fireTopAltitudeMeters), 1000, 60000);\n        this._firePathRefMeters = clamp(this._readFiniteConfig(config, ['pathRefMeters', 'pathRef'], this._firePathRefMeters), 10000, 500000);\n        this._fireDepthBiasMeters = clamp(this._readFiniteConfig(config, ['depthBiasMeters', 'depthBias'], this._fireDepthBiasMeters), 0, 200);\n        this._syncFireConfig();\n        if (!this._fireEnabled && this._fireSystem?.mesh) this._fireSystem.mesh.visible = false;\n    }\n\n    _syncFireConfig() {\n        this._fireSystem?.applyConfig?.(this._getFireConfig());\n    }\n\n    setSmokeFeatures(features = [], metadata = {}) {\n        this._pendingSmokeFeatures = Array.isArray(features) ? features : [];\n        this._pendingSmokeMetadata = metadata && typeof metadata === 'object'\n            ? metadata\n            : {};\n        this._smokeSystem?.setFeatures?.(\n            this._pendingSmokeFeatures,\n            this._pendingSmokeMetadata\n        );\n    }\n\n    setSmokeEnabled(enabled) {\n        this._smokeEnabled = enabled === true;\n        this._smokeSystem?.setEnabled?.(this._smokeEnabled);\n        if (!this._smokeEnabled && this._smokeSystem?.mesh) {\n            this._smokeSystem.mesh.visible = false;\n        }\n    }\n\n    _getSmokeConfig() {\n        return {\n            enabled: this._smokeEnabled === true,\n            strength: this._smokeStrength,\n            topAltitudeMeters: this._smokeTopAltitudeMeters,\n            depthBiasMeters: this._smokeDepthBiasMeters\n        };\n    }\n\n    _applySmokeConfig(config = {}) {\n        if (!config || typeof config !== 'object') return;\n        if (typeof config.enabled === 'boolean') {\n            this._smokeEnabled = config.enabled;\n        }\n        this._smokeStrength = THREE.MathUtils.clamp(\n            this._readFiniteConfig(config, ['strength', 'intensity'], this._smokeStrength),\n            0,\n            2\n        );\n        this._smokeTopAltitudeMeters = THREE.MathUtils.clamp(\n            this._readFiniteConfig(\n                config,\n                ['topAltitudeMeters', 'topAltMeters', 'topAlt'],\n                this._smokeTopAltitudeMeters\n            ),\n            1000,\n            40000\n        );\n        this._smokeDepthBiasMeters = THREE.MathUtils.clamp(\n            this._readFiniteConfig(\n                config,\n                ['depthBiasMeters', 'depthBias'],\n                this._smokeDepthBiasMeters\n            ),\n            0,\n            200\n        );\n        this._syncSmokeConfig();\n        if (!this._smokeEnabled && this._smokeSystem?.mesh) {\n            this._smokeSystem.mesh.visible = false;\n        }\n    }\n\n    _syncSmokeConfig() {\n        this._smokeSystem?.applyConfig?.(this._getSmokeConfig());\n    }\n\n    _applyLightPollutionBloomConfig(config = {}) {\n        if (!config || typeof config !== 'object') return;\n        const next = {\n            ...(this._lightPollutionBloomSettings\n                || LIGHT_POLLUTION_BLOOM_DEFAULTS),\n        };\n        if (typeof config.enabled === 'boolean') next.enabled = config.enabled;\n        if (Number.isFinite(config.intensity)) {\n            next.intensity = THREE.MathUtils.clamp(config.intensity, 0, 3);\n        }\n        if (Number.isFinite(config.radiusPixels)) {\n            next.radiusPixels = THREE.MathUtils.clamp(\n                config.radiusPixels,\n                0.5,\n                16\n            );\n        }\n        if (Number.isFinite(config.threshold)) {\n            next.threshold = THREE.MathUtils.clamp(config.threshold, 0, 1);\n        }\n        if (Number.isFinite(config.orbitFadeStartMeters)) {\n            next.orbitFadeStartMeters = THREE.MathUtils.clamp(\n                config.orbitFadeStartMeters,\n                0,\n                2_000_000\n            );\n        }\n        if (Number.isFinite(config.orbitFadeEndMeters)) {\n            next.orbitFadeEndMeters = THREE.MathUtils.clamp(\n                config.orbitFadeEndMeters,\n                next.orbitFadeStartMeters + 1,\n                4_000_000\n            );\n        }\n        next.orbitFadeEndMeters = Math.max(\n            next.orbitFadeStartMeters + 1,\n            next.orbitFadeEndMeters\n        );\n        this._lightPollutionBloomSettings = next;\n        this._lightPollutionBloomEffect?.applySettings(next);\n    }\n\n    _applyBloomConfig(config = {}) {\n        if (!config || typeof config !== 'object') return;\n        let needsRefresh = false;\n        if (typeof config.enabled === 'boolean' && config.enabled !== this._bloomEnabled) {\n            this._bloomEnabled = config.enabled;\n            needsRefresh = true;\n        }\n        if (!this._bloomSettings) {\n            this._bloomSettings = { ...POSTPROCESS_BLOOM_EFFECT_DEFAULTS };\n        }\n\n        if (Number.isFinite(config.intensity)) {\n            this._bloomSettings.intensity = THREE.MathUtils.clamp(config.intensity, 0, 6);\n        }\n        if (Number.isFinite(config.threshold)) {\n            this._bloomSettings.luminanceThreshold = THREE.MathUtils.clamp(config.threshold, 0, 1);\n        }\n        if (Number.isFinite(config.smoothing)) {\n            this._bloomSettings.luminanceSmoothing = THREE.MathUtils.clamp(config.smoothing, 0, 1);\n        }\n        if (Number.isFinite(config.radius)) {\n            this._bloomSettings.radius = THREE.MathUtils.clamp(config.radius, 0, 1);\n        }\n        if (Number.isFinite(config.levels)) {\n            this._bloomSettings.levels = THREE.MathUtils.clamp(Math.round(config.levels), 1, 8);\n        }\n        if (typeof config.mipmapBlur === 'boolean') {\n            this._bloomSettings.mipmapBlur = config.mipmapBlur;\n        }\n\n        if (this._bloomEffect) {\n            this._bloomEffect.intensity = this._bloomSettings.intensity;\n            this._bloomEffect.luminanceThreshold = this._bloomSettings.luminanceThreshold;\n            this._bloomEffect.luminanceSmoothing = this._bloomSettings.luminanceSmoothing;\n            this._bloomEffect.radius = this._bloomSettings.radius;\n            this._bloomEffect.levels = this._bloomSettings.levels;\n            this._bloomEffect.mipmapBlur = this._bloomSettings.mipmapBlur;\n        }\n\n        if (this.composer && (needsRefresh || (this._bloomEnabled && !this._bloomEffect))) {\n            this._refreshPostEffectsPass();\n        }\n    }\n\n    _refreshPostEffectsPass() {\n        if (!this.composer) return;\n\n        this._underwaterEffect ||= new UnderwaterEffect(this.camera);\n        this._nightVisionEffect ||= new NightVisionEffect();\n        this._nightVisionEffect.setState(this._nightVisionEnabled, this._nightVisionSettings);\n        const effects = [this._underwaterEffect];\n        if (this._bloomEnabled) {\n            if (!this._bloomEffect) {\n                this._bloomEffect = new BloomEffect({ ...this._bloomSettings });\n            }\n            effects.push(this._bloomEffect);\n        } else {\n            this._bloomEffect = null;\n        }\n\n        // The former projected-map bloom is intentionally retired. Artificial\n        // light remains part of the surface-lighting compositor only.\n        this._lightPollutionBloomEffect = null;\n\n        if (this.useToneMapping) {\n            if (!this._toneMappingEffect) {\n                this._toneMappingEffect = new ToneMappingEffect({ mode: this.toneMappingMode });\n            }\n            effects.push(this._toneMappingEffect);\n        } else {\n            this._toneMappingEffect = null;\n        }\n\n        if (this._composerSamples === 0) {\n            if (!this._smaaEffect) {\n                this._smaaEffect = new SMAAEffect({ preset: SMAAPreset.MEDIUM });\n            }\n            effects.push(this._smaaEffect);\n        } else {\n            this._smaaEffect = null;\n        }\n\n        // Sensor grain: always compiled in; its uniform switches it.\n        this._lensStage ||= new LensEffectsStage({ camera: this.camera });\n        effects.push(this._lensStage.grade, this._lensStage.grain);\n\n        if (this.enableDithering) {\n            if (!this._ditheringEffect) {\n                this._ditheringEffect = new DitheringEffect();\n            }\n            effects.push(this._ditheringEffect);\n        } else {\n            this._ditheringEffect = null;\n        }\n\n        this._sarEffect ||= new SarEffect();\n        effects.push(this._nightVisionEffect, this._sarEffect);\n        if (this._photoLightingMaskPass) {\n            this._photorealBackfaceEffect ||= new PhotorealBackfaceEffect(this._photoLightingMaskPass.texture, !this._orbitalOverviewActive && !this._photorealUnderwater);\n            effects.push(this._photorealBackfaceEffect);\n        }\n        if (!this._postEffectsPass) {\n            if (effects.length === 0) return;\n            this._postEffectsPass = new EffectPass(this.camera, ...effects);\n            this.composer.addPass(this._postEffectsPass);\n            return;\n        }\n\n        if (effects.length === 0) {\n            this.composer.removePass(this._postEffectsPass);\n            this._postEffectsPass.dispose?.();\n            this._postEffectsPass = null;\n            return;\n        }\n\n        this._postEffectsPass.setEffects(effects);\n        this._postEffectsPass.recompile();\n    }\n\n    _normalizeCloudQualityPreset(value) {\n        if (typeof value !== 'string') return null;\n        const preset = value.trim().toLowerCase();\n        if (preset === 'low' || preset === 'medium' || preset === 'high' || preset === 'ultra') {\n            return preset;\n        }\n        return null;\n    }\n\n    _applyCloudQualityPreset() {\n        if (!this.clouds) return;\n        const preset = this._normalizeCloudQualityPreset(this._cloudQualityPreset);\n        if (!preset) return;\n        this.clouds.qualityPreset = preset;\n        this._captureCloudBaseSettings();\n    }\n\n    _applyCloudShadowTuning(overrides = null) {\n        if (overrides && typeof overrides === 'object') {\n            this._cloudShadowTuning = {\n                ...this._cloudShadowTuning,\n                ...overrides\n            };\n        }\n        const tuning = this._cloudShadowTuning;\n        const apply = (effect) => {\n            if (!effect?.shadow) return;\n            if (Number.isFinite(tuning.farScale)) effect.shadow.farScale = tuning.farScale;\n            if (Number.isFinite(tuning.maxFar)) effect.shadow.maxFar = tuning.maxFar;\n            if (Number.isFinite(tuning.cascadeCount)) {\n                effect.shadow.cascadeCount = Math.max(1, Math.round(tuning.cascadeCount));\n            }\n            const mapSize = tuning.mapSize;\n            if (Number.isFinite(mapSize)) {\n                effect.shadow.mapSize.set(mapSize, mapSize);\n            } else if (mapSize && Number.isFinite(mapSize.x) && Number.isFinite(mapSize.y)) {\n                effect.shadow.mapSize.set(mapSize.x, mapSize.y);\n            }\n            if (typeof tuning.splitMode === 'string') effect.shadow.splitMode = tuning.splitMode;\n            if (Number.isFinite(tuning.splitLambda)) effect.shadow.splitLambda = tuning.splitLambda;\n        };\n        apply(this.clouds);\n        apply(this._orbitCloudsEffect);\n    }\n\n    _syncCloudAtmosphereAttachments() {\n        if (this._cloudAtmosphereAttachments) {\n            this._cloudAtmosphereAttachments.set(true, this.clouds); return;\n        }\n        if (!this.aerialPerspective || !this.clouds) return;\n        this.aerialPerspective.overlay = this.clouds.atmosphereOverlay;\n        this.aerialPerspective.shadow = this.clouds.atmosphereShadow;\n        this.aerialPerspective.shadowLength = this.clouds.atmosphereShadowLength;\n    }\n\n    _clearCloudAtmosphereAttachments() {\n        if (this._cloudAtmosphereAttachments) {\n            this._cloudAtmosphereAttachments.set(false, this.clouds); return;\n        }\n        if (!this.aerialPerspective) return;\n        this.aerialPerspective.overlay = null;\n        this.aerialPerspective.shadow = null;\n        this.aerialPerspective.shadowLength = null;\n    }\n\n    _applySkyTuningConfig(skyTuning) {\n        if (!skyTuning || typeof skyTuning !== 'object') return;\n        const next = { ...this._skyTuning };\n        const clamp01 = (value) => THREE.MathUtils.clamp(value, 0, 1);\n        const setNumber = (key, value, clamp) => {\n            if (!Number.isFinite(value)) return;\n            next[key] = clamp ? clamp(value) : value;\n        };\n\n        setNumber('alphaScale', skyTuning.alphaScale, clamp01);\n        setNumber('alphaClamp', skyTuning.alphaClamp, clamp01);\n        setNumber('limbBoost', skyTuning.limbBoost, (value) => Math.max(0, value));\n        setNumber('pathShort', skyTuning.pathShort, clamp01);\n        setNumber('limbMax', skyTuning.limbMax, (value) => Math.max(0.1, value));\n        setNumber('densityScale', skyTuning.densityScale, (value) => Math.max(0, value));\n        setNumber('scaleHeight', skyTuning.scaleHeight, (value) => Math.max(0.001, value));\n        setNumber('verticalFadeStart', skyTuning.verticalFadeStart, clamp01);\n        setNumber('verticalFadeEnd', skyTuning.verticalFadeEnd, clamp01);\n        setNumber('altitudeFadeStart', skyTuning.altitudeFadeStart, clamp01);\n        setNumber('altitudeFadeEnd', skyTuning.altitudeFadeEnd, clamp01);\n        setNumber('outsideFadeStart', skyTuning.outsideFadeStart, clamp01);\n        setNumber('outsideFadeEnd', skyTuning.outsideFadeEnd, clamp01);\n        setNumber('depthThreshold', skyTuning.depthThreshold, clamp01);\n\n        next.verticalFadeEnd = Math.max(next.verticalFadeStart, next.verticalFadeEnd);\n        next.altitudeFadeEnd = Math.max(next.altitudeFadeStart, next.altitudeFadeEnd);\n        next.outsideFadeEnd = Math.max(next.outsideFadeStart, next.outsideFadeEnd);\n\n        this._skyTuning = next;\n        this._applySkyTuning();\n    }\n\n    _applyCloudSettings(clouds) {\n        if (!this.clouds) return;\n        const clamp01 = (value) => THREE.MathUtils.clamp(value, 0, 1);\n        if (!this._cloudBaseSettings) this._captureCloudBaseSettings();\n\n        if (Number.isFinite(clouds.coverage)) {\n            const next = clamp01(clouds.coverage);\n            this.clouds.coverage = next;\n            this._cloudBaseSettings.coverage = next;\n        }\n        if (Number.isFinite(clouds.scatteringCoefficient)) {\n            const next = Math.max(0, clouds.scatteringCoefficient);\n            this.clouds.scatteringCoefficient = next;\n            this._cloudBaseSettings.scatteringCoefficient = next;\n        }\n        if (Number.isFinite(clouds.absorptionCoefficient)) {\n            const next = Math.max(0, clouds.absorptionCoefficient);\n            this.clouds.absorptionCoefficient = next;\n            this._cloudBaseSettings.absorptionCoefficient = next;\n        }\n        if (Number.isFinite(clouds.turbulenceDisplacement)) {\n            const next = Math.max(0, clouds.turbulenceDisplacement);\n            this.clouds.turbulenceDisplacement = next;\n            this._cloudBaseSettings.turbulenceDisplacement = next;\n        }\n        if (typeof clouds.lightShafts === 'boolean') {\n            this.clouds.lightShafts = clouds.lightShafts;\n            this._cloudBaseSettings.lightShafts = clouds.lightShafts;\n        }\n        if (typeof clouds.shapeDetail === 'boolean') {\n            this.clouds.shapeDetail = clouds.shapeDetail;\n            this._cloudBaseSettings.shapeDetail = clouds.shapeDetail;\n        }\n        if (typeof clouds.turbulence === 'boolean') {\n            this.clouds.turbulence = clouds.turbulence;\n            this._cloudBaseSettings.turbulence = clouds.turbulence;\n        }\n        if (typeof clouds.haze === 'boolean') {\n            this.clouds.haze = clouds.haze;\n            this._cloudBaseSettings.haze = clouds.haze;\n        }\n    }\n\n    _applyCloudLayerSettings(cloudLayers) {\n        if (!this.clouds?.cloudLayers) return;\n        const layers = this.clouds.cloudLayers;\n\n        // Apply terrain-relative altitudes to our internal config\n        const applyLayerConfig = (layerIndex, source) => {\n            if (!source) return;\n            const config = this._cloudLayerHeightsAboveTerrain[layerIndex] || {};\n\n            // Altitudes are specified as heights above terrain (0 = terrain surface)\n            if (Number.isFinite(source.altitude)) {\n                config.altitude = Math.max(0, source.altitude);\n            }\n            if (Number.isFinite(source.height)) {\n                config.height = Math.max(100, source.height);\n            }\n            this._cloudLayerHeightsAboveTerrain[layerIndex] = config;\n        };\n\n        // Apply other layer properties directly to the library layer\n        const applyLayerProperties = (target, source) => {\n            if (!target || !source) return;\n            if (Number.isFinite(source.densityScale)) target.densityScale = Math.max(0, source.densityScale);\n            if (Number.isFinite(source.shapeAmount)) target.shapeAmount = Math.max(0, source.shapeAmount);\n            if (Number.isFinite(source.shapeDetailAmount)) {\n                target.shapeDetailAmount = Math.max(0, source.shapeDetailAmount);\n            }\n            if (Number.isFinite(source.weatherExponent)) target.weatherExponent = Math.max(0, source.weatherExponent);\n            if (Number.isFinite(source.shapeAlteringBias)) target.shapeAlteringBias = source.shapeAlteringBias;\n            if (Number.isFinite(source.coverageFilterWidth)) {\n                target.coverageFilterWidth = source.coverageFilterWidth;\n            }\n            if (typeof source.shadow === 'boolean') target.shadow = source.shadow;\n        };\n\n        if (Array.isArray(cloudLayers)) {\n            cloudLayers.forEach((layer, index) => {\n                applyLayerConfig(index, layer);\n                applyLayerProperties(layers[index], layer);\n            });\n        } else {\n            const layerMap = {\n                low: 0,\n                mid: 1,\n                high: 2,\n                upper: 3\n            };\n            Object.entries(layerMap).forEach(([key, index]) => {\n                if (!cloudLayers[key]) return;\n                applyLayerConfig(index, cloudLayers[key]);\n                applyLayerProperties(layers[index], cloudLayers[key]);\n            });\n        }\n\n        // Trigger terrain update to apply the new altitudes\n        this._updateCloudLayersForTerrain();\n    }\n\n    _getOrbitCloudsParent() {\n        return this.planetGroup || this.scene || null;\n    }\n\n    // The orbit cloud overlay remains an unlit MeshBasicMaterial so its public\n    // map/opacity lifecycle stays compatible with existing tuneables, but its\n    // generic r185 shader is replaced completely. The uniform shares the live\n    // planet-local _sunDirection reference, so it tracks the sun each frame.\n    _installOrbitCloudDayNight(material) {\n        if (!material) return;\n        const previousProgramKey = material.customProgramCacheKey?.() || '';\n        material.name ||= 'OrbitCloudsLeanMaterial';\n        material.onBeforeCompile = (shader) => {\n            shader.uniforms.uOrbitSunDir = { value: this._sunDirection };\n            this._orbitCloudsShader = shader;\n            shader.uniforms.uOrbitCloudHeight = { value: Math.max(0, this._orbitClouds.radiusOffsetM || 0) };\n            bindNightCloudLighting(shader.uniforms, this._earthMaterial?.uniforms);\n            shader.uniforms.uOrbitNightAirglowColor = this._earthMaterial?.uniforms\n                ?.simpleCloudsNightAirglowColor\n                ?? { value: new THREE.Color('#9fb3c2') };\n            shader.uniforms.uOrbitNightAirglowStrength = this._earthMaterial?.uniforms\n                ?.simpleCloudsNightAirglowStrength\n                ?? { value: 0.006 };\n            shader.uniforms.uOrbitNightTransitionStart = this._earthMaterial?.uniforms\n                ?.nightTransitionStart\n                ?? { value: 0 };\n            shader.uniforms.uOrbitNightTransitionEnd = this._earthMaterial?.uniforms\n                ?.nightTransitionEnd\n                ?? { value: 0.5 };\n            shader.vertexShader = ORBIT_CLOUD_VERTEX_SHADER;\n            shader.fragmentShader = ORBIT_CLOUD_FRAGMENT_SHADER;\n            material.userData.orbitDayNightShader = shader;\n        };\n        material.customProgramCacheKey = () => `${previousProgramKey}|nca-orbit-clouds-r185-v2-city-scatter`;\n        material.needsUpdate = true;\n    }\n\n    _ensureOrbitCloudsMesh() {\n        if (!this._orbitClouds.enabled) {\n            if (this._orbitCloudsMesh) {\n                this._orbitCloudsMesh.parent?.remove?.(this._orbitCloudsMesh);\n                this._orbitCloudsMesh = null;\n            }\n            if (this._orbitCloudsRawMesh) {\n                this._orbitCloudsRawMesh.parent?.remove?.(this._orbitCloudsRawMesh);\n                this._orbitCloudsRawMesh = null;\n            }\n            return;\n        }\n        const showRaw = !!this._orbitClouds.rawOverlay;\n        const parent = this._getOrbitCloudsParent();\n        if (!parent) return;\n\n        // Never attach a mapless cloud sphere. Async cloud acquisition can\n        // finish between animation frames; attaching the placeholder here used\n        // to expose a one-off stock MeshBasic program even though the surface\n        // altitude fade made the layer fully transparent moments later.\n        if (!this._orbitCloudsTexture) {\n            if (this._orbitCloudsMesh) this._orbitCloudsMesh.visible = false;\n            if (this._orbitCloudsRawMesh) this._orbitCloudsRawMesh.visible = false;\n            return;\n        }\n\n        const radius = PLANET_RADIUS + Math.max(0, this._orbitClouds.radiusOffsetM || 0);\n        const needsGeometry = !this._orbitCloudsGeometry\n            || Math.abs((this._orbitCloudsGeometry.parameters?.radius ?? 0) - radius) > 1;\n\n        if (needsGeometry) {\n            this._orbitCloudsGeometry?.dispose?.();\n            this._orbitCloudsGeometry = new THREE.SphereGeometry(radius, 96, 48);\n        }\n        if (this._orbitCloudsMesh && this._orbitCloudsMesh.geometry !== this._orbitCloudsGeometry) {\n            this._orbitCloudsMesh.geometry = this._orbitCloudsGeometry;\n        }\n        if (this._orbitCloudsRawMesh && this._orbitCloudsRawMesh.geometry !== this._orbitCloudsGeometry) {\n            this._orbitCloudsRawMesh.geometry = this._orbitCloudsGeometry;\n        }\n\n        // Always create the main orbit cloud layer sphere\n        if (!this._orbitCloudsMaterial) {\n            this._orbitCloudsMaterial = new THREE.MeshBasicMaterial({\n                color: 0xffffff,\n                transparent: true,\n                opacity: THREE.MathUtils.clamp(this._orbitClouds.opacity, 0, 1),\n                depthWrite: false,\n                depthTest: true,\n                side: THREE.FrontSide,\n                toneMapped: false\n            });\n            this._installOrbitCloudDayNight(this._orbitCloudsMaterial);\n        }\n        if (this._orbitCloudsTexture) {\n            this._orbitCloudsMaterial.map = this._orbitCloudsTexture;\n            this._applyOrbitCloudOverlayMapping(this._orbitCloudsTexture);\n        }\n        if (!this._orbitCloudsMesh) {\n            this._orbitCloudsMesh = new THREE.Mesh(this._orbitCloudsGeometry, this._orbitCloudsMaterial);\n            this._orbitCloudsMesh.name = 'OrbitCloudsLayer';\n            this._orbitCloudsMesh.userData.lensflare = 'no-occlusion';\n            this._orbitCloudsMesh.renderOrder = 10;\n            this._orbitCloudsMesh.frustumCulled = false;\n            parent.add(this._orbitCloudsMesh);\n        } else if (this._orbitCloudsMesh.parent !== parent) {\n            this._orbitCloudsMesh.parent?.remove?.(this._orbitCloudsMesh);\n            parent.add(this._orbitCloudsMesh);\n        }\n\n        // Raw overlay sphere (debug tool, controlled by rawOverlay flag)\n        if (showRaw) {\n            if (!this._orbitCloudsRawMaterial) {\n                this._orbitCloudsRawMaterial = new THREE.MeshBasicMaterial({\n                    color: 0xffffff,\n                    transparent: true,\n                    opacity: THREE.MathUtils.clamp(this._orbitClouds.opacity, 0, 1),\n                    depthWrite: false,\n                    depthTest: true,\n                    side: THREE.FrontSide,\n                    toneMapped: false\n                });\n            }\n            if (this._orbitCloudsRawTexture) {\n                this._orbitCloudsRawMaterial.map = this._orbitCloudsRawTexture;\n                this._applyOrbitCloudOverlayMapping(this._orbitCloudsRawTexture);\n            }\n            if (!this._orbitCloudsRawMesh) {\n                this._orbitCloudsRawMesh = new THREE.Mesh(this._orbitCloudsGeometry, this._orbitCloudsRawMaterial);\n                this._orbitCloudsRawMesh.name = 'OrbitCloudsRaw';\n                this._orbitCloudsRawMesh.userData.lensflare = 'no-occlusion';\n                this._orbitCloudsRawMesh.renderOrder = 9;\n                this._orbitCloudsRawMesh.frustumCulled = false;\n                parent.add(this._orbitCloudsRawMesh);\n            } else if (this._orbitCloudsRawMesh.parent !== parent) {\n                this._orbitCloudsRawMesh.parent?.remove?.(this._orbitCloudsRawMesh);\n                parent.add(this._orbitCloudsRawMesh);\n            }\n        } else if (this._orbitCloudsRawMesh) {\n            this._orbitCloudsRawMesh.parent?.remove?.(this._orbitCloudsRawMesh);\n            this._orbitCloudsRawMesh = null;\n        }\n\n        if (this._orbitCloudsMaterial) {\n            this._orbitCloudsMaterial.opacity = THREE.MathUtils.clamp(this._orbitClouds.opacity, 0, 1);\n        }\n        if (this._orbitCloudsRawMaterial) {\n            this._orbitCloudsRawMaterial.opacity = THREE.MathUtils.clamp(this._orbitClouds.opacity, 0, 1);\n        }\n    }\n\n    _getOrbitCloudsSnapshotTime() {\n        const sourceDate = this.lightingSystem?.currentDate || new Date();\n        const stepMinutes = Math.max(1, Number(this._orbitClouds.timeStepMinutes) || 60);\n        const stepMs = stepMinutes * 60 * 1000;\n        const snappedMs = Math.floor(sourceDate.getTime() / stepMs) * stepMs;\n        let snapped = new Date(snappedMs);\n        const now = new Date();\n        if (snapped.getTime() > now.getTime()) {\n            snapped = now;\n        }\n        if (this._orbitClouds.dateOnly) {\n            let day = new Date(Date.UTC(\n                snapped.getUTCFullYear(),\n                snapped.getUTCMonth(),\n                snapped.getUTCDate()\n            ));\n            // The current UTC day's global mosaic is only partially imaged (daytime\n            // swaths in progress), which leaves large uncovered regions. Step back to\n            // the previous complete day so the live layer has full global coverage.\n            const todayUtc = Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate());\n            if (day.getTime() >= todayUtc) {\n                day = new Date(todayUtc - 24 * 60 * 60 * 1000);\n            }\n            return day;\n        }\n        return snapped;\n    }\n\n    _isOrbitCloudsNasa(baseUrl) {\n        if (typeof this._orbitClouds.nasaSnapshot === 'boolean') {\n            return this._orbitClouds.nasaSnapshot;\n        }\n        return (baseUrl || '').includes('wvs.earthdata.nasa.gov');\n    }\n\n    _scheduleOrbitCloudsRetry(isRaw) {\n        const now = Date.now();\n        if (isRaw) {\n            this._orbitCloudsRawFailureCount = Math.min(this._orbitCloudsRawFailureCount + 1, 6);\n            const delay = Math.min(\n                ORBIT_CLOUDS_RETRY_BASE_MS * 2 ** (this._orbitCloudsRawFailureCount - 1),\n                ORBIT_CLOUDS_RETRY_MAX_MS\n            );\n            const jitter = Math.random() * delay * 0.2;\n            this._orbitCloudsRawNextRetryMs = now + delay + jitter;\n            return;\n        }\n        this._orbitCloudsFailureCount = Math.min(this._orbitCloudsFailureCount + 1, 6);\n        const delay = Math.min(\n            ORBIT_CLOUDS_RETRY_BASE_MS * 2 ** (this._orbitCloudsFailureCount - 1),\n            ORBIT_CLOUDS_RETRY_MAX_MS\n        );\n        const jitter = Math.random() * delay * 0.2;\n        this._orbitCloudsNextRetryMs = now + delay + jitter;\n    }\n\n    _resetOrbitCloudsRetry(isRaw) {\n        if (isRaw) {\n            this._orbitCloudsRawFailureCount = 0;\n            this._orbitCloudsRawNextRetryMs = 0;\n            return;\n        }\n        this._orbitCloudsFailureCount = 0;\n        this._orbitCloudsNextRetryMs = 0;\n    }\n\n    _shouldDeferOrbitCloudsFetch(now, isRaw) {\n        const nextRetry = isRaw ? this._orbitCloudsRawNextRetryMs : this._orbitCloudsNextRetryMs;\n        return Number.isFinite(nextRetry) && nextRetry > 0 && now < nextRetry;\n    }\n\n    _buildOrbitCloudsUrl(snapshotDate, variant = 'mask') {\n        const baseUrl = resolveOrbitCloudsBaseUrl(this._orbitClouds.baseUrl || '');\n        const timeParam = this._orbitClouds.dateOnly\n            ? snapshotDate.toISOString().slice(0, 10)\n            : snapshotDate.toISOString().replace(/\\.\\d{3}Z$/, 'Z');\n        const width = Math.max(256, Math.round(this._orbitClouds.width));\n        const height = Math.max(128, Math.round(this._orbitClouds.height));\n        const isNasa = this._isOrbitCloudsNasa(baseUrl);\n        if (isNasa) {\n            const params = new URLSearchParams({\n                REQUEST: 'GetSnapshot',\n                TIME: timeParam,\n                CRS: 'EPSG:4326',\n                BBOX: ORBIT_CLOUDS_BBOX,\n                LAYERS: this._orbitClouds.layer,\n                FORMAT: this._orbitClouds.format,\n                WIDTH: String(width),\n                HEIGHT: String(height)\n            });\n            return `${baseUrl}?${params.toString()}`;\n        }\n\n        const params = new URLSearchParams({\n            variant: variant === 'raw' ? 'raw' : 'mask',\n            layer: this._orbitClouds.layer,\n            width: String(width),\n            height: String(height)\n        });\n        if (this._orbitClouds.dateOnly) {\n            params.set('date', timeParam);\n        } else {\n            params.set('time', timeParam);\n        }\n        return `${baseUrl}?${params.toString()}`;\n    }\n\n    async _loadOrbitCloudsImage(blob) {\n        if (typeof createImageBitmap === 'function') {\n            return createImageBitmap(blob);\n        }\n        return new Promise((resolve, reject) => {\n            const img = new Image();\n            const objectUrl = URL.createObjectURL(blob);\n            img.onload = () => {\n                URL.revokeObjectURL(objectUrl);\n                resolve(img);\n            };\n            img.onerror = (error) => {\n                URL.revokeObjectURL(objectUrl);\n                reject(error);\n            };\n            img.src = objectUrl;\n        });\n    }\n\n    async _fetchOrbitCloudsTexture(snapshotDate, snapshotKey) {\n        if (this._orbitCloudsInFlight) return;\n        if (typeof document === 'undefined') return;\n        this._orbitCloudsInFlight = true;\n        try {\n            const baseUrl = resolveOrbitCloudsBaseUrl(this._orbitClouds.baseUrl || '');\n            const isNasa = this._isOrbitCloudsNasa(baseUrl);\n            const url = this._buildOrbitCloudsUrl(snapshotDate, isNasa ? 'raw' : 'mask');\n            const response = await getNoclipGovernanceClient().request(url, { mode: 'cors', governanceLane: 'scene' });\n            if (!response.ok) {\n                throw new Error(`Orbit cloud fetch failed: ${response.status}`);\n            }\n            const blob = await response.blob();\n            const image = await this._loadOrbitCloudsImage(blob);\n            const width = Math.max(256, Math.round(this._orbitClouds.width));\n            const height = Math.max(128, Math.round(this._orbitClouds.height));\n\n            if (!this._orbitCloudsCanvas) {\n                this._orbitCloudsCanvas = document.createElement('canvas');\n            }\n            const canvas = this._orbitCloudsCanvas;\n            if (canvas.width !== width || canvas.height !== height) {\n                canvas.width = width;\n                canvas.height = height;\n            }\n            if (!this._orbitCloudsCtx) {\n                this._orbitCloudsCtx = canvas.getContext('2d');\n            }\n            const ctx = this._orbitCloudsCtx;\n            if (!ctx) return;\n\n            ctx.setTransform(1, 0, 0, 1, 0, 0);\n            ctx.clearRect(0, 0, width, height);\n            if (!isNasa && this._orbitClouds.flipY) {\n                ctx.translate(0, height);\n                ctx.scale(1, -1);\n            }\n            if (isNasa) {\n                if (!this._orbitCloudsRawCanvas) {\n                    this._orbitCloudsRawCanvas = document.createElement('canvas');\n                }\n                const rawCanvas = this._orbitCloudsRawCanvas;\n                if (rawCanvas.width !== width || rawCanvas.height !== height) {\n                    rawCanvas.width = width;\n                    rawCanvas.height = height;\n                }\n                if (!this._orbitCloudsRawCtx) {\n                    this._orbitCloudsRawCtx = rawCanvas.getContext('2d');\n                }\n                const rawCtx = this._orbitCloudsRawCtx;\n                if (!rawCtx) return;\n\n                rawCtx.setTransform(1, 0, 0, 1, 0, 0);\n                rawCtx.clearRect(0, 0, width, height);\n                if (this._orbitClouds.flipY) {\n                    rawCtx.translate(0, height);\n                    rawCtx.scale(1, -1);\n                }\n                rawCtx.drawImage(image, 0, 0, width, height);\n                ctx.drawImage(rawCanvas, 0, 0, width, height);\n\n                const imageData = ctx.getImageData(0, 0, width, height);\n                const data = imageData.data;\n                const alphaScale = Number.isFinite(this._orbitClouds.alphaScale)\n                    ? this._orbitClouds.alphaScale\n                    : 1;\n                const alphaBias = Number.isFinite(this._orbitClouds.alphaBias)\n                    ? this._orbitClouds.alphaBias\n                    : 0;\n                for (let i = 0; i < data.length; i += 4) {\n                    const r = data[i];\n                    const g = data[i + 1];\n                    const b = data[i + 2];\n                    const rn = r / 255;\n                    const gn = g / 255;\n                    const bn = b / 255;\n                    const isNoData = r < 5 && g < 5 && b < 5;\n                    const redDominant = rn > 0.6 && rn > (gn + 0.15) && rn > (bn + 0.15);\n                    let cloud = 0;\n                    if (!isNoData && !redDominant) {\n                        cloud = Math.max(gn, bn);\n                    }\n                    const alpha = THREE.MathUtils.clamp((cloud + alphaBias) * alphaScale, 0, 1);\n                    data[i] = 255;\n                    data[i + 1] = 255;\n                    data[i + 2] = 255;\n                    data[i + 3] = Math.round(alpha * 255);\n                }\n                ctx.putImageData(imageData, 0, 0);\n            } else {\n                ctx.drawImage(image, 0, 0, width, height);\n                const imageData = ctx.getImageData(0, 0, width, height);\n                const data = imageData.data;\n                const alphaScale = Number.isFinite(this._orbitClouds.alphaScale)\n                    ? this._orbitClouds.alphaScale\n                    : 1;\n                const alphaBias = Number.isFinite(this._orbitClouds.alphaBias)\n                    ? this._orbitClouds.alphaBias\n                    : 0;\n                // Extract clouds from true-color imagery (e.g. MODIS CorrectedReflectance).\n                // Clouds are bright AND neutral (low saturation); land/desert is bright but\n                // warm/saturated and ocean/vegetation is dark — so brightness*neutrality\n                // isolates cloud cover while leaving clear sky transparent (no white fill).\n                // NOTE: snow/ice reads as cloud (acceptable; the static base covers poles too).\n                for (let i = 0; i < data.length; i += 4) {\n                    const r = data[i] / 255;\n                    const g = data[i + 1] / 255;\n                    const b = data[i + 2] / 255;\n                    const srcAlpha = Number.isFinite(data[i + 3]) ? data[i + 3] / 255 : 1;\n                    const mx = Math.max(r, g, b);\n                    const mn = Math.min(r, g, b);\n                    const sat = mx <= 0 ? 0 : (mx - mn) / mx;\n                    const bright = THREE.MathUtils.smoothstep(mx, 0.45, 0.80);\n                    const neutral = 1 - THREE.MathUtils.smoothstep(sat, 0.12, 0.32);\n                    const coverage = bright * neutral * srcAlpha;\n                    const adjusted = THREE.MathUtils.clamp((coverage + alphaBias) * alphaScale, 0, 1);\n                    data[i] = 255;\n                    data[i + 1] = 255;\n                    data[i + 2] = 255;\n                    data[i + 3] = Math.round(adjusted * 255);\n                }\n                ctx.putImageData(imageData, 0, 0);\n            }\n            if (image.close) {\n                image.close();\n            }\n\n            if (isNasa && this._orbitCloudsRawCanvas) {\n                if (!this._orbitCloudsRawTexture) {\n                    this._orbitCloudsRawTexture = new THREE.CanvasTexture(this._orbitCloudsRawCanvas);\n                    this._orbitCloudsRawTexture.minFilter = THREE.LinearFilter;\n                    this._orbitCloudsRawTexture.magFilter = THREE.LinearFilter;\n                    this._orbitCloudsRawTexture.wrapS = THREE.RepeatWrapping;\n                    this._orbitCloudsRawTexture.wrapT = THREE.ClampToEdgeWrapping;\n                    this._orbitCloudsRawTexture.colorSpace = THREE.NoColorSpace;\n                }\n                this._applyOrbitCloudOverlayMapping(this._orbitCloudsRawTexture);\n                this._orbitCloudsRawTexture.needsUpdate = true;\n                if (this._orbitCloudsRawMaterial && this._orbitCloudsRawMaterial.map !== this._orbitCloudsRawTexture) {\n                    this._orbitCloudsRawMaterial.map = this._orbitCloudsRawTexture;\n                    this._orbitCloudsRawMaterial.needsUpdate = true;\n                }\n                this._orbitCloudsRawLastKey = snapshotKey;\n                this._orbitCloudsRawLastFetchMs = Date.now();\n            }\n\n            if (!this._orbitCloudsTexture) {\n                this._orbitCloudsTexture = new THREE.CanvasTexture(canvas);\n                this._orbitCloudsTexture.minFilter = THREE.LinearFilter;\n                this._orbitCloudsTexture.magFilter = THREE.LinearFilter;\n                this._orbitCloudsTexture.wrapS = THREE.RepeatWrapping;\n                this._orbitCloudsTexture.wrapT = THREE.ClampToEdgeWrapping;\n                this._orbitCloudsTexture.colorSpace = THREE.NoColorSpace;\n            }\n            this._applyOrbitCloudOverlayMapping(this._orbitCloudsTexture);\n            this._orbitCloudsTexture.needsUpdate = true;\n            if (this._orbitCloudsMaterial && this._orbitCloudsMaterial.map !== this._orbitCloudsTexture) {\n                this._orbitCloudsMaterial.map = this._orbitCloudsTexture;\n                this._orbitCloudsMaterial.needsUpdate = true;\n            }\n            if (this._earthMaterial?.uniforms?.orbitCloudsTexture) {\n                this._earthMaterial.uniforms.orbitCloudsTexture.value = this._orbitCloudsTexture;\n                this._earthMaterial.uniforms.orbitCloudsEnabled.value = this._orbitClouds.enabled ? 1.0 : 0.0;\n                if (this._earthMaterial.uniforms.orbitCloudsShadowHeight) {\n                    this._earthMaterial.uniforms.orbitCloudsShadowHeight.value = Math.max(0, this._orbitClouds.radiusOffsetM || 12000);\n                }\n            }\n            this._orbitCloudsLastKey = snapshotKey;\n            this._orbitCloudsLastFetchMs = Date.now();\n            this._resetOrbitCloudsRetry(false);\n        } catch (error) {\n            console.warn('[AtmosphereClouds] Failed to fetch orbit clouds', error);\n            this._scheduleOrbitCloudsRetry(false);\n        } finally {\n            this._orbitCloudsInFlight = false;\n        }\n    }\n\n    async _fetchOrbitCloudsRawTexture(snapshotDate, snapshotKey) {\n        if (this._orbitCloudsRawInFlight) return;\n        if (typeof document === 'undefined') return;\n        this._orbitCloudsRawInFlight = true;\n        try {\n            const url = this._buildOrbitCloudsUrl(snapshotDate, 'raw');\n            const response = await getNoclipGovernanceClient().request(url, { mode: 'cors', governanceLane: 'scene' });\n            if (!response.ok) {\n                throw new Error(`Orbit cloud raw fetch failed: ${response.status}`);\n            }\n            const blob = await response.blob();\n            const image = await this._loadOrbitCloudsImage(blob);\n            const width = Math.max(256, Math.round(this._orbitClouds.width));\n            const height = Math.max(128, Math.round(this._orbitClouds.height));\n\n            if (!this._orbitCloudsRawCanvas) {\n                this._orbitCloudsRawCanvas = document.createElement('canvas');\n            }\n            const rawCanvas = this._orbitCloudsRawCanvas;\n            if (rawCanvas.width !== width || rawCanvas.height !== height) {\n                rawCanvas.width = width;\n                rawCanvas.height = height;\n            }\n            if (!this._orbitCloudsRawCtx) {\n                this._orbitCloudsRawCtx = rawCanvas.getContext('2d');\n            }\n            const rawCtx = this._orbitCloudsRawCtx;\n            if (!rawCtx) return;\n\n            rawCtx.setTransform(1, 0, 0, 1, 0, 0);\n            rawCtx.clearRect(0, 0, width, height);\n            if (this._orbitClouds.flipY) {\n                rawCtx.translate(0, height);\n                rawCtx.scale(1, -1);\n            }\n            rawCtx.drawImage(image, 0, 0, width, height);\n            if (image.close) {\n                image.close();\n            }\n\n            if (!this._orbitCloudsRawTexture) {\n                this._orbitCloudsRawTexture = new THREE.CanvasTexture(rawCanvas);\n                this._orbitCloudsRawTexture.minFilter = THREE.LinearFilter;\n                this._orbitCloudsRawTexture.magFilter = THREE.LinearFilter;\n                this._orbitCloudsRawTexture.wrapS = THREE.RepeatWrapping;\n                this._orbitCloudsRawTexture.wrapT = THREE.ClampToEdgeWrapping;\n                this._orbitCloudsRawTexture.colorSpace = THREE.NoColorSpace;\n            }\n            this._applyOrbitCloudOverlayMapping(this._orbitCloudsRawTexture);\n            this._orbitCloudsRawTexture.needsUpdate = true;\n            if (this._orbitCloudsRawMaterial && this._orbitCloudsRawMaterial.map !== this._orbitCloudsRawTexture) {\n                this._orbitCloudsRawMaterial.map = this._orbitCloudsRawTexture;\n                this._orbitCloudsRawMaterial.needsUpdate = true;\n            }\n            this._orbitCloudsRawLastKey = snapshotKey;\n            this._orbitCloudsRawLastFetchMs = Date.now();\n            this._resetOrbitCloudsRetry(true);\n        } catch (error) {\n            console.warn('[AtmosphereClouds] Failed to fetch orbit clouds raw overlay', error);\n            this._scheduleOrbitCloudsRetry(true);\n        } finally {\n            this._orbitCloudsRawInFlight = false;\n        }\n    }\n\n    _updateOrbitClouds() {\n        const orbitEnabled = this._orbitClouds.enabled && this.enabled;\n        if (!orbitEnabled) {\n            if (this._orbitCloudsMesh) this._orbitCloudsMesh.visible = false;\n            this._queueOrbitCloudVisibility(false);\n            if (this._earthMaterial?.uniforms?.orbitCloudsEnabled) {\n                this._earthMaterial.uniforms.orbitCloudsEnabled.value = 0.0;\n            }\n            return;\n        }\n\n        this._patchOrbitCloudsUvMapping();\n\n        this._ensureOrbitCloudsMesh();\n\n        this.camera.getWorldPosition(this._cameraWorldPosition);\n        const camRadius = this._cameraWorldPosition.length();\n        const ellipsoidR = ellipsoidRadiusForWorldDir(this._cameraWorldPosition, this.planetGroup);\n        const altitude = Math.max(0, camRadius - ellipsoidR);\n        const fadeStart = Math.max(0, this._orbitClouds.fadeStartM);\n        const fadeEnd = Math.max(fadeStart + 1, this._orbitClouds.fadeEndM);\n        const t = THREE.MathUtils.smoothstep(altitude, fadeStart, fadeEnd);\n\n        if (this._orbitCloudsMesh && this._orbitCloudsMaterial) {\n            const opacity = THREE.MathUtils.clamp(this._orbitClouds.opacity, 0, 1) * t;\n            this._orbitCloudsMesh.visible = opacity > 0.001;\n            this._orbitCloudsMaterial.opacity = opacity;\n        }\n        if (this._orbitCloudsRawMesh && this._orbitCloudsRawMaterial) {\n            const opacity = THREE.MathUtils.clamp(this._orbitClouds.opacity, 0, 1) * t;\n            this._orbitCloudsRawMesh.visible = this._orbitClouds.rawOverlay && opacity > 0.001;\n            this._orbitCloudsRawMaterial.opacity = opacity;\n        }\n\n        const snapshotDate = this._getOrbitCloudsSnapshotTime();\n        const width = Math.max(256, Math.round(this._orbitClouds.width));\n        const height = Math.max(128, Math.round(this._orbitClouds.height));\n        const snapshotKey = `${this._orbitClouds.layer}|${width}x${height}|${snapshotDate.toISOString()}`;\n        const refreshMs = Math.max(1, this._orbitClouds.refreshMinutes) * 60 * 1000;\n        const now = Date.now();\n        const stale = (now - this._orbitCloudsLastFetchMs) > refreshMs;\n        const needsFetch = !this._orbitCloudsTexture || this._orbitCloudsLastKey !== snapshotKey || stale;\n\n        if (needsFetch && !this._shouldDeferOrbitCloudsFetch(now, false)) {\n            this._fetchOrbitCloudsTexture(snapshotDate, snapshotKey);\n        }\n\n        const baseUrl = resolveOrbitCloudsBaseUrl(this._orbitClouds.baseUrl || '');\n        const isNasa = this._isOrbitCloudsNasa(baseUrl);\n        const rawStale = (now - this._orbitCloudsRawLastFetchMs) > refreshMs;\n        const needsRawFetch = !!this._orbitClouds.rawOverlay\n            && !isNasa\n            && (!this._orbitCloudsRawTexture || this._orbitCloudsRawLastKey !== snapshotKey || rawStale);\n        if (needsRawFetch && !this._shouldDeferOrbitCloudsFetch(now, true)) {\n            this._fetchOrbitCloudsRawTexture(snapshotDate, snapshotKey);\n        }\n\n        if (this._orbitCloudsEffect) {\n            if (this._orbitCloudsTexture && this._orbitCloudsEffect.localWeatherTexture !== this._orbitCloudsTexture) {\n                this._orbitCloudsEffect.localWeatherTexture = this._orbitCloudsTexture;\n            }\n            this._updateOrbitCloudDistanceTuning(altitude, camRadius);\n            this._applyOrbitCloudIntensity(t);\n            const canRender = this._orbitClouds.volumetricEnabled\n                && !this._orbitCloudsLodState.disabled\n                && t > 0.02\n                && !!this._orbitCloudsTexture;\n            this._queueOrbitCloudVisibility(canRender);\n        }\n    }\n\n    _applyOrbitCloudsConfig(config) {\n        if (!config || typeof config !== 'object') return;\n        const prevRadius = this._orbitClouds.radiusOffsetM;\n        const prevLayer = this._orbitClouds.layer;\n        const prevSize = `${this._orbitClouds.width}x${this._orbitClouds.height}`;\n        const prevBaseUrl = this._orbitClouds.baseUrl;\n        const prevNasaSnapshot = this._orbitClouds.nasaSnapshot;\n\n        if (typeof config.enabled === 'boolean') this._orbitClouds.enabled = config.enabled;\n        if (Number.isFinite(config.opacity)) this._orbitClouds.opacity = THREE.MathUtils.clamp(config.opacity, 0, 1);\n        if (Number.isFinite(config.radiusOffsetM)) {\n            this._orbitClouds.radiusOffsetM = Math.max(0, config.radiusOffsetM);\n            if (this._earthMaterial?.uniforms?.orbitCloudsShadowHeight) {\n                this._earthMaterial.uniforms.orbitCloudsShadowHeight.value = Math.max(0, this._orbitClouds.radiusOffsetM || 12000);\n            }\n        }\n        if (Number.isFinite(config.fadeStartM)) this._orbitClouds.fadeStartM = Math.max(0, config.fadeStartM);\n        if (Number.isFinite(config.fadeEndM)) this._orbitClouds.fadeEndM = Math.max(0, config.fadeEndM);\n        if (Number.isFinite(config.refreshMinutes)) this._orbitClouds.refreshMinutes = Math.max(1, config.refreshMinutes);\n        if (Number.isFinite(config.timeStepMinutes)) this._orbitClouds.timeStepMinutes = Math.max(1, config.timeStepMinutes);\n        if (Number.isFinite(config.width)) this._orbitClouds.width = Math.max(256, Math.round(config.width));\n        if (Number.isFinite(config.height)) this._orbitClouds.height = Math.max(128, Math.round(config.height));\n        if (typeof config.layer === 'string') this._orbitClouds.layer = config.layer;\n        if (typeof config.format === 'string') this._orbitClouds.format = config.format;\n        if (typeof config.baseUrl === 'string') this._orbitClouds.baseUrl = config.baseUrl;\n        if (typeof config.nasaSnapshot === 'boolean') this._orbitClouds.nasaSnapshot = config.nasaSnapshot;\n        if (Number.isFinite(config.alphaScale)) this._orbitClouds.alphaScale = Math.max(0, config.alphaScale);\n        if (Number.isFinite(config.alphaBias)) this._orbitClouds.alphaBias = config.alphaBias;\n        if (typeof config.flipY === 'boolean') this._orbitClouds.flipY = config.flipY;\n        if (typeof config.dateOnly === 'boolean') this._orbitClouds.dateOnly = config.dateOnly;\n        if (typeof config.rawOverlay === 'boolean') this._orbitClouds.rawOverlay = config.rawOverlay;\n        if (typeof config.debugOverlay === 'boolean') this._orbitClouds.debugOverlay = config.debugOverlay;\n        if (typeof config.volumetricEnabled === 'boolean') {\n            this._orbitClouds.volumetricEnabled = config.volumetricEnabled;\n        }\n        if (typeof config.qualityPreset === 'string') {\n            this._orbitClouds.qualityPreset = config.qualityPreset.toLowerCase();\n        }\n        if (Number.isFinite(config.resolutionScale)) {\n            this._orbitClouds.resolutionScale = THREE.MathUtils.clamp(config.resolutionScale, 0.1, 1);\n        }\n        if (Number.isFinite(config.coverageScale)) {\n            this._orbitClouds.coverageScale = Math.max(0, config.coverageScale);\n        }\n        if (Number.isFinite(config.scatteringScale)) {\n            this._orbitClouds.scatteringScale = Math.max(0, config.scatteringScale);\n        }\n        if (Number.isFinite(config.absorptionScale)) {\n            this._orbitClouds.absorptionScale = Math.max(0, config.absorptionScale);\n        }\n        if (Number.isFinite(config.turbulenceScale)) {\n            this._orbitClouds.turbulenceScale = Math.max(0, config.turbulenceScale);\n        }\n        if (Number.isFinite(config.maxRayDistance)) {\n            this._orbitClouds.maxRayDistance = Math.max(1, config.maxRayDistance);\n        }\n        if (Number.isFinite(config.cullAltitude)) {\n            this._orbitClouds.cullAltitude = Math.max(0, config.cullAltitude);\n        }\n        if (Number.isFinite(config.cullHysteresis)) {\n            this._orbitClouds.cullHysteresis = Math.max(0, config.cullHysteresis);\n        }\n\n        const sizeKey = `${this._orbitClouds.width}x${this._orbitClouds.height}`;\n        if (prevRadius !== this._orbitClouds.radiusOffsetM || !this._orbitCloudsMesh) {\n            this._orbitCloudsDirty = true;\n        }\n        if (prevLayer !== this._orbitClouds.layer || prevSize !== sizeKey || prevBaseUrl !== this._orbitClouds.baseUrl || prevNasaSnapshot !== this._orbitClouds.nasaSnapshot) {\n            this._orbitCloudsLastKey = null;\n            this._orbitCloudsRawLastKey = null;\n            this._resetOrbitCloudsRetry(false);\n            this._resetOrbitCloudsRetry(true);\n        }\n        if (this._orbitCloudsMaterial) {\n            this._orbitCloudsMaterial.opacity = THREE.MathUtils.clamp(this._orbitClouds.opacity, 0, 1);\n        }\n        if (this._orbitCloudsDirty) {\n            this._ensureOrbitCloudsMesh();\n            this._orbitCloudsDirty = false;\n        }\n        this._applyOrbitCloudEffectSettings();\n        this._applyCloudsEnabled();\n    }\n}\n","/**\n * Flashlight Module\n *\n * A toggleable spotlight attached to the camera for illuminating\n * the scene at night. Toggle with the G key (F pitches the 3D camera down).\n */\n\nimport * as THREE from 'three';\n\nconst DEFAULT_CONFIG = {\n    color: 0xffffff,\n    intensity: 50,           // Spotlight intensity\n    distance: 5000,          // Max range in meters\n    angle: Math.PI / 6,     // 30 degree cone angle\n    penumbra: 0.3,          // Soft edge falloff\n    decay: 1.1,             // Light falloff with distance\n    castShadow: false,      // Shadows are expensive, disabled by default\n    enabled: false          // Start with flashlight off\n};\n\nexport class Flashlight {\n    constructor(camera, options = {}) {\n        this.camera = camera;\n        this.config = { ...DEFAULT_CONFIG, ...options };\n\n        // Create the spotlight\n        this.light = new THREE.SpotLight(\n            this.config.color,\n            this.config.intensity,\n            this.config.distance,\n            this.config.angle,\n            this.config.penumbra,\n            this.config.decay\n        );\n\n        // Position slightly below camera center to simulate handheld flashlight\n        this.light.position.set(0, -0.1, 0);\n\n        // Target is in front of camera\n        this.target = new THREE.Object3D();\n        this.target.position.set(0, 0, -10);\n        this.light.target = this.target;\n\n        // Shadow configuration (if enabled)\n        if (this.config.castShadow) {\n            this.light.castShadow = true;\n            this.light.shadow.mapSize.width = 1024;\n            this.light.shadow.mapSize.height = 1024;\n            this.light.shadow.camera.near = 0.5;\n            this.light.shadow.camera.far = this.config.distance;\n        }\n\n        // Create a group to hold light and target\n        this.group = new THREE.Group();\n        this.group.name = 'Flashlight';\n        this.group.add(this.light);\n        this.group.add(this.target);\n\n        // Add to camera\n        this.camera.add(this.group);\n\n        // Set initial state\n        this.light.visible = this.config.enabled;\n        this._enabled = this.config.enabled;\n\n        // Bind key handler\n        this._onKeyDown = this._handleKeyDown.bind(this);\n        window.addEventListener('keydown', this._onKeyDown);\n    }\n\n    /**\n     * Handle keydown events\n     */\n    _handleKeyDown(event) {\n        if (event.repeat || event.ctrlKey || event.metaKey || event.altKey || event.isComposing || event.defaultPrevented) return;\n        // Ignore if user is typing in an input field\n        if (event.target.tagName === 'INPUT' ||\n            event.target.tagName === 'TEXTAREA' ||\n            event.target.isContentEditable) {\n            return;\n        }\n\n        // F belongs to 3D pitch-down; keep the flashlight an explicit toggle.\n        if (event.code === 'KeyG' || event.key === 'g' || event.key === 'G') {\n            this.toggle();\n        }\n    }\n\n    /**\n     * Toggle flashlight on/off\n     */\n    toggle() {\n        this._enabled = !this._enabled;\n        this.light.visible = this._enabled;\n        console.log(`[Flashlight] ${this._enabled ? 'ON' : 'OFF'}`);\n    }\n\n    /**\n     * Turn flashlight on\n     */\n    enable() {\n        this._enabled = true;\n        this.light.visible = true;\n    }\n\n    /**\n     * Turn flashlight off\n     */\n    disable() {\n        this._enabled = false;\n        this.light.visible = false;\n    }\n\n    /**\n     * Check if flashlight is currently on\n     */\n    get enabled() {\n        return this._enabled;\n    }\n\n    /**\n     * Set flashlight enabled state\n     */\n    set enabled(value) {\n        this._enabled = !!value;\n        this.light.visible = this._enabled;\n    }\n\n    /**\n     * Set flashlight intensity\n     */\n    setIntensity(intensity) {\n        this.light.intensity = intensity;\n    }\n\n    /**\n     * Set flashlight color\n     */\n    setColor(color) {\n        this.light.color.set(color);\n    }\n\n    /**\n     * Set flashlight beam angle (radians)\n     */\n    setAngle(angle) {\n        this.light.angle = angle;\n    }\n\n    /**\n     * Set flashlight range (meters)\n     */\n    setDistance(distance) {\n        this.light.distance = distance;\n        if (this.light.shadow) {\n            this.light.shadow.camera.far = distance;\n        }\n    }\n\n    /**\n     * Get configuration for serialization\n     */\n    getConfig() {\n        return {\n            enabled: this._enabled,\n            intensity: this.light.intensity,\n            color: this.light.color.getHex(),\n            distance: this.light.distance,\n            angle: this.light.angle,\n            penumbra: this.light.penumbra\n        };\n    }\n\n    /**\n     * Apply configuration\n     */\n    setConfig(config) {\n        if (config.enabled !== undefined) {\n            this.enabled = config.enabled;\n        }\n        if (config.intensity !== undefined) {\n            this.light.intensity = config.intensity;\n        }\n        if (config.color !== undefined) {\n            this.light.color.set(config.color);\n        }\n        if (config.distance !== undefined) {\n            this.setDistance(config.distance);\n        }\n        if (config.angle !== undefined) {\n            this.light.angle = config.angle;\n        }\n        if (config.penumbra !== undefined) {\n            this.light.penumbra = config.penumbra;\n        }\n    }\n\n    /**\n     * Dispose of the flashlight\n     */\n    dispose() {\n        window.removeEventListener('keydown', this._onKeyDown);\n        this.camera.remove(this.group);\n        this.light.dispose?.();\n    }\n}\n","export const RENDER_FRAME_OWNER = Object.freeze({\n    XR: 'xr',\n    STEREO: 'stereo',\n    HD_PROXY: 'hd-proxy',\n    PHOTOREAL_INTERIOR: 'photoreal-interior',\n    ATMOSPHERE_COMPOSITOR: 'atmosphere-compositor',\n    DIRECT_BASIC: 'direct-basic',\n    DIRECT_FALLBACK: 'direct-fallback',\n    DIRECT_NO_ATMOSPHERE: 'direct-no-atmosphere',\n    DIRECT_ATMOSPHERE: 'direct-atmosphere',\n});\n\n/**\n * One final-frame owner per animation frame.\n *\n * Auxiliary depth/normal/mask passes are not owners. An owner is recorded only\n * after a callback successfully returns a final frame, which makes compositor\n * failure and direct fallback observable without introducing another renderer.\n */\nexport class RenderFrameCoordinator {\n    constructor() {\n        this.frame = 0;\n        this.owner = null;\n        this.attempts = [];\n        this.metadata = null;\n    }\n\n    beginFrame(metadata = null) {\n        this.frame++;\n        this.owner = null;\n        this.attempts.length = 0;\n        this.metadata = metadata;\n        return this.frame;\n    }\n\n    render(owner, callback) {\n        this._assertUnclaimed(owner);\n        callback();\n        this.owner = owner;\n        this.attempts.push({ owner, outcome: 'rendered' });\n        return owner;\n    }\n\n    tryRender(owner, callback) {\n        this._assertUnclaimed(owner);\n        const rendered = callback() === true;\n        this.attempts.push({\n            owner,\n            outcome: rendered ? 'rendered' : 'yielded',\n        });\n        if (rendered) this.owner = owner;\n        return rendered;\n    }\n\n    yield(owner, reason = 'ineligible') {\n        this._assertUnclaimed(owner);\n        this.attempts.push({ owner, outcome: 'yielded', reason });\n    }\n\n    complete() {\n        if (!this.owner) {\n            throw new Error('Render frame completed without a final-frame owner');\n        }\n        return this.owner;\n    }\n\n    snapshot() {\n        return {\n            frame: this.frame,\n            owner: this.owner,\n            attempts: this.attempts.map((attempt) => ({ ...attempt })),\n            metadata: this.metadata,\n        };\n    }\n\n    _assertUnclaimed(nextOwner) {\n        if (!nextOwner) {\n            throw new Error('A final-frame owner name is required');\n        }\n        if (this.owner) {\n            throw new Error(\n                `Render frame already belongs to ${this.owner}; ${nextOwner} cannot render again`\n            );\n        }\n    }\n}\n","import * as THREE from 'three';\nimport { nightLightsGeodeticLatitude } from './NightLightsGeoreference.js';\n\nexport const NASA_NIGHT_LIGHTS_TILE_SOURCE = Object.freeze({\n  id: 'nasa-black-marble',\n  label: 'NASA Night Lights',\n  protocol: 'wmts',\n  url: 'https://gibs.earthdata.nasa.gov/wmts/epsg3857/best/VIIRS_Black_Marble/default/2016-01-01/GoogleMapsCompatible_Level8/{z}/{y}/{x}.png',\n  attribution: 'NASA EOSDIS GIBS · VIIRS Black Marble',\n  tileSize: 256,\n  maxNativeZoom: 8,\n});\n\nexport const NIGHT_LIGHTS_GLOBAL_ZOOM = 3;\nexport const NIGHT_LIGHTS_DETAIL_TILE_SPAN = 6;\n\nconst MAX_MERCATOR_LATITUDE_RAD = 1.4844222297453324;\nconst TWO_PI = Math.PI * 2;\n\nconst modulo = (value, divisor) => ((value % divisor) + divisor) % divisor;\nconst clamp = (value, min, max) => Math.min(max, Math.max(min, value));\n\nexport function nasaNightLightsTileUrl(z, x, y, template = NASA_NIGHT_LIGHTS_TILE_SOURCE.url) {\n  return String(template)\n    .replaceAll('{z}', String(z))\n    .replaceAll('{x}', String(x))\n    .replaceAll('{y}', String(y));\n}\n\nexport function planetLocalToWebMercator(position) {\n  const radius = Math.hypot(position?.x || 0, position?.y || 0, position?.z || 0);\n  if (!(radius > 0)) return { u: 0.5, v: 0.5, latitude: 0, longitude: 0 };\n\n  const latitude = nightLightsGeodeticLatitude(position);\n  const longitude = Math.atan2(position.x, position.z);\n  const mercatorLatitude = clamp(latitude, -MAX_MERCATOR_LATITUDE_RAD, MAX_MERCATOR_LATITUDE_RAD);\n  const sinLatitude = Math.sin(mercatorLatitude);\n  return {\n    u: modulo(longitude / TWO_PI + 0.5, 1),\n    v: clamp(\n      0.5 - 0.25 * Math.log((1 + sinLatitude) / (1 - sinLatitude)) / Math.PI,\n      0,\n      1,\n    ),\n    latitude,\n    longitude,\n  };\n}\n\nexport function nightLightsDetailZoomForAltitude(altitudeMeters, view = {}) {\n  const altitude = Number.isFinite(altitudeMeters) ? Math.max(1, altitudeMeters) : Infinity;\n  const height = Math.max(1, Number(view.viewportHeight) || 1080);\n  const fov = clamp(Number(view.fovDegrees) || 45, 1, 160) * Math.PI / 180;\n  const latitude = clamp(Number(view.latitudeDegrees) || 0, -85, 85) * Math.PI / 180;\n  const metresPerPixel = 2 * altitude * Math.tan(fov * .5) / height;\n  // Native Web-Mercator sampling; target at least one source texel per display\n  // pixel. Fixed altitude bands previously selected 8-16x coarser imagery.\n  const zoom = Math.ceil(Math.log2(156543.03392804097 * Math.cos(latitude) / metresPerPixel));\n  return clamp(zoom, NIGHT_LIGHTS_GLOBAL_ZOOM, NASA_NIGHT_LIGHTS_TILE_SOURCE.maxNativeZoom);\n}\n\nexport function createNightLightsTileWindow(u, v, zoom, tileSpan = NIGHT_LIGHTS_DETAIL_TILE_SPAN) {\n  const tileCount = 2 ** zoom;\n  const span = clamp(Math.round(tileSpan), 1, tileCount);\n  const focusX = modulo(Number.isFinite(u) ? u : 0.5, 1) * tileCount;\n  const focusY = clamp(Number.isFinite(v) ? v : 0.5, 0, 1 - Number.EPSILON) * tileCount;\n  const startX = modulo(Math.floor(focusX) - Math.floor(span / 2), tileCount);\n  const startY = clamp(Math.floor(focusY) - Math.floor(span / 2), 0, tileCount - span);\n  const spanUv = span / tileCount;\n\n  return {\n    zoom,\n    tileCount,\n    tileSpan: span,\n    startX,\n    startY,\n    centerU: modulo((startX + span * 0.5) / tileCount, 1),\n    minV: startY / tileCount,\n    spanU: spanUv,\n    spanV: spanUv,\n    key: `${zoom}:${startX}:${startY}:${span}`,\n  };\n}\n\nfunction windowContainsFocus(window, u, v, marginTiles = 1) {\n  if (!window) return false;\n  const wrappedDeltaU = modulo(u - window.centerU + 0.5, 1) - 0.5;\n  const localX = wrappedDeltaU / window.spanU + 0.5;\n  const localY = (v - window.minV) / window.spanV;\n  const margin = marginTiles / window.tileSpan;\n  return localX >= margin\n    && localX <= 1 - margin\n    && localY >= margin\n    && localY <= 1 - margin;\n}\n\n/**\n * Streams the exact WMTS source used by the 2D NASA Night Lights basemap into\n * two bounded CanvasTextures. The complete z3 atlas is the global/orbit\n * fallback; a camera-centred z4-z8 atlas is atomically swapped after its tile\n * window is ready so a moving surface view never flashes through to black.\n */\nexport class NasaNightLightsTileField {\n  constructor({\n    tileUrl = NASA_NIGHT_LIGHTS_TILE_SOURCE.url,\n    tileSize = NASA_NIGHT_LIGHTS_TILE_SOURCE.tileSize,\n    maxNativeZoom = NASA_NIGHT_LIGHTS_TILE_SOURCE.maxNativeZoom,\n    detailTileSpan = NIGHT_LIGHTS_DETAIL_TILE_SPAN,\n    concurrency = 6,\n    fetchImpl = globalThis.fetch?.bind(globalThis),\n    createCanvas = null,\n    onUpdate = null,\n  } = {}) {\n    this.tileUrl = tileUrl;\n    this.tileSize = tileSize;\n    this.maxNativeZoom = maxNativeZoom;\n    this.detailTileSpan = detailTileSpan;\n    this.concurrency = clamp(Math.round(concurrency), 1, 12);\n    this.fetchImpl = fetchImpl;\n    this.createCanvas = createCanvas;\n    this.onUpdate = typeof onUpdate === 'function' ? onUpdate : null;\n\n    this.enabled = true;\n    this.globalTexture = null;\n    this.detailTexture = null;\n    this.detailWindow = null;\n    this._pendingDetailWindow = null;\n    this._globalPromise = null;\n    this._detailPromise = null;\n    this._globalController = null;\n    this._detailController = null;\n    this._generation = 0;\n  }\n\n  get state() {\n    return {\n      globalTexture: this.globalTexture,\n      detailTexture: this.detailTexture,\n      detailWindow: this.detailWindow,\n      detailEnabled: !!(this.detailTexture && this.detailWindow),\n    };\n  }\n\n  setEnabled(enabled) {\n    const next = enabled === true;\n    if (this.enabled === next) return;\n    this.enabled = next;\n    if (!next) this.dispose();\n  }\n\n  ensureGlobal() {\n    if (!this.enabled || this.globalTexture) return Promise.resolve(this.globalTexture);\n    if (this._globalPromise) return this._globalPromise;\n\n    const generation = this._generation;\n    const controller = new AbortController();\n    this._globalController = controller;\n    const window = createNightLightsTileWindow(0.5, 0.5, NIGHT_LIGHTS_GLOBAL_ZOOM, 2 ** NIGHT_LIGHTS_GLOBAL_ZOOM);\n    const promise = this._loadAtlas(window, controller.signal, 'global')\n      .then((texture) => {\n        if (!texture || !this.enabled || generation !== this._generation) {\n          texture?.dispose?.();\n          return null;\n        }\n        this.globalTexture?.dispose?.();\n        this.globalTexture = texture;\n        this._notify();\n        return texture;\n      })\n      .catch((error) => {\n        if (error?.name !== 'AbortError') {\n          console.warn('[NasaNightLightsTileField] Global atlas failed:', error);\n        }\n        return null;\n      })\n      .finally(() => {\n        if (this._globalPromise === promise) this._globalPromise = null;\n        if (this._globalController === controller) this._globalController = null;\n      });\n    this._globalPromise = promise;\n    return promise;\n  }\n\n  updateForPlanetLocalPosition(position, planetRadius, view = {}) {\n    if (!this.enabled) return;\n    this.ensureGlobal();\n\n    const radius = Math.hypot(position?.x || 0, position?.y || 0, position?.z || 0);\n    const altitude = radius - (Number.isFinite(planetRadius) ? planetRadius : 0);\n    const focus = planetLocalToWebMercator(view.focusPosition || position);\n    const zoom = Math.min(this.maxNativeZoom, nightLightsDetailZoomForAltitude(altitude, { ...view, latitudeDegrees: focus.latitude * 180 / Math.PI }));\n    if (zoom <= NIGHT_LIGHTS_GLOBAL_ZOOM) {\n      this._detailController?.abort();\n      this._pendingDetailWindow = null;\n      this._replaceDetail(null, null);\n      return;\n    }\n\n    const height=Math.max(1,Number(view.viewportHeight)||1080),width=Math.max(height,Number(view.viewportWidth)||height);\n    const worldPerPixel=2*Math.max(1,altitude)*Math.tan(clamp(Number(view.fovDegrees)||45,1,160)*Math.PI/360)/height;\n    const tileMetres=40075016.686*Math.cos(focus.latitude)/(2**zoom);\n    const span=clamp(Math.ceil(width*worldPerPixel/tileMetres)+2,this.detailTileSpan,12);\n    if (this.detailWindow?.tileSpan >= span && this.detailWindow?.zoom === zoom && windowContainsFocus(this.detailWindow, focus.u, focus.v)) return;\n    if (this._pendingDetailWindow?.tileSpan >= span && this._pendingDetailWindow?.zoom === zoom\n      && windowContainsFocus(this._pendingDetailWindow, focus.u, focus.v, 0)) return;\n\n    const window = createNightLightsTileWindow(focus.u, focus.v, zoom, span);\n    if (window.key === this.detailWindow?.key || window.key === this._pendingDetailWindow?.key) return;\n    this._requestDetail(window);\n  }\n\n  _requestDetail(window) {\n    this._detailController?.abort();\n    const generation = this._generation;\n    const controller = new AbortController();\n    this._detailController = controller;\n    this._pendingDetailWindow = window;\n    const promise = this._loadAtlas(window, controller.signal, 'detail')\n      .then((texture) => {\n        if (!texture || !this.enabled || generation !== this._generation\n          || this._pendingDetailWindow?.key !== window.key) {\n          texture?.dispose?.();\n          return null;\n        }\n        this._replaceDetail(texture, window);\n        return texture;\n      })\n      .catch((error) => {\n        if (error?.name !== 'AbortError') {\n          console.warn('[NasaNightLightsTileField] Detail atlas failed:', error);\n        }\n        return null;\n      })\n      .finally(() => {\n        if (this._detailPromise === promise) this._detailPromise = null;\n        if (this._detailController === controller) this._detailController = null;\n        if (this._pendingDetailWindow?.key === window.key) this._pendingDetailWindow = null;\n      });\n    this._detailPromise = promise;\n  }\n\n  _replaceDetail(texture, window) {\n    if (this.detailTexture === texture && this.detailWindow === window) return;\n    const previous = this.detailTexture;\n    this.detailTexture = texture;\n    this.detailWindow = window;\n    previous?.dispose?.();\n    this._notify();\n  }\n\n  _notify() {\n    this.onUpdate?.(this.state);\n  }\n\n  _makeCanvas(width, height) {\n    if (this.createCanvas) return this.createCanvas(width, height);\n    if (typeof OffscreenCanvas !== 'undefined') return new OffscreenCanvas(width, height);\n    if (typeof document !== 'undefined') {\n      const canvas = document.createElement('canvas');\n      canvas.width = width;\n      canvas.height = height;\n      return canvas;\n    }\n    throw new Error('Canvas is unavailable for NASA night-light atlas assembly');\n  }\n\n  async _loadAtlas(window, signal, kind) {\n    if (!this.fetchImpl) throw new Error('Fetch is unavailable for NASA night-light tiles');\n    const canvas = this._makeCanvas(window.tileSpan * this.tileSize, window.tileSpan * this.tileSize);\n    const context = canvas.getContext('2d', { alpha: false });\n    if (!context) throw new Error('2D canvas context is unavailable for NASA night-light atlas assembly');\n    context.fillStyle = '#000';\n    context.fillRect(0, 0, canvas.width, canvas.height);\n\n    const jobs = [];\n    for (let row = 0; row < window.tileSpan; row++) {\n      for (let column = 0; column < window.tileSpan; column++) {\n        jobs.push({\n          x: modulo(window.startX + column, window.tileCount),\n          y: window.startY + row,\n          column,\n          row,\n        });\n      }\n    }\n\n    let cursor = 0;\n    let loaded = 0;\n    const worker = async () => {\n      while (cursor < jobs.length) {\n        if (signal.aborted) throw new DOMException('Aborted', 'AbortError');\n        const job = jobs[cursor++];\n        try {\n          const image = await this._loadTile(window.zoom, job.x, job.y, signal);\n          if (signal.aborted) throw new DOMException('Aborted', 'AbortError');\n          context.drawImage(\n            image,\n            job.column * this.tileSize,\n            job.row * this.tileSize,\n            this.tileSize,\n            this.tileSize,\n          );\n          image.close?.();\n          loaded++;\n        } catch (error) {\n          if (error?.name === 'AbortError') throw error;\n          // GIBS can return a sparse/no-data tile. The black canvas is the\n          // physically correct no-emission fallback for that cell.\n        }\n      }\n    };\n    await Promise.all(Array.from({ length: Math.min(this.concurrency, jobs.length) }, worker));\n    if (signal.aborted) throw new DOMException('Aborted', 'AbortError');\n    if (loaded === 0) throw new Error(`NASA night-light ${kind} atlas returned no usable tiles`);\n\n    const texture = new THREE.CanvasTexture(canvas);\n    texture.name = `NASA VIIRS Black Marble ${kind} z${window.zoom}`;\n    texture.colorSpace = THREE.NoColorSpace;\n    texture.flipY = false;\n    texture.wrapS = THREE.ClampToEdgeWrapping;\n    texture.wrapT = THREE.ClampToEdgeWrapping;\n    texture.minFilter = THREE.LinearMipmapLinearFilter;\n    texture.magFilter = THREE.LinearFilter;\n    texture.generateMipmaps = true;\n    texture.anisotropy = 4;\n    texture.needsUpdate = true;\n    texture.userData.nasaNightLightsWindow = { ...window };\n    return texture;\n  }\n\n  async _loadTile(z, x, y, signal) {\n    const url = nasaNightLightsTileUrl(z, x, y, this.tileUrl);\n    const response = await this.fetchImpl(url, {\n      signal,\n      mode: 'cors',\n      cache: 'force-cache',\n      credentials: 'omit',\n    });\n    if (!response.ok) throw new Error(`NASA night-light tile ${z}/${x}/${y} returned ${response.status}`);\n    const blob = await response.blob();\n    if (typeof createImageBitmap === 'function') return createImageBitmap(blob);\n\n    if (typeof document === 'undefined' || typeof URL === 'undefined') {\n      throw new Error('Image decoding is unavailable for NASA night-light tiles');\n    }\n    const objectUrl = URL.createObjectURL(blob);\n    try {\n      const image = new Image();\n      image.decoding = 'async';\n      image.crossOrigin = 'anonymous';\n      await new Promise((resolve, reject) => {\n        image.onload = resolve;\n        image.onerror = reject;\n        image.src = objectUrl;\n      });\n      return image;\n    } finally {\n      URL.revokeObjectURL(objectUrl);\n    }\n  }\n\n  dispose() {\n    this._generation++;\n    this._globalController?.abort();\n    this._detailController?.abort();\n    this._globalController = null;\n    this._detailController = null;\n    this._globalPromise = null;\n    this._detailPromise = null;\n    this._pendingDetailWindow = null;\n    this.globalTexture?.dispose?.();\n    this.detailTexture?.dispose?.();\n    this.globalTexture = null;\n    this.detailTexture = null;\n    this.detailWindow = null;\n    this._notify();\n  }\n}\n","/**\n * Scene Initializer Module\n *\n * Handles all Three.js scene initialization including:\n * - Renderer, scene, camera, and controls setup\n * - Lighting system and visual sun sphere\n * - Earth materials and atmosphere\n * - Hex selection visualization\n * - Auto-tilt camera behavior\n */\n\nimport * as THREE from 'three';\nimport { PhotorealInteriorRenderer } from '../refactor/render/PhotorealInterior.js';\nimport { Scheduler as TileScheduler } from '3d-tiles-renderer/core';\nimport { createSceneRenderer } from '../refactor/render/SceneRendererStartup.js';\nimport { XRSurfaceRig } from '../refactor/vr/XRSurfaceRig.js';\nimport { getHudInfoStore } from './hud-info-store.js';\nimport { OrbitControls } from 'three/addons/controls/OrbitControls.js';\nimport { RGBELoader } from 'three/addons/loaders/RGBELoader.js';\nimport { LightingSystem } from './lighting-system.js';\nimport { properMotionVector, julianYearsSinceJ2000 } from './celestial-frame.js';\nimport { skyLimitingMagnitude, SKY_VISIBILITY_GLSL } from './sky-visibility.js';\nimport { SkyFeatures } from './sky-features.js';\nimport { stellarFlux, stellarExposureCompensation } from './stellar-catalog-math.js';\nimport { getLabelSystem } from '../refactor/labels/LabelSystem.js';\nimport { FirstDrawGuard } from '../refactor/render/FirstDrawGuard.js';\nimport { readBoundedBytes } from '../refactor/shared/readBoundedBytes.js';\nimport { EffectComposer, RenderPass, EffectPass, BloomEffect, DepthOfFieldEffect, FXAAEffect } from 'postprocessing';\nimport { MotionBlurPass } from './motion-blur-pass.js';\nimport { LENS_DEFAULTS, normalizeLensConfig } from '../refactor/render/LensContract.js';\n// REMOVED: texture-loader.js - no longer loading static textures\nimport { createEarthMaterial, createAtmosphereMaterial } from './earth-material.js';\nimport { MoonSystem } from './moon-system.js';\nimport { OceanSurface } from './ocean-surface.js';\nimport { canStreamImageTextures, loadStreamedImageTexture } from '../refactor/render/StreamedImageTexture.js';\nimport { RegionalWaterMask } from '../refactor/imagery/RegionalWaterMask.js';\nimport { getOceanWaterLevel } from './ocean-water-level.js';\nimport { readOceanTier, demoteOceanTier } from './ocean-quality.js';\nimport { LensFlareEffect } from './LenseFlare.js';\nimport { SOLAR_DISC_DEFAULTS, solarDiscRadianceScale } from '../refactor/render/SolarOpticsContract.js';\nimport { SolarOpticsRenderer } from '../refactor/render/SolarOpticsRenderer.js';\nimport { HdSceneProxy, HD_PROXY_LIMITS } from '../refactor/render/HdSceneProxy.js';\nimport { resolveBackendApiUrl, hasBackendOverride, isLocalRuntime } from '../refactor/shared/backend.js';\nimport {\n    CAMERA_NEAR,\n    CAMERA_FAR,\n    PLANET_RADIUS,\n    EARTH_ORBIT_MAX_DISTANCE_M,\n    SUN_EARTH_DISTANCE_M,\n    SUN_RADIUS_M,\n    MOON_RADIUS_M,\n    ATMOSPHERE_RADIUS_M,\n    AXIAL_TILT_RAD,\n    ALT_10K_UNITS,\n    ALT_30K_UNITS,\n    DEG2RAD\n} from './constants.js';\nimport { TerrainPathfinder } from './terrain-pathfinder.js';\nimport { AtmosphereCloudsSystem } from './atmosphere-clouds-system.js';\nimport { Flashlight } from './flashlight.js';\nimport { ellipsoidRadiusForWorldDir, ellipsoidRadiusForLocalDir, dirToLatLonLocal } from './geometry-utils.js';\nimport { enforceCelestialOpaqueDepthMaterial } from '../refactor/render/CelestialOcclusionContract.js';\nimport {\n    RENDER_FRAME_OWNER,\n    RenderFrameCoordinator,\n} from '../refactor/render/RenderFrameCoordinator.js';\nimport {\n    ASTRONOMICAL_LENS_FLARE_DEFAULTS,\n    lambertianSpherePhase,\n    orbitalExposureResponseSeconds,\n    ORBITAL_HDR_EXPOSURE_DEFAULTS,\n    POSTPROCESS_BLOOM_DEFAULTS,\n    resolveOrbitalHdrExposureTarget,\n    STAR_SCINTILLATION_DEFAULTS,\n} from '../refactor/render/PostProcessingContract.js';\nimport {\n    PHOTOREAL_OCEAN_DEFAULTS,\n} from '../refactor/tiles/PhotorealAppearanceContract.js';\nimport {\n    NASA_NIGHT_LIGHTS_TILE_SOURCE,\n    NasaNightLightsTileField,\n} from '../refactor/imagery/NasaNightLightsTileField.js';\nimport {\n    NIGHT_LIGHTS_EMISSION_DEFAULTS,\n} from '../refactor/render/NightLightsEmissionContract.js';\nimport {\n    resolveSceneRuntimeBasePath,\n    resolveSceneRuntimeResource,\n} from '../refactor/scene/SceneRuntimeResources.js';\nimport {\n    apparentAngularRadius,\n    ATMOSPHERIC_TRANSMITTANCE_GLSL,\n    atmosphericTransmittance,\n    finiteSourceVisibility,\n} from '../refactor/render/CelestialIrradianceContract.js';\n\nconst DEFAULT_HDR_URL = resolveSceneRuntimeResource('/textures/venice_sunset_1k.hdr');\nconst MATTEASON_LIVE_CLOUD_MAPS_BASE_URL = 'https://clouds.matteason.co.uk/images/8192x4096';\nconst EARTH_SPECULAR_TEXTURE_URL = resolveSceneRuntimeResource('/textures/8k_earth_specular_map.png');\nconst EARTH_SIMPLE_CLOUDS_TEXTURE_URL = `${MATTEASON_LIVE_CLOUD_MAPS_BASE_URL}/clouds-alpha.png`;\nconst EARTH_SIMPLE_CLOUDS_REFRESH_MS = 3 * 60 * 60 * 1000;\nconst EARTH_WATER_NORMALS_TEXTURE_URL = resolveSceneRuntimeResource('/textures/waternormals.jpg');\nconst PUBLIC_LIGHT_POLLUTION_WMS_URL = 'https://gibs.earthdata.nasa.gov/wms/epsg4326/best/wms.cgi';\nconst PUBLIC_LIGHT_POLLUTION_LAYER = 'VIIRS_Black_Marble';\nconst LEGACY_NIGHT_LIGHTS_IMAGE_SERVER = 'https://ic.img.arcgis.com/arcgis/rest/services/VIIRS/NighttimeLightsMDNB/ImageServer';\nconst NIGHT_LIGHTS_IMAGE_SERVER = PUBLIC_LIGHT_POLLUTION_WMS_URL;\nconst NIGHT_LIGHTS_RENDERING_RULE = { rasterFunction: 'Average Monthly Radiance (Raw Values)' };\nconst DEFAULT_TONE_MAPPING_EXPOSURE = ORBITAL_HDR_EXPOSURE_DEFAULTS.deepSpaceExposure;\n// Ground-level imagery is display-referred (not an HDR orbital plate). The\n// old surface branch inherited the 10x deep-space exposure, clipping roofs and\n// making the XR sky appear black by comparison. Keep a calibrated, bounded\n// ground exposure while the astronomical meter is reserved for orbit.\nconst SURFACE_TONE_MAPPING_EXPOSURE = 1.6;\nconst MAX_MERCATOR = 20037508.342789244;\nconst WORLD_BBOX_MERCATOR = `${-MAX_MERCATOR},${-MAX_MERCATOR},${MAX_MERCATOR},${MAX_MERCATOR}`;\nconst isPlainObject = (value) => {\n    if (!value || typeof value !== 'object') return false;\n    return Object.prototype.toString.call(value) === '[object Object]';\n};\nconst mergeDeep = (target, source) => {\n    const out = isPlainObject(target) ? { ...target } : {};\n    if (!isPlainObject(source)) return out;\n    Object.entries(source).forEach(([key, value]) => {\n        if (isPlainObject(value)) {\n            out[key] = mergeDeep(out[key], value);\n        } else if (Array.isArray(value)) {\n            out[key] = value.map((entry) => (isPlainObject(entry) ? mergeDeep({}, entry) : entry));\n        } else {\n            out[key] = value;\n        }\n    });\n    return out;\n};\n\nexport class SceneInitializer {\n    constructor(container, options = {}) {\n        this.container = container;\n        this.options = options;\n        this.environmentHdrUrl = options.environmentHdrUrl || DEFAULT_HDR_URL;\n        this._environmentStreamingEnabled = options.environmentStreamingEnabled !== false;\n        this._environmentHdrLoading = false;\n        this._frameCoordinator = new RenderFrameCoordinator();\n        this._lastRenderOwner = null;\n        this._postCompositeLayers = new Map();\n\n        // Scene components\n        this.renderer = null;\n        this.scene = null;\n        this.camera = null;\n        this.controls = null;\n        this.renderScale = 1;\n        this._lastClientWidth = 0;\n        this._lastClientHeight = 0;\n        this._lastRenderWidth = 0;\n        this._lastRenderHeight = 0;\n        this.lightingSystem = null;\n        this.sunMesh = null;\n        this.lensFlare = null;\n        this.lensFlareEnabled = true;\n        this._astronomicalLensFlareSuppressed = false;\n        this._surfaceLensFlareSuppressed = false;\n        this._orbitalSolarExposure = DEFAULT_TONE_MAPPING_EXPOSURE;\n        this.moonSystem = null;\n        this.flashlight = null;\n        this.starField = null;\n        this.galaxyField = null;\n        this.starFieldGroup = null; // Inertial reference group for starfield rotation\n        this.worldRoot = null; // World root for floating origin system\n        this._hdrEnvMap = null;\n        this.terrainPathfinder = new TerrainPathfinder();\n        this.pathWeights = {\n            lateralMaxDeg: 1,\n            stepsS: 200,\n            stepsT: 33,\n            weightUphill: 4,\n            weightDownhill: 1.1,\n            weightElevDelta: 3.3,\n            weightSlopeSq: 0,\n            weightLateral: 2,\n            weightDistance: 4,\n            weightHigh: 1.1,\n            weightRough: 1.75,\n            smoothIterations: 5\n        };\n\n        // Earth materials\n        this.atmosphereMesh = null;\n        this.atmosphereMaterial = null;\n        this.atmosphereDepthTarget = null;\n        this._atmosphereDepthMaterial = null;\n        this._tmpSize = new THREE.Vector2();\n        this._tmpVec3 = new THREE.Vector3();\n        this._tmpClearColor = new THREE.Color();\n        this._tmpCameraQuat = new THREE.Quaternion();\n        this._motionTmpOrigin = new THREE.Vector3();\n        this._motionTmpQuat = new THREE.Quaternion();\n        this.atmosphereDepthScale = 1.0;\n        this.atmosphereDepthUnitMeters = 1000;\n        this.atmosphereSampleScale = 1.0;\n        this.atmosphereTuning = {};\n        this.atmosphereBase = null;\n        this.atmosphereLayer = 1;\n        this._earthSpecularTexture = null;\n        this._earthSimpleCloudsTexture = null;\n        this._lightPollutionTexture = null;\n        this._lightPollutionDetailTexture = null;\n        this._lightPollutionDetailWindow = null;\n        this._nightLightsTileField = null;\n        this._lightPollutionKey = null;\n        this._earthWaterNormalsTexture = null;\n        this._earthOverlayConfig = {\n            specularMap: { enabled: true, strength: 0.9 },\n            simpleClouds: {\n                enabled: true,\n                opacity: 1,\n                shadowStrength: 1,\n                shadowHeightMeters: 12600,\n                blendMode: 'overlay',\n                alphaThreshold: 0,\n                alphaSoftness: 1,\n                nightAirglowColor: '#9fb3c2',\n                nightAirglowStrength: 0.006\n            },\n            lightPollution: {\n                enabled: false,\n                intensity: NIGHT_LIGHTS_EMISSION_DEFAULTS.intensity,\n                mapGain: NIGHT_LIGHTS_EMISSION_DEFAULTS.mapGain,\n                surfaceIntensityScale:\n                    NIGHT_LIGHTS_EMISSION_DEFAULTS.surfaceIntensityScale,\n                emissionThreshold: NIGHT_LIGHTS_EMISSION_DEFAULTS.emissionThreshold,\n                emissionSoftness: NIGHT_LIGHTS_EMISSION_DEFAULTS.emissionSoftness,\n                emissionPower: NIGHT_LIGHTS_EMISSION_DEFAULTS.emissionPower,\n                emissionBlueSuppression:\n                    NIGHT_LIGHTS_EMISSION_DEFAULTS.emissionBlueSuppression,\n                color: '#ffb57a',\n                source: 'nasa-gibs-wmts-tiles',\n                tileUrl: NASA_NIGHT_LIGHTS_TILE_SOURCE.url,\n                maxNativeZoom: NASA_NIGHT_LIGHTS_TILE_SOURCE.maxNativeZoom,\n                mercator: true\n            },\n            water: {\n                enabled: true,\n                opacity: PHOTOREAL_OCEAN_DEFAULTS.opacity,\n                color: PHOTOREAL_OCEAN_DEFAULTS.color,\n                normalScale: 0.7,\n                distortion: 0.35,\n                specularStrength: 1.1,\n                specularPower: 64,\n                fresnelStrength: 0.6,\n                fresnelPower: 5,\n                uvScale: 1.2,\n                speed: 0.25\n            }\n        };\n        this._earthOverlayPromise = null;\n        this._earthOverlayLoading = false;\n        // Overview mode deliberately renders a lightweight fallback globe. Do\n        // not decode or upload the high-resolution surface overlays until the\n        // user enters a local view where their detail is visible.\n        this._earthOverlayStreamingEnabled = true;\n        // Orbital overview may warm the bounded NASA night-light tile field,\n        // but never projects it as replacement imagery. Emission begins only\n        // after provider terrain owns the frame and supplies real depth.\n        this._orbitalOverviewStreamingEnabled = false;\n        this._earthOverlayGeneration = 0;\n        this._earthSimpleCloudsPromise = null;\n        this._earthSimpleCloudsRefreshSlot = null;\n        this._lightPollutionPromise = null;\n        this._atmosphereCompositeScene = null;\n        this._atmosphereCompositeCamera = null;\n        this._atmosphereCompositeQuad = null;\n        // Atmosphere depth pre-pass thresholds (relaxed for better performance)\n        // Staleness cap for the atmosphere depth pre-pass. This is a FULL extra\n        // scene render, so it must not run every frame. 200ms means a fully\n        // static camera refreshes depth ~5x/sec (imperceptible for the soft,\n        // horizon-aligned atmosphere blend); real camera/planet motion triggers\n        // refreshes via the eps gates in _shouldUpdateAtmosphereDepth, which are\n        // additionally throttled to every-other-frame during continuous motion.\n        this.atmosphereDepthUpdateMs = 200;\n        this.atmosphereDepthMoveEps = 20; // Allow more camera movement before update\n        this.atmosphereDepthRotateEps = 0.02; // ~1.15° rotation threshold (was 0.11°)\n        this.atmosphereDepthPlanetRotateEps = 0.005; // ~0.29° planet rotation threshold\n        this._atmosphereDepthLastUpdate = 0;\n        this._atmosphereDepthLastCamPos = new THREE.Vector3();\n        this._atmosphereDepthLastCamQuat = new THREE.Quaternion();\n        this._atmosphereDepthLastProj = new THREE.Matrix4();\n        this.planetGroup = null;\n        this._atmosphereDepthLastPlanetQuat = new THREE.Quaternion();\n        this._atmosphereDepthTmpPlanetQuat = new THREE.Quaternion();\n        this._atmosphereDepthDirty = true;\n        this._atmosphereDepthShaderWarmupState = 'idle';\n        this._atmosphereDepthShaderWarmupGeneration = 0;\n        this._lowFpsMode = false;\n        this._depthPassExcludeObjects = []; // Objects/groups to exclude from atmosphere depth passes\n        this._perf = null;\n        this._perfStart = () => {};\n        this._perfEnd = () => {};\n\n        // Bloom + emissive tuning\n        this._bloomEnabled = false;\n        this._bloomSettings = { ...POSTPROCESS_BLOOM_DEFAULTS };\n        this._bloomComposer = null;\n        this._bloomRenderPass = null;\n        this._bloomEffect = null;\n        this._bloomEffectPass = null;\n        this._lensSettings = normalizeLensConfig({}, LENS_DEFAULTS);\n        this._lensVersion = 0;\n        this._lensAppliedVersion = -1;\n        this._lensAppliedTarget = null;\n        this._depthOfFieldEnabled = false;\n        this._depthOfFieldSettings = {\n            autofocus: true,\n            focusDistance: 25,\n            focalLength: 12,\n            bokehScale: 2.5,\n            resolutionScale: 0.5,\n            response: 0.18,\n            sampleIntervalMs: 140,\n            maxFocusDistance: 2_000_000\n        };\n        // When auto-focus is enabled, derive depth-of-field range from hit distance\n        // (about 1/4 of the center-focus distance). We avoid hard-coded tiny caps\n        // so long-distance surfaces can still maintain a usable field envelope.\n        this._depthOfFieldAutoRangeScale = 0.25;\n        this._depthOfFieldAutoRangeMin = 0.5;\n        this._depthOfFieldEffect = null;\n        this._depthOfFieldPass = null;\n        this._depthOfFieldTargetProvider = null;\n        this._depthOfFieldRaycaster = new THREE.Raycaster();\n        this._depthOfFieldNdc = new THREE.Vector2(0, 0);\n        this._depthOfFieldFocusDistance = 25;\n        this._depthOfFieldFocusTarget = 25;\n        this._depthOfFieldLastSampleAt = 0;\n        this._motionBlurEnabled = false;\n        this._motionBlurSettings = {\n            intensity: 0.55,\n            maxSpeed: 300,\n            smoothing: 0.2,\n            dampMin: 0.85,\n            dampMax: 0.985\n        };\n        this._motionBlurPass = null;\n        this._motionBlurStrength = 0;\n        this._motionBlurSpeed = 0;\n        this._motionBlurPrevEnabled = false;\n        this._fxaaEnabled = false;\n        this._fxaaEffect = null;\n        this._fxaaPass = null;\n        this._speedFovEnabled = false;\n        this._speedFovSettings = {\n            baseFov: null,\n            maxBoost: 8,\n            maxSpeed: 300,\n            smoothing: 0.15\n        };\n        this._speedFovBase = null;\n        this._speedFovCurrent = null;\n        this._speedFovSpeed = 0;\n        this._motionLastPos = new THREE.Vector3();\n        this._motionLastTime = null;\n        this._motionHasSample = false;\n        this._emissiveConfig = {\n            materialIntensity: 1,\n            materialColor: '#ffffff',\n            starfieldIntensity: 1,\n            galaxyIntensity: 1,\n            sunIntensity: 1\n        };\n        this._emissiveDirty = true;\n        this._emissiveLastApply = 0;\n        this._emissiveRefreshIntervalMs = 2000;\n\n        // Takram atmosphere + clouds system (geospatial port)\n        this.atmosphereClouds = null;\n        this.atmosphereCloudsFailed = false;\n        // The compact overview globe is a standalone surface with no valid\n        // photoreal G-buffer contract. Keep it on the continuous direct\n        // atmosphere path at every orbital altitude; this state is forwarded\n        // whenever the optional Takram system is (re)created.\n        this._atmosphereOrbitalOverviewActive = false;\n        this._atmosphereCloudStreamingEnabled = options.atmosphereCloudStreamingEnabled !== false;\n        this._atmosphereCloudsSetupRequested = false;\n        this._atmosphereCloudsSetupRequestedAt = 0;\n        this._atmosphereCloudRenderFailures = 0;\n        this._atmosphereCompositorRenderedAt = 0;\n        this._lastAtmosphereCloudRenderFailureLog = 0;\n        this._atmosphereCloudRecoveryTimer = null;\n        this._forceLegacyAtmosphereUntil = 0;\n        this.atmosphereEnabled = true;\n        this._atmosphereCloudsConfig = null;\n        this.weatherSystem = null;\n        this._weatherConfig = null;\n\n        // Hex visualization\n        this.hexLine = null;\n        this.hexGeometry = null;\n        this.hexPathLine = null;\n        this.hexPathGeometry = null;\n        this.hexTargetOpacity = 0;\n        this.hexFadeInSpeed = 6;\n        this.hexFadeOutSpeed = 3;\n\n        // VR/XR support\n        // The dolly (rig) is the player's position in world space\n        // Camera is a child of dolly - in VR, the headset controls local camera position/rotation\n        this.vrDolly = null;\n        this.vrButton = null;\n        this.xrPresenting = false;\n        this._xrSessionStartCallback = null;\n        this._xrSessionEndCallback = null;\n        this._vrEyeHeight = 1.7; // Default eye height in meters\n\n        // Initialize scene\n        this.initializeScene();\n    }\n\n    initializeScene() {\n        // A hybrid GPU may reject high-performance/MSAA admission. Retry once\n        // with default GPU selection and no MSAA, retaining logarithmic depth\n        // and HDR output. The boot owner retries transient admission in place.\n        const startup = createSceneRenderer();\n        this.renderer = startup.renderer;\n        this.rendererStartupProfile = startup.profile;\n        window.__noclipGraphicsStartup = { status: 'ready', profile: startup.profile, attempts: startup.attempts };\n        if (this.renderer.debug) {\n            this.renderer.debug.checkShaderErrors = false;\n        }\n        const width = this.container.clientWidth;\n        const height = this.container.clientHeight;\n        // Keep render resolution fixed. Pixel-ratio/render-scale changes break\n        // raycasting, overlay alignment, and photoreal tile projection.\n        this.renderScale = 1;\n        this.renderer.setPixelRatio(1);\n\n        // Set canvas CSS to full container size\n        this.renderer.domElement.style.width = '100%';\n        this.renderer.domElement.style.height = '100%';\n\n        // Internal render buffer matches the display size.\n        const renderWidth = Math.floor(width * this.renderScale);\n        const renderHeight = Math.floor(height * this.renderScale);\n        this.renderer.setSize(renderWidth, renderHeight, false);\n        this._lastClientWidth = width;\n        this._lastClientHeight = height;\n        this._lastRenderWidth = renderWidth;\n        this._lastRenderHeight = renderHeight;\n        this.renderer.toneMapping = THREE.AgXToneMapping;\n        this.renderer.toneMappingExposure = DEFAULT_TONE_MAPPING_EXPOSURE;\n        // Keep Three's global shadow pass OFF during the normal geospatial\n        // render lifecycle. With r185 + KHR_parallel_shader_compile, enabling\n        // one astronomical-scale shadow caster injects USE_SHADOWMAP into\n        // every visible program. On the live NVIDIA/ANGLE path the first\n        // MeshBasicMaterial then blocks ACTIVE_UNIFORMS reflection for\n        // roughly 18 seconds. The r185 3D Tiles reference also renders with\n        // the global shadow map disabled. Cloud shadows remain in the Takram\n        // atmosphere pipeline; the explicit sun-study ShadowPass may opt in.\n        // Do not turn this back on as a renderer default without a live\n        // noclip.org trace proving that first-frame program reflection stays\n        // non-blocking.\n        this.renderer.shadowMap.enabled = false;\n        this.renderer.shadowMap.autoUpdate = false;\n        this.container.appendChild(this.renderer.domElement);\n        this.renderer.domElement.addEventListener('contextmenu', e => e.preventDefault());\n        this._installContextLossHandlers();\n\n        // Create scene\n        this.scene = new THREE.Scene();\n        this.scene.background = new THREE.Color('#000000');\n        if (this._environmentStreamingEnabled) {\n            this.loadEnvironmentHDR();\n        }\n\n        // Depth target for atmosphere scattering clamp\n        this.setupAtmosphereDepthTarget();\n\n        // Create camera\n        this.camera = new THREE.PerspectiveCamera(\n            45,\n            this.container.clientWidth / this.container.clientHeight,\n            CAMERA_NEAR,\n            CAMERA_FAR\n        );\n        this.camera.position.set(0, 0, PLANET_RADIUS * 3);\n        this.camera.lookAt(0, 0, 0);\n\n        // VR Dolly (rig) setup\n        // In VR, the camera is a child of the dolly. The dolly's position is the player's feet position.\n        // The headset controls the camera's local position/rotation within the dolly.\n        // CRITICAL: For Three.js WebXR, the camera MUST be a child of a group for proper positioning.\n        this.vrDolly = new THREE.Group();\n        this.vrDolly.name = 'vr-dolly';\n        this.vrDolly.userData.isVRCameraRig = true;\n        this.vrDolly.add(this.camera);\n        this.scene.add(this.vrDolly);\n\n        // For non-VR mode, reset camera to local origin (dolly controls world position)\n        // The camera.position is relative to dolly in VR, but in non-VR we move the camera directly\n        // We'll handle this in the XR session callbacks\n\n        // Enable WebXR\n        this.renderer.xr.enabled = true;\n        try {\n            this.renderer.xr.setReferenceSpaceType('local-floor');\n        } catch (e) {\n            try {\n                this.renderer.xr.setReferenceSpaceType('local');\n            } catch (e2) {\n                console.warn('[VR] Could not set reference space type:', e2);\n            }\n        }\n\n        // HudManager/VRManager own the capability, eligibility and session\n        // lifecycle. A second Three VRButton bypasses that shared entry path.\n\n        // XR session handlers\n        this._setupXRSessionHandlers();\n\n        // Create orbit controls\n        this.controls = new OrbitControls(this.camera, this.renderer.domElement);\n        this.controls.enableDamping = true;\n        this.controls.dampingFactor = 0.08;\n        this.controls.minDistance = PLANET_RADIUS + 2.0;\n        this.controls.maxDistance = EARTH_ORBIT_MAX_DISTANCE_M;\n        this.controls.target.set(0, 0, 0);\n        this.controls.enablePan = false; // Keep focus on globe center\n\n        // Create lighting system\n        this.lightingSystem = new LightingSystem(this.scene, PLANET_RADIUS, SUN_EARTH_DISTANCE_M);\n        this.lightingSystem.updateSunPosition(new Date());\n\n        // Takram atmosphere + clouds system (postprocessing-based). It owns\n        // volumetric textures and render targets, so overview startup may\n        // explicitly defer its allocation until local detail is requested.\n        if (this._atmosphereCloudStreamingEnabled) {\n            this._setupAtmosphereClouds();\n        }\n\n        // Moon system\n        this.moonSystem = new MoonSystem(this.scene, PLANET_RADIUS, {\n            renderer: this.renderer,\n            camera: this.camera,\n            mobile: this.renderer?.domElement?.clientWidth > 0 && this.renderer.domElement.clientWidth < 768,\n        });\n        this.moonSystem.update(\n            this.lightingSystem.currentDate,\n            this.lightingSystem.getCelestialEphemeris(),\n        );\n\n        // Camera-attached flashlight (toggle with G key)\n        this.flashlight = new Flashlight(this.camera, {\n            intensity: 8,\n            distance: 300,\n            angle: Math.PI / 5,  // ~36 degree cone\n            penumbra: 0.4,\n            enabled: false\n        });\n\n        // Create visual sun sphere\n        this.createSunMesh();\n        this._syncAtmosphereCelestialOccluders();\n        this.createLensFlare();\n\n        // Create hex selector visualization\n        this.createHexVisualization();\n\n        // Load the compact sky map only during boot. The full BSC5 catalog is\n        // several MB and competes directly with photoreal terrain.\n        this._starFieldTimer = setTimeout(() => this.createStarField({ highDetail: false }), 2500);\n    }\n\n    setLowFpsMode(active) {\n        // General scene pressure does not own cloud fidelity. Its independent\n        // hard-stall policy consumes actual foreground frame timings below.\n        this._lowFpsMode = !!active;\n    }\n\n    updateCloudQualityPressure(frameMs, visible) {\n        this.atmosphereClouds?.updateQualityPressure?.(frameMs, visible && this._hdSceneProxy?.stats.ready !== true);\n    }\n\n    // ─────────────────────────────────────────────────────────────────────────\n    // VR/XR Session Handling\n    // ─────────────────────────────────────────────────────────────────────────\n\n    _setupXRSessionHandlers() {\n        const xr = this.renderer?.xr;\n        if (!xr) return;\n\n        xr.addEventListener('sessionstart', () => {\n            // Immersive browsers can suspend window RAF while native XR keeps\n            // rendering. Move upstream queues/LRU/throttles to that same session;\n            // setXRSession also settles work pending on the previous clock.\n            TileScheduler.setXRSession(xr.getSession());\n            getHudInfoStore({ root: globalThis.document || null }).setPresentationSuspended(true);\n            this.xrPresenting = true;\n            this._xrControlsEnabled = this.controls?.enabled;\n            this._xrCameraAutoUpdate = xr.cameraAutoUpdate;\n            this._xrSurfaceRig = this._xrSurfaceController?.enterVRMode()\n                || new XRSurfaceRig(this.vrDolly, this.camera);\n            this.camera.position.set(0, 0, 0);\n            this.camera.quaternion.identity();\n            this._xrSurfaceRig.apply();\n            // Publish both native eye poses before LOD/sky consumers.\n            xr.cameraAutoUpdate = false;\n            if (this.controls) this.controls.enabled = false;\n            this._xrSessionStartCallback?.();\n        });\n\n        xr.addEventListener('sessionend', () => {\n            TileScheduler.setXRSession(null);\n            getHudInfoStore({ root: globalThis.document || null }).setPresentationSuspended(false);\n            this.xrPresenting = false;\n            if (this._xrSurfaceRig) {\n                if (this._xrSurfaceController?._xrSurfaceRig === this._xrSurfaceRig) {\n                    this._xrSurfaceController.exitVRMode();\n                } else {\n                    this._xrSurfaceRig.restore();\n                }\n                this._xrSurfaceRig = null;\n            }\n            xr.cameraAutoUpdate = this._xrCameraAutoUpdate ?? true;\n            if (this.controls) this.controls.enabled = this._xrControlsEnabled;\n            this._xrSessionEndCallback?.();\n        });\n    }\n\n    setXRSurfaceController(controller) {\n        this._xrSurfaceController = controller;\n        controller?.setVRDolly(this.vrDolly);\n    }\n\n    syncXRCamera() {\n        if (!this.renderer?.xr?.isPresenting || !this._xrSurfaceRig) return false;\n        const rigApplied = this._xrSurfaceController?._xrSurfaceRig === this._xrSurfaceRig\n            && typeof this._xrSurfaceController?.commitVRRigPose === 'function';\n        this._xrSurfaceController?.commitVRRigPose();\n        const synced = this._xrSurfaceRig.sync(this.renderer.xr, { rigApplied });\n        if (!synced) return false;\n        // Calibration becomes available inside sync(). Reconcile the native\n        // local-floor origin immediately and republish both eyes in this same\n        // frame so controllers/feet cannot spend one render below a refined\n        // photoreal surface.\n        if (this._xrSurfaceController?.alignXRReferenceFloor?.()) {\n            this._xrSurfaceController.commitVRRigPose();\n            return this._xrSurfaceRig.sync(this.renderer.xr, { rigApplied });\n        }\n        return true;\n    }\n\n    /**\n     * Set callback for XR session start (called after dolly is positioned)\n     */\n    setXRSessionStartCallback(callback) {\n        this._xrSessionStartCallback = callback;\n    }\n\n    /**\n     * Set callback for XR session end (called after camera is restored)\n     */\n    setXRSessionEndCallback(callback) {\n        this._xrSessionEndCallback = callback;\n    }\n\n    /**\n     * Position the VR dolly at a specific world position\n     * Use this to teleport the user in VR\n     */\n    setVRDollyPosition(worldPos, yawRad = null) {\n        if (!this.vrDolly) return;\n\n        this.vrDolly.position.copy(worldPos);\n\n        if (yawRad !== null) {\n            this.vrDolly.rotation.set(0, yawRad, 0);\n        }\n\n        this.vrDolly.updateMatrixWorld(true);\n    }\n\n    /**\n     * Get the VR dolly's current world position\n     */\n    getVRDollyPosition() {\n        if (!this.vrDolly) return new THREE.Vector3();\n        return this.vrDolly.position.clone();\n    }\n\n    /**\n     * Get the VR camera's world position (accounts for headset movement)\n     */\n    getVRCameraWorldPosition() {\n        if (!this.xrPresenting || !this.renderer.xr) {\n            return this.camera.position.clone();\n        }\n\n        const xrCamera = this.renderer.xr.getCamera(this.camera);\n        if (xrCamera) {\n            const pos = new THREE.Vector3();\n            pos.setFromMatrixPosition(xrCamera.matrixWorld);\n            return pos;\n        }\n\n        return this.camera.position.clone();\n    }\n\n    /**\n     * Check if currently presenting in VR\n     */\n    isXRPresenting() {\n        return this.xrPresenting && this.renderer?.xr?.isPresenting;\n    }\n\n    loadEnvironmentHDR() {\n        if (!this._environmentStreamingEnabled\n            || this._environmentHdrLoading\n            || this._hdrEnvMap\n            || !this.environmentHdrUrl\n            || !this.renderer\n            || !this.scene) {\n            return;\n        }\n        this._environmentHdrLoading = true;\n        const loader = new RGBELoader();\n        const pmremGenerator = new THREE.PMREMGenerator(this.renderer);\n        pmremGenerator.compileEquirectangularShader();\n\n        loader.load(\n            this.environmentHdrUrl,\n            (texture) => {\n                const envMap = pmremGenerator.fromEquirectangular(texture).texture;\n                this.scene.environment = envMap;\n                this._hdrEnvMap = envMap;\n                texture.dispose();\n                pmremGenerator.dispose();\n                this._environmentHdrLoading = false;\n                this._markMaterialsForEnv();\n            },\n            undefined,\n            () => {\n                pmremGenerator.dispose();\n                this._environmentHdrLoading = false;\n            }\n        );\n    }\n\n    setEnvironmentStreamingEnabled(enabled) {\n        this._environmentStreamingEnabled = enabled === true;\n        if (this._environmentStreamingEnabled) {\n            this.loadEnvironmentHDR();\n        }\n    }\n\n    _markMaterialsForEnv() {\n        if (!this.scene) return;\n        this.scene.traverse((child) => {\n            if (!child.material) return;\n            if (Array.isArray(child.material)) {\n                child.material.forEach((mat) => {\n                    if (mat && mat.isMeshStandardMaterial) mat.needsUpdate = true;\n                });\n            } else if (child.material.isMeshStandardMaterial) {\n                child.material.needsUpdate = true;\n            }\n        });\n    }\n\n    setupAtmosphereDepthTarget() {\n        if (!this.renderer) return;\n        this.renderer.getDrawingBufferSize(this._tmpSize);\n        const scale = THREE.MathUtils.clamp(this.atmosphereDepthScale ?? 1, 0.1, 1.0);\n        const width = Math.max(1, Math.floor((this._tmpSize.x || 1) * scale));\n        const height = Math.max(1, Math.floor((this._tmpSize.y || 1) * scale));\n\n        this.atmosphereDepthTarget = new THREE.WebGLRenderTarget(width, height);\n        this.atmosphereDepthTarget.texture.minFilter = THREE.NearestFilter;\n        this.atmosphereDepthTarget.texture.magFilter = THREE.NearestFilter;\n        this.atmosphereDepthTarget.texture.generateMipmaps = false;\n        this.atmosphereDepthTarget.depthBuffer = true;\n        this.atmosphereDepthTarget.depthTexture = new THREE.DepthTexture(width, height, THREE.UnsignedIntType);\n        this.atmosphereDepthTarget.depthTexture.format = THREE.DepthFormat;\n        this.atmosphereDepthTarget.depthTexture.minFilter = THREE.NearestFilter;\n        this.atmosphereDepthTarget.depthTexture.magFilter = THREE.NearestFilter;\n\n        this._depthMaterial = new THREE.MeshDepthMaterial({\n            depthPacking: THREE.BasicDepthPacking\n        });\n        this._atmosphereDepthShaderWarmupGeneration += 1;\n        this._atmosphereDepthShaderWarmupState = 'idle';\n\n        this._setupAtmosphereComposite();\n    }\n\n    _ensureAtmosphereDepthShaderReady() {\n        if (this._atmosphereDepthShaderWarmupState === 'ready') return true;\n        if (this._atmosphereDepthShaderWarmupState !== 'idle') return false;\n\n        const renderer = this.renderer;\n        if (!renderer || !this.camera || !this._depthMaterial\n            || typeof renderer.compileAsync !== 'function') {\n            // Requiring KHR_parallel_shader_compile here disabled the depth\n            // pre-pass outright on Firefox, which silently removed aurora and\n            // fire depth occlusion. compileAsync is warmed off the render path\n            // in an idle slice either way; only the driver's internal\n            // parallelism differs.\n            this._atmosphereDepthShaderWarmupState = 'unavailable';\n            return false;\n        }\n\n        const generation = this._atmosphereDepthShaderWarmupGeneration;\n        this._atmosphereDepthShaderWarmupState = 'scheduled';\n        const run = () => {\n            if (generation !== this._atmosphereDepthShaderWarmupGeneration) return;\n            this._atmosphereDepthShaderWarmupState = 'pending';\n            const geometry = new THREE.BufferGeometry();\n            geometry.setAttribute('position', new THREE.Float32BufferAttribute([\n                -1, -1, 0,\n                1, -1, 0,\n                0, 1, 0,\n            ], 3));\n            const probe = new THREE.Mesh(geometry, this._depthMaterial);\n            Promise.resolve(renderer.compileAsync(probe, this.camera, this.scene))\n                .then(() => {\n                    geometry.dispose();\n                    if (generation !== this._atmosphereDepthShaderWarmupGeneration) return;\n                    this._atmosphereDepthShaderWarmupState = 'ready';\n                    this._atmosphereDepthDirty = true;\n                })\n                .catch(() => {\n                    geometry.dispose();\n                    if (generation !== this._atmosphereDepthShaderWarmupGeneration) return;\n                    this._atmosphereDepthShaderWarmupState = 'unavailable';\n                });\n        };\n        if (typeof window !== 'undefined' && typeof window.requestIdleCallback === 'function') {\n            window.requestIdleCallback(run);\n        } else {\n            setTimeout(run, 0);\n        }\n        return false;\n    }\n\n    _setupAtmosphereClouds({ clearOnly = false } = {}) {\n        if (this._presentationSuspended) return;\n        if (this._atmosphereCloudStreamingEnabled === false && !clearOnly) return;\n        if (this._atmosphereCloudsSetupRequested && !this.atmosphereCloudsFailed) return;\n        if (this.atmosphereClouds) {\n            if (!this.atmosphereCloudsFailed) return;\n            this._disposeAtmosphereClouds({ quiet: true, preserveFailureState: true });\n        }\n        if (!this.renderer || !this.scene || !this.camera) {\n            this._atmosphereCloudsSetupRequested = false;\n            return;\n        }\n        this._atmosphereCloudsSetupRequested = true;\n        this._atmosphereCompositorRenderedAt = 0;\n\n        try {\n            const atmosphereClouds = new AtmosphereCloudsSystem({\n                renderer: this.renderer,\n                scene: this.scene,\n                camera: this.camera,\n                lightingSystem: this.lightingSystem,\n                planetGroup: this.planetGroup,\n                basePath: resolveSceneRuntimeBasePath(),\n                enableDithering: false,\n                deferCloudWarmup: clearOnly && this._atmosphereCloudStreamingEnabled === false\n            });\n            this.atmosphereClouds = atmosphereClouds;\n            atmosphereClouds.getPhotorealTileLoader = () => this.getPhotorealTileLoader?.() || null;\n            atmosphereClouds.setToneMappingExposure?.(this._orbitalSolarExposure);\n            // The heavy compositor is constructed by the boot entry gate,\n            // after loadEarthMaterials() created the canonical night-light\n            // uniforms. Rebind that already-live material here;\n            // otherwise deferred surface city irradiance and orbital light\n            // bloom both remain disconnected until an unrelated material\n            // reload happens.\n            atmosphereClouds.setEarthMaterial?.(this.earthMaterial);\n            atmosphereClouds.setCelestialOccluders?.({\n                moonMesh: this.moonSystem?.moonMesh,\n                sunMesh: this.sunMesh,\n            });\n            atmosphereClouds.setPerformanceMonitor?.(this._perf);\n            atmosphereClouds.setOrbitalOverviewActive?.(\n                this._atmosphereOrbitalOverviewActive\n            );\n            atmosphereClouds.setSurfaceCameraModeActive?.(\n                this._atmosphereSurfaceCameraModeActive === true,\n                { force: true }\n            );\n            atmosphereClouds.setEnabled(this.atmosphereEnabled);\n            const initPromise = atmosphereClouds.init();\n            if (this._atmosphereCloudsConfig) {\n                atmosphereClouds.applyConfig(this._atmosphereCloudsConfig);\n            }\n            this._applyBloomToAtmosphereClouds();\n            initPromise\n                .then(() => {\n                    // Streaming can be disabled while the cooperative init is\n                    // between frame slices. Never attach or configure an old,\n                    // disposed instance after a later transition owns state.\n                    if (this.atmosphereClouds !== atmosphereClouds) return;\n                    atmosphereClouds.setRainSystem?.(this.rainSystem);\n                    if (globalThis.__noclipDebugAtmosphere === true) {\n                        console.log('[SceneInitializer] Atmosphere + clouds system ready');\n                    }\n                    if (this._atmosphereCloudsConfig) {\n                        atmosphereClouds.applyConfig(this._atmosphereCloudsConfig);\n                    }\n                    this._applyBloomToAtmosphereClouds();\n                    if (this.weatherSystem?.setAtmosphereClouds) {\n                        this.weatherSystem.setAtmosphereClouds(atmosphereClouds);\n                        if (this._weatherConfig) {\n                            this.weatherSystem.applyConfig?.(this._weatherConfig);\n                        }\n                    }\n                })\n                .catch((error) => {\n                    if (this.atmosphereClouds !== atmosphereClouds) return;\n                    this.atmosphereCloudsFailed = true;\n                    console.warn('[SceneInitializer] Atmosphere + clouds init failed', error);\n                    this._atmosphereCloudsSetupRequested = false;\n                    this.setAtmosphereEnabled(this.atmosphereEnabled);\n                    this._scheduleAtmosphereCloudsRecovery();\n                });\n        } catch (error) {\n            this.atmosphereCloudsFailed = true;\n            this._atmosphereCloudsSetupRequested = false;\n            console.warn('[SceneInitializer] Atmosphere + clouds setup failed', error);\n            this.setAtmosphereEnabled(this.atmosphereEnabled);\n            this._scheduleAtmosphereCloudsRecovery();\n        }\n    }\n\n    _disposeAtmosphereClouds({\n        preserveFailureState = false,\n        quiet = false\n    } = {}) {\n        const clouds = this.atmosphereClouds;\n        this._atmosphereCompositorRenderedAt = 0;\n        if (!clouds) {\n            this.atmosphereClouds = null;\n            this._atmosphereCloudsSetupRequested = false;\n            this._atmosphereCloudsSetupRequestedAt = 0;\n            return;\n        }\n        this._atmosphereCloudsSetupRequested = false;\n        this._atmosphereCloudsSetupRequestedAt = 0;\n        this.atmosphereClouds = null;\n        try {\n            this.weatherSystem?.setAtmosphereClouds?.(null);\n        } catch (error) {\n            if (!quiet) {\n                console.warn('[SceneInitializer] Failed to detach weather system from atmosphere clouds', error);\n            }\n        }\n        try {\n            clouds.dispose?.();\n        } catch (error) {\n            if (!quiet) {\n                console.warn('[SceneInitializer] Atmosphere clouds dispose failed', error);\n            }\n        }\n        if (!preserveFailureState) {\n            this.atmosphereCloudsFailed = false;\n        }\n    }\n\n    _setupAtmosphereComposite() {\n        if (!this.atmosphereDepthTarget) return;\n        if (!this._atmosphereCompositeScene) {\n            this._atmosphereCompositeScene = new THREE.Scene();\n            this._atmosphereCompositeCamera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0, 1);\n            const material = new THREE.MeshBasicMaterial({\n                map: this.atmosphereDepthTarget.texture,\n                depthTest: false,\n                depthWrite: false,\n                toneMapped: false\n            });\n            const quad = new THREE.Mesh(new THREE.PlaneGeometry(2, 2), material);\n            quad.frustumCulled = false;\n            this._atmosphereCompositeQuad = quad;\n            this._atmosphereCompositeScene.add(quad);\n            return;\n        }\n        if (this._atmosphereCompositeQuad?.material?.map !== this.atmosphereDepthTarget.texture) {\n            this._atmosphereCompositeQuad.material.map = this.atmosphereDepthTarget.texture;\n            this._atmosphereCompositeQuad.material.needsUpdate = true;\n        }\n    }\n\n    createSunMesh() {\n        const sunGeometry = new THREE.SphereGeometry(SUN_RADIUS_M, 32, 32);\n        const sunColor = new THREE.Color('#ffffff');\n        // Do not replace this with MeshBasicMaterial. In r185 that stock\n        // program is the first ordinary material reached by the live scene;\n        // WebGLRenderer reflects its uniforms without waiting for\n        // KHR_parallel_shader_compile and blocked ANGLE for 20 seconds. The\n        // astronomical sun needs only a color plus logarithmic depth, so keep\n        // its program intentionally tiny and independent of lights/shadows.\n        const sunMaterial = enforceCelestialOpaqueDepthMaterial(new THREE.ShaderMaterial({\n            name: 'AstronomicalSunMaterial',\n            uniforms: {\n                sunColor: { value: sunColor },\n                solarRadiance: { value: new THREE.Vector3(...SOLAR_DISC_DEFAULTS.irradiance)\n                    .multiplyScalar(solarDiscRadianceScale()) },\n                ncaPlanetCenterWorld: { value: new THREE.Vector3() },\n                ncaPlanetRadius: { value: PLANET_RADIUS },\n                ncaAtmosphereHeight: { value: ATMOSPHERE_RADIUS_M - PLANET_RADIUS },\n                ncaBetaRayleigh: { value: new THREE.Vector3(5.8e-6, 13.5e-6, 33.1e-6) },\n                ncaBetaMie: { value: new THREE.Vector3(21e-6, 21e-6, 21e-6) },\n                ncaRayleighScaleHeight: { value: 8000 },\n                ncaMieScaleHeight: { value: 1200 },\n            },\n            vertexShader: `\n                #include <common>\n                #include <logdepthbuf_pars_vertex>\n                varying vec3 vNcaSunWorldPosition;\n                varying vec3 vNcaSunViewNormal;\n                varying vec3 vNcaSunViewDirection;\n                void main() {\n                    vec4 worldPosition = modelMatrix * vec4(position, 1.0);\n                    vec4 viewPosition = viewMatrix * worldPosition;\n                    vNcaSunWorldPosition = worldPosition.xyz;\n                    vNcaSunViewNormal = normalize(normalMatrix * normal);\n                    vNcaSunViewDirection = normalize(-viewPosition.xyz);\n                    gl_Position = projectionMatrix * viewPosition;\n                    #include <logdepthbuf_vertex>\n                }\n            `,\n            fragmentShader: `\n                #include <common>\n                #include <logdepthbuf_pars_fragment>\n                uniform vec3 sunColor;\n                uniform vec3 solarRadiance;\n                uniform vec3 ncaPlanetCenterWorld;\n                uniform float ncaPlanetRadius;\n                uniform float ncaAtmosphereHeight;\n                uniform vec3 ncaBetaRayleigh;\n                uniform vec3 ncaBetaMie;\n                uniform float ncaRayleighScaleHeight;\n                uniform float ncaMieScaleHeight;\n                varying vec3 vNcaSunWorldPosition;\n                varying vec3 vNcaSunViewNormal;\n                varying vec3 vNcaSunViewDirection;\n                ${ATMOSPHERIC_TRANSMITTANCE_GLSL}\n                void main() {\n                    #include <logdepthbuf_fragment>\n                    float mu = clamp(\n                      dot(normalize(vNcaSunViewNormal), normalize(vNcaSunViewDirection)),\n                      0.0,\n                      1.0\n                    );\n                    float oneMinusMu = 1.0 - mu;\n                    float limbDarkening = clamp(\n                      1.0 - 0.47 * oneMinusMu - 0.23 * oneMinusMu * oneMinusMu,\n                      0.25,\n                      1.0\n                    );\n                    vec3 photosphereColor = mix(\n                      vec3(1.0, 0.72, 0.48),\n                      vec3(1.0, 0.97, 0.91),\n                      pow(mu, 0.35)\n                    );\n                    vec3 directTransmittance = ncaAtmosphericTransmittance(\n                      cameraPosition,\n                      normalize(vNcaSunWorldPosition - cameraPosition),\n                      ncaPlanetCenterWorld,\n                      ncaPlanetRadius,\n                      ncaAtmosphereHeight,\n                      ncaBetaRayleigh,\n                      ncaBetaMie,\n                      ncaRayleighScaleHeight,\n                      ncaMieScaleHeight\n                    );\n                    gl_FragColor = vec4(\n                      min(vec3(60000.0), sunColor * solarRadiance * photosphereColor\n                        * limbDarkening * directTransmittance),\n                      1.0\n                    );\n                    #include <tonemapping_fragment>\n                    #include <colorspace_fragment>\n                }\n            `,\n            toneMapped: true,\n        }));\n        // Preserve the existing emissive tuneable contract. This color and\n        // the shader uniform deliberately share the same mutable Color.\n        sunMaterial.color = sunColor;\n        this.sunMesh = new THREE.Mesh(sunGeometry, sunMaterial);\n        this.sunMesh.name = 'SunVisual';\n        this.sunMesh.userData.celestialOccluder = 'sun';\n        this.sunMesh.userData.celestialOccluderRadiusM = SUN_RADIUS_M;\n        this.sunMesh.userData.noOcclusion = true;\n        this.sunMesh.raycast = () => {};\n        this.scene.add(this.sunMesh);\n        this.updateSunVisual();\n        this._applyEmissiveToSun();\n    }\n\n    _syncAtmosphereCelestialOccluders() {\n        this.atmosphereClouds?.setCelestialOccluders?.({\n            moonMesh: this.moonSystem?.moonMesh,\n            sunMesh: this.sunMesh,\n        });\n    }\n\n    createLensFlare() {\n        if (!this.scene) return;\n        if (this.lensFlare) return;\n        const source = this.sunMesh?.position || this.lightingSystem?.sun?.position;\n        if (!source) return;\n        const lensFlare = LensFlareEffect(\n            source,\n            ASTRONOMICAL_LENS_FLARE_DEFAULTS.opacity,\n            {\n            celestialOccluders: [this.moonSystem?.moonMesh].filter(Boolean),\n            getEnvironment: () => ({\n                surface: this._atmosphereSurfaceCameraModeActive === true,\n            }),\n            }\n        );\n        lensFlare.name = 'LensFlare';\n        lensFlare.renderOrder = 1001; // Render after atmosphere\n        // Don't set layers - use default layer 0 so camera can see it\n        this.lensFlare = lensFlare;\n        this._solarOpticsRenderer = new SolarOpticsRenderer(lensFlare);\n        this._syncLensFlareVisibility();\n        this.scene.add(lensFlare);\n    }\n\n    _syncLensFlareVisibility() {\n        if (!this.lensFlare) return;\n        this.lensFlare.visible = !!this.lensFlareEnabled\n            && !this._astronomicalLensFlareSuppressed\n            && !this._surfaceLensFlareSuppressed;\n    }\n\n    setLensFlareEnabled(enabled) {\n        const next = !!enabled;\n        this.lensFlareEnabled = next;\n        if (!next) {\n            if (this.lensFlare) this.lensFlare.visible = false;\n            return;\n        }\n        if (!this.lensFlare) {\n            this.createLensFlare();\n        } else {\n            this._syncLensFlareVisibility();\n        }\n    }\n\n    // The procedural lens-flare fills the viewport when the camera is itself\n    // orbiting Sol. The sun remains visible and bloom stays available, but the\n    // screen-space flare is retired in that astronomical close-up context.\n    setAstronomicalLensFlareSuppressed(suppressed) {\n        this._astronomicalLensFlareSuppressed = !!suppressed;\n        this._syncLensFlareVisibility();\n    }\n\n\n    createHexVisualization() {\n        this.hexGeometry = new THREE.BufferGeometry();\n        const hexMaterial = new THREE.LineBasicMaterial({\n            color: 0xffae00,\n            transparent: true,\n            opacity: 0,\n            linewidth: 3,\n            depthWrite: false\n        });\n        this.hexLine = new THREE.LineLoop(this.hexGeometry, hexMaterial);\n        this.hexLine.visible = false;\n        this.scene.add(this.hexLine);\n\n        this.hexPathGeometry = new THREE.BufferGeometry();\n        const pathMaterial = new THREE.LineBasicMaterial({\n            color: 0xffae00,\n            transparent: true,\n            opacity: 0,\n            linewidth: 3,\n            depthWrite: false\n        });\n        this.hexPathLine = new THREE.Line(this.hexPathGeometry, pathMaterial);\n        this.hexPathLine.visible = false;\n        this.scene.add(this.hexPathLine);\n    }\n\n    updateSunVisual(deltaTime = 0) {\n        if (this.sunMesh && this.lightingSystem) {\n            this.sunMesh.position.copy(this.lightingSystem.sun.position);\n        }\n        const ephemeris = this.lightingSystem?.getCelestialEphemeris?.();\n        const earthUniforms = this.earthMaterial?.uniforms;\n        if (ephemeris && earthUniforms) {\n            earthUniforms.moonCenterWorld?.value?.copy(ephemeris.moonPosition);\n            if (earthUniforms.moonRadius) {\n                earthUniforms.moonRadius.value = MOON_RADIUS_M;\n            }\n            if (earthUniforms.sunAngularRadius) {\n                earthUniforms.sunAngularRadius.value = apparentAngularRadius(\n                    SUN_RADIUS_M,\n                    ephemeris.sunDistance,\n                );\n            }\n            if (earthUniforms.sunDistance) {\n                earthUniforms.sunDistance.value = ephemeris.sunDistance;\n            }\n        }\n        const sunUniforms = this.sunMesh?.material?.uniforms;\n        if (sunUniforms?.ncaPlanetCenterWorld && this.camera) {\n            const planetCenter = sunUniforms.ncaPlanetCenterWorld.value;\n            if (this.planetGroup?.getWorldPosition) {\n                this.planetGroup.getWorldPosition(planetCenter);\n            } else {\n                planetCenter.set(0, 0, 0);\n            }\n            this._solarObserverScratch ??= new THREE.Vector3();\n            this._solarObserverDirectionScratch ??= new THREE.Vector3();\n            this.camera.getWorldPosition(this._solarObserverScratch);\n            this._solarObserverDirectionScratch\n                .subVectors(this._solarObserverScratch, planetCenter);\n            const radius = ellipsoidRadiusForWorldDir(\n                this._solarObserverDirectionScratch,\n                this.planetGroup,\n            );\n            if (Number.isFinite(radius) && radius > 0) {\n                sunUniforms.ncaPlanetRadius.value = radius;\n            }\n        }\n        this._updateOrbitalSolarExposure?.(deltaTime);\n        // Sync atmosphere material with sun direction\n        if (this.atmosphereMesh && this.atmosphereMesh.material && this.atmosphereMesh.material.uniforms && this.atmosphereMesh.material.uniforms.sunDirection) {\n            this.atmosphereMesh.material.uniforms.sunDirection.value.copy(this.lightingSystem.sun.position).normalize();\n        }\n    }\n\n    /**\n     * Bounded analytic exposure for the astronomical Sun. This deliberately\n     * avoids a framebuffer luminance readback: the Sun is sub-pixel at many\n     * orbital distances and a sampled average would make adaptation dependent\n     * on resolution, bloom, and whichever render path happened to own the\n     * previous frame. The CPU contract instead uses the actual finite solar\n     * disc, Earth/Moon parallax, atmospheric transmission, and camera framing.\n     */\n    _updateOrbitalSolarExposure(deltaTime = 0) {\n        if (!this.renderer || !this.camera) return;\n\n        const frameSeconds = THREE.MathUtils.clamp(\n            Number.isFinite(deltaTime) && deltaTime > 0 ? deltaTime : 1 / 60,\n            1 / 240,\n            0.25,\n        );\n        let targetExposure = this._atmosphereSurfaceCameraModeActive === true\n            ? SURFACE_TONE_MAPPING_EXPOSURE\n            : DEFAULT_TONE_MAPPING_EXPOSURE;\n        let cameraAngularSpeed = 0;\n        const ephemeris = this.lightingSystem?.getCelestialEphemeris?.();\n        const sunVisible = this.sunMesh?.visible !== false;\n        if (ephemeris && sunVisible && this._atmosphereSurfaceCameraModeActive !== true) {\n            this._solarExposureObserver ??= new THREE.Vector3();\n            this._solarExposurePlanetCenter ??= new THREE.Vector3();\n            this._solarExposureSunOffset ??= new THREE.Vector3();\n            this._solarExposureSunFromPlanet ??= new THREE.Vector3();\n            this._solarExposurePlanetOffset ??= new THREE.Vector3();\n            this._solarExposureOccluderOffset ??= new THREE.Vector3();\n            this._solarExposureForward ??= new THREE.Vector3();\n            this._solarExposureLastForward ??= new THREE.Vector3();\n            this._solarExposureObserverRadial ??= new THREE.Vector3();\n            this._solarExposureTransmission ??= new THREE.Vector3(1, 1, 1);\n\n            this.camera.getWorldPosition(this._solarExposureObserver);\n            if (this.planetGroup?.getWorldPosition) {\n                this.planetGroup.getWorldPosition(this._solarExposurePlanetCenter);\n            } else {\n                this._solarExposurePlanetCenter.set(0, 0, 0);\n            }\n\n            this.camera.getWorldDirection(this._solarExposureForward);\n            if (this._solarExposureHasLastForward === true) {\n                cameraAngularSpeed = Math.acos(THREE.MathUtils.clamp(\n                    this._solarExposureForward.dot(this._solarExposureLastForward),\n                    -1,\n                    1,\n                )) / frameSeconds;\n            }\n            this._solarExposureLastForward.copy(this._solarExposureForward);\n            this._solarExposureHasLastForward = true;\n            const priorAngularSpeed = Number.isFinite(this._solarExposureAngularSpeed)\n                ? this._solarExposureAngularSpeed\n                : cameraAngularSpeed;\n            const motionAlpha = 1 - Math.exp(-frameSeconds / 0.08);\n            this._solarExposureAngularSpeed = THREE.MathUtils.lerp(\n                priorAngularSpeed,\n                cameraAngularSpeed,\n                motionAlpha,\n            );\n            cameraAngularSpeed = this._solarExposureAngularSpeed;\n\n            const halfVertical = THREE.MathUtils.degToRad(\n                Math.max(1, this.camera.fov || 45) * 0.5,\n            );\n            const halfHorizontal = Math.atan(\n                Math.tan(halfVertical) * Math.max(0.25, this.camera.aspect || 1),\n            );\n            const frameRadius = Math.atan(Math.hypot(\n                Math.tan(halfVertical),\n                Math.tan(halfHorizontal),\n            ));\n            const inverseSmoothstep = (value, inner, outer) => {\n                const t = THREE.MathUtils.clamp(\n                    (value - inner) / Math.max(1e-6, outer - inner),\n                    0,\n                    1,\n                );\n                return 1 - t * t * (3 - 2 * t);\n            };\n\n            this._solarExposureObserverRadial.subVectors(\n                this._solarExposureObserver,\n                this._solarExposurePlanetCenter,\n            );\n            const observerDistance = this._solarExposureObserverRadial.length();\n            const planetRadius = ellipsoidRadiusForWorldDir(\n                this._solarExposureObserverRadial,\n                this.planetGroup,\n            ) || PLANET_RADIUS;\n            this._solarExposurePlanetOffset.subVectors(\n                this._solarExposurePlanetCenter,\n                this._solarExposureObserver,\n            );\n            const planetViewAngle = this._solarExposurePlanetOffset.lengthSq() > 1e-8\n                ? Math.acos(THREE.MathUtils.clamp(\n                    this._solarExposureForward.dot(\n                        this._solarExposurePlanetOffset.normalize(),\n                    ),\n                    -1,\n                    1,\n                ))\n                : Math.PI;\n            const planetAngularRadius = apparentAngularRadius(\n                planetRadius,\n                observerDistance,\n            );\n            const planetFullFrameAngle = Math.max(\n                0,\n                planetAngularRadius - frameRadius * 0.65,\n            );\n            const planetOverlap = inverseSmoothstep(\n                planetViewAngle,\n                planetFullFrameAngle,\n                planetAngularRadius + frameRadius,\n            );\n            const planetCoverage = planetAngularRadius >= frameRadius * 0.8\n                ? 1\n                : THREE.MathUtils.clamp(\n                    1.5 * (planetAngularRadius / Math.max(frameRadius, 1e-6)) ** 2,\n                    0,\n                    1,\n                );\n            const earthFrameWeight = planetOverlap * planetCoverage;\n            this._solarExposureSunFromPlanet.subVectors(\n                ephemeris.sunPosition,\n                this._solarExposurePlanetCenter,\n            ).normalize();\n            const earthPhaseLuminance = observerDistance > 1e-6\n                ? lambertianSpherePhase(\n                    this._solarExposureObserverRadial.dot(\n                        this._solarExposureSunFromPlanet,\n                    ) / observerDistance,\n                )\n                : 0;\n\n            let sunFrameWeight = 0;\n            let earthVisibility = 0;\n            let moonVisibility = 0;\n            let transmissionLuminance = 0;\n            this._solarExposureSunOffset.subVectors(\n                ephemeris.sunPosition,\n                this._solarExposureObserver,\n            );\n            const sunDistance = this._solarExposureSunOffset.length();\n            if (sunDistance > SUN_RADIUS_M) {\n                this._solarExposureSunOffset.multiplyScalar(1 / sunDistance);\n                const viewAngle = Math.acos(THREE.MathUtils.clamp(\n                    this._solarExposureForward.dot(this._solarExposureSunOffset),\n                    -1,\n                    1,\n                ));\n                const sunAngularRadius = apparentAngularRadius(SUN_RADIUS_M, sunDistance);\n                sunFrameWeight = inverseSmoothstep(\n                    viewAngle,\n                    frameRadius * 0.82,\n                    frameRadius + sunAngularRadius + THREE.MathUtils.degToRad(4),\n                );\n\n                if (sunFrameWeight > 1e-5) {\n                    earthVisibility = finiteSourceVisibility({\n                        observerPosition: this._solarExposureObserver,\n                        sourceCenter: ephemeris.sunPosition,\n                        sourceRadius: SUN_RADIUS_M,\n                        occluderCenter: this._solarExposurePlanetCenter,\n                        occluderRadius: planetRadius,\n                        sourceOffset: this._solarExposureSunOffset,\n                        occluderOffset: this._solarExposureOccluderOffset,\n                    });\n                    moonVisibility = finiteSourceVisibility({\n                        observerPosition: this._solarExposureObserver,\n                        sourceCenter: ephemeris.sunPosition,\n                        sourceRadius: SUN_RADIUS_M,\n                        occluderCenter: ephemeris.moonPosition,\n                        occluderRadius: MOON_RADIUS_M,\n                        sourceOffset: this._solarExposureSunOffset,\n                        occluderOffset: this._solarExposureOccluderOffset,\n                    });\n                    atmosphericTransmittance({\n                        observerPosition: this._solarExposureObserver,\n                        lightDirection: this._solarExposureSunOffset,\n                        planetCenter: this._solarExposurePlanetCenter,\n                        planetRadius,\n                        result: this._solarExposureTransmission,\n                    });\n                    transmissionLuminance =\n                        this._solarExposureTransmission.x * 0.2126\n                        + this._solarExposureTransmission.y * 0.7152\n                        + this._solarExposureTransmission.z * 0.0722;\n                    // A center ray can enter solid Earth while a finite solar\n                    // crescent remains visible. Retain bounded red-limb energy\n                    // in that interval instead of treating the entire disc as\n                    // point-occluded.\n                    transmissionLuminance = earthVisibility > 1e-5\n                        && earthVisibility < 1 - 1e-5\n                        ? Math.max(transmissionLuminance, 0.18)\n                        : transmissionLuminance;\n                }\n            }\n\n            const exposureTarget = resolveOrbitalHdrExposureTarget({\n                earthFrameWeight,\n                earthPhaseLuminance,\n                sunFrameWeight,\n                solarVisibility: earthVisibility * moonVisibility,\n                solarTransmission: transmissionLuminance,\n            });\n            targetExposure = exposureTarget.targetExposure;\n            this._orbitalHdrMeter = exposureTarget;\n        }\n\n        const current = Number.isFinite(this._orbitalSolarExposure)\n            ? this._orbitalSolarExposure\n            : DEFAULT_TONE_MAPPING_EXPOSURE;\n        const responseSeconds = orbitalExposureResponseSeconds({\n            currentExposure: current,\n            targetExposure,\n            angularSpeedRadPerSecond: cameraAngularSpeed,\n        });\n        const alpha = 1 - Math.exp(-frameSeconds / responseSeconds);\n        this._orbitalSolarExposure = THREE.MathUtils.lerp(current, targetExposure, alpha);\n\n        const flareUniforms = this.lensFlare?.material?.uniforms;\n        if (flareUniforms?.exposureCompensation) {\n            flareUniforms.exposureCompensation.value = THREE.MathUtils.clamp(\n                (DEFAULT_TONE_MAPPING_EXPOSURE\n                    / Math.max(0.05, this._orbitalSolarExposure)) ** 0.32,\n                1,\n                2.4,\n            );\n        }\n\n        if (this.atmosphereClouds?.setToneMappingExposure) {\n            this.atmosphereClouds.setToneMappingExposure(this._orbitalSolarExposure);\n        } else {\n            this.renderer.toneMappingExposure = this._orbitalSolarExposure;\n        }\n    }\n\n    updateWater(dt = 0) {\n        if (!this.earthMaterial?.uniforms?.waterTime) return;\n        if (!Number.isFinite(dt)) return;\n        const speed = Number.isFinite(this._earthOverlayConfig?.water?.speed)\n            ? this._earthOverlayConfig.water.speed\n            : 0.25;\n        this.earthMaterial.uniforms.waterTime.value += dt * speed;\n        const oceanState = this.oceanStateProvider?.();\n        try {\n            this._updateOceanSurface(oceanState);\n        } catch (error) {\n            // The sea is optional: any failure costs one ocean tier, not the world.\n            this._demoteOcean(`update failed: ${error?.message || error}`);\n        }\n        if (this.atmosphereClouds) this.atmosphereClouds._oceanSurface = this.oceanSurface;\n        this.atmosphereClouds?._underwaterEffect?.setState(oceanState, this.camera, this.oceanSurface);\n    }\n\n    _updateOceanSurface(oceanState) {\n        if (this.planetGroup && this.camera\n            && (this._earthOverlayConfig?.water?.enabled !== false || this._earthOverlayConfig?.specularMap?.enabled !== false)) {\n            const local = this._waterCoveragePosition ||= new THREE.Vector3();\n            this.planetGroup.updateWorldMatrix(true, false);\n            this.planetGroup.worldToLocal(this.camera.getWorldPosition(local));\n            const radius = local.length(); local.normalize();\n            const altitude = radius - ellipsoidRadiusForLocalDir(local);\n            const geo = dirToLatLonLocal(local, this._waterCoverageGeo ||= {});\n            if (!this.regionalWaterMask) {\n                this.regionalWaterMask = new RegionalWaterMask(this.earthMaterial.uniforms,\n                    { tileSize: typeof matchMedia === 'function' && matchMedia('(max-width: 700px), (pointer: coarse)').matches ? 256 : 512,\n                      renderer: this.renderer });\n                this._waterAttribution = globalThis.document?.getElementById?.('water-map-attribution');\n                if (this._waterAttribution) this._waterAttribution.hidden = false;\n            }\n            this.regionalWaterMask.update(geo.latDeg, geo.lonDeg, altitude);\n            // Near-ground volumetric clouds follow real local cover + radar.\n            this.atmosphereClouds?.updateLocalCloudField?.(geo.latDeg, geo.lonDeg, altitude);\n        }\n        this.oceanWaterLevel ||= getOceanWaterLevel();\n        this.oceanWaterLevel.load();\n        this._oceanTier ||= readOceanTier();\n        if (!this.oceanSurface && this._oceanTier !== 'off' && this.planetGroup && this.camera) {\n            this._installOceanContextGuard();\n            this.oceanSurface = new OceanSurface({ parent: this.planetGroup,\n                camera: this.camera, uniforms: this.earthMaterial.uniforms,\n                waterLevel: this.oceanWaterLevel,\n                renderer: this.renderer, sunLight: this.lightingSystem?.sun,\n                environment: this.scene?.environment, tier: this._oceanTier });\n        }\n        const regionalWeather = this.weatherSystem?._weatherData?.current;\n        const waterOptics=this.oceanSurface?.optics;\n        if(waterOptics && this._waterOptics!==waterOptics){\n            this._waterOptics=waterOptics;\n            this.earthMaterial.uniforms.waterDiffuseAttenuation.value.set(...waterOptics.diffuseAttenuation);\n        }\n        if (Number.isFinite(regionalWeather?.wind_speed_10m)) {\n            this.earthMaterial.uniforms.waterWindSpeed.value = regionalWeather.wind_speed_10m / 3.6;\n            this.oceanSurface?.setSeaState({ windSpeed: regionalWeather.wind_speed_10m / 3.6,\n                windDirection: regionalWeather.wind_direction_10m });\n        }\n        this.oceanSurface?.update(oceanState, { rendering: this._hdSceneProxy?.stats.ready !== true });\n        // Reuse the shared datum and the ocean's already evaluated tide; do\n        // not allocate another per-frame sample/predictor result for specular.\n        const waterGeo = this._waterCoverageGeo;\n        const geoid = waterGeo ? this.oceanWaterLevel.meanHeight(waterGeo.latDeg, waterGeo.lonDeg) : null;\n        this.earthMaterial.uniforms.waterSurfaceDatumReady.value = Number.isFinite(geoid) ? 1 : 0;\n        this.earthMaterial.uniforms.waterSurfaceGeoid.value = geoid ?? 0;\n        this.earthMaterial.uniforms.waterSurfaceSeaHeight.value = (geoid ?? 0) + (this.oceanSurface?.level?.tideMeters ?? 0);\n        if (this.oceanSurface?.mesh.visible) this._oceanVisibleAt = performance.now();\n    }\n\n    _demoteOcean(reason) {\n        const from = this._oceanTier || 'full';\n        this._oceanTier = demoteOceanTier(from, reason);\n        console.warn(`[SceneInitializer] Ocean ${from} → ${this._oceanTier}: ${reason}`);\n        try { this.oceanSurface?.dispose(); } catch { /* already released */ }\n        this.oceanSurface = null;\n        const u = this.earthMaterial?.uniforms;\n        if (u?.seaSurfaceActive) u.seaSurfaceActive.value = 0;\n        if (u?.seaConfirmedRadius) u.seaConfirmedRadius.value = 0;\n    }\n\n    // A context lost while the sea was drawn (or just before) is charged to the\n    // sea. The cheaper tier is rebuilt after restore and kept for later loads.\n    _installOceanContextGuard() {\n        if (this._oceanContextGuard || typeof document === 'undefined') return;\n        this._oceanContextGuard = () => {\n            if (this._oceanTier === 'off') return;\n            if (performance.now() - (this._oceanVisibleAt ?? -Infinity) < 10000) this._demoteOcean('WebGL context lost');\n        };\n        document.addEventListener('noclip:webglcontextlost', this._oceanContextGuard);\n    }\n\n    updateImageryLoading(nowMs) {\n        if (!this.earthMaterial?.uniforms?.loadingTime) return;\n        if (!Number.isFinite(nowMs)) return;\n        this.earthMaterial.uniforms.loadingTime.value = nowMs;\n        this._refreshLiveSimpleCloudsTextureIfNeeded();\n    }\n\n    _shouldUpdateAtmosphereDepth(camera) {\n        if (!camera) return false;\n        if (this._atmosphereDepthDirty || !this._atmosphereDepthLastUpdate) {\n            this._atmoDepthSkippedLastFrame = false;\n            return true;\n        }\n\n        const now = (typeof performance !== 'undefined' && performance.now)\n            ? performance.now()\n            : Date.now();\n\n        // Low-FPS mode keeps its own conservative (already rare) cadence.\n        if (this._lowFpsMode) {\n            const lowFpsUpdateMs = Math.max(this.atmosphereDepthUpdateMs, 5000);\n            return now - this._atmosphereDepthLastUpdate >= lowFpsUpdateMs;\n        }\n\n        // Measure how much the view changed since the last depth update.\n        const worldPos = camera.userData?.worldPosition;\n        const camPos = worldPos || camera.position;\n        const moveSq = camPos.distanceToSquared(this._atmosphereDepthLastCamPos);\n\n        const camQuat = camera.getWorldQuaternion(this._tmpCameraQuat);\n        const camDot = Math.abs(this._atmosphereDepthLastCamQuat.dot(camQuat));\n        const angleDelta = 2 * Math.acos(Math.min(1, Math.max(-1, camDot)));\n\n        let planetAngle = 0;\n        if (this.planetGroup) {\n            const planetQuat = this.planetGroup.getWorldQuaternion\n                ? this.planetGroup.getWorldQuaternion(this._atmosphereDepthTmpPlanetQuat)\n                : this._atmosphereDepthTmpPlanetQuat.copy(this.planetGroup.quaternion);\n            const planetDot = Math.abs(this._atmosphereDepthLastPlanetQuat.dot(planetQuat));\n            planetAngle = 2 * Math.acos(Math.min(1, Math.max(-1, planetDot)));\n        }\n\n        const moveEps = this.atmosphereDepthMoveEps;\n        const rotateEps = this.atmosphereDepthRotateEps;\n        const planetRotateEps = this.atmosphereDepthPlanetRotateEps;\n\n        // Fast motion → refresh depth every frame so the atmosphere/terrain\n        // blend edge never visibly lags during quick look-around or dives.\n        const bigJump = moveSq > moveEps * moveEps * 16\n            || angleDelta > rotateEps * 4\n            || planetAngle > planetRotateEps * 4;\n        if (bigJump) {\n            this._atmoDepthSkippedLastFrame = false;\n            return true;\n        }\n\n        // Did anything change enough to warrant a refresh at all?\n        const wantUpdate = (now - this._atmosphereDepthLastUpdate >= this.atmosphereDepthUpdateMs)\n            || moveSq > moveEps * moveEps\n            || angleDelta > rotateEps\n            || planetAngle > planetRotateEps;\n\n        if (!wantUpdate) {\n            // Camera + planet effectively static → keep the cached depth.\n            // (No per-frame full scene render at all while standing still.)\n            this._atmoDepthSkippedLastFrame = false;\n            return false;\n        }\n\n        // Ordinary continuous motion: halve the pre-pass rate. The depth\n        // pre-pass is a FULL extra scene render; a terrain-depth texture that\n        // is one frame stale is imperceptible in the low-frequency, horizon-\n        // aligned atmosphere blend, so skipping every other one removes a full\n        // scene render from half of all moving frames with no visible cost.\n        // (This method is called exactly once per rendered frame.)\n        if (this._atmoDepthSkippedLastFrame) {\n            this._atmoDepthSkippedLastFrame = false;\n            return true;\n        }\n        this._atmoDepthSkippedLastFrame = true;\n        return false;\n    }\n\n    _markAtmosphereDepthUpdated(camera) {\n        if (!camera) return;\n        this._atmosphereDepthLastUpdate = (typeof performance !== 'undefined' && performance.now)\n            ? performance.now()\n            : Date.now();\n        const worldPos = camera.userData?.worldPosition;\n        const camPos = worldPos || camera.position;\n        this._atmosphereDepthLastCamPos.copy(camPos);\n        camera.getWorldQuaternion(this._atmosphereDepthLastCamQuat);\n        if (this.planetGroup) {\n            if (this.planetGroup.getWorldQuaternion) {\n                this.planetGroup.getWorldQuaternion(this._atmosphereDepthLastPlanetQuat);\n            } else {\n                this._atmosphereDepthLastPlanetQuat.copy(this.planetGroup.quaternion);\n            }\n        }\n        this._atmosphereDepthDirty = false;\n    }\n\n    renderAtmosphereDepth(renderer, scene, camera, { force = false } = {}) {\n        if (!renderer || !scene || !camera) return false;\n        if (!this.atmosphereDepthTarget || !this._depthMaterial) return false;\n        if (!this._ensureAtmosphereDepthShaderReady()) return false;\n        // Aurora and fire ray-march against this depth target. Low-FPS mode\n        // already throttles it to a conservative cadence in\n        // _shouldUpdateAtmosphereDepth(); skipping it altogether leaves those\n        // transparent shells with no terrain occlusion, so they bleed through\n        // photorealistic tiles and the far side of Earth.\n        if (!force && !this._shouldUpdateAtmosphereDepth(camera)) return false;\n\n        let prevOverride = null;\n        let prevTarget = null;\n        let hasPrevOverride = false;\n        let hasPrevTarget = false;\n        let rendered = false;\n        const excludedVisibility = [];\n        const excluded = [\n            ...this._depthPassExcludeObjects,\n            this.atmosphereMesh,\n            this.sunMesh,\n            this.lensFlare,\n            this.starFieldGroup,\n            this.starField,\n            this.skyFeatures?.mesh,\n            this.galaxyField,\n            this.moonSystem?.moonMesh,\n            this.hexLine,\n            this.hexPathLine,\n            ...(this.atmosphereClouds?.getDepthPassExcludeObjects?.() || [])\n        ];\n        const seen = new Set();\n\n        this._perfStart('atmosphere.depth.prepass');\n        try {\n            prevOverride = scene.overrideMaterial;\n            hasPrevOverride = true;\n            prevTarget = renderer.getRenderTarget();\n            hasPrevTarget = true;\n\n            for (const obj of excluded) {\n                if (!obj || seen.has(obj)) continue;\n                seen.add(obj);\n                excludedVisibility.push({ obj, visible: obj.visible });\n                obj.visible = false;\n            }\n\n            scene.overrideMaterial = this._depthMaterial;\n            renderer.setRenderTarget(this.atmosphereDepthTarget);\n            renderer.clear();\n            renderer.render(scene, camera);\n\n            this._markAtmosphereDepthUpdated(camera);\n            rendered = true;\n        } finally {\n            for (const { obj, visible } of excludedVisibility) {\n                obj.visible = visible;\n            }\n            if (hasPrevTarget) renderer.setRenderTarget(prevTarget);\n            if (hasPrevOverride) scene.overrideMaterial = prevOverride;\n            this._perfEnd('atmosphere.depth.prepass');\n        }\n        return rendered;\n    }\n\n    _syncAtmosphereCloudTerrainDepthSource(camera) {\n        if (!this.atmosphereClouds?.setTerrainDepthSource) return;\n        const needsDepth = this.atmosphereClouds.needsTerrainDepth?.() === true;\n        if (!needsDepth || !camera || !this.atmosphereDepthTarget?.depthTexture || !this._atmosphereDepthLastUpdate) {\n            this.atmosphereClouds.setTerrainDepthSource(null);\n            return;\n        }\n\n        camera.updateMatrixWorld();\n        this.renderer.getDrawingBufferSize(this._tmpSize);\n        this.atmosphereClouds.setTerrainDepthSource({\n            depthTexture: this.atmosphereDepthTarget.depthTexture,\n            resolution: this._tmpSize,\n            invProjectionMatrix: camera.projectionMatrixInverse,\n            invViewMatrix: camera.matrixWorld,\n            enabled: true\n        });\n    }\n\n    updateAtmosphereUniforms(camera, opts = {}) {\n        const { force = false, resolution = null } = opts;\n        if (this._lowFpsMode && !force) return;\n        if (!this.atmosphereMaterial || !camera) return;\n        this._perfStart('atmosphere.uniforms');\n        try {\n            const uniforms = this.atmosphereMaterial.uniforms;\n            camera.updateMatrixWorld();\n            uniforms.invProjectionMatrix.value.copy(camera.projectionMatrixInverse);\n            uniforms.invViewMatrix.value.copy(camera.matrixWorld);\n            if (resolution && Number.isFinite(resolution.width) && Number.isFinite(resolution.height)) {\n                uniforms.resolution.value.set(resolution.width, resolution.height);\n            } else {\n                this.renderer.getDrawingBufferSize(this._tmpSize);\n                uniforms.resolution.value.set(this._tmpSize.x, this._tmpSize.y);\n            }\n            if (this.atmosphereDepthTarget) {\n                uniforms.depthTexture.value = this.atmosphereDepthTarget.depthTexture;\n            }\n\n            const worldPos = camera.userData?.worldPosition;\n            const camPos = worldPos || camera.position;\n            const camRadius = camPos.length();\n            const ellipsoidR = ellipsoidRadiusForWorldDir(camPos, this.planetGroup);\n            const altitude = camRadius - ellipsoidR;\n            const insideAtmosphere = camRadius < ATMOSPHERE_RADIUS_M;\n            const nextSide = insideAtmosphere ? THREE.BackSide : THREE.FrontSide;\n            if (this.atmosphereMaterial.side !== nextSide) {\n                this.atmosphereMaterial.side = nextSide;\n                this.atmosphereMaterial.needsUpdate = true;\n            }\n\n            let targetSamples = 16;\n            let targetSamplesLight = 8;\n            if (!insideAtmosphere && altitude > 500_000) {\n                // Keep one stable orbital integration budget. The former\n                // 2 Mm switch to 8/4 samples under-sampled Earth's thin\n                // atmosphere and created a literal black visual boundary.\n                targetSamples = 12;\n                targetSamplesLight = 6;\n            }\n\n            const sampleScale = Number.isFinite(this.atmosphereSampleScale)\n                ? this.atmosphereSampleScale\n                : 1.0;\n            targetSamples = Math.round(targetSamples * sampleScale);\n            targetSamplesLight = Math.round(targetSamplesLight * sampleScale);\n            targetSamples = THREE.MathUtils.clamp(targetSamples, 4, 32);\n            targetSamplesLight = THREE.MathUtils.clamp(targetSamplesLight, 2, 16);\n\n            if (uniforms.numSamples && uniforms.numSamples.value !== targetSamples) {\n                uniforms.numSamples.value = targetSamples;\n            }\n            if (uniforms.numSamplesLight && uniforms.numSamplesLight.value !== targetSamplesLight) {\n                uniforms.numSamplesLight.value = targetSamplesLight;\n            }\n        } finally {\n            this._perfEnd('atmosphere.uniforms');\n        }\n    }\n\n    registerPostCompositeLayer(layer) {\n        const index = Number(layer);\n        if (!Number.isInteger(index) || index < 0 || index > 31) return false;\n        this._postCompositeLayers ??= new Map();\n        this._postCompositeLayers.set(\n            index,\n            (this._postCompositeLayers.get(index) || 0) + 1\n        );\n        return true;\n    }\n\n    unregisterPostCompositeLayer(layer) {\n        const index = Number(layer);\n        const registrations = this._postCompositeLayers?.get(index) || 0;\n        if (registrations <= 1) {\n            this._postCompositeLayers?.delete(index);\n        } else {\n            this._postCompositeLayers.set(index, registrations - 1);\n        }\n    }\n\n    _renderPostCompositeLayers(renderer, scene, camera) {\n        if (!this._postCompositeLayers?.size || renderer?.xr?.isPresenting) return false;\n\n        let layerMask = 0;\n        for (const layer of this._postCompositeLayers.keys()) {\n            layerMask |= (1 << layer);\n        }\n        if (layerMask === 0) return false;\n\n        const previousCameraMask = camera.layers.mask;\n        const previousBackground = scene.background;\n        const previousOverrideMaterial = scene.overrideMaterial;\n        const previousAutoClear = renderer.autoClear;\n        const previousTarget = renderer.getRenderTarget?.();\n        try {\n            camera.layers.mask = layerMask;\n            scene.background = null;\n            scene.overrideMaterial = null;\n            renderer.autoClear = false;\n            renderer.setRenderTarget?.(null);\n            renderer.render(scene, camera);\n            this._postCompositeRenderErrorLogged = false;\n            return true;\n        } catch (error) {\n            if (!this._postCompositeRenderErrorLogged) {\n                console.warn('[SceneInitializer] Post-composite overlay render failed', error);\n                this._postCompositeRenderErrorLogged = true;\n            }\n            return false;\n        } finally {\n            camera.layers.mask = previousCameraMask;\n            scene.background = previousBackground;\n            scene.overrideMaterial = previousOverrideMaterial;\n            renderer.autoClear = previousAutoClear;\n            if (previousTarget !== undefined) renderer.setRenderTarget?.(previousTarget);\n        }\n    }\n\n    recordExternalFrameOwner(\n        owner = RENDER_FRAME_OWNER.STEREO,\n        metadata = null\n    ) {\n        const coordinator = this._frameCoordinator ??= new RenderFrameCoordinator();\n        coordinator.beginFrame(metadata);\n        coordinator.render(owner, () => {});\n        this._lastRenderOwner = coordinator.complete();\n        return this._lastRenderOwner;\n    }\n\n    getRenderOwnershipState() {\n        return (this._frameCoordinator ??= new RenderFrameCoordinator()).snapshot();\n    }\n\n    setHdSceneProxy({ width, height, mode = 'structure', getSources } = {}) {\n        if (this._hdSceneProxy && this._hdSceneProxy.mode !== mode) this.clearHdSceneProxy();\n        if (this._hdSceneProxy) {\n            this._hdSceneProxy.setSize(width, height);\n            return this._hdSceneProxy;\n        }\n        this._hdSceneProxy = new HdSceneProxy({ width, height, mode,\n            waitForRetirement: this._hdSceneProxyRetirement,\n            getSourceVersion: () => {\n                const photo = this.getPhotorealTileLoader?.(), overview = this.getOverviewGlobe?.(), moon = this.moonSystem?.moonMesh;\n                return `${overview?.id}:${overview?.visible}:${moon?.id}:${moon?.visible}:${photo?.enabled}:${photo?.group?.userData.photoModelChangeSeq}:${photo?._tiles?.visibleTiles?.size}`;\n            },\n            getSunPosition: () => this.lightingSystem?.sun?.position,\n            getPlanetCenter: () => this.planetGroup?.getWorldPosition(this._hdProxyPlanetCenter ||= new THREE.Vector3()),\n            getSources: getSources || (() => {\n                const sources = [];\n                const moon = this.moonSystem?.moonMesh;\n                if (moon && moon.visible !== false) sources.push({ object: moon, kind: 'moon', version: moon.material?.version });\n                const overview = this.getOverviewGlobe?.();\n                if (overview?.visible === true) {\n                    sources.push({ object: overview, frameRoot: this.planetGroup || overview, kind: 'overview',\n                        version: `${overview.material?.id}:${overview.material?.uniforms?.orbitalDayTexture?.value?.id ?? 0}` });\n                    return sources;\n                }\n                const photo = this.getPhotorealTileLoader?.();\n                if (photo?.enabled && photo.group) {\n                    const visible = photo._tiles?.visibleTiles;\n                    if (visible) {\n                        const roots = new Set(), limit = mode === 'color' ? HD_PROXY_LIMITS.nodes : HD_PROXY_LIMITS.sourceRoots;\n                        const accept = (mesh) => mesh.userData.photoDeferredLighting === true;\n                        for (const tile of visible) {\n                            const object = tile.engineData?.scene;\n                            // Native fade-out parents can still paint coverage\n                            // after traversal activity ends. Their visible set,\n                            // not activity alone, owns this control inventory.\n                            if (!object || roots.has(object)) continue;\n                            roots.add(object);\n                            if (sources.length >= limit) throw new Error('HD proxy native visible tile inventory exceeds its node bound');\n                            sources.push({ object, frameRoot: photo.group, version: photo.group.userData.photoModelChangeSeq, accept });\n                        }\n                        return sources;\n                    }\n                    sources.push({ object: photo.group, version: photo.group.userData.photoModelChangeSeq,\n                        accept: (mesh) => mesh.userData.photoDeferredLighting === true });\n                    return sources;\n                }\n                if (this.planetGroup) sources.push({ object: this.planetGroup, kind: 'terrain',\n                    accept: (mesh) => !!mesh.userData.tile || mesh.userData.isTriTreeSkirt === true,\n                });\n                return sources;\n            }) });\n        return this._hdSceneProxy;\n    }\n\n    clearHdSceneProxy(expected = this._hdSceneProxy) {\n        if (!this._hdSceneProxy || expected !== this._hdSceneProxy) return false;\n        const proxy = this._hdSceneProxy; this._hdSceneProxy = null;\n        this._hdSceneProxyRetirement = Promise.allSettled([this._hdSceneProxyRetirement, proxy.dispose()]);\n        this._syncHdProxyGpuPresentation();\n        return true;\n    }\n\n    getHdSceneProxyRetirement() { return this._hdSceneProxyRetirement || Promise.resolve(); }\n\n    _syncHdProxyGpuPresentation() {\n        const suspended = this._presentationSuspended === true || this._hdSceneProxy?.stats?.ready === true;\n        if (this._hdProxyGpuSuspended === suspended && this._hdProxyCloudOwner === this.atmosphereClouds) return;\n        this._hdProxyGpuSuspended = suspended; this._hdProxyCloudOwner = this.atmosphereClouds;\n        // Reuse the optional warm-up wait owner. This does not park the native\n        // camera/physics frame or free/reduce any rich scene GPU resources.\n        try { this.atmosphereClouds?.setPresentationSuspended?.(suspended); }\n        catch (error) {\n            this._hdProxyGpuSuspended = undefined;\n            if (this._hdSceneProxy?.stats) this._hdSceneProxy.stats.error = `HD GPU preparation suspension failed: ${error.message}`;\n        }\n    }\n\n    getHdSceneProxyStatus() {\n        return this._hdSceneProxy ? { active: true, ...this._hdSceneProxy.status() } : { active: false };\n    }\n\n    getHdSceneProxyCapture() {\n        return this._lastRenderOwner === RENDER_FRAME_OWNER.HD_PROXY\n            ? this._hdSceneProxy?.captureSource(this.renderer) || null : null;\n    }\n\n    /**\n     * Every render of this frame (depth pre-pass, reflections, compositor)\n     * runs inside the first-draw guard: objects whose shader program is not\n     * linked yet skip a frame while it links asynchronously, rather than any\n     * pass blocking on getProgramParameter.\n     */\n    renderSceneWithAtmosphere(renderer, scene, camera, deltaTime) {\n        if (!renderer || !scene || !camera) return null;\n        // A blocked frame must not touch the renderer at all.\n        if (this.isRenderBlocked()) return null;\n        this._firstDrawGuard ||= new FirstDrawGuard(renderer);\n        this._firstDrawGuard.beforeRender(scene, camera);\n        try { return this._renderSceneWithAtmosphereFrame(renderer, scene, camera, deltaTime); }\n        finally { this._firstDrawGuard.afterRender(); }\n    }\n\n    _renderSceneWithAtmosphereFrame(renderer, scene, camera, deltaTime) {\n        if (this.isRenderBlocked()) return null;\n        const coordinator = this._frameCoordinator ??= new RenderFrameCoordinator();\n        coordinator.beginFrame({\n            atmosphereEnabled: this.atmosphereEnabled === true,\n            cameraMode: this._atmosphereSurfaceCameraModeActive ? 'surface' : 'orbit',\n        });\n        this.atmosphereClouds?.setPhotorealUnderwater?.(this.photorealUnderwater === true);\n        if (this.photorealInterior === true) {\n            this.atmosphereClouds?.releaseFrameOwnership?.();\n            this._photorealInteriorRenderer ||= new PhotorealInteriorRenderer();\n            coordinator.render(RENDER_FRAME_OWNER.PHOTOREAL_INTERIOR,\n                () => this._photorealInteriorRenderer.render(renderer, camera));\n            this._lastRenderOwner = coordinator.complete();\n            return this._lastRenderOwner;\n        }\n        // Native imagery demand remains camera-owned even when a cheap HD\n        // control owns the draw. This update schedules bounded CPU acquisition,\n        // not a rich scene render or immediate texture upload.\n        this._updateLightPollutionTileField();\n        // A generated display covers this structural control framebuffer. All\n        // camera, physics, provider and label updates still use the native frame\n        // clock; rich scene resources/settings remain untouched for exact return.\n        if (this._hdSceneProxy && !renderer.xr?.isPresenting) {\n            this._perfStart('hd.proxy.render');\n            try {\n                if (coordinator.tryRender(RENDER_FRAME_OWNER.HD_PROXY,\n                    () => this._hdSceneProxy.render(renderer, camera))) {\n                    this._lastRenderOwner = coordinator.complete();\n                    return this._lastRenderOwner;\n                }\n            } catch (error) {\n                this._hdSceneProxy.stats.ready = false;\n                this._hdSceneProxy.stats.error = error.message;\n                coordinator.yield(RENDER_FRAME_OWNER.HD_PROXY, 'render-error');\n            } finally {\n                this._syncHdProxyGpuPresentation();\n                this._perfEnd('hd.proxy.render');\n            }\n        }\n        let finalFramebufferWritten = false;\n        const completeFrame = () => {\n            // The cloud compositor can own a cadence-skipped frame without\n            // touching the retained framebuffer. Rendering a transparent\n            // post layer again in that case compounds its alpha every\n            // animation tick, then resets on the next composer refresh.\n            if (finalFramebufferWritten) {\n                if (lateSolarOptics) {\n                    try { this._solarOpticsRenderer?.render(renderer, scene, camera,\n                        orbitalSolarOptics ? null : this.atmosphereClouds, { orbital: orbitalSolarOptics }); }\n                    catch (error) {\n                        // An optional optical overlay cannot interrupt the world\n                        // or labels. Restore the original direct draw next frame.\n                        this._solarOpticsRenderer.failed = true;\n                        console.warn('[SolarOptics] Returning to direct optics', error);\n                    }\n                }\n                this._renderPostCompositeLayers(renderer, scene, camera);\n            }\n            this._lastRenderOwner = coordinator.complete();\n            return this._lastRenderOwner;\n        };\n        let lateSolarOptics = false;\n        let orbitalSolarOptics = false;\n        this._refreshEmissiveIfNeeded();\n        this._updateMotionEffects(deltaTime);\n        if (renderer.xr?.isPresenting) {\n            if (!this.atmosphereClouds && !this._atmosphereCloudsSetupRequested && this.atmosphereEnabled) {\n                this.setAtmosphereCloudStreamingEnabled(true);\n            }\n            // The direct XR path, shared by AR and VR, does not own the desktop\n            // composer. Restore its saved output state before submitting eyes.\n            this.atmosphereClouds?.releaseFrameOwnership?.();\n            this.atmosphereClouds?.prepareNativeXRFrame?.({ enabled: this.atmosphereEnabled });\n            coordinator.render(\n                RENDER_FRAME_OWNER.XR,\n                () => {\n                    // Mono depth textures are stale and in the wrong eye frame.\n                    // Suppress the legacy shell for the whole native submission.\n                    const legacyVisible = this.atmosphereMesh?.visible;\n                    if (this.atmosphereMesh) this.atmosphereMesh.visible = false;\n                    try {\n                        if (!this.atmosphereClouds?.renderNativeXRFrame?.(deltaTime, { enabled: this.atmosphereEnabled })) renderer.render(scene, camera);\n                    } finally {\n                        if (this.atmosphereMesh) this.atmosphereMesh.visible = legacyVisible;\n                    }\n                    finalFramebufferWritten = true;\n                }\n            );\n            globalThis.window?.__noclipXRDiagnostics?.frame(performance.now());\n            return completeFrame();\n        }\n\n        this.atmosphereClouds?.restoreDesktopSky?.();\n\n        const renderMain = (owner) => coordinator.render(owner, () => {\n            const flare = this.lensFlare;\n            const flareVisible = flare?.visible;\n            const useLateOptics = !this._atmosphereSurfaceCameraModeActive\n                && this._solarOpticsRenderer?.canRender(renderer, null, { orbital: true }) === true;\n            if (useLateOptics) flare.visible = false;\n            try {\n                lateSolarOptics = orbitalSolarOptics = useLateOptics;\n                if (this._bloomEnabled\n                    || this._depthOfFieldEnabled\n                    || this._motionBlurEnabled\n                    || this._fxaaEnabled) {\n                    this._ensureBloomComposer();\n                    this._updateDepthOfFieldFocus(deltaTime);\n                    this._applyMotionBlurSettings();\n                    this._applyFxaaSettings();\n                    if (this._bloomComposer) {\n                        if (this._bloomRenderPass) {\n                            this._bloomRenderPass.scene = scene;\n                            this._bloomRenderPass.camera = camera;\n                        }\n                        if (this._bloomEffectPass) this._bloomEffectPass.camera = camera;\n                        if (this._depthOfFieldPass) this._depthOfFieldPass.camera = camera;\n                        if (this._motionBlurPass) this._motionBlurPass.camera = camera;\n                        if (this._fxaaPass) this._fxaaPass.camera = camera;\n                        this._syncBloomComposerSize();\n                        this._bloomComposer.render(deltaTime);\n                        finalFramebufferWritten = true;\n                        return;\n                    }\n                }\n                renderer.render(scene, camera);\n                finalFramebufferWritten = true;\n            } finally {\n                if (flare) flare.visible = flareVisible;\n            }\n        });\n\n        if (this.atmosphereClouds && !this.atmosphereCloudsFailed && this.atmosphereEnabled) {\n            const shouldRenderAtmosphereCloudPipeline = this._shouldUseAtmosphereCloudsPipeline();\n            this._syncAtmosphereMeshVisibility();\n            let rendered = false;\n            if (shouldRenderAtmosphereCloudPipeline) {\n                this._perfStart('atmosphere.clouds.total');\n                this._perfStart('gpu.clouds.render');\n                try {\n                    if (this.atmosphereClouds.needsTerrainDepth?.() === true) {\n                        this.renderAtmosphereDepth(renderer, scene, camera);\n                    }\n                    this._applyBloomToAtmosphereClouds();\n                    this._applyLensToAtmosphereClouds();\n                    this._syncAtmosphereCloudTerrainDepthSource(camera);\n                    rendered = coordinator.tryRender(\n                        RENDER_FRAME_OWNER.ATMOSPHERE_COMPOSITOR,\n                        () => {\n                            const flare = this.lensFlare;\n                            const flareVisible = flare?.visible;\n                            const orbital = !this._atmosphereSurfaceCameraModeActive;\n                            const useLateOptics = this._solarOpticsRenderer?.canRender(renderer,\n                                orbital ? null : this.atmosphereClouds, { orbital }) === true;\n                            if (useLateOptics) flare.visible = false;\n                            let handled;\n                            try { handled = this.atmosphereClouds.render(deltaTime); }\n                            finally { if (flare) flare.visible = flareVisible; }\n                            lateSolarOptics = handled && useLateOptics;\n                            orbitalSolarOptics = lateSolarOptics && orbital;\n                            if (handled) {\n                                // Older compositor implementations always\n                                // wrote when they returned true. Preserve that\n                                // contract while allowing the current system\n                                // to report an intentional retained-frame hit.\n                                finalFramebufferWritten =\n                                    this.atmosphereClouds.didWriteFinalFrame?.() !== false;\n                            }\n                            return handled;\n                        }\n                    );\n                    if (rendered) {\n                        this._atmosphereCloudRenderFailures = 0;\n                        this._forceLegacyAtmosphereUntil = 0;\n                        this._atmosphereCompositorRenderedAt = (typeof performance !== 'undefined'\n                            && Number.isFinite(performance.now?.()))\n                            ? performance.now()\n                            : Date.now();\n                    }\n                } catch (error) {\n                    coordinator.yield(\n                        RENDER_FRAME_OWNER.ATMOSPHERE_COMPOSITOR,\n                        'render-error'\n                    );\n                    this._handleAtmosphereCloudsRenderFailure(error);\n                } finally {\n                    this._perfEnd('gpu.clouds.render');\n                    this._perfEnd('atmosphere.clouds.total');\n                }\n            } else {\n                coordinator.yield(\n                    RENDER_FRAME_OWNER.ATMOSPHERE_COMPOSITOR,\n                    'pipeline-ineligible'\n                );\n            }\n            if (rendered) return completeFrame();\n            // A warm compositor can still yield because of an explicit\n            // recovery window or a render exception. Restore the saved\n            // AGX/exposure transaction before any direct owner draws.\n            this.atmosphereClouds.releaseFrameOwnership?.();\n        } else {\n            this.atmosphereClouds?.releaseFrameOwnership?.();\n        }\n\n        this.atmosphereClouds?.prepareDirectFrame?.({ enabled: this.atmosphereEnabled });\n\n        if (!this.atmosphereEnabled) {\n            this._perfStart('gpu.render.basic');\n            renderMain(RENDER_FRAME_OWNER.DIRECT_BASIC);\n            this._perfEnd('gpu.render.basic');\n            return completeFrame();\n        }\n\n        // If atmosphere system isn't set up, just render normally\n        if (!this.atmosphereDepthTarget || !this.atmosphereMesh) {\n            this._perfStart('gpu.render.fallback');\n            renderMain(RENDER_FRAME_OWNER.DIRECT_FALLBACK);\n            this._perfEnd('gpu.render.fallback');\n            return completeFrame();\n        }\n\n        // Check if atmosphere is actually visible\n        const hasAtmosphere = !!(this.atmosphereMesh && this.atmosphereMesh.visible);\n\n        // If atmosphere is disabled, just render normally without multipass\n        if (!hasAtmosphere) {\n            this._perfStart('gpu.render.noatmos');\n            renderMain(RENDER_FRAME_OWNER.DIRECT_NO_ATMOSPHERE);\n            this._perfEnd('gpu.render.noatmos');\n            return completeFrame();\n        }\n\n        // Update atmosphere shader with depth texture\n        if (this.atmosphereMaterial?.uniforms?.depthTexture &&\n            this.atmosphereMaterial.uniforms.depthTexture.value !== this.atmosphereDepthTarget.depthTexture) {\n            this.atmosphereMaterial.uniforms.depthTexture.value = this.atmosphereDepthTarget.depthTexture;\n        }\n\n        const prevTarget = renderer.getRenderTarget();\n        const prevAtmosphereVisible = this.atmosphereMesh.visible;\n\n        // Save visibility state of every object that samples this depth target.\n        // Aurora and fire are created asynchronously by AtmosphereCloudsSystem,\n        // so the static exclusion list alone is stale during cold/fallback\n        // frames. Rendering either shell while its material samples the target\n        // currently attached to the framebuffer is a WebGL feedback loop.\n        const excludedVisibility = [];\n        const excludedObjects = [\n            ...this._depthPassExcludeObjects,\n            this.starFieldGroup,\n            ...(this.atmosphereClouds?.getDepthPassExcludeObjects?.() || []),\n        ];\n        const excludedSeen = new Set();\n        for (const obj of excludedObjects) {\n            if (!obj || excludedSeen.has(obj)) continue;\n            excludedSeen.add(obj);\n            excludedVisibility.push({ obj, visible: obj.visible });\n        }\n        const shouldUpdateDepth = this._shouldUpdateAtmosphereDepth(camera);\n\n        try {\n            if (shouldUpdateDepth) {\n                // PASS 1: Depth pre-pass - render terrain ONLY to depth target\n                // Hide overlay objects AND atmosphere so they don't affect depth calculations\n                for (const { obj } of excludedVisibility) {\n                    obj.visible = false;\n                }\n                this.atmosphereMesh.visible = false;\n\n                this._perfStart('atmosphere.depth.prepass');\n                this._perfStart('gpu.depth.setTarget');\n                renderer.setRenderTarget(this.atmosphereDepthTarget);\n                this._perfEnd('gpu.depth.setTarget');\n                this._perfStart('gpu.depth.clear');\n                renderer.clear(true, true, false);\n                this._perfEnd('gpu.depth.clear');\n                this._perfStart('gpu.depth.render');\n                renderer.render(scene, camera);\n                this._perfEnd('gpu.depth.render');\n                this._markAtmosphereDepthUpdated(camera);\n                this._perfEnd('atmosphere.depth.prepass');\n\n                // Restore visibility\n                for (const { obj, visible } of excludedVisibility) {\n                    obj.visible = visible;\n                }\n                this.atmosphereMesh.visible = prevAtmosphereVisible;\n            }\n\n            // PASS 2: Main render - render everything (terrain, overlays, atmosphere)\n            // Atmosphere will blend over terrain due to transparent material + high renderOrder\n            this.updateAtmosphereUniforms(camera, { force: true });\n\n            // STANDARD: Direct rendering with mesh-based atmosphere\n            this._perfStart('atmosphere.render.mesh');\n            this._perfStart('gpu.main.setTarget');\n            renderer.setRenderTarget(null);\n            this._perfEnd('gpu.main.setTarget');\n            this._perfStart('gpu.main.clear');\n            renderer.clear(true, true, false);\n            this._perfEnd('gpu.main.clear');\n            this._perfStart('gpu.main.render');\n            renderMain(RENDER_FRAME_OWNER.DIRECT_ATMOSPHERE);\n            this._perfEnd('gpu.main.render');\n            this._perfEnd('atmosphere.render.mesh');\n\n        } finally {\n            // Restore all state\n            for (const { obj, visible } of excludedVisibility) {\n                obj.visible = visible;\n            }\n            this.atmosphereMesh.visible = prevAtmosphereVisible;\n            renderer.setRenderTarget(prevTarget);\n        }\n        return completeFrame();\n    }\n\n    _applyAtmosphereTuning() {\n        if (!this.atmosphereMaterial || !this.atmosphereMaterial.uniforms) return;\n        const uniforms = this.atmosphereMaterial.uniforms;\n        if (!this.atmosphereBase) {\n            this.atmosphereBase = {\n                rayleighCoeff: uniforms.rayleighCoeff?.value?.clone?.() || new THREE.Vector3(),\n                mieCoeff: uniforms.mieCoeff?.value ?? 0,\n                rayleighScaleHeight: uniforms.rayleighScaleHeight?.value ?? 0,\n                mieScaleHeight: uniforms.mieScaleHeight?.value ?? 0,\n                mieG: uniforms.mieG?.value ?? 0,\n                sunIntensity: uniforms.sunIntensity?.value ?? 0\n            };\n        }\n\n        const tuning = this.atmosphereTuning || {};\n\n        if (Number.isFinite(tuning.rayleighStrength) && uniforms.rayleighCoeff?.value) {\n            uniforms.rayleighCoeff.value\n                .copy(this.atmosphereBase.rayleighCoeff)\n                .multiplyScalar(tuning.rayleighStrength);\n        }\n        if (Number.isFinite(tuning.rayleighScaleHeight) && uniforms.rayleighScaleHeight) {\n            uniforms.rayleighScaleHeight.value = tuning.rayleighScaleHeight;\n        }\n        if (Number.isFinite(tuning.mieStrength) && uniforms.mieCoeff) {\n            uniforms.mieCoeff.value = this.atmosphereBase.mieCoeff * tuning.mieStrength;\n        }\n        if (Number.isFinite(tuning.mieScaleHeight) && uniforms.mieScaleHeight) {\n            uniforms.mieScaleHeight.value = tuning.mieScaleHeight;\n        }\n        if (Number.isFinite(tuning.mieG) && uniforms.mieG) {\n            uniforms.mieG.value = tuning.mieG;\n        }\n        if (Number.isFinite(tuning.sunIntensity) && uniforms.sunIntensity) {\n            uniforms.sunIntensity.value = tuning.sunIntensity;\n        }\n    }\n\n    setAtmosphereScattering(updates = {}) {\n        if (!updates || typeof updates !== 'object') return;\n        const next = { ...(this.atmosphereTuning || {}) };\n\n        if (Number.isFinite(updates.rayleighStrength)) {\n            next.rayleighStrength = THREE.MathUtils.clamp(updates.rayleighStrength, 0.0, 5.0);\n        }\n        if (Number.isFinite(updates.rayleighScaleHeight)) {\n            next.rayleighScaleHeight = THREE.MathUtils.clamp(updates.rayleighScaleHeight, 1000, 30000);\n        }\n        if (Number.isFinite(updates.mieStrength)) {\n            next.mieStrength = THREE.MathUtils.clamp(updates.mieStrength, 0.0, 5.0);\n        }\n        if (Number.isFinite(updates.mieScaleHeight)) {\n            next.mieScaleHeight = THREE.MathUtils.clamp(updates.mieScaleHeight, 200, 20000);\n        }\n        if (Number.isFinite(updates.mieG)) {\n            next.mieG = THREE.MathUtils.clamp(updates.mieG, 0.0, 0.99);\n        }\n        if (Number.isFinite(updates.sunIntensity)) {\n            next.sunIntensity = THREE.MathUtils.clamp(updates.sunIntensity, 0.0, 100.0);\n        }\n        if (Number.isFinite(updates.sampleScale)) {\n            this.atmosphereSampleScale = THREE.MathUtils.clamp(updates.sampleScale, 0.25, 3.0);\n            next.sampleScale = this.atmosphereSampleScale;\n        }\n\n        this.atmosphereTuning = next;\n        this._applyAtmosphereTuning();\n    }\n\n    setAtmosphereDepthScale(scale) {\n        if (!Number.isFinite(scale)) return;\n        const next = THREE.MathUtils.clamp(scale, 0.1, 1.0);\n        if (Math.abs(next - this.atmosphereDepthScale) < 1e-4) return;\n        this.atmosphereDepthScale = next;\n        if (!this.renderer || !this.atmosphereDepthTarget) return;\n        this.renderer.getDrawingBufferSize(this._tmpSize);\n        const width = Math.max(1, Math.floor(this._tmpSize.x * next));\n        const height = Math.max(1, Math.floor(this._tmpSize.y * next));\n        this.atmosphereDepthTarget.setSize(width, height);\n        this._atmosphereDepthDirty = true;\n    }\n\n    setAtmosphereDepthUpdateMs(value) {\n        if (!Number.isFinite(value)) return;\n        const next = THREE.MathUtils.clamp(Math.floor(value), 16, 2000);\n        if (Math.abs(next - this.atmosphereDepthUpdateMs) < 1) return;\n        this.atmosphereDepthUpdateMs = next;\n        this._atmosphereDepthDirty = true;\n    }\n\n    setAtmosphereDepthThresholds({ moveEps, rotateEps, planetRotateEps } = {}) {\n        let dirty = false;\n        if (Number.isFinite(moveEps)) {\n            const next = Math.max(0, moveEps);\n            if (Math.abs(next - this.atmosphereDepthMoveEps) > 1e-4) {\n                this.atmosphereDepthMoveEps = next;\n                dirty = true;\n            }\n        }\n        if (Number.isFinite(rotateEps)) {\n            const next = Math.max(0, rotateEps);\n            if (Math.abs(next - this.atmosphereDepthRotateEps) > 1e-6) {\n                this.atmosphereDepthRotateEps = next;\n                dirty = true;\n            }\n        }\n        if (Number.isFinite(planetRotateEps)) {\n            const next = Math.max(0, planetRotateEps);\n            if (Math.abs(next - this.atmosphereDepthPlanetRotateEps) > 1e-6) {\n                this.atmosphereDepthPlanetRotateEps = next;\n                dirty = true;\n            }\n        }\n        if (dirty) {\n            this._atmosphereDepthDirty = true;\n        }\n    }\n\n    setAtmosphereAerialPerspective(updates = {}) {\n        if (!updates || typeof updates !== 'object') {\n            console.warn('[Atmosphere] setAtmosphereAerialPerspective: invalid updates', updates);\n            return;\n        }\n        if (!this.atmosphereMaterial || !this.atmosphereMaterial.uniforms) {\n            console.warn('[Atmosphere] setAtmosphereAerialPerspective: atmosphereMaterial not ready');\n            return;\n        }\n\n        const uniforms = this.atmosphereMaterial.uniforms;\n        const appliedUpdates = {};\n\n        if (Number.isFinite(updates.aerialPerspectiveStrength) && uniforms.aerialPerspectiveStrength) {\n            const newValue = THREE.MathUtils.clamp(updates.aerialPerspectiveStrength, 0.0, 2.0);\n            uniforms.aerialPerspectiveStrength.value = newValue;\n            appliedUpdates.aerialPerspectiveStrength = newValue;\n        }\n        if (Number.isFinite(updates.aerialPerspectiveDensity) && uniforms.aerialPerspectiveDensity) {\n            const newValue = THREE.MathUtils.clamp(updates.aerialPerspectiveDensity, 0.0, 0.001);\n            uniforms.aerialPerspectiveDensity.value = newValue;\n            appliedUpdates.aerialPerspectiveDensity = newValue;\n        }\n        if (Number.isFinite(updates.aerialPerspectiveHeightFalloff) && uniforms.aerialPerspectiveHeightFalloff) {\n            const newValue = THREE.MathUtils.clamp(updates.aerialPerspectiveHeightFalloff, 500, 50000);\n            uniforms.aerialPerspectiveHeightFalloff.value = newValue;\n            appliedUpdates.aerialPerspectiveHeightFalloff = newValue;\n        }\n        if (Number.isFinite(updates.minAtmospherePathLength) && uniforms.minAtmospherePathLength) {\n            const newValue = THREE.MathUtils.clamp(updates.minAtmospherePathLength, 0.0, 10000);\n            uniforms.minAtmospherePathLength.value = newValue;\n            appliedUpdates.minAtmospherePathLength = newValue;\n        }\n        if (Number.isFinite(updates.atmosphereAlphaScale) && uniforms.atmosphereAlphaScale) {\n            const newValue = THREE.MathUtils.clamp(updates.atmosphereAlphaScale, 0.1, 10.0);\n            uniforms.atmosphereAlphaScale.value = newValue;\n            appliedUpdates.atmosphereAlphaScale = newValue;\n        }\n        if (Number.isFinite(updates.atmosphereDepthClamp) && uniforms.atmosphereDepthClamp) {\n            const newValue = THREE.MathUtils.clamp(updates.atmosphereDepthClamp, 0.0, 1.0);\n            uniforms.atmosphereDepthClamp.value = newValue;\n            appliedUpdates.atmosphereDepthClamp = newValue;\n        }\n\n        console.log('[Atmosphere] Applied aerial perspective updates:', appliedUpdates);\n    }\n\n    /**\n     * Update terrain aerial perspective parameters (distance fog)\n     *\n     * @param {Object} updates - { aerialPerspectiveStrength?, aerialPerspectiveDensity?, aerialPerspectiveHeightFalloff? }\n     */\n    setTerrainAerialPerspective(updates = {}) {\n        if (!updates || typeof updates !== 'object') {\n            return;\n        }\n        if (!this.earthMaterial || !this.earthMaterial.uniforms) {\n            console.warn('[SceneInitializer] setTerrainAerialPerspective: No earth material available');\n            return;\n        }\n\n        const uniforms = this.earthMaterial.uniforms;\n        const missingUniforms = [];\n        const applyUniform = (key, min, max) => {\n            if (!Number.isFinite(updates[key])) return;\n            if (!uniforms[key] || !Object.prototype.hasOwnProperty.call(uniforms[key], 'value')) {\n                missingUniforms.push(key);\n                return;\n            }\n            uniforms[key].value = THREE.MathUtils.clamp(updates[key], min, max);\n        };\n\n        applyUniform('aerialPerspectiveStrength', 0.0, 2.0);\n        applyUniform('aerialPerspectiveDensity', 0.0, 0.001);\n        applyUniform('aerialPerspectiveHeightFalloff', 500, 50000);\n\n        if (missingUniforms.length > 0 && !this._terrainAerialPerspectiveUnsupportedWarned) {\n            this._terrainAerialPerspectiveUnsupportedWarned = true;\n            console.warn(\n                `[SceneInitializer] setTerrainAerialPerspective: terrain material does not expose uniforms (${missingUniforms.join(', ')}).`\n            );\n        }\n    }\n\n    /**\n     * Update terrain night-side visibility settings\n     *\n     * @param {Object} updates - Night visibility tuneables\n     * @param {number} [updates.nightMinBrightness] - Minimum brightness on night side (0-1, default 0.002)\n     * @param {THREE.Vector3|{r,g,b}} [updates.nightAmbientColor] - Ambient color mixed in at night\n     * @param {number} [updates.nightAmbientStrength] - How much ambient color is mixed in (0-1)\n     * @param {number} [updates.nightTransitionStart] - Sun dot where night begins (-1 to 1)\n     * @param {number} [updates.nightTransitionEnd] - Sun dot where day begins (-1 to 1)\n     * @param {number} [updates.nightPower] - Exponential falloff for night mask\n     */\n    setTerrainNightSettings(updates = {}) {\n        if (!this.earthMaterial || !this.earthMaterial.uniforms) {\n            console.warn('[SceneInitializer] setTerrainNightSettings: No earth material available');\n            return;\n        }\n\n        const uniforms = this.earthMaterial.uniforms;\n\n        if (updates.nightMinBrightness !== undefined && uniforms.nightMinBrightness) {\n            const clamped = Math.max(0, Math.min(1, updates.nightMinBrightness));\n            uniforms.nightMinBrightness.value = clamped;\n        }\n\n        if (updates.nightAmbientColor !== undefined && uniforms.nightAmbientColor) {\n            const color = updates.nightAmbientColor;\n            if (color.isVector3) {\n                uniforms.nightAmbientColor.value.copy(color);\n            } else if (typeof color === 'object' && 'r' in color) {\n                uniforms.nightAmbientColor.value.set(color.r, color.g, color.b);\n            } else if (typeof color === 'string') {\n                // Handle hex color string\n                const c = new THREE.Color(color);\n                uniforms.nightAmbientColor.value.set(c.r, c.g, c.b);\n            }\n        }\n\n        if (updates.nightAmbientStrength !== undefined && uniforms.nightAmbientStrength) {\n            const clamped = Math.max(0, Math.min(1, updates.nightAmbientStrength));\n            uniforms.nightAmbientStrength.value = clamped;\n        }\n\n        if (updates.nightTransitionStart !== undefined && uniforms.nightTransitionStart) {\n            const clamped = Math.max(-1, Math.min(1, updates.nightTransitionStart));\n            uniforms.nightTransitionStart.value = clamped;\n        }\n\n        if (updates.nightTransitionEnd !== undefined && uniforms.nightTransitionEnd) {\n            const clamped = Math.max(-1, Math.min(1, updates.nightTransitionEnd));\n            uniforms.nightTransitionEnd.value = clamped;\n        }\n\n        if (updates.nightPower !== undefined && uniforms.nightPower) {\n            const clamped = Math.max(0.1, Math.min(5, updates.nightPower));\n            uniforms.nightPower.value = clamped;\n        }\n    }\n\n    _shouldUseAtmosphereCloudsPipeline() {\n        const now = (typeof performance !== 'undefined' && performance.now)\n            ? performance.now()\n            : Date.now();\n        if (this._forceLegacyAtmosphereUntil && now < this._forceLegacyAtmosphereUntil) {\n            return false;\n        }\n        return !!(\n            this.atmosphereClouds &&\n            !this.atmosphereCloudsFailed &&\n            this.atmosphereClouds.enabled !== false &&\n            this.atmosphereClouds.shouldUseLegacyFallback?.() !== true &&\n            this.atmosphereClouds.ready\n        );\n    }\n\n    _syncAtmosphereMeshVisibility() {\n        if (!this.atmosphereMesh) return;\n        // Retire the unrelated gradient as soon as the physical owner exists,\n        // including its asynchronous LUT/clear-sky preparation. Fast terrain\n        // entry must not briefly expose a second atmosphere while those\n        // bounded jobs finish. Keep the shell only for explicit setup failure.\n        const legacyAllowed = !this.atmosphereClouds || this.atmosphereCloudsFailed\n            || this.atmosphereClouds.shouldUseLegacyFallback?.() === true;\n        this.atmosphereMesh.visible = !!(\n            this.atmosphereEnabled &&\n            legacyAllowed &&\n            !this._shouldUseAtmosphereCloudsPipeline() &&\n            this.atmosphereClouds?.hasDirectPhysicalSky?.() !== true\n        );\n    }\n\n    _handleAtmosphereCloudsRenderFailure(error) {\n        this._atmosphereCloudRenderFailures += 1;\n        const now = (typeof performance !== 'undefined' && performance.now)\n            ? performance.now()\n            : Date.now();\n        if (!this._lastAtmosphereCloudRenderFailureLog ||\n            (now - this._lastAtmosphereCloudRenderFailureLog) > 2000) {\n            console.warn('[SceneInitializer] Atmosphere clouds render failed; falling back to legacy atmosphere', error);\n            this._lastAtmosphereCloudRenderFailureLog = now;\n        }\n        this._forceLegacyAtmosphereUntil = now + 5000;\n\n        if (this._atmosphereCloudRenderFailures < 3) {\n            this._syncAtmosphereMeshVisibility();\n            return;\n        }\n\n        this.atmosphereCloudsFailed = true;\n        try {\n            this.atmosphereClouds?.setEnabled?.(false);\n        } catch (disableError) {\n            console.warn('[SceneInitializer] Failed to disable broken atmosphere clouds pipeline', disableError);\n        }\n        this._syncAtmosphereMeshVisibility();\n        this._scheduleAtmosphereCloudsRecovery();\n    }\n\n    _scheduleAtmosphereCloudsRecovery(delayMs = 10000) {\n        if (this._atmosphereCloudRecoveryTimer || !this.atmosphereClouds) return;\n        this._atmosphereCloudRecoveryTimer = setTimeout(() => {\n            this._atmosphereCloudRecoveryTimer = null;\n            if (!this.atmosphereClouds || !this.atmosphereEnabled) return;\n            // Desktop recovery must never dispose the live stereo renderer or\n            // its shared LUTs underneath an immersive frame. Retry after exit.\n            if (this.renderer?.xr?.isPresenting) {\n                this._scheduleAtmosphereCloudsRecovery(delayMs);\n                return;\n            }\n            try {\n                this._atmosphereCloudRenderFailures = 0;\n                this.atmosphereCloudsFailed = true;\n                this._disposeAtmosphereClouds({ quiet: true });\n                this.atmosphereCloudsFailed = false;\n                this._setupAtmosphereClouds();\n            } catch (error) {\n                this.atmosphereCloudsFailed = true;\n                console.warn('[SceneInitializer] Atmosphere + clouds recovery failed', error);\n                this._syncAtmosphereMeshVisibility();\n                this._scheduleAtmosphereCloudsRecovery(Math.min(delayMs * 2, 60000));\n            }\n        }, delayMs);\n    }\n\n    /**\n     * Toggle atmosphere rendering\n     * @param {boolean} enabled - true to enable atmosphere and clouds, false to disable\n     */\n    setAtmosphereEnabled(enabled) {\n        this.atmosphereEnabled = !!enabled;\n        if (this.atmosphereClouds && !this.atmosphereCloudsFailed) {\n            try {\n                this.atmosphereClouds.setEnabled(this.atmosphereEnabled);\n            } catch (error) {\n                this._handleAtmosphereCloudsRenderFailure(error);\n                return;\n            }\n        }\n        this._syncAtmosphereMeshVisibility();\n    }\n\n    isAtmosphereEnabled() {\n        return !!this.atmosphereEnabled;\n    }\n\n    /**\n     * Toggle the standalone sky-background mesh independently of the\n     * master atmosphere flag. Even when the master is on, callers can\n     * disable just the sky quad to get a pure stars/space backdrop\n     * (useful for orbital/wireframe modes).\n     */\n    setAtmosphereSkyEnabled(enabled) {\n        if (this.atmosphereClouds && !this.atmosphereCloudsFailed) {\n            this.atmosphereClouds.setSkyEnabled(!!enabled);\n        }\n    }\n\n    isAtmosphereSkyEnabled() {\n        if (this.atmosphereClouds && !this.atmosphereCloudsFailed) {\n            return this.atmosphereClouds.isSkyEnabled();\n        }\n        return false;\n    }\n\n    setAtmosphereOrbitalOverviewActive(active) {\n        const next = active === true;\n        this._atmosphereOrbitalOverviewActive = next;\n        this.atmosphereClouds?.setOrbitalOverviewActive?.(next);\n        this._syncAtmosphereOverviewDepthContract();\n        this._syncAtmosphereMeshVisibility();\n    }\n\n    setAtmosphereSurfaceCameraModeActive(active) {\n        const next = active === true;\n        if (next === this._atmosphereSurfaceCameraModeActive) return;\n        this._atmosphereSurfaceCameraModeActive = next;\n        // The flare now shares primary logarithmic depth: lunar/terrain pixels\n        // reject it. Surface glare is bounded and weather-attenuated by its\n        // environment callback instead of globally disappearing at eye height.\n        this._surfaceLensFlareSuppressed = false;\n        this._syncLensFlareVisibility();\n        this.atmosphereClouds?.setSurfaceCameraModeActive?.(next);\n    }\n\n    _syncAtmosphereOverviewDepthContract() {\n        const analyticDepth = this.atmosphereMaterial?.uniforms?.analyticPlanetDepth;\n        if (!analyticDepth) return;\n        // OverviewGlobeFallback is the same sphere used by tPlanet in the\n        // atmosphere shader, so analytic intersection is both more accurate\n        // and more stable than a 0.1 m -> astronomical-far log-depth sample.\n        // Local photoreal tiles are not spherical and therefore retain the\n        // terrain depth clamp when overview ownership ends.\n        analyticDepth.value = this._atmosphereOrbitalOverviewActive ? 1.0 : 0.0;\n    }\n\n    setAtmosphereCloudsConfig(patch = {}) {\n        if (!patch || typeof patch !== 'object') return;\n        this._atmosphereCloudsConfig = mergeDeep(this._atmosphereCloudsConfig || {}, patch);\n        // Sun/Moon are physical scene geometry. Apply their saved disk\n        // visibility even while the streamed atmosphere compositor is cold;\n        // AtmosphereCloudsSystem will independently suppress its procedural\n        // duplicates once it owns a frame.\n        if (typeof patch.sun === 'boolean' && this.sunMesh) {\n            this.sunMesh.visible = patch.sun;\n        }\n        if (typeof patch.moon === 'boolean' && this.moonSystem?.moonMesh) {\n            this.moonSystem.moonMesh.visible = patch.moon;\n        }\n        if (this.atmosphereClouds && !this.atmosphereCloudsFailed) {\n            this.atmosphereClouds.applyConfig(this._atmosphereCloudsConfig);\n        }\n    }\n\n    setAtmosphereCloudStreamingEnabled(enabled) {\n        const next = enabled === true;\n        const now = typeof performance !== 'undefined' && Number.isFinite(performance.now?.())\n            ? performance.now()\n            : Date.now();\n        if (next\n            && this._atmosphereCloudStreamingEnabled === true\n            && !this.atmosphereCloudsFailed\n            && (\n                this._atmosphereCloudsSetupRequested\n                || this.atmosphereClouds\n                || (this._atmosphereCloudsSetupRequestedAt > 0\n                    && (now - this._atmosphereCloudsSetupRequestedAt) < 250)\n            )) {\n            return;\n        }\n        if (!next && !this.atmosphereClouds && !this._atmosphereCloudsSetupRequested) return;\n        this._atmosphereCloudStreamingEnabled = next;\n        if (next) this.atmosphereClouds?.setCloudWarmupDeferred?.(false);\n        if (!next) {\n            if (this._atmosphereCloudRecoveryTimer) {\n                clearTimeout(this._atmosphereCloudRecoveryTimer);\n                this._atmosphereCloudRecoveryTimer = null;\n            }\n            this._disposeAtmosphereClouds({ quiet: true });\n            this._atmosphereCompositorRenderedAt = 0;\n            this.atmosphereCloudsFailed = false;\n            this._syncAtmosphereMeshVisibility();\n            return;\n        }\n        if (this._atmosphereCloudRecoveryTimer) {\n            clearTimeout(this._atmosphereCloudRecoveryTimer);\n            this._atmosphereCloudRecoveryTimer = null;\n        }\n        if (this.atmosphereClouds && this.atmosphereCloudsFailed) {\n            this._disposeAtmosphereClouds({ quiet: true });\n        }\n        this.atmosphereCloudsFailed = false;\n        this._atmosphereCloudsSetupRequestedAt = now;\n        this._setupAtmosphereClouds();\n        this._syncAtmosphereMeshVisibility();\n    }\n\n    /**\n     * Report whether revealing the scene can produce a stable atmosphere\n     * frame immediately. Texture readiness alone is insufficient: the Takram\n     * pipeline validates its patched shaders on its first owned frame. Until\n     * that frame succeeds, the direct atmosphere remains the safe owner.\n     */\n    getAtmosphereSceneEntryState() {\n        if (this.atmosphereEnabled === false) {\n            return {\n                ready: true,\n                active: false,\n                mode: 'disabled',\n                reason: 'atmosphere-disabled',\n            };\n        }\n        if (this.atmosphereCloudsFailed) {\n            return {\n                ready: true,\n                active: false,\n                mode: 'direct-fallback',\n                reason: 'compositor-failed',\n            };\n        }\n        if (this._atmosphereCloudStreamingEnabled !== true) {\n            return {\n                ready: false,\n                active: false,\n                mode: 'dormant',\n                reason: 'streaming-disabled',\n            };\n        }\n\n        const atmosphere = this.atmosphereClouds;\n        if (!atmosphere) {\n            return {\n                ready: false,\n                active: false,\n                mode: 'loading',\n                reason: this._atmosphereCloudsSetupRequested\n                    ? 'compositor-constructing'\n                    : 'compositor-not-requested',\n            };\n        }\n\n        const warmupState = atmosphere._cloudWarmupState || 'cold';\n        if (warmupState === 'fallback' || warmupState === 'failed') {\n            return {\n                ready: true,\n                active: false,\n                mode: 'direct-fallback',\n                reason: `cloud-warmup-${warmupState}`,\n                textureReady: atmosphere.ready === true,\n                warmupState,\n            };\n        }\n\n        const active = atmosphere.ready === true\n            && atmosphere.shouldUseLegacyFallback?.() !== true\n            && this._atmosphereCompositorRenderedAt > 0;\n        return {\n            ready: active,\n            active,\n            mode: active ? 'compositor' : 'loading',\n            reason: active\n                ? 'compositor-frame-rendered'\n                : (atmosphere.ready === true\n                    ? 'compositor-first-frame'\n                    : 'atmosphere-textures-loading'),\n            textureReady: atmosphere.ready === true,\n            warmupState,\n            renderedAt: this._atmosphereCompositorRenderedAt || 0,\n        };\n    }\n\n    getAtmosphereCloudsConfig() {\n        const config = this.atmosphereClouds?.getConfig?.() ||\n            (this._atmosphereCloudsConfig ? { ...this._atmosphereCloudsConfig } : {});\n        return {\n            ...config,\n            enabled: this.isAtmosphereEnabled()\n        };\n    }\n\n    _getEarthOverlayLoadPlan() {\n        const specular = this._earthOverlayConfig?.specularMap || {};\n        const simpleClouds = this._earthOverlayConfig?.simpleClouds || {};\n        const water = this._earthOverlayConfig?.water || {};\n        const streamingEnabled = this._earthOverlayStreamingEnabled !== false;\n        const simpleCloudStreamingEnabled = streamingEnabled\n            || this._orbitalOverviewStreamingEnabled === true;\n        const plan = {\n            specular: (streamingEnabled || this._orbitalOverviewStreamingEnabled === true)\n                && (specular.enabled !== false || water.enabled !== false),\n            simpleClouds: simpleCloudStreamingEnabled && simpleClouds.enabled === true,\n            water: streamingEnabled && water.enabled !== false,\n        };\n        plan.any = plan.specular || plan.simpleClouds || plan.water;\n        return plan;\n    }\n\n    _shouldLoadEarthOverlayTextures() {\n        return this._getEarthOverlayLoadPlan().any;\n    }\n\n    _disposeEarthOverlayTexture(texture) {\n        if (!texture) return null;\n        try {\n            texture.dispose?.();\n        } catch {\n            // ignore disposal failures\n        }\n        return null;\n    }\n\n    _disposeInactiveEarthOverlayTextures(plan = this._getEarthOverlayLoadPlan()) {\n        if (!plan.specular) {\n            this._earthSpecularTexture = this._disposeEarthOverlayTexture(this._earthSpecularTexture);\n        }\n        if (!plan.simpleClouds) {\n            this._earthSimpleCloudsTexture = this._disposeEarthOverlayTexture(this._earthSimpleCloudsTexture);\n            this._earthSimpleCloudsRefreshSlot = null;\n        }\n        if (!plan.water) {\n            this._earthWaterNormalsTexture = this._disposeEarthOverlayTexture(this._earthWaterNormalsTexture);\n        }\n    }\n\n    _disposeEarthOverlayTextures() {\n        this._earthOverlayGeneration++;\n        this._earthSpecularTexture = this._disposeEarthOverlayTexture(this._earthSpecularTexture);\n        this._earthSimpleCloudsTexture = this._disposeEarthOverlayTexture(this._earthSimpleCloudsTexture);\n        this._earthWaterNormalsTexture = this._disposeEarthOverlayTexture(this._earthWaterNormalsTexture);\n        this._earthOverlayPromise = null;\n        this._earthOverlayLoading = false;\n        this._earthSimpleCloudsPromise = null;\n        this._earthSimpleCloudsRefreshSlot = null;\n    }\n\n    _earthSimpleCloudsSlot(nowMs = Date.now()) {\n        return Math.floor(nowMs / EARTH_SIMPLE_CLOUDS_REFRESH_MS);\n    }\n\n    _buildEarthSimpleCloudsUrl(slot = this._earthSimpleCloudsSlot()) {\n        return `${EARTH_SIMPLE_CLOUDS_TEXTURE_URL}?noclip-live=${slot}`;\n    }\n\n    _configureEarthSimpleCloudsTexture(texture) {\n        if (!texture) return null;\n        if (texture.userData?.streamed) return texture; // configured before its row-streamed upload\n        texture.colorSpace = THREE.SRGBColorSpace;\n        texture.wrapS = THREE.RepeatWrapping;\n        texture.wrapT = THREE.ClampToEdgeWrapping;\n        texture.flipY = false;\n        texture.needsUpdate = true;\n        return texture;\n    }\n\n    /**\n     * 8K Earth maps (specular mask, live cloud map, water normals). With a\n     * renderer they decode in a worker and upload a band of rows per frame\n     * (StreamedImageTexture); as <img> textures they decoded + uploaded\n     * inside one frame — 200-730 ms freezes at startup and on every live\n     * cloud-map refresh. `streamed` carries the sampler/format settings that\n     * must be fixed before the first upload.\n     */\n    _loadTexture(url, streamed = null) {\n        // Streaming is opt-in until its GPU upload is verified by pixel\n        // readback: the streamed live cloud map loaded intact but did not\n        // render, so the original <img> path is the default again.\n        if (streamed && globalThis.__noclipEnableStreamedTextures === true\n            && this.renderer?.initTexture && canStreamImageTextures()) {\n            return loadStreamedImageTexture(url, { renderer: this.renderer, ...streamed });\n        }\n        const loader = new THREE.TextureLoader();\n        return new Promise((resolve, reject) => {\n            loader.load(url, resolve, undefined, reject);\n        });\n    }\n\n    _streamedCloudsTexture() {\n        return {\n            channels: 4,\n            configure: (texture) => {\n                texture.colorSpace = THREE.SRGBColorSpace;\n                texture.wrapS = THREE.RepeatWrapping;\n                texture.wrapT = THREE.ClampToEdgeWrapping;\n            },\n        };\n    }\n\n    _refreshLiveSimpleCloudsTextureIfNeeded() {\n        const simpleClouds = this._earthOverlayConfig?.simpleClouds || {};\n        const streamingEnabled = this._earthOverlayStreamingEnabled !== false\n            || this._orbitalOverviewStreamingEnabled === true;\n        if (!streamingEnabled || simpleClouds.enabled !== true) return;\n        if (this._earthOverlayLoading || this._earthSimpleCloudsPromise) return;\n        const slot = this._earthSimpleCloudsSlot();\n        if (this._earthSimpleCloudsRefreshSlot === slot && this._earthSimpleCloudsTexture) return;\n\n        const promise = this._loadTexture(this._buildEarthSimpleCloudsUrl(slot), this._streamedCloudsTexture())\n            .then((clouds) => {\n                const stillStreaming = this._earthOverlayStreamingEnabled !== false\n                    || this._orbitalOverviewStreamingEnabled === true;\n                if (!stillStreaming\n                    || this._earthOverlayConfig?.simpleClouds?.enabled !== true) {\n                    clouds?.dispose?.();\n                    return null;\n                }\n                const previous = this._earthSimpleCloudsTexture;\n                this._earthSimpleCloudsTexture = this._configureEarthSimpleCloudsTexture(clouds);\n                this._earthSimpleCloudsRefreshSlot = slot;\n                this._applyEarthOverlayConfig();\n                if (previous && previous !== this._earthSimpleCloudsTexture) {\n                    try {\n                        previous.dispose?.();\n                    } catch {\n                        // ignore disposal failures\n                    }\n                }\n                return this._earthSimpleCloudsTexture;\n            })\n            .catch((err) => {\n                console.warn('[SceneInitializer] Failed to refresh Matteason live cloud map:', err);\n                return null;\n            })\n            .finally(() => {\n                if (this._earthSimpleCloudsPromise === promise) {\n                    this._earthSimpleCloudsPromise = null;\n                }\n            });\n        this._earthSimpleCloudsPromise = promise;\n    }\n\n    _disposeLightPollutionTexture() {\n        const tileField = this._nightLightsTileField;\n        const tileFieldGlobal = tileField?.globalTexture || null;\n        const tileFieldDetail = tileField?.detailTexture || null;\n        this._nightLightsTileField = null;\n        if (tileField) {\n            tileField.onUpdate = null;\n            tileField.dispose();\n        }\n        if (this._lightPollutionTexture && this._lightPollutionTexture !== tileFieldGlobal) {\n            try {\n                this._lightPollutionTexture.dispose?.();\n            } catch {\n                // ignore disposal failures\n            }\n        }\n        if (this._lightPollutionDetailTexture\n            && this._lightPollutionDetailTexture !== tileFieldDetail) {\n            try {\n                this._lightPollutionDetailTexture.dispose?.();\n            } catch {\n                // ignore disposal failures\n            }\n        }\n        this._lightPollutionTexture = null;\n        this._lightPollutionDetailTexture = null;\n        this._lightPollutionDetailWindow = null;\n        this._lightPollutionKey = null;\n        this._lightPollutionPromise = null;\n    }\n\n    _loadEarthOverlayTextures() {\n        const plan = this._getEarthOverlayLoadPlan();\n        if (!plan.any) {\n            this._disposeEarthOverlayTextures();\n            this._applyEarthOverlayConfig();\n            return Promise.resolve(null);\n        }\n        this._disposeInactiveEarthOverlayTextures(plan);\n        if (this._earthOverlayLoading && this._earthOverlayPromise) return this._earthOverlayPromise;\n\n        const loadSpecular = plan.specular && !this._earthSpecularTexture;\n        const loadClouds = plan.simpleClouds && !this._earthSimpleCloudsTexture;\n        const loadWater = plan.water && !this._earthWaterNormalsTexture;\n        if (!loadSpecular && !loadClouds && !loadWater) {\n            this._applyEarthOverlayConfig();\n            return Promise.resolve({\n                specular: this._earthSpecularTexture,\n                clouds: this._earthSimpleCloudsTexture,\n                waterNormals: this._earthWaterNormalsTexture,\n            });\n        }\n\n        const generation = this._earthOverlayGeneration;\n        const cloudSlot = this._earthSimpleCloudsSlot();\n        const cloudPromise = loadClouds\n            ? this._loadTexture(this._buildEarthSimpleCloudsUrl(cloudSlot), this._streamedCloudsTexture())\n            : null;\n        const cloudResult = cloudPromise || Promise.resolve(null);\n        this._earthSimpleCloudsPromise = cloudPromise;\n        this._earthOverlayLoading = true;\n        let overlayPromise;\n        // Adopt each independent map as soon as it is ready. A stalled cloud\n        // request must not hold the coastline mask or spectral ocean hostage.\n        const adopt = async (promise, feature, field, configure) => {\n            let texture;\n            try { texture = await promise; }\n            catch (error) {\n                console.warn(`[SceneInitializer] Optional earth map ${feature} unavailable:`, error);\n                return;\n            }\n            if (!texture) return;\n            if (generation !== this._earthOverlayGeneration || !this._getEarthOverlayLoadPlan()[feature]) {\n                this._disposeEarthOverlayTexture(texture);\n                return;\n            }\n            configure(texture);\n            this[field] = texture;\n            this._applyEarthOverlayConfig();\n        };\n        overlayPromise = Promise.all([\n            adopt(loadSpecular ? this._loadTexture(EARTH_SPECULAR_TEXTURE_URL, {\n                channels: 1,\n                configure: (texture) => {\n                    texture.colorSpace = THREE.NoColorSpace;\n                    texture.wrapS = THREE.RepeatWrapping;\n                    texture.wrapT = THREE.ClampToEdgeWrapping;\n                },\n            }) : null,\n                'specular', '_earthSpecularTexture', texture => {\n                    if (texture.userData?.streamed) return; // R8, configured before upload\n                    texture.format = THREE.RedFormat;\n                    texture.internalFormat = 'R8';\n                    texture.colorSpace = THREE.NoColorSpace;\n                    texture.wrapS = THREE.RepeatWrapping;\n                    texture.wrapT = THREE.ClampToEdgeWrapping;\n                    texture.flipY = false;\n                    texture.needsUpdate = true;\n                }),\n            adopt(cloudResult, 'simpleClouds', '_earthSimpleCloudsTexture', texture => {\n                this._configureEarthSimpleCloudsTexture(texture);\n                this._earthSimpleCloudsRefreshSlot = cloudSlot;\n            }),\n            adopt(loadWater ? this._loadTexture(EARTH_WATER_NORMALS_TEXTURE_URL, {\n                channels: 4,\n                configure: (texture) => {\n                    texture.colorSpace = THREE.NoColorSpace;\n                    texture.wrapS = THREE.RepeatWrapping;\n                    texture.wrapT = THREE.RepeatWrapping;\n                },\n            }) : null,\n                'water', '_earthWaterNormalsTexture', texture => {\n                    if (texture.userData?.streamed) return;\n                    texture.colorSpace = THREE.NoColorSpace;\n                    texture.wrapS = THREE.RepeatWrapping;\n                    texture.wrapT = THREE.RepeatWrapping;\n                    texture.flipY = false;\n                    texture.needsUpdate = true;\n                }),\n        ]).then(() => {\n            if (generation !== this._earthOverlayGeneration) return null;\n            return {\n                specular: this._earthSpecularTexture,\n                clouds: this._earthSimpleCloudsTexture,\n                waterNormals: this._earthWaterNormalsTexture,\n            };\n        }).catch((err) => {\n            console.warn('[SceneInitializer] Failed to load earth overlay textures:', err);\n            if (this._earthOverlayPromise === overlayPromise) {\n                this._earthOverlayPromise = null;\n            }\n            if (this._earthSimpleCloudsPromise === cloudPromise) {\n                this._earthSimpleCloudsPromise = null;\n            }\n            return null;\n        }).finally(() => {\n            if (this._earthOverlayPromise === overlayPromise) {\n                this._earthOverlayPromise = null;\n                this._earthOverlayLoading = false;\n            }\n            if (this._earthSimpleCloudsPromise === cloudPromise) {\n                this._earthSimpleCloudsPromise = null;\n            }\n        });\n        this._earthOverlayPromise = overlayPromise;\n        return overlayPromise;\n    }\n\n    _applyEarthOverlayConfig() {\n        if (!this.earthMaterial || !this.earthMaterial.uniforms) return;\n        const uniforms = this.earthMaterial.uniforms;\n        const specular = this._earthOverlayConfig?.specularMap || {};\n        const simpleClouds = this._earthOverlayConfig?.simpleClouds || {};\n        const lightPollution = this._earthOverlayConfig?.lightPollution || {};\n        const water = this._earthOverlayConfig?.water || {};\n\n        if (uniforms.specularTexture) {\n            uniforms.specularTexture.value = this._earthSpecularTexture || null;\n        }\n        if (uniforms.waterMaskEnabled) uniforms.waterMaskEnabled.value = this._earthSpecularTexture ? 1 : 0;\n        if (uniforms.specularStrength && Number.isFinite(specular.strength)) {\n            uniforms.specularStrength.value = THREE.MathUtils.clamp(specular.strength, 0, 2);\n        }\n        if (uniforms.specularEnabled) {\n            uniforms.specularEnabled.value = (specular.enabled !== false && this._earthSpecularTexture) ? 1.0 : 0.0;\n        }\n\n        if (uniforms.simpleCloudsTexture) {\n            uniforms.simpleCloudsTexture.value = this._earthSimpleCloudsTexture || null;\n        }\n        if (uniforms.simpleCloudsOpacity && Number.isFinite(simpleClouds.opacity)) {\n            uniforms.simpleCloudsOpacity.value = THREE.MathUtils.clamp(simpleClouds.opacity, 0, 1);\n        }\n        if (uniforms.simpleCloudsShadowStrength && Number.isFinite(simpleClouds.shadowStrength)) {\n            uniforms.simpleCloudsShadowStrength.value = THREE.MathUtils.clamp(simpleClouds.shadowStrength, 0, 1);\n        }\n        if (uniforms.simpleCloudsShadowHeight && Number.isFinite(simpleClouds.shadowHeightMeters)) {\n            uniforms.simpleCloudsShadowHeight.value = THREE.MathUtils.clamp(simpleClouds.shadowHeightMeters, 0, 60000);\n        }\n        if (uniforms.simpleCloudsAlphaThreshold && Number.isFinite(simpleClouds.alphaThreshold)) {\n            uniforms.simpleCloudsAlphaThreshold.value = THREE.MathUtils.clamp(simpleClouds.alphaThreshold, 0, 1);\n        }\n        if (uniforms.simpleCloudsAlphaSoftness && Number.isFinite(simpleClouds.alphaSoftness)) {\n            uniforms.simpleCloudsAlphaSoftness.value = THREE.MathUtils.clamp(simpleClouds.alphaSoftness, 0, 0.5);\n        }\n        if (uniforms.simpleCloudsNightAirglowColor\n            && typeof simpleClouds.nightAirglowColor === 'string') {\n            uniforms.simpleCloudsNightAirglowColor.value.set(simpleClouds.nightAirglowColor);\n        }\n        if (uniforms.simpleCloudsNightAirglowStrength\n            && Number.isFinite(simpleClouds.nightAirglowStrength)) {\n            uniforms.simpleCloudsNightAirglowStrength.value = THREE.MathUtils.clamp(\n                simpleClouds.nightAirglowStrength,\n                0,\n                0.05\n            );\n        }\n        if (uniforms.simpleCloudsBlendMode) {\n            let blendMode = 0;\n            if (Number.isFinite(simpleClouds.blendMode)) {\n                blendMode = THREE.MathUtils.clamp(Math.floor(simpleClouds.blendMode), 0, 3);\n            } else {\n                const mode = String(simpleClouds.blendMode || 'overlay').toLowerCase();\n                if (mode === 'additive') blendMode = 1;\n                else if (mode === 'screen') blendMode = 2;\n                else if (mode === 'multiply') blendMode = 3;\n            }\n            uniforms.simpleCloudsBlendMode.value = blendMode;\n        }\n        if (uniforms.simpleCloudsEnabled) {\n            uniforms.simpleCloudsEnabled.value = (simpleClouds.enabled && this._earthSimpleCloudsTexture) ? 1.0 : 0.0;\n        }\n\n        const lightPollutionStreaming = this._isLightPollutionStreamingEnabled();\n        if (lightPollutionStreaming && lightPollution.enabled) {\n            this._ensureLightPollutionTexture();\n        }\n        if (uniforms.lightPollutionTexture) {\n            uniforms.lightPollutionTexture.value = this._lightPollutionTexture || null;\n        }\n        if (uniforms.lightPollutionDetailTexture) {\n            uniforms.lightPollutionDetailTexture.value = this._lightPollutionDetailTexture || null;\n        }\n        if (uniforms.lightPollutionDetailEnabled) {\n            uniforms.lightPollutionDetailEnabled.value = (\n                this._lightPollutionDetailTexture && this._lightPollutionDetailWindow\n            ) ? 1.0 : 0.0;\n        }\n        if (uniforms.lightPollutionDetailBounds) {\n            const detail = this._lightPollutionDetailWindow;\n            uniforms.lightPollutionDetailBounds.value.set(\n                detail?.centerU ?? 0.5,\n                detail?.minV ?? 0,\n                detail?.spanU ?? 1,\n                detail?.spanV ?? 1,\n            );\n        }\n        if (uniforms.lightPollutionIntensity && Number.isFinite(lightPollution.intensity)) {\n            uniforms.lightPollutionIntensity.value = THREE.MathUtils.clamp(lightPollution.intensity, 0, 10);\n        }\n        if (uniforms.lightPollutionMapGain && Number.isFinite(lightPollution.mapGain)) {\n            uniforms.lightPollutionMapGain.value = THREE.MathUtils.clamp(lightPollution.mapGain, 0, 10);\n        }\n        if (uniforms.lightPollutionSurfaceIntensityScale\n            && Number.isFinite(lightPollution.surfaceIntensityScale)) {\n            uniforms.lightPollutionSurfaceIntensityScale.value = THREE.MathUtils.clamp(\n                lightPollution.surfaceIntensityScale,\n                0,\n                1\n            );\n        }\n        if (uniforms.lightPollutionEmissionThreshold\n            && Number.isFinite(lightPollution.emissionThreshold)) {\n            uniforms.lightPollutionEmissionThreshold.value = THREE.MathUtils.clamp(\n                lightPollution.emissionThreshold,\n                0,\n                0.95\n            );\n        }\n        if (uniforms.lightPollutionEmissionSoftness\n            && Number.isFinite(lightPollution.emissionSoftness)) {\n            uniforms.lightPollutionEmissionSoftness.value = THREE.MathUtils.clamp(\n                lightPollution.emissionSoftness,\n                0.001,\n                0.5\n            );\n        }\n        if (uniforms.lightPollutionEmissionPower\n            && Number.isFinite(lightPollution.emissionPower)) {\n            uniforms.lightPollutionEmissionPower.value = THREE.MathUtils.clamp(\n                lightPollution.emissionPower,\n                0.1,\n                4\n            );\n        }\n        if (uniforms.lightPollutionEmissionBlueSuppression\n            && Number.isFinite(lightPollution.emissionBlueSuppression)) {\n            uniforms.lightPollutionEmissionBlueSuppression.value = THREE.MathUtils.clamp(\n                lightPollution.emissionBlueSuppression,\n                0,\n                1.5\n            );\n        }\n        if (uniforms.lightPollutionColor) {\n            const color = lightPollution.color;\n            if (color && typeof color === 'object' && 'r' in color) {\n                uniforms.lightPollutionColor.value.set(color.r, color.g, color.b);\n            } else if (typeof color === 'string') {\n                uniforms.lightPollutionColor.value.set(color);\n            }\n        }\n        if (uniforms.lightPollutionEnabled) {\n            uniforms.lightPollutionEnabled.value = (lightPollutionStreaming && lightPollution.enabled && this._lightPollutionTexture) ? 1.0 : 0.0;\n        }\n        // Manual alignment is retained for legacy custom sources. The shared\n        // NASA WMTS field is already north-up Web Mercator and uses identity.\n        if (uniforms.lightPollutionMercator) {\n            uniforms.lightPollutionMercator.value = lightPollution.mercator ? 1.0 : 0.0;\n        }\n        if (uniforms.lightPollutionUvOffset) {\n            const ou = Number.isFinite(lightPollution.offsetU) ? lightPollution.offsetU : 0;\n            const ov = Number.isFinite(lightPollution.offsetV) ? lightPollution.offsetV : 0;\n            uniforms.lightPollutionUvOffset.value.set(ou, ov);\n        }\n        if (uniforms.lightPollutionUvScale) {\n            const su = Number.isFinite(lightPollution.scaleU) ? lightPollution.scaleU : 1;\n            const sv = Number.isFinite(lightPollution.scaleV) ? lightPollution.scaleV : 1;\n            uniforms.lightPollutionUvScale.value.set(su || 1, sv || 1);\n        }\n\n        if (uniforms.waterNormalsTexture) {\n            uniforms.waterNormalsTexture.value = this._earthWaterNormalsTexture || null;\n        }\n        if (uniforms.waterOpacity && Number.isFinite(water.opacity)) {\n            uniforms.waterOpacity.value = THREE.MathUtils.clamp(water.opacity, 0, 1);\n        }\n        if (uniforms.waterColor) {\n            const color = water.color;\n            if (color && typeof color === 'object' && 'r' in color) {\n                uniforms.waterColor.value.set(color.r, color.g, color.b);\n            } else if (typeof color === 'string') {\n                uniforms.waterColor.value.set(color);\n            }\n        }\n        if (uniforms.waterNormalScale && Number.isFinite(water.normalScale)) {\n            uniforms.waterNormalScale.value = THREE.MathUtils.clamp(water.normalScale, 0, 4);\n        }\n        if (uniforms.waterDistortion && Number.isFinite(water.distortion)) {\n            uniforms.waterDistortion.value = THREE.MathUtils.clamp(water.distortion, 0, 4);\n        }\n        if (uniforms.waterSpecularStrength && Number.isFinite(water.specularStrength)) {\n            uniforms.waterSpecularStrength.value = THREE.MathUtils.clamp(water.specularStrength, 0, 4);\n        }\n        if (uniforms.waterSpecularPower && Number.isFinite(water.specularPower)) {\n            uniforms.waterSpecularPower.value = THREE.MathUtils.clamp(water.specularPower, 1, 256);\n        }\n        if (uniforms.waterFresnelStrength && Number.isFinite(water.fresnelStrength)) {\n            uniforms.waterFresnelStrength.value = THREE.MathUtils.clamp(water.fresnelStrength, 0, 4);\n        }\n        if (uniforms.waterFresnelPower && Number.isFinite(water.fresnelPower)) {\n            uniforms.waterFresnelPower.value = THREE.MathUtils.clamp(water.fresnelPower, 0.5, 10);\n        }\n        if (uniforms.waterUvScale && Number.isFinite(water.uvScale)) {\n            uniforms.waterUvScale.value = THREE.MathUtils.clamp(water.uvScale, 0.1, 10);\n        }\n        if (uniforms.waterNormalsEnabled) {\n            uniforms.waterNormalsEnabled.value = this._earthWaterNormalsTexture ? 1.0 : 0.0;\n        }\n        if (uniforms.waterEnabled) {\n            uniforms.waterEnabled.value = water.enabled !== false ? 1.0 : 0.0;\n        }\n    }\n\n    setEarthOverlayConfig(patch = {}) {\n        if (!patch || typeof patch !== 'object') return;\n        this._earthOverlayConfig = mergeDeep(this._earthOverlayConfig || {}, patch);\n        const lightPollutionEnabled = this._isLightPollutionStreamingEnabled()\n            && this._earthOverlayConfig?.lightPollution?.enabled === true;\n        if (!lightPollutionEnabled) {\n            this._disposeLightPollutionTexture();\n        }\n        if (this._shouldLoadEarthOverlayTextures()) {\n            if (!this._earthOverlayPromise) {\n                this._loadEarthOverlayTextures();\n            } else {\n                this._applyEarthOverlayConfig();\n            }\n        } else {\n            this._disposeEarthOverlayTextures();\n            this._applyEarthOverlayConfig();\n        }\n    }\n\n    setEarthOverlayStreamingEnabled(enabled) {\n        const next = enabled === true;\n        if (this._earthOverlayStreamingEnabled === next) return;\n        this._earthOverlayStreamingEnabled = next;\n        const plan = this._getEarthOverlayLoadPlan();\n        this._disposeInactiveEarthOverlayTextures(plan);\n        if (!this._isLightPollutionStreamingEnabled()) {\n            this._disposeLightPollutionTexture();\n        }\n        this._applyEarthOverlayConfig();\n        if (plan.any) {\n            this._loadEarthOverlayTextures();\n        }\n    }\n\n    _isLightPollutionStreamingEnabled() {\n        return this._earthOverlayStreamingEnabled !== false\n            || this._orbitalOverviewStreamingEnabled === true;\n    }\n\n    /**\n     * Keep orbital night emission, the water mask and live simple-cloud map\n     * available to OverviewGlobeFallback while retiring local normal textures.\n     * The live map is the lightweight non-GIBS orbital cloud path.\n     */\n    setOrbitalOverviewStreamingEnabled(enabled) {\n        const next = enabled === true;\n        if (this._orbitalOverviewStreamingEnabled === next) return;\n        this._orbitalOverviewStreamingEnabled = next;\n        const plan = this._getEarthOverlayLoadPlan();\n        this._disposeInactiveEarthOverlayTextures(plan);\n        if (!this._isLightPollutionStreamingEnabled()) {\n            this._disposeLightPollutionTexture();\n        }\n        this._applyEarthOverlayConfig();\n        if (plan.any) {\n            this._loadEarthOverlayTextures();\n        }\n    }\n\n    getEarthOverlayConfig() {\n        return {\n            specularMap: { ...(this._earthOverlayConfig?.specularMap || {}) },\n            simpleClouds: { ...(this._earthOverlayConfig?.simpleClouds || {}) },\n            lightPollution: { ...(this._earthOverlayConfig?.lightPollution || {}) },\n            water: { ...(this._earthOverlayConfig?.water || {}) }\n        };\n    }\n\n    _buildLightPollutionUrl(config) {\n        const width = Number.isFinite(config?.width) ? Math.round(config.width) : 2048;\n        const height = Number.isFinite(config?.height) ? Math.round(config.height) : 2048;\n        const rawBaseUrl = (config?.baseUrl && String(config.baseUrl).trim()) || NIGHT_LIGHTS_IMAGE_SERVER;\n        // Direct static image (e.g. vendored equirectangular night-lights map).\n        // Load it verbatim; WMS/ImageServer query parameters do not apply and a\n        // plain 2:1 equirect texture samples correctly with the globe's vUv.\n        if (/\\.(png|jpe?g|webp|avif)(?:[?#]|$)/i.test(rawBaseUrl)) {\n            return rawBaseUrl;\n        }\n        const imageServerCandidate = (config?.imageServerUrl && String(config.imageServerUrl).trim()) || rawBaseUrl;\n        const buildWmsUrl = (baseUrl) => {\n            const layer = (config?.fallbackLayer && String(config.fallbackLayer).trim())\n                || PUBLIC_LIGHT_POLLUTION_LAYER;\n            // The BBOX below is the full globe (360 deg x 180 deg = 2:1). The\n            // requested image dimensions must match that aspect or GIBS returns\n            // a vertically squished map that then smears pole-to-pole when\n            // sampled as an equirectangular texture (vUv is linear in latitude).\n            // The shared `height` default is square — correct for the Mercator\n            // ImageServer branch (square WORLD_BBOX_MERCATOR) but wrong here —\n            // so derive a 2:1 height from the width for this EPSG:4326 request.\n            const wmsWidth = width;\n            const wmsHeight = Math.max(1, Math.round(wmsWidth / 2));\n            const params = new URLSearchParams({\n                SERVICE: 'WMS',\n                REQUEST: 'GetMap',\n                VERSION: '1.1.1',\n                LAYERS: layer,\n                FORMAT: 'image/png',\n                TRANSPARENT: 'true',\n                WIDTH: String(wmsWidth),\n                HEIGHT: String(wmsHeight),\n                SRS: 'EPSG:4326',\n                BBOX: '-180,-90,180,90'\n            });\n            return `${baseUrl}?${params.toString()}`;\n        };\n        if (imageServerCandidate.replace(/\\/+$/, '').startsWith(LEGACY_NIGHT_LIGHTS_IMAGE_SERVER)) {\n            return buildWmsUrl(PUBLIC_LIGHT_POLLUTION_WMS_URL);\n        }\n        const imageServerMatch = imageServerCandidate.match(/^(.*?\\/ImageServer)(?:\\/.*)?$/i);\n        if (imageServerMatch && imageServerMatch[1]) {\n            const imageServerUrl = imageServerMatch[1];\n            const exportUrl = `${imageServerUrl.replace(/\\/+$/, '')}/exportImage`;\n            const bbox = (config?.bbox && String(config.bbox).trim()) || WORLD_BBOX_MERCATOR;\n            const bboxSR = Number.isFinite(config?.bboxSR) ? String(config.bboxSR) : '3857';\n            const imageSR = Number.isFinite(config?.imageSR) ? String(config.imageSR) : '3857';\n            const format = (config?.format && String(config.format).trim()) || 'png32';\n            const params = new URLSearchParams({\n                f: 'image',\n                bbox,\n                bboxSR,\n                imageSR,\n                size: `${width},${height}`,\n                format,\n                transparent: 'true'\n            });\n            const renderingRule = config?.renderingRule ?? NIGHT_LIGHTS_RENDERING_RULE;\n            if (renderingRule) {\n                params.set(\n                    'renderingRule',\n                    typeof renderingRule === 'string' ? renderingRule : JSON.stringify(renderingRule)\n                );\n            }\n            if (config?.mosaicRule) {\n                params.set(\n                    'mosaicRule',\n                    typeof config.mosaicRule === 'string' ? config.mosaicRule : JSON.stringify(config.mosaicRule)\n                );\n            }\n            return `${exportUrl}?${params.toString()}`;\n        }\n\n        const allowRemote = config?.allowRemote === true;\n        const shouldFallback = allowRemote\n            && (rawBaseUrl === '/api/light-pollution' || !rawBaseUrl)\n            && !hasBackendOverride()\n            && !isLocalRuntime();\n        const baseUrl = shouldFallback\n            ? PUBLIC_LIGHT_POLLUTION_WMS_URL\n            : resolveBackendApiUrl(rawBaseUrl);\n        if (baseUrl.includes('gibs.earthdata.nasa.gov')) {\n            return buildWmsUrl(baseUrl);\n        }\n        const params = new URLSearchParams({\n            width: String(width),\n            height: String(height)\n        });\n        if (config?.source) params.set('source', String(config.source));\n        if (config?.renderingRule) {\n            params.set(\n                'renderingRule',\n                typeof config.renderingRule === 'string'\n                    ? config.renderingRule\n                    : JSON.stringify(config.renderingRule)\n            );\n        }\n        if (config?.format) params.set('format', String(config.format));\n        if (config?.bbox) params.set('bbox', String(config.bbox));\n        if (Number.isFinite(config?.bboxSR)) params.set('bboxSR', String(config.bboxSR));\n        if (Number.isFinite(config?.imageSR)) params.set('imageSR', String(config.imageSR));\n        return `${baseUrl}?${params.toString()}`;\n    }\n\n    _ensureLightPollutionTexture() {\n        if (!this._isLightPollutionStreamingEnabled()) return;\n        const config = this._earthOverlayConfig?.lightPollution || {};\n        const tileUrl = (config.tileUrl && String(config.tileUrl).trim())\n            || NASA_NIGHT_LIGHTS_TILE_SOURCE.url;\n        const maxNativeZoom = Number.isFinite(config.maxNativeZoom)\n            ? THREE.MathUtils.clamp(Math.round(config.maxNativeZoom), 3, 8)\n            : NASA_NIGHT_LIGHTS_TILE_SOURCE.maxNativeZoom;\n        const key = `${tileUrl}|${maxNativeZoom}`;\n        if (this._nightLightsTileField && this._lightPollutionKey !== key) {\n            this._disposeLightPollutionTexture();\n        }\n\n        if (!this._nightLightsTileField) {\n            this._lightPollutionKey = key;\n            this._nightLightsTileField = new NasaNightLightsTileField({\n                tileUrl,\n                maxNativeZoom,\n                onUpdate: (state) => {\n                    if (this._lightPollutionKey !== key || !this._nightLightsTileField) return;\n                    this._lightPollutionTexture = state.globalTexture || null;\n                    this._lightPollutionDetailTexture = state.detailTexture || null;\n                    this._lightPollutionDetailWindow = state.detailWindow || null;\n                    this._applyEarthOverlayConfig();\n                },\n            });\n        }\n\n        const field = this._nightLightsTileField;\n        if (!this._lightPollutionPromise && !field.globalTexture) {\n            const promise = field.ensureGlobal().finally(() => {\n                if (this._lightPollutionPromise === promise) this._lightPollutionPromise = null;\n            });\n            this._lightPollutionPromise = promise;\n        }\n        this._updateLightPollutionTileField();\n    }\n\n    _updateLightPollutionTileField() {\n        const field = this._nightLightsTileField;\n        if (!field || !this.camera) return;\n        const position = this._getCameraMotionPosition();\n        const planetRadius = this.earthMaterial?.uniforms?.planetRadius?.value || PLANET_RADIUS;\n        // One analytic WGS84 ray selects the actual viewed region; no terrain\n        // query, provider camera or extra tile-demand hierarchy is involved.\n        this._nightLightViewDirection ||= new THREE.Vector3();\n        this._nightLightFocus ||= new THREE.Vector3();\n        const ray=this.camera.getWorldDirection(this._nightLightViewDirection);\n        if(this.planetGroup){\n            this.planetGroup.getWorldQuaternion(this._motionTmpQuat).invert();\n            ray.applyQuaternion(this._motionTmpQuat);\n        }\n        const aa=6378137**2,bb=6356752.314245**2;\n        const qa=(ray.x*ray.x+ray.z*ray.z)/aa+ray.y*ray.y/bb;\n        const qb=(position.x*ray.x+position.z*ray.z)/aa+position.y*ray.y/bb;\n        const qc=(position.x*position.x+position.z*position.z)/aa+position.y*position.y/bb-1;\n        const disc=qb*qb-qa*qc,hit=disc>=0?(-qb-Math.sqrt(disc))/qa:-1;\n        const focus=this._nightLightFocus.copy(position);\n        if(hit>0)focus.addScaledVector(ray,hit);\n        field.updateForPlanetLocalPosition(position, planetRadius, {\n            focusPosition:focus,\n            viewportWidth: this.renderer?.domElement?.width,\n            viewportHeight: this.renderer?.domElement?.height,\n            fovDegrees: this.camera.getEffectiveFOV?.() || this.camera.fov,\n        });\n    }\n\n    setWeatherSystem(system) {\n        this.weatherSystem = system || null;\n        if (this.weatherSystem && this._weatherConfig) {\n            this.weatherSystem.applyConfig?.(this._weatherConfig);\n        }\n    }\n\n    setRainSystem(system) {\n        this.rainSystem = system || null;\n        this.atmosphereClouds?.setRainSystem?.(this.rainSystem);\n    }\n\n    setWeatherConfig(patch = {}) {\n        if (!patch || typeof patch !== 'object') return;\n        this._weatherConfig = mergeDeep(this._weatherConfig || {}, patch);\n        if (this.weatherSystem) {\n            this.weatherSystem.applyConfig?.(this._weatherConfig);\n        }\n    }\n\n    getWeatherConfig() {\n        return this.weatherSystem?.getConfig?.() ||\n            (this._weatherConfig ? { ...this._weatherConfig } : {});\n    }\n\n    setWorldRoot(worldRoot) {\n        this.worldRoot = worldRoot || null;\n    }\n\n    setPlanetGroup(group) {\n        if (this.planetGroup === group) return;\n        this.planetGroup = group || null;\n        if (this.atmosphereClouds) {\n            this.atmosphereClouds.setPlanetGroup(this.planetGroup);\n        }\n        if (this.planetGroup) {\n            if (this.planetGroup.getWorldQuaternion) {\n                this.planetGroup.getWorldQuaternion(this._atmosphereDepthLastPlanetQuat);\n            } else {\n                this._atmosphereDepthLastPlanetQuat.copy(this.planetGroup.quaternion);\n            }\n        }\n        this._motionHasSample = false;\n        this._atmosphereDepthDirty = true;\n    }\n\n    setPerformanceMonitor(perf) {\n        this._perf = perf || null;\n        if (perf && typeof perf.start === 'function' && typeof perf.end === 'function') {\n            this._perfStart = (name) => perf.start(name);\n            this._perfEnd = (name) => perf.end(name);\n        } else {\n            this._perfStart = () => {};\n            this._perfEnd = () => {};\n        }\n        if (this.atmosphereClouds?.setPerformanceMonitor) {\n            this.atmosphereClouds.setPerformanceMonitor(perf);\n        }\n    }\n\n    /**\n     * Register objects/groups to exclude from atmosphere depth passes\n     * This prevents overlays and other non-terrain objects from affecting atmosphere scattering\n     * @param {THREE.Object3D} object - Object or group to exclude\n     */\n    addDepthPassExclude(object) {\n        if (object && !this._depthPassExcludeObjects.includes(object)) {\n            this._depthPassExcludeObjects.push(object);\n        }\n    }\n\n    /**\n     * Remove object from depth pass exclusion list\n     * @param {THREE.Object3D} object - Object to remove from exclusion list\n     */\n    removeDepthPassExclude(object) {\n        const index = this._depthPassExcludeObjects.indexOf(object);\n        if (index !== -1) {\n            this._depthPassExcludeObjects.splice(index, 1);\n        }\n    }\n\n    /**\n     * Force the atmosphere depth pre-pass to re-render on the next frame.\n     * The pre-pass is normally throttled to camera motion, so opaque\n     * geometry that changes while the view is settled — e.g. photorealistic\n     * tiles streaming/refining in — leaves the depth texture stale and the\n     * aurora/clouds bleed through it. Callers invalidate on such changes.\n     */\n    markAtmosphereDepthDirty() {\n        this._atmosphereDepthDirty = true;\n    }\n\n    /** True while the WebGL context is lost. The render loop checks this to\n     *  stop issuing GL work against a dead context (which hard-crashes the\n     *  tab) until the context is restored. */\n    isContextLost() {\n        return this._glContextLost === true;\n    }\n\n    setRenderReadinessProvider(provider) {\n        this._renderReadinessProvider = typeof provider === 'function' ? provider : null;\n    }\n\n    setPresentationSuspended(suspended) {\n        this._presentationSuspended = !!suspended;\n        if (suspended) this.regionalWaterMask?.suspend();\n        if (this._waterAttribution) this._waterAttribution.hidden = !!suspended;\n        const gpuSuspended = !!suspended || this._hdSceneProxy?.stats.ready === true;\n        this.skyFeatures?.setPresentationSuspended(suspended);\n        this.atmosphereClouds?.setPresentationSuspended?.(gpuSuspended);\n        if (!suspended) this.handleResize();\n    }\n\n    // A restored WebGL context and upload-ready native tile images are separate\n    // facts. Never report recovery work as a second context-loss event.\n    isRenderBlocked() {\n        return this._presentationSuspended === true || this.isContextLost() || this._renderReadinessProvider?.() === false;\n    }\n\n    /**\n     * Handle WebGL context loss/restore. Scene overload (GPU VRAM exhausted\n     * by too many photoreal tiles/textures) makes the browser drop the\n     * context; without preventDefault + a render guard the loop keeps\n     * hammering a dead context and the tab crashes. Here we:\n     *   • preventDefault on loss so the browser can restore the context,\n     *   • flag the loss so the animation loop parks instead of crashing,\n     *   • ask the scene to shed tile-cache pressure so restore has headroom,\n     *   • recreate size-dependent GPU resources and resume on restore.\n     */\n    _installContextLossHandlers() {\n        const canvas = this.renderer?.domElement;\n        if (!canvas || this._contextLossHandlersInstalled) return;\n        this._contextLossHandlersInstalled = true;\n        this._glContextLost = false;\n\n        canvas.addEventListener('webglcontextlost', (event) => {\n            // Must preventDefault for 'webglcontextrestored' to ever fire.\n            event.preventDefault();\n            this._glContextLost = true;\n            console.warn('[SceneInitializer] WebGL context lost — parking render loop (scene overload / GPU memory).');\n            try {\n                if (typeof document !== 'undefined' && typeof CustomEvent !== 'undefined') {\n                    document.dispatchEvent(new CustomEvent('noclip:webglcontextlost'));\n                }\n            } catch { /* noop */ }\n        }, false);\n\n        canvas.addEventListener('webglcontextrestored', () => {\n            console.info('[SceneInitializer] WebGL context restored — resuming.');\n            this._glContextLost = false;\n            try {\n                // Size-dependent targets are invalid after a restore; rebuild\n                // the atmosphere depth target and force its next pre-pass.\n                this.setupAtmosphereDepthTarget?.();\n                this._atmosphereDepthDirty = true;\n                const w = this._lastClientWidth || this.container?.clientWidth || 0;\n                const h = this._lastClientHeight || this.container?.clientHeight || 0;\n                if (w > 0 && h > 0) this.renderer?.setSize?.(Math.floor(w * this.renderScale), Math.floor(h * this.renderScale), false);\n            } catch (err) {\n                console.warn('[SceneInitializer] context-restore rebuild failed', err);\n            }\n            try {\n                if (typeof document !== 'undefined' && typeof CustomEvent !== 'undefined') {\n                    document.dispatchEvent(new CustomEvent('noclip:webglcontextrestored'));\n                }\n            } catch { /* noop */ }\n        }, false);\n    }\n\n    setBloomConfig(patch = {}) {\n        if (!patch || typeof patch !== 'object') return;\n        const next = { ...(this._bloomSettings || {}) };\n\n        if (typeof patch.enabled === 'boolean') {\n            this._bloomEnabled = patch.enabled;\n        }\n        if (Number.isFinite(patch.intensity)) {\n            next.intensity = THREE.MathUtils.clamp(patch.intensity, 0, 6);\n        }\n        if (Number.isFinite(patch.radius)) {\n            next.radius = THREE.MathUtils.clamp(patch.radius, 0, 1);\n        }\n        if (Number.isFinite(patch.threshold)) {\n            next.threshold = THREE.MathUtils.clamp(patch.threshold, 0, 1);\n        }\n        if (Number.isFinite(patch.smoothing)) {\n            next.smoothing = THREE.MathUtils.clamp(patch.smoothing, 0, 1);\n        }\n        if (Number.isFinite(patch.levels)) {\n            next.levels = THREE.MathUtils.clamp(Math.round(patch.levels), 1, 8);\n        }\n        if (typeof patch.mipmapBlur === 'boolean') {\n            next.mipmapBlur = patch.mipmapBlur;\n        }\n\n        this._bloomSettings = next;\n        this._applyBloomToAtmosphereClouds();\n        try {\n            if (this._bloomEnabled) {\n                this._ensureBloomComposer();\n            }\n            this._applyBloomSettings();\n        } catch (error) {\n            const now = (typeof performance !== 'undefined' && performance.now)\n                ? performance.now()\n                : Date.now();\n            if (!this._lastBloomComposerErrorLog || (now - this._lastBloomComposerErrorLog) > 2000) {\n                console.warn('[SceneInitializer] Renderer bloom composer setup failed; atmosphere bloom remains synced', error);\n                this._lastBloomComposerErrorLog = now;\n            }\n        }\n        this._applyBloomToAtmosphereClouds();\n    }\n\n    getBloomConfig() {\n        return {\n            enabled: !!this._bloomEnabled,\n            intensity: this._bloomSettings?.intensity ?? 0,\n            radius: this._bloomSettings?.radius ?? 0,\n            threshold: this._bloomSettings?.threshold ?? 1,\n            smoothing: this._bloomSettings?.smoothing ?? 0,\n            levels: this._bloomSettings?.levels ?? 5,\n            mipmapBlur: !!this._bloomSettings?.mipmapBlur\n        };\n    }\n\n    /** scene.lens: physical DOF + chromatic aberration in the atmosphere compositor. */\n    setLensConfig(patch = {}) {\n        if (!patch || typeof patch !== 'object') return;\n        this._lensSettings = normalizeLensConfig(patch, this._lensSettings);\n        this._lensVersion += 1;\n        this._applyLensToAtmosphereClouds();\n    }\n\n    getLensConfig() {\n        return this._lensSettings;\n    }\n\n    _applyLensToAtmosphereClouds() {\n        const target = this.atmosphereClouds;\n        if (!target?.setLensEffects) return;\n        if (this._lensAppliedTarget === target && this._lensAppliedVersion === this._lensVersion) return;\n        target.setLensEffects(this._lensSettings);\n        this._lensAppliedTarget = target;\n        this._lensAppliedVersion = this._lensVersion;\n    }\n\n    setDepthOfFieldTargetProvider(provider) {\n        this._depthOfFieldTargetProvider = typeof provider === 'function' ? provider : null;\n    }\n\n    setDepthOfFieldConfig(patch = {}) {\n        if (!patch || typeof patch !== 'object') return;\n        const next = { ...(this._depthOfFieldSettings || {}) };\n        if (typeof patch.enabled === 'boolean') this._depthOfFieldEnabled = patch.enabled;\n        if (typeof patch.autofocus === 'boolean') next.autofocus = patch.autofocus;\n        if (Number.isFinite(patch.focusDistance)) {\n            next.focusDistance = THREE.MathUtils.clamp(patch.focusDistance, 0.1, 2_000_000);\n        }\n        const focalLength = Number.isFinite(patch.focalLength) ? patch.focalLength : patch.focusRange;\n        if (Number.isFinite(focalLength)) next.focalLength = THREE.MathUtils.clamp(focalLength, 0.1, 500_000);\n        if (Number.isFinite(patch.bokehScale)) next.bokehScale = THREE.MathUtils.clamp(patch.bokehScale, 0, 20);\n        if (Number.isFinite(patch.resolutionScale)) next.resolutionScale = THREE.MathUtils.clamp(patch.resolutionScale, 0.25, 1);\n        if (Number.isFinite(patch.response)) next.response = THREE.MathUtils.clamp(patch.response, 0.02, 2);\n        if (Number.isFinite(patch.sampleIntervalMs)) next.sampleIntervalMs = THREE.MathUtils.clamp(patch.sampleIntervalMs, 60, 1000);\n        if (Number.isFinite(patch.maxFocusDistance)) {\n            next.maxFocusDistance = THREE.MathUtils.clamp(patch.maxFocusDistance, 10, 20_000_000);\n        }\n        if (Number.isFinite(patch.autoRangeScale)) {\n            this._depthOfFieldAutoRangeScale = THREE.MathUtils.clamp(patch.autoRangeScale, 0.01, 1);\n        }\n        if (Number.isFinite(patch.autoRangeMin)) {\n            this._depthOfFieldAutoRangeMin = Math.max(0.01, patch.autoRangeMin);\n        }\n        this._depthOfFieldSettings = next;\n\n        if (!next.autofocus || !Number.isFinite(this._depthOfFieldFocusTarget)) {\n            this._depthOfFieldFocusTarget = next.focusDistance;\n        }\n        if (!Number.isFinite(this._depthOfFieldFocusDistance)) {\n            this._depthOfFieldFocusDistance = next.focusDistance;\n        }\n        if (this._depthOfFieldEnabled) {\n            this._ensureBloomComposer();\n            this._ensureDepthOfFieldPass();\n        }\n        this._applyDepthOfFieldSettings();\n    }\n\n    getDepthOfFieldConfig() {\n        const settings = this._depthOfFieldSettings || {};\n        return {\n            enabled: !!this._depthOfFieldEnabled,\n            autofocus: settings.autofocus !== false,\n            focusDistance: settings.focusDistance ?? 25,\n            focalLength: settings.focalLength ?? 12,\n            bokehScale: settings.bokehScale ?? 2.5,\n            resolutionScale: settings.resolutionScale ?? 0.5,\n            response: settings.response ?? 0.18,\n            sampleIntervalMs: settings.sampleIntervalMs ?? 140,\n            maxFocusDistance: settings.maxFocusDistance ?? 2_000_000,\n            autoRangeScale: this._depthOfFieldAutoRangeScale,\n            autoRangeMin: this._depthOfFieldAutoRangeMin,\n            resolvedFocusDistance: this._depthOfFieldFocusDistance\n        };\n    }\n\n    setMotionBlurConfig(patch = {}) {\n        if (!patch || typeof patch !== 'object') return;\n        const next = { ...(this._motionBlurSettings || {}) };\n\n        if (typeof patch.enabled === 'boolean') {\n            this._motionBlurEnabled = patch.enabled;\n        }\n        if (Number.isFinite(patch.intensity)) {\n            next.intensity = THREE.MathUtils.clamp(patch.intensity, 0, 1);\n        }\n        if (Number.isFinite(patch.maxSpeed)) {\n            next.maxSpeed = Math.max(1, patch.maxSpeed);\n        }\n        if (Number.isFinite(patch.smoothing)) {\n            next.smoothing = THREE.MathUtils.clamp(patch.smoothing, 0, 1);\n        }\n        if (Number.isFinite(patch.dampMin)) {\n            next.dampMin = THREE.MathUtils.clamp(patch.dampMin, 0, 0.99);\n        }\n        if (Number.isFinite(patch.dampMax)) {\n            next.dampMax = THREE.MathUtils.clamp(patch.dampMax, 0.5, 0.999);\n        }\n\n        if (Number.isFinite(next.dampMin) && Number.isFinite(next.dampMax) && next.dampMin > next.dampMax) {\n            const swap = next.dampMin;\n            next.dampMin = next.dampMax;\n            next.dampMax = swap;\n        }\n\n        this._motionBlurSettings = next;\n        if (this._motionBlurEnabled) {\n            this._ensureBloomComposer();\n        }\n        this._applyMotionBlurSettings();\n    }\n\n    getMotionBlurConfig() {\n        return {\n            enabled: !!this._motionBlurEnabled,\n            intensity: this._motionBlurSettings?.intensity ?? 0,\n            maxSpeed: this._motionBlurSettings?.maxSpeed ?? 0,\n            smoothing: this._motionBlurSettings?.smoothing ?? 0,\n            dampMin: this._motionBlurSettings?.dampMin ?? 0.85,\n            dampMax: this._motionBlurSettings?.dampMax ?? 0.98\n        };\n    }\n\n    setSpeedFovConfig(patch = {}) {\n        if (!patch || typeof patch !== 'object') return;\n        const next = { ...(this._speedFovSettings || {}) };\n\n        if (typeof patch.enabled === 'boolean') {\n            this._speedFovEnabled = patch.enabled;\n        }\n        if (Number.isFinite(patch.baseFov)) {\n            next.baseFov = THREE.MathUtils.clamp(patch.baseFov, 10, 120);\n        }\n        if (Number.isFinite(patch.maxBoost)) {\n            next.maxBoost = THREE.MathUtils.clamp(patch.maxBoost, 0, 60);\n        }\n        if (Number.isFinite(patch.maxSpeed)) {\n            next.maxSpeed = Math.max(1, patch.maxSpeed);\n        }\n        if (Number.isFinite(patch.smoothing)) {\n            next.smoothing = THREE.MathUtils.clamp(patch.smoothing, 0, 1);\n        }\n\n        this._speedFovSettings = next;\n        if (Number.isFinite(next.baseFov)) {\n            this._speedFovBase = next.baseFov;\n            this._speedFovCurrent = next.baseFov;\n        } else if (this._speedFovEnabled && this.camera) {\n            this._speedFovBase = this.camera.fov;\n            this._speedFovCurrent = this.camera.fov;\n        }\n        if (!this._speedFovEnabled) {\n            this._resetSpeedFov();\n        }\n    }\n\n    getSpeedFovConfig() {\n        return {\n            enabled: !!this._speedFovEnabled,\n            baseFov: this._speedFovSettings?.baseFov ?? null,\n            maxBoost: this._speedFovSettings?.maxBoost ?? 0,\n            maxSpeed: this._speedFovSettings?.maxSpeed ?? 0,\n            smoothing: this._speedFovSettings?.smoothing ?? 0\n        };\n    }\n\n    setEmissiveConfig(patch = {}) {\n        if (!patch || typeof patch !== 'object') return;\n        const next = { ...(this._emissiveConfig || {}) };\n\n        if (Number.isFinite(patch.materialIntensity)) {\n            next.materialIntensity = THREE.MathUtils.clamp(patch.materialIntensity, 0, 8);\n        }\n        if (typeof patch.materialColor === 'string') {\n            next.materialColor = patch.materialColor;\n        }\n        if (Number.isFinite(patch.starfieldIntensity)) {\n            next.starfieldIntensity = THREE.MathUtils.clamp(patch.starfieldIntensity, 0, 8);\n        }\n        if (Number.isFinite(patch.galaxyIntensity)) {\n            next.galaxyIntensity = THREE.MathUtils.clamp(patch.galaxyIntensity, 0, 8);\n        }\n        if (Number.isFinite(patch.sunIntensity)) {\n            next.sunIntensity = THREE.MathUtils.clamp(patch.sunIntensity, 0, 8);\n        }\n\n        this._emissiveConfig = next;\n        this._emissiveDirty = true;\n        this._applyEmissiveTuning();\n    }\n\n    _ensureBloomComposer() {\n        if (!this.renderer || !this.scene || !this.camera) return;\n        if (this._bloomComposer) return;\n\n        const composer = new EffectComposer(this.renderer, {\n            frameBufferType: THREE.HalfFloatType\n        });\n        const renderPass = new RenderPass(this.scene, this.camera);\n        composer.addPass(renderPass);\n\n        this._bloomComposer = composer;\n        this._bloomRenderPass = renderPass;\n\n        if (this._bloomEnabled) {\n            const bloom = new BloomEffect({\n                intensity: this._bloomSettings?.intensity ?? POSTPROCESS_BLOOM_DEFAULTS.intensity,\n                luminanceThreshold: this._bloomSettings?.threshold ?? POSTPROCESS_BLOOM_DEFAULTS.threshold,\n                luminanceSmoothing: this._bloomSettings?.smoothing ?? POSTPROCESS_BLOOM_DEFAULTS.smoothing,\n                radius: this._bloomSettings?.radius ?? POSTPROCESS_BLOOM_DEFAULTS.radius,\n                levels: this._bloomSettings?.levels ?? POSTPROCESS_BLOOM_DEFAULTS.levels,\n                mipmapBlur: this._bloomSettings?.mipmapBlur ?? POSTPROCESS_BLOOM_DEFAULTS.mipmapBlur\n            });\n            const bloomPass = new EffectPass(this.camera, bloom);\n            composer.addPass(bloomPass);\n            this._bloomEffect = bloom;\n            this._bloomEffectPass = bloomPass;\n        }\n\n        if (this._depthOfFieldEnabled) {\n            this._ensureDepthOfFieldPass();\n        }\n\n        if (this._motionBlurEnabled) {\n            this._ensureMotionBlurPass();\n        }\n        if (this._fxaaEnabled) {\n            this._ensureFxaaPass();\n        }\n\n        this._syncBloomComposerSize();\n    }\n\n    _ensureDepthOfFieldPass() {\n        if (!this._bloomComposer || !this.camera || this._depthOfFieldPass) return;\n        const settings = this._depthOfFieldSettings || {};\n        const effect = new DepthOfFieldEffect(this.camera, {\n            worldFocusDistance: settings.focusDistance ?? 25,\n            worldFocusRange: this._resolveDepthOfFieldRange(settings.focusDistance ?? 25),\n            bokehScale: settings.bokehScale ?? 2.5,\n            resolutionScale: settings.resolutionScale ?? 0.5\n        });\n        const pass = new EffectPass(this.camera, effect);\n        pass.enabled = !!this._depthOfFieldEnabled;\n        this._depthOfFieldEffect = effect;\n        this._depthOfFieldPass = pass;\n        this._bloomComposer.addPass(pass);\n        this._reorderPostEffectPasses();\n    }\n\n    _reorderPostEffectPasses() {\n        if (!this._bloomComposer) return;\n        const ordered = [\n            this._bloomEffectPass,\n            this._depthOfFieldPass,\n            this._motionBlurPass,\n            this._fxaaPass\n        ].filter(Boolean);\n        ordered.forEach((pass) => this._bloomComposer.removePass?.(pass));\n        ordered.forEach((pass) => this._bloomComposer.addPass(pass));\n    }\n\n    _applyDepthOfFieldSettings() {\n        if (!this._depthOfFieldPass && this._depthOfFieldEnabled) {\n            this._ensureBloomComposer();\n            this._ensureDepthOfFieldPass();\n        }\n        if (!this._depthOfFieldEffect) return;\n        const settings = this._depthOfFieldSettings || {};\n        this._depthOfFieldPass.enabled = !!this._depthOfFieldEnabled;\n        this._depthOfFieldEffect.bokehScale = settings.bokehScale ?? 2.5;\n        if (this._depthOfFieldEffect.resolution && Number.isFinite(settings.resolutionScale)) {\n            this._depthOfFieldEffect.resolution.scale = settings.resolutionScale;\n        }\n        this._depthOfFieldEffect.cocMaterial.worldFocusRange = this._resolveDepthOfFieldRange(this._depthOfFieldFocusDistance);\n        if (settings.autofocus === false) {\n            this._depthOfFieldFocusTarget = settings.focusDistance ?? 25;\n        }\n    }\n\n    _resolveDepthOfFieldRange(distanceHint) {\n        const settings = this._depthOfFieldSettings || {};\n        const manualRange = Number.isFinite(settings.focalLength) ? settings.focalLength : 12;\n        if (settings.autofocus === false) {\n            return manualRange;\n        }\n\n        const hintDistance = Number.isFinite(distanceHint)\n            ? distanceHint\n            : Number.isFinite(this._depthOfFieldFocusDistance)\n                ? this._depthOfFieldFocusDistance\n                : Number.isFinite(this._depthOfFieldFocusTarget)\n                    ? this._depthOfFieldFocusTarget\n                    : Number.isFinite(settings.focusDistance)\n                        ? settings.focusDistance\n                        : 25;\n        if (!Number.isFinite(hintDistance)) {\n            return manualRange;\n        }\n\n        const autoRange = hintDistance * this._depthOfFieldAutoRangeScale;\n        const maxRange = Number.isFinite(settings.maxFocusDistance)\n            ? settings.maxFocusDistance\n            : 2_000_000;\n        return THREE.MathUtils.clamp(autoRange, this._depthOfFieldAutoRangeMin, maxRange);\n    }\n\n    _resolveDepthOfFieldTargets() {\n        let targets = null;\n        try {\n            targets = this._depthOfFieldTargetProvider?.();\n        } catch {\n            targets = null;\n        }\n        const list = Array.isArray(targets) ? targets : (targets ? [targets] : []);\n        return list.filter((target) => target?.visible !== false && target?.isObject3D);\n    }\n\n    _updateDepthOfFieldFocus(deltaTime = 0) {\n        if (!this._depthOfFieldEnabled || !this._depthOfFieldEffect || !this.camera) return;\n        const settings = this._depthOfFieldSettings || {};\n        const now = typeof performance !== 'undefined' && performance.now ? performance.now() : Date.now();\n        const interval = settings.sampleIntervalMs ?? 140;\n\n        if (settings.autofocus !== false && now - this._depthOfFieldLastSampleAt >= interval) {\n            this._depthOfFieldLastSampleAt = now;\n            const targets = this._resolveDepthOfFieldTargets();\n            if (targets.length) {\n                this.camera.updateMatrixWorld?.();\n                const raycaster = this._depthOfFieldRaycaster;\n                raycaster.near = Math.max(0.01, this.camera.near || 0.1);\n                raycaster.far = Math.min(this.camera.far || 20_000_000, settings.maxFocusDistance ?? 2_000_000);\n                raycaster.firstHitOnly = true;\n                raycaster.setFromCamera(this._depthOfFieldNdc, this.camera);\n                const hit = raycaster.intersectObjects(targets, true).find((entry) => (\n                    entry?.object?.visible !== false\n                    && entry.object?.userData?.excludeFromDepthOfField !== true\n                    && Number.isFinite(entry.distance)\n                ));\n                if (hit) {\n                    this._depthOfFieldFocusTarget = THREE.MathUtils.clamp(\n                        hit.distance,\n                        raycaster.near,\n                        raycaster.far\n                    );\n                }\n            }\n        } else if (settings.autofocus === false) {\n            this._depthOfFieldFocusTarget = settings.focusDistance ?? 25;\n        }\n\n        const target = Number.isFinite(this._depthOfFieldFocusTarget)\n            ? this._depthOfFieldFocusTarget\n            : (settings.focusDistance ?? 25);\n        const current = Number.isFinite(this._depthOfFieldFocusDistance)\n            ? this._depthOfFieldFocusDistance\n            : target;\n        const response = Math.max(0.02, settings.response ?? 0.18);\n        const dt = Number.isFinite(deltaTime) && deltaTime > 0 ? Math.min(deltaTime, 0.1) : 1 / 60;\n        const alpha = 1 - Math.exp(-dt / response);\n        this._depthOfFieldFocusDistance = THREE.MathUtils.lerp(current, target, alpha);\n        this._depthOfFieldEffect.cocMaterial.worldFocusDistance = this._depthOfFieldFocusDistance;\n        this._depthOfFieldEffect.cocMaterial.worldFocusRange = this._resolveDepthOfFieldRange(\n            this._depthOfFieldFocusDistance\n        );\n    }\n\n    _applyBloomSettings() {\n        if (this._bloomEnabled && !this._bloomEffectPass) {\n            this._ensureBloomComposer();\n            if (this._bloomComposer && !this._bloomEffectPass) {\n                const bloom = new BloomEffect({\n                    intensity: this._bloomSettings?.intensity ?? POSTPROCESS_BLOOM_DEFAULTS.intensity,\n                    luminanceThreshold: this._bloomSettings?.threshold ?? POSTPROCESS_BLOOM_DEFAULTS.threshold,\n                    luminanceSmoothing: this._bloomSettings?.smoothing ?? POSTPROCESS_BLOOM_DEFAULTS.smoothing,\n                    radius: this._bloomSettings?.radius ?? POSTPROCESS_BLOOM_DEFAULTS.radius,\n                    levels: this._bloomSettings?.levels ?? POSTPROCESS_BLOOM_DEFAULTS.levels,\n                    mipmapBlur: this._bloomSettings?.mipmapBlur ?? POSTPROCESS_BLOOM_DEFAULTS.mipmapBlur\n                });\n                const bloomPass = new EffectPass(this.camera, bloom);\n                if (this._motionBlurPass && this._bloomComposer) {\n                    this._bloomComposer.removePass?.(this._motionBlurPass);\n                    this._bloomComposer.addPass(bloomPass);\n                    this._bloomComposer.addPass(this._motionBlurPass);\n                } else {\n                    this._bloomComposer.addPass(bloomPass);\n                }\n                this._bloomEffect = bloom;\n                this._bloomEffectPass = bloomPass;\n                this._reorderPostEffectPasses();\n            }\n        }\n        if (!this._bloomEffect) return;\n        const settings = this._bloomSettings || {};\n        if (Number.isFinite(settings.intensity)) this._bloomEffect.intensity = settings.intensity;\n        if (Number.isFinite(settings.threshold)) this._bloomEffect.luminanceThreshold = settings.threshold;\n        if (Number.isFinite(settings.smoothing)) this._bloomEffect.luminanceSmoothing = settings.smoothing;\n        if (Number.isFinite(settings.radius)) this._bloomEffect.radius = settings.radius;\n        if (Number.isFinite(settings.levels)) this._bloomEffect.levels = Math.round(settings.levels);\n        if (typeof settings.mipmapBlur === 'boolean') this._bloomEffect.mipmapBlur = settings.mipmapBlur;\n        if (this._bloomEffectPass) {\n            this._bloomEffectPass.enabled = !!this._bloomEnabled;\n        }\n    }\n\n    _syncBloomComposerSize() {\n        if (!this._bloomComposer || !this.renderer) return;\n        this.renderer.getDrawingBufferSize(this._tmpSize);\n        const width = Math.max(1, Math.floor(this._tmpSize.x));\n        const height = Math.max(1, Math.floor(this._tmpSize.y));\n        this._bloomComposer.setSize(width, height);\n    }\n\n    _ensureMotionBlurPass() {\n        if (!this._bloomComposer) return;\n        if (this._motionBlurPass) return;\n        const pass = new MotionBlurPass({ damp: 0.96 });\n        pass.enabled = !!this._motionBlurEnabled;\n        this._motionBlurPass = pass;\n        this._bloomComposer.addPass(pass);\n        this._reorderPostEffectPasses();\n    }\n\n    _applyMotionBlurSettings() {\n        if (!this._motionBlurPass) {\n            if (this._motionBlurEnabled) {\n                this._ensureBloomComposer();\n                this._ensureMotionBlurPass();\n            }\n        }\n        if (this._motionBlurPass) {\n            this._motionBlurPass.enabled = !!this._motionBlurEnabled;\n            if (this._motionBlurEnabled && !this._motionBlurPrevEnabled) {\n                this._motionBlurPass.reset?.();\n            }\n        }\n        this._motionBlurPrevEnabled = !!this._motionBlurEnabled;\n    }\n\n    _ensureFxaaPass() {\n        if (!this._bloomComposer) return;\n        if (this._fxaaPass) return;\n        const fxaa = new FXAAEffect();\n        const pass = new EffectPass(this.camera, fxaa);\n        pass.enabled = !!this._fxaaEnabled;\n        this._fxaaEffect = fxaa;\n        this._fxaaPass = pass;\n        this._bloomComposer.addPass(pass);\n        this._reorderPostEffectPasses();\n    }\n\n    _ensureFxaaPassOrder() {\n        this._reorderPostEffectPasses();\n    }\n\n    _applyFxaaSettings() {\n        if (!this._fxaaPass) {\n            if (this._fxaaEnabled) {\n                this._ensureBloomComposer();\n                this._ensureFxaaPass();\n            }\n        }\n        if (this._fxaaPass) {\n            this._fxaaPass.enabled = !!this._fxaaEnabled;\n        }\n    }\n\n    _resetSpeedFov() {\n        if (!this.camera) return;\n        const base = Number.isFinite(this._speedFovSettings?.baseFov)\n            ? this._speedFovSettings.baseFov\n            : (Number.isFinite(this._speedFovBase) ? this._speedFovBase : this.camera.fov);\n        if (Number.isFinite(base) && Math.abs(this.camera.fov - base) > 0.001) {\n            this.camera.fov = base;\n            this.camera.updateProjectionMatrix();\n        }\n        this._speedFovCurrent = base;\n    }\n\n    _getCameraWorldPosition(out = this._tmpVec3) {\n        const worldPos = this.camera?.userData?.worldPosition;\n        if (worldPos && typeof worldPos.x === 'number') {\n            out.set(worldPos.x, worldPos.y, worldPos.z);\n            return out;\n        }\n        return out.copy(this.camera?.position || out);\n    }\n\n    _getCameraMotionPosition(out = this._tmpVec3) {\n        this._getCameraWorldPosition(out);\n        if (!this.planetGroup) return out;\n        const origin = this._motionTmpOrigin;\n        if (this.planetGroup.getWorldPosition) {\n            this.planetGroup.getWorldPosition(origin);\n        } else {\n            origin.copy(this.planetGroup.position || origin);\n        }\n        out.sub(origin);\n        const quat = this._motionTmpQuat;\n        if (this.planetGroup.getWorldQuaternion) {\n            this.planetGroup.getWorldQuaternion(quat);\n        } else {\n            quat.copy(this.planetGroup.quaternion || quat);\n        }\n        quat.invert();\n        out.applyQuaternion(quat);\n        return out;\n    }\n\n    _updateMotionEffects(deltaTime) {\n        if (!this.camera) return;\n        if (this.renderer?.xr?.isPresenting) return;\n\n        const now = (typeof performance !== 'undefined' && performance.now)\n            ? performance.now()\n            : Date.now();\n        const dt = Number.isFinite(deltaTime) && deltaTime > 0\n            ? deltaTime\n            : (this._motionLastTime ? Math.max(0, (now - this._motionLastTime) / 1000) : 0);\n        const pos = this._getCameraMotionPosition();\n\n        if (!this._motionHasSample) {\n            this._motionLastPos.copy(pos);\n            this._motionLastTime = now;\n            this._motionHasSample = true;\n            if (this.camera && !Number.isFinite(this._speedFovSettings?.baseFov)) {\n                this._speedFovBase = this.camera.fov;\n                this._speedFovCurrent = this.camera.fov;\n            }\n            return;\n        }\n\n        const distance = pos.distanceTo(this._motionLastPos);\n        let speed = 0;\n        if (Number.isFinite(dt) && dt > 0) {\n            speed = distance / dt;\n        }\n        if (!Number.isFinite(speed)) speed = 0;\n\n        const blurSmooth = Number.isFinite(this._motionBlurSettings?.smoothing)\n            ? this._motionBlurSettings.smoothing\n            : 0.2;\n        this._motionBlurSpeed = THREE.MathUtils.lerp(this._motionBlurSpeed || 0, speed, blurSmooth);\n\n        const fovSmooth = Number.isFinite(this._speedFovSettings?.smoothing)\n            ? this._speedFovSettings.smoothing\n            : 0.15;\n        this._speedFovSpeed = THREE.MathUtils.lerp(this._speedFovSpeed || 0, speed, fovSmooth);\n\n        if (this._speedFovEnabled) {\n            this._applySpeedFov(this._speedFovSpeed);\n        } else if (this._speedFovCurrent !== null) {\n            this._resetSpeedFov();\n        }\n\n        if (this._motionBlurEnabled) {\n            this._applyMotionBlurSpeed(this._motionBlurSpeed);\n        }\n\n        this._motionLastPos.copy(pos);\n        this._motionLastTime = now;\n    }\n\n    _applySpeedFov(speed) {\n        if (!this.camera) return;\n        const settings = this._speedFovSettings || {};\n        const baseFov = Number.isFinite(settings.baseFov)\n            ? settings.baseFov\n            : (Number.isFinite(this._speedFovBase) ? this._speedFovBase : this.camera.fov);\n        const maxBoost = Number.isFinite(settings.maxBoost) ? settings.maxBoost : 0;\n        const maxSpeed = Number.isFinite(settings.maxSpeed) && settings.maxSpeed > 0 ? settings.maxSpeed : 1;\n        const normalized = THREE.MathUtils.clamp(speed / maxSpeed, 0, 1);\n        const target = THREE.MathUtils.clamp(baseFov + maxBoost * normalized, 10, 120);\n        const current = Number.isFinite(this._speedFovCurrent) ? this._speedFovCurrent : this.camera.fov;\n        const smooth = Number.isFinite(settings.smoothing) ? settings.smoothing : 0.15;\n        const next = THREE.MathUtils.lerp(current, target, smooth);\n        this._speedFovCurrent = next;\n        if (Math.abs(this.camera.fov - next) > 0.001) {\n            this.camera.fov = next;\n            this.camera.updateProjectionMatrix();\n        }\n    }\n\n    _applyMotionBlurSpeed(speed) {\n        if (!this._motionBlurPass) return;\n        const settings = this._motionBlurSettings || {};\n        const intensity = Number.isFinite(settings.intensity) ? settings.intensity : 0;\n        const maxSpeed = Number.isFinite(settings.maxSpeed) && settings.maxSpeed > 0 ? settings.maxSpeed : 1;\n        const dampMin = Number.isFinite(settings.dampMin) ? settings.dampMin : 0.85;\n        const dampMax = Number.isFinite(settings.dampMax) ? settings.dampMax : 0.98;\n        const normalized = THREE.MathUtils.clamp(speed / maxSpeed, 0, 1);\n        const strength = THREE.MathUtils.clamp(intensity * normalized, 0, 1);\n        const damp = strength <= 0.0001 ? 0 : THREE.MathUtils.lerp(dampMin, dampMax, strength);\n        this._motionBlurStrength = strength;\n        this._motionBlurPass.damp = damp;\n    }\n\n    _applyBloomToAtmosphereClouds() {\n        if (!this.atmosphereClouds || !this.atmosphereClouds.applyConfig) return;\n        const settings = this.getBloomConfig();\n        this.atmosphereClouds.applyConfig({\n            bloom: {\n                enabled: settings.enabled,\n                intensity: settings.intensity,\n                threshold: settings.threshold,\n                smoothing: settings.smoothing,\n                radius: settings.radius,\n                levels: settings.levels,\n                mipmapBlur: settings.mipmapBlur\n            }\n        });\n    }\n\n    _refreshEmissiveIfNeeded() {\n        if (!this.scene) return;\n        const now = (typeof performance !== 'undefined' && performance.now)\n            ? performance.now()\n            : Date.now();\n        if (this._emissiveDirty) {\n            this._applyEmissiveTuning(now);\n            return;\n        }\n        const cfg = this._emissiveConfig || {};\n        const needsRefresh = cfg.materialIntensity !== 1\n            || cfg.starfieldIntensity !== 1\n            || cfg.galaxyIntensity !== 1\n            || cfg.sunIntensity !== 1\n            || (cfg.materialColor && cfg.materialColor !== '#ffffff');\n        if (!needsRefresh) return;\n        if ((now - this._emissiveLastApply) >= this._emissiveRefreshIntervalMs) {\n            this._applyEmissiveTuning(now);\n        }\n    }\n\n    _applyEmissiveTuning(now = null) {\n        if (!this.scene) return;\n        const stamp = Number.isFinite(now) ? now : ((typeof performance !== 'undefined' && performance.now)\n            ? performance.now()\n            : Date.now());\n        this._emissiveDirty = false;\n        this._emissiveLastApply = stamp;\n\n        const cfg = this._emissiveConfig || {};\n        const materialIntensity = Number.isFinite(cfg.materialIntensity) ? cfg.materialIntensity : 1;\n        let tint = null;\n        if (typeof cfg.materialColor === 'string') {\n            try {\n                tint = new THREE.Color(cfg.materialColor);\n            } catch (error) {\n                tint = null;\n            }\n        }\n\n        const applyMaterial = (mat) => {\n            if (!mat || !mat.emissive) return;\n            if (!mat.userData) mat.userData = {};\n            if (!mat.userData._emissiveBase) {\n                mat.userData._emissiveBase = {\n                    color: mat.emissive.clone?.() || new THREE.Color(0x000000),\n                    intensity: Number.isFinite(mat.emissiveIntensity) ? mat.emissiveIntensity : 1\n                };\n            }\n            const base = mat.userData._emissiveBase;\n            if (mat.emissive && base?.color) {\n                mat.emissive.copy(base.color);\n                if (tint) mat.emissive.multiply(tint);\n            }\n            if (Number.isFinite(mat.emissiveIntensity)) {\n                mat.emissiveIntensity = base.intensity * materialIntensity;\n            }\n        };\n\n        this.scene.traverse((child) => {\n            if (!child) return;\n            if (child.userData?.noEmissiveTuning) return;\n            const material = child.material;\n            if (Array.isArray(material)) {\n                material.forEach(applyMaterial);\n            } else {\n                applyMaterial(material);\n            }\n        });\n\n        this._applyEmissiveToStars();\n        this._applyEmissiveToSun();\n    }\n\n    _applyEmissiveToStars() {\n        const cfg = this._emissiveConfig || {};\n        const starIntensity = Number.isFinite(cfg.starfieldIntensity) ? cfg.starfieldIntensity : 1;\n        const galaxyIntensity = Number.isFinite(cfg.galaxyIntensity) ? cfg.galaxyIntensity : 1;\n\n        const apply = (points, multiplier) => {\n            const material = points?.material;\n            const uniforms = material?.uniforms;\n            if (!uniforms || !uniforms.uIntensity) return;\n            if (!material.userData) material.userData = {};\n            if (!Number.isFinite(material.userData._emissiveBaseIntensity)) {\n                material.userData._emissiveBaseIntensity = uniforms.uIntensity.value;\n            }\n            const base = material.userData._emissiveBaseIntensity ?? uniforms.uIntensity.value;\n            uniforms.uIntensity.value = base * multiplier;\n        };\n\n        apply(this.starField, starIntensity);\n        apply(this.galaxyField, galaxyIntensity);\n    }\n\n    _applyEmissiveToSun() {\n        const cfg = this._emissiveConfig || {};\n        const sunIntensity = Number.isFinite(cfg.sunIntensity) ? cfg.sunIntensity : 1;\n        const material = this.sunMesh?.material;\n        if (!material || !material.color) return;\n        if (!material.userData) material.userData = {};\n        if (!material.userData._emissiveBaseColor) {\n            material.userData._emissiveBaseColor = material.color.clone();\n        }\n        material.color.copy(material.userData._emissiveBaseColor).multiplyScalar(sunIntensity);\n    }\n\n    setRenderScale(scale) {\n        if (!Number.isFinite(scale) || !this.renderer) return;\n        const next = 1;\n        const pixelRatio = this.renderer.getPixelRatio?.() ?? 1;\n        const changed = Math.abs((this.renderScale ?? 1) - next) >= 1e-4\n            || Math.abs(pixelRatio - 1) >= 1e-4;\n        this.renderScale = next;\n        this.renderer.setPixelRatio(1);\n        if (changed) this.handleResize();\n    }\n\n    /**\n     * Build a star field from a real catalog (RA/Dec + magnitude) plus key galaxies.\n     * J2000 catalog vectors use the same apparent Earth/world frame as the ephemeris.\n     */\n    async createStarField() {\n        if (this._skyDisposed || this.starField || this._starFieldController) return;\n        const controller = this._starFieldController = new AbortController();\n        const signal = controller.signal;\n        const deadline = setTimeout(() => controller.abort(), 30000);\n        const fetchCatalog = async (url, maxBytes) => {\n            const response = await fetch(url, { signal, mode: 'same-origin', credentials: 'same-origin', redirect: 'error' });\n            if (!response.ok) { await response.body?.cancel(); throw new Error(`Star catalog HTTP ${response.status}`); }\n            const bytes = await readBoundedBytes(response, { maxBytes, signal });\n            signal.throwIfAborted();\n            return JSON.parse(new TextDecoder().decode(bytes));\n        };\n        const fallbackStars = [\n            [101.287215, -16.716116, -1.44, 0.009], // Sirius\n            [95.987925, -52.69566, -0.62, 0.164], // Canopus\n            [213.91545, 19.18241, -0.05, 1.239], // Arcturus\n            [219.911475, -60.833976, -0.01, 0.71], // Alpha Centauri\n            [279.2346, 38.783692, 0.03, -0.001], // Vega\n            [79.17225, 45.997991, 0.08, 0.795], // Capella\n            [78.63447, -8.20164, 0.18, -0.03], // Rigel\n            [114.825495, 5.224993, 0.4, 0.432], // Procyon\n            [24.42834, -57.236757, 0.45, -0.158], // Achernar\n            [88.792935, 7.407063, 0.45, 1.5] // Betelgeuse\n        ];\n\n        let stars = fallbackStars;\n        let galaxies = [];\n        let motions = [];\n        let named = [];\n        let designations = [];\n        let constellations = [];\n\n        // The compact source contains every BSC5 star through magnitude 6.7,\n        // proper motion, and named-star records. Never load the multi-MB\n        // cross-reference archive in the browser, including legacy highDetail calls.\n        try {\n            const data = await fetchCatalog(resolveSceneRuntimeResource('/refactor/data/space/stars/sky-map.json'), 1024 * 1024);\n            if (Array.isArray(data.stars) && data.stars.length) stars = data.stars;\n            motions = Array.isArray(data.motions) ? data.motions : [];\n            named = Array.isArray(data.named) ? data.named : [];\n            designations = Array.isArray(data.designations) ? data.designations : [];\n            constellations = Array.isArray(data.constellations) ? data.constellations : [];\n            galaxies = Array.isArray(data.galaxies) ? data.galaxies : [];\n        } catch (error) {\n            if (!signal.aborted) console.warn('[StarField] Local catalog unavailable; using ten real bright stars:', error.message);\n        }\n\n        clearTimeout(deadline);\n        if (signal.aborted || this._skyDisposed) return;\n\n        const starRadius = (this.camera ? this.camera.far : CAMERA_FAR) * 0.95;\n        const starPositions = [];\n        const starSizes = [];\n        const starColors = [];\n        const starAlphas = [];\n        const starTwinkles = [];\n        const starMotions = [];\n        const starMagnitudes = [];\n        const motionVector = new THREE.Vector3();\n\n        const coolR = 0.7;\n        const coolG = 0.8;\n        const coolB = 1.0;\n        const midR = 1.0;\n        const midG = 0.95;\n        const midB = 0.85;\n        const warmR = 1.0;\n        const warmG = 0.7;\n        const warmB = 0.5;\n\n        for (let starIndex = 0; starIndex < Math.min(stars.length, 10000); starIndex++) {\n            const star = stars[starIndex];\n            if (!Array.isArray(star) || star.length < 3) continue;\n            const raDeg = star[0];\n            const decDeg = star[1];\n            const mag = Number.isFinite(star[2]) ? star[2] : 6.5;\n            if (mag < -2.0) continue; // exclude the Sun and other non-stellar entries\n\n            const ra = raDeg * DEG2RAD;\n            const dec = decDeg * DEG2RAD;\n            const cosDec = Math.cos(dec);\n            const x = cosDec * Math.cos(ra);\n            const y = cosDec * Math.sin(ra);\n            const z = Math.sin(dec);\n\n            starPositions.push(x * starRadius, y * starRadius, z * starRadius);\n            const motion = motions[starIndex] || [0, 0];\n            properMotionVector(raDeg, decDeg, motion[0], motion[1], motionVector);\n            starMotions.push(motionVector.x, motionVector.y, motionVector.z);\n            starMagnitudes.push(mag);\n\n            const magNorm = THREE.MathUtils.clamp((mag + 1.5) / 8.0, 0.0, 1.0);\n            starSizes.push(THREE.MathUtils.lerp(5.0, 1.0, magNorm));\n            starAlphas.push(stellarFlux(mag));\n            const twinkleSeed = Math.sin(\n                raDeg * 12.9898 + decDeg * 78.233\n            ) * 43758.5453;\n            const twinkleUnit = twinkleSeed - Math.floor(twinkleSeed);\n            const twinkleSecondary = (\n                twinkleUnit * 1.61803398875 + 0.271828\n            ) % 1;\n            starTwinkles.push(\n                twinkleUnit * Math.PI * 2,\n                THREE.MathUtils.lerp(0.65, 1.55, twinkleSecondary),\n                THREE.MathUtils.lerp(1.0, 0.65, magNorm)\n            );\n\n            let r = 0.95;\n            let g = 0.97;\n            let b = 1.0;\n            const bv = star.length > 3 ? star[3] : null;\n            if (Number.isFinite(bv)) {\n                const t = THREE.MathUtils.clamp((bv + 0.4) / 2.4, 0.0, 1.0);\n                if (t < 0.5) {\n                    const k = t / 0.5;\n                    r = coolR + (midR - coolR) * k;\n                    g = coolG + (midG - coolG) * k;\n                    b = coolB + (midB - coolB) * k;\n                } else {\n                    const k = (t - 0.5) / 0.5;\n                    r = midR + (warmR - midR) * k;\n                    g = midG + (warmG - midG) * k;\n                    b = midB + (warmB - midB) * k;\n                }\n            }\n            starColors.push(r, g, b);\n        }\n\n        const buildMaterial = (softness, intensity) => new THREE.ShaderMaterial({\n            uniforms: {\n                uPixelRatio: { value: this.renderer ? this.renderer.getPixelRatio() : 1.0 },\n                uSoftness: { value: softness },\n                uIntensity: { value: intensity },\n                uSkyGain: { value: 0.00025 },\n                uFocalPixels: { value: 500 },\n                uTime: { value: 0 },\n                uScintillationBase: { value: 0 },\n                uYears: { value: 0 },\n                uLimitingMagnitude: { value: -4 },\n                uAtmosphereWeight: { value: 1 },\n                // sin(altitude) of Earth's limb from the camera: stars below it\n                // are behind the planet (≈0 on the surface, → −1 far away).\n                uLimbSin: { value: -1 },\n                uObserverUp: { value: new THREE.Vector3(0, 1, 0) }\n            },\n            vertexShader: `\n                uniform float uPixelRatio;\n                uniform vec3 uObserverUp;\n                uniform float uYears;\n                uniform float uLimitingMagnitude;\n                uniform float uAtmosphereWeight;\n                uniform float uLimbSin;\n                attribute vec3 aMotion;\n                attribute float aMagnitude;\n                attribute float size;\n                attribute vec3 aColor;\n                attribute float aAlpha;\n                attribute vec3 aTwinkle;\n                varying vec3 vColor;\n                varying float vAlpha;\n                varying vec3 vTwinkle;\n                varying float vAirMassGain;\n                varying float vPointSize;\n                #include <common>\n                #include <logdepthbuf_pars_vertex>\n                ${SKY_VISIBILITY_GLSL}\n                void main() {\n                    vColor = aColor;\n                    vec3 catalogPosition = normalize(normalize(position) + aMotion*uYears)*length(position);\n                    vAlpha = aAlpha*skyObjectVisibility(aMagnitude,uLimitingMagnitude);\n                    vTwinkle = aTwinkle;\n                    vec3 starWorldDirection = normalize(\n                        (modelMatrix * vec4(catalogPosition, 0.0)).xyz\n                    );\n                    float sinAltitude = clamp(\n                        dot(starWorldDirection, normalize(uObserverUp)),\n                        -1.0,\n                        1.0\n                    );\n                    float zenithDegrees = degrees(acos(sinAltitude));\n                    float airMass = 1.0;\n                    if (zenithDegrees < 90.0) {\n                        airMass = 1.0 / (\n                            sinAltitude\n                              + 0.50572 * pow(\n                                  max(96.07995 - zenithDegrees, 0.01),\n                                  -1.6364\n                              )\n                        );\n                    }\n                    // Scintillation variance scales approximately with\n                    // air-mass^(7/6), so modulation amplitude uses 7/12.\n                    float horizonVisibility = smoothstep(\n                        -0.015,\n                        0.035,\n                        sinAltitude\n                    );\n                    vAlpha *= mix(1.0, smoothstep(0.0, 0.035, sinAltitude), uAtmosphereWeight);\n                    // Behind the Earth at any altitude, not only under thick air.\n                    vAlpha *= smoothstep(uLimbSin - 0.003, uLimbSin + 0.003, sinAltitude);\n                    vAirMassGain = pow(\n                        clamp(\n                            airMass,\n                            1.0,\n                            ${STAR_SCINTILLATION_DEFAULTS.maximumAirMass.toFixed(1)}\n                        ),\n                        7.0 / 12.0\n                    ) * horizonVisibility;\n                    vec4 mvPosition = modelViewMatrix * vec4(catalogPosition, 1.0);\n                    gl_PointSize = size * uPixelRatio;\n                    vPointSize = gl_PointSize;\n                    gl_Position = projectionMatrix * mvPosition;\n                    #include <logdepthbuf_vertex>\n                }\n            `,\n            fragmentShader: `\n                uniform float uSoftness;\n                uniform float uIntensity;\n                uniform float uSkyGain;\n                uniform float uFocalPixels;\n                uniform float uTime;\n                uniform float uScintillationBase;\n                varying vec3 vColor;\n                varying float vAlpha;\n                varying vec3 vTwinkle;\n                varying float vAirMassGain;\n                varying float vPointSize;\n                #include <logdepthbuf_pars_fragment>\n                void main() {\n                    #include <logdepthbuf_fragment>\n                    if (vAlpha <= 0.0) discard;\n                    float d = length(gl_PointCoord - vec2(0.5));\n                    if (d > 0.5) discard;\n                    float falloff = pow(1.0 - d * 2.0, uSoftness);\n                    float slowWave = sin(uTime * vTwinkle.y + vTwinkle.x);\n                    float irregularWave = sin(\n                        uTime * (vTwinkle.y * 0.43 + 0.17)\n                          + vTwinkle.x * 1.731\n                    );\n                    float amplitude = min(\n                        ${STAR_SCINTILLATION_DEFAULTS.maximumStrength.toFixed(3)},\n                        uScintillationBase * vAirMassGain * vTwinkle.z\n                    );\n                    float scintillation = 1.0\n                      + amplitude\n                        * (slowWave * 0.68 + irregularWave * 0.32);\n                    vec3 color = vColor * uIntensity * scintillation;\n                    float integral = 3.14159265359 / (2.0*(uSoftness+1.0)*(uSoftness+2.0));\n                    color *= vAlpha*falloff/(integral*vPointSize*vPointSize)*uFocalPixels*uFocalPixels*uSkyGain;\n                    gl_FragColor = vec4(color, 1.0);\n                    #include <tonemapping_fragment>\n                    #include <colorspace_fragment>\n                }\n            `,\n            transparent: true,\n            depthWrite: false,\n            blending: THREE.AdditiveBlending\n        });\n\n        const starGeometry = new THREE.BufferGeometry();\n        starGeometry.setAttribute('position', new THREE.Float32BufferAttribute(starPositions, 3));\n        starGeometry.setAttribute('size', new THREE.Float32BufferAttribute(starSizes, 1));\n        starGeometry.setAttribute('aColor', new THREE.Float32BufferAttribute(starColors, 3));\n        starGeometry.setAttribute('aAlpha', new THREE.Float32BufferAttribute(starAlphas, 1));\n        starGeometry.setAttribute('aTwinkle', new THREE.Float32BufferAttribute(starTwinkles, 3));\n        starGeometry.setAttribute('aMotion', new THREE.Float32BufferAttribute(starMotions, 3));\n        starGeometry.setAttribute('aMagnitude', new THREE.Float32BufferAttribute(starMagnitudes, 1));\n        starGeometry.computeBoundingSphere();\n\n        const starMaterial = buildMaterial(1.5, 1.0);\n        this.starField = new THREE.Points(starGeometry, starMaterial);\n        this.starField.name = 'StarField';\n        this.starField.frustumCulled = false;\n        this.starField.userData.noOcclusion = true;\n        this.starField.raycast = () => {};\n\n        this.starFieldGroup = new THREE.Group();\n        this.starFieldGroup.name = 'StarFieldInertialGroup';\n        this.starFieldGroup.matrixAutoUpdate = false;\n        this.starFieldGroup.add(this.starField);\n        this.scene.add(this.starFieldGroup);\n        this.skyFeatures = new SkyFeatures({\n            group: this.starFieldGroup, radius: starRadius, labels: getLabelSystem(), named, stars, motions, designations, constellations,\n            catalogOptions: this.skyCatalogOptions || {},\n            uniforms: { uVisibility: { value: 0 },\n                uObserverUp: starMaterial.uniforms.uObserverUp,\n                uAtmosphereWeight: starMaterial.uniforms.uAtmosphereWeight,\n                uLimbSin: starMaterial.uniforms.uLimbSin },\n        });\n        this.skyFeatures.setPresentationSuspended(this._presentationSuspended === true);\n        if (this.skyLabelKinds) this.skyFeatures.setLabelKinds(this.skyLabelKinds);\n\n        if (galaxies.length > 0) {\n            const galaxyPositions = [];\n            const galaxySizes = [];\n            const galaxyColors = [];\n            const galaxyAlphas = [];\n            const galaxyTwinkles = [];\n\n            for (const galaxy of galaxies) {\n                if (!galaxy || !Number.isFinite(galaxy.ra) || !Number.isFinite(galaxy.dec)) continue;\n                const ra = galaxy.ra * DEG2RAD;\n                const dec = galaxy.dec * DEG2RAD;\n                const cosDec = Math.cos(dec);\n                const x = cosDec * Math.cos(ra);\n                const y = cosDec * Math.sin(ra);\n                const z = Math.sin(dec);\n\n                galaxyPositions.push(x * starRadius, y * starRadius, z * starRadius);\n\n                const sizeArcMin = Number.isFinite(galaxy.size) ? galaxy.size : 30;\n                const size = THREE.MathUtils.clamp(sizeArcMin / 12.0, 6.0, 28.0);\n                galaxySizes.push(size);\n\n                const mag = Number.isFinite(galaxy.mag) ? galaxy.mag : 6.0;\n                const magNorm = THREE.MathUtils.clamp((mag + 1.0) / 9.0, 0.0, 1.0);\n                galaxyAlphas.push(THREE.MathUtils.lerp(0.9, 0.25, magNorm));\n                galaxyTwinkles.push(0, 0, 0);\n\n                galaxyColors.push(0.75, 0.85, 1.0);\n            }\n\n            const galaxyGeometry = new THREE.BufferGeometry();\n            galaxyGeometry.setAttribute('position', new THREE.Float32BufferAttribute(galaxyPositions, 3));\n            galaxyGeometry.setAttribute('size', new THREE.Float32BufferAttribute(galaxySizes, 1));\n            galaxyGeometry.setAttribute('aColor', new THREE.Float32BufferAttribute(galaxyColors, 3));\n            galaxyGeometry.setAttribute('aAlpha', new THREE.Float32BufferAttribute(galaxyAlphas, 1));\n            galaxyGeometry.setAttribute('aTwinkle', new THREE.Float32BufferAttribute(galaxyTwinkles, 3));\n            galaxyGeometry.setAttribute('aMotion', new THREE.Float32BufferAttribute(new Float32Array(galaxySizes.length * 3), 3));\n            galaxyGeometry.setAttribute('aMagnitude', new THREE.Float32BufferAttribute(new Float32Array(galaxySizes.length).fill(6), 1));\n            galaxyGeometry.computeBoundingSphere();\n\n            const galaxyMaterial = buildMaterial(2.2, 0.65);\n            this.galaxyField = new THREE.Points(galaxyGeometry, galaxyMaterial);\n            this.galaxyField.name = 'GalaxyField';\n            this.galaxyField.frustumCulled = false;\n            this.galaxyField.userData.noOcclusion = true;\n            this.galaxyField.raycast = () => {};\n            this.starFieldGroup.add(this.galaxyField);\n        }\n\n        this._applyEmissiveToStars();\n        this.updateStarFieldRotation();\n    }\n\n    /**\n     * Update starfield orientation.\n     * One matrix maps the inertial J2000 sky to the live planet frame.\n     */\n    updateStarFieldRotation(_earthRotationAngle) {\n        const uniforms = this.starField?.material?.uniforms;\n        if (!uniforms?.uTime\n            || !uniforms?.uScintillationBase\n            || !uniforms?.uObserverUp) return;\n        const now = (typeof performance !== 'undefined' && performance.now)\n            ? performance.now()\n            : Date.now();\n        uniforms.uTime.value = (now * 0.001) % 4096;\n        if (uniforms.uSkyGain) {\n            uniforms.uSkyGain.value = 0.00025 * stellarExposureCompensation(this.renderer?.toneMappingExposure);\n            this._skyDrawingBuffer ||= new THREE.Vector2();\n            this.renderer?.getDrawingBufferSize?.(this._skyDrawingBuffer);\n            uniforms.uFocalPixels.value = (this._skyDrawingBuffer.y || 600)\n                / (2 * Math.tan((this.camera.fov || 60) * Math.PI / 360) / (this.camera.zoom || 1));\n        }\n\n        // Atmospheric scintillation is subtle from the surface and vanishes\n        // through the upper atmosphere. Extended galaxy sprites deliberately\n        // remain stable; only point-like catalog stars receive this signal.\n        const cameraWorld = uniforms.uObserverUp.value;\n        if (this.camera?.getWorldPosition) {\n            this.camera.getWorldPosition(cameraWorld);\n        } else if (this.camera?.userData?.worldPosition) {\n            cameraWorld.copy(this.camera.userData.worldPosition);\n        } else if (this.camera?.position) {\n            cameraWorld.copy(this.camera.position);\n        } else {\n            cameraWorld.set(0, 0, 0);\n        }\n        let altitude = Number.POSITIVE_INFINITY;\n        if (cameraWorld?.lengthSq?.() > 0) {\n            const ellipsoidRadius = ellipsoidRadiusForWorldDir(\n                cameraWorld,\n                this.planetGroup\n            );\n            const cameraRadius = cameraWorld.length();\n            altitude = Math.max(0, cameraRadius - ellipsoidRadius);\n            const limbRatio = Math.min(1, ellipsoidRadius / Math.max(cameraRadius, 1));\n            if (uniforms.uLimbSin) uniforms.uLimbSin.value = -Math.sqrt(Math.max(0, 1 - limbRatio * limbRatio));\n            uniforms.uObserverUp.value.normalize();\n        }\n        const turbulenceAttenuation = Math.exp(\n            -altitude\n              / STAR_SCINTILLATION_DEFAULTS.turbulenceScaleHeightMeters\n        );\n        uniforms.uScintillationBase.value =\n            STAR_SCINTILLATION_DEFAULTS.zenithStrength\n              * turbulenceAttenuation;\n        const ephemeris = this.lightingSystem?.celestialEphemeris;\n        if (ephemeris?.frame && Number.isFinite(ephemeris.timeMs) && this.starFieldGroup) {\n            this.starFieldGroup.matrix.copy(ephemeris.frame.eqjToWorld);\n            // Camera-centred far-shell projection is for depth precision only.\n            // Gaia parallax uses true parsecs, not this renderer radius.\n            this._skyCameraOrigin ||= new THREE.Vector3();\n            this.camera.getWorldPosition(this._skyCameraOrigin);\n            this.starFieldGroup.matrix.setPosition(this._skyCameraOrigin);\n            this.starFieldGroup.matrixWorldNeedsUpdate = true;\n            const sunAltitude = Math.asin(THREE.MathUtils.clamp(\n                uniforms.uObserverUp.value.dot(ephemeris.sunDirection), -1, 1)) / DEG2RAD;\n            const limit = skyLimitingMagnitude(sunAltitude, altitude);\n            uniforms.uYears.value = julianYearsSinceJ2000(ephemeris.timeMs);\n            uniforms.uLimitingMagnitude.value = limit;\n            uniforms.uAtmosphereWeight.value = turbulenceAttenuation;\n            if (this.galaxyField) {\n                const g = this.galaxyField.material.uniforms;\n                g.uLimitingMagnitude.value = limit;\n                g.uObserverUp.value.copy(uniforms.uObserverUp.value);\n                g.uAtmosphereWeight.value = turbulenceAttenuation;\n            }\n            this.skyFeatures?.update(this.camera, ephemeris.frame, ephemeris.timeMs, limit, now, this.renderer);\n        }\n    }\n\n    disposeSky() {\n        this._skyDisposed = true;\n        clearTimeout(this._starFieldTimer);\n        this._starFieldController?.abort();\n        this.skyFeatures?.dispose();\n        this.starFieldGroup?.removeFromParent();\n        for (const points of [this.starField, this.galaxyField]) {\n            points?.geometry.dispose(); points?.material.dispose();\n        }\n        this.starField = this.galaxyField = this.starFieldGroup = this.skyFeatures = null;\n    }\n\n    /**\n     * Load and apply Earth materials (async)\n     * @param {TriTreeManager} triTree - The terrain manager to apply materials to\n     * @param {Function} onAtmosphereCreated - Callback when atmosphere mesh is created\n     * @param {Function} onMaterialsReady - Callback when materials are fully ready for UI updates\n     */\n    async loadEarthMaterials(triTree, onAtmosphereCreated, onMaterialsReady) {\n        try {\n            console.log('Initializing Earth material (WMTS imagery only, no static textures)...');\n\n            // SIMPLIFIED: No texture loading - WMTS provides all imagery\n            // Create empty texture object that material expects but won't use\n            const emptyTextures = {\n                bumpRoughnessClouds: null,\n                usingFallback: false\n            };\n\n            // Create Earth material (uses WMTS imagery only)\n            const earthMaterial = createEarthMaterial(emptyTextures, this.lightingSystem.sun, {\n                atmosphereDayColor: '#4db2ff',\n                atmosphereTwilightColor: '#bc490b',\n                roughnessLow: 0.25,\n                roughnessHigh: 0.35\n            });\n            if (earthMaterial?.uniforms?.sunDirection) {\n                earthMaterial.uniforms.sunDirection.value.copy(this.lightingSystem.sun.position).normalize();\n            }\n\n            // Store terrain material reference for runtime updates\n            this.earthMaterial = earthMaterial;\n            if (this._shouldLoadEarthOverlayTextures()) {\n                this._loadEarthOverlayTextures();\n            } else {\n                this._disposeEarthOverlayTextures();\n                this._disposeLightPollutionTexture();\n            }\n            this._applyEarthOverlayConfig();\n\n            // Update all tiles to use new material\n            triTree.setMaterial(earthMaterial);\n\n            // Propagate earth material to atmosphere system for orbit cloud shadows\n            if (this.atmosphereClouds?.setEarthMaterial) {\n                this.atmosphereClouds.setEarthMaterial(earthMaterial);\n            }\n\n            // Begin the shared physical clear sky/irradiance path while\n            // terrain is still booting. Volumetric shader/target preparation\n            // stays with the existing post-entry admission owner.\n            this._setupAtmosphereClouds({ clearOnly: true });\n\n            // Create atmosphere shell\n            const atmosphereGeometry = new THREE.SphereGeometry(ATMOSPHERE_RADIUS_M, 64, 64);\n            const atmosphereMaterial = createAtmosphereMaterial(\n                { day: '#4db2ff', twilight: '#bc490b' },\n                this.lightingSystem.sun\n            );\n            this.atmosphereMaterial = atmosphereMaterial;\n            this.atmosphereBase = null;\n            this._syncAtmosphereOverviewDepthContract();\n            this._applyAtmosphereTuning();\n\n            this.atmosphereMesh = new THREE.Mesh(atmosphereGeometry, atmosphereMaterial);\n            this.atmosphereMesh.name = 'Atmosphere';\n            this.atmosphereMesh.renderOrder = 5; // Below labels (10-12) so atmosphere doesn't occlude UI elements\n            // Don't set layers - use default layer 0 so camera can see it\n            this.atmosphereMesh.userData.lensflare = 'no-occlusion';\n            this.scene.add(this.atmosphereMesh);\n            this.setAtmosphereEnabled(this.atmosphereEnabled);\n\n            if (this.atmosphereDepthTarget && atmosphereMaterial.uniforms && atmosphereMaterial.uniforms.depthTexture) {\n                atmosphereMaterial.uniforms.depthTexture.value = this.atmosphereDepthTarget.depthTexture;\n            }\n\n            if (onAtmosphereCreated) {\n                onAtmosphereCreated(this.atmosphereMesh);\n            }\n\n            // Notify that materials are ready for UI value application\n            if (onMaterialsReady) {\n                onMaterialsReady();\n            }\n\n            console.log('Earth materials initialized successfully');\n        } catch (error) {\n            console.error('Failed to initialize Earth materials:', error);\n        }\n    }\n\n    /**\n     * Update hex visualization based on selection\n     * @param {Object} hexSelection - Hex selection data {centerDir, radius, surfaceRadius?}\n     * @param {HTMLElement} metricHex - DOM element to display hex radius\n     * @param {TriTreeManager} triTree - Terrain manager to set hex patch\n     */\n    updateHexVisualization(hexSelection, metricHex, triTree) {\n        if (!hexSelection.centerDir) {\n            metricHex.textContent = 'none';\n            triTree.setHexPatch(null, 0);\n            if (this.hexLine && this.hexLine.material) {\n                this.hexTargetOpacity = 0;\n                if (this.hexLine.material.opacity <= 0.001) {\n                    this.hexLine.visible = false;\n                } else {\n                    this.hexLine.visible = true;\n                }\n            }\n            if (this.hexPathLine && this.hexPathLine.material) {\n                this.hexPathLine.visible = false;\n            }\n            return;\n        }\n\n        const segments = 6;\n        const c = hexSelection.centerDir.clone().normalize();\n        const r = hexSelection.radius;\n        const sampleRadius = (dir) => {\n            if (triTree && typeof triTree.sampleTerrainRadiusForDir === 'function') {\n                const val = triTree.sampleTerrainRadiusForDir(dir);\n                if (Number.isFinite(val)) return val;\n            }\n            if (triTree && typeof triTree.getSurfaceRadiusAtDir === 'function') {\n                const val = triTree.getSurfaceRadiusAtDir(dir);\n                if (Number.isFinite(val)) return val;\n            }\n            return PLANET_RADIUS;\n        };\n\n        let up = new THREE.Vector3(0, 1, 0);\n        if (Math.abs(up.dot(c)) > 0.98) up = new THREE.Vector3(1, 0, 0);\n        const east = new THREE.Vector3().crossVectors(up, c).normalize();\n        const north = new THREE.Vector3().crossVectors(c, east).normalize();\n\n        const cornerDirs = [];\n        const midDirs = [];\n        const positions = [];\n        const clearance = 0.35 + 1.6 + 1.0; // lift hex and path an extra unit\n        const eyeHeight = 1.6;\n        const offset = eyeHeight + clearance;\n\n        for (let k = 0; k < segments; k++) {\n            const phi = (Math.PI / 3) * k;\n            const tangent = new THREE.Vector3()\n                .copy(east).multiplyScalar(Math.cos(phi))\n                .add(new THREE.Vector3().copy(north).multiplyScalar(Math.sin(phi)));\n\n            const dir = new THREE.Vector3()\n                .copy(c).multiplyScalar(Math.cos(r))\n                .add(tangent.multiplyScalar(Math.sin(r)))\n                .normalize();\n            cornerDirs.push(dir);\n        }\n\n        for (let k = 0; k < segments; k++) {\n            const next = (k + 1) % segments;\n            const mid = new THREE.Vector3().addVectors(cornerDirs[k], cornerDirs[next]).normalize();\n            midDirs.push(mid);\n        }\n\n        for (let k = 0; k < segments; k++) {\n            const cornerDir = cornerDirs[k];\n            const cornerRadius = sampleRadius(cornerDir) + offset;\n            positions.push(\n                cornerDir.x * cornerRadius,\n                cornerDir.y * cornerRadius,\n                cornerDir.z * cornerRadius\n            );\n\n            const midDir = midDirs[k];\n            const midRadius = sampleRadius(midDir) + offset;\n            positions.push(\n                midDir.x * midRadius,\n                midDir.y * midRadius,\n                midDir.z * midRadius\n            );\n        }\n        // Close the loop by repeating the first corner\n        const firstCorner = cornerDirs[0];\n        const firstRadius = sampleRadius(firstCorner) + offset;\n        positions.push(\n            firstCorner.x * firstRadius,\n            firstCorner.y * firstRadius,\n            firstCorner.z * firstRadius\n        );\n\n        const positionArray = new Float32Array(positions);\n        this.hexGeometry.setAttribute('position', new THREE.BufferAttribute(positionArray, 3));\n        this.hexGeometry.computeBoundingSphere();\n        this.hexLine.visible = true;\n        this.hexTargetOpacity = 1;\n\n        // Build terrain-aware dashed path from camera to hex center using pathfinder\n        if (this.hexPathGeometry && this.camera && triTree && this.terrainPathfinder) {\n            const worldPos = this.camera.userData?.worldPosition;\n            const camDir = (worldPos ? worldPos.clone() : this.camera.position.clone()).normalize();\n            const endDir = c.clone();\n            let pathPositions = null;\n            const pw = this.pathWeights || {};\n            const path = this.terrainPathfinder.computePath(camDir, endDir, triTree, {\n                lateralMaxDeg: pw.lateralMaxDeg ?? 6,\n                stepsS: pw.stepsS ?? 96,\n                stepsT: pw.stepsT ?? 13,\n                clearance,\n                weightUphill: pw.weightUphill ?? 12,\n                weightDownhill: pw.weightDownhill ?? 2,\n                weightElevDelta: pw.weightElevDelta ?? 2.0,\n                weightSlopeSq: pw.weightSlopeSq ?? 10,\n                weightLateral: pw.weightLateral ?? 1.2,\n                weightDistance: pw.weightDistance ?? 2.0,\n                weightHigh: pw.weightHigh ?? 0.35,\n                weightRough: pw.weightRough ?? 0.6,\n                smoothIterations: pw.smoothIterations ?? 2\n            });\n\n            if (path && path.length >= 2) {\n                pathPositions = new Float32Array(path.length * 3);\n                for (let i = 0; i < path.length; i++) {\n                    const p = path[i];\n                    const i3 = i * 3;\n                    pathPositions[i3 + 0] = p.x;\n                    pathPositions[i3 + 1] = p.y;\n                    pathPositions[i3 + 2] = p.z;\n                }\n\n                this.hexPathGeometry.setAttribute('position', new THREE.BufferAttribute(pathPositions, 3));\n                this.hexPathGeometry.computeBoundingSphere();\n\n                if (this.hexPathLine && this.hexPathLine.material) {\n                    this.hexPathLine.visible = true;\n                }\n            } else if (this.hexPathLine) {\n                this.hexPathLine.visible = false;\n            }\n        }\n\n        metricHex.textContent = (hexSelection.radius / DEG2RAD).toFixed(1) + '°';\n        triTree.setHexPatch(hexSelection.centerDir, hexSelection.radius);\n    }\n\n    updateHexFade(dt) {\n        if (!this.hexLine || !this.hexLine.material) return;\n        if (!Number.isFinite(dt)) return;\n        const target = this.hexTargetOpacity ?? 0;\n        const material = this.hexLine.material;\n        let opacity = material.opacity ?? 0;\n        const speed = target > opacity ? this.hexFadeInSpeed : this.hexFadeOutSpeed;\n        const delta = Math.max(0, speed * dt);\n        if (target > opacity) {\n            opacity = Math.min(target, opacity + delta);\n        } else {\n            opacity = Math.max(target, opacity - delta);\n        }\n        material.opacity = opacity;\n        if (opacity <= 0.001 && target === 0) {\n            this.hexLine.visible = false;\n        } else {\n            this.hexLine.visible = true;\n        }\n        if (this.hexPathLine && this.hexPathLine.material) {\n            this.hexPathLine.material.opacity = opacity;\n            if (opacity <= 0.001 && target === 0) {\n                this.hexPathLine.visible = false;\n            } else if (this.hexPathGeometry && this.hexPathGeometry.getAttribute('position')?.count > 1) {\n                this.hexPathLine.visible = true;\n            }\n        }\n    }\n\n    /**\n     * Auto tilt camera when approaching the globe\n     * @param {THREE.PerspectiveCamera} camera\n     * @param {OrbitControls} controls\n     */\n    autoTilt(camera, controls) {\n        const worldPos = camera.userData?.worldPosition;\n        const camPos = worldPos ? worldPos.clone() : camera.position.clone();\n        const dist = camPos.length();\n        const ellipsoidR = ellipsoidRadiusForWorldDir(camPos, this.planetGroup);\n        const altUnits = dist - ellipsoidR;\n\n        if (altUnits <= ALT_30K_UNITS) {\n            const up = camPos.clone().normalize();\n            const down = up.clone().multiplyScalar(-1);\n            let tangent = new THREE.Vector3().crossVectors(up, new THREE.Vector3(0, 1, 0));\n            if (tangent.lengthSq() < 1e-6) tangent.set(1, 0, 0);\n            tangent.normalize();\n\n            let pitchAngle = 0;\n            if (altUnits <= ALT_10K_UNITS) {\n                pitchAngle = Math.PI / 2;\n            } else {\n                const t = (ALT_30K_UNITS - altUnits) / (ALT_30K_UNITS - ALT_10K_UNITS);\n                const clamped = THREE.MathUtils.clamp(t, 0, 1);\n                pitchAngle = clamped * (Math.PI / 2);\n            }\n\n            const lookDir = down.multiplyScalar(Math.cos(pitchAngle))\n                .add(tangent.multiplyScalar(Math.sin(pitchAngle)))\n                .normalize();\n\n            const target = camPos.clone().add(lookDir);\n            controls.target.copy(target);\n            controls.update();\n        }\n    }\n\n    /**\n     * Handle window resize\n     */\n    handleResize() {\n        if (this._presentationSuspended) return;\n        if (!this.camera || !this.renderer || !this.container) return;\n\n        const width = this.container.clientWidth;\n        const height = this.container.clientHeight;\n        const renderWidth = Math.floor(width * this.renderScale);\n        const renderHeight = Math.floor(height * this.renderScale);\n        const sizeUnchanged = width === this._lastClientWidth &&\n            height === this._lastClientHeight &&\n            renderWidth === this._lastRenderWidth &&\n            renderHeight === this._lastRenderHeight;\n        if (sizeUnchanged) return;\n\n        this._lastClientWidth = width;\n        this._lastClientHeight = height;\n        this._lastRenderWidth = renderWidth;\n        this._lastRenderHeight = renderHeight;\n\n        this.camera.aspect = width / height;\n        this.camera.updateProjectionMatrix();\n\n        // Keep canvas CSS at full container size, but render buffer at 75%\n        this.renderer.domElement.style.width = '100%';\n        this.renderer.domElement.style.height = '100%';\n        this.renderer.setSize(renderWidth, renderHeight, false);\n\n        const pixelRatio = this.renderer.getPixelRatio();\n        if (this.starField && this.starField.material && this.starField.material.uniforms && this.starField.material.uniforms.uPixelRatio) {\n            this.starField.material.uniforms.uPixelRatio.value = pixelRatio;\n        }\n        if (this.galaxyField && this.galaxyField.material && this.galaxyField.material.uniforms && this.galaxyField.material.uniforms.uPixelRatio) {\n            this.galaxyField.material.uniforms.uPixelRatio.value = pixelRatio;\n        }\n\n        if (this.atmosphereDepthTarget) {\n            this.renderer.getDrawingBufferSize(this._tmpSize);\n            const scale = THREE.MathUtils.clamp(this.atmosphereDepthScale ?? 1, 0.1, 1.0);\n            const depthW = Math.max(1, Math.floor(this._tmpSize.x * scale));\n            const depthH = Math.max(1, Math.floor(this._tmpSize.y * scale));\n            this.atmosphereDepthTarget.setSize(depthW, depthH);\n            this._atmosphereDepthDirty = true;\n        }\n        if (this.atmosphereMaterial && this.atmosphereMaterial.uniforms && this.atmosphereMaterial.uniforms.resolution) {\n            this.renderer.getDrawingBufferSize(this._tmpSize);\n            this.atmosphereMaterial.uniforms.resolution.value.set(this._tmpSize.x, this._tmpSize.y);\n        }\n\n        if (this._bloomComposer) {\n            this._syncBloomComposerSize();\n        }\n\n        if (this.atmosphereClouds) {\n            this.atmosphereClouds.resize();\n        }\n    }\n\n    /**\n     * Get all scene components\n     */\n    getComponents() {\n        return {\n            renderer: this.renderer,\n            scene: this.scene,\n            camera: this.camera,\n            controls: this.controls,\n            lightingSystem: this.lightingSystem,\n            moonSystem: this.moonSystem,\n            sunMesh: this.sunMesh,\n            atmosphereMesh: this.atmosphereMesh,\n            hexLine: this.hexLine\n        };\n    }\n}\n","// Reversible GPU-only texture ownership between the scene and full-screen map.\n// CPU pixels, native models, geometry, shader programs and temporal targets stay\n// owned by their original systems. Never close images or clear source caches.\nfunction canRestore(texture) {\n  if (!texture?.isTexture || texture.isRenderTargetTexture || texture.isVideoTexture\n    || texture.isExternalTexture || texture.isCubeTexture) return false;\n  const image = texture.source?.data ?? texture.image;\n  return !!image && image.width > 0 && image.height > 0\n    && (!image.data || image.data.byteLength > 0);\n}\n\n// A conservative scheduling weight, not measured physical GPU/process memory.\nfunction weight(texture) {\n  const image = texture.source?.data ?? texture.image;\n  const component = texture.type === 1015 ? 4 : texture.type === 1016 ? 2 : 1;\n  return Math.ceil(image.width * image.height * (image.depth || 1) * 4 * component\n    * (texture.generateMipmaps ? 4 / 3 : 1));\n}\n\nexport function* presentationTextures(roots, extras = []) {\n  const nodes = [...roots], visited = new Set();\n  yield* extras;\n  while (nodes.length) {\n    const node = nodes.pop();\n    if (!node || visited.has(node)) continue;\n    visited.add(node);\n    // A sentinel makes even a textureless large tree yield cooperatively.\n    yield null;\n    if (node.children) nodes.push(...node.children);\n    for (const material of Array.isArray(node.material) ? node.material : [node.material]) {\n      if (!material) continue;\n      for (const value of Object.values(material)) if (value?.isTexture) yield value;\n      for (const uniform of Object.values(material.uniforms || {})) {\n        const value = uniform?.value;\n        if (value?.isTexture) yield value;\n        else if (Array.isArray(value)) for (const item of value) if (item?.isTexture) yield item;\n      }\n    }\n  }\n}\n\nexport class MapPresentationResources {\n  constructor(renderer, { schedule = callback => setTimeout(callback, 0), now = () => performance.now(),\n    budgetMs = 3, maxItems = 32, maxWeight = 8 * 1024 ** 2 } = {}) {\n    Object.assign(this, { renderer, schedule, now, budgetMs, maxItems, maxWeight });\n    this._generation = 0; this._retired = new Set(); this._byTexture = new WeakMap();\n    this._mode = '3d'; this._disposed = false;\n    this._ready = Promise.resolve(true);\n    this._stats = { phase: 'active', retired: 0, restored: 0, tasks: 0, maxTaskMs: 0, errors: 0 };\n  }\n  get ready() { return this._ready; }\n  get active() { return this._stats.phase === 'active'; }\n  getStats() { return { ...this._stats, retainedSources: this._retired.size }; }\n\n  park(roots, extras) {\n    if (this._disposed) return Promise.resolve(false);\n    if (this._mode === '2d') return this._ready;\n    this._mode = '2d'; const generation = ++this._generation;\n    const seen = new Set();\n    this._stats.phase = 'parking';\n    this._ready = this._run(presentationTextures(roots, extras), texture => {\n      if (!texture || seen.has(texture)) return 0;\n      seen.add(texture);\n      if (!canRestore(texture) || this._byTexture.has(texture)\n        || !this.renderer.properties.has(texture)\n        || !this.renderer.properties.get(texture).__webglTexture) return 0;\n      const bytes = weight(texture);\n      texture.dispose();\n      const reference = new WeakRef(texture);\n      this._retired.add(reference); this._byTexture.set(texture, reference);\n      this._stats.retired++;\n      return bytes;\n    }, generation, 'parked');\n    return this._ready;\n  }\n\n  resume() {\n    if (this._disposed) return Promise.resolve(false);\n    if (this._mode === '3d') return this._ready;\n    this._mode = '3d'; const generation = ++this._generation;\n    this._stats.phase = 'restoring';\n    this._ready = this._run(this._retired.values(), reference => {\n      const texture = reference.deref();\n      // Native model eviction may have closed a source while the map owned\n      // presentation. That model is gone; never resurrect an invalid image.\n      if (!canRestore(texture)) {\n        this._retired.delete(reference);\n        if (texture) this._byTexture.delete(texture);\n        return 0;\n      }\n      const bytes = weight(texture);\n      this.renderer.initTexture(texture);\n      this._retired.delete(reference); this._byTexture.delete(texture); this._stats.restored++;\n      return bytes;\n    }, generation, 'active');\n    return this._ready;\n  }\n\n  _run(iterator, operation, generation, completePhase) {\n    return new Promise((resolve, reject) => {\n      const run = () => {\n        if (this._disposed || generation !== this._generation) { resolve(false); return; }\n        const start = this.now(); let count = 0, bytes = 0, done = false;\n        try {\n          while (count < this.maxItems && bytes < this.maxWeight && this.now() - start < this.budgetMs) {\n            const next = iterator.next(); if (next.done) { done = true; break; }\n            bytes += operation(next.value); count++;\n          }\n          this._stats.tasks++;\n          this._stats.maxTaskMs = Math.max(this._stats.maxTaskMs, this.now() - start);\n          if (done) { this._stats.phase = completePhase; resolve(true); }\n          else this.schedule(run);\n        } catch (error) { this._stats.errors++; this._stats.phase = 'failed'; reject(error); }\n      };\n      // A real task boundary lets the retiring renderer finish before the\n      // other owner starts allocating; never perform the first batch inline.\n      this.schedule(run);\n    });\n  }\n\n  dispose() {\n    this._disposed = true; this._generation++;\n    this._retired.clear(); this._stats.phase = 'disposed';\n    this._byTexture = new WeakMap();\n  }\n}\n","import * as THREE from 'three';\nimport { PLANET_RADIUS } from './constants.js';\nimport { dirToLatLonLocal, ellipsoidRadiusForWorldDir } from './geometry-utils.js';\n\nconst DEFAULT_DIR_SMOOTH = 0.18;\nconst DEFAULT_SPEED_SMOOTH = 0.22;\nconst DEFAULT_MIN_SPEED_MPS = 0.08;\nconst DEFAULT_EMIT_INTERVAL_MS = 100;\n\nexport class MotionTracker {\n    constructor({\n        eventBus,\n        planetRadius = PLANET_RADIUS,\n        planetGroup = null,\n        dirSmoothing = DEFAULT_DIR_SMOOTH,\n        speedSmoothing = DEFAULT_SPEED_SMOOTH,\n        minSpeedMps = DEFAULT_MIN_SPEED_MPS,\n        emitIntervalMs = DEFAULT_EMIT_INTERVAL_MS\n    } = {}) {\n        this.eventBus = eventBus || null;\n        this.planetRadius = Number.isFinite(planetRadius) ? planetRadius : PLANET_RADIUS;\n        this.planetGroup = planetGroup || null;\n        this.dirSmoothing = Number.isFinite(dirSmoothing) ? dirSmoothing : DEFAULT_DIR_SMOOTH;\n        this.speedSmoothing = Number.isFinite(speedSmoothing) ? speedSmoothing : DEFAULT_SPEED_SMOOTH;\n        this.minSpeedMps = Number.isFinite(minSpeedMps) ? minSpeedMps : DEFAULT_MIN_SPEED_MPS;\n        this.emitIntervalMs = Number.isFinite(emitIntervalMs) ? emitIntervalMs : DEFAULT_EMIT_INTERVAL_MS;\n\n        this._hasPrev = false;\n        this._prevPos = new THREE.Vector3();\n        this._tmpPos = new THREE.Vector3();\n        this._tmpDir = new THREE.Vector3();\n        this._tmpVel = new THREE.Vector3();\n        this._tmpRadial = new THREE.Vector3();\n        this._tmpTangent = new THREE.Vector3();\n        this._tmpSurfacePos = new THREE.Vector3();\n\n        this._lastEmitMs = 0;\n        this._state = {\n            position: new THREE.Vector3(),\n            surfaceDir: new THREE.Vector3(0, 1, 0),\n            tangentDir: new THREE.Vector3(1, 0, 0),\n            velocity: new THREE.Vector3(),\n            speedMps: 0,\n            confidence: 0,\n            source: 'camera',\n            timestamp: 0,\n            lat: null,\n            lon: null,\n            altitudeM: null\n        };\n    }\n\n    getState() {\n        return {\n            position: this._state.position.clone(),\n            surfaceDir: this._state.surfaceDir.clone(),\n            tangentDir: this._state.tangentDir.clone(),\n            velocity: this._state.velocity.clone(),\n            speedMps: this._state.speedMps,\n            confidence: this._state.confidence,\n            source: this._state.source,\n            timestamp: this._state.timestamp,\n            lat: this._state.lat,\n            lon: this._state.lon,\n            altitudeM: this._state.altitudeM\n        };\n    }\n\n    update({ camera, surfaceController, now, dt } = {}) {\n        if (!camera || !Number.isFinite(dt) || dt <= 0) return;\n        const timestamp = Number.isFinite(now)\n            ? now\n            : (typeof performance !== 'undefined' && performance.now ? performance.now() : Date.now());\n\n        const worldPos = camera.userData?.worldPosition || camera.getWorldPosition(this._tmpPos);\n        this._tmpPos.copy(worldPos);\n\n        if (!this._hasPrev) {\n            this._prevPos.copy(this._tmpPos);\n            this._hasPrev = true;\n            this._state.position.copy(this._tmpPos);\n            this._state.timestamp = timestamp;\n            return;\n        }\n\n        const delta = this._tmpVel.subVectors(this._tmpPos, this._prevPos);\n        this._prevPos.copy(this._tmpPos);\n\n        const invDt = 1 / Math.max(dt, 1e-5);\n        this._tmpVel.multiplyScalar(invDt);\n\n        let source = 'camera';\n        if (surfaceController?.isInSurfaceMode?.() &&\n            typeof surfaceController.getSurfaceVelocity === 'function') {\n            const surfaceVel = surfaceController.getSurfaceVelocity();\n            if (surfaceVel && surfaceVel.lengthSq() > 0) {\n                this._tmpVel.copy(surfaceVel);\n                source = 'surface';\n            }\n        }\n\n        const surfacePos = surfaceController?.getSurfacePosition?.();\n        if (surfacePos && surfacePos.lengthSq() > 0) {\n            this._tmpSurfacePos.copy(surfacePos);\n        } else {\n            this._tmpSurfacePos.copy(this._tmpPos).setLength(this.planetRadius);\n        }\n\n        const surfaceDir = this._tmpDir.copy(this._tmpSurfacePos).normalize();\n\n        const radialAmount = this._tmpVel.dot(surfaceDir);\n        this._tmpRadial.copy(surfaceDir).multiplyScalar(radialAmount);\n        this._tmpTangent.copy(this._tmpVel).sub(this._tmpRadial);\n\n        const speed = this._tmpTangent.length();\n        let hasMotion = speed >= this.minSpeedMps;\n        if (hasMotion) {\n            this._tmpTangent.normalize();\n        }\n\n        const dirAlpha = 1 - Math.exp(-this.dirSmoothing * dt);\n        const speedAlpha = 1 - Math.exp(-this.speedSmoothing * dt);\n\n        if (hasMotion) {\n            this._state.tangentDir.lerp(this._tmpTangent, dirAlpha);\n            if (this._state.tangentDir.lengthSq() > 0) {\n                this._state.tangentDir.normalize();\n            }\n            this._state.speedMps = THREE.MathUtils.lerp(this._state.speedMps, speed, speedAlpha);\n        } else {\n            this._state.speedMps = THREE.MathUtils.lerp(this._state.speedMps, 0, speedAlpha);\n            hasMotion = this._state.speedMps >= this.minSpeedMps;\n        }\n\n        this._state.position.copy(this._tmpPos);\n        this._state.surfaceDir.copy(surfaceDir);\n        this._state.velocity.copy(this._state.tangentDir).multiplyScalar(this._state.speedMps);\n        this._state.source = source;\n        this._state.timestamp = timestamp;\n        this._state.confidence = THREE.MathUtils.clamp(this._state.speedMps / Math.max(this.minSpeedMps, 0.01), 0, 1);\n\n        const ellipsoidR = ellipsoidRadiusForWorldDir(this._tmpPos, this.planetGroup);\n        const altitude = this._tmpPos.length() - ellipsoidR;\n        this._state.altitudeM = Number.isFinite(altitude) ? altitude : null;\n\n        const latLon = dirToLatLonLocal(this._state.surfaceDir);\n        if (latLon) {\n            this._state.lat = latLon.lat;\n            this._state.lon = latLon.lon;\n        }\n\n        if (this.eventBus && (timestamp - this._lastEmitMs) >= this.emitIntervalMs) {\n            this._lastEmitMs = timestamp;\n            this.eventBus.emit('motion:update', {\n                position: this._state.position.clone(),\n                surfaceDir: this._state.surfaceDir.clone(),\n                tangentDir: this._state.tangentDir.clone(),\n                velocity: this._state.velocity.clone(),\n                speedMps: this._state.speedMps,\n                confidence: this._state.confidence,\n                source: this._state.source,\n                timestamp: this._state.timestamp,\n                lat: this._state.lat,\n                lon: this._state.lon,\n                altitudeM: this._state.altitudeM\n            });\n        }\n    }\n}\n","/**\n * Transport Types (JavaScript with JSDoc)\n *\n * These type definitions mirror the TypeScript types in @noclip/shared.\n * They provide IDE support and documentation for the transport layer.\n *\n * @fileoverview Transport layer type definitions\n */\n\n/**\n * Transport connection status\n * @typedef {'disconnected' | 'connecting' | 'connected' | 'reconnecting' | 'error'} TransportStatus\n */\n\n/**\n * Transport type identifier\n * @typedef {'centralized' | 'nkn'} TransportType\n */\n\n/**\n * Error structure for transport error responses\n * @typedef {Object} TransportError\n * @property {string} code - Machine-readable error code\n * @property {string} message - Human-readable error message\n * @property {Object} [details] - Additional error details\n */\n\n/**\n * Canonical message envelope for all transport communications\n * @template T\n * @typedef {Object} TransportMessage\n * @property {string} id - Unique message ID (UUIDv4)\n * @property {string} event - Event type (domain.action pattern)\n * @property {number} ts - Unix timestamp in milliseconds\n * @property {string} [sessionId] - Session ID (set after auth)\n * @property {string} [deviceId] - Device ID (set after registration)\n * @property {number} [seq] - Sequence number for ordering\n * @property {T} payload - Message payload\n * @property {TransportError} [error] - Error info (on error responses)\n */\n\n/**\n * Transport configuration options\n * @typedef {Object} TransportConfig\n * @property {TransportType} type - Transport type to use\n * @property {string} [wsUrl] - WebSocket URL for centralized transport\n * @property {string} [httpUrl] - HTTP base URL for centralized transport\n * @property {string} [nknIdentifier] - NKN identifier for decentralized transport\n * @property {number} [nknSubclients] - Number of NKN subclients (default: 8)\n * @property {number} [timeout] - Request timeout in ms (default: 15000)\n * @property {Object} [reconnect] - Reconnection settings\n * @property {boolean} reconnect.enabled - Enable auto reconnection\n * @property {number} reconnect.maxAttempts - Max reconnection attempts\n * @property {number} reconnect.baseDelay - Base delay in ms\n * @property {number} reconnect.maxDelay - Max delay in ms\n * @property {number} [pingInterval] - Ping interval in ms (default: 20000)\n */\n\n/**\n * Transport statistics\n * @typedef {Object} TransportStats\n * @property {TransportStatus} status - Current connection status\n * @property {TransportType} type - Transport type in use\n * @property {number} messagesSent - Number of messages sent\n * @property {number} messagesReceived - Number of messages received\n * @property {number} reconnectAttempts - Number of reconnection attempts\n * @property {number} [lastConnectedAt] - Last connection timestamp\n * @property {number} [lastMessageAt] - Last message timestamp\n * @property {number} [latencyMs] - Round-trip latency in ms\n */\n\n/**\n * Subscription handle\n * @typedef {Object} TransportSubscription\n * @property {function(): void} unsubscribe - Unsubscribe from this event\n */\n\n/**\n * Send options\n * @typedef {Object} TransportSendOptions\n * @property {number} [timeout] - Override timeout for this request\n * @property {boolean} [noReply] - Don't wait for response\n * @property {number} [priority] - Priority level\n */\n\n// Standard event names (matching @noclip/shared constants)\nexport const TransportEvent = {\n  // System events\n  PING: 'system.ping',\n  PONG: 'system.pong',\n  ERROR: 'system.error',\n  ACK: 'system.ack',\n\n  // Auth events\n  AUTH_LOGIN: 'auth.login',\n  AUTH_LOGOUT: 'auth.logout',\n  AUTH_REGISTER: 'auth.register',\n  AUTH_REFRESH: 'auth.refresh',\n  AUTH_STATUS: 'auth.status',\n\n  // Overlay events\n  OVERLAY_LIST: 'overlay.list',\n  OVERLAY_GET: 'overlay.get',\n  OVERLAY_CREATE: 'overlay.create',\n  OVERLAY_UPDATE: 'overlay.update',\n  OVERLAY_DELETE: 'overlay.delete',\n  OVERLAY_SUBSCRIBE: 'overlay.subscribe',\n  OVERLAY_UNSUBSCRIBE: 'overlay.unsubscribe',\n  OVERLAY_CHANGE: 'overlay.change',\n\n  // Presence events\n  PRESENCE_JOIN: 'presence.join',\n  PRESENCE_LEAVE: 'presence.leave',\n  PRESENCE_UPDATE: 'presence.update',\n  PRESENCE_BATCH: 'presence.batch',\n  DEVICE_PRESENCE: 'device.presence',\n\n  // Chat/LLM events\n  CHAT_BEGIN: 'chat.begin',\n  CHAT_CHUNK: 'chat.chunk',\n  CHAT_DONE: 'chat.done',\n  CHAT_ABORT: 'chat.abort',\n  CHAT_MESSAGE: 'chat.message',\n  DM_MESSAGE: 'dm.message',\n  DM_DELETE: 'dm.delete',\n\n  // Friend events\n  FRIEND_REQUEST: 'friend.request',\n  FRIEND_RESPOND: 'friend.respond',\n  FRIEND_REMOVE: 'friend.remove',\n  FRIEND_LIST: 'friend.list',\n\n  // Notification events\n  NOTIFICATION_PUSH: 'notification.push',\n  NOTIFICATION_ACK: 'notification.ack',\n  NOTIFICATION_LIST: 'notification.list',\n\n  // Geo events\n  GEO_ELEVATION_QUERY: 'geo.elevation.query',\n\n  // Comms events\n  COMMS_CALL_REQUEST: 'comm.call.request',\n  COMMS_CALL_RESPONSE: 'comm.call.response',\n  COMMS_CALL_HANGUP: 'comm.call.hangup',\n  COMMS_PCM_CHUNK: 'comm.pcm.chunk',\n  COMMS_VIDEO_FRAME: 'comm.video.frame',\n\n  // P2P/NKN events\n  P2P_ENDPOINT_UPSERT: 'p2p.endpoint.upsert',\n  P2P_ENDPOINT_LIST: 'p2p.endpoint.list',\n  P2P_ENDPOINT_REMOVE: 'p2p.endpoint.remove',\n  P2P_ENDPOINT_UPDATE: 'p2p.endpoint.update',\n  P2P_INFERENCE_STATUS: 'p2p.inference.status',\n  P2P_TICKET_ISSUE: 'p2p.ticket.issue',\n  P2P_TICKET_VERIFY: 'p2p.ticket.verify',\n  INTEROP_CONTRACT_GET: 'interop.contract.get',\n  MARKET_SERVICE_CATALOG: 'market.service.catalog',\n  MARKET_SERVICE_STATUS: 'market.service.status',\n  MARKET_QUOTE_REQUEST: 'market.quote.request',\n  MARKET_QUOTE_RESULT: 'market.quote.result',\n  MARKET_CREDIT_BALANCE: 'market.credit.balance',\n  MARKET_ACCESS_TICKET_ISSUE: 'market.access.ticket.issue',\n  MARKET_ACCESS_TICKET_VERIFY: 'market.access.ticket.verify',\n  MARKET_USAGE_RECORD: 'market.usage.record',\n\n  // Camera control/observe events\n  CAMERA_CONTROL_REQUEST: 'camera.control.request',\n  CAMERA_CONTROL_STOP: 'camera.control.stop',\n  CAMERA_OBSERVE_REQUEST: 'camera.observe.request',\n  CAMERA_OBSERVE_STOP: 'camera.observe.stop',\n  CAMERA_STATE_PUSH: 'camera.state.push',\n  AGENT_INTERFACE_COMMAND_REQUEST: 'agent.interface.command.request',\n  AGENT_INTERFACE_COMMAND_RESULT: 'agent.interface.command.result',\n};\n\n// Transport status constants\nexport const TransportStatus = {\n  DISCONNECTED: 'disconnected',\n  CONNECTING: 'connecting',\n  CONNECTED: 'connected',\n  RECONNECTING: 'reconnecting',\n  ERROR: 'error',\n};\n\n// Transport type constants\nexport const TransportType = {\n  CENTRALIZED: 'centralized',\n  NKN: 'nkn',\n};\n","/**\n * BaseTransport - Abstract base class for transport implementations\n *\n * Provides common functionality for transport implementations including:\n * - Message ID generation\n * - Request-reply correlation\n * - Event subscription management\n * - Statistics tracking\n *\n * @fileoverview Base transport class\n */\n\nimport { TransportStatus, TransportType } from './types.js';\n\n/**\n * Generate a UUID v4\n * @returns {string}\n */\nfunction generateUUID() {\n  if (typeof crypto !== 'undefined' && crypto.randomUUID) {\n    return crypto.randomUUID();\n  }\n  // Fallback for older browsers\n  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n    const r = (Math.random() * 16) | 0;\n    const v = c === 'x' ? r : (r & 0x3) | 0x8;\n    return v.toString(16);\n  });\n}\n\n/**\n * Create a transport message envelope\n * @template T\n * @param {string} event - Event type\n * @param {T} payload - Message payload\n * @param {string} [sessionId] - Session ID\n * @param {string} [deviceId] - Device ID\n * @returns {import('./types.js').TransportMessage<T>}\n */\nexport function createMessage(event, payload, sessionId, deviceId) {\n  return {\n    id: generateUUID(),\n    event,\n    ts: Date.now(),\n    sessionId,\n    deviceId,\n    payload,\n  };\n}\n\n/**\n * Base transport class - implements common transport functionality\n * Subclasses must implement: _connect(), _disconnect(), _sendRaw()\n */\nexport class BaseTransport {\n  /**\n   * @param {import('./types.js').TransportConfig} config\n   */\n  constructor(config) {\n    /** @type {import('./types.js').TransportConfig} */\n    this._config = {\n      timeout: 15000,\n      pingInterval: 20000,\n      reconnect: {\n        enabled: true,\n        maxAttempts: 10,\n        baseDelay: 1000,\n        maxDelay: 30000,\n      },\n      ...config,\n    };\n\n    /** @type {import('./types.js').TransportStatus} */\n    this._status = TransportStatus.DISCONNECTED;\n\n    /** @type {import('./types.js').TransportStats} */\n    this._stats = {\n      status: TransportStatus.DISCONNECTED,\n      type: config.type,\n      messagesSent: 0,\n      messagesReceived: 0,\n      reconnectAttempts: 0,\n    };\n\n    // Credentials\n    /** @type {string | undefined} */\n    this._sessionId = undefined;\n    /** @type {string | undefined} */\n    this._deviceId = undefined;\n\n    // Pending request-reply map\n    /** @type {Map<string, { resolve: Function, reject: Function, timeout: number }>} */\n    this._pendingRequests = new Map();\n\n    // Event subscriptions\n    /** @type {Map<string, Set<Function>>} */\n    this._subscriptions = new Map();\n\n    // All-message subscribers\n    /** @type {Set<Function>} */\n    this._allSubscribers = new Set();\n\n    // Status change listeners\n    /** @type {Set<Function>} */\n    this._statusListeners = new Set();\n\n    // Ping interval handle\n    /** @type {number | undefined} */\n    this._pingInterval = undefined;\n\n    // Reconnect state\n    /** @type {number} */\n    this._reconnectAttempts = 0;\n    /** @type {number | undefined} */\n    this._reconnectTimeout = undefined;\n    this._pingRetryAt = 0;\n  }\n\n  /**\n   * Current connection status\n   * @returns {import('./types.js').TransportStatus}\n   */\n  get status() {\n    return this._status;\n  }\n\n  /**\n   * Transport type\n   * @returns {import('./types.js').TransportType}\n   */\n  get type() {\n    return this._config.type;\n  }\n\n  /**\n   * Transport statistics\n   * @returns {import('./types.js').TransportStats}\n   */\n  get stats() {\n    return { ...this._stats, status: this._status };\n  }\n\n  /**\n   * Set connection status and notify listeners\n   * @param {import('./types.js').TransportStatus} status\n   * @protected\n   */\n  _setStatus(status) {\n    if (this._status === status) return;\n\n    const oldStatus = this._status;\n    this._status = status;\n    this._stats.status = status;\n\n    if (status === TransportStatus.CONNECTED) {\n      this._stats.lastConnectedAt = Date.now();\n      this._reconnectAttempts = 0;\n      this._stats.reconnectAttempts = 0;\n    }\n\n    // Notify listeners\n    for (const listener of this._statusListeners) {\n      try {\n        listener(status, oldStatus);\n      } catch (err) {\n        console.error('[Transport] Status listener error:', err);\n      }\n    }\n  }\n\n  /**\n   * Connect to the transport layer\n   * @returns {Promise<void>}\n   */\n  async connect() {\n    if (this._status === TransportStatus.CONNECTED) {\n      return;\n    }\n\n    if (this._status === TransportStatus.CONNECTING) {\n      // Wait for existing connection attempt\n      return new Promise((resolve, reject) => {\n        const unsub = this.onStatusChange((status) => {\n          if (status === TransportStatus.CONNECTED) {\n            unsub.unsubscribe();\n            resolve();\n          } else if (status === TransportStatus.ERROR) {\n            unsub.unsubscribe();\n            reject(new Error('Connection failed'));\n          }\n        });\n      });\n    }\n\n    this._setStatus(TransportStatus.CONNECTING);\n\n    try {\n      await this._connect();\n      this._setStatus(TransportStatus.CONNECTED);\n      this._startPing();\n    } catch (err) {\n      this._setStatus(TransportStatus.ERROR);\n      if (err?.reconnect !== false) this._scheduleReconnect();\n      throw err;\n    }\n  }\n\n  /**\n   * Disconnect from the transport layer\n   * @returns {Promise<void>}\n   */\n  async disconnect() {\n    this._stopPing();\n    this._clearReconnect();\n\n    if (this._status === TransportStatus.DISCONNECTED) {\n      return;\n    }\n\n    try {\n      await this._disconnect();\n    } finally {\n      this._setStatus(TransportStatus.DISCONNECTED);\n      this._rejectAllPending(new Error('Disconnected'));\n    }\n  }\n\n  /**\n   * Send a message and optionally wait for response\n   * @template TReq, TRes\n   * @param {string} event - Event type\n   * @param {TReq} payload - Message payload\n   * @param {import('./types.js').TransportSendOptions} [options]\n   * @returns {Promise<import('./types.js').TransportMessage<TRes>>}\n   */\n  async send(event, payload, options = {}) {\n    if (this._status !== TransportStatus.CONNECTED) {\n      throw new Error(`Transport not connected (status: ${this._status})`);\n    }\n\n    const message = createMessage(event, payload, this._sessionId, this._deviceId);\n\n    if (options.noReply) {\n      await this._sendRaw(message);\n      this._stats.messagesSent++;\n      return message;\n    }\n\n    const timeout = options.timeout || this._config.timeout;\n\n    return new Promise((resolve, reject) => {\n      const timeoutId = setTimeout(() => {\n        this._pendingRequests.delete(message.id);\n        reject(new Error(`Request timeout for ${event} (${timeout}ms)`));\n      }, timeout);\n\n      this._pendingRequests.set(message.id, {\n        resolve: (response) => {\n          clearTimeout(timeoutId);\n          this._pendingRequests.delete(message.id);\n          resolve(response);\n        },\n        reject: (error) => {\n          clearTimeout(timeoutId);\n          this._pendingRequests.delete(message.id);\n          reject(error);\n        },\n        timeout: timeoutId,\n      });\n\n      this._sendRaw(message)\n        .then(() => {\n          this._stats.messagesSent++;\n        })\n        .catch((err) => {\n          this._pendingRequests.delete(message.id);\n          clearTimeout(timeoutId);\n          reject(err);\n        });\n    });\n  }\n\n  /**\n   * Subscribe to incoming messages for a specific event\n   * @template T\n   * @param {string} event - Event type pattern (supports wildcards like \"overlay.*\")\n   * @param {function(import('./types.js').TransportMessage<T>): void} handler\n   * @returns {import('./types.js').TransportSubscription}\n   */\n  subscribe(event, handler) {\n    if (!this._subscriptions.has(event)) {\n      this._subscriptions.set(event, new Set());\n    }\n    this._subscriptions.get(event).add(handler);\n\n    return {\n      unsubscribe: () => {\n        const handlers = this._subscriptions.get(event);\n        if (handlers) {\n          handlers.delete(handler);\n          if (handlers.size === 0) {\n            this._subscriptions.delete(event);\n          }\n        }\n      },\n    };\n  }\n\n  /**\n   * Subscribe to all incoming messages\n   * @param {function(import('./types.js').TransportMessage): void} handler\n   * @returns {import('./types.js').TransportSubscription}\n   */\n  subscribeAll(handler) {\n    this._allSubscribers.add(handler);\n\n    return {\n      unsubscribe: () => {\n        this._allSubscribers.delete(handler);\n      },\n    };\n  }\n\n  /**\n   * Subscribe to transport status changes\n   * @param {function(import('./types.js').TransportStatus, import('./types.js').TransportStatus): void} handler\n   * @returns {import('./types.js').TransportSubscription}\n   */\n  onStatusChange(handler) {\n    this._statusListeners.add(handler);\n\n    return {\n      unsubscribe: () => {\n        this._statusListeners.delete(handler);\n      },\n    };\n  }\n\n  /**\n   * Set authentication credentials\n   * @param {string} sessionId\n   * @param {string} deviceId\n   */\n  setCredentials(sessionId, deviceId) {\n    this._sessionId = sessionId;\n    this._deviceId = deviceId;\n  }\n\n  /**\n   * Clear authentication credentials\n   */\n  clearCredentials() {\n    this._sessionId = undefined;\n    this._deviceId = undefined;\n  }\n\n  /**\n   * Handle incoming message (called by subclass)\n   * @param {import('./types.js').TransportMessage} message\n   * @protected\n   */\n  _handleMessage(message) {\n    this._stats.messagesReceived++;\n    this._stats.lastMessageAt = Date.now();\n\n    // Check for pending request-reply\n    if (message.id && this._pendingRequests.has(message.id)) {\n      const pending = this._pendingRequests.get(message.id);\n      if (message.error) {\n        const error = new Error(message.error.message || message.error.code);\n        error.code = message.error.code || 'TRANSPORT_ERROR';\n        error.retryAfterMs = message.payload?.rateLimit?.retryAfterMs;\n        pending.reject(error);\n      } else {\n        pending.resolve(message);\n      }\n      return;\n    }\n\n    // Notify all-message subscribers\n    for (const handler of this._allSubscribers) {\n      try {\n        handler(message);\n      } catch (err) {\n        console.error('[Transport] All-subscriber error:', err);\n      }\n    }\n\n    // Find matching subscriptions (including wildcards)\n    for (const [pattern, handlers] of this._subscriptions) {\n      if (this._matchEvent(message.event, pattern)) {\n        for (const handler of handlers) {\n          try {\n            handler(message);\n          } catch (err) {\n            console.error(`[Transport] Subscription handler error for ${pattern}:`, err);\n          }\n        }\n      }\n    }\n  }\n\n  /**\n   * Match event against pattern (supports wildcards)\n   * @param {string} event\n   * @param {string} pattern\n   * @returns {boolean}\n   * @private\n   */\n  _matchEvent(event, pattern) {\n    if (pattern === event) return true;\n    if (pattern === '*') return true;\n\n    // Handle wildcards like \"overlay.*\"\n    if (pattern.endsWith('.*')) {\n      const prefix = pattern.slice(0, -2);\n      return event.startsWith(prefix + '.');\n    }\n\n    return false;\n  }\n\n  /**\n   * Start ping interval\n   * @private\n   */\n  _startPing() {\n    this._stopPing();\n\n    if (this._config.pingInterval > 0) {\n      this._pingInterval = setInterval(() => {\n        this._sendPing();\n      }, this._config.pingInterval);\n    }\n  }\n\n  /**\n   * Stop ping interval\n   * @private\n   */\n  _stopPing() {\n    if (this._pingInterval) {\n      clearInterval(this._pingInterval);\n      this._pingInterval = undefined;\n    }\n  }\n\n  /**\n   * Send a ping message\n   * @private\n   */\n  async _sendPing() {\n    if (this._status !== TransportStatus.CONNECTED) return;\n    if (Date.now() < this._pingRetryAt) return;\n\n    try {\n      const startTime = Date.now();\n      await this.send('system.ping', { clientTs: startTime }, { timeout: 5000 });\n      this._stats.latencyMs = Date.now() - startTime;\n      this._pingRetryAt = 0;\n    } catch (err) {\n      // A correlated quota reply proves this connection is alive. Reopening\n      // the same socket cannot reset server quota and creates a retry storm.\n      if (err.code === 'RATE_LIMITED' || err.code === 'QUOTA_UNAVAILABLE') {\n        const delay = Number(err.retryAfterMs);\n        this._pingRetryAt = Date.now() + (Number.isFinite(delay) && delay > 0 ? delay : 60000);\n        return;\n      }\n      console.warn('[Transport] Ping failed:', err.message);\n      // Connection might be dead, trigger reconnect\n      this._handleDisconnect();\n    }\n  }\n\n  /**\n   * Handle disconnection (called by subclass or ping failure)\n   * @protected\n   */\n  _handleDisconnect() {\n    this._stopPing();\n\n    if (this._status === TransportStatus.DISCONNECTED) return;\n\n    this._setStatus(TransportStatus.DISCONNECTED);\n    this._scheduleReconnect();\n  }\n\n  /**\n   * Schedule a reconnection attempt\n   * @private\n   */\n  _scheduleReconnect() {\n    if (!this._config.reconnect?.enabled) return;\n    if (this._reconnectAttempts >= this._config.reconnect.maxAttempts) {\n      console.error('[Transport] Max reconnection attempts reached');\n      this._setStatus(TransportStatus.ERROR);\n      return;\n    }\n\n    this._clearReconnect();\n    this._setStatus(TransportStatus.RECONNECTING);\n\n    const delay = Math.min(\n      this._config.reconnect.baseDelay * Math.pow(2, this._reconnectAttempts),\n      this._config.reconnect.maxDelay\n    );\n\n    console.log(`[Transport] Reconnecting in ${delay}ms (attempt ${this._reconnectAttempts + 1})`);\n\n    this._reconnectTimeout = setTimeout(async () => {\n      this._reconnectAttempts++;\n      this._stats.reconnectAttempts = this._reconnectAttempts;\n\n      try {\n        await this._connect();\n        this._setStatus(TransportStatus.CONNECTED);\n        this._startPing();\n      } catch (err) {\n        console.error('[Transport] Reconnection failed:', err.message);\n        if (err?.reconnect === false) {\n          this._clearReconnect();\n          this._setStatus(TransportStatus.ERROR);\n        } else {\n          this._scheduleReconnect();\n        }\n      }\n    }, delay);\n  }\n\n  /**\n   * Clear pending reconnection\n   * @private\n   */\n  _clearReconnect() {\n    if (this._reconnectTimeout) {\n      clearTimeout(this._reconnectTimeout);\n      this._reconnectTimeout = undefined;\n    }\n  }\n\n  /**\n   * Reject all pending requests\n   * @param {Error} error\n   * @private\n   */\n  _rejectAllPending(error) {\n    for (const [id, pending] of this._pendingRequests) {\n      pending.reject(error);\n    }\n    this._pendingRequests.clear();\n  }\n\n  // ============================================================================\n  // Abstract methods - must be implemented by subclasses\n  // ============================================================================\n\n  /**\n   * Connect implementation\n   * @returns {Promise<void>}\n   * @protected\n   * @abstract\n   */\n  async _connect() {\n    throw new Error('_connect() must be implemented by subclass');\n  }\n\n  /**\n   * Disconnect implementation\n   * @returns {Promise<void>}\n   * @protected\n   * @abstract\n   */\n  async _disconnect() {\n    throw new Error('_disconnect() must be implemented by subclass');\n  }\n\n  /**\n   * Send raw message implementation\n   * @param {import('./types.js').TransportMessage} message\n   * @returns {Promise<void>}\n   * @protected\n   * @abstract\n   */\n  async _sendRaw(message) {\n    throw new Error('_sendRaw() must be implemented by subclass');\n  }\n}\n","/**\n * CentralizedTransport - WebSocket-based transport implementation\n *\n * Connects to the centralized backend via WebSocket for real-time communication.\n * Falls back to HTTP for request-response patterns when WebSocket is unavailable.\n *\n * @fileoverview WebSocket transport implementation\n */\n\nimport { BaseTransport, createMessage } from './BaseTransport.js';\nimport { TransportEvent, TransportType, TransportStatus } from './types.js';\nimport { getNoclipGovernanceClient } from '../shared/NoclipGovernanceClient.js';\n\n/**\n * Centralized transport using WebSocket\n * @extends BaseTransport\n */\nexport class CentralizedTransport extends BaseTransport {\n  /**\n   * @param {Object} options\n   * @param {string} options.wsUrl - WebSocket URL (e.g., \"wss://api.example.com/ws\")\n   * @param {string} [options.httpUrl] - HTTP base URL for fallback\n   * @param {number} [options.timeout] - Request timeout in ms\n   * @param {number} [options.pingInterval] - Ping interval in ms\n   * @param {Object} [options.reconnect] - Reconnection settings\n   */\n  constructor(options) {\n    super({\n      type: TransportType.CENTRALIZED,\n      ...options,\n    });\n\n    /** @type {WebSocket | null} */\n    this._ws = null;\n\n    /** @type {string} */\n    this._wsUrl = options.wsUrl;\n\n    /** @type {string | undefined} */\n    this._httpUrl = options.httpUrl;\n\n    /** @type {Array<import('./types.js').TransportMessage>} */\n    this._messageQueue = [];\n\n    /** @type {boolean} */\n    this._isConnecting = false;\n\n    /**\n     * Current browser access token. This remains memory-only and is retained\n     * solely so a replacement WebSocket can establish the same verified\n     * account/device identity before any queued traffic is released.\n     * @type {string | null}\n     */\n    this._authToken = null;\n\n    /** @type {string | null} */\n    this._socketAuthRequestId = null;\n\n    /** @type {WeakSet<WebSocket>} */\n    this._intentionalCloseSockets = new WeakSet();\n  }\n\n  /**\n   * Remember a successful caller-supplied auth intent for reconnects, then\n   * delegate normal request/reply handling to BaseTransport.\n   */\n  async send(event, payload, options = {}) {\n    if (event === TransportEvent.AUTH_STATUS) {\n      const token = typeof payload?.token === 'string' ? payload.token.trim() : '';\n      const response = await super.send(event, payload, options);\n      if (token) this._authToken = token;\n      return response;\n    }\n    return super.send(event, payload, options);\n  }\n\n  /**\n   * Connect to WebSocket server\n   * @returns {Promise<void>}\n   * @protected\n   */\n  async _connect() {\n    if (this._ws && this._ws.readyState === WebSocket.OPEN) {\n      return;\n    }\n\n    if (this._isConnecting) {\n      // Wait for existing connection attempt\n      return new Promise((resolve, reject) => {\n        const checkInterval = setInterval(() => {\n          if (this._ws && this._ws.readyState === WebSocket.OPEN) {\n            clearInterval(checkInterval);\n            resolve();\n          } else if (!this._isConnecting) {\n            clearInterval(checkInterval);\n            reject(new Error('Connection failed'));\n          }\n        }, 100);\n      });\n    }\n\n    this._isConnecting = true;\n\n    return new Promise((resolve, reject) => {\n      try {\n        // Build WebSocket URL with auth params if available\n        let url = this._wsUrl;\n        const params = new URLSearchParams();\n\n        if (this._sessionId) {\n          params.set('sessionId', this._sessionId);\n        }\n        if (this._deviceId) {\n          params.set('deviceId', this._deviceId);\n        }\n\n        const queryString = params.toString();\n        if (queryString) {\n          url += (url.includes('?') ? '&' : '?') + queryString;\n        }\n\n        this._ws = new WebSocket(url);\n\n        const socket = this._ws;\n\n        this._ws.onopen = async () => {\n          console.log('[CentralizedTransport] Connected to', this._wsUrl);\n          this._isConnecting = false;\n          try {\n            if (this._authToken) {\n              await this._authenticateOpenSocket(socket);\n            }\n            if (this._ws !== socket || socket.readyState !== WebSocket.OPEN) {\n              throw new Error('WebSocket closed during authentication');\n            }\n            this._flushMessageQueue();\n            resolve();\n          } catch (error) {\n            const terminalAuthFailure = [\n              'UNAUTHORIZED',\n              'AUTH_REQUIRED',\n              'API_KEY_NOT_ALLOWED',\n              'INVALID_REQUEST',\n            ].includes(error?.code);\n            if (terminalAuthFailure) {\n              // The server explicitly rejected this credential. Retrying the\n              // same bearer can only create an auth.status storm and consume\n              // unrelated authentication capacity. Drop every stale\n              // credential-bound message and wait for AuthService to provide\n              // a newly verified session.\n              this._authToken = null;\n              this._messageQueue.length = 0;\n              error.reconnect = false;\n              this._intentionalCloseSockets.add(socket);\n              this._rejectAllPending(error);\n            }\n            if (this._ws === socket) this._ws = null;\n            if (socket.readyState === WebSocket.OPEN) {\n              socket.close(4003, 'Authentication failed');\n            }\n            reject(error instanceof Error ? error : new Error('WebSocket authentication failed'));\n          }\n        };\n\n        this._ws.onclose = (event) => {\n          console.log('[CentralizedTransport] Disconnected:', event.code, event.reason);\n          this._isConnecting = false;\n          const intentionalClose = this._intentionalCloseSockets.has(socket);\n          this._intentionalCloseSockets.delete(socket);\n          if (this._ws === socket) {\n            this._ws = null;\n            this._rejectSocketAuthentication(new Error('WebSocket closed during authentication'));\n          }\n          if (intentionalClose) return;\n          this._handleDisconnect();\n        };\n\n        this._ws.onerror = (error) => {\n          console.error('[CentralizedTransport] Error:', error);\n          this._isConnecting = false;\n\n          if (this._ws?.readyState !== WebSocket.OPEN) {\n            reject(new Error('WebSocket connection failed'));\n          }\n        };\n\n        this._ws.onmessage = (event) => {\n          this._onMessage(event);\n        };\n\n        // Connection timeout\n        setTimeout(() => {\n          if (this._isConnecting) {\n            this._isConnecting = false;\n            if (this._ws) {\n              this._ws.close();\n              this._ws = null;\n            }\n            reject(new Error('Connection timeout'));\n          }\n        }, this._config.timeout);\n      } catch (err) {\n        this._isConnecting = false;\n        reject(err);\n      }\n    });\n  }\n\n  /**\n   * Disconnect from WebSocket server\n   * @returns {Promise<void>}\n   * @protected\n   */\n  async _disconnect() {\n    if (this._ws) {\n      // Send close frame\n      this._intentionalCloseSockets.add(this._ws);\n      if (this._ws.readyState === WebSocket.OPEN) {\n        this._ws.close(1000, 'Client disconnect');\n      }\n      this._ws = null;\n    }\n    this._rejectSocketAuthentication(new Error('Disconnected'));\n  }\n\n  /**\n   * Authenticate a newly opened socket before queued authenticated messages\n   * can cross it. The request is registered in the normal correlation map so\n   * backend errors and timeouts retain standard transport semantics.\n   * @param {WebSocket} socket\n   * @returns {Promise<void>}\n   * @private\n   */\n  _authenticateOpenSocket(socket) {\n    const message = createMessage(\n      TransportEvent.AUTH_STATUS,\n      { token: this._authToken },\n      this._sessionId,\n      this._deviceId\n    );\n    const timeout = this._config.timeout;\n    this._socketAuthRequestId = message.id;\n\n    return new Promise((resolve, reject) => {\n      const timeoutId = setTimeout(() => {\n        this._pendingRequests.delete(message.id);\n        if (this._socketAuthRequestId === message.id) this._socketAuthRequestId = null;\n        reject(new Error(`Request timeout for ${TransportEvent.AUTH_STATUS} (${timeout}ms)`));\n      }, timeout);\n\n      this._pendingRequests.set(message.id, {\n        resolve: () => {\n          clearTimeout(timeoutId);\n          this._pendingRequests.delete(message.id);\n          if (this._socketAuthRequestId === message.id) this._socketAuthRequestId = null;\n          resolve();\n        },\n        reject: (error) => {\n          clearTimeout(timeoutId);\n          this._pendingRequests.delete(message.id);\n          if (this._socketAuthRequestId === message.id) this._socketAuthRequestId = null;\n          reject(error);\n        },\n        timeout: timeoutId,\n      });\n\n      try {\n        socket.send(JSON.stringify(message));\n        this._stats.messagesSent++;\n      } catch (error) {\n        const pending = this._pendingRequests.get(message.id);\n        pending?.reject(error);\n      }\n    });\n  }\n\n  /** @private */\n  _rejectSocketAuthentication(error) {\n    if (!this._socketAuthRequestId) return;\n    const pending = this._pendingRequests.get(this._socketAuthRequestId);\n    pending?.reject(error);\n  }\n\n  clearCredentials() {\n    super.clearCredentials();\n    this._authToken = null;\n    this._messageQueue.length = 0;\n    const error = new Error('Authentication credentials cleared');\n    this._rejectSocketAuthentication(error);\n    this._rejectAllPending(error);\n  }\n\n  /**\n   * Send raw message over WebSocket\n   * @param {import('./types.js').TransportMessage} message\n   * @returns {Promise<void>}\n   * @protected\n   */\n  async _sendRaw(message) {\n    if (!this._ws || this._ws.readyState !== WebSocket.OPEN) {\n      // Queue message for when connection is restored\n      this._messageQueue.push(message);\n\n      if (this._status === TransportStatus.RECONNECTING) {\n        // Message will be sent after reconnection\n        return;\n      }\n\n      throw new Error('WebSocket not connected');\n    }\n\n    const data = JSON.stringify(message);\n    this._ws.send(data);\n  }\n\n  /**\n   * Handle incoming WebSocket message\n   * @param {MessageEvent} event\n   * @private\n   */\n  _onMessage(event) {\n    try {\n      const message = JSON.parse(event.data);\n\n      // Validate message structure\n      if (!message.id || !message.event) {\n        console.warn('[CentralizedTransport] Invalid message:', message);\n        return;\n      }\n\n      // Handle pong specially for latency tracking\n      if (message.event === 'system.pong') {\n        const latency = Date.now() - (message.payload?.clientTs || 0);\n        this._stats.latencyMs = latency;\n      }\n\n      this._handleMessage(message);\n    } catch (err) {\n      console.error('[CentralizedTransport] Message parse error:', err);\n    }\n  }\n\n  /**\n   * Flush queued messages after reconnection\n   * @private\n   */\n  _flushMessageQueue() {\n    while (this._messageQueue.length > 0) {\n      const message = this._messageQueue.shift();\n      try {\n        this._sendRaw(message);\n      } catch (err) {\n        console.error('[CentralizedTransport] Failed to send queued message:', err);\n        // Re-queue on failure\n        this._messageQueue.unshift(message);\n        break;\n      }\n    }\n  }\n\n  /**\n   * Send HTTP request (fallback when WebSocket unavailable)\n   * @template TReq, TRes\n   * @param {string} event - Event type\n   * @param {TReq} payload - Request payload\n   * @returns {Promise<TRes>}\n   */\n  async sendHttp(event, payload) {\n    if (!this._httpUrl) {\n      throw new Error('HTTP URL not configured');\n    }\n\n    const url = `${this._httpUrl}/transport`;\n\n    const headers = {\n      'Content-Type': 'application/json',\n    };\n\n    if (this._sessionId) {\n      headers['Authorization'] = `Bearer ${this._sessionId}`;\n    }\n\n    if (this._deviceId) {\n      headers['X-Device-ID'] = this._deviceId;\n    }\n\n    const response = await getNoclipGovernanceClient().request(url, {\n      method: 'POST',\n      headers,\n      body: JSON.stringify({\n        event,\n        payload,\n        ts: Date.now(),\n      }),\n    });\n\n    if (!response.ok) {\n      const error = await response.json().catch(() => ({ message: response.statusText }));\n      throw new Error(error.message || `HTTP ${response.status}`);\n    }\n\n    return response.json();\n  }\n}\n\n/**\n * Create a CentralizedTransport instance with default configuration\n * @param {string} wsUrl - WebSocket URL\n * @param {string} [httpUrl] - HTTP URL (optional fallback)\n * @returns {CentralizedTransport}\n */\nexport function createCentralizedTransport(wsUrl, httpUrl) {\n  return new CentralizedTransport({\n    wsUrl,\n    httpUrl,\n    timeout: 15000,\n    pingInterval: 20000,\n    reconnect: {\n      enabled: true,\n      maxAttempts: 10,\n      baseDelay: 1000,\n      maxDelay: 30000,\n    },\n  });\n}\n","/**\n * TransportManager - Manages transport layer connections\n *\n * Provides a unified interface for communicating with the backend,\n * handling transport selection, failover, and credential management.\n *\n * @fileoverview Transport manager for frontend\n */\n\nimport { CentralizedTransport, createCentralizedTransport } from './CentralizedTransport.js';\nimport { TransportStatus, TransportType, TransportEvent } from './types.js';\nimport { getAuthService } from '../auth/AuthService.js';\n\n/**\n * Transport Manager - singleton that manages transport connections\n */\nclass TransportManager {\n  constructor() {\n    /** @type {import('./BaseTransport.js').BaseTransport | null} */\n    this._primary = null;\n\n    /** @type {import('./BaseTransport.js').BaseTransport | null} */\n    this._fallback = null;\n\n    /** @type {import('./BaseTransport.js').BaseTransport | null} */\n    this._active = null;\n\n    /** @type {import('./types.js').TransportConfig | null} */\n    this._config = null;\n\n    /** @type {boolean} */\n    this._initialized = false;\n\n    /** @type {Set<Function>} */\n    this._statusListeners = new Set();\n\n    /** @type {string | undefined} */\n    this._sessionId = undefined;\n\n    /** @type {string | undefined} */\n    this._deviceId = undefined;\n\n    /** @type {Array<import('./types.js').TransportSubscription>} */\n    this._authLogoutSubscriptions = [];\n\n    /** @type {boolean} */\n    this._authLogoutInitialized = false;\n\n    /** @type {import('../p2p/NknTransport.js').NknTransport | null} */\n    this._discoveryNkn = null;\n\n    this._selectionTelemetry = {\n      preferred: 'centralized',\n      selected: 'centralized',\n      fallbackUsed: false,\n      discoveryNknState: 'disabled',\n      discoveryNknAddress: '',\n      reason: 'init'\n    };\n  }\n\n  /**\n   * Get the active transport\n   * @returns {import('./BaseTransport.js').BaseTransport | null}\n   */\n  get active() {\n    return this._active;\n  }\n\n  /**\n   * Get the primary transport\n   * @returns {import('./BaseTransport.js').BaseTransport | null}\n   */\n  get primary() {\n    return this._primary;\n  }\n\n  /**\n   * Get the fallback transport\n   * @returns {import('./BaseTransport.js').BaseTransport | null}\n   */\n  get fallback() {\n    return this._fallback;\n  }\n\n  /**\n   * Get current connection status\n   * @returns {import('./types.js').TransportStatus}\n   */\n  get status() {\n    return this._active?.status || TransportStatus.DISCONNECTED;\n  }\n\n  /**\n   * Get current transport type\n   * @returns {import('./types.js').TransportType | null}\n   */\n  get type() {\n    return this._active?.type || null;\n  }\n\n  /**\n   * Check if connected\n   * @returns {boolean}\n   */\n  get isConnected() {\n    return this._active?.status === TransportStatus.CONNECTED;\n  }\n\n  getSelectionTelemetry() {\n    return { ...(this._selectionTelemetry || {}) };\n  }\n\n  /**\n   * Initialize the transport manager\n   * @param {Object} config\n   * @param {string} config.wsUrl - WebSocket URL for centralized transport\n   * @param {string} [config.httpUrl] - HTTP URL for fallback\n   * @param {'centralized' | 'nkn'} [config.preferredTransport='centralized'] - Preferred transport\n   * @param {string} [config.nknIdentifier] - NKN identifier (for NKN transport)\n   * @param {boolean} [config.enableFallback=true] - Enable fallback transport\n   */\n  async init(config) {\n    if (this._initialized) {\n      console.warn('[TransportManager] Already initialized');\n      return;\n    }\n\n    this._config = config;\n\n    // Create primary transport based on preference\n    const preferredTransport = config.preferredTransport || 'centralized';\n\n    if (preferredTransport === 'centralized') {\n      this._primary = createCentralizedTransport(config.wsUrl, config.httpUrl);\n      this._selectionTelemetry = {\n        ...this._selectionTelemetry,\n        preferred: 'centralized',\n        selected: 'centralized',\n        reason: 'preferred-centralized'\n      };\n    } else if (preferredTransport === 'nkn') {\n      // Keep centralized for authenticated backend RPC while enabling\n      // NKN address discovery and peer routing telemetry in parallel.\n      this._primary = createCentralizedTransport(config.wsUrl, config.httpUrl);\n      const { getSharedNknTransport } = await import('../p2p/index.js');\n      this._discoveryNkn = getSharedNknTransport({\n        identifier: config.nknIdentifier || 'earth'\n      });\n      this._selectionTelemetry = {\n        ...this._selectionTelemetry,\n        preferred: 'nkn',\n        selected: 'centralized',\n        discoveryNknState: 'enabled',\n        reason: 'nkn-enabled-centralized-control-plane'\n      };\n    }\n\n    // Create fallback transport if enabled and different from primary\n    if (config.enableFallback !== false && preferredTransport === 'nkn') {\n      this._fallback = createCentralizedTransport(config.wsUrl, config.httpUrl);\n    }\n\n    // Set up status change listener on primary\n    this._primary.onStatusChange((status, oldStatus) => {\n      this._handleTransportStatusChange(this._primary, status, oldStatus);\n    });\n\n    this._active = this._primary;\n    this._initialized = true;\n    this._setupAuthLogoutHandling();\n\n    console.log('[TransportManager] Initialized with', preferredTransport, 'transport');\n  }\n\n  /**\n   * Connect to the transport layer\n   * @returns {Promise<void>}\n   */\n  async connect() {\n    if (!this._initialized) {\n      throw new Error('TransportManager not initialized. Call init() first.');\n    }\n\n    // Apply credentials if set\n    if (this._sessionId && this._deviceId) {\n      this._active.setCredentials(this._sessionId, this._deviceId);\n    }\n\n    try {\n      await this._active.connect();\n      if (this._discoveryNkn) {\n        void this._discoveryNkn.connect().then(() => {\n          this._selectionTelemetry = {\n            ...this._selectionTelemetry,\n            discoveryNknState: 'connected',\n            discoveryNknAddress: String(this._discoveryNkn.address || ''),\n            selected: this._active?.type || 'centralized',\n            reason: 'primary-connected'\n          };\n        }).catch((nknErr) => {\n          this._selectionTelemetry = {\n            ...this._selectionTelemetry,\n            discoveryNknState: 'error',\n            reason: `discovery-nkn-error:${nknErr?.message || nknErr}`\n          };\n        });\n        this._selectionTelemetry = {\n          ...this._selectionTelemetry,\n          discoveryNknState: 'connecting',\n          selected: this._active?.type || 'centralized',\n          reason: 'primary-connected-nkn-background'\n        };\n      } else {\n        this._selectionTelemetry = {\n          ...this._selectionTelemetry,\n          selected: this._active?.type || 'centralized',\n          reason: 'primary-connected'\n        };\n      }\n    } catch (err) {\n      console.error('[TransportManager] Primary transport failed:', err);\n      this._selectionTelemetry = {\n        ...this._selectionTelemetry,\n        fallbackUsed: !!this._fallback,\n        reason: `primary-error:${err?.message || err}`\n      };\n\n      // Try fallback if available\n      if (this._fallback && this._fallback !== this._active) {\n        console.log('[TransportManager] Attempting fallback transport');\n        this._active = this._fallback;\n\n        if (this._sessionId && this._deviceId) {\n          this._active.setCredentials(this._sessionId, this._deviceId);\n        }\n\n        await this._active.connect();\n        this._selectionTelemetry = {\n          ...this._selectionTelemetry,\n          selected: this._active?.type || 'centralized',\n          fallbackUsed: true,\n          reason: 'fallback-connected'\n        };\n      } else {\n        throw err;\n      }\n    }\n  }\n\n  /**\n   * Disconnect from the transport layer\n   * @returns {Promise<void>}\n   */\n  async disconnect() {\n    if (this._primary) {\n      await this._primary.disconnect();\n    }\n    if (this._fallback) {\n      await this._fallback.disconnect();\n    }\n    if (this._discoveryNkn) {\n      await this._discoveryNkn.disconnect().catch(() => undefined);\n    }\n  }\n\n  /**\n   * Send a message and wait for response\n   * @template TReq, TRes\n   * @param {string} event - Event type\n   * @param {TReq} payload - Message payload\n   * @param {import('./types.js').TransportSendOptions} [options]\n   * @returns {Promise<import('./types.js').TransportMessage<TRes>>}\n   */\n  async send(event, payload, options) {\n    if (!this._active) {\n      throw new Error('TransportManager not initialized');\n    }\n    return this._active.send(event, payload, options);\n  }\n\n  /**\n   * Subscribe to incoming messages for a specific event\n   * @template T\n   * @param {string} event - Event pattern\n   * @param {function(import('./types.js').TransportMessage<T>): void} handler\n   * @returns {import('./types.js').TransportSubscription}\n   */\n  subscribe(event, handler) {\n    if (!this._active) {\n      throw new Error('TransportManager not initialized');\n    }\n    return this._active.subscribe(event, handler);\n  }\n\n  /**\n   * Subscribe to all messages\n   * @param {function(import('./types.js').TransportMessage): void} handler\n   * @returns {import('./types.js').TransportSubscription}\n   */\n  subscribeAll(handler) {\n    if (!this._active) {\n      throw new Error('TransportManager not initialized');\n    }\n    return this._active.subscribeAll(handler);\n  }\n\n  /**\n   * Subscribe to status changes\n   * @param {function(import('./types.js').TransportStatus): void} handler\n   * @returns {import('./types.js').TransportSubscription}\n   */\n  onStatusChange(handler) {\n    this._statusListeners.add(handler);\n    return {\n      unsubscribe: () => {\n        this._statusListeners.delete(handler);\n      },\n    };\n  }\n\n  /**\n   * Set authentication credentials\n   * @param {string} sessionId\n   * @param {string} deviceId\n   */\n  setCredentials(sessionId, deviceId) {\n    this._sessionId = sessionId;\n    this._deviceId = deviceId;\n\n    if (this._primary) {\n      this._primary.setCredentials(sessionId, deviceId);\n    }\n    if (this._fallback) {\n      this._fallback.setCredentials(sessionId, deviceId);\n    }\n  }\n\n  /**\n   * Clear authentication credentials\n   */\n  clearCredentials() {\n    this._sessionId = undefined;\n    this._deviceId = undefined;\n\n    if (this._primary) {\n      this._primary.clearCredentials();\n    }\n    if (this._fallback) {\n      this._fallback.clearCredentials();\n    }\n  }\n\n  /**\n   * Force switch to a specific transport type\n   * @param {import('./types.js').TransportType} type\n   * @returns {Promise<void>}\n   */\n  async switchTransport(type) {\n    if (type === this._active?.type) {\n      return; // Already using this transport\n    }\n\n    const newTransport =\n      type === this._primary?.type ? this._primary : this._fallback;\n\n    if (!newTransport) {\n      throw new Error(`Transport type ${type} not available`);\n    }\n\n    // Disconnect current\n    if (this._active) {\n      await this._active.disconnect();\n    }\n\n    // Switch and connect\n    this._active = newTransport;\n\n    if (this._sessionId && this._deviceId) {\n      this._active.setCredentials(this._sessionId, this._deviceId);\n    }\n\n    await this._active.connect();\n  }\n\n  /**\n   * Handle transport status changes\n   * @param {import('./BaseTransport.js').BaseTransport} transport\n   * @param {import('./types.js').TransportStatus} status\n   * @param {import('./types.js').TransportStatus} oldStatus\n   * @private\n   */\n  _handleTransportStatusChange(transport, status, oldStatus) {\n    // Only care about active transport changes\n    if (transport !== this._active) return;\n\n    // Notify listeners\n    for (const listener of this._statusListeners) {\n      try {\n        listener(status);\n      } catch (err) {\n        console.error('[TransportManager] Status listener error:', err);\n      }\n    }\n\n    // Auto-failover to fallback on error\n    if (status === TransportStatus.ERROR && this._fallback && this._fallback !== this._active) {\n      console.log('[TransportManager] Primary failed, switching to fallback');\n      this._active = this._fallback;\n\n      if (this._sessionId && this._deviceId) {\n        this._active.setCredentials(this._sessionId, this._deviceId);\n      }\n\n      this._active.connect().catch((err) => {\n        console.error('[TransportManager] Fallback connection failed:', err);\n      });\n    }\n  }\n\n  /**\n   * Get transport statistics\n   * @returns {import('./types.js').TransportStats | null}\n   */\n  getStats() {\n    return this._active?.stats || null;\n  }\n\n  /**\n   * Set up subscriptions for social features (friends/notifications)\n   * Automatically routes push events to the SocialStore.\n   * @returns {Array<import('./types.js').TransportSubscription>}\n   */\n  setupSocialSubscriptions() {\n    const subscriptions = [];\n\n    // Dynamically import SocialStore to avoid circular dependencies\n    import('../social/SocialStore.js').then(({ getSocialStore }) => {\n      const store = getSocialStore();\n\n      // Subscribe to notification push events\n      subscriptions.push(\n        this.subscribe(TransportEvent.NOTIFICATION_PUSH, (message) => {\n          const notification = message.payload?.notification;\n          if (notification) {\n            store.handleNotificationPush(notification);\n          }\n        })\n      );\n\n      console.log('[TransportManager] Social subscriptions set up');\n    }).catch((err) => {\n      console.warn('[TransportManager] SocialStore not available:', err.message);\n    });\n\n    return subscriptions;\n  }\n\n  /**\n   * Destroy the transport manager\n   */\n  async destroy() {\n    await this.disconnect();\n    this._primary = null;\n    this._fallback = null;\n    this._active = null;\n    this._initialized = false;\n    this._statusListeners.clear();\n    this._authLogoutSubscriptions.forEach((sub) => sub?.unsubscribe?.());\n    this._authLogoutSubscriptions = [];\n    this._authLogoutInitialized = false;\n  }\n\n  _setupAuthLogoutHandling() {\n    if (this._authLogoutInitialized) return;\n    const authService = getAuthService();\n    const handler = (message) => {\n      const payload = message?.payload || {};\n      const state = authService?.getState?.() || {};\n      if (!state.isAuthenticated) return;\n      const localDeviceId = state.device?.deviceId || authService.deviceId || null;\n      const localSessionId = state.session?.sessionId || null;\n      const targetDeviceId = payload.deviceId || null;\n      const reason = payload.reason || null;\n      const sessionIds = Array.isArray(payload.sessionIds) ? payload.sessionIds : [];\n      if (targetDeviceId && localDeviceId && targetDeviceId !== localDeviceId) return;\n      if (sessionIds.length && localSessionId && !sessionIds.includes(localSessionId)) return;\n      if (reason === 'device_revoked') {\n        authService.clearDeviceId?.({ clearSession: true });\n      }\n      authService.logout();\n    };\n\n    this._authLogoutInitialized = true;\n    const transports = [this._primary, this._fallback].filter(Boolean);\n    transports.forEach((transport) => {\n      this._authLogoutSubscriptions.push(\n        transport.subscribe(TransportEvent.AUTH_LOGOUT, handler)\n      );\n    });\n  }\n}\n\n// Singleton instance\nlet instance = null;\n\n/**\n * Get the TransportManager singleton instance\n * @returns {TransportManager}\n */\nexport function getTransportManager() {\n  if (!instance) {\n    instance = new TransportManager();\n  }\n  return instance;\n}\n\n/**\n * Initialize the transport manager with configuration\n * @param {Object} config - Transport configuration\n * @returns {Promise<TransportManager>}\n */\nexport async function initTransport(config) {\n  const manager = getTransportManager();\n  await manager.init(config);\n  return manager;\n}\n\n// Re-export types and constants\nexport { TransportManager, TransportStatus, TransportType, TransportEvent };\n","/**\n * Unified IndexedDB scene state store.\n * Replaces the three separate IDB databases (elevation-cache, imagery-cache,\n * scene-snapshot-cache) with a single atomic database.\n *\n * The envelope record (key 'current') is the versioned root of all persisted\n * state.  writeCheckpoint / writeSyncCheckpoint open a single readwrite\n * transaction across all stores so the commit is all-or-nothing.\n */\n\nconst DB_NAME = 'noclip-scene-state';\n// v2 invalidates elevation values written before Mapzen orthometric heights\n// were converted through EGM96 into the WGS84 ellipsoidal datum used by ECEF.\nconst DB_VERSION = 2;\n\nconst ENVELOPE_STORE = 'envelope';\nconst ELEVATION_STORE = 'elevation';\nconst IMAGERY_TILE_STORE = 'imagery-tiles';\nconst IMAGERY_ATLAS_STORE = 'imagery-atlases';\nconst IMAGERY_META_STORE = 'imagery-meta';\n\nconst ALL_STORES = [\n    ENVELOPE_STORE,\n    ELEVATION_STORE,\n    IMAGERY_TILE_STORE,\n    IMAGERY_ATLAS_STORE,\n    IMAGERY_META_STORE\n];\n\nconst ELEVATION_MAX_ENTRIES = 100000;\nconst ELEVATION_PRUNE_BATCH = 10000;\nconst IMAGERY_DEFAULT_MAX_BYTES = 200 * 1024 * 1024;\nconst IMAGERY_DEFAULT_MAX_ENTRIES = 5000;\nconst IMAGERY_PRUNE_BATCH = 200;\nconst DEFAULT_BUCKET_DEG = 2;\n\n// ── Elevation utilities (ported from elevation-cache.js) ─────────────\n\nfunction normalizeLon(lonDeg) {\n    if (!Number.isFinite(lonDeg)) return null;\n    let lon = lonDeg;\n    while (lon < -180) lon += 360;\n    while (lon >= 180) lon -= 360;\n    return lon;\n}\n\nfunction parseLatLonFromKey(key) {\n    if (typeof key !== 'string') return null;\n    const parts = key.split(',');\n    if (parts.length < 2) return null;\n    const lat = Number(parts[0]);\n    const lon = Number(parts[1]);\n    if (!Number.isFinite(lat) || !Number.isFinite(lon)) return null;\n    return { lat, lon };\n}\n\nfunction getBucketForLatLon(latDeg, lonDeg, bucketDeg = DEFAULT_BUCKET_DEG) {\n    if (!Number.isFinite(latDeg) || !Number.isFinite(lonDeg)) return null;\n    const step = Math.max(0.25, Number.isFinite(bucketDeg) ? bucketDeg : DEFAULT_BUCKET_DEG);\n    const clampedLat = Math.max(-89.999999, Math.min(89.999999, latDeg));\n    const normalizedLon = normalizeLon(lonDeg);\n    if (!Number.isFinite(normalizedLon)) return null;\n    const latIndex = Math.floor((clampedLat + 90) / step);\n    const lonIndex = Math.floor((normalizedLon + 180) / step);\n    return `${step}:${latIndex}:${lonIndex}`;\n}\n\nfunction decorateElevationEntry(entry, now = Date.now()) {\n    if (!entry || !entry.k) return null;\n    entry.t = now;\n    if (!entry.b) {\n        const latLon = parseLatLonFromKey(entry.k);\n        if (latLon) {\n            const bucket = getBucketForLatLon(latLon.lat, latLon.lon);\n            if (bucket) entry.b = bucket;\n        }\n    }\n    return entry;\n}\n\n// ── SceneStateStore ──────────────────────────────────────────────────\n\nclass SceneStateStore {\n    constructor() {\n        this.db = null;\n        this._initPromise = null;\n        this._imageryTotalBytes = null;\n        this.imageryMaxBytes = IMAGERY_DEFAULT_MAX_BYTES;\n        this.imageryMaxEntries = IMAGERY_DEFAULT_MAX_ENTRIES;\n        this.elevationMaxEntries = ELEVATION_MAX_ENTRIES;\n    }\n\n    // ── Init ─────────────────────────────────────────────────────────\n\n    async init() {\n        if (this.db) return this.db;\n        if (this._initPromise) return this._initPromise;\n\n        if (typeof indexedDB === 'undefined') return null;\n\n        this._initPromise = (async () => {\n            const db = await new Promise((resolve, reject) => {\n                const request = indexedDB.open(DB_NAME, DB_VERSION);\n\n                request.onerror = () => {\n                    console.error('[SceneStateStore] Failed to open database:', request.error);\n                    reject(request.error);\n                };\n\n                request.onsuccess = () => resolve(request.result);\n\n                request.onupgradeneeded = (event) => {\n                    const db = event.target.result;\n\n                    if (!db.objectStoreNames.contains(ENVELOPE_STORE)) {\n                        db.createObjectStore(ENVELOPE_STORE, { keyPath: 'id' });\n                    }\n\n                    if (!db.objectStoreNames.contains(ELEVATION_STORE)) {\n                        const store = db.createObjectStore(ELEVATION_STORE, { keyPath: 'k' });\n                        store.createIndex('timestamp', 't', { unique: false });\n                        store.createIndex('bucket', 'b', { unique: false });\n                    }\n\n                    if (!db.objectStoreNames.contains(IMAGERY_TILE_STORE)) {\n                        const store = db.createObjectStore(IMAGERY_TILE_STORE, { keyPath: 'k' });\n                        store.createIndex('timestamp', 't', { unique: false });\n                    }\n\n                    if (!db.objectStoreNames.contains(IMAGERY_ATLAS_STORE)) {\n                        const store = db.createObjectStore(IMAGERY_ATLAS_STORE, { keyPath: 'k' });\n                        store.createIndex('timestamp', 't', { unique: false });\n                    }\n\n                    if (!db.objectStoreNames.contains(IMAGERY_META_STORE)) {\n                        db.createObjectStore(IMAGERY_META_STORE, { keyPath: 'k' });\n                    }\n\n                    // Old elevation rows have no datum metadata and may be\n                    // about 20-100 m wrong depending on geoid undulation.\n                    // Preserve imagery/envelope state, but never seed terrain\n                    // geometry from those ambiguous heights after v2.\n                    if (event.oldVersion > 0 && event.oldVersion < 2\n                        && db.objectStoreNames.contains(ELEVATION_STORE)) {\n                        event.target.transaction.objectStore(ELEVATION_STORE).clear();\n                    }\n                };\n            });\n\n            this.db = db;\n            console.log('[SceneStateStore] Database opened');\n\n            // Run migration if envelope is empty\n            const { migrateIfNeeded } = await import('./scene-state-migration.js');\n            await migrateIfNeeded(this);\n\n            // Load imagery byte counter\n            await this._loadImageryTotalBytes();\n\n            return this.db;\n        })();\n\n        return this._initPromise;\n    }\n\n    // ── Atomic checkpoint ────────────────────────────────────────────\n\n    /**\n     * Write envelope + pending data in one readwrite transaction.\n     * Returns a promise that resolves when the transaction commits.\n     */\n    async writeCheckpoint(envelope, elevationEntries = [], imgTiles = [], imgAtlases = [], imgMeta = []) {\n        if (!this.db) await this.init();\n        if (!this.db) return;\n\n        return this._writeCheckpointTxn(envelope, elevationEntries, imgTiles, imgAtlases, imgMeta);\n    }\n\n    /**\n     * Synchronous-start variant for pagehide / beforeunload.\n     * Opens the transaction on the already-open db synchronously.\n     * The browser is required to complete the IDB readwrite transaction\n     * even if the page is destroyed after this function returns.\n     */\n    writeSyncCheckpoint(envelope, elevationEntries = [], imgTiles = [], imgAtlases = [], imgMeta = []) {\n        if (!this.db) return;\n        this._writeCheckpointTxn(envelope, elevationEntries, imgTiles, imgAtlases, imgMeta);\n        // Intentionally not awaited — the transaction is live and will commit.\n    }\n\n    _writeCheckpointTxn(envelope, elevationEntries, imgTiles, imgAtlases, imgMeta) {\n        const dedupedElevationEntries = this._dedupeElevationEntries(elevationEntries);\n        const stores = [ENVELOPE_STORE];\n        if (dedupedElevationEntries.length > 0) stores.push(ELEVATION_STORE);\n        if (imgTiles.length > 0) stores.push(IMAGERY_TILE_STORE);\n        if (imgAtlases.length > 0) stores.push(IMAGERY_ATLAS_STORE);\n        if (imgMeta.length > 0) stores.push(IMAGERY_META_STORE);\n\n        return new Promise((resolve, reject) => {\n            const txn = this.db.transaction(stores, 'readwrite');\n\n            txn.oncomplete = () => resolve();\n            txn.onerror = () => reject(txn.error);\n            txn.onabort = () => reject(txn.error || new Error('Transaction aborted'));\n\n            // Envelope\n            const envStore = txn.objectStore(ENVELOPE_STORE);\n            envStore.put(envelope);\n\n            // Elevation\n            if (dedupedElevationEntries.length > 0) {\n                const now = Date.now();\n                const elStore = txn.objectStore(ELEVATION_STORE);\n                for (const entry of dedupedElevationEntries) {\n                    const decorated = decorateElevationEntry(entry, now);\n                    if (decorated) elStore.put(decorated);\n                }\n            }\n\n            // Imagery tiles\n            if (imgTiles.length > 0) {\n                const tStore = txn.objectStore(IMAGERY_TILE_STORE);\n                for (const entry of imgTiles) {\n                    if (entry?.k) tStore.put(entry);\n                }\n            }\n\n            // Imagery atlases\n            if (imgAtlases.length > 0) {\n                const aStore = txn.objectStore(IMAGERY_ATLAS_STORE);\n                for (const entry of imgAtlases) {\n                    if (entry?.k) aStore.put(entry);\n                }\n            }\n\n            // Imagery meta\n            if (imgMeta.length > 0) {\n                const mStore = txn.objectStore(IMAGERY_META_STORE);\n                for (const entry of imgMeta) {\n                    if (entry?.k) mStore.put(entry);\n                }\n            }\n        });\n    }\n\n    // ── Envelope ─────────────────────────────────────────────────────\n\n    async readEnvelope() {\n        if (!this.db) await this.init();\n        if (!this.db) return null;\n\n        return new Promise((resolve, reject) => {\n            const txn = this.db.transaction([ENVELOPE_STORE], 'readonly');\n            const store = txn.objectStore(ENVELOPE_STORE);\n            const request = store.get('current');\n            request.onsuccess = () => resolve(request.result || null);\n            request.onerror = () => reject(request.error);\n        });\n    }\n\n    // ── Elevation reads ──────────────────────────────────────────────\n\n    getBucketForLatLon(latDeg, lonDeg, bucketDeg) {\n        return getBucketForLatLon(latDeg, lonDeg, bucketDeg);\n    }\n\n    _dedupeElevationEntries(entries) {\n        if (!Array.isArray(entries) || entries.length === 0) return [];\n        const byKey = new Map();\n        for (const entry of entries) {\n            if (!entry?.k || !Number.isFinite(entry?.e)) continue;\n            const key = entry.k;\n            byKey.set(key, {\n                k: key,\n                e: Math.round(entry.e),\n                l: Number.isFinite(entry.l)\n                    ? Math.max(0, Math.floor(entry.l))\n                    : (Number.isFinite(entry.t) ? Math.max(0, Math.floor(entry.t)) : 0)\n            });\n        }\n        return Array.from(byKey.values());\n    }\n\n    async readElevationByKeys(keys) {\n        if (!keys || keys.length === 0) return [];\n        if (!this.db) await this.init();\n        if (!this.db) return [];\n\n        const uniqueKeys = [];\n        const seen = new Set();\n        for (const key of keys) {\n            if (typeof key !== 'string' || !key) continue;\n            if (seen.has(key)) continue;\n            seen.add(key);\n            uniqueKeys.push(key);\n        }\n        if (!uniqueKeys.length) return [];\n\n        return new Promise((resolve, reject) => {\n            const results = [];\n            const txn = this.db.transaction([ELEVATION_STORE], 'readonly');\n            const store = txn.objectStore(ELEVATION_STORE);\n            let completed = 0;\n\n            for (const key of uniqueKeys) {\n                const request = store.get(key);\n                request.onsuccess = () => {\n                    if (request.result) results.push(request.result);\n                    completed++;\n                    if (completed === uniqueKeys.length) resolve(results);\n                };\n                request.onerror = () => {\n                    completed++;\n                    if (completed === uniqueKeys.length) resolve(results);\n                };\n            }\n        });\n    }\n\n    async readElevationAll(maxEntries = ELEVATION_MAX_ENTRIES) {\n        if (!this.db) await this.init();\n        if (!this.db) return [];\n\n        return new Promise((resolve, reject) => {\n            const entries = [];\n            const txn = this.db.transaction([ELEVATION_STORE], 'readonly');\n            const store = txn.objectStore(ELEVATION_STORE);\n            const request = store.indexNames.contains('timestamp')\n                ? store.index('timestamp').openCursor(null, 'prev')\n                : store.openCursor();\n\n            request.onsuccess = (event) => {\n                const cursor = event.target.result;\n                if (cursor && entries.length < maxEntries) {\n                    entries.push({\n                        k: cursor.value.k,\n                        e: cursor.value.e,\n                        t: cursor.value.l || 0\n                    });\n                    cursor.continue();\n                } else {\n                    resolve(entries);\n                }\n            };\n            request.onerror = () => reject(request.error);\n        });\n    }\n\n    async readElevationNearby(latDeg, lonDeg, {\n        bucketRadius = 2,\n        maxEntries = 12000,\n        bucketDeg = DEFAULT_BUCKET_DEG\n    } = {}) {\n        if (!Number.isFinite(latDeg) || !Number.isFinite(lonDeg)) {\n            return this.readElevationAll(maxEntries);\n        }\n        if (!this.db) await this.init();\n        if (!this.db) return [];\n\n        const step = Math.max(0.25, Number.isFinite(bucketDeg) ? bucketDeg : DEFAULT_BUCKET_DEG);\n        const clampedLat = Math.max(-89.999999, Math.min(89.999999, latDeg));\n        const normalizedLon = normalizeLon(lonDeg);\n        if (!Number.isFinite(normalizedLon)) return [];\n\n        const latBucketCount = Math.max(1, Math.ceil(180 / step));\n        const lonBucketCount = Math.max(1, Math.ceil(360 / step));\n        const centerLat = Math.floor((clampedLat + 90) / step);\n        const centerLon = Math.floor((normalizedLon + 180) / step);\n        const radius = Math.max(0, Math.floor(bucketRadius));\n        const hardMax = Math.max(1, Math.floor(maxEntries));\n\n        const candidates = [];\n        for (let dLat = -radius; dLat <= radius; dLat += 1) {\n            const latIndex = centerLat + dLat;\n            if (latIndex < 0 || latIndex >= latBucketCount) continue;\n            for (let dLon = -radius; dLon <= radius; dLon += 1) {\n                const rawLon = centerLon + dLon;\n                const lonIndex = ((rawLon % lonBucketCount) + lonBucketCount) % lonBucketCount;\n                candidates.push({\n                    key: `${step}:${latIndex}:${lonIndex}`,\n                    ring: Math.max(Math.abs(dLat), Math.abs(dLon))\n                });\n            }\n        }\n        candidates.sort((a, b) => a.ring - b.ring);\n\n        const byKey = new Map();\n        for (const bucket of candidates) {\n            if (byKey.size >= hardMax) break;\n            const remaining = hardMax - byKey.size;\n            const bucketEntries = await this._readElevationBucket(bucket.key, remaining);\n            for (const value of bucketEntries) {\n                if (!value?.k) continue;\n                if (byKey.has(value.k)) continue;\n                byKey.set(value.k, value);\n                if (byKey.size >= hardMax) break;\n            }\n        }\n\n        const sorted = Array.from(byKey.values())\n            .sort((a, b) => (Number(b?.t) || 0) - (Number(a?.t) || 0))\n            .slice(0, hardMax);\n        return sorted.map((entry) => ({\n            k: entry.k,\n            e: entry.e,\n            t: entry.l || 0\n        }));\n    }\n\n    async _readElevationBucket(bucketKey, maxEntries = ELEVATION_MAX_ENTRIES) {\n        if (!this.db) return [];\n        return new Promise((resolve, reject) => {\n            const entries = [];\n            const txn = this.db.transaction([ELEVATION_STORE], 'readonly');\n            const store = txn.objectStore(ELEVATION_STORE);\n            if (!store.indexNames.contains('bucket')) {\n                resolve(entries);\n                return;\n            }\n            const index = store.index('bucket');\n            const request = index.openCursor(IDBKeyRange.only(bucketKey));\n\n            request.onsuccess = (event) => {\n                const cursor = event.target.result;\n                if (cursor && entries.length < maxEntries) {\n                    entries.push(cursor.value);\n                    cursor.continue();\n                } else {\n                    resolve(entries);\n                }\n            };\n            request.onerror = () => reject(request.error);\n        });\n    }\n\n    // ── Elevation writes (incremental, outside checkpoint) ───────────\n\n    async writeElevationBatch(entries) {\n        if (!entries || entries.length === 0) return;\n        if (!this.db) await this.init();\n        if (!this.db) return;\n\n        const dedupedEntries = this._dedupeElevationEntries(entries);\n        if (!dedupedEntries.length) return;\n        const now = Date.now();\n        return new Promise((resolve, reject) => {\n            const txn = this.db.transaction([ELEVATION_STORE], 'readwrite');\n            const store = txn.objectStore(ELEVATION_STORE);\n            txn.oncomplete = () => resolve();\n            txn.onerror = () => reject(txn.error);\n\n            for (const entry of dedupedEntries) {\n                const decorated = decorateElevationEntry(entry, now);\n                if (decorated) store.put(decorated);\n            }\n        });\n    }\n\n    async getElevationCount() {\n        if (!this.db) await this.init();\n        if (!this.db) return 0;\n        return this._countStore(ELEVATION_STORE);\n    }\n\n    async pruneElevation(maxEntries = ELEVATION_MAX_ENTRIES) {\n        const count = await this.getElevationCount();\n        if (count <= maxEntries) return 0;\n        return this._pruneStoreOldest(ELEVATION_STORE, Math.max(ELEVATION_PRUNE_BATCH, count - maxEntries));\n    }\n\n    // ── Imagery reads ────────────────────────────────────────────────\n\n    async readImageryTile(key) {\n        if (!key) return null;\n        return this._getFromStore(IMAGERY_TILE_STORE, key);\n    }\n\n    async readImageryAtlas(key) {\n        if (!key) return null;\n        return this._getFromStore(IMAGERY_ATLAS_STORE, key);\n    }\n\n    async readImageryMeta(key) {\n        if (!key) return null;\n        if (!this.db) await this.init();\n        if (!this.db) return null;\n        return new Promise((resolve, reject) => {\n            const txn = this.db.transaction([IMAGERY_META_STORE], 'readonly');\n            const store = txn.objectStore(IMAGERY_META_STORE);\n            const request = store.get(key);\n            request.onsuccess = () => resolve(request.result?.v ?? null);\n            request.onerror = () => reject(request.error);\n        });\n    }\n\n    // ── Imagery writes (incremental, outside checkpoint) ─────────────\n\n    async writeImageryTileBatch(entries) {\n        if (!entries || entries.length === 0) return;\n        if (!this.db) await this.init();\n        if (!this.db) return;\n\n        const now = Date.now();\n        return new Promise((resolve, reject) => {\n            const txn = this.db.transaction([IMAGERY_TILE_STORE], 'readwrite');\n            const store = txn.objectStore(IMAGERY_TILE_STORE);\n            txn.oncomplete = () => resolve();\n            txn.onerror = () => reject(txn.error);\n\n            for (const entry of entries) {\n                if (!entry?.k) continue;\n                if (!Number.isFinite(entry.t)) entry.t = now;\n                if (!Number.isFinite(entry.s) && entry.b) entry.s = entry.b.size || 0;\n                store.put(entry);\n            }\n        });\n    }\n\n    async writeImageryAtlasBatch(entries) {\n        if (!entries || entries.length === 0) return;\n        if (!this.db) await this.init();\n        if (!this.db) return;\n\n        const now = Date.now();\n        return new Promise((resolve, reject) => {\n            const txn = this.db.transaction([IMAGERY_ATLAS_STORE], 'readwrite');\n            const store = txn.objectStore(IMAGERY_ATLAS_STORE);\n            txn.oncomplete = () => resolve();\n            txn.onerror = () => reject(txn.error);\n\n            for (const entry of entries) {\n                if (!entry?.k) continue;\n                if (!Number.isFinite(entry.t)) entry.t = now;\n                if (!Number.isFinite(entry.s) && entry.b) entry.s = entry.b.size || 0;\n                store.put(entry);\n            }\n        });\n    }\n\n    async writeImageryMeta(key, value) {\n        if (!key) return;\n        if (!this.db) await this.init();\n        if (!this.db) return;\n        return new Promise((resolve, reject) => {\n            const txn = this.db.transaction([IMAGERY_META_STORE], 'readwrite');\n            const store = txn.objectStore(IMAGERY_META_STORE);\n            const request = store.put({ k: key, v: value });\n            request.onsuccess = () => resolve();\n            request.onerror = () => reject(request.error);\n        });\n    }\n\n    async pruneImagery(maxBytes = IMAGERY_DEFAULT_MAX_BYTES, maxEntries = IMAGERY_DEFAULT_MAX_ENTRIES) {\n        if (!this.db) await this.init();\n        if (!this.db) return;\n\n        if (!Number.isFinite(this._imageryTotalBytes)) {\n            this._imageryTotalBytes = await this._recountImageryBytes();\n        }\n        let count = await this._getImageryCount();\n\n        while (this._imageryTotalBytes > maxBytes || count > maxEntries) {\n            const toDeleteByCount = count > maxEntries ? Math.max(1, count - maxEntries) : 1;\n            const overBytes = Math.max(0, this._imageryTotalBytes - maxBytes);\n            const avgBytes = count > 0 ? (this._imageryTotalBytes / count) : 0;\n            const toDeleteByBytes = (avgBytes > 0 && overBytes > 0)\n                ? Math.max(1, Math.ceil(overBytes / avgBytes))\n                : 1;\n            const deleteTarget = Math.max(toDeleteByCount, toDeleteByBytes);\n            const deleted = await this._pruneImageryOldest(Math.min(IMAGERY_PRUNE_BATCH, deleteTarget));\n            if (!deleted) break;\n            count = Math.max(0, count - deleted);\n        }\n        await this.writeImageryMeta('totalBytes', this._imageryTotalBytes);\n    }\n\n    // ── Stats ────────────────────────────────────────────────────────\n\n    getStats() {\n        return {\n            ready: !!this.db,\n            imageryTotalBytes: this._imageryTotalBytes,\n            imageryMaxBytes: this.imageryMaxBytes,\n            imageryMaxEntries: this.imageryMaxEntries,\n            elevationMaxEntries: this.elevationMaxEntries\n        };\n    }\n\n    // ── Lifecycle ────────────────────────────────────────────────────\n\n    close() {\n        if (this.db) {\n            this.db.close();\n            this.db = null;\n        }\n        this._initPromise = null;\n        this._imageryTotalBytes = null;\n    }\n\n    // ── Internal helpers ─────────────────────────────────────────────\n\n    async _getFromStore(storeName, key) {\n        if (!this.db) await this.init();\n        if (!this.db) return null;\n        return new Promise((resolve, reject) => {\n            const txn = this.db.transaction([storeName], 'readonly');\n            const store = txn.objectStore(storeName);\n            const request = store.get(key);\n            request.onsuccess = () => resolve(request.result || null);\n            request.onerror = () => reject(request.error);\n        });\n    }\n\n    async _countStore(storeName) {\n        if (!this.db) return 0;\n        return new Promise((resolve, reject) => {\n            const txn = this.db.transaction([storeName], 'readonly');\n            const store = txn.objectStore(storeName);\n            const request = store.count();\n            request.onsuccess = () => resolve(request.result || 0);\n            request.onerror = () => reject(request.error);\n        });\n    }\n\n    async _pruneStoreOldest(storeName, maxDeletes) {\n        if (!this.db || !Number.isFinite(maxDeletes) || maxDeletes <= 0) return 0;\n        return new Promise((resolve, reject) => {\n            const txn = this.db.transaction([storeName], 'readwrite');\n            const store = txn.objectStore(storeName);\n            const index = store.index('timestamp');\n            let deleted = 0;\n            const request = index.openCursor();\n\n            request.onsuccess = (event) => {\n                const cursor = event.target.result;\n                if (cursor && deleted < maxDeletes) {\n                    cursor.delete();\n                    deleted++;\n                    cursor.continue();\n                } else {\n                    resolve(deleted);\n                }\n            };\n            request.onerror = () => reject(request.error);\n        });\n    }\n\n    async _loadImageryTotalBytes() {\n        const stored = await this.readImageryMeta('totalBytes');\n        if (Number.isFinite(stored)) {\n            this._imageryTotalBytes = stored;\n            return;\n        }\n        this._imageryTotalBytes = await this._recountImageryBytes();\n        await this.writeImageryMeta('totalBytes', this._imageryTotalBytes);\n    }\n\n    async _recountImageryBytes() {\n        const [tileBytes, atlasBytes] = await Promise.all([\n            this._sumStoreBytes(IMAGERY_TILE_STORE),\n            this._sumStoreBytes(IMAGERY_ATLAS_STORE)\n        ]);\n        return tileBytes + atlasBytes;\n    }\n\n    async _sumStoreBytes(storeName) {\n        if (!this.db) return 0;\n        return new Promise((resolve, reject) => {\n            let total = 0;\n            const txn = this.db.transaction([storeName], 'readonly');\n            const store = txn.objectStore(storeName);\n            const request = store.openCursor();\n\n            request.onsuccess = (event) => {\n                const cursor = event.target.result;\n                if (cursor) {\n                    total += cursor.value?.s || 0;\n                    cursor.continue();\n                } else {\n                    resolve(total);\n                }\n            };\n            request.onerror = () => reject(request.error);\n        });\n    }\n\n    async _getImageryCount() {\n        const [tileCount, atlasCount] = await Promise.all([\n            this._countStore(IMAGERY_TILE_STORE),\n            this._countStore(IMAGERY_ATLAS_STORE)\n        ]);\n        return tileCount + atlasCount;\n    }\n\n    async _pruneImageryOldest(maxDeletes) {\n        if (!this.db || maxDeletes <= 0) return 0;\n\n        const [tileCandidates, atlasCandidates] = await Promise.all([\n            this._collectOldestEntries(IMAGERY_TILE_STORE, maxDeletes),\n            this._collectOldestEntries(IMAGERY_ATLAS_STORE, maxDeletes)\n        ]);\n        const candidates = [...tileCandidates, ...atlasCandidates]\n            .sort((a, b) => a.timestamp - b.timestamp)\n            .slice(0, maxDeletes);\n        if (!candidates.length) return 0;\n\n        await this._deleteEntries(candidates);\n\n        if (Number.isFinite(this._imageryTotalBytes)) {\n            let deletedBytes = 0;\n            for (const entry of candidates) {\n                deletedBytes += Number.isFinite(entry?.size) ? entry.size : 0;\n            }\n            this._imageryTotalBytes = Math.max(0, this._imageryTotalBytes - deletedBytes);\n        }\n        return candidates.length;\n    }\n\n    async _collectOldestEntries(storeName, maxEntries) {\n        if (!this.db || maxEntries <= 0) return [];\n        return new Promise((resolve, reject) => {\n            const out = [];\n            const txn = this.db.transaction([storeName], 'readonly');\n            const store = txn.objectStore(storeName);\n            const index = store.index('timestamp');\n            const request = index.openCursor();\n\n            request.onsuccess = (event) => {\n                const cursor = event.target.result;\n                if (cursor && out.length < maxEntries) {\n                    out.push({\n                        storeName,\n                        key: cursor.primaryKey,\n                        size: Number.isFinite(cursor.value?.s) ? cursor.value.s : 0,\n                        timestamp: Number.isFinite(cursor.value?.t) ? cursor.value.t : 0\n                    });\n                    cursor.continue();\n                } else {\n                    resolve(out);\n                }\n            };\n            request.onerror = () => reject(request.error);\n        });\n    }\n\n    async _deleteEntries(entries) {\n        const storeSet = new Set(entries.map((e) => e?.storeName).filter(Boolean));\n        const stores = Array.from(storeSet);\n        if (!stores.length) return;\n\n        return new Promise((resolve, reject) => {\n            const txn = this.db.transaction(stores, 'readwrite');\n            txn.oncomplete = () => resolve();\n            txn.onerror = () => reject(txn.error);\n\n            const storesByName = new Map();\n            for (const name of stores) {\n                storesByName.set(name, txn.objectStore(name));\n            }\n            for (const entry of entries) {\n                const store = storesByName.get(entry?.storeName);\n                if (store) store.delete(entry.key);\n            }\n        });\n    }\n}\n\n// ── Singleton ────────────────────────────────────────────────────────\n\nlet instance = null;\n\nfunction getSceneStateStore() {\n    if (!instance) {\n        instance = new SceneStateStore();\n    }\n    return instance;\n}\n\nexport {\n    SceneStateStore,\n    getSceneStateStore,\n    getBucketForLatLon,\n    normalizeLon,\n    parseLatLonFromKey,\n    decorateElevationEntry,\n    ENVELOPE_STORE,\n    ELEVATION_STORE,\n    IMAGERY_TILE_STORE,\n    IMAGERY_ATLAS_STORE,\n    IMAGERY_META_STORE,\n    ALL_STORES,\n    DB_NAME,\n    DB_VERSION\n};\n","/**\n * Elevation data fetching client with FOV-aware batching and metering\n */\n\nimport * as THREE from 'three';\nimport { PLANET_RADIUS, DEG2RAD, RAD2DEG, MAX_TILE_LEVEL } from './constants.js';\nimport { dirToLatLonLocal, latLonToLocalDir, ellipsoidRadiusForLocalDir } from './geometry-utils.js';\nimport { getTransportManager, initTransport, TransportEvent } from '../refactor/transport/index.js';\nimport { SceneStateStore, getSceneStateStore, getBucketForLatLon } from './scene-state-store.js';\nimport {\n    getElevationApiBase,\n    getElevationWsUrl,\n    getElevationFallbackEnabled,\n    hasBackendOverride,\n    hasElevationOverride,\n    isLocalRuntime\n} from '../refactor/shared/backend.js';\nimport {\n    MAPZEN_GEOTIFF_TEMPLATE,\n    MapzenElevationTileSource,\n    resolveMapzenSourceZoomForTriangle\n} from '../refactor/imagery/MapzenElevationTileSource.js';\n\nconst OPEN_METEO_FALLBACK_URL = 'https://api.open-meteo.com/v1/elevation';\nconst OPEN_METEO_MAX_POINTS = 100;\nconst EPQS_FALLBACK_URL = 'https://epqs.nationalmap.gov/v1/json';\nconst GMRT_FALLBACK_URL = 'https://www.gmrt.org/services/PointServer';\nconst OPEN_TOPO_FALLBACK_ENV_KEY = 'VITE_OPEN_TOPO_FALLBACK_URL';\nconst OPEN_TOPO_FALLBACK_URL = (() => {\n    if (typeof import.meta !== 'undefined' && import.meta.env && import.meta.env[OPEN_TOPO_FALLBACK_ENV_KEY]) {\n        const raw = String(import.meta.env[OPEN_TOPO_FALLBACK_ENV_KEY]).trim();\n        if (raw) return raw;\n    }\n    return 'https://api.opentopodata.org/v1/mapzen';\n})();\n\nfunction _buildOpenTopoUrl(base, locations) {\n    if (!Array.isArray(locations) || !locations.length) return null;\n    const locParam = locations\n        .map((loc) => `${Number(loc.lat).toFixed(6)},${Number(loc.lng).toFixed(6)}`)\n        .join('|');\n    return `${base}?locations=${encodeURIComponent(locParam)}`;\n}\nconst OPEN_TOPO_MAX_POINTS = 100;\n\nexport class ElevationClient {\n    constructor() {\n        this.mc = null;\n        this.enableNkn = true; // NKN elevation path retired for now; backend WSS is primary.\n        this.relayDest = '';\n        this.dataset = 'mapzen';\n        this.enableMapzenRasterTiles = false;\n        this._mapzenRasterTileSource = new MapzenElevationTileSource({\n            urlTemplate: MAPZEN_GEOTIFF_TEMPLATE,\n            zoom: 14,\n            maxConcurrentTiles: 4\n        });\n        this._mapzenMinRequestedZoom = Infinity;\n        this._mapzenMaxRequestedZoom = -Infinity;\n\n        this.vertexMap = new Map();\n        this.tileVertexKeys = new WeakMap(); // Track vertex keys per tile for fast pruning\n        this.cameraPos = new THREE.Vector3();\n        this.cameraDir = new THREE.Vector3(0, 0, -1);\n        this.cameraFovRad = 45 * DEG2RAD;\n        this.planetGroup = null; // Reference to planet group for coordinate transform\n        this.lastFocusLatLon = null;\n        this.activeTilePriorities = new Map();\n        this._activeTileEntries = [];\n        this._activeTileEntriesScratch = [];\n        this._activeCandidatesScratch = [];\n        this._inView = [];\n        this._offView = [];\n        this._forcedInView = [];\n        this._normalInView = [];\n        this._forcedOffView = [];\n        this._normalOffView = [];\n        this._inViewNear = [];\n        this._inViewMid = [];\n        this._inViewFar = [];\n        this._pickedScratch = new Set();\n\n        // Fetch tuning (aggressive defaults for rapid elevation delivery)\n        this.targetMaxLevel = null;\n        this.fullFetchMaxLevel = -1;\n        this.strictFullFetch = false;\n        this.fullFetchMinLevel = 10;\n\n        this.maxConcurrentBatches = 512;\n        this.currentBatches = 0;\n        this.batchSize = 1024;\n        this.minIntervalMs = 25;\n        this.angleLimitDeg = 80;      // limit off-axis vertices considered\n        this.surfaceMinLevel = 6;     // minimum tile level to fetch when near surface\n        this.viewshedMinDeg = 0.5;    // minimum angular radius to fetch around user\n        this.viewshedMarginDeg = 0.5; // extra angle beyond horizon for prefetch\n        this.lastScheduleTime = 0;\n        this.debugLogLocations = false;\n        this.debugLogStats = false;\n        this.debugLogBatchSampleLimit = 0; // 0 = log all samples in batch\n        this._lastResponseLogMs = 0;\n        this._responseLogIntervalMs = 2000;\n        this._lastNoMatchLogMs = 0;\n        this._noMatchLogIntervalMs = 5000;\n        this._lastResponseDiagLogMs = 0;\n        this._responseDiagLogIntervalMs = 5000;\n        this._lastBackendTransitionLogMs = 0;\n        this._backendTransitionLogIntervalMs = 5000;\n\n        this.maxKBPerMinute = 0; // 0 = unlimited\n        this.maxChunkBytes = 65536; // 64 KiB per response chunk\n        this.maxRequestBytes = 524288; // 512 KiB cap for outbound requests\n        this.windowMs = 60_000;\n        this.sendEvents = [];\n        this._textEncoder = new TextEncoder();\n        this._onNknSendError = null;\n        this._nknBlockedUntilMs = 0;\n        this._nknFailureCount = 0;\n        this._nknBackoffBaseMs = 800;\n        this._nknBackoffMaxMs = 15000;\n        this.transport = null;\n        this._transportInitPromise = null;\n        this._backendFailureCount = 0;\n        this._backendFailureLimit = 3;\n        this._backendBlockedUntilMs = 0;\n        this._backendBackoffMs = 15000;\n        this._backendTimeoutMs = 15000;\n        this.pendingTimeoutMs = 12000;\n        this.pendingRecoveryIntervalMs = 750;\n        this.pendingRecoveryMaxPerTick = 4096;\n        this._lastPendingRecoveryMs = 0;\n        this._pendingRecoveryCount = 0;\n        this._lastPendingRecoveryLogMs = 0;\n        this._pendingRecoveryLogIntervalMs = 3000;\n        this._transportResetCooldownMs = 5000;\n        this._lastTransportResetMs = 0;\n        this._connectCooldownUntilMs = 0;\n        this._connectFailureCount = 0;\n        this._connectInFlight = null;\n        this.enableFallbacks = getElevationFallbackEnabled();\n        this.fallbackOnBackendError = this.enableFallbacks;\n        this.enableOpenMeteoFallback = true;\n        this.enableEpqsFallback = true;\n        this.enableGmrtFallback = true;\n        this.enableOpenTopoFallback = true;\n        this.preferDirectFallbacks = true;\n        this._fallbackFailureLimit = 6;\n        this._fallbackBackoffBaseMs = 15000;\n        this._fallbackBackoffMaxMs = 5 * 60 * 1000;\n        this._fallbackConcurrency = 2;\n        this._fallbackState = {\n            'open-meteo': { failures: 0, nextRetryAt: 0 },\n            epqs: { failures: 0, nextRetryAt: 0 },\n            gmrt: { failures: 0, nextRetryAt: 0 },\n            'open-topo': { failures: 0, nextRetryAt: 0 }\n        };\n        this._fallbackRateLimits = {\n            'open-meteo': {\n                perMinute: 600,\n                perHour: 5000,\n                perDay: 10000,\n                minIntervalMs: 100\n            },\n            epqs: {\n                perMinute: 60,\n                perHour: 1000,\n                minIntervalMs: 1000\n            },\n            gmrt: {\n                perMinute: 60,\n                perHour: 1000,\n                minIntervalMs: 1000\n            },\n            'open-topo': {\n                perMinute: 60,\n                perHour: 1000,\n                minIntervalMs: 1000\n            }\n        };\n        this._fallbackRateState = {};\n        this._fallbackRateQueue = {};\n\n        this.stats = {\n            requestCount: 0,\n            pointsRequested: 0,\n            bytesOut: 0,\n            responseCount: 0,\n            pointsReceived: 0,\n            bytesIn: 0,\n            cacheLookupCount: 0,\n            cacheLookupHits: 0,\n            persistentImportedCount: 0,\n            persistentNearbyImportedCount: 0\n        };\n\n        this.maxVertexRecords = 800000;\n        this._memoryBudgetBaseline = this.maxVertexRecords;\n        this._memoryPressure = 0;\n        this.vertexPressureEvictRatio = 0.03;\n        this.vertexPressureActiveEvictRatio = 0.01;\n        this._lastVertexCapLogMs = 0;\n        this._vertexCapLogIntervalMs = 2000;\n        this._evictionHighWaterMark = 0.90; // start proactive eviction at 90% capacity\n        this._evictionBudgetMs = 2;         // max ms per tick for eviction work\n        this._evictionTargetFreeRatio = 0.05; // free 5% of capacity per eviction pass\n        this.sampleStrideMultiplier = 1;\n        this.sampleStrideBaseByLevel = {\n            0: 1, 1: 1, 2: 1, 3: 1, 4: 1, 5: 1, 6: 1,\n            7: 1, 8: 1, 9: 1, 10: 1,\n            11: 2, 12: 2, 13: 2, 14: 2,\n            15: 2, 16: 2, 17: 2, 18: 2\n        };\n        this.sampleStrideByLevel = { ...this.sampleStrideBaseByLevel };\n\n        this.retryBaseDelayMs = 500;\n        this.retryMaxDelayMs = 10000;\n\n        // Track camera position for cache invalidation\n        this.lastCameraPos = new THREE.Vector3();\n        this.cacheInvalidationDistanceM = 1_000_000; // Clear cache if camera moves >1000km\n\n        // Distance rings for surface bias (meters)\n        // Expanded to ensure surrounding tiles get elevation data beyond the underfoot patch.\n        this.ringNearMeters = 20_000;  // 0-20km near ring\n        this.ringMidMeters = 80_000;   // 20-80km mid ring\n        this.ringLodCaps = {\n            near: MAX_TILE_LEVEL,\n            mid: Math.max(0, MAX_TILE_LEVEL - 2),\n            far: Math.max(0, MAX_TILE_LEVEL - 4)\n        };\n        this.ringPriorityWeights = { near: 1.0, mid: 0.8, far: 0.6 };\n        this.ringBudgetWeights = { near: 0.5, mid: 0.30, far: 0.20 };\n        this.ringStrideMultiplier = { near: 1, mid: 1, far: 2 };\n\n        // Active tile scan throttles (performance tuning)\n        this.activeTileScanMax = 512;\n        this.activeTileScanPerTile = 512;\n        this.activeCandidateMax = 8192;\n        this.activeCandidateCacheMs = 100;\n        this._activeCandidateCache = null;\n        this._activeTileKeyCache = new WeakMap();\n        this.activeTileScanMaxBase = this.activeTileScanMax;\n        this.activeCandidateMaxBase = this.activeCandidateMax;\n        this._activeTileOverflowCursor = 0;\n\n        // IndexedDB cache for persistent storage\n        this._persistentCache = null;\n        this._persistentCacheEnabled = false;\n        this._persistentCacheInitPromise = null;\n        this._cacheSaveTimer = null;\n        this._cacheSaveIntervalMs = 4000; // Save to persistent cache every 4s\n        this._cacheWriteQueue = [];\n        this._cacheWriteQueueMap = new Map();\n        this._cacheWriteFlushTimer = null;\n        this._cacheWriteFlushInFlightPromise = null;\n        this._cacheWriteFlushDelayMs = 400;\n        this._cacheWriteImmediateFlushThreshold = 500;\n        this.persistentNearbyImportEnabled = true;\n        this.persistentNearbyImportBucketRadius = 3;\n        this.persistentNearbyImportMaxEntries = 25000;\n        this._persistentNearbyWarmPromise = null;\n        this._persistentNearbyWarmBucket = null;\n        this._persistentNearbyWarmSignature = null;\n        this.persistentStartupImportMaxEntries = 100000;\n\n        // In-memory cache toggle (disable to prevent reload crashes)\n        this.cacheEnabled = true;\n\n        // Optional water classification; DEM requests retain seabed elevations\n        this._oceanResolver = null;\n        this._hasCameraAnchor = false;\n    }\n\n    setMultiClient(mc) {\n        this.mc = mc;\n    }\n\n    setOceanResolver(resolver) {\n        this._oceanResolver = (typeof resolver === 'function') ? resolver : null;\n    }\n\n    resolveOcean(latDeg, lonDeg, dir, tile, index) {\n        if (!this._oceanResolver) return null;\n        return this._oceanResolver(latDeg, lonDeg, dir, tile, index);\n    }\n\n    _maybeWarmPersistentCacheNearby(camPos) {\n        if (!this.cacheEnabled) return;\n        if (!this._persistentCacheEnabled) return;\n        if (!this.persistentNearbyImportEnabled) return;\n        if (!camPos || typeof camPos.lengthSq !== 'function' || camPos.lengthSq() <= 1e-8) return;\n\n        const dir = camPos.clone().normalize();\n        const { latDeg, lonDeg } = dirToLatLonLocal(dir);\n        this.prewarmPersistentCacheAtLatLon(latDeg, lonDeg).catch((err) => {\n            console.warn('[ElevationClient] Nearby persistent warmup failed:', err);\n        });\n    }\n\n    async prewarmPersistentCacheAtLatLon(latDeg, lonDeg, {\n        bucketRadius = null,\n        maxEntries = null,\n        force = false\n    } = {}) {\n        if (!this.cacheEnabled || !this._persistentCacheEnabled) return { imported: 0, bucket: null };\n        if (!Number.isFinite(latDeg) || !Number.isFinite(lonDeg)) return { imported: 0, bucket: null };\n\n        await this.initPersistentCache();\n        if (!this._persistentCache || typeof this._persistentCache.queryNearby !== 'function') {\n            return { imported: 0, bucket: null };\n        }\n\n        const bucketKey = (typeof this._persistentCache.getBucketForLatLon === 'function')\n            ? this._persistentCache.getBucketForLatLon(latDeg, lonDeg)\n            : `${latDeg.toFixed(1)},${lonDeg.toFixed(1)}`;\n        if (!bucketKey) return { imported: 0, bucket: null };\n        const queryBucketRadius = Number.isFinite(bucketRadius)\n            ? Math.max(0, Math.floor(bucketRadius))\n            : Math.max(0, Math.floor(this.persistentNearbyImportBucketRadius || 0));\n        const queryMaxEntries = Number.isFinite(maxEntries)\n            ? Math.max(500, Math.floor(maxEntries))\n            : Math.max(500, Math.floor(this.persistentNearbyImportMaxEntries || 12000));\n        const querySignature = `${bucketKey}|r${queryBucketRadius}|m${queryMaxEntries}`;\n\n        if (!force &&\n            querySignature === this._persistentNearbyWarmSignature &&\n            !this._persistentNearbyWarmPromise) {\n            return { imported: 0, bucket: bucketKey };\n        }\n        if (this._persistentNearbyWarmPromise) {\n            if (!force && querySignature === this._persistentNearbyWarmSignature) {\n                await this._persistentNearbyWarmPromise.catch(() => {});\n                return { imported: 0, bucket: bucketKey };\n            }\n            await this._persistentNearbyWarmPromise.catch(() => {});\n        }\n\n        this._persistentNearbyWarmBucket = bucketKey;\n        this._persistentNearbyWarmSignature = querySignature;\n\n        this._persistentNearbyWarmPromise = this._persistentCache.queryNearby(latDeg, lonDeg, {\n            bucketRadius: queryBucketRadius,\n            maxEntries: queryMaxEntries\n        }).then((entries) => {\n            if (!Array.isArray(entries) || entries.length === 0) return 0;\n            const imported = this.importCache(entries);\n            if (imported > 0) {\n                this.stats.persistentNearbyImportedCount += imported;\n                if (this.debugLogStats) {\n                    console.log(`[elev] Warmed ${imported} nearby persistent vertices for bucket ${bucketKey}`);\n                }\n            }\n            return imported;\n        }).catch((err) => {\n            if (this._persistentNearbyWarmBucket === bucketKey) {\n                this._persistentNearbyWarmBucket = null;\n                this._persistentNearbyWarmSignature = null;\n            }\n            throw err;\n        }).finally(() => {\n            this._persistentNearbyWarmPromise = null;\n        });\n\n        const imported = await this._persistentNearbyWarmPromise;\n        return { imported, bucket: bucketKey };\n    }\n\n    async prewarmPersistentCacheByKeys(keys, {\n        maxEntries = 120000\n    } = {}) {\n        if (!this.cacheEnabled || !this._persistentCacheEnabled) {\n            return { imported: 0, requested: 0, loaded: 0 };\n        }\n        if (!Array.isArray(keys) || keys.length === 0) {\n            return { imported: 0, requested: 0, loaded: 0 };\n        }\n\n        await this.initPersistentCache();\n        if (!this._persistentCache || typeof this._persistentCache.getMany !== 'function') {\n            return { imported: 0, requested: 0, loaded: 0 };\n        }\n\n        const hardLimit = Number.isFinite(maxEntries)\n            ? Math.max(1, Math.floor(maxEntries))\n            : 120000;\n        const unique = [];\n        const seen = new Set();\n        for (const key of keys) {\n            if (typeof key !== 'string' || !key) continue;\n            if (seen.has(key)) continue;\n            seen.add(key);\n            unique.push(key);\n            if (unique.length >= hardLimit) break;\n        }\n        if (!unique.length) {\n            return { imported: 0, requested: 0, loaded: 0 };\n        }\n\n        const chunkSize = 4000;\n        const loadedEntries = [];\n        for (let i = 0; i < unique.length; i += chunkSize) {\n            const chunk = unique.slice(i, i + chunkSize);\n            const rows = await this._persistentCache.getMany(chunk);\n            if (!rows || !rows.length) continue;\n            for (const row of rows) {\n                if (!row?.k || !Number.isFinite(row?.e)) continue;\n                loadedEntries.push({\n                    k: row.k,\n                    e: row.e,\n                    t: Number.isFinite(row.l) ? row.l : (Number.isFinite(row.t) ? row.t : 0)\n                });\n            }\n        }\n\n        const imported = this.importCache(loadedEntries);\n        if (imported > 0) {\n            this.stats.persistentNearbyImportedCount += imported;\n        }\n        return {\n            imported,\n            requested: unique.length,\n            loaded: loadedEntries.length\n        };\n    }\n\n    /**\n     * Initialize persistent cache and load saved data\n     */\n    async initPersistentCache() {\n        if (!this._persistentCacheEnabled || !this.cacheEnabled) return;\n        if (this._persistentCache) {\n            this._startCacheSaveTimer();\n            return;\n        }\n        if (this._persistentCacheInitPromise) {\n            return this._persistentCacheInitPromise;\n        }\n        this._persistentCacheInitPromise = (async () => {\n            try {\n                const _store = getSceneStateStore();\n                await _store.init();\n                this._persistentCache = {\n                    getBucketForLatLon: (lat, lon) => getBucketForLatLon(lat, lon),\n                    queryNearby: (lat, lon, opts) => _store.readElevationNearby(lat, lon, opts),\n                    getMany: (keys) => _store.readElevationByKeys(keys),\n                    exportAll: (max) => _store.readElevationAll(max),\n                    putMany: (entries) => _store.writeElevationBatch(entries),\n                    flush: () => Promise.resolve(),\n                    close: () => {},\n                    getPendingWriteCount: () => 0,\n                    init: () => Promise.resolve()\n                };\n\n                // Import only recent entries to avoid long startup stalls.\n                const startupImportCap = Number.isFinite(this.persistentStartupImportMaxEntries)\n                    ? Math.max(1000, Math.floor(this.persistentStartupImportMaxEntries))\n                    : 12000;\n                const maxImportEntries = Math.max(1000, Math.min(this.maxVertexRecords, startupImportCap));\n                const entries = await this._persistentCache.exportAll(maxImportEntries);\n                if (entries.length > 0) {\n                    const imported = this.importCache(entries);\n                    this.stats.persistentImportedCount = imported;\n                    console.log(`[ElevationClient] Loaded ${imported} entries from persistent cache`);\n                }\n                if (this._hasCameraAnchor) {\n                    this._maybeWarmPersistentCacheNearby(this.cameraPos);\n                }\n\n                // Start periodic save timer\n                this._startCacheSaveTimer();\n            } catch (err) {\n                console.error('[ElevationClient] Failed to init persistent cache:', err);\n                this._persistentCache = null;\n            } finally {\n                this._persistentCacheInitPromise = null;\n            }\n        })();\n        return this._persistentCacheInitPromise;\n    }\n\n    /**\n     * Start timer to periodically save to persistent cache\n     */\n    _startCacheSaveTimer() {\n        if (this._cacheSaveTimer) return;\n        this._cacheSaveTimer = setInterval(() => {\n            this._flushCacheWrites();\n        }, this._cacheSaveIntervalMs);\n    }\n\n    _stopCacheSaveTimer() {\n        if (!this._cacheSaveTimer) return;\n        clearInterval(this._cacheSaveTimer);\n        this._cacheSaveTimer = null;\n    }\n\n    /**\n     * Queue an entry for persistent cache write\n     */\n    _queueCacheWrite(key, elevation, tileLevel) {\n        if (!this.cacheEnabled || !this._persistentCacheEnabled) return;\n        if (!key) return;\n        const next = {\n            k: key,\n            e: Math.round(elevation),\n            l: Number.isFinite(tileLevel) ? Math.max(0, Math.floor(tileLevel)) : 0\n        };\n        const existing = this._cacheWriteQueueMap.get(key);\n        if (existing) {\n            existing.e = next.e;\n            existing.l = Math.max(existing.l || 0, next.l || 0);\n        } else {\n            this._cacheWriteQueueMap.set(key, next);\n            this._cacheWriteQueue.push(key);\n        }\n\n        // Initialize persistent cache lazily if writes arrive before startup init completes.\n        if (!this._persistentCache && !this._persistentCacheInitPromise) {\n            this.initPersistentCache().catch(() => {});\n        }\n\n        // Always schedule a short-delay flush so reloads don't lose recent writes.\n        if (!this._cacheWriteFlushTimer) {\n            this._cacheWriteFlushTimer = setTimeout(() => {\n                this._cacheWriteFlushTimer = null;\n                this._flushCacheWrites();\n            }, this._cacheWriteFlushDelayMs);\n        }\n\n        // Large queues should flush immediately to avoid long write backlogs.\n        if (this._cacheWriteQueueMap.size >= this._cacheWriteImmediateFlushThreshold) {\n            this._flushCacheWrites();\n        }\n    }\n\n    _takePendingCacheWriteBatch(maxEntries = 500) {\n        const limit = Number.isFinite(maxEntries)\n            ? Math.max(1, Math.floor(maxEntries))\n            : 500;\n        const out = [];\n        while (this._cacheWriteQueue.length > 0 && out.length < limit) {\n            const token = this._cacheWriteQueue.shift();\n            if (!token) continue;\n            if (typeof token === 'string') {\n                const entry = this._cacheWriteQueueMap.get(token);\n                if (!entry) continue;\n                this._cacheWriteQueueMap.delete(token);\n                out.push(entry);\n                continue;\n            }\n            // Backward compatibility for tests/legacy paths that push entry objects directly.\n            if (token?.k && Number.isFinite(token?.e)) {\n                const key = token.k;\n                const normalized = {\n                    k: key,\n                    e: Math.round(token.e),\n                    l: Number.isFinite(token.l) ? Math.max(0, Math.floor(token.l)) : 0\n                };\n                this._cacheWriteQueueMap.delete(key);\n                out.push(normalized);\n            }\n        }\n        return out;\n    }\n\n    _requeuePendingCacheWrites(entries, { front = false } = {}) {\n        if (!Array.isArray(entries) || !entries.length) return 0;\n        let added = 0;\n        for (const entry of entries) {\n            if (!entry?.k || !Number.isFinite(entry?.e)) continue;\n            const key = entry.k;\n            const normalized = {\n                k: key,\n                e: Math.round(entry.e),\n                l: Number.isFinite(entry.l) ? Math.max(0, Math.floor(entry.l)) : 0\n            };\n            const existing = this._cacheWriteQueueMap.get(key);\n            if (existing) {\n                existing.e = normalized.e;\n                existing.l = Math.max(existing.l || 0, normalized.l || 0);\n                continue;\n            }\n            this._cacheWriteQueueMap.set(key, normalized);\n            if (front) {\n                this._cacheWriteQueue.unshift(key);\n            } else {\n                this._cacheWriteQueue.push(key);\n            }\n            added += 1;\n        }\n        return added;\n    }\n\n    drainPendingPersistentWrites(maxEntries = Infinity) {\n        const limit = Number.isFinite(maxEntries)\n            ? Math.max(1, Math.floor(maxEntries))\n            : Number.POSITIVE_INFINITY;\n        const out = [];\n        while (this._cacheWriteQueue.length > 0 && out.length < limit) {\n            const token = this._cacheWriteQueue.shift();\n            if (!token) continue;\n            if (typeof token === 'string') {\n                const entry = this._cacheWriteQueueMap.get(token);\n                if (!entry) continue;\n                this._cacheWriteQueueMap.delete(token);\n                out.push(entry);\n                continue;\n            }\n            if (token?.k && Number.isFinite(token?.e)) {\n                const key = token.k;\n                const normalized = {\n                    k: key,\n                    e: Math.round(token.e),\n                    l: Number.isFinite(token.l) ? Math.max(0, Math.floor(token.l)) : 0\n                };\n                this._cacheWriteQueueMap.delete(key);\n                out.push(normalized);\n            }\n        }\n        return out;\n    }\n\n    requeuePendingPersistentWrites(entries, { front = true } = {}) {\n        return this._requeuePendingCacheWrites(entries, { front });\n    }\n\n    /**\n     * Flush pending writes to persistent cache\n     */\n    async _flushCacheWrites() {\n        if (!this._persistentCache ||\n            (this._cacheWriteQueueMap.size === 0 && this._cacheWriteQueue.length === 0)) return;\n        if (this._cacheWriteFlushInFlightPromise) {\n            return this._cacheWriteFlushInFlightPromise;\n        }\n\n        this._cacheWriteFlushInFlightPromise = (async () => {\n            while (this._persistentCache &&\n                (this._cacheWriteQueueMap.size > 0 || this._cacheWriteQueue.length > 0)) {\n                const batch = this._takePendingCacheWriteBatch(500);\n                if (!batch.length) break;\n                try {\n                    await this._persistentCache.putMany(batch);\n                } catch (err) {\n                    this._requeuePendingCacheWrites(batch, { front: true });\n                    console.error('[ElevationClient] Cache write error:', err);\n                    break;\n                }\n            }\n        })();\n\n        try {\n            await this._cacheWriteFlushInFlightPromise;\n        } finally {\n            this._cacheWriteFlushInFlightPromise = null;\n        }\n    }\n\n    setNknErrorHandler(handler) {\n        this._onNknSendError = (typeof handler === 'function') ? handler : null;\n    }\n\n    isPersistentCacheEnabled() {\n        return !!this._persistentCacheEnabled;\n    }\n\n    setPersistentCacheEnabled(enabled) {\n        const next = !!enabled;\n        if (this._persistentCacheEnabled === next) return;\n        this._persistentCacheEnabled = next;\n        if (!next) {\n            this._stopCacheSaveTimer();\n            this._persistentNearbyWarmPromise = null;\n            this._persistentNearbyWarmBucket = null;\n            this._persistentNearbyWarmSignature = null;\n            return;\n        }\n        if (this.cacheEnabled) {\n            this.initPersistentCache().catch((err) => {\n                console.warn('[ElevationClient] Failed to enable persistent cache:', err);\n            });\n        }\n    }\n\n    isCacheEnabled() {\n        return !!this.cacheEnabled;\n    }\n\n    setCacheEnabled(enabled) {\n        const next = !!enabled;\n        if (this.cacheEnabled === next) return;\n        this.cacheEnabled = next;\n        if (!next) {\n            this._cacheWriteQueue.length = 0;\n            this._cacheWriteQueueMap.clear();\n            if (this._cacheWriteFlushTimer) {\n                clearTimeout(this._cacheWriteFlushTimer);\n                this._cacheWriteFlushTimer = null;\n            }\n            this._persistentNearbyWarmPromise = null;\n            this._persistentNearbyWarmBucket = null;\n            this._persistentNearbyWarmSignature = null;\n            return;\n        }\n        if (this._persistentCacheEnabled) {\n            this.initPersistentCache().catch((err) => {\n                console.warn('[ElevationClient] Failed to initialize cache after enable:', err);\n            });\n        }\n    }\n\n    async flushPersistentCache() {\n        await this._flushCacheWrites();\n        if (this._persistentCache && typeof this._persistentCache.flush === 'function') {\n            await this._persistentCache.flush();\n        }\n    }\n\n    dispose() {\n        this._stopCacheSaveTimer();\n        if (this._cacheWriteFlushTimer) {\n            clearTimeout(this._cacheWriteFlushTimer);\n            this._cacheWriteFlushTimer = null;\n        }\n        this.flushPersistentCache()\n            .catch(() => {})\n            .finally(() => {\n                if (this._persistentCache && typeof this._persistentCache.close === 'function') {\n                    try {\n                        this._persistentCache.close();\n                    } catch {\n                        // ignore close errors\n                    }\n                }\n                this._persistentCache = null;\n                this._persistentCacheInitPromise = null;\n                this._persistentNearbyWarmPromise = null;\n                this._persistentNearbyWarmBucket = null;\n                this._persistentNearbyWarmSignature = null;\n                this._cacheWriteQueue.length = 0;\n                this._cacheWriteQueueMap.clear();\n            });\n    }\n\n    setRelayAndDataset(relay, dataset) {\n        this.relayDest = (relay || '').trim();\n        this.dataset = (dataset || 'mapzen').trim();\n    }\n\n    _normalizeRingBudgetWeights(weights, fallback = this.ringBudgetWeights) {\n        const base = fallback && typeof fallback === 'object'\n            ? fallback\n            : { near: 0.6, mid: 0.25, far: 0.15 };\n        const input = weights && typeof weights === 'object' ? weights : null;\n\n        const nearRaw = Number.isFinite(input?.near) ? input.near : base.near;\n        const midRaw = Number.isFinite(input?.mid) ? input.mid : base.mid;\n        const farRaw = Number.isFinite(input?.far) ? input.far : base.far;\n\n        let near = Math.max(0, nearRaw);\n        let mid = Math.max(0, midRaw);\n        let far = Math.max(0, farRaw);\n\n        let sum = near + mid + far;\n        if (!(sum > 0)) {\n            return { ...base };\n        }\n\n        near /= sum;\n        mid /= sum;\n        far /= sum;\n        if (far < 0.05) {\n            const deficit = 0.05 - far;\n            const total = near + mid;\n            if (total > 0) {\n                near = Math.max(0, near - deficit * (near / total));\n                mid = Math.max(0, mid - deficit * (mid / total));\n            }\n            far = 0.05;\n            sum = near + mid + far;\n            if (sum > 0) {\n                near /= sum;\n                mid /= sum;\n                far /= sum;\n            }\n        }\n\n        return { near, mid, far };\n    }\n\n    _normalizeRingStrideMultiplier(strides, fallback = this.ringStrideMultiplier) {\n        const base = fallback && typeof fallback === 'object'\n            ? fallback\n            : { near: 1, mid: 2, far: 4 };\n        const input = strides && typeof strides === 'object' ? strides : null;\n        const clampStride = (value, fallbackValue) => {\n            if (!Number.isFinite(value)) return Math.max(1, Math.floor(fallbackValue || 1));\n            return Math.max(1, Math.floor(value));\n        };\n        const near = clampStride(input?.near, base.near);\n        const mid = Math.max(near, clampStride(input?.mid, base.mid));\n        const far = Math.max(mid, clampStride(input?.far, base.far));\n        return { near, mid, far };\n    }\n\n    getSchedulingProfile() {\n        return {\n            ringBudgetWeights: { ...this.ringBudgetWeights },\n            ringStrideMultiplier: { ...this.ringStrideMultiplier },\n            sampleStrideMultiplier: this.sampleStrideMultiplier\n        };\n    }\n\n    setSchedulingProfile({\n        ringBudgetWeights,\n        ringStrideMultiplier,\n        sampleStrideMultiplier\n    } = {}) {\n        if (ringBudgetWeights && typeof ringBudgetWeights === 'object') {\n            this.ringBudgetWeights = this._normalizeRingBudgetWeights(ringBudgetWeights, this.ringBudgetWeights);\n        }\n        if (ringStrideMultiplier && typeof ringStrideMultiplier === 'object') {\n            this.ringStrideMultiplier = this._normalizeRingStrideMultiplier(ringStrideMultiplier, this.ringStrideMultiplier);\n        }\n        if (Number.isFinite(sampleStrideMultiplier)) {\n            const next = Math.max(1, Math.min(8, Math.floor(sampleStrideMultiplier)));\n            if (next !== this.sampleStrideMultiplier) {\n                this.sampleStrideMultiplier = next;\n                this._applySampleStrideMultiplier();\n            }\n        }\n        return this.getSchedulingProfile();\n    }\n\n    setConfig({\n        batchSize,\n        maxConcurrent,\n        minIntervalMs,\n        maxKBPerMinute,\n        maxChunkBytes,\n        maxRequestBytes,\n        backendTimeoutMs,\n        angleLimitDeg,\n        surfaceMinLevel,\n        maxVertexRecords,\n        pendingTimeoutMs,\n        pendingRecoveryIntervalMs,\n        pendingRecoveryMaxPerTick,\n        fullFetchMinLevel,\n        initialSampleStrideMultiplier,\n        sampleStrideMultiplier,\n        viewshedMinDeg,\n        viewshedMarginDeg,\n        ringNearMeters,\n        ringMidMeters,\n        ringBudgetNear,\n        ringBudgetMid,\n        ringLodCaps,\n        cacheEnabled\n    }) {\n        if (Number.isFinite(batchSize) && batchSize > 0) {\n            this.batchSize = Math.max(1, Math.min(512, Math.floor(batchSize)));\n        }\n        if (Number.isFinite(maxConcurrent) && maxConcurrent > 0) {\n            this.maxConcurrentBatches = Math.max(1, Math.min(512, Math.floor(maxConcurrent)));\n        }\n        if (Number.isFinite(minIntervalMs) && minIntervalMs >= 0) {\n            this.minIntervalMs = Math.max(0, Math.min(5000, Math.floor(minIntervalMs)));\n        }\n        if (Number.isFinite(maxKBPerMinute) && maxKBPerMinute >= 0) {\n            this.maxKBPerMinute = Math.floor(maxKBPerMinute);\n        }\n        if (Number.isFinite(maxChunkBytes) && maxChunkBytes >= 0) {\n            this.maxChunkBytes = Math.floor(maxChunkBytes);\n        }\n        if (Number.isFinite(maxRequestBytes) && maxRequestBytes >= 0) {\n            this.maxRequestBytes = Math.floor(maxRequestBytes);\n        }\n        if (Number.isFinite(backendTimeoutMs) && backendTimeoutMs >= 1000) {\n            this._backendTimeoutMs = Math.max(1000, Math.min(120000, Math.floor(backendTimeoutMs)));\n        }\n        if (Number.isFinite(angleLimitDeg)) {\n            this.angleLimitDeg = Math.max(10, Math.min(170, angleLimitDeg));\n        }\n        if (Number.isFinite(surfaceMinLevel)) {\n            this.surfaceMinLevel = Math.max(0, Math.floor(surfaceMinLevel));\n        }\n        if (Number.isFinite(maxVertexRecords) && maxVertexRecords > 0) {\n            this.setMemoryBudgetBaseline(maxVertexRecords);\n        }\n        if (Number.isFinite(pendingTimeoutMs) && pendingTimeoutMs >= 500) {\n            this.pendingTimeoutMs = Math.max(500, Math.min(180000, Math.floor(pendingTimeoutMs)));\n        }\n        if (Number.isFinite(pendingRecoveryIntervalMs) && pendingRecoveryIntervalMs >= 50) {\n            this.pendingRecoveryIntervalMs = Math.max(50, Math.min(60000, Math.floor(pendingRecoveryIntervalMs)));\n        }\n        if (Number.isFinite(pendingRecoveryMaxPerTick) && pendingRecoveryMaxPerTick >= 1) {\n            this.pendingRecoveryMaxPerTick = Math.max(1, Math.min(65536, Math.floor(pendingRecoveryMaxPerTick)));\n        }\n        if (Number.isFinite(fullFetchMinLevel)) {\n            this.fullFetchMinLevel = Math.max(0, Math.floor(fullFetchMinLevel));\n        }\n        const strideMult = Number.isFinite(sampleStrideMultiplier)\n            ? sampleStrideMultiplier\n            : initialSampleStrideMultiplier;\n        if (Number.isFinite(strideMult)) {\n            this.setSchedulingProfile({ sampleStrideMultiplier: strideMult });\n        }\n        if (Number.isFinite(viewshedMinDeg)) {\n            this.viewshedMinDeg = Math.max(0, Math.min(30, viewshedMinDeg));\n        }\n        if (Number.isFinite(viewshedMarginDeg)) {\n            this.viewshedMarginDeg = Math.max(0, Math.min(30, viewshedMarginDeg));\n        }\n        if (Number.isFinite(ringNearMeters)) {\n            this.ringNearMeters = Math.max(0, ringNearMeters);\n        }\n        if (Number.isFinite(ringMidMeters)) {\n            this.ringMidMeters = Math.max(this.ringNearMeters, ringMidMeters);\n        }\n        if (Number.isFinite(ringBudgetNear) || Number.isFinite(ringBudgetMid)) {\n            const clampPercent = (value, fallback) => {\n                if (!Number.isFinite(value)) return fallback;\n                return Math.max(0, Math.min(100, value));\n            };\n            let nearPct = clampPercent(ringBudgetNear, this.ringBudgetWeights.near * 100) / 100;\n            let midPct = clampPercent(ringBudgetMid, this.ringBudgetWeights.mid * 100) / 100;\n            let farPct = 1 - nearPct - midPct;\n            if (farPct < 0.05) {\n                const deficit = 0.05 - farPct;\n                const total = nearPct + midPct;\n                if (total > 0) {\n                    nearPct = Math.max(0, nearPct - deficit * (nearPct / total));\n                    midPct = Math.max(0, midPct - deficit * (midPct / total));\n                }\n                farPct = 0.05;\n            }\n            const sum = nearPct + midPct + farPct;\n            if (sum > 0) {\n                this.setSchedulingProfile({\n                    ringBudgetWeights: {\n                        near: nearPct / sum,\n                        mid: midPct / sum,\n                        far: farPct / sum\n                    }\n                });\n            }\n        }\n        if (ringLodCaps && typeof ringLodCaps === 'object') {\n            this.setRingLodCaps(ringLodCaps);\n        }\n        if (typeof cacheEnabled === 'boolean') {\n            this.setCacheEnabled(cacheEnabled);\n        }\n    }\n\n    setRingLodCaps({ near, mid, far } = {}) {\n        const clampLevel = (value, fallback) => {\n            if (!Number.isFinite(value)) return fallback;\n            return Math.max(0, Math.floor(value));\n        };\n        const nextNear = clampLevel(near, this.ringLodCaps.near);\n        const nextMid = clampLevel(mid, this.ringLodCaps.mid);\n        const nextFar = clampLevel(far, this.ringLodCaps.far);\n        const normalizedMid = Math.min(nextNear, nextMid);\n        const normalizedFar = Math.min(normalizedMid, nextFar);\n        this.ringLodCaps = { near: nextNear, mid: normalizedMid, far: normalizedFar };\n    }\n\n    _applySampleStrideMultiplier() {\n        const multiplier = Number.isFinite(this.sampleStrideMultiplier)\n            ? Math.max(1, Math.floor(this.sampleStrideMultiplier))\n            : 1;\n        const base = this.sampleStrideBaseByLevel || {};\n        const next = {};\n        Object.keys(base).forEach((level) => {\n            const baseStride = base[level];\n            const lvl = Number(level);\n            const stride = (Number.isFinite(lvl) && lvl < 7)\n                ? Math.max(1, Math.round(baseStride))\n                : Math.max(1, Math.round(baseStride * multiplier));\n            next[level] = stride;\n        });\n        this.sampleStrideByLevel = next;\n    }\n\n    setTargetMaxLevel(level, { fullFetch = false } = {}) {\n        if (Number.isFinite(level)) {\n            this.targetMaxLevel = Math.max(0, Math.floor(level));\n            this.strictFullFetch = !!fullFetch;\n            this.fullFetchMaxLevel = this.strictFullFetch ? this.targetMaxLevel : -1;\n        } else {\n            this.targetMaxLevel = null;\n            this.strictFullFetch = false;\n            this.fullFetchMaxLevel = -1;\n        }\n    }\n\n    setActiveTiles(tiles = []) {\n        this.activeTilePriorities.clear();\n        // Active tile priorities drive candidate selection; invalidate cached candidates immediately.\n        this._activeCandidateCache = null;\n        const nextEntries = this._activeTileEntriesScratch;\n        nextEntries.length = 0;\n        for (const entry of tiles) {\n            const tile = entry?.tile || entry;\n            if (!tile) continue;\n            const priority = Number.isFinite(entry?.priority) ? entry.priority : 0;\n            this.activeTilePriorities.set(tile, priority);\n            nextEntries.push([tile, priority]);\n        }\n        nextEntries.sort((a, b) => (b[1] || 0) - (a[1] || 0));\n        this._activeTileEntriesScratch = this._activeTileEntries;\n        this._activeTileEntries = nextEntries;\n        if (!this._activeTileEntries.length) {\n            this._activeTileOverflowCursor = 0;\n        } else if (this._activeTileOverflowCursor >= this._activeTileEntries.length) {\n            this._activeTileOverflowCursor %= this._activeTileEntries.length;\n        }\n    }\n\n    setActiveScanLimits({ tileMax, candidateMax } = {}) {\n        if (!Number.isFinite(this.activeTileScanMaxBase)) {\n            this.activeTileScanMaxBase = this.activeTileScanMax;\n        }\n        if (!Number.isFinite(this.activeCandidateMaxBase)) {\n            this.activeCandidateMaxBase = this.activeCandidateMax;\n        }\n\n        if (Number.isFinite(tileMax)) {\n            this.activeTileScanMax = Math.max(16, Math.min(4096, Math.floor(tileMax)));\n        } else {\n            this.activeTileScanMax = this.activeTileScanMaxBase;\n        }\n\n        if (Number.isFinite(candidateMax)) {\n            this.activeCandidateMax = Math.max(256, Math.min(65536, Math.floor(candidateMax)));\n        } else {\n            this.activeCandidateMax = this.activeCandidateMaxBase;\n        }\n    }\n\n    isFullFetchLevel(tileLevel) {\n        if (!Number.isFinite(tileLevel)) return false;\n        if (Number.isFinite(this.fullFetchMinLevel) && tileLevel >= this.fullFetchMinLevel) {\n            return true;\n        }\n        return this.strictFullFetch && tileLevel <= this.fullFetchMaxLevel;\n    }\n\n    isFullFetchTile(tile) {\n        if (!tile) return false;\n        if (typeof tile === 'number') return this.isFullFetchLevel(tile);\n        if (tile.forceFullFetch) return true;\n        return this.isFullFetchLevel(tile.level);\n    }\n\n    /**\n     * Check if a vertex should be registered based on tile level and sampling stride\n     */\n    shouldRegisterVertex(tile, vertexIndex, resolution) {\n        const tileLevel = (tile && typeof tile === 'object')\n            ? tile.level\n            : tile;\n        if (this.isFullFetchTile(tile)) return true;\n        if (Number.isFinite(this.targetMaxLevel) && tileLevel > this.targetMaxLevel) {\n            return false;\n        }\n\n        // Always register for low LOD tiles\n        if (tileLevel < 7) return true;\n\n        // CRITICAL: Always register edge vertices to ensure adjacent tiles sharing\n        // an edge get the same elevation data. Edge vertices must match exactly\n        // between neighbors to prevent visible holes/gaps at tile boundaries.\n        if (tile && tile.edgeVertexMask && tile.edgeVertexMask[vertexIndex]) {\n            return true;\n        }\n\n        // Get sampling stride for this level\n        const stride = this.sampleStrideByLevel[tileLevel] || 1;\n        if (stride === 1) return true;\n\n        // Sample every Nth vertex based on stride\n        return (vertexIndex % stride) === 0;\n    }\n\n    _recordOutbound(bytes, count) {\n        if (!Number.isFinite(bytes)) return null;\n        const now = performance.now();\n        const ev = { t: now, bytes, count: Number.isFinite(count) ? count : 0 };\n        this.sendEvents.push(ev);\n        const cutoff = now - this.windowMs;\n        this.sendEvents = this.sendEvents.filter(ev => ev.t >= cutoff);\n\n        this.stats.requestCount++;\n        this.stats.pointsRequested += ev.count;\n        this.stats.bytesOut += bytes;\n        return ev;\n    }\n\n    _recordInbound(bytes, count) {\n        if (!Number.isFinite(bytes)) return;\n        this.stats.responseCount++;\n        this.stats.pointsReceived += (count || 0);\n        this.stats.bytesIn += bytes;\n    }\n\n    _noteNknFailure() {\n        const now = performance.now();\n        this._nknFailureCount = Math.min(this._nknFailureCount + 1, 8);\n        const delay = Math.min(\n            this._nknBackoffBaseMs * Math.pow(1.5, this._nknFailureCount - 1),\n            this._nknBackoffMaxMs\n        );\n        this._nknBlockedUntilMs = Math.max(this._nknBlockedUntilMs, now + delay);\n    }\n\n    _clearNknBackoff() {\n        this._nknFailureCount = 0;\n        this._nknBlockedUntilMs = 0;\n    }\n\n    _noteBackendFailure() {\n        this._backendFailureCount = Math.min(this._backendFailureCount + 1, this._backendFailureLimit);\n        if (this._backendFailureCount >= this._backendFailureLimit) {\n            const now = performance.now();\n            this._backendBlockedUntilMs = Math.max(this._backendBlockedUntilMs, now + this._backendBackoffMs);\n            this._backendFailureCount = 0;\n        }\n    }\n\n    _clearBackendFailures() {\n        this._backendFailureCount = 0;\n        this._backendBlockedUntilMs = 0;\n        this._connectFailureCount = 0;\n        this._connectCooldownUntilMs = 0;\n    }\n\n    _logBackendFallbackTransition({\n        reason = 'backend-degraded',\n        status = null,\n        batchSize = 0,\n        fallbackTried = false,\n        fallbackApplied = false,\n        error = null\n    } = {}) {\n        const now = performance.now();\n        const statusCode = Number.isFinite(status) ? Math.floor(status) : null;\n        const isUnauthorized = statusCode === 401;\n        const minInterval = isUnauthorized\n            ? Math.min(1000, this._backendTransitionLogIntervalMs)\n            : this._backendTransitionLogIntervalMs;\n        if (now - this._lastBackendTransitionLogMs < minInterval) return;\n        this._lastBackendTransitionLogMs = now;\n\n        const statusText = statusCode !== null ? `status=${statusCode}` : 'status=n/a';\n        const batchText = Number.isFinite(batchSize) ? `batch=${Math.max(0, Math.floor(batchSize))}` : 'batch=0';\n        const fallbackText = fallbackTried\n            ? `fallback=${fallbackApplied ? 'applied' : 'not-applied'}`\n            : 'fallback=not-tried';\n        const msg = `[elev] ${reason} (${statusText}, ${batchText}, ${fallbackText})`;\n        if (error) {\n            console.warn(msg, error);\n        } else {\n            console.warn(msg);\n        }\n    }\n\n    _logResponseMatchDiagnostics(diag, { batchSize = 0, resultSize = 0 } = {}) {\n        if (!diag) return;\n        const hasIssues = (diag.unmatchedResults || 0) > 0 ||\n            (diag.locationMismatches || 0) > 0 ||\n            (diag.invalidElevation || 0) > 0 ||\n            (diag.retriedPending || 0) > 0;\n        if (!hasIssues) return;\n        const now = performance.now();\n        if (now - this._lastResponseDiagLogMs < this._responseDiagLogIntervalMs) return;\n        this._lastResponseDiagLogMs = now;\n        console.warn(\n            `[elev] response diagnostics ` +\n            `results=${Math.max(0, Math.floor(resultSize || 0))} ` +\n            `batch=${Math.max(0, Math.floor(batchSize || 0))} ` +\n            `keyMatches=${Math.max(0, Math.floor(diag.keyMatches || 0))} ` +\n            `indexMatches=${Math.max(0, Math.floor(diag.indexMatches || 0))} ` +\n            `unmatched=${Math.max(0, Math.floor(diag.unmatchedResults || 0))} ` +\n            `locationMismatches=${Math.max(0, Math.floor(diag.locationMismatches || 0))} ` +\n            `invalidElev=${Math.max(0, Math.floor(diag.invalidElevation || 0))} ` +\n            `retriedPending=${Math.max(0, Math.floor(diag.retriedPending || 0))}`\n        );\n    }\n\n    _shouldUseFallbacks() {\n        if (!this.enableFallbacks) return false;\n        if (this.fallbackOnBackendError) return true;\n        return !hasBackendOverride() && !hasElevationOverride();\n    }\n\n    _getFallbackState(providerId) {\n        if (!providerId || !this._fallbackState) return null;\n        if (this._fallbackState[providerId]) return this._fallbackState[providerId];\n        // Backward compatibility with legacy provider ids.\n        const legacyMap = {\n            'open-meteo': 'openMeteo',\n            'open-topo': 'openTopo'\n        };\n        const legacyId = legacyMap[providerId];\n        if (legacyId && this._fallbackState[legacyId]) {\n            return this._fallbackState[legacyId];\n        }\n        return null;\n    }\n\n    _canUseFallback(providerId) {\n        if (!this._shouldUseFallbacks()) return false;\n        if (providerId === 'open-meteo' && !this.enableOpenMeteoFallback) return false;\n        if (providerId === 'epqs' && !this.enableEpqsFallback) return false;\n        if (providerId === 'gmrt' && !this.enableGmrtFallback) return false;\n        if (providerId === 'open-topo' && !this.enableOpenTopoFallback) return false;\n        const state = this._getFallbackState(providerId);\n        if (!state) return true;\n        const now = performance.now();\n        if (Number.isFinite(state.nextRetryAt) && state.nextRetryAt > 0 && now < state.nextRetryAt) {\n            return false;\n        }\n        return true;\n    }\n\n    _noteFallbackFailure(providerId) {\n        const state = this._getFallbackState(providerId);\n        if (!state) return;\n        state.failures = Math.min((state.failures || 0) + 1, this._fallbackFailureLimit);\n        const exponent = Math.max(0, state.failures - 1);\n        const delay = Math.min(\n            this._fallbackBackoffBaseMs * Math.pow(2, exponent),\n            this._fallbackBackoffMaxMs\n        );\n        const jitter = Math.random() * delay * 0.2;\n        state.nextRetryAt = performance.now() + delay + jitter;\n    }\n\n    _clearFallbackFailure(providerId) {\n        const state = this._getFallbackState(providerId);\n        if (!state) return;\n        state.failures = 0;\n        state.nextRetryAt = 0;\n    }\n\n    async _sleep(ms) {\n        if (!ms || ms <= 0) return;\n        await new Promise((resolve) => setTimeout(resolve, ms));\n    }\n\n    _getFallbackRateState(providerId) {\n        if (!this._fallbackRateState[providerId]) {\n            this._fallbackRateState[providerId] = {\n                minute: [],\n                hour: [],\n                day: [],\n                lastRequestAt: 0\n            };\n        }\n        return this._fallbackRateState[providerId];\n    }\n\n    _pruneRateWindow(list, windowMs, now) {\n        if (!Array.isArray(list) || !list.length) return;\n        let idx = 0;\n        while (idx < list.length && now - list[idx] > windowMs) {\n            idx += 1;\n        }\n        if (idx > 0) list.splice(0, idx);\n    }\n\n    async _waitForFallbackSlot(providerId) {\n        const limits = this._fallbackRateLimits?.[providerId];\n        if (!limits) return;\n        const state = this._getFallbackRateState(providerId);\n        while (true) {\n            const now = Date.now();\n            const minuteMs = 60_000;\n            const hourMs = 60 * 60_000;\n            const dayMs = 24 * 60 * 60_000;\n            this._pruneRateWindow(state.minute, minuteMs, now);\n            this._pruneRateWindow(state.hour, hourMs, now);\n            this._pruneRateWindow(state.day, dayMs, now);\n\n            let waitMs = 0;\n            if (Number.isFinite(limits.minIntervalMs) && limits.minIntervalMs > 0) {\n                const sinceLast = now - (state.lastRequestAt || 0);\n                if (sinceLast < limits.minIntervalMs) {\n                    waitMs = Math.max(waitMs, limits.minIntervalMs - sinceLast);\n                }\n            }\n            if (Number.isFinite(limits.perMinute) && limits.perMinute > 0) {\n                if (state.minute.length >= limits.perMinute) {\n                    const oldest = state.minute[0];\n                    waitMs = Math.max(waitMs, minuteMs - (now - oldest));\n                }\n            }\n            if (Number.isFinite(limits.perHour) && limits.perHour > 0) {\n                if (state.hour.length >= limits.perHour) {\n                    const oldest = state.hour[0];\n                    waitMs = Math.max(waitMs, hourMs - (now - oldest));\n                }\n            }\n            if (Number.isFinite(limits.perDay) && limits.perDay > 0) {\n                if (state.day.length >= limits.perDay) {\n                    const oldest = state.day[0];\n                    waitMs = Math.max(waitMs, dayMs - (now - oldest));\n                }\n            }\n\n            if (!waitMs || waitMs <= 0) {\n                state.lastRequestAt = now;\n                state.minute.push(now);\n                state.hour.push(now);\n                state.day.push(now);\n                return;\n            }\n            await this._sleep(waitMs);\n        }\n    }\n\n    async _withFallbackRateLimit(providerId, fn) {\n        if (typeof fn !== 'function') return null;\n        const queue = this._fallbackRateQueue[providerId] || Promise.resolve();\n        const run = queue.then(async () => {\n            await this._waitForFallbackSlot(providerId);\n            return fn();\n        });\n        this._fallbackRateQueue[providerId] = run.catch(() => {});\n        return run;\n    }\n\n    _getFallbackBase(directUrl, proxyPath) {\n        if (this.preferDirectFallbacks) return directUrl;\n        return isLocalRuntime() ? directUrl : proxyPath;\n    }\n\n    _resolveBackendHost() {\n        if (typeof window === 'undefined') return null;\n        const { hostname, port, protocol } = window.location;\n        const devPorts = new Set(['3000', '3001', '4173', '5173']);\n        if (devPorts.has(port) && protocol === 'https:') {\n            return port ? `${hostname}:${port}` : hostname;\n        }\n        const wsPort = devPorts.has(port) ? '8080' : port;\n        return wsPort ? `${hostname}:${wsPort}` : hostname;\n    }\n\n    _resolveBackendEndpoints() {\n        const wsUrl = getElevationWsUrl();\n        const httpUrl = getElevationApiBase();\n        if (!wsUrl || !httpUrl) return null;\n        return { wsUrl, httpUrl };\n    }\n\n    _buildMapzenResults(locations, elevations) {\n        if (!Array.isArray(locations) || !Array.isArray(elevations)) return [];\n        const results = [];\n        const count = Math.min(locations.length, elevations.length);\n        for (let i = 0; i < count; i++) {\n            const loc = locations[i];\n            const elev = elevations[i];\n            if (!loc || !Number.isFinite(Number(elev))) continue;\n            results.push({\n                location: { lat: Number(loc.lat), lng: Number(loc.lng) },\n                elevation: Number(elev),\n                sourceZoom: Number.isFinite(Number(loc.sourceZoom))\n                    ? Number(loc.sourceZoom)\n                    : this._mapzenRasterTileSource.zoom\n            });\n        }\n        return results;\n    }\n\n    setMapzenRasterTilesEnabled(enabled) {\n        const next = !!enabled;\n        if (this.enableMapzenRasterTiles === next) return;\n        this.enableMapzenRasterTiles = next;\n        this.clearPendingRequests({ immediateReschedule: true });\n        this.lastScheduleTime = 0;\n    }\n\n    async _fetchMapzenRasterTiles(locations, batch) {\n        if (!Array.isArray(locations) || !locations.length) return false;\n        if (!Array.isArray(batch) || !batch.length) return false;\n        const sourceLocations = locations.map((location, index) => {\n            const rec = batch[index];\n            const sourceZoom = Number.isFinite(rec?.mapzenSourceZoom)\n                ? rec.mapzenSourceZoom\n                : this._mapzenRasterTileSource.zoom;\n            if (rec) rec.mapzenPendingSourceZoom = sourceZoom;\n            this._mapzenMinRequestedZoom = Math.min(this._mapzenMinRequestedZoom, sourceZoom);\n            this._mapzenMaxRequestedZoom = Math.max(this._mapzenMaxRequestedZoom, sourceZoom);\n            return { lat: location.lat, lng: location.lng, sourceZoom };\n        });\n        const elevations = await this._mapzenRasterTileSource.sampleLocations(sourceLocations);\n        const results = this._buildMapzenResults(sourceLocations, elevations);\n        return this._applyElevationResponse({\n            body: {\n                dataset: 'mapzen-geotiff-regional',\n                results\n            }\n        }, batch);\n    }\n\n    async _fetchOpenMeteoFallback(locations, batch) {\n        if (!Array.isArray(locations) || !locations.length) return false;\n        if (!Array.isArray(batch) || !batch.length) return false;\n        const fallbackBase = this._getFallbackBase(OPEN_METEO_FALLBACK_URL, '/api/open-meteo-elevation');\n        let appliedAny = false;\n        for (let i = 0; i < locations.length; i += OPEN_METEO_MAX_POINTS) {\n            const locSlice = locations.slice(i, i + OPEN_METEO_MAX_POINTS);\n            const batchSlice = batch.slice(i, i + OPEN_METEO_MAX_POINTS);\n            if (!locSlice.length || !batchSlice.length) continue;\n            const latList = locSlice.map((loc) => Number(loc.lat).toFixed(6)).join(',');\n            const lonList = locSlice.map((loc) => Number(loc.lng).toFixed(6)).join(',');\n            const url = `${fallbackBase}?latitude=${encodeURIComponent(latList)}&longitude=${encodeURIComponent(lonList)}`;\n            const json = await this._withFallbackRateLimit('open-meteo', async () => {\n                const response = await fetch(url);\n                if (!response.ok) {\n                    throw new Error(`Open-Meteo error: ${response.status}`);\n                }\n                return response.json();\n            });\n            const elevations = Array.isArray(json?.elevation) ? json.elevation : [];\n            const results = this._buildMapzenResults(locSlice, elevations);\n            const applied = this._applyElevationResponse({ body: { results } }, batchSlice);\n            appliedAny = appliedAny || applied;\n        }\n        return appliedAny;\n    }\n\n    async _fetchEpqsFallback(locations, batch) {\n        if (!Array.isArray(locations) || !locations.length) return false;\n        if (!Array.isArray(batch) || !batch.length) return false;\n        const fallbackBase = this._getFallbackBase(EPQS_FALLBACK_URL, '/api/epqs');\n        const results = new Array(locations.length).fill(null);\n        let cursor = 0;\n        const maxConcurrency = Math.max(1, Math.floor(this._fallbackConcurrency || 1));\n        const worker = async () => {\n            while (cursor < locations.length) {\n                const idx = cursor;\n                cursor += 1;\n                const loc = locations[idx];\n                if (!loc) continue;\n                const url = `${fallbackBase}?x=${encodeURIComponent(Number(loc.lng).toFixed(6))}` +\n                    `&y=${encodeURIComponent(Number(loc.lat).toFixed(6))}&wkid=4326&units=Meters&includeDate=false`;\n                const json = await this._withFallbackRateLimit('epqs', async () => {\n                    const resp = await fetch(url);\n                    if (!resp.ok) {\n                        throw new Error(`EPQS error: ${resp.status}`);\n                    }\n                    return resp.json();\n                });\n                const value = Number(\n                    json?.value ??\n                    json?.elevation ??\n                    json?.Elevation ??\n                    json?.result?.value ??\n                    json?.data?.value\n                );\n                if (Number.isFinite(value)) {\n                    results[idx] = value;\n                }\n            }\n        };\n        const workers = Array.from({ length: Math.min(maxConcurrency, locations.length) }, () => worker());\n        await Promise.all(workers);\n        const mapped = this._buildMapzenResults(locations, results);\n        return this._applyElevationResponse({ body: { results: mapped } }, batch);\n    }\n\n    async _fetchGmrtFallback(locations, batch) {\n        if (!Array.isArray(locations) || !locations.length) return false;\n        if (!Array.isArray(batch) || !batch.length) return false;\n        const fallbackBase = this._getFallbackBase(GMRT_FALLBACK_URL, '/api/gmrt');\n        const results = new Array(locations.length).fill(null);\n        let cursor = 0;\n        const maxConcurrency = Math.max(1, Math.floor(this._fallbackConcurrency || 1));\n        const pickElevation = (json) => {\n            const candidates = [\n                json?.elevation,\n                json?.Elevation,\n                json?.depth,\n                json?.Depth,\n                json?.z,\n                json?.Z,\n                json?.value,\n                json?.Value,\n                json?.data?.elevation,\n                json?.data?.z,\n                json?.data?.value\n            ];\n            for (const entry of candidates) {\n                const num = Number(entry);\n                if (Number.isFinite(num)) return num;\n            }\n            return null;\n        };\n        const worker = async () => {\n            while (cursor < locations.length) {\n                const idx = cursor;\n                cursor += 1;\n                const loc = locations[idx];\n                if (!loc) continue;\n                const url = `${fallbackBase}?latitude=${encodeURIComponent(Number(loc.lat).toFixed(6))}` +\n                    `&longitude=${encodeURIComponent(Number(loc.lng).toFixed(6))}&format=json`;\n                const json = await this._withFallbackRateLimit('gmrt', async () => {\n                    const resp = await fetch(url);\n                    if (!resp.ok) {\n                        throw new Error(`GMRT error: ${resp.status}`);\n                    }\n                    return resp.json();\n                });\n                const value = pickElevation(json);\n                if (Number.isFinite(value)) {\n                    results[idx] = value;\n                }\n            }\n        };\n        const workers = Array.from({ length: Math.min(maxConcurrency, locations.length) }, () => worker());\n        await Promise.all(workers);\n        const mapped = this._buildMapzenResults(locations, results);\n        return this._applyElevationResponse({ body: { results: mapped } }, batch);\n    }\n\n    async _fetchOpenTopoFallback(locations, batch) {\n        if (!Array.isArray(locations) || !locations.length) return false;\n        if (!Array.isArray(batch) || !batch.length) return false;\n        const fallbackBase = this._getFallbackBase(OPEN_TOPO_FALLBACK_URL, '/api/opentopo');\n        let appliedAny = false;\n        for (let i = 0; i < locations.length; i += OPEN_TOPO_MAX_POINTS) {\n            const locSlice = locations.slice(i, i + OPEN_TOPO_MAX_POINTS);\n            const batchSlice = batch.slice(i, i + OPEN_TOPO_MAX_POINTS);\n            if (!locSlice.length || !batchSlice.length) continue;\n            const locParam = locSlice\n                .map((loc) => `${Number(loc.lat).toFixed(6)},${Number(loc.lng).toFixed(6)}`)\n                .join('|');\n            const url = `${fallbackBase}?locations=${encodeURIComponent(locParam)}`;\n            const json = await this._withFallbackRateLimit('open-topo', async () => {\n                const response = await fetch(url);\n                if (!response.ok) {\n                    throw new Error(`OpenTopoData error: ${response.status}`);\n                }\n                const body = await response.json();\n                // Local OpenTopoData (and some proxies) return HTTP 200 with a\n                // JSON error body like { status: 'SERVER_ERROR', error: '...' }\n                // when the dataset is missing/unreadable. Treat that as a failure\n                // so the fallback chain advances instead of stalling on null data.\n                if (body && (body.status === 'SERVER_ERROR' || body.status === 'error' || body.error)) {\n                    throw new Error(`OpenTopoData server error: ${body.error || body.status || 'unknown'}`);\n                }\n                return body;\n            });\n            const applied = this._applyElevationResponse({ body: json }, batchSlice);\n            appliedAny = appliedAny || applied;\n        }\n        return appliedAny;\n    }\n\n    async _fetchFallbackChain(locations, batch) {\n        if (!this._shouldUseFallbacks()) return false;\n        const providers = [\n            { id: 'open-meteo', fn: this._fetchOpenMeteoFallback.bind(this) },\n            { id: 'epqs', fn: this._fetchEpqsFallback.bind(this) },\n            { id: 'gmrt', fn: this._fetchGmrtFallback.bind(this) },\n            { id: 'open-topo', fn: this._fetchOpenTopoFallback.bind(this) }\n        ];\n\n        for (const provider of providers) {\n            if (!this._canUseFallback(provider.id)) continue;\n            try {\n                const applied = await provider.fn(locations, batch);\n                if (applied) {\n                    this._clearFallbackFailure(provider.id);\n                    return true;\n                }\n                this._noteFallbackFailure(provider.id);\n            } catch (error) {\n                this._noteFallbackFailure(provider.id);\n                console.warn(`[elev] ${provider.id} fallback failed`, error);\n            }\n        }\n        return false;\n    }\n\n    async _guardedConnect(transport) {\n        const now = performance.now();\n        if (this._connectCooldownUntilMs > now) {\n            throw new Error('Backend transport in reconnect cooldown');\n        }\n        if (this._connectInFlight) {\n            return this._connectInFlight;\n        }\n        this._connectInFlight = transport.connect()\n            .then(() => {\n                this._connectFailureCount = 0;\n                this._connectCooldownUntilMs = 0;\n            })\n            .catch((err) => {\n                this._connectFailureCount = Math.min((this._connectFailureCount || 0) + 1, 20);\n                const delay = Math.min(30000, 2000 * Math.pow(1.5, this._connectFailureCount - 1));\n                this._connectCooldownUntilMs = performance.now() + delay;\n                throw err;\n            })\n            .finally(() => {\n                this._connectInFlight = null;\n            });\n        return this._connectInFlight;\n    }\n\n    async _ensureBackendTransport() {\n        if (this.transport) {\n            if (!this.transport.isConnected) {\n                await this._guardedConnect(this.transport);\n            }\n            return this.transport;\n        }\n        if (!this._transportInitPromise) {\n            this._transportInitPromise = (async () => {\n                const endpoints = this._resolveBackendEndpoints();\n                if (!endpoints) {\n                    throw new Error('Backend endpoints unavailable');\n                }\n                await initTransport(endpoints);\n                const manager = getTransportManager();\n                this.transport = manager;\n                if (!manager.isConnected) {\n                    await this._guardedConnect(manager);\n                }\n                return manager;\n            })().catch((err) => {\n                this._transportInitPromise = null;\n                throw err;\n            });\n        }\n        const manager = await this._transportInitPromise;\n        if (!manager.isConnected) {\n            await this._guardedConnect(manager);\n        }\n        return manager;\n    }\n\n    _withTimeout(promise, timeoutMs, label = 'operation') {\n        const ms = Number.isFinite(timeoutMs)\n            ? Math.max(1, Math.floor(timeoutMs))\n            : 15000;\n        return new Promise((resolve, reject) => {\n            let settled = false;\n            const timer = setTimeout(() => {\n                if (settled) return;\n                settled = true;\n                reject(new Error(`${label} timed out after ${ms}ms`));\n            }, ms);\n            Promise.resolve(promise)\n                .then((value) => {\n                    if (settled) return;\n                    settled = true;\n                    clearTimeout(timer);\n                    resolve(value);\n                })\n                .catch((err) => {\n                    if (settled) return;\n                    settled = true;\n                    clearTimeout(timer);\n                    reject(err);\n                });\n        });\n    }\n\n    async _resetBackendTransport(reason = 'reset') {\n        const now = performance.now();\n        if (Number.isFinite(this._lastTransportResetMs) &&\n            (now - this._lastTransportResetMs) < this._transportResetCooldownMs) {\n            return false;\n        }\n        this._lastTransportResetMs = now;\n        const existing = this.transport;\n        this.transport = null;\n        this._transportInitPromise = null;\n        this._connectInFlight = null;\n        this._connectCooldownUntilMs = 0;\n        this._connectFailureCount = 0;\n        if (existing && typeof existing.disconnect === 'function') {\n            try {\n                await existing.disconnect();\n            } catch {\n                // Ignore disconnect failures during recovery.\n            }\n        }\n        console.warn(`[elev] backend transport reset (${reason})`);\n        return true;\n    }\n\n    _recordHasActiveClient(rec) {\n        if (!rec || !Array.isArray(rec.clients) || !rec.clients.length) return false;\n        for (const ref of rec.clients) {\n            const tile = ref?.tile;\n            if (tile && this.activeTilePriorities?.has(tile)) {\n                return true;\n            }\n        }\n        return false;\n    }\n\n    _recoverStalePending(now = performance.now()) {\n        const interval = Number.isFinite(this.pendingRecoveryIntervalMs)\n            ? Math.max(100, Math.floor(this.pendingRecoveryIntervalMs))\n            : 750;\n        if (Number.isFinite(this._lastPendingRecoveryMs) &&\n            (now - this._lastPendingRecoveryMs) < interval) {\n            return 0;\n        }\n        this._lastPendingRecoveryMs = now;\n\n        const timeoutMs = Number.isFinite(this.pendingTimeoutMs)\n            ? Math.max(1000, Math.floor(this.pendingTimeoutMs))\n            : 12000;\n        const maxRecoveries = Number.isFinite(this.pendingRecoveryMaxPerTick)\n            ? Math.max(1, Math.floor(this.pendingRecoveryMaxPerTick))\n            : 4096;\n\n        let recovered = 0;\n        let activeRecovered = 0;\n        for (const rec of this.vertexMap.values()) {\n            if (recovered >= maxRecoveries) break;\n            if (!rec || rec.status !== 'pending') continue;\n            const pendingSince = Number.isFinite(rec.pendingSince) ? rec.pendingSince : 0;\n            if (!pendingSince || (now - pendingSince) < timeoutMs) continue;\n            const isActive = this._recordHasActiveClient(rec);\n            if (isActive) activeRecovered++;\n            this._markRetry(rec, now, { immediate: true });\n            recovered++;\n        }\n        if (recovered <= 0) return 0;\n\n        this._pendingRecoveryCount += recovered;\n        this._noteBackendFailure();\n\n        if ((now - this._lastPendingRecoveryLogMs) >= this._pendingRecoveryLogIntervalMs) {\n            this._lastPendingRecoveryLogMs = now;\n            console.warn(\n                `[elev] recovered ${recovered} stale pending vertices ` +\n                `(active=${activeRecovered}, timeoutMs=${timeoutMs})`\n            );\n        }\n\n        const resetThreshold = Math.max(64, Math.floor(maxRecoveries * 0.5));\n        if (recovered >= resetThreshold) {\n            this._resetBackendTransport('stale-pending').catch(() => {});\n        }\n        return recovered;\n    }\n\n    _canUseNkn(now) {\n        if (!this.enableNkn) return false;\n        if (!this.mc || !this.relayDest) return false;\n        if (this.mc && typeof this.mc.isReady === 'boolean' && !this.mc.isReady) return false;\n        if (Number.isFinite(this._nknBlockedUntilMs) && now < this._nknBlockedUntilMs) return false;\n        return true;\n    }\n\n    _shouldUseBackend(now) {\n        if (Number.isFinite(this._backendBlockedUntilMs) && now >= this._backendBlockedUntilMs) {\n            this._backendBlockedUntilMs = 0;\n        }\n        if (Number.isFinite(this._backendBlockedUntilMs) && now < this._backendBlockedUntilMs) {\n            // While backend is in backoff, route work to fallback providers when available.\n            return false;\n        }\n        return true;\n    }\n\n    _getBackendFailurePressure() {\n        const failures = Number.isFinite(this._backendFailureCount)\n            ? Math.max(0, this._backendFailureCount)\n            : 0;\n        const limit = Number.isFinite(this._backendFailureLimit)\n            ? Math.max(1, this._backendFailureLimit)\n            : 10;\n        return THREE.MathUtils.clamp(failures / limit, 0, 1);\n    }\n\n    _getEffectiveMaxConcurrentBatches() {\n        const configured = Number.isFinite(this.maxConcurrentBatches)\n            ? Math.max(1, Math.floor(this.maxConcurrentBatches))\n            : 1;\n        // One Mapzen batch already coalesces hundreds of vertices by raster\n        // tile and the shared source bounds physical downloads. Limiting the\n        // number of batch coordinators prevents promise/sort churn from\n        // competing with TriTree traversal on every animation frame.\n        const sourceConfigured = this.enableMapzenRasterTiles\n            ? Math.min(configured, 4)\n            : configured;\n        const pressure = this._getBackendFailurePressure();\n        if (pressure <= 0) return sourceConfigured;\n        const floor = this.enableMapzenRasterTiles\n            ? 1\n            : Math.max(4, Math.min(sourceConfigured, Math.floor(sourceConfigured * 0.12)));\n        const scaled = Math.floor(sourceConfigured * (1 - pressure * 0.85));\n        return Math.max(floor, Math.min(sourceConfigured, scaled));\n    }\n\n    _getEffectiveMinIntervalMs() {\n        const base = Number.isFinite(this.minIntervalMs)\n            ? Math.max(0, Math.floor(this.minIntervalMs))\n            : 0;\n        const pressure = this._getBackendFailurePressure();\n        const sourceBase = this.enableMapzenRasterTiles ? Math.max(base, 32) : base;\n        if (pressure <= 0) return sourceBase;\n        const boost = Math.ceil(pressure * 40);\n        return sourceBase + boost;\n    }\n\n    _getEffectiveBatchSize() {\n        const configured = Number.isFinite(this.batchSize)\n            ? Math.max(1, Math.floor(this.batchSize))\n            : 1;\n        const pressure = this._getBackendFailurePressure();\n        if (pressure <= 0) return configured;\n        const scaled = Math.floor(configured * (1 - pressure * 0.6));\n        return Math.max(32, Math.min(configured, scaled));\n    }\n\n    _applyElevationResponse(resp, thisBatch) {\n        let json = null;\n        let results = null;\n        let bytesIn = 0;\n        try {\n            if (resp?.body_b64) {\n                bytesIn = resp.body_b64.length * 0.75;\n                const decoded = atob(resp.body_b64);\n                json = JSON.parse(decoded);\n            } else if (resp?.body) {\n                const bodyStr = (typeof resp.body === 'string') ? resp.body : JSON.stringify(resp.body);\n                bytesIn = bodyStr.length;\n                json = typeof resp.body === 'string' ? JSON.parse(resp.body) : resp.body;\n            } else if (Array.isArray(resp?.results)) {\n                const direct = resp;\n                const bodyStr = JSON.stringify(direct);\n                bytesIn = bodyStr.length;\n                json = direct;\n            } else if (Array.isArray(resp?.payload?.results)) {\n                const direct = resp.payload;\n                const bodyStr = JSON.stringify(direct);\n                bytesIn = bodyStr.length;\n                json = direct;\n            }\n        } catch (e) {\n            console.error('[elev] bad JSON', e);\n        }\n\n        const toResults = (payload) => {\n            if (!payload || typeof payload !== 'object') return null;\n            if (Array.isArray(payload.results)) return payload.results;\n            if (Array.isArray(payload.body?.results)) return payload.body.results;\n            if (Array.isArray(payload.data?.results)) return payload.data.results;\n            if (Array.isArray(payload.data) &&\n                payload.data.every((entry) => entry && typeof entry === 'object' &&\n                    ('elevation' in entry || 'height' in entry))) {\n                return payload.data.map((entry) => ({\n                    ...entry,\n                    elevation: Number.isFinite(Number(entry?.elevation))\n                        ? Number(entry.elevation)\n                        : Number(entry?.height)\n                }));\n            }\n            if (Array.isArray(payload.elevations)) {\n                return payload.elevations.map((entry, idx) => {\n                    const batchRec = thisBatch?.[idx];\n                    const hasLocation = Number.isFinite(batchRec?.lat) && Number.isFinite(batchRec?.lng);\n                    return {\n                        elevation: entry,\n                        location: hasLocation ? { lat: batchRec.lat, lng: batchRec.lng } : undefined\n                    };\n                });\n            }\n            return null;\n        };\n\n        results = toResults(json) || toResults(resp) || toResults(resp?.payload);\n        if (!Array.isArray(results)) {\n            console.warn('[elev] unexpected response format', json);\n            for (const rec of thisBatch) {\n                if (rec.status === 'pending') {\n                    this._markRetry(rec, performance.now());\n                }\n            }\n            return false;\n        }\n        const basePayload = (json && typeof json === 'object')\n            ? json\n            : ((resp && typeof resp === 'object') ? resp : {});\n        json = { ...basePayload, results };\n\n        this._recordInbound(bytesIn, json.results.length || 0);\n\n        let appliedCount = 0;\n        let elevStats = { min: Infinity, max: -Infinity, sum: 0, count: 0 };\n        const batchSamples = [];\n        const matchedIndices = new Set();\n        const diag = {\n            keyMatches: 0,\n            indexMatches: 0,\n            locationMismatches: 0,\n            invalidElevation: 0,\n            retriedPending: 0,\n            unmatchedResults: 0\n        };\n\n        const responseDataset = String(json?.dataset || json?.body?.dataset || '');\n        const isMapzenRasterResponse = responseDataset === 'mapzen-geotiff-regional';\n        const applyRecord = (rec, elev, lat, lng, result = null) => {\n            if (!rec) return 0;\n            rec.height = elev;\n            rec.status = 'done';\n            rec.retryCount = 0;\n            rec.nextRetryAt = 0;\n            rec.pendingSince = 0;\n            if (isMapzenRasterResponse) {\n                const resolvedZoom = Number.isFinite(Number(result?.sourceZoom))\n                    ? Number(result.sourceZoom)\n                    : rec.mapzenPendingSourceZoom;\n                rec.elevationSource = 'mapzen-geotiff-regional';\n                rec.mapzenResolvedZoom = Number.isFinite(resolvedZoom)\n                    ? resolvedZoom\n                    : rec.mapzenSourceZoom;\n                rec.mapzenPendingSourceZoom = null;\n                rec.fromCache = false;\n            }\n\n            // Queue for persistent cache\n            if (this.cacheEnabled && rec.key && Number.isFinite(elev)) {\n                this._queueCacheWrite(rec.key, elev, rec.maxTileLevel || 0);\n            }\n\n            if (this.debugLogLocations) {\n                const latStr = Number.isFinite(lat) ? lat.toFixed(6) : 'NaN';\n                const lngStr = Number.isFinite(lng) ? lng.toFixed(6) : 'NaN';\n                const elevStr = Number.isFinite(elev) ? elev.toFixed(1) : 'NaN';\n                const dot = this.cameraDir ? THREE.MathUtils.clamp(rec.dir.dot(this.cameraDir), -1, 1) : null;\n                const angleDeg = Number.isFinite(dot) ? (Math.acos(dot) * RAD2DEG) : null;\n                const angleStr = Number.isFinite(angleDeg) ? angleDeg.toFixed(2) : '–';\n                if (this.debugLogBatchSampleLimit === 0 || batchSamples.length < this.debugLogBatchSampleLimit) {\n                    batchSamples.push(`${latStr},${lngStr}=${elevStr}m Δ${angleStr}°`);\n                }\n            }\n\n            elevStats.min = Math.min(elevStats.min, elev);\n            elevStats.max = Math.max(elevStats.max, elev);\n            elevStats.sum += elev;\n            elevStats.count++;\n\n            let applied = 0;\n            for (const ref of rec.clients) {\n                ref.tile.updateVertex(ref.index, elev);\n                applied++;\n            }\n\n            if (!this.cacheEnabled && rec.key) {\n                for (const ref of rec.clients) {\n                    const keySet = this.tileVertexKeys.get(ref.tile);\n                    if (keySet) keySet.delete(rec.key);\n                }\n                this.vertexMap.delete(rec.key);\n                rec.clients = [];\n            }\n            return applied;\n        };\n\n        const retryInvalidRecord = (rec) => {\n            if (!rec || rec.status !== 'pending') return;\n            this._markRetry(rec, performance.now());\n        };\n\n        const toFiniteElevation = (value) => {\n            const elev = Number(value);\n            return Number.isFinite(elev) ? elev : null;\n        };\n        const positionalToleranceDeg = 5e-5;\n        const hasLocation = (result) => !!(\n            result &&\n            result.location &&\n            result.location.lat != null &&\n            result.location.lng != null\n        );\n        const resultMatchesBatchRecord = (result, rec) => {\n            if (!hasLocation(result) || !rec) return false;\n            const lat = Number(result.location.lat);\n            const lng = Number(result.location.lng);\n            if (!Number.isFinite(lat) || !Number.isFinite(lng)) return false;\n            if (!Number.isFinite(rec.lat) || !Number.isFinite(rec.lng)) return false;\n            return Math.abs(lat - rec.lat) <= positionalToleranceDeg &&\n                Math.abs(lng - rec.lng) <= positionalToleranceDeg;\n        };\n\n        for (let i = 0; i < json.results.length; i++) {\n            const r = json.results[i];\n            let rec = null;\n            let lat = null;\n            let lng = null;\n            if (r && r.location && r.location.lat != null && r.location.lng != null) {\n                lat = Number(r.location.lat);\n                lng = Number(r.location.lng);\n                const key = `${lat.toFixed(6)},${lng.toFixed(6)}`;\n                rec = this.vertexMap.get(key);\n            }\n            if (!rec) continue;\n\n            const elev = toFiniteElevation(r?.elevation);\n            if (!Number.isFinite(elev)) {\n                diag.invalidElevation++;\n                retryInvalidRecord(rec);\n                continue;\n            }\n            appliedCount += applyRecord(rec, elev, lat, lng, r);\n            diag.keyMatches++;\n            matchedIndices.add(i);\n        }\n\n        if (matchedIndices.size < json.results.length && thisBatch && thisBatch.length) {\n            const locationsPresent = json.results.some((result) => hasLocation(result));\n            const max = Math.min(json.results.length, thisBatch.length);\n            for (let i = 0; i < max; i++) {\n                if (matchedIndices.has(i)) continue;\n                const r = json.results[i];\n                const rec = thisBatch[i];\n                if (!rec) continue;\n                if (hasLocation(r)) {\n                    if (!resultMatchesBatchRecord(r, rec)) {\n                        diag.locationMismatches++;\n                        continue;\n                    }\n                } else if (locationsPresent) {\n                    // Mixed response format: avoid blind index mapping.\n                    continue;\n                }\n                const elev = toFiniteElevation(r?.elevation);\n                if (!Number.isFinite(elev)) {\n                    diag.invalidElevation++;\n                    retryInvalidRecord(rec);\n                    continue;\n                }\n                appliedCount += applyRecord(rec, elev, rec.lat, rec.lng, r);\n                diag.indexMatches++;\n                matchedIndices.add(i);\n            }\n        }\n\n        if (this.debugLogLocations && batchSamples.length) {\n            const suffix = (this.debugLogBatchSampleLimit > 0 && batchSamples.length >= this.debugLogBatchSampleLimit)\n                ? ' ...'\n                : '';\n            console.log(`[elev] batch samples (${batchSamples.length}) ${batchSamples.join(' | ')}${suffix}`);\n        }\n\n        if (this.debugLogStats && appliedCount > 0) {\n            const avg = elevStats.sum / elevStats.count;\n            console.log(`[elev] Applied ${appliedCount} elevations - min: ${elevStats.min.toFixed(1)}m, max: ${elevStats.max.toFixed(1)}m, avg: ${avg.toFixed(1)}m`);\n        }\n        if (this.debugLogStats && appliedCount > 0) {\n            const now = performance.now();\n            if (now - this._lastResponseLogMs >= this._responseLogIntervalMs) {\n                const kb = Math.round(bytesIn / 1024);\n                console.log(`[elev] response applied ${appliedCount}/${thisBatch.length} samples (${json.results.length} pts, ${kb} KB)`);\n                this._lastResponseLogMs = now;\n            }\n        } else if (this.debugLogStats && json.results.length) {\n            const now = performance.now();\n            if (now - this._lastNoMatchLogMs >= this._noMatchLogIntervalMs) {\n                console.warn('[elev] response had results but no matching vertices; check key precision or response mode');\n                this._lastNoMatchLogMs = now;\n            }\n        }\n\n        for (const rec of thisBatch) {\n            if (rec.status === 'pending') {\n                this._markRetry(rec, performance.now());\n                diag.retriedPending++;\n            }\n        }\n        diag.unmatchedResults = Math.max(0, json.results.length - matchedIndices.size);\n        this._logResponseMatchDiagnostics(diag, {\n            batchSize: thisBatch?.length || 0,\n            resultSize: json.results.length\n        });\n        return appliedCount > 0;\n    }\n\n    kickSurfaceMode({ clearPending = true } = {}) {\n        this._clearNknBackoff();\n        this._clearBackendFailures();\n        this.lastScheduleTime = 0;\n        this._activeCandidateCache = null;\n        if (clearPending) {\n            this.clearPendingRequests({ immediateReschedule: true });\n        }\n    }\n\n    _rollbackOutbound(ev) {\n        if (!ev) return;\n        const idx = this.sendEvents.indexOf(ev);\n        if (idx >= 0) {\n            this.sendEvents.splice(idx, 1);\n        }\n        if (this.stats.requestCount > 0) this.stats.requestCount -= 1;\n        if (Number.isFinite(ev.count)) {\n            this.stats.pointsRequested = Math.max(0, this.stats.pointsRequested - ev.count);\n        }\n        if (Number.isFinite(ev.bytes)) {\n            this.stats.bytesOut = Math.max(0, this.stats.bytesOut - ev.bytes);\n        }\n    }\n\n    _distanceRing(camPos, dir) {\n        if (!camPos || !dir) return 2;\n        const camDir = camPos.clone().normalize();\n        const dot = THREE.MathUtils.clamp(dir.dot(camDir), -1, 1);\n        const angle = Math.acos(dot);\n        const surfaceR = ellipsoidRadiusForLocalDir(dir);\n        const arcDist = angle * surfaceR;\n        const ellipsoidR = ellipsoidRadiusForLocalDir(camDir);\n        const alt = Math.max(0, camPos.length() - ellipsoidR);\n        const effective = Math.max(arcDist, alt);\n        if (effective <= this.ringNearMeters) return 0;\n        if (effective <= this.ringMidMeters) return 1;\n        return 2;\n    }\n\n    /**\n     * Remove all vertex records associated with a tile (called when tiles are destroyed)\n     */\n    pruneTile(tile, { keepRecords = false } = {}) {\n        if (!tile) return;\n\n        // Get the set of vertex keys for this tile\n        const keySet = this.tileVertexKeys.get(tile);\n        if (!keySet) return;\n\n        // Only iterate over this tile's vertices\n        for (const key of keySet) {\n            const rec = this.vertexMap.get(key);\n            if (!rec) continue;\n\n            // Remove this tile from the record's clients\n            rec.clients = rec.clients.filter(c => c.tile !== tile);\n\n            // Delete record if no clients remain\n            if (!rec.clients.length) {\n                if (keepRecords) {\n                    rec.lastUsed = performance.now();\n                } else {\n                    this.vertexMap.delete(key);\n                }\n            }\n        }\n\n        // Clean up the tile's key set\n        this.tileVertexKeys.delete(tile);\n    }\n\n    /**\n     * Clear vertices that are far from the camera (called when camera moves significantly)\n     * This prioritizes nearby vertices and prevents cache bloat\n     */\n    clearDistantVertices(maxDistanceM = 5_000_000) {\n        if (!this.cacheEnabled) return 0;\n        const camPos = this.cameraPos;\n        let cleared = 0;\n\n        for (const [key, rec] of this.vertexMap.entries()) {\n            if (rec.clients && rec.clients.length) continue;\n            if (rec.status === 'pending') continue; // Don't clear vertices mid-fetch\n\n            const baseR = ellipsoidRadiusForLocalDir(rec.dir);\n            const worldPos = rec.dir.clone().multiplyScalar(baseR);\n            const distance = worldPos.distanceTo(camPos);\n\n            if (distance > maxDistanceM) {\n                this.vertexMap.delete(key);\n                cleared++;\n            }\n        }\n\n        if (this.debugLogStats && cleared > 0) {\n            console.log(`[elev] Cleared ${cleared} distant vertices (>${(maxDistanceM/1000).toFixed(0)}km from camera)`);\n        }\n\n        return cleared;\n    }\n\n    /**\n     * Clear all pending vertex requests (use when switching modes/locations)\n     */\n    clearPendingRequests({ immediateReschedule = false } = {}) {\n        const now = performance.now();\n        let cleared = 0;\n        for (const rec of this.vertexMap.values()) {\n            if (rec.status === 'pending') {\n                if (immediateReschedule) {\n                    rec.status = 'new';\n                    rec.retryCount = 0;\n                    rec.nextRetryAt = 0;\n                    rec.pendingSince = 0;\n                } else {\n                    this._markRetry(rec, now);\n                }\n                cleared++;\n            }\n        }\n        if (this.debugLogStats && cleared > 0) {\n            console.log(`[elev] Cleared ${cleared} pending requests (${immediateReschedule ? 'reset' : 'retried'})`);\n        }\n        return cleared;\n    }\n\n    /**\n     * Clear lowest priority vertices (oldest/furthest) when cache is full\n     * This is a last-resort method to prevent cache gridlock\n     */\n    clearLowestPriorityVertices(targetCount) {\n        if (!this.cacheEnabled) return 0;\n        // Build array of all vertices with their current distance\n        const vertices = [];\n        const camPos = this.cameraPos;\n\n        for (const [key, rec] of this.vertexMap.entries()) {\n            if (rec.clients && rec.clients.length) continue;\n            if (rec.status === 'pending') continue; // Don't clear pending\n            const baseR = ellipsoidRadiusForLocalDir(rec.dir);\n            const worldPos = rec.dir.clone().multiplyScalar(baseR);\n            const distance = worldPos.distanceTo(camPos);\n            vertices.push({ key, distance, status: rec.status });\n        }\n\n        // Sort by distance (furthest first)\n        vertices.sort((a, b) => b.distance - a.distance);\n\n        // Clear the furthest ones\n        const toClear = Math.min(targetCount, vertices.length);\n        for (let i = 0; i < toClear; i++) {\n            this.vertexMap.delete(vertices[i].key);\n        }\n\n        if (this.debugLogStats) {\n            console.log(`[elev] Cleared ${toClear} lowest priority vertices (furthest from camera)`);\n        }\n        return toClear;\n    }\n\n    _evictStaleVertices(targetCount = 1000) {\n        if (!this.cacheEnabled) return 0;\n        const candidates = [];\n        for (const rec of this.vertexMap.values()) {\n            if (rec.status === 'pending') continue;\n            if (rec.clients && rec.clients.length) continue;\n            const lastUsed = Number.isFinite(rec.lastUsed) ? rec.lastUsed : 0;\n            candidates.push({ key: rec.key, lastUsed });\n        }\n        if (!candidates.length) return 0;\n        candidates.sort((a, b) => a.lastUsed - b.lastUsed);\n        const toRemove = Math.min(targetCount, candidates.length);\n        for (let i = 0; i < toRemove; i++) {\n            this.vertexMap.delete(candidates[i].key);\n        }\n        return toRemove;\n    }\n\n    _evictDoneVerticesUnderPressure(targetCount = 1000, { allowActiveClientTiles = false } = {}) {\n        if (!this.cacheEnabled) return 0;\n        if (!Number.isFinite(targetCount) || targetCount <= 0) return 0;\n\n        const candidates = [];\n        const camPos = this.cameraPos;\n        for (const rec of this.vertexMap.values()) {\n            if (!rec || rec.status !== 'done') continue;\n            if (!rec.dir) continue;\n\n            const clients = Array.isArray(rec.clients) ? rec.clients : [];\n            // Never evict records still bound to live tile vertices.\n            // Evicting bound records can leave tile vertex states stuck at \"registered\"\n            // with no backing rec, which starves fetch retries.\n            if (clients.length) continue;\n\n            const baseR = ellipsoidRadiusForLocalDir(rec.dir);\n            const worldPos = rec.dir.clone().multiplyScalar(baseR);\n            const distance = worldPos.distanceTo(camPos);\n            const level = Number.isFinite(rec.maxTileLevel)\n                ? rec.maxTileLevel\n                : (Number.isFinite(rec.tileLevel) ? rec.tileLevel : 0);\n            const hasClientsPenalty = clients.length ? 500000 : 0;\n            // Higher score = better eviction candidate (far, low-level, detached).\n            const evictScore = distance - (level * 25000) + hasClientsPenalty;\n            candidates.push({ key: rec.key, score: evictScore });\n        }\n\n        if (!candidates.length) return 0;\n        candidates.sort((a, b) => b.score - a.score);\n        const toRemove = Math.min(targetCount, candidates.length);\n        for (let i = 0; i < toRemove; i++) {\n            this.vertexMap.delete(candidates[i].key);\n        }\n        return toRemove;\n    }\n\n    _evictInactiveVertices(targetCount = 512) {\n        if (!this.cacheEnabled) return 0;\n        if (!Number.isFinite(targetCount) || targetCount <= 0) return 0;\n        const limit = Math.max(1, Math.floor(targetCount));\n        let removed = 0;\n        for (const [key, rec] of this.vertexMap.entries()) {\n            if (removed >= limit) break;\n            if (!rec || rec.status === 'pending') continue;\n            const clients = Array.isArray(rec.clients) ? rec.clients : [];\n            if (clients.length) continue;\n            this.vertexMap.delete(key);\n            removed++;\n        }\n        return removed;\n    }\n\n    hasVertexRecord(latDeg, lonDeg) {\n        const key = this._formatVertexKey(latDeg, lonDeg);\n        if (!key) return false;\n        return this.vertexMap.has(key);\n    }\n\n    _canSendBatch() {\n        const capKB = this.maxKBPerMinute;\n        if (!capKB || capKB <= 0) return true;\n        const now = performance.now();\n        const cutoff = now - this.windowMs;\n        let totalBytes = 0;\n        this.sendEvents = this.sendEvents.filter(ev => ev.t >= cutoff);\n        for (const ev of this.sendEvents) totalBytes += ev.bytes;\n        const totalKB = totalBytes / 1024;\n        return totalKB < capKB;\n    }\n\n    _isRetryReady(rec, now) {\n        return rec && rec.status === 'error' && (!rec.nextRetryAt || now >= rec.nextRetryAt);\n    }\n\n    _markRetry(rec, now, { immediate = false } = {}) {\n        if (!rec) return;\n        rec.pendingSince = 0;\n        rec.status = 'error';\n        if (immediate) {\n            rec.retryCount = 0;\n            rec.nextRetryAt = 0;\n            return;\n        }\n        const count = (rec.retryCount || 0) + 1;\n        rec.retryCount = count;\n        const delay = Math.min(this.retryBaseDelayMs * Math.pow(2, Math.min(count - 1, 6)), this.retryMaxDelayMs);\n        rec.nextRetryAt = now + delay;\n    }\n\n    _formatVertexKey(latDeg, lonDeg) {\n        if (!Number.isFinite(latDeg) || !Number.isFinite(lonDeg)) return null;\n        return `${latDeg.toFixed(6)},${lonDeg.toFixed(6)}`;\n    }\n\n    getCachedElevationMeters(latDeg, lonDeg) {\n        const key = this._formatVertexKey(latDeg, lonDeg);\n        if (!key) return null;\n        this.stats.cacheLookupCount += 1;\n        const rec = this.vertexMap.get(key);\n        if (!rec || rec.status !== 'done') return null;\n        const elev = Number.isFinite(rec.height)\n            ? rec.height\n            : (Number.isFinite(rec.elev) ? rec.elev : null);\n        if (!Number.isFinite(elev)) return null;\n        this.stats.cacheLookupHits += 1;\n        return elev;\n    }\n\n    registerVertex(latDeg, lonDeg, dir, tile, index) {\n        if (this._oceanResolver && tile && typeof tile.updateVertex === 'function') {\n            const ocean = this._oceanResolver(latDeg, lonDeg, dir, tile, index);\n            if (ocean && ocean.isOcean) {\n                const mask = Number.isFinite(ocean.waterMask) ? ocean.waterMask : 1;\n                if (typeof tile.setWaterMask === 'function') {\n                    tile.setWaterMask(index, mask);\n                }\n                // Classify water without replacing the provider's seabed with\n                // a sea-level cap; the ocean renderer owns the water surface.\n            } else if (ocean && Number.isFinite(ocean.waterMask) && typeof tile.setWaterMask === 'function') {\n                tile.setWaterMask(index, ocean.waterMask);\n            }\n        }\n\n        const key = this._formatVertexKey(latDeg, lonDeg);\n        if (!key) return false;\n        const mapzenSourceZoom = resolveMapzenSourceZoomForTriangle({\n            angularRadius: tile?.angularRadius,\n            resolution: tile?.resolution,\n            tileLevel: tile?.level,\n            latitude: latDeg\n        });\n\n        // Track this vertex key for the tile\n        let keySet = this.tileVertexKeys.get(tile);\n        if (!keySet) {\n            keySet = new Set();\n            this.tileVertexKeys.set(tile, keySet);\n        }\n        keySet.add(key);\n\n        const tileCache = tile?.elevationCache;\n        const hasCache = tileCache &&\n            tileCache.res === tile?.resolution &&\n            tileCache.done &&\n            tileCache.done[index] === 1 &&\n            tileCache.heights &&\n            Number.isFinite(tileCache.heights[index]);\n        const cachedHeight = hasCache ? tileCache.heights[index] : null;\n\n        let rec = this.vertexMap.get(key);\n        if (!rec) {\n            // O(1) capacity gate — eviction is handled proactively in tick(),\n            // never inline here.  If tick() hasn't freed enough headroom yet,\n            // the tile stays flat until the next frame.  Zero CPU cost.\n            if (this.cacheEnabled && this.vertexMap.size >= this.maxVertexRecords) {\n                return false;\n            }\n            rec = {\n                key,\n                lat: latDeg,\n                lng: lonDeg,\n                dir: dir.clone(),\n                clients: [],\n                status: Number.isFinite(cachedHeight) ? 'done' : 'new',\n                distance: Infinity,\n                height: Number.isFinite(cachedHeight) ? cachedHeight : 0,\n                maxTileLevel: tile.level, // Track highest LOD level needing this vertex\n                minTileLevel: tile.level, // Track lowest LOD level needing this vertex (base pass gating)\n                retryCount: 0,\n                nextRetryAt: 0,\n                pendingSince: 0,\n                lastUsed: performance.now(),\n                fromCache: Number.isFinite(cachedHeight),\n                mapzenSourceZoom,\n                mapzenResolvedZoom: null,\n                elevationSource: Number.isFinite(cachedHeight) ? 'persistent-cache' : null\n            };\n            this.vertexMap.set(key, rec);\n        } else {\n            // Update max tile level if this tile is higher detail\n            rec.maxTileLevel = Math.max(rec.maxTileLevel || 0, tile.level);\n            rec.minTileLevel = Math.min(rec.minTileLevel ?? tile.level, tile.level);\n            rec.mapzenSourceZoom = Math.max(\n                Number.isFinite(rec.mapzenSourceZoom) ? rec.mapzenSourceZoom : 0,\n                mapzenSourceZoom\n            );\n            rec.lastUsed = performance.now();\n            if (Number.isFinite(cachedHeight) && (!Number.isFinite(rec.height) || rec.status !== 'done')) {\n                rec.height = cachedHeight;\n                rec.status = 'done';\n                rec.retryCount = 0;\n                rec.nextRetryAt = 0;\n                rec.pendingSince = 0;\n                rec.fromCache = true;\n            }\n        }\n        if (!rec.clients.some(c => c.tile === tile && c.index === index)) {\n            rec.clients.push({ tile, index });\n        }\n\n        // A coarse/cache height remains a useful visual seed, but the active\n        // TriTree branch must refine it from the source level matched to its\n        // current vertex interval.\n        const hasSeedHeight = Number.isFinite(rec.height)\n            && (rec.status === 'done' || rec.elevationSource || rec.fromCache);\n        if (hasSeedHeight) {\n            tile.updateVertex(index, rec.height);\n        }\n        if (this.enableMapzenRasterTiles && rec.status === 'done' && (\n            rec.elevationSource !== 'mapzen-geotiff-regional'\n            || !Number.isFinite(rec.mapzenResolvedZoom)\n            || rec.mapzenResolvedZoom < rec.mapzenSourceZoom\n        )) {\n            rec.status = 'new';\n            rec.retryCount = 0;\n            rec.nextRetryAt = 0;\n            rec.pendingSince = 0;\n        }\n        return true;\n    }\n\n    updateCamera(camera, focusDirection = null) {\n        // Transform camera vectors into planet-local space for coherent scheduling\n        const invQ = this.planetGroup ? this.planetGroup.quaternion.clone().invert() : null;\n\n        // Transform camera position\n        const worldPos = camera?.userData?.worldPosition;\n        const camPos = worldPos ? worldPos.clone() : camera.position.clone();\n        if (invQ) camPos.applyQuaternion(invQ);\n\n        // Always update camera anchor first so cache-distance decisions use current position.\n        this.cameraPos.copy(camPos);\n\n        // First sample anchors movement tracking; do not invalidate cache on bootstrap frame.\n        if (!this._hasCameraAnchor) {\n            this.lastCameraPos.copy(camPos);\n            this._hasCameraAnchor = true;\n        }\n\n        if (this.cacheEnabled) {\n            // CRITICAL: Detect major camera movement and clear distant cache\n            const cameraMoveDistance = this.lastCameraPos.distanceTo(camPos);\n            if (cameraMoveDistance > this.cacheInvalidationDistanceM) {\n                if (this.debugLogStats) {\n                    console.log(`[elev] Camera moved ${(cameraMoveDistance/1000).toFixed(0)}km - clearing distant vertices`);\n                }\n                this.clearPendingRequests(); // Clear stale pending requests\n                this.clearDistantVertices(2_000_000); // Clear vertices >2000km away\n            }\n            // Also clear if cache is at capacity\n            if (this.vertexMap.size >= this.maxVertexRecords * 0.95) {\n                if (this.debugLogStats) {\n                    console.log(`[elev] Cache at ${this.vertexMap.size}/${this.maxVertexRecords} - clearing distant vertices`);\n                }\n                // Try increasingly aggressive clearing until we free up space\n                let cleared = this.clearDistantVertices(3_000_000);\n\n                // CRITICAL: Check total cleared, not per-stage cleared\n                if (cleared < 1000) {\n                    cleared += this.clearDistantVertices(1_000_000);\n                }\n                if (cleared < 1000) {\n                    cleared += this.clearDistantVertices(500_000);\n                }\n                if (cleared < 1000) {\n                    // Nuclear option: clear half the cache starting with lowest priority\n                    cleared += this.clearLowestPriorityVertices(this.maxVertexRecords / 2);\n                }\n\n                if (this.debugLogStats) {\n                    console.log(`[elev] Total cleared: ${cleared} vertices, cache now at ${this.vertexMap.size}`);\n                }\n            }\n        }\n        this.lastCameraPos.copy(camPos);\n        this._maybeWarmPersistentCacheNearby(camPos);\n\n        // Transform focus/view direction\n        if (focusDirection) {\n            const fd = focusDirection.clone();\n            if (invQ) fd.applyQuaternion(invQ);\n            // CRITICAL: Normalize focus direction before storing\n            fd.normalize();\n            // Guard against zero-length vectors\n            if (fd.lengthSq() < 1e-6) {\n                fd.set(0, 0, -1); // Default fallback\n            }\n            this.cameraDir.copy(fd);\n            this.lastFocusLatLon = dirToLatLonLocal(fd);\n            // Debug assertion for normalization\n            if (Math.abs(this.cameraDir.length() - 1) > 1e-3) {\n                console.warn('[elev] cameraDir not normalized:', this.cameraDir.length());\n            }\n        } else {\n            const d = new THREE.Vector3();\n            camera.getWorldDirection(d);\n            if (invQ) d.applyQuaternion(invQ);\n            d.normalize();\n            this.cameraDir.copy(d);\n            this.lastFocusLatLon = dirToLatLonLocal(d);\n        }\n\n        this.cameraFovRad = camera.fov * DEG2RAD;\n    }\n\n    /**\n     * Proactive, time-budgeted vertex eviction.  Called once per tick (once per\n     * frame) so the hot registerVertex() path stays O(1).\n     *\n     * Starts evicting when the map exceeds the high-water mark (default 90%\n     * of maxVertexRecords).  Work is capped to _evictionBudgetMs so it never\n     * dominates a frame even on large maps.\n     */\n    _proactiveEviction(now) {\n        if (!this.cacheEnabled) return;\n        const size = this.vertexMap.size;\n        const max = this.maxVertexRecords;\n        if (!max || size < max * this._evictionHighWaterMark) return;\n\n        const deadline = now + this._evictionBudgetMs;\n        // If a runtime policy just lowered the ceiling, catch up to that hard\n        // cap instead of freeing only five percent and letting stale records\n        // occupy the old budget for minutes.\n        const overCapacity = Math.max(0, size - max);\n        const targetFree = Math.max(\n            64,\n            Math.ceil(max * this._evictionTargetFreeRatio),\n            overCapacity,\n        );\n        let freed = 0;\n\n        // --- Pass 1: stale (no clients, older than 10s) ---\n        {\n            for (const [key, rec] of this.vertexMap) {\n                if (freed >= targetFree) break;\n                if (performance.now() > deadline) break;\n                if (rec.status === 'pending') continue;\n                if (rec.clients && rec.clients.length) continue;\n                const lu = Number.isFinite(rec.lastUsed) ? rec.lastUsed : 0;\n                if ((now - lu) > 10000) {\n                    this.vertexMap.delete(key);\n                    freed++;\n                }\n            }\n        }\n\n        if (freed >= targetFree || performance.now() > deadline) return;\n\n        // --- Pass 2: done, no clients, furthest from camera ---\n        {\n            const camPos = this.cameraPos;\n            for (const [key, rec] of this.vertexMap) {\n                if (freed >= targetFree) break;\n                if (performance.now() > deadline) break;\n                if (!rec || rec.status !== 'done') continue;\n                if (rec.clients && rec.clients.length) continue;\n                if (!rec.dir) { this.vertexMap.delete(key); freed++; continue; }\n                const baseR = ellipsoidRadiusForLocalDir(rec.dir);\n                const wx = rec.dir.x * baseR;\n                const wy = rec.dir.y * baseR;\n                const wz = rec.dir.z * baseR;\n                const dx = wx - camPos.x, dy = wy - camPos.y, dz = wz - camPos.z;\n                const distSq = dx * dx + dy * dy + dz * dz;\n                // Evict anything > 200km from camera (cheap squared compare)\n                if (distSq > 200000 * 200000) {\n                    this.vertexMap.delete(key);\n                    freed++;\n                }\n            }\n        }\n\n        if (freed >= targetFree || performance.now() > deadline) return;\n\n        // --- Pass 3: any non-pending, no-client record (last resort) ---\n        {\n            for (const [key, rec] of this.vertexMap) {\n                if (freed >= targetFree) break;\n                if (performance.now() > deadline) break;\n                if (rec.status === 'pending') continue;\n                if (rec.clients && rec.clients.length) continue;\n                this.vertexMap.delete(key);\n                freed++;\n            }\n        }\n    }\n\n    /**\n     * Establish the user/device-selected vertex budget. Pressure only adjusts\n     * the effective ceiling; it never loses the baseline used for recovery.\n     */\n    setMemoryBudgetBaseline(maxRecords) {\n        if (!Number.isFinite(maxRecords) || maxRecords <= 0) return;\n        this._memoryBudgetBaseline = Math.max(1_000, Math.floor(maxRecords));\n        this._applyMemoryPressureCap();\n    }\n\n    /**\n     * Shed detached elevation records under a scene-memory governor. This is\n     * intentionally O(1): tick() performs bounded eviction work afterwards.\n     */\n    applyMemoryPressure(level) {\n        const next = Math.max(0, Math.min(1, Number(level) || 0));\n        if (Math.abs(next - this._memoryPressure) < 0.02) return;\n        this._memoryPressure = next;\n        this._applyMemoryPressureCap();\n    }\n\n    _applyMemoryPressureCap() {\n        const baseline = Math.max(1_000, Math.floor(this._memoryBudgetBaseline || this.maxVertexRecords || 1_000));\n        // At maximum pressure preserve a small local working set, then rely\n        // on the existing time-budgeted eviction path to drain old records.\n        const floor = Math.min(baseline, Math.max(8_000, Math.floor(baseline * 0.28)));\n        const nextCap = Math.round(baseline - ((baseline - floor) * this._memoryPressure));\n        this.maxVertexRecords = Math.max(floor, nextCap);\n    }\n\n    tick() {\n        const now = performance.now();\n        this._proactiveEviction(now);\n        this._recoverStalePending(now);\n        const useBackend = this._shouldUseBackend(now);\n        const allowFallback = !useBackend && this._shouldUseFallbacks();\n        const effectiveMaxConcurrent = this._getEffectiveMaxConcurrentBatches();\n        const effectiveMinIntervalMs = this._getEffectiveMinIntervalMs();\n        if (!useBackend && allowFallback) {\n            this._logBackendFallbackTransition({\n                reason: 'backend-backoff',\n                batchSize: this.batchSize,\n                fallbackTried: false\n            });\n        }\n        if (!useBackend && !allowFallback) return;\n        if (this.currentBatches >= effectiveMaxConcurrent) return;\n        if (!this._canSendBatch()) return;\n        if (now - this.lastScheduleTime < effectiveMinIntervalMs) return;\n        this.lastScheduleTime = now;\n\n        const cameraPos = this.cameraPos;\n        const viewDir = this.cameraDir;\n        const maxAngle = this.cameraFovRad * 0.75;\n        const useActiveTiles = this.activeTilePriorities.size > 0;\n        let activeCandidates = null;\n        let activeCandidateCount = 0;\n\n        // Calculate altitude to determine LOD requirements\n        const camDist = cameraPos.length() || PLANET_RADIUS;\n        const camDirLocal = camDist > 0 ? cameraPos.clone().normalize() : null;\n        const ellipsoidR = camDirLocal ? ellipsoidRadiusForLocalDir(camDirLocal) : PLANET_RADIUS;\n        const altitude = camDist - ellipsoidR;\n        let camDir = null;\n        let viewshedLimitRad = 0;\n        const computeViewshed = () => {\n            camDir = cameraPos.clone().normalize();\n            const horizonRad = Math.acos(THREE.MathUtils.clamp(ellipsoidR / camDist, -1, 1));\n            const viewshedMinRad = (this.viewshedMinDeg || 0) * DEG2RAD;\n            const viewshedMarginRad = (this.viewshedMarginDeg || 0) * DEG2RAD;\n            viewshedLimitRad = Math.max(horizonRad, viewshedMinRad) + viewshedMarginRad;\n        };\n        if (!useActiveTiles) {\n            computeViewshed();\n        }\n\n        // Minimum tile level to fetch elevation for based on altitude\n        // Keep coarse tiles gated in global scans, but allow active/visible tiles through.\n        let minLevelToFetch = this.surfaceMinLevel || 0;\n        if (altitude > 2_000_000) minLevelToFetch = 0;       // > 2000km: only root tiles\n        else if (altitude > 1_000_000) minLevelToFetch = 1;  // 1000-2000km: level 1+\n        else if (altitude > 500_000) minLevelToFetch = 1;    // 500-1000km: level 1+\n        else if (altitude > 200_000) minLevelToFetch = 2;    // 200-500km: level 2+\n        else if (altitude > 100_000) minLevelToFetch = 2;    // 100-200km: level 2+\n        else if (altitude < 100) minLevelToFetch = Math.max(this.surfaceMinLevel || 0, 1);\n        else minLevelToFetch = Math.max(this.surfaceMinLevel || 0, 1); // < 100km: skip only root level\n\n        const inView = this._inView;\n        const offView = this._offView;\n        inView.length = 0;\n        offView.length = 0;\n\n        const ANGLE_LIMIT_DEG = this.angleLimitDeg || 80; // allow wider window to keep work flowing\n\n        const filterInPlace = (list, predicate) => {\n            let write = 0;\n            for (let i = 0; i < list.length; i++) {\n                const item = list[i];\n                if (predicate(item)) {\n                    list[write++] = item;\n                }\n            }\n            list.length = write;\n            return list;\n        };\n\n        if (useActiveTiles) {\n            const cache = this._activeCandidateCache;\n            const hasForcedActiveTiles = this._activeTileEntries.some(([tile]) =>\n                !!(tile && (tile._elevForceFetch || tile.forceFullFetch || tile._surfaceForceFullFetch))\n            );\n            if (!hasForcedActiveTiles &&\n                cache &&\n                Number.isFinite(cache.time) &&\n                cache.entries &&\n                (now - cache.time) < (this.activeCandidateCacheMs || 0)) {\n                activeCandidates = cache.entries;\n                activeCandidateCount = activeCandidates.length;\n            } else {\n                const baseMaxCandidates = Number.isFinite(this.activeCandidateMax)\n                    ? Math.max(this.batchSize * 2, this.activeCandidateMax)\n                    : Math.max(this.batchSize * 12, 1024);\n                const maxTiles = Number.isFinite(this.activeTileScanMax)\n                    ? this.activeTileScanMax\n                    : 64;\n                const candidateMap = new Map();\n                const activeTiles = this._activeTileEntries;\n                const activeTileCount = activeTiles.length;\n                const activeTileLimit = Math.min(\n                    activeTileCount,\n                    Math.max(1, maxTiles)\n                );\n                let selectedActiveTiles = activeTiles;\n                let selectedActiveTileCount = activeTileLimit;\n                if (activeTileCount > activeTileLimit) {\n                    const desiredProbeCount = Math.max(1, Math.floor(activeTileLimit * 0.1));\n                    const probeCount = Math.min(\n                        desiredProbeCount,\n                        Math.max(0, activeTileLimit - 1)\n                    );\n                    const headCount = Math.max(1, activeTileLimit - probeCount);\n                    const overflowStart = headCount;\n                    const overflowCount = Math.max(0, activeTileCount - overflowStart);\n                    const window = [];\n\n                    for (let i = 0; i < headCount && i < activeTileCount; i++) {\n                        window.push(activeTiles[i]);\n                    }\n\n                    if (probeCount > 0 && overflowCount > 0) {\n                        let cursor = this._activeTileOverflowCursor || 0;\n                        cursor %= overflowCount;\n                        for (let i = 0; i < probeCount; i++) {\n                            const idx = overflowStart + ((cursor + i) % overflowCount);\n                            const entry = activeTiles[idx];\n                            if (entry) window.push(entry);\n                        }\n                        this._activeTileOverflowCursor = (cursor + probeCount) % overflowCount;\n                    } else {\n                        this._activeTileOverflowCursor = 0;\n                    }\n\n                    selectedActiveTiles = window;\n                    selectedActiveTileCount = window.length;\n                } else {\n                    this._activeTileOverflowCursor = 0;\n                }\n                const desiredPerTileLimit = Number.isFinite(this.activeTileScanPerTile)\n                    ? Math.max(1, Math.floor(this.activeTileScanPerTile))\n                    : 256;\n                const maxCandidates = Math.max(baseMaxCandidates, selectedActiveTileCount);\n                const perTileLimit = Math.max(\n                    1,\n                    Math.min(desiredPerTileLimit, Math.floor(maxCandidates / Math.max(1, selectedActiveTileCount)))\n                );\n                const forcedSeedLimit = Math.max(1, Math.min(8, Math.floor(perTileLimit * 0.25)));\n                const forcedScanLimit = Math.max(\n                    perTileLimit,\n                    Math.min(maxCandidates, Math.max(desiredPerTileLimit * 4, 128))\n                );\n\n                const scanTileKeys = (tile, priority, scanLimit, forceTile) => {\n                    if (!tile || candidateMap.size >= maxCandidates) return;\n                    const keySet = this.tileVertexKeys.get(tile);\n                    if (!keySet || !keySet.size) return;\n\n                    let tileLevel = Number.isFinite(tile?.level) ? tile.level : -1;\n                    const cap = tile?.surfaceLodCap;\n                    if (Number.isFinite(cap) && Number.isFinite(tileLevel)) {\n                        tileLevel = Math.min(tileLevel, cap);\n                    }\n\n                    let cacheEntry = this._activeTileKeyCache.get(tile);\n                    if (!cacheEntry || cacheEntry.size !== keySet.size) {\n                        cacheEntry = {\n                            keys: Array.from(keySet),\n                            size: keySet.size,\n                            cursor: 0\n                        };\n                        this._activeTileKeyCache.set(tile, cacheEntry);\n                    }\n\n                    const keys = cacheEntry.keys;\n                    const keyCount = keys.length;\n                    if (!keyCount) return;\n\n                    let cursor = cacheEntry.cursor || 0;\n                    let scanned = 0;\n                    const limit = Math.min(scanLimit, keyCount);\n\n                    while (scanned < limit && candidateMap.size < maxCandidates) {\n                        const key = keys[cursor];\n                        cursor = (cursor + 1) % keyCount;\n                        scanned++;\n\n                        const rec = this.vertexMap.get(key);\n                        if (!rec) continue;\n                        const canRetry = this._isRetryReady(rec, now);\n                        if (rec.status !== 'new' && !canRetry) continue;\n\n                        let entry = candidateMap.get(key);\n                        if (!entry) {\n                            entry = {\n                                rec,\n                                maxLevel: -Infinity,\n                                minLevel: Infinity,\n                                maxPriority: 0,\n                                force: false\n                            };\n                            candidateMap.set(key, entry);\n                        }\n                        if (Number.isFinite(tileLevel)) {\n                            entry.maxLevel = Math.max(entry.maxLevel, tileLevel);\n                            entry.minLevel = Math.min(entry.minLevel, tileLevel);\n                        }\n                        entry.maxPriority = Math.max(entry.maxPriority, priority || 0);\n                        if (forceTile) {\n                            entry.force = true;\n                        }\n                    }\n\n                    cacheEntry.cursor = cursor;\n                };\n\n                const forcedTiles = [];\n                const normalTiles = [];\n                for (let i = 0; i < selectedActiveTileCount; i++) {\n                    const entry = selectedActiveTiles[i];\n                    const tile = entry?.[0];\n                    if (tile && tile._elevForceFetch) {\n                        forcedTiles.push(entry);\n                    } else {\n                        normalTiles.push(entry);\n                    }\n                }\n\n                // Seed at least one candidate per forced tile (when possible) to prevent starvation.\n                if (forcedTiles.length) {\n                    for (const [tile, priority] of forcedTiles) {\n                        if (candidateMap.size >= maxCandidates) break;\n                        scanTileKeys(tile, priority, forcedSeedLimit, true);\n                    }\n                }\n\n                for (const [tile, priority] of forcedTiles) {\n                    if (candidateMap.size >= maxCandidates) break;\n                    scanTileKeys(tile, priority, forcedScanLimit, true);\n                }\n                for (const [tile, priority] of normalTiles) {\n                    if (candidateMap.size >= maxCandidates) break;\n                    scanTileKeys(tile, priority, perTileLimit, false);\n                }\n\n                const nextCandidates = this._activeCandidatesScratch;\n                nextCandidates.length = 0;\n                for (const entry of candidateMap.values()) {\n                    nextCandidates.push(entry);\n                }\n                activeCandidates = nextCandidates;\n                activeCandidateCount = nextCandidates.length;\n                this._activeCandidateCache = {\n                    time: now,\n                    entries: nextCandidates\n                };\n            }\n        }\n\n        const useActiveRecords = useActiveTiles && activeCandidateCount > 0;\n        if (!useActiveRecords && !camDir) {\n            computeViewshed();\n        }\n\n        const records = useActiveRecords ? activeCandidates : this.vertexMap.values();\n        if (!records) return;\n\n        for (const entry of records) {\n            const rec = useActiveRecords ? entry?.rec : entry;\n            if (!rec) continue;\n            if (!rec.clients || rec.clients.length === 0) continue;\n            // Only touch the bounded active/viewshed candidate set. This\n            // incrementally replaces legacy/persistent seeds with the same\n            // Mapzen pyramid used by RAW ELEVATION without an O(N) cache sweep\n            // when terrain mode changes.\n            if (this.enableMapzenRasterTiles && rec.status === 'done' && (\n                rec.elevationSource !== 'mapzen-geotiff-regional'\n                || !Number.isFinite(rec.mapzenResolvedZoom)\n                || rec.mapzenResolvedZoom < (rec.mapzenSourceZoom || 0)\n            )) {\n                rec.status = 'new';\n                rec.retryCount = 0;\n                rec.nextRetryAt = 0;\n                rec.pendingSince = 0;\n            }\n            const canRetry = this._isRetryReady(rec, now);\n            if (rec.status !== 'new' && !canRetry) continue;\n            const force = useActiveRecords ? !!entry?.force : false;\n            rec.force = force;\n\n            // Skip vertices from low-detail tiles when zoomed in\n            // Only fetch elevation for tiles at appropriate LOD level\n            let tileLevel = rec.maxTileLevel || 0;\n            rec.tileLevel = tileLevel;\n            let activePriority = 0;\n            if (useActiveRecords) {\n                const maxLevel = Number.isFinite(entry?.maxLevel) ? entry.maxLevel : tileLevel;\n                tileLevel = Number.isFinite(maxLevel) ? maxLevel : tileLevel;\n                rec.tileLevel = tileLevel;\n                activePriority = Number.isFinite(entry?.maxPriority) ? entry.maxPriority : 0;\n            }\n            rec.activePriority = activePriority;\n            const entryMin = Number.isFinite(entry?.minLevel) ? entry.minLevel : Infinity;\n            const recMin = Number.isFinite(rec.minTileLevel) ? rec.minTileLevel : Infinity;\n            const baseLevel = Number.isFinite(Math.min(entryMin, recMin))\n                ? Math.min(entryMin, recMin)\n                : tileLevel;\n            rec.baseLevel = baseLevel;\n            const baseR = ellipsoidRadiusForLocalDir(rec.dir);\n            const worldPos = rec.dir.clone().multiplyScalar(baseR);\n            rec.distance = worldPos.distanceTo(cameraPos);\n            const ring = this._distanceRing(cameraPos, rec.dir);\n            rec.ring = ring;\n            const ringCap = (ring === 0) ? this.ringLodCaps.near\n                : (ring === 1 ? this.ringLodCaps.mid : this.ringLodCaps.far);\n            const allowForce = force;\n            if (Number.isFinite(this.targetMaxLevel) && tileLevel > this.targetMaxLevel) continue;\n            if (tileLevel < minLevelToFetch && !allowForce && !useActiveRecords) continue;\n            if (Number.isFinite(ringCap) && tileLevel > ringCap && !allowForce && !useActiveRecords) continue;\n\n            if (useActiveRecords) {\n                if (force) {\n                    const forceLevel = Number.isFinite(rec.baseLevel)\n                        ? rec.baseLevel\n                        : (Number.isFinite(tileLevel) ? tileLevel : 0);\n                    rec.forceLevel = forceLevel;\n                    rec.forceDistance = rec.distance;\n                    const basePriority = 1_000_000_000;\n                    const levelWeight = 250_000;\n                    const distClamp = 50_000_000;\n                    const distPenalty = Number.isFinite(rec.distance)\n                        ? Math.min(rec.distance, distClamp)\n                        : distClamp;\n                    rec.priority = basePriority + (forceLevel * levelWeight) - distPenalty;\n                    inView.push(rec);\n                } else {\n                    const maxDist = ellipsoidR * 2;\n                    const distScore = 1.0 - Math.min(rec.distance / maxDist, 1.0);\n                    const ringFactor = ring === 0\n                        ? this.ringPriorityWeights.near\n                        : (ring === 1 ? this.ringPriorityWeights.mid : this.ringPriorityWeights.far);\n                    rec.priority = (activePriority + distScore * 0.05) * ringFactor;\n                    inView.push(rec);\n                }\n            } else {\n                // Cull vertices beyond viewshed (based on horizon from camera position)\n                const dotCam = THREE.MathUtils.clamp(rec.dir.dot(camDir), -1, 1);\n                const angleToCam = Math.acos(dotCam);\n                if (angleToCam > viewshedLimitRad) continue;\n\n                const dot = THREE.MathUtils.clamp(rec.dir.dot(viewDir), -1, 1);\n                const angle = Math.acos(dot);\n                const angleDeg = angle * RAD2DEG;\n\n                // Calculate priority: combine distance (closer = better) and angle (center = better)\n                // CRITICAL: On surface (altitude < 1000m), heavily favor nearby vertices\n                let distScore, angleScore, lodScore;\n\n                if (altitude < 1000) {\n                    // Surface mode: exponential distance penalty (very close = much better)\n                    distScore = Math.exp(-rec.distance / 50000); // 50km falloff\n                    angleScore = Math.exp(-angleDeg / 30.0);\n                    lodScore = (tileLevel / 10.0) * 0.2; // Higher LOD bonus on surface\n\n                    // Surface priority: 70% distance, 20% angle, 10% LOD\n                    rec.priority = distScore * 0.7 + angleScore * 0.2 + lodScore * 0.1;\n                } else {\n                    // Space/orbit mode: linear distance penalty\n                    const maxDist = ellipsoidR * 2;\n                    distScore = 1.0 - Math.min(rec.distance / maxDist, 1.0);\n                    angleScore = Math.exp(-angleDeg / 20.0);\n                    lodScore = (tileLevel / 10.0) * 0.1;\n\n                    // Orbit priority: 60% distance, 30% angle, 10% LOD\n                    rec.priority = distScore * 0.6 + angleScore * 0.3 + lodScore * 0.1;\n                }\n\n                // Ring weighting: near dominates, mid/far downweighted\n                const ringFactor = ring === 0\n                    ? this.ringPriorityWeights.near\n                    : (ring === 1 ? this.ringPriorityWeights.mid : this.ringPriorityWeights.far);\n                rec.priority *= ringFactor;\n\n                // Skip vertices far off the view direction to prevent unbounded work\n                if (angleDeg > ANGLE_LIMIT_DEG) continue;\n\n                if (angle < maxAngle) inView.push(rec);\n                else if (angleDeg < 90) offView.push(rec); // Only include front hemisphere\n            }\n        }\n\n        if (!inView.length && !offView.length) return;\n\n        // IMPORTANT: Only run global base/coarse gating when scanning the global vertex map.\n        // In active-tile mode this gate can indefinitely starve outer-ring detail completion.\n        if (!useActiveRecords) {\n            const basePassLevel = Number.isFinite(this.surfaceMinLevel) ? this.surfaceMinLevel : null;\n            const basePassActive = Number.isFinite(basePassLevel) && basePassLevel > 0 && altitude < 200_000;\n            if (basePassActive) {\n                const hasBasePending = (list) => list.some((r) => {\n                    const level = Number.isFinite(r.baseLevel) ? r.baseLevel : r.tileLevel;\n                    return r.status === 'new' && Number.isFinite(level) && level <= basePassLevel;\n                });\n                if (hasBasePending(inView) || hasBasePending(offView)) {\n                    const allowBase = (r) => {\n                        const level = Number.isFinite(r.baseLevel) ? r.baseLevel : r.tileLevel;\n                        return r.status !== 'new' || !Number.isFinite(level) || level <= basePassLevel;\n                    };\n                    // Keep near/mid rings progressing while far ring satisfies base pass.\n                    filterInPlace(inView, (r) => (r.ring <= 1) || allowBase(r));\n                    filterInPlace(offView, allowBase);\n                }\n            } else {\n                const coarseOutstanding = inView.some(r => r.status === 'new' && r.tileLevel <= this.ringLodCaps.far);\n                if (coarseOutstanding) {\n                    filterInPlace(inView, (r) => r.tileLevel <= this.ringLodCaps.mid || r.status !== 'new');\n                    filterInPlace(offView, (r) => r.tileLevel <= this.ringLodCaps.mid || r.status !== 'new');\n                }\n            }\n        }\n\n        // Pre-compute sort keys to avoid repeated Number.isFinite checks during sort\n        const computeSortKey = (r) => {\n            const ringRank = r.ring === 0 ? 0 : (r.ring === 1 ? 1 : 2);\n            const level = r.forceLevel ?? r.baseLevel ?? r.tileLevel ?? 0;\n            const dist = r.forceDistance ?? r.distance ?? Infinity;\n            const tilePriority = Number.isFinite(r.activePriority) ? r.activePriority : -Infinity;\n            return { ringRank, level, dist, tilePriority };\n        };\n\n        const forcedInView = this._forcedInView;\n        const normalInView = this._normalInView;\n        const forcedOffView = this._forcedOffView;\n        const normalOffView = this._normalOffView;\n        forcedInView.length = 0;\n        normalInView.length = 0;\n        forcedOffView.length = 0;\n        normalOffView.length = 0;\n        for (const r of inView) {\n            if (r.force) {\n                forcedInView.push(r);\n            } else {\n                normalInView.push(r);\n            }\n        }\n        for (const r of offView) {\n            if (r.force) {\n                forcedOffView.push(r);\n            } else {\n                normalOffView.push(r);\n            }\n        }\n\n        // Pre-compute sort keys for forced arrays\n        for (const r of forcedInView) r._sortKey = computeSortKey(r);\n        for (const r of forcedOffView) r._sortKey = computeSortKey(r);\n\n        // Forced fetches should expand from center (underfoot) outward on surface.\n        const forcedSort = (a, b) => {\n            const ka = a._sortKey, kb = b._sortKey;\n            if (ka.ringRank !== kb.ringRank) return ka.ringRank - kb.ringRank;\n            if (ka.dist !== kb.dist) return ka.dist - kb.dist;\n            if (ka.tilePriority !== kb.tilePriority) return kb.tilePriority - ka.tilePriority;\n            if (ka.level !== kb.level) return kb.level - ka.level;\n            return 0;\n        };\n\n        forcedInView.sort(forcedSort);\n        forcedOffView.sort(forcedSort);\n\n        // Clean up temporary sort keys\n        for (const r of forcedInView) delete r._sortKey;\n        for (const r of forcedOffView) delete r._sortKey;\n        normalInView.sort((a, b) => b.priority - a.priority);\n        normalOffView.sort((a, b) => b.priority - a.priority);\n\n        const batch = [];\n        const totalBudget = this._getEffectiveBatchSize();\n        const normalReserve = totalBudget >= 16\n            ? Math.max(4, Math.floor(totalBudget * 0.08))\n            : 0;\n        const forcedBudget = Math.max(0, totalBudget - normalReserve);\n\n        const picked = this._pickedScratch;\n        picked.clear();\n        const addFrom = (list, limit) => {\n            let remaining = limit;\n            for (const rec of list) {\n                if (remaining <= 0) break;\n                if (picked.has(rec)) continue;\n                batch.push(rec);\n                picked.add(rec);\n                remaining--;\n            }\n            return remaining;\n        };\n\n        let forcedRemaining = forcedBudget;\n        forcedRemaining = addFrom(forcedInView, forcedRemaining);\n        if (forcedRemaining > 0) {\n            forcedRemaining = addFrom(forcedOffView, forcedRemaining);\n        }\n        let remaining = Math.max(0, totalBudget - batch.length);\n\n        if (remaining > 0) {\n            const inViewNear = this._inViewNear;\n            const inViewMid = this._inViewMid;\n            const inViewFar = this._inViewFar;\n            inViewNear.length = 0;\n            inViewMid.length = 0;\n            inViewFar.length = 0;\n            for (const r of normalInView) {\n                if (r.ring === 0) {\n                    inViewNear.push(r);\n                } else if (r.ring === 1) {\n                    inViewMid.push(r);\n                } else {\n                    inViewFar.push(r);\n                }\n            }\n\n            let nearBudget = Math.floor(remaining * this.ringBudgetWeights.near);\n            let midBudget = Math.floor(remaining * this.ringBudgetWeights.mid);\n            if (nearBudget + midBudget > remaining) {\n                const scale = remaining / Math.max(1, nearBudget + midBudget);\n                nearBudget = Math.floor(nearBudget * scale);\n                midBudget = Math.floor(midBudget * scale);\n            }\n            if (nearBudget < 1 && remaining > 0) nearBudget = 1;\n            if (midBudget < 0) midBudget = 0;\n            let farBudget = Math.max(0, remaining - nearBudget - midBudget);\n            if (inViewFar.length > 0 && remaining >= 3 && farBudget < 1) {\n                farBudget = 1;\n                if (nearBudget > midBudget && nearBudget > 1) {\n                    nearBudget--;\n                } else if (midBudget > 0) {\n                    midBudget--;\n                } else if (nearBudget > 0) {\n                    nearBudget--;\n                }\n            }\n\n            remaining = addFrom(inViewNear, nearBudget);\n            remaining = addFrom(inViewMid, midBudget);\n            remaining = addFrom(inViewFar, farBudget);\n            if (remaining > 0) remaining = addFrom(normalInView, remaining);\n            if (remaining > 0) addFrom(normalOffView, remaining);\n        }\n        if (!batch.length) return;\n\n        let sendBatch = batch;\n        let locations = sendBatch.map(r => ({\n            lat: r.lat,\n            lng: r.lng,\n            ...(this.enableMapzenRasterTiles && Number.isFinite(r.mapzenSourceZoom)\n                ? { sourceZoom: r.mapzenSourceZoom }\n                : {})\n        }));\n\n        const buildBackendPayload = (locs) => ({\n            dataset: this.dataset,\n            locations: locs\n        });\n\n        let backendPayload = buildBackendPayload(locations);\n        const maxRequestBytes = this.maxRequestBytes;\n        if (Number.isFinite(maxRequestBytes) && maxRequestBytes > 0 && locations.length > 1) {\n            const payloadBytes = (locs) => this._textEncoder.encode(JSON.stringify(buildBackendPayload(locs))).length;\n            if (payloadBytes(locations) > maxRequestBytes) {\n                let lo = 1;\n                let hi = locations.length;\n                let best = 1;\n                while (lo <= hi) {\n                    const mid = Math.floor((lo + hi) / 2);\n                    const size = payloadBytes(locations.slice(0, mid));\n                    if (size <= maxRequestBytes) {\n                        best = mid;\n                        lo = mid + 1;\n                    } else {\n                        hi = mid - 1;\n                    }\n                }\n                sendBatch = batch.slice(0, best);\n                locations = locations.slice(0, best);\n                backendPayload = buildBackendPayload(locations);\n            }\n        }\n\n        if (!sendBatch.length) return;\n\n        const pendingSince = performance.now();\n        for (const rec of sendBatch) {\n            rec.status = 'pending';\n            rec.pendingSince = pendingSince;\n        }\n\n        if (this.debugLogLocations && this.lastFocusLatLon) {\n            console.log(\n                `[elev] focus lat/lon ${this.lastFocusLatLon.latDeg.toFixed(6)}, ${this.lastFocusLatLon.lonDeg.toFixed(6)}`\n            );\n        }\n\n        const thisBatch = sendBatch;\n        this.currentBatches++;\n        let outboundEvent = null;\n\n        if (this.enableMapzenRasterTiles) {\n            (async () => {\n                try {\n                    const applied = await this._fetchMapzenRasterTiles(locations, thisBatch);\n                    if (applied) return;\n                    throw new Error('Mapzen regional GeoTIFF returned no usable samples');\n                } catch (error) {\n                    console.warn('[elev] Mapzen regional GeoTIFF batch failed', error);\n                    if (this._shouldUseFallbacks()) {\n                        try {\n                            if (await this._fetchFallbackChain(locations, thisBatch)) return;\n                        } catch (fallbackError) {\n                            console.warn('[elev] fallback chain failed after Mapzen GeoTIFF', fallbackError);\n                        }\n                    }\n                    const retryAt = performance.now();\n                    for (const rec of thisBatch) {\n                        if (rec.status === 'pending') this._markRetry(rec, retryAt);\n                    }\n                }\n            })().finally(() => {\n                this.currentBatches--;\n            });\n            return;\n        }\n\n        if (!useBackend) {\n            (async () => {\n                try {\n                    const applied = await this._fetchFallbackChain(locations, thisBatch);\n                    if (applied) return;\n                } catch (fallbackErr) {\n                    console.warn('[elev] Fallback batch failed', fallbackErr);\n                }\n                const errTime = performance.now();\n                for (const rec of thisBatch) {\n                    if (rec.status === 'pending') this._markRetry(rec, errTime);\n                }\n            })().finally(() => {\n                this.currentBatches--;\n            });\n            return;\n        }\n        const sendViaBackend = async () => {\n            const bytesOut = this._textEncoder.encode(JSON.stringify(backendPayload)).length;\n            outboundEvent = this._recordOutbound(bytesOut, locations.length);\n            try {\n                const transport = await this._ensureBackendTransport();\n                const response = await this._withTimeout(\n                    transport.send(\n                        TransportEvent.GEO_ELEVATION_QUERY,\n                        backendPayload,\n                        { timeout: this._backendTimeoutMs }\n                    ),\n                    this._backendTimeoutMs + 1000,\n                    'backend-request'\n                );\n                return response.payload;\n            } catch (err) {\n                if (outboundEvent) {\n                    this._rollbackOutbound(outboundEvent);\n                    outboundEvent = null;\n                }\n                const msg = String(err?.message || '');\n                if (msg.includes('timed out') || msg.includes('timeout')) {\n                    this._resetBackendTransport('request-timeout').catch(() => {});\n                }\n                this._noteBackendFailure();\n                throw err;\n            }\n        };\n\n        (async () => {\n            try {\n                const resp = await sendViaBackend();\n                if (!resp) return;\n                const applied = this._applyElevationResponse(resp, thisBatch);\n                const status = Number(resp.status);\n                // Treat partial-success payloads as healthy enough to keep scheduling.\n                // Backend may report degraded HTTP status while still returning usable results.\n                const backendOk = Number.isFinite(status) ? (status < 400 || applied) : applied;\n                if (!backendOk || !applied) {\n                    this._noteBackendFailure();\n                    let fallbackTried = false;\n                    let fallbackApplied = false;\n                    if (this._shouldUseFallbacks()) {\n                        fallbackTried = true;\n                        try {\n                            fallbackApplied = await this._fetchFallbackChain(locations, thisBatch);\n                            if (fallbackApplied) {\n                                this._logBackendFallbackTransition({\n                                    reason: 'backend-response-fallback',\n                                    status,\n                                    batchSize: thisBatch.length,\n                                    fallbackTried,\n                                    fallbackApplied\n                                });\n                                return;\n                            }\n                        } catch (fallbackErr) {\n                            this._logBackendFallbackTransition({\n                                reason: 'backend-response-fallback-error',\n                                status,\n                                batchSize: thisBatch.length,\n                                fallbackTried,\n                                fallbackApplied: false,\n                                error: fallbackErr\n                            });\n                            console.warn('[elev] Fallback chain failed after backend response', fallbackErr);\n                        }\n                    }\n                    this._logBackendFallbackTransition({\n                        reason: 'backend-response-degraded',\n                        status,\n                        batchSize: thisBatch.length,\n                        fallbackTried,\n                        fallbackApplied\n                    });\n                } else {\n                    this._clearBackendFailures();\n                }\n            } catch (err) {\n                let fallbackTried = false;\n                let fallbackApplied = false;\n                if (this._shouldUseFallbacks()) {\n                    fallbackTried = true;\n                    try {\n                        fallbackApplied = await this._fetchFallbackChain(locations, thisBatch);\n                        if (fallbackApplied) {\n                            this._logBackendFallbackTransition({\n                                reason: 'backend-request-fallback',\n                                batchSize: thisBatch.length,\n                                fallbackTried,\n                                fallbackApplied\n                            });\n                            return;\n                        }\n                    } catch (fallbackErr) {\n                        this._logBackendFallbackTransition({\n                            reason: 'backend-request-fallback-error',\n                            batchSize: thisBatch.length,\n                            fallbackTried,\n                            fallbackApplied: false,\n                            error: fallbackErr\n                        });\n                        console.warn('[elev] Fallback chain failed', fallbackErr);\n                    }\n                }\n                this._logBackendFallbackTransition({\n                    reason: 'backend-request-error',\n                    batchSize: thisBatch.length,\n                    fallbackTried,\n                    fallbackApplied,\n                    error: err\n                });\n                console.error('[elev] batch failed', err);\n                const errTime = performance.now();\n                for (const rec of thisBatch) {\n                    if (rec.status === 'pending') this._markRetry(rec, errTime);\n                }\n            } finally {\n                this.currentBatches--;\n            }\n        })();\n    }\n\n    getStats() {\n        const lookupCount = this.stats.cacheLookupCount || 0;\n        const lookupHits = this.stats.cacheLookupHits || 0;\n        const persistentQueuePending = Math.max(\n            this._cacheWriteQueueMap?.size || 0,\n            this._cacheWriteQueue?.length || 0\n        );\n        const storeQueuePending = this._persistentCache && typeof this._persistentCache.getPendingWriteCount === 'function'\n            ? this._persistentCache.getPendingWriteCount()\n            : 0;\n        const backendFailurePressure = this._getBackendFailurePressure();\n        return {\n            totalVertices: this.vertexMap.size,\n            maxVertexRecords: this.maxVertexRecords,\n            memoryBudgetBaseline: this._memoryBudgetBaseline,\n            memoryPressure: this._memoryPressure,\n            elevationSource: this.enableMapzenRasterTiles ? 'mapzen-geotiff-regional' : 'legacy-relay',\n            mapzenMinRequestedZoom: Number.isFinite(this._mapzenMinRequestedZoom)\n                ? this._mapzenMinRequestedZoom\n                : null,\n            mapzenMaxRequestedZoom: Number.isFinite(this._mapzenMaxRequestedZoom)\n                ? this._mapzenMaxRequestedZoom\n                : null,\n            currentBatches: this.currentBatches,\n            maxConcurrentBatchesConfigured: this.maxConcurrentBatches,\n            maxConcurrentBatchesEffective: this._getEffectiveMaxConcurrentBatches(),\n            batchSizeConfigured: this.batchSize,\n            batchSizeEffective: this._getEffectiveBatchSize(),\n            minIntervalMsConfigured: this.minIntervalMs,\n            minIntervalMsEffective: this._getEffectiveMinIntervalMs(),\n            backendFailureCount: this._backendFailureCount || 0,\n            backendFailurePressure,\n            pendingTimeoutMs: this.pendingTimeoutMs,\n            pendingRecoveries: this._pendingRecoveryCount || 0,\n            cacheLookupHitRatio: lookupCount > 0 ? (lookupHits / lookupCount) : 0,\n            persistentCacheEnabled: !!this._persistentCacheEnabled,\n            persistentCacheReady: !!this._persistentCache,\n            persistentQueuePending,\n            persistentStoreQueuePending: storeQueuePending,\n            persistentNearbyWarmInFlight: !!this._persistentNearbyWarmPromise,\n            persistentNearbyWarmBucket: this._persistentNearbyWarmBucket,\n            persistentNearbyWarmSignature: this._persistentNearbyWarmSignature,\n            ...this.stats\n        };\n    }\n\n    /**\n     * Export elevation cache for persistence.\n     * Only exports vertices that have been successfully fetched and have elevation data.\n     * Limits cache size to prevent localStorage overflow.\n     */\n    exportCache(maxEntries = 5000) {\n        if (!this.cacheEnabled) return [];\n        if (!Number.isFinite(maxEntries) || maxEntries <= 0) return [];\n        const entries = [];\n        const seen = new Set();\n\n        const pushRecord = (key, rec) => {\n            if (!rec || rec.status !== 'done') return false;\n            const elev = Number.isFinite(rec.height)\n                ? rec.height\n                : (Number.isFinite(rec.elev) ? rec.elev : null);\n            if (!Number.isFinite(elev)) return false;\n            if (seen.has(key)) return false;\n            entries.push({\n                k: key,\n                e: Math.round(elev),\n                t: rec.maxTileLevel ?? rec.tileLevel ?? 0\n            });\n            seen.add(key);\n            return entries.length >= maxEntries;\n        };\n\n        if (this.activeTilePriorities && this.activeTilePriorities.size) {\n            const activeTiles = this._activeTileEntries;\n            for (const entry of activeTiles) {\n                const tile = entry?.[0];\n                const keySet = this.tileVertexKeys.get(tile);\n                if (!keySet) continue;\n                for (const key of keySet) {\n                    const rec = this.vertexMap.get(key);\n                    if (pushRecord(key, rec)) {\n                        return entries;\n                    }\n                }\n            }\n        }\n\n        for (const [key, rec] of this.vertexMap.entries()) {\n            if (pushRecord(key, rec)) break;\n        }\n\n        return entries;\n    }\n\n    /**\n     * Import elevation cache from persistence.\n     * Restores previously fetched elevation data to avoid re-downloading.\n     */\n    importCache(entries) {\n        if (!this.cacheEnabled) return 0;\n        if (!entries || !Array.isArray(entries)) {\n            console.warn('[elev] Invalid cache data for import');\n            return 0;\n        }\n\n        let imported = 0;\n        for (const entry of entries) {\n            if (!entry || !entry.k) continue;\n\n            const key = entry.k;\n            const elev = entry.e;\n            const tileLevel = entry.t || 0;\n            const parts = key.split(',');\n            const lat = Number(parts[0]);\n            const lon = Number(parts[1]);\n            if (!Number.isFinite(lat) || !Number.isFinite(lon)) continue;\n\n            const existing = this.vertexMap.get(key);\n            if (existing) {\n                const shouldHydrateExisting = existing.status !== 'done' || !Number.isFinite(existing.height);\n                if (!shouldHydrateExisting) continue;\n                existing.dir = existing.dir || latLonToLocalDir(lat, lon);\n                existing.height = Number.isFinite(elev) ? elev : 0;\n                existing.status = 'done';\n                existing.retryCount = 0;\n                existing.nextRetryAt = 0;\n                existing.pendingSince = 0;\n                existing.lastUsed = performance.now();\n                existing.fromCache = true;\n                if (Array.isArray(existing.clients)) {\n                    for (const ref of existing.clients) {\n                        try {\n                            ref?.tile?.updateVertex?.(ref.index, existing.height);\n                        } catch {\n                            // Ignore stale refs while warming cache.\n                        }\n                    }\n                }\n                imported++;\n                continue;\n            }\n\n            const dir = latLonToLocalDir(lat, lon);\n\n            // Create a cached record\n            const rec = {\n                key,\n                lat,\n                lng: lon,\n                dir,\n                clients: [],\n                status: 'done',\n                height: Number.isFinite(elev) ? elev : 0,\n                maxTileLevel: tileLevel,\n                retryCount: 0,\n                nextRetryAt: 0,\n                pendingSince: 0,\n                lastUsed: performance.now(),\n                distance: Infinity,\n                fromCache: true\n            };\n\n            this.vertexMap.set(key, rec);\n            imported++;\n\n            // Respect cache size limit\n            if (this.vertexMap.size >= this.maxVertexRecords) break;\n        }\n\n        console.log(`[elev] Imported ${imported} cached elevation vertices`);\n        return imported;\n    }\n}\n","// Image sources can be shared by distinct textures and imagery managers.\n// Weak global records coordinate their final backing-store release.\nconst textures = new WeakMap(), images = new WeakMap();\nconst imageBytes = image => Math.max(0, (image?.width || 0) * (image?.height || 0) * 4);\n\nfunction acquireImage(image) {\n    if (!image || typeof image !== 'object') return null;\n    let record = images.get(image);\n    if (!record) { record = { refs: 0, closed: false, bytes: imageBytes(image) }; images.set(image, record); }\n    if (record.closed) throw new Error('Cannot retain a released imagery source');\n    record.refs++;\n    return record;\n}\nfunction releaseImage(image) {\n    const record = image && images.get(image);\n    if (!record || record.closed || --record.refs > 0) return;\n    record.closed = true;\n    if (typeof image.close === 'function') image.close();\n    else if (typeof image.getContext === 'function') {\n        // Private atlas canvas backing store; persistence/drawing must hold it.\n        image.width = 0; image.height = 0;\n    }\n}\n\nexport class ImageryTextureOwnership {\n    constructor() { this.owned = new Map(); this.canvasHolds = new Map(); this.statsCache = null; }\n\n    adopt(texture) {\n        if (!texture || this.owned.has(texture)) return texture;\n        this.statsCache = null;\n        let record = textures.get(texture);\n        if (!record) {\n            const source = texture.source?.data || texture.image;\n            record = { refs: 0, source, image: acquireImage(source), disposed: false };\n            textures.set(texture, record);\n        }\n        if (record.disposed) throw new Error('Cannot retain a released imagery texture');\n        record.refs++; this.owned.set(texture, 1);\n        return texture;\n    }\n\n    retain(texture) {\n        if (!texture) return () => {};\n        this.statsCache = null;\n        if (this.owned.has(texture)) {\n            this.owned.set(texture, this.owned.get(texture) + 1);\n            textures.get(texture).refs++;\n        } else this.adopt(texture);\n        let released = false;\n        return () => { if (!released) { released = true; this.release(texture); } };\n    }\n\n    release(texture) {\n        if (!texture) return;\n        this.statsCache = null;\n        // Compatibility for externally supplied cache entries: adopt their\n        // existing ownership once. Ordinary producers always adopt on creation.\n        if (!this.owned.has(texture)) {\n            if (textures.get(texture)?.disposed) return;\n            this.adopt(texture);\n        }\n        const count = this.owned.get(texture), record = textures.get(texture);\n        if (count <= 1) this.owned.delete(texture);\n        else this.owned.set(texture, count - 1);\n        if (--record.refs === 0 && !record.disposed) {\n            record.disposed = true;\n            try { texture.dispose(); } finally { releaseImage(record.source); }\n        }\n    }\n\n    holdCanvas(canvas) {\n        if (!canvas) return () => {};\n        this.statsCache = null;\n        acquireImage(canvas);\n        this.canvasHolds.set(canvas, (this.canvasHolds.get(canvas) || 0) + 1);\n        let released = false;\n        return () => {\n            if (released) return; released = true;\n            this.statsCache = null;\n            const count = this.canvasHolds.get(canvas) || 0;\n            if (count <= 1) this.canvasHolds.delete(canvas);\n            else this.canvasHolds.set(canvas, count - 1);\n            releaseImage(canvas);\n        };\n    }\n\n    getStats() {\n        if (this.statsCache) return this.statsCache;\n        const uniqueImages = new Set();\n        let textureBytes = 0, references = 0, decodedBytes = 0, stagingCanvasBytes = 0;\n        for (const [texture, refs] of this.owned) {\n            const record = textures.get(texture);\n            references += refs; textureBytes += record.image?.bytes || 0;\n            if (record.source) uniqueImages.add(record.source);\n        }\n        for (const canvas of this.canvasHolds.keys()) {\n            uniqueImages.add(canvas);\n            if (typeof canvas.getContext === 'function') stagingCanvasBytes += images.get(canvas)?.bytes || 0;\n        }\n        for (const source of uniqueImages) decodedBytes += images.get(source)?.bytes || 0;\n        return this.statsCache = Object.freeze({ textures: this.owned.size, references, decodedSources: uniqueImages.size, decodedBytes, textureBytes, stagingCanvasBytes });\n    }\n}\n","/**\n * Imagery manager for Esri Wayback WMTS tile loading and atlas generation\n */\n\nimport * as THREE from 'three';\nimport { WMTS_ROOT, WAYBACK_WMTS_CAPABILITIES, DEFAULT_WAYBACK_VERSION } from './constants.js';\nimport { getSceneStateStore } from './scene-state-store.js';\nimport { ImageryTextureOwnership } from './imagery-texture-ownership.js';\n\nexport class ImageryManager {\n    constructor({ mapSource = null } = {}) {\n        this.mapSource = mapSource;\n        this.enabled = true;\n        this.versionId = mapSource ? `mapsource:${mapSource.id}` : DEFAULT_WAYBACK_VERSION;\n        this._preferredVersionId = this.versionId;\n        this._desiredEnabled = this.enabled;\n        this._pendingLatest = false;\n        this._pendingLatestPromise = null;\n        this._latestFallbackVersion = null;\n        this._latestRequestId = 0;\n        this.zoom = 22; // Default to high zoom for underfoot tiles\n\n        // Wayback version discovery\n        this.availableVersions = []; // Array of { id, label, sortKey, date }\n        this._versionFetchPromise = null;\n        this._versionFetchTime = 0;\n        this._onVersionsLoaded = null; // Callback when versions are loaded\n\n        // Tile cache: version|z|x|y -> { texture, promise }\n        this.loader = new THREE.TextureLoader();\n        this.loader.crossOrigin = 'anonymous';\n        this.tileCache = new Map();\n\n        // Persistent IndexedDB cache (optional)\n        this._imageryCache = null;\n        this._imageryCacheInitPromise = null;\n        this._imageryCacheReady = false;\n        this._imageryCacheEnabled = typeof indexedDB !== 'undefined';\n        this._recentPersistentKeys = [];\n        this._recentPersistentKeysLoaded = false;\n        this._recentPersistentKeysDirty = false;\n        this._recentPersistentKeysMax = 160;\n        this._hotsetPrewarmed = false;\n        if (this._imageryCacheEnabled) {\n            const _store = getSceneStateStore();\n            this._imageryCache = {\n                init: () => _store.init(),\n                get: (key) => _store.readImageryTile(key),\n                getAtlas: (key) => _store.readImageryAtlas(key),\n                put: (entry) => _store.writeImageryTileBatch([entry]),\n                putAtlas: (entry) => _store.writeImageryAtlasBatch([entry]),\n                putMany: (entries) => _store.writeImageryTileBatch(entries),\n                putManyAtlas: (entries) => _store.writeImageryAtlasBatch(entries),\n                flush: () => Promise.resolve(),\n                close: () => {},\n                getPendingWriteCount: () => 0,\n                getRecentKeys: () => _store.readImageryMeta('recentKeys').then((v) => Array.isArray(v) ? v : []),\n                setRecentKeys: (keys) => _store.writeImageryMeta('recentKeys', keys)\n            };\n        }\n\n        // Atlas cache: version|z|minX|minY|w|h -> { texture, promise }\n        this.atlasCache = new Map();\n\n        // Atlas ref-counting for shared atlases\n        this.atlasRefCounts = new Map();\n        this._atlasTextureRefs = new Map();\n        this._textureOwnership = new ImageryTextureOwnership();\n        this._textureHandoffs = new Map();\n        this._textureHandoffTimer = null;\n\n        // Tile size configuration (can be set to 128 for mobile devices)\n        this.tileSize = 256;\n        this.useMobileTiles = false; // Will be set to true for mobile devices\n        this.textureAnisotropy = 4;\n\n        // Limits to avoid giant canvases\n        this.maxAtlasTiles = 4;     // bounded 4x4 atlas; fine leaves use 1-2 tiles\n        this.padTiles = 0;          // half-texel UV clamp handles edge bleed\n\n        // Cache budgets (bytes)\n        this.maxTileCacheBytes = 100 * 1024 * 1024;  // 100 MB\n        this.maxAtlasCacheBytes = 200 * 1024 * 1024; // 200 MB\n        this.currentTileCacheBytes = 0;\n        this.currentAtlasCacheBytes = 0;\n\n        // Bounded decode/canvas work; near-first scheduling keeps the visible\n        // center converging without a large background queue.\n        this.maxConcurrentAtlasBuilds = 4;\n        this.currentAtlasBuilds = 0;\n        this.maxConcurrentTileLoads = 12;\n        this.currentTileLoads = 0;\n        this.contextBurstMs = 3000;\n        this.contextBurstTileLoads = 12;\n        this.contextBurstAtlasBuilds = 6;\n        this._contextBurstUntil = 0;\n        this.atlasDrawBudgetMs = 4;\n        this.atlasDrawMinTiles = 4;\n        this.atlasQueue = [];\n        this.tileQueue = [];\n        this.maxQueuedTileRequests = 1024;\n        this.maxQueuedAtlasRequests = 256;\n        this._queueSeq = 0;\n        this.contextQueueStarvationMs = 800;\n        this.requestContextKey = null;\n        this._strictContextUntil = 0;\n        // Camera capture owns the mobile presentation exclusively. Keep this\n        // separate from `enabled`: enabled is user configuration, whereas\n        // resource suspension is a short-lived lifecycle state.\n        this._resourceSuspended = false;\n        this._resourceGeneration = 0;\n\n        // Retry delays — short so stuck tiles don't block the pipeline.\n        this.tileRetryDelayMs = 1200;\n        this.atlasRetryDelayMs = 2000;\n        this.retryBypassPriority = 100000;\n\n        // Per-atlas safeguards to avoid huge fan-out storms.\n        this.maxAtlasTileFetches = 64;\n        this.atlasTileFetchConcurrency = 12;\n        this.atlasParentFallbackEnabled = true;\n        this.atlasParentFallbackMaxParents = 64;\n\n        // Dynamic zoom fallback: track max available zoom per region\n        // Key: \"versionId|regionX|regionY\" (region = tile coords at zoom 10)\n        // Value: { maxZoom: number, checkedAt: timestamp }\n        this.regionMaxZoomCache = new Map();\n        this.regionMaxZoomCacheExpireMs = 600000; // 10 minute cache for zoom limits\n        this.regionZoomFallbackEnabled = true;\n        this.regionZoomMinFallback = 0; // Allow fallback to the best available zoom level\n\n        this._applyPreferredVersion(this.versionId);\n\n        // Bulk download state (zoom-level cache)\n        this._bulkDownload = null;\n        this.cacheStats = {\n            idbTileHits: 0,\n            idbTileMisses: 0,\n            idbAtlasHits: 0,\n            idbAtlasMisses: 0,\n            tileNetworkFetches: 0,\n            tileNetworkBytes: 0,\n            atlasNetworkAvoidedTiles: 0\n        };\n    }\n\n    async _initImageryCache() {\n        if (!this._imageryCacheEnabled || !this._imageryCache) return null;\n        if (this._imageryCacheReady) return this._imageryCache;\n        if (this._imageryCacheInitPromise) return this._imageryCacheInitPromise;\n        this._imageryCacheInitPromise = this._imageryCache.init()\n            .then(async () => {\n                this._imageryCacheReady = true;\n                await this._hydrateRecentPersistentKeys(this._imageryCache);\n                return this._imageryCache;\n            })\n            .catch((err) => {\n                console.warn('[imagery] IndexedDB cache init failed:', err);\n                this._imageryCacheEnabled = false;\n                return null;\n            });\n        return this._imageryCacheInitPromise;\n    }\n\n    async _textureFromBlob(blob) {\n        if (!blob) return null;\n        if (typeof createImageBitmap === 'function') {\n            const bitmap = await createImageBitmap(blob);\n            const tex = new THREE.Texture(bitmap);\n            this._applyTextureSettings(tex);\n            return tex;\n        }\n        return new Promise((resolve, reject) => {\n            const img = new Image();\n            const objectUrl = URL.createObjectURL(blob);\n            img.onload = () => {\n                URL.revokeObjectURL(objectUrl);\n                const tex = new THREE.Texture(img);\n                this._applyTextureSettings(tex);\n                resolve(tex);\n            };\n            img.onerror = (err) => {\n                URL.revokeObjectURL(objectUrl);\n                reject(err);\n            };\n            img.crossOrigin = 'anonymous';\n            img.src = objectUrl;\n        });\n    }\n\n    _applyTextureSettings(tex) {\n        if (!tex) return;\n        this._ownedTextures().adopt(tex);\n        tex.colorSpace = THREE.SRGBColorSpace;\n        tex.anisotropy = this._getTextureAnisotropy();\n        tex.wrapS = THREE.ClampToEdgeWrapping;\n        tex.wrapT = THREE.ClampToEdgeWrapping;\n        tex.format = THREE.RGBAFormat;\n        tex.type = THREE.UnsignedByteType;\n        tex.needsUpdate = true;\n    }\n\n    _ownedTextures() {\n        return this._textureOwnership ||= new ImageryTextureOwnership();\n    }\n\n    _releaseTexture(tex) {\n        this._ownedTextures().release(tex);\n    }\n\n    _handoffTexture(tex) {\n        if (!tex) return null;\n        // Producers can evict before Promise consumers run. Hold once through\n        // the next task so each synchronous consumer can acquire its own lease.\n        const holds = this._textureHandoffs ||= new Map();\n        if (!holds.has(tex)) holds.set(tex, this._ownedTextures().retain(tex));\n        if (this._textureHandoffTimer == null) {\n            this._textureHandoffTimer = setTimeout(() => {\n                this._textureHandoffTimer = null;\n                const releases = Array.from(holds.values());\n                holds.clear();\n                for (const release of releases) release();\n            }, 0);\n        }\n        return tex;\n    }\n\n    _isResourceCurrent(generation) {\n        return !this._resourceSuspended && generation === this._resourceGeneration;\n    }\n\n    _applyAtlasTextureSettings(tex) {\n        if (!tex) return;\n        this._applyTextureSettings(tex);\n        tex.generateMipmaps = false;\n        tex.minFilter = THREE.LinearFilter;\n        tex.magFilter = THREE.LinearFilter;\n        tex.anisotropy = this._getTextureAnisotropy();\n        // Disable flipY so atlas textures are uploaded as-is (top-left origin).\n        // This avoids relying on UNPACK_FLIP_Y_WEBGL which is unreliable for\n        // ImageBitmap sources restored from the persistent IndexedDB cache.\n        // UV computation in tri-tile.js maps v=0 to canvas top (north) directly.\n        tex.flipY = false;\n        tex.needsUpdate = true;\n    }\n\n    _getTextureAnisotropy() {\n        const raw = Number.isFinite(this.textureAnisotropy) ? this.textureAnisotropy : 4;\n        return Math.max(1, Math.min(16, Math.floor(raw)));\n    }\n\n    _getTileSizeValue() {\n        const fallback = this.useMobileTiles ? 128 : 256;\n        const raw = Number.isFinite(this.tileSize) ? this.tileSize : fallback;\n        const size = Math.floor(raw);\n        return Math.max(64, Math.min(512, size));\n    }\n\n    _touchRecentPersistentKey(type, cacheKey) {\n        if (!cacheKey) return;\n        if (type !== 'tile' && type !== 'atlas') return;\n        const tagged = `${type}:${cacheKey}`;\n        const list = this._recentPersistentKeys;\n        const idx = list.indexOf(tagged);\n        if (idx === 0) return;\n        if (idx > 0) {\n            list.splice(idx, 1);\n        }\n        list.unshift(tagged);\n        if (list.length > this._recentPersistentKeysMax) {\n            list.length = this._recentPersistentKeysMax;\n        }\n        this._recentPersistentKeysDirty = true;\n    }\n\n    async _hydrateRecentPersistentKeys(cache = null) {\n        if (this._recentPersistentKeysLoaded) return this._recentPersistentKeys;\n        const targetCache = cache || this._imageryCache;\n        if (!targetCache || typeof targetCache.getRecentKeys !== 'function') {\n            this._recentPersistentKeysLoaded = true;\n            return this._recentPersistentKeys;\n        }\n        try {\n            const keys = await targetCache.getRecentKeys();\n            if (Array.isArray(keys)) {\n                this._recentPersistentKeys = keys\n                    .filter((entry) => typeof entry === 'string' && entry.length > 0)\n                    .slice(0, this._recentPersistentKeysMax);\n            }\n        } catch (err) {\n            console.warn('[imagery] Failed to read recent persistent cache keys:', err);\n        } finally {\n            this._recentPersistentKeysLoaded = true;\n            this._recentPersistentKeysDirty = false;\n        }\n        return this._recentPersistentKeys;\n    }\n\n    async _persistRecentPersistentKeys(cache = null) {\n        if (!this._recentPersistentKeysDirty) return;\n        const targetCache = cache || this._imageryCache;\n        if (!targetCache || typeof targetCache.setRecentKeys !== 'function') return;\n        try {\n            await targetCache.setRecentKeys(this._recentPersistentKeys.slice(0, this._recentPersistentKeysMax));\n            this._recentPersistentKeysDirty = false;\n        } catch (err) {\n            console.warn('[imagery] Failed to persist recent persistent cache keys:', err);\n        }\n    }\n\n    async _loadTileTextureWithFetch(url, cacheKey) {\n        const cache = await this._initImageryCache();\n        let cacheHit = false;\n        if (cache && cacheKey) {\n            try {\n                const cached = await cache.get(cacheKey);\n                if (cached && cached.b) {\n                    const tex = await this._textureFromBlob(cached.b);\n                    if (tex) {\n                        cacheHit = true;\n                        this._touchRecentPersistentKey('tile', cacheKey);\n                        this.cacheStats.idbTileHits += 1;\n                        return { tex, failed: false };\n                    }\n                }\n            } catch (err) {\n                console.warn('[imagery] IndexedDB tile read failed:', err);\n            }\n        }\n        if (cache && cacheKey && !cacheHit) {\n            this.cacheStats.idbTileMisses += 1;\n        }\n\n        try {\n            this.cacheStats.tileNetworkFetches += 1;\n            const response = await fetch(url, { mode: 'cors' });\n            if (!response.ok) {\n                return { tex: null, failed: true, status: response.status };\n            }\n            const blob = await response.blob();\n            this.cacheStats.tileNetworkBytes += Number.isFinite(blob?.size) ? blob.size : 0;\n            const tex = await this._textureFromBlob(blob);\n            if (tex && cache && cacheKey) {\n                try {\n                    await cache.put({ k: cacheKey, b: blob });\n                    this._touchRecentPersistentKey('tile', cacheKey);\n                } catch (err) {\n                    console.warn('[imagery] IndexedDB tile write failed:', err);\n                }\n            }\n            return { tex, failed: !tex };\n        } catch (err) {\n            return { tex: null, failed: true, error: err };\n        }\n    }\n\n    async _persistLoadedImageToCache(cacheKey, image) {\n        const releaseImage = this._ownedTextures().holdCanvas(image);\n        try {\n            const cache = await this._initImageryCache();\n            if (!cache || !cacheKey || !image) return;\n\n            const width = Number.isFinite(image.width) ? image.width : 0;\n            const height = Number.isFinite(image.height) ? image.height : 0;\n            if (width <= 0 || height <= 0) return;\n\n            const toBlob = async () => {\n                if (typeof OffscreenCanvas !== 'undefined') {\n                    const canvas = new OffscreenCanvas(width, height);\n                    const releaseCanvas = this._ownedTextures().holdCanvas(canvas);\n                    try {\n                        const ctx = canvas.getContext('2d');\n                        if (!ctx) return null;\n                        ctx.drawImage(image, 0, 0, width, height);\n                        return await canvas.convertToBlob({ type: 'image/jpeg', quality: 0.92 });\n                    } finally { releaseCanvas(); }\n                }\n                if (typeof document === 'undefined') return null;\n                const canvas = document.createElement('canvas');\n                canvas.width = width;\n                canvas.height = height;\n                const releaseCanvas = this._ownedTextures().holdCanvas(canvas);\n                try {\n                    const ctx = canvas.getContext('2d');\n                    if (!ctx) return null;\n                    ctx.drawImage(image, 0, 0, width, height);\n                    return await new Promise((resolve) => {\n                        canvas.toBlob((blob) => resolve(blob || null), 'image/jpeg', 0.92);\n                    });\n                } finally { releaseCanvas(); }\n            };\n\n            try {\n                const blob = await toBlob();\n                if (blob && blob.size > 0) {\n                    await cache.put({ k: cacheKey, b: blob });\n                    this._touchRecentPersistentKey('tile', cacheKey);\n                }\n            } catch {\n                // Some image sources cannot be serialized (tainted canvas / unsupported source type).\n            }\n        } finally { releaseImage(); }\n    }\n\n    async _loadAtlasTextureFromPersistentCache(cacheKey, {\n        atlasTileCount = 1,\n        atlasZoom = null\n    } = {}) {\n        const cache = await this._initImageryCache();\n        if (!cache || !cacheKey || typeof cache.getAtlas !== 'function') {\n            return null;\n        }\n\n        let cacheHit = false;\n        try {\n            const cached = await cache.getAtlas(cacheKey);\n            if (cached && cached.b) {\n                const tex = await this._textureFromBlob(cached.b);\n                if (tex) {\n                    this._applyAtlasTextureSettings(tex);\n                    tex.userData = tex.userData || {};\n                    if (Number.isFinite(atlasZoom)) {\n                        tex.userData.actualZoom = Math.max(0, Math.floor(atlasZoom));\n                    }\n                    cacheHit = true;\n                    this._touchRecentPersistentKey('atlas', cacheKey);\n                    this.cacheStats.idbAtlasHits += 1;\n                    const avoidedTiles = Number.isFinite(cached.tc)\n                        ? Math.max(1, Math.floor(cached.tc))\n                        : Math.max(1, Math.floor(atlasTileCount || 1));\n                    this.cacheStats.atlasNetworkAvoidedTiles += avoidedTiles;\n                    return tex;\n                }\n            }\n        } catch (err) {\n            console.warn('[imagery] IndexedDB atlas read failed:', err);\n        }\n\n        if (!cacheHit) {\n            this.cacheStats.idbAtlasMisses += 1;\n        }\n        return null;\n    }\n\n    async _persistAtlasCanvasToCache(cacheKey, canvas, atlasTileCount = 1) {\n        const releaseCanvas = this._ownedTextures().holdCanvas(canvas);\n        try {\n            const cache = await this._initImageryCache();\n            if (!cache || !cacheKey || !canvas || typeof cache.putAtlas !== 'function') return;\n            const width = Number.isFinite(canvas.width) ? canvas.width : 0;\n            const height = Number.isFinite(canvas.height) ? canvas.height : 0;\n            if (width <= 0 || height <= 0) return;\n\n            const toBlob = async () => {\n                if (typeof canvas.convertToBlob === 'function') {\n                    return canvas.convertToBlob({ type: 'image/jpeg', quality: 0.92 });\n                }\n                if (typeof canvas.toBlob === 'function') {\n                    return new Promise((resolve) => {\n                        canvas.toBlob((blob) => resolve(blob || null), 'image/jpeg', 0.92);\n                    });\n                }\n                return null;\n            };\n\n            try {\n                const blob = await toBlob();\n                if (blob && blob.size > 0) {\n                    await cache.putAtlas({\n                        k: cacheKey,\n                        b: blob,\n                        tc: Math.max(1, Math.floor(atlasTileCount || 1))\n                    });\n                    this._touchRecentPersistentKey('atlas', cacheKey);\n                }\n            } catch {\n                // Atlas serialization is best-effort only.\n            }\n        } finally { releaseCanvas(); }\n    }\n\n    /**\n     * Fetch available Wayback imagery versions from WMTS Capabilities\n     * @param {boolean} force - Force refetch even if cached\n     * @returns {Promise<Array>} Array of { id, label, sortKey, date }\n     */\n    async fetchAvailableVersions(force = false) {\n        // Return cached if recent (5 minute cache)\n        const now = Date.now();\n        if (!force && this.availableVersions.length > 0 && (now - this._versionFetchTime) < 300000) {\n            return this.availableVersions;\n        }\n\n        // Return existing promise if in flight\n        if (this._versionFetchPromise) {\n            return this._versionFetchPromise;\n        }\n\n        this._versionFetchPromise = (async () => {\n            try {\n                const res = await fetch(WAYBACK_WMTS_CAPABILITIES, { mode: 'cors' });\n                if (!res.ok) throw new Error(`HTTP ${res.status} fetching Wayback capabilities`);\n                const text = await res.text();\n                const parser = new DOMParser();\n                const xml = parser.parseFromString(text, 'application/xml');\n                const layers = Array.from(xml.querySelectorAll('Contents > Layer'));\n                const versions = [];\n\n                for (const layer of layers) {\n                    const id = (layer.querySelector('ows\\\\:Identifier') || layer.querySelector('Identifier'))?.textContent?.trim() || '';\n                    const title = (layer.querySelector('ows\\\\:Title') || layer.querySelector('Title'))?.textContent?.trim() || id;\n                    const resURL = layer.querySelector('ResourceURL[resourceType=\"tile\"]')?.getAttribute('template') || '';\n                    const versionMatch = resURL.match(/\\/tile\\/(\\d+)\\/\\{?TileMatrix/i);\n                    const version = versionMatch ? versionMatch[1] : '';\n                    if (!version) continue;\n\n                    let sortKey = version;\n                    let label = title || version;\n                    let date = null;\n                    const dateMatch = title.match(/(\\d{4}-\\d{2}-\\d{2})/);\n                    if (dateMatch) {\n                        sortKey = dateMatch[1];\n                        date = dateMatch[1];\n                        label = `${dateMatch[1]} (v${version})`;\n                    } else {\n                        label = `${label} (v${version})`;\n                    }\n                    versions.push({ id: version, label, sortKey, date });\n                }\n\n                // Sort by date descending (newest first)\n                versions.sort((a, b) => (a.sortKey < b.sortKey ? 1 : (a.sortKey > b.sortKey ? -1 : 0)));\n\n                this.availableVersions = versions;\n                this._versionFetchTime = now;\n                console.log(`[ImageryManager] Loaded ${versions.length} Wayback imagery versions`);\n\n                // Notify callback if set\n                if (typeof this._onVersionsLoaded === 'function') {\n                    this._onVersionsLoaded(versions);\n                }\n\n                return versions;\n            } catch (err) {\n                console.warn('[ImageryManager] Wayback capabilities fetch failed:', err);\n                return this.availableVersions;\n            } finally {\n                this._versionFetchPromise = null;\n            }\n        })();\n\n        return this._versionFetchPromise;\n    }\n\n    /**\n     * Set callback for when versions are loaded\n     * @param {Function} callback - Called with array of versions\n     */\n    onVersionsLoaded(callback) {\n        this._onVersionsLoaded = callback;\n        // If already loaded, call immediately\n        if (this.availableVersions.length > 0) {\n            callback(this.availableVersions);\n        }\n    }\n\n    _normalizeVersionId(value) {\n        if (value === undefined || value === null) return '';\n        return String(value).trim();\n    }\n\n    _isLatestVersion(value) {\n        const normalized = this._normalizeVersionId(value).toLowerCase();\n        return normalized === '' || normalized === 'latest';\n    }\n\n    _applyPreferredVersion(versionId) {\n        const normalized = this._normalizeVersionId(versionId);\n        if (this._isLatestVersion(normalized)) {\n            if (this._preferredVersionId === 'latest' && this._pendingLatest) return;\n            this._preferredVersionId = 'latest';\n            this._queueLatestVersion();\n            return;\n        }\n\n        this._preferredVersionId = normalized;\n        if (this._pendingLatest) {\n            this._pendingLatest = false;\n            this._pendingLatestPromise = null;\n            this._latestFallbackVersion = null;\n            this._latestRequestId += 1;\n        }\n        if (normalized && this.versionId !== normalized) {\n            this.setVersion(normalized);\n        }\n        this.enabled = this._desiredEnabled;\n    }\n\n    _queueLatestVersion() {\n        if (this._pendingLatest) return;\n        const knownLatest = this.availableVersions?.[0]?.id;\n        if (knownLatest && this.versionId === knownLatest) {\n            this._preferredVersionId = 'latest';\n            this.enabled = this._desiredEnabled;\n            return;\n        }\n        this._pendingLatest = true;\n        const requestId = ++this._latestRequestId;\n        this._latestFallbackVersion = (!this._isLatestVersion(this.versionId) && this.versionId)\n            ? this.versionId\n            : null;\n        this._desiredEnabled = this.enabled;\n        this.enabled = false;\n        this._pendingLatestPromise = this.fetchAvailableVersions()\n            .then((versions) => {\n                if (requestId !== this._latestRequestId || this._preferredVersionId !== 'latest') return;\n                const latest = versions?.[0]?.id;\n                if (latest) {\n                    this.setVersion(latest);\n                } else if (this._latestFallbackVersion) {\n                    this.setVersion(this._latestFallbackVersion);\n                }\n            })\n            .catch(() => {\n                if (requestId !== this._latestRequestId || this._preferredVersionId !== 'latest') return;\n                if (this._latestFallbackVersion) {\n                    this.setVersion(this._latestFallbackVersion);\n                }\n            })\n            .finally(() => {\n                if (requestId !== this._latestRequestId || this._preferredVersionId !== 'latest') return;\n                this._pendingLatest = false;\n                this._latestFallbackVersion = null;\n                this.enabled = this._desiredEnabled;\n                this._pendingLatestPromise = null;\n            });\n    }\n\n    /**\n     * Set the active wayback version and rebuild textures\n     * @param {string} versionId - The version ID to use\n     */\n    setVersion(versionId) {\n        const normalized = this._normalizeVersionId(versionId);\n        if (this._isLatestVersion(normalized)) {\n            this._preferredVersionId = 'latest';\n            this._queueLatestVersion();\n            return;\n        }\n        if (!normalized || this.versionId === normalized) return;\n        const prev = this.versionId;\n        this.versionId = normalized;\n        console.log(`[ImageryManager] Switching from version ${prev} to ${this.versionId}`);\n        // Clear caches to force reload with new version\n        this._clearAllCaches();\n    }\n\n    _clearAllCaches({ keepTiles = false } = {}) {\n        this._resourceGeneration += 1;\n        // Atlas layout changes can reuse decoded source tiles. Only pending\n        // entries are invalidated in that case; version/teardown clears all.\n        for (const [key, entry] of this.tileCache) {\n            if (keepTiles && entry.texture) continue;\n            this._releaseTexture(entry.texture);\n            this.tileCache.delete(key);\n        }\n        if (!keepTiles) this.currentTileCacheBytes = 0;\n\n        // Clear atlas cache\n        for (const entry of this.atlasCache.values()) {\n            this._releaseTexture(entry.texture);\n        }\n        this.atlasCache.clear();\n        // Live tile/crossfade leases survive cache invalidation. Their owners\n        // release by texture identity, even after this key has been reloaded.\n        this.currentAtlasCacheBytes = 0;\n\n        // Clear region zoom cache (different versions may have different max zooms)\n        this.clearRegionZoomCache();\n\n        // Clear queues\n        this.clearQueues();\n        this._hotsetPrewarmed = false;\n    }\n\n    _collectSnapshotAtlasKeys(snapshotTiles, versionId, maxAtlasKeys) {\n        if (!Array.isArray(snapshotTiles) || snapshotTiles.length === 0) return [];\n        const limit = Math.max(0, Math.floor(maxAtlasKeys));\n        if (limit <= 0) return [];\n\n        const candidates = [];\n        const seen = new Set();\n        for (const entry of snapshotTiles) {\n            const atlas = entry?.imagery;\n            const z = Number.isFinite(atlas?.zoom) ? Math.max(0, Math.floor(atlas.zoom)) : null;\n            const minX = Number.isFinite(atlas?.minX) ? Math.floor(atlas.minX) : null;\n            const minY = Number.isFinite(atlas?.minY) ? Math.floor(atlas.minY) : null;\n            const w = Number.isFinite(atlas?.w) ? Math.max(1, Math.floor(atlas.w)) : null;\n            const h = Number.isFinite(atlas?.h) ? Math.max(1, Math.floor(atlas.h)) : null;\n            if (!Number.isFinite(z) || !Number.isFinite(minX) || !Number.isFinite(minY) ||\n                !Number.isFinite(w) || !Number.isFinite(h)) {\n                continue;\n            }\n\n            const key = this._atlasKey(versionId, z, minX, minY, w, h);\n            if (!key || seen.has(key)) continue;\n            seen.add(key);\n            candidates.push({\n                key,\n                level: Number.isFinite(entry?.level) ? entry.level : 0,\n                zoom: z,\n                area: w * h\n            });\n        }\n\n        candidates.sort((a, b) => {\n            if (b.level !== a.level) return b.level - a.level;\n            if (b.zoom !== a.zoom) return b.zoom - a.zoom;\n            return a.area - b.area;\n        });\n        return candidates.slice(0, limit).map((item) => item.key);\n    }\n\n    async _restorePrewarm(cache, key, atlas, generation) {\n        if (!this._isResourceCurrent(generation)) return false;\n        const target = atlas ? this.atlasCache : this.tileCache;\n        if (target.has(key)) return false;\n        const cached = await (atlas ? cache.getAtlas(key) : cache.get(key));\n        if (!cached?.b || !this._isResourceCurrent(generation) || target.has(key)) return false;\n        const tex = await this._textureFromBlob(cached.b);\n        if (!tex) return false;\n        if (!this._isResourceCurrent(generation) || target.has(key)) {\n            this._releaseTexture(tex);\n            return false;\n        }\n        if (atlas) this._applyAtlasTextureSettings(tex);\n        else this._applyTextureSettings(tex);\n        target.set(key, { texture: tex });\n        if (atlas) {\n            this.currentAtlasCacheBytes += this._estimateTextureBytes(tex);\n            this._evictAtlasCache();\n        } else {\n            this.currentTileCacheBytes += this._estimateTextureBytes(tex);\n            this._evictTileCache();\n        }\n        this._touchRecentPersistentKey(atlas ? 'atlas' : 'tile', key);\n        return true;\n    }\n\n    async prewarmPersistentForSnapshotTiles(snapshotTiles, {\n        preferVersionId = null,\n        maxAtlasKeys = 24\n    } = {}) {\n        const result = {\n            atlasLoaded: 0,\n            candidateCount: 0,\n            versionId: null\n        };\n        if (!this._imageryCacheEnabled || this._resourceSuspended) return result;\n        const generation = this._resourceGeneration;\n        const cache = await this._initImageryCache();\n        if (!cache) return result;\n        await this._hydrateRecentPersistentKeys(cache);\n\n        const normalizedPreferred = this._normalizeVersionId(preferVersionId);\n        const versionId = (!this._isLatestVersion(normalizedPreferred) && normalizedPreferred)\n            ? normalizedPreferred\n            : this.versionId;\n        result.versionId = versionId || null;\n        if (!versionId) return result;\n\n        const keys = this._collectSnapshotAtlasKeys(snapshotTiles, versionId, maxAtlasKeys);\n        result.candidateCount = keys.length;\n        if (!keys.length) return result;\n\n        for (const key of keys) {\n            if (this.atlasCache.has(key)) continue;\n            try {\n                if (!this._isResourceCurrent(generation)) break;\n                if (await this._restorePrewarm(cache, key, true, generation)) result.atlasLoaded += 1;\n            } catch {\n                // Snapshot prewarm is best-effort.\n            }\n        }\n        return result;\n    }\n\n    async prewarmPersistentHotset({\n        preferVersionId = null,\n        maxAtlasKeys = 10,\n        maxTileKeys = 40,\n        force = false\n    } = {}) {\n        const result = {\n            atlasLoaded: 0,\n            tileLoaded: 0,\n            candidateCount: 0\n        };\n        if (!this._imageryCacheEnabled || this._resourceSuspended) return result;\n        const generation = this._resourceGeneration;\n        if (this._hotsetPrewarmed && !force) return result;\n        const cache = await this._initImageryCache();\n        if (!cache) return result;\n        await this._hydrateRecentPersistentKeys(cache);\n\n        const atlasLimit = Math.max(0, Math.floor(maxAtlasKeys));\n        const tileLimit = Math.max(0, Math.floor(maxTileKeys));\n        if (atlasLimit <= 0 && tileLimit <= 0) {\n            this._hotsetPrewarmed = true;\n            return result;\n        }\n\n        const seenTile = new Set();\n        const seenAtlas = new Set();\n        const atlasKeys = [];\n        const tileKeys = [];\n        const versionPrefix = preferVersionId ? `${preferVersionId}|` : null;\n        for (const tagged of this._recentPersistentKeys) {\n            if (tagged.startsWith('atlas:')) {\n                const key = tagged.slice(6);\n                if (!key || seenAtlas.has(key)) continue;\n                if (versionPrefix && !key.startsWith(versionPrefix)) continue;\n                seenAtlas.add(key);\n                atlasKeys.push(key);\n            } else if (tagged.startsWith('tile:')) {\n                const key = tagged.slice(5);\n                if (!key || seenTile.has(key)) continue;\n                if (versionPrefix && !key.startsWith(versionPrefix)) continue;\n                seenTile.add(key);\n                tileKeys.push(key);\n            }\n        }\n\n        result.candidateCount = atlasKeys.length + tileKeys.length;\n\n        for (const key of atlasKeys) {\n            if (result.atlasLoaded >= atlasLimit) break;\n            if (this.atlasCache.has(key)) continue;\n            try {\n                if (!this._isResourceCurrent(generation)) break;\n                if (await this._restorePrewarm(cache, key, true, generation)) result.atlasLoaded += 1;\n            } catch {\n                // Hotset prewarm is best-effort only.\n            }\n        }\n\n        for (const key of tileKeys) {\n            if (result.tileLoaded >= tileLimit) break;\n            if (this.tileCache.has(key)) continue;\n            try {\n                if (!this._isResourceCurrent(generation)) break;\n                if (await this._restorePrewarm(cache, key, false, generation)) result.tileLoaded += 1;\n            } catch {\n                // Hotset prewarm is best-effort only.\n            }\n        }\n\n        if (this._isResourceCurrent(generation)) this._hotsetPrewarmed = true;\n        return result;\n    }\n\n    async flushPersistentCache() {\n        if (!this._imageryCacheEnabled) return;\n        const cache = await this._initImageryCache();\n        if (cache) {\n            await this._persistRecentPersistentKeys(cache);\n        }\n        if (cache && typeof cache.flush === 'function') {\n            await cache.flush();\n        }\n    }\n\n    dispose() {\n        this._resourceSuspended = true;\n        this._resourceGeneration += 1;\n        this.clearQueues();\n        this._clearAllCaches();\n\n        const cache = this._imageryCache;\n        if (cache) {\n            Promise.resolve()\n                .then(async () => {\n                    await this._persistRecentPersistentKeys(cache);\n                    if (typeof cache.flush === 'function') {\n                        await cache.flush();\n                    }\n                })\n                .catch(() => {})\n                .finally(() => {\n                    if (typeof cache.close === 'function') {\n                        cache.close();\n                    }\n                });\n        }\n        this._imageryCacheReady = false;\n        this._imageryCacheInitPromise = null;\n    }\n\n    /**\n     * Stop transient imagery work and release decoded/GPU textures without\n     * changing the user's imagery setting. In-flight requests carry a resource\n     * generation and discard their result when they return.\n     */\n    suspendAndReleaseTransient() {\n        const token = {\n            generation: ++this._resourceGeneration,\n            wasSuspended: this._resourceSuspended,\n        };\n        this._resourceSuspended = true;\n        this.clearQueues();\n        this._clearAllCaches();\n        return token;\n    }\n\n    resumeTransientResources(token = null) {\n        if (token && token.wasSuspended) return false;\n        this._resourceGeneration += 1;\n        this._resourceSuspended = false;\n        this._hotsetPrewarmed = false;\n        return true;\n    }\n\n    setRequestContext(key, { hardReset = false } = {}) {\n        if (!key) return;\n        const now = Date.now();\n        const changed = this.requestContextKey !== key;\n        if (changed) {\n            this.requestContextKey = key;\n            this._contextBurstUntil = now + this.contextBurstMs;\n        }\n        if (hardReset) {\n            // Keep queued work alive; strict mode will naturally prefer current context.\n            this._strictContextUntil = now + 800;\n        } else if (changed) {\n            this._strictContextUntil = 0;\n        }\n    }\n\n    clearQueues() {\n        while (this.tileQueue.length) {\n            const item = this.tileQueue.shift();\n            this._resolveQueuedItem(item, null);\n        }\n        while (this.atlasQueue.length) {\n            const item = this.atlasQueue.shift();\n            this._resolveQueuedItem(item, null);\n        }\n    }\n\n    _resolveQueuedItem(item, value) {\n        if (!item) return;\n        if (Array.isArray(item.resolvers) && item.resolvers.length) {\n            for (const resolve of item.resolvers) {\n                if (typeof resolve === 'function') resolve(value);\n            }\n            return;\n        }\n        if (typeof item.resolve === 'function') {\n            item.resolve(value);\n        }\n    }\n\n    _enqueue(queue, item) {\n        if (!Number.isFinite(item.priority)) item.priority = 0;\n        if (!Number.isFinite(item.enqueuedAt)) item.enqueuedAt = Date.now();\n        const maxQueue = queue === this.tileQueue\n            ? this.maxQueuedTileRequests\n            : this.maxQueuedAtlasRequests;\n        if (Number.isFinite(maxQueue) && maxQueue > 0 && queue.length >= maxQueue) {\n            const dropped = queue.pop();\n            this._resolveQueuedItem(dropped, null);\n        }\n        item.seq = this._queueSeq++;\n        const itemRing = Number.isFinite(item.ring) ? item.ring : 99;\n        let idx = queue.length;\n        while (idx > 0) {\n            const prev = queue[idx - 1];\n            const prevRing = Number.isFinite(prev.ring) ? prev.ring : 99;\n            if (prev.priority > item.priority) break;\n            if (prev.priority === item.priority) {\n                if (prevRing < itemRing) break;\n                if (prevRing === itemRing && prev.seq < item.seq) break;\n            }\n            idx--;\n        }\n        queue.splice(idx, 0, item);\n    }\n\n    _requeueItem(queue, item) {\n        if (!queue || !item) return;\n        const idx = queue.indexOf(item);\n        if (idx >= 0) {\n            queue.splice(idx, 1);\n        }\n        this._enqueue(queue, item);\n    }\n\n    _dequeue(queue) {\n        const strict = this._strictContextUntil > Date.now();\n        const contextKey = this.requestContextKey;\n        if (contextKey) {\n            const matchIndex = queue.findIndex((item) => item && item.contextKey === contextKey);\n            if (matchIndex >= 0) {\n                const [item] = queue.splice(matchIndex, 1);\n                return item;\n            }\n            if (strict) {\n                return null;\n            }\n\n            // If focused-context traffic is continuous, allow stale out-of-context\n            // work through to prevent permanent starvation of blinking tiles.\n            const now = Date.now();\n            const staleMs = Number.isFinite(this.contextQueueStarvationMs)\n                ? this.contextQueueStarvationMs\n                : 0;\n            if (staleMs > 0) {\n                const staleIndex = queue.findIndex((item) => {\n                    if (!item || item.contextKey === contextKey) return false;\n                    const enqueuedAt = Number.isFinite(item.enqueuedAt) ? item.enqueuedAt : now;\n                    return (now - enqueuedAt) >= staleMs;\n                });\n                if (staleIndex >= 0) {\n                    const [item] = queue.splice(staleIndex, 1);\n                    return item;\n                }\n            }\n        }\n        while (queue.length) {\n            const item = queue.shift();\n            if (!item) continue;\n            return item;\n        }\n        return null;\n    }\n\n    _burstActive(contextKey) {\n        if (!contextKey) return false;\n        if (!this.requestContextKey || contextKey !== this.requestContextKey) return false;\n        return Date.now() < this._contextBurstUntil;\n    }\n\n    async _drawAtlasTiles(ctx, queue, generation = this._resourceGeneration) {\n        try {\n            if (!ctx || !queue || !queue.length) return;\n            const budgetMs = Math.max(0, this.atlasDrawBudgetMs || 0);\n            const minTiles = Math.max(1, this.atlasDrawMinTiles || 1);\n            let idx = 0;\n\n            const yieldFrame = () => new Promise((resolve) => {\n                // A hidden document may stop RAF indefinitely. Keep the held draw\n                // sources bounded in lifetime, including cancellation/teardown.\n                let frame = null;\n                const finish = () => {\n                    clearTimeout(timer);\n                    if (frame != null && typeof cancelAnimationFrame === 'function') cancelAnimationFrame(frame);\n                    resolve();\n                };\n                const timer = setTimeout(finish, 32);\n                if (typeof requestAnimationFrame === 'function') frame = requestAnimationFrame(finish);\n            });\n\n            while (idx < queue.length) {\n                if (!this._isResourceCurrent(generation)) throw new DOMException('Stale atlas draw', 'AbortError');\n                const start = performance.now();\n                let drawn = 0;\n                while (idx < queue.length &&\n                    (drawn < minTiles || (performance.now() - start) < budgetMs)) {\n                    const entry = queue[idx++];\n                    const { image, x, y, size } = entry;\n                    const hasSourceRect = Number.isFinite(entry.sx) &&\n                        Number.isFinite(entry.sy) &&\n                        Number.isFinite(entry.sWidth) &&\n                        Number.isFinite(entry.sHeight);\n                    if (hasSourceRect) {\n                        ctx.drawImage(image, entry.sx, entry.sy, entry.sWidth, entry.sHeight, x, y, size, size);\n                    } else {\n                        ctx.drawImage(image, x, y, size, size);\n                    }\n                    entry.release?.();\n                    drawn++;\n                }\n                if (idx < queue.length && budgetMs > 0) {\n                    await yieldFrame();\n                }\n            }\n        } finally { this._releaseDrawQueue(queue); }\n    }\n\n    _releaseDrawQueue(queue) {\n        for (const entry of queue || []) entry.release?.();\n    }\n\n    _canBypassRetryDelay(opts = {}) {\n        const priority = Number.isFinite(opts?.priority) ? opts.priority : 0;\n        if (!Number.isFinite(this.retryBypassPriority)) return false;\n        return priority >= this.retryBypassPriority;\n    }\n\n    async _collectAtlasTiles({ minX, maxX, minY, maxY, z, n, versionId, opts, tileSize, generation = this._resourceGeneration }) {\n        const requests = [];\n        const drawQueue = [];\n        const failedEntries = [];\n\n        const h = (maxY - minY + 1);\n        const w = (maxX - minX + 1);\n        for (let ty = 0; ty < h; ty++) {\n            const y = minY + ty;\n            for (let tx = 0; tx < w; tx++) {\n                const xUnwrapped = minX + tx;\n                const x = THREE.MathUtils.euclideanModulo(xUnwrapped, n);\n                requests.push({\n                    x,\n                    y,\n                    drawX: tx * tileSize,\n                    drawY: ty * tileSize\n                });\n            }\n        }\n\n        let nextIndex = 0;\n        const workerLimit = Math.max(\n            1,\n            Math.min(\n                requests.length,\n                Math.floor(\n                    Number.isFinite(this.atlasTileFetchConcurrency)\n                        ? this.atlasTileFetchConcurrency\n                        : this.maxConcurrentTileLoads\n                )\n            )\n        );\n        const workers = Array.from({ length: workerLimit }, async () => {\n            while (true) {\n                const idx = nextIndex++;\n                if (idx >= requests.length || !this._isResourceCurrent(generation)) break;\n                const req = requests[idx];\n                const tex = await this.getTile(req.x, req.y, z, {\n                    priority: opts.priority,\n                    contextKey: opts.contextKey,\n                    versionId\n                });\n                if (tex && tex.image && this._isResourceCurrent(generation)) {\n                    drawQueue.push({\n                        release: this._ownedTextures().retain(tex),\n                        image: tex.image,\n                        x: req.drawX,\n                        y: req.drawY,\n                        size: tileSize\n                    });\n                } else {\n                    failedEntries.push(req);\n                }\n            }\n        });\n        const settled = await Promise.allSettled(workers);\n        const failed = settled.find(result => result.status === 'rejected');\n        if (failed || !this._isResourceCurrent(generation)) {\n            this._releaseDrawQueue(drawQueue);\n            if (failed) throw failed.reason;\n            drawQueue.length = 0;\n        }\n        return { drawQueue, failedEntries, totalTiles: requests.length };\n    }\n\n    async _buildParentFallbackDrawQueue({ failedEntries, z, versionId, opts, tileSize, generation = this._resourceGeneration }) {\n        if (!this.atlasParentFallbackEnabled) return [];\n        if (!Array.isArray(failedEntries) || failedEntries.length === 0) return [];\n        if (!Number.isFinite(z) || z <= 0) return [];\n\n        const parentByKey = new Map();\n        for (const entry of failedEntries) {\n            if (!entry) continue;\n            const px = Math.floor(entry.x / 2);\n            const py = Math.floor(entry.y / 2);\n            const key = `${px}|${py}`;\n            if (!parentByKey.has(key)) {\n                parentByKey.set(key, { x: px, y: py });\n            }\n        }\n        const parentList = Array.from(parentByKey.values());\n        const maxParents = Math.max(\n            1,\n            Math.floor(\n                Number.isFinite(this.atlasParentFallbackMaxParents)\n                    ? this.atlasParentFallbackMaxParents\n                    : 64\n            )\n        );\n        if (parentList.length > maxParents) {\n            parentList.length = maxParents;\n        }\n\n        const parentTexByKey = new Map();\n        const parentHolds = [];\n        const fallbackQueue = [];\n        try {\n        let nextIndex = 0;\n        const workerLimit = Math.max(\n            1,\n            Math.min(\n                parentList.length,\n                Math.floor(\n                    Number.isFinite(this.atlasTileFetchConcurrency)\n                        ? this.atlasTileFetchConcurrency\n                        : this.maxConcurrentTileLoads\n                )\n            )\n        );\n        const workers = Array.from({ length: workerLimit }, async () => {\n            while (true) {\n                const idx = nextIndex++;\n                if (idx >= parentList.length || !this._isResourceCurrent(generation)) break;\n                const parent = parentList[idx];\n                const tex = await this.getTile(parent.x, parent.y, z - 1, {\n                    priority: opts.priority,\n                    contextKey: opts.contextKey,\n                    versionId\n                });\n                if (tex && tex.image && this._isResourceCurrent(generation)) {\n                    parentHolds.push(this._ownedTextures().retain(tex));\n                    parentTexByKey.set(`${parent.x}|${parent.y}`, tex);\n                }\n            }\n        });\n        const settled = await Promise.allSettled(workers);\n        const failed = settled.find(result => result.status === 'rejected');\n        if (failed) throw failed.reason;\n        if (!this._isResourceCurrent(generation)) return [];\n        for (const entry of failedEntries) {\n            const px = Math.floor(entry.x / 2);\n            const py = Math.floor(entry.y / 2);\n            const parentTex = parentTexByKey.get(`${px}|${py}`);\n            if (!parentTex?.image) continue;\n            const parentImage = parentTex.image;\n            const parentW = Number.isFinite(parentImage.width) ? parentImage.width : this._getTileSizeValue();\n            const parentH = Number.isFinite(parentImage.height) ? parentImage.height : this._getTileSizeValue();\n            const quadW = parentW * 0.5;\n            const quadH = parentH * 0.5;\n            fallbackQueue.push({\n                release: this._ownedTextures().retain(parentTex),\n                image: parentImage,\n                sx: (entry.x & 1) ? quadW : 0,\n                sy: (entry.y & 1) ? quadH : 0,\n                sWidth: quadW,\n                sHeight: quadH,\n                x: entry.drawX,\n                y: entry.drawY,\n                size: tileSize\n            });\n        }\n        return fallbackQueue;\n        } catch (error) {\n            this._releaseDrawQueue(fallbackQueue);\n            throw error;\n        } finally {\n            for (const release of parentHolds) release();\n        }\n    }\n\n    setConfig({\n        enabled,\n        versionId,\n        zoom,\n        maxAtlasTiles,\n        padTiles,\n        maxTileCacheMB,\n        maxAtlasCacheMB,\n        textureAnisotropy,\n        tileSize,\n        useMobileTiles,\n        maxConcurrentAtlasBuilds,\n        maxConcurrentTileLoads,\n        contextBurstTileLoads,\n        contextBurstAtlasBuilds,\n        atlasDrawBudgetMs,\n        atlasDrawMinTiles,\n        tileRetryDelayMs,\n        atlasRetryDelayMs,\n        retryBypassPriority,\n        maxAtlasTileFetches,\n        atlasTileFetchConcurrency,\n        atlasParentFallbackEnabled,\n        atlasParentFallbackMaxParents,\n        maxQueuedTileRequests,\n        maxQueuedAtlasRequests\n    } = {}) {\n        // A fallback instance owns a fixed canonical raster. Scene settings\n        // still update the ordinary Wayback manager, never this source identity.\n        if (this.mapSource) {\n            versionId = this.versionId;\n            enabled = true;\n            tileSize = this.mapSource.tileSize || 256;\n        }\n        const prev = {\n            versionId: this.versionId,\n            zoom: this.zoom,\n            maxAtlasTiles: this.maxAtlasTiles,\n            padTiles: this.padTiles,\n            tileSize: this._getTileSizeValue()\n        };\n        if (typeof enabled === 'boolean') {\n            this._desiredEnabled = enabled;\n            if (!this._pendingLatest) {\n                this.enabled = enabled;\n            }\n        }\n        if (versionId !== undefined) {\n            this._applyPreferredVersion(versionId);\n        }\n        if (Number.isFinite(zoom)) this.zoom = Math.max(0, Math.min(18, Math.floor(zoom)));\n\n        if (Number.isFinite(maxAtlasTiles)) this.maxAtlasTiles = Math.max(1, Math.min(16, Math.floor(maxAtlasTiles)));\n        if (Number.isFinite(padTiles)) this.padTiles = Math.max(0, Math.min(2, Math.floor(padTiles)));\n\n        if (Number.isFinite(maxTileCacheMB)) this.maxTileCacheBytes = maxTileCacheMB * 1024 * 1024;\n        if (Number.isFinite(maxAtlasCacheMB)) this.maxAtlasCacheBytes = maxAtlasCacheMB * 1024 * 1024;\n        if (Number.isFinite(textureAnisotropy)) {\n            this.textureAnisotropy = Math.max(1, Math.min(16, Math.floor(textureAnisotropy)));\n        }\n        if (typeof useMobileTiles === 'boolean') {\n            this.useMobileTiles = useMobileTiles;\n            if (!Number.isFinite(tileSize)) {\n                this.tileSize = useMobileTiles ? 128 : 256;\n            }\n        }\n        if (Number.isFinite(tileSize)) {\n            this.tileSize = Math.max(64, Math.min(512, Math.floor(tileSize)));\n        }\n        if (Number.isFinite(maxConcurrentAtlasBuilds)) {\n            this.maxConcurrentAtlasBuilds = Math.max(1, Math.min(16, Math.floor(maxConcurrentAtlasBuilds)));\n        }\n        if (Number.isFinite(maxConcurrentTileLoads)) {\n            this.maxConcurrentTileLoads = Math.max(1, Math.min(64, Math.floor(maxConcurrentTileLoads)));\n        }\n        if (Number.isFinite(contextBurstTileLoads)) {\n            this.contextBurstTileLoads = Math.max(0, Math.min(32, Math.floor(contextBurstTileLoads)));\n        }\n        if (Number.isFinite(contextBurstAtlasBuilds)) {\n            this.contextBurstAtlasBuilds = Math.max(0, Math.min(8, Math.floor(contextBurstAtlasBuilds)));\n        }\n        if (Number.isFinite(atlasDrawBudgetMs)) {\n            this.atlasDrawBudgetMs = Math.max(0, Math.min(16, atlasDrawBudgetMs));\n        }\n        if (Number.isFinite(atlasDrawMinTiles)) {\n            this.atlasDrawMinTiles = Math.max(1, Math.min(64, Math.floor(atlasDrawMinTiles)));\n        }\n        if (Number.isFinite(tileRetryDelayMs)) {\n            this.tileRetryDelayMs = Math.max(0, Math.min(60000, Math.floor(tileRetryDelayMs)));\n        }\n        if (Number.isFinite(atlasRetryDelayMs)) {\n            this.atlasRetryDelayMs = Math.max(0, Math.min(60000, Math.floor(atlasRetryDelayMs)));\n        }\n        if (Number.isFinite(retryBypassPriority)) {\n            this.retryBypassPriority = Math.max(0, Math.floor(retryBypassPriority));\n        }\n        if (Number.isFinite(maxAtlasTileFetches)) {\n            this.maxAtlasTileFetches = Math.max(1, Math.min(512, Math.floor(maxAtlasTileFetches)));\n        }\n        if (Number.isFinite(atlasTileFetchConcurrency)) {\n            this.atlasTileFetchConcurrency = Math.max(1, Math.min(32, Math.floor(atlasTileFetchConcurrency)));\n        }\n        if (typeof atlasParentFallbackEnabled === 'boolean') {\n            this.atlasParentFallbackEnabled = atlasParentFallbackEnabled;\n        }\n        if (Number.isFinite(atlasParentFallbackMaxParents)) {\n            this.atlasParentFallbackMaxParents = Math.max(1, Math.min(512, Math.floor(atlasParentFallbackMaxParents)));\n        }\n        if (Number.isFinite(maxQueuedTileRequests)) {\n            this.maxQueuedTileRequests = Math.max(16, Math.min(16384, Math.floor(maxQueuedTileRequests)));\n        }\n        if (Number.isFinite(maxQueuedAtlasRequests)) {\n            this.maxQueuedAtlasRequests = Math.max(8, Math.min(4096, Math.floor(maxQueuedAtlasRequests)));\n        }\n\n        const next = {\n            versionId: this.versionId,\n            zoom: this.zoom,\n            maxAtlasTiles: this.maxAtlasTiles,\n            padTiles: this.padTiles,\n            tileSize: this._getTileSizeValue()\n        };\n        const atlasLayoutChanged = prev.versionId !== next.versionId ||\n            prev.zoom !== next.zoom ||\n            prev.maxAtlasTiles !== next.maxAtlasTiles ||\n            prev.padTiles !== next.padTiles ||\n            prev.tileSize !== next.tileSize;\n        if (atlasLayoutChanged) this._clearAllCaches({ keepTiles: true });\n    }\n\n    getConfig() {\n        return {\n            enabled: this.enabled,\n            versionId: this.versionId,\n            zoom: this.zoom,\n            maxAtlasTiles: this.maxAtlasTiles,\n            padTiles: this.padTiles,\n            maxTileCacheMB: this.maxTileCacheBytes / (1024 * 1024),\n            maxAtlasCacheMB: this.maxAtlasCacheBytes / (1024 * 1024),\n            textureAnisotropy: this.textureAnisotropy,\n            tileSize: this._getTileSizeValue(),\n            useMobileTiles: this.useMobileTiles,\n            maxConcurrentAtlasBuilds: this.maxConcurrentAtlasBuilds,\n            maxConcurrentTileLoads: this.maxConcurrentTileLoads,\n            contextBurstTileLoads: this.contextBurstTileLoads,\n            contextBurstAtlasBuilds: this.contextBurstAtlasBuilds,\n            atlasDrawBudgetMs: this.atlasDrawBudgetMs,\n            atlasDrawMinTiles: this.atlasDrawMinTiles,\n            tileRetryDelayMs: this.tileRetryDelayMs,\n            atlasRetryDelayMs: this.atlasRetryDelayMs,\n            retryBypassPriority: this.retryBypassPriority,\n            maxAtlasTileFetches: this.maxAtlasTileFetches,\n            atlasTileFetchConcurrency: this.atlasTileFetchConcurrency,\n            atlasParentFallbackEnabled: this.atlasParentFallbackEnabled,\n            atlasParentFallbackMaxParents: this.atlasParentFallbackMaxParents,\n            maxQueuedTileRequests: this.maxQueuedTileRequests,\n            maxQueuedAtlasRequests: this.maxQueuedAtlasRequests\n        };\n    }\n\n    /**\n     * Estimate texture memory usage in bytes\n     */\n    _estimateTextureBytes(tex) {\n        if (!tex || !tex.image) return 0;\n        const width = tex.image.width || 256;\n        const height = tex.image.height || 256;\n        // Assume RGBA (4 bytes per pixel)\n        return width * height * 4;\n    }\n\n    /**\n     * Evict oldest entries from tile cache until under budget\n     */\n    _evictTileCache() {\n        while (this.currentTileCacheBytes > this.maxTileCacheBytes && this.tileCache.size > 0) {\n            // Get oldest entry (first in Map)\n            const firstKey = Array.from(this.tileCache).find(([, entry]) => entry.texture)?.[0];\n            if (firstKey === undefined) break; // Pending requests retain their identity.\n            const cached = this.tileCache.get(firstKey);\n            if (cached && cached.texture) {\n                const bytes = this._estimateTextureBytes(cached.texture);\n                this._releaseTexture(cached.texture);\n                this.currentTileCacheBytes -= bytes;\n            }\n            this.tileCache.delete(firstKey);\n        }\n    }\n\n    /**\n     * Evict oldest entries from atlas cache until under budget\n     * Only evicts atlases with zero ref count\n     */\n    _evictAtlasCache() {\n        while (this.currentAtlasCacheBytes > this.maxAtlasCacheBytes && this.atlasCache.size > 0) {\n            let evicted = false;\n            // Find oldest entry with zero refs\n            for (const [key, cached] of this.atlasCache.entries()) {\n                const refCount = this._atlasTextureRefs?.get(key)?.get(cached.texture)?.length || 0;\n                if (cached.texture && refCount === 0) {\n                    if (cached && cached.texture) {\n                        const bytes = this._estimateTextureBytes(cached.texture);\n                        this._releaseTexture(cached.texture);\n                        this.currentAtlasCacheBytes -= bytes;\n                    }\n                    this.atlasCache.delete(key);\n                    evicted = true;\n                    break;\n                }\n            }\n            // If no unreferenced atlases found, stop\n            if (!evicted) break;\n        }\n    }\n\n    buildUrl(versionId, z, x, y) {\n        if (this.mapSource) return this.mapSource.url\n            .replaceAll('{z}', String(z)).replaceAll('{x}', String(x)).replaceAll('{y}', String(y));\n        return `${WMTS_ROOT}/tile/${versionId}/${z}/${y}/${x}`;\n    }\n\n    getZoomTileCount(z) {\n        const n = Math.max(1, Math.pow(2, Math.max(0, Math.floor(z))));\n        return n * n;\n    }\n\n    async _fetchTileBlob(url, cacheKey, { force = false, signal } = {}) {\n        const cache = await this._initImageryCache();\n        if (!force && cache && cacheKey) {\n            try {\n                const cached = await cache.get(cacheKey);\n                if (cached && cached.b) {\n                    return { blob: cached.b, cached: true };\n                }\n            } catch (err) {\n                console.warn('[imagery] IndexedDB tile read failed:', err);\n            }\n        }\n\n        try {\n            const response = await fetch(url, { mode: 'cors', signal });\n            if (!response.ok) {\n                throw new Error(`HTTP ${response.status}`);\n            }\n            const blob = await response.blob();\n            if (cache && cacheKey) {\n                try {\n                    cache.put({ k: cacheKey, b: blob });\n                } catch (err) {\n                    console.warn('[imagery] IndexedDB tile write failed:', err);\n                }\n            }\n            return { blob, cached: false };\n        } catch (err) {\n            return { blob: null, cached: false, error: err };\n        }\n    }\n\n    startZoomLevelDownload({ zoom, versionId, concurrency = 8, onProgress } = {}) {\n        if (this._bulkDownload?.active) return this._bulkDownload;\n        const safeZoom = Math.max(0, Math.floor(Number.isFinite(zoom) ? zoom : 0));\n        const vId = versionId || this.versionId;\n        const total = this.getZoomTileCount(safeZoom);\n        const n = Math.pow(2, safeZoom);\n        const aborter = new AbortController();\n        const state = {\n            active: true,\n            cancelled: false,\n            zoom: safeZoom,\n            versionId: vId,\n            total,\n            completed: 0,\n            downloaded: 0,\n            cached: 0,\n            failed: 0,\n            inFlight: 0,\n            startedAt: Date.now(),\n            cancel: () => {\n                state.cancelled = true;\n                aborter.abort();\n            },\n            promise: null\n        };\n\n        const workerCount = Math.max(1, Math.min(32, Math.floor(concurrency)));\n        let nextIndex = 0;\n\n        const notify = () => {\n            if (typeof onProgress === 'function') {\n                onProgress({\n                    zoom: state.zoom,\n                    versionId: state.versionId,\n                    total: state.total,\n                    completed: state.completed,\n                    downloaded: state.downloaded,\n                    cached: state.cached,\n                    failed: state.failed,\n                    inFlight: state.inFlight,\n                    cancelled: state.cancelled,\n                    percent: state.total > 0 ? state.completed / state.total : 0\n                });\n            }\n        };\n\n        const runWorker = async () => {\n            while (true) {\n                if (state.cancelled) return;\n                const idx = nextIndex++;\n                if (idx >= total) return;\n                const x = idx % n;\n                const y = Math.floor(idx / n);\n                const key = this._tileKey(vId, safeZoom, x, y);\n                const url = this.buildUrl(vId, safeZoom, x, y);\n                state.inFlight += 1;\n                const result = await this._fetchTileBlob(url, key, { signal: aborter.signal });\n                state.inFlight -= 1;\n                if (result?.blob) {\n                    if (result.cached) state.cached += 1;\n                    else state.downloaded += 1;\n                } else {\n                    state.failed += 1;\n                }\n                state.completed += 1;\n                if (state.completed % 10 === 0 || state.completed === total) {\n                    notify();\n                }\n            }\n        };\n\n        state.promise = (async () => {\n            try {\n                notify();\n                const workers = Array.from({ length: workerCount }, () => runWorker());\n                await Promise.all(workers);\n            } catch (err) {\n                if (!state.cancelled) {\n                    console.warn('[imagery] Bulk download failed:', err);\n                }\n            } finally {\n                state.active = false;\n                notify();\n                if (this._bulkDownload === state) {\n                    this._bulkDownload = null;\n                }\n            }\n            return {\n                zoom: state.zoom,\n                versionId: state.versionId,\n                total: state.total,\n                completed: state.completed,\n                downloaded: state.downloaded,\n                cached: state.cached,\n                failed: state.failed,\n                cancelled: state.cancelled,\n                durationMs: Date.now() - state.startedAt\n            };\n        })();\n\n        this._bulkDownload = state;\n        return state;\n    }\n\n    async exportZoomLevelTar({ zoom, versionId, onProgress } = {}) {\n        const cache = await this._initImageryCache();\n        if (!cache) {\n            throw new Error('Imagery cache not available.');\n        }\n        const safeZoom = Math.max(0, Math.floor(Number.isFinite(zoom) ? zoom : 0));\n        const vId = versionId || this.versionId;\n        const total = this.getZoomTileCount(safeZoom);\n        const n = Math.pow(2, safeZoom);\n        const chunks = [];\n        let processed = 0;\n        let exported = 0;\n        let missing = 0;\n        const now = Math.floor(Date.now() / 1000);\n\n        for (let y = 0; y < n; y++) {\n            for (let x = 0; x < n; x++) {\n                const key = this._tileKey(vId, safeZoom, x, y);\n                const cached = await cache.get(key);\n                if (!cached || !cached.b) {\n                    missing += 1;\n                    processed += 1;\n                    if (onProgress && processed % 10 === 0) {\n                        onProgress({ processed, total, exported, missing });\n                    }\n                    continue;\n                }\n                const blob = cached.b;\n                const buffer = new Uint8Array(await blob.arrayBuffer());\n                const ext = blob.type === 'image/png'\n                    ? 'png'\n                    : (blob.type === 'image/jpeg' ? 'jpg' : 'bin');\n                const name = `${vId}/${safeZoom}/${x}/${y}.${ext}`;\n                const header = this._buildTarHeader(name, buffer.length, now);\n                chunks.push(header, buffer);\n                const pad = (512 - (buffer.length % 512)) % 512;\n                if (pad) chunks.push(new Uint8Array(pad));\n                exported += 1;\n                processed += 1;\n                if (onProgress && processed % 10 === 0) {\n                    onProgress({ processed, total, exported, missing });\n                }\n            }\n        }\n\n        // End of archive: two 512-byte blocks of zeros\n        chunks.push(new Uint8Array(1024));\n        if (onProgress) onProgress({ processed, total, exported, missing });\n\n        return {\n            blob: new Blob(chunks, { type: 'application/x-tar' }),\n            total,\n            exported,\n            missing,\n            zoom: safeZoom,\n            versionId: vId\n        };\n    }\n\n    _buildTarHeader(name, size, mtime) {\n        const header = new Uint8Array(512);\n        const encoder = new TextEncoder();\n\n        const writeString = (str, offset, length) => {\n            const bytes = encoder.encode(str);\n            header.set(bytes.slice(0, length), offset);\n        };\n\n        const writeOctal = (value, offset, length) => {\n            const str = value.toString(8).padStart(length - 1, '0') + '\\0';\n            writeString(str, offset, length);\n        };\n\n        writeString(name, 0, 100);\n        writeOctal(0o644, 100, 8);\n        writeOctal(0, 108, 8);\n        writeOctal(0, 116, 8);\n        writeOctal(size, 124, 12);\n        writeOctal(mtime || 0, 136, 12);\n        // checksum field initially filled with spaces\n        for (let i = 148; i < 156; i++) header[i] = 0x20;\n        header[156] = '0'.charCodeAt(0);\n        writeString('ustar', 257, 5);\n        header[262] = 0;\n        writeString('00', 263, 2);\n\n        let sum = 0;\n        for (let i = 0; i < 512; i++) sum += header[i];\n        const checksum = sum.toString(8).padStart(6, '0');\n        writeString(checksum, 148, 6);\n        header[154] = 0;\n        header[155] = 0x20;\n        return header;\n    }\n\n    _tileKey(versionId, z, x, y) {\n        return `${versionId}|${z}|${x}|${y}`;\n    }\n\n    _atlasKey(versionId, z, minX, minY, w, h) {\n        return `${versionId}|${z}|${minX}|${minY}|${w}|${h}`;\n    }\n\n    _normalizeTileCoords(z, x, y) {\n        const zoom = Math.max(0, Math.floor(Number.isFinite(z) ? z : 0));\n        const n = Math.pow(2, zoom);\n        const nx = THREE.MathUtils.euclideanModulo(\n            Math.floor(Number.isFinite(x) ? x : 0),\n            n\n        );\n        const ny = Math.max(0, Math.min(n - 1, Math.floor(Number.isFinite(y) ? y : 0)));\n        return { x: nx, y: ny, n, z: zoom };\n    }\n\n    _getAtlasProbeCoords(minX, maxX, minY, maxY, n) {\n        const midX = Math.floor((minX + maxX) * 0.5);\n        const midY = Math.floor((minY + maxY) * 0.5);\n        const clampedMinY = Math.max(0, Math.min(n - 1, Math.floor(minY)));\n        const clampedMaxY = Math.max(0, Math.min(n - 1, Math.floor(maxY)));\n        const candidates = [\n            [midX, midY],\n            [minX, clampedMinY],\n            [minX, clampedMaxY],\n            [maxX, clampedMinY],\n            [maxX, clampedMaxY]\n        ];\n        const out = [];\n        const seen = new Set();\n        for (const [rawX, rawY] of candidates) {\n            const x = THREE.MathUtils.euclideanModulo(Math.floor(rawX), n);\n            const y = Math.max(0, Math.min(n - 1, Math.floor(rawY)));\n            const key = `${x}|${y}`;\n            if (seen.has(key)) continue;\n            seen.add(key);\n            out.push({ x, y });\n        }\n        return out;\n    }\n\n    _isHardMissingStatus(status) {\n        return status === 404 || status === 410;\n    }\n\n    _pruneQueuedUnavailableZoomRequests(versionId, regionKey, maxZoom) {\n        if (!regionKey || !Number.isFinite(maxZoom)) return;\n        const normalizedVersionId = this._normalizeVersionId(versionId) || this.versionId;\n\n        const shouldDropTileRequest = (item) => {\n            if (!item || !Number.isFinite(item.z) || item.z <= maxZoom) return false;\n            const itemVersionId = this._normalizeVersionId(item.versionId) || this.versionId;\n            if (itemVersionId !== normalizedVersionId) return false;\n            const itemRegionKey = this._regionKey(itemVersionId, item.z, item.x, item.y);\n            return itemRegionKey === regionKey;\n        };\n\n        const shouldDropAtlasRequest = (item) => {\n            if (!item || !Number.isFinite(item.z) || item.z <= maxZoom) return false;\n            const itemVersionId = this._normalizeVersionId(item.versionId) || this.versionId;\n            if (itemVersionId !== normalizedVersionId) return false;\n            const centerX = Number.isFinite(item.minX) && Number.isFinite(item.maxX)\n                ? Math.floor((item.minX + item.maxX) * 0.5)\n                : item.minX;\n            const centerY = Number.isFinite(item.minY) && Number.isFinite(item.maxY)\n                ? Math.floor((item.minY + item.maxY) * 0.5)\n                : item.minY;\n            const itemRegionKey = this._regionKey(itemVersionId, item.z, centerX, centerY);\n            return itemRegionKey === regionKey;\n        };\n\n        if (this.tileQueue.length > 0) {\n            const kept = [];\n            for (const item of this.tileQueue) {\n                if (shouldDropTileRequest(item)) {\n                    if (typeof item.resolve === 'function') item.resolve(null);\n                    continue;\n                }\n                kept.push(item);\n            }\n            this.tileQueue = kept;\n        }\n\n        if (this.atlasQueue.length > 0) {\n            const kept = [];\n            for (const item of this.atlasQueue) {\n                if (shouldDropAtlasRequest(item)) {\n                    if (typeof item.resolve === 'function') item.resolve(null);\n                    continue;\n                }\n                kept.push(item);\n            }\n            this.atlasQueue = kept;\n        }\n    }\n\n    /**\n     * Get region key for zoom fallback cache\n     * Regions are defined at zoom level 10 to group nearby tiles\n     */\n    _regionKey(versionId, z, x, y) {\n        const normalizedVersionId = this._normalizeVersionId(versionId) || this.versionId;\n        const tile = this._normalizeTileCoords(z, x, y);\n        const regionZoom = 10;\n        let regionX;\n        let regionY;\n\n        if (tile.z >= regionZoom) {\n            const divisor = Math.pow(2, tile.z - regionZoom);\n            regionX = Math.floor(tile.x / divisor);\n            regionY = Math.floor(tile.y / divisor);\n        } else {\n            const multiplier = Math.pow(2, regionZoom - tile.z);\n            regionX = Math.floor(tile.x * multiplier);\n            regionY = Math.floor(tile.y * multiplier);\n        }\n\n        return `${normalizedVersionId}|${regionX}|${regionY}`;\n    }\n\n    /**\n     * Get the effective max zoom for a region, accounting for known limits\n     * Returns the requested zoom if no limit is known, or the cached limit\n     */\n    getEffectiveMaxZoom(versionId, z, x, y) {\n        if (this.mapSource) z = Math.min(z, this.mapSource.maxZoom ?? 19);\n        if (!this.regionZoomFallbackEnabled) return z;\n\n        const regionKey = this._regionKey(versionId, z, x, y);\n        const cached = this.regionMaxZoomCache.get(regionKey);\n        const now = Date.now();\n\n        if (cached && (now - cached.checkedAt) < this.regionMaxZoomCacheExpireMs) {\n            // Use cached max zoom, but don't exceed requested zoom\n            return Math.min(z, cached.maxZoom);\n        }\n\n        return z;\n    }\n\n    /**\n     * Record that a zoom level failed for a region, triggering fallback\n     * @returns {number|null} The fallback zoom to try, or null if no fallback available\n     */\n    recordZoomFailure(versionId, z, x, y) {\n        if (!this.regionZoomFallbackEnabled) return null;\n        if (z <= this.regionZoomMinFallback) return null; // Don't fall back below minimum\n\n        const normalizedVersionId = this._normalizeVersionId(versionId) || this.versionId;\n        const regionKey = this._regionKey(normalizedVersionId, z, x, y);\n        const now = Date.now();\n        const cached = this.regionMaxZoomCache.get(regionKey);\n\n        // Determine the new max zoom (one less than failed level)\n        const newMaxZoom = z - 1;\n\n        // Only update if this is lower than cached or cache is stale\n        if (!cached || newMaxZoom < cached.maxZoom || (now - cached.checkedAt) > this.regionMaxZoomCacheExpireMs) {\n            this.regionMaxZoomCache.set(regionKey, {\n                maxZoom: newMaxZoom,\n                checkedAt: now\n            });\n            console.log(`[imagery] Region ${regionKey} max zoom updated to ${newMaxZoom} (zoom ${z} unavailable)`);\n            this._pruneQueuedUnavailableZoomRequests(normalizedVersionId, regionKey, newMaxZoom);\n        }\n\n        // Return fallback zoom if above minimum\n        if (newMaxZoom >= this.regionZoomMinFallback) {\n            return newMaxZoom;\n        }\n        return null;\n    }\n\n    /**\n     * Clear region zoom cache (e.g., when switching imagery versions)\n     */\n    clearRegionZoomCache() {\n        this.regionMaxZoomCache.clear();\n    }\n\n    /**\n     * Get atlas key for external use (by TriTile)\n     */\n    getAtlasKey(versionId, z, minX, minY, w, h) {\n        return this._atlasKey(versionId, z, minX, minY, w, h);\n    }\n\n    _mosaicKey(versionId, z, minX, minY, w, h) {\n        return `mosaic|${versionId}|${z}|${minX}|${minY}|${w}|${h}`;\n    }\n\n    /**\n     * Build a temporary atlas from existing tile imagery (merge-time mosaic).\n     * Returns null if no tiles are available.\n     */\n    buildMosaicAtlasFromTiles({ versionId, z, minX, minY, wTiles, hTiles, priority, contextKey } = {}) {\n        const vId = versionId || this.versionId;\n        const zoom = Number.isFinite(z) ? z : 0;\n        const w = Number.isFinite(wTiles) ? Math.max(1, Math.floor(wTiles)) : 1;\n        const h = Number.isFinite(hTiles) ? Math.max(1, Math.floor(hTiles)) : 1;\n        const normalizedMinY = Math.max(0, minY);\n        const normalizedMaxY = Math.min(Math.pow(2, zoom) - 1, minY + h - 1);\n        const normalizedH = normalizedMaxY - normalizedMinY + 1;\n        const key = this._mosaicKey(vId, zoom, minX, normalizedMinY, w, normalizedH);\n        return this.getAtlas(minX, minX + w - 1, normalizedMinY, normalizedMaxY, zoom, {\n            versionId: vId, priority, contextKey, mosaic: true, skipPersistentCache: true\n        }).then(texture => texture ? {\n            texture, atlasKey: key, atlasZoom: zoom, minX, minY: normalizedMinY,\n            wTiles: w, hTiles: normalizedH, versionId: vId\n        } : null);\n    }\n\n    /**\n     * Retain atlas reference (increment ref count)\n     */\n    retainAtlas(key, texture = this.atlasCache.get(key)?.texture) {\n        if (!key || !texture) return;\n        const byKey = this._atlasTextureRefs ||= new Map();\n        let refs = byKey.get(key);\n        if (!refs) byKey.set(key, refs = new Map());\n        let leases = refs.get(texture);\n        if (!leases) refs.set(texture, leases = []);\n        leases.push(this._ownedTextures().retain(texture));\n        this.atlasRefCounts.set(key, (this.atlasRefCounts.get(key) || 0) + 1);\n    }\n\n    /** Release the exact texture, not a newer cache entry with the same key. */\n    releaseAtlas(key, texture = this.atlasCache.get(key)?.texture) {\n        const refs = this._atlasTextureRefs?.get(key);\n        const leases = refs?.get(texture);\n        if (!leases?.length) return;\n        leases.pop()();\n        if (!leases.length) refs.delete(texture);\n        if (!refs.size) this._atlasTextureRefs.delete(key);\n        const count = this.atlasRefCounts.get(key) || 0;\n        if (count <= 1) this.atlasRefCounts.delete(key);\n        else this.atlasRefCounts.set(key, count - 1);\n        this._evictAtlasCache();\n    }\n\n    /**\n     * Loads a single WMTS tile as a THREE.Texture\n     * @param {number} x - Tile X coordinate\n     * @param {number} y - Tile Y coordinate\n     * @param {number} z - Zoom level\n     * @returns {Promise<THREE.Texture|null>} Texture promise\n     */\n    getTile(x, y, z, opts = {}) {\n        if (this._resourceSuspended) return Promise.resolve(null);\n        const resourceGeneration = this._resourceGeneration;\n        const versionId = opts.versionId || this.versionId;\n        const coords = this._normalizeTileCoords(z, x, y);\n        const tileX = coords.x;\n        const tileY = coords.y;\n        const tileZ = coords.z;\n        const key = this._tileKey(versionId, tileZ, tileX, tileY);\n        const now = Date.now();\n\n        const cached = this.tileCache.get(key);\n        if (cached) {\n            if ('texture' in cached) {\n                if (!cached.texture) {\n                    const failedAt = cached.failedAt;\n                    const bypassRetryDelay = this._canBypassRetryDelay(opts);\n                    if (Number.isFinite(failedAt) &&\n                        now - failedAt < this.tileRetryDelayMs &&\n                        !bypassRetryDelay) {\n                        return Promise.resolve(null);\n                    }\n                    this.tileCache.delete(key);\n                } else {\n                    // Move to end for LRU (re-insert)\n                    this.tileCache.delete(key);\n                    this.tileCache.set(key, cached);\n                    return Promise.resolve(this._handoffTexture(cached.texture));\n                }\n            }\n            if (cached.promise) return cached.promise;\n        }\n\n        const effectiveZoom = this.getEffectiveMaxZoom(versionId, tileZ, tileX, tileY);\n        if (Number.isFinite(effectiveZoom) && effectiveZoom < tileZ) {\n            return Promise.resolve(null);\n        }\n\n        // Check in-flight limit (allow short burst for current context)\n        const tileLimit = this.maxConcurrentTileLoads +\n            (this._burstActive(opts.contextKey) ? this.contextBurstTileLoads : 0);\n        if (this.currentTileLoads >= tileLimit) {\n            const queuedKey = `${versionId}|${tileZ}|${tileX}|${tileY}`;\n            const existingQueued = this.tileQueue.find((item) => item?.queueKey === queuedKey);\n            if (existingQueued) {\n                return new Promise((resolve) => {\n                    let shouldRequeue = false;\n                    if (!Array.isArray(existingQueued.resolvers)) {\n                        existingQueued.resolvers = [];\n                    }\n                    existingQueued.resolvers.push(resolve);\n                    if (opts.contextKey && existingQueued.contextKey !== opts.contextKey) {\n                        existingQueued.contextKey = opts.contextKey;\n                        shouldRequeue = true;\n                    }\n                    if (Number.isFinite(opts.priority) &&\n                        (!Number.isFinite(existingQueued.priority) || opts.priority > existingQueued.priority)) {\n                        existingQueued.priority = opts.priority;\n                        shouldRequeue = true;\n                    }\n                    if (shouldRequeue) {\n                        this._requeueItem(this.tileQueue, existingQueued);\n                    }\n                });\n            }\n            // Return a queued promise\n            return new Promise((resolve) => {\n                this._enqueue(this.tileQueue, {\n                    x: tileX,\n                    y: tileY,\n                    z: tileZ,\n                    resolvers: [resolve],\n                    priority: opts.priority,\n                    contextKey: opts.contextKey,\n                    versionId,\n                    queueKey: queuedKey\n                });\n            });\n        }\n\n        const url = this.buildUrl(versionId, tileZ, tileX, tileY);\n        const request = {};\n        this.tileCache.set(key, request);\n        const isCurrent = () => this._isResourceCurrent(resourceGeneration) && this.tileCache.get(key) === request;\n        this.currentTileLoads++;\n        let tex = null, cachedTexture = false;\n        const promise = (async () => {\n            let failed = false, fetchStatus = null, usedLoaderFallback = false;\n            if (this._imageryCacheEnabled) {\n                const result = await this._loadTileTextureWithFetch(url, key);\n                tex = result?.tex || null;\n                failed = !!result?.failed;\n                fetchStatus = Number.isFinite(result?.status) ? result.status : null;\n            }\n            if (!isCurrent()) return null;\n            // Preserve existing provider behavior; explicit 4xx never duplicate.\n            const shouldUseLoaderFallback = !failed || !Number.isFinite(fetchStatus) || fetchStatus < 400 || fetchStatus >= 500;\n            if (!tex && shouldUseLoaderFallback) {\n                usedLoaderFallback = true;\n                tex = await new Promise(resolve => {\n                    this.loader.load(url, resolve, undefined, () => resolve(null));\n                });\n                if (!tex) failed = true;\n            }\n            if (!isCurrent()) return null;\n            if (tex) {\n                this._applyTextureSettings(tex);\n                this._handoffTexture(tex);\n                if (usedLoaderFallback && this._imageryCacheEnabled && tex.image) {\n                    this._persistLoadedImageToCache(key, tex.image).catch(() => {});\n                }\n                this.currentTileCacheBytes += this._estimateTextureBytes(tex);\n                this.tileCache.set(key, { texture: tex });\n                cachedTexture = true;\n                this._evictTileCache();\n            } else {\n                if (failed && this.regionZoomFallbackEnabled && this._isHardMissingStatus(fetchStatus)) {\n                    this.recordZoomFailure(versionId, tileZ, tileX, tileY);\n                }\n                this.tileCache.set(key, { texture: null, failedAt: Date.now(), status: fetchStatus });\n            }\n            return tex || null;\n        })().catch(() => {\n            if (isCurrent()) this.tileCache.set(key, { texture: null, failedAt: Date.now() });\n            return null;\n        }).finally(() => {\n            if (tex && !cachedTexture) this._releaseTexture(tex);\n            this.currentTileLoads--;\n            this._processQueues();\n        });\n        request.promise = promise;\n        return promise;\n    }\n\n    /**\n     * Process queued requests when slots become available\n     */\n    _processQueues() {\n        if (this._resourceSuspended) {\n            this.clearQueues();\n            return;\n        }\n        // Process tile queue\n        while (this.tileQueue.length > 0) {\n            const queued = this._dequeue(this.tileQueue);\n            if (!queued) break;\n            const tileLimit = this.maxConcurrentTileLoads +\n                (this._burstActive(queued.contextKey) ? this.contextBurstTileLoads : 0);\n            if (this.currentTileLoads >= tileLimit) {\n                this._enqueue(this.tileQueue, queued);\n                break;\n            }\n            this.getTile(queued.x, queued.y, queued.z, {\n                priority: queued.priority,\n                contextKey: queued.contextKey,\n                versionId: queued.versionId\n            }).then((value) => this._resolveQueuedItem(queued, value));\n        }\n        // Process atlas queue\n        while (this.atlasQueue.length > 0) {\n            const queued = this._dequeue(this.atlasQueue);\n            if (!queued) break;\n            const atlasLimit = this.maxConcurrentAtlasBuilds +\n                (this._burstActive(queued.contextKey) ? this.contextBurstAtlasBuilds : 0);\n            if (this.currentAtlasBuilds >= atlasLimit) {\n                this._enqueue(this.atlasQueue, queued);\n                break;\n            }\n            this.getAtlas(queued.minX, queued.maxX, queued.minY, queued.maxY, queued.z, {\n                priority: queued.priority,\n                contextKey: queued.contextKey,\n                ring: queued.ring,\n                mosaic: queued.mosaic,\n                skipPersistentCache: queued.skipPersistentCache,\n                versionId: queued.versionId\n            }).then((value) => this._resolveQueuedItem(queued, value));\n        }\n    }\n\n    /**\n     * Builds a stitched atlas texture spanning [minX..maxX] × [minY..maxY] at zoom z.\n     * Handles X wrap (antimeridian) by modding into [0..n-1] at fetch time.\n     * @param {number} minX - Minimum X tile coordinate\n     * @param {number} maxX - Maximum X tile coordinate\n     * @param {number} minY - Minimum Y tile coordinate\n     * @param {number} maxY - Maximum Y tile coordinate\n     * @param {number} z - Zoom level\n     * @returns {Promise<THREE.Texture|null>} Atlas texture promise\n     */\n    getAtlas(minX, maxX, minY, maxY, z, opts = {}) {\n        if (this._resourceSuspended) return Promise.resolve(null);\n        const resourceGeneration = this._resourceGeneration;\n        const versionId = opts.versionId || this.versionId;\n        const n = Math.pow(2, z);\n        const now = Date.now();\n\n        // normalize\n        minY = Math.max(0, minY);\n        maxY = Math.min(n - 1, maxY);\n\n        const w = (maxX - minX + 1);\n        const h = (maxY - minY + 1);\n        const atlasTileCount = w * h;\n        const tileSize = this._getTileSizeValue();\n\n        if (!Number.isFinite(atlasTileCount) || w < 1 || h < 1) return Promise.resolve(null);\n        const key = opts.mosaic\n            ? this._mosaicKey(versionId, z, minX, minY, w, h)\n            : this._atlasKey(versionId, z, minX, minY, w, h);\n        const cached = this.atlasCache.get(key);\n        if (cached) {\n            if ('texture' in cached) {\n                if (!cached.texture) {\n                    const failedAt = cached.failedAt;\n                    const bypassRetryDelay = this._canBypassRetryDelay(opts);\n                    if (Number.isFinite(failedAt) &&\n                        now - failedAt < this.atlasRetryDelayMs &&\n                        !bypassRetryDelay) {\n                        if (opts.skipPersistentCache) {\n                            return Promise.resolve(null);\n                        }\n                        this.atlasCache.delete(key);\n                    } else {\n                        this.atlasCache.delete(key);\n                    }\n                } else {\n                    // Move to end for LRU (re-insert)\n                    this.atlasCache.delete(key);\n                    this.atlasCache.set(key, cached);\n                    return Promise.resolve(this._handoffTexture(cached.texture));\n                }\n            }\n            if (cached.promise) return cached.promise;\n        }\n\n        const centerX = Math.floor((minX + maxX) * 0.5);\n        const centerY = Math.floor((minY + maxY) * 0.5);\n        // Check in-flight limit (allow short burst for current context)\n        const atlasLimit = this.maxConcurrentAtlasBuilds +\n            (this._burstActive(opts.contextKey) ? this.contextBurstAtlasBuilds : 0);\n        if (this.currentAtlasBuilds >= atlasLimit) {\n            const queueKey = `${opts.mosaic ? 'mosaic|' : ''}${versionId}|${z}|${minX}|${maxX}|${minY}|${maxY}`;\n            const existingQueued = this.atlasQueue.find((item) => item?.queueKey === queueKey);\n            if (existingQueued) {\n                return new Promise((resolve) => {\n                    let shouldRequeue = false;\n                    if (!Array.isArray(existingQueued.resolvers)) {\n                        existingQueued.resolvers = [];\n                    }\n                    existingQueued.resolvers.push(resolve);\n                    if (opts.contextKey && existingQueued.contextKey !== opts.contextKey) {\n                        existingQueued.contextKey = opts.contextKey;\n                        shouldRequeue = true;\n                    }\n                    if (Number.isFinite(opts.ring) &&\n                        (!Number.isFinite(existingQueued.ring) || opts.ring < existingQueued.ring)) {\n                        existingQueued.ring = opts.ring;\n                        shouldRequeue = true;\n                    }\n                    if (Number.isFinite(opts.priority) &&\n                        (!Number.isFinite(existingQueued.priority) || opts.priority > existingQueued.priority)) {\n                        existingQueued.priority = opts.priority;\n                        shouldRequeue = true;\n                    }\n                    if (shouldRequeue) {\n                        this._requeueItem(this.atlasQueue, existingQueued);\n                    }\n                });\n            }\n            // Return a queued promise\n            return new Promise((resolve) => {\n                this._enqueue(this.atlasQueue, {\n                    minX,\n                    maxX,\n                    minY,\n                    maxY,\n                    z,\n                    resolvers: [resolve],\n                    priority: opts.priority,\n                    contextKey: opts.contextKey,\n                    ring: opts.ring,\n                    mosaic: opts.mosaic === true,\n                    skipPersistentCache: opts.skipPersistentCache === true,\n                    versionId,\n                    queueKey\n                });\n            });\n        }\n\n        this.currentAtlasBuilds++;\n        const request = {};\n        this.atlasCache.set(key, request);\n        const isCurrent = () => this._isResourceCurrent(resourceGeneration) && this.atlasCache.get(key) === request;\n        let drawQueue = [], releaseCanvas = null, atlasTex = null, cachedTexture = false;\n        const promise = (async () => {\n            const failAtlas = () => {\n                if (isCurrent()) this.atlasCache.set(key, { texture: null, failedAt: Date.now() });\n                return null;\n            };\n            // IndexedDB restore/decode shares the normal atlas admission limit.\n            if (!opts.skipPersistentCache) {\n                atlasTex = await this._loadAtlasTextureFromPersistentCache(key, { atlasTileCount, atlasZoom: z });\n                if (!isCurrent()) return null;\n                if (atlasTex) {\n                    this._applyAtlasTextureSettings(atlasTex);\n                    this._handoffTexture(atlasTex);\n                    this.currentAtlasCacheBytes += this._estimateTextureBytes(atlasTex);\n                    this.atlasCache.set(key, { texture: atlasTex });\n                    cachedTexture = true;\n                    this._evictAtlasCache();\n                    return atlasTex;\n                }\n            }\n            if (!isCurrent()) return null;\n            const effectiveZoom = this.getEffectiveMaxZoom(versionId, z, centerX, centerY);\n            if (!opts.mosaic && Number.isFinite(effectiveZoom) && effectiveZoom < z) return failAtlas();\n\n            if (!opts.mosaic && atlasTileCount > this.maxAtlasTileFetches &&\n                this.regionZoomFallbackEnabled &&\n                z > this.regionZoomMinFallback) {\n                const fallbackZoom = this.recordZoomFailure(versionId, z, centerX, centerY);\n                if (fallbackZoom !== null) {\n                    console.log(\n                        `[imagery] Atlas span ${atlasTileCount} tiles exceeds limit ${this.maxAtlasTileFetches} at z${z}; forcing fallback to z${fallbackZoom}`\n                    );\n                }\n                return failAtlas();\n            }\n\n            if (!opts.mosaic && this.regionZoomFallbackEnabled && z > this.regionZoomMinFallback) {\n                const probes = this._getAtlasProbeCoords(minX, maxX, minY, maxY, n);\n                if (probes.length) {\n                    const probeResults = await Promise.all(probes.map(({ x, y }) =>\n                        this.getTile(x, y, z, {\n                            priority: opts.priority,\n                            contextKey: opts.contextKey,\n                            versionId\n                        })\n                    ));\n                    if (!isCurrent()) return null;\n                    const successfulProbes = probeResults.filter((tex) => !!tex).length;\n                    const probeCount = probeResults.length;\n                    const failedProbes = probeCount - successfulProbes;\n                    const probeFailureRatio = probeCount > 0 ? (failedProbes / probeCount) : 0;\n                    const severeProbeFailure = z >= 18 &&\n                        atlasTileCount >= 64 &&\n                        probeFailureRatio >= 0.8;\n                    if (successfulProbes === 0 || severeProbeFailure) {\n                        for (const { x, y } of probes) {\n                            this.recordZoomFailure(versionId, z, x, y);\n                        }\n                        const fallbackZoom = this.recordZoomFailure(\n                            versionId,\n                            z,\n                            Math.floor((minX + maxX) * 0.5),\n                            Math.floor((minY + maxY) * 0.5)\n                        );\n                        if (fallbackZoom !== null) {\n                            console.log(\n                                successfulProbes === 0\n                                    ? `[imagery] Probe detected unavailable zoom ${z}, marking max zoom ${fallbackZoom} before full atlas fetch`\n                                    : `[imagery] Probe failure ratio ${Math.round(probeFailureRatio * 100)}% at zoom ${z}, marking max zoom ${fallbackZoom} before full atlas fetch`\n                            );\n                        }\n                        return failAtlas();\n                    }\n                }\n            }\n\n            if (!isCurrent()) return null;\n            const canvas = document.createElement('canvas');\n            canvas.width = w * tileSize;\n            canvas.height = h * tileSize;\n            releaseCanvas = this._ownedTextures().holdCanvas(canvas);\n\n            const ctx = canvas.getContext('2d', { alpha: false, desynchronized: true });\n            // Disable smoothing to avoid bleeding adjacent texels across tile edges\n            if (!ctx) return failAtlas();\n            ctx.imageSmoothingEnabled = false;\n\n            const collected = await this._collectAtlasTiles({\n                minX,\n                maxX,\n                minY,\n                maxY,\n                z,\n                n,\n                versionId,\n                opts,\n                tileSize,\n                generation: resourceGeneration\n            });\n            drawQueue = collected.drawQueue;\n            const { failedEntries } = collected;\n            if (!isCurrent()) return null;\n\n            if (!opts.mosaic && failedEntries.length > 0) {\n                const fallbackQueue = await this._buildParentFallbackDrawQueue({\n                    failedEntries,\n                    z,\n                    versionId,\n                    opts,\n                    tileSize,\n                    generation: resourceGeneration\n                });\n                if (fallbackQueue.length > 0) {\n                    drawQueue.push(...fallbackQueue);\n                }\n            }\n\n            if (!isCurrent()) return null;\n            if (opts.mosaic && !drawQueue.length) return failAtlas();\n\n            // Check if too many tiles failed - trigger fallback to lower zoom\n            const totalTiles = atlasTileCount;\n            const successfulTiles = drawQueue.length;\n            const failedTiles = totalTiles - successfulTiles;\n\n            // If ALL tiles failed and we're above min fallback zoom, try lower zoom\n            if (successfulTiles === 0 && z > this.regionZoomMinFallback && this.regionZoomFallbackEnabled) {\n                // Record failure for this region and stop; caller will retry at lower zoom.\n                const fallbackZoom = this.recordZoomFailure(versionId, z, centerX, centerY);\n                if (fallbackZoom !== null) {\n                    console.log(`[imagery] All ${totalTiles} tiles failed at zoom ${z}, marking max zoom ${fallbackZoom}`);\n                }\n                return failAtlas();\n            }\n\n            // If majority of tiles failed (>50%) at high zoom, record for future requests\n            if (!opts.mosaic && failedTiles > totalTiles / 2 && z > this.regionZoomMinFallback) {\n                this.recordZoomFailure(versionId, z, centerX, centerY);\n            }\n\n            await this._drawAtlasTiles(ctx, drawQueue, resourceGeneration);\n            if (!isCurrent()) return null;\n\n            atlasTex = new THREE.CanvasTexture(canvas);\n            this._applyAtlasTextureSettings(atlasTex);\n\n            // Store the actual zoom used in case of fallback\n            atlasTex.userData = atlasTex.userData || {};\n            atlasTex.userData.actualZoom = z;\n\n            const bytes = this._estimateTextureBytes(atlasTex);\n            this.currentAtlasCacheBytes += bytes;\n            this._handoffTexture(atlasTex);\n            this.atlasCache.set(key, { texture: atlasTex });\n            cachedTexture = true;\n            if (!opts.mosaic) this._persistAtlasCanvasToCache(key, canvas, atlasTileCount).catch(() => {});\n            this._evictAtlasCache();\n            return atlasTex;\n        })().catch(err => {\n            if (err?.name !== 'AbortError') console.error('[imagery] atlas build failed', err);\n            if (isCurrent()) this.atlasCache.set(key, { texture: null, failedAt: Date.now() });\n            return null;\n        }).finally(() => {\n            this._releaseDrawQueue(drawQueue);\n            if (atlasTex && !cachedTexture) this._releaseTexture(atlasTex);\n            releaseCanvas?.();\n            this.currentAtlasBuilds--;\n            this._processQueues();\n        });\n\n        request.promise = promise;\n        return promise;\n    }\n\n    getStats({ includeOwnership = true } = {}) {\n        const tileLookups = this.cacheStats.idbTileHits + this.cacheStats.idbTileMisses;\n        const atlasLookups = this.cacheStats.idbAtlasHits + this.cacheStats.idbAtlasMisses;\n        const pendingWrites = this._imageryCache && typeof this._imageryCache.getPendingWriteCount === 'function'\n            ? this._imageryCache.getPendingWriteCount()\n            : 0;\n        return {\n            enabled: this.enabled,\n            requestContextKey: this.requestContextKey,\n            strictContextMs: Math.max(0, this._strictContextUntil - Date.now()),\n            burstActive: this._burstActive(this.requestContextKey),\n            currentTileLoads: this.currentTileLoads,\n            currentAtlasBuilds: this.currentAtlasBuilds,\n            tileQueue: this.tileQueue.length,\n            atlasQueue: this.atlasQueue.length,\n            tileCacheEntries: this.tileCache.size,\n            atlasCacheEntries: this.atlasCache.size,\n            tileCacheMB: this.currentTileCacheBytes / (1024 * 1024),\n            atlasCacheMB: this.currentAtlasCacheBytes / (1024 * 1024),\n            // RGBA estimates, not measured JS heap/VRAM. Includes live leases\n            // outside cache budgets; decoded sources are counted once.\n            ownership: includeOwnership ? this._ownedTextures().getStats() : undefined,\n            maxTileCacheMB: this.maxTileCacheBytes / (1024 * 1024),\n            maxAtlasCacheMB: this.maxAtlasCacheBytes / (1024 * 1024),\n            maxConcurrentTileLoads: this.maxConcurrentTileLoads,\n            maxConcurrentAtlasBuilds: this.maxConcurrentAtlasBuilds,\n            tileSize: this._getTileSizeValue(),\n            atlasTileFetchConcurrency: this.atlasTileFetchConcurrency,\n            maxAtlasTileFetches: this.maxAtlasTileFetches,\n            idbTileHits: this.cacheStats.idbTileHits,\n            idbTileMisses: this.cacheStats.idbTileMisses,\n            idbTileHitRatio: tileLookups > 0 ? (this.cacheStats.idbTileHits / tileLookups) : 0,\n            idbAtlasHits: this.cacheStats.idbAtlasHits,\n            idbAtlasMisses: this.cacheStats.idbAtlasMisses,\n            idbAtlasHitRatio: atlasLookups > 0 ? (this.cacheStats.idbAtlasHits / atlasLookups) : 0,\n            idbPersistentEnabled: !!this._imageryCacheEnabled,\n            idbPersistentReady: !!this._imageryCacheReady,\n            idbPendingWrites: pendingWrites,\n            idbRecentKeys: this._recentPersistentKeys.length,\n            hotsetPrewarmed: this._hotsetPrewarmed,\n            tileNetworkFetches: this.cacheStats.tileNetworkFetches,\n            tileNetworkMB: this.cacheStats.tileNetworkBytes / (1024 * 1024),\n            estimatedNetworkAvoidedTiles: this.cacheStats.idbTileHits + this.cacheStats.atlasNetworkAvoidedTiles,\n            estimatedNetworkAvoidedAtlasTiles: this.cacheStats.atlasNetworkAvoidedTiles\n        };\n    }\n}\n","import * as THREE from 'three';\nimport { latLonToLocalDir, ellipsoidRadiusForLocalDir } from '../../modules/geometry-utils.js';\nimport { bilinearEgm96Undulation } from './MapzenElevationTileSource.js';\nimport { yieldToEventLoop } from '../async/scheduler/BudgetScheduler.js';\n\nexport const MERCATOR_LIMIT = 85.0511287798066;\nexport function tileCoordinate(lon, lat, z) {\n  const n = 2 ** z;\n  return { z, x: ((((lon + 180) / 360) % 1) + 1) % 1 * n,\n    y: (1 - Math.asinh(Math.tan(THREE.MathUtils.degToRad(Math.max(-MERCATOR_LIMIT, Math.min(MERCATOR_LIMIT, lat))))) / Math.PI) * n / 2 };\n}\nexport function tileLocation(z, x, y) {\n  const n = 2 ** z;\n  return { lon: x / n * 360 - 180, lat: THREE.MathUtils.radToDeg(Math.atan(Math.sinh(Math.PI * (1 - 2 * y / n)))) };\n}\nexport function sampleTerrarium(dem, u, v) {\n  if (!dem) return null;\n  const px = Math.max(0, Math.min(255, u * 256 - 0.5)), py = Math.max(0, Math.min(255, v * 256 - 0.5));\n  const x = Math.floor(px), y = Math.floor(py), fx = px - x, fy = py - y;\n  const value = (a, b) => dem[Math.min(255, b) * 256 + Math.min(255, a)];\n  return (value(x, y) * (1 - fx) + value(x + 1, y) * fx) * (1 - fy)\n    + (value(x, y + 1) * (1 - fx) + value(x + 1, y + 1) * fx) * fy;\n}\nexport function decodeTerrarium(pixels) {\n  const heights = new Float32Array(256 * 256);\n  for (let i = 0; i < heights.length; i++) {\n    if (!pixels[i * 4 + 3]) throw new Error('Missing Terrarium pixel');\n    heights[i] = pixels[i * 4] * 256 + pixels[i * 4 + 1] + pixels[i * 4 + 2] / 256 - 32768;\n  }\n  return heights;\n}\nexport function globePosition(lat, lon, orthometric, geoid, target = new THREE.Vector3()) {\n  latLonToLocalDir(lat, lon, target);\n  const radius = ellipsoidRadiusForLocalDir(target);\n  target.multiplyScalar(radius);\n  // Heights are measured along the geodetic normal, not a geocentric ray.\n  const phi = THREE.MathUtils.degToRad(lat), lambda = THREE.MathUtils.degToRad(lon);\n  const height = orthometric + (bilinearEgm96Undulation(geoid, lat, lon) ?? 0);\n  return target.addScaledVector(new THREE.Vector3(Math.cos(phi) * Math.sin(lambda), Math.sin(phi), Math.cos(phi) * Math.cos(lambda)), height);\n}\n\n// Quadrant index ranges let a loaded child replace precisely its own coverage.\n// A missing sibling keeps its parent's geometry; no ancestor/child z-fighting.\nexport function terrainGeometry(tile, heightAt, geoid, segments = 32) {\n  const center = tileLocation(tile.z, tile.x + 0.5, tile.y + 0.5);\n  const origin = globePosition(center.lat, center.lon, 0, geoid);\n  const positions = [], uv = [], uv2 = [], quadrants = [[], [], [], []], point = new THREE.Vector3();\n  const add = (u, v, skirt = 0) => {\n    const { lat, lon } = tileLocation(tile.z, tile.x + u, tile.y + v);\n    globePosition(lat, lon, heightAt(lat, lon) - skirt, geoid, point).sub(origin);\n    positions.push(point.x, point.y, point.z);\n    uv.push((lon + 180) / 360, (lat + 90) / 180); uv2.push(u, 1 - v);\n    return positions.length / 3 - 1;\n  };\n  for (let y = 0; y <= segments; y++) for (let x = 0; x <= segments; x++) add(x / segments, y / segments);\n  for (let y = 0; y < segments; y++) for (let x = 0; x < segments; x++) {\n    const a = y * (segments + 1) + x, b = a + 1, c = a + segments + 1, d = c + 1;\n    quadrants[(y >= segments / 2 ? 2 : 0) + (x >= segments / 2 ? 1 : 0)].push(a, c, b, b, c, d);\n  }\n  // Visual-only skirts seal different DEM/LOD borders. Contact uses the grid.\n  const surfaceIndices = quadrants.map(q => q.slice());\n  const depth = Math.max(30, Math.min(15000, 40075016 / 2 ** tile.z / segments * 0.12));\n  for (let edge = 0; edge < 4; edge++) for (let i = 0; i < segments; i++) {\n    let u, v, u1, v1, a, b;\n    if (edge === 0) { u = i / segments; u1 = (i + 1) / segments; v = v1 = 0; a = i; b = i + 1; }\n    if (edge === 1) { u = u1 = 1; v = i / segments; v1 = (i + 1) / segments; a = i * (segments + 1) + segments; b = a + segments + 1; }\n    if (edge === 2) { u = (i + 1) / segments; u1 = i / segments; v = v1 = 1; a = segments * (segments + 1) + i + 1; b = a - 1; }\n    if (edge === 3) { u = u1 = 0; v = (i + 1) / segments; v1 = i / segments; a = (i + 1) * (segments + 1); b = a - segments - 1; }\n    const c = add(u, v, depth), d = add(u1, v1, depth);\n    quadrants[((v + v1) / 2 >= 0.5 ? 2 : 0) + ((u + u1) / 2 >= 0.5 ? 1 : 0)].push(a, c, b, b, c, d);\n  }\n  const geometry = new THREE.BufferGeometry();\n  geometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3));\n  geometry.setAttribute('uv', new THREE.Float32BufferAttribute(uv, 2));\n  geometry.setAttribute('uv2', new THREE.Float32BufferAttribute(uv2, 2));\n  geometry.setAttribute('aWaterMask', new THREE.Float32BufferAttribute(new Float32Array(positions.length / 3), 1));\n  geometry.setIndex(new THREE.BufferAttribute(new Uint16Array(quadrants.flat()), 1));\n  geometry.computeVertexNormals(); geometry.computeBoundingSphere();\n  return { geometry, origin, quadrants, surfaceIndices };\n}\n\nexport function setTerrainCoverage(record, mask) {\n  if (record.mask === mask) return false;\n  record.mask = mask;\n  let offset = 0;\n  for (let q = 0; q < 4; q++) if (mask & (1 << q)) {\n    record.geometry.index.array.set(record.quadrants[q], offset); offset += record.quadrants[q].length;\n  }\n  record.geometry.index.needsUpdate = true; record.geometry.setDrawRange(0, offset);\n  record.mesh.visible = offset > 0;\n  return true;\n}\n\nexport function buildingGeometry(features, tile, heightAt, geoid, vertexLimit = 60000) {\n  const center = tileLocation(tile.z, tile.x + 0.5, tile.y + 0.5), origin = globePosition(center.lat, center.lon, 0, geoid);\n  const positions = [], indices = [], records = [], point = new THREE.Vector3();\n  for (const feature of features) {\n    const p = feature.properties || {}, height = Number(p.render_height), base = Number(p.render_min_height || 0);\n    if (!(height > base) || height > 1500 || base < 0) continue;\n    const polygons = feature.geometry?.type === 'Polygon' ? [feature.geometry.coordinates]\n      : feature.geometry?.type === 'MultiPolygon' ? feature.geometry.coordinates : [];\n    for (const polygon of polygons) {\n      const rings = polygon.map(r => r.slice(0, -1));\n      if (!rings[0]?.length || rings.some(r => r.length < 3)) continue;\n      const count = rings.reduce((n, ring) => n + ring.length, 0);\n      if (positions.length / 3 + count * 2 > vertexLimit) continue;\n      const offset = positions.length / 3;\n      const vectors = rings.map(r => r.map(([lon, lat]) => new THREE.Vector2(lon, lat)));\n      const roof = THREE.ShapeUtils.triangulateShape(vectors[0], vectors.slice(1));\n      for (const level of [base, height]) for (const ring of rings) for (const [lon, lat] of ring) {\n        globePosition(lat, lon, heightAt(lat, lon) + level, geoid, point).sub(origin); positions.push(point.x, point.y, point.z);\n      }\n      for (const triangle of roof) indices.push(...triangle.map(i => offset + count + i));\n      let start = offset;\n      for (const ring of rings) {\n        for (let i = 0; i < ring.length; i++) {\n          const a = start + i, b = start + (i + 1) % ring.length;\n          indices.push(a, b, a + count, b, b + count, a + count);\n        }\n        start += ring.length;\n      }\n      records.push({ id: feature.id ?? null, properties: p, firstVertex: offset, vertexCount: count * 2 });\n    }\n  }\n  const geometry = new THREE.BufferGeometry();\n  geometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3));\n  geometry.setIndex(indices); geometry.computeVertexNormals(); geometry.computeBoundingSphere();\n  return { geometry, origin, records };\n}\n\nexport async function buildingGeometryAsync(features, tile, heightAt, geoid, signal, vertexLimit = 60000) {\n  const batches = [], records = [];\n  let count = 0, indexCount = 0, origin;\n  try {\n    for (let i = 0; i < features.length; i += 4) {\n      await yieldToEventLoop('background'); signal.throwIfAborted();\n      const batch = buildingGeometry(features.slice(i, i + 4), tile, heightAt, geoid, vertexLimit - count);\n      origin = batch.origin;\n      for (const record of batch.records) records.push({ ...record, firstVertex: record.firstVertex + count });\n      batches.push({ geometry: batch.geometry, offset: count });\n      count += batch.geometry.attributes.position.count; indexCount += batch.geometry.index.count;\n    }\n    const positions = new Float32Array(count * 3), indices = new Uint32Array(indexCount);\n    let offset = 0;\n    for (const batch of batches) {\n      positions.set(batch.geometry.attributes.position.array, batch.offset * 3);\n      for (const index of batch.geometry.index.array) indices[offset++] = index + batch.offset;\n    }\n    const geometry = new THREE.BufferGeometry();\n    geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));\n    geometry.setIndex(new THREE.BufferAttribute(indices, 1)); geometry.computeVertexNormals(); geometry.computeBoundingSphere();\n    return { geometry, origin: origin || globePosition(tileLocation(tile.z, tile.x + .5, tile.y + .5).lat,\n      tileLocation(tile.z, tile.x + .5, tile.y + .5).lon, 0, geoid), records };\n  } finally { for (const batch of batches) batch.geometry.dispose(); }\n}\n","import * as THREE from 'three';\nimport Pbf from 'pbf';\nimport { VectorTile } from '@mapbox/vector-tile';\nimport { getMapTileApiBase } from '../shared/backend.js';\nimport { readBoundedBytes } from '../shared/readBoundedBytes.js';\nimport { yieldToEventLoop } from '../async/scheduler/BudgetScheduler.js';\nimport { loadMapsourceTerrain } from './MapSourceTerrainProtocol.js';\nimport { getEgm96GeoidRaster } from './MapzenElevationTileSource.js';\nimport { dirToLatLonLocal } from '../../modules/geometry-utils.js';\nimport { createTerrainSurfaceChangeRegion } from '../scene/TerrainSurfaceChange.js';\nimport { tileCoordinate, tileLocation, sampleTerrarium, decodeTerrarium, globePosition,\n  terrainGeometry, setTerrainCoverage, buildingGeometryAsync } from './MapSourceGlobeMath.js';\n\nconst keyOf = t => `${t.z}/${t.x}/${t.y}`;\nasync function imageFromBytes(bytes, signal) {\n  const url = URL.createObjectURL(new Blob([bytes]));\n  const image = new Image();\n  try {\n    await new Promise((resolve, reject) => {\n      const finish = error => {\n        image.onload = image.onerror = null; signal.removeEventListener('abort', abort);\n        if (error) { image.removeAttribute('src'); reject(error); } else resolve();\n      };\n      const abort = () => finish(signal.reason);\n      image.onload = () => finish(); image.onerror = () => finish(new Error('Invalid satellite image'));\n      signal.addEventListener('abort', abort, { once: true });\n      if (signal.aborted) return abort();\n      image.src = url;\n    });\n    if (image.naturalWidth !== 256 || image.naturalHeight !== 256) throw new Error('Invalid satellite dimensions');\n    return image;\n  } finally { URL.revokeObjectURL(url); }\n}\n\n/** Native XYZ terrain/raster/vector owner; never starts TriTree or MapLibre. */\nexport class MapSourceGlobe {\n  constructor({ parent, material, source, mobile = false, onSurfaceChange = () => {} }) {\n    this.group = new THREE.Group(); this.group.name = 'Mapsource satellite terrain';\n    this.group.userData.firstDrawGuard = false; // streaming terrain swaps seamlessly\n    this.group.userData.photoModelChangeSeq = 0;\n    parent?.add(this.group);\n    this.material = material; this.source = source; this.onSurfaceChange = onSurfaceChange;\n    this.maxTiles = mobile ? 112 : 192; this.maxLeaves = mobile ? 72 : 128;\n    this.maxBuildingTiles = mobile ? 8 : 16;\n    this.textureReferences = new Map();\n    this.tiles = new Map(); this.dems = new Map(); this.buildings = new Map();\n    this.controller = new AbortController(); this.active = 0; this.activeBuildings = 0;\n    this.disposed = false; this.lastSelection = -Infinity; this.base = getMapTileApiBase();\n    this.geoid = null; this.geoidPromise = null; this.revision = 0;\n    // Web Mercator has no polar imagery. Close only those unsourced caps with\n    // a neutral ellipsoid, rather than stretching somebody else's XYZ pixels.\n    this.polarCaps = [];\n    for (const north of [true, false]) {\n      const span = Math.PI / 2 - Math.atan(6356752.314245 / 6378137 * Math.tan(85.0511287798066 * Math.PI / 180));\n      const geometry = new THREE.SphereGeometry(1, 64, 8, 0, Math.PI * 2, north ? 0 : Math.PI - span, span);\n      geometry.scale(6378137, 6356752.314245, 6378137);\n      const cap = new THREE.Mesh(geometry, new THREE.MeshStandardMaterial({ color: 0x7c878d, roughness: 1 }));\n      cap.name = 'Mapsource polar no-data cap'; cap.userData.mapsourceNoData = true;\n      this.group.add(cap); this.polarCaps.push(cap);\n    }\n    this.cameraLocal = new THREE.Vector3(); this.world = new THREE.Vector3();\n    this.frustum = new THREE.Frustum(); this.projection = new THREE.Matrix4();\n    this.sun = new THREE.Vector3(0, 0, 1);\n    this.stats = { selected: 0, resident: 0, pending: 0, buildings: 0, maxZoom: 0 };\n  }\n\n  async _bytes(path, signal) {\n    const response = await fetch(path, { signal });\n    if (!response.ok || response.status === 204) {\n      await response.body?.cancel().catch(() => {});\n      const error = new Error(`Mapsource tile unavailable (${response.status})`);\n      error.retryAfter = Math.min(300000, Math.max(30000, Number(response.headers.get('retry-after')) * 1000 || 30000));\n      throw error;\n    }\n    return readBoundedBytes(response, { maxBytes: 4 * 1024 * 1024, signal });\n  }\n\n  async _dem(tile) {\n    if (tile.controller?.signal.aborted || this.disposed) return null;\n    const z = Math.min(15, tile.z), scale = 2 ** (tile.z - z);\n    const coords = { z, x: Math.floor(tile.x / scale), y: Math.floor(tile.y / scale) }, key = keyOf(coords);\n    let record = this.dems.get(key);\n    if (record?.data) { record.touched = this.revision; return record; }\n    if (record?.promise) return this._waitDem(record, tile.controller?.signal);\n    if (record?.retryAt > performance.now()) return null;\n    record = { ...coords, touched: this.revision, controller: new AbortController() }; this.dems.set(key, record);\n    record.promise = (async () => {\n      const { data } = await loadMapsourceTerrain({ url: `noclip-dem://tile/${key}.png` },\n        { signal: AbortSignal.any([this.controller.signal, record.controller.signal]) });\n      record.controller.signal.throwIfAborted();\n      if (this.disposed) return null;\n      const canvas = document.createElement('canvas'); canvas.width = canvas.height = 256;\n      try {\n        const context = canvas.getContext('2d', { willReadFrequently: true }); context.drawImage(data, 0, 0);\n        record.data = decodeTerrarium(context.getImageData(0, 0, 256, 256).data);\n      } finally { canvas.width = canvas.height = 0; }\n      return record;\n    })().catch(() => { record.retryAt = performance.now() + 30000; return null; })\n      .finally(() => { record.promise = null; });\n    return this._waitDem(record, tile.controller?.signal);\n  }\n\n  _waitDem(record, signal) {\n    record.users = (record.users || 0) + 1;\n    let released = false;\n    const release = () => {\n      if (released) return;\n      released = true; signal?.removeEventListener('abort', release); record.users--;\n      if (!record.users && record.promise && !record.data) {\n        record.controller.abort();\n        const key = keyOf(record);\n        if (this.dems.get(key) === record) this.dems.delete(key);\n      }\n    };\n    const pending = record.promise;\n    signal?.addEventListener('abort', release, { once: true });\n    if (signal?.aborted) release();\n    return pending.finally(release);\n  }\n\n  heightAt(lat, lon, preferred = null) {\n    if (preferred?.data) {\n      const t = tileCoordinate(lon, lat, preferred.z);\n      const n = 2 ** preferred.z;\n      let u = t.x - preferred.x;\n      if (u < -n / 2) u += n;\n      if (u > n / 2) u -= n;\n      return sampleTerrarium(preferred.data, u, t.y - preferred.y);\n    }\n    for (let z = 15; z >= 0; z--) {\n      const t = tileCoordinate(lon, lat, z), record = this.dems.get(`${z}/${Math.floor(t.x)}/${Math.min(2 ** z - 1, Math.floor(t.y))}`);\n      if (record?.data) return sampleTerrarium(record.data, t.x % 1, t.y % 1);\n    }\n    return 0;\n  }\n\n  _node(z, x, y) {\n    const key = `${z}/${x}/${y}`;\n    let record = this.tiles.get(key);\n    if (record) return record;\n    const location = tileLocation(z, x + 0.5, y + 0.5);\n    const center = globePosition(location.lat, location.lon, 0, null);\n    const span = Math.min(Math.PI, 2 * Math.PI / 2 ** z);\n    record = { z, x, y, key, center, span, radius: Math.min(13000000, span * 6378137 * 0.8 + 12000), wanted: false };\n    this.tiles.set(key, record); return record;\n  }\n\n  _priority(tile, camera, targetZoom, focus) {\n    const sub = 2 ** (targetZoom - tile.z);\n    const underfoot = tile.z <= targetZoom && Math.floor(focus.x / sub) === tile.x && Math.floor(focus.y / sub) === tile.y;\n    if (underfoot && tile.z < targetZoom) return 1e12 - tile.z;\n    if (tile.z >= Math.min(19, this.source.maxNativeZoom ?? this.source.maxZoom ?? 19)) return 0;\n    const angle = tile.center.angleTo(this.cameraLocal), horizon = Math.acos(Math.min(1, 6356752 / this.cameraLocal.length()));\n    if (angle > horizon + tile.span) return 0;\n    this.world.copy(tile.center); this.group.localToWorld(this.world);\n    if (!this.frustum.intersectsSphere(new THREE.Sphere(this.world, tile.radius))) return 0;\n    const distance = Math.max(1, this.cameraLocal.distanceTo(tile.center) - tile.radius * 0.5);\n    const width = 40075016 / 2 ** tile.z * Math.max(0.05, Math.cos(tileLocation(tile.z, tile.x + .5, tile.y + .5).lat * Math.PI / 180));\n    return width / distance * camera.projectionMatrix.elements[5] * (globalThis.innerHeight || 800) / 2;\n  }\n\n  _select(camera, now) {\n    this.revision++;\n    this.group.updateWorldMatrix(true, false);\n    this.cameraLocal.copy(camera.userData.worldPosition || camera.position); this.group.worldToLocal(this.cameraLocal);\n    const location = dirToLatLonLocal(this.cameraLocal);\n    const altitude = Math.max(40, this.cameraLocal.length() - globePosition(location.latDeg, location.lonDeg, this.heightAt(location.latDeg, location.lonDeg), this.geoid).length());\n    const targetZoom = Math.max(0, Math.min(this.source.maxNativeZoom ?? this.source.maxZoom ?? 19,\n      Math.ceil(Math.log2(40075016 * Math.cos(location.latDeg * Math.PI / 180) * (globalThis.innerHeight || 800) / (altitude * 256)))));\n    const focus = tileCoordinate(location.lonDeg, location.latDeg, targetZoom);\n    focus.y = Math.max(0, Math.min(2 ** targetZoom - 1e-7, focus.y));\n    this.projection.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse); this.frustum.setFromProjectionMatrix(this.projection);\n    for (const t of this.tiles.values()) { t.wanted = false; t.split = false; }\n    const root = this._node(0, 0, 0), leaves = [root]; root.wanted = true;\n    root.priority = this._priority(root, camera, targetZoom, focus);\n    while (leaves.length + 3 <= this.maxLeaves) {\n      leaves.sort((a, b) => b.priority - a.priority);\n      const node = leaves[0];\n      if (!node || node.priority < 384 || node.z >= 19) break;\n      leaves.shift(); node.split = true;\n      for (let q = 0; q < 4; q++) {\n        const child = this._node(node.z + 1, node.x * 2 + q % 2, node.y * 2 + (q >> 1));\n        child.wanted = true; child.priority = this._priority(child, camera, targetZoom, focus); leaves.push(child);\n      }\n    }\n    // Out-of-view work is cancelled before replacements enter the bounded pool.\n    for (const [key, tile] of this.tiles) if (!tile.wanted) {\n      this._releaseTile(tile); this.tiles.delete(key);\n    }\n    const wanted = [...this.tiles.values()].filter(t => t.wanted);\n    wanted.sort((a, b) => (a.z === 0 ? -1 : b.z === 0 ? 1 : b.priority - a.priority));\n    for (const tile of wanted) {\n      if (this.active >= 6) break;\n      if ((!tile.mesh || tile.inherited) && !tile.pending && !(tile.retryAt > now)) void this._load(tile);\n    }\n    // Keep DEMs used by this frame's terrain, plus a bounded recent working set.\n    const retained = new Set(wanted.map(t => t.dem).filter(Boolean));\n    for (const [key, dem] of this.dems) if (!dem.promise && !retained.has(dem) && this.dems.size > 64) this.dems.delete(key);\n    this._updateBuildings(location, altitude, now);\n    this.stats.selected = leaves.length;\n  }\n\n  async _load(tile) {\n    this.active++; tile.pending = true; tile.controller = new AbortController();\n    const signal = AbortSignal.any([this.controller.signal, tile.controller.signal, AbortSignal.timeout(20000)]);\n    let texture = null;\n    try {\n      this.geoidPromise ||= getEgm96GeoidRaster().then(r => { this.geoid = r; return r; }).catch(error => { this.geoidPromise = null; throw error; });\n      const url = this.source.url.replace('{z}', tile.z).replace('{x}', tile.x).replace('{y}', tile.y);\n      let rasterError = null;\n      const [bytes, nativeDem] = await Promise.all([this._bytes(url, signal).catch(error => { rasterError = error; return null; }), this._dem(tile), this.geoidPromise]);\n      let ancestor = null, dem = nativeDem;\n      for (let z = tile.z - 1; z >= 0; z--) {\n        const scale = 2 ** (tile.z - z), parent = this.tiles.get(`${z}/${Math.floor(tile.x / scale)}/${Math.floor(tile.y / scale)}`);\n        if (!ancestor && parent?.texture) ancestor = parent;\n        if (!dem && parent?.dem) dem = parent.dem;\n      }\n      signal.throwIfAborted();\n      if (!dem) throw new Error('Terrain depth not yet available');\n      if (bytes) {\n        const image = await imageFromBytes(bytes, signal); signal.throwIfAborted();\n        texture = new THREE.Texture(image); texture.colorSpace = THREE.SRGBColorSpace;\n        texture.minFilter = THREE.LinearMipmapLinearFilter; texture.anisotropy = 4; texture.needsUpdate = true;\n      } else if (!ancestor) throw rasterError || new Error('Satellite parent is loading');\n      // Native UVs, native DEM sampling, and tile-relative vertices retain metre precision.\n      await yieldToEventLoop('background'); signal.throwIfAborted();\n      const built = terrainGeometry(tile, (lat, lon) => this.heightAt(lat, lon, dem), this.geoid, tile.z < 3 ? 64 : 32);\n      if (!texture) {\n        const imageTile = ancestor.imageTile || ancestor;\n        const scale = 2 ** (tile.z - imageTile.z), u0 = tile.x / scale - imageTile.x, v0 = tile.y / scale - imageTile.y;\n        const uv = built.geometry.attributes.uv2;\n        for (let i = 0; i < uv.count; i++) uv.setXY(i, u0 + uv.getX(i) / scale, 1 - v0 - (1 - uv.getY(i)) / scale);\n      }\n      this._releaseMesh(tile);\n      const material = this.material.clone(); material.side = THREE.FrontSide; material.map = texture || ancestor.texture;\n      tile.inherited = !texture || !nativeDem;\n      tile.retryAt = tile.inherited ? performance.now() + (rasterError?.retryAfter || 30000) : 0;\n      tile.mesh = new THREE.Mesh(built.geometry, material); tile.mesh.position.copy(built.origin);\n      tile.mesh.name = `Mapsource ${tile.key}`; tile.mesh.userData.mapsourceTile = { z: tile.z, x: tile.x, y: tile.y };\n      // Ignore skirts in surface/camera raycasts while retaining exact active quadrants.\n      const nativeRaycast = tile.mesh.raycast;\n      tile.mesh.raycast = function(raycaster, hits) {\n        const start = hits.length; nativeRaycast.call(this, raycaster, hits);\n        for (let i = hits.length - 1; i >= start; i--) {\n          const face = hits[i].face;\n          if (face && Math.max(face.a, face.b, face.c) >= (tile.z < 3 ? 65 : 33) ** 2) hits.splice(i, 1);\n        }\n      };\n      const inherited = !texture;\n      tile.texture = texture || ancestor.texture;\n      this.textureReferences.set(tile.texture, (this.textureReferences.get(tile.texture) || 0) + 1);\n      Object.assign(tile, built, { dem, imageTile: inherited ? (ancestor.imageTile || ancestor) : { z: tile.z, x: tile.x, y: tile.y } }); texture = null; this.group.add(tile.mesh);\n      this._coverageChanged(tile);\n    } catch (error) {\n      tile.retryAt = performance.now() + (error.retryAfter || 30000);\n    } finally { texture?.dispose(); tile.pending = false; this.active--; }\n  }\n\n  _present(tile, coveredByAncestor = false) {\n    if (!tile?.wanted) return false;\n    if (!tile.mesh && coveredByAncestor) {\n      this._hideDescendants(tile);\n      return false;\n    }\n    let mask = 15;\n    if (tile.split) for (let q = 0; q < 4; q++) {\n      const child = this.tiles.get(`${tile.z + 1}/${tile.x * 2 + q % 2}/${tile.y * 2 + (q >> 1)}`);\n      if (this._present(child, coveredByAncestor || !!tile.mesh)) mask &= ~(1 << q);\n    }\n    if (tile.mesh) { tile.mesh.visible = mask > 0; if (setTerrainCoverage(tile, mask)) this.group.userData.photoModelChangeSeq++; return true; }\n    // A deeper loaded tile does not falsely claim its missing siblings' coverage.\n    return mask === 0;\n  }\n\n  _hideDescendants(tile) {\n    if (tile.mesh) tile.mesh.visible = false;\n    if (tile.split) for (let q = 0; q < 4; q++) {\n      const child = this.tiles.get(`${tile.z + 1}/${tile.x * 2 + q % 2}/${tile.y * 2 + (q >> 1)}`);\n      if (child) this._hideDescendants(child);\n    }\n  }\n\n  _coverageChanged(tile) {\n    this.group.userData.photoModelChangeSeq++;\n    const nw = tileLocation(tile.z, tile.x, tile.y), se = tileLocation(tile.z, tile.x + 1, tile.y + 1);\n    this.changes ||= [];\n    const metadata = { source: 'mapsource', reason: 'tile-loaded' };\n    this.changes.push(tile.z === 0 ? { ...metadata, global: true } : createTerrainSurfaceChangeRegion([\n      { lat: nw.lat, lon: nw.lon }, { lat: nw.lat, lon: se.lon },\n      { lat: se.lat, lon: se.lon }, { lat: se.lat, lon: nw.lon }\n    ], metadata));\n    this.lastSelection = -Infinity;\n  }\n\n  _updateBuildings(location, altitude, now) {\n    const wanted = new Set();\n    if (altitude < 15000) {\n      const center = tileCoordinate(location.lonDeg, location.latDeg, 14);\n      const offsets = [[0, 0], [-1, 0], [1, 0], [0, -1], [0, 1], [-1, -1], [1, 1], [-1, 1], [1, -1]];\n      for (const [dx, dy] of offsets.slice(0, this.maxBuildingTiles)) {\n        const tile = { z: 14, x: (Math.floor(center.x) + dx + 16384) % 16384, y: Math.floor(center.y) + dy };\n        if (tile.y < 0 || tile.y >= 16384) continue;\n        const key = keyOf(tile); wanted.add(key);\n        let record = this.buildings.get(key);\n        if (!record) { record = tile; this.buildings.set(key, record); }\n        if (this.activeBuildings < 2 && !record.pending && !record.mesh && !(record.retryAt > now)) void this._loadBuildings(record);\n      }\n    }\n    for (const [key, tile] of this.buildings) if (!wanted.has(key)) { this._releaseTile(tile); this.buildings.delete(key); }\n  }\n\n  async _loadBuildings(tile) {\n    this.activeBuildings++; tile.pending = true; tile.controller = new AbortController();\n    const signal = AbortSignal.any([this.controller.signal, tile.controller.signal, AbortSignal.timeout(20000)]);\n    try {\n      const [bytes, dem] = await Promise.all([this._bytes(`${this.base}/tiles/vector/${keyOf(tile)}.pbf`, signal), this._dem(tile)]);\n      signal.throwIfAborted();\n      await this.geoidPromise; signal.throwIfAborted();\n      if (!dem || !this.geoid) throw new Error('Building terrain is loading');\n      const layer = new VectorTile(new Pbf(bytes)).layers.building;\n      if ((layer?.length || 0) > 4096) throw new Error('Building tile exceeds feature budget');\n      const features = [];\n      for (let i = 0; i < (layer?.length || 0); i++) {\n        if (i % 16 === 0) { await yieldToEventLoop('background'); signal.throwIfAborted(); }\n        features.push(layer.feature(i).toGeoJSON(tile.x, tile.y, tile.z));\n      }\n      const built = await buildingGeometryAsync(features, tile, (lat, lon) => this.heightAt(lat, lon, dem), this.geoid, signal);\n      if (signal.aborted) { built.geometry.dispose(); signal.throwIfAborted(); }\n      const material = new THREE.MeshStandardMaterial({ color: 0xbbb8ad, roughness: .9, side: THREE.DoubleSide });\n      tile.mesh = new THREE.Mesh(built.geometry, material); tile.mesh.position.copy(built.origin);\n      tile.mesh.name = `Mapsource buildings ${keyOf(tile)}`; tile.mesh.userData.mapsourceBuildings = built.records;\n      tile.mesh.castShadow = true; tile.mesh.receiveShadow = true;\n      this.group.add(tile.mesh); this._coverageChanged(tile);\n    } catch (error) { tile.retryAt = performance.now() + (error.retryAfter || 30000); }\n    finally { tile.pending = false; this.activeBuildings--; }\n  }\n\n  update(camera, sun) {\n    if (this.disposed || !camera || !this.material) return;\n    const now = performance.now();\n    if (now - this.lastSelection >= 150) { this.lastSelection = now; this._select(camera, now); }\n    this._present(this.tiles.get('0/0/0'));\n    for (const tile of this.tiles.values()) if (tile.mesh) {\n      const u = tile.mesh.material.uniforms;\n      u?.cameraWorldPosition?.value.copy(camera.userData.worldPosition || camera.position);\n      if (sun) u?.sunDirection?.value.copy(sun);\n    }\n    this.stats.resident = [...this.tiles.values()].filter(t => t.mesh).length;\n    this.stats.pending = this.active; this.stats.maxZoom = Math.max(0, ...[...this.tiles.values()].filter(t => t.mesh).map(t => t.z));\n    this.stats.buildings = [...this.buildings.values()].reduce((n, t) => n + (t.mesh?.userData.mapsourceBuildings?.length || 0), 0);\n    if (this.changes?.length) { const changes = this.changes; this.changes = []; this.onSurfaceChange(changes); }\n  }\n\n  getCoverageState() { return { ...this.stats, ready: this.stats.resident > 0 }; }\n  _releaseMesh(tile) {\n    tile.mesh?.removeFromParent(); tile.mesh?.geometry.dispose(); tile.mesh?.material.dispose();\n    if (tile.texture) {\n      const count = (this.textureReferences.get(tile.texture) || 1) - 1;\n      if (count) this.textureReferences.set(tile.texture, count);\n      else { this.textureReferences.delete(tile.texture); tile.texture.dispose(); }\n    }\n    tile.mesh = null; tile.texture = null; tile.mask = undefined;\n  }\n  _releaseTile(tile) { tile.controller?.abort(); this._releaseMesh(tile); }\n  dispose() {\n    if (this.disposed) return;\n    this.disposed = true; this.controller.abort(); this.group.removeFromParent();\n    for (const tile of this.tiles.values()) this._releaseTile(tile);\n    for (const tile of this.buildings.values()) this._releaseTile(tile);\n    for (const cap of this.polarCaps) { cap.geometry.dispose(); cap.material.dispose(); }\n    this.polarCaps.length = 0;\n    this.tiles.clear(); this.dems.clear(); this.buildings.clear(); this.changes = [];\n  }\n}\n","import { readBoundedBytes } from '../shared/readBoundedBytes.js';\nimport { resolveSceneRuntimeResource } from '../scene/SceneRuntimeResources.js';\n\nexport const OVERVIEW_IMAGE_URL = resolveSceneRuntimeResource('/textures/earth_day_4096.jpg');\nexport const OVERVIEW_MAX_ENCODED_BYTES = 8 * 1024 * 1024;\nexport const OVERVIEW_BITMAP_OPTIONS = Object.freeze({\n    imageOrientation: 'flipY', premultiplyAlpha: 'none', colorSpaceConversion: 'none',\n});\n\n/** Validate this fixed JPEG before starting a potentially large native decode. */\nexport function overviewJpegDimensions(bytes) {\n    const fail = () => { throw new RangeError('Invalid or oversized overview JPEG'); };\n    if (!(bytes instanceof Uint8Array) || bytes.length < 4 || bytes[0] !== 255 || bytes[1] !== 216) fail();\n    const limit = Math.min(bytes.length, 256 * 1024);\n    let offset = 2;\n    for (let segments = 0; segments < 128 && offset + 4 <= limit; segments++) {\n        if (bytes[offset++] !== 255) fail();\n        while (offset < limit && bytes[offset] === 255) offset++;\n        const marker = bytes[offset++];\n        if (marker === 0 || marker === 216 || marker === 217 || marker === 218) fail();\n        if (offset + 2 > limit) fail();\n        const length = bytes[offset] * 256 + bytes[offset + 1];\n        if (length < 2 || offset + length > limit) fail();\n        if ([192,193,194].includes(marker)) {\n            if (length < 8 || bytes[offset + 2] !== 8) fail();\n            const height = bytes[offset + 3] * 256 + bytes[offset + 4];\n            const width = bytes[offset + 5] * 256 + bytes[offset + 6];\n            const components = bytes[offset + 7];\n            if (length !== 8 + 3 * components || ![1,3,4].includes(components)\n                || height < 1 || width !== 2 * height || width > 8192 || height > 4096) fail();\n            return { width, height };\n        }\n        offset += length;\n    }\n    fail();\n}\n\n/** Owned native decode; the compatibility path also owns its blob URL/image. */\nexport async function decodeOverviewImage(blob, { signal,\n    createBitmap = typeof globalThis.createImageBitmap === 'function'\n        ? (source, options) => globalThis.createImageBitmap(source, options) : null,\n    createImage = () => new Image(), urlApi = URL,\n} = {}) {\n    signal?.throwIfAborted();\n    if (createBitmap) {\n        // No resize, quantization or canvas conversion. WebGL ignores flipY and\n        // unpack conversion for ImageBitmap; match the original r185 upload here.\n        const image = await createBitmap(blob, OVERVIEW_BITMAP_OPTIONS);\n        let released = false;\n        return { image, release() { if (!released) { released = true; image.close(); } } };\n    }\n\n    const image = createImage(), source = urlApi.createObjectURL(blob);\n    let released = false, revoked = false;\n    const revoke = () => { if (!revoked) { revoked = true; urlApi.revokeObjectURL(source); } };\n    const release = () => {\n        if (released) return;\n        released = true; image.removeAttribute('src'); revoke();\n    };\n    const abort = () => { image.removeAttribute('src'); };\n    image.decoding = 'async';\n    signal?.addEventListener('abort', abort, { once: true });\n    try {\n        if (typeof image.decode === 'function') {\n            image.src = source;\n            // Removing src rejects this native promise; retain the transaction\n            // until it actually settles, including when cancellation races load.\n            await image.decode();\n        } else {\n            let removeCancel = () => {};\n            await new Promise((resolve, reject) => {\n                const cancelled = () => reject(signal.reason);\n                image.onload = resolve; image.onerror = () => reject(new Error('Overview image decode failed'));\n                signal?.addEventListener('abort', cancelled, { once: true });\n                removeCancel = () => signal?.removeEventListener('abort', cancelled);\n                image.src = source;\n                if (signal?.aborted) cancelled();\n            }).finally(() => {\n                removeCancel();\n                image.onload = image.onerror = null;\n            });\n        }\n        signal?.throwIfAborted(); revoke();\n        return { image, release };\n    } catch (error) { release(); throw error; }\n    finally { signal?.removeEventListener('abort', abort); }\n}\n\n/**\n * One source owner per PlanetScene: one whole fetch/decode transaction and one\n * latest waiting intent. Abort never frees a non-cancellable bitmap decode slot.\n * The caller must detach/dispose its texture before release() closes the image.\n */\nexport class OverviewImageSource {\n    constructor({ fetch: fetcher = (...args) => globalThis.fetch(...args),\n        decode = decodeOverviewImage, timeoutMs = 30000 } = {}) {\n        if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) throw new RangeError('Invalid overview deadline');\n        this.fetch = fetcher; this.decode = decode; this.timeoutMs = timeoutMs;\n        this.active = null; this.wanted = null; this.current = null; this.disposed = false;\n        this.stats = { started: 0, decoded: 0, released: 0, cancelled: 0, failed: 0, timeouts: 0 };\n    }\n\n    acquire() {\n        if (this.disposed) return Promise.resolve(null);\n        if (this.current) return Promise.resolve(this.current.image);\n        if (this.wanted) return this.wanted.promise;\n        const job = { controller: new AbortController(), phase: 'waiting' };\n        job.promise = new Promise((resolve, reject) => { job.resolve = resolve; job.reject = reject; });\n        this.wanted = job; this._pump(); return job.promise;\n    }\n\n    release() {\n        const wanted = this.wanted; this.wanted = null;\n        if (wanted && wanted !== this.active) wanted.resolve(null);\n        if (this.active && !this.active.controller.signal.aborted) {\n            this.stats.cancelled++;\n            this.active.controller.abort(new DOMException('Overview no longer required', 'AbortError'));\n        }\n        const resource = this.current; this.current = null;\n        if (resource) { this.stats.released++; resource.release(); }\n    }\n\n    dispose() { this.disposed = true; this.release(); }\n\n    getStats() {\n        return { ...this.stats, active: !!this.active, phase: this.active?.phase || 'idle',\n            waiting: !!this.wanted && this.wanted !== this.active, disposed: this.disposed,\n            imageLive: !!this.current, width: this.current?.image.width || 0, height: this.current?.image.height || 0 };\n    }\n\n    _pump() {\n        if (this.disposed || this.active || !this.wanted) return;\n        const job = this.wanted; this.active = job; this.stats.started++;\n        void this._run(job);\n    }\n\n    async _run(job) {\n        const { signal } = job.controller;\n        let resource = null;\n        const timer = setTimeout(() => {\n            this.stats.timeouts++;\n            job.controller.abort(new DOMException('Overview acquisition timed out', 'TimeoutError'));\n        }, this.timeoutMs);\n        try {\n            job.phase = 'fetching';\n            const response = await this.fetch(OVERVIEW_IMAGE_URL, { signal, credentials: 'same-origin', mode: 'same-origin', redirect: 'error' });\n            if (!response.ok) {\n                await response.body?.cancel().catch(() => {});\n                throw new Error('Overview image request failed');\n            }\n            let bytes = await readBoundedBytes(response, { maxBytes: OVERVIEW_MAX_ENCODED_BYTES, signal });\n            const dimensions = overviewJpegDimensions(bytes);\n            const blob = new Blob([bytes], { type: 'image/jpeg' }); bytes = null;\n            signal.throwIfAborted(); job.phase = 'decoding';\n            resource = await this.decode(blob, { signal }); this.stats.decoded++;\n            signal.throwIfAborted();\n            if (this.wanted !== job || this.disposed) throw new DOMException('Stale overview image', 'AbortError');\n            if (resource.image.width !== dimensions.width || resource.image.height !== dimensions.height) {\n                throw new RangeError('Overview decoded dimensions differ from the validated JPEG');\n            }\n            this.current = resource; resource = null;\n            job.resolve(this.current.image);\n        } catch (error) {\n            if (signal.aborted || this.wanted !== job || this.disposed) job.resolve(null);\n            else { this.stats.failed++; job.reject(error); }\n        } finally {\n            clearTimeout(timer);\n            if (resource) { this.stats.released++; resource.release(); }\n            if (this.wanted === job) this.wanted = null;\n            if (this.active === job) this.active = null;\n            this._pump();\n        }\n    }\n}\n","/**\n * NKN networking utilities for message handling and communication\n */\n\n// Global state for pending requests\nconst pending = new Map();\nconst chunkStore = new Map();\nconst pendingChunkedResponses = new Map();\nlet lastPayloadBytes = 0;\nconst DEFAULT_RETRY_BACKOFF_MS = 800;\nconst DEFAULT_MAX_ATTEMPTS = 4;\nconst CHUNK_STALE_MS = 60_000;\nconst textDecoder = new TextDecoder();\n\nconst isNknDebugEnabled = () => globalThis.__noclipDebugNkn === true;\n\nfunction shouldRetryNknError(err) {\n    const msg = String((err && err.message) || err || '').toLowerCase();\n    return (\n        msg.includes('message timeout') ||\n        msg.includes('failed to send') ||\n        msg.includes('timeout') ||\n        msg.includes('readystate is not') ||\n        msg.includes('rtcdatachannel')\n    );\n}\n\nconst sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));\n\nfunction _decodeBase64ToBytes(b64) {\n    if (!b64) return new Uint8Array(0);\n    const binary = atob(b64);\n    const bytes = new Uint8Array(binary.length);\n    for (let i = 0; i < binary.length; i++) {\n        bytes[i] = binary.charCodeAt(i);\n    }\n    return bytes;\n}\n\nfunction _concatBytes(chunks) {\n    const total = chunks.reduce((sum, chunk) => sum + chunk.length, 0);\n    const merged = new Uint8Array(total);\n    let offset = 0;\n    for (const chunk of chunks) {\n        merged.set(chunk, offset);\n        offset += chunk.length;\n    }\n    return merged;\n}\n\nfunction _cleanupStaleChunks(now = Date.now()) {\n    for (const [id, entry] of chunkStore.entries()) {\n        if ((now - entry.updatedAt) > CHUNK_STALE_MS) {\n            chunkStore.delete(id);\n            pendingChunkedResponses.delete(id);\n        }\n    }\n}\n\nfunction _resolvePendingResponse(id, msg) {\n    const st = pending.get(id);\n    if (!st) {\n        if (isNknDebugEnabled()) {\n            console.warn(`NKN response ID ${id} not in pending map (size: ${pending.size}), likely timed out`);\n        }\n        return;\n    }\n    clearTimeout(st.timeout);\n    pending.delete(id);\n    st.resolve(msg);\n    if (isNknDebugEnabled()) {\n        console.log(`NKN matched response ID: ${id}, pending count: ${pending.size}`);\n    }\n}\n\nfunction _decodePayload(payload) {\n    if (typeof payload === 'string') return payload;\n    if (payload instanceof Uint8Array) return textDecoder.decode(payload);\n    if (payload && payload.payload) return _decodePayload(payload.payload);\n    return '';\n}\n\nfunction _parsePayload(text) {\n    if (!text) return null;\n    try {\n        return JSON.parse(text);\n    } catch {\n        // Some relays wrap JSON in base64; try decoding once.\n        try {\n            return JSON.parse(atob(text));\n        } catch {\n            return null;\n        }\n    }\n}\n\nfunction _tryAssembleChunks(id, resp) {\n    const entry = chunkStore.get(id);\n    if (!entry || entry.received < entry.totalChunks) return false;\n    const missing = entry.chunks.some(chunk => typeof chunk !== 'string');\n    if (missing) return false;\n    const byteChunks = entry.chunks.map(_decodeBase64ToBytes);\n    const merged = _concatBytes(byteChunks);\n    resp.body = new TextDecoder().decode(merged);\n    resp.body_b64 = '';\n    resp.bytes_total = entry.bytesTotal || merged.length;\n    chunkStore.delete(id);\n    return true;\n}\n\n/**\n * Generate a UUID v4 string\n * @returns {string} UUID v4\n */\nexport function uuidv4() {\n    if (crypto.randomUUID) return crypto.randomUUID();\n    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {\n        const r = Math.random() * 16 | 0, v = c === 'x' ? r : (r & 0x3 | 0x8); return v.toString(16);\n    });\n}\n\n/**\n * Send a message via NKN and wait for a reply\n * @param {object} mc - NKN MultiClient instance\n * @param {string} dest - Destination NKN address\n * @param {object} obj - Message object to send\n * @param {number} timeoutMs - Timeout in milliseconds (default: 25000)\n * @param {function} onBytes - Optional callback with (bytes, obj) when message is sent\n * @returns {Promise} Promise that resolves with the reply message\n */\nexport async function sendWithReply(mc, dest, obj, timeoutMs = 25000, onBytes, options = {}) {\n    if (!dest) {\n        throw new Error('NKN destination required');\n    }\n    const getClient = typeof options.getClient === 'function' ? options.getClient : null;\n    if (!getClient && (!mc || typeof mc.send !== 'function')) {\n        throw new Error('NKN client not ready');\n    }\n\n    const maxAttempts = Number.isFinite(options.maxAttempts)\n        ? Math.max(1, Math.floor(options.maxAttempts))\n        : DEFAULT_MAX_ATTEMPTS;\n    const backoffMs = Number.isFinite(options.backoffMs)\n        ? Math.max(0, Math.floor(options.backoffMs))\n        : DEFAULT_RETRY_BACKOFF_MS;\n    const preserveId = typeof options.preserveId === 'boolean'\n        ? options.preserveId\n        : (obj && (obj.type === 'elev.query' || obj.type === 'http.request'));\n    const maxChunkBytes = Number.isFinite(options.maxChunkBytes)\n        ? Math.max(0, Math.floor(options.maxChunkBytes))\n        : 0;\n    const onSendError = typeof options.onSendError === 'function'\n        ? options.onSendError\n        : null;\n    const sendOpts = (options && typeof options.sendOpts === 'object' && options.sendOpts)\n        ? options.sendOpts\n        : (Object.prototype.hasOwnProperty.call(options, 'noReply')\n            ? { noReply: !!options.noReply }\n            : { noReply: false });\n    if (maxChunkBytes > 0 && obj && obj.max_chunk_bytes == null) {\n        obj.max_chunk_bytes = maxChunkBytes;\n    }\n\n    const baseId = obj.id || uuidv4();\n    let lastErr = null;\n\n    for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n        const client = getClient ? getClient() : mc;\n        if (!client || typeof client.send !== 'function') {\n            lastErr = new Error('NKN client not ready');\n            if (attempt >= maxAttempts) {\n                break;\n            }\n            const delay = backoffMs * Math.pow(1.5, attempt - 1);\n            await sleep(delay);\n            continue;\n        }\n        const id = preserveId ? baseId : (attempt === 1 ? baseId : `${baseId}-r${attempt}`);\n        obj.id = id;\n        try {\n            const response = await new Promise((resolve, reject) => {\n                const encoded = new TextEncoder().encode(JSON.stringify(obj));\n                lastPayloadBytes = encoded.length;\n                if (typeof onBytes === 'function') onBytes(lastPayloadBytes, obj);\n\n                const t = setTimeout(() => {\n                    pending.delete(id);\n                    pendingChunkedResponses.delete(id);\n                    chunkStore.delete(id);\n                    reject(new Error('DM reply timeout'));\n                }, timeoutMs);\n                pending.set(id, { resolve, reject, timeout: t });\n\n                client.send(dest, JSON.stringify(obj), sendOpts).catch(err => {\n                    if (onSendError) {\n                        try { onSendError(err); } catch (_) { /* ignore */ }\n                    }\n                    const st = pending.get(id);\n                    if (st) {\n                        clearTimeout(st.timeout);\n                        pending.delete(id);\n                        pendingChunkedResponses.delete(id);\n                        chunkStore.delete(id);\n                        st.reject(new Error(err && err.message || String(err)));\n                    }\n                    if (isNknDebugEnabled()) {\n                        console.error('NKN send error:', err && err.message || err);\n                    }\n                });\n            });\n            return response;\n        } catch (err) {\n            lastErr = err;\n            const retryable = shouldRetryNknError(err);\n            if (!retryable || attempt >= maxAttempts) {\n                break;\n            }\n            const delay = backoffMs * Math.pow(1.5, attempt - 1);\n            await sleep(delay);\n        }\n    }\n\n    throw lastErr || new Error('NKN send failed');\n}\n\n/**\n * Handle incoming NKN messages\n * @param {string} src - Source NKN address\n * @param {string|Uint8Array} payload - Message payload\n */\nexport function handleIncoming(src, payload) {\n    _cleanupStaleChunks();\n    const text = _decodePayload(payload);\n    const msg = _parsePayload(text);\n    if (!msg) {\n        if (isNknDebugEnabled()) {\n            console.log('NKN incoming raw:', text);\n        }\n        return;\n    }\n    if (msg && msg.type === 'http.chunk' && msg.id) {\n        const id = msg.id;\n        const totalChunks = Number.isFinite(msg.chunk_count) ? msg.chunk_count : 0;\n        const idx = Number.isFinite(msg.chunk_index) ? msg.chunk_index : -1;\n        if (!totalChunks || idx < 0) return;\n        let entry = chunkStore.get(id);\n        if (!entry) {\n            entry = {\n                chunks: new Array(totalChunks),\n                totalChunks,\n                received: 0,\n                bytesTotal: Number.isFinite(msg.bytes_total) ? msg.bytes_total : 0,\n                updatedAt: Date.now()\n            };\n            chunkStore.set(id, entry);\n        }\n        if (entry.chunks[idx] == null) {\n            entry.chunks[idx] = msg.body_b64 || '';\n            entry.received += 1;\n        }\n        entry.updatedAt = Date.now();\n        const pendingResp = pendingChunkedResponses.get(id);\n        if (pendingResp && _tryAssembleChunks(id, pendingResp)) {\n            pendingChunkedResponses.delete(id);\n            _resolvePendingResponse(id, pendingResp);\n        }\n        return;\n    }\n\n    if (msg && msg.type === 'http.response' && msg.id) {\n        if (msg.chunked) {\n            const assembled = _tryAssembleChunks(msg.id, msg);\n            if (!assembled) {\n                pendingChunkedResponses.set(msg.id, msg);\n                return;\n            }\n        }\n        _resolvePendingResponse(msg.id, msg);\n        return;\n    }\n    if (isNknDebugEnabled()) {\n        console.log('NKN unsolicited from', src, msg);\n    }\n}\n\n/**\n * Get the last payload size in bytes\n * @returns {number} Last payload size\n */\nexport function getLastPayloadBytes() {\n    return lastPayloadBytes;\n}\n","/** Weather data through the canonical NOCLIP backend (Open-Meteo model source). */\nimport { resolveBackendApiUrl } from '../refactor/shared/backend.js';\n\nexport class WeatherManager {\n    constructor({\n        updateIntervalMs = 10 * 60 * 1000,\n        minDeltaDeg = 0.01,\n        minFetchIntervalMs = null,\n        cacheTtlMs = null,\n        maxCacheEntries = 32\n    } = {}) {\n        const safeUpdateInterval = Number.isFinite(updateIntervalMs) ? updateIntervalMs : 10 * 60 * 1000;\n        const defaultMinFetchInterval = Math.min(safeUpdateInterval, 30 * 1000);\n        const defaultCacheTtl = Math.min(safeUpdateInterval, 5 * 60 * 1000);\n        this.current = null;\n        this.currentUnits = null;\n        this.location = null;\n        this.hourly = null;\n        this.daily = null;\n        this.timezone = null;\n        this.timezoneAbbreviation = null;\n        this.utcOffsetSeconds = null;\n        this.lastUpdate = null;\n        this.updateInterval = safeUpdateInterval;\n        this.minDeltaDeg = minDeltaDeg;\n        this._minFetchIntervalAuto = !Number.isFinite(minFetchIntervalMs);\n        this.minFetchIntervalMs = Number.isFinite(minFetchIntervalMs)\n            ? Math.max(0, minFetchIntervalMs)\n            : defaultMinFetchInterval;\n        this._cacheTtlAuto = !Number.isFinite(cacheTtlMs);\n        this.cacheTtlMs = Number.isFinite(cacheTtlMs)\n            ? Math.max(0, cacheTtlMs)\n            : defaultCacheTtl;\n        this.maxCacheEntries = Number.isFinite(maxCacheEntries)\n            ? Math.max(0, Math.floor(maxCacheEntries))\n            : 32;\n        this.lat = null;\n        this.lon = null;\n        this._updateTimer = null;\n        this._fetchTimer = null;\n        this._fetchInFlight = null;\n        this._fetchEpoch = 0;\n        this._pendingFetch = false;\n        this._lastFetchAt = 0;\n        this._cooldownUntil = 0;\n        this._backoffMs = 0;\n        this._cache = new Map();\n        this.onUpdate = null;\n    }\n\n    /**\n     * Start weather updates for a location\n     * @param {number} lat - Latitude\n     * @param {number} lon - Longitude\n     */\n    start(lat, lon) {\n        this.lat = lat;\n        this.lon = lon;\n        this.fetchWeather();\n\n        // Set up periodic updates\n        if (this._updateTimer) clearInterval(this._updateTimer);\n        this._updateTimer = setInterval(() => this.fetchWeather(), this.updateInterval);\n    }\n\n    /**\n     * Stop weather updates\n     */\n    stop() {\n        this._fetchEpoch += 1;\n        if (this._updateTimer) {\n            clearInterval(this._updateTimer);\n            this._updateTimer = null;\n        }\n        if (this._fetchTimer) {\n            clearTimeout(this._fetchTimer);\n            this._fetchTimer = null;\n        }\n        if (this._fetchInFlight) {\n            try { this._fetchInFlight.abort(); } catch (error) {}\n            this._fetchInFlight = null;\n        }\n        this._pendingFetch = false;\n    }\n\n    /**\n     * Update location and fetch new weather data\n     */\n    updateLocation(lat, lon) {\n        const delta = Number.isFinite(this.minDeltaDeg) ? this.minDeltaDeg : 0.01;\n        const latChanged = Math.abs(this.lat - lat) > delta;\n        const lonChanged = Math.abs(this.lon - lon) > delta;\n\n        if (latChanged || lonChanged) {\n            this.lat = lat;\n            this.lon = lon;\n            this.fetchWeather();\n        }\n    }\n\n    /**\n     * Update refresh interval for weather polling\n     */\n    setUpdateInterval(updateIntervalMs) {\n        if (!Number.isFinite(updateIntervalMs) || updateIntervalMs <= 0) return;\n        this.updateInterval = updateIntervalMs;\n        if (this._minFetchIntervalAuto) {\n            this.minFetchIntervalMs = Math.min(this.updateInterval, 30 * 1000);\n        }\n        if (this._cacheTtlAuto) {\n            this.cacheTtlMs = Math.min(this.updateInterval, 5 * 60 * 1000);\n        }\n        if (this._updateTimer) {\n            clearInterval(this._updateTimer);\n            this._updateTimer = setInterval(() => this.fetchWeather(), this.updateInterval);\n        }\n    }\n\n    /**\n     * Update the minimum delta before a refresh is triggered\n     */\n    setMinDeltaDeg(minDeltaDeg) {\n        if (!Number.isFinite(minDeltaDeg) || minDeltaDeg < 0) return;\n        this.minDeltaDeg = minDeltaDeg;\n    }\n\n    /**\n     * Fetch weather data from Open-Meteo API\n     */\n    async fetchWeather({ force = false } = {}) {\n        if (!Number.isFinite(this.lat) || !Number.isFinite(this.lon)) {\n            console.warn('WeatherManager: Invalid coordinates', this.lat, this.lon);\n            return;\n        }\n\n        const now = Date.now();\n        if (this._fetchInFlight) {\n            this._pendingFetch = true;\n            return;\n        }\n        if (this._cooldownUntil && now < this._cooldownUntil) {\n            this._pendingFetch = true;\n            this._scheduleFetch(this._cooldownUntil - now);\n            return;\n        }\n        const earliestNext = this._lastFetchAt > 0\n            ? Math.max(this._cooldownUntil, this._lastFetchAt + this.minFetchIntervalMs)\n            : this._cooldownUntil;\n        if (!force && now < earliestNext) {\n            this._pendingFetch = true;\n            this._scheduleFetch(earliestNext - now);\n            return;\n        }\n\n        const requestLat = this.lat;\n        const requestLon = this.lon;\n        const requestEpoch = this._fetchEpoch;\n        const cacheKey = this._getCacheKey(requestLat, requestLon);\n        if (!force) {\n            const cached = this._getCached(cacheKey, now);\n            if (cached) {\n                this._applyWeatherData(cached.data, cached.timestamp);\n                return;\n            }\n        }\n\n        this._lastFetchAt = now;\n        const url = resolveBackendApiUrl(`/sensors/weather/forecast?lat=${requestLat.toFixed(4)}&lon=${requestLon.toFixed(4)}`);\n\n        const controller = new AbortController();\n        this._fetchInFlight = controller;\n        try {\n            const response = await fetch(url, { signal: controller.signal });\n            if (controller.signal.aborted || requestEpoch !== this._fetchEpoch\n                || this.lat !== requestLat || this.lon !== requestLon) return;\n            if (!response.ok) {\n                if (response.status === 429) {\n                    this._applyBackoff(response);\n                    this._pendingFetch = true;\n                }\n                throw new Error(`Weather API error: ${response.status}`);\n            }\n\n            const data = await response.json();\n            if (controller.signal.aborted || requestEpoch !== this._fetchEpoch\n                || this.lat !== requestLat || this.lon !== requestLon) return;\n            this._backoffMs = 0;\n            const timestamp = Date.now();\n            const scoped = { ...data, _requestLocation: { lat: requestLat, lon: requestLon } };\n            this._setCached(cacheKey, scoped, timestamp);\n            this._applyWeatherData(scoped, timestamp);\n        } catch (err) {\n            if (err?.name !== 'AbortError') {\n                console.error('Failed to fetch weather:', err);\n            }\n        } finally {\n            // An aborted predecessor must not clear or reschedule its successor.\n            if (this._fetchInFlight !== controller || requestEpoch !== this._fetchEpoch) return;\n            this._fetchInFlight = null;\n            if (this._pendingFetch) {\n                this._pendingFetch = false;\n                this.fetchWeather();\n            }\n        }\n    }\n\n    _applyWeatherData(data, timestamp) {\n        if (!data) return;\n        this.current = data.current;\n        this.currentUnits = data.current_units || null;\n        this.location = data._requestLocation || null;\n        this.hourly = data.hourly;\n        this.daily = data.daily;\n        this.timezone = typeof data.timezone === 'string' && data.timezone.trim()\n            ? data.timezone.trim()\n            : null;\n        this.timezoneAbbreviation = typeof data.timezone_abbreviation === 'string' && data.timezone_abbreviation.trim()\n            ? data.timezone_abbreviation.trim()\n            : null;\n        this.utcOffsetSeconds = Number.isFinite(data.utc_offset_seconds)\n            ? data.utc_offset_seconds\n            : null;\n        this.lastUpdate = timestamp;\n\n        // Dispatch event for listeners\n        if (typeof window !== 'undefined') {\n            window.dispatchEvent(new CustomEvent('weather-updated', { detail: this.getWeatherData() }));\n        }\n        if (typeof this.onUpdate === 'function') {\n            this.onUpdate(this.getWeatherData());\n        }\n    }\n\n    _scheduleFetch(delayMs) {\n        const delay = Math.max(0, delayMs || 0);\n        if (this._fetchTimer) {\n            clearTimeout(this._fetchTimer);\n        }\n        this._fetchTimer = setTimeout(() => {\n            this._fetchTimer = null;\n            if (this._pendingFetch) {\n                this._pendingFetch = false;\n                this.fetchWeather();\n            }\n        }, delay);\n    }\n\n    _applyBackoff(response) {\n        const now = Date.now();\n        const retryAfter = Number.parseInt(response?.headers?.get?.('retry-after') || '', 10);\n        const retryMs = Number.isFinite(retryAfter) ? retryAfter * 1000 : 0;\n        if (retryMs > 0) {\n            this._cooldownUntil = Math.max(this._cooldownUntil, now + retryMs);\n            this._backoffMs = retryMs;\n            return;\n        }\n        const next = this._backoffMs > 0 ? Math.min(this._backoffMs * 2, 5 * 60 * 1000) : 30 * 1000;\n        this._backoffMs = next;\n        this._cooldownUntil = Math.max(this._cooldownUntil, now + next);\n    }\n\n    _getCacheKey(lat, lon) {\n        return `${lat.toFixed(4)}|${lon.toFixed(4)}`;\n    }\n\n    _getCached(key, now) {\n        if (!this.cacheTtlMs || this.maxCacheEntries <= 0) return null;\n        const entry = this._cache.get(key);\n        if (!entry) return null;\n        if (now - entry.timestamp > this.cacheTtlMs) {\n            this._cache.delete(key);\n            return null;\n        }\n        return entry;\n    }\n\n    _setCached(key, data, timestamp) {\n        if (!this.cacheTtlMs || this.maxCacheEntries <= 0) return;\n        if (this._cache.has(key)) {\n            this._cache.delete(key);\n        }\n        this._cache.set(key, { data, timestamp });\n        if (this._cache.size > this.maxCacheEntries) {\n            const oldestKey = this._cache.keys().next().value;\n            if (oldestKey) {\n                this._cache.delete(oldestKey);\n            }\n        }\n    }\n\n    /**\n     * Get current weather data\n     */\n    getWeatherData() {\n        return {\n            current: this.current,\n            currentUnits: this.currentUnits,\n            location: this.location,\n            hourly: this.hourly,\n            daily: this.daily,\n            timezone: this.timezone,\n            timezoneAbbreviation: this.timezoneAbbreviation,\n            utcOffsetSeconds: this.utcOffsetSeconds,\n            lastUpdate: this.lastUpdate\n        };\n    }\n\n    /**\n     * Get weather code description\n     */\n    getWeatherDescription(code) {\n        const codes = {\n            0: 'Clear',\n            1: 'Mostly Clear',\n            2: 'Partly Cloudy',\n            3: 'Overcast',\n            45: 'Foggy',\n            48: 'Foggy',\n            51: 'Light Drizzle',\n            53: 'Drizzle',\n            55: 'Heavy Drizzle',\n            61: 'Light Rain',\n            63: 'Rain',\n            65: 'Heavy Rain',\n            71: 'Light Snow',\n            73: 'Snow',\n            75: 'Heavy Snow',\n            77: 'Snow Grains',\n            80: 'Light Showers',\n            81: 'Showers',\n            82: 'Heavy Showers',\n            85: 'Light Snow Showers',\n            86: 'Snow Showers',\n            95: 'Thunderstorm',\n            96: 'Thunderstorm',\n            99: 'Thunderstorm'\n        };\n        return codes[code] || 'Unknown';\n    }\n\n    /**\n     * Get a short icon label for a weather code\n     */\n    getWeatherIcon(code) {\n        if (code === 0) return 'SUN';\n        if (code === 1) return 'SUN-CLOUD';\n        if (code === 2) return 'PARTLY-CLOUDY';\n        if (code === 3) return 'OVERCAST';\n        if (code === 45 || code === 48) return 'FOG';\n        if (code >= 51 && code <= 55) return 'DRIZZLE';\n        if (code >= 61 && code <= 65) return 'RAIN';\n        if (code >= 71 && code <= 77) return 'SNOW';\n        if (code >= 80 && code <= 82) return 'SHOWERS';\n        if (code >= 85 && code <= 86) return 'SNOW-SHOWERS';\n        if (code >= 95) return 'THUNDER';\n        return 'UNKNOWN';\n    }\n\n    /**\n     * Get daily forecast for next N days\n     */\n    getDailyForecast(days = 7) {\n        if (!this.daily) return [];\n\n        const forecast = [];\n        const maxDays = Math.min(days, this.daily.time?.length || 0);\n\n        for (let i = 0; i < maxDays; i++) {\n            forecast.push({\n                date: this.daily.time[i],\n                weatherCode: this.daily.weather_code[i],\n                tempMax: this.daily.temperature_2m_max[i],\n                tempMin: this.daily.temperature_2m_min[i],\n                precipitation: this.daily.precipitation_sum[i],\n                precipProb: this.daily.precipitation_probability_max[i],\n                windSpeed: this.daily.wind_speed_10m_max[i]\n            });\n        }\n\n        return forecast;\n    }\n}\n","/**\n * WeatherSystem\n *\n * Bridges weather data to cloud rendering via a local weather map.\n * Supports auto-targeting based on HUD lat/lon and manual region overrides.\n */\n\nimport * as THREE from 'three';\nimport { PLANET_RADIUS } from './constants.js';\nimport { WeatherManager } from './weather-manager.js';\nimport { deriveSceneWeatherState } from '../refactor/weather/SceneWeatherState.js';\n\nconst DEFAULT_UPDATE_INTERVAL_MS = 10 * 60 * 1000;\nconst DEFAULT_MIN_DELTA_DEG = 0.05;\nconst DEFAULT_REGION_RADIUS_KM = 400;\nconst DEFAULT_CLOUD_INFLUENCE = 0.6;\nconst DEFAULT_MAP_WIDTH = 512;\nconst DEFAULT_MAP_HEIGHT = 256;\nconst AUTO_REGION_ID = '__auto__';\n\nexport class WeatherSystem {\n    constructor({\n        atmosphereClouds = null,\n        enabled = false,\n        autoTarget = true,\n        updateIntervalMs = DEFAULT_UPDATE_INTERVAL_MS,\n        minDeltaDeg = DEFAULT_MIN_DELTA_DEG,\n        regionRadiusKm = DEFAULT_REGION_RADIUS_KM,\n        cloudInfluence = DEFAULT_CLOUD_INFLUENCE,\n        lightingSystem = null,\n        uvLightingEnabled = true\n    } = {}) {\n        this.atmosphereClouds = null;\n        this.lightingSystem = lightingSystem || null;\n        this.uvLightingEnabled = uvLightingEnabled !== false;\n        this.enabled = !!enabled;\n        this.autoTarget = !!autoTarget;\n        this.updateIntervalMs = Number.isFinite(updateIntervalMs) ? updateIntervalMs : DEFAULT_UPDATE_INTERVAL_MS;\n        this.minDeltaDeg = Number.isFinite(minDeltaDeg) ? minDeltaDeg : DEFAULT_MIN_DELTA_DEG;\n        this.regionRadiusKm = Number.isFinite(regionRadiusKm) ? regionRadiusKm : DEFAULT_REGION_RADIUS_KM;\n        this.cloudInfluence = Number.isFinite(cloudInfluence) ? cloudInfluence : DEFAULT_CLOUD_INFLUENCE;\n\n        this.weatherManager = new WeatherManager({\n            updateIntervalMs: this.updateIntervalMs,\n            minDeltaDeg: this.minDeltaDeg\n        });\n        this.weatherManager.onUpdate = (data) => this._handleWeatherUpdated(data);\n        this.hoverWeatherManager = new WeatherManager({\n            updateIntervalMs: this.updateIntervalMs,\n            minDeltaDeg: this.minDeltaDeg\n        });\n        this.hoverWeatherManager.onUpdate = (data) => this._handleHoverWeatherUpdated(data);\n        this.onHoverUpdate = null;\n\n        this._regions = new Map();\n        this._targetCoords = null;\n        this._hoverCoords = null;\n        this._weatherData = null;\n        this._sceneWeatherState = {};\n        this._sceneWeatherOptions = {};\n        this._hoverWeatherData = null;\n        this._weatherActive = false;\n        this._hoverActive = false;\n        this._baseCloudSettings = null;\n        this._lastCloudTuneables = null;\n\n        this._defaultLocalWeatherTexture = null;\n        this._baseImage = null;\n        this._weatherCanvas = null;\n        this._weatherCtx = null;\n        this._weatherTexture = null;\n\n        this.setAtmosphereClouds(atmosphereClouds);\n        if (this.enabled) {\n            this._applyWeatherTexture();\n        }\n    }\n\n    setAtmosphereClouds(atmosphereClouds) {\n        this.atmosphereClouds = atmosphereClouds || null;\n        this._syncBaseTexture();\n        this._captureBaseCloudSettings();\n        if (this.enabled) {\n            this._applyWeatherTexture();\n            if (this._weatherData) {\n                this._refreshAutoRegion();\n                this._applyWeatherCloudTuneables();\n                this._applyWeatherLighting();\n                this._dispatchWeatherStatus();\n            }\n        } else {\n            this._restoreDefaultTexture();\n        }\n    }\n\n    setEnabled(enabled) {\n        const next = !!enabled;\n        if (this.enabled === next) return;\n        this.enabled = next;\n        if (this.enabled) {\n            this._captureBaseCloudSettings();\n            this._applyWeatherTexture();\n            if (this._targetCoords && !this.autoTarget) {\n                this._updateWeatherTarget(this._targetCoords.lat, this._targetCoords.lon);\n            }\n            if (this._hoverCoords) {\n                this._updateHoverTarget(this._hoverCoords.lat, this._hoverCoords.lon);\n            }\n            if (this._weatherData) {\n                this._refreshAutoRegion();\n                this._applyWeatherCloudTuneables();\n            }\n            this._applyWeatherLighting();\n        } else {\n            this.weatherManager.stop();\n            this._weatherActive = false;\n            this._regions.delete(AUTO_REGION_ID);\n            // Restore the sun to its base intensity when weather is turned off.\n            this.lightingSystem?.applyUvIndex?.(null, { enabled: false });\n            this.hoverWeatherManager.stop();\n            this._hoverActive = false;\n            this._hoverWeatherData = null;\n            this._restoreDefaultTexture();\n            this._restoreBaseCloudSettings();\n            if (typeof this.onHoverUpdate === 'function') {\n                this.onHoverUpdate(this.getHudWeatherSummary('hover'));\n            }\n        }\n        this._dispatchWeatherStatus();\n    }\n\n    setAutoTarget(autoTarget) {\n        this.autoTarget = !!autoTarget;\n        this._dispatchWeatherStatus();\n    }\n\n    setUpdateInterval(updateIntervalMs) {\n        if (!Number.isFinite(updateIntervalMs) || updateIntervalMs <= 0) return;\n        this.updateIntervalMs = updateIntervalMs;\n        this.weatherManager.setUpdateInterval(updateIntervalMs);\n        this.hoverWeatherManager.setUpdateInterval(updateIntervalMs);\n    }\n\n    setMinDeltaDeg(minDeltaDeg) {\n        if (!Number.isFinite(minDeltaDeg) || minDeltaDeg < 0) return;\n        this.minDeltaDeg = minDeltaDeg;\n        this.weatherManager.setMinDeltaDeg(minDeltaDeg);\n        this.hoverWeatherManager.setMinDeltaDeg(minDeltaDeg);\n    }\n\n    setRegionRadiusKm(regionRadiusKm) {\n        if (!Number.isFinite(regionRadiusKm) || regionRadiusKm <= 0) return;\n        this.regionRadiusKm = regionRadiusKm;\n        this._refreshAutoRegion();\n    }\n\n    setCloudInfluence(cloudInfluence) {\n        if (!Number.isFinite(cloudInfluence)) return;\n        this.cloudInfluence = THREE.MathUtils.clamp(cloudInfluence, -1, 1);\n        this._refreshAutoRegion();\n    }\n\n    setTarget(lat, lon) {\n        if (!Number.isFinite(lat) || !Number.isFinite(lon)) return;\n        this._targetCoords = { lat, lon };\n        if (this.enabled && !this.autoTarget) {\n            this._updateWeatherTarget(lat, lon);\n            if (this._weatherData) this._refreshAutoRegion();\n        }\n        this._dispatchWeatherStatus();\n    }\n\n    setHoverTarget(lat, lon) {\n        if (!Number.isFinite(lat) || !Number.isFinite(lon)) return;\n        this._hoverCoords = { lat, lon };\n        if (this.enabled) {\n            this._updateHoverTarget(lat, lon);\n        }\n    }\n\n    clearHoverTarget() {\n        this._hoverCoords = null;\n        this._hoverWeatherData = null;\n        if (this._hoverActive) {\n            this.hoverWeatherManager.stop();\n            this._hoverActive = false;\n        }\n        if (typeof this.onHoverUpdate === 'function') {\n            this.onHoverUpdate(this.getHudWeatherSummary('hover'));\n        }\n    }\n\n    updateFromHudElements(latEl, lonEl) {\n        this._syncBaseTexture();\n        if (!this.enabled || !this.autoTarget) return;\n        const lat = this._parseHudValue(latEl);\n        const lon = this._parseHudValue(lonEl);\n        this.updateFromHudValues(lat, lon);\n    }\n\n    updateFromHudValues(lat, lon) {\n        this._syncBaseTexture();\n        if (!this.enabled || !this.autoTarget) return;\n        if (!Number.isFinite(lat) || !Number.isFinite(lon)) return;\n        const prev = this._targetCoords;\n        const delta = Number.isFinite(this.minDeltaDeg) ? this.minDeltaDeg : 0;\n        const shouldUpdate = !prev ||\n            Math.abs(lat - prev.lat) >= delta ||\n            Math.abs(lon - prev.lon) >= delta;\n\n        this._targetCoords = { lat, lon };\n        if (shouldUpdate) {\n            this._updateWeatherTarget(lat, lon);\n        }\n        if (this._weatherData) this._refreshAutoRegion();\n        this._dispatchWeatherStatus();\n    }\n\n    setRegion(id, { lat, lon, radiusKm, intensity } = {}) {\n        if (!id) return;\n        if (!Number.isFinite(lat) || !Number.isFinite(lon)) return;\n        const next = {\n            lat,\n            lon,\n            radiusKm: Number.isFinite(radiusKm) ? radiusKm : this.regionRadiusKm,\n            intensity: Number.isFinite(intensity) ? THREE.MathUtils.clamp(intensity, -1, 1) : this.cloudInfluence\n        };\n        this._regions.set(id, next);\n        if (this.enabled) {\n            this._renderWeatherMap();\n        }\n    }\n\n    clearRegion(id) {\n        if (!id) return;\n        if (this._regions.delete(id) && this.enabled) {\n            this._renderWeatherMap();\n        }\n    }\n\n    clearRegions() {\n        if (this._regions.size === 0) return;\n        this._regions.clear();\n        if (this.enabled) this._renderWeatherMap();\n    }\n\n    applyConfig(config = {}) {\n        if (!config || typeof config !== 'object') return;\n        if (typeof config.enabled === 'boolean') this.setEnabled(config.enabled);\n        if (typeof config.autoTarget === 'boolean') this.setAutoTarget(config.autoTarget);\n        if (Number.isFinite(config.updateIntervalMs)) this.setUpdateInterval(config.updateIntervalMs);\n        if (Number.isFinite(config.minDeltaDeg)) this.setMinDeltaDeg(config.minDeltaDeg);\n        if (Number.isFinite(config.regionRadiusKm)) this.setRegionRadiusKm(config.regionRadiusKm);\n        if (Number.isFinite(config.cloudInfluence)) this.setCloudInfluence(config.cloudInfluence);\n    }\n\n    getConfig() {\n        return {\n            enabled: this.enabled,\n            autoTarget: this.autoTarget,\n            updateIntervalMs: this.updateIntervalMs,\n            minDeltaDeg: this.minDeltaDeg,\n            regionRadiusKm: this.regionRadiusKm,\n            cloudInfluence: this.cloudInfluence\n        };\n    }\n\n    getWeatherData() {\n        return this.weatherManager.getWeatherData();\n    }\n\n    // One bounded current-location snapshot shared by rain and wind. Hover data\n    // and manual targets elsewhere must never change the observer's weather.\n    getSceneWeatherState(latitude, longitude) {\n        const options = this._sceneWeatherOptions;\n        options.enabled = this.enabled;\n        options.latitude = latitude;\n        options.longitude = longitude;\n        options.now = Date.now();\n        return deriveSceneWeatherState(this._weatherData, options, this._sceneWeatherState);\n    }\n\n    getHoverWeatherData() {\n        return this._hoverWeatherData ? { ...this._hoverWeatherData } : null;\n    }\n\n    getTargetCoords() {\n        if (this._targetCoords) return { ...this._targetCoords };\n        if (Number.isFinite(this.weatherManager.lat) && Number.isFinite(this.weatherManager.lon)) {\n            return { lat: this.weatherManager.lat, lon: this.weatherManager.lon };\n        }\n        return null;\n    }\n\n    getHudWeatherSummary(source = 'nav') {\n        if (!this.enabled) return null;\n        const useHover = source === 'hover' || source === 'target';\n        const data = useHover ? this._hoverWeatherData : this._weatherData;\n        const coords = useHover ? this._hoverCoords : this.getTargetCoords();\n        return this._formatHudWeatherSummary(data, coords);\n    }\n\n    getWeatherDescription(code) {\n        return this.weatherManager.getWeatherDescription(code);\n    }\n\n    getCloudTuneables() {\n        return this._lastCloudTuneables ? { ...this._lastCloudTuneables } : null;\n    }\n\n    getOverlayLines() {\n        if (!this.enabled) return null;\n        const current = this._weatherData?.current;\n        if (!current) return ['Weather target: loading...'];\n\n        const code = Number.isFinite(current.weather_code) ? current.weather_code : null;\n        const desc = code != null ? (this.weatherManager.getWeatherDescription(code) || 'Unknown') : 'Unknown';\n        const temp = Number.isFinite(current.temperature_2m)\n            ? `${Math.round(current.temperature_2m)}C`\n            : '--C';\n        const cloudCover = Number.isFinite(current.cloud_cover)\n            ? `${Math.round(current.cloud_cover)}% cloud`\n            : null;\n        const humidity = Number.isFinite(current.relative_humidity_2m)\n            ? `${Math.round(current.relative_humidity_2m)}% RH`\n            : null;\n        const wind = Number.isFinite(current.wind_speed_10m)\n            ? `${Math.round(current.wind_speed_10m)} km/h wind`\n            : null;\n        const parts = [temp, cloudCover, humidity, wind].filter(Boolean);\n        const age = this._formatAge(this._weatherData?.lastUpdate);\n        const suffix = parts.length ? ` (${parts.join(' · ')})` : '';\n        const ageSuffix = age ? ` · ${age}` : '';\n        return [`Weather target: ${desc}${suffix}${ageSuffix}`];\n    }\n\n    _handleWeatherUpdated(data) {\n        this._weatherData = data;\n        if (!this.enabled) return;\n        this._refreshAutoRegion();\n        this._applyWeatherCloudTuneables();\n        this._applyWeatherLighting();\n        this._dispatchWeatherStatus();\n    }\n\n    _handleHoverWeatherUpdated(data) {\n        this._hoverWeatherData = data;\n        if (typeof this.onHoverUpdate === 'function') {\n            this.onHoverUpdate(this.getHudWeatherSummary('hover'));\n        }\n    }\n\n    _refreshAutoRegion() {\n        if (!this.enabled) return;\n        const current = this._weatherData?.current;\n        if (!current) return;\n        const lat = this._targetCoords?.lat ?? this.weatherManager.lat;\n        const lon = this._targetCoords?.lon ?? this.weatherManager.lon;\n        if (!Number.isFinite(lat) || !Number.isFinite(lon)) return;\n        const cloudCover = Number.isFinite(current.cloud_cover) ? current.cloud_cover : null;\n        if (!Number.isFinite(cloudCover)) return;\n        const intensity = THREE.MathUtils.clamp((cloudCover / 100) * this.cloudInfluence, -1, 1);\n        if (Math.abs(intensity) < 1e-3) {\n            this._regions.delete(AUTO_REGION_ID);\n        } else {\n            this._regions.set(AUTO_REGION_ID, {\n                lat,\n                lon,\n                radiusKm: this.regionRadiusKm,\n                intensity\n            });\n        }\n        this._renderWeatherMap();\n    }\n\n    /** Inject / replace the lighting system after construction. */\n    setLightingSystem(lightingSystem) {\n        this.lightingSystem = lightingSystem || null;\n        this._applyWeatherLighting();\n    }\n\n    /** Enable/disable UV-index sun modulation. */\n    setUvLightingEnabled(enabled) {\n        this.uvLightingEnabled = !!enabled;\n        // Restore base sun when turned off; re-derive from live data when on.\n        if (!this.uvLightingEnabled) {\n            this.lightingSystem?.applyUvIndex?.(null, { enabled: false });\n        } else {\n            this._applyWeatherLighting();\n        }\n    }\n\n    /**\n     * Drive the sun's diffuse intensity from the live UV index so sun-lit\n     * surfaces stop blowing out under the high-exposure AgX pipeline. Only\n     * applies when weather is enabled and a finite uv_index is present;\n     * otherwise the lighting system keeps its base intensity untouched.\n     */\n    _applyWeatherLighting() {\n        if (!this.lightingSystem?.applyUvIndex) return;\n        if (!this.enabled || !this.uvLightingEnabled) {\n            this.lightingSystem.applyUvIndex(null, { enabled: false });\n            return;\n        }\n        const current = this._weatherData?.current;\n        const uvIndex = Number.isFinite(current?.uv_index) ? current.uv_index : null;\n        this.lightingSystem.applyUvIndex(uvIndex, { enabled: Number.isFinite(uvIndex) });\n    }\n\n    _applyWeatherCloudTuneables() {\n        if (!this.enabled || !this.atmosphereClouds) return;\n        const current = this._weatherData?.current;\n        if (!current) return;\n        if (!this._baseCloudSettings) this._captureBaseCloudSettings();\n        const base = this._baseCloudSettings || {};\n        const tuneables = this._deriveCloudTuneables(current, base);\n        if (!tuneables) return;\n        this._lastCloudTuneables = tuneables;\n        this.atmosphereClouds.applyConfig?.({ clouds: tuneables });\n    }\n\n    _deriveCloudTuneables(current, base) {\n        if (!current) return null;\n        const clamp01 = (value) => THREE.MathUtils.clamp(value, 0, 1);\n        const cloudCover = Number.isFinite(current.cloud_cover)\n            ? clamp01(current.cloud_cover / 100)\n            : null;\n        const humidity = Number.isFinite(current.relative_humidity_2m)\n            ? clamp01(current.relative_humidity_2m / 100)\n            : null;\n        const precipitation = Number.isFinite(current.precipitation)\n            ? current.precipitation\n            : (Number.isFinite(current.rain) ? current.rain : 0);\n        const precipNorm = clamp01(precipitation / 10);\n        const wind = Number.isFinite(current.wind_speed_10m) ? current.wind_speed_10m : 0;\n        const windNorm = clamp01(wind / 60);\n        const cloudFactor = cloudCover ?? clamp01((humidity ?? 0.5) * 0.8);\n        const humidityFactor = humidity ?? clamp01(cloudFactor * 0.9 + 0.1);\n        const stormFactor = clamp01(precipNorm * 0.7 + cloudFactor * 0.3);\n\n        const baseCoverage = Number.isFinite(base.coverage) ? base.coverage : 0.4;\n        const baseScattering = Number.isFinite(base.scatteringCoefficient) ? base.scatteringCoefficient : 1;\n        const baseAbsorption = Number.isFinite(base.absorptionCoefficient) ? base.absorptionCoefficient : 0;\n        const baseTurbulence = Number.isFinite(base.turbulenceDisplacement) ? base.turbulenceDisplacement : 350;\n\n        const coverage = THREE.MathUtils.clamp(\n            baseCoverage * (0.4 + 1.4 * cloudFactor),\n            0.05,\n            0.95\n        );\n        const scatteringCoefficient = THREE.MathUtils.clamp(\n            baseScattering * (0.6 + 0.9 * humidityFactor + 0.3 * cloudFactor),\n            0.2,\n            3\n        );\n        const absorptionCoefficient = THREE.MathUtils.clamp(\n            baseAbsorption + 0.15 * cloudFactor + 0.4 * precipNorm,\n            0,\n            1\n        );\n        const turbulenceDisplacement = THREE.MathUtils.clamp(\n            baseTurbulence * (0.6 + 1.0 * windNorm + 0.3 * cloudFactor),\n            80,\n            1200\n        );\n\n        const lightShafts = (base.lightShafts ?? true) && cloudFactor < 0.75 && precipNorm < 0.35;\n        const shapeDetail = (base.shapeDetail ?? true) && cloudFactor > 0.15;\n        const turbulence = (base.turbulence ?? true) && (windNorm > 0.15 || stormFactor > 0.4);\n        const haze = (base.haze ?? true) && (humidityFactor > 0.55 || cloudFactor > 0.5);\n\n        return {\n            coverage,\n            scatteringCoefficient,\n            absorptionCoefficient,\n            turbulenceDisplacement,\n            lightShafts,\n            shapeDetail,\n            turbulence,\n            haze\n        };\n    }\n\n    _captureBaseCloudSettings() {\n        if (!this.atmosphereClouds) return;\n        const config = this.atmosphereClouds.getConfig?.();\n        const clouds = config?.clouds || this.atmosphereClouds.clouds;\n        if (!clouds) return;\n        this._baseCloudSettings = {\n            coverage: clouds.coverage,\n            scatteringCoefficient: clouds.scatteringCoefficient,\n            absorptionCoefficient: clouds.absorptionCoefficient,\n            turbulenceDisplacement: clouds.turbulenceDisplacement,\n            lightShafts: clouds.lightShafts,\n            shapeDetail: clouds.shapeDetail,\n            turbulence: clouds.turbulence,\n            haze: clouds.haze\n        };\n    }\n\n    _restoreBaseCloudSettings() {\n        if (!this.atmosphereClouds || !this._baseCloudSettings) return;\n        this.atmosphereClouds.applyConfig?.({ clouds: { ...this._baseCloudSettings } });\n        this._lastCloudTuneables = null;\n    }\n\n    _dispatchWeatherStatus() {\n        if (typeof window === 'undefined') return;\n        const detail = {\n            enabled: this.enabled,\n            autoTarget: this.autoTarget,\n            target: this.getTargetCoords(),\n            weather: this._weatherData?.current || null,\n            lastUpdate: this._weatherData?.lastUpdate || null,\n            cloudTuneables: this._lastCloudTuneables\n        };\n        window.dispatchEvent(new CustomEvent('weather-status', { detail }));\n    }\n\n    _updateWeatherTarget(lat, lon) {\n        if (!Number.isFinite(lat) || !Number.isFinite(lon)) return;\n        if (!this._weatherActive) {\n            this._weatherActive = true;\n            this.weatherManager.start(lat, lon);\n            return;\n        }\n        this.weatherManager.updateLocation(lat, lon);\n    }\n\n    _updateHoverTarget(lat, lon) {\n        if (!Number.isFinite(lat) || !Number.isFinite(lon)) return;\n        if (!this._hoverActive) {\n            this._hoverActive = true;\n            this.hoverWeatherManager.start(lat, lon);\n            return;\n        }\n        this.hoverWeatherManager.updateLocation(lat, lon);\n    }\n\n    _parseHudValue(el) {\n        if (!el) return null;\n        const raw = String(el.textContent || '').trim();\n        if (!raw || raw === '--') return null;\n        const parsed = Number.parseFloat(raw.replace(/[^\\d.-]/g, ''));\n        return Number.isFinite(parsed) ? parsed : null;\n    }\n\n    _formatAge(timestamp) {\n        if (!Number.isFinite(timestamp)) return '';\n        const ageMs = Date.now() - timestamp;\n        if (!Number.isFinite(ageMs) || ageMs < 0) return '';\n        const minutes = Math.round(ageMs / 60000);\n        if (minutes < 1) return 'just now';\n        if (minutes < 60) return `${minutes}m ago`;\n        const hours = Math.round(minutes / 60);\n        return `${hours}h ago`;\n    }\n\n    _formatHudWeatherSummary(data, coords) {\n        const lat = coords?.lat;\n        const lon = coords?.lon;\n        if (!Number.isFinite(lat) || !Number.isFinite(lon)) return null;\n\n        const current = data?.current || null;\n        const hasData = !!current;\n        const code = Number.isFinite(current?.weather_code) ? current.weather_code : null;\n        const desc = code != null\n            ? (this.weatherManager.getWeatherDescription(code) || 'Unknown')\n            : (hasData ? 'Unknown' : 'Loading...');\n\n        const tempVal = Number.isFinite(current?.temperature_2m) ? current.temperature_2m : null;\n        const cloudsVal = Number.isFinite(current?.cloud_cover) ? current.cloud_cover : null;\n        const humidityVal = Number.isFinite(current?.relative_humidity_2m) ? current.relative_humidity_2m : null;\n        const windVal = Number.isFinite(current?.wind_speed_10m) ? current.wind_speed_10m : null;\n        const precipVal = Number.isFinite(current?.precipitation)\n            ? current.precipitation\n            : (Number.isFinite(current?.rain) ? current.rain : null);\n        const updatedLabel = hasData ? this._formatAge(data?.lastUpdate) : '';\n\n        return {\n            coords: { lat, lon },\n            values: {\n                condition: desc,\n                temp: Number.isFinite(tempVal) ? `${Math.round(tempVal)}°C` : '--',\n                clouds: Number.isFinite(cloudsVal) ? `${Math.round(cloudsVal)}%` : '--',\n                humidity: Number.isFinite(humidityVal) ? `${Math.round(humidityVal)}%` : '--',\n                wind: Number.isFinite(windVal) ? `${Math.round(windVal)} km/h` : '--',\n                precip: Number.isFinite(precipVal) ? `${precipVal.toFixed(1)} mm` : '--',\n                updated: updatedLabel || '--'\n            },\n            data: {\n                condition: hasData ? desc : null,\n                temp: tempVal,\n                clouds: cloudsVal,\n                humidity: humidityVal,\n                wind: windVal,\n                precip: precipVal,\n                updated: Number.isFinite(data?.lastUpdate) ? data.lastUpdate : null,\n                code\n            }\n        };\n    }\n\n    _applyWeatherTexture() {\n        if (!this.atmosphereClouds) return;\n        this._syncBaseTexture();\n        if (!this._ensureWeatherCanvas()) return;\n        if (typeof this.atmosphereClouds.setLocalWeatherTexture === 'function') {\n            this.atmosphereClouds.setLocalWeatherTexture(this._weatherTexture);\n        } else if (this.atmosphereClouds.clouds) {\n            this.atmosphereClouds.clouds.localWeatherTexture = this._weatherTexture;\n        }\n        this._renderWeatherMap();\n    }\n\n    _restoreDefaultTexture() {\n        if (!this.atmosphereClouds) return;\n        if (typeof this.atmosphereClouds.restoreLocalWeatherTexture === 'function') {\n            this.atmosphereClouds.restoreLocalWeatherTexture();\n        } else if (this._defaultLocalWeatherTexture && this.atmosphereClouds.clouds) {\n            this.atmosphereClouds.clouds.localWeatherTexture = this._defaultLocalWeatherTexture;\n        }\n    }\n\n    _syncBaseTexture() {\n        if (!this.atmosphereClouds) return;\n        if (typeof this.atmosphereClouds.getDefaultLocalWeatherTexture === 'function') {\n            const candidate = this.atmosphereClouds.getDefaultLocalWeatherTexture();\n            if (candidate && candidate !== this._weatherTexture) {\n                this._defaultLocalWeatherTexture = candidate;\n            }\n        }\n        if (!this._defaultLocalWeatherTexture && this.atmosphereClouds.clouds?.localWeatherTexture) {\n            const candidate = this.atmosphereClouds.clouds.localWeatherTexture;\n            if (candidate && candidate !== this._weatherTexture) {\n                this._defaultLocalWeatherTexture = candidate;\n            }\n        }\n        const image = this._defaultLocalWeatherTexture?.image || null;\n        if (image && image !== this._baseImage) {\n            this._baseImage = image;\n            this._rebuildCanvas();\n        }\n    }\n\n    _ensureWeatherCanvas() {\n        if (typeof document === 'undefined') return false;\n        if (this._weatherCanvas && this._weatherTexture) return true;\n        const { width, height } = this._getBaseMapSize();\n        this._weatherCanvas = document.createElement('canvas');\n        this._weatherCanvas.width = width;\n        this._weatherCanvas.height = height;\n        this._weatherCtx = this._weatherCanvas.getContext('2d');\n\n        this._weatherTexture = new THREE.CanvasTexture(this._weatherCanvas);\n        this._weatherTexture.minFilter = THREE.LinearFilter;\n        this._weatherTexture.magFilter = THREE.LinearFilter;\n        this._weatherTexture.wrapS = THREE.RepeatWrapping;\n        this._weatherTexture.wrapT = THREE.RepeatWrapping;\n        this._weatherTexture.colorSpace = THREE.NoColorSpace;\n        this._weatherTexture.generateMipmaps = false;\n        this._weatherTexture.needsUpdate = true;\n        return true;\n    }\n\n    _rebuildCanvas() {\n        if (!this._weatherCanvas || !this._weatherTexture || typeof document === 'undefined') return;\n        const { width, height } = this._getBaseMapSize();\n        if (this._weatherCanvas.width === width && this._weatherCanvas.height === height) return;\n        this._weatherCanvas.width = width;\n        this._weatherCanvas.height = height;\n        this._weatherCtx = this._weatherCanvas.getContext('2d');\n        this._weatherTexture.needsUpdate = true;\n        if (this.enabled) {\n            this._applyWeatherTexture();\n        }\n    }\n\n    _getBaseMapSize() {\n        const width = Number.isFinite(this._baseImage?.width) ? this._baseImage.width : DEFAULT_MAP_WIDTH;\n        const height = Number.isFinite(this._baseImage?.height) ? this._baseImage.height : DEFAULT_MAP_HEIGHT;\n        return {\n            width: Math.max(1, Math.floor(width)),\n            height: Math.max(1, Math.floor(height))\n        };\n    }\n\n    _renderWeatherMap() {\n        if (!this._weatherCtx || !this._weatherCanvas || !this._weatherTexture) return;\n        const ctx = this._weatherCtx;\n        const width = this._weatherCanvas.width;\n        const height = this._weatherCanvas.height;\n\n        ctx.clearRect(0, 0, width, height);\n        if (this._baseImage && this._baseImage.complete && this._baseImage.width) {\n            ctx.drawImage(this._baseImage, 0, 0, width, height);\n        } else {\n            ctx.fillStyle = 'rgb(128,128,128)';\n            ctx.fillRect(0, 0, width, height);\n        }\n\n        for (const region of this._regions.values()) {\n            if (!region) continue;\n            this._drawRegion(region, width, height);\n        }\n\n        this._weatherTexture.needsUpdate = true;\n    }\n\n    _drawRegion(region, width, height) {\n        const { lat, lon, radiusKm, intensity } = region;\n        if (!Number.isFinite(lat) || !Number.isFinite(lon) || !Number.isFinite(radiusKm)) return;\n        if (!Number.isFinite(intensity) || Math.abs(intensity) <= 0) return;\n\n        const radiusDeg = (radiusKm * 1000 / PLANET_RADIUS) * (180 / Math.PI);\n        const latRad = THREE.MathUtils.degToRad(lat);\n        const cosLat = Math.max(0.2, Math.cos(latRad));\n        const lonRadiusDeg = Math.min(180, radiusDeg / cosLat);\n\n        const centerX = ((lon + 180) / 360) * width;\n        const centerY = ((90 - lat) / 180) * height;\n        const radiusX = (lonRadiusDeg / 360) * width;\n        const radiusY = (radiusDeg / 180) * height;\n\n        if (!Number.isFinite(centerX) || !Number.isFinite(centerY)) return;\n\n        const drawAt = (x) => {\n            const ctx = this._weatherCtx;\n            ctx.save();\n            ctx.translate(x, centerY);\n            ctx.scale(radiusX, radiusY);\n            const grad = ctx.createRadialGradient(0, 0, 0, 0, 0, 1);\n            const alpha = Math.min(1, Math.abs(intensity));\n            const color = intensity >= 0\n                ? `rgba(255,255,255,${alpha})`\n                : `rgba(0,0,0,${alpha})`;\n            grad.addColorStop(0, color);\n            grad.addColorStop(1, 'rgba(0,0,0,0)');\n            ctx.fillStyle = grad;\n            ctx.beginPath();\n            ctx.arc(0, 0, 1, 0, Math.PI * 2);\n            ctx.fill();\n            ctx.restore();\n        };\n\n        drawAt(centerX);\n        if (centerX - radiusX < 0) drawAt(centerX + width);\n        if (centerX + radiusX > width) drawAt(centerX - width);\n    }\n}\n","/** Collect resources owned by a model graph; avatar/atlas ownership is separate. */\nfunction collect(object3d) {\n    const geometries = new Set(), materials = new Set(), textures = new Set(), images = new Set(), skeletons = new Set();\n    object3d?.traverse?.(child => {\n        if (child.geometry) geometries.add(child.geometry);\n        if (child.skeleton) skeletons.add(child.skeleton);\n        for (const material of Array.isArray(child.material) ? child.material : [child.material]) {\n            if (!material) continue;\n            materials.add(material);\n            for (const value of Object.values(material)) if (value?.isTexture) textures.add(value);\n        }\n    });\n    for (const texture of textures) {\n        const data = texture.source?.data || texture.image;\n        for (const image of Array.isArray(data) ? data : [data]) {\n            if (typeof image?.close === 'function') images.add(image);\n        }\n    }\n    return { geometries, materials, textures, images, skeletons };\n}\n\n/** Release exclusively owned resources, optionally preserving another live root. */\nexport function disposeOwnedObject3D(object3d, { preserve = null } = {}) {\n    if (!object3d) return;\n    const owned = collect(object3d), keep = collect(preserve);\n    for (const geometry of owned.geometries) if (!keep.geometries.has(geometry)) geometry.dispose();\n    for (const texture of owned.textures) if (!keep.textures.has(texture)) texture.dispose();\n    // Texture.dispose() does not release ImageBitmap backing storage. A distinct\n    // texture may share the live root's bitmap, so image ownership is independent.\n    for (const image of owned.images) if (!keep.images.has(image)) image.close();\n    for (const material of owned.materials) if (!keep.materials.has(material)) material.dispose();\n    for (const skeleton of owned.skeletons) if (!keep.skeletons.has(skeleton)) skeleton.dispose?.();\n}\n","/** Admission shared across overlay subsystems. Count includes download+decode. */\nexport const MAX_MODEL_BYTES = 100 * 1024 * 1024;\nconst MAX_PENDING = 32;\nlet active = 0, bytes = 0;\nlet grants = 0;\nconst queue = [], listeners = new Set();\n\nexport class ModelAdmissionError extends Error {}\nexport const getModelLoadStats = () => ({ active, queued: queue.length, bytes, maxActive: 1, maxPending: MAX_PENDING, maxBytes: MAX_MODEL_BYTES });\nexport function onModelCapacityAvailable(callback) {\n    listeners.add(callback);\n    return () => listeners.delete(callback);\n}\n\nfunction nextEntryIndex() {\n    // At most 32 callbacks, only when an actual download/decode slot frees.\n    // No render-loop sorting, and a waiting job gets priority after at most\n    // 32 newer admissions so continual camera motion cannot starve it.\n    const aged = queue.findIndex(entry => grants - entry.enqueuedAt >= MAX_PENDING);\n    if (aged >= 0) return aged;\n    let selected = 0, bestPriority = Infinity, bestDistance = Infinity;\n    for (let i = 0; i < queue.length; i++) {\n        let rank;\n        try { rank = queue[i].priority?.(); } catch { /* A hint cannot prevent loading. */ }\n        const priority = Number.isFinite(rank?.priority) ? rank.priority : 1;\n        const distance = Number.isFinite(rank?.distance) ? rank.distance : Infinity;\n        if (priority < bestPriority || (priority === bestPriority && distance < bestDistance)) {\n            selected = i; bestPriority = priority; bestDistance = distance;\n        }\n    }\n    return selected;\n}\n\nfunction pump() {\n    if (active || !queue.length) return;\n    const [entry] = queue.splice(nextEntryIndex(), 1);\n    entry.signal?.removeEventListener('abort', entry.abort);\n    if (entry.signal?.aborted) { entry.reject(new DOMException('Model cancelled', 'AbortError')); pump(); return; }\n    active++; grants++;\n    let reserved = 0;\n    const reserve = amount => {\n        if (!Number.isSafeInteger(amount) || amount < 0 || bytes + amount > MAX_MODEL_BYTES) throw new RangeError('Model exceeds 100 MiB decoded resource budget');\n        reserved += amount; bytes += amount;\n    };\n    Promise.resolve().then(() => entry.run(reserve)).then(entry.resolve, entry.reject).finally(() => {\n        bytes -= reserved; active--;\n        pump();\n        for (const callback of listeners) { try { callback(); } catch {} }\n    });\n}\n\nexport function runModelLoad(run, signal, { priority } = {}) {\n    if (signal?.aborted) return Promise.reject(new DOMException('Model cancelled', 'AbortError'));\n    if (queue.length >= MAX_PENDING) return Promise.reject(new ModelAdmissionError('Model admission temporarily full'));\n    return new Promise((resolve, reject) => {\n        const entry = { run, signal, resolve, reject, priority, enqueuedAt: grants, abort: () => {\n            const index = queue.indexOf(entry);\n            if (index >= 0) queue.splice(index, 1);\n            reject(new DOMException('Model cancelled', 'AbortError'));\n        } };\n        signal?.addEventListener('abort', entry.abort, { once: true });\n        queue.push(entry); pump();\n    });\n}\n","import { getWorkerPool } from '../async/workers/WorkerPool.js';\nimport { readBoundedBytes } from './readBoundedBytes.js';\nimport { MAX_MODEL_BYTES } from './ModelLoadBudget.js';\nimport { disposeOwnedObject3D } from './disposeOwnedObject3D.js';\n\n/** Convert GLB/GLTF into an object + owned local resource URLs. Fetch referenced\n * resources lazily/serially through the same abort/byte boundary before decoding.\n * No token is inherited by an arbitrary external image/buffer URL. */\nexport async function prepareModelBundle(response, { url, signal, reserve, fetchResource }) {\n    const urls = new Set(), resolved = new Map();\n    const parentSignal = signal, controller = new AbortController(), textures = new Set();\n    const parentAbort = () => controller.abort(parentSignal.reason);\n    if (parentSignal?.aborted) parentAbort();\n    else parentSignal?.addEventListener('abort', parentAbort, { once: true });\n    signal = controller.signal;\n    let closed = false, transferred = false;\n    const releaseTextures = owned => disposeOwnedObject3D({ traverse: visit => {\n        for (const texture of owned) visit({ material: { map: texture, dispose() {} } });\n    } });\n    const dispose = () => {\n        if (closed) return;\n        closed = true; controller.abort();\n        parentSignal?.removeEventListener('abort', parentAbort);\n        for (const owned of urls) URL.revokeObjectURL(owned); urls.clear();\n        if (!transferred) releaseTextures(textures);\n        textures.clear();\n    };\n    const createUrl = blob => { const owned = URL.createObjectURL(blob); urls.add(owned); return owned; };\n    const check = () => signal?.throwIfAborted();\n    try {\n        let remaining = MAX_MODEL_BYTES;\n        const count = amount => { reserve(amount); remaining -= amount; };\n        const body = await readBoundedBytes(response, { maxBytes: remaining, signal, reserve: count });\n        check();\n        let jsonBytes = body, binary = null;\n        if (body.length >= 4 && new DataView(body.buffer, body.byteOffset, body.byteLength).getUint32(0, true) === 0x46546c67) {\n            const view = new DataView(body.buffer, body.byteOffset, body.byteLength);\n            if (body.length < 20 || view.getUint32(4, true) !== 2 || view.getUint32(8, true) !== body.length) throw new Error('Invalid GLB header');\n            jsonBytes = null;\n            for (let offset = 12; offset < body.length;) {\n                if (offset + 8 > body.length) throw new Error('Truncated GLB chunk');\n                const length = view.getUint32(offset, true), type = view.getUint32(offset + 4, true);\n                offset += 8;\n                if (offset + length > body.length) throw new Error('Truncated GLB chunk');\n                if (type === 0x4e4f534a) {\n                    if (jsonBytes) throw new Error('Duplicate GLB JSON chunk');\n                    jsonBytes = body.subarray(offset, offset + length);\n                } else if (type === 0x004e4942) {\n                    if (binary) throw new Error('Duplicate GLB BIN chunk');\n                    binary = body.subarray(offset, offset + length);\n                }\n                offset += length;\n            }\n            if (!jsonBytes) throw new Error('GLB JSON chunk missing');\n        }\n        let json;\n        if (jsonBytes.length >= 32768 && typeof Worker === 'function') {\n            const buffer = jsonBytes.slice().buffer;\n            const parsed = await getWorkerPool().run('parser-worker', 'parseJSONBuffer', { buffer, retentionCap: 1 }, { transfer: [buffer], signal });\n            if (!parsed.ok) throw new Error('Invalid model JSON');\n            json = parsed.data;\n        } else {\n            if (jsonBytes.length >= 32768 && typeof window !== 'undefined') throw new Error('Large model JSON requires a worker');\n            json = JSON.parse(new TextDecoder().decode(jsonBytes));\n        }\n        check();\n        if (!json?.asset?.version?.startsWith('2')) throw new Error('Unsupported model format');\n        // Supply the binary body as a normal URI to the documented object path\n        // in GLTFLoader.parse, avoiding a second main-thread JSON.parse.\n        if (binary && json.buffers?.[0] && !json.buffers[0].uri) {\n            json.buffers[0].uri = createUrl(new Blob([binary], { type: 'application/octet-stream' }));\n        }\n        let resourceCount = 0, tail = Promise.resolve();\n        const localize = async resource => {\n            check();\n            if (!resource?.uri || urls.has(resource.uri) || resource.uri.startsWith('data:')) return;\n            const absolute = new URL(resource.uri, url).href;\n            if (!resolved.has(absolute)) {\n                if (++resourceCount > 4096) throw new RangeError('Model resource count exceeds budget');\n                const loading = tail.then(async () => {\n                    check();\n                    if (remaining <= 0) throw new RangeError('Model resource budget exhausted');\n                    const asset = await fetchResource(absolute, signal);\n                    if (!asset.ok) throw new Error(`Model dependency failed: ${asset.status}`);\n                    const bytes = await readBoundedBytes(asset, { maxBytes: remaining, signal, reserve: count });\n                    check();\n                    return createUrl(new Blob([bytes], { type: asset.headers?.get?.('content-type') || 'application/octet-stream' }));\n                });\n                resolved.set(absolute, loading);\n                // A failed dependency prevents queued siblings from downloading.\n                tail = loading;\n            }\n            resource.uri = await resolved.get(absolute);\n        };\n        return { json, dispose, localize, transferOwnership: () => { transferred = true; textures.clear(); }, install: loader => loader.register(parser => {\n            // Version-locked Three r185 integration, covered by real GLB tests.\n            // Only resources actually requested by the parser are acquired;\n            // unused exported images/buffers must not become extra downloads.\n            const loadBuffer = parser.loadBuffer.bind(parser);\n            const loadImageSource = parser.loadImageSource.bind(parser);\n            parser.loadBuffer = async index => {\n                await localize(parser.json.buffers[index]);\n                return loadBuffer(index);\n            };\n            parser.loadImageSource = async (index, imageLoader) => {\n                await localize(parser.json.images[index]);\n                const texture = await loadImageSource(index, imageLoader);\n                if (!transferred) {\n                    if (closed) releaseTextures([texture]);\n                    else textures.add(texture);\n                }\n                return texture;\n            };\n            return { name: 'NOCLIP_bounded_resource_transport' };\n        }), resolveUrl: request => {\n            // Three creates additional blob URLs for embedded image bufferViews;\n            // these contain already-counted local bytes, not another network hop.\n            if (urls.has(request) || request.startsWith('data:') || request.startsWith('blob:')) return request;\n            throw new Error('Model attempted an undeclared resource request');\n        } };\n    } catch (error) { dispose(); throw error; }\n}\n","import { readBoundedBytes } from '../shared/readBoundedBytes.js';\nimport { jsonRetentionWeight } from '../shared/JsonRetentionWeight.js';\nimport { getWorkerPool } from '../async/workers/WorkerPool.js';\n\nexport const OVERLAY_PAGE_BYTES = 1024 * 1024;\nexport const OVERLAY_PAGE_WEIGHT = 8 * 1024 * 1024;\nconst MAX_ACTIVE = 2, MAX_WAITING = 8, MAX_PAGE_ITEMS = 128;\nconst UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\nconst TOKEN = /^op1\\.[A-Za-z0-9_-]{1062}$/;\nlet active = 0;\nconst waiting = [];\n\nexport class OverlayPageClientError extends Error {\n  constructor(code, { status = 0, retryAfterMs = 0 } = {}) {\n    super(code); this.name = 'OverlayPageClientError'; this.errorCode = code;\n    this.status = status; this.retryAfterMs = retryAfterMs;\n  }\n}\nexport const getOverlayPageStats = () => ({ active, waiting: waiting.length, maxActive: MAX_ACTIVE,\n  maxWaiting: MAX_WAITING, maxResponseBytes: OVERLAY_PAGE_BYTES, maxPageWeight: OVERLAY_PAGE_WEIGHT });\nconst invalid = () => { throw new OverlayPageClientError('INVALID_OVERLAY_PAGE'); };\nconst checkId = id => { if (typeof id !== 'string' || !UUID.test(id)) invalid(); };\nconst checkToken = token => { if (typeof token !== 'string' || !TOKEN.test(token)) invalid(); };\nconst checkAbort = signal => signal?.throwIfAborted();\n\nfunction drain() {\n  while (active < MAX_ACTIVE && waiting.length) {\n    const next = waiting.shift(); next.signal?.removeEventListener('abort', next.abort);\n    if (next.signal?.aborted) { next.reject(next.signal.reason); continue; }\n    active++; let released = false;\n    next.resolve(() => { if (!released) { released = true; active--; drain(); } });\n  }\n}\nfunction acquire(signal) {\n  checkAbort(signal);\n  if (waiting.length >= MAX_WAITING) return Promise.reject(new OverlayPageClientError('OVERLAY_PAGE_BUSY'));\n  return new Promise((resolve, reject) => {\n    const task = { resolve, reject, signal, abort: null };\n    task.abort = () => { const index = waiting.indexOf(task); if (index >= 0) waiting.splice(index, 1); reject(signal.reason); };\n    signal?.addEventListener('abort', task.abort, { once: true }); waiting.push(task); drain();\n  });\n}\nexport function waitForOverlayPage(ms, signal) {\n  checkAbort(signal);\n  return new Promise((resolve, reject) => {\n    const abort = () => { clearTimeout(timer); reject(signal.reason); };\n    const timer = setTimeout(() => { signal?.removeEventListener('abort', abort); resolve(); }, ms);\n    signal?.addEventListener('abort', abort, { once: true });\n  });\n}\nasync function parsePage(bytes) {\n  if (bytes.byteLength >= 32768 && typeof Worker !== 'undefined') {\n    // Do not reject/return the page permit early on abort: synchronous worker\n    // JSON parsing cannot process an abort message until the parse finishes.\n    const result = await getWorkerPool().run('parser-worker', 'parseJSONBuffer',\n      { buffer: bytes.buffer, retentionCap: OVERLAY_PAGE_WEIGHT, rejectOverRetentionCap: true },\n      { transfer: [bytes.buffer], timeoutMs: 15000 });\n    if (result?.errorCode === 'RETENTION_LIMIT') throw new OverlayPageClientError('OVERLAY_PAGE_MEMORY_LIMIT');\n    if (!result?.ok) invalid();\n    return result;\n  }\n  if (bytes.byteLength >= 32768 && typeof window !== 'undefined') {\n    throw new OverlayPageClientError('OVERLAY_PAGE_WORKER_REQUIRED');\n  }\n  const data = JSON.parse(new TextDecoder().decode(bytes));\n  return { data, weight: jsonRetentionWeight(data, OVERLAY_PAGE_WEIGHT) };\n}\n\n/** Account-private, no cache, one yielded page at a time. A permit spans body\n * acquisition, real parser settlement AND consumer admission of that page. */\nexport class OverlayPageClient {\n  constructor({ request, baseUrl, principal, parse = parsePage, wait = waitForOverlayPage }) {\n    this.request = request; this.baseUrl = baseUrl; this.principal = principal;\n    this.parse = parse; this.wait = wait;\n  }\n\n  async read(path, params, { signal, account, onStatus, collection = false } = {}) {\n    if (!account) throw new OverlayPageClientError('UNAUTHORIZED', { status: 401 });\n    for (let attempt = 0; ; attempt++) {\n      checkAbort(signal);\n      if (this.principal() !== account) throw new DOMException('Account changed', 'AbortError');\n      const release = await acquire(signal), controller = new AbortController();\n      const abort = () => controller.abort(signal.reason);\n      signal?.addEventListener('abort', abort, { once: true });\n      const timer = setTimeout(() => controller.abort(new DOMException('Overlay page timeout', 'TimeoutError')), 20000);\n      let yielded = false, retry = 0;\n      try {\n        checkAbort(signal);\n        if (this.principal() !== account) throw new DOMException('Account changed', 'AbortError');\n        const response = await this.request(`${this.baseUrl}${path}?${new URLSearchParams(params)}`, { signal: controller.signal });\n        const bytes = await readBoundedBytes(response, { maxBytes: OVERLAY_PAGE_BYTES, signal: controller.signal });\n        const parsed = await this.parse(bytes);\n        checkAbort(controller.signal);\n        if (this.principal() !== account) throw new DOMException('Account changed', 'AbortError');\n        if (!Number.isFinite(parsed.weight) || parsed.weight > OVERLAY_PAGE_WEIGHT) {\n          throw new OverlayPageClientError('OVERLAY_PAGE_MEMORY_LIMIT');\n        }\n        const data = parsed.data;\n        if (!response.ok) {\n          const header = response.headers?.get('retry-after');\n          const delay = header && /^\\d+$/.test(header) ? Number(header) * 1000 : Date.parse(header || '') - Date.now();\n          const retryAfterMs = Number.isFinite(delay) && delay > 0 ? delay : 1000;\n          const code = typeof data?.errorCode === 'string' && /^[A-Z0-9_]{1,80}$/.test(data.errorCode)\n            ? data.errorCode : `OVERLAY_PAGE_HTTP_${response.status}`;\n          // Respect real quota/service backoff; no tight loop and no /full fallback.\n          if ((response.status === 429 || (response.status === 503 && code === 'PAGE_BUSY'))\n            && attempt < 2 && retryAfterMs <= 60000) retry = retryAfterMs;\n          else throw new OverlayPageClientError(code, { status: response.status, retryAfterMs });\n        } else {\n          const page = collection ? data : data?.page;\n          if (data?.success !== true || !page || typeof page !== 'object') invalid();\n          yielded = true;\n          return { page, release, weight: parsed.weight };\n        }\n      } finally {\n        clearTimeout(timer); signal?.removeEventListener('abort', abort);\n        if (!yielded) release();\n      }\n      onStatus?.({ state: 'waiting', retryAfterMs: retry });\n      await this.wait(retry, signal);\n    }\n  }\n\n  async *stream(overlayId, { signal, bounds, limit = 32, onStatus, metadataOnly = false, revision: expectedRevision, cursor: manifestCursor } = {}) {\n    checkId(overlayId);\n    if (!Number.isInteger(limit) || limit < 1 || limit > MAX_PAGE_ITEMS) invalid();\n    if (bounds !== undefined && (!Array.isArray(bounds) || bounds.length !== 4 || !bounds.every(Number.isFinite)\n      || Math.abs(bounds[0]) > 180 || Math.abs(bounds[2]) > 180 || Math.abs(bounds[1]) > 90\n      || Math.abs(bounds[3]) > 90 || bounds[1] > bounds[3])) invalid();\n    const account = this.principal();\n    if (!account) throw new OverlayPageClientError('UNAUTHORIZED', { status: 401 });\n    const options = { signal, account, onStatus }, prefix = `/overlays/${overlayId}`;\n    if (expectedRevision !== undefined) checkToken(expectedRevision);\n    if (manifestCursor && !metadataOnly) invalid();\n    if (manifestCursor !== undefined && manifestCursor !== null) { checkToken(manifestCursor); checkToken(expectedRevision); }\n    let revision = expectedRevision, cursor = manifestCursor, lastLayer = '', creator;\n    do {\n      let lease = await this.read(`${prefix}/manifest`, { limit, ...(revision ? { revision } : {}), ...(cursor ? { cursor } : {}) }, options);\n      let layerIds, nextCursor;\n      try {\n        const page = lease.page; checkToken(page.revision); checkId(page.creatorUserId);\n        if (page.overlay?.overlay_id?.toLowerCase() !== overlayId.toLowerCase()\n          || (revision && page.revision !== revision) || (creator && page.creatorUserId !== creator)\n          || !Array.isArray(page.layers) || page.layers.length > limit) invalid();\n        revision = page.revision; creator = page.creatorUserId;\n        nextCursor = page.nextCursor; if (nextCursor !== null) checkToken(nextCursor);\n        if (cursor && nextCursor === cursor) invalid();\n        layerIds = page.layers.map(layer => {\n          checkId(layer?.layer_id);\n          if (layer.layer_id.toLowerCase() <= lastLayer || 'items' in layer) invalid();\n          lastLayer = layer.layer_id.toLowerCase(); return layer.layer_id;\n        });\n        yield { kind: 'manifest', page, weight: lease.weight };\n      } finally { lease.release(); lease = null; }\n      checkAbort(signal);\n      // Drain items for this manifest page before fetching more layer metadata.\n      // Only these <=128 layer IDs, not all metadata pages, remain staged here.\n      for (const layerId of metadataOnly ? [] : layerIds) {\n        let itemCursor, lastItem = '';\n        do {\n          const itemLease = await this.read(`${prefix}/layers/${layerId}/items/page`, { limit, revision,\n            ...(itemCursor ? { cursor: itemCursor } : {}), ...(bounds ? { bbox: bounds.join(',') } : {}) }, options);\n          try {\n            const page = itemLease.page;\n            if (page.overlayId?.toLowerCase() !== overlayId.toLowerCase() || page.layerId !== layerId\n              || page.revision !== revision || !Array.isArray(page.items) || page.items.length > limit) invalid();\n            if (page.nextCursor !== null) checkToken(page.nextCursor);\n            if (itemCursor && page.nextCursor === itemCursor) invalid();\n            for (const item of page.items) {\n              checkId(item?.item_id);\n              if (item.item_id.toLowerCase() <= lastItem || !item.current || typeof item.current !== 'object') invalid();\n              lastItem = item.item_id.toLowerCase();\n            }\n            itemCursor = page.nextCursor;\n            yield { kind: 'items', page, weight: itemLease.weight };\n          } finally { itemLease.release(); }\n          checkAbort(signal);\n        } while (itemCursor !== null);\n      }\n      cursor = nextCursor;\n    } while (cursor !== null);\n  }\n\n  /** A bounded UI page, not scene materialization. No content traversal or\n   * prefetch is hidden behind this call; the parser lease settles before return. */\n  async manifestPage(overlayId, options = {}) {\n    const pages = this.stream(overlayId, { ...options, metadataOnly: true });\n    try { return (await pages.next()).value; }\n    finally { await pages.return(); }\n  }\n\n  async itemPage(overlayId, layerId, { signal, revision, cursor, limit = 32, onStatus } = {}) {\n    checkId(overlayId); checkId(layerId); checkToken(revision);\n    if (cursor !== undefined && cursor !== null) checkToken(cursor);\n    if (!Number.isInteger(limit) || limit < 1 || limit > MAX_PAGE_ITEMS) invalid();\n    const lease = await this.read(`/overlays/${overlayId}/layers/${layerId}/items/page`, {\n      revision, limit, ...(cursor ? { cursor } : {}),\n    }, { signal, account: this.principal(), onStatus });\n    try {\n      const page = lease.page;\n      if (page.overlayId?.toLowerCase() !== overlayId.toLowerCase() || page.layerId !== layerId\n        || page.revision !== revision || !Array.isArray(page.items) || page.items.length > limit) invalid();\n      if (page.nextCursor !== null) checkToken(page.nextCursor);\n      if (cursor && page.nextCursor === cursor) invalid();\n      let lastItem = '';\n      for (const item of page.items) {\n        checkId(item?.item_id);\n        if (item.item_id.toLowerCase() <= lastItem || !item.current || typeof item.current !== 'object') invalid();\n        lastItem = item.item_id.toLowerCase();\n      }\n      return { kind: 'items', page, weight: lease.weight };\n    } finally { lease.release(); }\n  }\n}\n","import { OverlayPageClientError } from '../creator/OverlayPageClient.js';\n\nexport function overlayAccountId(state) {\n  if (!state?.isAuthenticated) return null;\n  return state.user?.userId || state.user?.user_id || state.user?.id || state.userId || state.session?.userId || null;\n}\n\n/** A scope contains no authored document or rendered object. Existing scene\n * entries carry its identity; one subsystem-owned auth listener retires them. */\nexport class OverlaySessionScope {\n  constructor(owner, auth) {\n    this.owner = owner; this.auth = auth; this.current = null; this.epoch = undefined;\n    this.refresh();\n    this.unsubscribe = auth.subscribe(() => this.refresh());\n  }\n\n  refresh() {\n    if (this.disposed) return;\n    const accountId = overlayAccountId(this.auth.getState()), epoch = this.auth.authEpoch;\n    if ((this.current?.accountId || null) === accountId && this.epoch === epoch) return;\n    const previous = this.current, previousController = this.controller;\n    this.epoch = epoch; this.controller = accountId ? new AbortController() : null;\n    this.current = accountId ? Object.freeze({ accountId, epoch, signal: this.controller.signal }) : null;\n    previousController?.abort(new DOMException('Overlay account changed', 'AbortError'));\n    if (!previous) return;\n    this.owner.endPlacementReview?.();\n    for (const [id, entry] of this.owner.overlays) {\n      if (entry.sessionScope !== previous) continue;\n      // A new same-ID load may already be waiting for the old scene to retire.\n      const job = this.owner._pageLoads?.get(id), build = this.owner._overlayBuilds?.get(id);\n      Promise.resolve(this.owner.unload(id, {\n        keepLoad: job?.sessionScope !== previous ? job : undefined,\n        keepBuild: build?.sessionScope !== previous ? build : undefined,\n      })).catch(error => this.owner.eventBus?.emit('overlay:error', { overlayId: id, error }));\n    }\n  }\n\n  capture({ required = false } = {}) {\n    this.refresh();\n    if (this.disposed) throw new DOMException('Disposed', 'AbortError');\n    if (required && !this.current) throw new OverlayPageClientError('UNAUTHORIZED', { status: 401 });\n    return this.current;\n  }\n\n  assert(scope) {\n    this.refresh();\n    scope?.signal.throwIfAborted();\n    if (this.disposed || (scope && scope !== this.current)) throw new DOMException('Overlay account changed', 'AbortError');\n  }\n\n  dispose() {\n    this.disposed = true; this.unsubscribe?.(); this.unsubscribe = null;\n    this.controller?.abort(new DOMException('Disposed', 'AbortError'));\n    this.current = null; this.controller = null;\n  }\n}\n\nexport function bindOverlaySession(scope, controller) {\n  if (!scope) return () => {};\n  const abort = () => controller.abort(scope.signal.reason);\n  scope.signal.addEventListener('abort', abort, { once: true });\n  if (scope.signal.aborted) abort();\n  return () => scope.signal.removeEventListener('abort', abort);\n}\n","import { Frustum, Matrix4, Vector3 } from 'three';\nimport { yieldToEventLoop } from '../async/scheduler/BudgetScheduler.js';\n\nexport const OVERLAY_ADMISSION_WINDOW = 128;\nexport const OVERLAY_ADMISSION_SLICE = 16;\n\n/** Anchor priority is deliberately NOT a visibility/culling test. A model,\n * spline, elevated object or custom renderer can extend beyond its anchor.\n * Unknown anchors remain eligible; every input is eventually admitted. */\nexport class OverlayAdmissionPlanner {\n  constructor(owner) {\n    this.owner = owner;\n    this.frustum = new Frustum(); this.projection = new Matrix4();\n    this.nextProjection = new Matrix4(); this.nextParent = new Matrix4();\n    this.parent = new Matrix4(); this.eye = new Vector3(); this.point = new Vector3();\n    this.active = false; this.version = 0;\n  }\n\n  refresh() {\n    const camera = this.owner.camera, parent = this.owner.parentGroup || this.owner.scene;\n    if (!camera?.isCamera) {\n      if (this.active) this.version++;\n      this.active = false; return;\n    }\n    // Update ancestors only, never recursively update an entire scene here.\n    camera.updateWorldMatrix(true, false); parent?.updateWorldMatrix?.(true, false);\n    this.nextProjection.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse);\n    if (parent?.matrixWorld) this.nextParent.copy(parent.matrixWorld);\n    else this.nextParent.identity();\n    if (!this.nextProjection.elements.every(Number.isFinite) || !this.nextParent.elements.every(Number.isFinite)) {\n      if (this.active) this.version++;\n      this.active = false; return;\n    }\n    if (this.active && this.projection.equals(this.nextProjection) && this.parent.equals(this.nextParent)\n      && this.coordinateSystem === camera.coordinateSystem && this.reversedDepth === camera.reversedDepth) return;\n    this.projection.copy(this.nextProjection); this.parent.copy(this.nextParent); this.version++;\n    this.coordinateSystem = camera.coordinateSystem; this.reversedDepth = camera.reversedDepth;\n    this.frustum.setFromProjectionMatrix(this.projection, this.coordinateSystem, this.reversedDepth);\n    this.eye.setFromMatrixPosition(camera.matrixWorld);\n    this.active = true;\n  }\n\n  rank(record) {\n    if (record.viewVersion === this.version) return;\n    record.viewVersion = this.version;\n    record.priority = 1; record.distance = Infinity;\n    if (!this.active) return;\n    const item = record.item, current = item?.current;\n    const coordinates = current?.geom?.type === 'Point' ? current.geom.coordinates : null;\n    const position = current?.position;\n    if (coordinates) {\n      if (!Array.isArray(coordinates) || !Number.isFinite(coordinates[0]) || !Number.isFinite(coordinates[1])\n        || Math.abs(coordinates[0]) > 180 || Math.abs(coordinates[1]) > 90) return;\n    } else if (!position || ![position.x, position.y, position.z].every(Number.isFinite)) return;\n    // Existing fast placement is only an ordering hint. In particular it does\n    // not raycast terrain or inspect/download geometry to find a model extent.\n    const anchor = this.owner._resolveItemPositionFast?.(item, this.point);\n    if (!anchor || ![anchor.x, anchor.y, anchor.z].every(Number.isFinite)) return;\n    this.point.copy(anchor).applyMatrix4(this.parent);\n    record.priority = this.frustum.containsPoint(this.point) ? 0 : 2;\n    record.distance = this.eye.distanceToSquared(this.point);\n  }\n}\n\n/** Bounded lookahead, not a whole-document sort or a persistent frame loop.\n * Re-rank the remaining window after each real task yield, so a camera turn\n * can prioritize waiting work without cancelling/re-fetching the same page.\n * Source arrays/order are untouched (editor order and cursor order are data).\n * One renderer call cannot be preempted; between calls we yield at 16 ops/2ms. */\nexport async function forOverlayAdmission(owner, values, apply, signal) {\n  const planner = new OverlayAdmissionPlanner(owner), window = [];\n  const iterator = values[Symbol.iterator]();\n  const stats = { admitted: 0, peakQueued: 0, slices: 0 };\n  let index = 0, exhausted = false, rankedVersion = -1;\n  try {\n    while (!exhausted || window.length) {\n      signal?.throwIfAborted();\n      const started = performance.now(); let operations = 0;\n      // Fill a fixed lookahead window once; do not refill it between slices,\n      // which could starve an older off-screen item indefinitely during motion.\n      if (!window.length) {\n        rankedVersion = -1;\n        while (window.length < OVERLAY_ADMISSION_WINDOW && !exhausted) {\n          signal?.throwIfAborted();\n          const next = iterator.next(); exhausted = !!next.done;\n          if (!exhausted) window.push({ item: next.value, index: index++ });\n        }\n        stats.peakQueued = Math.max(stats.peakQueued, window.length);\n      }\n      if (!window.length) break;\n      planner.refresh();\n      if (rankedVersion !== planner.version) {\n        for (const record of window) planner.rank(record);\n        window.sort((a, b) => a.priority - b.priority || a.distance - b.distance || a.index - b.index);\n        rankedVersion = planner.version;\n      }\n      do {\n        signal?.throwIfAborted();\n        const record = window.shift();\n        apply(record.item); stats.admitted++; operations++;\n      } while (window.length && operations < OVERLAY_ADMISSION_SLICE && performance.now() - started < 2);\n      if (window.length || !exhausted) {\n        stats.slices++; await yieldToEventLoop(); signal?.throwIfAborted();\n      }\n    }\n    return stats;\n  } finally {\n    window.length = 0;\n    // Generator sources can own a resource; cancel/failure must close them.\n    iterator.return?.();\n  }\n}\n","import { yieldToEventLoop } from '../async/scheduler/BudgetScheduler.js';\nimport { OverlayPageClientError } from '../creator/OverlayPageClient.js';\nimport { bindOverlaySession } from './OverlaySessionScope.js';\nimport { forOverlayAdmission } from './OverlayAdmissionPlanner.js';\n\nexport const OVERLAY_DOCUMENT_WEIGHT = 32 * 1024 * 1024;\n\n/** Count AND time bounded; a cheap fixture cannot hide an unbounded microtask loop. */\nexport async function forOverlaySlice(values, apply, signal) {\n  let count = 0, start = performance.now();\n  for (const value of values) {\n    signal?.throwIfAborted();\n    apply(value);\n    if (++count >= 16 || performance.now() - start >= 2) {\n      await yieldToEventLoop(); signal?.throwIfAborted(); count = 0; start = performance.now();\n    }\n  }\n}\n\n/** Async rule evaluation must yield a task too: resolved promises alone do not\n * give rendering/input a turn. One individual rule/render operation is not preempted. */\nexport async function forOverlayAsyncSlice(values, apply, isCurrent, budget = { count: 0, start: performance.now() }) {\n  for (const value of values) {\n    if (!isCurrent()) return;\n    await apply(value);\n    if (!isCurrent()) return;\n    if (++budget.count >= 16 || performance.now() - budget.start >= 2) {\n      await yieldToEventLoop(); budget.count = 0; budget.start = performance.now();\n    }\n  }\n}\n\n/** First loads admit pages immediately. Refreshes keep the last complete scene\n * while bounded replacement data is collected, then use the same sliced build.\n * A partial traversal is never represented as a complete authored document. */\nexport async function ingestOverlayPages(owner, overlayId, source, options = {}) {\n  const sessionScope = owner._session?.capture({ required: true });\n  owner._pageLoads ||= new Map();\n  owner._pageLoads.get(overlayId)?.controller.abort(new DOMException('Replaced', 'AbortError'));\n  const controller = new AbortController();\n  const releaseSession = bindOverlaySession(sessionScope, controller);\n  let previous = owner.overlays.get(overlayId);\n  const job = { controller, bounds: options.bounds, entry: null, sessionScope };\n  owner._pageLoads.set(overlayId, job);\n  const abort = () => controller.abort(options.signal.reason);\n  options.signal?.addEventListener('abort', abort, { once: true });\n  if (options.signal?.aborted) abort();\n  let doc, weight = 0, itemCount = 0, layerCount = 0;\n  const layers = new Map();\n  const current = () => {\n    owner._session?.assert(sessionScope);\n    controller.signal.throwIfAborted();\n    if (owner._disposed || owner._pageLoads.get(overlayId) !== job) throw new DOMException('Replaced', 'AbortError');\n  };\n  const status = (state, extra = {}) => {\n    const event = { overlayId, state, loadedItems: itemCount, loadedLayers: layerCount, ...extra };\n    owner.eventBus?.emit('overlay:progress', event); options.onProgress?.({ ...event, entry: doc });\n  };\n  try {\n    current(); status('loading');\n    // An abandoned first traversal is not a valid refresh baseline. Detach it\n    // before the replacement can admit rows with the same trigger/item IDs.\n    if (previous?.doc?.partial) {\n      await owner.unload(overlayId, { keepLoad: job }); current(); previous = null;\n    }\n    for await (const chunk of source({ signal: controller.signal, onStatus: info => status(info.state, info) })) {\n      current(); weight += chunk.weight;\n      if (!Number.isFinite(weight) || weight > OVERLAY_DOCUMENT_WEIGHT) throw new OverlayPageClientError('OVERLAY_DOCUMENT_MEMORY_LIMIT');\n      if (chunk.kind === 'manifest') {\n        if (!doc) {\n          doc = { overlay: chunk.page.overlay, creatorUserId: chunk.page.creatorUserId, layers: [], partial: true,\n            loadingState: 'loading', revision: chunk.page.revision };\n          options.prepareEntry?.(doc);\n          doc.partial = true; doc.loadingState = 'loading';\n          if (!previous) {\n            const result = await owner.load(doc, { signal: controller.signal, _pageJob: job, partial: true });\n            current();\n            if (result?.blocked) throw new OverlayPageClientError('FORBIDDEN', { status: 403 });\n            job.entry = owner.overlays.get(overlayId);\n          }\n        }\n        await forOverlaySlice(chunk.page.layers, layer => {\n          if (layers.has(layer.layer_id)) throw new OverlayPageClientError('INVALID_OVERLAY_PAGE');\n          const target = { ...layer, items: [] };\n          if (!target.visibility && target.style_json?.visibility) target.visibility = target.style_json.visibility;\n          layers.set(layer.layer_id, target); doc.layers.push(target); layerCount++;\n          if (job.entry) owner._appendPageLayer(job.entry, target);\n        }, controller.signal);\n      } else if (chunk.kind === 'items') {\n        const layer = layers.get(chunk.page.layerId);\n        if (!layer || chunk.page.revision !== doc.revision) throw new OverlayPageClientError('INVALID_OVERLAY_PAGE');\n        owner._bulkBuildDepth = (owner._bulkBuildDepth || 0) + 1;\n        try {\n          // Keep authored/cursor order independent of camera-based creation.\n          await forOverlaySlice(chunk.page.items, item => {\n            current(); layer.items.push(item);\n          }, controller.signal);\n          if (job.entry) {\n            await forOverlayAdmission(owner, chunk.page.items, item => {\n              current(); itemCount++;\n              owner._addItem(job.entry, layer.layer_id, item);\n            }, controller.signal);\n          } else itemCount += chunk.page.items.length; // Refresh ranks once, during its replacement build.\n        } finally { owner._bulkBuildDepth--; }\n        owner._requestGeoRefresh();\n      } else throw new OverlayPageClientError('INVALID_OVERLAY_PAGE');\n      current(); status('loading');\n      // Even a run of tiny/empty permitted pages gives input/render a macrotask.\n      await yieldToEventLoop();\n    }\n    current(); if (!doc) throw new OverlayPageClientError('INVALID_OVERLAY_PAGE');\n    if (previous) {\n      const result = await owner.load(doc, { signal: controller.signal, _pageJob: job, partial: true });\n      current(); if (result?.blocked) throw new OverlayPageClientError('FORBIDDEN', { status: 403 });\n      job.entry = owner.overlays.get(overlayId);\n    }\n    doc.partial = false; doc.loadingState = 'complete'; status('complete');\n    owner.eventBus?.emit('overlay:loaded', { overlayId });\n    return { overlayId, group: job.entry?.group, entry: doc, complete: true };\n  } catch (error) {\n    const owns = owner._pageLoads.get(overlayId) === job;\n    if (owns) {\n      if (doc) { doc.partial = true; doc.loadingState = controller.signal.aborted ? 'paused' : 'error'; }\n      if (error.status === 401 || error.status === 403) await owner.unload(overlayId, { keepLoad: job });\n      else if (!previous && job.entry && owner.overlays.get(overlayId) === job.entry) await owner.unload(overlayId, { keepLoad: job });\n      status(controller.signal.aborted ? 'paused' : 'error', { errorCode: error.errorCode || error.name });\n    }\n    throw error;\n  } finally {\n    releaseSession();\n    options.signal?.removeEventListener('abort', abort);\n    if (owner._pageLoads.get(overlayId) === job) owner._pageLoads.delete(overlayId);\n  }\n}\n","/**\n * Compatibility contract for reconstruction assets that predate the LingBot\n * capture publication schema. DA3 exports are GLB files (often point-cloud\n * primitives) and some older overlay rows retained only their item/file link\n * or an early output URL property spelling.\n */\n\nexport const DEFAULT_DA3_ANCHOR_AGL_M = 1.6;\n\nconst MODEL_FILE_ROLES = new Set([\n  'model',\n  'primary',\n  'pointcloud',\n  'point_cloud',\n  'reconstruction',\n]);\n\nconst firstString = (...values) => {\n  for (const value of values) {\n    if (typeof value === 'string' && value.trim()) return value.trim();\n  }\n  return '';\n};\n\nexport function isDa3ScanItem(item) {\n  if (item?.item_type && item.item_type !== 'model3d') return false;\n  const props = item?.current?.properties || {};\n  const source = String(props.source || props.pipeline || '').trim().toLowerCase();\n  if (source === 'lingbot-map' || props.capture_session_id) return false;\n  return source === 'da3'\n    || source === 'depth-anything-3'\n    || source === 'depth_anything_3'\n    || !!props.da3_job_id\n    || !!props.job_id\n    || !!props.scan_id;\n}\n\nexport function resolveDa3HeightMode(item) {\n  if (!isDa3ScanItem(item)) return null;\n  const props = item?.current?.properties || {};\n  if (props.height_authority === 'capture-placement') return 'absolute';\n  const raw = firstString(\n    props.height_reference,\n    props.da3_height_mode,\n    props.altitude_mode,\n  ).toLowerCase();\n  if (['absolute', 'absolute_ellipsoid', 'absolute_asl', 'ellipsoid', 'gps'].includes(raw)) {\n    return 'absolute';\n  }\n  return 'surface_agl';\n}\n\nexport function resolveDa3AnchorAglM(item) {\n  const props = item?.current?.properties || {};\n  for (const candidate of [\n    props.anchor_agl_m,\n    props.agl_m,\n    props.ground_offset_m,\n    props.offset_m,\n  ]) {\n    const value = Number(candidate);\n    if (candidate !== null && candidate !== undefined && Number.isFinite(value)) return value;\n  }\n  return DEFAULT_DA3_ANCHOR_AGL_M;\n}\n\nexport function resolveItemModelUrl(item) {\n  const props = item?.current?.properties || {};\n  const propertyUrl = firstString(\n    props.model_url,\n    props.model_path,\n    props.modelUrl,\n    props.pointcloud_url,\n    props.point_cloud_url,\n    props.pointCloudUrl,\n    props.output_url,\n    props.outputUrl,\n  );\n  if (propertyUrl) return propertyUrl;\n\n  const links = Array.isArray(item?.files) ? item.files : [];\n  const linked = links.find((entry) => MODEL_FILE_ROLES.has(String(entry?.role || '').toLowerCase()))\n    || links.find((entry) => {\n      const mime = String(entry?.file?.mime_type || entry?.mime_type || '').toLowerCase();\n      return mime === 'model/gltf-binary' || mime === 'model/gltf+json';\n    });\n  const fileId = firstString(linked?.file_id, linked?.file?.file_id);\n  if (fileId) return `/api/files/${encodeURIComponent(fileId)}/download`;\n\n  const outputFileId = firstString(props.output_file_id, props.outputFileId);\n  return outputFileId ? `/api/files/${encodeURIComponent(outputFileId)}/download` : '';\n}\n","/**\n * Pure runtime contract for surface-relative overlay anchors.\n *\n * Persisted overlay documents describe intent (follow or an explicit pin).\n * This module describes what the renderer actually knows right now. Keeping\n * those two concerns separate prevents a provisional GPS/ellipsoid fallback\n * from being mislabeled or persisted as a verified photoreal surface sample.\n */\n\nexport const SURFACE_ANCHOR_STATE = Object.freeze({\n  ABSOLUTE: 'absolute',\n  PENDING: 'pending',\n  MATED: 'mated',\n  HELD: 'held',\n  PINNED: 'pinned',\n  UNAVAILABLE: 'unavailable',\n});\n\nexport const SURFACE_ANCHOR_POLICY = Object.freeze({\n  FOLLOW: 'follow-surface',\n  PIN: 'pin-resolved-surface',\n});\n\nconst VERIFIED_STATES = new Set([\n  SURFACE_ANCHOR_STATE.MATED,\n  SURFACE_ANCHOR_STATE.HELD,\n  SURFACE_ANCHOR_STATE.PINNED,\n]);\n\nexport function normalizeSurfaceAnchorPolicy(value) {\n  return value === SURFACE_ANCHOR_POLICY.PIN\n    ? SURFACE_ANCHOR_POLICY.PIN\n    : SURFACE_ANCHOR_POLICY.FOLLOW;\n}\n\nexport function normalizeSurfaceAnchorSnapshot(value) {\n  if (!value || typeof value !== 'object') return null;\n  const radiusM = Number(value.radius_m);\n  const provider = typeof value.provider === 'string' ? value.provider.trim() : '';\n  const sampledAt = typeof value.sampled_at === 'string' ? value.sampled_at.trim() : '';\n  const sampledTime = Date.parse(sampledAt);\n  if (!Number.isFinite(radiusM) || radiusM <= 0 || !provider\n    || !sampledAt || !Number.isFinite(sampledTime)) return null;\n  const terrainRevision = typeof value.terrain_revision === 'string'\n    && value.terrain_revision.trim()\n    ? value.terrain_revision.trim()\n    : null;\n  return {\n    radiusM,\n    provider,\n    terrainRevision,\n    sampledAt,\n  };\n}\n\nexport function isVerifiedSurfaceAnchor(value) {\n  return !!value\n    && VERIFIED_STATES.has(value.state)\n    && Number.isFinite(value.surfaceRadiusM);\n}\n\nexport function resolveSurfaceAnchorState({\n  requiresSurface = true,\n  policy = SURFACE_ANCHOR_POLICY.FOLLOW,\n  snapshot = null,\n  sampledRadiusM = null,\n  previous = null,\n  fallbackRadiusM = null,\n  fallbackKind = null,\n  providerAvailable = true,\n  provider = 'photoreal',\n  terrainRevision = null,\n  aglM = 0,\n  sampleSequence = null,\n  reason = 'resolve',\n  authoredVersion = null,\n  attemptedAt = null,\n} = {}) {\n  const resolvedPolicy = normalizeSurfaceAnchorPolicy(policy);\n  const resolvedAglM = Number.isFinite(Number(aglM)) ? Number(aglM) : 0;\n  const attemptedAtValue = attemptedAt || new Date().toISOString();\n  const base = {\n    state: SURFACE_ANCHOR_STATE.PENDING,\n    policy: resolvedPolicy,\n    surfaceRadiusM: null,\n    displayRadiusM: Number.isFinite(fallbackRadiusM)\n      ? fallbackRadiusM + resolvedAglM\n      : null,\n    aglM: resolvedAglM,\n    fallbackKind: fallbackKind || null,\n    authoritative: false,\n    provider: null,\n    terrainRevision: null,\n    sampledAt: null,\n    sampleSequence: Number.isFinite(sampleSequence) ? sampleSequence : null,\n    attemptSequence: Number.isFinite(sampleSequence) ? sampleSequence : null,\n    lastAttemptAt: attemptedAtValue,\n    lastAttemptReason: reason,\n    authoredVersion: authoredVersion ?? null,\n  };\n\n  if (!requiresSurface) {\n    return {\n      ...base,\n      state: SURFACE_ANCHOR_STATE.ABSOLUTE,\n      aglM: 0,\n      displayRadiusM: Number.isFinite(fallbackRadiusM) ? fallbackRadiusM : null,\n      fallbackKind: null,\n      authoritative: true,\n    };\n  }\n\n  const pinned = resolvedPolicy === SURFACE_ANCHOR_POLICY.PIN\n    ? normalizeSurfaceAnchorSnapshot(snapshot)\n    : null;\n  if (pinned) {\n    return {\n      ...base,\n      state: SURFACE_ANCHOR_STATE.PINNED,\n      surfaceRadiusM: pinned.radiusM,\n      displayRadiusM: pinned.radiusM + resolvedAglM,\n      fallbackKind: null,\n      authoritative: true,\n      provider: pinned.provider,\n      terrainRevision: pinned.terrainRevision,\n      sampledAt: pinned.sampledAt,\n    };\n  }\n\n  if (Number.isFinite(sampledRadiusM)) {\n    return {\n      ...base,\n      state: SURFACE_ANCHOR_STATE.MATED,\n      surfaceRadiusM: sampledRadiusM,\n      displayRadiusM: sampledRadiusM + resolvedAglM,\n      fallbackKind: null,\n      authoritative: true,\n      provider: provider || 'photoreal',\n      terrainRevision: terrainRevision || null,\n      sampledAt: attemptedAtValue,\n    };\n  }\n\n  if (isVerifiedSurfaceAnchor(previous)) {\n    return {\n      ...base,\n      state: SURFACE_ANCHOR_STATE.HELD,\n      surfaceRadiusM: previous.surfaceRadiusM,\n      displayRadiusM: previous.surfaceRadiusM + resolvedAglM,\n      fallbackKind: null,\n      authoritative: true,\n      provider: previous.provider || null,\n      terrainRevision: previous.terrainRevision || null,\n      sampledAt: previous.sampledAt || null,\n      sampleSequence: previous.sampleSequence ?? base.sampleSequence,\n    };\n  }\n\n  return {\n    ...base,\n    state: providerAvailable\n      ? SURFACE_ANCHOR_STATE.PENDING\n      : SURFACE_ANCHOR_STATE.UNAVAILABLE,\n  };\n}\n","/**\n * OverlaySubsystem\n *\n * Purpose:\n * - Loads overlay documents, manages layer and item lifecycles, and applies\n *   policy decisions to interactions.\n * - Ensures overlay failures do not break base rendering.\n *\n * API intention:\n * - load(overlayDoc, opts), unload(overlayId), update(overlayId, patch)\n * - get(overlayId)\n *\n * Relationships:\n * - Uses OverlayRegistry for renderer selection per layer/item type.\n * - Uses AssetSubsystem for file resolution and caching.\n * - Uses AccessController for policy enforcement.\n * - Renders into scene and emits events via EventBus.\n */\nimport * as THREE from 'three';\nimport { disposeOwnedObject3D } from '../shared/disposeOwnedObject3D.js';\nimport { getModelLoadStats, ModelAdmissionError, onModelCapacityAvailable, runModelLoad } from '../shared/ModelLoadBudget.js';\nimport { prepareModelBundle } from '../shared/ModelResourceBundle.js';\nimport { preparePhotorealAssetLighting } from '../render/PhotorealAssetLighting.js';\nimport { readBoundedBytes } from '../shared/readBoundedBytes.js';\nimport { getNoclipGovernanceClient } from '../shared/NoclipGovernanceClient.js';\nimport { yieldToEventLoop } from '../async/scheduler/BudgetScheduler.js';\nimport { forOverlayAsyncSlice, ingestOverlayPages } from './OverlayPageIngestor.js';\nimport { OverlaySessionScope, bindOverlaySession } from './OverlaySessionScope.js';\nimport { forOverlayAdmission, OverlayAdmissionPlanner } from './OverlayAdmissionPlanner.js';\nimport { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';\nimport { latLonToLocalDir, ellipsoidRadiusForLocalDir } from '../../modules/geometry-utils.js';\nimport { PLANET_RADIUS } from '../../modules/constants.js';\nimport { GeoBoundaryService } from '../geo/GeoBoundaryService.js';\nimport { getAuthService } from '../auth/AuthService.js';\nimport { terrainSurfaceChangesAffectLatLon } from '../scene/TerrainSurfaceChange.js';\nimport { getTransportManager, TransportEvent } from '../transport/index.js';\nimport { resolveBackendApiUrl } from '../shared/backend.js';\nimport { getLabelSystem } from '../labels/LabelSystem.js';\nimport {\n    isDa3ScanItem,\n    resolveDa3AnchorAglM,\n    resolveDa3HeightMode,\n    resolveItemModelUrl,\n} from './ScanAssetCompatibility.js';\nimport {\n    SURFACE_ANCHOR_STATE,\n    normalizeSurfaceAnchorPolicy,\n    normalizeSurfaceAnchorSnapshot,\n    resolveSurfaceAnchorState,\n} from './SurfaceAnchorState.js';\n\nconst MISSING_MODEL_RETRY_MS = 5 * 60 * 1000;\n\nexport class OverlaySubsystem {\n    constructor({ scene, parentGroup, registry, assets, access, eventBus, planetRadius, splineSubsystem, sceneInitializer, proximityTriggerManager, physicsSystem, clickTriggerManager, triTree, camera, surfaceController, authService, debugLogs = false } = {}) {\n        this.scene = scene || null;\n        this.parentGroup = parentGroup || null;\n        this.camera = camera || null;\n        this.registry = registry || null;\n        this.assets = assets || null;\n        this.access = access || null;\n        this.eventBus = eventBus || null;\n        this.splineSubsystem = splineSubsystem || null;\n        this.sceneInitializer = sceneInitializer || null;\n        this.proximityTriggerManager = proximityTriggerManager || null;\n        this.physicsSystem = physicsSystem || null;\n        this.clickTriggerManager = clickTriggerManager || null;\n        this.triTree = triTree || null;\n        this.surfaceController = surfaceController || null;\n        this.planetRadius = Number.isFinite(planetRadius) ? planetRadius : PLANET_RADIUS;\n        this.debugLogs = !!debugLogs;\n\n        this.overlays = new Map();\n        this._authService = authService || getAuthService();\n        this._session = new OverlaySessionScope(this, this._authService);\n        this._gltfLoader = new GLTFLoader();\n        this._pointRadius = this.planetRadius * 0.001;\n        this._defaultOffsetM = 0;\n        this._geoBoundaryService = new GeoBoundaryService();\n        this._geoContext = null;\n        this._geoEvalSeq = 0;\n        this._geoRefreshPending = false;\n        this._proximityItems = new Map();\n        this._proximityObserver = new THREE.Vector3();\n        this._proximityHasObserver = false;\n        this._proximityGlobalIntervalMs = 200;\n        this._lastProximityUpdate = 0;\n        this._proximityTmpVec = new THREE.Vector3();\n        this._proximityTmpVec2 = new THREE.Vector3();\n        this._hoveredItem = null;\n        // Missing account assets can be referenced by several rebuilt item\n        // groups. Keep a short subsystem-wide negative cache so one stale\n        // file id cannot issue a new authenticated request every geo refresh.\n        this._unavailableModelUrls = new Map();\n        this._modelCapacityUnsubscribe = onModelCapacityAvailable(() => this._retryDeferredModelLoads());\n        this._cameraExclusiveState = null;\n        this._placementReviewPreview = null;\n        this._surfaceAnchorRetries = new Map();\n        this._surfaceAnchorGeneration = 0;\n        this._surfaceAnchorRetryTask = null;\n        this._queuedSurfaceAnchorRetry = null;\n        this._lastSurfaceAnchorWakeKey = null;\n\n        // Real-time sync: track subscriptions per overlay\n        this._overlaySubscriptions = new Map();\n        this._changeSubscription = null;\n        this._livePositionSubscription = null;\n        this._hydraIngressSubscription = null;\n        this._hydraIngressLegacySubscription = null;\n        this._hydraIngress = null;\n        this._initTransportSubscriptions();\n    }\n\n    _logDebug(...args) {\n        if (!this.debugLogs) return;\n        console.log(...args);\n    }\n\n    /** Stop overlay paging/building/model decode before phone camera ownership. */\n    async beginCameraExclusiveMode({ timeoutMs = 3000 } = {}) {\n        if (this._cameraExclusiveState) return this._cameraExclusiveState.ready;\n        const state = {\n            startedAt: performance.now(),\n            cancelledPageLoads: 0,\n            cancelledBuilds: 0,\n            cancelledModelLoads: 0,\n            deferredChanges: new Map(),\n            ready: null,\n        };\n        this._cameraExclusiveState = state;\n\n        for (const job of this._pageLoads?.values() || []) {\n            if (!job?.controller?.signal?.aborted) {\n                job.controller.abort(new DOMException('Camera exclusive mode', 'AbortError'));\n                state.cancelledPageLoads += 1;\n            }\n        }\n        for (const build of this._overlayBuilds?.values() || []) {\n            if (!build?.signal?.aborted) {\n                build.abort(new DOMException('Camera exclusive mode', 'AbortError'));\n                state.cancelledBuilds += 1;\n            }\n        }\n        for (const entry of this.overlays.values()) {\n            for (const record of entry.items.values()) {\n                const group = record.object3d?.userData?.modelContainer || record.object3d;\n                if (!group?.userData?.modelLoading) continue;\n                const wantedItem = group.userData.modelLoadItem || record.runtime?.effectiveItem || record.data;\n                this._invalidateModelLoad(group);\n                group.userData.modelLoadWanted = true;\n                group.userData.modelLoadItem = wantedItem;\n                group.userData.modelDeferred = true;\n                state.cancelledModelLoads += 1;\n            }\n        }\n\n        state.ready = (async () => {\n            const deadline = performance.now() + timeoutMs;\n            while (performance.now() < deadline) {\n                const modelStats = getModelLoadStats();\n                const builds = this._overlayBuilds?.size || 0;\n                const pages = this._pageLoads?.size || 0;\n                if (modelStats.active === 0 && modelStats.queued === 0 && builds === 0 && pages === 0) {\n                    state.durationMs = Math.max(0, Math.round(performance.now() - state.startedAt));\n                    state.modelDecoderIdle = true;\n                    return state;\n                }\n                await new Promise((resolve) => setTimeout(resolve, 16));\n            }\n            const modelStats = getModelLoadStats();\n            state.modelDecoderIdle = modelStats.active === 0 && modelStats.queued === 0;\n            state.pendingBuilds = this._overlayBuilds?.size || 0;\n            state.pendingPages = this._pageLoads?.size || 0;\n            throw new Error('Overlay paging, build, or model decode did not settle before camera handoff');\n        })();\n        return state.ready;\n    }\n\n    resumeAfterCameraExclusiveMode(state = this._cameraExclusiveState) {\n        if (!state || state !== this._cameraExclusiveState) return false;\n        this._cameraExclusiveState = null;\n        const changes = [...state.deferredChanges.values()];\n        state.deferredChanges.clear();\n        queueMicrotask(() => {\n            if (this._disposed || this._cameraExclusiveState) return;\n            for (const change of changes) this._handleOverlayChange(change);\n            void this._retryDeferredModelLoads();\n        });\n        return true;\n    }\n\n    /**\n     * Initialize transport subscriptions for real-time overlay changes\n     * Deferred until transport is connected\n     */\n    _initTransportSubscriptions() {\n        const scheduleRetry = (delayMs) => {\n            if (this._disposed) return;\n            if (this._transportInitTimer) {\n                clearTimeout(this._transportInitTimer);\n            }\n            this._transportInitTimer = setTimeout(() => {\n                this._transportInitTimer = null;\n                tryInit();\n            }, delayMs);\n        };\n\n        // Defer initialization - transport may not be ready yet\n        const tryInit = () => {\n            if (this._disposed) return;\n            let transport;\n            try {\n                transport = getTransportManager();\n            } catch (e) {\n                // Transport manager not available yet, retry later\n                scheduleRetry(2000);\n                return;\n            }\n\n            // Check if transport is initialized and connected\n            if (!transport || !transport.active || !transport.isConnected) {\n                // Retry after a short delay if not ready\n                scheduleRetry(1000);\n                return;\n            }\n\n            if (this._changeSubscription || this._livePositionSubscription) {\n                return;\n            }\n\n            try {\n                // Subscribe to overlay change events\n                this._changeSubscription = transport.subscribe(TransportEvent.OVERLAY_CHANGE, (message) => {\n                    this._handleOverlayChange(message?.payload);\n                });\n\n                // Subscribe to live position updates (during drag/placement)\n                this._livePositionSubscription = transport.subscribe('overlay.livePosition', (message) => {\n                    this._handleLivePositionUpdate(message?.payload);\n                });\n\n                // Subscribe to interop envelope ingress used for Hydra bridge packets\n                this._hydraIngressSubscription = transport.subscribe('interop.bridge.message', (message) => {\n                    const envelope = message?.payload || message || null;\n                    if (!envelope) return;\n                    this.eventBus?.emit?.('hydra:overlay:ingress', {\n                        envelope,\n                        meta: {\n                            source: 'transport',\n                            sourceAddress: envelope?.source_address || envelope?.sourceAddress || ''\n                        }\n                    });\n                });\n\n                // Backward-compatible ingress event alias used by older bridge shims\n                this._hydraIngressLegacySubscription = transport.subscribe('hydra.overlay.ingress', (message) => {\n                    const envelope = message?.payload || message || null;\n                    if (!envelope) return;\n                    this.eventBus?.emit?.('hydra:overlay:ingress', {\n                        envelope,\n                        meta: {\n                            source: 'transport',\n                            sourceAddress: envelope?.source_address || envelope?.sourceAddress || ''\n                        }\n                    });\n                });\n\n                console.log('[OverlaySubsystem] Transport subscriptions initialized');\n            } catch (err) {\n                try {\n                    this._changeSubscription?.unsubscribe?.();\n                } catch (_) {}\n                try {\n                    this._livePositionSubscription?.unsubscribe?.();\n                } catch (_) {}\n                this._changeSubscription = null;\n                this._livePositionSubscription = null;\n                // Subscribe failed, retry after delay\n                console.warn('[OverlaySubsystem] Transport subscribe failed, retrying...', err.message);\n                scheduleRetry(2000);\n            }\n        };\n\n        // Start trying to initialize after a delay to let transport init first\n        scheduleRetry(1000);\n    }\n\n    /**\n     * Handle incoming overlay change from WebSocket\n     */\n    _handleOverlayChange(payload) {\n        if (!payload?.overlayId) return;\n        if (this._cameraExclusiveState) {\n            // Keep only the latest bounded notification per loaded overlay.\n            if (this.overlays.has(payload.overlayId)) {\n                this._cameraExclusiveState.deferredChanges.set(payload.overlayId, payload);\n            }\n            return;\n        }\n        this._pageLoads?.get(payload.overlayId)?.controller.abort(new DOMException('Overlay changed', 'AbortError'));\n\n        const entry = this.overlays.get(payload.overlayId);\n        if (!entry) return; // We don't have this overlay loaded\n\n        const { changeType, itemId, layerId, data } = payload;\n\n        switch (changeType) {\n            case 'layer.create': {\n                const layerPayload = this._normalizeLayerPayload(layerId, data);\n                if (layerPayload) {\n                    entry.doc = entry.doc || {};\n                    entry.doc.layers = Array.isArray(entry.doc.layers) ? entry.doc.layers : [];\n                    const exists = entry.doc.layers.some((layer) => (layer?.layer_id || layer?.layerId) === layerPayload.layer_id);\n                    if (!exists) {\n                        entry.doc.layers.push(layerPayload);\n                    }\n                    this._syncOverlay(entry, { layers: [layerPayload] });\n                }\n                break;\n            }\n\n            case 'item.create':\n                if (data && layerId) {\n                    // Add the item to the overlay\n                    this._addItem(entry, layerId, this._convertBackendItemToFrontend(data));\n                }\n                break;\n\n            case 'item.update':\n                if (data && itemId) {\n                    const itemEntry = entry.items.get(itemId);\n                    if (itemEntry) {\n                        // Update item data and re-apply transform/appearance\n                        itemEntry.data = this._mergeItemData(itemEntry.data, data);\n                        itemEntry.runtime ||= {};\n                        itemEntry.runtime.effectiveItem = itemEntry.data;\n                        this._applyItemTransform(itemEntry.object3d, itemEntry.data);\n                        this._syncSurfaceAnchorRegistration(itemEntry, 'item-update');\n                        this._applyItemAppearance(itemEntry.object3d, itemEntry.data);\n                        this._applyModelScale(itemEntry.object3d?.userData?.modelContainer, itemEntry.data);\n                        this._applyModelOpacity(itemEntry.object3d?.userData?.modelContainer, itemEntry.data);\n                        const layerEntry = entry.layers.get(itemEntry.layerId);\n                        const nextPolicy = this._resolveRenderProximity(entry, layerEntry, itemEntry.data);\n                        if (nextPolicy) {\n                            if (!itemEntry.runtime) itemEntry.runtime = {};\n                            const proximityState = itemEntry.runtime.proximity || {};\n                            proximityState.policy = nextPolicy;\n                            proximityState.loaded = this._resolveLoadedState(itemEntry);\n                            itemEntry.runtime.proximity = proximityState;\n                            this._proximityItems.set(itemId, itemEntry);\n                        } else if (itemEntry.runtime?.proximity) {\n                            itemEntry.runtime.proximity = null;\n                            this._proximityItems.delete(itemId);\n                        }\n                    }\n                }\n                break;\n\n            case 'item.delete':\n                if (itemId) {\n                    this._removeItem(entry, itemId);\n                }\n                break;\n\n            case 'item.move':\n                // Position-only update (less data than full item.update)\n                if (data && itemId) {\n                    const itemEntry = entry.items.get(itemId);\n                    if (itemEntry) {\n                        itemEntry.data = this._mergeItemData(itemEntry.data, data);\n                        itemEntry.runtime ||= {};\n                        itemEntry.runtime.effectiveItem = itemEntry.data;\n                        this._applyItemTransform(itemEntry.object3d, itemEntry.data);\n                        this._syncSurfaceAnchorRegistration(itemEntry, 'item-move');\n                    }\n                }\n                break;\n\n            default:\n                break;\n        }\n    }\n\n    _normalizeLayerPayload(layerId, data) {\n        if (!data && !layerId) return null;\n        const resolvedId = data?.layer_id || data?.layerId || layerId;\n        if (!resolvedId) return null;\n        return {\n            layer_id: resolvedId,\n            layer_type: data?.layer_type || data?.layerType || '3d_assets',\n            name: data?.name || data?.layerName || resolvedId,\n            style_json: data?.style_json || data?.styleJson || {},\n            inherit_policies: data?.inherit_policies ?? data?.inheritPolicies ?? true,\n            source_ref: data?.source_ref || data?.sourceRef || undefined,\n            items: Array.isArray(data?.items) ? data.items : []\n        };\n    }\n\n    /**\n     * Handle live position update during drag operations\n     */\n    _handleLivePositionUpdate(payload) {\n        if (!payload?.overlayId || !payload?.itemId) return;\n        if (this._cameraExclusiveState) return;\n\n        const entry = this.overlays.get(payload.overlayId);\n        if (!entry) return;\n\n        const itemEntry = entry.items.get(payload.itemId);\n        if (!itemEntry) return;\n\n        // Shared media playback rides the same per-overlay relay.\n        if (payload.mediaPlayback) {\n            itemEntry.object3d?.userData?.mediaPlayback?.receive?.(payload.mediaPlayback);\n            return;\n        }\n\n        // Update position without persisting\n        const { position, properties } = payload;\n        if (position) {\n            const current = itemEntry.data?.current || {};\n            if (position.lat !== undefined && position.lon !== undefined) {\n                current.geom = {\n                    type: 'Point',\n                    coordinates: [position.lon, position.lat]\n                };\n            }\n            if (position.elevation_m !== undefined) {\n                current.elevation_m = position.elevation_m;\n            }\n            // Merge any additional properties (like rotation during placement)\n            if (properties) {\n                current.properties = { ...current.properties, ...properties };\n            }\n            itemEntry.data.current = current;\n            itemEntry.runtime ||= {};\n            itemEntry.runtime.effectiveItem = itemEntry.data;\n            this._applyItemTransform(itemEntry.object3d, itemEntry.data);\n            this._syncSurfaceAnchorRegistration(itemEntry, 'live-position');\n        }\n    }\n\n    /**\n     * Merge incoming item data with existing item data\n     */\n    _mergeItemData(existing, incoming) {\n        if (!existing) return incoming;\n        if (!incoming) return existing;\n\n        const merged = { ...existing };\n\n        // Merge current version data\n        if (incoming.geom !== undefined) {\n            merged.current = merged.current || {};\n            merged.current.geom = incoming.geom;\n        }\n        if (incoming.elevationM !== undefined || incoming.elevation_m !== undefined) {\n            merged.current = merged.current || {};\n            merged.current.elevation_m = incoming.elevationM ?? incoming.elevation_m;\n        }\n        if (incoming.orientationQuat !== undefined || incoming.orientation_quat !== undefined) {\n            merged.current = merged.current || {};\n            merged.current.orientation_quat = incoming.orientationQuat ?? incoming.orientation_quat;\n        }\n        if (incoming.properties) {\n            merged.current = merged.current || {};\n            merged.current.properties = { ...merged.current?.properties, ...incoming.properties };\n        }\n\n        return merged;\n    }\n\n    /**\n     * Convert backend item format (ItemWithMeta) to frontend overlay item format\n     */\n    _convertBackendItemToFrontend(backendItem) {\n        if (!backendItem) return null;\n        return {\n            item_id: backendItem.itemId,\n            item_type: backendItem.itemType,\n            current: {\n                geom: backendItem.geom,\n                elevation_m: backendItem.elevationM,\n                orientation_quat: backendItem.orientationQuat ?? backendItem.orientation_quat,\n                properties: backendItem.properties || {}\n            }\n        };\n    }\n\n    /**\n     * Subscribe to real-time updates for a specific overlay\n     */\n    async subscribeToOverlay(overlayId) {\n        if (!overlayId || this._disposed) return;\n\n        let transport;\n        try {\n            transport = getTransportManager();\n        } catch (error) {\n            console.warn('[OverlaySubsystem] subscribe transport error:', overlayId, error);\n            return;\n        }\n        if (!transport?.isConnected) return;\n\n        try {\n            await transport.send(TransportEvent.OVERLAY_SUBSCRIBE, { overlayId });\n            this._overlaySubscriptions.set(overlayId, true);\n        } catch (error) {\n            console.warn('[OverlaySubsystem] subscribe failed:', overlayId, error);\n        }\n    }\n\n    /**\n     * Unsubscribe from real-time updates for a specific overlay\n     */\n    async unsubscribeFromOverlay(overlayId) {\n        if (!overlayId) return;\n\n        let transport;\n        try {\n            transport = getTransportManager();\n        } catch (error) {\n            this._overlaySubscriptions.delete(overlayId);\n            console.warn('[OverlaySubsystem] unsubscribe transport error:', overlayId, error);\n            return;\n        }\n        if (!transport?.isConnected) {\n            this._overlaySubscriptions.delete(overlayId);\n            return;\n        }\n\n        try {\n            await transport.send(TransportEvent.OVERLAY_UNSUBSCRIBE, { overlayId });\n            this._overlaySubscriptions.delete(overlayId);\n        } catch (error) {\n            console.warn('[OverlaySubsystem] unsubscribe failed:', overlayId, error);\n        }\n    }\n\n    /**\n     * Broadcast live position update during drag/placement\n     */\n    broadcastLivePosition(overlayId, itemId, position, properties = null) {\n        const transport = getTransportManager();\n        if (!transport?.isConnected) return;\n\n        transport.send('overlay.livePosition', {\n            overlayId,\n            itemId,\n            position,\n            properties,\n            timestamp: Date.now()\n        }, { noReply: true }).catch(() => {\n            // Ignore errors for fire-and-forget live updates\n        });\n    }\n\n    /**\n     * Relay a shared media play/pause to everyone viewing the overlay.\n     */\n    broadcastMediaPlayback(overlayId, itemId, mediaPlayback) {\n        const transport = getTransportManager();\n        if (!overlayId || !itemId || !transport?.isConnected) return;\n        transport.send('overlay.livePosition', {\n            overlayId,\n            itemId,\n            mediaPlayback,\n            timestamp: Date.now()\n        }, { noReply: true }).catch(() => {});\n    }\n\n    async load(overlayDoc, opts = {}) {\n        if (this._disposed) {\n            throw new Error('OverlaySubsystem is disposed');\n        }\n        const overlayId = overlayDoc?.overlay?.overlay_id || opts.overlayId || null;\n        if (!overlayId) throw new Error('overlay_id missing');\n        const sessionScope = opts._pageJob ? opts._pageJob.sessionScope : this._session?.capture();\n        this._session?.assert(sessionScope);\n        this._overlayBuilds ||= new Map();\n        this._overlayBuilds.get(overlayId)?.abort(new DOMException('Replaced', 'AbortError'));\n        const build = new AbortController();\n        build.sessionScope = sessionScope;\n        const releaseSession = bindOverlaySession(sessionScope, build);\n        this._overlayBuilds.set(overlayId, build);\n        const abort = () => build.abort(opts.signal.reason);\n        opts.signal?.addEventListener('abort', abort, { once: true });\n        if (opts.signal?.aborted) abort();\n        const current = () => {\n            this._session?.assert(sessionScope);\n            build.signal.throwIfAborted();\n            if (this._disposed || this._overlayBuilds.get(overlayId) !== build ||\n                (opts._pageJob && this._pageLoads?.get(overlayId) !== opts._pageJob)) {\n                throw new DOMException('Replaced', 'AbortError');\n            }\n        };\n        try {\n            if (!opts._pageJob) this._pageLoads?.get(overlayId)?.controller.abort(new DOMException('Replaced', 'AbortError'));\n            current();\n\n            // ── Async gating check (P0: actually enforce token gating) ──\n            if (this.access && typeof this.access.canPerform === 'function') {\n                try {\n                    const allowed = await this.access.canPerform('overlay', overlayId, 'view');\n                    current();\n                    if (!allowed) {\n                        this.eventBus?.emit('overlay:blocked', { overlayId, reason: 'gating' });\n                        return { overlayId, blocked: true, reason: 'gating' };\n                    }\n                } catch (err) {\n                    // If access check fails (network error, not authenticated),\n                    // fall through to sync check below\n                    this._logDebug('[OverlaySubsystem] Access check failed, falling through:', err.message);\n                }\n            }\n\n            // Sync fallback (uses cached decisions)\n            current();\n            if (!this._canViewOverlay(overlayId)) {\n                this.eventBus?.emit('overlay:blocked', { overlayId, reason: 'gating' });\n                return { overlayId, blocked: true, reason: 'gating' };\n            }\n\n            if (this.overlays.has(overlayId)) {\n                await this.unload(overlayId, { keepLoad: opts._pageJob, keepBuild: build });\n            }\n            await this._overlayRetirements?.get(overlayId);\n            current();\n\n            const group = new THREE.Group();\n            group.name = `Overlay:${overlayId}`;\n            group.visible = this._resolveVisibilityFlag({ ...(overlayDoc.overlay?.metadata || {}), ...overlayDoc.overlay }, true) !== false\n                && !overlayDoc.overlay?.geo_gate?.rules?.length;\n            if (this.parentGroup) {\n                this.parentGroup.add(group);\n            } else if (this.scene) {\n                this.scene.add(group);\n            }\n\n            // Register overlay group to be excluded from atmosphere depth passes\n            if (this.sceneInitializer && typeof this.sceneInitializer.addDepthPassExclude === 'function') {\n                this.sceneInitializer.addDepthPassExclude(group);\n            }\n\n            const entry = {\n                overlayId,\n                anchorGeneration: this._surfaceAnchorGeneration = (this._surfaceAnchorGeneration || 0) + 1,\n                sessionScope,\n                doc: overlayDoc,\n                group,\n                layers: new Map(),\n                items: new Map(),\n                splineItems: new Map()\n            };\n\n            this.overlays.set(overlayId, entry);\n            if (opts._pageJob) opts._pageJob.entry = entry;\n            try { await this._buildOverlay(entry, build.signal); current(); }\n            catch (error) {\n                if (this.overlays.get(overlayId) === entry) {\n                    // Retire only this failed build. A newer job may already\n                    // own the ID while awaiting access or this retirement.\n                    await this.unload(overlayId, {\n                        keepLoad: this._pageLoads?.get(overlayId),\n                        keepBuild: this._overlayBuilds.get(overlayId)\n                    });\n                }\n                throw error;\n            }\n\n            // Subscribe to real-time updates for this overlay\n            this.subscribeToOverlay(overlayId);\n\n            if (!opts.partial) this.eventBus?.emit('overlay:loaded', { overlayId });\n            return { overlayId, group };\n        } catch (error) {\n            this.eventBus?.emit('overlay:error', { overlayId: overlayDoc?.overlay?.overlay_id, error });\n            throw error;\n        } finally {\n            releaseSession();\n            opts.signal?.removeEventListener('abort', abort);\n            if (this._overlayBuilds.get(overlayId) === build) this._overlayBuilds.delete(overlayId);\n        }\n    }\n\n    loadPages(overlayId, source, options = {}) {\n        return ingestOverlayPages(this, overlayId, source, options);\n    }\n\n    unload(overlayId, { keepLoad, keepBuild } = {}) {\n        const job = this._pageLoads?.get(overlayId);\n        if (job && job !== keepLoad) job.controller.abort(new DOMException('Unloaded', 'AbortError'));\n        const build = this._overlayBuilds?.get(overlayId);\n        if (build && build !== keepBuild) build.abort(new DOMException('Unloaded', 'AbortError'));\n        const entry = this.overlays.get(overlayId);\n        if (!entry) return this._overlayRetirements?.get(overlayId);\n        this.overlays.delete(overlayId);\n        entry.retiring = true;\n        if (entry.group?.parent) entry.group.parent.remove(entry.group);\n\n        // Unsubscribe from real-time updates\n        this.unsubscribeFromOverlay(overlayId);\n\n        const retire = async () => {\n            let count = 0, start = performance.now();\n            for (const itemId of entry.items.keys()) {\n                this._removeItem(entry, itemId);\n                if (++count >= 16 || performance.now() - start >= 2) {\n                    await yieldToEventLoop(); count = 0; start = performance.now();\n                }\n            }\n\n            count = 0; start = performance.now();\n            for (const layer of entry.layers.values()) {\n                if (layer?.renderer && typeof layer.renderer.dispose === 'function') {\n                    try {\n                        layer.renderer.dispose();\n                    } catch (error) {\n                        this.eventBus?.emit('overlay:error', { overlayId, error });\n                    }\n                }\n                if (++count >= 16 || performance.now() - start >= 2) {\n                    await yieldToEventLoop(); count = 0; start = performance.now();\n                }\n            }\n            entry.items.clear();\n            entry.splineItems?.clear();\n            entry.layers.clear();\n\n            // Unregister overlay group from depth pass exclusion\n            if (entry.group && this.sceneInitializer && typeof this.sceneInitializer.removeDepthPassExclude === 'function') {\n                this.sceneInitializer.removeDepthPassExclude(entry.group);\n            }\n\n            if (entry.group) {\n                if (entry.group.parent) entry.group.parent.remove(entry.group);\n                this._disposeObject(entry.group);\n            }\n        };\n        this._overlayRetirements ||= new Map();\n        const pending = retire().finally(() => {\n            if (this._overlayRetirements.get(overlayId) === pending) this._overlayRetirements.delete(overlayId);\n        });\n        this._overlayRetirements.set(overlayId, pending);\n        return pending;\n    }\n\n    update(overlayId, patch) {\n        const entry = this.overlays.get(overlayId);\n        if (!entry || !patch) return;\n        this._pageLoads?.get(overlayId)?.controller.abort(new DOMException('Overlay changed', 'AbortError'));\n        const replaceLayers = !!(patch._full || patch.full || patch.replace || patch.replaceLayers || patch.mode === 'replace');\n        entry.doc = this._mergeOverlayUpdate(entry.doc, patch, { replaceLayers });\n        if (patch.overlay) {\n            const visible = this._resolveVisibilityFlag({ ...(entry.doc.overlay?.metadata || {}), ...entry.doc.overlay }, true) !== false;\n            if (!visible || !entry.doc.overlay?.geo_gate?.rules?.length) entry.group.visible = visible;\n        }\n        this._syncOverlay(entry, patch, { replaceLayers });\n        if (patch.overlay || patch.layers) {\n            const layerIds = !patch.overlay && Array.isArray(patch.layers)\n                ? patch.layers.filter(layer => layer && Object.keys(layer).some(key => !['layer_id', 'name', 'items'].includes(key)))\n                    .map(layer => layer.layer_id || layer.name).filter(Boolean)\n                : null;\n            // _updateItem already refreshes the edited item's policy. Do not\n            // revisit every sibling for an item-only patch.\n            if (layerIds === null || layerIds.length) this._refreshProximityPolicies(entry, layerIds);\n            this._requestGeoRefresh();\n        }\n        this.eventBus?.emit('overlay:updated', { overlayId });\n    }\n\n    get(overlayId) {\n        return this.overlays.get(overlayId) || null;\n    }\n\n    /** Acquire a scene-only overlay item preview. The token is fenced to the\n     * exact overlay build, item entry, account session and caller generation;\n     * authored item data is never changed by per-frame motion. */\n    beginMotionPreview({ overlayId, itemId, executionId, generation } = {}) {\n        const entry = this.overlays.get(String(overlayId || ''));\n        const itemEntry = entry?.items?.get(String(itemId || ''));\n        if (!entry || !itemEntry || itemEntry.runtime?.motionPreview) return null;\n        const token = Object.freeze({\n            overlayId: entry.overlayId,\n            layerId: itemEntry.layerId,\n            itemId: itemEntry.itemId,\n            executionId: String(executionId || ''),\n            generation: Number(generation),\n            anchorGeneration: entry.anchorGeneration,\n            sessionScope: entry.sessionScope,\n            entry,\n            itemEntry,\n            originalItem: structuredClone(itemEntry.data),\n        });\n        itemEntry.runtime ||= {};\n        itemEntry.runtime.motionPreview = token;\n        return token;\n    }\n\n    _isMotionPreviewCurrent(token) {\n        if (!token || this._disposed || token.sessionScope?.signal?.aborted) return false;\n        const entry = this.overlays.get(token.overlayId);\n        return entry === token.entry\n            && entry.anchorGeneration === token.anchorGeneration\n            && entry.items?.get(token.itemId) === token.itemEntry\n            && token.itemEntry.layerId === token.layerId\n            && token.itemEntry.runtime?.motionPreview === token;\n    }\n\n    updateMotionPreview(token, previewItem) {\n        if (!this._isMotionPreviewCurrent(token) || !previewItem) return false;\n        token.itemEntry.runtime.motionPreviewItem = previewItem;\n        const layerEntry = token.entry.layers.get(token.itemEntry.layerId);\n        const visible = token.entry.group?.visible !== false && layerEntry?.group?.visible !== false;\n        this._applyItemGeoState(token.entry, token.itemEntry, null, visible);\n        this._syncSurfaceAnchorRegistration(token.itemEntry, 'motion-preview');\n        return true;\n    }\n\n    endMotionPreview(token, { restore = true } = {}) {\n        if (!this._isMotionPreviewCurrent(token)) return false;\n        delete token.itemEntry.runtime.motionPreview;\n        delete token.itemEntry.runtime.motionPreviewItem;\n        const layerEntry = token.entry.layers.get(token.itemEntry.layerId);\n        const visible = token.entry.group?.visible !== false && layerEntry?.group?.visible !== false;\n        // A terminal non-preview execution may retain the final visual until\n        // the next canonical overlay update. Preview/cancel always restores\n        // the latest authored item, not a stale pre-execution copy.\n        if (restore) this._applyItemGeoState(token.entry, token.itemEntry, null, visible);\n        return true;\n    }\n\n    /**\n     * Admit exactly one persisted hidden review draft for an explicit owner\n     * placement session. Authored visibility is never changed by this preview.\n     */\n    beginPlacementReview({ overlayId, itemId, captureSessionId, expectedRevision } = {}) {\n        const next = {\n            overlayId: String(overlayId || '').trim(),\n            itemId: String(itemId || '').trim(),\n            captureSessionId: String(captureSessionId || '').trim(),\n            expectedRevision: Number(expectedRevision),\n        };\n        if (!next.overlayId || !next.itemId || !next.captureSessionId\n            || !Number.isInteger(next.expectedRevision) || next.expectedRevision < 1) return false;\n        const previous = this._placementReviewPreview;\n        this._placementReviewPreview = next;\n        if (previous && (previous.overlayId !== next.overlayId\n            || previous.itemId !== next.itemId\n            || previous.captureSessionId !== next.captureSessionId\n            || previous.expectedRevision !== next.expectedRevision)) {\n            this._clearPlacementReviewDraft(previous);\n            this._refreshPlacementReviewTarget(previous);\n        }\n        const entry = this.overlays.get(next.overlayId);\n        const itemEntry = entry?.items?.get(next.itemId);\n        if (itemEntry && !this._isPlacementReviewItem(entry, itemEntry)) {\n            this._placementReviewPreview = null;\n            return false;\n        }\n        this._refreshPlacementReviewTarget(next);\n        return true;\n    }\n\n    updatePlacementReview({ overlayId, itemId, placement } = {}) {\n        const target = this._placementReviewPreview;\n        if (!target || target.overlayId !== String(overlayId || '') || target.itemId !== String(itemId || '')) {\n            return false;\n        }\n        if (target.captureSessionId !== String(placement?.captureSessionId || '')\n            || target.expectedRevision !== Number(placement?.expectedRevision)) return false;\n        const entry = this.overlays.get(target.overlayId);\n        const itemEntry = entry?.items?.get(target.itemId);\n        if (!itemEntry || !this._isPlacementReviewItem(entry, itemEntry)) return false;\n        const latitude = Number(placement?.latitude);\n        const longitude = Number(placement?.longitude);\n        const altitudeM = Number(placement?.altitudeM);\n        const ellipsoidAltitudeM = Number(placement?.ellipsoidAltitudeM);\n        const scale = Number(placement?.scale);\n        const rotationDeg = ['x', 'y', 'z'].map((axis) => Number(placement?.rotationDeg?.[axis]));\n        const modelOriginOffsetM = Array.isArray(placement?.modelOriginOffsetM)\n            ? placement.modelOriginOffsetM.map(Number)\n            : [];\n        if (!Number.isFinite(latitude) || latitude < -90 || latitude > 90\n            || !Number.isFinite(longitude) || longitude < -180 || longitude > 180\n            || !Number.isFinite(altitudeM) || altitudeM < -12000 || altitudeM > 100000\n            || !Number.isFinite(ellipsoidAltitudeM) || ellipsoidAltitudeM < -12000 || ellipsoidAltitudeM > 100000\n            || !['egm96', 'wgs84_ellipsoid'].includes(placement?.altitudeDatum)\n            || !Number.isFinite(scale) || scale <= 0 || scale > 10000\n            || rotationDeg.some((value) => !Number.isFinite(value) || Math.abs(value) > 360)\n            || modelOriginOffsetM.length !== 3\n            || modelOriginOffsetM.some((value) => !Number.isFinite(value) || Math.abs(value) > 1000000)) return false;\n        const current = itemEntry.data?.current || {};\n        const properties = current.properties || {};\n        itemEntry.runtime ||= {};\n        itemEntry.runtime.reviewPreviewItem = {\n            ...itemEntry.data,\n            current: {\n                ...current,\n                geom: { type: 'Point', coordinates: [longitude, latitude] },\n                elevation_m: ellipsoidAltitudeM,\n                properties: {\n                    ...properties,\n                    anchor_asl_m: placement.altitudeDatum === 'egm96' ? altitudeM : null,\n                    anchor_ellipsoid_m: ellipsoidAltitudeM,\n                    altitude_datum: placement.altitudeDatum,\n                    model_scale: scale,\n                    rotation_deg: {\n                        x: rotationDeg[0],\n                        y: rotationDeg[1],\n                        z: rotationDeg[2],\n                    },\n                    model_origin_offset_m: modelOriginOffsetM,\n                },\n            },\n        };\n        this._refreshPlacementReviewTarget(target);\n        this.eventBus?.emit?.('overlay:placement-review-updated', { ...target });\n        return true;\n    }\n\n    endPlacementReview({ overlayId, itemId, captureSessionId, expectedRevision } = {}) {\n        const target = this._placementReviewPreview;\n        if (!target) return false;\n        if (overlayId && target.overlayId !== String(overlayId)) return false;\n        if (itemId && target.itemId !== String(itemId)) return false;\n        if (captureSessionId && target.captureSessionId !== String(captureSessionId)) return false;\n        if (expectedRevision !== undefined && target.expectedRevision !== Number(expectedRevision)) return false;\n        this._clearPlacementReviewDraft(target);\n        this._placementReviewPreview = null;\n        this._refreshPlacementReviewTarget(target);\n        return true;\n    }\n\n    _clearPlacementReviewDraft(target) {\n        const itemEntry = this.overlays.get(target?.overlayId)?.items?.get(target?.itemId);\n        if (itemEntry?.runtime) delete itemEntry.runtime.reviewPreviewItem;\n    }\n\n    _isPlacementReviewItem(entry, itemOrEntry) {\n        const target = this._placementReviewPreview;\n        const item = itemOrEntry?.data || itemOrEntry;\n        const itemId = itemOrEntry?.itemId || item?.item_id;\n        const props = item?.current?.properties || {};\n        return !!target\n            && target.overlayId === entry?.overlayId\n            && target.itemId === itemId\n            && String(entry?.doc?.overlay?.visibility || '').toLowerCase() === 'private'\n            && props.review_required === true\n            && props.visible === false\n            && String(props.capture_session_id || '') === target.captureSessionId\n            && Number(props.placement_revision || props.alignment_revision) === target.expectedRevision;\n    }\n\n    _refreshPlacementReviewTarget(target) {\n        const entry = this.overlays.get(target?.overlayId);\n        const itemEntry = entry?.items?.get(target?.itemId);\n        if (!entry || !itemEntry) return;\n        const layerEntry = entry.layers.get(itemEntry.layerId);\n        const visible = entry.group?.visible !== false && layerEntry?.group?.visible !== false;\n        this._applyItemGeoState(entry, itemEntry, null, visible);\n    }\n\n    findItem(itemId) {\n        if (!itemId) return null;\n        for (const overlay of this.overlays.values()) {\n            const entry = overlay.items.get(itemId);\n            if (entry) return entry;\n        }\n        return null;\n    }\n\n    findItemInOverlay(overlayId, itemId) {\n        if (!overlayId || itemId === null || itemId === undefined) return null;\n        const overlay = this.overlays.get(overlayId);\n        if (!overlay) return null;\n        return overlay.items.get(itemId) || null;\n    }\n\n    setHydraIngress(ingress) {\n        this._hydraIngress = ingress || null;\n    }\n\n    findItemMatches(itemId) {\n        const normalized = itemId === null || itemId === undefined ? '' : String(itemId);\n        if (!normalized) return [];\n        const matches = [];\n        for (const [overlayId, overlayEntry] of this.overlays.entries()) {\n            const itemEntry = overlayEntry?.items?.get?.(normalized) || null;\n            if (!itemEntry) continue;\n            matches.push({ overlayId, itemEntry });\n        }\n        return matches;\n    }\n\n    resolveIngressTarget(target = {}) {\n        const normalizedOverlayId = String(target?.overlayId || target?.overlay_id || '').trim();\n        const normalizedItemId = String(\n            target?.itemId ||\n            target?.item_id ||\n            target?.objectUuid ||\n            target?.object_uuid ||\n            target?.objectId ||\n            target?.object_id ||\n            ''\n        ).trim();\n        const normalizedLayerId = String(target?.layerId || target?.layer_id || '').trim();\n\n        if (!normalizedOverlayId && !normalizedItemId) {\n            return { ok: false, error: 'missing-target' };\n        }\n\n        if (normalizedOverlayId && normalizedItemId) {\n            const itemEntry = this.findItemInOverlay(normalizedOverlayId, normalizedItemId);\n            if (!itemEntry) {\n                return { ok: false, error: 'target-item-not-found' };\n            }\n            return {\n                ok: true,\n                overlayId: normalizedOverlayId,\n                itemId: normalizedItemId,\n                layerId: itemEntry.layerId || normalizedLayerId || '',\n                itemEntry\n            };\n        }\n\n        if (normalizedItemId) {\n            const matches = this.findItemMatches(normalizedItemId);\n            if (!matches.length) {\n                return { ok: false, error: 'target-item-not-found' };\n            }\n            if (matches.length > 1) {\n                return { ok: false, error: 'ambiguous-item-target' };\n            }\n            const match = matches[0];\n            return {\n                ok: true,\n                overlayId: match.overlayId,\n                itemId: normalizedItemId,\n                layerId: match.itemEntry?.layerId || normalizedLayerId || '',\n                itemEntry: match.itemEntry || null\n            };\n        }\n\n        return {\n            ok: true,\n            overlayId: normalizedOverlayId,\n            itemId: normalizedItemId,\n            layerId: normalizedLayerId,\n            itemEntry: null\n        };\n    }\n\n    _ingressCanMutate(overlayId, itemEntry, { assetMutation = false } = {}) {\n        if (!overlayId) return { ok: false, error: 'missing-overlay-id' };\n        if (!this._canViewOverlay(overlayId)) {\n            return { ok: false, error: 'overlay-view-blocked' };\n        }\n        if (itemEntry && !this._canUpdateItem(itemEntry.data)) {\n            return { ok: false, error: 'item-update-blocked' };\n        }\n        if (assetMutation && itemEntry?.data && this._isAssetBlocked(itemEntry.data)) {\n            return { ok: false, error: 'asset-view-blocked' };\n        }\n        return { ok: true };\n    }\n\n    applyIngressItemPatch({ overlayId, itemId, layerId, patch, createIfMissing = false, itemType = 'model3d' } = {}) {\n        const target = this.resolveIngressTarget({ overlayId, itemId, layerId });\n        if (!target.ok && target.error !== 'target-item-not-found') {\n            return target;\n        }\n        const resolvedOverlayId = target.overlayId || String(overlayId || '').trim();\n        if (!resolvedOverlayId) {\n            return { ok: false, error: 'missing-overlay-id' };\n        }\n        const overlayEntry = this.overlays.get(resolvedOverlayId);\n        if (!overlayEntry) {\n            return { ok: false, error: 'overlay-not-loaded' };\n        }\n\n        const existingItem = target.itemEntry || null;\n        const access = this._ingressCanMutate(resolvedOverlayId, existingItem, { assetMutation: false });\n        if (!access.ok) return access;\n\n        const requestedItemId = String(itemId || target.itemId || '').trim();\n        if (!existingItem && !createIfMissing) {\n            return { ok: false, error: 'target-item-not-found' };\n        }\n\n        let resolvedLayerId = String(layerId || target.layerId || existingItem?.layerId || '').trim();\n        if (!resolvedLayerId) {\n            const firstLayerId = overlayEntry.layers?.keys?.().next?.()?.value || '';\n            resolvedLayerId = firstLayerId ? String(firstLayerId) : '';\n        }\n        if (!resolvedLayerId) {\n            return { ok: false, error: 'missing-layer-id' };\n        }\n        if (!this._canViewLayer(resolvedLayerId)) {\n            return { ok: false, error: 'layer-view-blocked' };\n        }\n\n        const incomingPatch = patch && typeof patch === 'object' ? patch : {};\n        const itemPatch = existingItem\n            ? this._mergeOverlayDoc(existingItem.data, incomingPatch)\n            : this._mergeOverlayDoc({\n                item_id: requestedItemId || incomingPatch.item_id || incomingPatch.itemId || '',\n                item_type: incomingPatch.item_type || incomingPatch.itemType || itemType || 'model3d',\n                current: {\n                    properties: {}\n                }\n            }, incomingPatch);\n        if (!itemPatch.item_id) {\n            itemPatch.item_id = requestedItemId || `ingress-${Date.now().toString(36)}`;\n        }\n        if (!itemPatch.item_type) {\n            itemPatch.item_type = itemType || 'model3d';\n        }\n        itemPatch.current = itemPatch.current && typeof itemPatch.current === 'object' ? itemPatch.current : {};\n        itemPatch.current.properties = itemPatch.current.properties && typeof itemPatch.current.properties === 'object'\n            ? itemPatch.current.properties\n            : {};\n\n        if (!existingItem && !this._canViewItem(itemPatch)) {\n            return { ok: false, error: 'item-view-blocked' };\n        }\n\n        this.update(resolvedOverlayId, {\n            layers: [\n                {\n                    layer_id: resolvedLayerId,\n                    items: [itemPatch]\n                }\n            ]\n        });\n\n        const nextItemEntry = this.findItemInOverlay(resolvedOverlayId, itemPatch.item_id);\n        return {\n            ok: !!nextItemEntry,\n            overlayId: resolvedOverlayId,\n            itemId: itemPatch.item_id,\n            layerId: resolvedLayerId,\n            itemEntry: nextItemEntry || null,\n            error: nextItemEntry ? null : 'item-patch-not-applied'\n        };\n    }\n\n    applyIngressLivePosition({ overlayId, itemId, position, properties = null } = {}) {\n        const target = this.resolveIngressTarget({ overlayId, itemId });\n        if (!target.ok) return target;\n        if (!target.itemEntry) return { ok: false, error: 'target-item-required' };\n        const access = this._ingressCanMutate(target.overlayId, target.itemEntry, { assetMutation: false });\n        if (!access.ok) return access;\n        this._handleLivePositionUpdate({\n            overlayId: target.overlayId,\n            itemId: target.itemId,\n            position,\n            properties\n        });\n        return { ok: true, overlayId: target.overlayId, itemId: target.itemId };\n    }\n\n    applyIngressPointcloudData({ overlayId, itemId, pointcloud } = {}) {\n        const target = this.resolveIngressTarget({ overlayId, itemId });\n        if (!target.ok) return target;\n        if (!target.itemEntry) return { ok: false, error: 'target-item-required' };\n        const access = this._ingressCanMutate(target.overlayId, target.itemEntry, { assetMutation: false });\n        if (!access.ok) return access;\n        const payload = pointcloud && typeof pointcloud === 'object' ? pointcloud : {};\n        const positionData = Array.isArray(payload.positions)\n            ? payload.positions\n            : (Array.isArray(payload.vertices) ? payload.vertices : (Array.isArray(payload.points) ? payload.points : null));\n        if (!positionData || positionData.length < 3 || (positionData.length % 3) !== 0) {\n            return { ok: false, error: 'invalid-pointcloud-positions' };\n        }\n        const object3d = target.itemEntry.object3d || null;\n        const nodes = this._getPointCloudNodes(object3d) || [];\n        if (!nodes.length) {\n            return { ok: false, error: 'pointcloud-node-missing' };\n        }\n        const pointsNode = nodes[0];\n        const geometry = pointsNode.geometry;\n        if (!geometry) {\n            return { ok: false, error: 'pointcloud-geometry-missing' };\n        }\n\n        const positions = new Float32Array(positionData.length);\n        for (let i = 0; i < positionData.length; i += 1) {\n            const num = Number(positionData[i]);\n            positions[i] = Number.isFinite(num) ? num : 0;\n        }\n        geometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3));\n        if (Array.isArray(payload.colors) && payload.colors.length >= positionData.length) {\n            const colors = new Float32Array(positionData.length);\n            let scale = 1;\n            for (let i = 0; i < payload.colors.length; i += 1) {\n                const sample = Number(payload.colors[i]);\n                if (Number.isFinite(sample) && sample > 1) {\n                    scale = 255;\n                    break;\n                }\n            }\n            for (let i = 0; i < positionData.length; i += 1) {\n                const value = Number(payload.colors[i] || 0);\n                const normalized = Number.isFinite(value) ? Math.max(0, Math.min(1, value / scale)) : 0;\n                colors[i] = normalized;\n            }\n            geometry.setAttribute('color', new THREE.Float32BufferAttribute(colors, 3));\n        }\n        geometry.computeBoundingBox?.();\n        geometry.computeBoundingSphere?.();\n        geometry.attributes.position.needsUpdate = true;\n        if (geometry.attributes.color) geometry.attributes.color.needsUpdate = true;\n        if (Number.isFinite(payload.size) && pointsNode.material) {\n            pointsNode.material.size = Number(payload.size);\n            pointsNode.material.needsUpdate = true;\n        }\n        this._getPointCloudDrawRange(geometry);\n        this._requestGeoRefresh();\n        return { ok: true, overlayId: target.overlayId, itemId: target.itemId };\n    }\n\n    applyIngressModelUrl({ overlayId, itemId, layerId, modelUrl } = {}) {\n        if (!modelUrl || typeof modelUrl !== 'string') {\n            return { ok: false, error: 'missing-model-url' };\n        }\n        const target = this.resolveIngressTarget({ overlayId, itemId, layerId });\n        if (!target.ok && target.error !== 'target-item-not-found') return target;\n        const access = this._ingressCanMutate(\n            target.overlayId || String(overlayId || '').trim(),\n            target.itemEntry || null,\n            { assetMutation: true }\n        );\n        if (!access.ok) return access;\n        return this.applyIngressItemPatch({\n            overlayId: target.overlayId || overlayId,\n            itemId: target.itemId || itemId,\n            layerId: target.layerId || layerId,\n            createIfMissing: true,\n            itemType: 'model3d',\n            patch: {\n                item_id: target.itemId || itemId || '',\n                item_type: 'model3d',\n                current: {\n                    properties: {\n                        model_url: modelUrl\n                    }\n                }\n            }\n        });\n    }\n\n    getItemObject(itemId) {\n        const entry = this.findItem(itemId);\n        return entry ? entry.object3d : null;\n    }\n\n    updateHover(raycaster) {\n        if (!raycaster) {\n            this._hoveredItem = null;\n            return null;\n        }\n        const objects = [];\n        for (const overlay of this.overlays.values()) {\n            for (const itemEntry of overlay.items.values()) {\n                const object3d = itemEntry?.object3d;\n                if (!object3d) continue;\n                if (!this._isObjectVisible(object3d)) continue;\n                const props = itemEntry.data?.current?.properties || {};\n                if (props.visible === false) continue;\n                if (props.hover_enabled === false) continue;\n                if (itemEntry.runtime?.proximity && itemEntry.runtime.proximity.loaded === false) continue;\n                objects.push(object3d);\n            }\n        }\n\n        if (!objects.length) {\n            this._hoveredItem = null;\n            return null;\n        }\n\n        const hits = raycaster.intersectObjects(objects, true);\n        let next = null;\n        if (hits.length) {\n            const itemId = this._resolveHoverItemId(hits[0].object);\n            if (itemId) {\n                next = this.findItem(itemId);\n            }\n        }\n\n        const prevOverlayId = this._hoveredItem?.overlayEntry?.overlayId || null;\n        const nextOverlayId = next?.overlayEntry?.overlayId || null;\n        if (prevOverlayId === nextOverlayId && this._hoveredItem?.itemId === next?.itemId) {\n            return this._hoveredItem;\n        }\n        this._hoveredItem = next || null;\n        return this._hoveredItem;\n    }\n\n    getHoveredItem() {\n        return this._hoveredItem;\n    }\n\n    _resolveHoverItemId(object3d) {\n        let current = object3d;\n        while (current) {\n            const itemId = current.userData?.itemId;\n            if (itemId) return itemId;\n            current = current.parent;\n        }\n        return null;\n    }\n\n    _isObjectVisible(object3d) {\n        let current = object3d;\n        while (current) {\n            if (current.visible === false) return false;\n            current = current.parent;\n        }\n        return true;\n    }\n\n    get pendingSurfaceAnchorCount() {\n        return this._surfaceAnchorRetries?.size || 0;\n    }\n\n    _surfaceAnchorKey(overlayId, itemId) {\n        return `${String(overlayId || '')}\\u0000${String(itemId || '')}`;\n    }\n\n    getSurfaceAnchorState(overlayId, itemId) {\n        const itemEntry = this.overlays.get(overlayId)?.items?.get(itemId);\n        const state = itemEntry?.object3d?.userData?.surfaceAnchor;\n        return state ? { ...state } : null;\n    }\n\n    _removeSurfaceAnchorRegistration(overlayId, itemId) {\n        this._surfaceAnchorRetries?.delete(this._surfaceAnchorKey(overlayId, itemId));\n    }\n\n    _syncSurfaceAnchorRegistration(itemEntry, reason = 'transform') {\n        this._surfaceAnchorRetries ||= new Map();\n        const entry = itemEntry?.overlayEntry;\n        const item = itemEntry?.runtime?.effectiveItem || itemEntry?.data;\n        const overlayId = entry?.overlayId;\n        const itemId = itemEntry?.itemId || item?.item_id;\n        if (!overlayId || !itemId) return false;\n        const key = this._surfaceAnchorKey(overlayId, itemId);\n        const state = itemEntry?.object3d?.userData?.surfaceAnchor;\n        const retryable = isDa3ScanItem(item)\n            && resolveDa3HeightMode(item) === 'surface_agl'\n            && [\n                SURFACE_ANCHOR_STATE.PENDING,\n                SURFACE_ANCHOR_STATE.HELD,\n                SURFACE_ANCHOR_STATE.UNAVAILABLE,\n            ].includes(state?.state);\n        if (!retryable) {\n            this._surfaceAnchorRetries.delete(key);\n            return false;\n        }\n        this._surfaceAnchorRetries.set(key, {\n            key,\n            overlayId,\n            itemId,\n            generation: entry.anchorGeneration,\n            entry,\n            itemEntry,\n            reason,\n        });\n        return true;\n    }\n\n    _isSurfaceAnchorRetryCurrent(record) {\n        if (!record || this._disposed) return false;\n        const entry = this.overlays.get(record.overlayId);\n        if (!entry || entry !== record.entry || entry.retiring\n            || entry.anchorGeneration !== record.generation) return false;\n        return entry.items?.get(record.itemId) === record.itemEntry;\n    }\n\n    retrySurfaceAnchor(overlayId, itemId, { reason = 'editor-retry', sequence = null } = {}) {\n        const itemEntry = this.overlays.get(overlayId)?.items?.get(itemId);\n        if (!itemEntry) return null;\n        const item = itemEntry.runtime?.effectiveItem || itemEntry.data;\n        this.surfaceController?.prepareTerrainSamplingBatch?.();\n        this._applyItemTransform(itemEntry.object3d, item, {\n            reason,\n            sampleSequence: sequence,\n        });\n        this._syncSurfaceAnchorRegistration(itemEntry, reason);\n        return this.getSurfaceAnchorState(overlayId, itemId);\n    }\n\n    refreshPendingTerrainPositions({ changes = null, cause = 'terrain-change', sequence = null } = {}) {\n        if (this._disposed || !this._surfaceAnchorRetries?.size) return 0;\n        const wakeKey = Number.isFinite(sequence) ? `${cause}:${sequence}` : null;\n        const request = { changes, cause, sequence };\n        if (this._surfaceAnchorRetryTask) {\n            const queuedKey = Number.isFinite(this._queuedSurfaceAnchorRetry?.sequence)\n                ? `${this._queuedSurfaceAnchorRetry.cause}:${this._queuedSurfaceAnchorRetry.sequence}`\n                : null;\n            if (wakeKey && (wakeKey === this._lastSurfaceAnchorWakeKey || wakeKey === queuedKey)) return 0;\n            this._queuedSurfaceAnchorRetry = request;\n            return 0;\n        }\n        if (wakeKey && wakeKey === this._lastSurfaceAnchorWakeKey) return 0;\n        if (wakeKey) this._lastSurfaceAnchorWakeKey = wakeKey;\n\n        this.surfaceController?.prepareTerrainSamplingBatch?.();\n        const task = {\n            records: Array.from(this._surfaceAnchorRetries.values()),\n            index: 0,\n            changes,\n            cause,\n            sequence,\n        };\n        this._surfaceAnchorRetryTask = task;\n        return this._runSurfaceAnchorRetrySlice(task);\n    }\n\n    _runSurfaceAnchorRetrySlice(task) {\n        if (!task || task !== this._surfaceAnchorRetryTask || this._disposed) return 0;\n        const startedAt = typeof performance !== 'undefined' ? performance.now() : Date.now();\n        const regional = Array.isArray(task.changes) && task.changes.length > 0;\n        let processed = 0;\n        while (task.index < task.records.length) {\n            const record = task.records[task.index++];\n            if (!this._isSurfaceAnchorRetryCurrent(record)) {\n                if (this._surfaceAnchorRetries.get(record.key) === record) {\n                    this._surfaceAnchorRetries.delete(record.key);\n                }\n                continue;\n            }\n            const item = record.itemEntry.runtime?.effectiveItem || record.itemEntry.data;\n            const coordinates = item?.current?.geom?.coordinates;\n            const lon = Number(coordinates?.[0]);\n            const lat = Number(coordinates?.[1]);\n            if (regional && !terrainSurfaceChangesAffectLatLon(task.changes, lat, lon)) continue;\n            this._applyItemTransform(record.itemEntry.object3d, item, {\n                reason: task.cause,\n                sampleSequence: task.sequence,\n            });\n            this._syncSurfaceAnchorRegistration(record.itemEntry, task.cause);\n            processed += 1;\n            const now = typeof performance !== 'undefined' ? performance.now() : Date.now();\n            if (processed >= 16 || now - startedAt >= 2) break;\n        }\n\n        if (task.index < task.records.length && !this._disposed) {\n            queueMicrotask(() => this._runSurfaceAnchorRetrySlice(task));\n        } else {\n            this._surfaceAnchorRetryTask = null;\n            const queued = this._queuedSurfaceAnchorRetry;\n            this._queuedSurfaceAnchorRetry = null;\n            if (queued && !this._disposed) {\n                queueMicrotask(() => this.refreshPendingTerrainPositions(queued));\n            }\n        }\n        return processed;\n    }\n\n    /**\n     * Re-snap surface-relative items to current terrain. Legacy DA3 scans keep\n     * their authored world quaternion but still use a terrain-mated AGL anchor.\n     */\n    refreshTerrainPositions(changes = null) {\n        if (!this.triTree && !this.surfaceController) return 0;\n        this.surfaceController?.prepareTerrainSamplingBatch?.();\n        const regional = Array.isArray(changes) && changes.length > 0;\n        const sequence = regional\n            ? Math.max(...changes.map((change) => Number(change?.sequence)).filter(Number.isFinite), 0)\n            : null;\n        let updated = 0;\n        for (const overlay of this.overlays.values()) {\n            for (const itemEntry of overlay.items.values()) {\n                const props = itemEntry.data?.current?.properties;\n                const surfaceRelativeDa3 = resolveDa3HeightMode(itemEntry.data) === 'surface_agl';\n                if (props?.align_to_surface === false && !surfaceRelativeDa3) continue;\n                const coordinates = itemEntry.data?.current?.geom?.coordinates;\n                const lon = Number(coordinates?.[0]);\n                const lat = Number(coordinates?.[1]);\n                if (regional\n                    && !terrainSurfaceChangesAffectLatLon(changes, lat, lon)) continue;\n                const item = itemEntry.runtime?.effectiveItem || itemEntry.data;\n                this._applyItemTransform(itemEntry.object3d, item, {\n                    reason: regional ? 'terrain-change' : 'manual-refresh',\n                    sampleSequence: sequence,\n                });\n                this._syncSurfaceAnchorRegistration(itemEntry, 'terrain-change');\n                updated += 1;\n            }\n        }\n        return updated;\n    }\n\n    setGeoContext(context = {}, { force = false } = {}) {\n        const lat = Number(context.lat);\n        const lon = Number(context.lon);\n        if (!Number.isFinite(lat) || !Number.isFinite(lon)) return;\n        const next = { lat, lon };\n        if (!force && this._geoContext) {\n            if (this._geoContext.lat === next.lat && this._geoContext.lon === next.lon) {\n                return;\n            }\n        }\n        this._geoContext = next;\n        this._applyGeoContext();\n    }\n\n    _requestGeoRefresh() {\n        if (this._bulkBuildDepth || !this._geoContext || this._geoRefreshPending) return;\n        this._geoRefreshPending = true;\n        Promise.resolve().then(() => {\n            this._geoRefreshPending = false;\n            this._applyGeoContext();\n        });\n    }\n\n    _applyGeoContext() {\n        if (!this._geoContext || this._disposed) return;\n        this._geoEvalSeq = (this._geoEvalSeq || 0) + 1;\n        this._geoApplyRequested = true;\n        // One evaluator owns the work. A newer context invalidates its result,\n        // but cannot start another chain while an old boundary request is pending.\n        if (this._geoApplyPromise) return this._geoApplyPromise;\n        const apply = async () => {\n            while (this._geoApplyRequested && !this._disposed) {\n                this._geoApplyRequested = false;\n                const seq = this._geoEvalSeq, context = { ...this._geoContext };\n                const budget = { count: 0, start: performance.now() };\n                await forOverlayAsyncSlice(this.overlays.values(), entry =>\n                    this._applyGeoContextToOverlay(entry, context, seq, budget),\n                () => !this._disposed && seq === this._geoEvalSeq, budget);\n            }\n        };\n        this._geoApplyPromise = apply().catch((error) => {\n            console.warn('[OverlaySubsystem] Geo gate evaluation failed', error);\n        }).finally(() => {\n            this._geoApplyPromise = null;\n            if (this._geoApplyRequested && !this._disposed) this._applyGeoContext();\n        });\n        return this._geoApplyPromise;\n    }\n\n    async _applyGeoContextToOverlay(entry, context, seq, budget = { count: 0, start: performance.now() }) {\n        const current = () => !!entry && !this._disposed && !entry.retiring && seq === this._geoEvalSeq\n            && this.overlays.get(entry.overlayId) === entry;\n        if (!current()) return;\n        const overlayGate = await this._evaluateGeoGate(entry.doc?.overlay?.geo_gate, context);\n        if (!current()) return;\n        const overlaySource = entry.doc?.overlay\n            ? { ...(entry.doc.overlay.metadata || {}), ...entry.doc.overlay }\n            : null;\n        const overlayFlag = this._resolveVisibilityFlag(overlaySource, true);\n        const overlayVisible = overlayGate !== false && overlayFlag !== false;\n        if (entry.group) entry.group.visible = overlayVisible;\n\n        const overlayOverrides = await this._evaluateGeoOverrides(entry.doc?.overlay?.geo_overrides, context);\n        if (!current()) return;\n\n        await forOverlayAsyncSlice(entry.layers.entries(), async ([layerId, layerEntry]) => {\n            const layerCurrent = () => current() && entry.layers.get(layerId) === layerEntry;\n            if (!layerCurrent()) return;\n            const layerGate = await this._evaluateGeoGate(layerEntry?.data?.geo_gate, context);\n            if (!layerCurrent()) return;\n            const layerFlag = this._resolveVisibilityFlag(layerEntry?.data, true);\n            const layerVisible = overlayVisible && layerGate !== false && layerFlag !== false;\n            if (layerEntry?.group) layerEntry.group.visible = layerVisible;\n\n            const layerOverrides = await this._evaluateGeoOverrides(layerEntry?.data?.geo_overrides, context);\n            if (!layerCurrent()) return;\n\n            await forOverlayAsyncSlice(layerEntry.items.values(), async itemEntry => {\n                const itemCurrent = () => layerCurrent() && entry.items.get(itemEntry.itemId) === itemEntry;\n                if (!itemCurrent()) return;\n                const itemGate = await this._evaluateGeoGate(itemEntry?.data?.geo_gate, context);\n                if (!itemCurrent()) return;\n                const itemVisible = layerVisible && itemGate !== false;\n                const itemOverrides = await this._evaluateGeoOverrides(itemEntry?.data?.geo_overrides, context);\n                if (!itemCurrent()) return;\n                const mergedOverrides = {\n                    ...(overlayOverrides || {}),\n                    ...(layerOverrides || {}),\n                    ...(itemOverrides || {})\n                };\n                this._applyItemGeoState(entry, itemEntry, mergedOverrides, itemVisible);\n            }, layerCurrent, budget);\n        }, current, budget);\n    }\n\n    async _evaluateGeoGate(geoGate, context) {\n        if (!geoGate || !Array.isArray(geoGate.rules) || geoGate.rules.length === 0) return true;\n        const mode = String(geoGate.mode || 'allow').toLowerCase() === 'deny' ? 'deny' : 'allow';\n        let matched = false;\n        for (const rule of geoGate.rules) {\n            const hit = await this._geoBoundaryService.matchRule(context.lat, context.lon, rule);\n            if (hit) {\n                matched = true;\n                if (mode === 'allow') return true;\n                if (mode === 'deny') return false;\n            }\n        }\n        return mode === 'allow' ? false : true;\n    }\n\n    async _evaluateGeoOverrides(rules, context) {\n        if (!Array.isArray(rules) || rules.length === 0) return null;\n        const merged = {};\n        let matched = false;\n        for (const rule of rules) {\n            const hit = await this._geoBoundaryService.matchRule(context.lat, context.lon, rule);\n            if (!hit) continue;\n            const props = rule?.properties;\n            if (props && typeof props === 'object' && !Array.isArray(props)) {\n                Object.assign(merged, props);\n                matched = true;\n            }\n        }\n        return matched ? merged : null;\n    }\n\n    // ──────────────────────────────────────────────────────────────\n    // Proximity-based rendering\n    // ──────────────────────────────────────────────────────────────\n\n    updateProximity(observerPos, now = null) {\n        if (!observerPos) return;\n        const timestamp = Number.isFinite(now)\n            ? now\n            : (typeof performance !== 'undefined' ? performance.now() : Date.now());\n        if (timestamp - this._lastProximityUpdate < this._proximityGlobalIntervalMs) return;\n        this._lastProximityUpdate = timestamp;\n        this._proximityObserver.copy(observerPos);\n        this._proximityHasObserver = true;\n        if (!this._proximityItems.size) return;\n\n        for (const itemEntry of this._proximityItems.values()) {\n            this._updateItemProximity(itemEntry, this._proximityObserver, timestamp);\n        }\n    }\n\n    _updateItemProximity(itemEntry, observerPos, timestamp) {\n        if (!itemEntry) return;\n        const runtime = itemEntry.runtime || {};\n        const proximity = runtime.proximity;\n        const policy = proximity?.policy;\n        if (!policy || policy.enabled === false) return;\n\n        const nextAllowed = Number.isFinite(proximity.nextUpdate)\n            ? proximity.nextUpdate\n            : 0;\n        if (timestamp < nextAllowed) return;\n\n        const intervalMs = Number.isFinite(policy.updateIntervalMs)\n            ? policy.updateIntervalMs\n            : this._proximityGlobalIntervalMs;\n        proximity.nextUpdate = timestamp + Math.max(50, intervalMs);\n\n        const entry = itemEntry.overlayEntry;\n        const layerEntry = entry?.layers?.get?.(itemEntry.layerId);\n        const overlayVisible = entry?.group ? entry.group.visible !== false : true;\n        const layerVisible = layerEntry?.group ? layerEntry.group.visible !== false : true;\n        const itemVisible = itemEntry?.runtime?.visible !== false;\n        const gatingVisible = overlayVisible && layerVisible && itemVisible;\n\n        const itemPos = this._getItemWorldPosition(itemEntry, this._proximityTmpVec);\n        if (!itemPos) return;\n\n        const distSq = gatingVisible\n            ? observerPos.distanceToSquared(itemPos)\n            : Number.POSITIVE_INFINITY;\n        proximity.lastDistanceSq = distSq;\n\n        const loadSq = policy.loadDistanceSq;\n        const unloadSq = policy.unloadDistanceSq;\n        const shouldLoad = !Number.isFinite(loadSq) || distSq <= loadSq;\n        const shouldUnload = Number.isFinite(unloadSq) && distSq > unloadSq;\n\n        const toggleCooldownMs = Number.isFinite(policy.toggleCooldownMs)\n            ? policy.toggleCooldownMs\n            : 500;\n        const lastToggle = Number.isFinite(proximity.lastToggleMs) ? proximity.lastToggleMs : 0;\n        const canToggle = (timestamp - lastToggle) >= toggleCooldownMs;\n\n        const object3d = itemEntry.object3d;\n        const isModelAsset = !!object3d?.userData?.modelAsset;\n\n        if (policy.mode === 'unload' && isModelAsset) {\n            if (!proximity.loaded && shouldLoad && canToggle) {\n                this._loadDeferredModel(object3d, itemEntry.data);\n                proximity.loaded = true;\n                proximity.lastToggleMs = timestamp;\n            } else if (proximity.loaded && shouldUnload && canToggle && !this._hasModelPreviewOwner(object3d)) {\n                this._unloadModelAsset(object3d);\n                proximity.loaded = false;\n                proximity.lastToggleMs = timestamp;\n            }\n        }\n\n        const visibleThresholdSq = Number.isFinite(unloadSq) ? unloadSq : loadSq;\n        const shouldShow = gatingVisible && (!Number.isFinite(visibleThresholdSq) || distSq <= visibleThresholdSq);\n        if (object3d && object3d.visible !== shouldShow) {\n            object3d.visible = shouldShow;\n        }\n\n        if (object3d && proximity.loaded !== false && policy.points?.enabled) {\n            const pointsInterval = Number.isFinite(policy.points.updateIntervalMs)\n                ? policy.points.updateIntervalMs\n                : 0;\n            if (!pointsInterval || (timestamp - (proximity.lastPointsUpdateMs || 0) >= pointsInterval)) {\n                proximity.lastPointsUpdateMs = timestamp;\n                const dist = Number.isFinite(distSq) ? Math.sqrt(distSq) : Infinity;\n                this._applyPointCloudFalloff(object3d, policy.points, dist, proximity);\n            }\n        }\n    }\n\n    _refreshProximityPolicies(entry, layerIds = null) {\n        if (!entry) return;\n        const candidates = function* () {\n            if (!Array.isArray(layerIds)) { yield* entry.items.values(); return; }\n            for (const layerId of new Set(layerIds)) yield* entry.layers.get(layerId)?.items?.values() || [];\n        };\n        for (const itemEntry of candidates()) {\n            const layerEntry = entry.layers.get(itemEntry.layerId);\n            const nextPolicy = this._resolveRenderProximity(entry, layerEntry, itemEntry.data);\n            if (nextPolicy) {\n                if (!itemEntry.runtime) itemEntry.runtime = {};\n                const proximityState = itemEntry.runtime.proximity || {};\n                proximityState.policy = nextPolicy;\n                proximityState.loaded = this._resolveLoadedState(itemEntry);\n                itemEntry.runtime.proximity = proximityState;\n                this._proximityItems.set(itemEntry.itemId, itemEntry);\n            } else if (itemEntry.runtime?.proximity) {\n                itemEntry.runtime.proximity = null;\n                this._proximityItems.delete(itemEntry.itemId);\n            }\n        }\n    }\n\n    _resolveLoadedState(itemEntry) {\n        const object3d = itemEntry?.object3d;\n        if (!object3d) return false;\n        if (!object3d.userData?.modelAsset) return true;\n        return !!object3d.userData.modelRoot;\n    }\n\n    _resolveRenderProximity(entry, layerEntry, item) {\n        const isDa3 = this._isDa3Item(item);\n        const overlayPolicy = entry?.doc?.overlay?.render_proximity\n            || entry?.doc?.overlay?.proximity_render\n            || entry?.doc?.overlay?.proximity;\n        const layerPolicy = layerEntry?.data?.render_proximity\n            || layerEntry?.data?.proximity_render\n            || layerEntry?.data?.proximity;\n        const itemPolicy = item?.current?.properties?.render_proximity\n            || item?.current?.properties?.proximity_render;\n\n        let merged = this._mergeRenderProximity(null, overlayPolicy);\n        const inherit = layerEntry?.data?.inherit_policies !== false;\n        if (!inherit) {\n            merged = this._mergeRenderProximity(null, layerPolicy);\n        } else {\n            merged = this._mergeRenderProximity(merged, layerPolicy);\n        }\n        merged = this._mergeRenderProximity(merged, itemPolicy);\n\n        if (!merged && !isDa3) return null;\n\n        const defaults = isDa3 ? {\n            enabled: true,\n            mode: 'unload',\n            loadDistanceM: 1000,\n            unloadDistanceM: 1000,\n            toggleCooldownMs: 750,\n            updateIntervalMs: 200,\n            points: {\n                enabled: true,\n                startM: 200,\n                endM: 1000,\n                minFraction: 0.2,\n                curve: 'inverseSquare',\n                updateIntervalMs: 250\n            }\n        } : null;\n\n        return this._normalizeRenderProximity(merged, defaults);\n    }\n\n    _mergeRenderProximity(base, patch) {\n        if (!patch || typeof patch !== 'object') return base;\n        const next = { ...(base || {}) };\n        for (const [key, value] of Object.entries(patch)) {\n            if (value && typeof value === 'object' && !Array.isArray(value)) {\n                next[key] = { ...(next[key] || {}), ...value };\n            } else {\n                next[key] = value;\n            }\n        }\n        return next;\n    }\n\n    _normalizeRenderProximity(raw, defaults = null) {\n        const source = raw && typeof raw === 'object' ? raw : {};\n        const base = defaults || {};\n        const enabled = this._readBool(source, base, ['enabled', 'render_enabled', 'renderEnabled'], true);\n        if (!enabled) return null;\n\n        const mode = this._readString(source, base, ['mode'], 'hide');\n        const loadDistanceM = this._readNumber(source, base, ['load_distance_m', 'loadDistanceM', 'loadDistance'], null);\n        const unloadDistanceM = this._readNumber(source, base, ['unload_distance_m', 'unloadDistanceM', 'unloadDistance'], null);\n        const updateIntervalMs = this._readNumber(source, base, ['update_interval_ms', 'updateIntervalMs'], null);\n        const toggleCooldownMs = this._readNumber(source, base, ['toggle_cooldown_ms', 'toggleCooldownMs'], null);\n        const points = this._normalizePointFalloff(source.points, base.points || null);\n\n        let loadDist = Number.isFinite(loadDistanceM) ? Math.max(0, loadDistanceM) : null;\n        let unloadDist = Number.isFinite(unloadDistanceM) ? Math.max(0, unloadDistanceM) : null;\n        if (!Number.isFinite(loadDist) && Number.isFinite(points?.endM)) {\n            loadDist = points.endM;\n        }\n        if (!Number.isFinite(unloadDist) && Number.isFinite(loadDist)) {\n            unloadDist = loadDist;\n        }\n\n        return {\n            enabled: true,\n            mode: mode === 'unload' ? 'unload' : 'hide',\n            loadDistanceM: loadDist,\n            unloadDistanceM: unloadDist,\n            loadDistanceSq: Number.isFinite(loadDist) ? loadDist * loadDist : null,\n            unloadDistanceSq: Number.isFinite(unloadDist) ? unloadDist * unloadDist : null,\n            updateIntervalMs: Number.isFinite(updateIntervalMs) ? updateIntervalMs : null,\n            toggleCooldownMs: Number.isFinite(toggleCooldownMs) ? toggleCooldownMs : null,\n            points\n        };\n    }\n\n    _normalizePointFalloff(raw, defaults = null) {\n        if (!raw && !defaults) return null;\n        const source = raw && typeof raw === 'object' ? raw : {};\n        const base = defaults || {};\n        const enabled = this._readBool(source, base, ['enabled'], false);\n        if (!enabled) return null;\n        const startM = this._readNumber(source, base, ['start_m', 'startM'], 0);\n        const endM = this._readNumber(source, base, ['end_m', 'endM'], null);\n        const minFraction = this._readNumber(source, base, ['min_fraction', 'minFraction'], 0);\n        const curve = this._readString(source, base, ['curve'], 'linear');\n        const updateIntervalMs = this._readNumber(source, base, ['update_interval_ms', 'updateIntervalMs'], null);\n        return {\n            enabled: true,\n            startM: Number.isFinite(startM) ? Math.max(0, startM) : 0,\n            endM: Number.isFinite(endM) ? Math.max(0, endM) : null,\n            minFraction: Number.isFinite(minFraction) ? Math.max(0, Math.min(1, minFraction)) : 0,\n            curve,\n            updateIntervalMs: Number.isFinite(updateIntervalMs) ? updateIntervalMs : null\n        };\n    }\n\n    _readNumber(source, fallback, keys, defaultValue) {\n        for (const key of keys) {\n            const value = source?.[key];\n            if (Number.isFinite(value)) return value;\n        }\n        for (const key of keys) {\n            const value = fallback?.[key];\n            if (Number.isFinite(value)) return value;\n        }\n        return defaultValue;\n    }\n\n    _readBool(source, fallback, keys, defaultValue) {\n        for (const key of keys) {\n            const value = source?.[key];\n            if (typeof value === 'boolean') return value;\n        }\n        for (const key of keys) {\n            const value = fallback?.[key];\n            if (typeof value === 'boolean') return value;\n        }\n        return defaultValue;\n    }\n\n    _readString(source, fallback, keys, defaultValue) {\n        for (const key of keys) {\n            const value = source?.[key];\n            if (typeof value === 'string' && value.length) return value;\n        }\n        for (const key of keys) {\n            const value = fallback?.[key];\n            if (typeof value === 'string' && value.length) return value;\n        }\n        return defaultValue;\n    }\n\n    _resolveVisibilityFlag(source, defaultValue = true) {\n        return this._readBool(source, null, ['visible', 'render_enabled', 'renderEnabled'], defaultValue);\n    }\n\n    _isDa3Item(item) {\n        return isDa3ScanItem(item);\n    }\n\n    _getItemWorldPosition(itemEntry, out) {\n        if (!itemEntry || !out) return null;\n        if (itemEntry.object3d) {\n            return itemEntry.object3d.getWorldPosition(out);\n        }\n        const itemData = itemEntry.runtime?.effectiveItem || itemEntry.data;\n        const local = this._resolveItemPositionFast(itemData, this._proximityTmpVec2);\n        if (!local) return null;\n        if (this.triTree?.group && typeof this.triTree.group.localToWorld === 'function') {\n            out.copy(local);\n            return this.triTree.group.localToWorld(out);\n        }\n        return out.copy(local);\n    }\n\n    _resolveItemPositionFast(item, out) {\n        const current = item?.current || {};\n        const geom = current.geom;\n        if (geom?.type === 'Point' && Array.isArray(geom.coordinates)) {\n            const lon = geom.coordinates[0];\n            const lat = geom.coordinates[1];\n            const da3SurfaceRelative = resolveDa3HeightMode(item) === 'surface_agl';\n            const offset = da3SurfaceRelative\n                ? resolveDa3AnchorAglM(item)\n                : Number.isFinite(current.properties?.offset_m)\n                    ? current.properties.offset_m\n                    : this._defaultOffsetM;\n            const dir = latLonToLocalDir(lat, lon);\n            const baseRadius = ellipsoidRadiusForLocalDir(dir);\n            const elevation = Number.isFinite(current.elevation_m) ? current.elevation_m : 0;\n            const distance = baseRadius + elevation + offset;\n            if (out) return out.copy(dir).multiplyScalar(distance);\n            return dir.multiplyScalar(distance);\n        }\n        if (current.position && Number.isFinite(current.position.x)) {\n            if (out) return out.set(current.position.x, current.position.y, current.position.z);\n            return new THREE.Vector3(current.position.x, current.position.y, current.position.z);\n        }\n        return null;\n    }\n\n    _applyPointCloudFalloff(object3d, pointsPolicy, distance, proximityState) {\n        if (!object3d || !pointsPolicy || !pointsPolicy.enabled) return;\n        if (!Number.isFinite(pointsPolicy.endM)) return;\n        const startM = Number.isFinite(pointsPolicy.startM) ? pointsPolicy.startM : 0;\n        const endM = pointsPolicy.endM;\n        if (distance <= startM) {\n            this._applyPointCloudFraction(object3d, 1, proximityState);\n            return;\n        }\n        if (distance >= endM) {\n            this._applyPointCloudFraction(object3d, pointsPolicy.minFraction, proximityState);\n            return;\n        }\n\n        const t = Math.min(1, Math.max(0, (distance - startM) / Math.max(1, endM - startM)));\n        let fraction;\n        const curve = String(pointsPolicy.curve || 'linear').toLowerCase();\n        if (curve === 'inversesquare' || curve === 'inverse-square' || curve === 'inverse_square') {\n            const minF = pointsPolicy.minFraction ?? 0;\n            const k = minF > 0 ? (1 / Math.max(1e-4, minF)) - 1 : 8;\n            const inv = 1 / (1 + k * t * t);\n            fraction = minF + (1 - minF) * inv;\n        } else if (curve === 'smoothstep') {\n            const smooth = t * t * (3 - 2 * t);\n            fraction = 1 - (1 - (pointsPolicy.minFraction ?? 0)) * smooth;\n        } else {\n            fraction = 1 - (1 - (pointsPolicy.minFraction ?? 0)) * t;\n        }\n        this._applyPointCloudFraction(object3d, fraction, proximityState);\n    }\n\n    _applyPointCloudFraction(object3d, fraction, proximityState) {\n        const clamped = Math.max(0, Math.min(1, Number.isFinite(fraction) ? fraction : 1));\n        const prev = Number.isFinite(proximityState?.pointsFraction) ? proximityState.pointsFraction : null;\n        if (prev !== null && Math.abs(prev - clamped) < 0.02) return;\n        if (proximityState) proximityState.pointsFraction = clamped;\n\n        const nodes = this._getPointCloudNodes(object3d);\n        if (!nodes || !nodes.length) return;\n        for (const points of nodes) {\n            const geom = points.geometry;\n            if (!geom) continue;\n            const original = this._getPointCloudDrawRange(geom);\n            if (!original) continue;\n            const targetCount = Math.max(1, Math.floor(original.count * clamped));\n            if (geom.drawRange.count !== targetCount || geom.drawRange.start !== original.start) {\n                geom.setDrawRange(original.start, targetCount);\n            }\n        }\n    }\n\n    _getPointCloudNodes(object3d) {\n        if (!object3d) return null;\n        if (object3d.userData?.pointCloudNodes) return object3d.userData.pointCloudNodes;\n        const nodes = [];\n        object3d.traverse?.((child) => {\n            if (child?.isPoints) {\n                nodes.push(child);\n            }\n        });\n        object3d.userData.pointCloudNodes = nodes;\n        return nodes;\n    }\n\n    _getPointCloudDrawRange(geometry) {\n        if (!geometry) return null;\n        const cached = geometry.userData?.proximityDrawRange;\n        if (cached) return cached;\n        const indexCount = geometry.index ? geometry.index.count : null;\n        const positionCount = geometry.attributes?.position?.count ?? null;\n        const total = Number.isFinite(indexCount)\n            ? indexCount\n            : (Number.isFinite(positionCount) ? positionCount : null);\n        if (!Number.isFinite(total)) return null;\n        const start = Number.isFinite(geometry.drawRange?.start) ? geometry.drawRange.start : 0;\n        const count = Number.isFinite(geometry.drawRange?.count)\n            ? Math.min(total, geometry.drawRange.count)\n            : total;\n        const range = { start, count };\n        if (!geometry.userData) geometry.userData = {};\n        geometry.userData.proximityDrawRange = range;\n        return range;\n    }\n\n    retainItemModelPreview(overlayId, itemId) {\n        const entry = this.overlays.get(overlayId), record = entry?.items?.get(itemId);\n        const group = record?.object3d?.userData?.modelContainer || record?.object3d;\n        if (!entry || entry.retiring || this._disposed || !group?.userData?.modelAsset || group.userData.modelDisposed) return () => {};\n        this._session?.assert(entry.sessionScope);\n        const owners = this._modelPreviewOwners ||= new WeakMap();\n        let leases = owners.get(group);\n        if (!leases) owners.set(group, leases = new Set());\n        const token = {}; leases.add(token);\n        const signal = entry.sessionScope?.signal;\n        const release = () => {\n            if (!leases.delete(token)) return;\n            signal?.removeEventListener('abort', release);\n            // Refresh replaces its pin synchronously. Only a real close/hide\n            // may cancel a solely preview-owned, distant pending download.\n            queueMicrotask(() => {\n                const proximity = record.runtime?.proximity;\n                if (!leases.size && !group.userData.modelDisposed && record.object3d === group\n                    && group.userData.modelLoading && proximity?.policy?.mode === 'unload'\n                    && proximity.lastDistanceSq > proximity.policy.unloadDistanceSq) {\n                    this._unloadModelAsset(group); proximity.loaded = false;\n                }\n            });\n        };\n        signal?.addEventListener('abort', release, { once: true });\n        return release;\n    }\n\n    _hasModelPreviewOwner(group) {\n        return (this._modelPreviewOwners?.get(group)?.size || 0) > 0;\n    }\n\n    loadItemModel(overlayId, itemId, { retry = false } = {}) {\n        const entry = this.overlays.get(overlayId), record = entry?.items?.get(itemId);\n        if (!entry || entry.retiring || !record || this._disposed) return;\n        this._session?.assert(entry.sessionScope);\n        const group = record.object3d?.userData?.modelContainer || record.object3d;\n        if (!group?.userData?.modelAsset || group.userData.modelDisposed) return;\n        if (retry && !group.userData.modelLoading) {\n            this._unavailableModelUrls.delete(group.userData.modelUrl);\n            delete group.userData.modelUnavailableUrl;\n            delete group.userData.modelLoadError;\n        }\n        return this._loadDeferredModel(group, record.runtime?.effectiveItem || record.data);\n    }\n\n    _loadDeferredModel(group, item) {\n        if (!group || !group.userData?.modelAsset) return;\n        if (this._cameraExclusiveState) {\n            group.userData.modelLoadWanted = true;\n            group.userData.modelLoadItem = item;\n            group.userData.modelDeferred = true;\n            return;\n        }\n        if (group.userData.modelRoot || group.userData.modelLoading) return;\n        const url = group.userData.modelUrl || resolveItemModelUrl(item);\n        if (!url) return;\n        const retryAt = this._unavailableModelUrls.get(url) || 0;\n        if (retryAt > Date.now()) return;\n        if (retryAt) this._unavailableModelUrls.delete(url);\n        if (group.userData.modelUnavailableUrl === url) delete group.userData.modelUnavailableUrl;\n        if (url.startsWith('/api/files/') || url.includes('/api/files/')) {\n            return this._loadAuthenticatedModel(url, group, item);\n        } else {\n            return this._startModelLoad(url, group, item, false);\n        }\n    }\n\n    _unloadModelAsset(group) {\n        if (!group || !group.userData?.modelAsset) return;\n        this._invalidateModelLoad(group);\n        const children = Array.from(group.children || []);\n        for (const child of children) {\n            if (child?.userData?.keepOnUnload) continue;\n            if (child.parent) {\n                child.parent.remove(child);\n            }\n            this._disposeObject(child);\n        }\n        group.userData.modelRoot = null;\n        group.userData.pointCloudNodes = null;\n        group.dispatchEvent({ type: 'model-unloaded' });\n    }\n\n    _setItemLoadedState(itemId, loaded) {\n        if (!itemId) return;\n        for (const entry of this.overlays.values()) {\n            const itemEntry = entry.items.get(itemId);\n            if (!itemEntry?.runtime?.proximity) continue;\n            itemEntry.runtime.proximity.loaded = !!loaded;\n            return;\n        }\n    }\n\n    _mergeItemProperties(item, overrides) {\n        if (!overrides || !Object.keys(overrides).length) return item;\n        const current = item?.current || {};\n        const baseProps = current.properties || {};\n        const mergedProps = { ...baseProps, ...overrides };\n        return {\n            ...item,\n            current: {\n                ...current,\n                properties: mergedProps\n            }\n        };\n    }\n\n    _hashString(value) {\n        let hash = 5381;\n        for (let i = 0; i < value.length; i += 1) {\n            hash = ((hash << 5) + hash) ^ value.charCodeAt(i);\n        }\n        return (hash >>> 0).toString(16);\n    }\n\n    _resolveItemId(item, layerId) {\n        if (!item) return null;\n        if (item.item_id) return item.item_id;\n        if (item.itemId) return item.itemId;\n        if (item.id) return item.id;\n\n        const current = item.current || {};\n        const props = current.properties || {};\n        const scanId = props.scan_id || props.job_id || props.source_id || props.id;\n        if (scanId) {\n            return `${layerId || 'layer'}:${String(scanId)}`;\n        }\n\n        const seedParts = [];\n        if (layerId) seedParts.push(`layer:${layerId}`);\n\n        const geom = current.geom;\n        if (geom?.type && Array.isArray(geom.coordinates)) {\n            seedParts.push(`geom:${geom.type}:${geom.coordinates.join(',')}`);\n        }\n        if (current.position && Number.isFinite(current.position.x)) {\n            seedParts.push(`pos:${current.position.x},${current.position.y},${current.position.z}`);\n        }\n        const modelUrl = resolveItemModelUrl(item);\n        if (modelUrl) seedParts.push(`model:${modelUrl}`);\n\n        if (!seedParts.length) {\n            const label = props.label || props.name;\n            if (label) seedParts.push(`label:${String(label)}`);\n        }\n\n        if (!seedParts.length) return null;\n        return `item-${this._hashString(seedParts.join('|'))}`;\n    }\n\n    _applyItemGeoState(entry, itemEntry, overrides, visible) {\n        if (!entry || !itemEntry) return;\n        const reviewPreview = this._isPlacementReviewItem(entry, itemEntry);\n        const motionPreview = itemEntry.runtime?.motionPreviewItem;\n        const baseItem = motionPreview || (reviewPreview && itemEntry.runtime?.reviewPreviewItem\n            ? itemEntry.runtime.reviewPreviewItem\n            : itemEntry.data);\n        const effectiveItem = this._mergeItemProperties(baseItem, overrides);\n        const previous = itemEntry.runtime?.effectiveItem || baseItem;\n        const propertyVisible = this._resolveVisibilityFlag(effectiveItem?.current?.properties, true);\n        const nextVisible = !!visible && (propertyVisible !== false || reviewPreview);\n\n        const renderSignature = this._getRenderSignature(effectiveItem);\n        if ((itemEntry.runtime?.renderSignature ?? this._getRenderSignature(previous)) !== renderSignature) {\n            this._rebuildItemWithEffective(entry, itemEntry, effectiveItem);\n        } else if (previous !== effectiveItem) {\n            this._applyItemTransform(itemEntry.object3d, effectiveItem);\n            this._applyItemAppearance(itemEntry.object3d, effectiveItem);\n            const updateHook = itemEntry.object3d?.userData?.updateItem;\n            if (typeof updateHook === 'function') {\n                updateHook(effectiveItem, itemEntry.object3d);\n            }\n        }\n\n        if (itemEntry.object3d) {\n            itemEntry.object3d.visible = nextVisible;\n            if (itemEntry.object3d.userData?.modelAsset) {\n                const proximity = itemEntry.runtime?.proximity;\n                const unloadMode = proximity?.policy?.mode === 'unload';\n                if (!nextVisible && !this._hasModelPreviewOwner(itemEntry.object3d)) {\n                    this._unloadModelAsset(itemEntry.object3d);\n                    if (proximity) proximity.loaded = false;\n                } else if (!unloadMode && !itemEntry.object3d.userData?.modelRoot) {\n                    this._loadDeferredModel(itemEntry.object3d, effectiveItem);\n                    if (proximity) proximity.loaded = true;\n                }\n            }\n        }\n        itemEntry.runtime = {\n            ...(itemEntry.runtime || {}),\n            effectiveItem,\n            renderSignature,\n            visible: nextVisible\n        };\n        this._syncSurfaceAnchorRegistration(itemEntry, 'geo-state');\n    }\n\n    _rebuildItemWithEffective(entry, itemEntry, effectiveItem) {\n        const layerEntry = entry.layers.get(itemEntry.layerId);\n        if (!layerEntry) return;\n        const onRemove = itemEntry.object3d?.userData?.onRemove;\n        if (typeof onRemove === 'function') {\n            try {\n                onRemove(itemEntry.data);\n            } catch (error) {\n                this.eventBus?.emit('overlay:error', { overlayId: entry.overlayId, error });\n            }\n        }\n        if (itemEntry.object3d?.parent) {\n            itemEntry.object3d.parent.remove(itemEntry.object3d);\n        }\n        this._disposeObject(itemEntry.object3d);\n        const proximityPolicy = this._resolveRenderProximity(entry, layerEntry, effectiveItem);\n        const isModelAsset = effectiveItem.item_type === 'model3d' && !!resolveItemModelUrl(effectiveItem);\n        const deferModelLoad = !!(proximityPolicy && proximityPolicy.mode === 'unload' && isModelAsset);\n        const rendered = this._renderItem(entry, effectiveItem, layerEntry.data, { deferModelLoad });\n        if (rendered) {\n            layerEntry.group.add(rendered);\n            itemEntry.object3d = rendered;\n        }\n        if (!itemEntry.runtime) itemEntry.runtime = {};\n        itemEntry.runtime.effectiveItem = effectiveItem;\n        if (proximityPolicy) {\n            itemEntry.runtime.proximity = {\n                policy: proximityPolicy,\n                loaded: !deferModelLoad,\n                pointsFraction: null,\n                lastToggleMs: 0,\n                nextUpdate: 0\n            };\n            this._proximityItems.set(itemEntry.itemId, itemEntry);\n        } else if (itemEntry.runtime.proximity) {\n            itemEntry.runtime.proximity = null;\n            this._proximityItems.delete(itemEntry.itemId);\n        }\n        this._syncSurfaceAnchorRegistration(itemEntry, 'item-rebuild');\n        this.eventBus?.emit('overlay:asset-replaced', { overlayId: entry.overlayId, itemId: itemEntry.itemId });\n    }\n\n    _appendPageLayer(entry, layer) {\n        const layerId = layer?.layer_id || layer?.name || `layer-${Math.random()}`;\n        if (!this._canViewLayer(layerId) || entry.layers.has(layerId)) return;\n        const layerGroup = new THREE.Group(); layerGroup.name = `OverlayLayer:${layerId}`;\n        entry.group.add(layerGroup);\n        const layerEntry = { group: layerGroup, data: layer, renderer: null, items: new Map() };\n        entry.layers.set(layerId, layerEntry); this._initLayerRenderer(entry, layerEntry);\n    }\n\n    async _buildOverlay(entry, signal) {\n        const layers = Array.isArray(entry.doc?.layers) ? entry.doc.layers : [];\n        this._bulkBuildDepth = (this._bulkBuildDepth || 0) + 1;\n        try {\n        for (const layer of layers) {\n            signal?.throwIfAborted();\n            if (entry.retiring || this._disposed) throw new DOMException('Unloaded', 'AbortError');\n            const layerId = layer?.layer_id || layer?.name || `layer-${Math.random()}`;\n            if (!layer.layer_id) layer.layer_id = layerId;\n            this._appendPageLayer(entry, layer);\n            const items = Array.isArray(layer?.items) ? layer.items : [];\n            await forOverlayAdmission(this, items, item => {\n                if (entry.retiring || this._disposed) throw new DOMException('Unloaded', 'AbortError');\n                this._addItem(entry, layerId, item);\n            }, signal);\n            await yieldToEventLoop();\n        }\n        } finally { this._bulkBuildDepth--; }\n        this._requestGeoRefresh();\n    }\n\n    _syncOverlay(entry, patch, { replaceLayers = false } = {}) {\n        if (!patch.layers) return;\n        const layers = Array.isArray(patch.layers) ? patch.layers : [];\n        const documents = new Map((entry.doc?.layers || []).map(layer => [layer?.layer_id || layer?.name, layer]));\n        for (const layer of layers) {\n            const layerId = layer?.layer_id || layer?.name;\n            if (!layerId) continue;\n            let layerEntry = entry.layers.get(layerId);\n            if (!layerEntry) {\n                const layerGroup = new THREE.Group();\n                layerGroup.name = `OverlayLayer:${layerId}`;\n                entry.group.add(layerGroup);\n                layerEntry = { group: layerGroup, data: documents.get(layerId) || layer, renderer: null, items: new Map() };\n                entry.layers.set(layerId, layerEntry);\n                this._initLayerRenderer(entry, layerEntry);\n            } else if (layer) {\n                layerEntry.data = documents.get(layerId) || layerEntry.data;\n                if (Object.keys(layer).some(key => !['layer_id', 'items'].includes(key))) this._updateLayerRenderer(entry, layerEntry);\n            }\n\n            const items = Array.isArray(layer?.items) ? layer.items : [];\n            for (const item of items) {\n                this._updateItem(entry, layerId, item);\n            }\n\n            if (replaceLayers && Array.isArray(layer?.items)) {\n                const nextIds = new Set();\n                for (const item of items) {\n                    const id = this._resolveItemId(item, layerId);\n                    if (id) {\n                        if (!item.item_id) item.item_id = id;\n                        nextIds.add(id);\n                    }\n                }\n                for (const [itemId] of layerEntry.items) {\n                    if (!nextIds.has(itemId)) {\n                        this._removeItem(entry, itemId);\n                    }\n                }\n            }\n        }\n        this._requestGeoRefresh();\n    }\n\n    _addItem(entry, layerId, item) {\n        if (!item || !layerId) return;\n        const itemId = this._resolveItemId(item, layerId);\n        if (!itemId) {\n            console.warn('[OverlaySubsystem] Item missing stable id; skipping add.', item);\n            return;\n        }\n        if (!item.item_id) item.item_id = itemId;\n        const layerEntry = entry.layers.get(layerId);\n        if (!layerEntry) return;\n\n        if (!this._canViewItem(item)) {\n            return;\n        }\n\n        const proximityPolicy = this._resolveRenderProximity(entry, layerEntry, item);\n        const isModelAsset = item.item_type === 'model3d' && !!resolveItemModelUrl(item);\n        const propertyVisible = this._resolveVisibilityFlag(item?.current?.properties, true);\n        const reviewPreview = this._isPlacementReviewItem(entry, item);\n        const deferModelLoad = !!(\n            (proximityPolicy && proximityPolicy.mode === 'unload' && isModelAsset)\n            || (isModelAsset && propertyVisible === false && !reviewPreview)\n        );\n        const rendered = this._renderItem(entry, item, layerEntry.data, { deferModelLoad });\n        if (!rendered) return;\n        rendered.visible = propertyVisible !== false || reviewPreview;\n        layerEntry.group.add(rendered);\n        const runtime = { effectiveItem: item, renderSignature: this._getRenderSignature(item) };\n        if (proximityPolicy) {\n            runtime.proximity = {\n                policy: proximityPolicy,\n                loaded: !deferModelLoad,\n                pointsFraction: null,\n                lastToggleMs: 0,\n                nextUpdate: 0\n            };\n        }\n        const itemEntry = {\n            itemId,\n            object3d: rendered,\n            data: item,\n            layerId,\n            runtime,\n            overlayEntry: entry\n        };\n        entry.items.set(itemId, itemEntry);\n        layerEntry.items ||= new Map();\n        layerEntry.items.set(itemId, itemEntry);\n        entry.splineItems ||= new Map();\n        if (item.item_type === 'spline') entry.splineItems.set(itemId, itemEntry);\n        else entry.splineItems.delete(itemId);\n        this._syncSurfaceAnchorRegistration(itemEntry, 'item-created');\n        const updateHook = rendered.userData?.updateItem;\n        if (typeof updateHook === 'function') {\n            updateHook(item, rendered);\n        }\n\n        // Setup proximity triggers if configured\n        this._setupProximityTriggers(itemId, rendered, item);\n\n        // Setup physics if configured\n        this._setupPhysics(itemId, rendered, item);\n\n        // Setup click triggers if configured\n        this._setupClickTriggers(itemId, rendered, item);\n        this._setupMediaPlayback(itemId, rendered, item);\n\n        this._refreshSplineReferences(entry, itemId);\n        this._requestGeoRefresh();\n\n        if (runtime.proximity) {\n            this._proximityItems.set(itemId, itemEntry);\n            if (this._proximityHasObserver) {\n                this._updateItemProximity(itemEntry, this._proximityObserver, performance.now());\n            }\n        }\n    }\n\n    _updateItem(entry, layerId, item) {\n        if (!item || !layerId) return;\n        const itemId = item.item_id || this._resolveItemId(item, layerId);\n        if (!itemId) return;\n        if (!item.item_id) item.item_id = itemId;\n        if (this._shouldRemoveItem(item)) {\n            this._removeItem(entry, itemId);\n            return;\n        }\n        const existing = entry.items.get(itemId);\n        if (!existing) {\n            this._addItem(entry, layerId, item);\n            return;\n        }\n\n        if (!this._canUpdateItem(item)) {\n            return;\n        }\n\n        existing.data = this._mergeOverlayDoc(existing.data, item);\n\n        // Compose authored edits beneath an active motion preview instead of\n        // clobbering it (or later restoring an obsolete pre-edit snapshot).\n        const layerEntry = entry.layers.get(layerId);\n        const visible = entry.group?.visible !== false && layerEntry?.group?.visible !== false;\n        this._applyItemGeoState(entry, existing, null, visible);\n\n        // Re-setup triggers when item properties change (hot-reload)\n        this._refreshTriggers(itemId, existing.object3d, existing.data);\n\n        const nextPolicy = this._resolveRenderProximity(entry, layerEntry, existing.data);\n        if (nextPolicy) {\n            if (!existing.runtime) existing.runtime = {};\n            const proximityState = existing.runtime.proximity || {};\n            proximityState.policy = nextPolicy;\n            proximityState.loaded = this._resolveLoadedState(existing);\n            existing.runtime.proximity = proximityState;\n            this._proximityItems.set(itemId, existing);\n        } else if (existing.runtime?.proximity) {\n            existing.runtime.proximity = null;\n            this._proximityItems.delete(itemId);\n        }\n\n        if (existing.data?.item_type !== 'spline') {\n            this._refreshSplineReferences(entry, itemId);\n        }\n        this._requestGeoRefresh();\n    }\n\n    _initLayerRenderer(entry, layerEntry) {\n        if (!layerEntry || !this.registry) return;\n        const layerData = layerEntry.data || {};\n        const layerType = layerData.layer_type || layerData.layerType || null;\n        const hasSourceRef = !!(layerData.source_ref || layerData.sourceRef);\n        let rendererFactory = layerType ? this.registry.getLayerRenderer(layerType) : null;\n        if (!rendererFactory && hasSourceRef) {\n            rendererFactory = this.registry.getLayerRenderer('data_source');\n        }\n        if (!rendererFactory) return;\n\n        if (layerEntry.renderer && typeof layerEntry.renderer.dispose === 'function') {\n            try {\n                layerEntry.renderer.dispose();\n            } catch (error) {\n                this.eventBus?.emit('overlay:error', { overlayId: entry.overlayId, error });\n            }\n        }\n\n        try {\n            layerEntry.renderer = rendererFactory({\n                overlay: entry,\n                layer: layerData,\n                group: layerEntry.group,\n                scene: this.scene,\n                parentGroup: this.parentGroup,\n                camera: this.camera,\n                planetRadius: this.planetRadius,\n                triTree: this.triTree,\n                eventBus: this.eventBus,\n                sceneInitializer: this.sceneInitializer,\n                assets: this.assets,\n                access: this.access,\n            });\n        } catch (error) {\n            this.eventBus?.emit('overlay:error', { overlayId: entry.overlayId, error });\n        }\n    }\n\n    _updateLayerRenderer(entry, layerEntry) {\n        if (!layerEntry?.renderer) {\n            this._initLayerRenderer(entry, layerEntry);\n            return;\n        }\n        try {\n            layerEntry.renderer.update?.({\n                overlay: entry,\n                layer: layerEntry.data,\n            });\n        } catch (error) {\n            this.eventBus?.emit('overlay:error', { overlayId: entry.overlayId, error });\n        }\n    }\n\n    _shouldRemoveItem(item) {\n        if (!item) return false;\n        if (item._remove || item.remove || item.deleted) return true;\n        if (item.state && String(item.state).toLowerCase() === 'removed') return true;\n        return false;\n    }\n\n    _removeItem(entry, itemId) {\n        if (!entry || !itemId) return;\n        const existing = entry.items.get(itemId);\n        if (!existing) return;\n\n        this._proximityItems.delete(itemId);\n        this._removeSurfaceAnchorRegistration(entry.overlayId, itemId);\n\n        // Remove proximity triggers\n        if (this.proximityTriggerManager) {\n            this.proximityTriggerManager.removeTrigger(itemId);\n            this.proximityTriggerManager.removeTrigger(`${itemId}-physics-spawn`);\n            this.proximityTriggerManager.removeTrigger(`${itemId}-media`);\n        }\n\n        // Remove physics\n        if (this.physicsSystem && existing.object3d?.userData?.hasPhysics) {\n            this.physicsSystem.removePhysicsObject(existing.object3d);\n        }\n\n        // Remove click triggers\n        if (this.clickTriggerManager) {\n            this.clickTriggerManager.removeTrigger(itemId);\n            this.clickTriggerManager.removeTrigger(`${itemId}-media`);\n        }\n\n        const onRemove = existing.object3d?.userData?.onRemove;\n        if (typeof onRemove === 'function') {\n            try {\n                onRemove(existing.data);\n            } catch (error) {\n                this.eventBus?.emit('overlay:error', { overlayId: entry.overlayId, error });\n            }\n        }\n        if (existing.object3d?.parent) {\n            existing.object3d.parent.remove(existing.object3d);\n        }\n        this._disposeObject(existing.object3d);\n        entry.items.delete(itemId);\n        entry.splineItems?.delete(itemId);\n        const layerEntry = entry.layers.get(existing.layerId);\n        layerEntry?.items?.delete(itemId);\n        if (!entry.retiring && layerEntry?.data?.items && Array.isArray(layerEntry.data.items)) {\n            layerEntry.data.items = layerEntry.data.items.filter((it) => it?.item_id !== itemId);\n        }\n        if (!entry.retiring) this._refreshSplineReferences(entry, itemId);\n    }\n\n    _renderItem(entry, item, layer, options = {}) {\n        if (!this._canViewItem(item)) {\n            return null;\n        }\n        if (item.item_type === 'model3d' && this._isAssetBlocked(item)) {\n            return null;\n        }\n        const renderer = this.registry?.getItemRenderer?.(item.item_type);\n        if (renderer) {\n            return renderer(item, layer);\n        }\n\n        if (item.item_type === 'spline') {\n            return this._renderSpline(entry, item);\n        }\n        if (item.item_type === 'annotation') {\n            return this._renderAnnotation(item);\n        }\n        if (item.item_type === 'point') {\n            return this._renderPoint(item);\n        }\n        if (item.item_type === 'model3d') {\n            const shape = item?.current?.properties?.shape;\n            if (shape === 'column') {\n                return this._renderColumn(item);\n            }\n            if (shape === 'anchor') {\n                return this._renderAnchor(item);\n            }\n            if (shape === 'sphere') {\n                return this._renderSphere(item);\n            }\n            const modelUrl = resolveItemModelUrl(item);\n            if (modelUrl) {\n                const deferModelLoad = !!options.deferModelLoad;\n                return this._renderModelAsset(item, modelUrl, { deferModelLoad, owner: entry });\n            }\n            return this._renderModelPlaceholder(item);\n        }\n\n        return null;\n    }\n\n    _renderSpline(entry, item) {\n        if (!this.splineSubsystem) {\n            console.warn('[OverlaySubsystem] SplineSubsystem not available');\n            return null;\n        }\n\n        const config = this._getSplineConfig(entry, item);\n        const result = this.splineSubsystem.createSpline({\n            id: item.item_id,\n            ...config\n        });\n\n        if (result && result.spline && result.spline.line) {\n            const line = result.spline.line;\n            line.userData.itemId = item.item_id;\n            line.userData.splineInstance = result.spline;\n            line.userData.isSpline = true;\n            line.userData.updateItem = (nextItem) => {\n                this._updateSplineItem(entry, nextItem, line);\n            };\n            line.userData.onRemove = () => {\n                this.splineSubsystem?.removeSpline?.(item.item_id);\n            };\n            return line;\n        }\n\n        return null;\n    }\n\n    _enableShadows(object3d) {\n        if (!object3d) return;\n        object3d.traverse((child) => {\n            if (!child.isMesh) return;\n            child.castShadow = true;\n            child.receiveShadow = true;\n        });\n    }\n\n    _getSplineConfig(entry, item) {\n        const props = item?.current?.properties || {};\n        const start = this._resolveSplineEndpoint(entry, item, 'start') || { lat: 0, lon: 0, elevation: 0 };\n        const end = this._resolveSplineEndpoint(entry, item, 'end') || { lat: 0, lon: 0, elevation: 0 };\n        return {\n            startLat: start.lat,\n            startLon: start.lon,\n            startElevation: Number.isFinite(start.elevation) ? start.elevation : 0,\n            endLat: end.lat,\n            endLon: end.lon,\n            endElevation: Number.isFinite(end.elevation) ? end.elevation : 0,\n            arcType: props.arcType || 'auto',\n            apexHeight: props.apexHeight,\n            apexHeightMin: props.apexHeightMin,\n            apexHeightMax: props.apexHeightMax,\n            color: props.color || '#00ffff',\n            opacity: props.opacity !== undefined ? props.opacity : 0.8,\n            lineWidth: Number.isFinite(props.lineWidth) ? props.lineWidth : 2,\n            marchingAnts: props.marchingAnts === true,\n            marchingSpeed: Number.isFinite(props.marchingSpeed) ? props.marchingSpeed : 1.0,\n            flowDirection: Number.isFinite(props.flowDirection) ? props.flowDirection : 1,\n            segments: Number.isFinite(props.segments) ? props.segments : 64\n        };\n    }\n\n    _updateSplineItem(entry, item, object3d) {\n        const spline = object3d?.userData?.splineInstance || object3d?.userData?.spline;\n        if (!spline || typeof spline.updateProperties !== 'function') return;\n        spline.updateProperties(this._getSplineConfig(entry, item));\n    }\n\n    _resolveSplineEndpoint(entry, item, prefix) {\n        const props = item?.current?.properties || {};\n        const refKey = prefix === 'start' ? props.startItemId : props.endItemId;\n        if (refKey) {\n            const refItem = this._findEntryItem(entry, refKey);\n            const coords = this._extractItemLatLon(refItem);\n            if (coords) return coords;\n        }\n        const lat = prefix === 'start' ? props.startLat : props.endLat;\n        const lon = prefix === 'start' ? props.startLon : props.endLon;\n        const elevation = prefix === 'start' ? props.startElevation : props.endElevation;\n        if (!Number.isFinite(lat) || !Number.isFinite(lon)) return null;\n        return {\n            lat,\n            lon,\n            elevation: Number.isFinite(elevation) ? elevation : 0\n        };\n    }\n\n    _findEntryItem(entry, itemId) {\n        if (!entry || !itemId) return null;\n        const existing = entry.items.get(itemId);\n        if (existing?.data) return existing.data;\n        const layers = Array.isArray(entry.doc?.layers) ? entry.doc.layers : [];\n        for (const layer of layers) {\n            const items = Array.isArray(layer?.items) ? layer.items : [];\n            const match = items.find((candidate) => candidate?.item_id === itemId);\n            if (match) return match;\n        }\n        return null;\n    }\n\n    _extractItemLatLon(item) {\n        const geom = item?.current?.geom;\n        if (geom?.type === 'Point' && Array.isArray(geom.coordinates)) {\n            const lon = geom.coordinates[0];\n            const lat = geom.coordinates[1];\n            if (!Number.isFinite(lat) || !Number.isFinite(lon)) return null;\n            const elevation = Number.isFinite(item?.current?.elevation_m) ? item.current.elevation_m : 0;\n            return { lat, lon, elevation };\n        }\n        return null;\n    }\n\n    _refreshSplineReferences(entry, itemId) {\n        if (!entry || !itemId) return;\n        for (const existing of (entry.splineItems || entry.items).values()) {\n            const data = existing?.data;\n            if (!data || data.item_type !== 'spline') continue;\n            const props = data.current?.properties || {};\n            if (props.startItemId === itemId || props.endItemId === itemId) {\n                this._updateSplineItem(entry, data, existing.object3d);\n            }\n        }\n    }\n\n    _renderPoint(item) {\n        const diameter = Number.isFinite(item?.current?.properties?.size_m)\n            ? item.current.properties.size_m\n            : this._pointRadius * 2;\n        const radius = diameter * 0.5;\n        const geom = new THREE.SphereGeometry(radius, 16, 16);\n        const color = item?.current?.properties?.color || '#ffffff';\n        const mat = new THREE.MeshStandardMaterial({ color });\n        const mesh = new THREE.Mesh(geom, mat);\n        mesh.name = `OverlayPoint:${item.item_id || 'point'}`;\n        this._enableShadows(mesh);\n        this._applyItemTransform(mesh, item);\n        mesh.userData.itemId = item.item_id;\n        mesh.userData.point = true;\n        return mesh;\n    }\n\n    _renderAnnotation(item) {\n        const props = item?.current?.properties || {};\n\n        // Account notes already have a canonical, private LabelSystem owner in\n        // AccountNoteLayer. Rendering their backing overlay item here creates a\n        // second label that cannot share the note category lifecycle.\n        if (props.accountNote === true) return null;\n\n        // An annotation without authored copy has no visual label. Never invent\n        // the old generic \"Annotation\" fallback: besides being meaningless, the\n        // legacy canvas sprite rendered it at planet-relative kilometre scale.\n        const label = String(props.label || props.name || '').replace(/\\s+/g, ' ').trim();\n        if (!label) return null;\n\n        const description = String(props.description || '').trim();\n        const objectRadius = Number.isFinite(props.object_radius_m)\n            ? THREE.MathUtils.clamp(props.object_radius_m, 1, 10_000)\n            : 8;\n        const maxDistance = Number.isFinite(props.max_distance_m)\n            ? Math.max(1, props.max_distance_m)\n            : 500_000;\n        let labelColor;\n        if (Number.isFinite(props.color)) {\n            labelColor = props.color;\n        } else if (typeof props.color === 'string' && props.color.trim()) {\n            try {\n                labelColor = new THREE.Color(props.color.trim()).getHex();\n            } catch (_error) {\n                labelColor = undefined;\n            }\n        }\n        const handle = getLabelSystem().createLabel(label, {\n            position: new THREE.Vector3(),\n            type: 'overlay',\n            color: labelColor,\n            objectRadius,\n            subText: description || null,\n            maxDistance,\n            labelPriority: Number.isFinite(props.label_priority) ? props.label_priority : 20,\n            metadata: {\n                id: item?.item_id || null,\n                itemId: item?.item_id || null,\n                entityType: 'overlay-annotation',\n                typeLabel: 'Overlay annotation',\n                name: label,\n                description,\n            },\n        });\n        const group = handle?.group;\n        if (!group) return null;\n        group.name = `OverlayAnnotation:${item?.item_id || 'annotation'}`;\n        group.userData.itemId = item?.item_id;\n        group.userData.label = label;\n        group.userData.labelHandle = handle;\n        group.userData.onRemove = () => handle.dispose?.();\n        this._applyItemTransform(group, item);\n        return group;\n    }\n\n    _renderModelPlaceholder(item) {\n        const size = Number.isFinite(item?.current?.properties?.size_m)\n            ? item.current.properties.size_m\n            : this._pointRadius * 2;\n        const geom = new THREE.BoxGeometry(size, size, size);\n        const color = item?.current?.properties?.color || '#4f46e5';\n        const mat = new THREE.MeshStandardMaterial({ color });\n        const mesh = new THREE.Mesh(geom, mat);\n        mesh.name = `OverlayModel:${item.item_id || 'model'}`;\n        this._enableShadows(mesh);\n        this._applyItemTransform(mesh, item);\n        mesh.userData.itemId = item.item_id;\n        mesh.userData.placeholder = true;\n        return mesh;\n    }\n\n    _renderSphere(item) {\n        const diameter = Number.isFinite(item?.current?.properties?.size_m)\n            ? item.current.properties.size_m\n            : this._pointRadius * 2;\n        const radius = diameter * 0.5;\n        const geom = new THREE.SphereGeometry(radius, 32, 16);\n        const props = item?.current?.properties || {};\n        const color = props.color || '#000000';\n        const mat = new THREE.MeshStandardMaterial({ color, roughness: 0.6, metalness: 0.1 });\n        const mesh = new THREE.Mesh(geom, mat);\n        mesh.name = `OverlaySphere:${item.item_id || 'sphere'}`;\n        this._enableShadows(mesh);\n        const lightIntensity = Number.isFinite(props.light_intensity) ? props.light_intensity : 120;\n        const lightDistance = Number.isFinite(props.light_distance) ? props.light_distance : this.planetRadius * 0.2;\n        const lightDecay = Number.isFinite(props.light_decay) ? props.light_decay : 1.2;\n        const light = new THREE.PointLight(0xffffff, lightIntensity, lightDistance, lightDecay);\n        light.name = `OverlaySphereLight:${item.item_id || 'sphere'}`;\n        mesh.add(light);\n        mesh.userData.light = light;\n        this._applyItemTransform(mesh, item);\n        mesh.userData.itemId = item.item_id;\n        mesh.userData.sphere = true;\n        return mesh;\n    }\n\n    _renderColumn(item) {\n        const height = Number.isFinite(item?.current?.properties?.height_m)\n            ? item.current.properties.height_m\n            : this._pointRadius * 4;\n        const radius = Number.isFinite(item?.current?.properties?.radius_m)\n            ? item.current.properties.radius_m\n            : this._pointRadius * 0.35;\n        const geom = new THREE.CylinderGeometry(radius, radius, height, 16, 1, false);\n        geom.translate(0, height / 2, 0);\n        const color = item?.current?.properties?.color || '#38bdf8';\n        const mat = new THREE.MeshStandardMaterial({ color });\n        const mesh = new THREE.Mesh(geom, mat);\n        mesh.name = `OverlayColumn:${item.item_id || 'column'}`;\n        this._enableShadows(mesh);\n        const audioAnchor = new THREE.Object3D();\n        audioAnchor.name = `AudioAnchor:${item.item_id || 'column'}`;\n        audioAnchor.position.set(0, height * 0.5, 0);\n        mesh.add(audioAnchor);\n        mesh.userData.audioAnchor = audioAnchor;\n        this._applyItemTransform(mesh, item);\n        mesh.userData.itemId = item.item_id;\n        mesh.userData.column = true;\n        return mesh;\n    }\n\n    _renderModelAsset(item, url, { deferModelLoad = false, owner } = {}) {\n        const group = new THREE.Group();\n        group.name = `OverlayModelAsset:${item.item_id || 'model'}`;\n        group.userData.itemId = item.item_id;\n        group.userData.modelAsset = true;\n        group.userData.overlayOwner = owner ? new WeakRef(owner) : null;\n        group.userData.modelContainer = group;\n        group.userData.modelUrl = url;\n        group.userData.modelDeferred = !!deferModelLoad;\n        group.userData.modelLoading = false;\n\n        const audioAnchor = new THREE.Object3D();\n        audioAnchor.name = `AudioAnchor:${item.item_id || 'model'}`;\n        audioAnchor.userData.keepOnUnload = true;\n        group.add(audioAnchor);\n        group.userData.audioAnchor = audioAnchor;\n\n        this._applyItemTransform(group, item);\n\n        if (!deferModelLoad) {\n            this._loadDeferredModel(group, item);\n        }\n\n        return group;\n    }\n\n    /**\n     * Load a model from an authenticated API endpoint\n     */\n    async _loadAuthenticatedModel(url, group, item) {\n        const retryAt = this._unavailableModelUrls.get(url) || 0;\n        if (retryAt > Date.now()) {\n            group.userData.modelUnavailableUrl = url;\n            group.userData.modelLoading = false;\n            return;\n        }\n        if (retryAt) this._unavailableModelUrls.delete(url);\n        return this._startModelLoad(url, group, item, true);\n    }\n\n    _invalidateModelLoad(group) {\n        if (!group?.userData) return;\n        const lease = group.userData.modelLease;\n        group.userData.modelLease = null;\n        group.userData.modelLoading = false;\n        group.userData.modelLoadWanted = false;\n        delete group.userData.modelLoadItem;\n        lease?.controller.abort();\n        lease?.releaseSession?.();\n    }\n\n    _beginModelLoad(group, item, url) {\n        this._invalidateModelLoad(group);\n        const lease = { controller: new AbortController(), item, url, group };\n        lease.sessionScope = group.userData.overlayOwner ? group.userData.overlayOwner.deref()?.sessionScope : this._session?.capture();\n        lease.releaseSession = bindOverlaySession(lease.sessionScope, lease.controller);\n        group.userData.modelLease = lease;\n        group.userData.modelLoading = true;\n        delete group.userData.modelLoadError;\n        return lease;\n    }\n\n    _isModelLoadCurrent(group, lease) {\n        if (!lease || this._disposed || !group?.userData || group.userData.modelDisposed ||\n            group.userData.modelLease !== lease || lease.controller.signal.aborted) return false;\n        if (lease.sessionScope?.signal.aborted) return false;\n        const ownerRef = group.userData.overlayOwner, owner = ownerRef?.deref();\n        if (ownerRef && (!owner || owner.retiring || this.overlays.get(owner.overlayId) !== owner)) return false;\n        const id = lease.item?.item_id;\n        for (const entry of this.overlays?.values?.() || []) {\n            const current = entry.items?.get?.(id);\n            if (current && current.object3d !== group && current.object3d?.userData?.modelContainer !== group) return false;\n        }\n        return true;\n    }\n\n    _disposeModelResult(gltf, preserve = null) {\n        const roots = new Set([gltf?.scene, ...(gltf?.scenes || [])].filter(Boolean));\n        if (roots.size === 1 && roots.has(preserve)) return;\n        disposeOwnedObject3D({ traverse: visitor => { for (const root of roots) root.traverse(visitor); } }, { preserve });\n    }\n\n    _createModelLoader(manager) {\n        const loader = new GLTFLoader(manager);\n        // Keep registered decoder/extension support; only the per-load manager\n        // and resource transport change.\n        for (const key of ['dracoLoader', 'ktx2Loader', 'meshoptDecoder', 'crossOrigin']) {\n            if (this._gltfLoader?.[key] != null) loader[key] = this._gltfLoader[key];\n        }\n        if (this._gltfLoader?.pluginCallbacks) loader.pluginCallbacks = this._gltfLoader.pluginCallbacks.slice();\n        return loader;\n    }\n\n    async _startModelLoad(url, group, item, authenticated) {\n        if (this._disposed || !group?.userData || group.userData.modelDisposed) return;\n        const lease = this._beginModelLoad(group, item, url);\n        const signal = lease.controller.signal;\n        const current = () => this._isModelLoadCurrent(group, lease);\n        let timeout;\n        try {\n            await runModelLoad(async reserve => {\n                if (!current()) return;\n                timeout = setTimeout(() => lease.controller.abort(new DOMException('Model load timed out', 'TimeoutError')), 60000);\n                const resolved = authenticated ? resolveBackendApiUrl(url) : url;\n                const absolute = new URL(resolved, globalThis.location?.href || 'http://localhost/').href;\n                const auth = authenticated ? (this._authService || getAuthService()) : null;\n                const fileBase = new URL(resolveBackendApiUrl('/api/files/'), globalThis.location?.href || 'http://localhost/');\n                const fetchResource = (target, requestSignal) => {\n                    const parsed = new URL(target, absolute);\n                    // Auth applies to our file routes only, never a remote glTF image.\n                    if (auth && parsed.origin === fileBase.origin && parsed.pathname.startsWith(fileBase.pathname)) {\n                        return auth.authenticatedFetch(parsed.href, { signal: requestSignal });\n                    }\n                    // ModelLoadBudget/ModelResourceBundle still own streaming\n                    // admission and bytes. The shared transport owns governance\n                    // and strips credentials from external model dependencies.\n                    return getNoclipGovernanceClient().request(parsed.href, {\n                        signal: requestSignal, credentials: 'same-origin', governanceLane: 'scene',\n                        governanceRetry: false, governanceProblemBodyLimit: 32768,\n                    });\n                };\n                const response = await fetchResource(absolute, signal);\n                if (!current()) { await response.body?.cancel().catch(() => {}); return; }\n                if (!response.ok) {\n                    if (response.status === 403 && authenticated) {\n                        const bytes = await readBoundedBytes(response, { maxBytes: 65536, signal, reserve });\n                        let denial;\n                        try { denial = JSON.parse(new TextDecoder().decode(bytes)); } catch {}\n                        if (!current()) return;\n                        if (denial?.gated) {\n                            this._createGatedPlaceholder(group, item, denial.reasonCodes || []);\n                            return;\n                        }\n                    } else await response.body?.cancel().catch(() => {});\n                    if (!current()) return;\n                    if (response.status === 404 || response.status === 410) {\n                        group.userData.modelUnavailableUrl = url;\n                        if (!this._unavailableModelUrls.has(url) && this._unavailableModelUrls.size >= 512) {\n                            this._unavailableModelUrls.delete(this._unavailableModelUrls.keys().next().value);\n                        }\n                        this._unavailableModelUrls.set(url, Date.now() + MISSING_MODEL_RETRY_MS);\n                        return;\n                    }\n                    throw new Error(`Failed to load model: ${response.status}`);\n                }\n                const bundle = await prepareModelBundle(response, { url: absolute, signal, reserve, fetchResource });\n                const manager = new THREE.LoadingManager();\n                manager.setURLModifier(request => { signal.throwIfAborted(); return bundle.resolveUrl(request); });\n                const abort = () => manager.abort();\n                signal.addEventListener('abort', abort, { once: true });\n                try {\n                    if (!current()) return;\n                    const loader = this._createModelLoader(manager);\n                    bundle.install(loader);\n                    // Keep the decode slot until parsing actually settles. Releasing\n                    // it at abort while a non-cancellable decoder still runs would\n                    // admit overlapping old generations and recreate the leak.\n                    const gltf = await new Promise((resolve, reject) => loader.parse(bundle.json, '', resolve, reject));\n                    if (!gltf?.scene && !gltf?.scenes?.[0]) throw new Error('Model has no renderable scene');\n                    bundle.transferOwnership();\n                    if (!current()) { this._disposeModelResult(gltf); return; }\n                    this._unavailableModelUrls.delete(url);\n                    this._onModelLoaded(gltf, group, item, url, lease);\n                } finally {\n                    signal.removeEventListener('abort', abort);\n                    manager.abort();\n                    bundle.dispose();\n                }\n            }, signal, { priority: () => {\n                const planner = this._modelAdmissionPlanner ||= new OverlayAdmissionPlanner(this);\n                const rank = { item }; // Re-read edited coordinates at actual admission.\n                planner.refresh(); planner.rank(rank); return rank;\n            } });\n        } catch (error) {\n            if (current()) {\n                if (error instanceof ModelAdmissionError) {\n                    // The existing item holds retry intent; no extra unbounded\n                    // promise queue or per-item retry timers.\n                    group.userData.modelLoadWanted = true;\n                    group.userData.modelLoadItem = item;\n                    group.userData.modelDeferred = true;\n                } else {\n                    group.userData.modelLoadError = String(error.message || error).slice(0, 500);\n                    group.userData.modelDeferred = false;\n                    this._onModelError(error, item);\n                }\n            }\n        } finally {\n            clearTimeout(timeout);\n            lease.releaseSession?.();\n            if (group.userData.modelLease === lease) {\n                group.userData.modelLoading = false;\n                group.userData.modelLease = null;\n                if (!group.userData.modelRoot && !group.userData.modelDisposed && !lease.sessionScope?.signal.aborted) {\n                    if (signal.reason?.name === 'TimeoutError') {\n                        group.userData.modelLoadError = 'Model load timed out';\n                        group.userData.modelDeferred = false;\n                    }\n                    group.dispatchEvent({ type: 'model-load-settled' });\n                }\n            }\n        }\n    }\n\n    async _retryDeferredModelLoads() {\n        if (this._disposed || this._modelRetrying || this._cameraExclusiveState) return;\n        this._modelRetrying = true;\n        let start = performance.now(), count = 0;\n        try {\n            for (const entry of this.overlays.values()) {\n                for (const record of entry.items.values()) {\n                    if (this._disposed || getModelLoadStats().queued >= getModelLoadStats().maxPending) return;\n                    const group = record.object3d?.userData?.modelContainer || record.object3d;\n                    if (group?.userData?.modelLoadWanted && !group.userData.modelDisposed) {\n                        this._loadDeferredModel(group, group.userData.modelLoadItem || record.runtime?.effectiveItem || record.data);\n                    }\n                    if (++count % 128 === 0 || performance.now() - start >= 4) {\n                        await yieldToEventLoop('background'); start = performance.now();\n                    }\n                }\n            }\n        } finally { this._modelRetrying = false; }\n    }\n\n    /**\n     * Create a placeholder mesh for gated/blocked assets\n     * Shows a locked icon and requirements info\n     */\n    _createGatedPlaceholder(group, item, reasonCodes) {\n        const props = item.current?.properties || {};\n        const size = props.size_m || 100;\n\n        // Create semi-transparent box as placeholder\n        const geometry = new THREE.BoxGeometry(size, size, size);\n        const material = new THREE.MeshBasicMaterial({\n            color: 0x666666,\n            transparent: true,\n            opacity: 0.3,\n            wireframe: true,\n        });\n        const placeholder = new THREE.Mesh(geometry, material);\n        placeholder.name = 'GatedPlaceholder';\n        group.add(placeholder);\n        group.userData.modelRoot = placeholder;\n        group.userData.modelDeferred = false;\n        group.userData.modelLoading = false;\n\n        // Create a lock icon sprite\n        const lockSprite = this._createLockSprite();\n        lockSprite.position.set(0, size * 0.6, 0);\n        group.add(lockSprite);\n\n        // Store gating info for UI\n        group.userData.isGated = true;\n        group.userData.gatingReasonCodes = reasonCodes;\n        group.userData.gatingRequirements = this._formatGatingRequirements(reasonCodes);\n        if (item?.item_id) {\n            this._setItemLoadedState(item.item_id, true);\n        }\n\n        // Emit event for UI to show tooltip/modal\n        this.eventBus?.emit('overlay:asset-gated', {\n            overlayId: item.overlay_id,\n            itemId: item.item_id,\n            reasonCodes,\n            requirements: group.userData.gatingRequirements,\n        });\n    }\n\n    /**\n     * Create a lock icon sprite for gated assets\n     */\n    _createLockSprite() {\n        const canvas = document.createElement('canvas');\n        const ctx = canvas.getContext('2d');\n        const size = 128;\n        canvas.width = size;\n        canvas.height = size;\n\n        // Draw lock icon\n        ctx.fillStyle = 'rgba(0, 0, 0, 0.7)';\n        ctx.beginPath();\n        ctx.arc(size / 2, size / 2, size / 2.5, 0, Math.PI * 2);\n        ctx.fill();\n\n        ctx.strokeStyle = '#ffffff';\n        ctx.lineWidth = 4;\n        ctx.beginPath();\n        ctx.arc(size / 2, size / 2, size / 2.5, 0, Math.PI * 2);\n        ctx.stroke();\n\n        // Lock body\n        ctx.fillStyle = '#ffffff';\n        ctx.fillRect(size * 0.35, size * 0.45, size * 0.3, size * 0.25);\n\n        // Lock shackle\n        ctx.strokeStyle = '#ffffff';\n        ctx.lineWidth = 6;\n        ctx.beginPath();\n        ctx.arc(size / 2, size * 0.42, size * 0.12, Math.PI, 0, false);\n        ctx.stroke();\n\n        const texture = new THREE.CanvasTexture(canvas);\n        texture.needsUpdate = true;\n\n        const material = new THREE.SpriteMaterial({\n            map: texture,\n            transparent: true,\n            depthTest: false,\n        });\n\n        const sprite = new THREE.Sprite(material);\n        sprite.scale.set(50, 50, 1);\n        sprite.renderOrder = 10;\n        sprite.name = 'GatedLockIcon';\n\n        return sprite;\n    }\n\n    /**\n     * Format gating reason codes into human-readable requirements\n     */\n    _formatGatingRequirements(reasonCodes) {\n        const requirements = [];\n\n        for (const code of reasonCodes) {\n            if (code.startsWith('token_balance:')) {\n                // Format: token_balance:erc20:0x123...abc:100[:Token Label]\n                const parts = code.split(':');\n                const tokenType = parts[1]?.toUpperCase() || 'TOKEN';\n                const amount = parts[3] || '?';\n                const tokenLabel = parts[4] || '';\n                const display = tokenLabel || tokenType;\n                requirements.push(`Requires ${amount} ${display} tokens`);\n            } else if (code.startsWith('nft_ownership:')) {\n                // Format: nft_ownership:erc721:0x123...abc[:tokenId][:Token Label]\n                const parts = code.split(':');\n                const nftType = parts[1]?.toUpperCase() || 'NFT';\n                let tokenId = null;\n                let label = '';\n\n                if (parts.length >= 5) {\n                    tokenId = parts[3];\n                    label = parts[4] || '';\n                } else if (parts.length === 4) {\n                    const maybeId = parts[3];\n                    const isNumericId = typeof maybeId === 'string' && /^\\d+$/.test(maybeId);\n                    if (isNumericId && maybeId !== '*') {\n                        tokenId = maybeId;\n                    } else {\n                        label = maybeId || '';\n                    }\n                }\n\n                const hasTokenId = tokenId && tokenId !== '*';\n                const display = label || (hasTokenId ? `${nftType} #${tokenId}` : nftType);\n                requirements.push(`Requires ${display} ownership`);\n            } else if (code.startsWith('erc20_balance:') || code.startsWith('erc1155_balance:')) {\n                const parts = code.split(':');\n                const tokenType = parts[0]?.startsWith('erc1155') ? 'ERC1155' : 'ERC20';\n                requirements.push(`Requires ${tokenType} tokens`);\n            } else if (code.startsWith('erc721_owns_')) {\n                requirements.push('Requires NFT ownership');\n            } else if (code === 'subscription_required') {\n                requirements.push('Subscription required');\n            } else if (code === 'payment_required') {\n                requirements.push('Payment required');\n            } else {\n                // Generic fallback\n                requirements.push(`Access restricted: ${code}`);\n            }\n        }\n\n        return requirements.length > 0 ? requirements : ['Access restricted'];\n    }\n\n    /**\n     * Handle successful model load\n     */\n    _onModelLoaded(gltf, group, item, url, lease) {\n        if (!this._isModelLoadCurrent(group, lease)) {\n            this._disposeModelResult(gltf);\n            return;\n        }\n        const root = gltf.scene || gltf.scenes?.[0];\n        if (!root) return;\n        const existingRoot = group?.userData?.modelRoot;\n        if (existingRoot && existingRoot !== root) {\n            if (existingRoot.parent) {\n                existingRoot.parent.remove(existingRoot);\n            }\n            this._disposeObject(existingRoot);\n        }\n        root.name = `ModelRoot:${item.item_id || 'model'}`;\n        const box = new THREE.Box3().setFromObject(root);\n        const size = new THREE.Vector3();\n        box.getSize(size);\n        group.userData.modelRoot = root;\n        group.userData.modelSize = { x: size.x, y: size.y, z: size.z };\n        group.userData.modelUrl = url;\n        group.userData.modelLoading = false;\n        group.userData.modelDeferred = false;\n        this._applyModelScale(group, item, root);\n        // Lit like a photoreal tile (deferred, same mask/depth), never by the\n        // terrain that happens to sit behind it on screen.\n        group.userData.photorealAssetLighting = preparePhotorealAssetLighting(root);\n        group.add(root);\n        this._applyModelOpacity(group, item);\n        this._enableShadows(root);\n        this._getPointCloudNodes(group);\n        this._disposeModelResult(gltf, root);\n        const itemId = item?.item_id;\n        if (itemId) {\n            this._setItemLoadedState(itemId, true);\n        }\n        group.dispatchEvent({ type: 'model-loaded' });\n        this.eventBus?.emit('overlay:asset-ready', {\n            overlayId: group.userData.overlayOwner?.deref()?.overlayId || item?.overlay_id || null,\n            itemId,\n        });\n    }\n\n    /**\n     * Handle model load error\n     */\n    _onModelError(error, item) {\n        this.eventBus?.emit('overlay:error', {\n            overlayId: item?.overlay_id,\n            error\n        });\n    }\n\n    _renderAnchor(item) {\n        const anchor = new THREE.Object3D();\n        anchor.name = `OverlayAnchor:${item.item_id || 'anchor'}`;\n        this._applyItemTransform(anchor, item);\n        anchor.userData.itemId = item.item_id;\n        anchor.userData.anchor = true;\n        return anchor;\n    }\n\n    _getDa3SurfaceAnchorAuthoredKey(item) {\n        const current = item?.current || {};\n        const props = current.properties || {};\n        const coordinates = current.geom?.coordinates || [];\n        const snapshot = normalizeSurfaceAnchorSnapshot(props.surface_anchor_snapshot);\n        return JSON.stringify([\n            Number(coordinates[0]),\n            Number(coordinates[1]),\n            resolveDa3HeightMode(item),\n            normalizeSurfaceAnchorPolicy(props.surface_anchor_policy),\n            snapshot?.radiusM ?? null,\n            snapshot?.provider ?? null,\n            snapshot?.terrainRevision ?? null,\n            snapshot?.sampledAt ?? null,\n        ]);\n    }\n\n    _applySurfaceAnchorRuntime(object3d, state) {\n        if (!object3d?.userData || !state) return;\n        object3d.userData.surfaceAnchor = state;\n        object3d.userData.surfaceAnchorState = state.state;\n        object3d.userData.surfaceAnchorMated = state.state === SURFACE_ANCHOR_STATE.MATED;\n        if (Number.isFinite(state.surfaceRadiusM)) {\n            object3d.userData.surfaceAnchorRadius = state.surfaceRadiusM;\n        } else {\n            delete object3d.userData.surfaceAnchorRadius;\n        }\n    }\n\n    _clearSurfaceAnchorRuntime(object3d) {\n        if (!object3d?.userData) return;\n        delete object3d.userData.surfaceAnchor;\n        delete object3d.userData.surfaceAnchorState;\n        delete object3d.userData.surfaceAnchorMated;\n        delete object3d.userData.surfaceAnchorRadius;\n    }\n\n    _resolveItemPosition(item, object3d = null, resolution = {}) {\n        const current = item?.current || {};\n        const geom = current.geom;\n        if (geom?.type === 'Point' && Array.isArray(geom.coordinates)) {\n            const lon = geom.coordinates[0];\n            const lat = geom.coordinates[1];\n            const da3HeightMode = resolveDa3HeightMode(item);\n            const da3SurfaceRelative = da3HeightMode === 'surface_agl';\n            const alignToSurface = current.properties?.align_to_surface !== false;\n            const placementOwnsHeight = current.properties?.height_authority === 'capture-placement';\n            const offset = da3SurfaceRelative\n                ? resolveDa3AnchorAglM(item)\n                : placementOwnsHeight\n                ? 0\n                : Number.isFinite(current.properties?.offset_m)\n                ? current.properties.offset_m\n                : this._defaultOffsetM;\n            const dir = latLonToLocalDir(lat, lon);\n            const baseRadius = ellipsoidRadiusForLocalDir(dir);\n            const anchoredRaw = current.properties?.anchor_ellipsoid_m;\n            const anchoredElevation = Number(anchoredRaw);\n            const elevation = placementOwnsHeight && anchoredRaw !== null\n                && anchoredRaw !== undefined && Number.isFinite(anchoredElevation)\n                ? anchoredElevation\n                : (Number.isFinite(current.elevation_m) ? current.elevation_m : 0);\n\n            if (isDa3ScanItem(item) && !placementOwnsHeight) {\n                const authoredKey = this._getDa3SurfaceAnchorAuthoredKey(item);\n                const existing = object3d?.userData?.surfaceAnchor;\n                const previous = existing?.authoredKey === authoredKey ? existing : null;\n                const props = current.properties || {};\n                const policy = normalizeSurfaceAnchorPolicy(props.surface_anchor_policy);\n                const pinnedSnapshot = policy === 'pin-resolved-surface'\n                    ? normalizeSurfaceAnchorSnapshot(props.surface_anchor_snapshot)\n                    : null;\n                const providerAvailable = !!(this.surfaceController || this.triTree);\n                let sampledRadiusM = null;\n                if (da3SurfaceRelative && !pinnedSnapshot && providerAvailable) {\n                    sampledRadiusM = this._sampleTerrainRadiusForDir(dir);\n                }\n                const fallbackKind = Number.isFinite(current.elevation_m) ? 'gps' : 'ellipsoid';\n                const state = resolveSurfaceAnchorState({\n                    requiresSurface: da3SurfaceRelative,\n                    policy,\n                    snapshot: props.surface_anchor_snapshot,\n                    sampledRadiusM,\n                    previous,\n                    fallbackRadiusM: baseRadius + elevation,\n                    fallbackKind,\n                    providerAvailable,\n                    provider: this.surfaceController?.mapSourceTerrainGroup ? 'mapsource'\n                        : this.surfaceController?.photoTileGroup ? 'photoreal' : 'tritree',\n                    aglM: da3SurfaceRelative ? offset : 0,\n                    sampleSequence: resolution.sampleSequence,\n                    reason: resolution.reason || 'transform',\n                    authoredVersion: current.version_id\n                        || current.version\n                        || item.version_id\n                        || item.version\n                        || null,\n                });\n                state.authoredKey = authoredKey;\n                this._applySurfaceAnchorRuntime(object3d, state);\n                return dir.multiplyScalar(state.displayRadiusM);\n            }\n\n            if (placementOwnsHeight) this._clearSurfaceAnchorRuntime(object3d);\n\n            // DA3 height mating is independent of orientation alignment: old\n            // rows carry an Earth/world sensor quaternion and must not have a\n            // second radial-up rotation applied to it.\n            if ((alignToSurface || da3SurfaceRelative) && (this.surfaceController || this.triTree)) {\n                const terrainRadius = this._sampleTerrainRadiusForDir(dir);\n                if (Number.isFinite(terrainRadius)) {\n                    if (object3d?.userData) {\n                        object3d.userData.surfaceAnchorRadius = terrainRadius;\n                        object3d.userData.surfaceAnchorMated = true;\n                    }\n                    // Use terrain radius + offset; ignore stored elevation_m when aligning to surface\n                    return dir.clone().multiplyScalar(terrainRadius + offset);\n                }\n                const heldRadius = object3d?.userData?.surfaceAnchorRadius;\n                if (Number.isFinite(heldRadius)) {\n                    return dir.clone().multiplyScalar(heldRadius + offset);\n                }\n            }\n\n            // Fall back to stored elevation_m or planet radius. DA3 retains its\n            // raw phone altitude only as a coarse pre-tile fallback, then mates\n            // to the rendered surface at its explicit AGL anchor.\n            // When align_to_surface is true but terrain isn't available, use offset only (not elevation_m)\n            if (alignToSurface) {\n                return dir.multiplyScalar(baseRadius + offset);\n            }\n            return dir.multiplyScalar(baseRadius + elevation + offset);\n        }\n\n        if (current.position && Number.isFinite(current.position.x)) {\n            return new THREE.Vector3(current.position.x, current.position.y, current.position.z);\n        }\n\n        return null;\n    }\n\n    _sampleTerrainRadiusForDir(localDir) {\n        const dir = localDir.clone().normalize();\n        // Prefer surfaceController — it checks photoTileGroup first, then triTree\n        if (this.surfaceController?.sampleTerrainRadiusForDir) {\n            const worldDir = dir.clone();\n            const group = this.triTree?.group || this.parentGroup;\n            if (group) {\n                const worldQuat = group.getWorldQuaternion(new THREE.Quaternion());\n                worldDir.applyQuaternion(worldQuat).normalize();\n            }\n            const requireFreshPhotoHit = !!this.surfaceController.photoTileGroup;\n            const r = this.surfaceController.sampleTerrainRadiusForDir(worldDir, {\n                mutateCache: false,\n                requireFreshPhotoHit,\n                allowTriTreeFallback: !requireFreshPhotoHit,\n                skipWorldMatrixUpdate: true,\n            });\n            if (Number.isFinite(r)) return r;\n            if (requireFreshPhotoHit) return null;\n        }\n        // Fallback: direct triTree access\n        if (!this.triTree) return null;\n        if (this.triTree.group) {\n            const worldQuat = this.triTree.group.getWorldQuaternion(new THREE.Quaternion());\n            const worldDir = dir.clone().applyQuaternion(worldQuat).normalize();\n            const raycastR = this.triTree.sampleTerrainRadiusForDir?.(worldDir);\n            if (Number.isFinite(raycastR)) {\n                return raycastR;\n            }\n            const vertexR = this.triTree.getSurfaceRadiusAtDir?.(worldDir);\n            if (Number.isFinite(vertexR)) {\n                return vertexR;\n            }\n        }\n        return null;\n    }\n\n    _resolveOrientation(item) {\n        const q = item?.current?.orientation_quat;\n        let baseQuat = null;\n        if (Array.isArray(q) && q.length === 4 && q.every(Number.isFinite)) {\n            baseQuat = new THREE.Quaternion(q[0], q[1], q[2], q[3]);\n        }\n        const degQuat = this._resolveRotationDeg(item);\n        if (baseQuat && degQuat) {\n            return baseQuat.multiply(degQuat);\n        }\n        if (baseQuat) return baseQuat;\n        if (degQuat) return degQuat;\n        return null;\n    }\n\n    _resolveRotationDeg(item) {\n        const props = item?.current?.properties;\n        if (!props) return null;\n        const rotation = props.rotation_deg || props.rotation_euler_deg || null;\n        if (!rotation) return null;\n        const x = Array.isArray(rotation)\n            ? (Number.isFinite(rotation[0]) ? rotation[0] : 0)\n            : (Number.isFinite(rotation.x) ? rotation.x : 0);\n        const y = Array.isArray(rotation)\n            ? (Number.isFinite(rotation[1]) ? rotation[1] : 0)\n            : (Number.isFinite(rotation.y) ? rotation.y : 0);\n        const z = Array.isArray(rotation)\n            ? (Number.isFinite(rotation[2]) ? rotation[2] : 0)\n            : (Number.isFinite(rotation.z) ? rotation.z : 0);\n        const order = props.rotation_order || props.rotation_deg_order || 'XYZ';\n        const euler = new THREE.Euler(\n            THREE.MathUtils.degToRad(x),\n            THREE.MathUtils.degToRad(y),\n            THREE.MathUtils.degToRad(z),\n            order\n        );\n        const quat = new THREE.Quaternion();\n        quat.setFromEuler(euler);\n        return quat;\n    }\n\n    _resolveUpAxis(item) {\n        const axis = this._resolveUpAxisName(item);\n        if (axis === 'x') return new THREE.Vector3(1, 0, 0);\n        if (axis === 'z') return new THREE.Vector3(0, 0, 1);\n        return new THREE.Vector3(0, 1, 0);\n    }\n\n    _resolveUpAxisName(item) {\n        const axisRaw = item?.current?.properties?.up_axis || 'y';\n        const axis = String(axisRaw).toLowerCase().trim();\n        return axis.startsWith('-') ? axis.slice(1) : axis;\n    }\n\n    _resolveUpAxisSign(item) {\n        const axisRaw = item?.current?.properties?.up_axis || 'y';\n        const axis = String(axisRaw).toLowerCase().trim();\n        return axis.startsWith('-') ? -1 : 1;\n    }\n\n    _applyItemTransform(object3d, item, resolution = {}) {\n        if (!object3d) return;\n        const position = this._resolveItemPosition(item, object3d, resolution);\n        if (position) {\n            object3d.position.copy(position);\n            if (item?.current?.properties?.precision_anchor === 'ecef-double-parent-local-float') {\n                object3d.userData.precisionAnchor = {\n                    mode: 'ecef-double-parent-local-float',\n                    placementRevision: Number(item.current.properties.placement_revision || 1),\n                    tileIndependentHeight: true,\n                };\n            }\n        }\n\n        const localQuat = this._resolveOrientation(item);\n        const alignToSurface = item?.current?.properties?.align_to_surface !== false;\n        const alignMissingDa3Orientation = this._isDa3Item(item) && !localQuat;\n        if ((alignToSurface || alignMissingDa3Orientation) && position) {\n            const surfaceDir = position.clone().normalize();\n            const upAxis = this._resolveUpAxis(item);\n            const alignQuat = new THREE.Quaternion().setFromUnitVectors(\n                upAxis,\n                surfaceDir\n            );\n            const upSign = this._resolveUpAxisSign(item);\n            if (upSign < 0) {\n                const flipQuat = new THREE.Quaternion().setFromAxisAngle(upAxis, Math.PI);\n                alignQuat.multiply(flipQuat);\n            }\n            if (localQuat) {\n                alignQuat.multiply(localQuat);\n            }\n            object3d.quaternion.copy(alignQuat);\n        } else if (localQuat) {\n            object3d.quaternion.copy(localQuat);\n        }\n    }\n\n    _applyItemAppearance(object3d, item) {\n        if (!object3d || !item) return;\n        const props = item?.current?.properties || {};\n        if (object3d.isMesh && object3d.material?.color && !object3d.userData?.modelAsset) {\n            const color = props.color;\n            if (color) {\n                object3d.material.color.set(color);\n                object3d.material.needsUpdate = true;\n            }\n            // Apply opacity to primitive shapes\n            if (Number.isFinite(props.opacity)) {\n                object3d.material.opacity = props.opacity;\n                object3d.material.transparent = props.opacity < 1;\n                object3d.material.needsUpdate = true;\n            }\n        }\n        const light = object3d.userData?.light;\n        if (light) {\n            if (Number.isFinite(props.light_intensity)) light.intensity = props.light_intensity;\n            if (Number.isFinite(props.light_distance)) light.distance = props.light_distance;\n            if (Number.isFinite(props.light_decay)) light.decay = props.light_decay;\n        }\n        if (object3d.userData?.modelAsset) {\n            this._applyModelScale(object3d, item);\n            this._applyModelOpacity(object3d, item);\n        }\n    }\n\n    _applyModelOpacity(container, item) {\n        if (!container) return;\n        const props = item?.current?.properties || {};\n        const opacity = Number.isFinite(props.opacity) ? Math.max(0, Math.min(1, props.opacity)) : 1;\n        const root = container.userData?.modelRoot;\n        if (!root) return;\n        this._modelMaterialAppearance ||= new WeakMap();\n        root.traverse(child => {\n            if (!(child.isMesh || child.isPoints || child.isLine) || !child.material) return;\n            for (const material of [child.material].flat()) {\n                let original = this._modelMaterialAppearance.get(material);\n                if (!original) {\n                    original = { opacity: material.opacity, transparent: material.transparent,\n                        size: material.size, sizeAttenuation: material.sizeAttenuation };\n                    this._modelMaterialAppearance.set(material, original);\n                }\n                const transparent = original.transparent || opacity < 1;\n                if (transparent !== material.transparent) material.needsUpdate = true;\n                material.transparent = transparent; material.opacity = original.opacity * opacity;\n                if (child.isPoints) {\n                    const override = Number.isFinite(props.point_size_m) && props.point_size_m > 0;\n                    const attenuation = override ? true : original.sizeAttenuation;\n                    if (material.sizeAttenuation !== attenuation) material.needsUpdate = true;\n                    material.size = override ? Math.max(.0001, Math.min(10, props.point_size_m)) : original.size;\n                    material.sizeAttenuation = attenuation;\n                }\n            }\n        });\n    }\n\n    _applyModelScale(container, item, rootOverride) {\n        if (!container) return;\n        const root = rootOverride || container.userData?.modelRoot;\n        if (!root) return;\n        const props = item?.current?.properties || {};\n        const baseScale = Number.isFinite(props.model_scale)\n            ? props.model_scale\n            : (Number.isFinite(props.scale) ? props.scale : 1);\n        const targetSize = Number.isFinite(props.size_m) ? props.size_m : null;\n        const upAxisName = this._resolveUpAxisName(item);\n        let size = container.userData?.modelSize;\n        if (!size) {\n            const box = new THREE.Box3().setFromObject(root);\n            const tmp = new THREE.Vector3();\n            box.getSize(tmp);\n            size = { x: tmp.x, y: tmp.y, z: tmp.z };\n            container.userData.modelSize = size;\n        }\n        const axisSize = upAxisName === 'x'\n            ? size.x\n            : (upAxisName === 'z' ? size.z : size.y);\n        let scale = baseScale;\n        if (targetSize && axisSize > 0) {\n            scale = (targetSize / axisSize) * baseScale;\n        }\n\n        // Apply flip_up by inverting the up axis scale component\n        const flipUp = !!props.flip_up;\n        if (flipUp) {\n            // Invert on up axis to flip the model\n            if (upAxisName === 'x') {\n                root.scale.set(-scale, scale, scale);\n            } else if (upAxisName === 'z') {\n                root.scale.set(scale, scale, -scale);\n            } else {\n                root.scale.set(scale, -scale, scale);\n            }\n        } else {\n            root.scale.setScalar(scale);\n        }\n\n        // LingBot alignment anchors the first reconstructed camera at the\n        // geodetic item position. Root translation is in unscaled model space,\n        // so apply the effective scale before the parent anchor rotates it into\n        // the Earth tangent frame.\n        const originOffset = props.model_origin_offset_m;\n        if (Array.isArray(originOffset) && originOffset.length >= 3\n            && originOffset.slice(0, 3).every(Number.isFinite)) {\n            root.position.set(originOffset[0], originOffset[1], originOffset[2]).multiplyScalar(scale);\n        } else {\n            root.position.set(0, 0, 0);\n        }\n\n        root.updateMatrixWorld(true);\n        const anchor = container.userData?.audioAnchor;\n        if (anchor) {\n            const bounds = new THREE.Box3().setFromObject(root);\n            const center = new THREE.Vector3();\n            bounds.getCenter(center);\n            anchor.position.copy(center);\n        }\n    }\n\n    _shouldRebuildItem(previous, next) {\n        if (!previous || !next) return true;\n        if ((previous.item_type || '') !== (next.item_type || '')) return true;\n        const prevKey = this._getRenderKey(previous);\n        const nextKey = this._getRenderKey(next);\n        if (prevKey !== nextKey) return true;\n\n        if ((next.item_type || '') === 'point') {\n            const prevProps = previous.current?.properties || {};\n            const nextProps = next.current?.properties || {};\n            if (this._hasNumericChange(prevProps.size_m, nextProps.size_m)) return true;\n        }\n\n        if ((next.item_type || '') === 'model3d') {\n            const prevProps = previous.current?.properties || {};\n            const nextProps = next.current?.properties || {};\n            if (nextKey.startsWith('model3d:column')) {\n                if (this._hasNumericChange(prevProps.height_m, nextProps.height_m)) return true;\n                if (this._hasNumericChange(prevProps.radius_m, nextProps.radius_m)) return true;\n            }\n            if (nextKey.startsWith('model3d:sphere') || nextKey.startsWith('model3d:placeholder')) {\n                if (this._hasNumericChange(prevProps.size_m, nextProps.size_m)) return true;\n            }\n            if (nextKey.startsWith('model3d:asset')) {\n                return false;\n            }\n        }\n\n        return false;\n    }\n\n    // Store only the render-affecting scalars, not a duplicate item/document.\n    // Editor controls mutate the shared authored object before update arrives.\n    _getRenderSignature(item) {\n        const key = this._getRenderKey(item), props = item?.current?.properties || {};\n        const number = value => Number.isFinite(value) ? value : null;\n        if (item?.item_type === 'point' || key.startsWith('model3d:sphere') || key.startsWith('model3d:placeholder')) {\n            return JSON.stringify([key, number(props.size_m)]);\n        }\n        if (key.startsWith('model3d:column')) return JSON.stringify([key, number(props.height_m), number(props.radius_m)]);\n        return JSON.stringify([key]);\n    }\n\n    _getRenderKey(item) {\n        if (!item) return '';\n        const type = item.item_type || 'unknown';\n        const props = item?.current?.properties || {};\n        if (type === 'annotation') {\n            if (props.accountNote === true) return 'annotation:account-note-managed';\n            const label = String(props.label || props.name || '').replace(/\\s+/g, ' ').trim();\n            const description = String(props.description || '').trim();\n            return label ? `annotation:${label}:${description}` : 'annotation:empty';\n        }\n        if (type === 'model3d') {\n            const shape = props.shape ? String(props.shape).toLowerCase() : '';\n            if (shape && shape !== 'custom') return `model3d:${shape}`;\n            const modelUrl = resolveItemModelUrl(item);\n            if (modelUrl) return `model3d:asset:${modelUrl}`;\n            return 'model3d:placeholder';\n        }\n        return type;\n    }\n\n    _hasNumericChange(previous, next) {\n        const prevNum = Number.isFinite(previous) ? previous : null;\n        const nextNum = Number.isFinite(next) ? next : null;\n        if (prevNum === null && nextNum === null) return false;\n        return prevNum !== nextNum;\n    }\n\n    _primeAccessDecision(objectType, objectId, action) {\n        if (!this.access || !objectId || typeof this.access.canPerform !== 'function') return;\n        Promise.resolve(this.access.canPerform(objectType, objectId, action)).catch(() => undefined);\n    }\n\n    _readAccessDecisionSync(objectType, objectId, action, fallback = true) {\n        if (!this.access || !objectId) return fallback;\n        this._primeAccessDecision(objectType, objectId, action);\n        if (typeof this.access.hasCachedDecision === 'function' &&\n            !this.access.hasCachedDecision(objectType, objectId, action)) {\n            return fallback;\n        }\n        if (typeof this.access.canPerformSync === 'function') {\n            return !!this.access.canPerformSync(objectType, objectId, action);\n        }\n        return fallback;\n    }\n\n    _canViewItem(item) {\n        if (item?.policy?.allowed_actions && !item.policy.allowed_actions.includes('view_item')) {\n            return false;\n        }\n        return this._readAccessDecisionSync('item', item?.item_id, 'view_item', true);\n    }\n\n    _canViewOverlay(overlayId) {\n        return this._readAccessDecisionSync('overlay', overlayId, 'view_overlay', true);\n    }\n\n    _canViewLayer(layerId) {\n        return this._readAccessDecisionSync('layer', layerId, 'view_layer', true);\n    }\n\n    _canUpdateItem(item) {\n        if (!item?.item_id) return true;\n        const canEdit = this._readAccessDecisionSync('item', item.item_id, 'edit_metadata', true);\n        const canMove = this._readAccessDecisionSync('item', item.item_id, 'move_item', true);\n        return canEdit || canMove;\n    }\n\n    _isAssetBlocked(item) {\n        if (!item?.item_id) return false;\n        return !this._readAccessDecisionSync('item', item.item_id, 'view_asset', true);\n    }\n\n    _disposeObject(object3d) {\n        object3d?.traverse?.(child => {\n            if (!child.userData?.modelAsset) return;\n            this._invalidateModelLoad(child);\n            this._modelPreviewOwners?.delete(child);\n            child.userData.modelDisposed = true;\n        });\n        disposeOwnedObject3D(object3d);\n    }\n\n    _mergeOverlayDoc(base, patch) {\n        if (!patch || typeof patch !== 'object') return base;\n        if (!base || typeof base !== 'object') return patch;\n        const next = Array.isArray(base) ? [...base] : { ...base };\n        for (const [key, value] of Object.entries(patch)) {\n            if (value && typeof value === 'object' && !Array.isArray(value)) {\n                next[key] = this._mergeOverlayDoc(base[key], value);\n            } else {\n                next[key] = value;\n            }\n        }\n        return next;\n    }\n\n    _mergeOverlayUpdate(base, patch, { replaceLayers = false } = {}) {\n        const { layers, ...metadata } = patch;\n        const next = this._mergeOverlayDoc(base, metadata);\n        if (!Array.isArray(layers)) return next;\n        const layerDocs = new Map((base?.layers || []).filter(Boolean).map(layer => [layer.layer_id || layer.name, layer]));\n        for (const layer of layers) {\n            const id = layer?.layer_id || layer?.name;\n            if (!id) continue; // Existing controls may send sparse positional arrays.\n            const { items, ...layerMetadata } = layer;\n            const existing = layerDocs.get(id);\n            const merged = this._mergeOverlayDoc(existing || {}, layerMetadata);\n            if (Array.isArray(items)) {\n                const itemDocs = new Map((replaceLayers ? [] : existing?.items || []).filter(Boolean).map(item => [this._resolveItemId(item, id), item]));\n                for (const item of items) {\n                    const itemId = item && this._resolveItemId(item, id);\n                    if (!itemId) continue;\n                    if (this._shouldRemoveItem(item)) itemDocs.delete(itemId);\n                    else itemDocs.set(itemId, this._mergeOverlayDoc(itemDocs.get(itemId), item));\n                }\n                merged.items = [...itemDocs.values()];\n            }\n            layerDocs.set(id, merged);\n        }\n        // Replacement is scoped to supplied layers' item lists, matching the\n        // renderer contract. An item/layer patch must never erase its siblings.\n        next.layers = [...layerDocs.values()];\n        return next;\n    }\n\n    /**\n     * Refresh all triggers when item properties change (hot-reload support)\n     */\n    _refreshTriggers(itemId, object3d, item) {\n        if (!object3d || !item) return;\n\n        // Remove existing triggers first\n        if (this.proximityTriggerManager) {\n            this.proximityTriggerManager.removeTrigger(itemId);\n            this.proximityTriggerManager.removeTrigger(`${itemId}-physics-spawn`);\n            this.proximityTriggerManager.removeTrigger(`${itemId}-media`);\n        }\n        if (this.clickTriggerManager) {\n            this.clickTriggerManager.removeTrigger(itemId);\n            this.clickTriggerManager.removeTrigger(`${itemId}-media`);\n        }\n        if (this.physicsSystem && object3d.userData?.hasPhysics) {\n            this.physicsSystem.removePhysicsObject(object3d);\n        }\n\n        // Re-setup with new properties\n        this._setupProximityTriggers(itemId, object3d, item);\n        this._setupPhysics(itemId, object3d, item);\n        this._setupClickTriggers(itemId, object3d, item);\n        this._setupMediaPlayback(itemId, object3d, item);\n    }\n\n    /**\n     * Setup proximity triggers for an item\n     */\n    _setupProximityTriggers(itemId, object3d, item) {\n        if (!this.proximityTriggerManager || !object3d) return;\n\n        const triggers = item?.current?.properties?.proximity_triggers;\n        if (!triggers || !Array.isArray(triggers) || triggers.length === 0) return;\n\n        const actions = [];\n\n        for (const trigger of triggers) {\n            const type = trigger.type || 'audio';\n\n            if (type === 'audio') {\n                actions.push({\n                    type: 'audio',\n                    sound: trigger.sound || trigger.url,\n                    volume: trigger.volume ?? 0.8,\n                    loop: trigger.loop ?? false,\n                    refDistance: trigger.ref_distance ?? 10,\n                    rolloff: trigger.rolloff ?? 1.0,\n                    stopOnExit: trigger.stop_on_exit ?? true\n                });\n            } else if (type === 'motion') {\n                const offset = trigger.offset;\n                actions.push({\n                    type: 'motion',\n                    offset: offset ? new THREE.Vector3(offset.x || 0, offset.y || 0, offset.z || 0) : new THREE.Vector3(0, 1, 0),\n                    duration: trigger.duration ?? 1.0,\n                    easing: trigger.easing || 'easeInOutQuad'\n                });\n            } else if (type === 'scale') {\n                actions.push({\n                    type: 'scale',\n                    from: trigger.from ?? 1.0,\n                    to: trigger.to ?? 1.5,\n                    duration: trigger.duration ?? 0.5,\n                    easing: trigger.easing || 'easeInOutQuad'\n                });\n            } else if (type === 'rotation') {\n                const axis = trigger.axis;\n                actions.push({\n                    type: 'rotation',\n                    axis: axis ? new THREE.Vector3(axis.x || 0, axis.y || 1, axis.z || 0) : new THREE.Vector3(0, 1, 0),\n                    angle: trigger.angle ?? Math.PI * 2,\n                    duration: trigger.duration ?? 2.0,\n                    continuous: trigger.continuous ?? false\n                });\n            } else if (type === 'visibility') {\n                actions.push({\n                    type: 'visibility',\n                    fadeIn: trigger.fade_in ?? false,\n                    duration: trigger.duration ?? 0.3\n                });\n            }\n        }\n\n        if (actions.length === 0) return;\n\n        const triggerDistance = item?.current?.properties?.trigger_distance ?? 10;\n        const exitDistance = item?.current?.properties?.exit_distance ?? triggerDistance * 1.2;\n        const once = item?.current?.properties?.trigger_once ?? false;\n        const cooldown = item?.current?.properties?.trigger_cooldown ?? 0;\n\n        this.proximityTriggerManager.addTrigger(itemId, {\n            object3d,\n            triggerDistance,\n            exitDistance,\n            actions,\n            once,\n            cooldown,\n            debugName: `Overlay:${itemId}`\n        });\n    }\n\n    /**\n     * Setup physics for an item\n     */\n    _setupPhysics(itemId, object3d, item) {\n        if (!this.physicsSystem || !object3d) return;\n\n        const props = item?.current?.properties || {};\n        const physicsEnabled = props.physics_enabled === true;\n\n        if (!physicsEnabled) return;\n\n        // Get physics parameters\n        const mass = props.physics_mass ?? 1.0;\n        const restitution = props.physics_restitution ?? 0.3;\n        const friction = props.physics_friction ?? 0.7;\n        const radius = props.physics_radius ?? (props.size_m ? props.size_m * 0.5 : null);\n\n        // Add physics to object\n        const physicsData = this.physicsSystem.addPhysicsObject(object3d, {\n            mass,\n            restitution,\n            friction,\n            radius\n        });\n\n        if (physicsData) {\n            object3d.userData.hasPhysics = true;\n            object3d.userData.physicsData = physicsData;\n\n            this._logDebug(`[OverlaySubsystem] Physics enabled for ${itemId}:`, {\n                mass,\n                restitution,\n                friction,\n                radius\n            });\n        }\n\n        // Handle custom physics trigger action (spawn physics on proximity)\n        const triggers = props.proximity_triggers;\n        if (triggers && Array.isArray(triggers)) {\n            for (const trigger of triggers) {\n                if (trigger.type === 'custom' && trigger.action === 'spawn_physics') {\n                    this._setupPhysicsSpawnTrigger(itemId, object3d, item);\n                }\n            }\n        }\n    }\n\n    /**\n     * Setup physics spawn trigger - creates physics object on proximity\n     */\n    _setupPhysicsSpawnTrigger(itemId, object3d, item) {\n        if (!this.proximityTriggerManager || !this.physicsSystem) return;\n\n        const props = item?.current?.properties || {};\n        const triggerDistance = props.trigger_distance ?? 100;\n        const exitDistance = props.exit_distance ?? triggerDistance * 1.2;\n        const once = props.trigger_once ?? true;\n\n        this.proximityTriggerManager.addTrigger(`${itemId}-physics-spawn`, {\n            object3d,\n            triggerDistance,\n            exitDistance,\n            once,\n            actions: [\n                {\n                    type: 'custom',\n                    callback: ({ isEntering }) => {\n                        if (isEntering && !object3d.userData.physicsSpawned) {\n                            // Enable physics on this object\n                            const mass = props.physics_mass ?? 1.0;\n                            const restitution = props.physics_restitution ?? 0.3;\n                            const friction = props.physics_friction ?? 0.7;\n                            const radius = props.physics_radius ?? (props.size_m ? props.size_m * 0.5 : null);\n\n                            const physicsData = this.physicsSystem.addPhysicsObject(object3d, {\n                                mass,\n                                restitution,\n                                friction,\n                                radius\n                            });\n\n                            if (physicsData) {\n                                object3d.userData.hasPhysics = true;\n                                object3d.userData.physicsData = physicsData;\n                                object3d.userData.physicsSpawned = true;\n\n                                this._logDebug(`[OverlaySubsystem] Physics spawned for ${itemId} - ball will fall!`);\n\n                                // Disable align_to_surface so it falls\n                                object3d.userData.disableAlignment = true;\n                            }\n                        }\n                    }\n                }\n            ],\n            debugName: `Overlay:${itemId}:PhysicsSpawn`\n        });\n    }\n\n    /**\n     * Wire an item's media playback controller to its authored trigger:\n     * proximity range, a click/tap on the item, or always on.\n     */\n    _setupMediaPlayback(itemId, object3d, item) {\n        const playback = object3d?.userData?.mediaPlayback;\n        if (!playback) return;\n        playback.configure(item?.current?.properties || {});\n        const overlayIdFor = () => {\n            if (item?.overlay_id) return item.overlay_id;\n            for (const [overlayId, entry] of this.overlays) {\n                if (entry.items?.has(itemId)) return overlayId;\n            }\n            return null;\n        };\n        playback.setBroadcaster((message) => this.broadcastMediaPlayback(overlayIdFor(), itemId, message));\n\n        const { trigger, rangeM } = playback.config;\n        if (trigger === 'proximity' && this.proximityTriggerManager) {\n            this.proximityTriggerManager.addTrigger(`${itemId}-media`, {\n                object3d,\n                triggerDistance: rangeM,\n                exitDistance: rangeM * 1.15,\n                actions: [{ type: 'custom', callback: ({ isEntering }) => playback.setInRange(isEntering) }],\n                debugName: `Overlay:${itemId}:Media`\n            });\n        }\n        if (this.clickTriggerManager) {\n            // Every media surface is clickable: interaction toggles playback,\n            // other triggers use it to unblock a refused autoplay. One click\n            // trigger per object wins the raycast, so join authored actions.\n            const authored = this.clickTriggerManager.triggers?.get?.(itemId);\n            if (authored) {\n                authored.actions = [...(authored.actions || []), { type: 'custom', callback: () => playback.interact() }];\n                return;\n            }\n            this.clickTriggerManager.addTrigger(`${itemId}-media`, {\n                object3d,\n                actions: [{ type: 'custom', callback: () => playback.interact() }],\n                debugName: `Overlay:${itemId}:Media`\n            });\n        }\n    }\n\n    /**\n     * Setup click triggers for an item\n     */\n    _setupClickTriggers(itemId, object3d, item) {\n        if (!this.clickTriggerManager || !object3d) return;\n\n        const props = item?.current?.properties || {};\n        const clickTriggers = props.click_triggers;\n\n        if (!clickTriggers || !Array.isArray(clickTriggers) || clickTriggers.length === 0) return;\n\n        // Parse conditions\n        const conditions = [];\n        const clickConditions = props.click_conditions;\n\n        if (clickConditions && Array.isArray(clickConditions)) {\n            for (const cond of clickConditions) {\n                const type = cond.type || 'proximity';\n\n                if (type === 'proximity') {\n                    conditions.push({\n                        type: 'proximity',\n                        distance: cond.distance ?? 100,\n                        min_distance: cond.min_distance ?? 0\n                    });\n                } else if (type === 'state') {\n                    conditions.push({\n                        type: 'state',\n                        key: cond.key || 'state',\n                        value: cond.value,\n                        operator: cond.operator || 'equals'\n                    });\n                } else if (type === 'click_count') {\n                    conditions.push({\n                        type: 'click_count',\n                        min: cond.min ?? 0,\n                        max: cond.max ?? Infinity\n                    });\n                }\n            }\n        }\n\n        // Parse actions\n        const actions = [];\n\n        for (const trigger of clickTriggers) {\n            const type = trigger.type || 'custom';\n\n            if (type === 'physics') {\n                actions.push({\n                    type: 'physics',\n                    spawn: trigger.spawn ?? true,\n                    mass: trigger.mass ?? 1.0,\n                    restitution: trigger.restitution ?? 0.3,\n                    friction: trigger.friction ?? 0.7,\n                    radius: trigger.radius ?? null\n                });\n            } else if (type === 'audio') {\n                actions.push({\n                    type: 'audio',\n                    sound: trigger.sound || trigger.url,\n                    volume: trigger.volume ?? 0.8,\n                    loop: trigger.loop ?? false,\n                    blip: trigger.blip ?? false,\n                    intensity: trigger.intensity ?? 0.5\n                });\n            } else if (type === 'state') {\n                actions.push({\n                    type: 'state',\n                    key: trigger.key || 'state',\n                    value: trigger.value\n                });\n            } else if (type === 'visibility') {\n                actions.push({\n                    type: 'visibility',\n                    visible: trigger.visible\n                });\n            } else if (type === 'material') {\n                actions.push({\n                    type: 'material',\n                    color: trigger.color,\n                    emissive: trigger.emissive,\n                    opacity: trigger.opacity\n                });\n            }\n        }\n\n        if (actions.length === 0 && conditions.length === 0) return;\n\n        const hoverEnabled = props.hover_enabled ?? true;\n        const clickEnabled = props.click_enabled ?? true;\n\n        this.clickTriggerManager.addTrigger(itemId, {\n            object3d,\n            conditions,\n            actions,\n            hoverEnabled,\n            clickEnabled,\n            debugName: `Overlay:${itemId}`\n        });\n\n        this._logDebug(`[OverlaySubsystem] Click trigger added for ${itemId}:`, {\n            conditions: conditions.length,\n            actions: actions.length,\n            hoverEnabled,\n            clickEnabled\n        });\n    }\n\n    dispose() {\n        if (this._disposed) return;\n        this._disposed = true;\n        this._session?.dispose();\n        for (const job of this._pageLoads?.values() || []) job.controller.abort(new DOMException('Disposed', 'AbortError'));\n        for (const build of this._overlayBuilds?.values() || []) build.abort(new DOMException('Disposed', 'AbortError'));\n        this._modelCapacityUnsubscribe?.();\n        this._modelCapacityUnsubscribe = null;\n\n        if (this._transportInitTimer) {\n            clearTimeout(this._transportInitTimer);\n            this._transportInitTimer = null;\n        }\n\n        try {\n            this._changeSubscription?.unsubscribe?.();\n        } catch (_) {}\n        try {\n            this._livePositionSubscription?.unsubscribe?.();\n        } catch (_) {}\n        try { this._hydraIngressSubscription?.unsubscribe?.(); } catch (_) {}\n        try { this._hydraIngressLegacySubscription?.unsubscribe?.(); } catch (_) {}\n        this._changeSubscription = null;\n        this._livePositionSubscription = null;\n        this._hydraIngressSubscription = null;\n        this._hydraIngressLegacySubscription = null;\n\n        const overlayIds = Array.from(this.overlays.keys());\n        const retirements = overlayIds.map(overlayId => this.unload(overlayId));\n        this._overlaySubscriptions.clear();\n        this._proximityItems.clear();\n        this._surfaceAnchorRetries?.clear();\n        this._surfaceAnchorRetryTask = null;\n        this._queuedSurfaceAnchorRetry = null;\n        this._unavailableModelUrls.clear();\n\n        this._hoveredItem = null;\n        this._placementReviewPreview = null;\n        this._geoContext = null;\n        this._geoRefreshPending = false;\n        return Promise.allSettled(retirements);\n    }\n}\n","/**\n * OverlayApiService\n *\n * API client for overlay CRUD operations.\n * Uses the AuthService for authenticated requests.\n */\n\nimport { getAuthService } from '../auth/AuthService.js';\nimport { getBackendApiBase } from '../shared/backend.js';\nimport { OverlayPageClient, OverlayPageClientError } from './OverlayPageClient.js';\nimport { jsonRetentionWeight } from '../shared/JsonRetentionWeight.js';\n\nconst API_BASE = getBackendApiBase();\n\n/**\n * Rich error class for overlay API failures. Carries the structured\n * reason codes, HTTP status, and any quota/gating metadata from the\n * backend so the UI can render specific CTAs (e.g. \"Hold more NOCLIP\"\n * for OVERLAY_QUOTA_EXCEEDED) instead of a generic error toast.\n */\nexport class OverlayApiError extends Error {\n  constructor(message, { status, errorCode, reason, reasonCodes, payload } = {}) {\n    super(message);\n    this.name = 'OverlayApiError';\n    this.status = status || 0;\n    this.errorCode = errorCode || null;\n    this.reason = reason || null;\n    this.reasonCodes = Array.isArray(reasonCodes) ? reasonCodes : [];\n    this.payload = payload || null;\n  }\n\n  isQuotaExceeded() {\n    return this.reason === 'resource-cap'\n      || this.reason === 'OVERLAY_QUOTA_EXCEEDED'\n      || this.errorCode === 'OVERLAY_QUOTA_EXCEEDED'\n      || this.errorCode === 'RESOURCE_QUOTA_EXCEEDED';\n  }\n\n  isGatingDenied() {\n    return this.status === 403 && this.payload?.gated === true;\n  }\n\n  isAuthRequired() {\n    return this.status === 401;\n  }\n}\n\nexport class OverlayApiService {\n  constructor() {\n    this.authService = getAuthService();\n  }\n\n  _getPageClient() {\n    if (!this._pageClient) this._pageClient = new OverlayPageClient({\n      baseUrl: API_BASE,\n      request: (url, options) => this.authService.authenticatedFetch(url, options),\n      principal: () => {\n        const state = this.authService.getState();\n        if (!state?.isAuthenticated) return null;\n        return state.user?.userId || state.user?.user_id || state.user?.id || state.userId || state.session?.userId || null;\n      },\n    });\n    return this._pageClient;\n  }\n\n  /** Pull-based pages: the next request starts only after the consumer resumes. */\n  streamOverlay(overlayId, options = {}) {\n    return this._getPageClient().stream(overlayId, options);\n  }\n\n  /**\n   * Create a new overlay\n   *\n   * Throws OverlayApiError on non-2xx responses with full\n   * reason/payload preserved so the caller can show the right CTA.\n   */\n  async createOverlay({ title, description, visibility = 'private', metadata, geoGate }) {\n    const response = await this.authService.authenticatedFetch(`${API_BASE}/overlays`, {\n      method: 'POST',\n      headers: { 'Content-Type': 'application/json' },\n      body: JSON.stringify({ title, description, visibility, metadata, geoGate }),\n    });\n\n    const data = await response.json().catch(() => ({}));\n    if (!response.ok) {\n      throw new OverlayApiError(data.message || data.error || 'Failed to create overlay', {\n        status: response.status,\n        errorCode: data.errorCode || data.error || null,\n        reason: data.reason || null,\n        reasonCodes: data.reasonCodes || [],\n        payload: data,\n      });\n    }\n    return data.overlay;\n  }\n\n  /**\n   * List user's overlays\n   */\n  async listOverlays({ limit = 50, offset = 0, includePublic = false, includeOwnedEntries = false, signal } = {}) {\n    if (includeOwnedEntries) throw new OverlayPageClientError('OVERLAY_DOCUMENT_REQUIRES_STREAMING');\n    const params = {\n      limit: String(limit),\n      offset: String(offset),\n      includePublic: String(includePublic),\n      includeOwnedEntries: 'false',\n    };\n    const client = this._getPageClient();\n    const lease = await client.read('/overlays', params, { signal, account: client.principal(), collection: true });\n    try {\n      if (!Array.isArray(lease.page.overlays) || lease.page.overlays.length > limit\n        || !Number.isSafeInteger(lease.page.total) || lease.page.total < 0) {\n        throw new OverlayPageClientError('INVALID_OVERLAY_PAGE');\n      }\n      return { ...lease.page, retentionWeight: lease.weight };\n    } finally { lease.release(); }\n  }\n\n  /**\n   * Collection discovery contains metadata only. Item acquisition belongs to\n   * streamOverlay; listing must never eagerly hydrate every owned overlay.\n   */\n  async listOverlayEntries({ includePublic = false, pageSize = 100, signal } = {}) {\n    const limit = Math.max(1, Math.min(100, Math.floor(pageSize) || 100));\n    const overlays = [];\n    const seen = new Set();\n    let weight = 0;\n    let offset = 0;\n    let total = 0;\n    do {\n      const page = await this.listOverlays({\n        limit,\n        offset,\n        includePublic,\n        includeOwnedEntries: false,\n        signal,\n      });\n      const pageOverlays = Array.isArray(page?.overlays) ? page.overlays : [];\n      weight += page.retentionWeight ?? jsonRetentionWeight(page, 32 * 1024 * 1024);\n      if (weight > 32 * 1024 * 1024) throw new OverlayPageClientError('OVERLAY_COLLECTION_REQUIRES_STREAMING');\n      for (const overlay of pageOverlays) {\n        const id = overlay?.overlay?.overlay_id;\n        if (!id || seen.has(id)) throw new OverlayPageClientError('OVERLAY_COLLECTION_CHANGED');\n        seen.add(id);\n      }\n      overlays.push(...pageOverlays);\n      total = Math.max(0, Number(page?.total) || 0);\n      offset += pageOverlays.length;\n      if (pageOverlays.length === 0 && offset < total) throw new OverlayPageClientError('OVERLAY_COLLECTION_CHANGED');\n    } while (offset < total);\n    return { overlays, ownedEntries: [], total };\n  }\n\n  /**\n   * Get a specific overlay (metadata only)\n   */\n  async getOverlay(overlayId) {\n    const response = await this.authService.authenticatedFetch(`${API_BASE}/overlays/${overlayId}`);\n    const data = await response.json();\n    if (!response.ok) {\n      throw new Error(data.error || 'Failed to get overlay');\n    }\n    return data.overlay;\n  }\n\n  /**\n   * Explicit compatibility/editor collection, never /full HTTP acquisition.\n   * Large interactive consumers must use streamOverlay, not this accumulator.\n   */\n  async getOverlayFull(overlayId, options = {}) {\n    let entry, weight = 0;\n    const layers = new Map();\n    for await (const chunk of this.streamOverlay(overlayId, options)) {\n      weight += chunk.weight;\n      if (weight > 32 * 1024 * 1024) throw new OverlayPageClientError('OVERLAY_DOCUMENT_REQUIRES_STREAMING');\n      if (chunk.kind === 'manifest') {\n        if (!entry) entry = { overlay: chunk.page.overlay, creatorUserId: chunk.page.creatorUserId, layers: [] };\n        for (const layer of chunk.page.layers) {\n          const target = { ...layer, items: [] }; layers.set(layer.layer_id, target); entry.layers.push(target);\n        }\n      } else {\n        layers.get(chunk.page.layerId).items.push(...chunk.page.items);\n      }\n    }\n    return entry;\n  }\n\n  /**\n   * Update an overlay\n   */\n  async updateOverlay(overlayId, { title, description, visibility, metadata, geoGate, signal }) {\n    const response = await this.authService.authenticatedFetch(`${API_BASE}/overlays/${overlayId}`, {\n      method: 'PATCH',\n      headers: { 'Content-Type': 'application/json' },\n      body: JSON.stringify({ title, description, visibility, metadata, geoGate }),\n      signal,\n    });\n\n    const data = await response.json();\n    if (!response.ok) {\n      throw new Error(data.error || 'Failed to update overlay');\n    }\n    return data.overlay;\n  }\n\n  async _motionPathRequest(path, { method = 'GET', body, signal, idempotencyKey } = {}) {\n    const headers = {};\n    if (body !== undefined) headers['Content-Type'] = 'application/json';\n    if (idempotencyKey) headers['Idempotency-Key'] = idempotencyKey;\n    const response = await this.authService.authenticatedFetch(`${API_BASE}${path}`, {\n      method,\n      headers,\n      ...(body !== undefined ? { body: JSON.stringify(body) } : {}),\n      signal,\n    });\n    const data = await response.json().catch(() => ({}));\n    if (!response.ok) {\n      throw new OverlayApiError(data.message || data.error || 'Motion path request failed', {\n        status: response.status,\n        errorCode: data.error || null,\n        reason: data.reason || null,\n        reasonCodes: data.diagnostics?.map?.(entry => entry.code).filter(Boolean) || [],\n        payload: data,\n      });\n    }\n    return data;\n  }\n\n  listMotionPaths(overlayId, { limit = 50, cursor, includeArchived = false, signal } = {}) {\n    const params = new URLSearchParams({ limit: String(limit), includeArchived: String(includeArchived) });\n    if (cursor) params.set('cursor', cursor);\n    return this._motionPathRequest(`/overlays/${overlayId}/paths?${params}`, { signal });\n  }\n\n  getMotionPath(overlayId, pathId, { signal } = {}) {\n    return this._motionPathRequest(`/overlays/${overlayId}/paths/${pathId}`, { signal });\n  }\n\n  createMotionPath(overlayId, definition, { signal, idempotencyKey } = {}) {\n    return this._motionPathRequest(`/overlays/${overlayId}/paths`, { method: 'POST', body: { definition }, signal, idempotencyKey });\n  }\n\n  updateMotionPath(overlayId, pathId, definition, { expectedRevision, expectedRowVersion, signal, idempotencyKey } = {}) {\n    return this._motionPathRequest(`/overlays/${overlayId}/paths/${pathId}`, {\n      method: 'PATCH', body: { definition, expectedRevision, expectedRowVersion }, signal, idempotencyKey,\n    });\n  }\n\n  validateMotionPath(overlayId, pathId, { definition, publication = false, signal } = {}) {\n    return this._motionPathRequest(`/overlays/${overlayId}/paths/${pathId}/validate`, { method: 'POST', body: { definition, publication }, signal });\n  }\n\n  publishMotionPath(overlayId, pathId, { expectedRevision, expectedRowVersion, signal, idempotencyKey } = {}) {\n    return this._motionPathRequest(`/overlays/${overlayId}/paths/${pathId}/publish`, {\n      method: 'POST', body: { expectedRevision, expectedRowVersion }, signal, idempotencyKey,\n    });\n  }\n\n  listMotionPathRevisions(overlayId, pathId, { limit = 50, cursor, signal } = {}) {\n    const params = new URLSearchParams({ limit: String(limit) });\n    if (cursor) params.set('cursor', String(cursor));\n    return this._motionPathRequest(`/overlays/${overlayId}/paths/${pathId}/revisions?${params}`, { signal });\n  }\n\n  getMotionPathRevision(overlayId, pathId, revision, { signal } = {}) {\n    return this._motionPathRequest(`/overlays/${overlayId}/paths/${pathId}/revisions/${revision}`, { signal });\n  }\n\n  restoreMotionPathRevision(overlayId, pathId, revision, { expectedRowVersion, signal, idempotencyKey } = {}) {\n    return this._motionPathRequest(`/overlays/${overlayId}/paths/${pathId}/revisions/${revision}/restore`, {\n      method: 'POST', body: { expectedRowVersion }, signal, idempotencyKey,\n    });\n  }\n\n  archiveMotionPath(overlayId, pathId, { expectedRevision, expectedRowVersion, signal, idempotencyKey } = {}) {\n    return this._motionPathRequest(`/overlays/${overlayId}/paths/${pathId}`, {\n      method: 'DELETE', body: { expectedRevision, expectedRowVersion }, signal, idempotencyKey,\n    });\n  }\n\n  _planningSegment(kind) {\n    if (kind === 'region') return 'regions';\n    if (kind === 'travel-plan') return 'travel-plans';\n    if (kind === 'mission') return 'missions';\n    throw new TypeError('Unsupported operational planning resource.');\n  }\n\n  _planningRequest(kind, overlayId, suffix = '', options = {}) {\n    return this._motionPathRequest(`/overlays/${overlayId}/${this._planningSegment(kind)}${suffix}`, options);\n  }\n\n  listPlanningResources(kind, overlayId, { limit = 50, cursor, includeArchived = false, signal } = {}) {\n    const params = new URLSearchParams({ limit: String(limit), includeArchived: String(includeArchived) });\n    if (cursor) params.set('cursor', cursor);\n    return this._planningRequest(kind, overlayId, `?${params}`, { signal });\n  }\n\n  getPlanningResource(kind, overlayId, resourceId, { signal } = {}) {\n    return this._planningRequest(kind, overlayId, `/${resourceId}`, { signal });\n  }\n\n  createPlanningResource(kind, overlayId, definition, { signal, idempotencyKey } = {}) {\n    return this._planningRequest(kind, overlayId, '', { method: 'POST', body: { definition }, signal, idempotencyKey });\n  }\n\n  updatePlanningResource(kind, overlayId, resourceId, definition, { expectedRevision, expectedRowVersion, signal, idempotencyKey } = {}) {\n    return this._planningRequest(kind, overlayId, `/${resourceId}`, { method: 'PATCH', body: { definition, expectedRevision, expectedRowVersion }, signal, idempotencyKey });\n  }\n\n  validatePlanningResource(kind, overlayId, resourceId, { definition, publication = false, signal } = {}) {\n    return this._planningRequest(kind, overlayId, `/${resourceId}/validate`, { method: 'POST', body: { definition, publication }, signal });\n  }\n\n  publishPlanningResource(kind, overlayId, resourceId, { expectedRevision, expectedRowVersion, signal, idempotencyKey } = {}) {\n    return this._planningRequest(kind, overlayId, `/${resourceId}/publish`, { method: 'POST', body: { expectedRevision, expectedRowVersion }, signal, idempotencyKey });\n  }\n\n  listPlanningRevisions(kind, overlayId, resourceId, { limit = 50, cursor, signal } = {}) {\n    const params = new URLSearchParams({ limit: String(limit) });\n    if (cursor) params.set('cursor', String(cursor));\n    return this._planningRequest(kind, overlayId, `/${resourceId}/revisions?${params}`, { signal });\n  }\n\n  restorePlanningRevision(kind, overlayId, resourceId, revision, { expectedRowVersion, signal, idempotencyKey } = {}) {\n    return this._planningRequest(kind, overlayId, `/${resourceId}/revisions/${revision}/restore`, { method: 'POST', body: { expectedRowVersion }, signal, idempotencyKey });\n  }\n\n  archivePlanningResource(kind, overlayId, resourceId, { expectedRevision, expectedRowVersion, signal, idempotencyKey } = {}) {\n    return this._planningRequest(kind, overlayId, `/${resourceId}`, { method: 'DELETE', body: { expectedRevision, expectedRowVersion }, signal, idempotencyKey });\n  }\n\n  admitMissionExecution(input, { signal, idempotencyKey } = {}) {\n    return this._motionPathRequest('/mission-executions', { method: 'POST', body: input, signal, idempotencyKey });\n  }\n\n  listMissionExecutions({ limit = 50, cursor, signal } = {}) {\n    const params = new URLSearchParams({ limit: String(limit) }); if (cursor) params.set('cursor', cursor);\n    return this._motionPathRequest(`/mission-executions?${params}`, { signal });\n  }\n\n  getMissionExecution(executionId, { signal } = {}) {\n    return this._motionPathRequest(`/mission-executions/${executionId}`, { signal });\n  }\n\n  commandMissionExecution(executionId, action, { expectedRowVersion, deadline, signal, idempotencyKey } = {}) {\n    return this._motionPathRequest(`/mission-executions/${executionId}/actions`, { method: 'POST', body: { action, expectedRowVersion, ...(deadline ? { deadline } : {}) }, signal, idempotencyKey });\n  }\n\n  reconcileMissionExecution(executionId, { expectedRowVersion, signal, idempotencyKey } = {}) {\n    return this._motionPathRequest(`/mission-executions/${executionId}/reconcile`, { method: 'POST', body: { expectedRowVersion }, signal, idempotencyKey });\n  }\n\n  getMissionExecutionEvents(executionId, { after = 0, limit = 100, signal } = {}) {\n    const params = new URLSearchParams({ after: String(after), limit: String(limit) });\n    return this._motionPathRequest(`/mission-executions/${executionId}/events?${params}`, { signal });\n  }\n\n  getMissionExecutionObservability(executionId, { commandLimit = 25, telemetryLimit = 120, signal } = {}) {\n    const params = new URLSearchParams({ commandLimit: String(commandLimit), telemetryLimit: String(telemetryLimit) });\n    return this._motionPathRequest(`/mission-executions/${executionId}/observability?${params}`, { signal });\n  }\n\n  _pathExecutionAuthorityRequest(path, { method = 'GET', body, grantSecret, signal, idempotencyKey } = {}) {\n    const headers = {};\n    if (body !== undefined) headers['Content-Type'] = 'application/json';\n    if (idempotencyKey) headers['Idempotency-Key'] = idempotencyKey;\n    // Capability secrets are deliberately accepted only as an ephemeral argument.\n    // They are never retained on the API service or serialized into workspace recovery.\n    if (grantSecret) headers['X-Noclip-Execution-Grant'] = grantSecret;\n    return this.authService.authenticatedFetch(`${API_BASE}${path}`, {\n      method, headers, ...(body !== undefined ? { body: JSON.stringify(body) } : {}), signal,\n    }).then(async response => {\n      const data = await response.json().catch(() => ({}));\n      if (!response.ok) throw new OverlayApiError(data.message || data.error || 'Path execution authority request failed', {\n        status: response.status, errorCode: data.error || null, payload: data,\n      });\n      return data;\n    });\n  }\n\n  issuePathExecutionGrant(input, options = {}) {\n    return this._pathExecutionAuthorityRequest('/path-execution-grants', { method: 'POST', body: input, ...options });\n  }\n\n  createPathExecution(input, { grantSecret, ...options } = {}) {\n    return this._pathExecutionAuthorityRequest('/path-executions', { method: 'POST', body: input, grantSecret, ...options });\n  }\n\n  acquirePathExecutionLease(executionId, { ttlSeconds = 120, grantSecret, ...options } = {}) {\n    return this._pathExecutionAuthorityRequest(`/path-executions/${executionId}/lease/acquire`, { method: 'POST', body: { ttlSeconds }, grantSecret, ...options });\n  }\n\n  renewPathExecutionLease(executionId, { leaseId, generation, ttlSeconds = 120, grantSecret, ...options } = {}) {\n    return this._pathExecutionAuthorityRequest(`/path-executions/${executionId}/lease/renew`, { method: 'POST', body: { leaseId, generation, ttlSeconds }, grantSecret, ...options });\n  }\n\n  releasePathExecutionLease(executionId, { leaseId, generation, grantSecret, ...options } = {}) {\n    return this._pathExecutionAuthorityRequest(`/path-executions/${executionId}/lease/release`, { method: 'POST', body: { leaseId, generation }, grantSecret, ...options });\n  }\n\n  createFleet(definition, { overlayId, signal } = {}) { return this._motionPathRequest('/fleets', { method: 'POST', body: { definition, ...(overlayId ? { overlayId } : {}) }, signal }); }\n  listFleets({ limit = 50, cursor, includeArchived = false, signal } = {}) { const params = new URLSearchParams({ limit: String(limit), includeArchived: String(includeArchived) }); if (cursor) params.set('cursor', cursor); return this._motionPathRequest(`/fleets?${params}`, { signal }); }\n  getFleet(fleetId, { signal } = {}) { return this._motionPathRequest(`/fleets/${fleetId}`, { signal }); }\n  updateFleet(fleetId, definition, expectedRowVersion, { signal } = {}) { return this._motionPathRequest(`/fleets/${fleetId}`, { method: 'PATCH', body: { definition, expectedRowVersion }, signal }); }\n  archiveFleet(fleetId, expectedRowVersion, { signal } = {}) { return this._motionPathRequest(`/fleets/${fleetId}`, { method: 'DELETE', body: { expectedRowVersion }, signal }); }\n  listFleetMembers(fleetId, { limit = 100, cursor, signal } = {}) { const params = new URLSearchParams({ limit: String(limit) }); if (cursor) params.set('cursor', cursor); return this._motionPathRequest(`/fleets/${fleetId}/members?${params}`, { signal }); }\n  addFleetMember(fleetId, definition, { signal } = {}) { return this._motionPathRequest(`/fleets/${fleetId}/members`, { method: 'POST', body: definition, signal }); }\n  proposeFleetAssignment(fleetId, missionId, { expiresInSeconds = 300, signal } = {}) { return this._motionPathRequest(`/fleets/${fleetId}/assignment-proposals`, { method: 'POST', body: { missionId, expiresInSeconds }, signal }); }\n  listFleetAssignments(fleetId, { status, limit = 100, cursor, signal } = {}) { const params = new URLSearchParams({ limit: String(limit) }); if (status) params.set('status', status); if (cursor) params.set('cursor', cursor); return this._motionPathRequest(`/fleets/${fleetId}/assignments?${params}`, { signal }); }\n  acceptFleetAssignment(fleetId, assignmentId, expectedRowVersion, { signal } = {}) { return this._motionPathRequest(`/fleets/${fleetId}/assignments/${assignmentId}/accept`, { method: 'POST', body: { expectedRowVersion }, signal }); }\n  cancelFleetAssignment(fleetId, assignmentId, expectedRowVersion, reason, { signal } = {}) { return this._motionPathRequest(`/fleets/${fleetId}/assignments/${assignmentId}/cancel`, { method: 'POST', body: { expectedRowVersion, reason }, signal }); }\n  reassignFleetAssignment(fleetId, assignmentId, expectedRowVersion, reason, { expiresInSeconds = 300, signal } = {}) { return this._motionPathRequest(`/fleets/${fleetId}/assignments/${assignmentId}/reassign`, { method: 'POST', body: { expectedRowVersion, reason, expiresInSeconds }, signal }); }\n  updateFleetMember(fleetId, memberId, input, { signal } = {}) { return this._motionPathRequest(`/fleets/${fleetId}/members/${memberId}`, { method: 'PATCH', body: input, signal }); }\n  issueFleetDelegation(fleetId, definition, { signal } = {}) { return this._motionPathRequest(`/fleets/${fleetId}/delegations`, { method: 'POST', body: definition, signal }); }\n  listFleetDelegations(fleetId, { includeRevoked = false, signal } = {}) { return this._motionPathRequest(`/fleets/${fleetId}/delegations?includeRevoked=${includeRevoked}`, { signal }); }\n  revokeFleetDelegation(fleetId, delegationId, reason, { signal } = {}) { return this._motionPathRequest(`/fleets/${fleetId}/delegations/${delegationId}/revoke`, { method: 'POST', body: { reason }, signal }); }\n\n  /**\n   * Delete an overlay\n   */\n  async deleteOverlay(overlayId) {\n    const response = await this.authService.authenticatedFetch(`${API_BASE}/overlays/${overlayId}`, {\n      method: 'DELETE',\n    });\n\n    const data = await response.json();\n    if (!response.ok) {\n      throw new Error(data.error || 'Failed to delete overlay');\n    }\n    return true;\n  }\n\n  /**\n   * Create a layer in an overlay\n   */\n  async createLayer(overlayId, {\n    layerType,\n    name,\n    styleJson,\n    inheritPolicies = true,\n    dataSourceVersionId,\n  }) {\n    const response = await this.authService.authenticatedFetch(`${API_BASE}/overlays/${overlayId}/layers`, {\n      method: 'POST',\n      headers: { 'Content-Type': 'application/json' },\n      body: JSON.stringify({ layerType, name, styleJson, inheritPolicies, dataSourceVersionId }),\n    });\n\n    const data = await response.json();\n    if (!response.ok) {\n      throw new Error(data.error || 'Failed to create layer');\n    }\n    return data.layer;\n  }\n\n  /**\n   * Get layer metadata only. Item browsing uses getLayerItemsPage; selectors\n   * must not download every model/annotation merely to choose a layer.\n   */\n  async getLayers(overlayId, options = {}) {\n    const layers = []; let weight = 0;\n    for await (const chunk of this.streamOverlay(overlayId, { ...options, metadataOnly: true })) {\n      weight += chunk.weight;\n      if (weight > 32 * 1024 * 1024) throw new OverlayPageClientError('OVERLAY_DOCUMENT_REQUIRES_STREAMING');\n      layers.push(...chunk.page.layers);\n    }\n    return layers;\n  }\n\n  getOverlayManifestPage(overlayId, options = {}) {\n    return this._getPageClient().manifestPage(overlayId, options);\n  }\n\n  async getLayerItemsPage(overlayId, layerId, options = {}) {\n    const revision = options.revision || (await this.getOverlayManifestPage(overlayId, options)).page.revision;\n    return this._getPageClient().itemPage(overlayId, layerId, { ...options, revision });\n  }\n\n  async findLayer(overlayId, predicate, options = {}) {\n    for await (const chunk of this.streamOverlay(overlayId, { ...options, metadataOnly: true })) {\n      const layer = chunk.page.layers.find(predicate);\n      if (layer) return layer;\n    }\n    return null;\n  }\n\n  /**\n   * Update layer configuration, including persisted dynamic input bindings in\n   * styleJson.\n   */\n  async updateLayer(layerId, { name, styleJson, inheritPolicies, dataSourceVersionId } = {}) {\n    const response = await this.authService.authenticatedFetch(`${API_BASE}/layers/${layerId}`, {\n      method: 'PATCH',\n      headers: { 'Content-Type': 'application/json' },\n      body: JSON.stringify({ name, styleJson, inheritPolicies, dataSourceVersionId }),\n    });\n\n    const data = await response.json();\n    if (!response.ok) {\n      throw new Error(data.error || 'Failed to update layer');\n    }\n    return data.layer;\n  }\n\n  /** Reversibly archive a layer. */\n  async deleteLayer(layerId) {\n    const response = await this.authService.authenticatedFetch(`${API_BASE}/layers/${layerId}`, {\n      method: 'DELETE',\n    });\n\n    const data = await response.json();\n    if (!response.ok) {\n      throw new Error(data.error || 'Failed to delete layer');\n    }\n    return true;\n  }\n\n  async restoreLayer(layerId) {\n    const response = await this.authService.authenticatedFetch(`${API_BASE}/layers/${layerId}/restore`, { method: 'POST' });\n    const data = await response.json();\n    if (!response.ok) throw new Error(data.error || 'Failed to restore layer');\n    return true;\n  }\n\n  /**\n   * Create an item in a layer\n   */\n  async createItem(layerId, { itemType, geom, elevationM, orientationQuat, properties }) {\n    const response = await this.authService.authenticatedFetch(`${API_BASE}/layers/${layerId}/items`, {\n      method: 'POST',\n      headers: { 'Content-Type': 'application/json' },\n      body: JSON.stringify({ itemType, geom, elevationM, orientationQuat, properties }),\n    });\n\n    const data = await response.json();\n    if (!response.ok) {\n      throw new Error(data.error || 'Failed to create item');\n    }\n    return data.item;\n  }\n\n  /**\n   * Update an item\n   */\n  async updateItem(itemId, { geom, elevationM, orientationQuat, properties }) {\n    const response = await this.authService.authenticatedFetch(`${API_BASE}/items/${itemId}`, {\n      method: 'PATCH',\n      headers: { 'Content-Type': 'application/json' },\n      body: JSON.stringify({ geom, elevationM, orientationQuat, properties }),\n    });\n\n    const data = await response.json();\n    if (!response.ok) {\n      throw new Error(data.error || 'Failed to update item');\n    }\n    return data.item;\n  }\n\n  /** Reversibly archive an item. */\n  async deleteItem(itemId) {\n    const response = await this.authService.authenticatedFetch(`${API_BASE}/items/${itemId}`, {\n      method: 'DELETE',\n    });\n\n    const data = await response.json();\n    if (!response.ok) {\n      throw new Error(data.error || 'Failed to delete item');\n    }\n    return true;\n  }\n\n  async restoreItem(itemId) {\n    const response = await this.authService.authenticatedFetch(`${API_BASE}/items/${itemId}/restore`, { method: 'POST' });\n    const data = await response.json();\n    if (!response.ok) throw new Error(data.error || 'Failed to restore item');\n    return true;\n  }\n\n  /**\n   * Get item version history\n   */\n  async getItemHistory(itemId) {\n    const response = await this.authService.authenticatedFetch(`${API_BASE}/items/${itemId}/history`);\n    const data = await response.json();\n    if (!response.ok) {\n      throw new Error(data.error || 'Failed to get item history');\n    }\n    return data.history;\n  }\n\n  // ============================================\n  // THEATER ENDPOINTS\n  // ============================================\n\n  /**\n   * Create a theater channel for an overlay item\n   */\n  async createTheaterChannel({ itemId, overlayId, sourceType, title, embedUrl } = {}) {\n    const response = await this.authService.authenticatedFetch(`${API_BASE}/theater/channels`, {\n      method: 'POST',\n      headers: { 'Content-Type': 'application/json' },\n      body: JSON.stringify({ itemId, overlayId, sourceType, title, embedUrl }),\n    });\n\n    const data = await response.json();\n    if (!response.ok) {\n      throw new Error(data.error || 'Failed to create theater channel');\n    }\n    return data.channel;\n  }\n\n  /**\n   * Get theater channel by channel ID\n   */\n  async getTheaterChannel(channelId) {\n    const response = await this.authService.authenticatedFetch(`${API_BASE}/theater/channels/${channelId}`);\n    const data = await response.json();\n    if (!response.ok) {\n      throw new Error(data.error || 'Failed to get theater channel');\n    }\n    return data.channel;\n  }\n\n  /**\n   * Get theater channel linked to an item\n   */\n  async getTheaterChannelByItem(itemId) {\n    const response = await this.authService.authenticatedFetch(`${API_BASE}/theater/items/${itemId}/channel`);\n    const data = await response.json();\n    if (!response.ok) {\n      throw new Error(data.error || 'Failed to get theater channel');\n    }\n    return data.channel;\n  }\n\n  /**\n   * Delete theater channel\n   */\n  async deleteTheaterChannel(channelId) {\n    const response = await this.authService.authenticatedFetch(`${API_BASE}/theater/channels/${channelId}`, {\n      method: 'DELETE',\n    });\n    const data = await response.json();\n    if (!response.ok) {\n      throw new Error(data.error || 'Failed to delete theater channel');\n    }\n    return true;\n  }\n\n  /**\n   * Create a short-lived RTMP ingest token\n   */\n  async createTheaterIngestToken(channelId) {\n    const response = await this.authService.authenticatedFetch(`${API_BASE}/theater/channels/${channelId}/token`, {\n      method: 'POST',\n    });\n    const data = await response.json();\n    if (!response.ok) {\n      throw new Error(data.error || 'Failed to create ingest token');\n    }\n    return data.token;\n  }\n\n  // ============================================\n  // FILE ENDPOINTS\n  // ============================================\n\n  /**\n   * Upload a file\n   */\n  async uploadFile(file, role = null, encrypt = false, options = {}) {\n    const formData = new FormData();\n    formData.append('file', file);\n\n    const params = new URLSearchParams();\n    if (role) params.set('role', role);\n    params.set('encrypt', encrypt ? 'true' : 'false');\n    const url = `${API_BASE}/files?${params.toString()}`;\n    const response = await this.authService.authenticatedFetch(url, {\n      method: 'POST',\n      body: formData,\n      signal: options.signal,\n    });\n\n    const data = await response.json();\n    if (!response.ok) {\n      throw new Error(data.error || 'Failed to upload file');\n    }\n    return data.file;\n  }\n\n  /**\n   * Link a file to an item\n   */\n  async linkFileToItem(fileId, itemId, role, options = {}) {\n    const response = await this.authService.authenticatedFetch(`${API_BASE}/files/${fileId}/link`, {\n      method: 'POST',\n      headers: { 'Content-Type': 'application/json' },\n      body: JSON.stringify({ itemId, role }),\n      signal: options.signal,\n    });\n\n    const data = await response.json();\n    if (!response.ok) {\n      throw new Error(data.error || 'Failed to link file');\n    }\n    return data.link;\n  }\n\n  /**\n   * Get files for an item\n   */\n  async getItemFiles(itemId, options = {}) {\n    const response = await this.authService.authenticatedFetch(`${API_BASE}/items/${itemId}/files`, { signal: options.signal });\n    const data = await response.json();\n    if (!response.ok) {\n      throw new Error(data.error || 'Failed to get item files');\n    }\n    return data.files;\n  }\n\n  /**\n   * Delete a file\n   */\n  async deleteFile(fileId, options = {}) {\n    const response = await this.authService.authenticatedFetch(`${API_BASE}/files/${fileId}`, {\n      method: 'DELETE',\n      signal: options.signal,\n    });\n\n    const data = await response.json();\n    if (!response.ok) {\n      throw new Error(data.error || 'Failed to delete file');\n    }\n    return true;\n  }\n\n  /**\n   * Get download URL for a file\n   */\n  getFileDownloadUrl(fileId) {\n    return `${API_BASE}/files/${fileId}/download`;\n  }\n\n  // ============================================\n  // DA3 ENDPOINTS\n  // ============================================\n\n  /**\n   * Submit a frame or video for DA3 processing\n   */\n  async submitDA3Job(file, sensorMetadata, options = {}, fileName) {\n    const formData = new FormData();\n    const resolvedName = fileName\n      || (file && typeof file === 'object' && 'name' in file ? file.name : null);\n    if (resolvedName) {\n      formData.append('file', file, resolvedName);\n    } else {\n      formData.append('file', file);\n    }\n    formData.append('sensorData', JSON.stringify(sensorMetadata));\n    formData.append('options', JSON.stringify(options));\n\n    const response = await this.authService.authenticatedFetch(`${API_BASE}/da3/process`, {\n      method: 'POST',\n      body: formData,\n    });\n\n    const data = await response.json();\n    if (!response.ok) {\n      const error = new Error(data.message || data.error || 'Failed to submit DA3 job');\n      error.code = data.error;\n      error.status = response.status;\n      error.problem = data;\n      throw error;\n    }\n    return data.job || data;\n  }\n\n  async getDA3Usage() {\n    const response = await this.authService.authenticatedFetch(`${API_BASE}/da3/usage`, {\n      governanceLane: 'camera',\n    });\n    const data = await response.json().catch(() => ({}));\n    if (!response.ok) {\n      throw new Error(data.message || data.error || 'Failed to get DA3 usage');\n    }\n    return data;\n  }\n\n  /**\n   * Get user's DA3 jobs\n   */\n  async getDA3Jobs(limit = 50, offset = 0, status) {\n    const params = new URLSearchParams({\n      limit: String(limit),\n      offset: String(offset),\n      ...(status && { status })\n    });\n\n    const response = await this.authService.authenticatedFetch(`${API_BASE}/da3/jobs?${params}`);\n    const data = await response.json();\n    if (!response.ok) {\n      throw new Error(data.error || 'Failed to get DA3 jobs');\n    }\n    return data;\n  }\n\n  /**\n   * Get specific DA3 job status\n   */\n  async getDA3JobStatus(jobId) {\n    const response = await this.authService.authenticatedFetch(`${API_BASE}/da3/jobs/${jobId}/status`);\n    const data = await response.json();\n    if (!response.ok) {\n      throw new Error(data.error || 'Failed to get job status');\n    }\n    return data;\n  }\n\n  /**\n   * Get DA3 job results\n   */\n  async getDA3JobResults(jobId) {\n    const response = await this.authService.authenticatedFetch(`${API_BASE}/da3/jobs/${jobId}/results`);\n    const data = await response.json();\n    if (!response.ok) {\n      throw new Error(data.error || 'Failed to get job results');\n    }\n    return data;\n  }\n\n  /**\n   * Create a new DA3 scene\n   */\n  async createDA3Scene(sceneData = {}) {\n    const response = await this.authService.authenticatedFetch(`${API_BASE}/da3/scenes`, {\n      method: 'POST',\n      headers: { 'Content-Type': 'application/json' },\n      body: JSON.stringify(sceneData),\n    });\n\n    const data = await response.json();\n    if (!response.ok) {\n      throw new Error(data.error || 'Failed to create DA3 scene');\n    }\n    return data;\n  }\n\n  /**\n   * Get user's DA3 scenes\n   */\n  async getDA3Scenes(limit = 50, offset = 0) {\n    const params = new URLSearchParams({\n      limit: String(limit),\n      offset: String(offset)\n    });\n\n    const response = await this.authService.authenticatedFetch(`${API_BASE}/da3/scenes?${params}`);\n    const data = await response.json();\n    if (!response.ok) {\n      throw new Error(data.error || 'Failed to get DA3 scenes');\n    }\n    return data;\n  }\n\n  /**\n   * Get specific DA3 scene\n   */\n  async getDA3Scene(sceneId) {\n    const response = await this.authService.authenticatedFetch(`${API_BASE}/da3/scenes/${sceneId}`);\n    const data = await response.json();\n    if (!response.ok) {\n      throw new Error(data.error || 'Failed to get DA3 scene');\n    }\n    return data;\n  }\n\n  /**\n   * Update DA3 scene\n   */\n  async updateDA3Scene(sceneId, updateData) {\n    const response = await this.authService.authenticatedFetch(`${API_BASE}/da3/scenes/${sceneId}`, {\n      method: 'PATCH',\n      headers: { 'Content-Type': 'application/json' },\n      body: JSON.stringify(updateData),\n    });\n\n    const data = await response.json();\n    if (!response.ok) {\n      throw new Error(data.error || 'Failed to update DA3 scene');\n    }\n    return data;\n  }\n\n  /**\n   * Delete DA3 scene\n   */\n  async deleteDA3Scene(sceneId) {\n    const response = await this.authService.authenticatedFetch(`${API_BASE}/da3/scenes/${sceneId}`, {\n      method: 'DELETE',\n    });\n\n    const data = await response.json();\n    if (!response.ok) {\n      throw new Error(data.error || 'Failed to delete DA3 scene');\n    }\n    return data;\n  }\n\n  /**\n   * Ensure 'My Scans' overlay exists for user\n   */\n  async ensureMyScansOverlay() {\n    // Check if \"My Scans\" overlay exists\n    const overlays = await this.listOverlays();\n    const entries = overlays.overlays || [];\n    let myScansOverlay = entries.find((entry) =>\n      entry?.overlay?.title === 'My Scans' && entry?.overlay?.metadata?.category === 'user_scans'\n    )?.overlay;\n\n    if (!myScansOverlay) {\n      // Auto-create overlay\n      myScansOverlay = await this.createOverlay({\n        title: 'My Scans',\n        visibility: 'private',\n        metadata: {\n          category: 'user_scans',\n          source: 'da3',\n          autoCreated: true,\n          description: 'Automatically created overlay for DA3 camera captures'\n        }\n      });\n\n    }\n\n    return myScansOverlay;\n  }\n\n  // ============================================\n  // GATING ENDPOINTS\n  // ============================================\n\n  /**\n   * Add gating policy to overlay\n   */\n  async addOverlayGating(overlayId, gatingPolicyId, action = 'view') {\n    const response = await this.authService.authenticatedFetch(`${API_BASE}/overlays/${overlayId}/gating`, {\n      method: 'POST',\n      headers: { 'Content-Type': 'application/json' },\n      body: JSON.stringify({ gatingPolicyId, action }),\n    });\n\n    const data = await response.json();\n    if (!response.ok) {\n      throw new Error(data.error || 'Failed to add gating');\n    }\n    return data.binding;\n  }\n\n  /**\n   * Get overlay gating bindings\n   */\n  async getOverlayGating(overlayId) {\n    const response = await this.authService.authenticatedFetch(`${API_BASE}/overlays/${overlayId}/gating`);\n    const data = await response.json();\n    if (!response.ok) {\n      throw new Error(data.error || 'Failed to get gating');\n    }\n    return data.bindings;\n  }\n\n  /**\n   * Remove gating from overlay\n   */\n  async removeOverlayGating(overlayId, bindingId) {\n    const response = await this.authService.authenticatedFetch(`${API_BASE}/overlays/${overlayId}/gating/${bindingId}`, {\n      method: 'DELETE',\n    });\n\n    const data = await response.json();\n    if (!response.ok) {\n      throw new Error(data.error || 'Failed to remove gating');\n    }\n    return true;\n  }\n\n  /**\n   * Add gating policy to layer\n   */\n  async addLayerGating(layerId, gatingPolicyId, action = 'view') {\n    const response = await this.authService.authenticatedFetch(`${API_BASE}/layers/${layerId}/gating`, {\n      method: 'POST',\n      headers: { 'Content-Type': 'application/json' },\n      body: JSON.stringify({ gatingPolicyId, action }),\n    });\n\n    const data = await response.json();\n    if (!response.ok) {\n      throw new Error(data.error || 'Failed to add gating');\n    }\n    return data.binding;\n  }\n\n  /**\n   * Get layer gating bindings\n   */\n  async getLayerGating(layerId) {\n    const response = await this.authService.authenticatedFetch(`${API_BASE}/layers/${layerId}/gating`);\n    const data = await response.json();\n    if (!response.ok) {\n      throw new Error(data.error || 'Failed to get gating');\n    }\n    return data.bindings;\n  }\n\n  /**\n   * Remove gating from layer\n   */\n  async removeLayerGating(layerId, bindingId) {\n    const response = await this.authService.authenticatedFetch(`${API_BASE}/layers/${layerId}/gating/${bindingId}`, {\n      method: 'DELETE',\n    });\n\n    const data = await response.json();\n    if (!response.ok) {\n      throw new Error(data.error || 'Failed to remove gating');\n    }\n    return true;\n  }\n\n  /**\n   * Add gating policy to item\n   */\n  async addItemGating(itemId, gatingPolicyId, action = 'view') {\n    const response = await this.authService.authenticatedFetch(`${API_BASE}/items/${itemId}/gating`, {\n      method: 'POST',\n      headers: { 'Content-Type': 'application/json' },\n      body: JSON.stringify({ gatingPolicyId, action }),\n    });\n\n    const data = await response.json();\n    if (!response.ok) {\n      throw new Error(data.error || 'Failed to add gating');\n    }\n    return data.binding;\n  }\n\n  /**\n   * Get item gating bindings\n   */\n  async getItemGating(itemId) {\n    const response = await this.authService.authenticatedFetch(`${API_BASE}/items/${itemId}/gating`);\n    const data = await response.json();\n    if (!response.ok) {\n      throw new Error(data.error || 'Failed to get gating');\n    }\n    return data.bindings;\n  }\n\n  /**\n   * Remove gating from item\n   */\n  async removeItemGating(itemId, bindingId) {\n    const response = await this.authService.authenticatedFetch(`${API_BASE}/items/${itemId}/gating/${bindingId}`, {\n      method: 'DELETE',\n    });\n\n    const data = await response.json();\n    if (!response.ok) {\n      throw new Error(data.error || 'Failed to remove gating');\n    }\n    return true;\n  }\n\n  /**\n   * Create a share key for an overlay\n   */\n  async createShareKey(overlayId, { role = 'viewer', maxUses, expiresAt } = {}) {\n    const response = await this.authService.authenticatedFetch(`${API_BASE}/overlays/${overlayId}/share-keys`, {\n      method: 'POST',\n      headers: { 'Content-Type': 'application/json' },\n      body: JSON.stringify({ role, maxUses, expiresAt }),\n    });\n\n    const data = await response.json();\n    if (!response.ok) {\n      throw new Error(data.error || 'Failed to create share key');\n    }\n    return data.shareKey;\n  }\n\n  /**\n   * Redeem a share key for overlay access\n   */\n  async redeemShareKey(shareKey) {\n    const response = await this.authService.authenticatedFetch(`${API_BASE}/overlays/share/accept`, {\n      method: 'POST',\n      headers: { 'Content-Type': 'application/json' },\n      body: JSON.stringify({ shareKey }),\n    });\n\n    const data = await response.json();\n    if (!response.ok) {\n      throw new Error(data.error || 'Failed to redeem share key');\n    }\n    return data.access;\n  }\n\n  /**\n   * List available gating policies\n   */\n  async listGatingPolicies() {\n    const response = await this.authService.authenticatedFetch(`${API_BASE}/gating-policies`);\n    const data = await response.json();\n    if (!response.ok) {\n      throw new Error(data.error || 'Failed to list gating policies');\n    }\n    return data.policies;\n  }\n\n  /**\n   * Create a new gating policy\n   */\n  async createGatingPolicy(payload) {\n    const response = await this.authService.authenticatedFetch(`${API_BASE}/gating-policies`, {\n      method: 'POST',\n      headers: { 'Content-Type': 'application/json' },\n      body: JSON.stringify(payload),\n    });\n    const data = await response.json();\n    if (!response.ok) {\n      throw new Error(data.error || 'Failed to create gating policy');\n    }\n    return data.policy;\n  }\n}\n\n// Singleton instance\nlet overlayApiServiceInstance = null;\n\nexport function getOverlayApiService() {\n  if (!overlayApiServiceInstance) {\n    overlayApiServiceInstance = new OverlayApiService();\n  }\n  return overlayApiServiceInstance;\n}\n","import { getOverlayApiService } from '../creator/OverlayApiService.js';\n\n/** Stable scene facade. One subsystem owns both streamed and local documents. */\nexport function createOverlaySceneApi(getSubsystem, getApi = getOverlayApiService) {\n  return {\n    load: async (doc, options) => getSubsystem()?.load(doc, options) ?? null,\n    loadFromApi: async (id, options = {}) => {\n      const subsystem = getSubsystem();\n      if (!subsystem) throw new Error('OVERLAY_SUBSYSTEM_UNAVAILABLE');\n      return subsystem.loadPages(id, pageOptions => getApi().streamOverlay(id, { ...options, ...pageOptions }), options);\n    },\n    unload: id => getSubsystem()?.unload(id),\n    update: (id, patch) => getSubsystem()?.update(id, patch),\n    get: id => getSubsystem()?.get(id) || null,\n    beginPlacementReview: target => getSubsystem()?.beginPlacementReview(target) || false,\n    updatePlacementReview: draft => getSubsystem()?.updatePlacementReview(draft) || false,\n    endPlacementReview: target => getSubsystem()?.endPlacementReview(target) || false,\n    getSubsystem,\n  };\n}\n","import {\n  HYDRA_INTEROP_CONTRACT,\n  INTEROP_ERROR_CODE,\n  normalizeInteropEnvelope,\n  withInteropContractFields\n} from '../shared/interopContract.js';\n\nconst MOVE_FLUSH_MS = 60;\nconst MAX_PENDING_MOVES = 96;\nconst MAX_TARGET_CACHE = 256;\n\nconst textId = (value) => {\n  if (value === null || value === undefined) return '';\n  const text = String(value).trim();\n  return text || '';\n};\n\nconst numberOrNull = (value) => {\n  const num = Number(value);\n  return Number.isFinite(num) ? num : null;\n};\n\nconst normalizeTarget = (source = {}) => {\n  const src = source && typeof source === 'object' ? source : {};\n  const objectUuid = textId(\n    src.objectUuid ||\n    src.object_uuid ||\n    src.objectId ||\n    src.object_id\n  );\n  return {\n    sessionId: textId(src.sessionId || src.session_id),\n    objectUuid,\n    objectId: objectUuid,\n    overlayId: textId(src.overlayId || src.overlay_id),\n    itemId: textId(src.itemId || src.item_id || objectUuid),\n    layerId: textId(src.layerId || src.layer_id)\n  };\n};\n\nconst mergeTarget = (primary = {}, fallback = {}) => {\n  const head = normalizeTarget(primary);\n  const tail = normalizeTarget(fallback);\n  const objectUuid = head.objectUuid || tail.objectUuid;\n  return {\n    sessionId: head.sessionId || tail.sessionId,\n    objectUuid,\n    objectId: objectUuid,\n    overlayId: head.overlayId || tail.overlayId,\n    itemId: head.itemId || tail.itemId || objectUuid,\n    layerId: head.layerId || tail.layerId\n  };\n};\n\nconst hasTarget = (target) => !!(\n  target?.sessionId ||\n  target?.objectUuid ||\n  target?.overlayId ||\n  target?.itemId ||\n  target?.layerId\n);\n\nconst parseJsonMaybe = (value) => {\n  if (!value) return null;\n  if (typeof value === 'object') return value;\n  if (typeof value !== 'string') return null;\n  const trimmed = value.trim();\n  if (!trimmed) return null;\n  try {\n    return JSON.parse(trimmed);\n  } catch (_) {\n    return null;\n  }\n};\n\nconst decodeBase64ToUint8 = (value) => {\n  if (typeof value !== 'string') return null;\n  const raw = value.trim();\n  if (!raw) return null;\n  const normalized = raw.startsWith('data:')\n    ? raw.slice(raw.indexOf(',') + 1)\n    : raw;\n  try {\n    const binary = atob(normalized);\n    const bytes = new Uint8Array(binary.length);\n    for (let i = 0; i < binary.length; i += 1) {\n      bytes[i] = binary.charCodeAt(i);\n    }\n    return bytes;\n  } catch (_) {\n    return null;\n  }\n};\n\nconst normalizePointcloudPayload = (source = {}) => {\n  const payload = source && typeof source === 'object' ? source : {};\n  const positions =\n    (Array.isArray(payload.positions) && payload.positions) ||\n    (Array.isArray(payload.vertices) && payload.vertices) ||\n    (Array.isArray(payload.points) && payload.points) ||\n    null;\n  if (!positions || positions.length < 3) return null;\n  const colors = Array.isArray(payload.colors) ? payload.colors : null;\n  const size = numberOrNull(payload.size || payload.pointSize || payload.point_size);\n  return { positions, colors, size };\n};\n\nexport class HydraOverlayIngress {\n  constructor(options = {}) {\n    this.overlaySubsystem = options.overlaySubsystem || null;\n    this.commsSystem = options.commsSystem || null;\n    this.eventBus = options.eventBus || null;\n    this.logger = typeof options.logger === 'function' ? options.logger : null;\n    this._sessionTargets = new Map();\n    this._objectTargets = new Map();\n    this._blobUrlsByItem = new Map();\n    this._pendingMoves = new Map();\n    this._moveFlushTimer = null;\n    this._interopStatus = {\n      expected: {\n        name: HYDRA_INTEROP_CONTRACT.name,\n        version: HYDRA_INTEROP_CONTRACT.version,\n        compat_min_version: HYDRA_INTEROP_CONTRACT.compatMinVersion,\n        namespace: HYDRA_INTEROP_CONTRACT.namespace,\n        schema: HYDRA_INTEROP_CONTRACT.schema\n      },\n      accepted: 0,\n      rejected: 0,\n      lastErrorCode: '',\n      lastError: '',\n      lastValidatedAt: 0,\n      contractOk: true,\n      contractNameOk: true,\n      contractVersionOk: true,\n      contractCompatOk: true\n    };\n    this._boundIngress = (payload) => {\n      const envelope = payload?.envelope || payload || null;\n      const meta = payload?.meta && typeof payload.meta === 'object' ? payload.meta : {};\n      void this.ingest(envelope, meta);\n    };\n    this._boundSession = (payload) => {\n      this.registerSession(payload);\n    };\n\n    if (this.eventBus?.on) {\n      this.eventBus.on('hydra:overlay:ingress', this._boundIngress);\n      this.eventBus.on('hydra:overlay:session', this._boundSession);\n    }\n  }\n\n  dispose() {\n    if (this.eventBus?.off) {\n      this.eventBus.off('hydra:overlay:ingress', this._boundIngress);\n      this.eventBus.off('hydra:overlay:session', this._boundSession);\n    }\n    if (this._moveFlushTimer) {\n      clearTimeout(this._moveFlushTimer);\n      this._moveFlushTimer = null;\n    }\n    this._pendingMoves.clear();\n    this._sessionTargets.clear();\n    this._objectTargets.clear();\n    this._blobUrlsByItem.forEach((url) => {\n      try { URL.revokeObjectURL(url); } catch (_) {}\n    });\n    this._blobUrlsByItem.clear();\n  }\n\n  registerSession(session) {\n    const target = normalizeTarget(session || {});\n    if (!hasTarget(target)) return;\n    if (target.sessionId) {\n      this._sessionTargets.set(target.sessionId, target);\n      this._pruneMap(this._sessionTargets);\n    }\n    if (target.objectUuid) {\n      this._objectTargets.set(target.objectUuid, target);\n      this._pruneMap(this._objectTargets);\n    }\n  }\n\n  async ingest(rawEnvelope, meta = {}) {\n    const interopEnvelope = normalizeInteropEnvelope(rawEnvelope, {\n      expectedContract: HYDRA_INTEROP_CONTRACT,\n      requireTypeOrEvent: true\n    });\n    const envelope = this._normalizeEnvelope(interopEnvelope.envelope || rawEnvelope, meta);\n    if (interopEnvelope.contractStatus && typeof interopEnvelope.contractStatus === 'object') {\n      envelope.contractStatus = interopEnvelope.contractStatus;\n    }\n    if (!interopEnvelope.ok) {\n      const code = String(interopEnvelope.errorCode || INTEROP_ERROR_CODE.INVALID_ENVELOPE);\n      const detail = String(interopEnvelope.error || 'invalid interop envelope');\n      this._recordInteropValidation(false, code, detail, interopEnvelope.contractStatus || null);\n      this._emitAck(envelope, envelope.target || null, 'error', detail, code, 400);\n      return { ok: false, error: detail, error_code: code, status_code: 400 };\n    }\n    const targetResolution = this._resolveTarget(envelope);\n    if (!targetResolution.ok) {\n      const targetError = targetResolution.error || 'unresolved-target';\n      const statusCode = /not-found|not-loaded|missing-target|unresolved-target/i.test(String(targetError)) ? 404 : 400;\n      this._recordInteropValidation(false, 'INVALID_TARGET', targetError, envelope.contractStatus || null);\n      this._emitAck(envelope, targetResolution.target || null, 'error', targetError, 'INVALID_TARGET', statusCode);\n      return { ok: false, error: targetError, error_code: 'INVALID_TARGET', status_code: statusCode };\n    }\n    const target = targetResolution.target;\n    this._rememberTarget(target);\n    const auth = await this._enforceMutationAuthorization(envelope, target);\n    if (!auth.ok) {\n      const code = textId(auth.errorCode || 'signature_invalid') || 'signature_invalid';\n      const detail = textId(auth.error || 'access denied') || 'access denied';\n      const statusCode = (code === 'quote_missing' || code === 'credit_reservation_missing' || code === 'insufficient_credit_reservation') ? 402 : 403;\n      this._recordInteropValidation(false, code, detail, envelope.contractStatus || null);\n      this._emitAck(envelope, target, 'error', detail, code, statusCode, {\n        family: textId(envelope?.family).toLowerCase(),\n        billable: !!auth.billable,\n        metering: auth.metering && typeof auth.metering === 'object' ? { ...auth.metering } : null\n      });\n      return {\n        ok: false,\n        error: detail,\n        error_code: code,\n        status_code: statusCode,\n        metering: auth.metering && typeof auth.metering === 'object' ? { ...auth.metering } : null\n      };\n    }\n    try {\n      let result;\n      if (envelope.family === 'pose') {\n        result = await this._applyPose(target, envelope);\n      } else if (envelope.family === 'geometry') {\n        result = await this._applyGeometry(target, envelope);\n      } else if (envelope.family === 'media') {\n        result = await this._applyMedia(target, envelope);\n      } else if (envelope.family === 'command') {\n        result = await this._applyCommand(target, envelope);\n      } else {\n        result = await this._applyResource(target, envelope);\n      }\n      const detail = result?.detail || 'applied';\n      this._recordInteropValidation(true, '', '', envelope.contractStatus || null);\n      this._emitAck(envelope, target, 'ok', detail, '', 200, {\n        family: textId(envelope?.family).toLowerCase(),\n        billable: !!auth.billable,\n        metering: auth.metering && typeof auth.metering === 'object' ? { ...auth.metering } : null\n      });\n      this.eventBus?.emit?.('hydra:overlay:ingress:applied', { envelope, target, result });\n      return { ok: true, detail, status_code: 200 };\n    } catch (error) {\n      const detail = error?.message || 'ingress-failed';\n      this._log('error', detail, { envelope, target, error });\n      this._recordInteropValidation(false, 'INGRESS_FAILED', detail, envelope.contractStatus || null);\n      this._emitAck(envelope, target, 'error', detail, 'INGRESS_FAILED', 500);\n      return { ok: false, error: detail, error_code: 'INGRESS_FAILED', status_code: 500 };\n    }\n  }\n\n  _extractAccessTicket(envelope = {}) {\n    if (!envelope || typeof envelope !== 'object') return '';\n    return textId(\n      envelope.access_ticket ||\n      envelope.accessTicket ||\n      envelope.ticket ||\n      envelope.auth?.ticket ||\n      envelope.auth?.access_ticket ||\n      envelope.meta?.ticket ||\n      envelope.meta?.access_ticket\n    );\n  }\n\n  _extractMutationMetering(envelope = {}) {\n    const metering = envelope?.metering && typeof envelope.metering === 'object' ? envelope.metering : {};\n    const readInt = (...values) => {\n      for (const value of values) {\n        const n = Number(value);\n        if (Number.isFinite(n) && n >= 0) return Math.round(n);\n      }\n      return 0;\n    };\n    const readFloat = (...values) => {\n      for (const value of values) {\n        const n = Number(value);\n        if (Number.isFinite(n) && n > 0) return n;\n      }\n      return 1;\n    };\n    return {\n      quoteId: textId(envelope.quote_id || envelope.quoteId || metering.quote_id || metering.quoteId),\n      chargeId: textId(envelope.charge_id || envelope.chargeId || metering.charge_id || metering.chargeId),\n      reservationId: textId(\n        envelope.reservation_id ||\n        envelope.reservationId ||\n        envelope.credit_reservation_id ||\n        metering.reservation_id ||\n        metering.reservationId ||\n        metering.credit_reservation_id\n      ),\n      requestedUnits: readFloat(\n        envelope.requested_units,\n        envelope.requestedUnits,\n        metering.requested_units,\n        metering.requestedUnits,\n        1\n      ),\n      pricePerUnitMicros: readInt(\n        envelope.price_per_unit_micros,\n        envelope.pricePerUnitMicros,\n        metering.price_per_unit_micros,\n        metering.pricePerUnitMicros\n      ),\n      maxChargeMicros: readInt(\n        envelope.max_charge_micros,\n        envelope.maxChargeMicros,\n        metering.max_charge_micros,\n        metering.maxChargeMicros\n      ),\n      settledMicros: readInt(\n        envelope.settled_micros,\n        envelope.settledMicros,\n        metering.settled_micros,\n        metering.settledMicros\n      ),\n      correlationId: textId(envelope.correlation_id || envelope.correlationId || metering.correlation_id || metering.correlationId),\n    };\n  }\n\n  async _enforceMutationAuthorization(envelope, target) {\n    const family = textId(envelope?.family).toLowerCase();\n    const mutableFamily = family === 'pose' || family === 'geometry' || family === 'media' || family === 'resource';\n    if (!mutableFamily) return { ok: true };\n    const requireAuth = envelope?.requireAuth !== false && envelope?.authOptional !== true;\n    if (!requireAuth) return { ok: true };\n    const ticket = this._extractAccessTicket(envelope);\n    if (!ticket) {\n      return { ok: false, errorCode: 'ticket_missing', error: 'overlay mutation ticket required' };\n    }\n    if (!this.commsSystem || typeof this.commsSystem.verifyHydraAccessTicket !== 'function') {\n      return { ok: false, errorCode: 'signature_invalid', error: 'ticket verifier unavailable' };\n    }\n    const verification = await this.commsSystem.verifyHydraAccessTicket(ticket, {\n      requiredScope: 'overlay.write',\n      target,\n      enforceReplay: true\n    });\n    if (!verification?.valid) {\n      return {\n        ok: false,\n        errorCode: textId(verification?.errorCode || 'signature_invalid') || 'signature_invalid',\n        error: textId(verification?.error || 'overlay mutation denied') || 'overlay mutation denied'\n      };\n    }\n    const metering = this._extractMutationMetering(envelope);\n    const billable = envelope?.billable === true\n      || envelope?.requireMarketplaceAuth === true\n      || Number(metering.pricePerUnitMicros || 0) > 0\n      || Number(metering.maxChargeMicros || 0) > 0\n      || Number(metering.settledMicros || 0) > 0\n      || !!metering.quoteId\n      || !!metering.chargeId\n      || !!metering.reservationId;\n    const requireBilling = envelope?.requireBillingPreflight !== false;\n    if (requireBilling && billable) {\n      if (!metering.quoteId) {\n        return { ok: false, errorCode: 'quote_missing', error: 'billable mutation requires quote_id', metering, billable };\n      }\n      const reservationMicros = metering.settledMicros > 0 ? metering.settledMicros : metering.maxChargeMicros;\n      const hasReservation = !!metering.chargeId || !!metering.reservationId || reservationMicros > 0;\n      if (!hasReservation) {\n        return { ok: false, errorCode: 'credit_reservation_missing', error: 'billable mutation requires credit reservation', metering, billable };\n      }\n      const estimatedMicros = Math.max(0, Math.round(Math.max(1, Number(metering.requestedUnits || 1)) * Math.max(0, Number(metering.pricePerUnitMicros || 0))));\n      if (reservationMicros > 0 && estimatedMicros > 0 && estimatedMicros > reservationMicros) {\n        return {\n          ok: false,\n          errorCode: 'insufficient_credit_reservation',\n          error: `estimated charge ${estimatedMicros} exceeds reservation ${reservationMicros}`,\n          metering,\n          billable\n        };\n      }\n    }\n    return { ok: true, claims: verification.claims || null, metering, billable };\n  }\n\n  _normalizeEnvelope(rawEnvelope, meta = {}) {\n    const base = rawEnvelope && typeof rawEnvelope === 'object' ? rawEnvelope : {};\n    const payload = base.payload && typeof base.payload === 'object' ? base.payload : {};\n    const merged = { ...payload, ...base };\n    const messageId = textId(merged.messageId || merged.message_id);\n    const type = textId(merged.type);\n    const event = textId(merged.event);\n    const resource =\n      (merged.resource && typeof merged.resource === 'object' ? merged.resource : null) ||\n      parseJsonMaybe(merged.payload_data) ||\n      null;\n    const command = merged.command && typeof merged.command === 'object' ? merged.command : null;\n    const mediaPayload = merged.audioPacket || merged.videoPacket || null;\n    const family = this._resolveFamily(type, event, merged, resource, mediaPayload);\n    const target = mergeTarget(merged, merged.target || {});\n    const interopContract = merged.interop_contract && typeof merged.interop_contract === 'object'\n      ? merged.interop_contract\n      : {\n          name: textId(merged.interop_contract_name),\n          version: textId(merged.interop_contract_version),\n          compat_min_version: textId(merged.interop_contract_compat_min_version),\n          namespace: textId(merged.interop_contract_namespace),\n          schema: textId(merged.interop_contract_schema)\n        };\n    return {\n      ...merged,\n      messageId,\n      type,\n      event,\n      family,\n      resource,\n      command,\n      mediaPayload,\n      target,\n      interop_contract: interopContract,\n      interop_contract_version: textId(merged.interop_contract_version || interopContract.version),\n      interop_contract_compat_min_version: textId(merged.interop_contract_compat_min_version || interopContract.compat_min_version),\n      interop_contract_namespace: textId(merged.interop_contract_namespace || interopContract.namespace),\n      sessionId: target.sessionId || textId(merged.sessionId || merged.session_id),\n      objectUuid: target.objectUuid || textId(merged.objectUuid || merged.object_uuid || merged.objectId || merged.object_id),\n      sourceAddress: textId(merged.source_address || merged.sourceAddress || meta.sourceAddress),\n      sourcePub: textId(meta.sourcePub || merged.sourcePub || merged.source_pub)\n    };\n  }\n\n  _resolveFamily(type, event, payload, resource, mediaPayload) {\n    const normalizedType = String(type || '').toLowerCase();\n    const normalizedEvent = String(event || '').toLowerCase();\n    if (normalizedType === 'hybrid-bridge-update' || normalizedEvent === 'interop.asset.pose') return 'pose';\n    if (normalizedType === 'hybrid-bridge-geometry' || normalizedEvent === 'interop.asset.geometry') return 'geometry';\n    if (normalizedType === 'hybrid-bridge-command' || normalizedEvent === 'interop.asset.command') return 'command';\n    if (\n      normalizedType === 'smart-object-audio' ||\n      normalizedType === 'smart-object-audio-output' ||\n      normalizedEvent === 'interop.asset.media' ||\n      mediaPayload\n    ) return 'media';\n    if (normalizedType === 'hybrid-bridge-resource' || normalizedEvent === 'interop.asset.resource') return 'resource';\n    if (resource?.pointcloud || resource?.geometry || resource?.glbBase64) return 'geometry';\n    return 'resource';\n  }\n\n  _resolveTarget(envelope) {\n    const direct = mergeTarget(envelope, envelope.target || {});\n    const mappedBySession = direct.sessionId ? this._sessionTargets.get(direct.sessionId) : null;\n    const mappedByObject = !mappedBySession && direct.objectUuid ? this._objectTargets.get(direct.objectUuid) : null;\n    const mapped = mappedBySession || mappedByObject || null;\n    const target = mergeTarget(direct, mapped || {});\n\n    const resolver = this.overlaySubsystem?.resolveIngressTarget;\n    if (typeof resolver === 'function') {\n      const resolved = resolver.call(this.overlaySubsystem, target);\n      if (resolved?.ok) {\n        return {\n          ok: true,\n          target: {\n            ...target,\n            overlayId: resolved.overlayId || target.overlayId,\n            itemId: resolved.itemId || target.itemId,\n            layerId: resolved.layerId || target.layerId,\n            itemEntry: resolved.itemEntry || null\n          }\n        };\n      }\n      return { ok: false, error: resolved?.error || 'unresolved-target', target };\n    }\n\n    const overlayId = target.overlayId;\n    const itemId = target.itemId || target.objectUuid;\n    if (!overlayId && !itemId) {\n      return { ok: false, error: 'missing-target', target };\n    }\n\n    if (overlayId && itemId && typeof this.overlaySubsystem?.findItemInOverlay === 'function') {\n      const itemEntry = this.overlaySubsystem.findItemInOverlay(overlayId, itemId);\n      if (!itemEntry) {\n        const overlayLoaded = !!(\n          this.overlaySubsystem?.get?.(overlayId) ||\n          this.overlaySubsystem?.overlays?.get?.(overlayId)\n        );\n        if (!overlayLoaded) return { ok: false, error: 'target-overlay-not-loaded', target };\n        return {\n          ok: true,\n          target: { ...target, overlayId, itemId, layerId: target.layerId, itemEntry: null }\n        };\n      }\n      return { ok: true, target: { ...target, overlayId, itemId, layerId: itemEntry.layerId || target.layerId, itemEntry } };\n    }\n\n    if (itemId && typeof this.overlaySubsystem?.findItem === 'function') {\n      const itemEntry = this.overlaySubsystem.findItem(itemId);\n      if (!itemEntry) return { ok: false, error: 'target-item-not-found', target };\n      const resolvedOverlayId = itemEntry.overlayEntry?.overlayId || overlayId || '';\n      return {\n        ok: true,\n        target: {\n          ...target,\n          overlayId: resolvedOverlayId,\n          itemId,\n          layerId: itemEntry.layerId || target.layerId,\n          itemEntry\n        }\n      };\n    }\n\n    if (overlayId) {\n      return { ok: true, target: { ...target, overlayId, itemId, layerId: target.layerId, itemEntry: null } };\n    }\n\n    return { ok: false, error: 'unresolved-target', target };\n  }\n\n  _rememberTarget(target) {\n    if (!target) return;\n    const normalized = normalizeTarget(target);\n    if (normalized.sessionId) {\n      this._sessionTargets.set(normalized.sessionId, normalized);\n      this._pruneMap(this._sessionTargets);\n    }\n    if (normalized.objectUuid) {\n      this._objectTargets.set(normalized.objectUuid, normalized);\n      this._pruneMap(this._objectTargets);\n    }\n  }\n\n  _pruneMap(mapRef) {\n    while (mapRef.size > MAX_TARGET_CACHE) {\n      const oldest = mapRef.keys().next();\n      if (oldest.done) break;\n      mapRef.delete(oldest.value);\n    }\n  }\n\n  _emitAck(envelope, target, status, detail, errorCode = '', statusCode = 0, meta = null) {\n    const payload = withInteropContractFields({\n      type: 'hybrid-bridge-ack',\n      event: 'interop.bridge.ack',\n      inReplyTo: envelope?.messageId || '',\n      status: status === 'ok' ? 'ok' : 'error',\n      detail: textId(detail) || (status === 'ok' ? 'applied' : 'failed'),\n      error_code: status === 'ok' ? '' : textId(errorCode || INTEROP_ERROR_CODE.INVALID_ENVELOPE),\n      status_code: Number(statusCode) || (status === 'ok' ? 200 : 400),\n      sessionId: target?.sessionId || envelope?.sessionId || '',\n      objectUuid: target?.objectUuid || target?.itemId || envelope?.objectUuid || '',\n      objectId: target?.objectUuid || target?.itemId || envelope?.objectUuid || '',\n      target: {\n        overlayId: target?.overlayId || '',\n        itemId: target?.itemId || '',\n        layerId: target?.layerId || ''\n      },\n      ts: Date.now()\n    }, HYDRA_INTEROP_CONTRACT);\n    if (meta && typeof meta === 'object') {\n      payload.meta = { ...meta };\n    }\n    this.eventBus?.emit?.('hydra:overlay:ack', payload);\n  }\n\n  _recordInteropValidation(ok, errorCode = '', errorDetail = '', contractStatus = null) {\n    this._interopStatus.lastValidatedAt = Date.now();\n    if (ok) {\n      this._interopStatus.accepted += 1;\n      this._interopStatus.lastErrorCode = '';\n      this._interopStatus.lastError = '';\n    } else {\n      this._interopStatus.rejected += 1;\n      this._interopStatus.lastErrorCode = textId(errorCode);\n      this._interopStatus.lastError = textId(errorDetail);\n    }\n    if (contractStatus && typeof contractStatus === 'object') {\n      this._interopStatus.contractOk = !!contractStatus.ok;\n      this._interopStatus.contractNameOk = !!contractStatus.nameOk;\n      this._interopStatus.contractVersionOk = !!contractStatus.versionOk;\n      this._interopStatus.contractCompatOk = !!contractStatus.compatOk;\n    }\n  }\n\n  getInteropStatus() {\n    const status = { ...this._interopStatus };\n    if (status.expected && typeof status.expected === 'object') {\n      status.expected = { ...status.expected };\n    }\n    return status;\n  }\n\n  _guardMutableTarget(target, { requireItem = true, assetMutation = false } = {}) {\n    const overlayId = textId(target?.overlayId);\n    const itemEntry = target?.itemEntry || null;\n    if (!overlayId) {\n      throw new Error('missing-overlay-id');\n    }\n    if (typeof this.overlaySubsystem?._canViewOverlay === 'function' && !this.overlaySubsystem._canViewOverlay(overlayId)) {\n      throw new Error('overlay-view-blocked');\n    }\n    if (requireItem && !itemEntry) {\n      throw new Error('target-item-required');\n    }\n    if (itemEntry && typeof this.overlaySubsystem?._canUpdateItem === 'function' && !this.overlaySubsystem._canUpdateItem(itemEntry.data)) {\n      throw new Error('item-update-blocked');\n    }\n    if (assetMutation && itemEntry?.data && typeof this.overlaySubsystem?._isAssetBlocked === 'function' && this.overlaySubsystem._isAssetBlocked(itemEntry.data)) {\n      throw new Error('asset-blocked');\n    }\n  }\n\n  async _applyPose(target, envelope) {\n    this._guardMutableTarget(target, { requireItem: true });\n    const pose = envelope.pose && typeof envelope.pose === 'object' ? envelope.pose : {};\n    const position = pose.position && typeof pose.position === 'object'\n      ? pose.position\n      : (envelope.position && typeof envelope.position === 'object' ? envelope.position : null);\n    const lat = numberOrNull(position?.lat ?? position?.latitude ?? envelope.lat ?? envelope.latitude);\n    const lon = numberOrNull(position?.lon ?? position?.lng ?? position?.longitude ?? envelope.lon ?? envelope.lng ?? envelope.longitude);\n    const elevation = numberOrNull(position?.elevation_m ?? position?.elevation ?? position?.alt ?? position?.ground ?? envelope.elevation_m ?? envelope.alt);\n    const livePosition = {};\n    if (lat !== null && lon !== null) {\n      livePosition.lat = lat;\n      livePosition.lon = lon;\n    }\n    if (elevation !== null) {\n      livePosition.elevation_m = elevation;\n    }\n    if (!Object.keys(livePosition).length) {\n      throw new Error('pose-missing-latlon');\n    }\n    this._queueMove(target, livePosition, pose.meta && typeof pose.meta === 'object' ? pose.meta : null);\n    return { detail: 'pose-queued' };\n  }\n\n  async _applyCommand(target, envelope) {\n    const command = envelope.command && typeof envelope.command === 'object' ? envelope.command : {};\n    const op = textId(command.op || command.action || envelope.op || envelope.action).toLowerCase();\n    if (op === 'move' || op === 'position') {\n      const nextEnvelope = { ...envelope, pose: command.pose || command.position || envelope.pose };\n      return this._applyPose(target, nextEnvelope);\n    }\n    if (op === 'theater' || op === 'media') {\n      return this._applyMedia(target, { ...envelope, resource: command });\n    }\n    if (op === 'model' || op === 'geometry') {\n      return this._applyGeometry(target, { ...envelope, resource: command });\n    }\n    return this._applyResource(target, { ...envelope, resource: command });\n  }\n\n  async _applyResource(target, envelope) {\n    const resource = envelope.resource && typeof envelope.resource === 'object' ? envelope.resource : {};\n    const props = resource.properties && typeof resource.properties === 'object' ? resource.properties : {};\n    const patchProps = { ...props };\n    const explicitModelUrl = textId(resource.model_url || resource.modelUrl || resource.gltfUrl || resource.glbUrl);\n    if (explicitModelUrl) {\n      patchProps.model_url = explicitModelUrl;\n    }\n    if (Object.keys(patchProps).length || explicitModelUrl) {\n      const patchResult = this.overlaySubsystem?.applyIngressItemPatch?.({\n        overlayId: target.overlayId,\n        itemId: target.itemId || target.objectUuid,\n        layerId: target.layerId,\n        createIfMissing: true,\n        itemType: textId(resource.item_type || resource.itemType || 'model3d'),\n        patch: {\n          item_id: target.itemId || target.objectUuid,\n          item_type: textId(resource.item_type || resource.itemType || 'model3d') || 'model3d',\n          current: {\n            properties: patchProps\n          }\n        }\n      });\n      if (!patchResult?.ok) {\n        throw new Error(patchResult?.error || 'resource-patch-failed');\n      }\n      target.itemEntry = patchResult.itemEntry || target.itemEntry || null;\n      if (target.itemEntry) target.layerId = target.itemEntry.layerId || target.layerId;\n      this._rememberTarget(target);\n      return { detail: 'resource-applied' };\n    }\n    return { detail: 'resource-ignored' };\n  }\n\n  async _applyGeometry(target, envelope) {\n    this._guardMutableTarget(target, { requireItem: false, assetMutation: true });\n    const resource = envelope.resource && typeof envelope.resource === 'object'\n      ? envelope.resource\n      : (parseJsonMaybe(envelope.payload_data) || {});\n    const pointcloud = normalizePointcloudPayload(\n      resource.pointcloud ||\n      resource.geometry ||\n      resource.data ||\n      envelope.pointcloud ||\n      envelope.geometry ||\n      {}\n    );\n    if (pointcloud) {\n      const result = this.overlaySubsystem?.applyIngressPointcloudData?.({\n        overlayId: target.overlayId,\n        itemId: target.itemId || target.objectUuid,\n        pointcloud\n      });\n      if (!result?.ok) throw new Error(result?.error || 'pointcloud-apply-failed');\n      return { detail: 'pointcloud-applied' };\n    }\n\n    let modelUrl = textId(\n      resource.model_url ||\n      resource.modelUrl ||\n      resource.glbUrl ||\n      resource.gltfUrl ||\n      envelope.model_url ||\n      envelope.modelUrl\n    );\n    if (!modelUrl) {\n      const glbBytes = decodeBase64ToUint8(\n        resource.glbBase64 ||\n        resource.glb_base64 ||\n        envelope.glbBase64 ||\n        envelope.glb_base64\n      );\n      if (glbBytes) {\n        const blob = new Blob([glbBytes], { type: 'model/gltf-binary' });\n        modelUrl = URL.createObjectURL(blob);\n        this._setBlobUrl(target, modelUrl);\n      }\n    }\n    if (!modelUrl) throw new Error('geometry-missing-model');\n    const patchResult = this.overlaySubsystem?.applyIngressModelUrl?.({\n      overlayId: target.overlayId,\n      itemId: target.itemId || target.objectUuid,\n      layerId: target.layerId,\n      modelUrl\n    });\n    if (!patchResult?.ok) throw new Error(patchResult?.error || 'model-url-apply-failed');\n    return { detail: 'model-applied' };\n  }\n\n  async _applyMedia(target, envelope) {\n    this._guardMutableTarget(target, { requireItem: false });\n    const resource = envelope.resource && typeof envelope.resource === 'object' ? envelope.resource : {};\n    const payload = envelope.mediaPayload || resource.mediaPayload || resource;\n    const streamIds = this.commsSystem?.getOverlayStreamIds?.(target) || {};\n    const props = {};\n\n    if (payload?.data && (payload?.mime || payload?.contentType || '').toLowerCase().startsWith('image/')) {\n      const videoFramePayload = {\n        ...payload,\n        streamId: streamIds.videoStreamId || textId(resource.video_stream || resource.stream_id),\n        callId: null\n      };\n      this.commsSystem?.pushOverlayVideoFrame?.(target, videoFramePayload);\n      if (videoFramePayload.streamId) {\n        props.source_type = 'stream_id';\n        props.video_stream = videoFramePayload.streamId;\n      }\n    }\n\n    if (payload?.data && (payload?.mime || payload?.contentType || '').toLowerCase().startsWith('audio/')) {\n      const audioPayload = {\n        ...payload,\n        streamId: streamIds.audioStreamId || textId(resource.audio_stream),\n        callId: null\n      };\n      this.commsSystem?.pushOverlayAudioPacket?.(target, audioPayload);\n      if (audioPayload.streamId) {\n        props.audio_stream = audioPayload.streamId;\n      }\n    }\n\n    const videoStream = textId(resource.video_stream || resource.stream_id);\n    const audioStream = textId(resource.audio_stream);\n    const hlsUrl = textId(resource.hls_url || resource.playback_hls_url);\n    const embedUrl = textId(resource.embed_url);\n\n    if (videoStream) {\n      props.source_type = 'stream_id';\n      props.video_stream = videoStream;\n    }\n    if (audioStream) {\n      props.audio_stream = audioStream;\n    }\n    if (hlsUrl) {\n      props.source_type = 'hls';\n      props.hls_url = hlsUrl;\n      props.playback_hls_url = hlsUrl;\n    }\n    if (embedUrl) {\n      props.source_type = 'embed_url';\n      props.embed_url = embedUrl;\n    }\n\n    if (Object.keys(props).length) {\n      const patchResult = this.overlaySubsystem?.applyIngressItemPatch?.({\n        overlayId: target.overlayId,\n        itemId: target.itemId || target.objectUuid,\n        layerId: target.layerId,\n        createIfMissing: true,\n        itemType: textId(resource.item_type || resource.itemType || 'theater') || 'theater',\n        patch: {\n          item_id: target.itemId || target.objectUuid,\n          item_type: textId(resource.item_type || resource.itemType || 'theater') || 'theater',\n          current: {\n            properties: props\n          }\n        }\n      });\n      if (!patchResult?.ok) {\n        throw new Error(patchResult?.error || 'media-patch-failed');\n      }\n      target.itemEntry = patchResult.itemEntry || target.itemEntry || null;\n      if (target.itemEntry) target.layerId = target.itemEntry.layerId || target.layerId;\n      this._rememberTarget(target);\n      return { detail: 'media-applied' };\n    }\n\n    return { detail: 'media-routed' };\n  }\n\n  _queueMove(target, position, properties = null) {\n    const key = `${target.overlayId || ''}:${target.itemId || target.objectUuid || ''}`;\n    if (!key || key === ':') throw new Error('invalid-move-target');\n    if (this._pendingMoves.size >= MAX_PENDING_MOVES && !this._pendingMoves.has(key)) {\n      const oldest = this._pendingMoves.keys().next();\n      if (!oldest.done) this._pendingMoves.delete(oldest.value);\n    }\n    this._pendingMoves.set(key, {\n      overlayId: target.overlayId,\n      itemId: target.itemId || target.objectUuid,\n      position,\n      properties\n    });\n    if (!this._moveFlushTimer) {\n      this._moveFlushTimer = setTimeout(() => {\n        this._moveFlushTimer = null;\n        this._flushQueuedMoves();\n      }, MOVE_FLUSH_MS);\n    }\n  }\n\n  _flushQueuedMoves() {\n    if (!this._pendingMoves.size) return;\n    const queued = Array.from(this._pendingMoves.values());\n    this._pendingMoves.clear();\n    queued.forEach((entry) => {\n      const result = this.overlaySubsystem?.applyIngressLivePosition?.({\n        overlayId: entry.overlayId,\n        itemId: entry.itemId,\n        position: entry.position,\n        properties: entry.properties\n      });\n      if (!result?.ok) {\n        this._log('warn', result?.error || 'move-apply-failed', entry);\n      }\n    });\n  }\n\n  _setBlobUrl(target, url) {\n    const key = `${target.overlayId || ''}:${target.itemId || target.objectUuid || ''}`;\n    if (!key || key === ':') return;\n    const previous = this._blobUrlsByItem.get(key);\n    if (previous && previous !== url) {\n      try { URL.revokeObjectURL(previous); } catch (_) {}\n    }\n    this._blobUrlsByItem.set(key, url);\n  }\n\n  _log(level, message, payload = null) {\n    if (this.logger) {\n      this.logger(level, message, payload);\n      return;\n    }\n    const fn = level === 'error' ? console.error : (level === 'warn' ? console.warn : console.log);\n    fn('[HydraOverlayIngress]', message, payload || '');\n  }\n}\n","/**\n * OverlayRegistry\n *\n * Purpose:\n * - Registry for layer and item renderers, enabling plugin-style expansion.\n *\n * API intention:\n * - registerLayerRenderer(type, factory)\n * - registerItemRenderer(type, factory)\n * - getLayerRenderer(type), getItemRenderer(type)\n *\n * Relationships:\n * - Used by OverlaySubsystem to map layer/item types to renderer factories.\n */\nexport class OverlayRegistry {\n    constructor() {\n        this.layerRenderers = new Map();\n        this.itemRenderers = new Map();\n    }\n\n    registerLayerRenderer(type, factory) {\n        this.layerRenderers.set(type, factory);\n    }\n\n    registerItemRenderer(type, factory) {\n        this.itemRenderers.set(type, factory);\n    }\n\n    getLayerRenderer(type) {\n        return this.layerRenderers.get(type) || null;\n    }\n\n    getItemRenderer(type) {\n        return this.itemRenderers.get(type) || null;\n    }\n}\n","/**\n * DataSourceApiService\n *\n * API client for data source management.\n */\n\nimport { getAuthService } from '../auth/AuthService.js';\nimport { getBackendApiBase } from '../shared/backend.js';\n\nconst API_BASE = getBackendApiBase();\n\nexport class DataSourceApiService {\n  constructor() {\n    this.authService = getAuthService();\n  }\n\n  async listSources({ limit = 50, offset = 0, includePublic = false } = {}) {\n    const params = new URLSearchParams({\n      limit: String(limit),\n      offset: String(offset),\n      includePublic: String(includePublic),\n    });\n    const response = await this.authService.authenticatedFetch(`${API_BASE}/data-sources?${params.toString()}`);\n    const data = await response.json();\n    if (!response.ok) {\n      throw new Error(data.error || 'Failed to list data sources');\n    }\n    return data;\n  }\n\n  async createSource({ title, description, visibility = 'private', standardType, metadata, crs, bboxWgs84 }) {\n    const response = await this.authService.authenticatedFetch(`${API_BASE}/data-sources`, {\n      method: 'POST',\n      headers: { 'Content-Type': 'application/json' },\n      body: JSON.stringify({ title, description, visibility, standardType, metadata, crs, bboxWgs84 }),\n    });\n    const data = await response.json();\n    if (!response.ok) {\n      throw new Error(data.error || 'Failed to create data source');\n    }\n    return data.source;\n  }\n\n  async getSource(sourceId) {\n    const response = await this.authService.authenticatedFetch(`${API_BASE}/data-sources/${sourceId}`);\n    const data = await response.json();\n    if (!response.ok) {\n      throw new Error(data.error || 'Failed to get data source');\n    }\n    return data;\n  }\n\n  async listVersions(sourceId) {\n    const response = await this.authService.authenticatedFetch(`${API_BASE}/data-sources/${sourceId}/versions`);\n    const data = await response.json();\n    if (!response.ok) {\n      throw new Error(data.error || 'Failed to list data source versions');\n    }\n    return data.versions;\n  }\n\n  async createVersion(sourceId, { parentVersionId, transformChain, metadata, setActive = true } = {}) {\n    const response = await this.authService.authenticatedFetch(`${API_BASE}/data-sources/${sourceId}/versions`, {\n      method: 'POST',\n      headers: { 'Content-Type': 'application/json' },\n      body: JSON.stringify({ parentVersionId, transformChain, metadata, setActive }),\n    });\n    const data = await response.json();\n    if (!response.ok) {\n      throw new Error(data.error || 'Failed to create data source version');\n    }\n    return data.version;\n  }\n\n  async addAsset(sourceId, { versionId, fileId, remoteUrl, assetType, contentType, bytes, metadata }) {\n    const response = await this.authService.authenticatedFetch(`${API_BASE}/data-sources/${sourceId}/assets`, {\n      method: 'POST',\n      headers: { 'Content-Type': 'application/json' },\n      body: JSON.stringify({\n        versionId,\n        fileId,\n        remoteUrl,\n        assetType,\n        contentType,\n        bytes,\n        metadata,\n      }),\n    });\n    const data = await response.json();\n    if (!response.ok) {\n      throw new Error(data.error || 'Failed to add data source asset');\n    }\n    return data.asset;\n  }\n\n  async ingestSource(sourceId) {\n    const response = await this.authService.authenticatedFetch(`${API_BASE}/data-sources/${sourceId}/ingest`, {\n      method: 'POST',\n    });\n    const data = await response.json();\n    if (!response.ok) {\n      throw new Error(data.error || 'Failed to ingest data source');\n    }\n    return data.ingest;\n  }\n\n  async uploadFile(file, role = null, encrypt = false) {\n    const formData = new FormData();\n    formData.append('file', file);\n    const params = new URLSearchParams();\n    if (role) params.set('role', role);\n    params.set('encrypt', encrypt ? 'true' : 'false');\n    const url = `${API_BASE}/files?${params.toString()}`;\n    const response = await this.authService.authenticatedFetch(url, {\n      method: 'POST',\n      body: formData,\n    });\n    const data = await response.json();\n    if (!response.ok) {\n      throw new Error(data.error || 'Failed to upload file');\n    }\n    return data.file;\n  }\n}\n\nlet dataSourceApiServiceInstance = null;\n\nexport function getDataSourceApiService() {\n  if (!dataSourceApiServiceInstance) {\n    dataSourceApiServiceInstance = new DataSourceApiService();\n  }\n  return dataSourceApiServiceInstance;\n}\n","/**\n * VectorSourceLayer\n *\n * Renders vector data (GeoJSON or OGC API Features) onto the planet.\n */\nimport * as THREE from 'three';\nimport { latLonToLocalDir, ellipsoidRadiusForLocalDir } from '../../../modules/geometry-utils.js';\n\nconst DEFAULT_COLOR = '#6cf3ff';\nconst DEFAULT_OPACITY = 0.85;\nconst DEFAULT_POINT_SIZE = 2500;\nconst DEFAULT_OFFSET_M = 50;\nconst DEFAULT_LIMIT = 10000;\n\nconst normalizeType = (value) => String(value || '').trim().toLowerCase();\n\nconst resolveStyle = (layer) => (layer?.style_json && typeof layer.style_json === 'object'\n    ? layer.style_json\n    : {});\n\nexport class VectorSourceLayer {\n    constructor(options = {}) {\n        this.layer = options.layer || {};\n        this.group = options.group || null;\n        this.planetRadius = options.planetRadius || 6371000;\n        this.triTree = options.triTree || null;\n        this.camera = options.camera || null;\n        this.authService = options.authService || null;\n        this.apiBase = options.apiBase || '';\n        this.sourceId = options.sourceId || null;\n        this.source = options.source || null;\n        this.assets = Array.isArray(options.assets) ? options.assets : [];\n\n        this._active = true;\n        this._loadSeq = 0;\n        this._signature = '';\n\n        this.container = new THREE.Group();\n        this.container.name = 'VectorSourceLayer';\n        if (this.group) {\n            this.group.add(this.container);\n        }\n\n        this._refresh();\n    }\n\n    update(next) {\n        if (next?.layer) this.layer = next.layer;\n        if (next?.source) this.source = next.source;\n        if (Array.isArray(next?.assets)) this.assets = next.assets;\n        this._refresh();\n    }\n\n    async _refresh() {\n        if (!this._active) return;\n        const signature = this._computeSignature();\n        if (signature === this._signature) return;\n        this._signature = signature;\n\n        const seq = ++this._loadSeq;\n        try {\n            const geojson = await this._fetchGeoJson();\n            if (!this._active || seq !== this._loadSeq) return;\n            this._renderGeoJson(geojson);\n        } catch (error) {\n            console.warn('[VectorSourceLayer] Failed to load vector data', error);\n        }\n    }\n\n    _computeSignature() {\n        const style = resolveStyle(this.layer);\n        const ref = this.layer?.source_ref || this.layer?.sourceRef || {};\n        return JSON.stringify({\n            sourceId: this.sourceId,\n            versionId: ref?.data_source_version_id || null,\n            style,\n            assets: (this.assets || []).map((asset) => asset?.asset_id || asset?.file_id || asset?.remote_url || asset?.asset_type).slice(0, 5),\n        });\n    }\n\n    _pickAsset(types) {\n        const typeSet = new Set(types.map((t) => normalizeType(t)));\n        return this.assets.find((asset) => typeSet.has(normalizeType(asset?.asset_type)));\n    }\n\n    async _fetchGeoJson() {\n        const style = resolveStyle(this.layer);\n        const limit = Number.isFinite(style.limit) ? Math.min(style.limit, DEFAULT_LIMIT) : DEFAULT_LIMIT;\n        const collection = style.collection || style.collectionId || null;\n        const bbox = Array.isArray(style.bbox) && style.bbox.length >= 4 ? style.bbox : null;\n        const filter = style.filter || style.cql2 || null;\n        const filterLang = style.filter_lang || style.filterLang || null;\n\n        const ogcAsset = this._pickAsset(['ogc_api_features']);\n        if (ogcAsset || normalizeType(this.source?.standard_type) === 'ogc_api_features') {\n            return this._fetchFromOgca({ collection, filter, filterLang, limit, bbox });\n        }\n\n        const geoAsset = this._pickAsset(['geojson']);\n        if (geoAsset) {\n            return this._fetchFromGeoJsonAsset(geoAsset);\n        }\n\n        throw new Error('No vector asset configured for data source');\n    }\n\n    async _fetchFromOgca({ collection, filter, filterLang, limit, bbox }) {\n        if (!this.sourceId) throw new Error('Missing data source id');\n        const params = new URLSearchParams();\n        if (collection) params.set('collection', collection);\n        if (bbox) params.set('bbox', bbox.join(','));\n        if (Number.isFinite(limit)) params.set('limit', String(limit));\n\n        if (filter) {\n            if (typeof filter === 'string') {\n                params.set('filter', filter);\n                params.set('filter-lang', filterLang || 'cql2-text');\n                const url = `${this.apiBase}/data-sources/${this.sourceId}/features?${params.toString()}`;\n                return this._fetchJson(url);\n            }\n            if (typeof filter === 'object') {\n                params.set('filter-lang', filterLang || 'cql2-json');\n                const url = `${this.apiBase}/data-sources/${this.sourceId}/features?${params.toString()}`;\n                return this._fetchJson(url, {\n                    method: 'POST',\n                    body: JSON.stringify(filter),\n                    headers: { 'Content-Type': 'application/json' },\n                });\n            }\n        }\n\n        const url = `${this.apiBase}/data-sources/${this.sourceId}/features?${params.toString()}`;\n        return this._fetchJson(url);\n    }\n\n    async _fetchFromGeoJsonAsset(asset) {\n        if (!asset) throw new Error('Missing GeoJSON asset');\n        const remote = asset.remote_url;\n        if (remote) {\n            return this._fetchJson(remote, { useAuth: false });\n        }\n        if (!asset.file_id) {\n            throw new Error('GeoJSON asset missing remote_url and file_id');\n        }\n        const url = `${this.apiBase}/files/${asset.file_id}/download`;\n        return this._fetchJson(url);\n    }\n\n    async _fetchJson(url, options = {}) {\n        const useAuth = options.useAuth !== false;\n        const fetchOptions = { ...options };\n        delete fetchOptions.useAuth;\n\n        const response = useAuth && this.authService\n            ? await this.authService.authenticatedFetch(url, { ...fetchOptions, includeContentType: false })\n            : await fetch(url, fetchOptions);\n\n        if (!response.ok) {\n            const text = await response.text().catch(() => '');\n            throw new Error(`Request failed (${response.status}): ${text}`);\n        }\n        return response.json();\n    }\n\n    _renderGeoJson(geojson) {\n        this._clear();\n        if (!geojson) return;\n\n        const style = resolveStyle(this.layer);\n        const color = style.line_color || style.color || DEFAULT_COLOR;\n        const pointColor = style.point_color || color;\n        const opacity = Number.isFinite(style.opacity) ? style.opacity : DEFAULT_OPACITY;\n        const fillColor = style.fill_color || color;\n        const fillOpacity = Number.isFinite(style.fill_opacity) ? style.fill_opacity : Math.min(0.4, opacity * 0.4);\n        const pointSize = Number.isFinite(style.point_size_m)\n            ? style.point_size_m\n            : (Number.isFinite(style.point_size) ? style.point_size : DEFAULT_POINT_SIZE);\n        const offsetM = Number.isFinite(style.offset_m) ? style.offset_m : DEFAULT_OFFSET_M;\n        const alignToSurface = style.align_to_surface === true;\n        const fillEnabled = style.fill_enabled !== false;\n        const labelField = typeof style.label_field === 'string' ? style.label_field : null;\n        const labelMax = Number.isFinite(style.label_max) ? Math.max(0, Math.floor(style.label_max)) : 200;\n        const worldQuat = alignToSurface && this.triTree?.group\n            ? this.triTree.group.getWorldQuaternion(new THREE.Quaternion())\n            : null;\n\n        const linePositions = [];\n        const pointPositions = [];\n        const fillPositions = [];\n        const labels = [];\n        const maxFeatures = Number.isFinite(style.limit)\n            ? Math.min(style.limit, DEFAULT_LIMIT)\n            : DEFAULT_LIMIT;\n        let featureCount = 0;\n\n        const handleCoords = (coords, cb) => {\n            if (!Array.isArray(coords)) return;\n            for (const coord of coords) {\n                if (Array.isArray(coord) && typeof coord[0] === 'number') {\n                    cb(coord);\n                } else if (Array.isArray(coord)) {\n                    handleCoords(coord, cb);\n                }\n            }\n        };\n\n        const pushPoint = (coord, properties = null) => {\n            const [lon, lat] = coord;\n            if (!Number.isFinite(lat) || !Number.isFinite(lon)) return;\n            const pos = this._toWorld(lon, lat, offsetM, alignToSurface, worldQuat);\n            if (!pos) return;\n            pointPositions.push(pos.x, pos.y, pos.z);\n            if (labelField && properties && labels.length < labelMax) {\n                const labelValue = properties[labelField];\n                if (labelValue !== undefined && labelValue !== null) {\n                    labels.push({ lon, lat, text: String(labelValue) });\n                }\n            }\n        };\n\n        const pushLine = (coords) => {\n            if (!Array.isArray(coords) || coords.length < 2) return;\n            for (let i = 0; i < coords.length - 1; i++) {\n                const [lonA, latA] = coords[i];\n                const [lonB, latB] = coords[i + 1];\n                if (!Number.isFinite(latA) || !Number.isFinite(lonA) || !Number.isFinite(latB) || !Number.isFinite(lonB)) {\n                    continue;\n                }\n                const a = this._toWorld(lonA, latA, offsetM, alignToSurface, worldQuat);\n                const b = this._toWorld(lonB, latB, offsetM, alignToSurface, worldQuat);\n                if (!a || !b) continue;\n                linePositions.push(a.x, a.y, a.z, b.x, b.y, b.z);\n            }\n        };\n\n        const pushPolygon = (rings, properties = null) => {\n            if (!Array.isArray(rings)) return;\n            for (const ring of rings) {\n                if (!Array.isArray(ring) || ring.length < 2) continue;\n                pushLine(ring);\n                const first = ring[0];\n                const last = ring[ring.length - 1];\n                if (first && last && (first[0] !== last[0] || first[1] !== last[1])) {\n                    pushLine([last, first]);\n                }\n            }\n            if (fillEnabled && Array.isArray(rings[0])) {\n                this._triangulatePolygonFill(rings, fillPositions, offsetM, alignToSurface, worldQuat);\n            }\n            if (labelField && properties && labels.length < labelMax) {\n                const labelValue = properties[labelField];\n                const centroid = this._estimatePolygonCentroid(rings?.[0]);\n                if (labelValue !== undefined && labelValue !== null && centroid) {\n                    labels.push({ lon: centroid.lon, lat: centroid.lat, text: String(labelValue) });\n                }\n            }\n        };\n\n        const handleGeometry = (geom, properties = null) => {\n            if (!geom || featureCount >= maxFeatures) return;\n            const type = geom.type;\n            const coords = geom.coordinates;\n            if (!type || coords === undefined) return;\n\n            switch (type) {\n                case 'Point':\n                    pushPoint(coords, properties);\n                    break;\n                case 'MultiPoint':\n                    handleCoords(coords, (coord) => pushPoint(coord, properties));\n                    break;\n                case 'LineString':\n                    pushLine(coords);\n                    break;\n                case 'MultiLineString':\n                    if (Array.isArray(coords)) {\n                        coords.forEach((line) => pushLine(line));\n                    }\n                    break;\n                case 'Polygon':\n                    pushPolygon(coords, properties);\n                    break;\n                case 'MultiPolygon':\n                    if (Array.isArray(coords)) {\n                        coords.forEach((poly) => pushPolygon(poly, properties));\n                    }\n                    break;\n                default:\n                    break;\n            }\n        };\n\n        const features = Array.isArray(geojson?.features) ? geojson.features : null;\n        if (features) {\n            for (const feature of features) {\n                if (featureCount >= maxFeatures) break;\n                handleGeometry(feature?.geometry, feature?.properties || null);\n                featureCount += 1;\n            }\n        } else if (geojson?.type) {\n            handleGeometry(geojson, geojson?.properties || null);\n        }\n\n        if (linePositions.length) {\n            const geometry = new THREE.BufferGeometry();\n            geometry.setAttribute('position', new THREE.Float32BufferAttribute(linePositions, 3));\n            const material = new THREE.LineBasicMaterial({\n                color: new THREE.Color(color),\n                opacity,\n                transparent: opacity < 1,\n            });\n            const lines = new THREE.LineSegments(geometry, material);\n            lines.renderOrder = 6;\n            lines.frustumCulled = false;\n            this.container.add(lines);\n        }\n\n        if (pointPositions.length) {\n            const geometry = new THREE.BufferGeometry();\n            geometry.setAttribute('position', new THREE.Float32BufferAttribute(pointPositions, 3));\n            const material = new THREE.PointsMaterial({\n                color: new THREE.Color(pointColor),\n                size: pointSize,\n                sizeAttenuation: true,\n                opacity,\n                transparent: opacity < 1,\n            });\n            const points = new THREE.Points(geometry, material);\n            points.renderOrder = 7;\n            points.frustumCulled = false;\n            this.container.add(points);\n        }\n\n        if (fillPositions.length) {\n            const geometry = new THREE.BufferGeometry();\n            geometry.setAttribute('position', new THREE.Float32BufferAttribute(fillPositions, 3));\n            const material = new THREE.MeshBasicMaterial({\n                color: new THREE.Color(fillColor),\n                opacity: fillOpacity,\n                transparent: fillOpacity < 1,\n                depthWrite: false,\n                side: THREE.DoubleSide,\n            });\n            const mesh = new THREE.Mesh(geometry, material);\n            mesh.renderOrder = 5;\n            mesh.frustumCulled = false;\n            this.container.add(mesh);\n        }\n\n        if (labels.length) {\n            labels.forEach((label) => {\n                const sprite = this._createLabelSprite(label.text, style);\n                const pos = this._toWorld(label.lon, label.lat, offsetM, alignToSurface, worldQuat);\n                if (!pos) return;\n                sprite.position.copy(pos);\n                sprite.renderOrder = 8;\n                this.container.add(sprite);\n            });\n        }\n    }\n\n    _estimatePolygonCentroid(ring) {\n        if (!Array.isArray(ring) || ring.length === 0) return null;\n        let sumLat = 0;\n        let sumLon = 0;\n        let count = 0;\n        for (const coord of ring) {\n            if (!Array.isArray(coord) || coord.length < 2) continue;\n            const lon = coord[0];\n            const lat = coord[1];\n            if (!Number.isFinite(lat) || !Number.isFinite(lon)) continue;\n            sumLat += lat;\n            sumLon += lon;\n            count += 1;\n        }\n        if (!count) return null;\n        return { lat: sumLat / count, lon: sumLon / count };\n    }\n\n    _computeBounds(ring) {\n        let minLat = Infinity;\n        let maxLat = -Infinity;\n        let minLon = Infinity;\n        let maxLon = -Infinity;\n        for (const coord of ring) {\n            if (!Array.isArray(coord) || coord.length < 2) continue;\n            const lon = coord[0];\n            const lat = coord[1];\n            if (!Number.isFinite(lat) || !Number.isFinite(lon)) continue;\n            minLat = Math.min(minLat, lat);\n            maxLat = Math.max(maxLat, lat);\n            minLon = Math.min(minLon, lon);\n            maxLon = Math.max(maxLon, lon);\n        }\n        if (!Number.isFinite(minLat) || !Number.isFinite(minLon)) return null;\n        return { spanLat: maxLat - minLat, spanLon: maxLon - minLon };\n    }\n\n    _triangulatePolygonFill(rings, fillPositions, offsetM, alignToSurface, worldQuat) {\n        if (!Array.isArray(rings) || !rings.length) return;\n        const outer = rings[0];\n        if (!Array.isArray(outer) || outer.length < 3) return;\n\n        const bounds = this._computeBounds(outer);\n        if (!bounds || bounds.spanLon > 60 || bounds.spanLat > 60) {\n            return;\n        }\n\n        const center = this._estimatePolygonCentroid(outer);\n        if (!center) return;\n        const centerDir = latLonToLocalDir(center.lat, center.lon).normalize();\n\n        const east = new THREE.Vector3(0, 1, 0).cross(centerDir);\n        if (east.lengthSq() < 1e-6) {\n            east.set(1, 0, 0);\n        } else {\n            east.normalize();\n        }\n        const north = new THREE.Vector3().crossVectors(centerDir, east).normalize();\n\n        const to2D = (coord) => {\n            const [lon, lat] = coord;\n            if (!Number.isFinite(lat) || !Number.isFinite(lon)) return null;\n            const dir = latLonToLocalDir(lat, lon);\n            return new THREE.Vector2(dir.dot(east), dir.dot(north));\n        };\n\n        const shape = [];\n        for (const coord of outer) {\n            const p = to2D(coord);\n            if (p) shape.push(p);\n        }\n        if (shape.length < 3) return;\n\n        const holes = [];\n        for (let i = 1; i < rings.length; i++) {\n            const ring = rings[i];\n            if (!Array.isArray(ring) || ring.length < 3) continue;\n            const hole = [];\n            for (const coord of ring) {\n                const p = to2D(coord);\n                if (p) hole.push(p);\n            }\n            if (hole.length >= 3) holes.push(hole);\n        }\n\n        const triangles = THREE.ShapeUtils.triangulateShape(shape, holes);\n        if (!triangles.length) return;\n\n        const allPoints = [...shape, ...holes.flat()];\n        const radius = this.planetRadius + offsetM;\n\n        for (const tri of triangles) {\n            for (const idx of tri) {\n                const pt = allPoints[idx];\n                if (!pt) continue;\n                const dir = centerDir.clone()\n                    .add(east.clone().multiplyScalar(pt.x))\n                    .add(north.clone().multiplyScalar(pt.y))\n                    .normalize();\n                fillPositions.push(dir.x * radius, dir.y * radius, dir.z * radius);\n            }\n        }\n    }\n\n    _createLabelSprite(text, style) {\n        const fontSize = Number.isFinite(style.label_size) ? style.label_size : 32;\n        const padding = 12;\n        const canvas = document.createElement('canvas');\n        const ctx = canvas.getContext('2d');\n        ctx.font = `600 ${fontSize}px system-ui`;\n        const metrics = ctx.measureText(text);\n        const width = Math.ceil(metrics.width) + padding * 2;\n        const height = fontSize + padding * 2;\n        canvas.width = width;\n        canvas.height = height;\n        ctx.font = `600 ${fontSize}px system-ui`;\n        ctx.fillStyle = style.label_bg || 'rgba(0,0,0,0.6)';\n        ctx.fillRect(0, 0, width, height);\n        ctx.fillStyle = style.label_color || '#ffffff';\n        ctx.textBaseline = 'middle';\n        ctx.fillText(text, padding, height / 2);\n\n        const texture = new THREE.CanvasTexture(canvas);\n        texture.needsUpdate = true;\n        const material = new THREE.SpriteMaterial({ map: texture, transparent: true });\n        const sprite = new THREE.Sprite(material);\n        const aspect = width / height;\n        const scale = (this.planetRadius * 0.001) * (Number.isFinite(style.label_scale) ? style.label_scale : 1);\n        sprite.scale.set(scale * aspect, scale, 1);\n        return sprite;\n    }\n\n    _toWorld(lon, lat, offsetM, alignToSurface, worldQuat) {\n        const dir = latLonToLocalDir(lat, lon);\n        if (!dir) return null;\n        let radius = ellipsoidRadiusForLocalDir(dir);\n        if (alignToSurface && worldQuat) {\n            const worldDir = dir.clone().applyQuaternion(worldQuat).normalize();\n            const raycast = this.triTree.sampleTerrainRadiusForDir?.(worldDir);\n            const sampled = Number.isFinite(raycast)\n                ? raycast\n                : this.triTree.getSurfaceRadiusAtDir?.(worldDir);\n            if (Number.isFinite(sampled)) radius = sampled;\n        }\n        return dir.multiplyScalar(radius + offsetM);\n    }\n\n    _clear() {\n        if (!this.container) return;\n        while (this.container.children.length) {\n            const child = this.container.children.pop();\n            if (child.geometry) child.geometry.dispose();\n            if (child.material) {\n                if (Array.isArray(child.material)) {\n                    child.material.forEach((mat) => mat.dispose?.());\n                } else {\n                    child.material.dispose?.();\n                }\n            }\n        }\n    }\n\n    dispose() {\n        this._active = false;\n        this._loadSeq += 1;\n        this._clear();\n        if (this.container?.parent) {\n            this.container.parent.remove(this.container);\n        }\n        this.container = null;\n    }\n}\n","import {createDataSurfaceGeometry,dataSurfaceRadius} from '../../environment/DataSurfaceGeometry.js';\n/**\n * TileSourceLayer\n *\n * Renders raster tile sources (WMS/WMTS/COG) as a global overlay texture.\n * Uses a low-zoom tile atlas, reprojected to equirectangular for sphere mapping.\n */\nimport * as THREE from 'three';\nimport { latLonToLocalDir, lonLatToTileCoords, worldPosToLatLonLocal } from '../../../modules/geometry-utils.js';\n\nconst DEFAULT_OPACITY = 0.7;\nconst DEFAULT_OFFSET_M = 150;\nconst DEFAULT_ZOOM = 2;\nconst MAX_ZOOM = 4;\n\nconst normalizeType = (value) => String(value || '').trim().toLowerCase();\nconst resolveStyle = (layer) => (layer?.style_json && typeof layer.style_json === 'object'\n    ? layer.style_json\n    : {});\n\nexport class TileSourceLayer {\n    constructor(options = {}) {\n        this.layer = options.layer || {};\n        this.group = options.group || null;\n        this.planetRadius = options.planetRadius || 6371000;\n        this.triTree = options.triTree || null;\n        this.camera = options.camera || null;\n        this.authService = options.authService || null;\n        this.apiBase = options.apiBase || '';\n        this.sourceId = options.sourceId || null;\n        this.source = options.source || null;\n        this.assets = Array.isArray(options.assets) ? options.assets : [];\n        this.mode = options.mode || 'tiles';\n\n        this._active = true;\n        this._loadSeq = 0;\n        this._signature = '';\n        this._detailSeq = 0;\n        this._detailTimer = null;\n        this._detailCenter = null;\n        this._detailBounds = null;\n\n        this.container = new THREE.Group();\n        this.container.name = 'TileSourceLayer';\n        if (this.group) {\n            this.group.add(this.container);\n        }\n\n        this._buildMesh();\n        this._refresh();\n        this._startDetailUpdates();\n    }\n\n    update(next) {\n        if (next?.layer) this.layer = next.layer;\n        if (next?.source) this.source = next.source;\n        if (Array.isArray(next?.assets)) this.assets = next.assets;\n        this._refresh();\n    }\n\n    _buildMesh() {\n        const style = resolveStyle(this.layer);\n        const offsetM = Number.isFinite(style.offset_m) ? style.offset_m : DEFAULT_OFFSET_M;\n        this._offsetM = offsetM;\n        const opacity = Number.isFinite(style.opacity) ? style.opacity : DEFAULT_OPACITY;\n\n        const geometry = createDataSurfaceGeometry(offsetM);\n        const material = new THREE.MeshBasicMaterial({\n            color: 0xffffff,\n            transparent: opacity < 1,\n            opacity,\n            depthWrite: false,\n        });\n\n        const mesh = new THREE.Mesh(geometry, material);\n        mesh.renderOrder = 5;\n        mesh.frustumCulled = false;\n        this.mesh = mesh;\n        this.container.add(mesh);\n    }\n\n    _applyStyle() {\n        if (!this.mesh) return;\n        const style = resolveStyle(this.layer);\n        const opacity = Number.isFinite(style.opacity) ? style.opacity : DEFAULT_OPACITY;\n        const offsetM = Number.isFinite(style.offset_m) ? style.offset_m : DEFAULT_OFFSET_M;\n\n        if (Number.isFinite(opacity)) {\n            this.mesh.material.opacity = opacity;\n            this.mesh.material.transparent = opacity < 1;\n        }\n\n        if (Number.isFinite(offsetM) && offsetM !== this._offsetM) {\n            this.mesh.geometry?.dispose();\n            this.mesh.geometry = createDataSurfaceGeometry(offsetM);\n            this._offsetM = offsetM;\n        }\n    }\n\n    _computeSignature() {\n        const style = resolveStyle(this.layer);\n        const ref = this.layer?.source_ref || this.layer?.sourceRef || {};\n        return JSON.stringify({\n            sourceId: this.sourceId,\n            versionId: ref?.data_source_version_id || null,\n            style,\n            mode: this.mode,\n        });\n    }\n\n    async _refresh() {\n        if (!this._active) return;\n        const signature = this._computeSignature();\n        if (signature === this._signature) return;\n        this._signature = signature;\n\n        const seq = ++this._loadSeq;\n        try {\n            this._applyStyle();\n            const texture = await this._buildTexture();\n            if (!this._active || seq !== this._loadSeq) return;\n            if (this.mesh?.material) {\n                if (this.mesh.material.map) {\n                    this.mesh.material.map.dispose?.();\n                }\n                this.mesh.material.map = texture;\n                this.mesh.material.needsUpdate = true;\n            }\n            this._updateDetailPatch({ force: true }).catch(() => null);\n        } catch (error) {\n            console.warn('[TileSourceLayer] Failed to build tile texture', error);\n        }\n    }\n\n    _resolveZoom() {\n        const style = resolveStyle(this.layer);\n        const zoom = Number.isFinite(style.tile_zoom) ? style.tile_zoom\n            : (Number.isFinite(style.zoom) ? style.zoom : DEFAULT_ZOOM);\n        return Math.max(0, Math.min(MAX_ZOOM, Math.round(zoom)));\n    }\n\n    _resolveTileMode() {\n        const style = resolveStyle(this.layer);\n        const requested = normalizeType(style.tile_mode || style.mode);\n        if (requested) return requested;\n        return this.mode;\n    }\n\n    _tileUrl(z, x, y) {\n        const mode = this._resolveTileMode();\n        if (mode === 'cog') {\n            return `${this.apiBase}/data-sources/${this.sourceId}/cog/tiles/${z}/${x}/${y}.png`;\n        }\n        return `${this.apiBase}/data-sources/${this.sourceId}/tiles/${z}/${x}/${y}`;\n    }\n\n    async _buildTexture() {\n        if (!this.sourceId) throw new Error('Missing data source id');\n        const zoom = this._resolveZoom();\n        const n = Math.pow(2, zoom);\n\n        const firstTile = await this._fetchTile(zoom, 0, 0);\n        if (!firstTile) {\n            throw new Error('Failed to fetch tile 0/0');\n        }\n        const tileSize = firstTile.width || firstTile.height || 256;\n        const mercatorCanvas = document.createElement('canvas');\n        mercatorCanvas.width = tileSize * n;\n        mercatorCanvas.height = tileSize * n;\n        const mercCtx = mercatorCanvas.getContext('2d');\n\n        mercCtx.drawImage(firstTile, 0, 0);\n\n        const tiles = [];\n        for (let x = 0; x < n; x++) {\n            for (let y = 0; y < n; y++) {\n                if (x === 0 && y === 0) continue;\n                tiles.push({ x, y });\n            }\n        }\n\n        await this._mapLimit(tiles, 6, async (tile) => {\n            const image = await this._fetchTile(zoom, tile.x, tile.y);\n            if (!image) return;\n            mercCtx.drawImage(image, tile.x * tileSize, tile.y * tileSize, tileSize, tileSize);\n        });\n\n        const equirectCanvas = this._reprojectMercator(mercatorCanvas);\n        const texture = new THREE.CanvasTexture(equirectCanvas);\n        texture.colorSpace = THREE.SRGBColorSpace;\n        texture.wrapS = THREE.RepeatWrapping;\n        texture.wrapT = THREE.ClampToEdgeWrapping;\n        texture.needsUpdate = true;\n        return texture;\n    }\n\n    _startDetailUpdates() {\n        if (this._detailTimer) return;\n        this._detailTimer = setInterval(() => {\n            this._updateDetailPatch({ force: false }).catch(() => null);\n        }, 5000);\n    }\n\n    _stopDetailUpdates() {\n        if (this._detailTimer) {\n            clearInterval(this._detailTimer);\n            this._detailTimer = null;\n        }\n    }\n\n    _getCameraLatLon() {\n        if (!this.camera || !this.triTree?.group) return null;\n        const pos = new THREE.Vector3();\n        this.camera.getWorldPosition(pos);\n        const latLon = worldPosToLatLonLocal(pos, this.triTree.group);\n        if (!latLon) return null;\n        return { lat: latLon.latDeg, lon: latLon.lonDeg };\n    }\n\n    async _updateDetailPatch({ force = false } = {}) {\n        if (!this._active || !this.camera || !this.triTree) return;\n        const style = resolveStyle(this.layer);\n        const enabled = style.detail_enabled !== false;\n        if (!enabled) {\n            this._clearDetailMesh();\n            return;\n        }\n\n        const center = this._getCameraLatLon();\n        if (!center) return;\n\n        const span = Number.isFinite(style.detail_span_deg)\n            ? Math.max(5, Math.min(60, style.detail_span_deg))\n            : 20;\n        const updateDeg = Number.isFinite(style.detail_update_deg)\n            ? Math.max(0.2, Math.min(10, style.detail_update_deg))\n            : 2;\n        const detailZoom = Number.isFinite(style.detail_zoom)\n            ? Math.max(0, Math.min(8, Math.round(style.detail_zoom)))\n            : Math.min(MAX_ZOOM + 2, 6);\n\n        if (!force && this._detailCenter) {\n            const dLat = Math.abs(center.lat - this._detailCenter.lat);\n            const dLon = Math.abs(center.lon - this._detailCenter.lon);\n            if (dLat < updateDeg && dLon < updateDeg) {\n                return;\n            }\n        }\n\n        const bounds = this._computeDetailBounds(center, span);\n        if (!bounds) return;\n\n        const seq = ++this._detailSeq;\n        try {\n            const texture = await this._buildDetailTexture(bounds, detailZoom);\n            if (!this._active || seq !== this._detailSeq) return;\n            this._detailCenter = center;\n            this._detailBounds = bounds;\n            this._applyDetailTexture(bounds, texture);\n        } catch (error) {\n            console.warn('[TileSourceLayer] Detail patch failed', error);\n        }\n    }\n\n    _computeDetailBounds(center, spanDeg) {\n        const maxLatLimit = 85.05112878;\n        const half = spanDeg * 0.5;\n        let minLat = center.lat - half;\n        let maxLat = center.lat + half;\n        minLat = Math.max(-maxLatLimit, Math.min(maxLatLimit, minLat));\n        maxLat = Math.max(-maxLatLimit, Math.min(maxLatLimit, maxLat));\n\n        let minLon = center.lon - half;\n        let maxLon = center.lon + half;\n        if (minLon < -180 || maxLon > 180) {\n            // Skip if bounds wrap dateline for now.\n            return null;\n        }\n\n        return { minLat, maxLat, minLon, maxLon };\n    }\n\n    async _buildDetailTexture(bounds, zoom) {\n        const n = Math.pow(2, zoom);\n        const tileSize = 256;\n\n        const minX = Math.floor((bounds.minLon + 180) / 360 * n);\n        const maxX = Math.floor((bounds.maxLon + 180) / 360 * n);\n        const minY = lonLatToTileCoords(0, bounds.maxLat, zoom).y;\n        const maxY = lonLatToTileCoords(0, bounds.minLat, zoom).y;\n\n        const tileWidth = (maxX - minX + 1);\n        const tileHeight = (maxY - minY + 1);\n        if (tileWidth <= 0 || tileHeight <= 0) throw new Error('Invalid tile bounds');\n\n        const mercCanvas = document.createElement('canvas');\n        mercCanvas.width = tileWidth * tileSize;\n        mercCanvas.height = tileHeight * tileSize;\n        const ctx = mercCanvas.getContext('2d');\n\n        const tiles = [];\n        for (let x = minX; x <= maxX; x++) {\n            for (let y = minY; y <= maxY; y++) {\n                tiles.push({ x, y });\n            }\n        }\n\n        await this._mapLimit(tiles, 6, async (tile) => {\n            const image = await this._fetchTile(zoom, tile.x, tile.y);\n            if (!image) return;\n            const dx = (tile.x - minX) * tileSize;\n            const dy = (tile.y - minY) * tileSize;\n            ctx.drawImage(image, dx, dy, tileSize, tileSize);\n        });\n\n        const patch = this._reprojectMercatorPatch(mercCanvas, bounds, zoom, { minX, minY, tileSize, n });\n        const texture = new THREE.CanvasTexture(patch);\n        texture.colorSpace = THREE.SRGBColorSpace;\n        texture.wrapS = THREE.ClampToEdgeWrapping;\n        texture.wrapT = THREE.ClampToEdgeWrapping;\n        texture.needsUpdate = true;\n        return texture;\n    }\n\n    _reprojectMercatorPatch(mercCanvas, bounds, zoom, meta) {\n        const { minX, minY, tileSize, n } = meta;\n        const mercCtx = mercCanvas.getContext('2d');\n        const mercWidth = mercCanvas.width;\n        const mercHeight = mercCanvas.height;\n        const mercImage = mercCtx.getImageData(0, 0, mercWidth, mercHeight);\n        const mercData = mercImage.data;\n\n        const spanLon = bounds.maxLon - bounds.minLon;\n        const spanLat = bounds.maxLat - bounds.minLat;\n        const outWidth = mercWidth;\n        const outHeight = mercHeight;\n        const outCanvas = document.createElement('canvas');\n        outCanvas.width = outWidth;\n        outCanvas.height = outHeight;\n        const outCtx = outCanvas.getContext('2d');\n        const outImage = outCtx.createImageData(outWidth, outHeight);\n        const outData = outImage.data;\n\n        for (let y = 0; y < outHeight; y++) {\n            const lat = bounds.maxLat - (y / outHeight) * spanLat;\n            const latRad = (Math.max(-85.05112878, Math.min(85.05112878, lat)) * Math.PI) / 180;\n            const mercYFull = (1 - Math.log(Math.tan(latRad) + 1 / Math.cos(latRad)) / Math.PI) / 2 * (tileSize * n);\n            const mercY = mercYFull - minY * tileSize;\n            const my = Math.max(0, Math.min(mercHeight - 1, Math.floor(mercY)));\n            for (let x = 0; x < outWidth; x++) {\n                const lon = bounds.minLon + (x / outWidth) * spanLon;\n                const mercXFull = ((lon + 180) / 360) * (tileSize * n);\n                const mercX = mercXFull - minX * tileSize;\n                const mx = Math.max(0, Math.min(mercWidth - 1, Math.floor(mercX)));\n                const srcIdx = (my * mercWidth + mx) * 4;\n                const dstIdx = (y * outWidth + x) * 4;\n                outData[dstIdx] = mercData[srcIdx];\n                outData[dstIdx + 1] = mercData[srcIdx + 1];\n                outData[dstIdx + 2] = mercData[srcIdx + 2];\n                outData[dstIdx + 3] = mercData[srcIdx + 3];\n            }\n        }\n\n        outCtx.putImageData(outImage, 0, 0);\n        return outCanvas;\n    }\n\n    _applyDetailTexture(bounds, texture) {\n        if (!this.detailMesh) {\n            this.detailMesh = new THREE.Mesh(\n                this._buildDetailGeometry(bounds),\n                new THREE.MeshBasicMaterial({\n                    transparent: true,\n                    opacity: 0.95,\n                    depthWrite: false,\n                })\n            );\n            this.detailMesh.renderOrder = 6;\n            this.container.add(this.detailMesh);\n        } else {\n            this.detailMesh.geometry?.dispose();\n            this.detailMesh.geometry = this._buildDetailGeometry(bounds);\n        }\n        const material = this.detailMesh.material;\n        if (material.map) {\n            material.map.dispose?.();\n        }\n        material.map = texture;\n        material.needsUpdate = true;\n    }\n\n    _buildDetailGeometry(bounds) {\n        const segments = 32;\n        const rows = segments;\n        const cols = segments * 2;\n        const spanLon = bounds.maxLon - bounds.minLon;\n        const spanLat = bounds.maxLat - bounds.minLat;\n        const offset = Number.isFinite(this._offsetM) ? this._offsetM : DEFAULT_OFFSET_M;\n\n        const positions = [];\n        const uvs = [];\n        const indices = [];\n\n        for (let y = 0; y <= rows; y++) {\n            const v = y / rows;\n            const lat = bounds.maxLat - v * spanLat;\n            for (let x = 0; x <= cols; x++) {\n                const u = x / cols;\n                const lon = bounds.minLon + u * spanLon;\n                const dir = this._latLonToDir(lat, lon);\n                const radius=dataSurfaceRadius(dir,offset);\n                positions.push(dir.x * radius, dir.y * radius, dir.z * radius);\n                uvs.push(u, v);\n            }\n        }\n\n        for (let y = 0; y < rows; y++) {\n            for (let x = 0; x < cols; x++) {\n                const a = y * (cols + 1) + x;\n                const b = a + cols + 1;\n                const c = b + 1;\n                const d = a + 1;\n                indices.push(a, b, d, b, c, d);\n            }\n        }\n\n        const geometry = new THREE.BufferGeometry();\n        geometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3));\n        geometry.setAttribute('uv', new THREE.Float32BufferAttribute(uvs, 2));\n        geometry.setIndex(indices);\n        geometry.computeVertexNormals();\n        return geometry;\n    }\n\n    _latLonToDir(lat, lon) {\n        return latLonToLocalDir(lat, lon);\n    }\n\n    _clearDetailMesh() {\n        if (!this.detailMesh) return;\n        if (this.detailMesh.material?.map) {\n            this.detailMesh.material.map.dispose?.();\n        }\n        this.detailMesh.geometry?.dispose();\n        this.detailMesh.material?.dispose?.();\n        this.detailMesh.removeFromParent?.();\n        this.detailMesh = null;\n        this._detailCenter = null;\n        this._detailBounds = null;\n    }\n\n    async _fetchTile(z, x, y) {\n        const url = this._tileUrl(z, x, y);\n        const response = this.authService\n            ? await this.authService.authenticatedFetch(url, { includeContentType: false })\n            : await fetch(url);\n        if (!response.ok) return null;\n        const blob = await response.blob();\n        if (!blob) return null;\n        return this._blobToImage(blob);\n    }\n\n    async _blobToImage(blob) {\n        if (typeof createImageBitmap === 'function') {\n            return createImageBitmap(blob);\n        }\n        return new Promise((resolve, reject) => {\n            const img = new Image();\n            const url = URL.createObjectURL(blob);\n            img.onload = () => {\n                URL.revokeObjectURL(url);\n                resolve(img);\n            };\n            img.onerror = (err) => {\n                URL.revokeObjectURL(url);\n                reject(err);\n            };\n            img.src = url;\n        });\n    }\n\n    _reprojectMercator(mercatorCanvas) {\n        const mercCtx = mercatorCanvas.getContext('2d');\n        const mercWidth = mercatorCanvas.width;\n        const mercHeight = mercatorCanvas.height;\n        const mercImage = mercCtx.getImageData(0, 0, mercWidth, mercHeight);\n        const mercData = mercImage.data;\n\n        const outWidth = mercWidth;\n        const outHeight = Math.round(outWidth / 2);\n        const outCanvas = document.createElement('canvas');\n        outCanvas.width = outWidth;\n        outCanvas.height = outHeight;\n        const outCtx = outCanvas.getContext('2d');\n        const outImage = outCtx.createImageData(outWidth, outHeight);\n        const outData = outImage.data;\n\n        const latLookup = new Float32Array(outHeight);\n        const maxLat = 85.05112878;\n        for (let y = 0; y < outHeight; y++) {\n            const lat = 90 - (y / outHeight) * 180;\n            const latClamped = Math.max(-maxLat, Math.min(maxLat, lat));\n            const latRad = (latClamped * Math.PI) / 180;\n            const mercY = (1 - Math.log(Math.tan(latRad) + 1 / Math.cos(latRad)) / Math.PI) / 2 * mercHeight;\n            latLookup[y] = Math.max(0, Math.min(mercHeight - 1, mercY));\n        }\n\n        for (let y = 0; y < outHeight; y++) {\n            const mercY = Math.floor(latLookup[y]);\n            for (let x = 0; x < outWidth; x++) {\n                const mercX = Math.floor((x / outWidth) * mercWidth);\n                const srcIdx = (mercY * mercWidth + mercX) * 4;\n                const dstIdx = (y * outWidth + x) * 4;\n                outData[dstIdx] = mercData[srcIdx];\n                outData[dstIdx + 1] = mercData[srcIdx + 1];\n                outData[dstIdx + 2] = mercData[srcIdx + 2];\n                outData[dstIdx + 3] = mercData[srcIdx + 3];\n            }\n        }\n\n        outCtx.putImageData(outImage, 0, 0);\n        return outCanvas;\n    }\n\n    async _mapLimit(items, limit, iterator) {\n        const queue = items.slice();\n        const workers = new Array(Math.min(limit, items.length)).fill(null).map(async () => {\n            while (queue.length) {\n                const item = queue.shift();\n                if (!item) break;\n                await iterator(item);\n            }\n        });\n        await Promise.all(workers);\n    }\n\n    dispose() {\n        this._active = false;\n        this._loadSeq += 1;\n        this._stopDetailUpdates();\n        this._clearDetailMesh();\n        if (this.mesh) {\n            this.mesh.geometry?.dispose();\n            if (this.mesh.material) {\n                if (this.mesh.material.map) {\n                    this.mesh.material.map.dispose?.();\n                }\n                if (Array.isArray(this.mesh.material)) {\n                    this.mesh.material.forEach((mat) => mat.dispose?.());\n                } else {\n                    this.mesh.material.dispose?.();\n                }\n            }\n        }\n        if (this.container?.parent) {\n            this.container.parent.remove(this.container);\n        }\n        this.container = null;\n        this.mesh = null;\n    }\n}\n","/**\n * DataSourceLayerRenderer\n *\n * Resolves a data source reference on an overlay layer and delegates\n * rendering to vector/tile renderers.\n */\nimport * as THREE from 'three';\nimport { getAuthService } from '../../auth/AuthService.js';\nimport { getDataSourceApiService } from '../../creator/DataSourceApiService.js';\nimport { getBackendApiBase } from '../../shared/backend.js';\nimport { VectorSourceLayer } from './VectorSourceLayer.js';\nimport { TileSourceLayer } from './TileSourceLayer.js';\n\nconst VECTOR_ASSET_TYPES = new Set(['ogc_api_features', 'geojson']);\nconst TILE_ASSET_TYPES = new Set(['wms', 'wmts']);\nconst COG_ASSET_TYPES = new Set(['cog', 'geotiff', 'geotiff_cog']);\n\nconst normalizeType = (value) => String(value || '').trim().toLowerCase();\n\nfunction pickAssetByType(assets, typeSet) {\n    if (!Array.isArray(assets)) return null;\n    return assets.find((asset) => typeSet.has(normalizeType(asset?.asset_type)));\n}\n\nexport class DataSourceLayerRenderer {\n    constructor(options = {}) {\n        this.layer = options.layer || null;\n        this.group = options.group || null;\n        this.planetRadius = options.planetRadius;\n        this.triTree = options.triTree || null;\n        this.camera = options.camera || null;\n        this.eventBus = options.eventBus || null;\n        this.sceneInitializer = options.sceneInitializer || null;\n\n        this.authService = options.authService || getAuthService();\n        this.dataSourceApi = options.dataSourceApi || getDataSourceApiService();\n        this.apiBase = options.apiBase || getBackendApiBase();\n\n        this._active = true;\n        this._loadSeq = 0;\n        this._delegate = null;\n        this._delegateType = null;\n        this._sourceId = null;\n        this._sourceDetails = null;\n\n        this.container = new THREE.Group();\n        this.container.name = 'DataSourceLayer';\n        if (this.group) {\n            this.group.add(this.container);\n        }\n\n        this._init();\n    }\n\n    update(nextLayer) {\n        this.layer = nextLayer || this.layer;\n        this._init();\n    }\n\n    async _init() {\n        if (!this._active) return;\n        const seq = ++this._loadSeq;\n        const sourceId = this._resolveSourceId(this.layer);\n        if (!sourceId) return;\n\n        if (sourceId !== this._sourceId) {\n            this._sourceId = sourceId;\n            this._sourceDetails = null;\n        }\n\n        try {\n            const details = await this._getSourceDetails(sourceId);\n            if (!this._active || seq !== this._loadSeq) return;\n\n            this._sourceDetails = details;\n            const nextDelegate = this._buildDelegate(details);\n            if (!nextDelegate) {\n                this._disposeDelegate();\n                return;\n            }\n            if (this._delegate && this._delegateType === nextDelegate.type) {\n                this._delegate.update?.(nextDelegate.payload);\n                return;\n            }\n            this._disposeDelegate();\n            this._delegate = nextDelegate.instance;\n            this._delegateType = nextDelegate.type;\n        } catch (error) {\n            console.warn('[DataSourceLayerRenderer] Failed to init data source layer', error);\n        }\n    }\n\n    _resolveSourceId(layer) {\n        const ref = layer?.source_ref || layer?.sourceRef || null;\n        return ref?.data_source_id || ref?.source_id || null;\n    }\n\n    async _getSourceDetails(sourceId) {\n        if (this._sourceDetails && this._sourceId === sourceId) {\n            return this._sourceDetails;\n        }\n        return this.dataSourceApi.getSource(sourceId);\n    }\n\n    _buildDelegate(details) {\n        const source = details?.source;\n        const assets = Array.isArray(details?.assets) ? details.assets : [];\n        const layer = this.layer || {};\n\n        const vectorAsset = pickAssetByType(assets, VECTOR_ASSET_TYPES);\n        const tileAsset = pickAssetByType(assets, TILE_ASSET_TYPES);\n        const cogAsset = pickAssetByType(assets, COG_ASSET_TYPES);\n        const standard = normalizeType(source?.standard_type);\n\n        if (vectorAsset || standard === 'ogc_api_features' || standard === 'geojson') {\n            const instance = new VectorSourceLayer({\n                layer,\n                group: this.container,\n                planetRadius: this.planetRadius,\n                triTree: this.triTree,\n                camera: this.camera,\n                authService: this.authService,\n                apiBase: this.apiBase,\n                sourceId: this._sourceId,\n                source,\n                assets,\n            });\n            return { type: 'vector', instance, payload: { layer, source, assets } };\n        }\n\n        const tileMode = cogAsset || standard === 'cog' || standard === 'geotiff'\n            ? 'cog'\n            : 'tiles';\n\n        const wantsTile = !!tileAsset\n            || !!cogAsset\n            || ['wms', 'wmts', 'cog'].includes(standard)\n            || (standard === 'stac' && !!cogAsset)\n            || (standard === 'stac' && !!tileAsset);\n\n        if (wantsTile) {\n            const instance = new TileSourceLayer({\n                layer,\n                group: this.container,\n                planetRadius: this.planetRadius,\n                triTree: this.triTree,\n                camera: this.camera,\n                authService: this.authService,\n                apiBase: this.apiBase,\n                sourceId: this._sourceId,\n                source,\n                assets,\n                mode: tileMode,\n            });\n            return { type: 'tiles', instance, payload: { layer, source, assets } };\n        }\n\n        return null;\n    }\n\n    _disposeDelegate() {\n        if (this._delegate && typeof this._delegate.dispose === 'function') {\n            try {\n                this._delegate.dispose();\n            } catch (error) {\n                console.warn('[DataSourceLayerRenderer] Failed to dispose delegate', error);\n            }\n        }\n        this._delegate = null;\n        this._delegateType = null;\n    }\n\n    dispose() {\n        this._active = false;\n        this._loadSeq += 1;\n        this._disposeDelegate();\n        if (this.container?.parent) {\n            this.container.parent.remove(this.container);\n        }\n        this._disposeGroup(this.container);\n        this.container = null;\n    }\n\n    _disposeGroup(group) {\n        if (!group) return;\n        group.traverse((child) => {\n            if (child.geometry) child.geometry.dispose();\n            if (child.material) {\n                if (Array.isArray(child.material)) {\n                    child.material.forEach((mat) => mat.dispose?.());\n                } else {\n                    child.material.dispose?.();\n                }\n            }\n        });\n    }\n}\n","/**\n * StreamHub\n *\n * Purpose:\n * - Central registry for named streams with buffering and backpressure.\n * - Normalizes local and remote stream sources into a common interface.\n *\n * API intention:\n * - register(name, source), push(name, payload)\n * - status(name), connect(name, source), disconnect(name)\n *\n * Relationships:\n * - Used by EntitySystem, OverlaySubsystem, and AudioSystem.\n * - Emits stream status events through EventBus.\n */\nexport class StreamHub {\n    constructor(eventBus, options = {}) {\n        this.eventBus = eventBus;\n        this.streams = new Map();\n        this.defaultBufferLimit = Number.isFinite(options.defaultBufferLimit)\n            ? options.defaultBufferLimit\n            : 256;\n    }\n\n    register(name, source = null, options = {}) {\n        if (!name) return null;\n        const entry = this._ensureEntry(name);\n        if (Number.isFinite(options.bufferLimit)) {\n            entry.bufferLimit = options.bufferLimit;\n        }\n        if (typeof options.dropWhenUnbound === 'boolean') {\n            entry.dropWhenUnbound = options.dropWhenUnbound;\n        }\n        entry.source = source;\n        entry.handler = this._resolveHandler(source);\n        entry.connected = true;\n        this._emitStatus(name, entry);\n        if (source && typeof source.onConnect === 'function') {\n            source.onConnect();\n        }\n        return {\n            name,\n            push: (payload) => this.push(name, payload),\n            disconnect: () => this.disconnect(name),\n            release: () => this.release(name)\n        };\n    }\n\n    push(name, payload) {\n        if (!name) return;\n        const entry = this._ensureEntry(name);\n        if (!entry.connected) {\n            if (entry.dropWhenUnbound) {\n                entry.dropped++;\n                this._emitStatus(name, entry);\n                return;\n            }\n            this._buffer(entry, payload);\n            return;\n        }\n\n        if (entry.handler) {\n            try {\n                entry.handler(payload);\n            } catch (error) {\n                entry.dropped++;\n                this._emitStatus(name, entry);\n                console.warn(`[StreamHub] handler error for ${name}`, error);\n            }\n            return;\n        }\n\n        if (entry.dropWhenUnbound) {\n            entry.dropped++;\n            this._emitStatus(name, entry);\n            return;\n        }\n        this._buffer(entry, payload);\n    }\n\n    status(name) {\n        return this.streams.get(name) || { connected: false, buffered: 0, dropped: 0 };\n    }\n\n    connect(name, source) {\n        this.register(name, source);\n    }\n\n    disconnect(name) {\n        const entry = this.streams.get(name);\n        if (entry) {\n            entry.connected = false;\n            if (entry.source && typeof entry.source.onDisconnect === 'function') {\n                entry.source.onDisconnect();\n            }\n            this._emitStatus(name, entry);\n        }\n    }\n\n    release(name) {\n        const entry = this.streams.get(name);\n        if (!entry) return;\n        entry.source = null;\n        entry.handler = null;\n        entry.connected = false;\n        entry.buffer = [];\n        entry.buffered = 0;\n        this._emitStatus(name, entry);\n    }\n\n    _ensureEntry(name) {\n        if (!this.streams.has(name)) {\n            this.streams.set(name, {\n                name,\n                source: null,\n                handler: null,\n                connected: true,\n                buffer: [],\n                bufferLimit: this.defaultBufferLimit,\n                buffered: 0,\n                dropped: 0,\n                dropWhenUnbound: false\n            });\n        }\n        return this.streams.get(name);\n    }\n\n    _resolveHandler(source) {\n        if (typeof source === 'function') return source;\n        if (source && typeof source.onPayload === 'function') return source.onPayload.bind(source);\n        return null;\n    }\n\n    _buffer(entry, payload) {\n        const limit = Number.isFinite(entry.bufferLimit) ? entry.bufferLimit : this.defaultBufferLimit;\n        if (limit <= 0) {\n            entry.dropped++;\n            this._emitStatus(entry.name, entry);\n            return;\n        }\n        if (!Array.isArray(entry.buffer)) entry.buffer = [];\n        if (entry.buffer.length >= limit) {\n            entry.buffer.shift();\n            entry.dropped++;\n        }\n        entry.buffer.push(payload);\n        entry.buffered = entry.buffer.length;\n        this._emitStatus(entry.name, entry);\n    }\n\n    _emitStatus(name, entry) {\n        if (entry) entry.name = name;\n        this.eventBus?.emit('stream:status', {\n            name,\n            connected: !!entry?.connected,\n            buffered: entry?.buffered || 0,\n            dropped: entry?.dropped || 0\n        });\n    }\n}\n","/**\n * EntitySystem\n *\n * Purpose:\n * - Maintains entity state and binds entities to rendered items.\n * - Consumes location/orientation/trajectory streams.\n *\n * API intention:\n * - upsert(entity), remove(entityId), bind(entityId, itemId)\n * - updateFromStream(payload)\n *\n * Relationships:\n * - Uses StreamHub for live updates.\n * - Uses PlanetScene for spatial transforms.\n * - Coordinates with OverlaySubsystem for item lookup when bound.\n */\nimport * as THREE from 'three';\nimport { latLonToLocalDir, ellipsoidRadiusForLocalDir } from '../../modules/geometry-utils.js';\nimport { PLANET_RADIUS } from '../../modules/constants.js';\n\nexport class EntitySystem {\n    constructor({ parentGroup, overlaySubsystem, accessController, eventBus, planetRadius } = {}) {\n        this.parentGroup = parentGroup || null;\n        this.overlaySubsystem = overlaySubsystem || null;\n        this.accessController = accessController || null;\n        this.eventBus = eventBus || null;\n        this.planetRadius = Number.isFinite(planetRadius) ? planetRadius : PLANET_RADIUS;\n\n        this.entities = new Map();\n        this.bindings = new Map();\n        this.markers = new Map();\n        this._markerRadius = this.planetRadius * 0.0012;\n        this._defaultOffsetM = 1500;\n    }\n\n    upsert(entity) {\n        if (!entity || !entity.entity_id) return;\n        const id = entity.entity_id;\n        const prev = this.entities.get(id) || {};\n        const next = { ...prev, ...entity };\n        this.entities.set(id, next);\n\n        if (!this.bindings.has(id) && !this.markers.has(id)) {\n            const marker = this._createMarker(next);\n            if (marker) {\n                this.markers.set(id, marker);\n                this.parentGroup?.add(marker);\n            }\n        }\n    }\n\n    remove(entityId) {\n        if (!entityId) return;\n        const marker = this.markers.get(entityId);\n        if (marker) {\n            if (marker.parent) marker.parent.remove(marker);\n            this._disposeMarker(marker);\n        }\n        this.markers.delete(entityId);\n        this.entities.delete(entityId);\n        this.bindings.delete(entityId);\n    }\n\n    bind(entityId, itemId) {\n        if (!entityId || !itemId) return;\n        this.bindings.set(entityId, itemId);\n        const marker = this.markers.get(entityId);\n        if (marker) {\n            if (marker.parent) marker.parent.remove(marker);\n            this._disposeMarker(marker);\n            this.markers.delete(entityId);\n        }\n        const entity = this.entities.get(entityId);\n        if (entity?.lastPosition) {\n            this._applyPosition(entityId, entity.lastPosition, entity.lastOrientation);\n        }\n    }\n\n    updateFromStream(payload) {\n        if (!payload || !payload.entity_id) return;\n        const id = payload.entity_id;\n        const boundItemId = this.bindings.get(id);\n        if (boundItemId && this.accessController) {\n            if (typeof this.accessController.canPerform === 'function') {\n                Promise.resolve(\n                    this.accessController.canPerform('item', boundItemId, 'move_item')\n                ).catch(() => undefined);\n            }\n            const hasCached = typeof this.accessController.hasCachedDecision === 'function'\n                ? this.accessController.hasCachedDecision('item', boundItemId, 'move_item')\n                : false;\n            const canMove = hasCached && typeof this.accessController.canPerformSync === 'function'\n                ? this.accessController.canPerformSync('item', boundItemId, 'move_item')\n                : true;\n            if (!canMove) {\n                return;\n            }\n        }\n        const entity = this.entities.get(id) || { entity_id: id };\n        const position = this._resolvePosition(payload);\n        const orientation = this._resolveOrientation(payload);\n\n        if (position) {\n            entity.lastPosition = position.clone();\n        }\n        if (orientation) {\n            entity.lastOrientation = orientation.clone();\n        }\n        this.entities.set(id, entity);\n\n        if (position || orientation) {\n            this._applyPosition(id, position, orientation);\n            this.eventBus?.emit('entity:updated', { entityId: id });\n        }\n    }\n\n    _applyPosition(entityId, position, orientation) {\n        const boundObject = this._getBoundObject(entityId);\n        const target = boundObject || this.markers.get(entityId);\n        if (!target) return;\n\n        if (position) {\n            target.position.copy(position);\n        }\n        if (orientation) {\n            target.quaternion.copy(orientation);\n        }\n    }\n\n    _resolvePosition(payload) {\n        if (Number.isFinite(payload.lat) && Number.isFinite(payload.lon)) {\n            const elevation = Number.isFinite(payload.elevation_m) ? payload.elevation_m : 0;\n            const offset = Number.isFinite(payload.offset_m) ? payload.offset_m : this._defaultOffsetM;\n            const dir = latLonToLocalDir(payload.lat, payload.lon);\n            const baseRadius = ellipsoidRadiusForLocalDir(dir);\n            return dir.multiplyScalar(baseRadius + elevation + offset);\n        }\n        if (payload.position && Number.isFinite(payload.position.x)) {\n            return new THREE.Vector3(payload.position.x, payload.position.y, payload.position.z);\n        }\n        return null;\n    }\n\n    _resolveOrientation(payload) {\n        const q = payload.orientation_quat;\n        if (Array.isArray(q) && q.length === 4 && q.every(Number.isFinite)) {\n            return new THREE.Quaternion(q[0], q[1], q[2], q[3]);\n        }\n        return null;\n    }\n\n    _getBoundObject(entityId) {\n        const itemId = this.bindings.get(entityId);\n        if (!itemId || !this.overlaySubsystem) return null;\n        return this.overlaySubsystem.getItemObject(itemId);\n    }\n\n    getObjectForEntity(entityId) {\n        const bound = this._getBoundObject(entityId);\n        if (bound) return bound;\n        return this.markers.get(entityId) || null;\n    }\n\n    _createMarker(entity) {\n        if (!this.parentGroup) return null;\n        const geom = new THREE.SphereGeometry(this._markerRadius, 16, 16);\n        const color = entity?.color || '#22d3ee';\n        const mat = new THREE.MeshStandardMaterial({ color });\n        const mesh = new THREE.Mesh(geom, mat);\n        mesh.name = `Entity:${entity?.entity_id || 'entity'}`;\n        return mesh;\n    }\n\n    _disposeMarker(marker) {\n        if (marker.geometry) marker.geometry.dispose();\n        if (marker.material) {\n            if (Array.isArray(marker.material)) {\n                marker.material.forEach((mat) => mat.dispose());\n            } else {\n                marker.material.dispose();\n            }\n        }\n    }\n}\n","/**\n * AssetSubsystem\n *\n * Purpose:\n * - Loads, caches, and disposes file-backed assets (models, textures, audio).\n * - Provides a shared cache for overlays and planet systems.\n *\n * API intention:\n * - preload(fileDescriptors), get(fileId), release(fileId), dispose()\n *\n * Relationships:\n * - Used by OverlaySubsystem and PlanetScene.\n * - May use renderer for GPU resource management.\n */\nexport class AssetSubsystem {\n    constructor(options = {}) {\n        this.renderer = options.renderer || null;\n        this.cache = new Map();\n    }\n\n    async preload(_fileDescriptors) {\n    }\n\n    get(fileId) {\n        return this.cache.get(fileId) || null;\n    }\n\n    release(_fileId) {\n    }\n\n    dispose() {\n    }\n}\n","import * as THREE from 'three';\n\nconst CLOCK_UNCERTAINTY_FLOOR_MS = 4;\nconst MAX_SENSOR_AGE_MS = 60_000;\nconst DEFAULT_ORIENTATION_ACCURACY_DEG = 45;\n\nconst finite = (value) => value !== null\n  && value !== undefined\n  && value !== ''\n  && Number.isFinite(Number(value));\nconst clamp = (value, minimum, maximum) => Math.max(minimum, Math.min(maximum, Number(value)));\n\nfunction screenOrientationDegrees(environment = globalThis) {\n  const angle = environment?.screen?.orientation?.angle;\n  if (finite(angle)) return Number(angle);\n  return finite(environment?.orientation) ? Number(environment.orientation) : 0;\n}\n\nfunction diagonalCovariance(x, y, z) {\n  return [x, 0, 0, 0, y, 0, 0, 0, z];\n}\n\nfunction normalizeQuaternion(value) {\n  if (!value || ![value.x, value.y, value.z, value.w].every(finite)) return null;\n  const length = Math.hypot(value.x, value.y, value.z, value.w);\n  if (length < 1e-9) return null;\n  return {\n    x: Number(value.x) / length,\n    y: Number(value.y) / length,\n    z: Number(value.z) / length,\n    w: Number(value.w) / length,\n  };\n}\n\nfunction multiplyQuaternion(a, b) {\n  const left = normalizeQuaternion(a);\n  const right = normalizeQuaternion(b);\n  if (!left || !right) return null;\n  return normalizeQuaternion({\n    x: left.w * right.x + left.x * right.w + left.y * right.z - left.z * right.y,\n    y: left.w * right.y - left.x * right.z + left.y * right.w + left.z * right.x,\n    z: left.w * right.z + left.x * right.y - left.y * right.x + left.z * right.w,\n    w: left.w * right.w - left.x * right.x - left.y * right.y - left.z * right.z,\n  });\n}\n\n/** Convert the calibrated Three.js camera quaternion to OpenCV camera-to-ENU. */\nexport function cameraToEnuQuaternion(sensors) {\n  const hasLiveOrientation = sensors?.ready === true || sensors?.orient?.ready === true;\n  if (!sensors?.enabled || !hasLiveOrientation || !sensors.cameraQuat) return null;\n  const source = normalizeQuaternion(sensors.cameraQuat);\n  if (!source) return null;\n  const sourceQuaternion = new THREE.Quaternion(source.x, source.y, source.z, source.w);\n  const cameraToWorld = new THREE.Matrix4().makeRotationFromQuaternion(sourceQuaternion);\n  const opencvToThreeCamera = new THREE.Matrix4().set(\n    1, 0, 0, 0,\n    0, -1, 0, 0,\n    0, 0, -1, 0,\n    0, 0, 0, 1,\n  );\n  const threeWorldToEnu = new THREE.Matrix4().set(\n    1, 0, 0, 0,\n    0, 0, -1, 0,\n    0, 1, 0, 0,\n    0, 0, 0, 1,\n  );\n  const matrix = threeWorldToEnu.multiply(cameraToWorld).multiply(opencvToThreeCamera);\n  const quaternion = new THREE.Quaternion().setFromRotationMatrix(matrix).normalize();\n  return { x: quaternion.x, y: quaternion.y, z: quaternion.z, w: quaternion.w };\n}\n\nfunction orientationRecord(cameraToEnu, heading) {\n  if (!cameraToEnu) return null;\n  const headingConfidence = finite(heading?.confidence) ? clamp(heading.confidence, 0, 1) : null;\n  return {\n    cameraToEnu,\n    quaternionOrder: 'xyzw',\n    frame: 'camera_to_enu',\n    headingDeg: finite(heading?.deg) ? ((Number(heading.deg) % 360) + 360) % 360 : null,\n    headingAccuracyDeg: headingConfidence === null ? null : Math.max(1, (1 - headingConfidence) * 90),\n    orientationAccuracyDeg: headingConfidence === null\n      ? DEFAULT_ORIENTATION_ACCURACY_DEG\n      : Math.max(2, (1 - headingConfidence) * 120),\n    source: String(heading?.source || 'device-orientation').slice(0, 64),\n  };\n}\n\nfunction covarianceForOrientation(orientation) {\n  if (!orientation || !finite(orientation.orientationAccuracyDeg)) return null;\n  const radians = Math.max(0.001, Number(orientation.orientationAccuracyDeg) * Math.PI / 180);\n  return diagonalCovariance(radians * radians, radians * radians, radians * radians);\n}\n\nexport class BrowserGeoPoseProvider {\n  constructor({ gps, sensors, environment = globalThis } = {}) {\n    this.type = 'browser';\n    this.gps = gps;\n    this.sensors = sensors;\n    this.environment = environment;\n    this.wallClockOriginMs = Date.now() - (environment?.performance?.now?.() || 0);\n    this.monotonicOriginMs = environment?.performance?.now?.() || 0;\n  }\n\n  beginCapture({ wallClockOriginMs, monotonicOriginMs } = {}) {\n    if (finite(wallClockOriginMs)) this.wallClockOriginMs = Number(wallClockOriginMs);\n    if (finite(monotonicOriginMs)) this.monotonicOriginMs = Number(monotonicOriginMs);\n  }\n\n  sample({ sampleIndex = 0, monotonicMs, capturedAtMs } = {}) {\n    const nowMonotonicMs = finite(monotonicMs)\n      ? Number(monotonicMs)\n      : (this.environment?.performance?.now?.() || 0);\n    const nowWallMs = finite(capturedAtMs) ? Number(capturedAtMs) : Date.now();\n    const gps = this.gps?.getPosition?.() || null;\n    const heading = this.sensors?.getHeading?.() || null;\n    const cameraToEnu = cameraToEnuQuaternion(this.sensors);\n    const orientation = orientationRecord(cameraToEnu, heading);\n    const hasPosition = finite(gps?.latitude) && finite(gps?.longitude);\n    const horizontalAccuracyM = finite(gps?.accuracy) ? Math.max(0, Number(gps.accuracy)) : null;\n    const verticalAccuracyM = finite(gps?.altitudeAccuracy)\n      ? Math.max(0, Number(gps.altitudeAccuracy))\n      : null;\n    const sensorTimeMs = finite(gps?.timestamp) ? Number(gps.timestamp) : null;\n    const sensorAgeMs = sensorTimeMs === null ? null : Math.max(0, nowWallMs - sensorTimeMs);\n    const positionSigma = horizontalAccuracyM ?? 50;\n    const verticalSigma = verticalAccuracyM ?? Math.max(positionSigma * 1.5, 10);\n    const motion = this.sensors?.motion;\n    const angular = this.sensors?.angularVelocity;\n    return {\n      sampleIndex: Math.max(0, Math.floor(Number(sampleIndex) || 0)),\n      capturedAt: new Date(nowWallMs).toISOString(),\n      monotonicMs: nowMonotonicMs,\n      position: hasPosition ? {\n        latitude: Number(gps.latitude),\n        longitude: Number(gps.longitude),\n        altitudeM: finite(gps.altitude) ? Number(gps.altitude) : null,\n        altitudeDatum: 'wgs84_ellipsoid',\n        horizontalAccuracyM,\n        verticalAccuracyM,\n      } : null,\n      orientation,\n      motion: {\n        linearAccelerationMps2: motion?.ready && [motion.ax, motion.ay, motion.az].every(finite)\n          ? [Number(motion.ax), Number(motion.ay), Number(motion.az)]\n          : null,\n        angularVelocityRps: angular && [angular.x, angular.y, angular.z].every(finite)\n          ? [Number(angular.x), Number(angular.y), Number(angular.z)]\n          : null,\n      },\n      provider: {\n        type: 'browser',\n        provenance: {\n          source: 'browser-geolocation-device-sensors',\n          globalPosition: 'estimated-browser-gnss',\n          orientation: orientation?.source || 'unavailable',\n          screenOrientationDeg: screenOrientationDegrees(this.environment),\n          fixAgeMs: sensorAgeMs,\n          stale: sensorAgeMs !== null && sensorAgeMs > MAX_SENSOR_AGE_MS,\n          rtk: false,\n        },\n        positionCovariance: hasPosition\n          ? diagonalCovariance(positionSigma ** 2, positionSigma ** 2, verticalSigma ** 2)\n          : null,\n        orientationCovariance: covarianceForOrientation(orientation),\n        sensorTimeMs,\n        clockFit: {\n          offsetMs: -this.wallClockOriginMs,\n          driftPpm: 0,\n          uncertaintyMs: Math.max(CLOCK_UNCERTAINTY_FLOOR_MS, sensorAgeMs || 0),\n          sampleCount: sensorTimeMs === null ? 0 : 1,\n        },\n      },\n    };\n  }\n\n  previewPose() {\n    const gps = this.gps?.getPosition?.() || null;\n    const cameraToEnu = cameraToEnuQuaternion(this.sensors);\n    if (!finite(gps?.latitude) || !finite(gps?.longitude) || !cameraToEnu) return null;\n    return {\n      position: {\n        latitude: Number(gps.latitude),\n        longitude: Number(gps.longitude),\n        altitudeM: finite(gps.altitude) ? Number(gps.altitude) : null,\n        horizontalAccuracyM: finite(gps.accuracy) ? Number(gps.accuracy) : null,\n      },\n      cameraToEnu,\n    };\n  }\n}\n\n/**\n * Local XR provider. It deliberately emits no global position. Consumers may\n * relate orientation to a separately established capture origin, but the XR\n * tracking volume is never presented as GNSS or RTK evidence.\n */\nexport class WebXrGeoPoseProvider {\n  constructor({ getViewerPose, captureOriginId, originCameraToEnu = null } = {}) {\n    this.type = 'webxr';\n    this.getViewerPose = getViewerPose;\n    this.captureOriginId = String(captureOriginId || 'unresolved');\n    this.originCameraToEnu = normalizeQuaternion(originCameraToEnu);\n  }\n\n  beginCapture({ captureOriginId, originCameraToEnu } = {}) {\n    if (captureOriginId) this.captureOriginId = String(captureOriginId);\n    if (originCameraToEnu) this.originCameraToEnu = normalizeQuaternion(originCameraToEnu);\n  }\n\n  sample({ sampleIndex = 0, monotonicMs = performance.now(), capturedAtMs = Date.now() } = {}) {\n    const pose = this.getViewerPose?.() || null;\n    const localOrientation = normalizeQuaternion(pose?.orientation);\n    const cameraToEnu = this.originCameraToEnu && localOrientation\n      ? multiplyQuaternion(this.originCameraToEnu, localOrientation)\n      : null;\n    return {\n      sampleIndex: Math.max(0, Math.floor(Number(sampleIndex) || 0)),\n      capturedAt: new Date(capturedAtMs).toISOString(),\n      monotonicMs,\n      position: null,\n      orientation: cameraToEnu ? orientationRecord(cameraToEnu, { source: 'webxr-local-origin' }) : null,\n      motion: {},\n      provider: {\n        type: 'webxr',\n        provenance: {\n          source: 'webxr-local-tracking',\n          relationship: 'xr-local-to-capture-origin',\n          captureOriginId: this.captureOriginId,\n          globalPosition: false,\n          rtk: false,\n          localPositionM: pose?.position && [pose.position.x, pose.position.y, pose.position.z].every(finite)\n            ? [Number(pose.position.x), Number(pose.position.y), Number(pose.position.z)]\n            : null,\n          localOrientationXyzw: localOrientation\n            ? [localOrientation.x, localOrientation.y, localOrientation.z, localOrientation.w]\n            : null,\n        },\n        positionCovariance: null,\n        orientationCovariance: covarianceForOrientation(cameraToEnu\n          ? { orientationAccuracyDeg: Number(pose?.orientationAccuracyDeg) || 5 }\n          : null),\n        sensorTimeMs: finite(pose?.sensorTimeMs) ? Number(pose.sensorTimeMs) : null,\n        clockFit: {\n          offsetMs: finite(pose?.clockOffsetMs) ? Number(pose.clockOffsetMs) : 0,\n          driftPpm: finite(pose?.clockDriftPpm) ? Number(pose.clockDriftPpm) : 0,\n          uncertaintyMs: finite(pose?.clockUncertaintyMs)\n            ? Math.max(0, Number(pose.clockUncertaintyMs)) : 5,\n          sampleCount: finite(pose?.clockSampleCount)\n            ? Math.max(0, Math.floor(Number(pose.clockSampleCount))) : 0,\n        },\n      },\n    };\n  }\n}\n\nexport class ExternalRtkGeoPoseProvider {\n  constructor({ sourceId, getFix, approvedSourceIds = [] } = {}) {\n    this.type = 'external-rtk';\n    this.sourceId = String(sourceId || '');\n    this.getFix = getFix;\n    this.approvedSourceIds = new Set(approvedSourceIds.map(String));\n    if (!this.sourceId || !this.approvedSourceIds.has(this.sourceId)) {\n      throw new Error('External RTK source is not approved');\n    }\n  }\n\n  sample({ sampleIndex = 0, monotonicMs = performance.now(), capturedAtMs = Date.now() } = {}) {\n    const fix = this.getFix?.();\n    if (!fix || !finite(fix.latitude) || !finite(fix.longitude)) {\n      throw new Error('Approved external RTK source has no valid fix');\n    }\n    const fixState = ['fixed', 'float', 'degraded'].includes(fix.fixState)\n      ? fix.fixState\n      : 'degraded';\n    const cameraToEnu = normalizeQuaternion(fix.cameraToEnu);\n    const orientation = cameraToEnu\n      ? orientationRecord(cameraToEnu, {\n        deg: fix.headingDeg,\n        confidence: fix.headingConfidence,\n        source: 'external-rtk-attitude',\n      })\n      : null;\n    const positionCovariance = Array.isArray(fix.positionCovariance)\n      && [9, 36].includes(fix.positionCovariance.length)\n      && fix.positionCovariance.every(finite)\n      ? fix.positionCovariance.map(Number)\n      : null;\n    const horizontalAccuracyM = finite(fix.horizontalAccuracyM)\n      ? Math.max(0, Number(fix.horizontalAccuracyM))\n      : null;\n    const verticalAccuracyM = finite(fix.verticalAccuracyM)\n      ? Math.max(0, Number(fix.verticalAccuracyM))\n      : null;\n    return {\n      sampleIndex: Math.max(0, Math.floor(Number(sampleIndex) || 0)),\n      capturedAt: new Date(capturedAtMs).toISOString(),\n      monotonicMs,\n      position: {\n        latitude: Number(fix.latitude),\n        longitude: Number(fix.longitude),\n        altitudeM: finite(fix.altitudeM) ? Number(fix.altitudeM) : null,\n        altitudeDatum: ['wgs84_ellipsoid', 'egm96'].includes(fix.altitudeDatum)\n          ? fix.altitudeDatum : 'unknown',\n        horizontalAccuracyM,\n        verticalAccuracyM,\n      },\n      orientation,\n      motion: {},\n      provider: {\n        type: 'external-rtk',\n        provenance: {\n          source: this.sourceId,\n          correctionSource: String(fix.correctionSource || 'unknown'),\n          fixState,\n          rtk: fixState === 'fixed' || fixState === 'float',\n          globalPosition: true,\n          datum: fix.altitudeDatum || 'unknown',\n        },\n        positionCovariance: positionCovariance || (horizontalAccuracyM !== null\n          ? diagonalCovariance(\n            horizontalAccuracyM ** 2,\n            horizontalAccuracyM ** 2,\n            (verticalAccuracyM ?? horizontalAccuracyM * 1.5) ** 2,\n          )\n          : null),\n        orientationCovariance: Array.isArray(fix.orientationCovariance)\n          && [9, 36].includes(fix.orientationCovariance.length)\n          && fix.orientationCovariance.every(finite)\n          ? fix.orientationCovariance.map(Number)\n          : covarianceForOrientation(orientation),\n        sensorTimeMs: finite(fix.sensorTimeMs) ? Number(fix.sensorTimeMs) : null,\n        clockFit: {\n          offsetMs: finite(fix.clockOffsetMs) ? Number(fix.clockOffsetMs) : 0,\n          driftPpm: finite(fix.clockDriftPpm) ? Number(fix.clockDriftPpm) : 0,\n          uncertaintyMs: finite(fix.clockUncertaintyMs)\n            ? Math.max(0, Number(fix.clockUncertaintyMs)) : 25,\n          sampleCount: finite(fix.clockSampleCount)\n            ? Math.max(0, Math.floor(Number(fix.clockSampleCount))) : 0,\n        },\n      },\n    };\n  }\n}\n\nexport class DeterministicMockGeoPoseProvider {\n  constructor(samples = [], { fixtureId = 'synthetic-trajectory', loop = false } = {}) {\n    this.type = 'deterministic-mock';\n    this.samples = samples.map((sample) => structuredClone(sample));\n    this.fixtureId = String(fixtureId);\n    this.loop = loop === true;\n    this.cursor = 0;\n  }\n\n  beginCapture() {\n    this.cursor = 0;\n  }\n\n  sample({ sampleIndex = this.cursor, monotonicMs = performance.now(), capturedAtMs = Date.now() } = {}) {\n    if (!this.samples.length) throw new Error('Deterministic GeoPose fixture is empty');\n    const index = this.loop ? this.cursor % this.samples.length : Math.min(this.cursor, this.samples.length - 1);\n    const value = structuredClone(this.samples[index]);\n    this.cursor += 1;\n    return {\n      ...value,\n      sampleIndex,\n      monotonicMs,\n      capturedAt: new Date(capturedAtMs).toISOString(),\n      provider: {\n        type: 'deterministic-mock',\n        provenance: {\n          fixtureId: this.fixtureId,\n          source: 'deterministic-test-fixture',\n          synthetic: true,\n          rtk: false,\n        },\n        positionCovariance: value.provider?.positionCovariance || null,\n        orientationCovariance: value.provider?.orientationCovariance || null,\n        sensorTimeMs: value.provider?.sensorTimeMs ?? null,\n        clockFit: value.provider?.clockFit || {\n          offsetMs: 0,\n          driftPpm: 0,\n          uncertaintyMs: 0,\n          sampleCount: 1,\n        },\n      },\n    };\n  }\n}\n","import { cameraToEnuQuaternion } from '../camera/GeoPoseProvider.js';\n\nexport { cameraToEnuQuaternion } from '../camera/GeoPoseProvider.js';\n\nexport const FIELD_PROOF_SCHEMA = 'noclip.field-asset-proof/1.0';\nexport const FIELD_PROOF_MAX_GPS_AGE_MS = 20_000;\nexport const FIELD_PROOF_MAX_GPS_ACCURACY_M = 50;\nexport const FIELD_PROOF_MIN_PROXIMITY_M = 35;\nexport const FIELD_PROOF_MAX_PROXIMITY_M = 100;\n\nconst finite = (value) => (\n  value !== null\n  && value !== undefined\n  && value !== ''\n  && Number.isFinite(Number(value))\n);\nconst clamp = (value, min, max) => Math.max(min, Math.min(max, value));\nconst cleanText = (value) => String(value ?? '').replace(/\\s+/g, ' ').trim();\n\nexport function normalizeFieldContributor(input = null) {\n  const contributor = input && typeof input === 'object' ? input : {};\n  const displayName = cleanText(\n    contributor.displayName\n    || contributor.name\n    || contributor.handle\n    || contributor.username\n    || 'Pending account attribution',\n  );\n  const handle = cleanText(contributor.handle || contributor.username || '');\n  const id = cleanText(\n    contributor.id\n    || contributor.userId\n    || contributor.user_id\n    || contributor.uuid\n    || '',\n  );\n  return {\n    id: id || null,\n    displayName,\n    handle: handle || null,\n  };\n}\n\nexport function geodesicDistanceMeters(a, b) {\n  if (!a || !b || !finite(a.latitude ?? a.lat) || !finite(a.longitude ?? a.lon)\n    || !finite(b.latitude ?? b.lat) || !finite(b.longitude ?? b.lon)) return null;\n  const lat1 = Number(a.latitude ?? a.lat) * Math.PI / 180;\n  const lat2 = Number(b.latitude ?? b.lat) * Math.PI / 180;\n  const dLat = lat2 - lat1;\n  const dLon = (Number(b.longitude ?? b.lon) - Number(a.longitude ?? a.lon)) * Math.PI / 180;\n  const h = Math.sin(dLat / 2) ** 2\n    + Math.cos(lat1) * Math.cos(lat2) * Math.sin(dLon / 2) ** 2;\n  return 2 * 6_378_137 * Math.asin(Math.min(1, Math.sqrt(h)));\n}\n\nexport function isMobileFieldDevice(environment = globalThis) {\n  const navigatorObject = environment?.navigator;\n  const windowObject = environment?.window || environment;\n  if (!navigatorObject || !windowObject) return false;\n  if (navigatorObject.userAgentData?.mobile === true) return true;\n  const uaMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i\n    .test(navigatorObject.userAgent || '');\n  const touch = Number(navigatorObject.maxTouchPoints || 0) > 0\n    || 'ontouchstart' in windowObject;\n  const coarsePointer = typeof windowObject.matchMedia === 'function'\n    && windowObject.matchMedia('(pointer: coarse)').matches;\n  return uaMobile || (touch && coarsePointer);\n}\n\nexport function buildFieldPose({\n  gps,\n  sensors,\n  capturedAtMs = Date.now(),\n  monotonicMs = globalThis.performance?.now?.() ?? 0,\n} = {}) {\n  const position = gps?.getPosition?.() || gps || {};\n  const heading = sensors?.getHeading?.() || {};\n  const cameraToEnu = cameraToEnuQuaternion(sensors);\n  const latitude = finite(position.latitude) ? Number(position.latitude) : NaN;\n  const longitude = finite(position.longitude) ? Number(position.longitude) : NaN;\n  const positionTimestampMs = finite(position.timestamp) ? Number(position.timestamp) : null;\n  return {\n    capturedAt: new Date(capturedAtMs).toISOString(),\n    capturedAtMs,\n    monotonicMs,\n    position: finite(latitude) && finite(longitude) ? {\n      latitude,\n      longitude,\n      altitudeM: finite(position.altitude) ? Number(position.altitude) : null,\n      altitudeDatum: 'wgs84_ellipsoid',\n      horizontalAccuracyM: finite(position.accuracy) ? Number(position.accuracy) : null,\n      verticalAccuracyM: finite(position.altitudeAccuracy) ? Number(position.altitudeAccuracy) : null,\n      measuredAtMs: positionTimestampMs,\n    } : null,\n    orientation: cameraToEnu ? {\n      cameraToEnu,\n      quaternionOrder: 'xyzw',\n      frame: 'camera_to_enu',\n      yawRad: finite(sensors?.yaw) ? Number(sensors.yaw) : null,\n      pitchRad: finite(sensors?.pitch) ? Number(sensors.pitch) : null,\n      rollRad: finite(sensors?.roll) ? Number(sensors.roll) : null,\n      headingDeg: finite(heading.deg)\n        ? ((Number(heading.deg) % 360) + 360) % 360\n        : null,\n      headingConfidence: finite(heading.confidence) ? clamp(Number(heading.confidence), 0, 1) : null,\n      source: cleanText(heading.source || 'device-orientation'),\n    } : null,\n    coordinateSystem: {\n      geodetic: 'WGS84',\n      geodeticCrs: 'EPSG:4979',\n      altitudeDatum: 'wgs84_ellipsoid',\n      localFrame: 'ENU',\n      cameraAxes: 'opencv_x_right_y_down_z_forward',\n      quaternionOrder: 'xyzw',\n      handedness: 'right',\n      units: 'meters',\n    },\n  };\n}\n\nexport function evaluateFieldProof({\n  pose,\n  target = null,\n  mobile = isMobileFieldDevice(),\n  nowMs = Date.now(),\n} = {}) {\n  const reasons = [];\n  if (!mobile) reasons.push('A phone with touch and device sensors is required.');\n  if (!pose?.position) reasons.push('A live GPS fix is required.');\n  if (!pose?.orientation) reasons.push('Device orientation permission and a live orientation sample are required.');\n\n  const rawAccuracyM = pose?.position?.horizontalAccuracyM;\n  const accuracyM = finite(rawAccuracyM) ? Number(rawAccuracyM) : NaN;\n  if (pose?.position && (!finite(accuracyM) || accuracyM > FIELD_PROOF_MAX_GPS_ACCURACY_M)) {\n    reasons.push(`GPS accuracy must be ${FIELD_PROOF_MAX_GPS_ACCURACY_M} m or better.`);\n  }\n  const rawMeasuredAtMs = pose?.position?.measuredAtMs;\n  const measuredAtMs = finite(rawMeasuredAtMs) ? Number(rawMeasuredAtMs) : NaN;\n  const gpsAgeMs = finite(measuredAtMs) ? Math.max(0, nowMs - measuredAtMs) : Infinity;\n  if (pose?.position && gpsAgeMs > FIELD_PROOF_MAX_GPS_AGE_MS) {\n    reasons.push('The GPS fix is stale; acquire a new position.');\n  }\n\n  const targetPosition = target && finite(target.lat) && finite(target.lon)\n    ? { latitude: Number(target.lat), longitude: Number(target.lon) }\n    : null;\n  const distanceToTargetM = targetPosition && pose?.position\n    ? geodesicDistanceMeters(pose.position, targetPosition)\n    : 0;\n  const allowedDistanceM = clamp(\n    Math.max(FIELD_PROOF_MIN_PROXIMITY_M, (finite(accuracyM) ? accuracyM : 0) * 2),\n    FIELD_PROOF_MIN_PROXIMITY_M,\n    FIELD_PROOF_MAX_PROXIMITY_M,\n  );\n  if (targetPosition && finite(distanceToTargetM) && distanceToTargetM > allowedDistanceM) {\n    reasons.push(`Move within ${Math.round(allowedDistanceM)} m of the asset (currently ${Math.round(distanceToTargetM)} m away).`);\n  }\n\n  return {\n    valid: reasons.length === 0,\n    reasons,\n    gpsAgeMs,\n    accuracyM: finite(accuracyM) ? accuracyM : null,\n    distanceToTargetM: finite(distanceToTargetM) ? distanceToTargetM : null,\n    allowedDistanceM,\n  };\n}\n\nexport function buildFieldAssetProof({\n  asset,\n  pose,\n  validation,\n  note = '',\n  capture = null,\n  mode = 'create',\n  contributor = null,\n} = {}) {\n  const hasPhoto = !!capture?.blob;\n  const normalizedNote = cleanText(note);\n  return {\n    schema: FIELD_PROOF_SCHEMA,\n    assetId: asset.id,\n    mode,\n    visibility: 'public',\n    contributor: normalizeFieldContributor(contributor),\n    asset: {\n      id: asset.id,\n      type: asset.type || 'place',\n      name: asset.name || 'Field asset',\n      address: asset.address || '',\n      target: {\n        latitude: Number(asset.lat),\n        longitude: Number(asset.lon),\n      },\n      area: Number.isFinite(Number(asset.metadata?.coverageRadiusM))\n        ? {\n          shape: 'circle',\n          radiusM: clamp(Number(asset.metadata.coverageRadiusM), 5, 500),\n        }\n        : null,\n    },\n    observation: {\n      ...pose,\n      proximity: {\n        distanceToAssetM: validation.distanceToTargetM,\n        allowedDistanceM: validation.allowedDistanceM,\n        horizontalAccuracyM: validation.accuracyM,\n        gpsAgeMs: validation.gpsAgeMs,\n      },\n    },\n    contribution: {\n      kind: hasPhoto && normalizedNote ? 'photo-and-text' : (hasPhoto ? 'photo' : 'text'),\n      text: normalizedNote,\n    },\n    media: hasPhoto ? {\n      kind: 'frame',\n      fileName: capture.fileName || 'field-proof.jpg',\n      mimeType: capture.blob.type || 'image/jpeg',\n      width: Number(capture.width) || null,\n      height: Number(capture.height) || null,\n      intrinsics: capture.intrinsics || null,\n      imageTransform: capture.imageTransform || { mirrored: false, rotationDeg: 0 },\n    } : null,\n  };\n}\n","import { getAuthService } from '../auth/AuthService.js';\nimport { getBackendApiBase } from '../shared/backend.js';\nimport { getNoclipGovernanceClient } from '../shared/NoclipGovernanceClient.js';\nimport { normalizeFieldContributor } from './FieldAssetProof.js';\n\nconst cleanText = (value) => String(value ?? '').replace(/\\s+/g, ' ').trim();\nconst finiteNumber = (value) => {\n  if (value === null || value === undefined || value === '') return null;\n  const number = Number(value);\n  return Number.isFinite(number) ? number : null;\n};\n\nconst feedRecords = (payload) => {\n  if (Array.isArray(payload)) return payload;\n  if (!payload || typeof payload !== 'object') return [];\n  const direct = payload.assets || payload.contributions || payload.items || payload.results;\n  if (Array.isArray(direct)) return direct;\n  if (payload.data && payload.data !== payload) return feedRecords(payload.data);\n  return [];\n};\n\nconst normalizeEvidence = (record, proof) => {\n  const observation = proof?.observation || record?.observation || {};\n  const contribution = proof?.contribution || record?.contribution || {};\n  const remoteMedia = record?.media || record?.evidence?.media || null;\n  return {\n    id: record?.id || record?.evidenceId || record?.contributionId || null,\n    remoteId: record?.id || record?.evidenceId || record?.contributionId || null,\n    capturedAt: observation.capturedAt || record?.capturedAt || record?.createdAt || null,\n    contributionKind: contribution.kind || (remoteMedia ? 'photo' : 'text'),\n    text: cleanText(contribution.text || record?.text || record?.note || ''),\n    position: observation.position || record?.position || null,\n    orientation: observation.orientation || record?.orientation || null,\n    proximity: observation.proximity || record?.proximity || null,\n    media: proof?.media || remoteMedia || null,\n    mediaUrl: cleanText(\n      record?.mediaUrl\n      || record?.url\n      || record?.evidence?.mediaUrl\n      || remoteMedia?.url\n      || '',\n    ) || null,\n    contributor: normalizeFieldContributor(\n      record?.contributor\n      || record?.author\n      || proof?.contributor\n      || null,\n    ),\n    syncStatus: 'synced',\n  };\n};\n\n/**\n * Convert the public backend feed into the same tag-shaped records consumed by\n * FieldAssetLayer, without inserting other users' records into local TagStore.\n */\nexport function normalizePublicFieldAssetFeed(payload) {\n  const grouped = new Map();\n  for (const record of feedRecords(payload)) {\n    if (!record) continue;\n    const proof = record.proof || record.fieldProof || record.evidence?.proof || null;\n    if (record.visibility === 'private' || proof?.visibility === 'private') continue;\n    const proofAsset = proof?.asset || {};\n    const target = proofAsset.target || record.target || record.asset?.target || {};\n    const lat = finiteNumber(\n      record.lat\n      ?? record.latitude\n      ?? record.asset?.lat\n      ?? record.asset?.latitude\n      ?? target.latitude,\n    );\n    const lon = finiteNumber(\n      record.lon\n      ?? record.longitude\n      ?? record.asset?.lon\n      ?? record.asset?.longitude\n      ?? target.longitude,\n    );\n    if (!Number.isFinite(lat) || !Number.isFinite(lon)) continue;\n\n    const id = cleanText(\n      record.assetId\n      || record.asset?.id\n      || proof?.assetId\n      || proofAsset.id\n      || record.id\n      || '',\n    );\n    if (!id) continue;\n    const evidence = Array.isArray(record.meta?.evidence)\n      ? record.meta.evidence.map((item) => ({\n        ...item,\n        contributor: normalizeFieldContributor(item?.contributor || item?.author || null),\n        syncStatus: 'synced',\n      }))\n      : [normalizeEvidence(record, proof)];\n    const existing = grouped.get(id);\n    const createdBy = existing?.meta?.createdBy\n      || record.meta?.createdBy\n      || evidence[0]?.contributor\n      || normalizeFieldContributor(null);\n    const areaRadiusM = finiteNumber(\n      record.meta?.coverageRadiusM\n      ?? record.asset?.coverageRadiusM\n      ?? proofAsset.area?.radiusM,\n    );\n    const metadata = {\n      ...(existing?.meta || {}),\n      ...(record.meta || {}),\n      fieldAsset: true,\n      fieldProofSchema: proof?.schema || record.meta?.fieldProofSchema || null,\n      entityType: cleanText(\n        proofAsset.type\n        || record.asset?.type\n        || record.entityType\n        || record.meta?.entityType\n        || 'note',\n      ),\n      sourceAssetId: cleanText(\n        record.meta?.sourceAssetId\n        || record.sourceAssetId\n        || proofAsset.id\n        || id,\n      ),\n      createdBy,\n      lastContributor: evidence.at(-1)?.contributor || createdBy,\n      evidence: [...(existing?.meta?.evidence || []), ...evidence].slice(-50),\n      evidenceCount: Math.max(\n        Number(record.evidenceCount || record.meta?.evidenceCount || 0),\n        (existing?.meta?.evidence?.length || 0) + evidence.length,\n      ),\n      lastVerifiedAt: evidence.at(-1)?.capturedAt || existing?.meta?.lastVerifiedAt || null,\n      remotePublic: true,\n    };\n    if (Number.isFinite(areaRadiusM)) metadata.coverageRadiusM = Math.max(5, Math.min(500, areaRadiusM));\n    grouped.set(id, {\n      id,\n      lat,\n      lon,\n      name: cleanText(proofAsset.name || record.asset?.name || record.name || 'Community note'),\n      address: cleanText(proofAsset.address || record.asset?.address || record.address || ''),\n      category: cleanText(record.category || record.asset?.category || 'poi'),\n      visibility: 'public',\n      createdAt: record.createdAt || evidence[0]?.capturedAt || null,\n      updatedAt: record.updatedAt || evidence.at(-1)?.capturedAt || null,\n      meta: metadata,\n    });\n  }\n  return [...grouped.values()];\n}\n\nexport class FieldAssetApiService {\n  constructor({\n    authService = getAuthService(),\n    apiBase = getBackendApiBase(),\n    fetchImpl = null,\n  } = {}) {\n    this.authService = authService;\n    this.apiBase = apiBase;\n    this.fetchImpl = fetchImpl || getNoclipGovernanceClient().request.bind(getNoclipGovernanceClient());\n  }\n\n  canPublish() {\n    return this.authService?.getState?.()?.isAuthenticated === true;\n  }\n\n  async publishContribution({ proof, blob = null, fileName = 'field-proof.jpg' } = {}) {\n    if (!this.canPublish()) throw new Error('Sign in to publish field assets.');\n    const form = new FormData();\n    form.append('proof', JSON.stringify(proof));\n    if (blob) form.append('file', blob, fileName);\n    const response = await this.authService.authenticatedFetch(\n      `${this.apiBase}/field-assets/contributions`,\n      {\n        method: 'POST',\n        body: form,\n        includeContentType: false,\n      },\n    );\n    const payload = await response.json().catch(() => ({}));\n    if (!response.ok) {\n      throw new Error(payload.message || payload.error || `Field asset publication failed (${response.status}).`);\n    }\n    return payload.contribution || payload.evidence || payload;\n  }\n\n  async fetchPublicContributions({\n    lat,\n    lon,\n    radiusM = 180_000,\n    limit = 500,\n    signal = null,\n  } = {}) {\n    if (!this.fetchImpl) return [];\n    const query = new URLSearchParams({\n      visibility: 'public',\n      limit: String(Math.max(1, Math.min(1000, Math.round(limit)))),\n    });\n    if (Number.isFinite(Number(lat)) && Number.isFinite(Number(lon))) {\n      query.set('lat', String(Number(lat)));\n      query.set('lon', String(Number(lon)));\n      query.set('radiusM', String(Math.max(100, Math.min(500_000, Math.round(radiusM)))));\n    }\n    const response = await this.fetchImpl(\n      `${this.apiBase}/field-assets/contributions?${query}`,\n      { method: 'GET', governanceLane: 'scene', ...(signal ? { signal } : {}) },\n    );\n    if (response.status === 404) return [];\n    const payload = await response.json().catch(() => ({}));\n    if (!response.ok) {\n      throw new Error(payload.message || payload.error || `Public field asset feed failed (${response.status}).`);\n    }\n    return normalizePublicFieldAssetFeed(payload);\n  }\n}\n\nlet _instance = null;\n\nexport function getFieldAssetApiService() {\n  if (!_instance) _instance = new FieldAssetApiService();\n  return _instance;\n}\n","import * as THREE from 'three';\nimport {\n  ellipsoidRadiusForLocalDir,\n  latLonToLocalDir,\n} from '../../modules/geometry-utils.js';\nimport { getLabelSystem } from '../labels/LabelSystem.js';\nimport { terrainSurfaceChangesAffectLatLon } from '../scene/TerrainSurfaceChange.js';\nimport { getTagStore } from '../tags/TagStore.js';\nimport { getFieldAssetApiService } from './FieldAssetApiService.js';\n\nconst _tmpWorldDir = new THREE.Vector3();\nconst _tmpWorldQuat = new THREE.Quaternion();\nconst _tmpPosition = new THREE.Vector3();\nconst PUBLIC_REFRESH_MS = 60_000;\nconst PUBLIC_REFRESH_MOVE_DEG = 0.005;\nconst PUBLIC_RADIUS_M = 180_000;\n\nconst contributorLabel = (contributor) => (\n  String(\n    contributor?.displayName\n    || contributor?.handle\n    || 'Pending account attribution',\n  ).trim()\n);\n\nconst shortDate = (value) => {\n  const date = new Date(value);\n  return Number.isFinite(date.getTime()) ? date.toLocaleDateString() : '';\n};\n\nconst mergeFieldAssetRecords = (remote, local) => {\n  if (!remote) return local;\n  const evidence = [];\n  const seen = new Set();\n  for (const item of [...(remote.meta?.evidence || []), ...(local.meta?.evidence || [])]) {\n    const key = String(\n      item?.remoteId\n      || item?.id\n      || `${item?.capturedAt || ''}:${item?.position?.latitude || ''}:${item?.position?.longitude || ''}`,\n    );\n    if (key && seen.has(key)) continue;\n    if (key) seen.add(key);\n    evidence.push(item);\n  }\n  return {\n    ...remote,\n    ...local,\n    visibility: 'public',\n    createdAt: remote.createdAt || local.createdAt,\n    meta: {\n      ...(remote.meta || {}),\n      ...(local.meta || {}),\n      fieldAsset: true,\n      createdBy: remote.meta?.createdBy || local.meta?.createdBy || null,\n      evidence: evidence.slice(-50),\n      evidenceCount: Math.max(\n        evidence.length,\n        Number(remote.meta?.evidenceCount || 0),\n        Number(local.meta?.evidenceCount || 0),\n      ),\n    },\n  };\n};\n\nexport class FieldAssetLayer {\n  constructor({\n    parentGroup,\n    surfaceController,\n    tagStore = getTagStore(),\n    api = getFieldAssetApiService(),\n  } = {}) {\n    this.parentGroup = parentGroup || null;\n    this.surfaceController = surfaceController || null;\n    this.tagStore = tagStore;\n    this.api = api;\n    this._entries = new Map();\n    this._remoteTags = new Map();\n    this._publicRecords = [];\n    this._unsubscribe = null;\n    this._geoContext = null;\n    this._lastPublicContext = null;\n    this._lastPublicRefreshAt = 0;\n    this._publicRefreshTimer = null;\n    this._publicRefreshSequence = 0;\n    this._publicAbortController = null;\n  }\n\n  start() {\n    if (!this._unsubscribe) {\n      this._unsubscribe = this.tagStore.onChange(() => this.sync());\n    }\n    this.sync();\n    this._schedulePublicRefresh();\n    return this;\n  }\n\n  sync() {\n    const activeIds = new Set();\n    const tags = new Map(this._remoteTags);\n    for (const tag of this.tagStore.list()) {\n      if (tag?.meta?.fieldAsset === true) {\n        tags.set(tag.id, mergeFieldAssetRecords(tags.get(tag.id), tag));\n      }\n    }\n    for (const tag of tags.values()) {\n      if (tag?.meta?.fieldAsset !== true) continue;\n      if ((tag.visibility || tag.meta?.visibility || 'public') !== 'public') continue;\n      if (!Number.isFinite(tag.lat) || !Number.isFinite(tag.lon)) continue;\n      activeIds.add(tag.id);\n      let entry = this._entries.get(tag.id);\n      if (!entry) {\n        entry = {\n          id: tag.id,\n          dir: latLonToLocalDir(tag.lat, tag.lon).normalize(),\n          position: new THREE.Vector3(),\n          stableRadius: null,\n          labelHandle: null,\n          tag: null,\n        };\n        this._entries.set(tag.id, entry);\n      } else if (entry.tag?.lat !== tag.lat || entry.tag?.lon !== tag.lon) {\n        entry.dir.copy(latLonToLocalDir(tag.lat, tag.lon)).normalize();\n        entry.stableRadius = null;\n      }\n      entry.tag = tag;\n      this._positionEntry(entry);\n      this._createOrUpdateLabel(entry);\n    }\n    for (const [id, entry] of this._entries) {\n      if (activeIds.has(id)) continue;\n      this._disposeEntry(entry);\n      this._entries.delete(id);\n    }\n    this._publicRecords = [...tags.values()].filter((tag) => (\n      tag?.meta?.fieldAsset === true\n      && (tag.visibility || tag.meta?.visibility || 'public') === 'public'\n      && Number.isFinite(tag.lat)\n      && Number.isFinite(tag.lon)\n    ));\n    if (typeof document !== 'undefined' && typeof CustomEvent !== 'undefined') {\n      document.dispatchEvent(new CustomEvent('noclip:field-assets:public', {\n        detail: { assets: this.getPublicRecords() },\n      }));\n    }\n  }\n\n  getPublicRecords() {\n    return [...this._publicRecords];\n  }\n\n  setGeoContext(context = {}) {\n    const lat = Number(context.lat);\n    const lon = Number(context.lon);\n    if (!Number.isFinite(lat) || !Number.isFinite(lon)) return;\n    this._geoContext = { lat, lon };\n    const moved = !this._lastPublicContext\n      || Math.abs(this._lastPublicContext.lat - lat) >= PUBLIC_REFRESH_MOVE_DEG\n      || Math.abs(this._lastPublicContext.lon - lon) >= PUBLIC_REFRESH_MOVE_DEG;\n    const stale = Date.now() - this._lastPublicRefreshAt >= PUBLIC_REFRESH_MS;\n    if (moved || stale) void this.refreshPublicFeed();\n  }\n\n  async refreshPublicFeed({ force = false } = {}) {\n    if (!this._geoContext || !this.api?.fetchPublicContributions) return [];\n    const now = Date.now();\n    if (!force\n      && this._lastPublicContext\n      && Math.abs(this._lastPublicContext.lat - this._geoContext.lat) < PUBLIC_REFRESH_MOVE_DEG\n      && Math.abs(this._lastPublicContext.lon - this._geoContext.lon) < PUBLIC_REFRESH_MOVE_DEG\n      && now - this._lastPublicRefreshAt < PUBLIC_REFRESH_MS) {\n      return [...this._remoteTags.values()];\n    }\n    const sequence = ++this._publicRefreshSequence;\n    this._publicAbortController?.abort?.();\n    const controller = typeof AbortController !== 'undefined' ? new AbortController() : null;\n    this._publicAbortController = controller;\n    const context = { ...this._geoContext };\n    try {\n      const records = await this.api.fetchPublicContributions({\n        ...context,\n        radiusM: PUBLIC_RADIUS_M,\n        signal: controller?.signal || null,\n      });\n      if (sequence !== this._publicRefreshSequence) return [];\n      this._remoteTags = new Map(\n        records\n          .filter((tag) => tag?.id && tag?.visibility !== 'private')\n          .map((tag) => [tag.id, tag]),\n      );\n      this._lastPublicContext = context;\n      this._lastPublicRefreshAt = Date.now();\n      this.sync();\n      return records;\n    } catch (error) {\n      if (error?.name !== 'AbortError') {\n        // Local contributions remain visible when the public feed is offline.\n      }\n      return [];\n    } finally {\n      if (sequence === this._publicRefreshSequence) this._publicAbortController = null;\n      this._schedulePublicRefresh();\n    }\n  }\n\n  _schedulePublicRefresh() {\n    if (this._publicRefreshTimer) clearTimeout(this._publicRefreshTimer);\n    this._publicRefreshTimer = setTimeout(() => {\n      this._publicRefreshTimer = null;\n      void this.refreshPublicFeed({ force: true });\n    }, PUBLIC_REFRESH_MS);\n    this._publicRefreshTimer?.unref?.();\n  }\n\n  _sampleSurfaceRadius(entry) {\n    const ellipsoidRadius = ellipsoidRadiusForLocalDir(entry.dir);\n    const sampler = this.surfaceController?.sampleTerrainRadiusForDir;\n    if (typeof sampler !== 'function') return { radius: ellipsoidRadius, authoritative: false };\n    _tmpWorldDir.copy(entry.dir);\n    if (this.parentGroup?.getWorldQuaternion) {\n      this.parentGroup.getWorldQuaternion(_tmpWorldQuat);\n      _tmpWorldDir.applyQuaternion(_tmpWorldQuat).normalize();\n    }\n    const requireFreshPhotoHit = !!this.surfaceController?.photoTileGroup;\n    const sampled = sampler.call(this.surfaceController, _tmpWorldDir, {\n      mutateCache: false,\n      requireFreshPhotoHit,\n      allowTriTreeFallback: !requireFreshPhotoHit,\n      skipWorldMatrixUpdate: true,\n    });\n    return Number.isFinite(sampled)\n      ? { radius: sampled, authoritative: true }\n      : { radius: ellipsoidRadius, authoritative: false };\n  }\n\n  _positionEntry(entry) {\n    const sample = this._sampleSurfaceRadius(entry);\n    if (sample.authoritative || !Number.isFinite(entry.stableRadius)) {\n      entry.stableRadius = sample.radius;\n    }\n    entry.position.copy(entry.dir).multiplyScalar(entry.stableRadius + 10);\n    if (entry.labelHandle) {\n      getLabelSystem().updatePosition?.(entry.labelHandle, entry.position);\n    }\n  }\n\n  _metadata(tag) {\n    return {\n      ...(tag.meta || {}),\n      id: tag.id,\n      entityType: tag.meta?.entityType || 'place',\n      typeLabel: 'Community field asset',\n      name: tag.name || 'Field asset',\n      address: tag.address || '',\n      lat: tag.lat,\n      lon: tag.lon,\n      category: tag.category || 'poi',\n      visibility: 'public',\n      evidenceCount: Number(tag.meta?.evidenceCount || tag.meta?.evidence?.length || 0),\n      createdAt: tag.createdAt || tag.meta?.createdAt || '',\n      updatedAt: tag.updatedAt || tag.meta?.updatedAt || '',\n      createdBy: tag.meta?.createdBy || null,\n      lastContributor: tag.meta?.lastContributor || null,\n      source: 'NOCLIP field proof',\n    };\n  }\n\n  _createOrUpdateLabel(entry) {\n    const tag = entry.tag;\n    const labelSystem = getLabelSystem();\n    const evidence = Array.isArray(tag.meta?.evidence) ? tag.meta.evidence : [];\n    const createdBy = tag.meta?.createdBy || evidence[0]?.contributor || null;\n    const createdAt = tag.createdAt || evidence[0]?.capturedAt || '';\n    const subText = [\n      `by ${contributorLabel(createdBy)}`,\n      shortDate(createdAt),\n      `${Number(tag.meta?.evidenceCount || tag.meta?.evidence?.length || 0)} field proof${Number(tag.meta?.evidenceCount || tag.meta?.evidence?.length || 0) === 1 ? '' : 's'}`,\n    ].filter(Boolean).join(' · ');\n    if (entry.labelHandle) {\n      labelSystem.updateText?.(entry.labelHandle, tag.name || 'Field asset', subText);\n      labelSystem.updateMetadata?.(entry.labelHandle, this._metadata(tag));\n      return;\n    }\n    entry.labelHandle = labelSystem.createLabel(tag.name || 'Field asset', {\n      position: entry.position,\n      type: 'community-note',\n      objectRadius: Math.max(8, Math.min(40, Number(tag.meta?.coverageRadiusM || 0) * 0.15)),\n      subText,\n      metadata: this._metadata(tag),\n      labelPriority: 22,\n      maxDistance: 180_000,\n    });\n    if (entry.labelHandle?.group && this.parentGroup) {\n      this.parentGroup.add(entry.labelHandle.group);\n    }\n  }\n\n  refreshTerrainAnchors(changes) {\n    if (!Array.isArray(changes) || changes.length === 0) return 0;\n    let updated = 0;\n    for (const entry of this._entries.values()) {\n      const tag = entry.tag;\n      if (!terrainSurfaceChangesAffectLatLon(changes, tag?.lat, tag?.lon)) continue;\n      this._positionEntry(entry);\n      updated += 1;\n    }\n    return updated;\n  }\n\n  _disposeEntry(entry) {\n    if (!entry?.labelHandle) return;\n    entry.labelHandle.group?.parent?.remove?.(entry.labelHandle.group);\n    entry.labelHandle.dispose?.();\n    entry.labelHandle = null;\n  }\n\n  dispose() {\n    this._unsubscribe?.();\n    this._unsubscribe = null;\n    if (this._publicRefreshTimer) clearTimeout(this._publicRefreshTimer);\n    this._publicRefreshTimer = null;\n    this._publicRefreshSequence += 1;\n    this._publicAbortController?.abort?.();\n    this._publicAbortController = null;\n    for (const entry of this._entries.values()) this._disposeEntry(entry);\n    this._entries.clear();\n    this._remoteTags.clear();\n    this._publicRecords.length = 0;\n  }\n}\n","import { getAuthService } from '../auth/AuthService.js';\nimport { getBackendApiBase } from '../shared/backend.js';\nimport {\n  ACCOUNT_NOTE_ACTIVATION_RADIUS_DEFAULT_M,\n  ACCOUNT_NOTE_ACTIVATION_RADIUS_MAX_M,\n  ACCOUNT_NOTE_ACTIVATION_RADIUS_MIN_M,\n  normalizeAccountNoteActivationRadius,\n} from './AccountNoteActivation.js';\n\nconst API_BASE = getBackendApiBase();\nconst clean = (value, max = 10_000) => String(value ?? '').trim().slice(0, max);\nconst publicAttachmentUrl = (value) => {\n  const path = clean(value, 1000);\n  if (!path || /^https?:\\/\\//i.test(path)) return path;\n  const base = API_BASE.startsWith('/') && globalThis.location?.origin\n    ? `${globalThis.location.origin}${API_BASE}`\n    : API_BASE;\n  return `${String(base || '').replace(/\\/+$/, '')}/${path.replace(/^\\/+/, '')}`;\n};\n\nexport class AccountNoteApiError extends Error {\n  constructor(message, { status = 0, code = null, payload = null } = {}) {\n    super(message);\n    this.name = 'AccountNoteApiError';\n    this.status = status;\n    this.code = code;\n    this.payload = payload;\n  }\n}\n\nexport function normalizeAccountNote(record = {}) {\n  const lat = Number(record.lat);\n  const lon = Number(record.lon);\n  if (!record.noteId || !Number.isFinite(lat) || !Number.isFinite(lon)) return null;\n  return {\n    noteId: String(record.noteId),\n    title: clean(record.title, 120) || 'Note',\n    body: clean(record.body),\n    lat,\n    lon,\n    activationRadiusM: normalizeAccountNoteActivationRadius(record.activationRadiusM),\n    target: record.target && typeof record.target === 'object' ? record.target : {},\n    overlayId: record.overlayId || null,\n    layerId: record.layerId || null,\n    itemId: record.itemId || null,\n    attachments: (Array.isArray(record.attachments) ? record.attachments : []).map((attachment) => ({\n      attachmentId: String(attachment.attachmentId || ''),\n      fileName: clean(attachment.fileName, 240) || 'Image',\n      mimeType: clean(attachment.mimeType, 100),\n      bytes: Number(attachment.bytes || 0),\n      sortOrder: Number(attachment.sortOrder || 0),\n      url: publicAttachmentUrl(attachment.url),\n      createdAt: attachment.createdAt || '',\n    })).filter((attachment) => attachment.attachmentId),\n    visibility: record.visibility === 'public' ? 'public' : 'private',\n    owner: record.owner === true,\n    createdAt: record.createdAt || '',\n    updatedAt: record.updatedAt || '',\n  };\n}\n\nfunction mutationPayload(input = {}) {\n  const activationRadiusM = input.activationRadiusM == null || input.activationRadiusM === ''\n    ? ACCOUNT_NOTE_ACTIVATION_RADIUS_DEFAULT_M\n    : Number(input.activationRadiusM);\n  if (!Number.isFinite(activationRadiusM)\n    || activationRadiusM < ACCOUNT_NOTE_ACTIVATION_RADIUS_MIN_M\n    || activationRadiusM > ACCOUNT_NOTE_ACTIVATION_RADIUS_MAX_M) {\n    throw new AccountNoteApiError(\n      `Activation distance must be between ${ACCOUNT_NOTE_ACTIVATION_RADIUS_MIN_M} and ${ACCOUNT_NOTE_ACTIVATION_RADIUS_MAX_M} metres.`,\n      { code: 'INVALID_ACTIVATION_RADIUS' },\n    );\n  }\n  return {\n    title: clean(input.title, 120),\n    body: clean(input.body),\n    lat: Number(input.lat),\n    lon: Number(input.lon),\n    activationRadiusM,\n    target: input.target && typeof input.target === 'object' ? input.target : {},\n    visibility: input.visibility === 'public' ? 'public' : 'private',\n    removeAttachmentIds: Array.isArray(input.removeAttachmentIds)\n      ? input.removeAttachmentIds.map(String)\n      : [],\n  };\n}\n\nexport class AccountNoteApiService {\n  constructor({ authService = getAuthService(), fetchImpl = globalThis.fetch?.bind(globalThis) } = {}) {\n    this.authService = authService;\n    this.fetchImpl = fetchImpl;\n  }\n\n  async _response(response) {\n    const payload = await response.json().catch(() => ({}));\n    if (!response.ok) {\n      throw new AccountNoteApiError(\n        payload.message || payload.error || `Account note request failed (${response.status})`,\n        { status: response.status, code: payload.error || null, payload },\n      );\n    }\n    return payload;\n  }\n\n  _form(input, images = []) {\n    const form = new FormData();\n    form.append('note', JSON.stringify(mutationPayload(input)));\n    for (const image of images) {\n      if (!(image instanceof Blob)) continue;\n      form.append('images', image, image.name || 'note-image');\n    }\n    return form;\n  }\n\n  async list({ limit = 500, offset = 0 } = {}) {\n    const params = new URLSearchParams({ limit: String(limit), offset: String(offset) });\n    const response = await this.authService.authenticatedFetch(`${API_BASE}/account-notes?${params}`);\n    const payload = await this._response(response);\n    return (Array.isArray(payload.notes) ? payload.notes : [])\n      .map((record) => normalizeAccountNote({ ...record, owner: true }))\n      .filter(Boolean);\n  }\n\n  async listPublic({ limit = 500, offset = 0 } = {}) {\n    if (!this.fetchImpl) return [];\n    const params = new URLSearchParams({ limit: String(limit), offset: String(offset) });\n    const response = await this.fetchImpl(`${API_BASE}/account-notes/public?${params}`);\n    const payload = await this._response(response);\n    return (Array.isArray(payload.notes) ? payload.notes : [])\n      .map((record) => normalizeAccountNote({ ...record, owner: false, visibility: 'public' }))\n      .filter(Boolean);\n  }\n\n  async getCollection() {\n    const response = await this.authService.authenticatedFetch(`${API_BASE}/account-notes/collection`);\n    return (await this._response(response)).collection || null;\n  }\n\n  async create(input, images = []) {\n    const response = await this.authService.authenticatedFetch(`${API_BASE}/account-notes`, {\n      method: 'POST',\n      body: this._form(input, images),\n    });\n    return normalizeAccountNote({ ...(await this._response(response)).note, owner: true });\n  }\n\n  async update(noteId, input, images = []) {\n    const response = await this.authService.authenticatedFetch(\n      `${API_BASE}/account-notes/${encodeURIComponent(noteId)}`,\n      { method: 'PATCH', body: this._form(input, images) },\n    );\n    return normalizeAccountNote({ ...(await this._response(response)).note, owner: true });\n  }\n\n  async remove(noteId) {\n    const response = await this.authService.authenticatedFetch(\n      `${API_BASE}/account-notes/${encodeURIComponent(noteId)}`,\n      { method: 'DELETE' },\n    );\n    await this._response(response);\n    return true;\n  }\n\n  async getAttachmentBlob(noteId, attachmentId) {\n    const response = await this.authService.authenticatedFetch(\n      `${API_BASE}/account-notes/${encodeURIComponent(noteId)}/attachments/${encodeURIComponent(attachmentId)}`,\n    );\n    if (!response.ok) {\n      const payload = await response.json().catch(() => ({}));\n      throw new AccountNoteApiError(payload.message || 'Could not load note image.', {\n        status: response.status,\n        code: payload.error || null,\n        payload,\n      });\n    }\n    return response.blob();\n  }\n}\n\nlet instance = null;\n\nexport function getAccountNoteApiService() {\n  instance ||= new AccountNoteApiService();\n  return instance;\n}\n\nexport function resetAccountNoteApiServiceForTests() {\n  instance = null;\n}\n","import * as THREE from 'three';\nimport { ellipsoidRadiusForLocalDir, latLonToLocalDir } from '../../modules/geometry-utils.js';\nimport { getAuthService } from '../auth/AuthService.js';\nimport { getLabelSystem } from '../labels/LabelSystem.js';\nimport { terrainSurfaceChangesAffectLatLon } from '../scene/TerrainSurfaceChange.js';\nimport { getAccountNoteApiService, normalizeAccountNote } from './AccountNoteApiService.js';\nimport {\n  formatAccountNoteActivationRadius,\n  normalizeAccountNoteActivationRadius,\n} from './AccountNoteActivation.js';\n\nconst _worldDir = new THREE.Vector3();\nconst _worldQuat = new THREE.Quaternion();\nconst shortText = (value, max = 120) => {\n  const text = String(value || '').replace(/\\s+/g, ' ').trim();\n  return text.length > max ? `${text.slice(0, max - 1)}…` : text;\n};\n\nexport class AccountNoteLayer {\n  constructor({\n    parentGroup,\n    surfaceController,\n    api = getAccountNoteApiService(),\n    authService = getAuthService(),\n  } = {}) {\n    this.parentGroup = parentGroup || null;\n    this.surfaceController = surfaceController || null;\n    this.api = api;\n    this.authService = authService;\n    this._records = new Map();\n    this._entries = new Map();\n    this._authUnsubscribe = null;\n    this._refreshPromise = null;\n    this._sequence = 0;\n    this._onChanged = (event) => this._handleChanged(event?.detail || {});\n  }\n\n  start() {\n    this._authUnsubscribe ||= this.authService.subscribe(() => void this.refresh());\n    globalThis.document?.addEventListener?.('noclip:account-notes:changed', this._onChanged);\n    void this.refresh();\n    void this.authService.whenResolved?.().then(() => this.refresh());\n    return this;\n  }\n\n  getRecords() {\n    return [...this._records.values()];\n  }\n\n  get(noteId) {\n    return this._records.get(String(noteId)) || null;\n  }\n\n  async refresh() {\n    if (this._refreshPromise) return this._refreshPromise;\n    const sequence = ++this._sequence;\n    const ownerRequest = this.authService.getState().isAuthenticated\n      ? this.api.list({ limit: 1000 })\n      : Promise.resolve([]);\n    this._refreshPromise = Promise.all([\n      this.api.listPublic({ limit: 1000 }),\n      ownerRequest,\n    ]).then(([publicNotes, ownerNotes]) => {\n      if (sequence !== this._sequence) return [];\n      const notes = new Map(publicNotes.map((note) => [note.noteId, note]));\n      for (const note of ownerNotes) notes.set(note.noteId, note);\n      this._records = notes;\n      this.sync();\n      return [...notes.values()];\n    }).catch((error) => {\n      console.warn('[AccountNotes] Could not load account notes:', error?.message || error);\n      return [];\n    }).finally(() => {\n      if (sequence === this._sequence) this._refreshPromise = null;\n    });\n    return this._refreshPromise;\n  }\n\n  _handleChanged(detail) {\n    if (detail.removedNoteId) {\n      this._records.delete(String(detail.removedNoteId));\n      this.sync();\n      return;\n    }\n    const note = normalizeAccountNote(detail.note);\n    if (note) {\n      this._records.set(note.noteId, note);\n      this.sync();\n      return;\n    }\n    if (detail.refresh) void this.refresh();\n  }\n\n  sync() {\n    const active = new Set();\n    for (const note of this._records.values()) {\n      if (!Number.isFinite(note.lat) || !Number.isFinite(note.lon)) continue;\n      active.add(note.noteId);\n      let entry = this._entries.get(note.noteId);\n      if (!entry) {\n        entry = {\n          note,\n          dir: latLonToLocalDir(note.lat, note.lon).normalize(),\n          position: new THREE.Vector3(),\n          stableRadius: null,\n          labelHandle: null,\n        };\n        this._entries.set(note.noteId, entry);\n      } else {\n        if (entry.note.lat !== note.lat || entry.note.lon !== note.lon) {\n          entry.dir.copy(latLonToLocalDir(note.lat, note.lon)).normalize();\n          entry.stableRadius = null;\n        }\n        entry.note = note;\n      }\n      this._position(entry);\n      this._label(entry);\n    }\n    for (const [id, entry] of this._entries) {\n      if (active.has(id)) continue;\n      this._disposeEntry(entry);\n      this._entries.delete(id);\n    }\n    globalThis.document?.dispatchEvent?.(new CustomEvent('noclip:account-notes:loaded', {\n      detail: { notes: this.getRecords() },\n    }));\n  }\n\n  _sample(entry) {\n    const ellipsoid = ellipsoidRadiusForLocalDir(entry.dir);\n    const sampler = this.surfaceController?.sampleTerrainRadiusForDir;\n    if (typeof sampler !== 'function') return { radius: ellipsoid, authoritative: false };\n    _worldDir.copy(entry.dir);\n    this.parentGroup?.getWorldQuaternion?.(_worldQuat);\n    if (this.parentGroup) _worldDir.applyQuaternion(_worldQuat).normalize();\n    const requirePhoto = !!this.surfaceController?.photoTileGroup;\n    const radius = sampler.call(this.surfaceController, _worldDir, {\n      mutateCache: false,\n      requireFreshPhotoHit: requirePhoto,\n      allowTriTreeFallback: !requirePhoto,\n      skipWorldMatrixUpdate: true,\n    });\n    return Number.isFinite(radius)\n      ? { radius, authoritative: true }\n      : { radius: ellipsoid, authoritative: false };\n  }\n\n  _position(entry) {\n    const sample = this._sample(entry);\n    if (sample.authoritative || !Number.isFinite(entry.stableRadius)) entry.stableRadius = sample.radius;\n    entry.position.copy(entry.dir).multiplyScalar(entry.stableRadius + 10);\n    if (entry.labelHandle) getLabelSystem().updatePosition?.(entry.labelHandle, entry.position);\n  }\n\n  _metadata(note) {\n    return {\n      id: note.noteId,\n      noteId: note.noteId,\n      entityType: 'account-note',\n      typeLabel: note.visibility === 'public' ? 'Public account note' : 'Private account note',\n      name: note.title,\n      title: note.title,\n      description: note.body,\n      noteBody: note.body,\n      body: note.body,\n      lat: note.lat,\n      lon: note.lon,\n      activationRadiusM: note.activationRadiusM,\n      activationDistance: formatAccountNoteActivationRadius(note.activationRadiusM),\n      target: note.target,\n      targetType: note.target?.type || null,\n      targetId: note.target?.id || null,\n      targetName: note.target?.name || null,\n      address: note.target?.metadata?.address || '',\n      attachments: note.attachments,\n      attachmentCount: note.attachments.length,\n      overlayId: note.overlayId,\n      layerId: note.layerId,\n      itemId: note.itemId,\n      ownerAccountNote: note.owner === true,\n      visibility: note.visibility,\n      createdAt: note.createdAt,\n      updatedAt: note.updatedAt,\n      source: 'My Notes overlay',\n    };\n  }\n\n  _label(entry) {\n    const note = entry.note;\n    const labelSystem = getLabelSystem();\n    const subText = [\n      shortText(note.body, 100),\n      note.attachments.length ? `${note.attachments.length} image${note.attachments.length === 1 ? '' : 's'}` : '',\n    ].filter(Boolean).join(' · ');\n    if (entry.labelHandle) {\n      labelSystem.updateText?.(entry.labelHandle, note.title, subText);\n      labelSystem.updateMetadata?.(entry.labelHandle, this._metadata(note));\n      // The marker sits 10 m above the sampled surface. Preserve the requested\n      // ground-proximity radius while accounting for that visual lift in the\n      // LabelSystem's world-space distance cull.\n      entry.labelHandle.maxDistance = normalizeAccountNoteActivationRadius(note.activationRadiusM) + 10;\n      entry.labelHandle.surfaceActivationRadiusM = normalizeAccountNoteActivationRadius(note.activationRadiusM);\n      return;\n    }\n    entry.labelHandle = labelSystem.createLabel(note.title, {\n      position: entry.position,\n      type: 'account-note',\n      objectRadius: 8,\n      subText,\n      metadata: this._metadata(note),\n      labelPriority: 24,\n      maxDistance: normalizeAccountNoteActivationRadius(note.activationRadiusM) + 10,\n      surfaceActivationRadiusM: normalizeAccountNoteActivationRadius(note.activationRadiusM),\n    });\n    if (entry.labelHandle?.group && this.parentGroup) this.parentGroup.add(entry.labelHandle.group);\n  }\n\n  refreshTerrainAnchors(changes) {\n    let updated = 0;\n    for (const entry of this._entries.values()) {\n      if (!terrainSurfaceChangesAffectLatLon(changes, entry.note.lat, entry.note.lon)) continue;\n      this._position(entry);\n      updated += 1;\n    }\n    return updated;\n  }\n\n  _disposeEntry(entry) {\n    entry?.labelHandle?.group?.parent?.remove?.(entry.labelHandle.group);\n    entry?.labelHandle?.dispose?.();\n    entry.labelHandle = null;\n  }\n\n  clear() {\n    this._sequence += 1;\n    this._records.clear();\n    for (const entry of this._entries.values()) this._disposeEntry(entry);\n    this._entries.clear();\n    globalThis.document?.dispatchEvent?.(new CustomEvent('noclip:account-notes:loaded', {\n      detail: { notes: [] },\n    }));\n  }\n\n  dispose() {\n    this._authUnsubscribe?.();\n    this._authUnsubscribe = null;\n    globalThis.document?.removeEventListener?.('noclip:account-notes:changed', this._onChanged);\n    this.clear();\n  }\n}\n","/**\n * GatingApiService\n *\n * REST client for gating policy evaluation and balance management.\n * Provides access to backend gating endpoints for token-gated content.\n */\n\nimport { getAuthService } from '../auth/AuthService.js';\nimport { getBackendApiBase } from '../shared/backend.js';\n\nconst API_BASE = getBackendApiBase();\nconst MAX_ACCESS_EVALUATION_BATCH = 100;\n\nconst buildApiError = async (response, fallbackMessage) => {\n  const payload = await response.json().catch(() => ({}));\n  const error = new Error(\n    payload.error ||\n    payload.message ||\n    `${fallbackMessage}: ${response.status}`\n  );\n  error.status = response.status;\n  error.payload = payload;\n  return error;\n};\n\nexport class GatingApiService {\n  constructor() {\n    this.authService = getAuthService();\n    this._balanceRefreshPromise = null;\n    this._balanceRefreshResult = null;\n    this._balanceRefreshAvailableAtMs = 0;\n    this._accessEvaluationQueue = [];\n    this._accessEvaluationFlushScheduled = false;\n  }\n\n  /**\n   * Evaluate access for the current user on an object\n   * @param {string} objectType - 'overlay' | 'layer' | 'item'\n   * @param {string} objectId - UUID of the object\n   * @param {string} action - 'view' | 'edit' | 'interact'\n   * @returns {Promise<{decision: string, reasonCodes: string[], cached: boolean}>}\n   */\n  async evaluateAccess(objectType, objectId, action = 'view') {\n    return new Promise((resolve, reject) => {\n      this._accessEvaluationQueue.push({\n        request: { objectType, objectId, actionName: action },\n        resolve,\n        reject,\n      });\n      this._scheduleAccessEvaluationFlush();\n    });\n  }\n\n  _scheduleAccessEvaluationFlush() {\n    if (this._accessEvaluationFlushScheduled) return;\n    this._accessEvaluationFlushScheduled = true;\n    queueMicrotask(() => this._flushAccessEvaluations());\n  }\n\n  async _flushAccessEvaluations() {\n    this._accessEvaluationFlushScheduled = false;\n    const batch = this._accessEvaluationQueue.splice(0, MAX_ACCESS_EVALUATION_BATCH);\n    if (this._accessEvaluationQueue.length > 0) this._scheduleAccessEvaluationFlush();\n    if (batch.length === 0) return;\n\n    try {\n      const response = await this.authService.authenticatedFetch(`${API_BASE}/access/evaluate`, {\n        method: 'POST',\n        headers: { 'Content-Type': 'application/json' },\n        body: JSON.stringify({ evaluations: batch.map((entry) => entry.request) }),\n      });\n\n      if (!response.ok) {\n        throw await buildApiError(response, 'Access evaluation failed');\n      }\n\n      const payload = await response.json();\n      if (!Array.isArray(payload?.results) || payload.results.length !== batch.length) {\n        throw new Error('Access evaluation returned an invalid batch response');\n      }\n      payload.results.forEach((result, index) => batch[index].resolve(result));\n    } catch (error) {\n      batch.forEach((entry) => entry.reject(error));\n    }\n  }\n\n  /**\n   * Evaluate access for an item with hierarchical gating\n   * @param {string} itemId - UUID of the item\n   * @param {string} action - 'view' | 'edit' | 'interact'\n   * @returns {Promise<{decision: string, reasonCodes: string[]}>}\n   */\n  async evaluateItemAccess(itemId, action = 'view') {\n    const response = await this.authService.authenticatedFetch(`${API_BASE}/access/evaluate/item`, {\n      method: 'POST',\n      headers: { 'Content-Type': 'application/json' },\n      body: JSON.stringify({ itemId, action }),\n    });\n\n    if (!response.ok) {\n      throw await buildApiError(response, 'Item access evaluation failed');\n    }\n\n    return response.json();\n  }\n\n  /**\n   * Get current user's aggregate token balances\n   * @returns {Promise<{balances: Array<{chainId, contractAddress, tokenStandard, balance}>}>}\n   */\n  async getBalances({signal} = {}) {\n    const response = await this.authService.authenticatedFetch(`${API_BASE}/balances`, {\n      signal,\n      governanceLane: 'control',\n    });\n\n    if (!response.ok) {\n      throw new Error('Failed to fetch balances');\n    }\n\n    return response.json();\n  }\n\n  /**\n   * Force refresh balances from Alchemy\n   * Also invalidates gating decision cache\n   * @returns {Promise<{success: boolean}>}\n   */\n  async refreshBalances() {\n    if (this._balanceRefreshPromise) return this._balanceRefreshPromise;\n    if (this._balanceRefreshResult && Date.now() < this._balanceRefreshAvailableAtMs) {\n      return this._balanceRefreshResult;\n    }\n\n    const pending = this._refreshBalancesRequest();\n    this._balanceRefreshPromise = pending;\n    try {\n      return await pending;\n    } finally {\n      if (this._balanceRefreshPromise === pending) this._balanceRefreshPromise = null;\n    }\n  }\n\n  async _refreshBalancesRequest() {\n    const response = await this.authService.authenticatedFetch(`${API_BASE}/balances/refresh`, {\n      method: 'POST',\n      governanceLane: 'control',\n    });\n\n    if (!response.ok) {\n      throw await buildApiError(response, 'Failed to refresh balances');\n    }\n\n    const result = await response.json();\n    const resetSeconds = Number(response.headers.get('RateLimit-Reset'));\n    const cooldownMs = Number.isFinite(resetSeconds) && resetSeconds >= 0\n      ? Math.max(10_000, resetSeconds * 1000)\n      : 30_000;\n    this._balanceRefreshResult = result;\n    this._balanceRefreshAvailableAtMs = Date.now() + cooldownMs;\n    return result;\n  }\n\n  /**\n   * List all gating policies (for policy management)\n   * @param {number} limit\n   * @param {number} offset\n   * @returns {Promise<{policies: Array, total: number}>}\n   */\n  async listPolicies(limit = 50, offset = 0) {\n    const response = await this.authService.authenticatedFetch(\n      `${API_BASE}/gating-policies?limit=${limit}&offset=${offset}`\n    );\n\n    if (!response.ok) {\n      throw new Error('Failed to list policies');\n    }\n\n    return response.json();\n  }\n\n  /**\n   * Get a specific gating policy with full condition tree\n   * @param {string} policyId\n   * @returns {Promise<{policy: Object}>}\n   */\n  async getPolicy(policyId) {\n    const response = await this.authService.authenticatedFetch(\n      `${API_BASE}/gating-policies/${policyId}`\n    );\n\n    if (!response.ok) {\n      throw new Error('Failed to get policy');\n    }\n\n    return response.json();\n  }\n\n  /**\n   * Create a new gating policy\n   * @param {string} name - Policy name\n   * @param {Object} rootGroup - Policy condition tree\n   * @returns {Promise<{policy: Object}>}\n   */\n  async createPolicy(name, rootGroup) {\n    const response = await this.authService.authenticatedFetch(`${API_BASE}/gating-policies`, {\n      method: 'POST',\n      headers: { 'Content-Type': 'application/json' },\n      body: JSON.stringify({ name, rootGroup }),\n    });\n\n    if (!response.ok) {\n      const error = await response.json().catch(() => ({}));\n      throw new Error(error.error || 'Failed to create policy');\n    }\n\n    return response.json();\n  }\n\n  /**\n   * Delete a gating policy\n   * @param {string} policyId\n   * @returns {Promise<void>}\n   */\n  async deletePolicy(policyId) {\n    const response = await this.authService.authenticatedFetch(\n      `${API_BASE}/gating-policies/${policyId}`,\n      { method: 'DELETE' }\n    );\n\n    if (!response.ok) {\n      throw new Error('Failed to delete policy');\n    }\n  }\n\n  // ============================================\n  // GATING BINDING MANAGEMENT\n  // ============================================\n\n  /**\n   * Add gating policy to an overlay\n   * @param {string} overlayId\n   * @param {string} policyId\n   * @param {string} action - 'view' | 'edit' | 'interact'\n   * @returns {Promise<{binding: Object}>}\n   */\n  async addGatingToOverlay(overlayId, policyId, action = 'view') {\n    const response = await this.authService.authenticatedFetch(\n      `${API_BASE}/overlays/${overlayId}/gating`,\n      {\n        method: 'POST',\n        headers: { 'Content-Type': 'application/json' },\n        body: JSON.stringify({ gatingPolicyId: policyId, action }),\n      }\n    );\n\n    if (!response.ok) {\n      const error = await response.json().catch(() => ({}));\n      throw new Error(error.error || 'Failed to add gating to overlay');\n    }\n\n    return response.json();\n  }\n\n  /**\n   * Get gating bindings for an overlay\n   * @param {string} overlayId\n   * @returns {Promise<{bindings: Array}>}\n   */\n  async getOverlayGating(overlayId) {\n    const response = await this.authService.authenticatedFetch(\n      `${API_BASE}/overlays/${overlayId}/gating`\n    );\n\n    if (!response.ok) {\n      throw new Error('Failed to get overlay gating');\n    }\n\n    return response.json();\n  }\n\n  /**\n   * Remove gating binding from overlay\n   * @param {string} overlayId\n   * @param {string} bindingId\n   * @returns {Promise<void>}\n   */\n  async removeOverlayGating(overlayId, bindingId) {\n    const response = await this.authService.authenticatedFetch(\n      `${API_BASE}/overlays/${overlayId}/gating/${bindingId}`,\n      { method: 'DELETE' }\n    );\n\n    if (!response.ok) {\n      throw new Error('Failed to remove overlay gating');\n    }\n  }\n\n  /**\n   * Add gating policy to a layer\n   * @param {string} layerId\n   * @param {string} policyId\n   * @param {string} action\n   * @returns {Promise<{binding: Object}>}\n   */\n  async addGatingToLayer(layerId, policyId, action = 'view') {\n    const response = await this.authService.authenticatedFetch(\n      `${API_BASE}/layers/${layerId}/gating`,\n      {\n        method: 'POST',\n        headers: { 'Content-Type': 'application/json' },\n        body: JSON.stringify({ gatingPolicyId: policyId, action }),\n      }\n    );\n\n    if (!response.ok) {\n      const error = await response.json().catch(() => ({}));\n      throw new Error(error.error || 'Failed to add gating to layer');\n    }\n\n    return response.json();\n  }\n\n  /**\n   * Add gating policy to an item\n   * @param {string} itemId\n   * @param {string} policyId\n   * @param {string} action\n   * @returns {Promise<{binding: Object}>}\n   */\n  async addGatingToItem(itemId, policyId, action = 'view') {\n    const response = await this.authService.authenticatedFetch(\n      `${API_BASE}/items/${itemId}/gating`,\n      {\n        method: 'POST',\n        headers: { 'Content-Type': 'application/json' },\n        body: JSON.stringify({ gatingPolicyId: policyId, action }),\n      }\n    );\n\n    if (!response.ok) {\n      const error = await response.json().catch(() => ({}));\n      throw new Error(error.error || 'Failed to add gating to item');\n    }\n\n    return response.json();\n  }\n\n  /**\n   * Get gating bindings for an item\n   * @param {string} itemId\n   * @returns {Promise<{bindings: Array}>}\n   */\n  async getItemGating(itemId) {\n    const response = await this.authService.authenticatedFetch(\n      `${API_BASE}/items/${itemId}/gating`\n    );\n\n    if (!response.ok) {\n      throw new Error('Failed to get item gating');\n    }\n\n    return response.json();\n  }\n\n}\n\n// Singleton instance\nlet gatingApiServiceInstance = null;\n\nexport function getGatingApiService() {\n  if (!gatingApiServiceInstance) {\n    gatingApiServiceInstance = new GatingApiService();\n  }\n  return gatingApiServiceInstance;\n}\n","/**\n * AccessController\n *\n * Purpose:\n * - Enforces policy decisions and action constraints from the backend.\n * - Provides a single authoritative gate for overlay and item access.\n * - Integrates with backend gating evaluation for token-gated content.\n *\n * API:\n * - canPerform(objectType, objectId, actionName) -> Promise<boolean>\n * - canPerformSync(objectType, objectId, actionName) -> boolean (cached)\n * - preEvaluate(objects) -> Promise<void>\n * - invalidateCache() -> void\n * - on(event, handler) -> unsubscribe function\n *\n * Relationships:\n * - Used by OverlaySubsystem and EntitySystem.\n * - Fed by backend policy decisions via GatingApiService.\n */\n\nimport { getGatingApiService } from './GatingApiService.js';\nimport { getAuthService } from '../auth/AuthService.js';\nimport { EventBus } from '../shared/EventBus.js';\n\n// Event types\nexport const AccessEvents = {\n  DECISION_UPDATED: 'access:decision:updated',\n  ACCESS_DENIED: 'access:denied',\n  CACHE_INVALIDATED: 'access:cache:invalidated',\n  EVALUATION_ERROR: 'access:error',\n};\n\nexport class AccessController {\n  constructor({ authService, api } = {}) {\n    this.decisions = new Map();\n    this.pendingEvaluations = new Map();\n    this._evaluationEpoch = 0;\n    this.defaultDecision = false; // Deny by default for security\n    this.eventBus = new EventBus();\n    this._warnThrottleMs = 10000;\n    this._lastBackendWarnAt = 0;\n    this._authFailureBackoffUntil = 0;\n\n    // Lazy-load API service to avoid circular dependencies\n    this._api = api || null;\n    this._auth = authService || getAuthService();\n    this._authState = this._auth?.getState?.() || null;\n    this._authEpoch = this._auth?.authEpoch;\n    this._authUnsubscribe = this._auth?.subscribe?.(state => this._syncAuthState(state));\n  }\n\n  _syncAuthState(state) {\n    // Keep this optional method call out of a default parameter: the current\n    // production target lowers its receiver into an out-of-scope temporary.\n    if (state === undefined) state = this._auth?.getState?.();\n    if (this._disposed || !state) return;\n    const changed = !!this._authState?.isAuthenticated !== !!state.isAuthenticated\n      || this._resolveUserId(this._authState) !== this._resolveUserId(state) || this._authEpoch !== this._auth?.authEpoch;\n    this._authState = state; this._authEpoch = this._auth?.authEpoch;\n    if (changed) {\n      this._authFailureBackoffUntil = 0; this.defaultDecision = false;\n      this.invalidateCache();\n    }\n  }\n\n  get api() {\n    if (!this._api) {\n      this._api = getGatingApiService();\n    }\n    return this._api;\n  }\n\n  /**\n   * Check if user can perform action on object.\n   * Returns cached decision if available, otherwise evaluates with backend.\n   *\n   * @param {string} objectType - 'overlay' | 'layer' | 'item'\n   * @param {string} objectId - UUID of the object\n   * @param {string} action - 'view' | 'edit' | 'interact'\n   * @returns {Promise<boolean>}\n   */\n  async canPerform(objectType, objectId, action = 'view') {\n    if (this._disposed) return false;\n    this._syncAuthState();\n    const key = this._key(objectType, objectId, action);\n\n    // Return cached decision\n    if (this.decisions.has(key)) {\n      return this.decisions.get(key);\n    }\n\n    // Check if evaluation is already in progress\n    if (this.pendingEvaluations.has(key)) {\n      return this.pendingEvaluations.get(key);\n    }\n\n    // Start async evaluation\n    const epoch = this._evaluationEpoch;\n    let evaluationPromise;\n    const current = () => {\n      this._syncAuthState();\n      return !this._disposed && this._evaluationEpoch === epoch && this.pendingEvaluations.get(key) === evaluationPromise;\n    };\n    // Store the final boolean promise, not the raw { decision } API promise.\n    // Otherwise a second caller receives a truthy object even for a denial.\n    evaluationPromise = (async () => {\n    try {\n      const result = await this._evaluateAccess(objectType, objectId, action, current);\n      if (!current()) return false;\n      const allowed = result.decision === 'allow';\n\n      // Cache the decision\n      this.decisions.set(key, allowed);\n\n      // Emit events\n      this.eventBus.emit(AccessEvents.DECISION_UPDATED, {\n        key,\n        objectType,\n        objectId,\n        action,\n        allowed,\n        reasonCodes: result.reasonCodes,\n        cached: result.cached,\n      });\n\n      if (!allowed) {\n        this.eventBus.emit(AccessEvents.ACCESS_DENIED, {\n          objectType,\n          objectId,\n          action,\n          reasonCodes: result.reasonCodes,\n        });\n      }\n\n      return allowed;\n    } catch (err) {\n      if (!current()) return false;\n      console.error('[AccessController] Evaluation failed:', err);\n\n      this.eventBus.emit(AccessEvents.EVALUATION_ERROR, {\n        objectType,\n        objectId,\n        action,\n        error: err.message,\n      });\n\n      // Return default (deny) on error\n      return this.defaultDecision;\n    } finally {\n      if (this.pendingEvaluations.get(key) === evaluationPromise) this.pendingEvaluations.delete(key);\n    }\n    })();\n    this.pendingEvaluations.set(key, evaluationPromise);\n    return evaluationPromise;\n  }\n\n  /**\n   * Synchronous check - returns cached value or default.\n   * Use this when you need immediate response and can tolerate stale data.\n   *\n   * @param {string} objectType\n   * @param {string} objectId\n   * @param {string} action\n   * @returns {boolean}\n   */\n  canPerformSync(objectType, objectId, action = 'view') {\n    if (this._disposed) return false;\n    this._syncAuthState();\n    const key = this._key(objectType, objectId, action);\n    return this.decisions.has(key) ? this.decisions.get(key) : this.defaultDecision;\n  }\n\n  /**\n   * Check if a decision is cached for an object.\n   *\n   * @param {string} objectType\n   * @param {string} objectId\n   * @param {string} action\n   * @returns {boolean}\n   */\n  hasCachedDecision(objectType, objectId, action = 'view') {\n    if (this._disposed) return false;\n    this._syncAuthState();\n    const key = this._key(objectType, objectId, action);\n    return this.decisions.has(key);\n  }\n\n  /**\n   * Pre-evaluate access for multiple objects in parallel.\n   * Useful when loading an overlay with many items.\n   *\n   * @param {Array<{objectType: string, objectId: string, action?: string}>} objects\n   * @returns {Promise<Map<string, boolean>>}\n   */\n  async preEvaluate(objects) {\n    const results = new Map();\n\n    const promises = objects.map(async ({ objectType, objectId, action = 'view' }) => {\n      const allowed = await this.canPerform(objectType, objectId, action);\n      const key = this._key(objectType, objectId, action);\n      results.set(key, allowed);\n    });\n\n    await Promise.all(promises);\n    return results;\n  }\n\n  /**\n   * Update decisions from server-pushed batch.\n   * Used for real-time updates via WebSocket.\n   *\n   * @param {Object} decisionSet - { allow: Array, deny: Array, defaultDecision?: boolean }\n   */\n  updateDecisions(decisionSet = {}) {\n    if (this._disposed) return;\n    this._syncAuthState();\n    const allow = Array.isArray(decisionSet.allow) ? decisionSet.allow : [];\n    const deny = Array.isArray(decisionSet.deny) ? decisionSet.deny : [];\n\n    if (decisionSet.defaultDecision !== undefined) {\n      this.defaultDecision = !!decisionSet.defaultDecision;\n    }\n\n    for (const rule of allow) {\n      const key = this._keyFromRule(rule);\n      if (key) {\n        this.pendingEvaluations.delete(key);\n        this.decisions.set(key, true);\n        this.eventBus.emit(AccessEvents.DECISION_UPDATED, {\n          key,\n          allowed: true,\n          source: 'push',\n        });\n      }\n    }\n\n    for (const rule of deny) {\n      const key = this._keyFromRule(rule);\n      if (key) {\n        this.pendingEvaluations.delete(key);\n        this.decisions.set(key, false);\n        this.eventBus.emit(AccessEvents.DECISION_UPDATED, {\n          key,\n          allowed: false,\n          source: 'push',\n        });\n      }\n    }\n  }\n\n  /**\n   * Clear all cached decisions.\n   * Should be called after balance refresh or logout.\n   */\n  invalidateCache() {\n    this._evaluationEpoch++;\n    this.decisions.clear();\n    this.pendingEvaluations.clear();\n    this.eventBus.emit(AccessEvents.CACHE_INVALIDATED, {});\n  }\n\n  /**\n   * Invalidate decisions for a specific object.\n   *\n   * @param {string} objectType\n   * @param {string} objectId\n   */\n  invalidateObject(objectType, objectId) {\n    for (const key of this.decisions.keys()) {\n      if (key.startsWith(`${objectType}:${objectId}:`)) {\n        this.decisions.delete(key);\n      }\n    }\n    for (const key of this.pendingEvaluations.keys()) {\n      if (key.startsWith(`${objectType}:${objectId}:`)) this.pendingEvaluations.delete(key);\n    }\n  }\n\n  dispose() {\n    if (this._disposed) return;\n    this._disposed = true; this._authUnsubscribe?.(); this._authUnsubscribe = null;\n    this.invalidateCache(); this.eventBus.listeners.clear(); this.eventBus._wildcards.clear();\n  }\n\n  /**\n   * Subscribe to access events.\n   *\n   * @param {string} event - Event name from AccessEvents\n   * @param {Function} handler - Event handler\n   * @returns {Function} Unsubscribe function\n   */\n  on(event, handler) {\n    this.eventBus.on(event, handler);\n    return () => this.eventBus.off(event, handler);\n  }\n\n  /**\n   * Apply constraints to a payload (for edit operations).\n   * Currently a passthrough - can be extended for field-level access control.\n   *\n   * @param {string} action\n   * @param {Object} payload\n   * @returns {Object}\n   */\n  applyConstraints(action, payload) {\n    // TODO: Implement field-level constraints based on action rules\n    return payload;\n  }\n\n  // ============================================\n  // PRIVATE METHODS\n  // ============================================\n\n  /**\n   * Evaluate access via backend API\n   * @private\n   */\n  async _evaluateAccess(objectType, objectId, action, current = () => !this._disposed) {\n    const now = Date.now();\n    if (!this._isAuthenticated() || now < this._authFailureBackoffUntil) {\n      return this._denyResult('unauthenticated');\n    }\n\n    try {\n      const response = await this.api.evaluateAccess(objectType, objectId, action);\n      if (!current()) return { decision: 'deny', reasonCodes: ['stale_session'], cached: false };\n      this._authFailureBackoffUntil = 0;\n      return {\n        decision: response.decision,\n        reasonCodes: response.reasonCodes || [],\n        cached: response.cached || false,\n      };\n    } catch (err) {\n      if (!current()) return { decision: 'deny', reasonCodes: ['stale_session'], cached: false };\n      if (err?.status === 401) {\n        this._authFailureBackoffUntil = Date.now() + 15000;\n        return this._denyResult('unauthenticated');\n      }\n\n      const warnNow = Date.now();\n      if (!this._lastBackendWarnAt || (warnNow - this._lastBackendWarnAt) >= this._warnThrottleMs) {\n        this._lastBackendWarnAt = warnNow;\n        console.warn('[AccessController] Backend evaluation failed, using default:', err?.message || err);\n      }\n\n      // If backend unavailable, check for offline decision\n      return {\n        decision: this.defaultDecision ? 'allow' : 'deny',\n        reasonCodes: ['backend_unavailable'],\n        cached: false,\n      };\n    }\n  }\n\n  _denyResult(reasonCode = 'unauthenticated') {\n    return {\n      decision: this.defaultDecision ? 'allow' : 'deny',\n      reasonCodes: [reasonCode],\n      cached: false,\n    };\n  }\n\n  _isAuthenticated() {\n    const state = this._auth?.getState?.() || this._authState;\n    return !!state?.isAuthenticated;\n  }\n\n  _resolveUserId(state) {\n    return state?.user?.user_id || state?.user?.userId || state?.user?.id || state?.userId || state?.session?.userId || null;\n  }\n\n  /**\n   * Generate cache key for object+action\n   * @private\n   */\n  _key(objectType, objectId, action) {\n    return `${objectType}:${objectId}:${action}`;\n  }\n\n  /**\n   * Generate cache key from rule object\n   * @private\n   */\n  _keyFromRule(rule) {\n    if (!rule) return null;\n    const objectType = rule.objectType || rule.object_type;\n    const objectId = rule.objectId || rule.object_id || '*';\n    const action = rule.action || rule.actionName || rule.action_name || 'view';\n    if (!objectType) return null;\n    return `${objectType}:${objectId}:${action}`;\n  }\n}\n\n// Singleton instance\nlet accessControllerInstance = null;\n\nexport function getAccessController() {\n  if (!accessControllerInstance) {\n    accessControllerInstance = new AccessController();\n  }\n  return accessControllerInstance;\n}\n","export class PresenceClient {\n    constructor(options = {}) {\n        this.url = options.url || null;\n        this.path = options.path || '/presence';\n        this.autoReconnect = options.autoReconnect !== false;\n        this.reconnectMinMs = Number.isFinite(options.reconnectMinMs) ? options.reconnectMinMs : 500;\n        this.reconnectMaxMs = Number.isFinite(options.reconnectMaxMs) ? options.reconnectMaxMs : 5000;\n        this.maxBufferedBytes = Number.isFinite(options.maxBufferedBytes) ? options.maxBufferedBytes : 2_000_000;\n\n        this.onWelcome = typeof options.onWelcome === 'function' ? options.onWelcome : null;\n        this.onJoin = typeof options.onJoin === 'function' ? options.onJoin : null;\n        this.onUpdate = typeof options.onUpdate === 'function' ? options.onUpdate : null;\n        this.onLeave = typeof options.onLeave === 'function' ? options.onLeave : null;\n        this.onStatus = typeof options.onStatus === 'function' ? options.onStatus : null;\n        this.onError = typeof options.onError === 'function' ? options.onError : null;\n\n        this._ws = null;\n        this._connected = false;\n        this._shouldReconnect = true;\n        this._reconnectDelay = this.reconnectMinMs;\n        this._reconnectTimer = null;\n        this._id = null;\n    }\n\n    connect() {\n        const url = this._resolveUrl();\n        if (!url) {\n            this._emitStatus(false);\n            return;\n        }\n        if (this._ws && (this._ws.readyState === WebSocket.OPEN || this._ws.readyState === WebSocket.CONNECTING)) {\n            return;\n        }\n\n        this._shouldReconnect = true;\n        this._clearReconnectTimer();\n\n        let ws;\n        try {\n            ws = new WebSocket(url);\n        } catch (error) {\n            this._emitStatus(false);\n            this._scheduleReconnect();\n            if (this.onError) this.onError(error);\n            return;\n        }\n\n        this._ws = ws;\n        ws.onopen = () => {\n            this._connected = true;\n            this._reconnectDelay = this.reconnectMinMs;\n            this._emitStatus(true);\n        };\n        ws.onmessage = (event) => {\n            this._handleMessage(event.data);\n        };\n        ws.onclose = () => {\n            this._connected = false;\n            this._emitStatus(false);\n            if (this._shouldReconnect && this.autoReconnect) {\n                this._scheduleReconnect();\n            }\n        };\n        ws.onerror = (event) => {\n            if (this.onError) this.onError(event);\n        };\n    }\n\n    disconnect() {\n        this._shouldReconnect = false;\n        this._clearReconnectTimer();\n        if (this._ws) {\n            try {\n                this._ws.close();\n            } catch {}\n        }\n        this._ws = null;\n        this._connected = false;\n        this._emitStatus(false);\n    }\n\n    sendUpdate(state) {\n        if (!this._ws || this._ws.readyState !== WebSocket.OPEN) return false;\n        if (typeof this._ws.bufferedAmount === 'number' && this._ws.bufferedAmount > this.maxBufferedBytes) {\n            return false;\n        }\n        this._ws.send(JSON.stringify({ type: 'update', state }));\n        return true;\n    }\n\n    isConnected() {\n        return this._connected;\n    }\n\n    getId() {\n        return this._id;\n    }\n\n    _handleMessage(data) {\n        let msg;\n        try {\n            msg = JSON.parse(String(data));\n        } catch {\n            return;\n        }\n        if (!msg || typeof msg !== 'object') return;\n        if (msg.type === 'welcome') {\n            this._id = msg.id || null;\n            if (Array.isArray(msg.peers)) {\n                msg.peers.forEach((peer) => {\n                    if (this.onUpdate) this.onUpdate(peer);\n                });\n            }\n            if (this.onWelcome) this.onWelcome(msg);\n            return;\n        }\n        if (msg.type === 'join') {\n            if (this.onJoin) this.onJoin(msg.peer || msg);\n            return;\n        }\n        if (msg.type === 'peer_update') {\n            if (this.onUpdate) this.onUpdate(msg.peer || msg);\n            return;\n        }\n        if (msg.type === 'leave') {\n            if (this.onLeave) this.onLeave(msg.id || null);\n        }\n    }\n\n    _resolveUrl() {\n        if (this.url) return this.url;\n        if (typeof window === 'undefined' || !window.location) return null;\n        const proto = window.location.protocol === 'https:' ? 'wss:' : 'ws:';\n        return proto + '//' + window.location.host + this.path;\n    }\n\n    _scheduleReconnect() {\n        if (!this.autoReconnect) return;\n        this._clearReconnectTimer();\n        const delay = Math.min(this._reconnectDelay, this.reconnectMaxMs);\n        this._reconnectTimer = setTimeout(() => {\n            this._reconnectTimer = null;\n            this.connect();\n        }, delay);\n        this._reconnectDelay = Math.min(this._reconnectDelay * 1.6, this.reconnectMaxMs);\n    }\n\n    _clearReconnectTimer() {\n        if (this._reconnectTimer) {\n            clearTimeout(this._reconnectTimer);\n            this._reconnectTimer = null;\n        }\n    }\n\n    _emitStatus(connected) {\n        if (this.onStatus) {\n            this.onStatus({ connected, id: this._id });\n        }\n    }\n}\n","/**\n * SocialApiService\n *\n * Handles friend and notification API calls.\n * Uses AuthService.authenticatedFetch for token management.\n */\n\nimport { getAuthService } from '../auth/AuthService.js';\nimport { getBackendApiBase } from '../shared/backend.js';\n\nconst API_BASE = getBackendApiBase();\n\nexport class SocialApiService {\n  constructor() {\n    this.authService = getAuthService();\n  }\n\n  /**\n   * Parse JSON response safely\n   */\n  async _parseResponse(response) {\n    const text = await response.text();\n    if (!text) {\n      return {};\n    }\n    try {\n      return JSON.parse(text);\n    } catch (e) {\n      console.error('[SocialApiService] Non-JSON response:', text.slice(0, 200));\n      throw new Error(`Server error: ${response.status} ${response.statusText}`);\n    }\n  }\n\n  // =========================================================================\n  // FRIENDS API\n  // =========================================================================\n\n  /**\n   * List user's friends\n   * @param {Object} options - Pagination options\n   * @param {number} [options.limit=50] - Max friends to return\n   * @param {number} [options.offset=0] - Offset for pagination\n   * @returns {Promise<{friends: Array, total: number}>}\n   */\n  async listFriends({ limit = 50, offset = 0 } = {}) {\n    const params = new URLSearchParams({ limit: String(limit), offset: String(offset) });\n    const response = await this.authService.authenticatedFetch(\n      `${API_BASE}/friends?${params}`\n    );\n\n    const data = await this._parseResponse(response);\n\n    if (!response.ok) {\n      throw new Error(data.message || data.error || 'Failed to list friends');\n    }\n\n    return {\n      friends: data.friends || [],\n      total: data.total || 0,\n    };\n  }\n\n  /**\n   * Search users by handle/username for friend adding\n   * @param {string} query - Search term\n   * @param {Object} options - Query options\n   * @param {number} [options.limit=10] - Max results to return\n   * @returns {Promise<{users: Array}>}\n   */\n  async searchUsers(query, { limit = 10 } = {}) {\n    const params = new URLSearchParams({ query, limit: String(limit) });\n    const response = await this.authService.authenticatedFetch(\n      `${API_BASE}/friends/search?${params}`\n    );\n\n    const data = await this._parseResponse(response);\n\n    if (!response.ok) {\n      throw new Error(data.message || data.error || 'Failed to search users');\n    }\n\n    return { users: data.users || [] };\n  }\n\n  /**\n   * Send a friend request\n   * @param {string} targetUserId - User ID to send request to\n   * @param {string} [message] - Optional message\n   * @returns {Promise<{requestId: string, status: string, createdAt: string}>}\n   */\n  async sendFriendRequest(targetUserId, message) {\n    const response = await this.authService.authenticatedFetch(\n      `${API_BASE}/friends/requests`,\n      {\n        method: 'POST',\n        headers: { 'Content-Type': 'application/json' },\n        body: JSON.stringify({ targetUserId, message }),\n      }\n    );\n\n    const data = await this._parseResponse(response);\n\n    if (!response.ok) {\n      throw new Error(data.message || data.error || 'Failed to send friend request');\n    }\n\n    return data;\n  }\n\n  /**\n   * Accept a friend request\n   * @param {string} requestId - Request ID to accept\n   * @returns {Promise<{friend: Object, status: string}>}\n   */\n  async acceptFriendRequest(requestId) {\n    const response = await this.authService.authenticatedFetch(\n      `${API_BASE}/friends/requests/${requestId}/accept`,\n      {\n        method: 'POST',\n        headers: { 'Content-Type': 'application/json' },\n        body: JSON.stringify({}),\n      }\n    );\n\n    const data = await this._parseResponse(response);\n\n    if (!response.ok) {\n      throw new Error(data.message || data.error || 'Failed to accept friend request');\n    }\n\n    return data;\n  }\n\n  /**\n   * Decline a friend request\n   * @param {string} requestId - Request ID to decline\n   * @returns {Promise<{requestId: string, status: string}>}\n   */\n  async declineFriendRequest(requestId) {\n    const response = await this.authService.authenticatedFetch(\n      `${API_BASE}/friends/requests/${requestId}/decline`,\n      {\n        method: 'POST',\n        headers: { 'Content-Type': 'application/json' },\n        body: JSON.stringify({}),\n      }\n    );\n\n    const data = await this._parseResponse(response);\n\n    if (!response.ok) {\n      throw new Error(data.message || data.error || 'Failed to decline friend request');\n    }\n\n    return data;\n  }\n\n  /**\n   * Remove a friend\n   * @param {string} userId - User ID to remove\n   * @returns {Promise<void>}\n   */\n  async removeFriend(userId) {\n    const response = await this.authService.authenticatedFetch(\n      `${API_BASE}/friends/${userId}`,\n      { method: 'DELETE' }\n    );\n\n    if (!response.ok && response.status !== 204) {\n      const data = await this._parseResponse(response);\n      throw new Error(data.message || data.error || 'Failed to remove friend');\n    }\n  }\n\n  /**\n   * Get incoming friend requests\n   * @param {Object} options - Pagination options\n   * @returns {Promise<{requests: Array}>}\n   */\n  async getIncomingRequests({ limit = 50, offset = 0 } = {}) {\n    const params = new URLSearchParams({ limit: String(limit), offset: String(offset) });\n    const response = await this.authService.authenticatedFetch(\n      `${API_BASE}/friends/requests/incoming?${params}`\n    );\n\n    const data = await this._parseResponse(response);\n\n    if (!response.ok) {\n      throw new Error(data.message || data.error || 'Failed to get incoming requests');\n    }\n\n    return { requests: data.requests || [] };\n  }\n\n  /**\n   * Get outgoing friend requests\n   * @param {Object} options - Pagination options\n   * @returns {Promise<{requests: Array}>}\n   */\n  async getOutgoingRequests({ limit = 50, offset = 0 } = {}) {\n    const params = new URLSearchParams({ limit: String(limit), offset: String(offset) });\n    const response = await this.authService.authenticatedFetch(\n      `${API_BASE}/friends/requests/outgoing?${params}`\n    );\n\n    const data = await this._parseResponse(response);\n\n    if (!response.ok) {\n      throw new Error(data.message || data.error || 'Failed to get outgoing requests');\n    }\n\n    return { requests: data.requests || [] };\n  }\n\n  // =========================================================================\n  // NOTIFICATIONS API\n  // =========================================================================\n\n  /**\n   * List user's notifications\n   * @param {Object} options - Query options\n   * @param {number} [options.limit=50] - Max notifications to return\n   * @param {number} [options.offset=0] - Offset for pagination\n   * @param {boolean} [options.includeDismissed=false] - Include dismissed notifications\n   * @returns {Promise<{notifications: Array, unreadCount: number}>}\n   */\n  async listNotifications({ limit = 50, offset = 0, includeDismissed = false } = {}) {\n    const params = new URLSearchParams({\n      limit: String(limit),\n      offset: String(offset),\n      includeDismissed: String(includeDismissed),\n    });\n    const response = await this.authService.authenticatedFetch(\n      `${API_BASE}/notifications?${params}`\n    );\n\n    const data = await this._parseResponse(response);\n\n    if (!response.ok) {\n      throw new Error(data.message || data.error || 'Failed to list notifications');\n    }\n\n    return {\n      notifications: data.notifications || [],\n      unreadCount: data.unreadCount || 0,\n    };\n  }\n\n  /**\n   * Update notification status\n   * @param {string} notificationId - Notification ID\n   * @param {'read' | 'dismissed'} status - New status\n   * @returns {Promise<{id: string, status: string}>}\n   */\n  async updateNotificationStatus(notificationId, status) {\n    const response = await this.authService.authenticatedFetch(\n      `${API_BASE}/notifications/${notificationId}`,\n      {\n        method: 'PATCH',\n        headers: { 'Content-Type': 'application/json' },\n        body: JSON.stringify({ status }),\n      }\n    );\n\n    const data = await this._parseResponse(response);\n\n    if (!response.ok) {\n      throw new Error(data.message || data.error || 'Failed to update notification');\n    }\n\n    return data;\n  }\n\n  /**\n   * Mark all notifications as read\n   * @returns {Promise<{success: boolean, markedCount: number}>}\n   */\n  async markAllNotificationsRead() {\n    const response = await this.authService.authenticatedFetch(\n      `${API_BASE}/notifications/mark-all-read`,\n      { method: 'POST' }\n    );\n\n    const data = await this._parseResponse(response);\n\n    if (!response.ok) {\n      throw new Error(data.message || data.error || 'Failed to mark all as read');\n    }\n\n    return data;\n  }\n\n  /**\n   * Get a single notification\n   * @param {string} notificationId - Notification ID\n   * @returns {Promise<{notification: Object}>}\n   */\n  async getNotification(notificationId) {\n    const response = await this.authService.authenticatedFetch(\n      `${API_BASE}/notifications/${notificationId}`\n    );\n\n    const data = await this._parseResponse(response);\n\n    if (!response.ok) {\n      throw new Error(data.message || data.error || 'Failed to get notification');\n    }\n\n    return data;\n  }\n}\n\n// Singleton instance\nlet socialApiServiceInstance = null;\n\nexport function getSocialApiService() {\n  if (!socialApiServiceInstance) {\n    socialApiServiceInstance = new SocialApiService();\n  }\n  return socialApiServiceInstance;\n}\n","/**\n * SocialStore\n *\n * Manages social state (friends, requests, notifications) with EventBus hooks.\n * Provides reactive state updates for UI components.\n */\n\nimport { EventBus } from '../shared/EventBus.js';\nimport { getSocialApiService } from './SocialApiService.js';\nimport { getAuthService } from '../auth/AuthService.js';\nimport { getTransportManager, initTransport, TransportEvent } from '../transport/index.js';\nimport { getBackendApiBase, getBackendWsUrl } from '../shared/backend.js';\n\n// Event names\nexport const SocialEvents = {\n  FRIENDS_UPDATED: 'social:friends:updated',\n  REQUESTS_UPDATED: 'social:requests:updated',\n  NOTIFICATIONS_UPDATED: 'social:notifications:updated',\n  UNREAD_COUNT_CHANGED: 'social:unread:changed',\n  FRIEND_ONLINE: 'social:friend:online',\n  FRIEND_OFFLINE: 'social:friend:offline',\n  NEW_NOTIFICATION: 'social:notification:new',\n};\n\nexport class SocialStore {\n  constructor() {\n    this.eventBus = new EventBus();\n    this.api = getSocialApiService();\n    this._authService = getAuthService();\n    this._transport = null;\n    this._transportReady = false;\n    this._transportSubscriptions = [];\n    this._authUnsubscribe = this._authService.subscribe((state) => {\n      this._handleAuthStateChange(state);\n    });\n\n    // State\n    this.friends = [];\n    this.incomingRequests = [];\n    this.outgoingRequests = [];\n    this.notifications = [];\n    this.unreadCount = 0;\n\n    // Loading states\n    this.loading = {\n      friends: false,\n      requests: false,\n      notifications: false,\n    };\n\n    // Polling interval (for fallback when WS not available)\n    this.pollInterval = null;\n    this._wsPollingFallbackMs = 300000;\n  }\n\n  // =========================================================================\n  // EVENT SUBSCRIPTION\n  // =========================================================================\n\n  /**\n   * Subscribe to store events\n   * @param {string} event - Event name from SocialEvents\n   * @param {Function} handler - Event handler\n   * @returns {Function} Unsubscribe function\n   */\n  on(event, handler) {\n    this.eventBus.on(event, handler);\n    return () => this.eventBus.off(event, handler);\n  }\n\n  /**\n   * Emit event to subscribers\n   */\n  _emit(event, payload) {\n    this.eventBus.emit(event, payload);\n  }\n\n  // =========================================================================\n  // FRIENDS\n  // =========================================================================\n\n  /**\n   * Refresh friends list from API\n   */\n  async refreshFriends() {\n    if (this.loading.friends) return;\n\n    this.loading.friends = true;\n    try {\n      const result = await this.api.listFriends();\n      this.friends = result.friends;\n      this._emit(SocialEvents.FRIENDS_UPDATED, this.friends);\n    } catch (err) {\n      console.error('[SocialStore] Failed to refresh friends:', err);\n    } finally {\n      this.loading.friends = false;\n    }\n  }\n\n  /**\n   * Send a friend request\n   */\n  async sendFriendRequest(targetUserId, message) {\n    const result = await this.api.sendFriendRequest(targetUserId, message);\n    await this.refreshRequests();\n    return result;\n  }\n\n  /**\n   * Search users for friend adding\n   */\n  async searchUsers(query, options = {}) {\n    return this.api.searchUsers(query, options);\n  }\n\n  /**\n   * Accept a friend request\n   */\n  async acceptFriendRequest(requestId) {\n    const result = await this.api.acceptFriendRequest(requestId);\n    await Promise.all([this.refreshFriends(), this.refreshRequests()]);\n    return result;\n  }\n\n  /**\n   * Decline a friend request\n   */\n  async declineFriendRequest(requestId) {\n    const result = await this.api.declineFriendRequest(requestId);\n    await this.refreshRequests();\n    return result;\n  }\n\n  /**\n   * Remove a friend\n   */\n  async removeFriend(userId) {\n    await this.api.removeFriend(userId);\n    await this.refreshFriends();\n  }\n\n  // =========================================================================\n  // REQUESTS\n  // =========================================================================\n\n  /**\n   * Refresh friend requests from API\n   */\n  async refreshRequests() {\n    if (this.loading.requests) return;\n\n    this.loading.requests = true;\n    try {\n      const [incoming, outgoing] = await Promise.all([\n        this.api.getIncomingRequests(),\n        this.api.getOutgoingRequests(),\n      ]);\n      this.incomingRequests = incoming.requests;\n      this.outgoingRequests = outgoing.requests;\n      this._emit(SocialEvents.REQUESTS_UPDATED, {\n        incoming: this.incomingRequests,\n        outgoing: this.outgoingRequests,\n      });\n    } catch (err) {\n      console.error('[SocialStore] Failed to refresh requests:', err);\n    } finally {\n      this.loading.requests = false;\n    }\n  }\n\n  // =========================================================================\n  // NOTIFICATIONS\n  // =========================================================================\n\n  /**\n   * Refresh notifications from API\n   */\n  async refreshNotifications() {\n    if (this.loading.notifications) return;\n\n    this.loading.notifications = true;\n    try {\n      const result = await this.api.listNotifications();\n      this.notifications = result.notifications;\n      const oldCount = this.unreadCount;\n      this.unreadCount = result.unreadCount;\n\n      this._emit(SocialEvents.NOTIFICATIONS_UPDATED, this.notifications);\n      if (oldCount !== this.unreadCount) {\n        this._emit(SocialEvents.UNREAD_COUNT_CHANGED, this.unreadCount);\n      }\n    } catch (err) {\n      console.error('[SocialStore] Failed to refresh notifications:', err);\n    } finally {\n      this.loading.notifications = false;\n    }\n  }\n\n  /**\n   * Mark a notification as read\n   */\n  async markNotificationRead(notificationId) {\n    await this.api.updateNotificationStatus(notificationId, 'read');\n    await this.refreshNotifications();\n  }\n\n  /**\n   * Dismiss a notification\n   */\n  async dismissNotification(notificationId) {\n    await this.api.updateNotificationStatus(notificationId, 'dismissed');\n    await this.refreshNotifications();\n  }\n\n  /**\n   * Mark all notifications as read\n   */\n  async markAllRead() {\n    await this.api.markAllNotificationsRead();\n    await this.refreshNotifications();\n  }\n\n  // =========================================================================\n  // REAL-TIME UPDATES\n  // =========================================================================\n\n  /**\n   * Handle incoming notification push from transport\n   * @param {Object} notification - Notification object\n   */\n  handleNotificationPush(notification) {\n    // Add to notifications array\n    const exists = this.notifications.find((n) => n.id === notification.id);\n    if (!exists) {\n      this.notifications.unshift(notification);\n      this.unreadCount++;\n      this._emit(SocialEvents.NOTIFICATIONS_UPDATED, this.notifications);\n      this._emit(SocialEvents.UNREAD_COUNT_CHANGED, this.unreadCount);\n      this._emit(SocialEvents.NEW_NOTIFICATION, notification);\n    }\n\n    // Handle specific notification types\n    if (notification.type === 'friend_request') {\n      this.refreshRequests();\n    } else if (notification.type === 'friend_accept') {\n      this.refreshFriends();\n      this.refreshRequests();\n    }\n  }\n\n  /**\n   * Handle friend status change\n   */\n  handleFriendStatusChange(userId, status) {\n    const friend = this.friends.find((f) => f.userId === userId);\n    if (friend) {\n      const oldStatus = friend.status;\n      friend.status = status;\n      this._emit(SocialEvents.FRIENDS_UPDATED, this.friends);\n\n      if (oldStatus !== 'online' && status === 'online') {\n        this._emit(SocialEvents.FRIEND_ONLINE, friend);\n      } else if (oldStatus === 'online' && status !== 'online') {\n        this._emit(SocialEvents.FRIEND_OFFLINE, friend);\n      }\n    }\n  }\n\n  // =========================================================================\n  // LIFECYCLE\n  // =========================================================================\n\n  /**\n   * Initialize store and start polling\n   */\n  async init() {\n    await Promise.all([\n      this.refreshFriends(),\n      this.refreshRequests(),\n      this.refreshNotifications(),\n    ]);\n\n    let connected = false;\n    try {\n      connected = await this._ensureTransport();\n    } catch (error) {\n      connected = false;\n      console.warn('[SocialStore] Transport init failed, using polling', error);\n    }\n    if (connected) {\n      this.startPolling(this._wsPollingFallbackMs);\n    } else {\n      // Start polling as fallback (60 second interval)\n      this.startPolling(60000);\n    }\n  }\n\n  /**\n   * Start polling for updates\n   */\n  startPolling(intervalMs = 60000) {\n    this.stopPolling();\n    this.pollInterval = setInterval(() => {\n      this.refreshNotifications();\n      this.refreshRequests();\n    }, intervalMs);\n  }\n\n  /**\n   * Stop polling\n   */\n  stopPolling() {\n    if (this.pollInterval) {\n      clearInterval(this.pollInterval);\n      this.pollInterval = null;\n    }\n  }\n\n  /**\n   * Cleanup\n   */\n  destroy() {\n    this.stopPolling();\n    this._clearTransportSubscriptions();\n    if (this._authUnsubscribe) {\n      this._authUnsubscribe();\n      this._authUnsubscribe = null;\n    }\n    this.eventBus = new EventBus();\n  }\n\n  async _ensureTransport() {\n    const authState = this._authService?.getState?.();\n    if (!authState?.isAuthenticated) return false;\n    const wsUrl = this._resolveWsUrl();\n    if (!wsUrl) return false;\n\n    const manager = getTransportManager();\n    if (!manager.active) {\n      const httpUrl = getBackendApiBase();\n      await initTransport({ wsUrl, httpUrl });\n    }\n    this._transport = getTransportManager();\n    this._transportReady = true;\n\n    if (!this._transport.isConnected) {\n      const sessionId = authState.session?.sessionId || null;\n      const deviceId = authState.device?.deviceId || authState.deviceId || null;\n      if (sessionId && deviceId) {\n        this._transport.setCredentials(sessionId, deviceId);\n      }\n      await this._transport.connect();\n    }\n\n    const accessToken = this._authService?.accessToken;\n    if (accessToken) {\n      await this._transport.send(TransportEvent.AUTH_STATUS, { token: accessToken });\n    }\n\n    this._ensureTransportSubscriptions();\n    return true;\n  }\n\n  _ensureTransportSubscriptions() {\n    if (!this._transport || this._transportSubscriptions.length) return;\n    this._transportSubscriptions.push(\n      this._transport.subscribe(TransportEvent.NOTIFICATION_PUSH, (message) => {\n        const notification = message.payload?.notification;\n        if (notification) {\n          this.handleNotificationPush(notification);\n        }\n      })\n    );\n  }\n\n  _clearTransportSubscriptions() {\n    this._transportSubscriptions.forEach((sub) => sub?.unsubscribe?.());\n    this._transportSubscriptions = [];\n  }\n\n  _handleAuthStateChange(state) {\n    if (!state?.isAuthenticated) {\n      this._clearTransportSubscriptions();\n      this.stopPolling();\n      return;\n    }\n    this._ensureTransport().catch((error) => {\n      console.warn('[SocialStore] Transport reconnect failed', error);\n    });\n  }\n\n  _resolveWsUrl() {\n    return getBackendWsUrl();\n  }\n\n  // =========================================================================\n  // GETTERS\n  // =========================================================================\n\n  getFriends() {\n    return this.friends;\n  }\n\n  getIncomingRequests() {\n    return this.incomingRequests;\n  }\n\n  getOutgoingRequests() {\n    return this.outgoingRequests;\n  }\n\n  getNotifications() {\n    return this.notifications;\n  }\n\n  getUnreadCount() {\n    return this.unreadCount;\n  }\n}\n\n// Singleton instance\nlet socialStoreInstance = null;\n\nexport function getSocialStore() {\n  if (!socialStoreInstance) {\n    socialStoreInstance = new SocialStore();\n  }\n  return socialStoreInstance;\n}\n","export const AVATAR_MODEL_ID = 'character-v1';\n\nexport const DEFAULT_AVATAR_APPEARANCE = Object.freeze({\n  modelId: AVATAR_MODEL_ID,\n  color: '#b8c4d8',\n  roughness: 0.62,\n  metalness: 0.12,\n});\n\nconst HEX_COLOR = /^#[0-9a-f]{6}$/i;\n\nconst clampNumber = (value, fallback, min, max) => {\n  const numeric = Number(value);\n  return Number.isFinite(numeric) ? Math.min(max, Math.max(min, numeric)) : fallback;\n};\n\n/**\n * Keep the public presence payload deliberately small and renderer-agnostic.\n * `modelId` is an extension point for future scanned/uploaded avatars; today\n * only the bundled character is accepted.\n */\nexport function normalizeAvatarAppearance(value = {}, fallback = DEFAULT_AVATAR_APPEARANCE) {\n  const source = value && typeof value === 'object' ? value : {};\n  const base = fallback && typeof fallback === 'object' ? fallback : DEFAULT_AVATAR_APPEARANCE;\n  const rawColor = typeof source.color === 'string' ? source.color.trim() : '';\n  const baseColor = typeof base.color === 'string' && HEX_COLOR.test(base.color)\n    ? base.color.toLowerCase()\n    : DEFAULT_AVATAR_APPEARANCE.color;\n\n  return {\n    modelId: source.modelId === AVATAR_MODEL_ID ? AVATAR_MODEL_ID : AVATAR_MODEL_ID,\n    color: HEX_COLOR.test(rawColor) ? rawColor.toLowerCase() : baseColor,\n    roughness: clampNumber(source.roughness, Number(base.roughness), 0.1, 1),\n    metalness: clampNumber(source.metalness, Number(base.metalness), 0, 0.8),\n  };\n}\n\nexport function avatarAppearanceSignature(value) {\n  const appearance = normalizeAvatarAppearance(value);\n  return [\n    appearance.modelId,\n    appearance.color,\n    appearance.roughness.toFixed(3),\n    appearance.metalness.toFixed(3),\n  ].join('|');\n}\n\nexport default normalizeAvatarAppearance;\n","import * as THREE from 'three';\nimport { PresenceClient } from '../../modules/presence-client.js';\nimport { worldPosToLatLonLocal, ellipsoidRadiusForWorldDir } from '../../modules/geometry-utils.js';\nimport { PLANET_RADIUS, DEG2RAD } from '../../modules/constants.js';\nimport { getAuthService } from '../auth/AuthService.js';\nimport { getSocialStore, SocialEvents } from '../social/SocialStore.js';\nimport { getTransportManager, initTransport, TransportEvent } from '../transport/index.js';\nimport { getBackendApiBase, getBackendWsUrl } from '../shared/backend.js';\nimport { normalizeAvatarAppearance } from '../avatar/AvatarAppearance.js';\n\nlet p2pModulePromise = null;\nlet nknIdentityStorePromise = null;\n\nfunction loadP2PModule() {\n    if (!p2pModulePromise) {\n        p2pModulePromise = import('../p2p/index.js');\n    }\n    return p2pModulePromise;\n}\n\nfunction loadNknIdentityStore() {\n    if (!nknIdentityStorePromise) {\n        nknIdentityStorePromise = import('../p2p/NknIdentityStore.js');\n    }\n    return nknIdentityStorePromise;\n}\n\nconst DEFAULT_SHARE_CONFIG = {\n    friends: {\n        enabled: true,\n        location: true,\n        altitude: true,\n        orientation: true,\n        motion: true,\n        label: true,\n        view: false\n    },\n    public: {\n        enabled: true,\n        location: true,\n        altitude: true,\n        orientation: true,\n        motion: true,\n        label: true,\n        view: true\n    }\n};\n\nconst DEFAULT_PEER_SHARE = {\n    friends: {\n        enabled: true,\n        location: true,\n        altitude: true,\n        orientation: true,\n        motion: true,\n        label: true,\n        view: true\n    },\n    public: {\n        enabled: true,\n        location: true,\n        altitude: true,\n        orientation: true,\n        motion: true,\n        label: true,\n        view: true\n    }\n};\n\nfunction normalizeAvatarConfig(config = {}) {\n    const source = config && typeof config === 'object' ? config : {};\n    return {\n        ...source,\n        appearance: normalizeAvatarAppearance(source.appearance),\n    };\n}\n\nexport const PUBLIC_PRESENCE_RADIUS_M = 100_000;\nexport const DEFAULT_PRESENCE_STREAM_HZ = 24;\nexport const MAX_PRESENCE_STREAM_HZ = 30;\n\nconst normalizeNetworkAddress = (address, network = 'noclip') => {\n    const raw = String(address || '').trim();\n    if (!raw) return '';\n    if (raw.includes('.')) return raw;\n    const prefix = String(network || '').trim().toLowerCase();\n    if (prefix === 'hydra' || prefix === 'noclip') return `${prefix}.${raw}`;\n  return raw;\n};\n\nconst TRANSPORT_ORDER = ['nkn', 'cloudflare', 'nats', 'upnp', 'local'];\n\nconst normalizeTransportLabel = (value) => {\n    const key = String(value || '').trim().toLowerCase();\n    if (!key) return '';\n    if (key === 'cloudflared' || key === 'cf') return 'cloudflare';\n    if (key === 'localhost' || key === 'lan') return 'local';\n    if (TRANSPORT_ORDER.includes(key)) return key;\n    return '';\n};\n\nconst endpointFromCandidate = (value) => {\n    if (!value) return '';\n    if (typeof value === 'string') return value.trim();\n    if (typeof value !== 'object') return '';\n    return String(\n        value.endpoint ||\n        value.base_url ||\n        value.baseUrl ||\n        value.http_endpoint ||\n        value.httpEndpoint ||\n        value.nkn_address ||\n        value.address ||\n        ''\n    ).trim();\n};\n\nconst candidateTimestampMs = (value, fallbackMs = 0) => {\n    if (!value || typeof value !== 'object') return Number(fallbackMs || 0);\n    const direct = Number(\n        value.last_verified_ms ||\n        value.lastVerifiedMs ||\n        value.updated_at_ms ||\n        value.updatedAtMs ||\n        value.last_seen_ms ||\n        value.lastSeenMs ||\n        0\n    );\n    if (Number.isFinite(direct) && direct > 0) return direct;\n    const iso = String(value.last_verified || value.lastVerified || value.updated_at || value.updatedAt || '').trim();\n    if (iso) {\n        const parsed = Date.parse(iso);\n        if (Number.isFinite(parsed) && parsed > 0) return parsed;\n    }\n    return Number(fallbackMs || 0);\n};\n\nconst normalizeEndpointCandidates = (input, fallbackMs = 0) => {\n    const src = input && typeof input === 'object' ? input : {};\n    const out = {};\n    const assign = (transportKey, candidate) => {\n        const transport = normalizeTransportLabel(transportKey || candidate?.transport || candidate?.selected_transport || candidate?.selectedTransport);\n        if (!transport) return;\n        const endpoint = endpointFromCandidate(candidate);\n        if (!endpoint) return;\n        out[transport] = {\n            endpoint,\n            lastVerifiedMs: candidateTimestampMs(candidate, fallbackMs),\n        };\n    };\n    Object.entries(src).forEach(([transport, candidate]) => assign(transport, candidate));\n    return out;\n};\n\nconst selectTransportCandidate = ({ selectedTransport = '', endpointCandidates = {}, staleRejectionCount = 0, fallbackMs = 0 } = {}) => {\n    const selected = normalizeTransportLabel(selectedTransport);\n    const candidates = normalizeEndpointCandidates(endpointCandidates, fallbackMs);\n    const transports = Object.keys(candidates);\n    if (!transports.length) {\n        return {\n            selectedTransport: selected || '',\n            selectedEndpoint: '',\n            endpointCandidates: {},\n            candidateFreshnessMs: {},\n            staleRejectionCount: Math.max(0, Number(staleRejectionCount || 0) || 0),\n        };\n    }\n    const now = Date.now();\n    const freshness = {};\n    let best = '';\n    let bestScore = Number.NEGATIVE_INFINITY;\n    transports.forEach((transport) => {\n        const candidate = candidates[transport];\n        const ts = Number(candidate?.lastVerifiedMs || 0);\n        const ageMs = ts > 0 ? Math.max(0, now - ts) : Number.MAX_SAFE_INTEGER;\n        freshness[transport] = ageMs;\n        const base = (TRANSPORT_ORDER.length - TRANSPORT_ORDER.indexOf(transport)) * 10;\n        const freshBonus = ageMs === Number.MAX_SAFE_INTEGER ? -30 : Math.max(-25, 25 - Math.floor(ageMs / 10000));\n        const selectedBonus = selected && selected === transport ? 8 : 0;\n        const stalePenalty = Math.max(0, Number(staleRejectionCount || 0)) * 6;\n        const score = base + freshBonus + selectedBonus - stalePenalty;\n        if (score > bestScore) {\n            bestScore = score;\n            best = transport;\n        }\n    });\n    const resolved = best || selected || transports[0];\n    return {\n        selectedTransport: resolved,\n        selectedEndpoint: candidates[resolved]?.endpoint || '',\n        endpointCandidates: candidates,\n        candidateFreshnessMs: freshness,\n        staleRejectionCount: Math.max(0, Math.floor(Number(staleRejectionCount || 0) || 0)),\n    };\n};\n\nexport class PresenceSystem {\n    constructor(options = {}) {\n        this.camera = options.camera || null;\n        this.triTree = options.triTree || null;\n        this.surfaceController = options.surfaceController || null;\n        this.entitySystem = options.entitySystem || null;\n        this.eventBus = options.eventBus || null;\n        this.localPlayer = options.localPlayer || null;\n        this.peerManager = options.peerManager || null;\n\n        this.planetRadius = Number.isFinite(options.planetRadius)\n            ? options.planetRadius\n            : PLANET_RADIUS;\n        this.enabled = options.enabled !== false;\n        // Presence has a small, separately bounded real-time transport lane.\n        // Twenty-four snapshots per second keeps input latency below one\n        // display frame at common refresh rates while render-frame\n        // interpolation supplies smooth 60/90/120 Hz presentation.\n        const requestedUpdateHz = Number.isFinite(options.updateHz)\n            ? Number(options.updateHz)\n            : DEFAULT_PRESENCE_STREAM_HZ;\n        this.updateHz = Math.max(1, Math.min(MAX_PRESENCE_STREAM_HZ, requestedUpdateHz));\n        this.useVisibility = options.useVisibility !== false;\n        this.autoConnect = options.autoConnect !== false;\n        this.useTransport = options.useTransport !== false;\n        this.useP2P = options.useP2P === true;\n\n        this._sendIntervalMs = 1000 / this.updateHz;\n        this._lastSend = 0;\n        this._sequence = 0;\n        this._lastPeerSweep = 0;\n        this._peerStaleMs = Number.isFinite(options.peerStaleMs) ? Math.max(5000, options.peerStaleMs) : 30000;\n        this._localId = null;\n        this._peers = new Map();\n        this._peerEntities = new Map();\n        this._status = { connected: false, id: null };\n        this._xrPresenting = false;\n\n        this._tmpDir = new THREE.Vector3();\n        this._tmpCameraWorld = new THREE.Vector3();\n        this._tmpParentQuat = new THREE.Quaternion();\n        this._tmpLocalQuat = new THREE.Quaternion();\n        this._tmpWorldQuat = new THREE.Quaternion();\n\n        this._authService = getAuthService();\n        this._transport = null;\n        this._transportReady = false;\n        this._transportSubscriptions = [];\n        this._connectPromise = null;\n\n        this._p2pTransport = null;\n        this._p2pDirectory = null;\n        this._p2pRegistry = null;\n        this._p2pSubscriptions = [];\n        this._p2pReady = false;\n        this._p2pConnectPromise = null;\n        this._p2pCooldownUntilMs = 0;\n        this._p2pFailureCount = 0;\n        this._p2pCooldownBaseMs = 60 * 1000;\n        this._p2pCooldownMaxMs = 10 * 60 * 1000;\n\n        this._shareConfig = this._normalizeShareConfig(options.shareConfig);\n        this._avatarConfig = normalizeAvatarConfig(options.avatarConfig);\n        this._socialStore = getSocialStore();\n        this._friendIds = new Set();\n        this._socialSubscriptions = [];\n        this._refreshFriendIds();\n        this._subscribeSocialUpdates();\n\n        this.client = this.useTransport ? null : new PresenceClient({\n            url: options.url || null,\n            path: options.path || '/presence',\n            autoReconnect: options.autoReconnect !== false,\n            reconnectMinMs: options.reconnectMinMs,\n            reconnectMaxMs: options.reconnectMaxMs,\n            maxBufferedBytes: options.maxBufferedBytes,\n            onWelcome: (msg) => this._handleWelcome(msg),\n            onJoin: (peer) => this._handlePeerUpdate(peer),\n            onUpdate: (peer) => this._handlePeerUpdate(peer),\n            onLeave: (id) => this._handlePeerLeave(id),\n            onStatus: (status) => { this._status = status; },\n            onError: (error) => this._handleError(error)\n        });\n    }\n\n    connect(options = {}) {\n        if (this.useTransport) {\n            void this._connectTransport(options).catch((error) => this._handleError(error));\n            return;\n        }\n        if (options.url) this.client.url = options.url;\n        if (options.path) this.client.path = options.path;\n        this.client.connect();\n    }\n\n    disconnect() {\n        this._stopMapClock();\n        if (this.useTransport) {\n            void this._sendTransportLeave();\n            this._clearTransportSubscriptions();\n            this._clearPeers();\n            this._localId = null;\n            this._status = { connected: false, id: null };\n            this._disableP2PTransport();\n            return;\n        }\n        this.client.disconnect();\n        this._clearPeers();\n    }\n\n    setEnabled(enabled) {\n        this.enabled = !!enabled;\n        if (!this.enabled) {\n            this.disconnect();\n        } else if (this.autoConnect) {\n            this.setMapPresentation(this._mapPresentation ? '2d' : '3d');\n            this.connect();\n        }\n    }\n\n    setUseP2P(enabled) {\n        const next = enabled === true;\n        if (this.useP2P === next) return;\n        this.useP2P = next;\n        if (!next) {\n            this._disableP2PTransport();\n            return;\n        }\n        if (this.enabled && this.autoConnect && this._transportReady) {\n            void this._ensureP2PTransport();\n        }\n    }\n\n    _disableP2PTransport() {\n        this._clearP2PSubscriptions();\n        this._p2pConnectPromise = null;\n        this._p2pCooldownUntilMs = 0;\n        this._p2pFailureCount = 0;\n        const transport = this._p2pTransport;\n        this._p2pTransport = null;\n        if (transport?.disconnect) {\n            void transport.disconnect().catch(() => undefined);\n        }\n    }\n\n    update(_dt, now) {\n        if (!this.enabled) return;\n        if (this.useTransport) {\n            if (this.autoConnect && !this._isTransportConnected()) {\n                void this._connectTransport().catch((error) => this._handleError(error));\n            }\n            if (this.useP2P && !this._p2pReady) {\n                void this._ensureP2PTransport();\n            }\n        } else if (this.autoConnect && !this.client.isConnected()) {\n            this.client.connect();\n        }\n        const timeMs = Number.isFinite(now) ? now : performance.now();\n        if (timeMs - this._lastPeerSweep >= 2000) {\n            this._lastPeerSweep = timeMs;\n            const wallNow = Date.now();\n            for (const [peerId, entry] of this._peers) {\n                if (wallNow - (entry?.lastSeen || 0) > this._peerStaleMs) {\n                    this._handlePeerLeave(peerId);\n                }\n            }\n        }\n        if (timeMs - this._lastSend < this._sendIntervalMs) return;\n        const state = this._buildLocalState();\n        if (!state) {\n            if (this._publishing) {\n                this._publishing = false;\n                void this._sendTransportLeave();\n            }\n            return;\n        }\n        if (this.useTransport) {\n            if (!this._isTransportConnected() || this._sendPending) return;\n            this._lastSend = timeMs;\n            this._publishing = true;\n            this._sendPending = true;\n            this._transport.send(TransportEvent.PRESENCE_UPDATE, { state }, { noReply: true })\n                .catch((error) => this._handleError(error))\n                .finally(() => { this._sendPending = false; });\n            this._broadcastP2PPresence(state);\n            return;\n        }\n        if (this.client.sendUpdate(state)) {\n            this._lastSend = timeMs;\n        }\n    }\n\n    setMapPresentation(mode) {\n        this._mapPresentation = mode === '2d';\n        this._stopMapClock();\n        if (this._mapPresentation && this.enabled) {\n            // Network-only cadence: never revive Three, terrain, or avatars.\n            this._mapClock = setInterval(() => this.update(0, performance.now()), this._sendIntervalMs);\n        } else {\n            this._mapState = null;\n            for (const [id, entry] of this._peers) {\n                if (entry.state) this.peerManager?.handlePeerUpdate?.(id, entry.state);\n            }\n        }\n    }\n\n    setMapState(state) {\n        if (Number.isFinite(state?.lat) && Number.isFinite(state?.lon)) this._mapState = state;\n    }\n\n    _stopMapClock() {\n        if (this._mapClock != null) clearInterval(this._mapClock);\n        this._mapClock = null;\n    }\n\n    getStatus() {\n        return {\n            connected: this.useTransport ? this._isTransportConnected() : this.client.isConnected(),\n            id: this._localId || (this.client ? this.client.getId() : null),\n            peers: this._peers.size,\n            publicRadiusM: PUBLIC_PRESENCE_RADIUS_M\n        };\n    }\n\n    getPeers() {\n        return Array.from(this._peers.values())\n            .map((entry) => entry.state)\n            .filter((state) => !!state);\n    }\n\n    _handleWelcome(msg) {\n        this._localId = msg?.id || null;\n        this._retireConfirmedLocalEcho();\n        if (Array.isArray(msg?.peers)) {\n            msg.peers.forEach((peer) => this._handlePeerUpdate(peer));\n        }\n        this.eventBus?.emit?.('presence:ready', { id: this._localId });\n    }\n\n    _handlePeerUpdate(peer) {\n        if (!peer) return;\n        const peerId = peer.id || peer.deviceId || null;\n        if (!peerId) return;\n        if (this._isLocalEcho(peer, peerId)) {\n            if (this._peers.has(peerId)) this._handlePeerLeave(peerId);\n            return;\n        }\n        const entry = this._peers.get(peerId) || { state: null, lastSeen: 0, lastSequence: -1 };\n        const sequence = Number(peer.seq);\n        if (Number.isFinite(sequence) && sequence <= Number(entry.lastSequence ?? -1)) return;\n        if (Number.isFinite(sequence)) entry.lastSequence = sequence;\n        entry.rawState = peer;\n        const selected = this._selectPeerState(peer);\n        // Share masks control fields, never the server's instance identity.\n        const filteredState = selected ? { ...selected, id: peerId } : null;\n        entry.state = filteredState;\n        entry.lastSeen = Date.now();\n        this._peers.set(peerId, entry);\n\n        if (!filteredState || !Number.isFinite(filteredState.lat) || !Number.isFinite(filteredState.lon)) {\n            this.peerManager?.handlePeerLeave?.(peerId);\n            return;\n        }\n\n        // Forward to PeerManager for avatar rendering\n        if (!this._mapPresentation) this.peerManager?.handlePeerUpdate?.(peerId, filteredState);\n\n        // Emit event for minimap and other listeners\n        this.eventBus?.emit?.('presence:peerUpdate', { peerId, state: filteredState });\n\n        // Skip entity marker creation if PeerManager is handling avatars\n        // The PeerManager renders proper 3D avatars instead of sphere markers\n        if (this.peerManager) return;\n\n        // Fallback: create entity markers if no PeerManager\n        const entityId = this._ensureEntity(peerId);\n        if (!entityId) return;\n        const payload = {\n            entity_id: entityId,\n            lat: filteredState.lat,\n            lon: filteredState.lon,\n            elevation_m: filteredState.elevation_m,\n            offset_m: 0\n        };\n        if (filteredState.q && Number.isFinite(filteredState.q.x)) {\n            payload.orientation_quat = [filteredState.q.x, filteredState.q.y, filteredState.q.z, filteredState.q.w];\n        }\n        this.entitySystem?.updateFromStream?.(payload);\n    }\n\n    _handlePeerLeave(id) {\n        if (!id) return;\n\n        // Forward to PeerManager for avatar cleanup\n        this.peerManager?.handlePeerLeave?.(id);\n\n        // Emit event for minimap and other listeners\n        this.eventBus?.emit?.('presence:peerLeave', { peerId: id });\n\n        // Clean up entity markers only if not using PeerManager\n        if (!this.peerManager) {\n            const entityId = this._peerEntities.get(id);\n            if (entityId) {\n                this.entitySystem?.remove?.(entityId);\n                this._peerEntities.delete(id);\n            }\n        }\n        this._peers.delete(id);\n    }\n\n    _handleError(error) {\n        this.eventBus?.emit?.('presence:error', { error });\n    }\n\n    async _connectTransport(options = {}) {\n        if (this._connectPromise) return this._connectPromise;\n        this._connectPromise = (async () => {\n            const authState = this._authService?.getState?.();\n            const wsUrl = options.wsUrl || this._resolveWsUrl();\n            if (!wsUrl) {\n                throw new Error('WebSocket URL unavailable');\n            }\n            const httpUrl = options.httpUrl || getBackendApiBase();\n            await initTransport({ wsUrl, httpUrl });\n            this._transport = getTransportManager();\n            this._transportReady = true;\n            if (!this._transport.isConnected) {\n                const sessionId = authState.session?.sessionId || null;\n                const deviceId = authState.device?.deviceId || authState.deviceId || null;\n                if (sessionId && deviceId) {\n                    this._transport.setCredentials(sessionId, deviceId);\n                }\n                await this._transport.connect();\n            }\n            const accessToken = this._authService?.accessToken || null;\n            if (accessToken) {\n                await this._transport.send(TransportEvent.AUTH_STATUS, { token: accessToken });\n            }\n            this._ensureTransportSubscriptions();\n            const response = await this._transport.send(TransportEvent.PRESENCE_JOIN, {});\n            this._handleTransportJoin(response?.payload);\n            const initialState = this._buildLocalState();\n            if (initialState) {\n                await this._transport.send(TransportEvent.PRESENCE_UPDATE, { state: initialState }, { noReply: true });\n                this._publishing = true;\n            }\n            await this._ensureP2PTransport();\n            this._status = { connected: true, id: this._localId };\n            return this._transport;\n        })().catch((error) => {\n            this._handleError(error);\n            return null;\n        }).finally(() => {\n            this._connectPromise = null;\n        });\n        return this._connectPromise;\n    }\n\n    _ensureTransportSubscriptions() {\n        if (!this._transport || this._transportSubscriptions.length) return;\n        this._transportSubscriptions.push(\n            this._transport.subscribe(TransportEvent.PRESENCE_UPDATE, (message) => {\n                const payload = message?.payload;\n                const peer = payload?.peer || payload?.state || payload?.peerState || payload || null;\n                if (peer) this._handlePeerUpdate(peer);\n            }),\n            this._transport.subscribe(TransportEvent.PRESENCE_LEAVE, (message) => {\n                const peerId = message?.payload?.id || null;\n                if (peerId) this._handlePeerLeave(peerId);\n            })\n        );\n    }\n\n    _clearTransportSubscriptions() {\n        this._transportSubscriptions.forEach((sub) => sub?.unsubscribe?.());\n        this._transportSubscriptions = [];\n    }\n\n    _clearP2PSubscriptions() {\n        this._p2pSubscriptions.forEach((sub) => sub?.unsubscribe?.());\n        this._p2pSubscriptions = [];\n        this._p2pReady = false;\n    }\n\n    async _ensureP2PTransport() {\n        if (!this.useP2P || this._p2pReady) return;\n        if (this._p2pConnectPromise) return this._p2pConnectPromise;\n        const now = Date.now();\n        if (this._p2pCooldownUntilMs && now < this._p2pCooldownUntilMs) return;\n        this._p2pConnectPromise = (async () => {\n        try {\n            const { getSharedNknTransport, P2PDirectory, P2PRegistryClient } = await loadP2PModule();\n            if (!this._p2pTransport) {\n                this._p2pTransport = getSharedNknTransport({ identifier: 'earth' });\n            }\n            if (!this._p2pRegistry) {\n                this._p2pRegistry = new P2PRegistryClient();\n            }\n            if (!this._p2pDirectory) {\n                this._p2pDirectory = new P2PDirectory();\n                this._p2pDirectory.connect();\n                void this._p2pDirectory.refresh().catch(() => undefined);\n            }\n            // Exact coordinates are never subscribed over the global P2P\n            // directory. The backend establishes the reciprocal, public,\n            // 100 km nearby cohort before precise presence is exchanged.\n            await this._p2pTransport.connect();\n            const { getStoredAddress } = await loadNknIdentityStore();\n            const address = this._p2pTransport.address || getStoredAddress();\n            if (address) {\n                const canonicalAddress = normalizeNetworkAddress(address, 'noclip');\n                await this._p2pRegistry.upsertEndpoint({\n                    nknAddress: canonicalAddress,\n                    selectedTransport: 'nkn',\n                    endpointCandidates: {\n                        nkn: canonicalAddress,\n                        cloudflare: '',\n                        local: '',\n                        upnp: '',\n                        nats: ''\n                    },\n                    discoverySource: 'presence.system',\n                    network: 'noclip',\n                    updateDeviceCaps: true\n                })\n                    .catch(() => undefined);\n            }\n            this._p2pReady = true;\n            this._p2pFailureCount = 0;\n            this._p2pCooldownUntilMs = 0;\n        } catch {\n            this._p2pReady = false;\n            this._clearP2PSubscriptions();\n            this._p2pFailureCount = Math.min(8, this._p2pFailureCount + 1);\n            const cooldown = Math.min(\n                this._p2pCooldownMaxMs,\n                this._p2pCooldownBaseMs * Math.pow(2, this._p2pFailureCount - 1)\n            );\n            this._p2pCooldownUntilMs = Date.now() + cooldown;\n            if (this._p2pTransport?.disconnect) {\n                await this._p2pTransport.disconnect().catch(() => undefined);\n            }\n        }\n        })().finally(() => {\n            this._p2pConnectPromise = null;\n        });\n        return this._p2pConnectPromise;\n    }\n\n    _handleP2PPresence(message) {\n        const payload = message?.payload || null;\n        const state = payload?.state || null;\n        if (!state || typeof state !== 'object') return;\n        const peer = { ...state };\n        if (!peer.id) {\n            peer.id = peer.deviceId || peer.userId || message?.from || null;\n        }\n        if (!peer.id) return;\n        if (this._isLocalEcho(peer, peer.id)) return;\n        this._handlePeerUpdate(peer);\n    }\n\n    _broadcastP2PPresence(state) {\n        // Exact geolocation is routed by the backend's reciprocal public\n        // 100 km cohort. Broadcasting it to the global P2P directory\n        // would disclose coordinates before that gate can run. P2P remains\n        // available for post-discovery media/comms, never raw presence fanout.\n        void state;\n    }\n\n    async _sendTransportLeave() {\n        if (!this._transport || !this._transport.isConnected) return;\n        try {\n            await this._transport.send(TransportEvent.PRESENCE_LEAVE, {}, { noReply: true });\n        } catch (error) {\n            this._handleError(error);\n        }\n    }\n\n    _handleTransportJoin(payload) {\n        if (!payload) return;\n        const selfId = payload.selfId || null;\n        if (selfId) {\n            this._localId = selfId;\n            this._retireConfirmedLocalEcho();\n            this.eventBus?.emit?.('presence:ready', { id: this._localId });\n        }\n        if (Array.isArray(payload.peers)) {\n            payload.peers.forEach((peer) => this._handlePeerUpdate(peer));\n        }\n    }\n\n    _resolveWsUrl() {\n        return getBackendWsUrl();\n    }\n\n    _isTransportConnected() {\n        return !!this._transport && this._transport.isConnected;\n    }\n\n    _clearPeers() {\n        for (const peerId of this._peers.keys()) {\n            this.peerManager?.handlePeerLeave?.(peerId);\n            this.eventBus?.emit?.('presence:peerLeave', { peerId });\n        }\n        for (const [peerId, entityId] of this._peerEntities.entries()) {\n            if (entityId) {\n                this.entitySystem?.remove?.(entityId);\n            }\n        }\n        this._peerEntities.clear();\n        this._peers.clear();\n    }\n\n    _ensureEntity(peerId) {\n        if (!this.entitySystem) return null;\n        let entityId = this._peerEntities.get(peerId);\n        if (entityId) return entityId;\n        entityId = 'peer-' + peerId;\n        this._peerEntities.set(peerId, entityId);\n        this.entitySystem.upsert({\n            entity_id: entityId,\n            color: this._colorForPeer(peerId)\n        });\n        return entityId;\n    }\n\n    _buildLocalState() {\n        if (this._mapPresentation && !this._mapState) return null;\n        if (!this.camera) return null;\n        const planetGroup = this.triTree?.group || null;\n        // The camera lives below worldRoot/vrDolly in immersive sessions. Use\n        // the published physical world pose (or resolve the hierarchy) instead\n        // of treating its centimetre-scale room position as an ECEF position.\n        const published = this.camera?.userData?.worldPosition;\n        const camPos = published?.isVector3\n            ? this._tmpCameraWorld.copy(published)\n            : this.camera.getWorldPosition(this._tmpCameraWorld);\n        const camDist = camPos.length();\n        if (!Number.isFinite(camDist) || camDist <= 0) return null;\n        const latLon = worldPosToLatLonLocal(camPos, planetGroup);\n        if (!latLon) return null;\n        const headingDeg = this.surfaceController?.getSurfaceHeadingDeg?.();\n        const pitchDeg = this.surfaceController?.getSurfacePitchDeg?.();\n        const label = this._getLocalLabel();\n\n        const authState = this._authService?.getState?.();\n        const deviceId = authState?.device?.deviceId || authState?.deviceId || null;\n        const userId = authState?.user?.id || authState?.user?.userId || authState?.user?.uuid || null;\n        const localQuat = this._getLocalCameraQuat(planetGroup);\n        const ellipsoidR = ellipsoidRadiusForWorldDir(camPos, planetGroup);\n        const state = {\n            seq: (Number(this._sequence) || 0) + 1,\n            sentAtMs: Date.now(),\n            lat: latLon.latDeg,\n            lon: latLon.lonDeg,\n            elevation_m: camDist - ellipsoidR,\n            offset_m: 0,\n            heading_deg: Number.isFinite(headingDeg) ? headingDeg : undefined,\n            pitch_deg: Number.isFinite(pitchDeg) ? pitchDeg : undefined,\n            q: {\n                x: localQuat.x,\n                y: localQuat.y,\n                z: localQuat.z,\n                w: localQuat.w\n            }\n        };\n        this._sequence = state.seq;\n        const contactRadius = this.surfaceController?.getSurfaceContactRadius?.(\n            this.surfaceController?.surfaceState?.up\n        );\n        if (Number.isFinite(contactRadius)) {\n            state.surface_contact_msl = contactRadius - ellipsoidR;\n        }\n        if (deviceId) {\n            state.deviceId = deviceId;\n        }\n        if (userId) {\n            state.userId = userId;\n        }\n        if (label) {\n            state.label = label;\n        }\n        state.appearance = normalizeAvatarAppearance(this._avatarConfig?.appearance);\n        const nknAddress = this._getNknAddress();\n        if (nknAddress) {\n            const canonicalAddress = normalizeNetworkAddress(nknAddress, 'noclip');\n            const candidateStamp = Date.now();\n            state.nknAddress = canonicalAddress;\n            state.network = 'noclip';\n            state.selectedTransport = 'nkn';\n            state.selectedEndpoint = canonicalAddress;\n            state.endpointCandidates = {\n                nkn: {\n                    endpoint: canonicalAddress,\n                    lastVerifiedMs: candidateStamp,\n                },\n                cloudflare: '',\n                local: '',\n                upnp: '',\n                nats: ''\n            };\n            state.discoverySource = 'presence.local';\n        }\n\n        // Add animation state from LocalPlayer or SurfaceController\n        const animState = this._getAnimationState();\n        if (animState) {\n            state.speed = animState.speed;\n            state.animState = animState.animState;\n            state.isGrounded = animState.isGrounded;\n            state.isCrouching = animState.isCrouching;\n            state.isJumping = animState.isJumping;\n            state.isMeditating = animState.isMeditating;\n            state.isSwimming = animState.isSwimming === true;\n        }\n\n        if (this.useVisibility) {\n            const viewDir = this._getLocalViewDir(planetGroup);\n            const viewHalfFov = this._getViewHalfFov();\n            const viewRad = this._computeViewRadius(camDist, ellipsoidR);\n            if (viewDir && Number.isFinite(viewHalfFov) && Number.isFinite(viewRad)) {\n                const viewportWidth = Math.max(1, Math.round(window.innerWidth || 1));\n                const viewportHeight = Math.max(1, Math.round(window.innerHeight || 1));\n                const verticalFov = (Number.isFinite(this.camera.fov) ? this.camera.fov : 60) * DEG2RAD;\n                const avatarHeight = Number.isFinite(this.localPlayer?.avatar?.height)\n                    ? this.localPlayer.avatar.height\n                    : 1.8;\n                const pixelRangeM = THREE.MathUtils.clamp(\n                    avatarHeight * viewportHeight / Math.max(0.001, 2 * Math.tan(verticalFov * 0.5)),\n                    25,\n                    7500\n                );\n                state.view = {\n                    rad: viewRad,\n                    fov: viewHalfFov,\n                    dir: { x: viewDir.x, y: viewDir.y, z: viewDir.z },\n                    viewport: { width: viewportWidth, height: viewportHeight },\n                    avatarHeightM: avatarHeight,\n                    pixelRangeM\n                };\n            }\n        }\n\n        const deviceType = authState?.device?.deviceType;\n        state.deviceClass = ['phone', 'tablet', 'laptop', 'desktop', 'vr'].includes(deviceType)\n            ? deviceType : (typeof navigator !== 'undefined' && /iPhone|Android.*Mobile/i.test(navigator.userAgent) ? 'phone' : 'desktop');\n        state.mapMode = this._mapPresentation ? '2d' : '3d';\n        state.locationSource = this.surfaceController?.isGPSPositionLocked?.() ? 'gps' : 'scene';\n        if (this._mapPresentation) {\n            Object.assign(state, this._mapState);\n            // The hidden camera's quaternion, contact radius and viewshed are stale.\n            delete state.q;\n            delete state.view;\n            delete state.surface_contact_msl;\n            delete state.pitch_deg;\n        }\n        return this._applyShareConfig(state);\n    }\n\n    _getNknAddress() {\n        if (this._p2pTransport?.address) return normalizeNetworkAddress(this._p2pTransport.address, 'noclip');\n        return null;\n    }\n\n    _getLocalLabel() {\n        const authState = this._authService?.getState?.();\n        const userLabel = authState?.user?.username || authState?.user?.handle || authState?.user?.displayName || null;\n        const exposeUsername = this._avatarConfig?.identity?.exposeUsername !== false;\n        if (authState?.isAuthenticated && userLabel && exposeUsername) return String(userLabel).trim();\n\n        const stableId = String(\n            authState?.user?.id\n            || authState?.user?.userId\n            || authState?.device?.deviceId\n            || this._localId\n            || 'nearby'\n        ).replace(/[^a-z0-9]/gi, '').slice(0, 4).toUpperCase() || 'NEAR';\n        return authState?.isAuthenticated ? `User ${stableId}` : `Guest ${stableId}`;\n    }\n\n    _getParentQuat(planetGroup) {\n        if (planetGroup?.getWorldQuaternion) {\n            planetGroup.getWorldQuaternion(this._tmpParentQuat);\n        } else if (planetGroup?.quaternion) {\n            this._tmpParentQuat.copy(planetGroup.quaternion);\n        } else {\n            this._tmpParentQuat.identity();\n        }\n        return this._tmpParentQuat;\n    }\n\n    _getLocalCameraQuat(planetGroup) {\n        const parentQuat = this._getParentQuat(planetGroup);\n        this.camera.getWorldQuaternion(this._tmpWorldQuat);\n        this._tmpLocalQuat.copy(parentQuat).invert().multiply(this._tmpWorldQuat);\n        return this._tmpLocalQuat;\n    }\n\n    _isLocalEcho(peer, peerId = peer?.id || peer?.deviceId || null) {\n        // The server connection is the instance identity in every renderer.\n        // Another tab on this device remains a peer, including in native XR.\n        return peerId != null && this._localId != null && String(peerId) === String(this._localId);\n    }\n\n    _retireConfirmedLocalEcho() {\n        // An update can arrive before welcome/join identifies this connection.\n        // Retire that exact previously rendered instance as soon as its identity\n        // is known; another tab/device/account instance remains a real peer.\n        if (this._localId && this._peers.has(this._localId)) {\n            this._handlePeerLeave(this._localId);\n        }\n    }\n\n    setXRPresenting(presenting) {\n        this._xrPresenting = !!presenting;\n        if (!this._xrPresenting) return;\n        // Remove an already-admitted echo synchronously at session entry; do\n        // not wait for the next 24 Hz presence packet to correct the view.\n        for (const [peerId, entry] of [...this._peers]) {\n            if (this._isLocalEcho(entry?.rawState || entry?.state, peerId)) {\n                this._handlePeerLeave(peerId);\n            }\n        }\n    }\n\n    _getLocalViewDir(planetGroup) {\n        const parentQuat = this._getParentQuat(planetGroup);\n        this.camera.getWorldDirection(this._tmpDir);\n        this._tmpDir.applyQuaternion(parentQuat.invert()).normalize();\n        return this._tmpDir;\n    }\n\n    _getViewHalfFov() {\n        const vFov = (Number.isFinite(this.camera.fov) ? this.camera.fov : 60) * DEG2RAD;\n        const aspect = Number.isFinite(this.camera.aspect)\n            ? this.camera.aspect\n            : ((window.innerWidth || 1) / Math.max(1, window.innerHeight || 1));\n        const hFov = 2 * Math.atan(Math.tan(vFov * 0.5) * Math.max(0.1, aspect));\n        return Math.max(vFov, hFov) * 0.5;\n    }\n\n    _computeViewRadius(camDist, ellipsoidR = null) {\n        const radius = Number.isFinite(camDist) ? camDist : this.planetRadius;\n        const baseRadius = Number.isFinite(ellipsoidR) ? ellipsoidR : this.planetRadius;\n        const horizonRad = Math.acos(THREE.MathUtils.clamp(baseRadius / radius, -1, 1));\n        const minRad = (this.triTree?.surfaceViewshedMinDeg || 0) * DEG2RAD;\n        const marginRadBase = (this.triTree?.surfaceViewshedMarginDeg || 0) * DEG2RAD;\n        const maxRad = (this.triTree?.surfaceCullAngleDeg || 80) * DEG2RAD;\n        const inSurfaceMode = !!this.surfaceController?.isInSurfaceMode?.();\n\n        if (inSurfaceMode) {\n            const surfaceMarginRad = Math.min(marginRadBase, horizonRad * 0.6);\n            return Math.min(maxRad, Math.max(horizonRad, minRad) + surfaceMarginRad);\n        }\n        const orbitMarginRad = Math.max(marginRadBase, horizonRad * 0.9);\n        return Math.min(maxRad, Math.max(horizonRad + orbitMarginRad, minRad));\n    }\n\n    _colorForPeer(peerId) {\n        let hash = 0;\n        for (let i = 0; i < peerId.length; i += 1) {\n            hash = (hash * 31 + peerId.charCodeAt(i)) % 360;\n        }\n        return `hsl(${hash}, 70%, 55%)`;\n    }\n\n    /**\n     * Get animation state from LocalPlayer or SurfaceController\n     */\n    _getAnimationState() {\n        // Prefer LocalPlayer if available\n        if (this.localPlayer?.getAnimationState) {\n            return this.localPlayer.getAnimationState();\n        }\n\n        // Fall back to SurfaceController state\n        if (this.surfaceController) {\n            const speed = this.surfaceController.getSurfaceSpeed?.() ?? 0;\n            const isGrounded = this.surfaceController.isGrounded?.() ?? true;\n            const isCrouching = this.surfaceController.isCrouching?.() ?? false;\n            const isJumping = this.surfaceController.isJumping?.() ?? false;\n            const isSwimming = this.surfaceController.getOceanNavigationState?.().swimming === true;\n\n            // Determine animation state\n            let animState = 'Idle';\n            if (isJumping) {\n                animState = 'Jump';\n            } else if (!isGrounded) {\n                animState = 'Fall';\n            } else if (speed > 3.4) {\n                animState = 'Sprint';\n            } else if (speed > 0.12) {\n                animState = isCrouching ? 'CrouchForward' : 'WalkForward';\n            } else if (isCrouching) {\n                animState = 'CrouchIdle';\n            }\n\n            return {\n                animState,\n                speed,\n                isGrounded,\n                isCrouching,\n                isJumping,\n                isMeditating: false,\n                isSwimming\n            };\n        }\n\n        return null;\n    }\n\n    /**\n     * Set LocalPlayer reference\n     */\n    setLocalPlayer(localPlayer) {\n        this.localPlayer = localPlayer;\n    }\n\n    /**\n     * Set PeerManager reference\n     */\n    setPeerManager(peerManager) {\n        this.peerManager = peerManager;\n    }\n\n    setShareConfig(config) {\n        this._shareConfig = this._normalizeShareConfig(config);\n    }\n\n    setAvatarConfig(config = {}) {\n        this._avatarConfig = normalizeAvatarConfig(config);\n        this.setShareConfig(this._avatarConfig.sharing);\n        // Appearance edits are user-visible multiplayer state, not a change\n        // that should wait behind the previous cadence slot. The next frame\n        // publishes the newly normalized color to every active transport.\n        this._lastSend = Number.NEGATIVE_INFINITY;\n    }\n\n    _subscribeSocialUpdates() {\n        if (!this._socialStore || this._socialSubscriptions.length) return;\n        this._socialSubscriptions.push(\n            this._socialStore.on(SocialEvents.FRIENDS_UPDATED, () => this._refreshFriendIds())\n        );\n    }\n\n    _refreshFriendIds() {\n        if (!this._socialStore?.getFriends) return;\n        const friends = this._socialStore.getFriends() || [];\n        this._friendIds.clear();\n        friends.forEach((friend) => {\n            const friendId = this._extractUserId(friend);\n            if (friendId) this._friendIds.add(friendId);\n        });\n        if (this._peers.size) {\n            this._reapplyPeerStates();\n        }\n    }\n\n    _reapplyPeerStates() {\n        const entries = Array.from(this._peers.values());\n        entries.forEach((entry) => {\n            if (!entry?.rawState) return;\n            this._handlePeerUpdate(entry.rawState);\n        });\n    }\n\n    _selectPeerState(peer) {\n        const share = this._normalizePeerShare(peer?.share);\n        const isFriend = this._isFriend(peer);\n        if (isFriend && !share.friends.enabled && !share.public.enabled) return null;\n        if (!isFriend && !share.public.enabled) return null;\n\n        // Nearby public presence is the baseline even for friends. A friend\n        // mask may enrich it, but disabling the optional friend audience must\n        // never suppress a server-approved nearby avatar.\n        const publicState = share.public.enabled\n            ? this._applyShareMask(peer, share.public)\n            : this._applyShareMask(peer?.friend, share.friends);\n        const endpointCandidates = peer?.endpointCandidates && typeof peer.endpointCandidates === 'object'\n            ? peer.endpointCandidates\n            : (peer?.candidates && typeof peer.candidates === 'object' ? peer.candidates : (peer?.endpoint_candidates && typeof peer.endpoint_candidates === 'object' ? peer.endpoint_candidates : null));\n        const network = String(peer?.network || peer?.meta?.network || '').trim().toLowerCase();\n        const discoverySource = String(peer?.discoverySource || peer?.discovery_source || '').trim();\n        const staleRejectionCount = Number.isFinite(peer?.staleRejectionCount)\n            ? Number(peer.staleRejectionCount)\n            : (Number.isFinite(peer?.stale_rejection_count) ? Number(peer.stale_rejection_count) : 0);\n        const fallbackMs = Number(peer?.updatedAtMs || peer?.updated_at_ms || peer?.lastSeenAt || 0)\n            || (typeof peer?.updatedAt === 'string' ? (Date.parse(peer.updatedAt) || 0) : 0)\n            || Date.now();\n        const selectedCandidate = selectTransportCandidate({\n            selectedTransport: peer?.selectedTransport || peer?.selected_transport || peer?.transport || '',\n            endpointCandidates: endpointCandidates || {},\n            staleRejectionCount,\n            fallbackMs,\n        });\n        const providerFingerprint = String(peer?.providerFingerprint || peer?.provider_key_fingerprint || '').trim();\n        const marketplaceCatalog = peer?.marketplaceCatalog && typeof peer.marketplaceCatalog === 'object'\n            ? peer.marketplaceCatalog\n            : (peer?.marketplace_catalog && typeof peer.marketplace_catalog === 'object' ? peer.marketplace_catalog : null);\n        if (isFriend && share.friends.enabled && peer.friend && typeof peer.friend === 'object') {\n            const friendState = this._applyShareMask(peer.friend, share.friends);\n            const nknAddress = peer.friend?.nknAddress || peer.nknAddress;\n            const merged = nknAddress ? { ...publicState, ...friendState, nknAddress } : { ...publicState, ...friendState };\n            if (selectedCandidate.selectedTransport) merged.selectedTransport = selectedCandidate.selectedTransport;\n            if (selectedCandidate.selectedEndpoint) merged.selectedEndpoint = selectedCandidate.selectedEndpoint;\n            merged.endpointCandidates = { ...selectedCandidate.endpointCandidates };\n            merged.candidateFreshnessMs = { ...selectedCandidate.candidateFreshnessMs };\n            if (network) merged.network = network;\n            if (discoverySource) merged.discoverySource = discoverySource;\n            if (selectedCandidate.staleRejectionCount > 0) merged.staleRejectionCount = selectedCandidate.staleRejectionCount;\n            if (providerFingerprint) merged.providerFingerprint = providerFingerprint;\n            if (marketplaceCatalog) merged.marketplaceCatalog = { ...marketplaceCatalog };\n            return merged;\n        }\n        if (peer?.nknAddress) {\n            const merged = { ...publicState, nknAddress: peer.nknAddress };\n            if (selectedCandidate.selectedTransport) merged.selectedTransport = selectedCandidate.selectedTransport;\n            if (selectedCandidate.selectedEndpoint) merged.selectedEndpoint = selectedCandidate.selectedEndpoint;\n            merged.endpointCandidates = { ...selectedCandidate.endpointCandidates };\n            merged.candidateFreshnessMs = { ...selectedCandidate.candidateFreshnessMs };\n            if (network) merged.network = network;\n            if (discoverySource) merged.discoverySource = discoverySource;\n            if (selectedCandidate.staleRejectionCount > 0) merged.staleRejectionCount = selectedCandidate.staleRejectionCount;\n            if (providerFingerprint) merged.providerFingerprint = providerFingerprint;\n            if (marketplaceCatalog) merged.marketplaceCatalog = { ...marketplaceCatalog };\n            return merged;\n        }\n        if (selectedCandidate.selectedTransport) publicState.selectedTransport = selectedCandidate.selectedTransport;\n        if (selectedCandidate.selectedEndpoint) publicState.selectedEndpoint = selectedCandidate.selectedEndpoint;\n        publicState.endpointCandidates = { ...selectedCandidate.endpointCandidates };\n        publicState.candidateFreshnessMs = { ...selectedCandidate.candidateFreshnessMs };\n        if (network) publicState.network = network;\n        if (discoverySource) publicState.discoverySource = discoverySource;\n        if (selectedCandidate.staleRejectionCount > 0) publicState.staleRejectionCount = selectedCandidate.staleRejectionCount;\n        if (providerFingerprint) publicState.providerFingerprint = providerFingerprint;\n        if (marketplaceCatalog) publicState.marketplaceCatalog = { ...marketplaceCatalog };\n        return publicState;\n    }\n\n    _isFriend(peer) {\n        const userId = this._extractUserId(peer);\n        const friendUserId = this._extractUserId(peer?.friend);\n        const localUserId = this._extractUserId(this._authService?.getState?.()?.user);\n        if (localUserId && (userId === localUserId || friendUserId === localUserId)) return true;\n        if (userId && this._friendIds.has(userId)) return true;\n        if (friendUserId && this._friendIds.has(friendUserId)) return true;\n        // If backend already provided friend-only payload, honor it.\n        if (peer?.friend && typeof peer.friend === 'object') return true;\n        return false;\n    }\n\n    _extractUserId(value) {\n        if (!value) return null;\n        return value.userId\n            || value.user_id\n            || value.id\n            || value.uuid\n            || value?.user?.id\n            || value?.user?.userId\n            || value?.user?.uuid\n            || null;\n    }\n\n    _applyShareConfig(state) {\n        const share = this._normalizeShareConfig(this._shareConfig);\n        const friendsEnabled = !!share.friends.enabled;\n        const publicEnabled = !!share.public.enabled;\n        if (!friendsEnabled && !publicEnabled) return null;\n        const sharesLocation = (friendsEnabled && share.friends.location) || (publicEnabled && share.public.location);\n        if (!sharesLocation) return null;\n\n        const publicState = this._applyShareMask(state, share.public);\n        publicState.share = share;\n        if (!Number.isFinite(publicState.lat) || !Number.isFinite(publicState.lon)) {\n            publicState.lat = state.lat;\n            publicState.lon = state.lon;\n            if (Number.isFinite(state.offset_m)) {\n                publicState.offset_m = state.offset_m;\n            }\n        }\n        if (friendsEnabled) {\n            publicState.friend = this._applyShareMask(state, share.friends);\n        }\n        if (state.deviceId) publicState.deviceId = state.deviceId;\n        if (state.userId) publicState.userId = state.userId;\n        if (state.nknAddress) {\n            publicState.nknAddress = state.nknAddress;\n            if (publicState.friend) {\n                publicState.friend.nknAddress = state.nknAddress;\n            }\n        }\n        if (state.selectedTransport) {\n            publicState.selectedTransport = String(state.selectedTransport || '').trim().toLowerCase();\n            if (publicState.friend) publicState.friend.selectedTransport = publicState.selectedTransport;\n        }\n        if (state.endpointCandidates && typeof state.endpointCandidates === 'object') {\n            publicState.endpointCandidates = { ...state.endpointCandidates };\n            if (publicState.friend) publicState.friend.endpointCandidates = { ...state.endpointCandidates };\n        }\n        if (state.network) {\n            publicState.network = String(state.network || '').trim().toLowerCase();\n            if (publicState.friend) publicState.friend.network = publicState.network;\n        }\n        if (state.discoverySource) {\n            publicState.discoverySource = String(state.discoverySource || '').trim();\n            if (publicState.friend) publicState.friend.discoverySource = publicState.discoverySource;\n        }\n        const staleCount = Number.isFinite(state?.staleRejectionCount)\n            ? Number(state.staleRejectionCount)\n            : (Number.isFinite(state?.stale_rejection_count) ? Number(state.stale_rejection_count) : 0);\n        if (staleCount > 0) {\n            publicState.staleRejectionCount = staleCount;\n            if (publicState.friend) publicState.friend.staleRejectionCount = staleCount;\n        }\n        const providerFingerprint = String(state?.providerFingerprint || state?.provider_key_fingerprint || '').trim();\n        if (providerFingerprint) {\n            publicState.providerFingerprint = providerFingerprint;\n            if (publicState.friend) publicState.friend.providerFingerprint = providerFingerprint;\n        }\n        const marketplaceCatalog = state?.marketplaceCatalog && typeof state.marketplaceCatalog === 'object'\n            ? state.marketplaceCatalog\n            : (state?.marketplace_catalog && typeof state.marketplace_catalog === 'object' ? state.marketplace_catalog : null);\n        if (marketplaceCatalog) {\n            publicState.marketplaceCatalog = { ...marketplaceCatalog };\n            if (publicState.friend) publicState.friend.marketplaceCatalog = { ...marketplaceCatalog };\n        }\n        return publicState;\n    }\n\n    _applyShareMask(state, mask) {\n        if (!state || !mask?.enabled) {\n            return {\n                id: state?.id,\n                deviceId: state?.deviceId,\n                userId: state?.userId,\n                seq: state?.seq,\n                sentAtMs: state?.sentAtMs,\n            };\n        }\n        const output = {\n            id: state.id,\n            deviceId: state.deviceId,\n            userId: state.userId,\n            seq: state.seq,\n            sentAtMs: state.sentAtMs,\n        };\n        if (mask.location) {\n            output.deviceClass = state.deviceClass;\n            output.mapMode = state.mapMode;\n            output.locationSource = state.locationSource;\n            output.lat = state.lat;\n            output.lon = state.lon;\n            output.offset_m = state.offset_m ?? 0;\n        }\n        if (mask.altitude) {\n            output.elevation_m = state.elevation_m;\n            output.surface_contact_msl = state.surface_contact_msl;\n        }\n        if (mask.orientation) {\n            output.heading_deg = state.heading_deg;\n            output.pitch_deg = state.pitch_deg;\n            if (state.q) output.q = state.q;\n        }\n        if (mask.motion) {\n            output.speed = state.speed;\n            output.animState = state.animState;\n            output.isGrounded = state.isGrounded;\n            output.isCrouching = state.isCrouching;\n            output.isJumping = state.isJumping;\n            output.isMeditating = state.isMeditating;\n            output.isSwimming = state.isSwimming;\n        }\n        if (mask.label) {\n            output.label = state.label;\n        }\n        if (state.appearance) {\n            output.appearance = normalizeAvatarAppearance(state.appearance);\n        }\n        if (mask.view) {\n            output.view = state.view;\n        }\n        return output;\n    }\n\n    _normalizeShareConfig(config) {\n        const input = config && typeof config === 'object' ? config : {};\n        const next = { friends: {}, public: {} };\n        ['friends', 'public'].forEach((group) => {\n            const defaults = DEFAULT_SHARE_CONFIG[group];\n            const src = input[group] || {};\n            next[group] = {\n                enabled: typeof src.enabled === 'boolean' ? src.enabled : defaults.enabled,\n                location: typeof src.location === 'boolean' ? src.location : defaults.location,\n                altitude: typeof src.altitude === 'boolean' ? src.altitude : defaults.altitude,\n                orientation: typeof src.orientation === 'boolean' ? src.orientation : defaults.orientation,\n                motion: typeof src.motion === 'boolean' ? src.motion : defaults.motion,\n                label: typeof src.label === 'boolean' ? src.label : defaults.label,\n                view: typeof src.view === 'boolean' ? src.view : defaults.view\n            };\n        });\n        return next;\n    }\n\n    _normalizePeerShare(config) {\n        const input = config && typeof config === 'object' ? config : {};\n        const next = { friends: {}, public: {} };\n        ['friends', 'public'].forEach((group) => {\n            const defaults = DEFAULT_PEER_SHARE[group];\n            const src = input[group] || {};\n            next[group] = {\n                enabled: typeof src.enabled === 'boolean' ? src.enabled : defaults.enabled,\n                location: typeof src.location === 'boolean' ? src.location : defaults.location,\n                altitude: typeof src.altitude === 'boolean' ? src.altitude : defaults.altitude,\n                orientation: typeof src.orientation === 'boolean' ? src.orientation : defaults.orientation,\n                motion: typeof src.motion === 'boolean' ? src.motion : defaults.motion,\n                label: typeof src.label === 'boolean' ? src.label : defaults.label,\n                view: typeof src.view === 'boolean' ? src.view : defaults.view\n            };\n        });\n        return next;\n    }\n}\n","/** Generated by scripts/build-birdsong-regional-profiles.mjs. Do not edit. */\nexport const BIRDSONG_PROFILE_SOURCE = Object.freeze({\n  \"title\": \"WABAD: A World Annotated Bird Acoustic Dataset for Passive Acoustic Monitoring\",\n  \"doi\": \"10.5281/zenodo.15629388\",\n  \"recordUrl\": \"https://zenodo.org/records/15629388\",\n  \"license\": \"CC BY-NC 4.0\",\n  \"retrieved\": \"2026-09-22\",\n  \"sourceFiles\": [\n    {\n      \"name\": \"Metadata.txt\",\n      \"md5\": \"78d2bf1ff6a749597e57c2cfa1cadbb4\"\n    },\n    {\n      \"name\": \"Pooled annotations.txt\",\n      \"md5\": \"59f02f10f87f253367b39d947a7a73d2\"\n    }\n  ],\n  \"siteCount\": 72,\n  \"annotationCount\": 91887,\n  \"generatedBy\": \"build-birdsong-regional-profiles.mjs\",\n  \"note\": \"Observation-hour weights describe sampling, not calibrated diel abundance.\"\n});\n\nexport const BIRDSONG_REGIONAL_PROFILES = Object.freeze([\n  {\n    \"id\": \"ARD\",\n    \"region\": \"San Jorge Private Reserve Misiones province\",\n    \"country\": \"Argentina\",\n    \"biome\": \"Tropical and Subtropical Moist Broadleaf Forest\",\n    \"latitude\": -25.7905,\n    \"longitude\": -54.2778,\n    \"annotationCount\": 2833,\n    \"voices\": [\n      {\n        \"scientificName\": \"Vireo chivi\",\n        \"weight\": 0.2462,\n        \"count\": 344,\n        \"lowHz\": 1892,\n        \"highHz\": 4445,\n        \"durationSeconds\": 0.594,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Saltator similis\",\n        \"weight\": 0.1646,\n        \"count\": 230,\n        \"lowHz\": 1498,\n        \"highHz\": 4117,\n        \"durationSeconds\": 1.612,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Thamnophilus caerulescens\",\n        \"weight\": 0.1518,\n        \"count\": 212,\n        \"lowHz\": 901,\n        \"highHz\": 2209,\n        \"durationSeconds\": 1.451,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Basileuterus culicivorus\",\n        \"weight\": 0.1102,\n        \"count\": 154,\n        \"lowHz\": 3590,\n        \"highHz\": 9237,\n        \"durationSeconds\": 1.191,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Tachyphonus coronatus\",\n        \"weight\": 0.0888,\n        \"count\": 124,\n        \"lowHz\": 1575,\n        \"highHz\": 11128,\n        \"durationSeconds\": 1.368,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Baryphthengus ruficapillus\",\n        \"weight\": 0.0838,\n        \"count\": 117,\n        \"lowHz\": 201,\n        \"highHz\": 953,\n        \"durationSeconds\": 1.033,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Thlypopsis pyrrhocoma\",\n        \"weight\": 0.0795,\n        \"count\": 111,\n        \"lowHz\": 5028,\n        \"highHz\": 9564,\n        \"durationSeconds\": 1.541,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Turdus rufiventris\",\n        \"weight\": 0.0752,\n        \"count\": 105,\n        \"lowHz\": 1255,\n        \"highHz\": 3523,\n        \"durationSeconds\": 4,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"BAM\",\n    \"region\": \"Bamenda Highlands. Big Babanki\",\n    \"country\": \"Cameroon\",\n    \"biome\": \"Tropical and Subtropical Moist Broadleaf Forest\",\n    \"latitude\": 6.0903,\n    \"longitude\": 10.3017,\n    \"annotationCount\": 1365,\n    \"voices\": [\n      {\n        \"scientificName\": \"Cinnyris bouvieri\",\n        \"weight\": 0.2325,\n        \"count\": 216,\n        \"lowHz\": 2256,\n        \"highHz\": 7406,\n        \"durationSeconds\": 1.895,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.847,\n          \"day\": 0.153,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Cinnyris reichenowi\",\n        \"weight\": 0.1744,\n        \"count\": 162,\n        \"lowHz\": 2803,\n        \"highHz\": 8299,\n        \"durationSeconds\": 2.346,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.71,\n          \"day\": 0.29,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Laniarius atroflavus\",\n        \"weight\": 0.1389,\n        \"count\": 129,\n        \"lowHz\": 964,\n        \"highHz\": 3409,\n        \"durationSeconds\": 4,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.798,\n          \"day\": 0.202,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Euplectes capensis\",\n        \"weight\": 0.1044,\n        \"count\": 97,\n        \"lowHz\": 5634,\n        \"highHz\": 8518,\n        \"durationSeconds\": 4,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.68,\n          \"day\": 0.32,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Sylvia abyssinica\",\n        \"weight\": 0.0926,\n        \"count\": 86,\n        \"lowHz\": 1092,\n        \"highHz\": 4156,\n        \"durationSeconds\": 3.53,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.802,\n          \"day\": 0.198,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Apalis cinerea\",\n        \"weight\": 0.0904,\n        \"count\": 84,\n        \"lowHz\": 2065,\n        \"highHz\": 3727,\n        \"durationSeconds\": 4,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.857,\n          \"day\": 0.143,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Pycnonotus barbatus\",\n        \"weight\": 0.0883,\n        \"count\": 82,\n        \"lowHz\": 1123,\n        \"highHz\": 4230,\n        \"durationSeconds\": 1.447,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.939,\n          \"day\": 0.061,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Oreolais pulcher\",\n        \"weight\": 0.0786,\n        \"count\": 73,\n        \"lowHz\": 2586,\n        \"highHz\": 4742,\n        \"durationSeconds\": 4,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.795,\n          \"day\": 0.205,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"BERB\",\n    \"region\": \"Berbak National Park\",\n    \"country\": \"Indonesia\",\n    \"biome\": \"Tropical and Subtropical Moist Broadleaf Forest\",\n    \"latitude\": -1.2837,\n    \"longitude\": 104.2642,\n    \"annotationCount\": 260,\n    \"voices\": [\n      {\n        \"scientificName\": \"Psilopogon duvaucelii\",\n        \"weight\": 0.1818,\n        \"count\": 18,\n        \"lowHz\": 1423,\n        \"highHz\": 2483,\n        \"durationSeconds\": 4,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Gracula religiosa\",\n        \"weight\": 0.1616,\n        \"count\": 16,\n        \"lowHz\": 752,\n        \"highHz\": 4051,\n        \"durationSeconds\": 3.9,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Prinia flaviventris\",\n        \"weight\": 0.1313,\n        \"count\": 13,\n        \"lowHz\": 2103,\n        \"highHz\": 5239,\n        \"durationSeconds\": 4,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Pelargopsis capensis\",\n        \"weight\": 0.1313,\n        \"count\": 13,\n        \"lowHz\": 1071,\n        \"highHz\": 3569,\n        \"durationSeconds\": 4,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Pycnonotus plumosus\",\n        \"weight\": 0.1111,\n        \"count\": 11,\n        \"lowHz\": 1292,\n        \"highHz\": 3711,\n        \"durationSeconds\": 4,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Micropternus brachyurus\",\n        \"weight\": 0.101,\n        \"count\": 10,\n        \"lowHz\": 2551,\n        \"highHz\": 3796,\n        \"durationSeconds\": 4,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Dicrurus paradiseus\",\n        \"weight\": 0.101,\n        \"count\": 10,\n        \"lowHz\": 1167,\n        \"highHz\": 3107,\n        \"durationSeconds\": 4,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Aegithina viridissima\",\n        \"weight\": 0.0808,\n        \"count\": 8,\n        \"lowHz\": 3355,\n        \"highHz\": 6977,\n        \"durationSeconds\": 4,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"BIAL\",\n    \"region\": \"Bialowieza forest district\",\n    \"country\": \"Poland\",\n    \"biome\": \"Temperate Broadleaf and Mixed Forest\",\n    \"latitude\": 52.7453,\n    \"longitude\": 23.7733,\n    \"annotationCount\": 2046,\n    \"voices\": [\n      {\n        \"scientificName\": \"Turdus merula\",\n        \"weight\": 0.2075,\n        \"count\": 316,\n        \"lowHz\": 1233,\n        \"highHz\": 2881,\n        \"durationSeconds\": 2.222,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Fringilla coelebs\",\n        \"weight\": 0.1989,\n        \"count\": 303,\n        \"lowHz\": 1542,\n        \"highHz\": 6972,\n        \"durationSeconds\": 2.49,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Erithacus rubecula\",\n        \"weight\": 0.1267,\n        \"count\": 193,\n        \"lowHz\": 2158,\n        \"highHz\": 9213,\n        \"durationSeconds\": 3.206,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Turdus philomelos\",\n        \"weight\": 0.1267,\n        \"count\": 193,\n        \"lowHz\": 1370,\n        \"highHz\": 4648,\n        \"durationSeconds\": 4,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Phylloscopus collybita\",\n        \"weight\": 0.1083,\n        \"count\": 165,\n        \"lowHz\": 3024,\n        \"highHz\": 7162,\n        \"durationSeconds\": 3.778,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Troglodytes troglodytes\",\n        \"weight\": 0.088,\n        \"count\": 134,\n        \"lowHz\": 3090,\n        \"highHz\": 8606,\n        \"durationSeconds\": 4,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Phylloscopus sibilatrix\",\n        \"weight\": 0.0749,\n        \"count\": 114,\n        \"lowHz\": 2538,\n        \"highHz\": 9937,\n        \"durationSeconds\": 3.835,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Sylvia atricapilla\",\n        \"weight\": 0.0689,\n        \"count\": 105,\n        \"lowHz\": 1731,\n        \"highHz\": 4968,\n        \"durationSeconds\": 3.22,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"BMT\",\n    \"region\": \"Pantanal Baia das Pedras\",\n    \"country\": \"Brazil\",\n    \"biome\": \"Wetland\",\n    \"latitude\": -16.5139,\n    \"longitude\": -56.3936,\n    \"annotationCount\": 2730,\n    \"voices\": [\n      {\n        \"scientificName\": \"Legatus leucophaius\",\n        \"weight\": 0.2308,\n        \"count\": 309,\n        \"lowHz\": 2500,\n        \"highHz\": 5164,\n        \"durationSeconds\": 0.642,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Cercomacra melanaria\",\n        \"weight\": 0.1464,\n        \"count\": 196,\n        \"lowHz\": 707,\n        \"highHz\": 3563,\n        \"durationSeconds\": 2.895,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Saltator coerulescens\",\n        \"weight\": 0.1277,\n        \"count\": 171,\n        \"lowHz\": 1077,\n        \"highHz\": 4297,\n        \"durationSeconds\": 1.379,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Crypturellus undulatus\",\n        \"weight\": 0.1128,\n        \"count\": 151,\n        \"lowHz\": 861,\n        \"highHz\": 1676,\n        \"durationSeconds\": 1.817,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Cacicus solitarius\",\n        \"weight\": 0.1016,\n        \"count\": 136,\n        \"lowHz\": 500,\n        \"highHz\": 4482,\n        \"durationSeconds\": 1.269,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Synallaxis albilora\",\n        \"weight\": 0.0948,\n        \"count\": 127,\n        \"lowHz\": 1214,\n        \"highHz\": 5150,\n        \"durationSeconds\": 1.583,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Hemitriccus striaticollis\",\n        \"weight\": 0.0941,\n        \"count\": 126,\n        \"lowHz\": 2036,\n        \"highHz\": 3734,\n        \"durationSeconds\": 0.348,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Cacicus cela\",\n        \"weight\": 0.0919,\n        \"count\": 123,\n        \"lowHz\": 625,\n        \"highHz\": 7740,\n        \"durationSeconds\": 0.502,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"BOLIN\",\n    \"region\": \"Torre Palacio. Doñana\",\n    \"country\": \"Spain\",\n    \"biome\": \"Wetland\",\n    \"latitude\": 36.9905,\n    \"longitude\": -6.4426,\n    \"annotationCount\": 1154,\n    \"voices\": [\n      {\n        \"scientificName\": \"Streptopelia decaocto\",\n        \"weight\": 0.2465,\n        \"count\": 210,\n        \"lowHz\": 422,\n        \"highHz\": 673,\n        \"durationSeconds\": 1.383,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.671,\n          \"day\": 0.286,\n          \"dusk\": 0.043,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Luscinia megarhynchos\",\n        \"weight\": 0.216,\n        \"count\": 184,\n        \"lowHz\": 1493,\n        \"highHz\": 5215,\n        \"durationSeconds\": 1.232,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.587,\n          \"day\": 0.413,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Sturnus unicolor\",\n        \"weight\": 0.1491,\n        \"count\": 127,\n        \"lowHz\": 150,\n        \"highHz\": 3880,\n        \"durationSeconds\": 2.524,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.37,\n          \"day\": 0.63,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Emberiza calandra\",\n        \"weight\": 0.142,\n        \"count\": 121,\n        \"lowHz\": 4202,\n        \"highHz\": 8545,\n        \"durationSeconds\": 1.404,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.413,\n          \"day\": 0.529,\n          \"dusk\": 0.058,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Carduelis carduelis\",\n        \"weight\": 0.1068,\n        \"count\": 91,\n        \"lowHz\": 2686,\n        \"highHz\": 15000,\n        \"durationSeconds\": 1.825,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.44,\n          \"day\": 0.56,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Ciconia ciconia\",\n        \"weight\": 0.0681,\n        \"count\": 58,\n        \"lowHz\": 496,\n        \"highHz\": 7736,\n        \"durationSeconds\": 4,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.466,\n          \"day\": 0.5,\n          \"dusk\": 0.034,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Chloris chloris\",\n        \"weight\": 0.0364,\n        \"count\": 31,\n        \"lowHz\": 2226,\n        \"highHz\": 5076,\n        \"durationSeconds\": 0.706,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.613,\n          \"day\": 0.387,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Saxicola rubicola\",\n        \"weight\": 0.0352,\n        \"count\": 30,\n        \"lowHz\": 2496,\n        \"highHz\": 6482,\n        \"durationSeconds\": 2.32,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"BRCAS\",\n    \"region\": \"Tengjhih Kaohsiung\",\n    \"country\": \"Taiwan\",\n    \"biome\": \"Tropical and Subtropical Moist Broadleaf Forest\",\n    \"latitude\": 23.065,\n    \"longitude\": 120.7636,\n    \"annotationCount\": 2729,\n    \"voices\": [\n      {\n        \"scientificName\": \"Abroscopus albogularis\",\n        \"weight\": 0.2981,\n        \"count\": 691,\n        \"lowHz\": 4483,\n        \"highHz\": 5126,\n        \"durationSeconds\": 0.791,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Cyanoderma ruficeps\",\n        \"weight\": 0.1268,\n        \"count\": 294,\n        \"lowHz\": 1739,\n        \"highHz\": 2334,\n        \"durationSeconds\": 1.145,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Yuhina brunneiceps\",\n        \"weight\": 0.1221,\n        \"count\": 283,\n        \"lowHz\": 1869,\n        \"highHz\": 5486,\n        \"durationSeconds\": 0.813,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Alcippe morrisonia\",\n        \"weight\": 0.1186,\n        \"count\": 275,\n        \"lowHz\": 2961,\n        \"highHz\": 7402,\n        \"durationSeconds\": 1.201,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Heterophasia auricularis\",\n        \"weight\": 0.1143,\n        \"count\": 265,\n        \"lowHz\": 1716,\n        \"highHz\": 4901,\n        \"durationSeconds\": 1.127,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Liocichla steerii\",\n        \"weight\": 0.0975,\n        \"count\": 226,\n        \"lowHz\": 2483,\n        \"highHz\": 5761,\n        \"durationSeconds\": 1.473,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Pericrocotus solaris\",\n        \"weight\": 0.0828,\n        \"count\": 192,\n        \"lowHz\": 4316,\n        \"highHz\": 6884,\n        \"durationSeconds\": 0.554,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Psilopogon nuchalis\",\n        \"weight\": 0.0397,\n        \"count\": 92,\n        \"lowHz\": 639,\n        \"highHz\": 1299,\n        \"durationSeconds\": 4,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"BRE\",\n    \"region\": \"Reserva Natural Bremen-La Popa\",\n    \"country\": \"Colombia\",\n    \"biome\": \"Tropical and Subtropical Moist Broadleaf Forest\",\n    \"latitude\": 4.6753,\n    \"longitude\": -75.6136,\n    \"annotationCount\": 1277,\n    \"voices\": [\n      {\n        \"scientificName\": \"Colibri cyanotus\",\n        \"weight\": 0.3974,\n        \"count\": 463,\n        \"lowHz\": 5228,\n        \"highHz\": 7769,\n        \"durationSeconds\": 2.426,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Empidonax virescens\",\n        \"weight\": 0.176,\n        \"count\": 205,\n        \"lowHz\": 2814,\n        \"highHz\": 6293,\n        \"durationSeconds\": 0.136,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Dysithamnus mentalis\",\n        \"weight\": 0.1142,\n        \"count\": 133,\n        \"lowHz\": 1005,\n        \"highHz\": 2105,\n        \"durationSeconds\": 2.45,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Pachysylvia semibrunnea\",\n        \"weight\": 0.097,\n        \"count\": 113,\n        \"lowHz\": 2885,\n        \"highHz\": 4768,\n        \"durationSeconds\": 1.015,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Myadestes ralloides\",\n        \"weight\": 0.0798,\n        \"count\": 93,\n        \"lowHz\": 2769,\n        \"highHz\": 4666,\n        \"durationSeconds\": 0.648,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Arremon brunneinucha\",\n        \"weight\": 0.0627,\n        \"count\": 73,\n        \"lowHz\": 7860,\n        \"highHz\": 10708,\n        \"durationSeconds\": 1.51,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Henicorhina leucophrys\",\n        \"weight\": 0.0524,\n        \"count\": 61,\n        \"lowHz\": 1913,\n        \"highHz\": 4935,\n        \"durationSeconds\": 1.855,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Phylloscartes ophthalmicus\",\n        \"weight\": 0.0206,\n        \"count\": 24,\n        \"lowHz\": 4617,\n        \"highHz\": 5887,\n        \"durationSeconds\": 0.282,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"BUR\",\n    \"region\": \"Ouagadougou\",\n    \"country\": \"Burkina Faso\",\n    \"biome\": \"Tropical and Subtropical Grasslands & Savannas and Shrublands\",\n    \"latitude\": 12.5036,\n    \"longitude\": -1.7205,\n    \"annotationCount\": 2171,\n    \"voices\": [\n      {\n        \"scientificName\": \"Pycnonotus barbatus\",\n        \"weight\": 0.2754,\n        \"count\": 368,\n        \"lowHz\": 1269,\n        \"highHz\": 4220,\n        \"durationSeconds\": 1.922,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Crithagra mozambica\",\n        \"weight\": 0.1594,\n        \"count\": 213,\n        \"lowHz\": 1944,\n        \"highHz\": 7739,\n        \"durationSeconds\": 2.599,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Passer griseus\",\n        \"weight\": 0.1437,\n        \"count\": 192,\n        \"lowHz\": 1749,\n        \"highHz\": 4746,\n        \"durationSeconds\": 0.668,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Streptopelia vinacea\",\n        \"weight\": 0.1392,\n        \"count\": 186,\n        \"lowHz\": 397,\n        \"highHz\": 1247,\n        \"durationSeconds\": 4,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Laniarius atroflavus\",\n        \"weight\": 0.0853,\n        \"count\": 114,\n        \"lowHz\": 674,\n        \"highHz\": 2323,\n        \"durationSeconds\": 0.518,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Turtur abyssinicus\",\n        \"weight\": 0.0756,\n        \"count\": 101,\n        \"lowHz\": 280,\n        \"highHz\": 818,\n        \"durationSeconds\": 4,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Euplectes franciscanus\",\n        \"weight\": 0.0636,\n        \"count\": 85,\n        \"lowHz\": 5272,\n        \"highHz\": 8564,\n        \"durationSeconds\": 3.045,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Tockus erythrorhynchus\",\n        \"weight\": 0.0576,\n        \"count\": 77,\n        \"lowHz\": 773,\n        \"highHz\": 1627,\n        \"durationSeconds\": 4,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"CARI\",\n    \"region\": \"Vereda Caribabare. Tame. Arauca\",\n    \"country\": \"Colombia\",\n    \"biome\": \"Tropical and Subtropical Dry Broadleaf Forest\",\n    \"latitude\": 6.2831,\n    \"longitude\": -71.7778,\n    \"annotationCount\": 2056,\n    \"voices\": [\n      {\n        \"scientificName\": \"Camptostoma obsoletum\",\n        \"weight\": 0.164,\n        \"count\": 254,\n        \"lowHz\": 3100,\n        \"highHz\": 4235,\n        \"durationSeconds\": 0.863,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Cantorchilus leucotis\",\n        \"weight\": 0.1614,\n        \"count\": 250,\n        \"lowHz\": 1231,\n        \"highHz\": 3959,\n        \"durationSeconds\": 0.928,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Turdus leucomelas\",\n        \"weight\": 0.1504,\n        \"count\": 233,\n        \"lowHz\": 1381,\n        \"highHz\": 3652,\n        \"durationSeconds\": 2.443,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Tolmomyias flaviventris\",\n        \"weight\": 0.1349,\n        \"count\": 209,\n        \"lowHz\": 4235,\n        \"highHz\": 6138,\n        \"durationSeconds\": 0.554,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Nyctidromus albicollis\",\n        \"weight\": 0.1175,\n        \"count\": 182,\n        \"lowHz\": 752,\n        \"highHz\": 2578,\n        \"durationSeconds\": 0.456,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Momotus momota\",\n        \"weight\": 0.1039,\n        \"count\": 161,\n        \"lowHz\": 154,\n        \"highHz\": 614,\n        \"durationSeconds\": 0.293,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Myiarchus tuberculifer\",\n        \"weight\": 0.0891,\n        \"count\": 138,\n        \"lowHz\": 1719,\n        \"highHz\": 2916,\n        \"durationSeconds\": 0.619,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Penelope purpurascens\",\n        \"weight\": 0.0788,\n        \"count\": 122,\n        \"lowHz\": 632,\n        \"highHz\": 1473,\n        \"durationSeconds\": 3.058,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"CAT\",\n    \"region\": \"Solsona\",\n    \"country\": \"Spain\",\n    \"biome\": \"Mediterranean Forests. Woodlands and shrublands\",\n    \"latitude\": 41.9919,\n    \"longitude\": 1.5098,\n    \"annotationCount\": 1254,\n    \"voices\": [\n      {\n        \"scientificName\": \"Erithacus rubecula\",\n        \"weight\": 0.1909,\n        \"count\": 235,\n        \"lowHz\": 2506,\n        \"highHz\": 9285,\n        \"durationSeconds\": 2.932,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Turdus philomelos\",\n        \"weight\": 0.1885,\n        \"count\": 232,\n        \"lowHz\": 6442,\n        \"highHz\": 10464,\n        \"durationSeconds\": 0.629,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Turdus merula\",\n        \"weight\": 0.1747,\n        \"count\": 215,\n        \"lowHz\": 1039,\n        \"highHz\": 4069,\n        \"durationSeconds\": 4,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Emberiza cirlus\",\n        \"weight\": 0.1665,\n        \"count\": 205,\n        \"lowHz\": 2958,\n        \"highHz\": 8973,\n        \"durationSeconds\": 1.881,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Parus major\",\n        \"weight\": 0.156,\n        \"count\": 192,\n        \"lowHz\": 3026,\n        \"highHz\": 7614,\n        \"durationSeconds\": 3.365,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Sylvia atricapilla\",\n        \"weight\": 0.0853,\n        \"count\": 105,\n        \"lowHz\": 1513,\n        \"highHz\": 5431,\n        \"durationSeconds\": 4,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Motacilla alba\",\n        \"weight\": 0.0227,\n        \"count\": 28,\n        \"lowHz\": 4195,\n        \"highHz\": 7535,\n        \"durationSeconds\": 0.512,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Phoenicurus ochruros\",\n        \"weight\": 0.0154,\n        \"count\": 19,\n        \"lowHz\": 3337,\n        \"highHz\": 8687,\n        \"durationSeconds\": 1.861,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"CB\",\n    \"region\": \"Eeyou Istchee James Bay\",\n    \"country\": \"Canada\",\n    \"biome\": \"Boreal forest/Taiga\",\n    \"latitude\": 49.3877,\n    \"longitude\": -79.138,\n    \"annotationCount\": 918,\n    \"voices\": [\n      {\n        \"scientificName\": \"Zonotrichia albicollis\",\n        \"weight\": 0.3047,\n        \"count\": 199,\n        \"lowHz\": 2839,\n        \"highHz\": 4452,\n        \"durationSeconds\": 2.989,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Empidonax minimus\",\n        \"weight\": 0.1715,\n        \"count\": 112,\n        \"lowHz\": 150,\n        \"highHz\": 7219,\n        \"durationSeconds\": 1.814,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Agelaius phoeniceus\",\n        \"weight\": 0.1179,\n        \"count\": 77,\n        \"lowHz\": 150,\n        \"highHz\": 6581,\n        \"durationSeconds\": 0.737,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Setophaga coronata\",\n        \"weight\": 0.1133,\n        \"count\": 74,\n        \"lowHz\": 3512,\n        \"highHz\": 7449,\n        \"durationSeconds\": 1.244,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Melospiza georgiana\",\n        \"weight\": 0.0873,\n        \"count\": 57,\n        \"lowHz\": 2981,\n        \"highHz\": 7432,\n        \"durationSeconds\": 2.06,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Quiscalus quiscula\",\n        \"weight\": 0.075,\n        \"count\": 49,\n        \"lowHz\": 150,\n        \"highHz\": 9131,\n        \"durationSeconds\": 0.385,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Tringa melanoleuca\",\n        \"weight\": 0.0658,\n        \"count\": 43,\n        \"lowHz\": 1553,\n        \"highHz\": 2951,\n        \"durationSeconds\": 0.7,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Corthylio calendula\",\n        \"weight\": 0.0643,\n        \"count\": 42,\n        \"lowHz\": 1936,\n        \"highHz\": 6775,\n        \"durationSeconds\": 1.43,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"CLH\",\n    \"region\": \"Eastern Scotland\",\n    \"country\": \"Scotland\",\n    \"biome\": \"Temperate Broadleaf and Mixed Forest\",\n    \"latitude\": 55.9247,\n    \"longitude\": -3.2315,\n    \"annotationCount\": 963,\n    \"voices\": [\n      {\n        \"scientificName\": \"Parus major\",\n        \"weight\": 0.1739,\n        \"count\": 156,\n        \"lowHz\": 2029,\n        \"highHz\": 8075,\n        \"durationSeconds\": 2.136,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.994,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0.006\n        }\n      },\n      {\n        \"scientificName\": \"Fringilla coelebs\",\n        \"weight\": 0.1683,\n        \"count\": 151,\n        \"lowHz\": 1838,\n        \"highHz\": 8928,\n        \"durationSeconds\": 2.475,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Erithacus rubecula\",\n        \"weight\": 0.1594,\n        \"count\": 143,\n        \"lowHz\": 1818,\n        \"highHz\": 9149,\n        \"durationSeconds\": 2.625,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.21,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0.79\n        }\n      },\n      {\n        \"scientificName\": \"Turdus merula\",\n        \"weight\": 0.1394,\n        \"count\": 125,\n        \"lowHz\": 1282,\n        \"highHz\": 7909,\n        \"durationSeconds\": 2.1,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.608,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0.392\n        }\n      },\n      {\n        \"scientificName\": \"Cyanistes caeruleus\",\n        \"weight\": 0.136,\n        \"count\": 122,\n        \"lowHz\": 2677,\n        \"highHz\": 8957,\n        \"durationSeconds\": 1.825,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Troglodytes troglodytes\",\n        \"weight\": 0.1338,\n        \"count\": 120,\n        \"lowHz\": 1738,\n        \"highHz\": 9439,\n        \"durationSeconds\": 4,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.992,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0.008\n        }\n      },\n      {\n        \"scientificName\": \"Phylloscopus collybita\",\n        \"weight\": 0.0502,\n        \"count\": 45,\n        \"lowHz\": 1610,\n        \"highHz\": 9115,\n        \"durationSeconds\": 4,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Fulica atra\",\n        \"weight\": 0.039,\n        \"count\": 35,\n        \"lowHz\": 150,\n        \"highHz\": 2520,\n        \"durationSeconds\": 1.558,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.743,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0.257\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"COU\",\n    \"region\": \"Couserans\",\n    \"country\": \"France\",\n    \"biome\": \"Montane Grasslands and Savannas & Boreal Forests/Taiga\",\n    \"latitude\": 42.7969,\n    \"longitude\": 1.0767,\n    \"annotationCount\": 178,\n    \"voices\": [\n      {\n        \"scientificName\": \"Anthus trivialis\",\n        \"weight\": 0.2388,\n        \"count\": 32,\n        \"lowHz\": 2180,\n        \"highHz\": 7646,\n        \"durationSeconds\": 2.105,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.438,\n          \"day\": 0.563,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Fringilla coelebs\",\n        \"weight\": 0.2313,\n        \"count\": 31,\n        \"lowHz\": 2086,\n        \"highHz\": 6648,\n        \"durationSeconds\": 1.752,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.387,\n          \"day\": 0.613,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Anthus spinoletta\",\n        \"weight\": 0.1119,\n        \"count\": 15,\n        \"lowHz\": 2653,\n        \"highHz\": 9166,\n        \"durationSeconds\": 4,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.867,\n          \"day\": 0.133,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Sylvia atricapilla\",\n        \"weight\": 0.1045,\n        \"count\": 14,\n        \"lowHz\": 1930,\n        \"highHz\": 4362,\n        \"durationSeconds\": 1.958,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.929,\n          \"day\": 0.071,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Corvus corone\",\n        \"weight\": 0.097,\n        \"count\": 13,\n        \"lowHz\": 829,\n        \"highHz\": 3575,\n        \"durationSeconds\": 2.206,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.615,\n          \"day\": 0.385,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Oenanthe oenanthe\",\n        \"weight\": 0.0746,\n        \"count\": 10,\n        \"lowHz\": 2280,\n        \"highHz\": 6217,\n        \"durationSeconds\": 0.888,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Phylloscopus collybita\",\n        \"weight\": 0.0746,\n        \"count\": 10,\n        \"lowHz\": 3202,\n        \"highHz\": 6154,\n        \"durationSeconds\": 3.891,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.4,\n          \"day\": 0.6,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Emberiza cia\",\n        \"weight\": 0.0672,\n        \"count\": 9,\n        \"lowHz\": 3208,\n        \"highHz\": 7919,\n        \"durationSeconds\": 0.943,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"CRAT\",\n    \"region\": \"Parque Ecologico Macuiltepetl\",\n    \"country\": \"Mexico\",\n    \"biome\": \"Tropical and Subtropical Moist Broadleaf Forest\",\n    \"latitude\": 19.5489,\n    \"longitude\": -96.9203,\n    \"annotationCount\": 1524,\n    \"voices\": [\n      {\n        \"scientificName\": \"Momotus coeruliceps\",\n        \"weight\": 0.2854,\n        \"count\": 415,\n        \"lowHz\": 331,\n        \"highHz\": 662,\n        \"durationSeconds\": 0.911,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Arremon brunneinucha\",\n        \"weight\": 0.174,\n        \"count\": 253,\n        \"lowHz\": 6778,\n        \"highHz\": 11496,\n        \"durationSeconds\": 2.428,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Psilorhinus morio\",\n        \"weight\": 0.1389,\n        \"count\": 202,\n        \"lowHz\": 645,\n        \"highHz\": 5645,\n        \"durationSeconds\": 4,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Myiodynastes luteiventris\",\n        \"weight\": 0.0942,\n        \"count\": 137,\n        \"lowHz\": 1116,\n        \"highHz\": 10465,\n        \"durationSeconds\": 0.792,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Saltator atriceps\",\n        \"weight\": 0.0846,\n        \"count\": 123,\n        \"lowHz\": 1068,\n        \"highHz\": 10627,\n        \"durationSeconds\": 0.816,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Basileuterus culicivorus\",\n        \"weight\": 0.0818,\n        \"count\": 119,\n        \"lowHz\": 1303,\n        \"highHz\": 6638,\n        \"durationSeconds\": 1.397,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Turdus grayi\",\n        \"weight\": 0.0708,\n        \"count\": 103,\n        \"lowHz\": 1007,\n        \"highHz\": 4262,\n        \"durationSeconds\": 4,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Pheugopedius maculipectus\",\n        \"weight\": 0.0702,\n        \"count\": 102,\n        \"lowHz\": 1167,\n        \"highHz\": 6331,\n        \"durationSeconds\": 1.738,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"CRUZ\",\n    \"region\": \"Las Cruces Biological Station\",\n    \"country\": \"Costa Rica\",\n    \"biome\": \"Tropical and Subtropical Moist Broadleaf Forest\",\n    \"latitude\": 8.7853,\n    \"longitude\": -82.9589,\n    \"annotationCount\": 2437,\n    \"voices\": [\n      {\n        \"scientificName\": \"Henicorhina leucosticta\",\n        \"weight\": 0.4021,\n        \"count\": 877,\n        \"lowHz\": 2163,\n        \"highHz\": 4419,\n        \"durationSeconds\": 0.345,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.875,\n          \"day\": 0.125,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Phaethornis striigularis\",\n        \"weight\": 0.2705,\n        \"count\": 590,\n        \"lowHz\": 5782,\n        \"highHz\": 8863,\n        \"durationSeconds\": 0.186,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0,\n          \"day\": 1,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Catharus aurantiirostris\",\n        \"weight\": 0.1064,\n        \"count\": 232,\n        \"lowHz\": 2210,\n        \"highHz\": 5283,\n        \"durationSeconds\": 0.714,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.06,\n          \"day\": 0.94,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Arremon aurantiirostris\",\n        \"weight\": 0.0656,\n        \"count\": 143,\n        \"lowHz\": 6363,\n        \"highHz\": 10149,\n        \"durationSeconds\": 0.989,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.636,\n          \"day\": 0.364,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Lophotriccus pileatus\",\n        \"weight\": 0.0518,\n        \"count\": 113,\n        \"lowHz\": 1604,\n        \"highHz\": 3730,\n        \"durationSeconds\": 0.603,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.726,\n          \"day\": 0.274,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Arremon torquatus\",\n        \"weight\": 0.0385,\n        \"count\": 84,\n        \"lowHz\": 5924,\n        \"highHz\": 8613,\n        \"durationSeconds\": 0.26,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.821,\n          \"day\": 0.179,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Leptotila cassinii\",\n        \"weight\": 0.0348,\n        \"count\": 76,\n        \"lowHz\": 235,\n        \"highHz\": 710,\n        \"durationSeconds\": 1.267,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 0,\n          \"day\": 1,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Ramphastos ambiguus\",\n        \"weight\": 0.0303,\n        \"count\": 66,\n        \"lowHz\": 1222,\n        \"highHz\": 2022,\n        \"durationSeconds\": 0.438,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"DEVA\",\n    \"region\": \"Domaine de Dva\",\n    \"country\": \"New Caledonia\",\n    \"biome\": \"Tropical and Subtropical Dry Broadleaf Forest\",\n    \"latitude\": -21.5891,\n    \"longitude\": 165.3762,\n    \"annotationCount\": 729,\n    \"voices\": [\n      {\n        \"scientificName\": \"Rhipidura albiscapa\",\n        \"weight\": 0.3274,\n        \"count\": 202,\n        \"lowHz\": 4339,\n        \"highHz\": 7056,\n        \"durationSeconds\": 1.233,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Pachycephala rufiventris\",\n        \"weight\": 0.1669,\n        \"count\": 103,\n        \"lowHz\": 1517,\n        \"highHz\": 5994,\n        \"durationSeconds\": 1.021,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Zosterops xanthochroa\",\n        \"weight\": 0.1524,\n        \"count\": 94,\n        \"lowHz\": 2917,\n        \"highHz\": 5530,\n        \"durationSeconds\": 0.987,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Todiramphus sanctus\",\n        \"weight\": 0.1102,\n        \"count\": 68,\n        \"lowHz\": 2427,\n        \"highHz\": 3681,\n        \"durationSeconds\": 0.812,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Lichmera incana\",\n        \"weight\": 0.0827,\n        \"count\": 51,\n        \"lowHz\": 1958,\n        \"highHz\": 3677,\n        \"durationSeconds\": 1.489,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Gerygone flavolateralis\",\n        \"weight\": 0.0567,\n        \"count\": 35,\n        \"lowHz\": 2350,\n        \"highHz\": 4473,\n        \"durationSeconds\": 4,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Corvus moneduloides\",\n        \"weight\": 0.0567,\n        \"count\": 35,\n        \"lowHz\": 478,\n        \"highHz\": 5534,\n        \"durationSeconds\": 1.038,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Myiagra caledonica\",\n        \"weight\": 0.047,\n        \"count\": 29,\n        \"lowHz\": 1872,\n        \"highHz\": 3900,\n        \"durationSeconds\": 0.203,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"DONG\",\n    \"region\": \"Dong Nai Province\",\n    \"country\": \"Vietnam\",\n    \"biome\": \"Tropical and Subtropical Moist Broadleaf Forest\",\n    \"latitude\": 11.4414,\n    \"longitude\": 107.4008,\n    \"annotationCount\": 4540,\n    \"voices\": [\n      {\n        \"scientificName\": \"Chloropsis cochinchinensis\",\n        \"weight\": 0.2103,\n        \"count\": 473,\n        \"lowHz\": 2102,\n        \"highHz\": 5255,\n        \"durationSeconds\": 0.792,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Orthotomus atrogularis\",\n        \"weight\": 0.1659,\n        \"count\": 373,\n        \"lowHz\": 2277,\n        \"highHz\": 5214,\n        \"durationSeconds\": 1.039,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.987,\n          \"day\": 0,\n          \"dusk\": 0.013,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Cinnyris jugularis\",\n        \"weight\": 0.1418,\n        \"count\": 319,\n        \"lowHz\": 3592,\n        \"highHz\": 7139,\n        \"durationSeconds\": 0.252,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Aethopyga siparaja\",\n        \"weight\": 0.1245,\n        \"count\": 280,\n        \"lowHz\": 4444,\n        \"highHz\": 8524,\n        \"durationSeconds\": 1.04,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Dicaeum cruentatum\",\n        \"weight\": 0.1236,\n        \"count\": 278,\n        \"lowHz\": 5382,\n        \"highHz\": 8847,\n        \"durationSeconds\": 1.39,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.968,\n          \"day\": 0,\n          \"dusk\": 0.032,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Pericrocotus speciosus\",\n        \"weight\": 0.0934,\n        \"count\": 210,\n        \"lowHz\": 2731,\n        \"highHz\": 6561,\n        \"durationSeconds\": 1.312,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Dicrurus paradiseus\",\n        \"weight\": 0.0743,\n        \"count\": 167,\n        \"lowHz\": 1113,\n        \"highHz\": 3641,\n        \"durationSeconds\": 1.533,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.922,\n          \"day\": 0,\n          \"dusk\": 0.078,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Copsychus saularis\",\n        \"weight\": 0.0663,\n        \"count\": 149,\n        \"lowHz\": 2106,\n        \"highHz\": 5710,\n        \"durationSeconds\": 1.684,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.946,\n          \"day\": 0,\n          \"dusk\": 0.054,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"DUNAS\",\n    \"region\": \"Parque Estadual Dunas de Natal\",\n    \"country\": \"Brazil\",\n    \"biome\": \"Tropical and Subtropical Moist Broadleaf Forest\",\n    \"latitude\": -5.8118,\n    \"longitude\": -35.1917,\n    \"annotationCount\": 1717,\n    \"voices\": [\n      {\n        \"scientificName\": \"Vireo chivi\",\n        \"weight\": 0.2562,\n        \"count\": 370,\n        \"lowHz\": 1828,\n        \"highHz\": 5022,\n        \"durationSeconds\": 0.472,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.314,\n          \"day\": 0.686,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Herpsilochmus pectoralis\",\n        \"weight\": 0.25,\n        \"count\": 361,\n        \"lowHz\": 1137,\n        \"highHz\": 2632,\n        \"durationSeconds\": 1.367,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.288,\n          \"day\": 0.712,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Coereba flaveola\",\n        \"weight\": 0.1558,\n        \"count\": 225,\n        \"lowHz\": 6233,\n        \"highHz\": 9615,\n        \"durationSeconds\": 0.319,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.053,\n          \"day\": 0.947,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Cyclarhis gujanensis\",\n        \"weight\": 0.0983,\n        \"count\": 142,\n        \"lowHz\": 1308,\n        \"highHz\": 4283,\n        \"durationSeconds\": 1.099,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.585,\n          \"day\": 0.415,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Thraupis palmarum\",\n        \"weight\": 0.0838,\n        \"count\": 121,\n        \"lowHz\": 3337,\n        \"highHz\": 9574,\n        \"durationSeconds\": 0.376,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.19,\n          \"day\": 0.81,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Cyanocorax cyanopogon\",\n        \"weight\": 0.0699,\n        \"count\": 101,\n        \"lowHz\": 1365,\n        \"highHz\": 3931,\n        \"durationSeconds\": 0.437,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.119,\n          \"day\": 0.881,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Tolmomyias flaviventris\",\n        \"weight\": 0.045,\n        \"count\": 65,\n        \"lowHz\": 4604,\n        \"highHz\": 7205,\n        \"durationSeconds\": 0.514,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.569,\n          \"day\": 0.431,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Euphonia chlorotica\",\n        \"weight\": 0.0409,\n        \"count\": 59,\n        \"lowHz\": 3570,\n        \"highHz\": 4378,\n        \"durationSeconds\": 0.731,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.322,\n          \"day\": 0.678,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"DYOM\",\n    \"region\": \"Western Cyprus\",\n    \"country\": \"Cyprus\",\n    \"biome\": \"Mediterranean Forests. Woodlands and shrublands\",\n    \"latitude\": 34.9193,\n    \"longitude\": 33.2008,\n    \"annotationCount\": 1029,\n    \"voices\": [\n      {\n        \"scientificName\": \"Fringilla coelebs\",\n        \"weight\": 0.4043,\n        \"count\": 399,\n        \"lowHz\": 1520,\n        \"highHz\": 7476,\n        \"durationSeconds\": 3.486,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Periparus ater\",\n        \"weight\": 0.2563,\n        \"count\": 253,\n        \"lowHz\": 1864,\n        \"highHz\": 7739,\n        \"durationSeconds\": 4,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Turdus merula\",\n        \"weight\": 0.2361,\n        \"count\": 233,\n        \"lowHz\": 1057,\n        \"highHz\": 4057,\n        \"durationSeconds\": 1.797,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Garrulus glandarius\",\n        \"weight\": 0.0355,\n        \"count\": 35,\n        \"lowHz\": 1099,\n        \"highHz\": 5409,\n        \"durationSeconds\": 0.69,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Cettia cetti\",\n        \"weight\": 0.0233,\n        \"count\": 23,\n        \"lowHz\": 1736,\n        \"highHz\": 7734,\n        \"durationSeconds\": 1.953,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Alectoris chukar\",\n        \"weight\": 0.0172,\n        \"count\": 17,\n        \"lowHz\": 485,\n        \"highHz\": 3339,\n        \"durationSeconds\": 0.969,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Oenanthe cypriaca\",\n        \"weight\": 0.0152,\n        \"count\": 15,\n        \"lowHz\": 3940,\n        \"highHz\": 6838,\n        \"durationSeconds\": 2.595,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Parus major\",\n        \"weight\": 0.0122,\n        \"count\": 12,\n        \"lowHz\": 2682,\n        \"highHz\": 5276,\n        \"durationSeconds\": 4,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"EFFOR\",\n    \"region\": \"EFForTS Riparian plots\",\n    \"country\": \"Indonesia\",\n    \"biome\": \"Tropical and Subtropical Moist Broadleaf Forest\",\n    \"latitude\": -1.8326,\n    \"longitude\": 103.2019,\n    \"annotationCount\": 118,\n    \"voices\": [\n      {\n        \"scientificName\": \"Malacopteron magnirostre\",\n        \"weight\": 0.1639,\n        \"count\": 10,\n        \"lowHz\": 1655,\n        \"highHz\": 3384,\n        \"durationSeconds\": 4,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Malacopteron magnum\",\n        \"weight\": 0.1639,\n        \"count\": 10,\n        \"lowHz\": 1455,\n        \"highHz\": 3522,\n        \"durationSeconds\": 4,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Stachyris maculata\",\n        \"weight\": 0.1475,\n        \"count\": 9,\n        \"lowHz\": 607,\n        \"highHz\": 1572,\n        \"durationSeconds\": 4,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Pellorneum bicolor\",\n        \"weight\": 0.1311,\n        \"count\": 8,\n        \"lowHz\": 2385,\n        \"highHz\": 4549,\n        \"durationSeconds\": 4,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Pellorneum malaccense\",\n        \"weight\": 0.1148,\n        \"count\": 7,\n        \"lowHz\": 1793,\n        \"highHz\": 4149,\n        \"durationSeconds\": 4,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Aegithina viridissima\",\n        \"weight\": 0.0984,\n        \"count\": 6,\n        \"lowHz\": 3756,\n        \"highHz\": 6251,\n        \"durationSeconds\": 4,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Eurylaimus ochromalus\",\n        \"weight\": 0.0984,\n        \"count\": 6,\n        \"lowHz\": 1049,\n        \"highHz\": 2537,\n        \"durationSeconds\": 4,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Rubigula erythropthalmos\",\n        \"weight\": 0.082,\n        \"count\": 5,\n        \"lowHz\": 2068,\n        \"highHz\": 4052,\n        \"durationSeconds\": 4,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"EFFOU\",\n    \"region\": \"EFForTS Upland core plots\",\n    \"country\": \"Indonesia\",\n    \"biome\": \"Tropical and Subtropical Moist Broadleaf Forest\",\n    \"latitude\": -1.7773,\n    \"longitude\": 102.9124,\n    \"annotationCount\": 202,\n    \"voices\": [\n      {\n        \"scientificName\": \"Gracula religiosa\",\n        \"weight\": 0.1978,\n        \"count\": 18,\n        \"lowHz\": 594,\n        \"highHz\": 3281,\n        \"durationSeconds\": 4,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Malacopteron magnirostre\",\n        \"weight\": 0.1978,\n        \"count\": 18,\n        \"lowHz\": 1744,\n        \"highHz\": 3942,\n        \"durationSeconds\": 4,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Pellorneum malaccense\",\n        \"weight\": 0.1429,\n        \"count\": 13,\n        \"lowHz\": 1186,\n        \"highHz\": 3376,\n        \"durationSeconds\": 4,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.462,\n          \"day\": 0,\n          \"dusk\": 0.538,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Picus puniceus\",\n        \"weight\": 0.1209,\n        \"count\": 11,\n        \"lowHz\": 2123,\n        \"highHz\": 3832,\n        \"durationSeconds\": 2.3,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Mixornis gularis\",\n        \"weight\": 0.0989,\n        \"count\": 9,\n        \"lowHz\": 1131,\n        \"highHz\": 3501,\n        \"durationSeconds\": 4,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.333,\n          \"day\": 0,\n          \"dusk\": 0.667,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Prinia familiaris\",\n        \"weight\": 0.0879,\n        \"count\": 8,\n        \"lowHz\": 1630,\n        \"highHz\": 10783,\n        \"durationSeconds\": 3.25,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.125,\n          \"day\": 0.875,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Pellorneum bicolor\",\n        \"weight\": 0.0769,\n        \"count\": 7,\n        \"lowHz\": 2909,\n        \"highHz\": 4687,\n        \"durationSeconds\": 4,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Stachyris poliocephala\",\n        \"weight\": 0.0769,\n        \"count\": 7,\n        \"lowHz\": 2605,\n        \"highHz\": 3970,\n        \"durationSeconds\": 4,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"EMP\",\n    \"region\": \"Mata do Jiqui - EMPARN\",\n    \"country\": \"Brazil\",\n    \"biome\": \"Tropical and Subtropical Moist Broadleaf Forest\",\n    \"latitude\": -5.8117,\n    \"longitude\": -35.1918,\n    \"annotationCount\": 198,\n    \"voices\": [\n      {\n        \"scientificName\": \"Vireo chivi\",\n        \"weight\": 0.4034,\n        \"count\": 71,\n        \"lowHz\": 2279,\n        \"highHz\": 4897,\n        \"durationSeconds\": 0.674,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Herpsilochmus pectoralis\",\n        \"weight\": 0.142,\n        \"count\": 25,\n        \"lowHz\": 774,\n        \"highHz\": 2963,\n        \"durationSeconds\": 2.139,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Euphonia chlorotica\",\n        \"weight\": 0.1364,\n        \"count\": 24,\n        \"lowHz\": 3358,\n        \"highHz\": 4645,\n        \"durationSeconds\": 1.214,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Coereba flaveola\",\n        \"weight\": 0.0852,\n        \"count\": 15,\n        \"lowHz\": 4684,\n        \"highHz\": 10236,\n        \"durationSeconds\": 2.254,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Myiothlypis flaveola\",\n        \"weight\": 0.0682,\n        \"count\": 12,\n        \"lowHz\": 2255,\n        \"highHz\": 7597,\n        \"durationSeconds\": 1.344,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Formicivora grisea\",\n        \"weight\": 0.0568,\n        \"count\": 10,\n        \"lowHz\": 1176,\n        \"highHz\": 4165,\n        \"durationSeconds\": 3.241,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Antrostomus rufus\",\n        \"weight\": 0.0568,\n        \"count\": 10,\n        \"lowHz\": 577,\n        \"highHz\": 2292,\n        \"durationSeconds\": 1.272,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 1\n        }\n      },\n      {\n        \"scientificName\": \"Neopelma pallescens\",\n        \"weight\": 0.0511,\n        \"count\": 9,\n        \"lowHz\": 704,\n        \"highHz\": 4645,\n        \"durationSeconds\": 1.445,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"EVROS\",\n    \"region\": \"Evros River Delta National Park\",\n    \"country\": \"Greece\",\n    \"biome\": \"Mediterranean Forests. Woodlands and shrublands\",\n    \"latitude\": 40.7971,\n    \"longitude\": 26.0527,\n    \"annotationCount\": 934,\n    \"voices\": [\n      {\n        \"scientificName\": \"Luscinia megarhynchos\",\n        \"weight\": 0.4612,\n        \"count\": 404,\n        \"lowHz\": 758,\n        \"highHz\": 8485,\n        \"durationSeconds\": 2.153,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0,\n          \"day\": 0,\n          \"dusk\": 0.483,\n          \"night\": 0.517\n        }\n      },\n      {\n        \"scientificName\": \"Emberiza calandra\",\n        \"weight\": 0.2295,\n        \"count\": 201,\n        \"lowHz\": 2796,\n        \"highHz\": 15000,\n        \"durationSeconds\": 1.953,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 0,\n          \"day\": 0.498,\n          \"dusk\": 0.502,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Alauda arvensis\",\n        \"weight\": 0.1176,\n        \"count\": 103,\n        \"lowHz\": 1284,\n        \"highHz\": 7746,\n        \"durationSeconds\": 4,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 0,\n          \"day\": 0.874,\n          \"dusk\": 0.126,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Merops apiaster\",\n        \"weight\": 0.0742,\n        \"count\": 65,\n        \"lowHz\": 898,\n        \"highHz\": 3015,\n        \"durationSeconds\": 0.175,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0,\n          \"day\": 0.985,\n          \"dusk\": 0.015,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Recurvirostra avosetta\",\n        \"weight\": 0.0468,\n        \"count\": 41,\n        \"lowHz\": 1385,\n        \"highHz\": 3077,\n        \"durationSeconds\": 3.577,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0,\n          \"day\": 0,\n          \"dusk\": 1,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Calandrella brachydactyla\",\n        \"weight\": 0.0331,\n        \"count\": 29,\n        \"lowHz\": 1283,\n        \"highHz\": 8983,\n        \"durationSeconds\": 3.024,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0,\n          \"day\": 0.552,\n          \"dusk\": 0.448,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Galerida cristata\",\n        \"weight\": 0.0194,\n        \"count\": 17,\n        \"lowHz\": 1350,\n        \"highHz\": 6773,\n        \"durationSeconds\": 2.569,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0,\n          \"day\": 1,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Cettia cetti\",\n        \"weight\": 0.0183,\n        \"count\": 16,\n        \"lowHz\": 1600,\n        \"highHz\": 8339,\n        \"durationSeconds\": 1.961,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0,\n          \"day\": 0.188,\n          \"dusk\": 0.688,\n          \"night\": 0.125\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"FEU\",\n    \"region\": \"Labrieville. Qubec\",\n    \"country\": \"Canada\",\n    \"biome\": \"Boreal Forests/Taiga\",\n    \"latitude\": 49.25,\n    \"longitude\": -69.72,\n    \"annotationCount\": 3079,\n    \"voices\": [\n      {\n        \"scientificName\": \"Chordeiles minor\",\n        \"weight\": 0.2692,\n        \"count\": 708,\n        \"lowHz\": 1838,\n        \"highHz\": 5791,\n        \"durationSeconds\": 0.324,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0,\n          \"day\": 0,\n          \"dusk\": 1,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Catharus guttatus\",\n        \"weight\": 0.1768,\n        \"count\": 465,\n        \"lowHz\": 1471,\n        \"highHz\": 5513,\n        \"durationSeconds\": 1.153,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.589,\n          \"day\": 0,\n          \"dusk\": 0.411,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Zonotrichia albicollis\",\n        \"weight\": 0.1654,\n        \"count\": 435,\n        \"lowHz\": 2370,\n        \"highHz\": 5396,\n        \"durationSeconds\": 1.988,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.756,\n          \"day\": 0,\n          \"dusk\": 0.244,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Turdus migratorius\",\n        \"weight\": 0.1148,\n        \"count\": 302,\n        \"lowHz\": 1398,\n        \"highHz\": 3990,\n        \"durationSeconds\": 1.693,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.927,\n          \"day\": 0,\n          \"dusk\": 0.073,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Junco hyemalis\",\n        \"weight\": 0.1042,\n        \"count\": 274,\n        \"lowHz\": 3488,\n        \"highHz\": 7124,\n        \"durationSeconds\": 1.348,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.861,\n          \"day\": 0,\n          \"dusk\": 0.139,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Setophaga coronata\",\n        \"weight\": 0.0715,\n        \"count\": 188,\n        \"lowHz\": 2703,\n        \"highHz\": 6857,\n        \"durationSeconds\": 0.146,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.92,\n          \"day\": 0,\n          \"dusk\": 0.08,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Catharus ustulatus\",\n        \"weight\": 0.0627,\n        \"count\": 165,\n        \"lowHz\": 1152,\n        \"highHz\": 6615,\n        \"durationSeconds\": 1.192,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.412,\n          \"day\": 0,\n          \"dusk\": 0.588,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Picoides arcticus\",\n        \"weight\": 0.0354,\n        \"count\": 93,\n        \"lowHz\": 485,\n        \"highHz\": 5847,\n        \"durationSeconds\": 0.167,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"FNCA\",\n    \"region\": \"Floresta Nacional de Caraj˜s\",\n    \"country\": \"Brazil\",\n    \"biome\": \"Tropical and Subtropical Moist Broadleaf Forest\",\n    \"latitude\": -6.1792,\n    \"longitude\": -50.1568,\n    \"annotationCount\": 2573,\n    \"voices\": [\n      {\n        \"scientificName\": \"Saltator grossus\",\n        \"weight\": 0.2897,\n        \"count\": 330,\n        \"lowHz\": 1428,\n        \"highHz\": 3273,\n        \"durationSeconds\": 1.077,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Leptotila rufaxilla\",\n        \"weight\": 0.1466,\n        \"count\": 167,\n        \"lowHz\": 337,\n        \"highHz\": 701,\n        \"durationSeconds\": 0.998,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Cercomacra cinerascens\",\n        \"weight\": 0.1255,\n        \"count\": 143,\n        \"lowHz\": 1192,\n        \"highHz\": 3474,\n        \"durationSeconds\": 3.002,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Antrostomus rufus\",\n        \"weight\": 0.1212,\n        \"count\": 138,\n        \"lowHz\": 859,\n        \"highHz\": 2217,\n        \"durationSeconds\": 0.873,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.775,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0.225\n        }\n      },\n      {\n        \"scientificName\": \"Myrmoborus myotherinus\",\n        \"weight\": 0.1027,\n        \"count\": 117,\n        \"lowHz\": 2359,\n        \"highHz\": 5782,\n        \"durationSeconds\": 2.28,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Ramphocaenus melanurus\",\n        \"weight\": 0.0825,\n        \"count\": 94,\n        \"lowHz\": 2370,\n        \"highHz\": 3390,\n        \"durationSeconds\": 1.921,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Nyctiphrynus ocellatus\",\n        \"weight\": 0.0729,\n        \"count\": 83,\n        \"lowHz\": 677,\n        \"highHz\": 2241,\n        \"durationSeconds\": 1.348,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.892,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0.108\n        }\n      },\n      {\n        \"scientificName\": \"Lipaugus vociferans\",\n        \"weight\": 0.0588,\n        \"count\": 67,\n        \"lowHz\": 877,\n        \"highHz\": 5615,\n        \"durationSeconds\": 1.881,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"GLEN\",\n    \"region\": \"Glencrippesdale\",\n    \"country\": \"Scotland\",\n    \"biome\": \"Temperate Broadleaf and Mixed Forest\",\n    \"latitude\": 56.68,\n    \"longitude\": -5.7,\n    \"annotationCount\": 753,\n    \"voices\": [\n      {\n        \"scientificName\": \"Phylloscopus trochilus\",\n        \"weight\": 0.4721,\n        \"count\": 313,\n        \"lowHz\": 2276,\n        \"highHz\": 7261,\n        \"durationSeconds\": 2.569,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Troglodytes troglodytes\",\n        \"weight\": 0.1478,\n        \"count\": 98,\n        \"lowHz\": 2848,\n        \"highHz\": 8721,\n        \"durationSeconds\": 3.974,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Fringilla coelebs\",\n        \"weight\": 0.1222,\n        \"count\": 81,\n        \"lowHz\": 1959,\n        \"highHz\": 6938,\n        \"durationSeconds\": 1.88,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Periparus ater\",\n        \"weight\": 0.0935,\n        \"count\": 62,\n        \"lowHz\": 3534,\n        \"highHz\": 8477,\n        \"durationSeconds\": 1.438,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Erithacus rubecula\",\n        \"weight\": 0.0543,\n        \"count\": 36,\n        \"lowHz\": 2324,\n        \"highHz\": 9044,\n        \"durationSeconds\": 2.03,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Cyanistes caeruleus\",\n        \"weight\": 0.0392,\n        \"count\": 26,\n        \"lowHz\": 4680,\n        \"highHz\": 8810,\n        \"durationSeconds\": 1.348,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Parus major\",\n        \"weight\": 0.0377,\n        \"count\": 25,\n        \"lowHz\": 3646,\n        \"highHz\": 6656,\n        \"durationSeconds\": 2.724,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Larus argentatus\",\n        \"weight\": 0.0332,\n        \"count\": 22,\n        \"lowHz\": 581,\n        \"highHz\": 2433,\n        \"durationSeconds\": 3.901,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"GTLU\",\n    \"region\": \"Mayan Biosphere Reserve\",\n    \"country\": \"Guatemala\",\n    \"biome\": \"Tropical and Subtropical Moist Broadleaf Forest\",\n    \"latitude\": 17.4828,\n    \"longitude\": -90.0569,\n    \"annotationCount\": 2141,\n    \"voices\": [\n      {\n        \"scientificName\": \"Pachysylvia decurtata\",\n        \"weight\": 0.1878,\n        \"count\": 290,\n        \"lowHz\": 2387,\n        \"highHz\": 7310,\n        \"durationSeconds\": 0.706,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Trogon melanocephalus\",\n        \"weight\": 0.1645,\n        \"count\": 254,\n        \"lowHz\": 450,\n        \"highHz\": 2182,\n        \"durationSeconds\": 2.475,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Uropsila leucogastra\",\n        \"weight\": 0.1405,\n        \"count\": 217,\n        \"lowHz\": 1121,\n        \"highHz\": 3343,\n        \"durationSeconds\": 1.939,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Formicarius moniliger\",\n        \"weight\": 0.1056,\n        \"count\": 163,\n        \"lowHz\": 1194,\n        \"highHz\": 2845,\n        \"durationSeconds\": 2.279,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Piranga roseogularis\",\n        \"weight\": 0.1056,\n        \"count\": 163,\n        \"lowHz\": 1613,\n        \"highHz\": 4222,\n        \"durationSeconds\": 2.46,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Attila spadiceus\",\n        \"weight\": 0.1036,\n        \"count\": 160,\n        \"lowHz\": 1696,\n        \"highHz\": 3626,\n        \"durationSeconds\": 2.302,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Momotus lessonii\",\n        \"weight\": 0.0984,\n        \"count\": 152,\n        \"lowHz\": 150,\n        \"highHz\": 1180,\n        \"durationSeconds\": 0.533,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Tunchiornis ochraceiceps\",\n        \"weight\": 0.0939,\n        \"count\": 145,\n        \"lowHz\": 2915,\n        \"highHz\": 4328,\n        \"durationSeconds\": 0.78,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"HAG\",\n    \"region\": \"Haute Garonne\",\n    \"country\": \"France\",\n    \"biome\": \"Temperate Broadleaf and Mixed Forest\",\n    \"latitude\": 43.2161,\n    \"longitude\": 0.8808,\n    \"annotationCount\": 3243,\n    \"voices\": [\n      {\n        \"scientificName\": \"Sylvia atricapilla\",\n        \"weight\": 0.2645,\n        \"count\": 534,\n        \"lowHz\": 1722,\n        \"highHz\": 5275,\n        \"durationSeconds\": 2.887,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.528,\n          \"day\": 0.472,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Turdus merula\",\n        \"weight\": 0.1976,\n        \"count\": 399,\n        \"lowHz\": 1249,\n        \"highHz\": 3407,\n        \"durationSeconds\": 1.925,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.531,\n          \"day\": 0.469,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Luscinia megarhynchos\",\n        \"weight\": 0.1263,\n        \"count\": 255,\n        \"lowHz\": 1313,\n        \"highHz\": 5542,\n        \"durationSeconds\": 1.723,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.655,\n          \"day\": 0.345,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Curruca communis\",\n        \"weight\": 0.1228,\n        \"count\": 248,\n        \"lowHz\": 1739,\n        \"highHz\": 7033,\n        \"durationSeconds\": 1.429,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.548,\n          \"day\": 0.452,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Emberiza calandra\",\n        \"weight\": 0.0788,\n        \"count\": 159,\n        \"lowHz\": 3727,\n        \"highHz\": 9488,\n        \"durationSeconds\": 1.471,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.73,\n          \"day\": 0.27,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Phylloscopus collybita\",\n        \"weight\": 0.0728,\n        \"count\": 147,\n        \"lowHz\": 2917,\n        \"highHz\": 8045,\n        \"durationSeconds\": 3.471,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.605,\n          \"day\": 0.395,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Corvus corone\",\n        \"weight\": 0.0723,\n        \"count\": 146,\n        \"lowHz\": 381,\n        \"highHz\": 2765,\n        \"durationSeconds\": 1.605,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.726,\n          \"day\": 0.274,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Erithacus rubecula\",\n        \"weight\": 0.0649,\n        \"count\": 131,\n        \"lowHz\": 2015,\n        \"highHz\": 10072,\n        \"durationSeconds\": 2.202,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.573,\n          \"day\": 0.427,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"HAK\",\n    \"region\": \"Hakalau NFWR \",\n    \"country\": \"Hawaii (USA)\",\n    \"biome\": \"Tropical and Subtropical Moist Broadleaf Forest\",\n    \"latitude\": 19.7942,\n    \"longitude\": -155.3216,\n    \"annotationCount\": 4693,\n    \"voices\": [\n      {\n        \"scientificName\": \"Himatione sanguinea\",\n        \"weight\": 0.3032,\n        \"count\": 1361,\n        \"lowHz\": 1159,\n        \"highHz\": 5975,\n        \"durationSeconds\": 1.714,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.508,\n          \"day\": 0.09,\n          \"dusk\": 0.402,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Drepanis coccinea\",\n        \"weight\": 0.2702,\n        \"count\": 1213,\n        \"lowHz\": 1130,\n        \"highHz\": 10145,\n        \"durationSeconds\": 0.596,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.585,\n          \"day\": 0.11,\n          \"dusk\": 0.306,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Myadestes obscurus\",\n        \"weight\": 0.1116,\n        \"count\": 501,\n        \"lowHz\": 727,\n        \"highHz\": 3752,\n        \"durationSeconds\": 0.751,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.854,\n          \"day\": 0.006,\n          \"dusk\": 0.14,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Chlorodrepanis virens\",\n        \"weight\": 0.0929,\n        \"count\": 417,\n        \"lowHz\": 1567,\n        \"highHz\": 7227,\n        \"durationSeconds\": 0.497,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.58,\n          \"day\": 0.031,\n          \"dusk\": 0.388,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Zosterops japonicus\",\n        \"weight\": 0.0662,\n        \"count\": 297,\n        \"lowHz\": 3024,\n        \"highHz\": 7898,\n        \"durationSeconds\": 1.255,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.899,\n          \"day\": 0.067,\n          \"dusk\": 0.034,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Loxops mana\",\n        \"weight\": 0.0579,\n        \"count\": 260,\n        \"lowHz\": 2309,\n        \"highHz\": 7112,\n        \"durationSeconds\": 0.343,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.273,\n          \"day\": 0.023,\n          \"dusk\": 0.704,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Leiothrix lutea\",\n        \"weight\": 0.0535,\n        \"count\": 240,\n        \"lowHz\": 1210,\n        \"highHz\": 3982,\n        \"durationSeconds\": 2.914,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.3,\n          \"day\": 0.008,\n          \"dusk\": 0.692,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Loxops coccineus\",\n        \"weight\": 0.0446,\n        \"count\": 200,\n        \"lowHz\": 2980,\n        \"highHz\": 5678,\n        \"durationSeconds\": 0.51,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.08,\n          \"day\": 0.07,\n          \"dusk\": 0.85,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"HAR\",\n    \"region\": \"Haute Arige\",\n    \"country\": \"France\",\n    \"biome\": \"Montane Grasslands and Savannas & Boreal Forests/Taiga\",\n    \"latitude\": 42.6191,\n    \"longitude\": 1.7644,\n    \"annotationCount\": 351,\n    \"voices\": [\n      {\n        \"scientificName\": \"Fringilla coelebs\",\n        \"weight\": 0.2024,\n        \"count\": 51,\n        \"lowHz\": 2153,\n        \"highHz\": 6208,\n        \"durationSeconds\": 1.701,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.49,\n          \"day\": 0.51,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Sylvia atricapilla\",\n        \"weight\": 0.1746,\n        \"count\": 44,\n        \"lowHz\": 2012,\n        \"highHz\": 4404,\n        \"durationSeconds\": 2.535,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.318,\n          \"day\": 0.682,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Anthus trivialis\",\n        \"weight\": 0.1627,\n        \"count\": 41,\n        \"lowHz\": 2300,\n        \"highHz\": 8148,\n        \"durationSeconds\": 3.998,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.561,\n          \"day\": 0.439,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Prunella modularis\",\n        \"weight\": 0.1111,\n        \"count\": 28,\n        \"lowHz\": 2589,\n        \"highHz\": 8042,\n        \"durationSeconds\": 2.699,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.607,\n          \"day\": 0.393,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Periparus ater\",\n        \"weight\": 0.1032,\n        \"count\": 26,\n        \"lowHz\": 3010,\n        \"highHz\": 8098,\n        \"durationSeconds\": 1.225,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.231,\n          \"day\": 0.769,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Erithacus rubecula\",\n        \"weight\": 0.0913,\n        \"count\": 23,\n        \"lowHz\": 2400,\n        \"highHz\": 9197,\n        \"durationSeconds\": 2.021,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.522,\n          \"day\": 0.478,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Turdus merula\",\n        \"weight\": 0.0873,\n        \"count\": 22,\n        \"lowHz\": 1585,\n        \"highHz\": 2990,\n        \"durationSeconds\": 1.548,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Troglodytes troglodytes\",\n        \"weight\": 0.0675,\n        \"count\": 17,\n        \"lowHz\": 3134,\n        \"highHz\": 9034,\n        \"durationSeconds\": 3.486,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.824,\n          \"day\": 0.176,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"HONDO\",\n    \"region\": \"El Hondo Natural Park\",\n    \"country\": \"Spain\",\n    \"biome\": \"Wetland\",\n    \"latitude\": 38.1826,\n    \"longitude\": -0.7544,\n    \"annotationCount\": 770,\n    \"voices\": [\n      {\n        \"scientificName\": \"Phoenicopterus roseus\",\n        \"weight\": 0.2078,\n        \"count\": 101,\n        \"lowHz\": 289,\n        \"highHz\": 9328,\n        \"durationSeconds\": 0.338,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Acrocephalus arundinaceus\",\n        \"weight\": 0.2037,\n        \"count\": 99,\n        \"lowHz\": 1221,\n        \"highHz\": 6262,\n        \"durationSeconds\": 4,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Recurvirostra avosetta\",\n        \"weight\": 0.144,\n        \"count\": 70,\n        \"lowHz\": 1345,\n        \"highHz\": 9245,\n        \"durationSeconds\": 1.438,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Gallinula chloropus\",\n        \"weight\": 0.1235,\n        \"count\": 60,\n        \"lowHz\": 150,\n        \"highHz\": 5075,\n        \"durationSeconds\": 0.388,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Curruca melanocephala\",\n        \"weight\": 0.0947,\n        \"count\": 46,\n        \"lowHz\": 1558,\n        \"highHz\": 10824,\n        \"durationSeconds\": 0.133,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Tachybaptus ruficollis\",\n        \"weight\": 0.0926,\n        \"count\": 45,\n        \"lowHz\": 541,\n        \"highHz\": 4639,\n        \"durationSeconds\": 2.682,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Chroicocephalus ridibundus\",\n        \"weight\": 0.07,\n        \"count\": 34,\n        \"lowHz\": 647,\n        \"highHz\": 9472,\n        \"durationSeconds\": 1.778,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Acrocephalus scirpaceus\",\n        \"weight\": 0.0638,\n        \"count\": 31,\n        \"lowHz\": 1300,\n        \"highHz\": 10790,\n        \"durationSeconds\": 4,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"HUAP\",\n    \"region\": \"Huaping National Nature Reserve\",\n    \"country\": \"China (mainland)\",\n    \"biome\": \"Tropical and Subtropical Moist Broadleaf Forest\",\n    \"latitude\": 25.5891,\n    \"longitude\": 109.8936,\n    \"annotationCount\": 1140,\n    \"voices\": [\n      {\n        \"scientificName\": \"Hemixos castanonotus\",\n        \"weight\": 0.4122,\n        \"count\": 399,\n        \"lowHz\": 1938,\n        \"highHz\": 4197,\n        \"durationSeconds\": 1.324,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.749,\n          \"day\": 0.251,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Phylloscopus ricketti\",\n        \"weight\": 0.2738,\n        \"count\": 265,\n        \"lowHz\": 3565,\n        \"highHz\": 7323,\n        \"durationSeconds\": 1.633,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.728,\n          \"day\": 0.272,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Staphida torqueola\",\n        \"weight\": 0.0764,\n        \"count\": 74,\n        \"lowHz\": 2396,\n        \"highHz\": 5099,\n        \"durationSeconds\": 0.794,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.851,\n          \"day\": 0.149,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Erpornis zantholeuca\",\n        \"weight\": 0.063,\n        \"count\": 61,\n        \"lowHz\": 3800,\n        \"highHz\": 8865,\n        \"durationSeconds\": 1.034,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.885,\n          \"day\": 0.115,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Pericrocotus solaris\",\n        \"weight\": 0.062,\n        \"count\": 60,\n        \"lowHz\": 4106,\n        \"highHz\": 7316,\n        \"durationSeconds\": 0.811,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.867,\n          \"day\": 0.133,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Pitta nympha\",\n        \"weight\": 0.0444,\n        \"count\": 43,\n        \"lowHz\": 1312,\n        \"highHz\": 2527,\n        \"durationSeconds\": 1.257,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.535,\n          \"day\": 0.465,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Abroscopus albogularis\",\n        \"weight\": 0.0424,\n        \"count\": 41,\n        \"lowHz\": 4217,\n        \"highHz\": 4842,\n        \"durationSeconds\": 0.92,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.634,\n          \"day\": 0.366,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Psilopogon virens\",\n        \"weight\": 0.0258,\n        \"count\": 25,\n        \"lowHz\": 924,\n        \"highHz\": 14344,\n        \"durationSeconds\": 1.121,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.76,\n          \"day\": 0.24,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"JUNCA\",\n    \"region\": \"Juncabalejo. Doñana\",\n    \"country\": \"Spain\",\n    \"biome\": \"Wetland\",\n    \"latitude\": 36.9361,\n    \"longitude\": -6.3783,\n    \"annotationCount\": 403,\n    \"voices\": [\n      {\n        \"scientificName\": \"Emberiza calandra\",\n        \"weight\": 0.3801,\n        \"count\": 149,\n        \"lowHz\": 3772,\n        \"highHz\": 8334,\n        \"durationSeconds\": 1.407,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.638,\n          \"day\": 0.362,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Cisticola juncidis\",\n        \"weight\": 0.3648,\n        \"count\": 143,\n        \"lowHz\": 3625,\n        \"highHz\": 8525,\n        \"durationSeconds\": 2.586,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.58,\n          \"day\": 0.42,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Melanocorypha calandra\",\n        \"weight\": 0.0842,\n        \"count\": 33,\n        \"lowHz\": 1943,\n        \"highHz\": 6763,\n        \"durationSeconds\": 2.878,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.939,\n          \"day\": 0.061,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Saxicola rubicola\",\n        \"weight\": 0.0459,\n        \"count\": 18,\n        \"lowHz\": 150,\n        \"highHz\": 1980,\n        \"durationSeconds\": 0.134,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.889,\n          \"day\": 0.111,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Motacilla flava\",\n        \"weight\": 0.0408,\n        \"count\": 16,\n        \"lowHz\": 3268,\n        \"highHz\": 8072,\n        \"durationSeconds\": 0.308,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.625,\n          \"day\": 0.375,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Coturnix coturnix\",\n        \"weight\": 0.0383,\n        \"count\": 15,\n        \"lowHz\": 1696,\n        \"highHz\": 3930,\n        \"durationSeconds\": 0.39,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Calandrella brachydactyla\",\n        \"weight\": 0.0383,\n        \"count\": 15,\n        \"lowHz\": 2516,\n        \"highHz\": 6387,\n        \"durationSeconds\": 1.233,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Chloris chloris\",\n        \"weight\": 0.0077,\n        \"count\": 3,\n        \"lowHz\": 2497,\n        \"highHz\": 4513,\n        \"durationSeconds\": 0.586,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"KAR\",\n    \"region\": \"Ecopark Kringberget\",\n    \"country\": \"Sweden\",\n    \"biome\": \"Boreal Forests/Taiga\",\n    \"latitude\": 64.0578,\n    \"longitude\": 18.6402,\n    \"annotationCount\": 1053,\n    \"voices\": [\n      {\n        \"scientificName\": \"Fringilla coelebs\",\n        \"weight\": 0.5836,\n        \"count\": 534,\n        \"lowHz\": 1708,\n        \"highHz\": 6468,\n        \"durationSeconds\": 2.64,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.929,\n          \"day\": 0.071,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Regulus regulus\",\n        \"weight\": 0.1093,\n        \"count\": 100,\n        \"lowHz\": 5499,\n        \"highHz\": 8197,\n        \"durationSeconds\": 2.727,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.93,\n          \"day\": 0.07,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Spinus spinus\",\n        \"weight\": 0.059,\n        \"count\": 54,\n        \"lowHz\": 2656,\n        \"highHz\": 6098,\n        \"durationSeconds\": 4,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.926,\n          \"day\": 0.074,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Fringilla montifringilla\",\n        \"weight\": 0.0579,\n        \"count\": 53,\n        \"lowHz\": 2372,\n        \"highHz\": 4435,\n        \"durationSeconds\": 1.171,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.925,\n          \"day\": 0.075,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Turdus viscivorus\",\n        \"weight\": 0.0568,\n        \"count\": 52,\n        \"lowHz\": 1755,\n        \"highHz\": 3670,\n        \"durationSeconds\": 2.867,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.865,\n          \"day\": 0.135,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Ficedula hypoleuca\",\n        \"weight\": 0.0525,\n        \"count\": 48,\n        \"lowHz\": 2414,\n        \"highHz\": 6442,\n        \"durationSeconds\": 2.258,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Erithacus rubecula\",\n        \"weight\": 0.0437,\n        \"count\": 40,\n        \"lowHz\": 2164,\n        \"highHz\": 9169,\n        \"durationSeconds\": 2.862,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Poecile montanus\",\n        \"weight\": 0.0372,\n        \"count\": 34,\n        \"lowHz\": 3422,\n        \"highHz\": 4719,\n        \"durationSeconds\": 2.107,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.794,\n          \"day\": 0.206,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"KIB\",\n    \"region\": \"Kibale National Park\",\n    \"country\": \"Uganda\",\n    \"biome\": \"Tropical and Subtropical Moist Broadleaf Forest\",\n    \"latitude\": 0.5664,\n    \"longitude\": 30.3725,\n    \"annotationCount\": 1917,\n    \"voices\": [\n      {\n        \"scientificName\": \"Illadopsis albipectus\",\n        \"weight\": 0.2443,\n        \"count\": 290,\n        \"lowHz\": 2170,\n        \"highHz\": 3190,\n        \"durationSeconds\": 1.646,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.741,\n          \"day\": 0.259,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Pogoniulus bilineatus\",\n        \"weight\": 0.1609,\n        \"count\": 191,\n        \"lowHz\": 738,\n        \"highHz\": 1411,\n        \"durationSeconds\": 4,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.356,\n          \"day\": 0.644,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Camaroptera brachyura\",\n        \"weight\": 0.1365,\n        \"count\": 162,\n        \"lowHz\": 1260,\n        \"highHz\": 6070,\n        \"durationSeconds\": 2.508,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.426,\n          \"day\": 0.574,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Oriolus brachyrynchus\",\n        \"weight\": 0.1297,\n        \"count\": 154,\n        \"lowHz\": 428,\n        \"highHz\": 1716,\n        \"durationSeconds\": 0.887,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.675,\n          \"day\": 0.325,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Turtur tympanistria\",\n        \"weight\": 0.1028,\n        \"count\": 122,\n        \"lowHz\": 161,\n        \"highHz\": 748,\n        \"durationSeconds\": 4,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.426,\n          \"day\": 0.574,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Pogoniulus subsulphureus\",\n        \"weight\": 0.0834,\n        \"count\": 99,\n        \"lowHz\": 1033,\n        \"highHz\": 1708,\n        \"durationSeconds\": 4,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.475,\n          \"day\": 0.525,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Illadopsis fulvescens\",\n        \"weight\": 0.0809,\n        \"count\": 96,\n        \"lowHz\": 1057,\n        \"highHz\": 2313,\n        \"durationSeconds\": 1.282,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Eurillas latirostris\",\n        \"weight\": 0.0615,\n        \"count\": 73,\n        \"lowHz\": 1190,\n        \"highHz\": 4242,\n        \"durationSeconds\": 3.877,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.329,\n          \"day\": 0.671,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"LIM\",\n    \"region\": \"Los Limones. Monte Plata\",\n    \"country\": \"Dominican Republic\",\n    \"biome\": \"Tropical and Subtropical Dry Broadleaf Forest\",\n    \"latitude\": 18.9581,\n    \"longitude\": -69.7111,\n    \"annotationCount\": 1324,\n    \"voices\": [\n      {\n        \"scientificName\": \"Vireo altiloquus\",\n        \"weight\": 0.2941,\n        \"count\": 372,\n        \"lowHz\": 1350,\n        \"highHz\": 3990,\n        \"durationSeconds\": 1.169,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Coereba flaveola\",\n        \"weight\": 0.1486,\n        \"count\": 188,\n        \"lowHz\": 4481,\n        \"highHz\": 9714,\n        \"durationSeconds\": 4,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Tiaris olivaceus\",\n        \"weight\": 0.1423,\n        \"count\": 180,\n        \"lowHz\": 6741,\n        \"highHz\": 9821,\n        \"durationSeconds\": 2.04,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Crotophaga ani\",\n        \"weight\": 0.1399,\n        \"count\": 177,\n        \"lowHz\": 798,\n        \"highHz\": 2394,\n        \"durationSeconds\": 0.521,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Dulus dominicus\",\n        \"weight\": 0.1075,\n        \"count\": 136,\n        \"lowHz\": 783,\n        \"highHz\": 4849,\n        \"durationSeconds\": 1.635,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Melanerpes striatus\",\n        \"weight\": 0.0885,\n        \"count\": 112,\n        \"lowHz\": 1166,\n        \"highHz\": 3683,\n        \"durationSeconds\": 1.263,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Volatinia jacarina\",\n        \"weight\": 0.0451,\n        \"count\": 57,\n        \"lowHz\": 3253,\n        \"highHz\": 8471,\n        \"durationSeconds\": 0.484,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Nesoctites micromegas\",\n        \"weight\": 0.034,\n        \"count\": 43,\n        \"lowHz\": 798,\n        \"highHz\": 2394,\n        \"durationSeconds\": 0.244,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"MABI\",\n    \"region\": \"Marsh-Billings-Rockefeller NHP\",\n    \"country\": \"USA\",\n    \"biome\": \"Temperate Broadleaf and Mixed Forest\",\n    \"latitude\": 43.6312,\n    \"longitude\": -72.5179,\n    \"annotationCount\": 646,\n    \"voices\": [\n      {\n        \"scientificName\": \"Seiurus aurocapilla\",\n        \"weight\": 0.2747,\n        \"count\": 125,\n        \"lowHz\": 211,\n        \"highHz\": 9425,\n        \"durationSeconds\": 2.228,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Contopus virens\",\n        \"weight\": 0.1846,\n        \"count\": 84,\n        \"lowHz\": 503,\n        \"highHz\": 7053,\n        \"durationSeconds\": 1.478,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Catharus guttatus\",\n        \"weight\": 0.1538,\n        \"count\": 70,\n        \"lowHz\": 150,\n        \"highHz\": 7562,\n        \"durationSeconds\": 1.611,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Vireo olivaceus\",\n        \"weight\": 0.1165,\n        \"count\": 53,\n        \"lowHz\": 150,\n        \"highHz\": 6795,\n        \"durationSeconds\": 1.016,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Piranga olivacea\",\n        \"weight\": 0.0945,\n        \"count\": 43,\n        \"lowHz\": 150,\n        \"highHz\": 5895,\n        \"durationSeconds\": 3.628,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Setophaga pinus\",\n        \"weight\": 0.0637,\n        \"count\": 29,\n        \"lowHz\": 1474,\n        \"highHz\": 7158,\n        \"durationSeconds\": 1.913,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Poecile atricapillus\",\n        \"weight\": 0.0571,\n        \"count\": 26,\n        \"lowHz\": 1579,\n        \"highHz\": 7211,\n        \"durationSeconds\": 1.46,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Certhia americana\",\n        \"weight\": 0.0549,\n        \"count\": 25,\n        \"lowHz\": 5022,\n        \"highHz\": 8682,\n        \"durationSeconds\": 2.12,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"MAPIMI\",\n    \"region\": \"Reserva de la Biosfera Mapimi\",\n    \"country\": \"Mexico\",\n    \"biome\": \"Deserts and Xeric Shrublands\",\n    \"latitude\": 26.6883,\n    \"longitude\": -103.75,\n    \"annotationCount\": 622,\n    \"voices\": [\n      {\n        \"scientificName\": \"Dryobates scalaris\",\n        \"weight\": 0.2317,\n        \"count\": 136,\n        \"lowHz\": 690,\n        \"highHz\": 7171,\n        \"durationSeconds\": 0.211,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 0,\n          \"day\": 1,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Toxostoma curvirostre\",\n        \"weight\": 0.2215,\n        \"count\": 130,\n        \"lowHz\": 704,\n        \"highHz\": 5596,\n        \"durationSeconds\": 2.482,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.262,\n          \"day\": 0.738,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Cardinalis sinuatus\",\n        \"weight\": 0.1959,\n        \"count\": 115,\n        \"lowHz\": 966,\n        \"highHz\": 5474,\n        \"durationSeconds\": 1.691,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.183,\n          \"day\": 0.817,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Melozone fusca\",\n        \"weight\": 0.0869,\n        \"count\": 51,\n        \"lowHz\": 539,\n        \"highHz\": 8792,\n        \"durationSeconds\": 0.388,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.216,\n          \"day\": 0.784,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Myiarchus cinerascens\",\n        \"weight\": 0.0852,\n        \"count\": 50,\n        \"lowHz\": 1244,\n        \"highHz\": 3913,\n        \"durationSeconds\": 0.186,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.18,\n          \"day\": 0.82,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Polioptila melanura\",\n        \"weight\": 0.0698,\n        \"count\": 41,\n        \"lowHz\": 2304,\n        \"highHz\": 7040,\n        \"durationSeconds\": 1.471,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0,\n          \"day\": 1,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Lanius ludovicianus\",\n        \"weight\": 0.0562,\n        \"count\": 33,\n        \"lowHz\": 705,\n        \"highHz\": 6549,\n        \"durationSeconds\": 2.732,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.061,\n          \"day\": 0.939,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Passerina caerulea\",\n        \"weight\": 0.0528,\n        \"count\": 31,\n        \"lowHz\": 1758,\n        \"highHz\": 7452,\n        \"durationSeconds\": 0.204,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0,\n          \"day\": 1,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"MARTI\",\n    \"region\": \"Caño de Martinazo. Doñana\",\n    \"country\": \"Spain\",\n    \"biome\": \"Wetland\",\n    \"latitude\": 37.0282,\n    \"longitude\": -6.438,\n    \"annotationCount\": 392,\n    \"voices\": [\n      {\n        \"scientificName\": \"Emberiza calandra\",\n        \"weight\": 0.3207,\n        \"count\": 110,\n        \"lowHz\": 3417,\n        \"highHz\": 8576,\n        \"durationSeconds\": 1.385,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.773,\n          \"day\": 0.227,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Saxicola rubicola\",\n        \"weight\": 0.2741,\n        \"count\": 94,\n        \"lowHz\": 2270,\n        \"highHz\": 7021,\n        \"durationSeconds\": 1.282,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.457,\n          \"day\": 0.362,\n          \"dusk\": 0.181,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Pica pica\",\n        \"weight\": 0.1458,\n        \"count\": 50,\n        \"lowHz\": 932,\n        \"highHz\": 4740,\n        \"durationSeconds\": 0.448,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.96,\n          \"day\": 0.04,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Curruca melanocephala\",\n        \"weight\": 0.0612,\n        \"count\": 21,\n        \"lowHz\": 1962,\n        \"highHz\": 7308,\n        \"durationSeconds\": 0.829,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.905,\n          \"day\": 0.095,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Parus major\",\n        \"weight\": 0.0583,\n        \"count\": 20,\n        \"lowHz\": 3078,\n        \"highHz\": 6819,\n        \"durationSeconds\": 0.522,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0,\n          \"day\": 0,\n          \"dusk\": 1,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Cettia cetti\",\n        \"weight\": 0.0496,\n        \"count\": 17,\n        \"lowHz\": 1883,\n        \"highHz\": 8491,\n        \"durationSeconds\": 1.788,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.882,\n          \"day\": 0.059,\n          \"dusk\": 0.059,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Milvus migrans\",\n        \"weight\": 0.0496,\n        \"count\": 17,\n        \"lowHz\": 1682,\n        \"highHz\": 3056,\n        \"durationSeconds\": 2.399,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.706,\n          \"day\": 0.294,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Hippolais polyglotta\",\n        \"weight\": 0.0408,\n        \"count\": 14,\n        \"lowHz\": 1502,\n        \"highHz\": 7075,\n        \"durationSeconds\": 0.595,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.071,\n          \"day\": 0.929,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"MILLAN\",\n    \"region\": \"Cancela Mill˜n. Doñana\",\n    \"country\": \"Spain\",\n    \"biome\": \"Wetland\",\n    \"latitude\": 37.0191,\n    \"longitude\": -6.6025,\n    \"annotationCount\": 174,\n    \"voices\": [\n      {\n        \"scientificName\": \"Emberiza calandra\",\n        \"weight\": 0.5698,\n        \"count\": 98,\n        \"lowHz\": 3959,\n        \"highHz\": 8556,\n        \"durationSeconds\": 1.521,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.622,\n          \"day\": 0.296,\n          \"dusk\": 0.082,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Motacilla flava\",\n        \"weight\": 0.25,\n        \"count\": 43,\n        \"lowHz\": 3332,\n        \"highHz\": 7771,\n        \"durationSeconds\": 0.25,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.837,\n          \"day\": 0.163,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Anthus pratensis\",\n        \"weight\": 0.064,\n        \"count\": 11,\n        \"lowHz\": 4714,\n        \"highHz\": 7797,\n        \"durationSeconds\": 0.336,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.909,\n          \"day\": 0.091,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Melanocorypha calandra\",\n        \"weight\": 0.0349,\n        \"count\": 6,\n        \"lowHz\": 1787,\n        \"highHz\": 6468,\n        \"durationSeconds\": 4,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0,\n          \"day\": 0.833,\n          \"dusk\": 0.167,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Riparia riparia\",\n        \"weight\": 0.0291,\n        \"count\": 5,\n        \"lowHz\": 1939,\n        \"highHz\": 7079,\n        \"durationSeconds\": 0.569,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Pica pica\",\n        \"weight\": 0.0233,\n        \"count\": 4,\n        \"lowHz\": 986,\n        \"highHz\": 4618,\n        \"durationSeconds\": 0.144,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.25,\n          \"day\": 0.75,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Galerida cristata\",\n        \"weight\": 0.0174,\n        \"count\": 3,\n        \"lowHz\": 1300,\n        \"highHz\": 6578,\n        \"durationSeconds\": 4,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0,\n          \"day\": 0,\n          \"dusk\": 1,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Corvus corax\",\n        \"weight\": 0.0116,\n        \"count\": 2,\n        \"lowHz\": 664,\n        \"highHz\": 3063,\n        \"durationSeconds\": 1.445,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 0,\n          \"day\": 1,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"MONTEB\",\n    \"region\": \"Monteblanco entrada. Doñana\",\n    \"country\": \"Spain\",\n    \"biome\": \"Mediterranean Forests. Woodlands and shrublands\",\n    \"latitude\": 37.0208,\n    \"longitude\": -6.5545,\n    \"annotationCount\": 335,\n    \"voices\": [\n      {\n        \"scientificName\": \"Galerida theklae\",\n        \"weight\": 0.4557,\n        \"count\": 149,\n        \"lowHz\": 2694,\n        \"highHz\": 5913,\n        \"durationSeconds\": 1.311,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.779,\n          \"day\": 0.221,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Curruca undata\",\n        \"weight\": 0.3211,\n        \"count\": 105,\n        \"lowHz\": 2484,\n        \"highHz\": 6050,\n        \"durationSeconds\": 1.482,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.505,\n          \"day\": 0.495,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Cyanopica cooki\",\n        \"weight\": 0.0887,\n        \"count\": 29,\n        \"lowHz\": 1781,\n        \"highHz\": 6823,\n        \"durationSeconds\": 0.607,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.966,\n          \"day\": 0.034,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Curruca melanocephala\",\n        \"weight\": 0.0642,\n        \"count\": 21,\n        \"lowHz\": 2501,\n        \"highHz\": 5967,\n        \"durationSeconds\": 1.396,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.857,\n          \"day\": 0.143,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Chloris chloris\",\n        \"weight\": 0.0398,\n        \"count\": 13,\n        \"lowHz\": 2557,\n        \"highHz\": 5041,\n        \"durationSeconds\": 0.905,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.846,\n          \"day\": 0.154,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Carduelis carduelis\",\n        \"weight\": 0.0183,\n        \"count\": 6,\n        \"lowHz\": 2739,\n        \"highHz\": 7486,\n        \"durationSeconds\": 1.292,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.667,\n          \"day\": 0.333,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Burhinus oedicnemus\",\n        \"weight\": 0.0061,\n        \"count\": 2,\n        \"lowHz\": 2489,\n        \"highHz\": 3459,\n        \"durationSeconds\": 0.368,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Curruca conspicillata\",\n        \"weight\": 0.0061,\n        \"count\": 2,\n        \"lowHz\": 2842,\n        \"highHz\": 6693,\n        \"durationSeconds\": 1.34,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 0,\n          \"day\": 1,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"MOPU\",\n    \"region\": \"Monte Pblico. Zarzalejo\",\n    \"country\": \"Spain\",\n    \"biome\": \"Mediterranean Forests. Woodlands and shrublands\",\n    \"latitude\": 40.527,\n    \"longitude\": -4.1768,\n    \"annotationCount\": 923,\n    \"voices\": [\n      {\n        \"scientificName\": \"Emberiza calandra\",\n        \"weight\": 0.3425,\n        \"count\": 273,\n        \"lowHz\": 2940,\n        \"highHz\": 9188,\n        \"durationSeconds\": 1.862,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.242,\n          \"day\": 0.637,\n          \"dusk\": 0.121,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Lullula arborea\",\n        \"weight\": 0.202,\n        \"count\": 161,\n        \"lowHz\": 2001,\n        \"highHz\": 4461,\n        \"durationSeconds\": 2.617,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.342,\n          \"day\": 0.615,\n          \"dusk\": 0.043,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Fringilla coelebs\",\n        \"weight\": 0.1543,\n        \"count\": 123,\n        \"lowHz\": 1831,\n        \"highHz\": 5519,\n        \"durationSeconds\": 1.455,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.163,\n          \"day\": 0.829,\n          \"dusk\": 0.008,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Turdus merula\",\n        \"weight\": 0.0878,\n        \"count\": 70,\n        \"lowHz\": 1220,\n        \"highHz\": 6675,\n        \"durationSeconds\": 2.294,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.671,\n          \"day\": 0.071,\n          \"dusk\": 0.257,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Petronia petronia\",\n        \"weight\": 0.0703,\n        \"count\": 56,\n        \"lowHz\": 2131,\n        \"highHz\": 6299,\n        \"durationSeconds\": 0.485,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0,\n          \"day\": 1,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Serinus serinus\",\n        \"weight\": 0.0577,\n        \"count\": 46,\n        \"lowHz\": 4429,\n        \"highHz\": 8759,\n        \"durationSeconds\": 0.683,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.326,\n          \"day\": 0.674,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Luscinia megarhynchos\",\n        \"weight\": 0.0464,\n        \"count\": 37,\n        \"lowHz\": 1394,\n        \"highHz\": 3954,\n        \"durationSeconds\": 1.173,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.405,\n          \"day\": 0.297,\n          \"dusk\": 0.297,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Cuculus canorus\",\n        \"weight\": 0.0389,\n        \"count\": 31,\n        \"lowHz\": 245,\n        \"highHz\": 1050,\n        \"durationSeconds\": 3.486,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.839,\n          \"day\": 0.161,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"NAV\",\n    \"region\": \"Navarra\",\n    \"country\": \"Spain\",\n    \"biome\": \"Temperate Broadleaf and Mixed Forest\",\n    \"latitude\": 43.0165,\n    \"longitude\": -1.7748,\n    \"annotationCount\": 1549,\n    \"voices\": [\n      {\n        \"scientificName\": \"Turdus philomelos\",\n        \"weight\": 0.2007,\n        \"count\": 237,\n        \"lowHz\": 1311,\n        \"highHz\": 5086,\n        \"durationSeconds\": 2.165,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Cyanistes caeruleus\",\n        \"weight\": 0.1931,\n        \"count\": 228,\n        \"lowHz\": 3139,\n        \"highHz\": 9536,\n        \"durationSeconds\": 1.136,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Erithacus rubecula\",\n        \"weight\": 0.1787,\n        \"count\": 211,\n        \"lowHz\": 2066,\n        \"highHz\": 9954,\n        \"durationSeconds\": 1.745,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Periparus ater\",\n        \"weight\": 0.1194,\n        \"count\": 141,\n        \"lowHz\": 2980,\n        \"highHz\": 8305,\n        \"durationSeconds\": 1.989,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Parus major\",\n        \"weight\": 0.0982,\n        \"count\": 116,\n        \"lowHz\": 3060,\n        \"highHz\": 8394,\n        \"durationSeconds\": 1.23,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Certhia brachydactyla\",\n        \"weight\": 0.0779,\n        \"count\": 92,\n        \"lowHz\": 3894,\n        \"highHz\": 7828,\n        \"durationSeconds\": 1.694,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Fringilla coelebs\",\n        \"weight\": 0.0711,\n        \"count\": 84,\n        \"lowHz\": 1589,\n        \"highHz\": 5305,\n        \"durationSeconds\": 1.542,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Dendrocopos major\",\n        \"weight\": 0.061,\n        \"count\": 72,\n        \"lowHz\": 150,\n        \"highHz\": 11930,\n        \"durationSeconds\": 0.827,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"NL\",\n    \"region\": \"Eeyou Istchee James Bay\",\n    \"country\": \"Canada\",\n    \"biome\": \"Boreal forest/Taiga\",\n    \"latitude\": 51.876,\n    \"longitude\": -76.065,\n    \"annotationCount\": 224,\n    \"voices\": [\n      {\n        \"scientificName\": \"Catharus guttatus\",\n        \"weight\": 0.2977,\n        \"count\": 64,\n        \"lowHz\": 1588,\n        \"highHz\": 4485,\n        \"durationSeconds\": 1.232,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Zonotrichia albicollis\",\n        \"weight\": 0.2512,\n        \"count\": 54,\n        \"lowHz\": 2796,\n        \"highHz\": 4750,\n        \"durationSeconds\": 2.956,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Setophaga striata\",\n        \"weight\": 0.0977,\n        \"count\": 21,\n        \"lowHz\": 2862,\n        \"highHz\": 7444,\n        \"durationSeconds\": 1.399,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Setophaga coronata\",\n        \"weight\": 0.093,\n        \"count\": 20,\n        \"lowHz\": 4008,\n        \"highHz\": 6131,\n        \"durationSeconds\": 1.461,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Turdus migratorius\",\n        \"weight\": 0.0884,\n        \"count\": 19,\n        \"lowHz\": 1491,\n        \"highHz\": 3393,\n        \"durationSeconds\": 1.184,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Melospiza georgiana\",\n        \"weight\": 0.0651,\n        \"count\": 14,\n        \"lowHz\": 3794,\n        \"highHz\": 6503,\n        \"durationSeconds\": 1.467,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Contopus cooperi\",\n        \"weight\": 0.0605,\n        \"count\": 13,\n        \"lowHz\": 2069,\n        \"highHz\": 4364,\n        \"durationSeconds\": 1.261,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Junco hyemalis\",\n        \"weight\": 0.0465,\n        \"count\": 10,\n        \"lowHz\": 3842,\n        \"highHz\": 6729,\n        \"durationSeconds\": 1.436,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"OESF\",\n    \"region\": \"Olympic Experimental SF\",\n    \"country\": \"USA\",\n    \"biome\": \"Temperate Coniferous Forest\",\n    \"latitude\": 47.7152,\n    \"longitude\": -124.1697,\n    \"annotationCount\": 1428,\n    \"voices\": [\n      {\n        \"scientificName\": \"Empidonax difficilis\",\n        \"weight\": 0.411,\n        \"count\": 570,\n        \"lowHz\": 3666,\n        \"highHz\": 8142,\n        \"durationSeconds\": 0.594,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.542,\n          \"day\": 0.337,\n          \"dusk\": 0.111,\n          \"night\": 0.011\n        }\n      },\n      {\n        \"scientificName\": \"Ixoreus naevius\",\n        \"weight\": 0.1478,\n        \"count\": 205,\n        \"lowHz\": 2719,\n        \"highHz\": 3746,\n        \"durationSeconds\": 1.599,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.537,\n          \"day\": 0.132,\n          \"dusk\": 0.263,\n          \"night\": 0.068\n        }\n      },\n      {\n        \"scientificName\": \"Poecile rufescens\",\n        \"weight\": 0.119,\n        \"count\": 165,\n        \"lowHz\": 3473,\n        \"highHz\": 8411,\n        \"durationSeconds\": 0.755,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.618,\n          \"day\": 0.321,\n          \"dusk\": 0.061,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Certhia americana\",\n        \"weight\": 0.1081,\n        \"count\": 150,\n        \"lowHz\": 6665,\n        \"highHz\": 8294,\n        \"durationSeconds\": 0.898,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.66,\n          \"day\": 0.293,\n          \"dusk\": 0.047,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Troglodytes pacificus\",\n        \"weight\": 0.0858,\n        \"count\": 119,\n        \"lowHz\": 3218,\n        \"highHz\": 8494,\n        \"durationSeconds\": 4,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.739,\n          \"day\": 0.109,\n          \"dusk\": 0.151,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Turdus migratorius\",\n        \"weight\": 0.0707,\n        \"count\": 98,\n        \"lowHz\": 1652,\n        \"highHz\": 3525,\n        \"durationSeconds\": 1.849,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.888,\n          \"day\": 0,\n          \"dusk\": 0.112,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Sitta canadensis\",\n        \"weight\": 0.0425,\n        \"count\": 59,\n        \"lowHz\": 2184,\n        \"highHz\": 2999,\n        \"durationSeconds\": 2.742,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.559,\n          \"day\": 0.305,\n          \"dusk\": 0.136,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Regulus satrapa\",\n        \"weight\": 0.0151,\n        \"count\": 21,\n        \"lowHz\": 6948,\n        \"highHz\": 9414,\n        \"durationSeconds\": 2.154,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.905,\n          \"day\": 0.095,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"OIO\",\n    \"region\": \"Ontigola Toledo & Villaconejos\",\n    \"country\": \"Spain\",\n    \"biome\": \"Mediterranean Forests. Woodlands and shrublands\",\n    \"latitude\": 40.0115,\n    \"longitude\": -3.577,\n    \"annotationCount\": 1001,\n    \"voices\": [\n      {\n        \"scientificName\": \"Pycnonotus barbatus\",\n        \"weight\": 0.2535,\n        \"count\": 143,\n        \"lowHz\": 1374,\n        \"highHz\": 3932,\n        \"durationSeconds\": 0.971,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.643,\n          \"day\": 0.168,\n          \"dusk\": 0.189,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Dicrurus divaricatus\",\n        \"weight\": 0.2039,\n        \"count\": 115,\n        \"lowHz\": 1140,\n        \"highHz\": 4965,\n        \"durationSeconds\": 0.347,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Streptopelia vinacea\",\n        \"weight\": 0.1064,\n        \"count\": 60,\n        \"lowHz\": 437,\n        \"highHz\": 1043,\n        \"durationSeconds\": 4,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.733,\n          \"day\": 0.1,\n          \"dusk\": 0.167,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Camaroptera brachyura\",\n        \"weight\": 0.1046,\n        \"count\": 59,\n        \"lowHz\": 1404,\n        \"highHz\": 4919,\n        \"durationSeconds\": 1.315,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.322,\n          \"day\": 0.678,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Melocichla mentalis\",\n        \"weight\": 0.094,\n        \"count\": 53,\n        \"lowHz\": 1677,\n        \"highHz\": 3881,\n        \"durationSeconds\": 1.686,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.755,\n          \"day\": 0.057,\n          \"dusk\": 0.189,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Pternistis bicalcaratus\",\n        \"weight\": 0.0816,\n        \"count\": 46,\n        \"lowHz\": 1014,\n        \"highHz\": 4032,\n        \"durationSeconds\": 4,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.609,\n          \"day\": 0.239,\n          \"dusk\": 0.152,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Oriolus auratus\",\n        \"weight\": 0.0816,\n        \"count\": 46,\n        \"lowHz\": 1102,\n        \"highHz\": 2461,\n        \"durationSeconds\": 0.629,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.63,\n          \"day\": 0.37,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Platysteira cyanea\",\n        \"weight\": 0.0745,\n        \"count\": 42,\n        \"lowHz\": 2043,\n        \"highHz\": 4364,\n        \"durationSeconds\": 3.261,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.357,\n          \"day\": 0.643,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"OLIV\",\n    \"region\": \"Oio Region. Guinea-Bissau\",\n    \"country\": \"Guinea-Bissau\",\n    \"biome\": \"Tropical and Subtropical Dry Broadleaf Forest\",\n    \"latitude\": 12.3808,\n    \"longitude\": -15.2043,\n    \"annotationCount\": 484,\n    \"voices\": [\n      {\n        \"scientificName\": \"Fringilla coelebs\",\n        \"weight\": 0.2894,\n        \"count\": 123,\n        \"lowHz\": 2356,\n        \"highHz\": 6877,\n        \"durationSeconds\": 0.476,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.837,\n          \"day\": 0.163,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Erithacus rubecula\",\n        \"weight\": 0.2212,\n        \"count\": 94,\n        \"lowHz\": 4426,\n        \"highHz\": 8403,\n        \"durationSeconds\": 0.627,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.989,\n          \"day\": 0.011,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Curruca melanocephala\",\n        \"weight\": 0.1906,\n        \"count\": 81,\n        \"lowHz\": 2083,\n        \"highHz\": 6159,\n        \"durationSeconds\": 1.19,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.63,\n          \"day\": 0.37,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Galerida cristata\",\n        \"weight\": 0.1129,\n        \"count\": 48,\n        \"lowHz\": 2708,\n        \"highHz\": 4982,\n        \"durationSeconds\": 1.766,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.208,\n          \"day\": 0.792,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Sylvia atricapilla\",\n        \"weight\": 0.08,\n        \"count\": 34,\n        \"lowHz\": 1899,\n        \"highHz\": 7344,\n        \"durationSeconds\": 4,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.912,\n          \"day\": 0.088,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Pyrrhocorax pyrrhocorax\",\n        \"weight\": 0.0494,\n        \"count\": 21,\n        \"lowHz\": 1184,\n        \"highHz\": 4288,\n        \"durationSeconds\": 0.595,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Chloris chloris\",\n        \"weight\": 0.0329,\n        \"count\": 14,\n        \"lowHz\": 2120,\n        \"highHz\": 4165,\n        \"durationSeconds\": 0.378,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.786,\n          \"day\": 0.214,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Parus major\",\n        \"weight\": 0.0235,\n        \"count\": 10,\n        \"lowHz\": 3032,\n        \"highHz\": 4930,\n        \"durationSeconds\": 0.467,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0,\n          \"day\": 1,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"PETI\",\n    \"region\": \"Estao Ambiental de Peti\",\n    \"country\": \"Brazil\",\n    \"biome\": \"Tropical and Subtropical Moist Broadleaf Forest\",\n    \"latitude\": -19.8992,\n    \"longitude\": -43.3686,\n    \"annotationCount\": 1006,\n    \"voices\": [\n      {\n        \"scientificName\": \"Basileuterus culicivorus\",\n        \"weight\": 0.2449,\n        \"count\": 192,\n        \"lowHz\": 3268,\n        \"highHz\": 7259,\n        \"durationSeconds\": 1.497,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Chiroxiphia caudata\",\n        \"weight\": 0.227,\n        \"count\": 178,\n        \"lowHz\": 1272,\n        \"highHz\": 3150,\n        \"durationSeconds\": 1.328,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.747,\n          \"day\": 0.253,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Herpsilochmus rufimarginatus\",\n        \"weight\": 0.1276,\n        \"count\": 100,\n        \"lowHz\": 1497,\n        \"highHz\": 2993,\n        \"durationSeconds\": 1.609,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Vireo chivi\",\n        \"weight\": 0.1173,\n        \"count\": 92,\n        \"lowHz\": 2147,\n        \"highHz\": 4835,\n        \"durationSeconds\": 0.399,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Tolmomyias sulphurescens\",\n        \"weight\": 0.111,\n        \"count\": 87,\n        \"lowHz\": 3726,\n        \"highHz\": 6796,\n        \"durationSeconds\": 2.166,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Saltator similis\",\n        \"weight\": 0.0651,\n        \"count\": 51,\n        \"lowHz\": 1755,\n        \"highHz\": 4278,\n        \"durationSeconds\": 1.611,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Casiornis rufus\",\n        \"weight\": 0.0561,\n        \"count\": 44,\n        \"lowHz\": 3517,\n        \"highHz\": 4839,\n        \"durationSeconds\": 0.45,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Turdus leucomelas\",\n        \"weight\": 0.051,\n        \"count\": 40,\n        \"lowHz\": 1983,\n        \"highHz\": 8257,\n        \"durationSeconds\": 1.001,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"PGF\",\n    \"region\": \"Parc des Grandes Fougres\",\n    \"country\": \"New Caledonia\",\n    \"biome\": \"Tropical and Subtropical Moist Broadleaf Forest\",\n    \"latitude\": -21.6222,\n    \"longitude\": 165.7612,\n    \"annotationCount\": 514,\n    \"voices\": [\n      {\n        \"scientificName\": \"Pachycephala caledonica\",\n        \"weight\": 0.3239,\n        \"count\": 126,\n        \"lowHz\": 1250,\n        \"highHz\": 5185,\n        \"durationSeconds\": 1.026,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.881,\n          \"day\": 0.119,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Myiagra caledonica\",\n        \"weight\": 0.1671,\n        \"count\": 65,\n        \"lowHz\": 1912,\n        \"highHz\": 5185,\n        \"durationSeconds\": 0.776,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Ducula goliath\",\n        \"weight\": 0.1131,\n        \"count\": 44,\n        \"lowHz\": 150,\n        \"highHz\": 368,\n        \"durationSeconds\": 2,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Myzomela caledonica\",\n        \"weight\": 0.0951,\n        \"count\": 37,\n        \"lowHz\": 3016,\n        \"highHz\": 7575,\n        \"durationSeconds\": 0.764,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.757,\n          \"day\": 0.243,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Drepanoptila holosericea\",\n        \"weight\": 0.09,\n        \"count\": 35,\n        \"lowHz\": 150,\n        \"highHz\": 369,\n        \"durationSeconds\": 4,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.971,\n          \"day\": 0.029,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Clytorhynchus pachycephaloides\",\n        \"weight\": 0.0848,\n        \"count\": 33,\n        \"lowHz\": 1471,\n        \"highHz\": 2648,\n        \"durationSeconds\": 0.911,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.909,\n          \"day\": 0.091,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Philemon diemenensis\",\n        \"weight\": 0.0643,\n        \"count\": 25,\n        \"lowHz\": 662,\n        \"highHz\": 2868,\n        \"durationSeconds\": 2.882,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.96,\n          \"day\": 0.04,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Zosterops xanthochroa\",\n        \"weight\": 0.0617,\n        \"count\": 24,\n        \"lowHz\": 2704,\n        \"highHz\": 5421,\n        \"durationSeconds\": 3.204,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.5,\n          \"day\": 0.5,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"PINA\",\n    \"region\": \"Tierra de Pinares. Valladolid\",\n    \"country\": \"Spain\",\n    \"biome\": \"Mediterranean Forests. Woodlands and shrublands\",\n    \"latitude\": 41.4582,\n    \"longitude\": -4.7137,\n    \"annotationCount\": 1670,\n    \"voices\": [\n      {\n        \"scientificName\": \"Periparus ater\",\n        \"weight\": 0.1973,\n        \"count\": 216,\n        \"lowHz\": 3147,\n        \"highHz\": 7378,\n        \"durationSeconds\": 1.632,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.94,\n          \"day\": 0.06,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Certhia brachydactyla\",\n        \"weight\": 0.1662,\n        \"count\": 182,\n        \"lowHz\": 4221,\n        \"highHz\": 7734,\n        \"durationSeconds\": 1.404,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.962,\n          \"day\": 0.038,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Fringilla coelebs\",\n        \"weight\": 0.1571,\n        \"count\": 172,\n        \"lowHz\": 1715,\n        \"highHz\": 4987,\n        \"durationSeconds\": 1.575,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.959,\n          \"day\": 0.041,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Phylloscopus bonelli\",\n        \"weight\": 0.1361,\n        \"count\": 149,\n        \"lowHz\": 2525,\n        \"highHz\": 7305,\n        \"durationSeconds\": 0.916,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.98,\n          \"day\": 0.02,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Serinus serinus\",\n        \"weight\": 0.1087,\n        \"count\": 119,\n        \"lowHz\": 4169,\n        \"highHz\": 9699,\n        \"durationSeconds\": 2.041,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.992,\n          \"day\": 0.008,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Lullula arborea\",\n        \"weight\": 0.0932,\n        \"count\": 102,\n        \"lowHz\": 1904,\n        \"highHz\": 4548,\n        \"durationSeconds\": 2.022,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.99,\n          \"day\": 0.01,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Lophophanes cristatus\",\n        \"weight\": 0.0795,\n        \"count\": 87,\n        \"lowHz\": 2209,\n        \"highHz\": 6678,\n        \"durationSeconds\": 1.072,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Turdus viscivorus\",\n        \"weight\": 0.0621,\n        \"count\": 68,\n        \"lowHz\": 1431,\n        \"highHz\": 7388,\n        \"durationSeconds\": 1.366,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.853,\n          \"day\": 0.147,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"PITI\",\n    \"region\": \"Pitillas Lagoon\",\n    \"country\": \"Spain\",\n    \"biome\": \"Wetlands\",\n    \"latitude\": 42.4116,\n    \"longitude\": -1.5861,\n    \"annotationCount\": 990,\n    \"voices\": [\n      {\n        \"scientificName\": \"Luscinia megarhynchos\",\n        \"weight\": 0.2913,\n        \"count\": 247,\n        \"lowHz\": 1230,\n        \"highHz\": 8000,\n        \"durationSeconds\": 2.2,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Motacilla flava\",\n        \"weight\": 0.2241,\n        \"count\": 190,\n        \"lowHz\": 3400,\n        \"highHz\": 7575,\n        \"durationSeconds\": 0.532,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Acrocephalus arundinaceus\",\n        \"weight\": 0.1899,\n        \"count\": 161,\n        \"lowHz\": 1021,\n        \"highHz\": 7235,\n        \"durationSeconds\": 3.152,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Acrocephalus scirpaceus\",\n        \"weight\": 0.1215,\n        \"count\": 103,\n        \"lowHz\": 1342,\n        \"highHz\": 5736,\n        \"durationSeconds\": 4,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Cettia cetti\",\n        \"weight\": 0.066,\n        \"count\": 56,\n        \"lowHz\": 1258,\n        \"highHz\": 8000,\n        \"durationSeconds\": 2.318,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Passer domesticus\",\n        \"weight\": 0.0389,\n        \"count\": 33,\n        \"lowHz\": 1486,\n        \"highHz\": 7890,\n        \"durationSeconds\": 2.391,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Circus aeruginosus\",\n        \"weight\": 0.0342,\n        \"count\": 29,\n        \"lowHz\": 1873,\n        \"highHz\": 7748,\n        \"durationSeconds\": 3.887,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Chloris chloris\",\n        \"weight\": 0.0342,\n        \"count\": 29,\n        \"lowHz\": 2036,\n        \"highHz\": 8000,\n        \"durationSeconds\": 0.818,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"POZO\",\n    \"region\": \"Pozo de Santa Olalla. Doñana\",\n    \"country\": \"Spain\",\n    \"biome\": \"Mediterranean Forests. Woodlands and shrublands\",\n    \"latitude\": 36.9819,\n    \"longitude\": -6.4824,\n    \"annotationCount\": 1260,\n    \"voices\": [\n      {\n        \"scientificName\": \"Luscinia megarhynchos\",\n        \"weight\": 0.3242,\n        \"count\": 367,\n        \"lowHz\": 1799,\n        \"highHz\": 4543,\n        \"durationSeconds\": 0.849,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.85,\n          \"day\": 0.15,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Cisticola juncidis\",\n        \"weight\": 0.2208,\n        \"count\": 250,\n        \"lowHz\": 4410,\n        \"highHz\": 7733,\n        \"durationSeconds\": 0.108,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.656,\n          \"day\": 0.344,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Curruca melanocephala\",\n        \"weight\": 0.1113,\n        \"count\": 126,\n        \"lowHz\": 2338,\n        \"highHz\": 6403,\n        \"durationSeconds\": 0.738,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.571,\n          \"day\": 0.429,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Saxicola rubicola\",\n        \"weight\": 0.1087,\n        \"count\": 123,\n        \"lowHz\": 2374,\n        \"highHz\": 7509,\n        \"durationSeconds\": 0.108,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.789,\n          \"day\": 0.211,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Galerida theklae\",\n        \"weight\": 0.0769,\n        \"count\": 87,\n        \"lowHz\": 2333,\n        \"highHz\": 5870,\n        \"durationSeconds\": 0.818,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.471,\n          \"day\": 0.529,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Chloris chloris\",\n        \"weight\": 0.0618,\n        \"count\": 70,\n        \"lowHz\": 2323,\n        \"highHz\": 4283,\n        \"durationSeconds\": 0.461,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.486,\n          \"day\": 0.514,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Merops apiaster\",\n        \"weight\": 0.053,\n        \"count\": 60,\n        \"lowHz\": 1580,\n        \"highHz\": 2441,\n        \"durationSeconds\": 0.149,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.367,\n          \"day\": 0.633,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Carduelis carduelis\",\n        \"weight\": 0.0433,\n        \"count\": 49,\n        \"lowHz\": 1932,\n        \"highHz\": 5797,\n        \"durationSeconds\": 1.482,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.878,\n          \"day\": 0.122,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"PUUL\",\n    \"region\": \"Pu'u L'au. Hawai'i\",\n    \"country\": \"Hawaii (USA)\",\n    \"biome\": \"Tropical and Subtropical Dry Broadleaf Forest\",\n    \"latitude\": 19.862,\n    \"longitude\": -155.5431,\n    \"annotationCount\": 2149,\n    \"voices\": [\n      {\n        \"scientificName\": \"Chlorodrepanis virens\",\n        \"weight\": 0.4596,\n        \"count\": 939,\n        \"lowHz\": 1865,\n        \"highHz\": 7210,\n        \"durationSeconds\": 0.329,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.693,\n          \"day\": 0.307,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Haemorhous mexicanus\",\n        \"weight\": 0.1875,\n        \"count\": 383,\n        \"lowHz\": 1638,\n        \"highHz\": 5590,\n        \"durationSeconds\": 1.504,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.843,\n          \"day\": 0.157,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Pternistis erckelii\",\n        \"weight\": 0.1424,\n        \"count\": 291,\n        \"lowHz\": 228,\n        \"highHz\": 3058,\n        \"durationSeconds\": 2.428,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.948,\n          \"day\": 0.052,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Meleagris gallopavo\",\n        \"weight\": 0.0548,\n        \"count\": 112,\n        \"lowHz\": 162,\n        \"highHz\": 2235,\n        \"durationSeconds\": 1.099,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.964,\n          \"day\": 0.036,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Zosterops japonicus\",\n        \"weight\": 0.0534,\n        \"count\": 109,\n        \"lowHz\": 2833,\n        \"highHz\": 7323,\n        \"durationSeconds\": 0.319,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.642,\n          \"day\": 0.358,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Crithagra mozambica\",\n        \"weight\": 0.0406,\n        \"count\": 83,\n        \"lowHz\": 2230,\n        \"highHz\": 7394,\n        \"durationSeconds\": 1.097,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.807,\n          \"day\": 0.193,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Callipepla californica\",\n        \"weight\": 0.0367,\n        \"count\": 75,\n        \"lowHz\": 595,\n        \"highHz\": 2165,\n        \"durationSeconds\": 0.55,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.96,\n          \"day\": 0.04,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Cardinalis cardinalis\",\n        \"weight\": 0.025,\n        \"count\": 51,\n        \"lowHz\": 1182,\n        \"highHz\": 4216,\n        \"durationSeconds\": 2.439,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.686,\n          \"day\": 0.314,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"QR\",\n    \"region\": \"Yucatán peninsula (Quintana Roo)\",\n    \"country\": \"Mexico\",\n    \"biome\": \"Tropical and Subtropical Dry Broadleaf Forest\",\n    \"latitude\": 18.7106,\n    \"longitude\": -88.3923,\n    \"annotationCount\": 705,\n    \"voices\": [\n      {\n        \"scientificName\": \"Hylocichla mustelina\",\n        \"weight\": 0.1957,\n        \"count\": 72,\n        \"lowHz\": 1256,\n        \"highHz\": 4107,\n        \"durationSeconds\": 0.448,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.417,\n          \"day\": 0.528,\n          \"dusk\": 0,\n          \"night\": 0.056\n        }\n      },\n      {\n        \"scientificName\": \"Myiarchus crinitus\",\n        \"weight\": 0.163,\n        \"count\": 60,\n        \"lowHz\": 1802,\n        \"highHz\": 4144,\n        \"durationSeconds\": 0.245,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.217,\n          \"day\": 0.533,\n          \"dusk\": 0,\n          \"night\": 0.25\n        }\n      },\n      {\n        \"scientificName\": \"Setophaga magnolia\",\n        \"weight\": 0.1603,\n        \"count\": 59,\n        \"lowHz\": 5807,\n        \"highHz\": 7507,\n        \"durationSeconds\": 0.2,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.712,\n          \"day\": 0.288,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Cyanocorax yncas\",\n        \"weight\": 0.1332,\n        \"count\": 49,\n        \"lowHz\": 1811,\n        \"highHz\": 3407,\n        \"durationSeconds\": 0.499,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.571,\n          \"day\": 0.429,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Saltator atriceps\",\n        \"weight\": 0.1196,\n        \"count\": 44,\n        \"lowHz\": 1144,\n        \"highHz\": 6864,\n        \"durationSeconds\": 0.24,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Cyanocorax yucatanicus\",\n        \"weight\": 0.0951,\n        \"count\": 35,\n        \"lowHz\": 1013,\n        \"highHz\": 3750,\n        \"durationSeconds\": 0.933,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Pachysylvia decurtata\",\n        \"weight\": 0.0679,\n        \"count\": 25,\n        \"lowHz\": 2950,\n        \"highHz\": 6497,\n        \"durationSeconds\": 1.253,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.64,\n          \"day\": 0.36,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Zenaida asiatica\",\n        \"weight\": 0.0652,\n        \"count\": 24,\n        \"lowHz\": 338,\n        \"highHz\": 930,\n        \"durationSeconds\": 4,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.458,\n          \"day\": 0.542,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"RBA\",\n    \"region\": \"Mata Rio Baldum\",\n    \"country\": \"Brazil\",\n    \"biome\": \"Tropical and Subtropical Moist Broadleaf Forest\",\n    \"latitude\": -6.202,\n    \"longitude\": -35.2276,\n    \"annotationCount\": 363,\n    \"voices\": [\n      {\n        \"scientificName\": \"Herpsilochmus pectoralis\",\n        \"weight\": 0.1867,\n        \"count\": 42,\n        \"lowHz\": 1057,\n        \"highHz\": 2625,\n        \"durationSeconds\": 1.564,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Vireo chivi\",\n        \"weight\": 0.1733,\n        \"count\": 39,\n        \"lowHz\": 2271,\n        \"highHz\": 4988,\n        \"durationSeconds\": 0.369,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.974,\n          \"day\": 0.026,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Nyctidromus albicollis\",\n        \"weight\": 0.1244,\n        \"count\": 28,\n        \"lowHz\": 781,\n        \"highHz\": 2836,\n        \"durationSeconds\": 0.523,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Euphonia chlorotica\",\n        \"weight\": 0.1156,\n        \"count\": 26,\n        \"lowHz\": 3558,\n        \"highHz\": 4804,\n        \"durationSeconds\": 0.542,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Hylophilus amaurocephalus\",\n        \"weight\": 0.1156,\n        \"count\": 26,\n        \"lowHz\": 2798,\n        \"highHz\": 3804,\n        \"durationSeconds\": 1.882,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Hemithraupis guira\",\n        \"weight\": 0.1067,\n        \"count\": 24,\n        \"lowHz\": 5842,\n        \"highHz\": 8249,\n        \"durationSeconds\": 0.206,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Chiroxiphia pareola\",\n        \"weight\": 0.0889,\n        \"count\": 20,\n        \"lowHz\": 1832,\n        \"highHz\": 3310,\n        \"durationSeconds\": 0.237,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.95,\n          \"day\": 0.05,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Thamnophilus pelzelni\",\n        \"weight\": 0.0889,\n        \"count\": 20,\n        \"lowHz\": 1271,\n        \"highHz\": 2070,\n        \"durationSeconds\": 0.113,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"RFP\",\n    \"region\": \"RPPN Fazenda Pacatuba\",\n    \"country\": \"Brazil\",\n    \"biome\": \"Tropical and Subtropical Moist Broadleaf Forest\",\n    \"latitude\": -7.0407,\n    \"longitude\": -35.1541,\n    \"annotationCount\": 684,\n    \"voices\": [\n      {\n        \"scientificName\": \"Hemitriccus griseipectus\",\n        \"weight\": 0.2657,\n        \"count\": 106,\n        \"lowHz\": 1616,\n        \"highHz\": 7408,\n        \"durationSeconds\": 0.317,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Vireo chivi\",\n        \"weight\": 0.203,\n        \"count\": 81,\n        \"lowHz\": 2160,\n        \"highHz\": 4844,\n        \"durationSeconds\": 0.572,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.815,\n          \"day\": 0.185,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Turdus leucomelas\",\n        \"weight\": 0.1454,\n        \"count\": 58,\n        \"lowHz\": 1574,\n        \"highHz\": 4691,\n        \"durationSeconds\": 1.16,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.655,\n          \"day\": 0.345,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Chiroxiphia pareola\",\n        \"weight\": 0.0977,\n        \"count\": 39,\n        \"lowHz\": 1288,\n        \"highHz\": 3354,\n        \"durationSeconds\": 1.104,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.897,\n          \"day\": 0.103,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Xenops minutus\",\n        \"weight\": 0.0877,\n        \"count\": 35,\n        \"lowHz\": 3835,\n        \"highHz\": 7546,\n        \"durationSeconds\": 1.063,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.771,\n          \"day\": 0.229,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Platyrinchus mystaceus\",\n        \"weight\": 0.0752,\n        \"count\": 30,\n        \"lowHz\": 1388,\n        \"highHz\": 7619,\n        \"durationSeconds\": 0.409,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Tolmomyias flaviventris\",\n        \"weight\": 0.0652,\n        \"count\": 26,\n        \"lowHz\": 4922,\n        \"highHz\": 7344,\n        \"durationSeconds\": 0.526,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.962,\n          \"day\": 0.038,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Myiothlypis flaveola\",\n        \"weight\": 0.0602,\n        \"count\": 24,\n        \"lowHz\": 2191,\n        \"highHz\": 6427,\n        \"durationSeconds\": 1.68,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.958,\n          \"day\": 0.042,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"RGU\",\n    \"region\": \"RPPN REBIO Guaribas\",\n    \"country\": \"Brazil\",\n    \"biome\": \"Tropical and Subtropical Moist Broadleaf Forest\",\n    \"latitude\": -6.7178,\n    \"longitude\": -35.1818,\n    \"annotationCount\": 125,\n    \"voices\": [\n      {\n        \"scientificName\": \"Turdus leucomelas\",\n        \"weight\": 0.2368,\n        \"count\": 27,\n        \"lowHz\": 1471,\n        \"highHz\": 12736,\n        \"durationSeconds\": 1.445,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Vireo chivi\",\n        \"weight\": 0.2368,\n        \"count\": 27,\n        \"lowHz\": 2305,\n        \"highHz\": 4801,\n        \"durationSeconds\": 0.535,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Ramphocaenus melanurus\",\n        \"weight\": 0.1579,\n        \"count\": 18,\n        \"lowHz\": 2220,\n        \"highHz\": 3422,\n        \"durationSeconds\": 1.539,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Hemitriccus griseipectus\",\n        \"weight\": 0.1228,\n        \"count\": 14,\n        \"lowHz\": 1665,\n        \"highHz\": 7048,\n        \"durationSeconds\": 0.152,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Neopelma pallescens\",\n        \"weight\": 0.1053,\n        \"count\": 12,\n        \"lowHz\": 868,\n        \"highHz\": 4443,\n        \"durationSeconds\": 1.488,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.667,\n          \"day\": 0.333,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Turdus rufiventris\",\n        \"weight\": 0.0614,\n        \"count\": 7,\n        \"lowHz\": 1309,\n        \"highHz\": 2916,\n        \"durationSeconds\": 1.39,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Herpsilochmus atricapillus\",\n        \"weight\": 0.0526,\n        \"count\": 6,\n        \"lowHz\": 1253,\n        \"highHz\": 2543,\n        \"durationSeconds\": 2.24,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Xiphorhynchus guttatus\",\n        \"weight\": 0.0263,\n        \"count\": 3,\n        \"lowHz\": 1084,\n        \"highHz\": 4916,\n        \"durationSeconds\": 2.948,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.667,\n          \"day\": 0.333,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"RME\",\n    \"region\": \"RPPN Mata Estrela\",\n    \"country\": \"Brazil\",\n    \"biome\": \"Tropical and Subtropical Moist Broadleaf Forest\",\n    \"latitude\": -6.3961,\n    \"longitude\": -35.0094,\n    \"annotationCount\": 175,\n    \"voices\": [\n      {\n        \"scientificName\": \"Vireo chivi\",\n        \"weight\": 0.1791,\n        \"count\": 24,\n        \"lowHz\": 2090,\n        \"highHz\": 5120,\n        \"durationSeconds\": 0.484,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Antrostomus rufus\",\n        \"weight\": 0.1716,\n        \"count\": 23,\n        \"lowHz\": 619,\n        \"highHz\": 2400,\n        \"durationSeconds\": 1.329,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0,\n          \"day\": 0,\n          \"dusk\": 1,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Herpsilochmus pectoralis\",\n        \"weight\": 0.1493,\n        \"count\": 20,\n        \"lowHz\": 774,\n        \"highHz\": 2865,\n        \"durationSeconds\": 2.139,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Herpsilochmus frater\",\n        \"weight\": 0.1418,\n        \"count\": 19,\n        \"lowHz\": 1414,\n        \"highHz\": 3317,\n        \"durationSeconds\": 1.584,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Hemitriccus griseipectus\",\n        \"weight\": 0.1045,\n        \"count\": 14,\n        \"lowHz\": 1615,\n        \"highHz\": 5954,\n        \"durationSeconds\": 0.123,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Camptostoma obsoletum\",\n        \"weight\": 0.097,\n        \"count\": 13,\n        \"lowHz\": 3561,\n        \"highHz\": 7277,\n        \"durationSeconds\": 1.329,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Lurocalis semitorquatus\",\n        \"weight\": 0.0896,\n        \"count\": 12,\n        \"lowHz\": 1168,\n        \"highHz\": 1939,\n        \"durationSeconds\": 0.322,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0,\n          \"day\": 0,\n          \"dusk\": 1,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Myiothlypis flaveola\",\n        \"weight\": 0.0672,\n        \"count\": 9,\n        \"lowHz\": 2400,\n        \"highHz\": 7355,\n        \"durationSeconds\": 2.023,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"ROTOK\",\n    \"region\": \"Rotokare Scenic Reserve\",\n    \"country\": \"New Zealand\",\n    \"biome\": \"Temperate Broadleaf and Mixed Forest\",\n    \"latitude\": -39.4542,\n    \"longitude\": 174.4091,\n    \"annotationCount\": 782,\n    \"voices\": [\n      {\n        \"scientificName\": \"Prosthemadera novaeseelandiae\",\n        \"weight\": 0.2952,\n        \"count\": 204,\n        \"lowHz\": 958,\n        \"highHz\": 2948,\n        \"durationSeconds\": 0.496,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.353,\n          \"day\": 0.647,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Zosterops lateralis\",\n        \"weight\": 0.1404,\n        \"count\": 97,\n        \"lowHz\": 3383,\n        \"highHz\": 5900,\n        \"durationSeconds\": 0.421,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.423,\n          \"day\": 0.577,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Petroica macrocephala\",\n        \"weight\": 0.1201,\n        \"count\": 83,\n        \"lowHz\": 5741,\n        \"highHz\": 7568,\n        \"durationSeconds\": 1.48,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.386,\n          \"day\": 0.614,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Philesturnus rufusater\",\n        \"weight\": 0.11,\n        \"count\": 76,\n        \"lowHz\": 1461,\n        \"highHz\": 4659,\n        \"durationSeconds\": 0.906,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.434,\n          \"day\": 0.566,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Rhipidura fuliginosa\",\n        \"weight\": 0.1085,\n        \"count\": 75,\n        \"lowHz\": 3663,\n        \"highHz\": 7821,\n        \"durationSeconds\": 0.386,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.4,\n          \"day\": 0.6,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Gerygone igata\",\n        \"weight\": 0.1027,\n        \"count\": 71,\n        \"lowHz\": 2853,\n        \"highHz\": 4715,\n        \"durationSeconds\": 1.647,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.324,\n          \"day\": 0.676,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Anthornis melanura\",\n        \"weight\": 0.0695,\n        \"count\": 48,\n        \"lowHz\": 1040,\n        \"highHz\": 3485,\n        \"durationSeconds\": 0.938,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.188,\n          \"day\": 0.813,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Gymnorhina tibicen\",\n        \"weight\": 0.0535,\n        \"count\": 37,\n        \"lowHz\": 723,\n        \"highHz\": 2569,\n        \"durationSeconds\": 0.841,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.459,\n          \"day\": 0.541,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"SAL\",\n    \"region\": \"Reserva Natural La Montaña\",\n    \"country\": \"Colombia\",\n    \"biome\": \"Tropical and Subtropical Moist Broadleaf Forest\",\n    \"latitude\": 4.6325,\n    \"longitude\": -75.4594,\n    \"annotationCount\": 1104,\n    \"voices\": [\n      {\n        \"scientificName\": \"Atlapetes schistaceus\",\n        \"weight\": 0.3397,\n        \"count\": 249,\n        \"lowHz\": 2427,\n        \"highHz\": 4688,\n        \"durationSeconds\": 0.818,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Scytalopus latrans\",\n        \"weight\": 0.1855,\n        \"count\": 136,\n        \"lowHz\": 1119,\n        \"highHz\": 2009,\n        \"durationSeconds\": 1.594,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Nothocercus julius\",\n        \"weight\": 0.116,\n        \"count\": 85,\n        \"lowHz\": 1211,\n        \"highHz\": 2202,\n        \"durationSeconds\": 1.859,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Cinnycerthia olivascens\",\n        \"weight\": 0.1023,\n        \"count\": 75,\n        \"lowHz\": 1323,\n        \"highHz\": 6429,\n        \"durationSeconds\": 1.702,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Myioborus ornatus\",\n        \"weight\": 0.075,\n        \"count\": 55,\n        \"lowHz\": 2953,\n        \"highHz\": 6647,\n        \"durationSeconds\": 1.77,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Zentrygon frenata\",\n        \"weight\": 0.0682,\n        \"count\": 50,\n        \"lowHz\": 151,\n        \"highHz\": 469,\n        \"durationSeconds\": 0.498,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Cyanolyca armillata\",\n        \"weight\": 0.0628,\n        \"count\": 46,\n        \"lowHz\": 4093,\n        \"highHz\": 4824,\n        \"durationSeconds\": 0.634,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Grallaria nuchalis\",\n        \"weight\": 0.0505,\n        \"count\": 37,\n        \"lowHz\": 1672,\n        \"highHz\": 2202,\n        \"durationSeconds\": 2.111,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"SBN\",\n    \"region\": \"Santuario del Bosque de Niebla\",\n    \"country\": \"Mexico\",\n    \"biome\": \"Tropical and Subtropical Moist Broadleaf Forest\",\n    \"latitude\": 19.3453,\n    \"longitude\": -96.9392,\n    \"annotationCount\": 793,\n    \"voices\": [\n      {\n        \"scientificName\": \"Cardellina pusilla\",\n        \"weight\": 0.3268,\n        \"count\": 233,\n        \"lowHz\": 2363,\n        \"highHz\": 7658,\n        \"durationSeconds\": 0.214,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 0,\n          \"day\": 1,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Melanerpes formicivorus\",\n        \"weight\": 0.2034,\n        \"count\": 145,\n        \"lowHz\": 414,\n        \"highHz\": 5385,\n        \"durationSeconds\": 0.472,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0,\n          \"day\": 1,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Myiozetetes similis\",\n        \"weight\": 0.1669,\n        \"count\": 119,\n        \"lowHz\": 2611,\n        \"highHz\": 5720,\n        \"durationSeconds\": 0.543,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0,\n          \"day\": 1,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Megarynchus pitangua\",\n        \"weight\": 0.1332,\n        \"count\": 95,\n        \"lowHz\": 1695,\n        \"highHz\": 4500,\n        \"durationSeconds\": 0.656,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0,\n          \"day\": 1,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Basileuterus culicivorus\",\n        \"weight\": 0.0561,\n        \"count\": 40,\n        \"lowHz\": 3215,\n        \"highHz\": 7471,\n        \"durationSeconds\": 3.382,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0,\n          \"day\": 1,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Melanotis caerulescens\",\n        \"weight\": 0.0547,\n        \"count\": 39,\n        \"lowHz\": 987,\n        \"highHz\": 4582,\n        \"durationSeconds\": 0.636,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 0,\n          \"day\": 1,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Pheugopedius maculipectus\",\n        \"weight\": 0.0351,\n        \"count\": 25,\n        \"lowHz\": 1527,\n        \"highHz\": 8709,\n        \"durationSeconds\": 1.046,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 0,\n          \"day\": 1,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Henicorhina leucophrys\",\n        \"weight\": 0.0238,\n        \"count\": 17,\n        \"lowHz\": 1655,\n        \"highHz\": 5389,\n        \"durationSeconds\": 4,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0,\n          \"day\": 1,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"SCHF\",\n    \"region\": \"Schorfheide-Chorin\",\n    \"country\": \"Germany\",\n    \"biome\": \"Temperate Broadleaf and Mixed Forest\",\n    \"latitude\": 52.8731,\n    \"longitude\": 13.9028,\n    \"annotationCount\": 883,\n    \"voices\": [\n      {\n        \"scientificName\": \"Turdus merula\",\n        \"weight\": 0.2763,\n        \"count\": 221,\n        \"lowHz\": 1000,\n        \"highHz\": 3350,\n        \"durationSeconds\": 2.911,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.443,\n          \"day\": 0.208,\n          \"dusk\": 0.271,\n          \"night\": 0.077\n        }\n      },\n      {\n        \"scientificName\": \"Fringilla coelebs\",\n        \"weight\": 0.2763,\n        \"count\": 221,\n        \"lowHz\": 1700,\n        \"highHz\": 7500,\n        \"durationSeconds\": 2.502,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.204,\n          \"day\": 0.385,\n          \"dusk\": 0.412,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Erithacus rubecula\",\n        \"weight\": 0.1313,\n        \"count\": 105,\n        \"lowHz\": 1600,\n        \"highHz\": 8900,\n        \"durationSeconds\": 3.503,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.438,\n          \"day\": 0.143,\n          \"dusk\": 0.362,\n          \"night\": 0.057\n        }\n      },\n      {\n        \"scientificName\": \"Cyanistes caeruleus\",\n        \"weight\": 0.1163,\n        \"count\": 93,\n        \"lowHz\": 3800,\n        \"highHz\": 8750,\n        \"durationSeconds\": 2.138,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.355,\n          \"day\": 0.495,\n          \"dusk\": 0.151,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Parus major\",\n        \"weight\": 0.085,\n        \"count\": 68,\n        \"lowHz\": 2788,\n        \"highHz\": 5346,\n        \"durationSeconds\": 2.684,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.324,\n          \"day\": 0.5,\n          \"dusk\": 0.176,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Sylvia atricapilla\",\n        \"weight\": 0.0513,\n        \"count\": 41,\n        \"lowHz\": 1350,\n        \"highHz\": 6350,\n        \"durationSeconds\": 4,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.463,\n          \"day\": 0.293,\n          \"dusk\": 0.244,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Troglodytes troglodytes\",\n        \"weight\": 0.0338,\n        \"count\": 27,\n        \"lowHz\": 2400,\n        \"highHz\": 8850,\n        \"durationSeconds\": 4,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.741,\n          \"day\": 0.259,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Turdus philomelos\",\n        \"weight\": 0.03,\n        \"count\": 24,\n        \"lowHz\": 1503,\n        \"highHz\": 4629,\n        \"durationSeconds\": 4,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.583,\n          \"day\": 0,\n          \"dusk\": 0.417,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"SCHG\",\n    \"region\": \"Schorfheide-Chorin\",\n    \"country\": \"Germany\",\n    \"biome\": \"Temperate Grasslands\",\n    \"latitude\": 53.001,\n    \"longitude\": 13.9002,\n    \"annotationCount\": 2107,\n    \"voices\": [\n      {\n        \"scientificName\": \"Emberiza calandra\",\n        \"weight\": 0.2323,\n        \"count\": 338,\n        \"lowHz\": 2730,\n        \"highHz\": 9527,\n        \"durationSeconds\": 1.47,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.447,\n          \"day\": 0,\n          \"dusk\": 0.16,\n          \"night\": 0.393\n        }\n      },\n      {\n        \"scientificName\": \"Saxicola rubetra\",\n        \"weight\": 0.2034,\n        \"count\": 296,\n        \"lowHz\": 1273,\n        \"highHz\": 15000,\n        \"durationSeconds\": 1.381,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.557,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0.443\n        }\n      },\n      {\n        \"scientificName\": \"Alauda arvensis\",\n        \"weight\": 0.1636,\n        \"count\": 238,\n        \"lowHz\": 1832,\n        \"highHz\": 6119,\n        \"durationSeconds\": 2.306,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.391,\n          \"day\": 0,\n          \"dusk\": 0.147,\n          \"night\": 0.462\n        }\n      },\n      {\n        \"scientificName\": \"Turdus merula\",\n        \"weight\": 0.09,\n        \"count\": 131,\n        \"lowHz\": 1169,\n        \"highHz\": 3917,\n        \"durationSeconds\": 1.578,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.252,\n          \"day\": 0,\n          \"dusk\": 0.382,\n          \"night\": 0.366\n        }\n      },\n      {\n        \"scientificName\": \"Emberiza citrinella\",\n        \"weight\": 0.0873,\n        \"count\": 127,\n        \"lowHz\": 4118,\n        \"highHz\": 6245,\n        \"durationSeconds\": 1.745,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.409,\n          \"day\": 0,\n          \"dusk\": 0.252,\n          \"night\": 0.339\n        }\n      },\n      {\n        \"scientificName\": \"Anthus pratensis\",\n        \"weight\": 0.0866,\n        \"count\": 126,\n        \"lowHz\": 3000,\n        \"highHz\": 13278,\n        \"durationSeconds\": 1.969,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.206,\n          \"day\": 0,\n          \"dusk\": 0.262,\n          \"night\": 0.532\n        }\n      },\n      {\n        \"scientificName\": \"Parus major\",\n        \"weight\": 0.0749,\n        \"count\": 109,\n        \"lowHz\": 3202,\n        \"highHz\": 5042,\n        \"durationSeconds\": 0.955,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.569,\n          \"day\": 0,\n          \"dusk\": 0.092,\n          \"night\": 0.339\n        }\n      },\n      {\n        \"scientificName\": \"Fringilla coelebs\",\n        \"weight\": 0.0619,\n        \"count\": 90,\n        \"lowHz\": 1860,\n        \"highHz\": 5358,\n        \"durationSeconds\": 1.624,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.467,\n          \"day\": 0,\n          \"dusk\": 0.344,\n          \"night\": 0.189\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"SD\",\n    \"region\": \"Eeyou Istchee James Bay\",\n    \"country\": \"Canada\",\n    \"biome\": \"Boreal forest/Taiga\",\n    \"latitude\": 52.544,\n    \"longitude\": -72.078,\n    \"annotationCount\": 328,\n    \"voices\": [\n      {\n        \"scientificName\": \"Branta canadensis\",\n        \"weight\": 0.3716,\n        \"count\": 110,\n        \"lowHz\": 159,\n        \"highHz\": 1881,\n        \"durationSeconds\": 0.466,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Zonotrichia albicollis\",\n        \"weight\": 0.1993,\n        \"count\": 59,\n        \"lowHz\": 2975,\n        \"highHz\": 4383,\n        \"durationSeconds\": 2.055,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Contopus cooperi\",\n        \"weight\": 0.1081,\n        \"count\": 32,\n        \"lowHz\": 2474,\n        \"highHz\": 4587,\n        \"durationSeconds\": 0.779,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Passerculus sandwichensis\",\n        \"weight\": 0.0946,\n        \"count\": 28,\n        \"lowHz\": 4180,\n        \"highHz\": 9446,\n        \"durationSeconds\": 2.284,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Passerella iliaca\",\n        \"weight\": 0.0676,\n        \"count\": 20,\n        \"lowHz\": 2026,\n        \"highHz\": 4170,\n        \"durationSeconds\": 1.577,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Melospiza lincolnii\",\n        \"weight\": 0.0642,\n        \"count\": 19,\n        \"lowHz\": 1951,\n        \"highHz\": 5730,\n        \"durationSeconds\": 1.548,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Turdus migratorius\",\n        \"weight\": 0.0541,\n        \"count\": 16,\n        \"lowHz\": 1602,\n        \"highHz\": 3381,\n        \"durationSeconds\": 1.843,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Corthylio calendula\",\n        \"weight\": 0.0405,\n        \"count\": 12,\n        \"lowHz\": 2177,\n        \"highHz\": 4527,\n        \"durationSeconds\": 1.532,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"SITH\",\n    \"region\": \"Sithonia Penninsula. Chalkidiki\",\n    \"country\": \"Greece\",\n    \"biome\": \"Mediterranean Forests. Woodlands and shrublands\",\n    \"latitude\": 40.1602,\n    \"longitude\": 23.7744,\n    \"annotationCount\": 1657,\n    \"voices\": [\n      {\n        \"scientificName\": \"Curruca melanocephala\",\n        \"weight\": 0.1951,\n        \"count\": 303,\n        \"lowHz\": 1764,\n        \"highHz\": 7810,\n        \"durationSeconds\": 1.526,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.974,\n          \"day\": 0.017,\n          \"dusk\": 0.01,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Phylloscopus collybita\",\n        \"weight\": 0.1893,\n        \"count\": 294,\n        \"lowHz\": 2109,\n        \"highHz\": 4362,\n        \"durationSeconds\": 0.405,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.19,\n          \"day\": 0.718,\n          \"dusk\": 0.092,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Fringilla coelebs\",\n        \"weight\": 0.1842,\n        \"count\": 286,\n        \"lowHz\": 1833,\n        \"highHz\": 5548,\n        \"durationSeconds\": 1.664,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Regulus regulus\",\n        \"weight\": 0.1816,\n        \"count\": 282,\n        \"lowHz\": 5803,\n        \"highHz\": 9282,\n        \"durationSeconds\": 0.852,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.145,\n          \"day\": 0.688,\n          \"dusk\": 0.167,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Regulus ignicapilla\",\n        \"weight\": 0.0947,\n        \"count\": 147,\n        \"lowHz\": 5806,\n        \"highHz\": 9778,\n        \"durationSeconds\": 1.991,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.435,\n          \"day\": 0.381,\n          \"dusk\": 0.184,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Turdus merula\",\n        \"weight\": 0.058,\n        \"count\": 90,\n        \"lowHz\": 1329,\n        \"highHz\": 4972,\n        \"durationSeconds\": 1.879,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.978,\n          \"day\": 0.022,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Garrulus glandarius\",\n        \"weight\": 0.0515,\n        \"count\": 80,\n        \"lowHz\": 588,\n        \"highHz\": 4660,\n        \"durationSeconds\": 0.782,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.588,\n          \"day\": 0.3,\n          \"dusk\": 0.113,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Lullula arborea\",\n        \"weight\": 0.0457,\n        \"count\": 71,\n        \"lowHz\": 1890,\n        \"highHz\": 4819,\n        \"durationSeconds\": 1.922,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"SLOB\",\n    \"region\": \"North-Eastern Ukraine\",\n    \"country\": \"Ukraine\",\n    \"biome\": \"Temperate Coniferous forest\",\n    \"latitude\": 50.06,\n    \"longitude\": 35.23,\n    \"annotationCount\": 2183,\n    \"voices\": [\n      {\n        \"scientificName\": \"Fringilla coelebs\",\n        \"weight\": 0.3753,\n        \"count\": 584,\n        \"lowHz\": 1705,\n        \"highHz\": 6658,\n        \"durationSeconds\": 1.834,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.829,\n          \"day\": 0.171,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Phylloscopus sibilatrix\",\n        \"weight\": 0.1375,\n        \"count\": 214,\n        \"lowHz\": 2960,\n        \"highHz\": 8596,\n        \"durationSeconds\": 2.189,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.93,\n          \"day\": 0.07,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Parus major\",\n        \"weight\": 0.1183,\n        \"count\": 184,\n        \"lowHz\": 2825,\n        \"highHz\": 6589,\n        \"durationSeconds\": 1.777,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.81,\n          \"day\": 0.19,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Ficedula albicollis\",\n        \"weight\": 0.0893,\n        \"count\": 139,\n        \"lowHz\": 2349,\n        \"highHz\": 8673,\n        \"durationSeconds\": 2.632,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.475,\n          \"day\": 0.525,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Erithacus rubecula\",\n        \"weight\": 0.0797,\n        \"count\": 124,\n        \"lowHz\": 2242,\n        \"highHz\": 8845,\n        \"durationSeconds\": 2.371,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.823,\n          \"day\": 0.177,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Muscicapa striata\",\n        \"weight\": 0.0746,\n        \"count\": 116,\n        \"lowHz\": 5969,\n        \"highHz\": 8995,\n        \"durationSeconds\": 0.266,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Turdus merula\",\n        \"weight\": 0.0713,\n        \"count\": 111,\n        \"lowHz\": 1286,\n        \"highHz\": 3213,\n        \"durationSeconds\": 1.517,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.946,\n          \"day\": 0.054,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Phylloscopus collybita\",\n        \"weight\": 0.054,\n        \"count\": 84,\n        \"lowHz\": 2850,\n        \"highHz\": 7218,\n        \"durationSeconds\": 3.918,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.786,\n          \"day\": 0.214,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"SPMCO\",\n    \"region\": \"San Pedro de los Milagros\",\n    \"country\": \"Colombia\",\n    \"biome\": \"Tropical and Subtropical Grasslands & Savannas and Shrublands\",\n    \"latitude\": 6.4258,\n    \"longitude\": -75.5358,\n    \"annotationCount\": 2077,\n    \"voices\": [\n      {\n        \"scientificName\": \"Zonotrichia capensis\",\n        \"weight\": 0.3138,\n        \"count\": 406,\n        \"lowHz\": 2515,\n        \"highHz\": 6955,\n        \"durationSeconds\": 1.406,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.946,\n          \"day\": 0.054,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Synallaxis azarae\",\n        \"weight\": 0.2179,\n        \"count\": 282,\n        \"lowHz\": 1127,\n        \"highHz\": 5465,\n        \"durationSeconds\": 0.49,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.911,\n          \"day\": 0.089,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Elaenia frantzii\",\n        \"weight\": 0.1059,\n        \"count\": 137,\n        \"lowHz\": 2331,\n        \"highHz\": 3771,\n        \"durationSeconds\": 0.174,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Tyrannus melancholicus\",\n        \"weight\": 0.0827,\n        \"count\": 107,\n        \"lowHz\": 4042,\n        \"highHz\": 6523,\n        \"durationSeconds\": 0.56,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Grallaria ruficapilla\",\n        \"weight\": 0.0788,\n        \"count\": 102,\n        \"lowHz\": 1200,\n        \"highHz\": 1992,\n        \"durationSeconds\": 1.175,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.863,\n          \"day\": 0.137,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Momotus aequatorialis\",\n        \"weight\": 0.075,\n        \"count\": 97,\n        \"lowHz\": 219,\n        \"highHz\": 730,\n        \"durationSeconds\": 0.177,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.773,\n          \"day\": 0.227,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Myioborus ornatus\",\n        \"weight\": 0.068,\n        \"count\": 88,\n        \"lowHz\": 2929,\n        \"highHz\": 7071,\n        \"durationSeconds\": 2.994,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.955,\n          \"day\": 0.045,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Henicorhina leucophrys\",\n        \"weight\": 0.058,\n        \"count\": 75,\n        \"lowHz\": 1340,\n        \"highHz\": 4133,\n        \"durationSeconds\": 3.544,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 0.987,\n          \"day\": 0.013,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"TAM\",\n    \"region\": \"Bosque el Algarrobo Tamara\",\n    \"country\": \"Colombia\",\n    \"biome\": \"Tropical and Subtropical Dry Broadleaf Forest\",\n    \"latitude\": 5.7533,\n    \"longitude\": -72.2108,\n    \"annotationCount\": 856,\n    \"voices\": [\n      {\n        \"scientificName\": \"Pheugopedius rutilus\",\n        \"weight\": 0.263,\n        \"count\": 213,\n        \"lowHz\": 1430,\n        \"highHz\": 4880,\n        \"durationSeconds\": 1.503,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Tersina viridis\",\n        \"weight\": 0.221,\n        \"count\": 179,\n        \"lowHz\": 6015,\n        \"highHz\": 12514,\n        \"durationSeconds\": 0.358,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Cyclarhis gujanensis\",\n        \"weight\": 0.1346,\n        \"count\": 109,\n        \"lowHz\": 1412,\n        \"highHz\": 3622,\n        \"durationSeconds\": 0.769,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Automolus rufipileatus\",\n        \"weight\": 0.1296,\n        \"count\": 105,\n        \"lowHz\": 2578,\n        \"highHz\": 3407,\n        \"durationSeconds\": 1.261,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Turdus nudigenis\",\n        \"weight\": 0.1086,\n        \"count\": 88,\n        \"lowHz\": 1806,\n        \"highHz\": 4373,\n        \"durationSeconds\": 0.535,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Tolmomyias flaviventris\",\n        \"weight\": 0.0716,\n        \"count\": 58,\n        \"lowHz\": 4488,\n        \"highHz\": 6015,\n        \"durationSeconds\": 1.698,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Hylophilus flavipes\",\n        \"weight\": 0.0481,\n        \"count\": 39,\n        \"lowHz\": 2564,\n        \"highHz\": 3759,\n        \"durationSeconds\": 1.857,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Pachyramphus polychopterus\",\n        \"weight\": 0.0235,\n        \"count\": 19,\n        \"lowHz\": 1872,\n        \"highHz\": 3453,\n        \"durationSeconds\": 1.867,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"UNI\",\n    \"region\": \"Jardðn Bot˜nico Univ. del Quindðo\",\n    \"country\": \"Colombia\",\n    \"biome\": \"Tropical and Subtropical Moist Broadleaf Forest\",\n    \"latitude\": 4.5539,\n    \"longitude\": -75.6611,\n    \"annotationCount\": 1080,\n    \"voices\": [\n      {\n        \"scientificName\": \"Arremon brunneinucha\",\n        \"weight\": 0.383,\n        \"count\": 352,\n        \"lowHz\": 6293,\n        \"highHz\": 11426,\n        \"durationSeconds\": 1.609,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Cercomacroides parkeri\",\n        \"weight\": 0.2013,\n        \"count\": 185,\n        \"lowHz\": 1736,\n        \"highHz\": 3594,\n        \"durationSeconds\": 2.308,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Cranioleuca erythrops\",\n        \"weight\": 0.1153,\n        \"count\": 106,\n        \"lowHz\": 3969,\n        \"highHz\": 8510,\n        \"durationSeconds\": 2.141,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Pheugopedius sclateri\",\n        \"weight\": 0.0729,\n        \"count\": 67,\n        \"lowHz\": 1614,\n        \"highHz\": 7436,\n        \"durationSeconds\": 1.917,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Saltator striatipectus\",\n        \"weight\": 0.0718,\n        \"count\": 66,\n        \"lowHz\": 1739,\n        \"highHz\": 3444,\n        \"durationSeconds\": 1.913,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Leptotila plumbeiceps\",\n        \"weight\": 0.0653,\n        \"count\": 60,\n        \"lowHz\": 150,\n        \"highHz\": 480,\n        \"durationSeconds\": 0.521,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Coereba flaveola\",\n        \"weight\": 0.0544,\n        \"count\": 50,\n        \"lowHz\": 5619,\n        \"highHz\": 10588,\n        \"durationSeconds\": 2.261,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Henicorhina leucophrys\",\n        \"weight\": 0.0359,\n        \"count\": 33,\n        \"lowHz\": 1769,\n        \"highHz\": 4626,\n        \"durationSeconds\": 0.753,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"VER\",\n    \"region\": \"Alto Quindðo. EL Vergel. Quindðo\",\n    \"country\": \"Colombia\",\n    \"biome\": \"Tropical and Subtropical Moist Broadleaf Forest\",\n    \"latitude\": 4.5914,\n    \"longitude\": -75.5908,\n    \"annotationCount\": 791,\n    \"voices\": [\n      {\n        \"scientificName\": \"Myiothlypis luteoviridis\",\n        \"weight\": 0.2762,\n        \"count\": 124,\n        \"lowHz\": 2452,\n        \"highHz\": 8599,\n        \"durationSeconds\": 1.942,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Diglossa lafresnayii\",\n        \"weight\": 0.1336,\n        \"count\": 60,\n        \"lowHz\": 2318,\n        \"highHz\": 6873,\n        \"durationSeconds\": 1.665,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Anisognathus igniventris\",\n        \"weight\": 0.1158,\n        \"count\": 52,\n        \"lowHz\": 2257,\n        \"highHz\": 6885,\n        \"durationSeconds\": 1.888,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Acropternis orthonyx\",\n        \"weight\": 0.1069,\n        \"count\": 48,\n        \"lowHz\": 1415,\n        \"highHz\": 2923,\n        \"durationSeconds\": 0.545,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Myioborus ornatus\",\n        \"weight\": 0.1047,\n        \"count\": 47,\n        \"lowHz\": 2869,\n        \"highHz\": 8482,\n        \"durationSeconds\": 1.937,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Diglossa cyanea\",\n        \"weight\": 0.0913,\n        \"count\": 41,\n        \"lowHz\": 2464,\n        \"highHz\": 8414,\n        \"durationSeconds\": 1.444,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Iridosornis rufivertex\",\n        \"weight\": 0.0869,\n        \"count\": 39,\n        \"lowHz\": 6218,\n        \"highHz\": 7758,\n        \"durationSeconds\": 1.986,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Cnemathraupis eximia\",\n        \"weight\": 0.0846,\n        \"count\": 38,\n        \"lowHz\": 3149,\n        \"highHz\": 6890,\n        \"durationSeconds\": 1.375,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  },\n  {\n    \"id\": \"VIL\",\n    \"region\": \"Villena shrublands\",\n    \"country\": \"Spain\",\n    \"biome\": \"Mediterranean Forests. Woodlands and shrublands\",\n    \"latitude\": 38.5603,\n    \"longitude\": -0.8778,\n    \"annotationCount\": 1025,\n    \"voices\": [\n      {\n        \"scientificName\": \"Galerida theklae\",\n        \"weight\": 0.3165,\n        \"count\": 244,\n        \"lowHz\": 1823,\n        \"highHz\": 6403,\n        \"durationSeconds\": 1.555,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Turdus merula\",\n        \"weight\": 0.2763,\n        \"count\": 213,\n        \"lowHz\": 1431,\n        \"highHz\": 3789,\n        \"durationSeconds\": 1.695,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Athene noctua\",\n        \"weight\": 0.1219,\n        \"count\": 94,\n        \"lowHz\": 776,\n        \"highHz\": 3640,\n        \"durationSeconds\": 0.656,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Burhinus oedicnemus\",\n        \"weight\": 0.0856,\n        \"count\": 66,\n        \"lowHz\": 1357,\n        \"highHz\": 3562,\n        \"durationSeconds\": 0.876,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Emberiza calandra\",\n        \"weight\": 0.0804,\n        \"count\": 62,\n        \"lowHz\": 2894,\n        \"highHz\": 10368,\n        \"durationSeconds\": 1.669,\n        \"contour\": \"warble\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Saxicola rubicola\",\n        \"weight\": 0.0428,\n        \"count\": 33,\n        \"lowHz\": 2841,\n        \"highHz\": 7336,\n        \"durationSeconds\": 1.431,\n        \"contour\": \"sweep\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Calandrella brachydactyla\",\n        \"weight\": 0.0389,\n        \"count\": 30,\n        \"lowHz\": 2088,\n        \"highHz\": 6530,\n        \"durationSeconds\": 2.406,\n        \"contour\": \"trill\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      },\n      {\n        \"scientificName\": \"Pyrrhocorax pyrrhocorax\",\n        \"weight\": 0.0376,\n        \"count\": 29,\n        \"lowHz\": 806,\n        \"highHz\": 3096,\n        \"durationSeconds\": 0.582,\n        \"contour\": \"chirp\",\n        \"observedHourWeights\": {\n          \"dawn\": 1,\n          \"day\": 0,\n          \"dusk\": 0,\n          \"night\": 0\n        }\n      }\n    ]\n  }\n]);\n","/**\n * Bounded procedural roadway and aircraft soundscape for photoreal surface mode.\n * Road voices approximate measured traffic sub-sources with spectral bands;\n * aircraft voices add HRTF placement, propagation color, reflection, and Doppler.\n */\nimport * as THREE from 'three';\nimport { ellipsoidRadiusForLocalDir, latLonToLocalDir } from '../../modules/geometry-utils.js';\nimport { BIRDSONG_REGIONAL_PROFILES } from './data/birdsong-regional-profiles.js';\n\n// Selected standard one-third-octave centers spanning the dominant roadway\n// engine/exhaust and tire/pavement energy without allocating the inaudible tails.\nconst ROAD_BANDS_HZ = [100, 125, 160, 200, 250, 315, 400, 500, 630, 800, 1000, 1250, 1600, 2000, 2500, 3150, 4000];\nconst DEFAULT_TEMPERATURE_C = 15;\nconst DEFAULT_HUMIDITY_PERCENT = 55;\n\nconst clamp = (value, low, high) => Math.min(high, Math.max(low, value));\n\nconst angularDistance = (latA, lonA, latB, lonB) => {\n  const a = THREE.MathUtils.degToRad(latA);\n  const b = THREE.MathUtils.degToRad(latB);\n  const deltaLat = b - a;\n  const deltaLon = THREE.MathUtils.degToRad(lonB - lonA);\n  const haversine = Math.sin(deltaLat / 2) ** 2\n    + Math.cos(a) * Math.cos(b) * Math.sin(deltaLon / 2) ** 2;\n  return 2 * Math.atan2(Math.sqrt(haversine), Math.sqrt(Math.max(0, 1 - haversine)));\n};\n\nexport function nearestBirdsongProfile(latitudeDeg, longitudeDeg, profiles = BIRDSONG_REGIONAL_PROFILES) {\n  if (!Number.isFinite(latitudeDeg) || !Number.isFinite(longitudeDeg) || !profiles?.length) return null;\n  let nearest = null;\n  let nearestAngle = Infinity;\n  for (const profile of profiles) {\n    const angle = angularDistance(latitudeDeg, longitudeDeg, profile.latitude, profile.longitude);\n    if (angle < nearestAngle) { nearest = profile; nearestAngle = angle; }\n  }\n  return nearest ? { profile: nearest, distanceKm: nearestAngle * 6371 } : null;\n}\n\nexport function solarDaylightHours(sceneTimeMs, latitudeDeg) {\n  const date = new Date(Number(sceneTimeMs));\n  const start = Date.UTC(date.getUTCFullYear(), 0, 0);\n  const day = Math.floor((date.getTime() - start) / 86_400_000);\n  const declination = THREE.MathUtils.degToRad(-23.44 * Math.cos((2 * Math.PI * (day + 10)) / 365));\n  const latitude = THREE.MathUtils.degToRad(clamp(Number(latitudeDeg) || 0, -66.5, 66.5));\n  const hourAngle = Math.acos(clamp(-Math.tan(latitude) * Math.tan(declination), -1, 1));\n  const daylightHours = 24 * hourAngle / Math.PI;\n  return { sunrise: 12 - daylightHours / 2, sunset: 12 + daylightHours / 2 };\n}\n\nexport function birdActivityForLocalHour(hour, sunrise = 6, sunset = 18) {\n  const h = ((Number(hour) % 24) + 24) % 24;\n  const wrappedDistance = (a, b) => Math.min(Math.abs(a - b), 24 - Math.abs(a - b));\n  const gaussian = (center, width) => Math.exp(-0.5 * (wrappedDistance(h, center) / width) ** 2);\n  const dawn = gaussian(sunrise + 0.35, 1.15);\n  const dusk = gaussian(sunset - 0.25, 1.4);\n  const daytime = h >= sunrise && h <= sunset ? 0.2 : 0.025;\n  return clamp(daytime + dawn * 0.8 + dusk * 0.34, 0.025, 1);\n}\n\nexport function nocturnalWildlifeActivity({\n  localHour, sunrise = 6, sunset = 18, temperatureC = DEFAULT_TEMPERATURE_C,\n  humidityPercent = DEFAULT_HUMIDITY_PERCENT, precipitationMm = 0, biome = '',\n} = {}) {\n  const hour = ((Number(localHour) % 24) + 24) % 24;\n  const distance = (a, b) => Math.min(Math.abs(a - b), 24 - Math.abs(a - b));\n  const dusk = Math.exp(-0.5 * (distance(hour, sunset + 0.8) / 1.7) ** 2);\n  const predawn = Math.exp(-0.5 * (distance(hour, sunrise - 1.2) / 2.1) ** 2);\n  const night = hour >= sunset || hour <= sunrise ? 1 : 0;\n  const darkness = clamp(night * 0.72 + dusk * 0.72 + predawn * 0.34, 0, 1);\n  const temperature = Number.isFinite(temperatureC) ? temperatureC : DEFAULT_TEMPERATURE_C;\n  const warmth = clamp((temperature - 8) / 18, 0, 1) * clamp((38 - temperature) / 8, 0.25, 1);\n  const humidity = clamp((Number(humidityPercent) || DEFAULT_HUMIDITY_PERCENT) / 100, 0, 1);\n  const rain = clamp((Number(precipitationMm) || 0) / 3, 0, 1);\n  const habitat = String(biome).toLowerCase();\n  const wetHabitat = /wetland|moist|rain|mangrove|flood|tropical/.test(habitat) ? 1 : 0.38;\n  const aridHabitat = /desert|xeric|dry/.test(habitat) ? 0.55 : 1;\n  return {\n    crickets: clamp(darkness * warmth * aridHabitat * (0.6 + humidity * 0.4), 0, 1),\n    frogs: clamp(darkness * warmth * wetHabitat * (humidity * 0.72 + rain * 0.85), 0, 1),\n  };\n}\n\nexport function birdSpectrogramCurves(voice = {}, points = 96, phase = 0) {\n  const count = Math.max(16, Math.floor(points));\n  const low = clamp(Number(voice.lowHz) || 1200, 150, 15_000);\n  const high = clamp(Math.max(low + 80, Number(voice.highHz) || 6500), low + 80, 15_000);\n  const range = high - low;\n  const frequency = new Float32Array(count);\n  const amplitude = new Float32Array(count);\n  const contour = voice.contour || 'warble';\n  const syllables = contour === 'trill' ? 10 : contour === 'chirp' ? 5 : contour === 'warble' ? 4 : 2;\n  for (let index = 0; index < count; index += 1) {\n    const t = index / (count - 1);\n    const cycle = (t * syllables + phase) % 1;\n    let normalized;\n    if (contour === 'sweep') normalized = 0.12 + 0.78 * t;\n    else if (contour === 'trill') normalized = 0.5 + 0.34 * Math.sin((t * 10 + phase) * Math.PI * 2);\n    else if (contour === 'chirp') normalized = 0.12 + 0.78 * cycle;\n    else normalized = 0.5 + 0.23 * Math.sin((t * 3.1 + phase) * Math.PI * 2)\n        + 0.12 * Math.sin((t * 7.3 + phase) * Math.PI * 2);\n    frequency[index] = low + range * clamp(normalized, 0.04, 0.96);\n    const syllableWindow = Math.sin(Math.PI * clamp(cycle / 0.82, 0, 1)) ** 2;\n    const phraseWindow = Math.sin(Math.PI * t) ** 0.55;\n    amplitude[index] = cycle <= 0.82 ? syllableWindow * phraseWindow : 0;\n  }\n  return { frequency, amplitude };\n}\n\nexport function speedOfSoundMps(temperatureC = DEFAULT_TEMPERATURE_C) {\n  const temperature = Number.isFinite(temperatureC) ? temperatureC : DEFAULT_TEMPERATURE_C;\n  return 331.3 + 0.606 * temperature;\n}\n\nexport function resolveLocalHour(sceneTimeMs, utcOffsetSeconds, longitudeDeg = 0) {\n  const offsetSeconds = Number.isFinite(utcOffsetSeconds)\n    ? utcOffsetSeconds\n    : (Number(longitudeDeg) / 15) * 3600;\n  const date = new Date(Number(sceneTimeMs) + offsetSeconds * 1000);\n  return date.getUTCHours() + date.getUTCMinutes() / 60 + date.getUTCSeconds() / 3600;\n}\n\nexport function trafficActivityForLocalHour(hour) {\n  const h = ((Number(hour) % 24) + 24) % 24;\n  const points = [\n    [0, 0.16], [5, 0.22], [7.5, 0.92], [9.5, 0.66], [13, 0.62],\n    [17.5, 1], [20, 0.68], [23, 0.28], [24, 0.16],\n  ];\n  for (let index = 1; index < points.length; index += 1) {\n    if (h <= points[index][0]) {\n      const [x0, y0] = points[index - 1];\n      const [x1, y1] = points[index];\n      return y0 + (y1 - y0) * ((h - x0) / (x1 - x0));\n    }\n  }\n  return points.at(-1)[1];\n}\n\nexport function atmosphericLowpassHz(distanceM, humidityPercent = DEFAULT_HUMIDITY_PERCENT) {\n  const distanceKm = Math.max(0, Number(distanceM) || 0) / 1000;\n  const humidity = clamp(Number(humidityPercent) || DEFAULT_HUMIDITY_PERCENT, 5, 100) / 100;\n  // A perceptual approximation of increasing high-frequency atmospheric loss.\n  return clamp(18000 / (1 + distanceKm * (1.9 - humidity)), 900, 18000);\n}\n\nexport function dopplerFactor({ sourcePosition, listenerPosition, sourceVelocity, listenerVelocity, soundSpeedMps = 343 } = {}) {\n  if (!sourcePosition || !listenerPosition) return 1;\n  const ray = new THREE.Vector3().subVectors(listenerPosition, sourcePosition);\n  if (ray.lengthSq() < 1e-6) return 1;\n  ray.normalize();\n  const sourceRadial = sourceVelocity?.dot?.(ray) || 0;\n  const listenerRadial = listenerVelocity?.dot?.(ray) || 0;\n  const c = Math.max(250, Number(soundSpeedMps) || 343);\n  return clamp((c - listenerRadial) / Math.max(c * 0.35, c - sourceRadial), 0.5, 2);\n}\n\nexport function roadAcousticProfile(road = {}, { localHour = 12, live = null } = {}) {\n  const roadClass = String(road.class || road.subclass || '').toLowerCase();\n  const classGain = {\n    motorway: 1, trunk: 0.94, primary: 0.82, secondary: 0.7,\n    tertiary: 0.58, street: 0.5, residential: 0.38, service: 0.28,\n  }[roadClass] ?? 0.42;\n  const flow = Number(live?.vehicleFlowVph);\n  const speed = Number(live?.speedKph);\n  const flowGain = Number.isFinite(flow) ? clamp(Math.sqrt(flow / 1100), 0.18, 1.35) : 1;\n  const speedGain = Number.isFinite(speed) ? clamp(0.55 + speed / 140, 0.55, 1.35) : 1;\n  const wet = /wet|gravel|unpaved|cobble/i.test(String(road.surface || '')) ? 1.12 : 1;\n  const bandGains = ROAD_BANDS_HZ.map((frequency) => {\n    const engine = Math.exp(-((Math.log2(frequency / 160) ** 2) / 1.2)) / speedGain;\n    const tire = Math.exp(-((Math.log2(frequency / 1000) ** 2) / 2.8)) * speedGain * wet;\n    return 0.08 + 0.48 * engine + 0.72 * tire;\n  });\n  return {\n    gain: classGain * trafficActivityForLocalHour(localHour) * flowGain,\n    bandGains,\n    speedKph: Number.isFinite(speed) ? speed : (roadClass === 'motorway' ? 95 : 45),\n  };\n}\n\nconst MEAN_EARTH_RADIUS_M = 6371008.8;\n\nexport function buildRoadPathMetrics(path) {\n  const points = (Array.isArray(path) ? path : [])\n    .map((point) => ({ lon: Number(point?.[0]), lat: Number(point?.[1]) }))\n    .filter((point) => Number.isFinite(point.lon) && Number.isFinite(point.lat));\n  const cumulativeM = [0];\n  for (let index = 1; index < points.length; index += 1) {\n    const previous = points[index - 1];\n    const current = points[index];\n    cumulativeM.push(cumulativeM[index - 1]\n      + angularDistance(previous.lat, previous.lon, current.lat, current.lon) * MEAN_EARTH_RADIUS_M);\n  }\n  return { points, cumulativeM, totalLengthM: cumulativeM.at(-1) || 0 };\n}\n\nexport function sampleRoadPath(metrics, distanceM) {\n  const points = metrics?.points || [];\n  const cumulativeM = metrics?.cumulativeM || [];\n  if (points.length < 2 || !(metrics.totalLengthM > 0)) return null;\n  const distance = clamp(Number(distanceM) || 0, 0, metrics.totalLengthM);\n  let index = 1;\n  while (index < cumulativeM.length - 1 && cumulativeM[index] < distance) index += 1;\n  const previousDistance = cumulativeM[index - 1];\n  const segmentLength = Math.max(0.001, cumulativeM[index] - previousDistance);\n  const t = clamp((distance - previousDistance) / segmentLength, 0, 1);\n  const a = points[index - 1];\n  const b = points[index];\n  const bearing = Math.atan2(\n    Math.sin(THREE.MathUtils.degToRad(b.lon - a.lon)) * Math.cos(THREE.MathUtils.degToRad(b.lat)),\n    Math.cos(THREE.MathUtils.degToRad(a.lat)) * Math.sin(THREE.MathUtils.degToRad(b.lat))\n      - Math.sin(THREE.MathUtils.degToRad(a.lat)) * Math.cos(THREE.MathUtils.degToRad(b.lat))\n      * Math.cos(THREE.MathUtils.degToRad(b.lon - a.lon)),\n  );\n  return {\n    lat: THREE.MathUtils.lerp(a.lat, b.lat, t),\n    lon: THREE.MathUtils.lerp(a.lon, b.lon, t),\n    bearingDeg: (THREE.MathUtils.radToDeg(bearing) + 360) % 360,\n    progress: distance / metrics.totalLengthM,\n  };\n}\n\nexport function vehicleEngineState({ speedMps = 0, accelerationMps2 = 0, variant = 0 } = {}) {\n  const speed = Math.max(0, Number(speedMps) || 0);\n  const acceleration = Number(accelerationMps2) || 0;\n  const gearThresholds = [0, 4.5, 9, 15, 23, 32];\n  let gear = 1;\n  for (let index = 1; index < gearThresholds.length; index += 1) {\n    if (speed >= gearThresholds[index]) gear = index + 1;\n  }\n  const gearRatios = [3.8, 2.2, 1.52, 1.13, 0.9, 0.74];\n  const wheelRpm = speed / (2 * Math.PI * 0.325) * 60;\n  const load = clamp(0.24 + Math.max(0, acceleration) * 0.24 + speed / 95, 0.18, 1);\n  const rpm = clamp(wheelRpm * gearRatios[gear - 1] * 3.42 + 780 + load * 210 + variant * 75, 760, 6200);\n  const cylinders = variant > 0.66 ? 6 : variant > 0.22 ? 4 : 3;\n  return { gear, rpm, load, cylinders, firingHz: rpm / 60 * (cylinders / 2) };\n}\n\nexport function habitatAcousticEligibility({ habitat, observerIsOcean = false } = {}) {\n  const greenDistanceM = Number(habitat?.greenSpaceDistanceM);\n  const waterDistanceM = Number(habitat?.waterDistanceM);\n  const hasGreenAnchor = Number.isFinite(habitat?.greenSpacePosition?.lat)\n    && Number.isFinite(habitat?.greenSpacePosition?.lon)\n    && Number.isFinite(greenDistanceM);\n  const hasWaterAnchor = Number.isFinite(habitat?.waterPosition?.lat)\n    && Number.isFinite(habitat?.waterPosition?.lon)\n    && Number.isFinite(waterDistanceM);\n  // Open water is not treated as an implicit habitat. Coastal wildlife remains\n  // possible only when a mapped land/greenspace anchor is genuinely nearby.\n  const coastalLand = hasGreenAnchor && greenDistanceM <= 600;\n  return {\n    birds: hasGreenAnchor && (!observerIsOcean || coastalLand),\n    crickets: hasGreenAnchor && (!observerIsOcean || coastalLand),\n    frogs: hasWaterAnchor && hasGreenAnchor && greenDistanceM <= 900 && (!observerIsOcean || coastalLand),\n  };\n}\n\nfunction seededNoiseBuffer(context, seconds = 4, seed = 0x51f15e) {\n  const length = Math.max(1, Math.floor(context.sampleRate * seconds));\n  const buffer = context.createBuffer(1, length, context.sampleRate);\n  const channel = buffer.getChannelData(0);\n  let state = seed >>> 0;\n  for (let index = 0; index < length; index += 1) {\n    state = (1664525 * state + 1013904223) >>> 0;\n    channel[index] = (state / 0x80000000) - 1;\n  }\n  return buffer;\n}\n\nfunction stopNode(node) {\n  try { node?.stop?.(); } catch {}\n  try { node?.disconnect?.(); } catch {}\n}\n\nexport class SpatialAmbientSoundscape {\n  constructor({\n    listener, camera, parentGroup, mobile = false,\n    prepareAcousticGeometry = null, sampleSurfaceRadius = null, sampleAcousticPath = null,\n  } = {}) {\n    this.listener = listener || null;\n    this.camera = camera || null;\n    this.parentGroup = parentGroup || null;\n    this.mobile = !!mobile;\n    this.enabled = true;\n    this.active = false;\n    this.roads = [];\n    this.traffic = [];\n    this.aircraft = [];\n    this.habitat = null;\n    this.prepareAcousticGeometry = typeof prepareAcousticGeometry === 'function' ? prepareAcousticGeometry : null;\n    this.sampleSurfaceRadius = typeof sampleSurfaceRadius === 'function' ? sampleSurfaceRadius : null;\n    this.sampleAcousticPath = typeof sampleAcousticPath === 'function' ? sampleAcousticPath : null;\n    this._roadVoices = [];\n    this._roadVehicles = [];\n    this._aircraftVoices = [];\n    this._birdCalls = new Set();\n    this._wildlifeCalls = new Set();\n    this._birdProfile = null;\n    this._birdProfileLocation = { latitude: NaN, longitude: NaN };\n    this._nextBirdCallMs = 0;\n    this._nextCricketCallMs = 0;\n    this._nextFrogCallMs = 0;\n    this._randomState = 0x9e3779b9;\n    this._lastUpdateMs = 0;\n    this._propagationCursor = 0;\n    this._observerWorld = new THREE.Vector3();\n    this._observerLocal = new THREE.Vector3();\n    this._previousObserverLocal = new THREE.Vector3();\n    this._listenerVelocity = new THREE.Vector3();\n    this._sourceVelocity = new THREE.Vector3();\n    this._sourcePosition = new THREE.Vector3();\n    this._sourceDirection = new THREE.Vector3();\n    this._sourceWorld = new THREE.Vector3();\n    this._reflectionLocal = new THREE.Vector3();\n    this._worldDirection = new THREE.Vector3();\n    this._parentWorldQuaternion = new THREE.Quaternion();\n    this._east = new THREE.Vector3();\n    this._north = new THREE.Vector3();\n    this._noiseBuffer = null;\n  }\n\n  setEnabled(enabled) {\n    this.enabled = !!enabled;\n    if (!this.enabled) this.setActive(false);\n  }\n\n  setActive(active) {\n    const next = !!active && this.enabled;\n    if (this.active === next) return;\n    this.active = next;\n    if (!next) this._silenceVoices();\n  }\n\n  setRoadSources(roads) { this.roads = Array.isArray(roads) ? roads.slice(0, 12) : []; }\n  setTrafficEntries(entries) { this.traffic = Array.isArray(entries) ? entries : []; }\n  setAircraftEntries(entries) { this.aircraft = Array.isArray(entries) ? entries : []; }\n  setHabitatContext(context) { this.habitat = context && typeof context === 'object' ? { ...context } : null; }\n\n  update({\n    active = true, sceneTimeMs = Date.now(), utcOffsetSeconds,\n    latitudeDeg = 0, longitudeDeg = 0, temperatureC, humidityPercent,\n    precipitationMm, observerIsOcean = false,\n  } = {}) {\n    this.setActive(active);\n    const now = typeof performance !== 'undefined' ? performance.now() : Date.now();\n    if (!this.active || now - this._lastUpdateMs < 100) return;\n    const dt = this._lastUpdateMs ? Math.max(0.001, (now - this._lastUpdateMs) / 1000) : 0;\n    this._lastUpdateMs = now;\n    if (!this.listener?.context || this.listener.context.state !== 'running' || !this.parentGroup || !this.camera) return;\n    this._ensureVoices();\n    try { this.prepareAcousticGeometry?.(); } catch {}\n\n    this.camera.getWorldPosition(this._observerWorld);\n    this._observerLocal.copy(this._observerWorld);\n    this.parentGroup.worldToLocal(this._observerLocal);\n    if (dt > 0) this._listenerVelocity.copy(this._observerLocal).sub(this._previousObserverLocal).multiplyScalar(1 / dt);\n    else this._listenerVelocity.set(0, 0, 0);\n    this._previousObserverLocal.copy(this._observerLocal);\n\n    const localHour = resolveLocalHour(sceneTimeMs, utcOffsetSeconds, longitudeDeg);\n    const soundSpeed = speedOfSoundMps(temperatureC);\n    const humidity = Number.isFinite(humidityPercent) ? humidityPercent : DEFAULT_HUMIDITY_PERCENT;\n    this._updateRoadVoices(localHour, humidity, dt, soundSpeed);\n    this._updateAircraftVoices(\n      soundSpeed,\n      humidity,\n    );\n    const habitatEligibility = habitatAcousticEligibility({ habitat: this.habitat, observerIsOcean });\n    this._updateBirdCalls({\n      now, sceneTimeMs, localHour, latitudeDeg, longitudeDeg,\n      habitat: this.habitat, eligible: habitatEligibility.birds,\n    });\n    this._updateNocturnalWildlife({\n      now, sceneTimeMs, localHour, latitudeDeg, longitudeDeg,\n      temperatureC, humidityPercent, precipitationMm,\n      habitat: this.habitat,\n      eligibility: habitatEligibility,\n    });\n    this._updatePropagation();\n  }\n\n  _random() {\n    this._randomState = (Math.imul(this._randomState, 1664525) + 1013904223) >>> 0;\n    return this._randomState / 0x1_0000_0000;\n  }\n\n  _selectBirdProfile(latitudeDeg, longitudeDeg) {\n    const moved = Math.abs(latitudeDeg - this._birdProfileLocation.latitude) > 0.25\n      || Math.abs(longitudeDeg - this._birdProfileLocation.longitude) > 0.25;\n    if (!this._birdProfile || moved) {\n      this._birdProfile = nearestBirdsongProfile(latitudeDeg, longitudeDeg)?.profile || null;\n      this._birdProfileLocation = { latitude: latitudeDeg, longitude: longitudeDeg };\n    }\n    return this._birdProfile;\n  }\n\n  _weightedBirdVoice(profile) {\n    let cursor = this._random();\n    for (const voice of profile.voices || []) {\n      cursor -= Math.max(0, Number(voice.weight) || 0);\n      if (cursor <= 0) return voice;\n    }\n    return profile.voices?.at(-1) || null;\n  }\n\n  _placeAtHabitatAnchor(holder, anchor, heightM = 0, spreadM = 0) {\n    if (!Number.isFinite(anchor?.lat) || !Number.isFinite(anchor?.lon)) return false;\n    const direction = latLonToLocalDir(anchor.lat, anchor.lon, this._sourceDirection);\n    const surfaceRadius = this._surfaceRadiusForDirection(direction);\n    if (this.sampleSurfaceRadius && !Number.isFinite(surfaceRadius)) return false;\n    const radius = (Number.isFinite(surfaceRadius) ? surfaceRadius : ellipsoidRadiusForLocalDir(direction)) + heightM;\n    holder.position.copy(direction).multiplyScalar(radius);\n    if (spreadM > 0) {\n      this._east.set(direction.z, 0, -direction.x);\n      if (this._east.lengthSq() < 1e-6) this._east.set(1, 0, 0);\n      this._east.normalize();\n      this._north.crossVectors(direction, this._east).normalize();\n      const azimuth = this._random() * Math.PI * 2;\n      const distance = this._random() * spreadM;\n      holder.position.addScaledVector(this._east, Math.cos(azimuth) * distance)\n        .addScaledVector(this._north, Math.sin(azimuth) * distance);\n    }\n    return true;\n  }\n\n  _surfaceRadiusForDirection(localDirection) {\n    if (!this.sampleSurfaceRadius) return null;\n    this.parentGroup.getWorldQuaternion(this._parentWorldQuaternion);\n    this._worldDirection.copy(localDirection).normalize().applyQuaternion(this._parentWorldQuaternion).normalize();\n    try {\n      const radius = this.sampleSurfaceRadius(this._worldDirection);\n      return Number.isFinite(radius) ? radius : null;\n    } catch {\n      return null;\n    }\n  }\n\n  _updateBirdCalls({ now, sceneTimeMs, localHour, latitudeDeg, longitudeDeg, habitat, eligible }) {\n    const profile = this._selectBirdProfile(Number(latitudeDeg), Number(longitudeDeg));\n    if (!eligible) {\n      for (const call of [...this._birdCalls]) call.stop();\n      this._nextBirdCallMs = now + 2500;\n      return;\n    }\n    if (!profile?.voices?.length || this._birdCalls.size >= (this.mobile ? 2 : 4)) return;\n    const { sunrise, sunset } = solarDaylightHours(sceneTimeMs, latitudeDeg);\n    const greenDistance = habitat?.greenSpaceDistanceM;\n    const greenFactor = Number.isFinite(greenDistance) ? 0.12 + 0.88 * Math.exp(-greenDistance / 260) : 0;\n    const activity = birdActivityForLocalHour(localHour, sunrise, sunset)\n      * greenFactor;\n    if (!this._nextBirdCallMs) this._nextBirdCallMs = now + 450 + this._random() * 650;\n    if (now < this._nextBirdCallMs) return;\n    const voice = this._weightedBirdVoice(profile);\n    if (voice && this._random() <= activity) this._spawnBirdCall(voice, profile, habitat);\n    const intervalSeconds = 2.8 + (1 - activity) * 18 + this._random() * (3 + (1 - activity) * 8);\n    this._nextBirdCallMs = now + intervalSeconds * 1000;\n  }\n\n  _updateNocturnalWildlife({\n    now, sceneTimeMs, localHour, latitudeDeg, longitudeDeg,\n    temperatureC, humidityPercent, precipitationMm, habitat, eligibility,\n  }) {\n    const profile = this._selectBirdProfile(Number(latitudeDeg), Number(longitudeDeg));\n    const { sunrise, sunset } = solarDaylightHours(sceneTimeMs, latitudeDeg);\n    const activity = nocturnalWildlifeActivity({\n      localHour, sunrise, sunset, temperatureC, humidityPercent, precipitationMm,\n      biome: profile?.biome,\n    });\n    const greenDistance = habitat?.greenSpaceDistanceM;\n    const waterDistance = habitat?.waterDistanceM;\n    const greenFactor = Number.isFinite(greenDistance) ? 0.12 + 0.88 * Math.exp(-greenDistance / 220) : 0;\n    const waterFactor = Number.isFinite(waterDistance) ? 0.05 + 0.95 * Math.exp(-waterDistance / 150) : 0;\n    activity.crickets *= eligibility?.crickets ? greenFactor : 0;\n    activity.frogs *= eligibility?.frogs ? waterFactor : 0;\n    for (const call of [...this._wildlifeCalls]) {\n      if ((call.kind === 'cricket' && !eligibility?.crickets)\n        || (call.kind === 'frog' && !eligibility?.frogs)) call.stop();\n    }\n    if (!this._nextCricketCallMs) this._nextCricketCallMs = now + 900 + this._random() * 1200;\n    if (!this._nextFrogCallMs) this._nextFrogCallMs = now + 1800 + this._random() * 2400;\n    const capacity = this.mobile ? 2 : 5;\n    if (now >= this._nextCricketCallMs && this._wildlifeCalls.size < capacity) {\n      if (this._random() <= activity.crickets) this._spawnWildlifeCall('cricket', activity.crickets, profile, habitat);\n      this._nextCricketCallMs = now + (1.1 + (1 - activity.crickets) * 8 + this._random() * 3.5) * 1000;\n    }\n    if (now >= this._nextFrogCallMs && this._wildlifeCalls.size < capacity) {\n      if (this._random() <= activity.frogs) this._spawnWildlifeCall('frog', activity.frogs, profile, habitat);\n      this._nextFrogCallMs = now + (2.4 + (1 - activity.frogs) * 13 + this._random() * 6) * 1000;\n    }\n  }\n\n  _spawnWildlifeCall(kind, activity, profile, habitat) {\n    const context = this.listener.context;\n    const cricket = kind === 'cricket';\n    const start = context.currentTime + 0.025;\n    const duration = cricket ? 1.15 + this._random() * 0.85 : 0.65 + this._random() * 0.7;\n    const call = this._baseVoice(\n      `${cricket ? 'Cricket' : 'Frog'}Sound:${profile?.id || 'regional'}`,\n      cricket ? 3 : 5,\n      cricket ? 1.45 : 1.2,\n      cricket ? 55 : 90,\n    );\n    call.kind = kind;\n    const anchor = cricket ? habitat?.greenSpacePosition : habitat?.waterPosition;\n    if (!this._placeAtHabitatAnchor(call.holder, anchor, cricket ? 0.22 : 0.08, cricket ? 1.5 : 0.8)) {\n      this._disposeEmitter(call);\n      return;\n    }\n\n    const samples = 96, envelope = new Float32Array(samples), frequency = new Float32Array(samples);\n    for (let index = 0; index < samples; index += 1) {\n      const t = index / (samples - 1);\n      if (cricket) {\n        const pulse = Math.sin(Math.PI * ((t * 18) % 1)) ** 8;\n        envelope[index] = pulse * (0.018 + activity * 0.035) * Math.sin(Math.PI * t) ** 0.25;\n        frequency[index] = 3900 + 1500 * Math.sin((t * 2.2 + this._random() * 0.03) * Math.PI * 2);\n      } else {\n        const pulsePhase = (t * 3.2) % 1;\n        envelope[index] = (pulsePhase < 0.72 ? Math.sin(Math.PI * pulsePhase / 0.72) ** 2 : 0)\n          * (0.035 + activity * 0.065) * Math.sin(Math.PI * t) ** 0.3;\n        frequency[index] = 210 + 85 * (1 - pulsePhase) + 14 * Math.sin(t * Math.PI * 12);\n      }\n    }\n    call.input.gain.setValueCurveAtTime(envelope, start, duration);\n    const fundamental = context.createOscillator(); fundamental.type = cricket ? 'square' : 'triangle';\n    fundamental.frequency.setValueCurveAtTime(frequency, start, duration);\n    const color = context.createBiquadFilter(); color.type = cricket ? 'bandpass' : 'lowpass';\n    color.frequency.value = cricket ? 5200 : 1100; color.Q.value = cricket ? 1.8 : 0.7;\n    fundamental.connect(color).connect(call.input);\n    const harmonic = context.createOscillator(); harmonic.type = 'sine';\n    harmonic.frequency.setValueCurveAtTime(frequency.map(value => value * (cricket ? 1.48 : 2.03)), start, duration);\n    const harmonicGain = context.createGain(); harmonicGain.gain.value = cricket ? 0.08 : 0.2;\n    harmonic.connect(harmonicGain).connect(call.input);\n    call.nodes.push(fundamental, harmonic, color, harmonicGain);\n    call.stopped = false;\n    call.stop = () => {\n      if (call.stopped) return; call.stopped = true;\n      this._disposeEmitter(call); this._wildlifeCalls.delete(call);\n    };\n    fundamental.onended = call.stop; this._wildlifeCalls.add(call); this._applyPropagation(call);\n    fundamental.start(start); harmonic.start(start);\n    fundamental.stop(start + duration + 0.03); harmonic.stop(start + duration + 0.03);\n  }\n\n  _spawnBirdCall(voice, profile, habitat) {\n    const context = this.listener.context;\n    const start = context.currentTime + 0.025;\n    const duration = clamp(Number(voice.durationSeconds) || 0.7, 0.12, 4);\n    const call = this._baseVoice(`RegionalBirdSound:${profile.id}`, 7, 1.25, 120);\n    const height = 2 + this._random() * 10;\n    if (!this._placeAtHabitatAnchor(call.holder, habitat?.greenSpacePosition, height, 3)) {\n      this._disposeEmitter(call);\n      return;\n    }\n\n    const { frequency, amplitude } = birdSpectrogramCurves(voice, 128, this._random());\n    const level = amplitude.map((value) => value * 0.09);\n    call.input.gain.setValueCurveAtTime(level, start, duration);\n    const fundamental = context.createOscillator();\n    fundamental.type = 'sine';\n    fundamental.frequency.setValueCurveAtTime(frequency, start, duration);\n    const harmonic = context.createOscillator();\n    harmonic.type = 'triangle';\n    harmonic.frequency.setValueCurveAtTime(frequency.map((value) => Math.min(value * 2.01, 18_000)), start, duration);\n    const fundamentalGain = context.createGain(); fundamentalGain.gain.value = 0.82;\n    const harmonicGain = context.createGain(); harmonicGain.gain.value = 0.14;\n    fundamental.connect(fundamentalGain).connect(call.input);\n    harmonic.connect(harmonicGain).connect(call.input);\n    call.nodes.push(fundamental, harmonic, fundamentalGain, harmonicGain);\n    call.stopped = false;\n    call.stop = () => {\n      if (call.stopped) return;\n      call.stopped = true;\n      this._disposeEmitter(call);\n      this._birdCalls.delete(call);\n    };\n    fundamental.onended = call.stop;\n    this._birdCalls.add(call); this._applyPropagation(call);\n    fundamental.start(start); harmonic.start(start);\n    fundamental.stop(start + duration + 0.03); harmonic.stop(start + duration + 0.03);\n  }\n\n  _ensureVoices() {\n    if (this._noiseBuffer) return;\n    const context = this.listener.context;\n    this._noiseBuffer = seededNoiseBuffer(context);\n    const roadCount = this.mobile ? 2 : 4;\n    const aircraftCount = this.mobile ? 2 : 4;\n    for (let index = 0; index < roadCount; index += 1) this._roadVoices.push(this._createRoadVoice(index));\n    for (let index = 0; index < aircraftCount; index += 1) this._aircraftVoices.push(this._createAircraftVoice(index));\n  }\n\n  _baseVoice(name, refDistance, rolloff, maxDistance = 2500) {\n    const context = this.listener.context;\n    const holder = new THREE.Object3D();\n    holder.name = name;\n    const reflectionHolder = new THREE.Object3D();\n    reflectionHolder.name = `${name}:EarlyReflection`;\n    const audio = new THREE.PositionalAudio(this.listener);\n    audio.setDistanceModel('inverse');\n    audio.setRefDistance(refDistance);\n    audio.setRolloffFactor(rolloff);\n    audio.setMaxDistance(maxDistance);\n    audio.panner.panningModel = 'HRTF';\n    audio.setVolume(1);\n    const input = context.createGain();\n    input.gain.value = 0;\n    const directFilter = context.createBiquadFilter();\n    directFilter.type = 'lowpass'; directFilter.frequency.value = 18_000; directFilter.Q.value = 0.42;\n    const directLevel = context.createGain(); directLevel.gain.value = 1;\n    input.connect(directFilter).connect(directLevel);\n    audio.setNodeSource(directLevel);\n\n    const reflectionAudio = new THREE.PositionalAudio(this.listener);\n    reflectionAudio.setDistanceModel('inverse');\n    reflectionAudio.setRefDistance(refDistance * 1.25);\n    reflectionAudio.setRolloffFactor(Math.max(0.65, rolloff * 0.88));\n    reflectionAudio.setMaxDistance(maxDistance);\n    reflectionAudio.panner.panningModel = 'HRTF';\n    const reflectionDelay = context.createDelay(0.25);\n    reflectionDelay.delayTime.value = 0.012;\n    const diffusionDelay = context.createDelay(0.25);\n    diffusionDelay.delayTime.value = 0.019;\n    const diffusionTap = context.createGain(); diffusionTap.gain.value = 0;\n    const reflectionFilter = context.createBiquadFilter();\n    reflectionFilter.type = 'lowpass'; reflectionFilter.frequency.value = 4200; reflectionFilter.Q.value = 0.35;\n    const reflectionLevel = context.createGain(); reflectionLevel.gain.value = 0;\n    input.connect(reflectionDelay).connect(reflectionFilter);\n    input.connect(diffusionDelay).connect(diffusionTap).connect(reflectionFilter);\n    reflectionFilter.connect(reflectionLevel);\n    reflectionAudio.setNodeSource(reflectionLevel);\n    holder.add(audio);\n    reflectionHolder.add(reflectionAudio);\n    this.parentGroup.add(holder, reflectionHolder);\n    return {\n      holder, reflectionHolder, audio, reflectionAudio, input,\n      directFilter, directLevel, reflectionDelay, diffusionDelay,\n      diffusionTap, reflectionFilter, reflectionLevel,\n      atmosphericCutoffHz: 18000,\n      propagation: { reflectionPoint: new THREE.Vector3() },\n      nodes: [input, directFilter, directLevel, reflectionDelay, diffusionDelay,\n        diffusionTap, reflectionFilter, reflectionLevel],\n    };\n  }\n\n  _disposeEmitter(emitter) {\n    emitter?.nodes?.forEach(stopNode);\n    try { emitter?.audio?.disconnect?.(); } catch {}\n    try { emitter?.reflectionAudio?.disconnect?.(); } catch {}\n    emitter?.holder?.removeFromParent?.();\n    emitter?.reflectionHolder?.removeFromParent?.();\n  }\n\n  _applyPropagation(emitter) {\n    if (!emitter?.holder || !this.listener?.context) return;\n    const audioNow = this.listener.context.currentTime;\n    let path = null;\n    if (this.sampleAcousticPath) {\n      emitter.holder.updateWorldMatrix?.(true, false);\n      emitter.holder.getWorldPosition(this._sourceWorld);\n      try {\n        path = this.sampleAcousticPath(this._sourceWorld, this._observerWorld, emitter.propagation);\n      } catch {\n        path = null;\n      }\n    }\n    const directGain = clamp(Number(path?.directGain ?? 1), 0, 1);\n    const atmosphericCutoff = clamp(Number(emitter.atmosphericCutoffHz) || 18_000, 600, 18_000);\n    const directCutoff = clamp(Math.min(atmosphericCutoff, Number(path?.lowpassHz) || 18_000), 450, 18_000);\n    emitter.directLevel.gain.setTargetAtTime(directGain, audioNow, 0.04);\n    emitter.directFilter.frequency.setTargetAtTime(directCutoff, audioNow, 0.06);\n\n    const reflectionPoint = path?.reflectionPoint;\n    const reflectionGain = reflectionPoint\n      ? clamp(Number(path?.reflectionGain) || 0, 0, 0.42)\n      : 0;\n    emitter.reflectionLevel.gain.setTargetAtTime(reflectionGain, audioNow, 0.08);\n    if (!reflectionPoint) return;\n    this._reflectionLocal.copy(reflectionPoint);\n    this.parentGroup.worldToLocal(this._reflectionLocal);\n    emitter.reflectionHolder.position.copy(this._reflectionLocal);\n    const delay = clamp(Number(path.reflectionDelaySeconds) || 0.006, 0.003, 0.22);\n    const diffusion = clamp(Number(path.diffusion) || 0, 0, 1);\n    emitter.reflectionDelay.delayTime.setTargetAtTime(delay, audioNow, 0.05);\n    emitter.diffusionDelay.delayTime.setTargetAtTime(delay + 0.004 + diffusion * 0.018, audioNow, 0.05);\n    emitter.diffusionTap.gain.setTargetAtTime(diffusion * 0.46, audioNow, 0.08);\n    emitter.reflectionFilter.frequency.setTargetAtTime(\n      clamp(6200 - diffusion * 3600, 1200, atmosphericCutoff),\n      audioNow,\n      0.08,\n    );\n  }\n\n  _updatePropagation() {\n    if (!this.sampleAcousticPath) return;\n    const emitters = [\n      ...this._roadVoices.filter((voice) => voice.vehicle?.active),\n      ...this._aircraftVoices.filter((voice) => voice.active),\n      ...this._birdCalls,\n      ...this._wildlifeCalls,\n    ];\n    if (!emitters.length) return;\n    const budget = Math.min(emitters.length, this.mobile ? 2 : 4);\n    for (let index = 0; index < budget; index += 1) {\n      this._applyPropagation(emitters[(this._propagationCursor + index) % emitters.length]);\n    }\n    this._propagationCursor = (this._propagationCursor + budget) % emitters.length;\n  }\n\n  _createRoadVoice(index) {\n    const context = this.listener.context;\n    const voice = this._baseVoice(`RoadVehicleSound:${index}`, 18, 1.2, 900);\n    const mix = context.createGain(); mix.gain.value = 1;\n    mix.connect(voice.input);\n    voice.bandGains = [];\n    voice.noiseSources = [];\n    ROAD_BANDS_HZ.forEach((frequency, bandIndex) => {\n      const source = context.createBufferSource();\n      source.buffer = this._noiseBuffer;\n      source.loop = true;\n      const filter = context.createBiquadFilter();\n      filter.type = 'bandpass';\n      filter.frequency.value = frequency;\n      // Q for a one-third-octave constant-Q band is approximately 4.318.\n      filter.Q.value = 4.318;\n      const gain = context.createGain();\n      gain.gain.value = 0;\n      source.connect(filter).connect(gain).connect(mix);\n      source.start(0, (index * 0.73 + bandIndex * 0.41) % this._noiseBuffer.duration);\n      voice.nodes.push(source, filter, gain);\n      voice.noiseSources.push(source);\n      voice.bandGains.push(gain);\n    });\n    const engineColor = context.createBiquadFilter();\n    engineColor.type = 'lowpass'; engineColor.frequency.value = 2100; engineColor.Q.value = 0.7;\n    const engineMix = context.createGain(); engineMix.gain.value = 0.42;\n    engineColor.connect(engineMix).connect(mix);\n    voice.engineOscillators = [0, 1, 2].map((harmonic) => {\n      const oscillator = context.createOscillator();\n      oscillator.type = harmonic === 0 ? 'sawtooth' : 'sine';\n      const gain = context.createGain(); gain.gain.value = [0.34, 0.11, 0.035][harmonic];\n      oscillator.connect(gain).connect(engineColor); oscillator.start();\n      voice.nodes.push(oscillator, gain);\n      return oscillator;\n    });\n    const engineLfo = context.createOscillator(); engineLfo.type = 'sine'; engineLfo.frequency.value = 8.7 + index * 0.71;\n    const engineLfoGain = context.createGain(); engineLfoGain.gain.value = 0.045;\n    engineLfo.connect(engineLfoGain).connect(engineMix.gain); engineLfo.start();\n    voice.nodes.push(mix, engineColor, engineMix, engineLfo, engineLfoGain);\n    voice.engineMix = engineMix;\n    voice.engineColor = engineColor;\n    voice.vehicle = null;\n    voice.previousPosition = new THREE.Vector3();\n    voice.velocity = new THREE.Vector3();\n    return voice;\n  }\n\n  _createAircraftVoice(index) {\n    const context = this.listener.context;\n    const voice = this._baseVoice(`AircraftSound:${index}`, 850, 0.78, 40_000);\n    voice.audio.setDirectionalCone(210, 330, 0.35);\n    const mix = context.createGain();\n    const lowpass = context.createBiquadFilter();\n    lowpass.type = 'lowpass'; lowpass.frequency.value = 8000;\n    mix.connect(lowpass).connect(voice.input);\n    const noise = context.createBufferSource();\n    noise.buffer = this._noiseBuffer; noise.loop = true;\n    const noiseGain = context.createGain(); noiseGain.gain.value = 0.32;\n    noise.connect(noiseGain).connect(mix);\n    noise.start(0, (index * 0.83) % this._noiseBuffer.duration);\n    voice.oscillators = [0, 1, 2].map((harmonic) => {\n      const oscillator = context.createOscillator();\n      oscillator.type = harmonic ? 'sawtooth' : 'sine';\n      const gain = context.createGain(); gain.gain.value = [0.16, 0.055, 0.025][harmonic];\n      oscillator.connect(gain).connect(mix); oscillator.start();\n      return oscillator;\n    });\n    voice.noise = noise;\n    voice.lowpass = lowpass;\n    voice.nodes.push(mix, lowpass, noise, noiseGain, ...voice.oscillators);\n    return voice;\n  }\n\n  _matchTraffic(road) {\n    const name = String(road.name || road.ref || '').toLowerCase();\n    if (!name) return null;\n    return this.traffic.find((entry) => String(entry.roadName || entry.title || '').toLowerCase().includes(name)) || null;\n  }\n\n  _scheduleNextRoadVehicle(vehicle, roadClass, localHour, audioNow) {\n    const night = localHour >= 21 || localHour < 5.5;\n    const mainRoad = /motorway|trunk|primary/.test(roadClass);\n    const minimum = night ? (mainRoad ? 1.4 : 5.5) : (mainRoad ? 0.25 : 1.4);\n    const range = night ? (mainRoad ? 7 : 22) : (mainRoad ? 2 : 8);\n    vehicle.nextSpawnAt = audioNow + minimum + this._random() * range;\n  }\n\n  _startRoadVehicle(vehicle, road, profile, localHour, audioNow) {\n    vehicle.active = true;\n    vehicle.direction = road.oneway || this._random() > 0.5 ? 1 : -1;\n    vehicle.positionM = vehicle.direction > 0 ? 0 : vehicle.metrics.totalLengthM;\n    vehicle.variant = this._random();\n    vehicle.speedMps = Math.max(3.5, profile.speedKph / 3.6 * (0.72 + this._random() * 0.24));\n    vehicle.targetSpeedMps = Math.max(4, profile.speedKph / 3.6 * (0.82 + this._random() * 0.28));\n    vehicle.accelerationMps2 = 0;\n    vehicle.nextSpeedChangeAt = audioNow + 1.2 + this._random() * 3.8;\n    vehicle.startedAt = audioNow;\n    vehicle.localHour = localHour;\n    vehicle.firstFrame = true;\n  }\n\n  _updateRoadVoices(localHour, humidityPercent, dt, soundSpeed) {\n    const hour = ((Number(localHour) % 24) + 24) % 24;\n    const audioNow = this.listener.context.currentTime;\n    this._roadVoices.forEach((voice, index) => {\n      const road = this.roads[index];\n      const roadKey = road?.id || `${road?.name || ''}:${road?.path?.length || 0}`;\n      if (!road || !Array.isArray(road.path)) {\n        voice.input.gain.setTargetAtTime(0, audioNow, 0.08);\n        if (voice.vehicle) voice.vehicle.active = false;\n        return;\n      }\n      const profile = roadAcousticProfile(road, { localHour, live: this._matchTraffic(road) });\n      const roadClass = String(road.class || road.subclass || '').toLowerCase();\n      if (!voice.vehicle || voice.vehicle.roadKey !== roadKey) {\n        const metrics = buildRoadPathMetrics(road.path);\n        voice.vehicle = {\n          roadKey, metrics, active: false, positionM: 0, direction: 1,\n          speedMps: 0, targetSpeedMps: 0, accelerationMps2: 0,\n          nextSpawnAt: audioNow + this._random() * 1.5,\n          variant: this._random(), nextSpeedChangeAt: 0,\n        };\n      }\n      const vehicle = voice.vehicle;\n      this._roadVehicles[index] = vehicle;\n      if (!(vehicle.metrics.totalLengthM >= 12)) {\n        vehicle.active = false;\n        voice.input.gain.setTargetAtTime(0, audioNow, 0.08);\n        return;\n      }\n      if (!vehicle.active && audioNow >= vehicle.nextSpawnAt) {\n        this._startRoadVehicle(vehicle, road, profile, hour, audioNow);\n      }\n      if (!vehicle.active) {\n        voice.input.gain.setTargetAtTime(0, audioNow, 0.08);\n        return;\n      }\n\n      if (audioNow >= vehicle.nextSpeedChangeAt) {\n        vehicle.targetSpeedMps = Math.max(3.5, profile.speedKph / 3.6 * (0.74 + this._random() * 0.34));\n        vehicle.nextSpeedChangeAt = audioNow + 1.8 + this._random() * 5.2;\n      }\n      const frameDt = clamp(dt || 0.1, 0.001, 0.25);\n      const acceleration = clamp((vehicle.targetSpeedMps - vehicle.speedMps) * 0.65, -2.8, 2.2);\n      vehicle.accelerationMps2 = THREE.MathUtils.lerp(vehicle.accelerationMps2, acceleration, 0.25);\n      vehicle.speedMps = Math.max(2.5, vehicle.speedMps + vehicle.accelerationMps2 * frameDt);\n      vehicle.positionM += vehicle.direction * vehicle.speedMps * frameDt;\n      if (vehicle.positionM < 0 || vehicle.positionM > vehicle.metrics.totalLengthM) {\n        vehicle.active = false;\n        voice.input.gain.setTargetAtTime(0, audioNow, 0.1);\n        this._scheduleNextRoadVehicle(vehicle, roadClass, hour, audioNow);\n        return;\n      }\n      const position = sampleRoadPath(vehicle.metrics, vehicle.positionM);\n      if (!position) return;\n      voice.previousPosition.copy(voice.holder.position);\n      const direction = latLonToLocalDir(position.lat, position.lon, this._sourceDirection);\n      const surfaceRadius = this._surfaceRadiusForDirection(direction);\n      if (this.sampleSurfaceRadius && !Number.isFinite(surfaceRadius)) {\n        voice.input.gain.setTargetAtTime(0, audioNow, 0.08);\n        return;\n      }\n      voice.holder.position.copy(direction).multiplyScalar(\n        (Number.isFinite(surfaceRadius) ? surfaceRadius : ellipsoidRadiusForLocalDir(direction)) + 1.15,\n      );\n      if (!vehicle.firstFrame && voice.previousPosition.lengthSq() > 0) {\n        voice.velocity.copy(voice.holder.position).sub(voice.previousPosition).multiplyScalar(1 / frameDt);\n      } else voice.velocity.set(0, 0, 0);\n      vehicle.firstFrame = false;\n      const factor = dopplerFactor({\n        sourcePosition: voice.holder.position,\n        listenerPosition: this._observerLocal,\n        sourceVelocity: voice.velocity,\n        listenerVelocity: this._listenerVelocity,\n        soundSpeedMps: soundSpeed,\n      });\n      const engine = vehicleEngineState({\n        speedMps: vehicle.speedMps,\n        accelerationMps2: vehicle.accelerationMps2,\n        variant: vehicle.variant,\n      });\n      voice.engineOscillators.forEach((oscillator, harmonic) => {\n        const harmonicRatio = [1, 2.02, 3.97][harmonic];\n        oscillator.frequency.setTargetAtTime(engine.firingHz * harmonicRatio * factor, audioNow, 0.045);\n      });\n      voice.noiseSources.forEach((source) => source.playbackRate.setTargetAtTime(factor, audioNow, 0.06));\n      voice.engineMix.gain.setTargetAtTime(0.28 + engine.load * 0.32, audioNow, 0.12);\n      voice.engineColor.frequency.setTargetAtTime(1200 + engine.load * 2500, audioNow, 0.1);\n      const gain = clamp(profile.gain * 0.105, 0.018, 0.16);\n      voice.input.gain.setTargetAtTime(gain, audioNow, 0.12);\n      voice.bandGains.forEach((node, band) => {\n        const tireShare = clamp(vehicle.speedMps / 30, 0.25, 1.15);\n        node.gain.setTargetAtTime(profile.bandGains[band] * tireShare * 0.72, audioNow, 0.16);\n      });\n      const distance = voice.holder.position.distanceTo(this._observerLocal);\n      voice.atmosphericCutoffHz = atmosphericLowpassHz(distance, humidityPercent);\n    });\n  }\n\n  _aircraftVelocity(entry, direction, target) {\n    const heading = THREE.MathUtils.degToRad(Number(entry.headingDeg) || 0);\n    this._east.set(direction.z, 0, -direction.x);\n    if (this._east.lengthSq() < 1e-6) this._east.set(1, 0, 0);\n    this._east.normalize();\n    this._north.crossVectors(direction, this._east).normalize();\n    return target.copy(this._north).multiplyScalar(Math.cos(heading) * (Number(entry.velocityMps) || 0))\n      .addScaledVector(this._east, Math.sin(heading) * (Number(entry.velocityMps) || 0))\n      .addScaledVector(direction, Number(entry.verticalRateMps) || 0);\n  }\n\n  _updateAircraftVoices(soundSpeed, humidityPercent) {\n    const audible = this.aircraft\n      .filter((entry) => !entry.onGround && Number.isFinite(entry.lat) && Number.isFinite(entry.lon))\n      .map((entry) => {\n        const direction = latLonToLocalDir(entry.lat, entry.lon);\n        const position = direction.clone().multiplyScalar(ellipsoidRadiusForLocalDir(direction) + Math.max(0, Number(entry.altitudeM) || 0));\n        return { entry, direction, position, distance: position.distanceTo(this._observerLocal) };\n      })\n      .sort((a, b) => a.distance - b.distance);\n\n    this._aircraftVoices.forEach((voice, index) => {\n      const candidate = audible[index];\n      if (!candidate) {\n        voice.active = false;\n        voice.input.gain.setTargetAtTime(0, this.listener.context.currentTime, 0.2);\n        return;\n      }\n      voice.active = true;\n      const { entry, direction, position, distance } = candidate;\n      this._aircraftVelocity(entry, direction, this._sourceVelocity);\n      const propagationDelay = Math.min(8, distance / soundSpeed);\n      this._sourcePosition.copy(position).addScaledVector(this._sourceVelocity, -propagationDelay);\n      voice.holder.position.copy(this._sourcePosition);\n      voice.holder.lookAt(this._sourcePosition.clone().add(this._sourceVelocity));\n      const factor = dopplerFactor({\n        sourcePosition: this._sourcePosition,\n        listenerPosition: this._observerLocal,\n        sourceVelocity: this._sourceVelocity,\n        listenerVelocity: this._listenerVelocity,\n        soundSpeedMps: soundSpeed,\n      });\n      const baseFrequency = 72 + clamp(Number(entry.velocityMps) || 0, 0, 320) * 0.22;\n      voice.oscillators.forEach((oscillator, harmonic) => {\n        oscillator.frequency.setTargetAtTime(baseFrequency * (harmonic + 1) * factor, this.listener.context.currentTime, 0.08);\n      });\n      voice.noise.playbackRate.setTargetAtTime(factor, this.listener.context.currentTime, 0.08);\n      voice.lowpass.frequency.setTargetAtTime(\n        atmosphericLowpassHz(distance, humidityPercent),\n        this.listener.context.currentTime,\n        0.15,\n      );\n      voice.atmosphericCutoffHz = atmosphericLowpassHz(distance, humidityPercent);\n      const gain = clamp(0.08 + (Number(entry.velocityMps) || 0) / 4000, 0.08, 0.17);\n      voice.input.gain.setTargetAtTime(gain, this.listener.context.currentTime, 0.2);\n    });\n  }\n\n  _silenceVoices() {\n    const time = this.listener?.context?.currentTime || 0;\n    [...this._roadVoices, ...this._aircraftVoices].forEach((voice) => voice.input?.gain?.setTargetAtTime?.(0, time, 0.08));\n    for (const call of [...this._birdCalls]) call.stop();\n    for (const call of [...this._wildlifeCalls]) call.stop();\n    this._nextBirdCallMs = 0;\n    this._nextCricketCallMs = this._nextFrogCallMs = 0;\n  }\n\n  dispose() {\n    for (const voice of [...this._roadVoices, ...this._aircraftVoices]) {\n      this._disposeEmitter(voice);\n    }\n    this._roadVoices = [];\n    this._roadVehicles = [];\n    this._aircraftVoices = [];\n    for (const call of [...this._birdCalls]) call.stop();\n    this._birdCalls.clear();\n    for (const call of [...this._wildlifeCalls]) call.stop();\n    this._wildlifeCalls.clear();\n    this._noiseBuffer = null;\n  }\n}\n","/** Procedural stereo rainfall: diffuse wash, fine spray, and sparse resonant impacts.\n * No recordings, ScriptProcessor, timers, private AudioContext, or per-frame voices.\n */\nconst target = (param, value, time, seconds = 0.35) => {\n    const current = param.value;\n    param.cancelScheduledValues(time);\n    // Firefox also cancels a .value assignment at this timestamp. Preserve\n    // the actual starting gain so cancelling automation cannot restore the\n    // AudioParam default (1) and create an audible dry-state transient.\n    param.setValueAtTime(current, time);\n    param.setTargetAtTime(value, time, seconds);\n};\n\nexport function createRainAudioGraph(context, output) {\n    let seed = 0x7261696e;\n    const random = () => { seed = (Math.imul(seed, 1664525) + 1013904223) >>> 0; return seed / 4294967296; };\n    const nodes = [], sources = [], gains = [];\n    const master = context.createGain(); master.gain.value = 0;\n    const limiter = context.createDynamicsCompressor();\n    limiter.threshold.value = -12; limiter.knee.value = 12; limiter.ratio.value = 3;\n    limiter.attack.value = 0.012; limiter.release.value = 0.2;\n    master.connect(limiter); limiter.connect(output); nodes.push(master, limiter);\n    const band = (seconds, kind, low, high) => {\n        const buffer = context.createBuffer(2, Math.ceil(context.sampleRate * seconds), context.sampleRate);\n        for (let channel = 0; channel < 2; channel++) {\n            const samples = buffer.getChannelData(channel);\n            if (kind === 'impacts') {\n                // Poisson arrivals, damped resonances and an initial broadband\n                // transient break up the continuous hiss without a voice scheduler.\n                let time = 0;\n                while (time < seconds) {\n                    time += -Math.log(Math.max(0.000001, 1 - random())) / 28;\n                    const start = Math.floor(time * context.sampleRate);\n                    const duration = 0.012 + random() * 0.045, frequency = 1100 + random() * 3900;\n                    const amplitude = 0.18 + random() * 0.45;\n                    for (let i = 0; i < duration * context.sampleRate && start + i < samples.length; i++) {\n                        const t = i / context.sampleRate;\n                        const envelope = (1 - Math.exp(-t * 3000)) * Math.exp(-t / (duration * 0.17));\n                        samples[start + i] += amplitude * envelope * (\n                            Math.sin(2 * Math.PI * frequency * t * (1 - 2.8 * t)) * 0.6 + (random() * 2 - 1) * 0.4);\n                    }\n                }\n            } else {\n                let pink = 0;\n                for (let i = 0; i < samples.length; i++) {\n                    const white = random() * 2 - 1;\n                    pink = pink * 0.985 + white * 0.015;\n                    samples[i] = kind === 'wash' ? pink * 3.5 + white * 0.18 : white * 0.45;\n                }\n            }\n            // Seam ends have zero value and slope; sources have different loop\n            // lengths/offsets so the layers never share a recurring gap.\n            const fade = Math.floor(context.sampleRate * 0.012);\n            for (let i = 0; i < fade; i++) {\n                const w = Math.sin(i / fade * Math.PI / 2) ** 2;\n                samples[i] *= w; samples[samples.length - 1 - i] *= w;\n            }\n        }\n        const source = context.createBufferSource(); source.buffer = buffer; source.loop = true;\n        const hp = context.createBiquadFilter(); hp.type = 'highpass'; hp.frequency.value = low; hp.Q.value = 0.5;\n        const lp = context.createBiquadFilter(); lp.type = 'lowpass'; lp.frequency.value = high; lp.Q.value = 0.5;\n        const gain = context.createGain(); gain.gain.value = 0;\n        source.connect(hp); hp.connect(lp); lp.connect(gain); gain.connect(master);\n        source.start(0, random() * seconds);\n        sources.push(source); gains.push(gain); nodes.push(source, hp, lp, gain);\n    };\n    band(7.3, 'wash', 180, 6200);\n    band(5.7, 'spray', 2100, 12500);\n    band(11.1, 'impacts', 650, 8500);\n    return {\n        master, sources,\n        update(rateMmH, gustExcessMps = 0) {\n            const now = context.currentTime;\n            const intensity = 1 - Math.exp(-Math.sqrt(Math.max(0, rateMmH)) * 0.32);\n            target(master.gain, rateMmH > 0 ? 0.65 : 0, now);\n            target(gains[0].gain, intensity * 0.7, now);\n            target(gains[1].gain, intensity * intensity * (0.25 + Math.min(1, Math.max(0, gustExcessMps) / 20) * 0.12), now);\n            target(gains[2].gain, Math.sqrt(intensity) * 0.65, now);\n        },\n        dispose() {\n            for (const source of sources) { try { source.stop(); } catch {} source.buffer = null; }\n            for (const node of nodes) node.disconnect();\n        },\n    };\n}\n\nexport class RainAudio {\n    constructor({ context, output } = {}) {\n        this.context = context; this.output = output;\n        this.enabled = true; this._graph = null; this._disposed = false; this._drySince = null;\n        this._onVisibility = () => { if (document.hidden) this.suspend(); };\n        globalThis.document?.addEventListener('visibilitychange', this._onVisibility);\n    }\n    setEnabled(enabled) { this.enabled = !!enabled; if (!this.enabled) this.suspend(); }\n    update(state, active = true) {\n        if (this._disposed || !this.enabled || !active || globalThis.document?.hidden\n            || !state?.available || this.context?.state !== 'running') { this.suspend(); return; }\n        const rate = Number.isFinite(state.rainRateMmH) ? Math.max(0, state.rainRateMmH) : 0;\n        if (rate <= 0) {\n            if (!this._graph) return;\n            this._drySince ??= this.context.currentTime;\n            this._graph.update(0);\n            if (this.context.currentTime - this._drySince > 1.5) this.suspend();\n            return;\n        }\n        this._drySince = null;\n        this._graph ||= createRainAudioGraph(this.context, this.output);\n        const excess = Number.isFinite(state.windGustMps) && Number.isFinite(state.windSpeedMps)\n            ? Math.max(0, state.windGustMps - state.windSpeedMps) : 0;\n        this._graph.update(rate, excess);\n    }\n    suspend() { this._graph?.dispose(); this._graph = null; this._drySince = null; }\n    dispose() {\n        this._disposed = true; this.suspend();\n        globalThis.document?.removeEventListener('visibilitychange', this._onVisibility);\n    }\n}\n","/**\n * AcousticEmitter — environmental acoustics for a THREE.PositionalAudio\n * source (theater media, proximity voice).\n *\n * The panner already gives HRTF direction and distance falloff. On top of it:\n *   - directivity cone: a screen/voice is loudest in front of it;\n *   - air absorption: high frequencies fade with distance;\n *   - occlusion: terrain/buildings between source and listener muffle and\n *     duck the direct path (sampled by the scene's acoustic path probe);\n *   - first-order ground reflection, delayed by the extra path length;\n *   - a shared diffuse reverb whose share grows with distance.\n *\n * `estimateEmitterGain` is the same model reduced to one number, for media\n * the browser will not route through Web Audio (YouTube/Vimeo iframes).\n */\nimport * as THREE from 'three';\n\nconst SPEED_OF_SOUND = 343;\nconst clamp = (v, lo, hi) => Math.min(hi, Math.max(lo, v));\n\n/** Air absorption as a low-pass cutoff (Hz) for a path length in metres. */\nexport function airAbsorptionCutoff(distanceM) {\n  const d = Math.max(0, Number(distanceM) || 0);\n  return clamp(20000 / (1 + d / 180), 900, 20000);\n}\n\n/** Gain of a directivity cone (Web Audio PannerNode semantics). */\nexport function coneGain(angleRad, { inner = 140, outer = 300, outerGain = 0.3 } = {}) {\n  const deg = Math.abs(THREE.MathUtils.radToDeg(angleRad));\n  if (deg <= inner / 2) return 1;\n  if (deg >= outer / 2) return outerGain;\n  const t = (deg - inner / 2) / Math.max(1e-6, (outer - inner) / 2);\n  return 1 + (outerGain - 1) * t;\n}\n\n/** Inverse distance model gain (PannerNode 'inverse'). */\nexport function distanceGain(distanceM, { refDistance = 4, rolloff = 1, maxDistance = Infinity } = {}) {\n  const d = clamp(Number(distanceM) || 0, refDistance, maxDistance);\n  return refDistance / (refDistance + rolloff * (d - refDistance));\n}\n\n/**\n * One-number loudness for a source we can only set a volume on.\n * @returns {number} 0..1\n */\nexport function estimateEmitterGain({ distanceM, facingAngleRad = 0, occlusionGain = 1, refDistance, rolloff, maxDistance, cone }) {\n  if (Number.isFinite(maxDistance) && distanceM > maxDistance * 1.25) return 0;\n  const air = Math.sqrt(airAbsorptionCutoff(distanceM) / 20000); // loudness share kept by highs\n  const g = distanceGain(distanceM, { refDistance, rolloff, maxDistance })\n    * coneGain(facingAngleRad, cone)\n    * clamp(occlusionGain, 0, 1)\n    * (0.55 + 0.45 * air);\n  return clamp(g, 0, 1);\n}\n\nlet sharedReverb = null;\nfunction getSharedReverb(listener) {\n  const ctx = listener.context;\n  if (sharedReverb?.ctx === ctx) return sharedReverb.input;\n  // Synthetic outdoor tail: 1.6 s of decaying stereo noise, dark-ish.\n  const seconds = 1.6;\n  const length = Math.floor(ctx.sampleRate * seconds);\n  const impulse = ctx.createBuffer(2, length, ctx.sampleRate);\n  for (let ch = 0; ch < 2; ch++) {\n    const data = impulse.getChannelData(ch);\n    let lp = 0;\n    for (let i = 0; i < length; i++) {\n      const t = i / length;\n      lp += 0.35 * ((Math.random() * 2 - 1) - lp);\n      data[i] = lp * Math.pow(1 - t, 3.2) * (i < ctx.sampleRate * 0.012 ? i / (ctx.sampleRate * 0.012) : 1);\n    }\n  }\n  const convolver = ctx.createConvolver();\n  convolver.buffer = impulse;\n  const input = ctx.createGain();\n  input.gain.value = 0.6;\n  input.connect(convolver);\n  convolver.connect(listener.getInput());\n  sharedReverb = { ctx, input };\n  return input;\n}\n\n/**\n * @param {object} o\n * @param {THREE.AudioListener} o.listener\n * @param {THREE.PositionalAudio} o.audio   already has its node source set\n * @param {AudioNode} o.source             the node feeding `audio` (tap point)\n * @param {object} [o.cone]                {inner, outer, outerGain} degrees\n * @param {Function} [o.sampleAcousticPath] (sourceWorld, listenerWorld, target) => path\n * @param {number} [o.reverb=0.18]         diffuse share at reference distance\n */\nexport function createAcousticEmitter({ listener, audio, source, cone = null, sampleAcousticPath = null, reverb = 0.18 }) {\n  const ctx = listener?.context;\n  if (!ctx || !audio?.panner || !source) return null; // a panner marks PositionalAudio\n\n  if (cone && audio.panner) {\n    audio.panner.coneInnerAngle = cone.inner ?? 140;\n    audio.panner.coneOuterAngle = cone.outer ?? 300;\n    audio.panner.coneOuterGain = cone.outerGain ?? 0.3;\n    // PositionalAudio aims along local +Z; avatars face -Z.\n    if (cone.forward === '-z') audio.rotation.y = Math.PI;\n  }\n\n  const air = ctx.createBiquadFilter();\n  air.type = 'lowpass'; air.Q.value = 0.5; air.frequency.value = 20000;\n  const occlusionFilter = ctx.createBiquadFilter();\n  occlusionFilter.type = 'lowpass'; occlusionFilter.Q.value = 0.42; occlusionFilter.frequency.value = 18000;\n  const directLevel = ctx.createGain();\n  audio.setFilters([air, occlusionFilter, directLevel]);\n\n  const reverbSend = ctx.createGain();\n  reverbSend.gain.value = 0;\n  source.connect(reverbSend);\n  reverbSend.connect(getSharedReverb(listener));\n\n  // Ground / wall reflection: its own positional source at the bounce point.\n  const reflectionDelay = ctx.createDelay(0.5);\n  const reflectionFilter = ctx.createBiquadFilter();\n  reflectionFilter.type = 'lowpass'; reflectionFilter.frequency.value = 4200;\n  const reflectionLevel = ctx.createGain();\n  reflectionLevel.gain.value = 0;\n  source.connect(reflectionDelay);\n  reflectionDelay.connect(reflectionFilter).connect(reflectionLevel);\n  const reflection = new THREE.PositionalAudio(listener);\n  reflection.panner.panningModel = 'HRTF';\n  reflection.setDistanceModel(audio.panner.distanceModel);\n  reflection.setRefDistance(audio.getRefDistance());\n  reflection.setRolloffFactor(audio.getRolloffFactor());\n  reflection.setMaxDistance(audio.getMaxDistance());\n  reflection.setNodeSource(reflectionLevel);\n  reflection.name = 'AcousticReflection';\n\n  const sourceWorld = new THREE.Vector3();\n  const listenerWorld = new THREE.Vector3();\n  const path = {};\n  const ref = () => Math.max(0.5, audio.getRefDistance());\n\n  return {\n    /** Re-sample propagation; cheap enough at ~8 Hz. */\n    update() {\n      if (!audio.parent) return;\n      const now = ctx.currentTime;\n      audio.getWorldPosition(sourceWorld);\n      listener.getWorldPosition(listenerWorld);\n      const distance = sourceWorld.distanceTo(listenerWorld);\n      let sampled = null;\n      if (sampleAcousticPath) {\n        try { sampled = sampleAcousticPath(sourceWorld, listenerWorld, path); } catch { sampled = null; }\n      }\n      const occluded = sampled?.occluded === true;\n      air.frequency.setTargetAtTime(airAbsorptionCutoff(distance), now, 0.08);\n      occlusionFilter.frequency.setTargetAtTime(clamp(Number(sampled?.lowpassHz) || 18000, 450, 18000), now, 0.06);\n      directLevel.gain.setTargetAtTime(clamp(Number(sampled?.directGain ?? 1), 0, 1), now, 0.05);\n\n      // Reverberant field decays far slower than the direct path.\n      const far = distance / ref();\n      const wet = reverb * clamp(1 / (1 + 0.08 * Math.max(0, far - 1)), 0, 1) * (occluded ? 1.6 : 1);\n      const fade = distance > audio.getMaxDistance() ? 0 : 1;\n      reverbSend.gain.setTargetAtTime(wet * fade, now, 0.12);\n\n      const bounce = sampled?.reflectionPoint;\n      if (bounce?.isVector3) {\n        let root = audio; while (root.parent) root = root.parent;\n        if (reflection.parent !== root) root.add(reflection);\n        reflection.position.copy(bounce);\n        if (root.matrixWorld) reflection.position.applyMatrix4(new THREE.Matrix4().copy(root.matrixWorld).invert());\n        const extra = Math.max(0, sourceWorld.distanceTo(bounce) + bounce.distanceTo(listenerWorld) - distance);\n        reflectionDelay.delayTime.setTargetAtTime(clamp(extra / SPEED_OF_SOUND, 0.002, 0.45), now, 0.05);\n        reflectionLevel.gain.setTargetAtTime(clamp(Number(sampled.reflectionGain) || 0, 0, 0.42), now, 0.08);\n      } else {\n        reflectionLevel.gain.setTargetAtTime(0, now, 0.1);\n      }\n    },\n    dispose() {\n      try { source.disconnect(reverbSend); } catch { /* already gone */ }\n      try { source.disconnect(reflectionDelay); } catch { /* already gone */ }\n      try { reflection.disconnect(); } catch { /* not connected */ }\n      reflection.removeFromParent();\n      for (const node of [air, occlusionFilter, directLevel, reverbSend, reflectionDelay, reflectionFilter, reflectionLevel]) {\n        try { node.disconnect(); } catch { /* not connected */ }\n      }\n    },\n  };\n}\n","/**\n * AudioSystem (Unified)\n *\n * Single audio system combining:\n * - PCM streaming and media element playback (entity/item/object attachment)\n * - 3D positional audio file playback (playSound)\n * - Procedural synthesis (blips, impacts)\n * - Ambient soundscapes (startAmbient/stopAmbient)\n * - Master volume control\n * - Auto-enable on user interaction\n *\n * API:\n *   init(listener, { camera, scene })\n *   attachGlobal(pcmStream, opts)\n *   attachToEntity(entityId, pcmStream, opts)\n *   attachToItem(itemId, pcmStream, opts)\n *   attachToObject(object, pcmStream, opts)\n *   detach(handleId), dispose()\n *   playSound(url, position, opts)\n *   triggerBlip(position, intensity)\n *   triggerImpact(position, params)\n *   startAmbient(volume, freq)\n *   stopAmbient()\n *   setMasterVolume(volume)\n *   setEnabled(enabled)\n *   isEnabled()\n *   resume() / start()\n */\nimport * as THREE from 'three';\nimport { SpatialAmbientSoundscape } from './SpatialAmbientSoundscape.js';\nimport { RainAudio } from './RainAudio.js';\nimport { createAcousticEmitter } from './AcousticEmitter.js';\n\nexport class AudioSystem {\n    constructor({ streamHub, entitySystem, overlaySubsystem, accessController, eventBus } = {}) {\n        this.streamHub = streamHub || null;\n        this.entitySystem = entitySystem || null;\n        this.overlaySubsystem = overlaySubsystem || null;\n        this.accessController = accessController || null;\n        this.eventBus = eventBus || null;\n\n        this.listener = null;\n        this.started = false;\n        this.enabled = true;\n        this.handles = new Map();\n        this._id = 0;\n\n        // Spatial audio defaults\n        this._scene = null;\n        this._camera = null;\n        this._spatialVolume = 0.16;\n        this._spatialRefDistance = 18;\n        this._spatialRolloff = 2.0;\n\n        // Blip synthesis\n        this._blipDuration = 0.2;\n        this._blipFreq = 12000;\n        this._maxVoices = 64;\n        this._voices = 0;\n        this._blipBuffers = null; // lazily created after init\n\n        // Impact synthesis\n        this._impactDuration = 0.22;\n        this._impactVolume = 0.22;\n        this._impactBufferCache = new Map();\n\n        // Ambient hum\n        this._humVolume = 0.08;\n        this._humFreq = 60;\n        this._humDetune = 1.01;\n        this._humFade = 0.35;\n        this._humNodes = null;\n\n        // Master gain (connected after init)\n        this._masterGain = null;\n\n        // Asset audio cache & active sources\n        this._audioBufferCache = new Map();\n        this._audioLoader = new THREE.AudioLoader();\n        this._activeSources = new Map();\n\n        // Auto-enable state\n        this._hardDisabled = false;\n        this._autoEnableCleanup = null;\n        this._spatialAmbient = null;\n        this._rainAudio = null;\n        this._onFlightEntries = (entries) => this._spatialAmbient?.setAircraftEntries(entries);\n        this._onRoadTrafficEntries = (entries) => this._spatialAmbient?.setTrafficEntries(entries);\n    }\n\n    async init(listener, { camera, scene, parentGroup = null, mobile = false, surfaceController = null } = {}) {\n        this.listener = listener || null;\n        this._camera = camera || null;\n        this._scene = scene || null;\n        this.started = this._isContextRunning();\n\n        // Set up master gain for spatial/ambient audio\n        const ctx = this.listener?.context;\n        if (ctx) {\n            this._masterGain = ctx.createGain();\n            this._masterGain.gain.value = 1.0;\n            this._masterGain.connect(ctx.destination);\n            this._rainAudio = new RainAudio({ context: ctx, output: this._masterGain });\n\n            // Pre-generate blip buffers\n            this._blipBuffers = this._makeBlipBuffers(3);\n            this._sampleAcousticPath = surfaceController?.samplePhotorealAcousticPath\n                ? (sourceWorldPos, listenerWorldPos, target) => surfaceController.samplePhotorealAcousticPath(\n                    sourceWorldPos, listenerWorldPos, target, { skipWorldMatrixUpdate: true })\n                : null;\n            this._spatialAmbient = new SpatialAmbientSoundscape({\n                listener: this.listener,\n                camera: this._camera,\n                parentGroup: parentGroup || this._scene,\n                mobile,\n                prepareAcousticGeometry: surfaceController?.preparePhotorealAcousticSampling\n                    ? () => surfaceController.preparePhotorealAcousticSampling()\n                    : null,\n                sampleSurfaceRadius: surfaceController?.samplePhotorealSurfaceForDir\n                    ? (worldDirection) => surfaceController.samplePhotorealSurfaceForDir(\n                        worldDirection,\n                        { skipWorldMatrixUpdate: true },\n                    )?.radius\n                    : null,\n                sampleAcousticPath: surfaceController?.samplePhotorealAcousticPath\n                    ? (sourceWorldPos, listenerWorldPos, target) => surfaceController.samplePhotorealAcousticPath(\n                        sourceWorldPos,\n                        listenerWorldPos,\n                        target,\n                        { skipWorldMatrixUpdate: true },\n                    )\n                    : null,\n            });\n        }\n\n        this.eventBus?.on?.('flights:entries', this._onFlightEntries);\n        this.eventBus?.on?.('roadTraffic:entries', this._onRoadTrafficEntries);\n\n        // Auto-enable on user interaction\n        this._setupAutoEnable();\n    }\n\n    // ── Streaming / Entity Audio API ──────────────────────────────────────\n\n    attachGlobal(pcmStream, opts = {}) {\n        return this._attach({ target: null, type: 'global' }, pcmStream, opts);\n    }\n\n    attachToEntity(entityId, pcmStream, opts = {}) {\n        if (!entityId) return null;\n        if (!this._canUseAudio('entity', entityId)) {\n            return { blocked: true, target: entityId };\n        }\n        const object = this.entitySystem?.getObjectForEntity?.(entityId) || null;\n        return this._attach({ target: object, targetId: entityId, type: 'entity' }, pcmStream, opts);\n    }\n\n    attachToItem(itemId, pcmStream, opts = {}) {\n        if (!itemId) return null;\n        if (!this._canUseAudio('item', itemId)) {\n            return { blocked: true, target: itemId };\n        }\n        const object = this.overlaySubsystem?.getItemObject?.(itemId) || null;\n        if (!object) {\n            return { missing: true, target: itemId };\n        }\n        const target = object?.userData?.audioAnchor\n            || object?.getObjectByName?.(`AudioAnchor:${itemId}`)\n            || object;\n        return this._attach({ target, targetId: itemId, type: 'item' }, pcmStream, opts);\n    }\n\n    attachToObject(object, pcmStream, opts = {}) {\n        if (!object) return null;\n        return this._attach({ target: object, targetId: object.uuid, type: 'object' }, pcmStream, opts);\n    }\n\n    detach(handleId) {\n        const handle = this.handles.get(handleId);\n        if (!handle) return;\n        handle.active = false;\n        handle.acoustic?.dispose();\n        handle.acoustic = null;\n        if (Array.isArray(handle.oscillators)) {\n            for (const { osc, gain } of handle.oscillators) {\n                osc?.stop();\n                osc?.disconnect();\n                gain?.disconnect();\n            }\n        }\n        if (handle.pcmSources) {\n            for (const source of handle.pcmSources) {\n                try { source.stop(); } catch (error) {}\n                try { source.disconnect(); } catch (error) {}\n            }\n            handle.pcmSources.clear();\n        }\n        if (handle.mediaSource) {\n            try { handle.mediaSource.disconnect(); } catch (error) {}\n        }\n        handle.gainNode?.disconnect();\n        handle.streamRelease?.();\n        if (handle.audio?.isPlaying) {\n            handle.audio.stop();\n        }\n        if (handle.audio?.disconnect) {\n            handle.audio.disconnect();\n        }\n        if (handle.audio && handle.audio.parent) {\n            handle.audio.parent.remove(handle.audio);\n        }\n        this.handles.delete(handleId);\n    }\n\n    dispose() {\n        for (const handleId of [...this.handles.keys()]) {\n            this.detach(handleId);\n        }\n        this.stopAmbient();\n        for (const { holder, sound } of this._activeSources.values()) {\n            try { sound.stop(); } catch (e) {}\n            if (holder.parent) holder.parent.remove(holder);\n        }\n        this._activeSources.clear();\n        this.eventBus?.off?.('flights:entries', this._onFlightEntries);\n        this.eventBus?.off?.('roadTraffic:entries', this._onRoadTrafficEntries);\n        this._spatialAmbient?.dispose?.();\n        this._spatialAmbient = null;\n        this._rainAudio?.dispose();\n        this._rainAudio = null;\n        this._autoEnableCleanup?.();\n    }\n\n    // ── Spatial Audio API (merged from legacy audio-system.js) ────────────\n\n    /**\n     * Play audio file at a 3D position.\n     * @param {string} url - Audio file URL\n     * @param {THREE.Vector3} position - World position\n     * @param {Object} options - { volume, loop, refDistance, rolloff, onEnd }\n     * @returns {Object|null} - { stop, setVolume, updatePosition }\n     */\n    async playSound(url, position, options = {}) {\n        if (!this.isEnabled() || !this.listener) return null;\n\n        const {\n            volume = 1.0,\n            loop = false,\n            refDistance = this._spatialRefDistance,\n            rolloff = this._spatialRolloff,\n            onEnd = null\n        } = options;\n\n        try {\n            const buffer = await this._loadAudioBuffer(url);\n            if (!buffer) return null;\n\n            const holder = new THREE.Object3D();\n            holder.position.copy(position);\n            if (this._scene) this._scene.add(holder);\n\n            const sound = new THREE.PositionalAudio(this.listener);\n            sound.setBuffer(buffer);\n            sound.setRefDistance(refDistance);\n            sound.setRolloffFactor(rolloff);\n            sound.setVolume(volume);\n            sound.setLoop(loop);\n            holder.add(sound);\n\n            const sourceId = `sound-${++this._id}`;\n            this._activeSources.set(sourceId, { holder, sound });\n\n            const cleanup = () => {\n                try { sound.stop(); } catch (e) {}\n                if (holder.parent) holder.parent.remove(holder);\n                this._activeSources.delete(sourceId);\n                if (onEnd) onEnd();\n            };\n            sound.onEnded = cleanup;\n\n            try { sound.play(); } catch (e) {\n                console.warn('[AudioSystem] Failed to play sound:', e);\n                cleanup();\n                return null;\n            }\n\n            return {\n                stop: cleanup,\n                setVolume: (v) => sound.setVolume(v),\n                updatePosition: (pos) => holder.position.copy(pos)\n            };\n        } catch (error) {\n            console.error('[AudioSystem] Error playing sound:', error);\n            return null;\n        }\n    }\n\n    /**\n     * Trigger procedural 12kHz blip at position.\n     */\n    triggerBlip(position, intensity = 0.2) {\n        if (!this.isEnabled() || !this.listener || this._voices >= this._maxVoices) return;\n        if (!this._blipBuffers?.length) return;\n\n        const holder = new THREE.Object3D();\n        holder.position.copy(position);\n        if (this._scene) this._scene.add(holder);\n\n        const snd = new THREE.PositionalAudio(this.listener);\n        const buf = this._blipBuffers[(Math.random() * this._blipBuffers.length) | 0];\n        snd.setBuffer(buf);\n        snd.setRefDistance(this._spatialRefDistance);\n        snd.setRolloffFactor(this._spatialRolloff);\n        snd.setVolume(this._spatialVolume * intensity);\n\n        const rate = 0.985 + Math.random() * 0.03;\n        if (typeof snd.setPlaybackRate === 'function') {\n            snd.setPlaybackRate(rate);\n        } else {\n            snd.playbackRate = rate;\n        }\n\n        holder.add(snd);\n        this._voices++;\n\n        try { snd.play(); } catch (e) {\n            console.warn('[AudioSystem] Blip play failed:', e);\n        }\n\n        const ms = (this._blipDuration / rate) * 1000 + 60;\n        setTimeout(() => {\n            try { snd.stop(); } catch (e) {}\n            holder.remove(snd);\n            if (this._scene && holder.parent) this._scene.remove(holder);\n            this._voices = Math.max(0, this._voices - 1);\n        }, ms);\n    }\n\n    /**\n     * Trigger physics-based impact sound.\n     */\n    triggerImpact(position, params = {}) {\n        if (!this.isEnabled() || !this.listener || this._voices >= this._maxVoices) return;\n\n        const {\n            mass = 1.0, hardness = 0.5, velocity = 1.0,\n            intensity, frequency, roughness = 0.15, decay\n        } = params;\n\n        const duration = decay ?? this._impactDuration;\n        const buf = (mass !== undefined || hardness !== undefined || velocity !== undefined)\n            ? this._getPhysicalImpactBuffer({ mass, hardness, velocity, duration, roughness })\n            : this._getImpactBuffer(frequency ?? 120, roughness, duration);\n\n        const holder = new THREE.Object3D();\n        holder.position.copy(position);\n        if (this._scene) this._scene.add(holder);\n\n        const snd = new THREE.PositionalAudio(this.listener);\n        snd.setBuffer(buf);\n        snd.setRefDistance(this._spatialRefDistance * 0.85);\n        snd.setRolloffFactor(this._spatialRolloff * 0.9);\n\n        const gainMul = intensity !== undefined\n            ? THREE.MathUtils.clamp(intensity, 0.05, 4)\n            : THREE.MathUtils.clamp((velocity ?? 1.0) * 0.9 + 0.2, 0.05, 4);\n        snd.setVolume(this._impactVolume * gainMul);\n\n        holder.add(snd);\n        this._voices++;\n\n        try { snd.play(); } catch (e) {\n            console.warn('[AudioSystem] Impact play failed:', e);\n        }\n\n        const ms = duration * 1000 + 80;\n        setTimeout(() => {\n            try { snd.stop(); } catch (e) {}\n            holder.remove(snd);\n            if (this._scene && holder.parent) this._scene.remove(holder);\n            this._voices = Math.max(0, this._voices - 1);\n        }, ms);\n    }\n\n    /**\n     * Start ambient hum.\n     */\n    startAmbient(volume = this._humVolume, freq = this._humFreq) {\n        if (!this.isEnabled() || this._humNodes) return;\n        const ctx = this.listener?.context;\n        if (!ctx || !this._masterGain) return;\n\n        const osc1 = ctx.createOscillator();\n        const osc2 = ctx.createOscillator();\n        const gain = ctx.createGain();\n\n        osc1.type = 'sine';\n        osc2.type = 'sine';\n        osc1.frequency.value = freq;\n        osc2.frequency.value = freq * this._humDetune;\n\n        const lp = ctx.createBiquadFilter();\n        lp.type = 'lowpass';\n        lp.frequency.value = 240;\n\n        gain.gain.value = 0.0;\n        osc1.connect(gain);\n        osc2.connect(gain);\n        gain.connect(lp);\n        lp.connect(this._masterGain);\n\n        const now = ctx.currentTime;\n        const target = Math.max(0, volume);\n        gain.gain.cancelScheduledValues(now);\n        gain.gain.setValueAtTime(0.0, now);\n        gain.gain.linearRampToValueAtTime(target, now + this._humFade);\n\n        osc1.start();\n        osc2.start();\n        this._humNodes = { osc1, osc2, gain, lp };\n    }\n\n    /**\n     * Stop ambient hum.\n     */\n    stopAmbient() {\n        const n = this._humNodes;\n        if (!n) return;\n        const ctx = this.listener?.context;\n        if (!ctx) { this._humNodes = null; return; }\n\n        const now = ctx.currentTime;\n        n.gain.gain.cancelScheduledValues(now);\n        n.gain.gain.setValueAtTime(n.gain.gain.value, now);\n        n.gain.gain.linearRampToValueAtTime(0.0, now + this._humFade);\n\n        setTimeout(() => {\n            try { n.osc1.stop(); n.osc2.stop(); } catch (e) {}\n            [n.osc1, n.osc2, n.gain, n.lp].forEach(node => {\n                try { node.disconnect(); } catch (e) {}\n            });\n            this._humNodes = null;\n        }, (this._humFade * 1000) + 30);\n    }\n\n    /**\n     * Set master volume (0-1).\n     */\n    setMasterVolume(volume) {\n        const normalized = THREE.MathUtils.clamp(volume, 0, 1);\n        if (this._masterGain) this._masterGain.gain.value = normalized;\n        this.listener?.setMasterVolume?.(normalized);\n    }\n\n    setRoadSoundSources(roads) {\n        this._spatialAmbient?.setRoadSources(roads);\n    }\n\n    setHabitatSoundContext(context) {\n        this._spatialAmbient?.setHabitatContext(context);\n    }\n\n    updateSpatialAmbient(options = {}) {\n        this._spatialAmbient?.update({ ...options, active: !!options.active && this.isEnabled() });\n        this._updateAcousticHandles();\n    }\n\n    /** Occlusion / reflection probe for sources outside Web Audio (iframes). */\n    sampleAcousticPath(sourceWorldPos, listenerWorldPos, target = {}) {\n        return this._sampleAcousticPath ? this._sampleAcousticPath(sourceWorldPos, listenerWorldPos, target) : null;\n    }\n\n    _updateAcousticHandles() {\n        const now = performance.now();\n        if (now - (this._acousticTickAt || 0) < 120) return;\n        this._acousticTickAt = now;\n        for (const handle of this.handles.values()) handle.acoustic?.update();\n    }\n\n    updateWeather(state, active = true) {\n        this._rainAudio?.update(state, active && this.isEnabled());\n    }\n\n    suspendWeather() { this._rainAudio?.suspend(); }\n\n    // ── Enable / Disable / State ──────────────────────────────────────────\n\n    isEnabled() {\n        return this.enabled && this.started && !this._hardDisabled;\n    }\n\n    async setEnabled(enabled) {\n        const next = !!enabled;\n        this._hardDisabled = !next;\n\n        if (!next) {\n            this.enabled = false;\n            this.stopAmbient();\n            this._spatialAmbient?.setEnabled(false);\n            this._rainAudio?.setEnabled(false);\n\n            // Stop all streaming handles\n            for (const handle of this.handles.values()) {\n                handle.pendingStart = handle.sourceType !== 'pcm';\n                handle.started = false;\n                if (Array.isArray(handle.oscillators)) {\n                    for (const { osc, gain } of handle.oscillators) {\n                        osc?.stop();\n                        osc?.disconnect();\n                        gain?.disconnect();\n                    }\n                    handle.oscillators = null;\n                }\n                if (handle.audio?.isPlaying) {\n                    handle.audio.stop();\n                }\n                if (handle.pcmSources) {\n                    for (const source of handle.pcmSources) {\n                        try { source.stop(); } catch (error) {}\n                        try { source.disconnect(); } catch (error) {}\n                    }\n                    handle.pcmSources.clear();\n                }\n                handle.pcmQueue = [];\n                handle.pcmNextTime = 0;\n            }\n            return;\n        }\n\n        this.enabled = true;\n        this._spatialAmbient?.setEnabled(true);\n        this._rainAudio?.setEnabled(true);\n        try {\n            await this.resume();\n        } catch (error) {\n            this.eventBus?.emit('audio:error', { error, scope: 'audio-enable' });\n        }\n    }\n\n    async resume() {\n        const ctx = this.listener?.context;\n        if (!ctx) return false;\n        if (ctx.state !== 'running') {\n            await ctx.resume();\n        }\n        this.started = ctx.state === 'running';\n        if (this.started) {\n            this._autoEnableCleanup?.();\n            this._autoEnableCleanup = null;\n        }\n        if (!this.started || !this.enabled) return false;\n        for (const handle of this.handles.values()) {\n            if (handle.sourceType === 'pcm') {\n                this._flushPcmQueue(handle);\n            } else if (handle.pendingStart) {\n                this._startHandle(handle);\n            }\n        }\n        return true;\n    }\n\n    /**\n     * Resume scene audio from a trusted WebXR entry/controller gesture.\n     * Respect the user's explicit audio toggle; XR must never silently undo it.\n     */\n    async resumeForXR() {\n        if (this._hardDisabled || !this.enabled) return false;\n        return this.resume();\n    }\n\n    async start() {\n        return this.resume();\n    }\n\n    // ── Auto-Enable on User Interaction ───────────────────────────────────\n\n    _setupAutoEnable() {\n        const enableAudio = async () => {\n            if (this.started) return;\n            if (this._hardDisabled) return;\n            try {\n                const ctx = this.listener?.context;\n                if (ctx && ctx.state === 'suspended') {\n                    await ctx.resume();\n                }\n                this.started = !!(ctx && ctx.state === 'running');\n                if (this.started) {\n                    cleanup();\n                    // Resume pending handles\n                    this.resume().catch(() => {});\n                }\n            } catch (e) {\n                console.warn('[AudioSystem] Failed to auto-enable:', e);\n            }\n        };\n\n        const events = ['click', 'touchstart', 'touchend', 'keydown', 'pointerdown', 'mousedown'];\n        for (const ev of events) {\n            window.addEventListener(ev, enableAudio, { passive: true });\n        }\n\n        const cleanup = () => {\n            for (const ev of events) {\n                window.removeEventListener(ev, enableAudio);\n            }\n        };\n        this._autoEnableCleanup = cleanup;\n    }\n\n    // ── Internal: Attach / Handle Management ──────────────────────────────\n\n    _attach(meta, pcmStream, opts) {\n        if (!this.listener) return null;\n\n        const audio = meta.target\n            ? new THREE.PositionalAudio(this.listener)\n            : new THREE.Audio(this.listener);\n        this._applyPositionalDefaults(audio, opts);\n\n        if (meta.target) {\n            meta.target.add(audio);\n        }\n\n        const resolvedStream = pcmStream || opts?.pcmStream || opts?.stream || null;\n        const handleId = `audio-${++this._id}`;\n        const handle = {\n            id: handleId,\n            audio,\n            target: meta.target,\n            targetId: meta.targetId,\n            type: meta.type,\n            sourceType: this._resolveSourceType(resolvedStream, opts),\n            opts,\n            pcmStream: resolvedStream,\n            started: false,\n            pendingStart: true,\n            loading: false,\n            buffer: null,\n            oscillators: null,\n            gainNode: null,\n            pcmQueue: [],\n            pcmSources: null,\n            pcmNextTime: 0,\n            streamRelease: null,\n            active: true\n        };\n        this.handles.set(handleId, handle);\n\n        if (handle.sourceType === 'pcm') {\n            this._primePcm(handle);\n        } else if (handle.sourceType === 'buffer') {\n            this._primeBuffer(handle);\n        } else if (handle.sourceType === 'media-element') {\n            this._primeMediaElement(handle);\n        }\n        if (opts?.acoustics && handle.gainNode && audio.panner) {\n            handle.acoustic = createAcousticEmitter({\n                listener: this.listener,\n                audio,\n                source: handle.gainNode,\n                cone: opts.acoustics.cone || null,\n                reverb: opts.acoustics.reverb,\n                sampleAcousticPath: this._sampleAcousticPath,\n            });\n        }\n\n        if (this.started && this.enabled && handle.sourceType !== 'pcm') {\n            this._startHandle(handle);\n        }\n\n        return { handleId };\n    }\n\n    _resolveSourceType(pcmStream, opts) {\n        if (opts?.sourceType) return opts.sourceType;\n        if (pcmStream instanceof HTMLMediaElement) return 'media-element';\n        if (pcmStream) return 'pcm';\n        return (opts?.url || opts?.urls || opts?.buffer || opts?.audioBuffer) ? 'buffer' : 'oscillator';\n    }\n\n    _primePcm(handle) {\n        const ctx = this.listener?.context;\n        if (!ctx || !handle?.audio) return;\n        const opts = handle.opts || {};\n        const masterGain = ctx.createGain();\n        const volume = Number.isFinite(opts.gain) ? opts.gain : 0.4;\n        masterGain.gain.setValueAtTime(volume, ctx.currentTime);\n\n        if (typeof handle.audio.setNodeSource === 'function') {\n            handle.audio.setNodeSource(masterGain);\n        } else if (handle.audio.getOutput && typeof handle.audio.getOutput === 'function') {\n            masterGain.connect(handle.audio.getOutput());\n        }\n\n        handle.gainNode = masterGain;\n        handle.pcmSources = new Set();\n        handle.pcmQueue = [];\n        handle.pcmNextTime = 0;\n        handle.pendingStart = false;\n        handle.started = true;\n\n        if (handle.pcmStream && this.streamHub) {\n            const subscription = this.streamHub.register(\n                handle.pcmStream,\n                (payload) => this._onPcmPacket(handle, payload),\n                { bufferLimit: 0, dropWhenUnbound: true }\n            );\n            handle.streamRelease = subscription?.release || null;\n        }\n    }\n\n    _primeBuffer(handle) {\n        const opts = handle.opts || {};\n        const buffer = opts.buffer || opts.audioBuffer;\n        if (buffer) {\n            handle.buffer = buffer;\n            return;\n        }\n        const urls = Array.isArray(opts.urls)\n            ? opts.urls.filter(Boolean)\n            : (opts.url ? [opts.url] : []);\n        if (!urls.length || handle.loading) return;\n        handle.loading = true;\n        const loader = new THREE.AudioLoader();\n        const tryLoad = (index) => {\n            if (index >= urls.length) {\n                handle.loading = false;\n                this.eventBus?.emit('audio:error', {\n                    target: handle.targetId || handle.type,\n                    error: new Error('AudioLoader failed for all URLs')\n                });\n                return;\n            }\n            loader.load(\n                urls[index],\n                (loaded) => {\n                    handle.loading = false;\n                    handle.buffer = loaded;\n                    if (this.started) {\n                        this._startHandle(handle);\n                    }\n                },\n                undefined,\n                () => {\n                    tryLoad(index + 1);\n                }\n            );\n        };\n        tryLoad(0);\n    }\n\n    _primeMediaElement(handle) {\n        const ctx = this.listener?.context;\n        if (!ctx || !handle?.audio) return;\n        const mediaEl = handle.pcmStream;\n        if (!(mediaEl instanceof HTMLMediaElement)) return;\n\n        try {\n            const source = ctx.createMediaElementSource(mediaEl);\n            const opts = handle.opts || {};\n            const masterGain = ctx.createGain();\n            const volume = Number.isFinite(opts.gain) ? opts.gain : 0.9;\n            masterGain.gain.setValueAtTime(volume, ctx.currentTime);\n            source.connect(masterGain);\n\n            if (typeof handle.audio.setNodeSource === 'function') {\n                handle.audio.setNodeSource(masterGain);\n            } else if (handle.audio.getOutput && typeof handle.audio.getOutput === 'function') {\n                masterGain.connect(handle.audio.getOutput());\n            }\n\n            handle.gainNode = masterGain;\n            handle.mediaSource = source;\n            handle.pendingStart = false;\n            handle.started = true;\n        } catch (err) {\n            if (err.name === 'InvalidStateError') {\n                console.warn('[AudioSystem] Media element already has a source node, skipping');\n            } else {\n                console.error('[AudioSystem] Failed to create media element source:', err);\n            }\n        }\n    }\n\n    _startHandle(handle) {\n        if (!handle || !handle.audio) return;\n        if (!this.enabled) { handle.pendingStart = true; return; }\n        if (!this.started) { handle.pendingStart = true; return; }\n        if (handle.started) return;\n\n        if (handle.sourceType === 'pcm') {\n            handle.pendingStart = false;\n            handle.started = true;\n            return;\n        }\n\n        if (handle.sourceType === 'buffer') {\n            if (!handle.buffer) { handle.pendingStart = true; return; }\n            const opts = handle.opts || {};\n            handle.audio.setBuffer(handle.buffer);\n            handle.audio.setLoop(opts.loop !== undefined ? !!opts.loop : true);\n            if (typeof handle.audio.setVolume === 'function') {\n                handle.audio.setVolume(Number.isFinite(opts.gain) ? opts.gain : 0.1);\n            }\n            handle.audio.play();\n            handle.started = true;\n            handle.pendingStart = false;\n            return;\n        }\n\n        const ctx = this.listener?.context;\n        if (!ctx) return;\n        const opts = handle.opts || {};\n        const oscGain = ctx.createGain();\n        const volume = Number.isFinite(opts.gain) ? opts.gain : 0.1;\n        oscGain.gain.setValueAtTime(volume, ctx.currentTime);\n\n        const frequency = Number.isFinite(opts.frequency) ? opts.frequency : 220;\n        const harmonics = Array.isArray(opts.harmonics)\n            ? opts.harmonics.filter(Number.isFinite)\n            : (frequency < 80 ? [frequency * 2] : []);\n        const harmonicGain = Number.isFinite(opts.harmonicGain) ? opts.harmonicGain : 0.2;\n        const oscillators = [];\n\n        const addOscillator = (freq, gainValue) => {\n            const osc = ctx.createOscillator();\n            osc.type = opts.waveform || 'sine';\n            osc.frequency.setValueAtTime(freq, ctx.currentTime);\n            const gain = ctx.createGain();\n            gain.gain.setValueAtTime(gainValue, ctx.currentTime);\n            osc.connect(gain);\n            gain.connect(oscGain);\n            osc.start();\n            oscillators.push({ osc, gain });\n        };\n\n        addOscillator(frequency, 1.0);\n        for (const freq of harmonics) {\n            addOscillator(freq, harmonicGain);\n        }\n\n        if (typeof handle.audio.setNodeSource === 'function') {\n            handle.audio.setNodeSource(oscGain);\n        } else if (handle.audio.getOutput && typeof handle.audio.getOutput === 'function') {\n            oscGain.connect(handle.audio.getOutput());\n        }\n\n        if (typeof handle.audio.setVolume === 'function') {\n            handle.audio.setVolume(1.0);\n        }\n\n        handle.gainNode = oscGain;\n        handle.oscillators = oscillators;\n        handle.started = true;\n        handle.pendingStart = false;\n    }\n\n    _applyPositionalDefaults(audio, opts = {}) {\n        // three's PositionalAudio carries no isPositionalAudio flag: its panner marks it.\n        if (!audio?.panner) return;\n        if (audio.panner) {\n            audio.panner.panningModel = opts.panningModel || 'HRTF';\n        }\n        audio.setDistanceModel(opts.distanceModel || 'inverse');\n        audio.setRefDistance(Number.isFinite(opts.refDistance) ? opts.refDistance : 2000);\n        audio.setRolloffFactor(Number.isFinite(opts.rolloff) ? opts.rolloff : 1);\n        if (Number.isFinite(opts.maxDistance)) {\n            if (typeof audio.setMaxDistance === 'function') {\n                audio.setMaxDistance(opts.maxDistance);\n            } else if (audio.panner) {\n                audio.panner.maxDistance = opts.maxDistance;\n            }\n        }\n    }\n\n    _isContextRunning() {\n        const ctx = this.listener?.context;\n        return !!(ctx && ctx.state === 'running');\n    }\n\n    _canUseAudio(objectType, objectId) {\n        if (!this.accessController || !objectId) return true;\n        if (typeof this.accessController.canPerform === 'function') {\n            Promise.resolve(\n                this.accessController.canPerform(objectType, objectId, 'use_audio')\n            ).catch(() => undefined);\n        }\n        const hasCached = typeof this.accessController.hasCachedDecision === 'function'\n            ? this.accessController.hasCachedDecision(objectType, objectId, 'use_audio')\n            : false;\n        if (!hasCached) return true;\n        if (typeof this.accessController.canPerformSync === 'function') {\n            return !!this.accessController.canPerformSync(objectType, objectId, 'use_audio');\n        }\n        return true;\n    }\n\n    // ── Internal: PCM Packet Processing ───────────────────────────────────\n\n    _onPcmPacket(handle, packet) {\n        if (!handle || !handle.active || !this.enabled) return;\n        if (!this.listener?.context || !this.started) {\n            this._queuePcmPacket(handle, packet);\n            return;\n        }\n        this._playPcmPacket(handle, packet);\n    }\n\n    _queuePcmPacket(handle, packet) {\n        if (!handle || !Array.isArray(handle.pcmQueue)) return;\n        const maxQueue = Number.isFinite(handle.opts?.maxQueue) ? handle.opts.maxQueue : 24;\n        handle.pcmQueue.push(packet);\n        while (handle.pcmQueue.length > maxQueue) {\n            handle.pcmQueue.shift();\n        }\n    }\n\n    _flushPcmQueue(handle) {\n        if (!handle || !Array.isArray(handle.pcmQueue) || !handle.pcmQueue.length) return;\n        const queued = handle.pcmQueue.slice();\n        handle.pcmQueue.length = 0;\n        for (const packet of queued) {\n            this._playPcmPacket(handle, packet);\n        }\n    }\n\n    _playPcmPacket(handle, packet) {\n        const ctx = this.listener?.context;\n        if (!ctx || !handle?.audio || !handle?.gainNode) return;\n        const buffer = this._pcmPacketToBuffer(packet, ctx);\n        if (!buffer) return;\n\n        const source = ctx.createBufferSource();\n        source.buffer = buffer;\n        source.connect(handle.gainNode);\n\n        const now = ctx.currentTime;\n        if (!Number.isFinite(handle.pcmNextTime) || handle.pcmNextTime < now - 0.05) {\n            handle.pcmNextTime = now;\n        }\n\n        const startTime = Math.max(now, handle.pcmNextTime);\n        source.start(startTime);\n        handle.pcmNextTime = startTime + buffer.duration;\n\n        handle.pcmSources?.add(source);\n        source.onended = () => {\n            handle.pcmSources?.delete(source);\n        };\n    }\n\n    _pcmPacketToBuffer(packet, ctx) {\n        if (!packet || !ctx) return null;\n        const format = packet.format || packet.encoding || 'pcm16';\n        const sampleRate = Number.isFinite(packet.sampleRate) ? packet.sampleRate : ctx.sampleRate;\n        const channels = Number.isFinite(packet.channels) ? packet.channels : 1;\n        const raw = packet.data;\n        if (!raw) return null;\n\n        let floatArray = null;\n\n        if (format === 'float32') {\n            if (raw instanceof Float32Array) {\n                floatArray = raw;\n            } else if (ArrayBuffer.isView(raw)) {\n                floatArray = new Float32Array(raw.buffer, raw.byteOffset, raw.byteLength / 4);\n            } else if (raw instanceof ArrayBuffer) {\n                floatArray = new Float32Array(raw);\n            } else if (Array.isArray(raw)) {\n                floatArray = Float32Array.from(raw);\n            }\n        } else {\n            let int16Array = null;\n            if (raw instanceof Int16Array) {\n                int16Array = raw;\n            } else if (ArrayBuffer.isView(raw)) {\n                int16Array = new Int16Array(raw.buffer, raw.byteOffset, raw.byteLength / 2);\n            } else if (raw instanceof ArrayBuffer) {\n                int16Array = new Int16Array(raw);\n            } else if (Array.isArray(raw)) {\n                int16Array = Int16Array.from(raw);\n            }\n            if (!int16Array) return null;\n            floatArray = new Float32Array(int16Array.length);\n            for (let i = 0; i < int16Array.length; i++) {\n                floatArray[i] = int16Array[i] / 32768.0;\n            }\n        }\n\n        if (!floatArray || floatArray.length === 0) return null;\n        const frameCount = Math.floor(floatArray.length / channels);\n        if (frameCount <= 0) return null;\n\n        const audioBuffer = ctx.createBuffer(channels, frameCount, sampleRate);\n        for (let channel = 0; channel < channels; channel++) {\n            const channelData = audioBuffer.getChannelData(channel);\n            for (let i = 0; i < frameCount; i++) {\n                channelData[i] = floatArray[i * channels + channel];\n            }\n        }\n        return audioBuffer;\n    }\n\n    // ── Internal: Audio Buffer Loading ────────────────────────────────────\n\n    async _loadAudioBuffer(url) {\n        if (this._audioBufferCache.has(url)) {\n            return this._audioBufferCache.get(url);\n        }\n        return new Promise((resolve, reject) => {\n            this._audioLoader.load(\n                url,\n                (buffer) => {\n                    this._audioBufferCache.set(url, buffer);\n                    resolve(buffer);\n                },\n                undefined,\n                (error) => {\n                    console.error('[AudioSystem] Failed to load audio:', url, error);\n                    reject(error);\n                }\n            );\n        });\n    }\n\n    // ── Internal: Procedural Synthesis ────────────────────────────────────\n\n    _makeBlipBuffers(n) {\n        const ctx = this.listener?.context;\n        if (!ctx) return [];\n        const out = [];\n        for (let k = 0; k < n; k++) {\n            const sr = ctx.sampleRate;\n            const len = Math.max(1, Math.floor(sr * this._blipDuration));\n            const buf = ctx.createBuffer(1, len, sr);\n            const data = buf.getChannelData(0);\n\n            const f0 = this._blipFreq * (0.995 + Math.random() * 0.01);\n            const amHz = 12 + Math.random() * 20;\n            const twoPI = 2 * Math.PI;\n\n            for (let i = 0; i < len; i++) {\n                const t = i / sr;\n                const x = i / (len - 1);\n                const env = Math.sin(Math.PI * x) ** 1.0;\n                const am = 0.85 + 0.15 * Math.sin(twoPI * amHz * t);\n                data[i] = Math.sin(twoPI * f0 * t) * env * am;\n            }\n            out.push(buf);\n        }\n        return out;\n    }\n\n    _getPhysicalImpactBuffer({ mass = 1.0, hardness = 0.5, velocity = 1.0, duration = this._impactDuration, roughness = 0.15 } = {}) {\n        const key = `phys:${mass.toFixed(2)}:${hardness.toFixed(2)}:${velocity.toFixed(2)}:${duration.toFixed(2)}:${roughness.toFixed(2)}`;\n        if (this._impactBufferCache.has(key)) {\n            return this._impactBufferCache.get(key);\n        }\n\n        const ctx = this.listener?.context;\n        if (!ctx) return null;\n        const sr = ctx.sampleRate;\n        const len = Math.max(1, Math.floor(sr * duration));\n        const buffer = ctx.createBuffer(1, len, sr);\n        const data = buffer.getChannelData(0);\n\n        const stiffness = THREE.MathUtils.clamp(hardness, 0, 1);\n        const baseF = 90 + 310 * stiffness;\n        const velBoost = 1 + 0.25 * THREE.MathUtils.clamp(velocity, 0, 4);\n        const f1 = baseF * velBoost;\n\n        const baseTau = 0.06 + 0.24 * (mass / (mass + 1)) * (0.25 + 0.75 * (1 - stiffness));\n        const tau1 = baseTau;\n        const tau2 = baseTau * 0.7;\n        const tau3 = baseTau * 0.45;\n\n        const modes = [\n            { f: f1, a: 1.00, tau: tau1 },\n            { f: f1 * 1.5, a: 0.55, tau: tau2 },\n            { f: f1 * 2.2, a: 0.35, tau: tau3 }\n        ];\n\n        const contactLen = Math.min(len, Math.floor(0.008 * sr));\n        const twoPI = 2 * Math.PI;\n\n        let phases = modes.map(() => Math.random() * twoPI);\n        for (let i = 0; i < len; i++) {\n            const t = i / sr;\n            const x = i / (len - 1);\n\n            const attack = Math.min(1, x * 60);\n            const release = (1 - x) ** 2.6;\n            let sum = 0.0;\n\n            for (let m = 0; m < modes.length; m++) {\n                const { f, a, tau } = modes[m];\n                phases[m] += twoPI * f / sr;\n                const env = Math.exp(-t / tau);\n                sum += Math.sin(phases[m]) * a * env;\n            }\n\n            let contact = 0;\n            if (i < contactLen) {\n                const w = Math.sin(Math.PI * (i / (contactLen - 1)));\n                const white = (Math.random() * 2 - 1);\n                contact = white * w * (0.25 + 0.75 * stiffness);\n            }\n\n            const micro = (Math.random() * 2 - 1) * THREE.MathUtils.clamp(roughness, 0, 1) * 0.15;\n            data[i] = (sum + contact + micro) * attack * release;\n        }\n\n        let max = 0;\n        for (let i = 0; i < len; i++) {\n            max = Math.max(max, Math.abs(data[i]));\n        }\n        const norm = max > 0 ? 1 / (max * 1.05) : 1;\n        if (norm !== 1) {\n            for (let i = 0; i < len; i++) {\n                data[i] *= norm;\n            }\n        }\n\n        this._impactBufferCache.set(key, buffer);\n        return buffer;\n    }\n\n    _getImpactBuffer(frequency = 120, roughness = 0.2, duration = this._impactDuration) {\n        const hardness = THREE.MathUtils.clamp((frequency - 90) / 310, 0, 1);\n        return this._getPhysicalImpactBuffer({ mass: 1.0, hardness, velocity: 1.0, duration, roughness });\n    }\n}\n","/**\n * WindAudio\n *\n * Purpose:\n * - Procedural wind sound synthesizer using Web Audio nodes.\n * - Measured geographic wind plus Earth-fixed observer travel; world-space\n *   upwind anchor during surface mode.\n */\n\nimport * as THREE from 'three';\n\nconst MPH_PER_MPS = 2.23694;\nconst DEFAULT_MAX_MPH = 160;\nconst DEFAULT_MAX_MPS = DEFAULT_MAX_MPH / MPH_PER_MPS;\n\nconst clamp = (value, min, max) => Math.max(min, Math.min(max, value));\nconst lerp = (a, b, t) => a + (b - a) * t;\n\nconst setTarget = (param, value, now, t = 0.08) => {\n    try {\n        param.cancelScheduledValues(now);\n        param.setTargetAtTime(value, now, t);\n    } catch {\n        param.value = value;\n    }\n};\n\nconst makeCurve = (fn, n = 2048) => {\n    const curve = new Float32Array(n);\n    for (let i = 0; i < n; i += 1) {\n        const x = (i / (n - 1)) * 2 - 1;\n        curve[i] = fn(x);\n    }\n    return curve;\n};\n\nconst noiseWorklets = new WeakMap();\nconst ensureNoiseWorklet = async (context) => {\n    if (!context?.audioWorklet) return;\n    if (noiseWorklets.has(context)) return noiseWorklets.get(context);\n    const workletCode = `\n        class WhiteNoiseProcessor extends AudioWorkletProcessor {\n            process(inputs, outputs) {\n                const out = outputs[0];\n                for (let ch = 0; ch < out.length; ch += 1) {\n                    const buf = out[ch];\n                    for (let i = 0; i < buf.length; i += 1) {\n                        buf[i] = (Math.random() * 2 - 1);\n                    }\n                }\n                return true;\n            }\n        }\n        class BrownNoiseProcessor extends AudioWorkletProcessor {\n            constructor() {\n                super();\n                this._last = 0;\n            }\n            process(inputs, outputs) {\n                const out = outputs[0];\n                for (let ch = 0; ch < out.length; ch += 1) {\n                    const buf = out[ch];\n                    let last = this._last;\n                    for (let i = 0; i < buf.length; i += 1) {\n                        const white = Math.random() * 2 - 1;\n                        last = (last + (0.02 * white)) * 0.995;\n                        buf[i] = last * 3.5;\n                    }\n                    this._last = last;\n                }\n                return true;\n            }\n        }\n        registerProcessor('white-noise', WhiteNoiseProcessor);\n        registerProcessor('brown-noise', BrownNoiseProcessor);\n    `;\n    const blob = new Blob([workletCode], { type: 'application/javascript' });\n    const url = URL.createObjectURL(blob);\n    const loading = context.audioWorklet.addModule(url).finally(() => URL.revokeObjectURL(url));\n    noiseWorklets.set(context, loading);\n    try { await loading; } catch (error) { noiseWorklets.delete(context); throw error; }\n};\n\nconst createNoiseNode = async (context) => {\n    if (context.audioWorklet) {\n        await ensureNoiseWorklet(context);\n        return new AudioWorkletNode(context, 'white-noise', {\n            numberOfOutputs: 1,\n            outputChannelCount: [1]\n        });\n    }\n\n    const sp = context.createScriptProcessor(2048, 0, 1);\n    sp.onaudioprocess = (e) => {\n        const out = e.outputBuffer.getChannelData(0);\n        for (let i = 0; i < out.length; i += 1) {\n            out[i] = (Math.random() * 2 - 1);\n        }\n    };\n    return sp;\n};\n\nconst createBrownNoiseNode = async (context) => {\n    if (context.audioWorklet) {\n        await ensureNoiseWorklet(context);\n        return new AudioWorkletNode(context, 'brown-noise', {\n            numberOfOutputs: 1,\n            outputChannelCount: [1]\n        });\n    }\n    const sp = context.createScriptProcessor(2048, 0, 1);\n    let last = 0;\n    sp.onaudioprocess = (e) => {\n        const out = e.outputBuffer.getChannelData(0);\n        for (let i = 0; i < out.length; i += 1) {\n            const white = Math.random() * 2 - 1;\n            last = (last + (0.02 * white)) * 0.995;\n            out[i] = last * 3.5;\n        }\n    };\n    return sp;\n};\n\nconst createWindEngine = async (ctx) => {\n    const noiseMain = await createNoiseNode(ctx);\n    const noiseGust = await createNoiseNode(ctx);\n    const noiseTurb = await createNoiseNode(ctx);\n    const noiseBrown = await createBrownNoiseNode(ctx);\n\n    const lowLP = ctx.createBiquadFilter();\n    lowLP.type = 'lowpass';\n    lowLP.frequency.value = 220;\n    lowLP.Q.value = 0.4;\n\n    const midBP = ctx.createBiquadFilter();\n    midBP.type = 'bandpass';\n    midBP.frequency.value = 900;\n    midBP.Q.value = 0.7;\n\n    const highHP = ctx.createBiquadFilter();\n    highHP.type = 'highpass';\n    highHP.frequency.value = 1600;\n    highHP.Q.value = 0.6;\n\n    const hissBP = ctx.createBiquadFilter();\n    hissBP.type = 'bandpass';\n    hissBP.frequency.value = 5000;\n    hissBP.Q.value = 0.9;\n\n    const lowGain = ctx.createGain();\n    const midGain = ctx.createGain();\n    const highGain = ctx.createGain();\n    const hissGain = ctx.createGain();\n\n    lowGain.gain.value = 0;\n    midGain.gain.value = 0;\n    highGain.gain.value = 0;\n    hissGain.gain.value = 0;\n\n    const whistleBP = ctx.createBiquadFilter();\n    whistleBP.type = 'bandpass';\n    whistleBP.frequency.value = 1200;\n    whistleBP.Q.value = 8;\n\n    const whistlePre = ctx.createBiquadFilter();\n    whistlePre.type = 'highpass';\n    whistlePre.frequency.value = 600;\n    whistlePre.Q.value = 0.7;\n\n    const whistleGain = ctx.createGain();\n    whistleGain.gain.value = 0;\n\n    const brownHP = ctx.createBiquadFilter();\n    brownHP.type = 'highpass';\n    brownHP.frequency.value = 18;\n    brownHP.Q.value = 0.7;\n\n    const brownLP = ctx.createBiquadFilter();\n    brownLP.type = 'lowpass';\n    brownLP.frequency.value = 140;\n    brownLP.Q.value = 0.7;\n\n    const brownBP = ctx.createBiquadFilter();\n    brownBP.type = 'bandpass';\n    brownBP.frequency.value = 70;\n    brownBP.Q.value = 0.95;\n\n    const brownGain = ctx.createGain();\n    brownGain.gain.value = 0;\n\n    const buffetGain = ctx.createGain();\n    buffetGain.gain.value = 0;\n\n    const mix = ctx.createGain();\n    mix.gain.value = 1;\n\n    const sat = ctx.createWaveShaper();\n    sat.curve = makeCurve((x) => Math.tanh(1.6 * x), 4096);\n    sat.oversample = '4x';\n\n    const baseGain = ctx.createGain();\n    baseGain.gain.value = 0;\n\n    const gustGain = ctx.createGain();\n    gustGain.gain.value = 1;\n\n    const comp = ctx.createDynamicsCompressor();\n    comp.threshold.value = -18;\n    comp.knee.value = 22;\n    comp.ratio.value = 6;\n    comp.attack.value = 0.003;\n    comp.release.value = 0.12;\n\n    const master = ctx.createGain();\n    master.gain.value = 0.7;\n\n    const gustLP = ctx.createBiquadFilter();\n    gustLP.type = 'lowpass';\n    gustLP.frequency.value = 0.7;\n    gustLP.Q.value = 0.7;\n\n    const gustPre = ctx.createGain();\n    gustPre.gain.value = 2.6;\n\n    const gustShape = ctx.createWaveShaper();\n    gustShape.curve = makeCurve((x) => {\n        const u = clamp((x + 1) * 0.5, 0, 1);\n        return Math.pow(u, 2.8);\n    }, 4096);\n\n    const gustDepth = ctx.createGain();\n    gustDepth.gain.value = 0.55;\n\n    const one = ctx.createConstantSource();\n    one.offset.value = 1;\n    one.start();\n\n    const turbLP = ctx.createBiquadFilter();\n    turbLP.type = 'lowpass';\n    turbLP.frequency.value = 24;\n    turbLP.Q.value = 0.6;\n\n    const turbToHiss = ctx.createGain();\n    const turbToWhistle = ctx.createGain();\n    const turbToBaseGain = ctx.createGain();\n    turbToHiss.gain.value = 350;\n    turbToWhistle.gain.value = 520;\n    turbToBaseGain.gain.value = 0.1;\n\n    noiseMain.connect(lowLP);\n    lowLP.connect(lowGain).connect(mix);\n\n    noiseMain.connect(midBP);\n    midBP.connect(midGain).connect(mix);\n\n    noiseMain.connect(highHP);\n    highHP.connect(highGain).connect(mix);\n    highHP.connect(hissBP);\n    hissBP.connect(hissGain).connect(mix);\n\n    noiseMain.connect(whistlePre);\n    whistlePre.connect(whistleBP);\n    whistleBP.connect(whistleGain).connect(mix);\n\n    noiseBrown.connect(brownHP);\n    brownHP.connect(brownLP);\n    brownLP.connect(brownGain).connect(mix);\n    brownHP.connect(brownBP);\n    brownBP.connect(buffetGain).connect(mix);\n\n    mix.connect(sat);\n    sat.connect(baseGain);\n    baseGain.connect(gustGain);\n    gustGain.connect(comp);\n    comp.connect(master);\n\n    noiseGust.connect(gustLP);\n    gustLP.connect(gustPre);\n    gustPre.connect(gustShape);\n    gustShape.connect(gustDepth);\n    one.connect(gustGain.gain);\n    gustDepth.connect(gustGain.gain);\n\n    noiseTurb.connect(turbLP);\n    turbLP.connect(turbToHiss);\n    turbLP.connect(turbToWhistle);\n    turbLP.connect(turbToBaseGain);\n\n    turbToHiss.connect(hissBP.frequency);\n    turbToWhistle.connect(whistleBP.frequency);\n    turbToBaseGain.connect(baseGain.gain);\n\n    const update = (speedMph, dirDeg, gustiness01, brown01, volume01) => {\n        const now = ctx.currentTime;\n        const speedMps = speedMph / MPH_PER_MPS;\n        const intensity = 1 - Math.exp(-speedMps / 12);\n\n        const rad = (dirDeg * Math.PI) / 180;\n        const frontFactor = clamp((1 + Math.cos(rad)) * 0.5, 0, 1);\n        const crossFactor = Math.abs(Math.sin(rad));\n        const dirLoud = lerp(0.52, 1.0, frontFactor);\n\n        const base = (intensity * dirLoud) * 0.95;\n        const low = base * lerp(0.55, 0.95, intensity);\n        const mid = base * lerp(0.35, 0.9, intensity);\n        const high = base * lerp(0.1, 0.95, intensity) * lerp(0.65, 1.0, frontFactor);\n        const hiss = base * lerp(0.06, 0.65, intensity) * lerp(0.6, 1.05, frontFactor);\n        const whistle = base * (0.1 + 1.25 * intensity) * (0.25 + 0.95 * crossFactor);\n\n        const lowHz = lerp(120, 520, intensity);\n        const midHz = lerp(520, 1200, intensity);\n        const highHz = lerp(850, 2400, intensity);\n        const hissHz = lerp(3200, 7600, intensity);\n\n        const whistleHz = (700 + 2400 * crossFactor + 900 * intensity * crossFactor) * lerp(0.92, 1.0, frontFactor);\n        const whistleQ = lerp(5, 22, intensity) * lerp(0.8, 1.15, crossFactor);\n\n        const gustDepthVal = (0.12 + 0.75 * intensity) * gustiness01;\n\n        turbToHiss.gain.value = lerp(120, 520, intensity);\n        turbToWhistle.gain.value = lerp(140, 820, intensity);\n        turbToBaseGain.gain.value = lerp(0.02, 0.12, intensity) * lerp(0.75, 1.0, frontFactor);\n\n        const brownDir = lerp(0.78, 1.05, frontFactor) * lerp(0.92, 1.15, crossFactor);\n        const brownCtl = (0.25 + 0.75 * brown01);\n        const brownLevel = base * lerp(0.12, 0.55, intensity) * brownCtl * brownDir;\n        const buffetLevel = base * lerp(0.05, 0.80, intensity) * gustiness01 * brownCtl * lerp(0.9, 1.25, crossFactor);\n        const brownHz = lerp(70, 240, intensity);\n        const buffetHz = lerp(45, 120, intensity);\n\n        const t = 0.07;\n        setTarget(lowGain.gain, low, now, t);\n        setTarget(midGain.gain, mid, now, t);\n        setTarget(highGain.gain, high, now, t);\n        setTarget(hissGain.gain, hiss, now, t);\n        setTarget(whistleGain.gain, whistle, now, t);\n\n        setTarget(lowLP.frequency, lowHz, now, t);\n        setTarget(midBP.frequency, midHz, now, t);\n        setTarget(highHP.frequency, highHz, now, t);\n        setTarget(hissBP.frequency, hissHz, now, t);\n\n        setTarget(whistleBP.frequency, whistleHz, now, t);\n        setTarget(whistleBP.Q, whistleQ, now, t);\n        setTarget(baseGain.gain, base, now, 0.08);\n        setTarget(gustDepth.gain, gustDepthVal, now, 0.2);\n\n        setTarget(brownLP.frequency, brownHz, now, 0.1);\n        setTarget(brownBP.frequency, buffetHz, now, 0.1);\n        setTarget(brownGain.gain, brownLevel, now, 0.12);\n        setTarget(buffetGain.gain, buffetLevel, now, 0.14);\n\n        setTarget(master.gain, volume01, now, 0.12);\n    };\n\n    const dispose = () => {\n        try { noiseMain.disconnect(); } catch {}\n        try { noiseGust.disconnect(); } catch {}\n        try { noiseTurb.disconnect(); } catch {}\n        try { noiseBrown.disconnect(); } catch {}\n        try { master.disconnect(); } catch {}\n        try { one.stop(); } catch {}\n    };\n\n    return { update, dispose, output: master };\n};\n\nexport class WindAudio {\n    constructor({ listener = null, eventBus = null, camera = null, parentGroup = null } = {}) {\n        this.listener = listener || null;\n        this.eventBus = eventBus || null;\n        this.camera = camera || null;\n        this.parentGroup = parentGroup || null;\n        this.enabled = true;\n        this.active = true;\n        this.settings = {\n            volume: 0.2,\n            gustiness: 0.55,\n            mass: 0.6,\n            speedScale: 1,\n            maxSpeedMps: DEFAULT_MAX_MPS,\n            minSpeedMps: 0,\n            verticalScale: 1\n        };\n        this._ctx = null;\n        this._engine = null;\n        this._ready = false;\n        this._loading = false;\n        this._anchor = null;\n        this._audio = null;\n        this._worldPosition = new THREE.Vector3();\n        this._localDirection = new THREE.Vector3();\n        this._worldQuaternion = new THREE.Quaternion();\n        this._pending = { speedMps: 0, dirDeg: 0, mass: 0.6, gustiness: null };\n        this._worldDirection = new THREE.Vector3();\n        this._hasWorldDirection = false;\n        this._disposed = false;\n    }\n\n    setListener(listener) {\n        this.listener = listener || null;\n        this._ctx = listener?.context || null;\n    }\n\n    setEnabled(enabled) {\n        this.enabled = !!enabled;\n        if (!this.enabled) this._applyParams(0, this._pending.dirDeg);\n    }\n\n    setActive(active) {\n        this.active = !!active;\n        if (!this.active && this._engine) {\n            this._applyParams(0, this._pending?.dirDeg ?? 0);\n        }\n    }\n\n    applySettings(next = {}) {\n        this.settings = { ...this.settings, ...next };\n    }\n\n    async _ensureReady() {\n        if (this._ready || this._loading || this._disposed) return;\n        const ctx = this.listener?.context || this._ctx;\n        if (!ctx || ctx.state !== 'running') return;\n        this._loading = true;\n        try {\n            const engine = await createWindEngine(ctx);\n            if (this._disposed || !this.enabled || !this.active) {\n                engine.dispose(); this._loading = false; return;\n            }\n            this._engine = engine;\n            this._anchor = new THREE.Object3D();\n            this._anchor.name = 'WeatherWindSound:UpwindField';\n            this._audio = new THREE.PositionalAudio(this.listener);\n            this._audio.setDistanceModel('inverse');\n            this._audio.setRefDistance(34);\n            this._audio.setRolloffFactor(0.12);\n            this._audio.setMaxDistance(180);\n            this._audio.panner.panningModel = 'HRTF';\n            this._audio.setNodeSource(this._engine.output);\n            this._anchor.add(this._audio);\n            (this.parentGroup || this.camera?.parent)?.add?.(this._anchor);\n            this._ctx = ctx;\n            this._ready = true;\n            this._loading = false;\n            this._applyPending();\n        } catch (error) {\n            this._loading = false;\n            this.eventBus?.emit?.('audio:error', { error, scope: 'wind-audio' });\n        }\n    }\n\n    _applyPending() {\n        if (!this._engine) return;\n        const { speedMps, dirDeg, mass, gustiness } = this._pending;\n        this._updateSpatialAnchor(dirDeg);\n        this._applyParams(speedMps, dirDeg, mass, gustiness);\n    }\n\n    _updateSpatialAnchor(dirDeg) {\n        if (!this._anchor || !this.camera || !this.parentGroup) return;\n        this.camera.getWorldPosition(this._worldPosition);\n        this.camera.getWorldQuaternion(this._worldQuaternion);\n        if (this._hasWorldDirection) this._localDirection.copy(this._worldDirection);\n        else {\n            const radians = (Number(dirDeg) || 0) * Math.PI / 180;\n            this._localDirection.set(Math.sin(radians), 0, -Math.cos(radians))\n                .applyQuaternion(this._worldQuaternion).normalize();\n        }\n        this._worldPosition.addScaledVector(this._localDirection, 32);\n        this.parentGroup.worldToLocal(this._worldPosition);\n        this._anchor.position.copy(this._worldPosition);\n    }\n\n    _applyParams(speedMps, dirDeg, mass, gustinessOverride = null) {\n        if (!this._engine) return;\n        const settings = this.settings || {};\n        const enabled = this.enabled && this.active;\n        const speedScale = Number.isFinite(settings.speedScale) ? settings.speedScale : 1;\n        const maxSpeed = Number.isFinite(settings.maxSpeedMps) ? settings.maxSpeedMps : DEFAULT_MAX_MPS;\n        const minSpeed = Number.isFinite(settings.minSpeedMps) ? settings.minSpeedMps : 0;\n        const gustiness = Number.isFinite(gustinessOverride)\n            ? gustinessOverride\n            : (Number.isFinite(settings.gustiness) ? settings.gustiness : 0.55);\n        const massBed = Number.isFinite(mass)\n            ? mass\n            : (Number.isFinite(settings.mass) ? settings.mass : 0.6);\n        const volume = Number.isFinite(settings.volume) ? settings.volume : 0.2;\n\n        let speed = Number.isFinite(speedMps) ? speedMps * speedScale : 0;\n        speed = speed > 0 ? clamp(speed, minSpeed, maxSpeed) : 0;\n        const mph = speed * MPH_PER_MPS;\n        const vol = enabled && speedMps > 0 ? volume : 0;\n        this._engine.update(\n            mph,\n            dirDeg,\n            clamp(gustiness, 0, 1),\n            clamp(massBed, 0, 1),\n            clamp(vol, 0, 1)\n        );\n    }\n\n    update(speedMps, dirDeg = 0, mass = null, modulation = null) {\n        this._pending.speedMps = Number.isFinite(speedMps) ? speedMps : 0;\n        this._pending.dirDeg = dirDeg;\n        this._pending.mass = Number.isFinite(mass) ? mass : null;\n        this._pending.gustiness = Number.isFinite(modulation?.gustiness) ? modulation.gustiness : null;\n        this._hasWorldDirection = modulation?.worldDirection?.isVector3 === true;\n        if (this._hasWorldDirection) this._worldDirection.copy(modulation.worldDirection);\n        this._updateSpatialAnchor(dirDeg);\n        if (this._disposed || !this.enabled || !this.active) return;\n        if (!this._engine) {\n            if (this._pending.speedMps > 0) this._ensureReady();\n            return;\n        }\n        this._applyPending();\n    }\n\n    dispose() {\n        this._disposed = true;\n        if (this._engine?.dispose) {\n            this._engine.dispose();\n        }\n        this._engine = null;\n        try { this._audio?.disconnect?.(); } catch {}\n        this._anchor?.removeFromParent?.();\n        this._audio = null;\n        this._anchor = null;\n        this._ready = false;\n        this._loading = false;\n    }\n}\n","import * as THREE from 'three';\n\n/** Small, GPU-only view of native terrain. No readback, copied scene, or collision ray loop. */\nexport class RainSurfaceAtlas {\n    constructor(renderer, { mobile = false, span = 64 } = {}) {\n        this.renderer = renderer;\n        this.span = span;\n        this.top = 96;\n        this.depth = 224;\n        this.camera = new THREE.OrthographicCamera(-span / 2, span / 2, span / 2, -span / 2, 0.1, this.depth);\n        this.camera.layers.enableAll();\n        this.center = new THREE.Vector3(Infinity, Infinity, Infinity);\n        this.up = new THREE.Vector3();\n        this._targetPoint = new THREE.Vector3();\n        this._color = new THREE.Color();\n        this._viewport = new THREE.Vector4();\n        this._scissor = new THREE.Vector4();\n        this._elapsed = Infinity;\n        this.valid = false;\n        const size = mobile ? 128 : 256;\n        this.target = new THREE.WebGLRenderTarget(size, size, { depthBuffer: true, stencilBuffer: false,\n            minFilter: THREE.NearestFilter, magFilter: THREE.NearestFilter, generateMipmaps: false });\n        this.target.depthTexture = new THREE.DepthTexture(size, size, THREE.UnsignedIntType);\n        this.target.texture.name = 'Rain:NativeSurfaceAtlas';\n        this.target.depthTexture.name = 'Rain:NativeSurfaceDepth';\n    }\n\n    update(dt, position, up, south, terrain) {\n        this._elapsed += dt;\n        if (!terrain?.visible) { this.valid = false; return; }\n        const moved = this.center.distanceToSquared(position) > 36 || this.up.dot(up) < 0.999999;\n        if (this.valid && this._elapsed < (moved ? 0.25 : 0.5)) return;\n        const renderer = this.renderer;\n        if (renderer.getContext().isContextLost()) { this.valid = false; return; }\n        this.center.copy(position);\n        this.up.copy(up);\n        this.camera.position.copy(position).addScaledVector(up, this.top);\n        this.camera.up.copy(south).negate();\n        this._targetPoint.copy(position).addScaledVector(up, -1);\n        this.camera.lookAt(this._targetPoint);\n        this.camera.updateMatrixWorld();\n        // Save the complete caller framebuffer state, including stereo substitution.\n        const target = renderer.getRenderTarget(), face = renderer.getActiveCubeFace(), level = renderer.getActiveMipmapLevel();\n        const autoClear = renderer.autoClear, xr = renderer.xr.enabled, shadows = renderer.shadowMap.autoUpdate;\n        const infoReset = renderer.info.autoReset, scissorTest = renderer.getScissorTest();\n        const alpha = renderer.getClearAlpha();\n        renderer.getClearColor(this._color);\n        renderer.getViewport(this._viewport); renderer.getScissor(this._scissor);\n        this.valid = false;\n        try {\n            renderer.xr.enabled = false;\n            renderer.shadowMap.autoUpdate = false;\n            renderer.info.autoReset = false;\n            renderer.autoClear = false;\n            renderer.setRenderTarget(this.target);\n            renderer.setScissorTest(false);\n            renderer.setClearColor(0, 0);\n            renderer.clear(true, true, true);\n            // Rendering the existing root retains native materials, alpha tests,\n            // transforms, fade visibility and geometry ownership.\n            terrain.updateWorldMatrix(true, false);\n            renderer.render(terrain, this.camera);\n            this.valid = true;\n            this._elapsed = 0;\n        } finally {\n            renderer.setRenderTarget(target, face, level);\n            renderer.setClearColor(this._color, alpha);\n            renderer.setViewport(this._viewport); renderer.setScissor(this._scissor);\n            renderer.setScissorTest(scissorTest);\n            renderer.autoClear = autoClear;\n            renderer.xr.enabled = xr;\n            renderer.shadowMap.autoUpdate = shadows;\n            renderer.info.autoReset = infoReset;\n        }\n    }\n\n    invalidate() { this.valid = false; this._elapsed = Infinity; }\n    dispose() { this.valid = false; this.target.dispose(); }\n}\n","// A finite camera-following residency window over an Earth-fixed particle field.\n// Seeds and motion are independent of yaw, pitch, FOV and observer velocity.\nexport const PRECIPITATION_SPAN_M = 96;\nexport const PRECIPITATION_HEIGHT_M = 64;\n\nfunction radicalInverse(index, base) {\n    let value = 0, weight = 1 / base;\n    while (index > 0) { value += (index % base) * weight;index = Math.floor(index / base);weight /= base; }\n    return value;\n}\n\n/** Every prefix covers the volume: increasing intensity cannot fill a single\n * grid slab or spawn particles at the observer / viewport vanishing point. */\nexport function precipitationSeed(index, out) {\n    const n = index + 1;\n    out[0] = radicalInverse(n, 2);\n    out[1] = radicalInverse(n, 3);\n    out[2] = radicalInverse(n, 5);\n    let hash = Math.imul(n ^ 0x7261696e, 0x45d9f3b);hash ^= hash >>> 16;\n    out[3] = (hash >>> 0) / 4294967296;\n    return out;\n}\n\n/** Rendering proxy budget, never an alternative reported observation. */\nexport function precipitationProxyDensity(rate) {\n    return Number.isFinite(rate) && rate > 0 ? 1 - Math.exp(-Math.sqrt(rate) * 0.36) : 0;\n}\n\n/** CPU reference for the shader's toroidal Earth-fixed translation. */\nexport function precipitationCoordinate(seed, travel, observer, span) {\n    return ((seed * span + travel - observer + span / 2) % span + span) % span - span / 2;\n}\n","import { PRECIPITATION_SPAN_M as SPAN, PRECIPITATION_HEIGHT_M as HEIGHT } from './PrecipitationContract.js';\n\nconst surface = /* glsl */`\n    uniform sampler2D uSurface;\n    uniform vec3 uCaptureOffset;\n    uniform float uSurfaceValid;\n    float surfaceHeight(vec2 xz) {\n        vec2 coord = (xz + uCaptureOffset.xz) / ${SPAN}.0 + 0.5;\n        coord.y = 1.0 - coord.y;\n        if (uSurfaceValid < 0.5 || any(lessThan(coord, vec2(0.0))) || any(greaterThan(coord, vec2(1.0)))) return -10000.0;\n        float d = texture2D(uSurface, coord).x;\n        return d > 0.99999 ? -10000.0 : 96.0 - (0.1 + d * (224.0 - 0.1)) - uCaptureOffset.y;\n    }\n`;\nconst vertexHeader = /* glsl */`\n    attribute vec4 aSeed;\n    uniform float uTime, uPixelScale, uRate, uCeiling;\n    uniform vec3 uCameraOffset, uTravel, uWind, uObserverVelocity;\n    varying vec2 vUv;\n    varying vec3 vLocal;\n    varying float vEnergy;\n    #include <common>\n    #include <logdepthbuf_pars_vertex>\n    vec3 localViewOffset(vec2 offset) {\n        vec3 v = vec3(offset, 0.0);\n        return vec3(dot(modelViewMatrix[0].xyz,v),dot(modelViewMatrix[1].xyz,v),dot(modelViewMatrix[2].xyz,v));\n    }\n    vec3 fieldPosition(float fallSpeed) {\n        vec3 span = vec3(${SPAN}.0, ${HEIGHT}.0, ${SPAN}.0);\n        vec3 travel = vec3(uTravel.x, -uTime * fallSpeed, uTravel.z);\n        return mod(aSeed.xyz * span + travel - uCameraOffset + span * 0.5, span) - span * 0.5;\n    }\n    // The residency window is a volume, not a screen-centered emitter. Its\n    // spherical fade keeps the view's angular density even when flying forward.\n    float fieldFade(vec3 center, float depth) {\n        return (1.0 - smoothstep(34.0, 47.0, length(center)))\n            * smoothstep(0.25, 1.2, depth) * step(center.y, uCeiling);\n    }\n`;\nexport const rainVertex = vertexHeader + /* glsl */`\n    void main() {\n        // A stationary exponential proposal is weighted by the rate-dependent\n        // Marshall-Palmer slope. Drop size/fall speed stay fixed per seed, so\n        // changing the weather cannot teleport every drop through time*speed.\n        float lambda = 4.1 * pow(max(0.05, uRate), -0.21);\n        float proposalMass = 1.0 - exp(-4.15);\n        float diameter = 0.35 - log(max(0.0001,1.0-aSeed.w*proposalMass));\n        float populationWeight = lambda*proposalMass/max(0.0001,1.0-exp(-lambda*4.15))\n            * exp(-(lambda-1.0)*(diameter-0.35));\n        float fallSpeed = max(1.0, 9.65 - 10.3 * exp(-0.6 * diameter));\n        vec3 velocity = vec3(uWind.x, -fallSpeed, uWind.z);\n        vec3 center = fieldPosition(fallSpeed);\n        vec4 view = modelViewMatrix * vec4(center, 1.0);\n        vec3 viewVelocity = mat3(modelViewMatrix) * (velocity - uObserverVelocity);\n        vec2 projected = viewVelocity.xy - view.xy * viewVelocity.z / min(-0.1, view.z);\n        float speed = length(projected);\n        vec2 along = speed > 0.0001 ? projected / speed : vec2(0.0, -1.0);\n        vec2 across = vec2(-along.y, along.x);\n        float physicalWidth = diameter * 0.001;\n        float width = max(physicalWidth, max(0.0001, -view.z * uPixelScale) * 0.7);\n        float exposure = 1.0 / 90.0;\n        float streak = max(width * 1.5, speed * exposure);\n        // Correctly shorten very close/fast streaks at the near plane; a\n        // camera teleport can never turn the whole screen into a rain quad.\n        streak = min(streak, max(0.02, -view.z * 0.18));\n        vec2 viewOffset = across * position.x * width * 0.5 + along * position.y * streak * 0.5;\n        view.xy += viewOffset;\n        gl_Position = projectionMatrix * view;\n        vLocal = center + localViewOffset(viewOffset);\n        vUv = uv;\n        vEnergy = fieldFade(center, -view.z) * mix(0.35, 1.0, aSeed.w) * populationWeight\n            * min(1.0, physicalWidth / width + 0.15);\n        #include <logdepthbuf_vertex>\n    }\n`;\nexport const rainFragment = /* glsl */`\n    uniform vec3 uColor;\n    uniform float uOpacity;\n    varying vec2 vUv;\n    varying vec3 vLocal;\n    varying float vEnergy;\n    ${surface}\n    #include <logdepthbuf_pars_fragment>\n    void main() {\n        float floorY = surfaceHeight(vLocal.xz);\n        if (floorY > -9999.0 && vLocal.y < floorY + 0.008) discard;\n        float crossSection = exp(-pow((vUv.x - 0.5) * 5.0, 2.0));\n        float ends = smoothstep(0.0, 0.18, vUv.y) * (1.0 - smoothstep(0.65, 1.0, vUv.y));\n        float alpha = crossSection * ends * vEnergy * uOpacity;\n        if (alpha < 0.002) discard;\n        gl_FragColor = vec4(uColor, alpha);\n        #include <logdepthbuf_fragment>\n        #include <tonemapping_fragment>\n        #include <colorspace_fragment>\n    }\n`;\nexport const snowVertex = vertexHeader + /* glsl */`\n    varying float vAngle;\n    void main() {\n        float fallSpeed = mix(0.45, 1.6, aSeed.w);\n        float phase = uTime * mix(1.1, 2.4, aSeed.w) + aSeed.y * 6.2831853;\n        vec3 center = fieldPosition(fallSpeed);\n        center.xz += vec2(sin(phase), cos(phase * 0.73)) * 0.22;\n        vec3 velocity = vec3(uWind.x + cos(phase) * 0.3, -fallSpeed, uWind.z - sin(phase * 0.73) * 0.22);\n        vec4 view = modelViewMatrix * vec4(center, 1.0);\n        vec3 relativeVelocity = mat3(modelViewMatrix) * (velocity - uObserverVelocity);\n        vec2 projected = relativeVelocity.xy - view.xy * relativeVelocity.z / min(-0.1, view.z);\n        float speed = length(projected);\n        vec2 along = speed > 0.0001 ? projected / speed : vec2(0.0, -1.0);\n        vec2 across = vec2(-along.y, along.x);\n        float diameter = mix(0.002, 0.007, aSeed.w);\n        float width = max(diameter, max(0.0001, -view.z * uPixelScale) * 1.1);\n        float tumble = 0.4 + 0.6 * abs(sin(phase * 0.6));\n        float lengthM = min(max(width, speed / 120.0), max(0.02, -view.z * 0.12));\n        vec2 viewOffset = across * position.x * width * tumble * 0.5 + along * position.y * lengthM * 0.5;\n        view.xy += viewOffset;\n        gl_Position = projectionMatrix * view;\n        vLocal = center + localViewOffset(viewOffset);vUv = uv;vAngle = phase;\n        vEnergy = fieldFade(center, -view.z) * min(1.0, diameter / width + 0.2);\n        #include <logdepthbuf_vertex>\n    }\n`;\nexport const snowFragment = /* glsl */`\n    uniform vec3 uColor;\n    uniform float uSnowOpacity;\n    varying vec2 vUv;\n    varying vec3 vLocal;\n    varying float vEnergy, vAngle;\n    ${surface}\n    #include <logdepthbuf_pars_fragment>\n    void main() {\n        float floorY = surfaceHeight(vLocal.xz);\n        if (floorY > -9999.0 && vLocal.y < floorY) discard;\n        vec2 p = (vUv - 0.5) * 2.0;\n        float radius = length(p);\n        float edge = 0.8 + 0.08 * cos(atan(p.y,p.x) * 6.0 + vAngle);\n        float shape = 1.0 - smoothstep(edge - 0.25, edge, radius);\n        float alpha = shape * vEnergy * uSnowOpacity;\n        if (alpha < 0.003) discard;\n        gl_FragColor = vec4(uColor, alpha);\n        #include <logdepthbuf_fragment>\n        #include <tonemapping_fragment>\n        #include <colorspace_fragment>\n    }\n`;\nexport const splashVertex = vertexHeader + /* glsl */`\n    varying float vLife;\n    ${surface}\n    void main() {\n        float life = fract(uTime * mix(2.0, 3.3, aSeed.w) + aSeed.y);\n        vec2 xz = mod(aSeed.xz * ${SPAN}.0 - uCameraOffset.xz + ${SPAN/2}.0, ${SPAN}.0) - ${SPAN/2}.0;\n        float floorY = surfaceHeight(xz);\n        float dx = surfaceHeight(xz + vec2(0.5,0.0)) - floorY;\n        float dz = surfaceHeight(xz + vec2(0.0,0.5)) - floorY;\n        float valid = floorY > -20.0 && floorY < -0.05 && abs(dx)<0.4 && abs(dz)<0.4 ? 1.0 : 0.0;\n        vec3 normal = normalize(vec3(-dx/0.5,1.0,-dz/0.5));\n        float angle = aSeed.w * 73.0;\n        vec3 launch = normal * mix(0.55,1.7,aSeed.y)\n            + vec3(cos(angle),0.0,sin(angle)) * mix(0.3,1.3,aSeed.w);\n        launch.xz += uWind.xz * 0.08;\n        float age = life * 0.35;\n        vec3 center = vec3(xz.x,floorY+0.01,xz.y) + launch * age - vec3(0.0,4.905*age*age,0.0);\n        vec3 velocity = launch - vec3(0.0,9.81*age,0.0);\n        vec4 view = modelViewMatrix * vec4(center,1.0);\n        vec3 relative = mat3(modelViewMatrix) * (velocity-uObserverVelocity);\n        vec2 projected = relative.xy-view.xy*relative.z/min(-0.1,view.z);\n        float speed = length(projected);\n        vec2 along = speed > 0.0001 ? projected/speed : vec2(0.0,1.0);\n        vec2 across = vec2(-along.y,along.x);\n        float width = max(0.0015,max(0.0001,-view.z*uPixelScale)*0.65);\n        float streak = min(max(width,speed/160.0),max(0.01,-view.z*0.08));\n        view.xy += across*position.x*width*0.5+along*position.y*streak*0.5;\n        gl_Position=projectionMatrix*view;\n        vLocal=center;vUv=uv;vLife=life;\n        vEnergy=valid*step(floorY,center.y)*fieldFade(center,-view.z);\n        #include <logdepthbuf_vertex>\n    }\n`;\nexport const splashFragment = /* glsl */`\n    uniform vec3 uColor;\n    uniform float uOpacity;\n    varying vec2 vUv;\n    varying vec3 vLocal;\n    varying float vEnergy, vLife;\n    #include <logdepthbuf_pars_fragment>\n    void main() {\n        float body = exp(-dot((vUv-0.5)*3.7,(vUv-0.5)*3.7));\n        float alpha = body * vEnergy * uOpacity * (1.0-vLife) * 0.65;\n        if(alpha<0.003)discard;\n        gl_FragColor=vec4(uColor,alpha);\n        #include <logdepthbuf_fragment>\n        #include <tonemapping_fragment>\n        #include <colorspace_fragment>\n    }\n`;\n","import * as THREE from 'three';\nimport { RainSurfaceAtlas } from './RainSurfaceAtlas.js';\nimport { setWeatherBasis } from './SceneWeatherState.js';\nimport { RAIN_LAYER } from './RainPass.js';\n\nimport { PRECIPITATION_SPAN_M as SPAN, PRECIPITATION_HEIGHT_M as HEIGHT,\n    precipitationSeed, precipitationProxyDensity } from './PrecipitationContract.js';\nimport { rainVertex, rainFragment, snowVertex, snowFragment, splashVertex, splashFragment } from './PrecipitationShaders.js';\nconst wrap = (value, period) => (((value + period / 2) % period) + period) % period - period / 2;\n\nfunction makeGeometry(capacity, seed) {\n    const geometry = new THREE.InstancedBufferGeometry();\n    geometry.setIndex([0, 1, 2, 0, 2, 3]);\n    geometry.setAttribute('position', new THREE.Float32BufferAttribute([-1,-1,0, 1,-1,0, 1,1,0, -1,1,0], 3));\n    geometry.setAttribute('uv', new THREE.Float32BufferAttribute([0,0, 1,0, 1,1, 0,1], 2));\n    const seeds = new Float32Array(capacity * 4);\n    for (let i = 0; i < capacity; i++) precipitationSeed(i + (seed & 1023), seeds.subarray(i * 4, i * 4 + 4));\n    geometry.setAttribute('aSeed', new THREE.InstancedBufferAttribute(seeds, 4));\n    geometry.instanceCount = 0;\n    return geometry;\n}\n\nexport class RainSystem {\n    constructor({ scene, renderer, camera, planetGroup, mobile = false } = {}) {\n        this.scene = scene; this.renderer = renderer; this.camera = camera; this.planetGroup = planetGroup;\n        this.mobile = mobile; this.capacity = mobile ? 8000 : 24000;\n        this.group = new THREE.Group(); this.group.name = 'Weather:LocalRain'; this.group.visible = false;\n        scene.add(this.group);\n        this._east = new THREE.Vector3(); this._up = new THREE.Vector3(); this._south = new THREE.Vector3();\n        this._position = new THREE.Vector3(); this._origin = new THREE.Vector3(); this._delta = new THREE.Vector3();\n        this._localPosition = new THREE.Vector3();\n        this._localEast = new THREE.Vector3(); this._localUp = new THREE.Vector3(); this._localSouth = new THREE.Vector3();\n        this._previous = new THREE.Vector3(); this._velocity = new THREE.Vector3();\n        this._planetQuaternion = new THREE.Quaternion(); this._parentQuaternion = new THREE.Quaternion();\n        this._worldQuaternion = new THREE.Quaternion(); this._basisMatrix = new THREE.Matrix4();\n        this._size = new THREE.Vector2();\n        this._initialized = false; this._active = false; this._disposed = false; this._opacity = 0; this._snowOpacity = 0;\n        this._lastUpdateMs = null;\n        this.rain = null; this.snow = null; this.splashes = null; this.atlas = null;\n    }\n\n    _create() {\n        if (this.rain) return;\n        this.atlas = new RainSurfaceAtlas(this.renderer, { mobile: this.mobile, span: SPAN });\n        const uniforms = this.uniforms = {\n            uTime: { value: 0 }, uRate: { value: 0 }, uOpacity: { value: 0 },\n            uSnowOpacity: { value: 0 }, uCeiling: { value: HEIGHT },\n            uPixelScale: { value: 0.001 }, uColor: { value: new THREE.Color() },\n            uCameraOffset: { value: new THREE.Vector3() }, uTravel: { value: new THREE.Vector3() },\n            uWind: { value: new THREE.Vector3() }, uObserverVelocity: { value: new THREE.Vector3() },\n            uCaptureOffset: { value: new THREE.Vector3() },\n            uSurface: { value: this.atlas.target.depthTexture }, uSurfaceValid: { value: 0 },\n        };\n        const material = (name, vertexShader, fragmentShader) => new THREE.ShaderMaterial({\n            name, uniforms, vertexShader, fragmentShader, transparent: true,\n            depthTest: true, depthWrite: false, side: THREE.DoubleSide,\n        });\n        this.rain = new THREE.Mesh(makeGeometry(this.capacity, 0x7261696e), material('Weather:RainStreaks', rainVertex, rainFragment));\n        this.snow = new THREE.Mesh(makeGeometry(this.mobile ? 4000 : 10000, 0x736e6f77), material('Weather:SnowFlakes', snowVertex, snowFragment));\n        this.splashes = new THREE.Mesh(makeGeometry(this.mobile ? 1024 : 3072, 0x73706c61), material('Weather:RainImpacts', splashVertex, splashFragment));\n        for (const mesh of [this.rain, this.snow, this.splashes]) {\n            mesh.frustumCulled = false;\n            mesh.raycast = () => {}; // Weather never owns scene picking.\n            mesh.userData.lensflare = 'no-occlusion';\n            this.group.add(mesh);\n        }\n        this.rain.renderOrder = 20; this.splashes.renderOrder = 19;\n    }\n\n    /** Called only by PlanetScene's existing frame owner. Weather remains in SI units. */\n    update(dt, state, latitude, longitude, active, terrain, sunDirection = null, frameNowMs = null, cloudTopRadius = Infinity) {\n        if (this._disposed) return;\n        if (!active || !state?.available) { this.suspend(); return; }\n        const rate = Number.isFinite(state.rainRateMmH) ? Math.max(0, state.rainRateMmH) : 0;\n        // Prefer measured/modelled liquid-water equivalent. A depth-only feed\n        // can still show snow without inventing a snow-to-water density ratio.\n        const snowRate = Number.isFinite(state.snowWaterEquivalentMmH)\n            ? Math.max(0, state.snowWaterEquivalentMmH)\n            : Number.isFinite(state.snowfallCmH) ? Math.max(0, state.snowfallCmH) : 0;\n        if (rate === 0 && snowRate === 0 && this._opacity < 0.001 && this._snowOpacity < 0.001) { this.suspend(); return; }\n        this._create();\n        dt = Number.isFinite(dt) ? THREE.MathUtils.clamp(dt, 0, 0.1) : 0;\n        // Scene physics clamps large dt. Presentation fades use the same frame\n        // owner's monotonic timestamp so a slow renderer cannot prolong old rain.\n        const fadeDt = Number.isFinite(frameNowMs) && this._lastUpdateMs !== null\n            ? THREE.MathUtils.clamp((frameNowMs - this._lastUpdateMs) / 1000, 0, 5) : dt;\n        this._lastUpdateMs = Number.isFinite(frameNowMs) ? frameNowMs : null;\n        const u = this.uniforms;\n        this.camera.getWorldPosition(this._position);\n        this._localPosition.copy(this._position);\n        this.planetGroup?.worldToLocal(this._localPosition);\n        this.planetGroup?.getWorldQuaternion(this._planetQuaternion);\n        setWeatherBasis(latitude, longitude, null, this._localEast, this._localUp, this._localSouth);\n        this._east.copy(this._localEast).applyQuaternion(this._planetQuaternion);\n        this._up.copy(this._localUp).applyQuaternion(this._planetQuaternion);\n        this._south.copy(this._localSouth).applyQuaternion(this._planetQuaternion);\n        this._basisMatrix.makeBasis(this._east, this._up, this._south);\n        this._worldQuaternion.setFromRotationMatrix(this._basisMatrix);\n        // Rebase around the observer without rotating the weather with camera yaw/pitch.\n        this.group.position.copy(this._position);\n        this.scene.worldToLocal(this.group.position);\n        this.scene.getWorldQuaternion(this._parentQuaternion).invert();\n        this.group.quaternion.copy(this._parentQuaternion).multiply(this._worldQuaternion);\n        if (!this._active || !this._initialized || this._previous.distanceToSquared(this._localPosition) > 4e6) {\n            this._origin.copy(this._localPosition); this._previous.copy(this._localPosition);\n            u.uTravel.value.set(0, 0, 0); this.atlas.invalidate(); this._initialized = true;\n        }\n        this._delta.copy(this._localPosition).sub(this._origin);\n        u.uCameraOffset.value.set(wrap(this._delta.dot(this._localEast), SPAN),\n            wrap(this._delta.dot(this._localUp), HEIGHT), wrap(this._delta.dot(this._localSouth), SPAN));\n        u.uCeiling.value = Math.min(HEIGHT, cloudTopRadius - this._localPosition.length());\n        this._velocity.copy(this._localPosition).sub(this._previous).multiplyScalar(fadeDt > 0 ? 1 / fadeDt : 0);\n        this._previous.copy(this._localPosition);\n        // Teleports must not produce multi-kilometre motion-blur quads.\n        if (this._velocity.lengthSq() > 250000) this._velocity.set(0, 0, 0);\n        u.uObserverVelocity.value.set(this._velocity.dot(this._localEast), this._velocity.dot(this._localUp), this._velocity.dot(this._localSouth));\n        const bearing = Number.isFinite(state.windFromDegrees) ? state.windFromDegrees * Math.PI / 180 : 0;\n        const speed = Number.isFinite(state.windSpeedMps) && Number.isFinite(state.windFromDegrees) ? state.windSpeedMps : 0;\n        u.uWind.value.set(-Math.sin(bearing) * speed, 0, Math.cos(bearing) * speed);\n        u.uTravel.value.addScaledVector(u.uWind.value, fadeDt);\n        u.uTravel.value.x %= SPAN; u.uTravel.value.z %= SPAN;\n        u.uTime.value += fadeDt;\n        this._opacity += ((rate > 0 ? 1 : 0) - this._opacity) * (1 - Math.exp(-fadeDt * 2));\n        this._snowOpacity += ((snowRate > 0 ? 1 : 0) - this._snowOpacity) * (1 - Math.exp(-fadeDt * 2));\n        u.uOpacity.value = this._opacity * 0.36;\n        u.uSnowOpacity.value = this._snowOpacity * 0.8;\n        u.uRate.value = rate;\n        this.renderer.getDrawingBufferSize(this._size);\n        u.uPixelScale.value = 2 * Math.tan(THREE.MathUtils.degToRad(this.camera.fov || 60) / 2) / Math.max(1, this._size.y);\n        const daylight = sunDirection ? THREE.MathUtils.smoothstep(this._up.dot(sunDirection), -0.12, 0.3) : 0.5;\n        u.uColor.value.setRGB(0.11 + daylight * 0.75, 0.13 + daylight * 0.77, 0.16 + daylight * 0.78);\n        const density = precipitationProxyDensity(rate);\n        const snowDensity = precipitationProxyDensity(snowRate);\n        // Caps are rendering proxies; they do not alter or report a different observed rate.\n        this.rain.geometry.instanceCount = rate > 0 ? Math.ceil(this.capacity * density) : this.rain.geometry.instanceCount;\n        this.snow.geometry.instanceCount = snowRate > 0 ? Math.ceil((this.mobile ? 4000 : 10000) * snowDensity) : this.snow.geometry.instanceCount;\n        this.snow.visible = this._snowOpacity > 0.001;\n        this.rain.visible = this._opacity > 0.001;\n        this.splashes.geometry.instanceCount = rate > 0 ? Math.ceil((this.mobile ? 1024 : 3072) * density) : this.splashes.geometry.instanceCount;\n        this.atlas.update(dt, this._position, this._up, this._south, terrain);\n        if (this.atlas.valid) {\n            this._delta.copy(this._position).sub(this.atlas.center);\n            u.uCaptureOffset.value.set(this._delta.dot(this._east), this._delta.dot(this._up), this._delta.dot(this._south));\n        } else u.uCaptureOffset.value.set(0, 0, 0);\n        u.uSurfaceValid.value = this.atlas.valid ? 1 : 0;\n        this.splashes.visible = this.atlas.valid && this._opacity > 0.001;\n        this.group.visible = this._opacity > 0.001 || this._snowOpacity > 0.001;\n        this._active = true;\n    }\n\n    suspend() {\n        this.group.visible = false; this._active = false; this._opacity = 0; this._snowOpacity = 0;\n        this._lastUpdateMs = null;\n        this.atlas?.invalidate();\n    }\n    setCompositionMode(composited) {\n        this.rain?.layers.set(composited ? RAIN_LAYER : 0);\n        this.splashes?.layers.set(composited ? RAIN_LAYER : 0);\n        this.snow?.layers.set(composited ? RAIN_LAYER : 0);\n    }\n    dispose() {\n        if (this._disposed) return;\n        this._disposed = true; this.group.removeFromParent();\n        for (const mesh of [this.rain, this.snow, this.splashes]) { mesh?.geometry.dispose(); mesh?.material.dispose(); }\n        this.atlas?.dispose(); this.rain = this.snow = this.splashes = this.atlas = null;\n    }\n}\n","/**\n * GlobeSpline - Creates curved arcs between two points on the globe\n *\n * Features:\n * - Smooth Catmull-Rom splines following great circle paths\n * - Configurable arc height (apex distance from surface)\n * - Marching ants animation\n * - Object attachment points for moving items along the path\n * - Color and styling options\n */\n\nimport * as THREE from 'three';\nimport { ellipsoidRadiusForLocalDir } from '../../modules/geometry-utils.js';\n\nexport class GlobeSpline {\n    constructor(options = {}) {\n        const {\n            startLat,\n            startLon,\n            startElevation = 0,\n            endLat,\n            endLon,\n            endElevation = 0,\n            planetRadius = 6371000,\n\n            // Arc shape parameters\n            arcType = 'auto', // 'auto', 'high', 'low', 'direct'\n            apexHeight = null, // meters above surface at highest point\n            apexHeightMin = 50000, // minimum apex height for auto mode\n            apexHeightMax = 500000, // maximum apex height for auto mode\n\n            // Visual parameters\n            color = '#00ffff',\n            opacity = 0.8,\n            lineWidth = 2,\n\n            // Animation parameters\n            marchingAnts = false,\n            marchingSpeed = 1.0, // cycles per second\n            flowDirection = 1, // 1 = start->end, -1 = end->start\n\n            // Spline resolution\n            segments = 64,\n\n        } = options;\n\n        this.planetRadius = planetRadius;\n\n        // Store endpoints\n        this.startLat = startLat;\n        this.startLon = startLon;\n        this.startElevation = startElevation;\n        this.endLat = endLat;\n        this.endLon = endLon;\n        this.endElevation = endElevation;\n\n        // Arc parameters\n        this.arcType = arcType;\n        this.apexHeight = apexHeight;\n        this.apexHeightMin = apexHeightMin;\n        this.apexHeightMax = apexHeightMax;\n\n        // Visual parameters\n        this.color = new THREE.Color(color);\n        this.opacity = opacity;\n        this.lineWidth = lineWidth;\n\n        // Animation parameters\n        this.marchingAnts = marchingAnts;\n        this.marchingSpeed = marchingSpeed;\n        this.flowDirection = flowDirection;\n        this.segments = segments;\n\n        // Internal state\n        this.curve = null;\n        this.line = null;\n        this.material = null;\n        this.animationTime = 0;\n\n        // Build the spline\n        this._buildSpline();\n    }\n\n    /**\n     * Convert lat/lon/elevation to 3D world position\n     */\n    _latLonToWorld(lat, lon, elevation) {\n        const phi = (90 - lat) * Math.PI / 180;\n        const theta = (lon + 180) * Math.PI / 180;\n        const dir = new THREE.Vector3(\n            -Math.sin(phi) * Math.cos(theta),\n            Math.cos(phi),\n            Math.sin(phi) * Math.sin(theta)\n        ).normalize();\n        const baseRadius = ellipsoidRadiusForLocalDir(dir);\n        const r = baseRadius + elevation;\n\n        return dir.multiplyScalar(r);\n    }\n\n    /**\n     * Calculate optimal apex height based on distance between points\n     */\n    _calculateApexHeight() {\n        if (this.apexHeight !== null) return this.apexHeight;\n\n        const start = this._latLonToWorld(this.startLat, this.startLon, 0);\n        const end = this._latLonToWorld(this.endLat, this.endLon, 0);\n        const distance = start.distanceTo(end);\n\n        // Scale apex height based on distance (longer arcs are higher)\n        const normalizedDist = distance / (this.planetRadius * 2); // 0-1 range\n        const height = THREE.MathUtils.lerp(\n            this.apexHeightMin,\n            this.apexHeightMax,\n            normalizedDist\n        );\n\n        return height;\n    }\n\n    /**\n     * Build the spline curve\n     */\n    _buildSpline() {\n        const start = this._latLonToWorld(this.startLat, this.startLon, this.startElevation);\n        const end = this._latLonToWorld(this.endLat, this.endLon, this.endElevation);\n\n        // Calculate midpoint and apex\n        const midpoint = new THREE.Vector3().addVectors(start, end).multiplyScalar(0.5);\n        const apexHeight = this._calculateApexHeight();\n\n        // Create control points for the arc\n        const controlPoints = [];\n\n        // Start point\n        controlPoints.push(start.clone());\n\n        // Create intermediate control points along great circle with height\n        const numControlPoints = 3; // Start, middle, end + 2 intermediate = 5 total\n        for (let i = 1; i < numControlPoints + 1; i++) {\n            const t = i / (numControlPoints + 1);\n\n            // Interpolate along great circle (spherical interpolation)\n            const point = this._slerp(start, end, t);\n\n            // Add height using a parabolic curve (highest at t=0.5)\n            const heightFactor = Math.sin(t * Math.PI); // 0 at ends, 1 at middle\n            const heightOffset = heightFactor * apexHeight;\n\n            // Add height by extending radially from planet center\n            const heightDir = point.clone().normalize();\n            point.add(heightDir.multiplyScalar(heightOffset));\n\n            controlPoints.push(point);\n        }\n\n        // End point\n        controlPoints.push(end.clone());\n\n        // Create Catmull-Rom curve\n        this.curve = new THREE.CatmullRomCurve3(controlPoints);\n        this.curve.closed = false;\n        this.curve.curveType = 'catmullrom';\n        this.curve.tension = 0.5;\n\n        // Create line geometry\n        const points = this.curve.getPoints(this.segments);\n        const geometry = new THREE.BufferGeometry().setFromPoints(points);\n\n        // Add line distance attribute for marching ants animation\n        if (this.marchingAnts) {\n            const lineDistances = new Float32Array(points.length);\n            for (let i = 0; i < points.length; i++) {\n                lineDistances[i] = i / (points.length - 1); // 0 to 1\n            }\n            geometry.setAttribute('lineDistance', new THREE.BufferAttribute(lineDistances, 1));\n        }\n\n        // Create material\n        let material;\n        if (this.marchingAnts) {\n            material = this._createMarchingAntsMaterial();\n        } else {\n            material = new THREE.LineBasicMaterial({\n                color: this.color,\n                opacity: this.opacity,\n                transparent: this.opacity < 1,\n                linewidth: this.lineWidth\n            });\n        }\n\n        this.material = material;\n\n        if (this.line) {\n            if (this.line.geometry) this.line.geometry.dispose();\n            if (this.line.material) this.line.material.dispose();\n            this.line.geometry = geometry;\n            this.line.material = material;\n            this.line.userData.spline = this;\n        } else {\n            this.line = new THREE.Line(geometry, material);\n            this.line.userData.spline = this;\n        }\n    }\n\n    /**\n     * Spherical linear interpolation for great circle path\n     */\n    _slerp(v1, v2, t) {\n        const dot = v1.clone().normalize().dot(v2.clone().normalize());\n        const theta = Math.acos(THREE.MathUtils.clamp(dot, -1, 1));\n\n        if (theta < 0.001) {\n            // Points are very close, use linear interpolation\n            return new THREE.Vector3().lerpVectors(v1, v2, t);\n        }\n\n        const sinTheta = Math.sin(theta);\n        const w1 = Math.sin((1 - t) * theta) / sinTheta;\n        const w2 = Math.sin(t * theta) / sinTheta;\n\n        return new THREE.Vector3(\n            v1.x * w1 + v2.x * w2,\n            v1.y * w1 + v2.y * w2,\n            v1.z * w1 + v2.z * w2\n        );\n    }\n\n    /**\n     * Create shader material for marching ants effect\n     */\n    _createMarchingAntsMaterial() {\n        return new THREE.ShaderMaterial({\n            uniforms: {\n                uColor: { value: this.color },\n                uOpacity: { value: this.opacity },\n                uTime: { value: 0 },\n                uSpeed: { value: this.marchingSpeed },\n                uDirection: { value: this.flowDirection },\n                uDashSize: { value: 0.1 },\n                uGapSize: { value: 0.05 }\n            },\n            vertexShader: `\n                attribute float lineDistance;\n                varying float vLineDistance;\n\n                void main() {\n                    vLineDistance = lineDistance;\n                    gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n                }\n            `,\n            fragmentShader: `\n                uniform vec3 uColor;\n                uniform float uOpacity;\n                uniform float uTime;\n                uniform float uSpeed;\n                uniform float uDirection;\n                uniform float uDashSize;\n                uniform float uGapSize;\n\n                varying float vLineDistance;\n\n                void main() {\n                    float dashGap = uDashSize + uGapSize;\n                    float offset = uTime * uSpeed * uDirection;\n                    // Scale vLineDistance (0-1) to create multiple dashes along line\n                    float pattern = mod(vLineDistance * 10.0 + offset, dashGap);\n\n                    if (pattern > uDashSize) {\n                        discard;\n                    }\n\n                    gl_FragColor = vec4(uColor, uOpacity);\n                }\n            `,\n            transparent: true,\n            depthWrite: false\n        });\n    }\n\n    /**\n     * Update animation (call this in render loop)\n     */\n    update(deltaTime) {\n        if (this.marchingAnts && this.material && this.material.uniforms) {\n            this.animationTime += deltaTime;\n            this.material.uniforms.uTime.value = this.animationTime;\n        }\n    }\n\n    /**\n     * Get point along the spline at time t (0-1)\n     */\n    getPointAt(t) {\n        if (!this.curve) return null;\n        return this.curve.getPoint(t);\n    }\n\n    /**\n     * Get tangent (direction) at time t (0-1)\n     */\n    getTangentAt(t) {\n        if (!this.curve) return null;\n        return this.curve.getTangent(t);\n    }\n\n    /**\n     * Get position and orientation for an object at time t (0-1)\n     */\n    getTransformAt(t) {\n        const position = this.getPointAt(t);\n        const tangent = this.getTangentAt(t);\n\n        if (!position || !tangent) return null;\n\n        // Create quaternion from tangent direction\n        const up = position.clone().normalize(); // Radial direction from planet center\n        const quaternion = new THREE.Quaternion();\n        const matrix = new THREE.Matrix4();\n        matrix.lookAt(new THREE.Vector3(), tangent, up);\n        quaternion.setFromRotationMatrix(matrix);\n\n        return { position, quaternion, tangent };\n    }\n\n    /**\n     * Add line to scene\n     */\n    addToScene(scene) {\n        if (this.line && scene) {\n            scene.add(this.line);\n        }\n    }\n\n    /**\n     * Remove line from scene\n     */\n    removeFromScene(scene) {\n        if (this.line && scene) {\n            scene.remove(this.line);\n        }\n    }\n\n    /**\n     * Update spline properties\n     */\n    updateProperties(props) {\n        let needsRebuild = false;\n\n        const hasChange = (key, current) => props[key] !== undefined && props[key] !== current;\n        if (hasChange('startLat', this.startLat) || hasChange('startLon', this.startLon) ||\n            hasChange('endLat', this.endLat) || hasChange('endLon', this.endLon) ||\n            hasChange('startElevation', this.startElevation) || hasChange('endElevation', this.endElevation) ||\n            hasChange('apexHeight', this.apexHeight) || hasChange('apexHeightMin', this.apexHeightMin) ||\n            hasChange('apexHeightMax', this.apexHeightMax) || hasChange('arcType', this.arcType) ||\n            hasChange('segments', this.segments) || hasChange('marchingAnts', this.marchingAnts)) {\n            needsRebuild = true;\n        }\n\n        // Update properties\n        Object.assign(this, props);\n\n        if (props.color !== undefined) {\n            this.color = new THREE.Color(props.color);\n        }\n\n        // Rebuild if needed\n        if (needsRebuild) {\n            this._buildSpline();\n        } else {\n            // Update material properties\n            if (this.material) {\n                if (this.material.uniforms) {\n                    if (props.color !== undefined) this.material.uniforms.uColor.value = this.color;\n                    if (props.opacity !== undefined) this.material.uniforms.uOpacity.value = this.opacity;\n                    if (props.marchingSpeed !== undefined) this.material.uniforms.uSpeed.value = this.marchingSpeed;\n                    if (props.flowDirection !== undefined) this.material.uniforms.uDirection.value = this.flowDirection;\n                } else {\n                    if (props.color !== undefined) this.material.color = this.color;\n                    if (props.opacity !== undefined) {\n                        this.material.opacity = this.opacity;\n                        this.material.transparent = this.opacity < 1;\n                    }\n                    if (props.lineWidth !== undefined) {\n                        this.material.linewidth = this.lineWidth;\n                    }\n                }\n            }\n        }\n    }\n\n    /**\n     * Clean up resources\n     */\n    dispose() {\n        if (this.line) {\n            if (this.line.geometry) this.line.geometry.dispose();\n            if (this.line.parent) this.line.parent.remove(this.line);\n        }\n        if (this.material) {\n            this.material.dispose();\n        }\n    }\n}\n","/**\n * SplineSubsystem - Manages globe splines for connecting points\n *\n * Handles:\n * - Creating/removing splines\n * - Updating splines each frame\n * - Asset relationship splines\n * - Spline registry and lookup\n */\n\nimport { GlobeSpline } from './GlobeSpline.js';\n\nexport class SplineSubsystem {\n    constructor(options = {}) {\n        const {\n            scene = null,\n            parentGroup = null,\n            planetRadius = 6371000\n        } = options;\n\n        this.scene = scene;\n        this.parentGroup = parentGroup;\n        this.planetRadius = planetRadius;\n\n        // Spline registry\n        this.splines = new Map(); // id -> GlobeSpline\n        this.nextId = 1;\n\n        // Asset relationship splines\n        this.relationshipSplines = new Map(); // `${asset1Id}:${asset2Id}` -> splineId\n    }\n\n    /**\n     * Create a new spline\n     */\n    createSpline(config) {\n        const {\n            id = `spline-${this.nextId++}`,\n            ...splineOptions\n        } = config;\n\n        // Create spline with planet radius\n        const spline = new GlobeSpline({\n            planetRadius: this.planetRadius,\n            ...splineOptions\n        });\n\n        // Add to scene\n        const target = this.parentGroup || this.scene;\n        if (target) {\n            spline.addToScene(target);\n        }\n\n        // Register\n        this.splines.set(id, spline);\n\n        return { id, spline };\n    }\n\n    /**\n     * Create spline between two assets\n     */\n    createAssetRelationship(asset1, asset2, config = {}) {\n        // Extract positions from assets\n        const start = this._extractAssetPosition(asset1);\n        const end = this._extractAssetPosition(asset2);\n\n        if (!start || !end) {\n            console.error('[SplineSubsystem] Could not extract asset positions');\n            return null;\n        }\n\n        // Create spline\n        const result = this.createSpline({\n            ...config,\n            startLat: start.lat,\n            startLon: start.lon,\n            startElevation: start.elevation || 0,\n            endLat: end.lat,\n            endLon: end.lon,\n            endElevation: end.elevation || 0\n        });\n\n        // Register relationship\n        const relationshipKey = `${asset1.id}:${asset2.id}`;\n        this.relationshipSplines.set(relationshipKey, result.id);\n\n        return result;\n    }\n\n    /**\n     * Extract position from asset\n     */\n    _extractAssetPosition(asset) {\n        // Handle different asset formats\n        if (asset.lat !== undefined && asset.lon !== undefined) {\n            return {\n                lat: asset.lat,\n                lon: asset.lon,\n                elevation: asset.elevation || 0\n            };\n        }\n\n        if (asset.position && asset.position.lat !== undefined) {\n            return {\n                lat: asset.position.lat,\n                lon: asset.position.lon,\n                elevation: asset.position.elevation || 0\n            };\n        }\n\n        if (asset.current && asset.current.lat !== undefined) {\n            return {\n                lat: asset.current.lat,\n                lon: asset.current.lon,\n                elevation: asset.current.elevation || 0\n            };\n        }\n\n        return null;\n    }\n\n    /**\n     * Get spline by ID\n     */\n    getSpline(id) {\n        return this.splines.get(id);\n    }\n\n    /**\n     * Get spline connecting two assets\n     */\n    getAssetRelationship(asset1Id, asset2Id) {\n        const key = `${asset1Id}:${asset2Id}`;\n        const splineId = this.relationshipSplines.get(key);\n        return splineId ? this.splines.get(splineId) : null;\n    }\n\n    /**\n     * Update spline properties\n     */\n    updateSpline(id, props) {\n        const spline = this.splines.get(id);\n        if (spline) {\n            spline.updateProperties(props);\n        }\n    }\n\n    /**\n     * Remove spline\n     */\n    removeSpline(id) {\n        const spline = this.splines.get(id);\n        if (spline) {\n            spline.dispose();\n            this.splines.delete(id);\n\n            // Remove from relationships\n            for (const [key, splineId] of this.relationshipSplines.entries()) {\n                if (splineId === id) {\n                    this.relationshipSplines.delete(key);\n                }\n            }\n        }\n    }\n\n    /**\n     * Remove asset relationship spline\n     */\n    removeAssetRelationship(asset1Id, asset2Id) {\n        const key = `${asset1Id}:${asset2Id}`;\n        const splineId = this.relationshipSplines.get(key);\n        if (splineId) {\n            this.removeSpline(splineId);\n        }\n    }\n\n    /**\n     * Update all splines (call each frame)\n     */\n    update(deltaTime) {\n        for (const spline of this.splines.values()) {\n            spline.update(deltaTime);\n        }\n    }\n\n    /**\n     * Clear all splines\n     */\n    clear() {\n        for (const spline of this.splines.values()) {\n            spline.dispose();\n        }\n        this.splines.clear();\n        this.relationshipSplines.clear();\n    }\n\n    /**\n     * Load splines from configuration\n     */\n    loadFromConfig(config) {\n        if (!config || !Array.isArray(config.splines)) return;\n\n        for (const splineConfig of config.splines) {\n            this.createSpline(splineConfig);\n        }\n    }\n\n    /**\n     * Get all splines as configuration\n     */\n    toConfig() {\n        const splines = [];\n\n        for (const [id, spline] of this.splines.entries()) {\n            splines.push({\n                id,\n                startLat: spline.startLat,\n                startLon: spline.startLon,\n                startElevation: spline.startElevation,\n                endLat: spline.endLat,\n                endLon: spline.endLon,\n                endElevation: spline.endElevation,\n                arcType: spline.arcType,\n                apexHeight: spline.apexHeight,\n                color: '#' + spline.color.getHexString(),\n                opacity: spline.opacity,\n                lineWidth: spline.lineWidth,\n                marchingAnts: spline.marchingAnts,\n                marchingSpeed: spline.marchingSpeed,\n                flowDirection: spline.flowDirection\n            });\n        }\n\n        return { splines };\n    }\n\n    /**\n     * Clean up\n     */\n    dispose() {\n        this.clear();\n    }\n}\n","/**\n * Shared photoreal protrusion classifier.\n *\n * The wireframe height gradient and missing-building repair must agree about\n * what constitutes ground, a horizontal protrusion (roof), and a steep\n * protrusion (wall). Keep this module CPU-only and dependency-free so bounded\n * overlay probes can reuse the math without importing the tile/auth stack.\n */\n\nexport const PHOTO_PROTRUSION_CLASSIFIER = Object.freeze({\n  maxVertexSamples: 4096,\n  groundLowPercentile: 0.08,\n  groundHighPercentile: 0.18,\n  groundClusterSpanM: 4,\n  heightPercentile: 0.96,\n  minHeightWindowM: 12,\n  maxHeightWindowM: 90,\n  groundDeadbandM: 2.5,\n  steepFloorCos: 0.15,\n  slopeThresholdCos: Math.cos(Math.PI / 6),\n  // Require a decisive roof/wall zone. Mid-angle, smooth terrain is left\n  // ambiguous instead of suppressing a requested OSM repair.\n  buildingEvidenceThreshold: 0.55,\n});\n\nfunction clamp(value, minimum, maximum) {\n  return Math.max(minimum, Math.min(maximum, value));\n}\n\nfunction smoothstep(edge0, edge1, value) {\n  const width = edge1 - edge0;\n  if (!(width > 0)) return value >= edge1 ? 1 : 0;\n  const x = clamp((value - edge0) / width, 0, 1);\n  return x * x * (3 - 2 * x);\n}\n\nfunction percentileFromSorted(values, percentile, fallback) {\n  if (!Array.isArray(values) || values.length === 0) return fallback;\n  const index = clamp(\n    Math.floor((values.length - 1) * percentile),\n    0,\n    values.length - 1,\n  );\n  const value = values[index];\n  return Number.isFinite(value) ? value : fallback;\n}\n\nfunction averageSortedRange(values, startPercentile, endPercentile, fallback) {\n  if (!Array.isArray(values) || values.length === 0) return fallback;\n  const start = clamp(\n    Math.floor((values.length - 1) * startPercentile),\n    0,\n    values.length - 1,\n  );\n  const end = clamp(\n    Math.floor((values.length - 1) * endPercentile),\n    start,\n    values.length - 1,\n  );\n  let sum = 0;\n  let count = 0;\n  for (let index = start; index <= end; index += 1) {\n    const value = values[index];\n    if (!Number.isFinite(value)) continue;\n    sum += value;\n    count += 1;\n  }\n  return count > 0 ? sum / count : fallback;\n}\n\nfunction averageSortedValueBand(values, minimum, maximum, fallback) {\n  if (!Array.isArray(values) || values.length === 0\n    || !Number.isFinite(minimum) || !Number.isFinite(maximum)) return fallback;\n  let sum = 0;\n  let count = 0;\n  for (const value of values) {\n    if (!Number.isFinite(value) || value < minimum) continue;\n    if (value > maximum) break;\n    sum += value;\n    count += 1;\n  }\n  return count > 0 ? sum / count : fallback;\n}\n\n/**\n * Derive the exact robust ground/height window used by the wireframe AGL\n * gradient. The input array is sorted in place to avoid another hot-path\n * allocation while native tile models are prepared.\n */\nexport function derivePhotorealProtrusionMetrics(radii, {\n  fallbackGroundR = 6_378_137,\n  groundDeadbandM = PHOTO_PROTRUSION_CLASSIFIER.groundDeadbandM,\n} = {}) {\n  if (!Array.isArray(radii) || radii.length === 0) {\n    return {\n      groundR: fallbackGroundR,\n      heightWindow: PHOTO_PROTRUSION_CLASSIFIER.minHeightWindowM,\n      groundDeadband: groundDeadbandM,\n    };\n  }\n\n  radii.sort((a, b) => a - b);\n  const p08 = percentileFromSorted(\n    radii,\n    PHOTO_PROTRUSION_CLASSIFIER.groundLowPercentile,\n    fallbackGroundR,\n  );\n  const fallbackGround = averageSortedRange(\n    radii,\n    PHOTO_PROTRUSION_CLASSIFIER.groundLowPercentile,\n    PHOTO_PROTRUSION_CLASSIFIER.groundHighPercentile,\n    p08,\n  );\n  const p18 = percentileFromSorted(\n    radii,\n    PHOTO_PROTRUSION_CLASSIFIER.groundHighPercentile,\n    fallbackGround,\n  );\n  const clusterCeiling = Math.min(\n    p18,\n    p08 + PHOTO_PROTRUSION_CLASSIFIER.groundClusterSpanM,\n  );\n  const groundR = averageSortedValueBand(\n    radii,\n    p08 - PHOTO_PROTRUSION_CLASSIFIER.groundClusterSpanM,\n    clusterCeiling,\n    fallbackGround,\n  );\n  const highR = percentileFromSorted(\n    radii,\n    PHOTO_PROTRUSION_CLASSIFIER.heightPercentile,\n    groundR,\n  );\n  const heightWindow = clamp(\n    Math.max(0, highR - groundR),\n    PHOTO_PROTRUSION_CLASSIFIER.minHeightWindowM,\n    PHOTO_PROTRUSION_CLASSIFIER.maxHeightWindowM,\n  );\n  const deadband = clamp(\n    Math.max(groundDeadbandM, heightWindow * 0.06),\n    1.25,\n    4,\n  );\n  return {\n    groundR: Number.isFinite(groundR) ? groundR : fallbackGroundR,\n    heightWindow,\n    groundDeadband: deadband,\n  };\n}\n\n/**\n * CPU analogue of the wireframe shader's AGL + radial-normal zones.\n */\nexport function evaluatePhotorealProtrusion({\n  aglM,\n  radialNormalDot,\n  heightWindowM = PHOTO_PROTRUSION_CLASSIFIER.minHeightWindowM,\n  groundDeadbandM = PHOTO_PROTRUSION_CLASSIFIER.groundDeadbandM,\n} = {}) {\n  const agl = Math.max(0, Number(aglM) || 0);\n  const window = Math.max(groundDeadbandM + 0.01, Number(heightWindowM) || 0);\n  const heightT = smoothstep(groundDeadbandM, window, agl);\n  const normalAvailable = Number.isFinite(radialNormalDot);\n  if (!normalAvailable) {\n    return { heightT, roofT: heightT, wallT: 0, strength: heightT, normalAvailable };\n  }\n\n  const upDot = clamp(Math.abs(radialNormalDot), 0, 1);\n  const roofZone = smoothstep(\n    PHOTO_PROTRUSION_CLASSIFIER.steepFloorCos,\n    PHOTO_PROTRUSION_CLASSIFIER.slopeThresholdCos,\n    upDot,\n  );\n  const roofT = heightT * roofZone;\n  const wallT = heightT * (1 - roofZone);\n  return {\n    heightT,\n    roofT,\n    wallT,\n    strength: Math.max(roofT, wallT),\n    normalAvailable,\n  };\n}\n\n/**\n * Decide whether footprint-local photoreal samples already contain built-up\n * geometry. Heights are residuals above the exterior ground plane; normals\n * are the same radial-alignment signal used by the wireframe shader.\n */\nexport function classifyPhotorealBuildingPresence(samples, {\n  minimumHeightM = 3.25,\n  expectedHeightM = 10,\n  exteriorNoiseM = 0,\n} = {}) {\n  const source = Array.isArray(samples)\n    ? samples.filter((sample) => Number.isFinite(sample?.residualM))\n    : [];\n  const residuals = source.map((sample) => Math.max(0, sample.residualM)).sort((a, b) => a - b);\n  const maximumResidual = residuals[residuals.length - 1] || 0;\n  const heightWindowM = clamp(\n    maximumResidual,\n    PHOTO_PROTRUSION_CLASSIFIER.minHeightWindowM,\n    PHOTO_PROTRUSION_CLASSIFIER.maxHeightWindowM,\n  );\n  const groundDeadbandM = clamp(\n    Math.max(PHOTO_PROTRUSION_CLASSIFIER.groundDeadbandM, heightWindowM * 0.06),\n    1.25,\n    4,\n  );\n  const roofThresholdM = Math.max(\n    Number(minimumHeightM) || 0,\n    Math.min(8, Math.max(0, Number(expectedHeightM) || 0) * 0.3),\n    Math.max(0, Number(exteriorNoiseM) || 0) * 3,\n  );\n  let raisedSamples = 0;\n  let protrusionSamples = 0;\n  let normalSamples = 0;\n  let maximumStrength = 0;\n\n  for (const sample of source) {\n    if (sample.residualM < roofThresholdM) continue;\n    raisedSamples += 1;\n    const signal = evaluatePhotorealProtrusion({\n      aglM: sample.residualM,\n      radialNormalDot: sample.radialNormalDot,\n      heightWindowM,\n      groundDeadbandM,\n    });\n    if (signal.normalAvailable) normalSamples += 1;\n    maximumStrength = Math.max(maximumStrength, signal.strength);\n    if (signal.strength >= PHOTO_PROTRUSION_CLASSIFIER.buildingEvidenceThreshold) {\n      protrusionSamples += 1;\n    }\n  }\n\n  const requiredSamples = Math.max(1, Math.ceil(source.length * 0.5));\n  return {\n    present: protrusionSamples >= requiredSamples,\n    raisedSamples,\n    protrusionSamples,\n    normalSamples,\n    requiredSamples,\n    maximumStrength,\n    roofThresholdM,\n    heightWindowM,\n    groundDeadbandM,\n  };\n}\n","/**\n * BuildingOverlay\n *\n * Purpose:\n * - Fetches lightweight OSM building footprints (Overpass) and extrudes them\n *   into meshes aligned to the planet surface.\n * - Provides radius-based falloff to thin buildings toward the edge of a region.\n *\n * API intention:\n * - constructor({ parentGroup, triTree, planetRadius, overpassUrl, maxFeatures })\n * - load({ center, radiusM, falloffStartM })\n * - setCenter(lat, lon, opts)\n * - refresh()\n * - update(dt)\n * - clear(), dispose()\n *\n * Relationships:\n * - Adds meshes under a parent group (usually triTree.group).\n * - Uses triTree sampling to snap to terrain surface if available.\n */\nimport * as THREE from 'three';\nimport { latLonToLocalDir, dirToLatLonLocal, lonLatToTileCoords, geodesicDistanceWGS84, ellipsoidRadiusForLocalDir } from '../../modules/geometry-utils.js';\nimport { PLANET_RADIUS, EARTH_PRIME_MERIDIAN_OFFSET_RAD } from '../../modules/constants.js';\nimport { getLabelSystem } from '../labels/LabelSystem.js';\nimport { getAsyncHarness } from '../async/AsyncHarness.js';\nimport { getFetchQueue } from '../async/fetch/FetchQueue.js';\nimport { terrainSurfaceChangesAffectLatLon } from '../scene/TerrainSurfaceChange.js';\nimport { classifyPhotorealBuildingPresence } from '../tiles/PhotorealProtrusionClassifier.js';\nimport { resolveBackendApiUrl } from '../shared/backend.js';\n\nconst OVERPASS_URL = resolveBackendApiUrl('/overpass');\nconst OVERPASS_FALLBACK_URLS = [];\nconst OSM_MAP_URL = 'https://api.openstreetmap.org/api/0.6/map';\nconst DEFAULT_OVERPASS_TIMEOUT_MS = 4500;\nconst DEFAULT_OSM_MAP_TIMEOUT_MS = 6500;\nconst MAX_OSM_MAP_FALLBACK_RADIUS_M = 1000;\nconst DEFAULT_MAX_FEATURES = 180;\nconst DEFAULT_REFRESH_DISTANCE_M = 250;\nconst DEFAULT_LOD_DETAIL_RADIUS_M = 1200;\nconst DEFAULT_LOD_IMPOSTOR_RADIUS_M = 5000;\nconst DEFAULT_LOD_UPDATE_INTERVAL_MS = 200;\nconst DEFAULT_LOD_BUDGET = 120;\nconst DEFAULT_LOD_HYSTERESIS_M = 150;\nconst DEFAULT_IMPOSTOR_MIN_SIZE_M = 6;\nconst DEFAULT_IMPOSTOR_MIN_HEIGHT_M = 4;\nconst DEFAULT_IMPOSTOR_REBUILD_BUDGET = 2;\nconst DEFAULT_IMAGERY_UPDATE_INTERVAL_MS = 500;\nconst DEFAULT_POLYP_MIN_POINT_SPACING_M = 4;\nconst DEFAULT_POLYP_MAX_POINTS = 48;\nconst DEFAULT_POLYP_MAX_ENTRIES_PER_TILE = 500;\nconst DEFAULT_POLYP_HEIGHT_SCALE = 1;\nconst DEFAULT_POLYP_MIN_HEIGHT_M = 3;\nconst DEFAULT_MOTION_MIN_SPEED_MPS = 0.35;\nconst DEFAULT_MOTION_SPEED_REF_MPS = 6;\nconst DEFAULT_MOTION_AHEAD_FACTOR = 1.4;\nconst DEFAULT_MOTION_BEHIND_FACTOR = 0.7;\nconst DEFAULT_MOTION_QUERY_BIAS = 0.35;\nconst DEFAULT_MOTION_RETENTION_FACTOR = 1.1;\nconst MIN_RESNAP_TOLERANCE_M = 0.05;\nconst DEFAULT_PHOTO_PROBE_RAYS_PER_FRAME = 2;\nconst DEFAULT_PHOTO_PROBE_BUDGET_MS = 1.5;\nconst DEFAULT_PHOTO_COVERAGE_MIN_HEIGHT_M = 3.25;\nconst DEFAULT_PHOTO_EXTERIOR_MARGIN_M = 5;\n\nfunction angularDistanceDeg(a, b) {\n    if (!Number.isFinite(a) || !Number.isFinite(b)) return Infinity;\n    return Math.abs((((a - b) % 360) + 540) % 360 - 180);\n}\n\nfunction destinationLatLon(lat, lon, bearingDeg, distanceM) {\n    const angular = Math.max(0, distanceM) / PLANET_RADIUS;\n    const bearing = THREE.MathUtils.degToRad(bearingDeg);\n    const phi1 = THREE.MathUtils.degToRad(lat);\n    const lambda1 = THREE.MathUtils.degToRad(lon);\n    const sinPhi1 = Math.sin(phi1);\n    const cosPhi1 = Math.cos(phi1);\n    const sinAngular = Math.sin(angular);\n    const cosAngular = Math.cos(angular);\n    const phi2 = Math.asin(\n        sinPhi1 * cosAngular + cosPhi1 * sinAngular * Math.cos(bearing)\n    );\n    const lambda2 = lambda1 + Math.atan2(\n        Math.sin(bearing) * sinAngular * cosPhi1,\n        cosAngular - sinPhi1 * Math.sin(phi2)\n    );\n    return {\n        lat: THREE.MathUtils.radToDeg(phi2),\n        lon: ((((THREE.MathUtils.radToDeg(lambda2) + 180) % 360) + 360) % 360) - 180,\n    };\n}\n\n/**\n * Build the deliberately small surface-camera acquisition window. A near\n * ring prevents adjacent/underfoot repairs from disappearing, while the\n * polygon follows the visible forward sector instead of querying a city-wide\n * square on every camera move.\n */\nexport function buildBuildingViewshed({\n    lat,\n    lon,\n    headingDeg,\n    horizontalFovDeg,\n    nearRadiusM,\n    farRadiusM,\n} = {}) {\n    if (!Number.isFinite(lat) || !Number.isFinite(lon)\n        || !Number.isFinite(headingDeg) || !Number.isFinite(farRadiusM)) return null;\n    const far = THREE.MathUtils.clamp(farRadiusM, 50, 1500);\n    const near = THREE.MathUtils.clamp(\n        Number.isFinite(nearRadiusM) ? nearRadiusM : 100,\n        25,\n        Math.min(250, far)\n    );\n    const fov = THREE.MathUtils.clamp(\n        Number.isFinite(horizontalFovDeg) ? horizontalFovDeg : 90,\n        35,\n        150\n    );\n    const half = fov * 0.5;\n    const bearings = [\n        headingDeg - half,\n        headingDeg - half * 0.5,\n        headingDeg,\n        headingDeg + half * 0.5,\n        headingDeg + half,\n    ];\n    const polygon = [\n        { lat, lon },\n        ...bearings.map((bearing) => destinationLatLon(lat, lon, bearing, far)),\n    ];\n    return {\n        centerLat: lat,\n        centerLon: lon,\n        headingDeg: ((headingDeg % 360) + 360) % 360,\n        horizontalFovDeg: fov,\n        nearRadiusM: near,\n        farRadiusM: far,\n        polygon,\n    };\n}\n\nexport function buildBuildingOverpassQuery({\n    queryLat,\n    queryLon,\n    queryRadius,\n    viewshed = null,\n} = {}) {\n    if (viewshed?.polygon?.length >= 3) {\n        const poly = viewshed.polygon\n            .map((point) => `${point.lat.toFixed(6)} ${point.lon.toFixed(6)}`)\n            .join(' ');\n        const near = Math.round(viewshed.nearRadiusM);\n        const lat = Number(viewshed.centerLat).toFixed(6);\n        const lon = Number(viewshed.centerLon).toFixed(6);\n        return `\n          [out:json][timeout:12];\n          (\n            way[\"building\"](around:${near},${lat},${lon});\n            relation[\"building\"](around:${near},${lat},${lon});\n            way[\"building\"](poly:\"${poly}\");\n            relation[\"building\"](poly:\"${poly}\");\n          );\n          (._;>;);\n          out body;\n        `.trim();\n    }\n    const latRad = THREE.MathUtils.degToRad(queryLat);\n    const dLat = queryRadius / metersPerDegLat(latRad);\n    const dLon = queryRadius / metersPerDegLon(latRad);\n    const minLat = (queryLat - dLat).toFixed(6);\n    const maxLat = (queryLat + dLat).toFixed(6);\n    const minLon = (queryLon - dLon).toFixed(6);\n    const maxLon = (queryLon + dLon).toFixed(6);\n    return `\n      [out:json][timeout:12];\n      (\n        way[\"building\"](${minLat},${minLon},${maxLat},${maxLon});\n        relation[\"building\"](${minLat},${minLon},${maxLat},${maxLon});\n      );\n      (._;>;);\n      out body;\n    `.trim();\n}\n\nfunction fitAffinePlane(samples, readValue) {\n    if (!Array.isArray(samples) || samples.length < 3) return null;\n    let xx = 0;\n    let xy = 0;\n    let x = 0;\n    let yy = 0;\n    let y = 0;\n    let n = 0;\n    let xv = 0;\n    let yv = 0;\n    let v = 0;\n    for (const sample of samples) {\n        const sx = sample?.x;\n        const sy = sample?.y;\n        const sv = readValue(sample);\n        if (!Number.isFinite(sx) || !Number.isFinite(sy) || !Number.isFinite(sv)) continue;\n        xx += sx * sx;\n        xy += sx * sy;\n        x += sx;\n        yy += sy * sy;\n        y += sy;\n        xv += sx * sv;\n        yv += sy * sv;\n        v += sv;\n        n += 1;\n    }\n    if (n < 3) return null;\n\n    // Pivoted Gaussian elimination for [a,b,c] in z = ax + by + c.\n    const m = [\n        [xx, xy, x, xv],\n        [xy, yy, y, yv],\n        [x, y, n, v],\n    ];\n    for (let col = 0; col < 3; col += 1) {\n        let pivot = col;\n        for (let row = col + 1; row < 3; row += 1) {\n            if (Math.abs(m[row][col]) > Math.abs(m[pivot][col])) pivot = row;\n        }\n        if (Math.abs(m[pivot][col]) < 1e-8) return null;\n        if (pivot !== col) [m[pivot], m[col]] = [m[col], m[pivot]];\n        const scale = m[col][col];\n        for (let k = col; k < 4; k += 1) m[col][k] /= scale;\n        for (let row = 0; row < 3; row += 1) {\n            if (row === col) continue;\n            const factor = m[row][col];\n            for (let k = col; k < 4; k += 1) m[row][k] -= factor * m[col][k];\n        }\n    }\n    return { a: m[0][3], b: m[1][3], c: m[2][3] };\n}\n\nfunction evaluateAffinePlane(plane, x, y) {\n    return plane ? plane.a * x + plane.b * y + plane.c : null;\n}\n\nfunction metersPerDegLat(phiRad) {\n    return (\n        111132.954 -\n        559.822 * Math.cos(2 * phiRad) +\n        1.175 * Math.cos(4 * phiRad) -\n        0.0023 * Math.cos(6 * phiRad)\n    );\n}\n\nfunction metersPerDegLon(phiRad) {\n    return (\n        111412.84 * Math.cos(phiRad) -\n        93.5 * Math.cos(3 * phiRad) +\n        0.118 * Math.cos(5 * phiRad)\n    );\n}\n\nfunction haversine(lat1, lon1, lat2, lon2, radius = PLANET_RADIUS) {\n    const dist = geodesicDistanceWGS84(lat1, lon1, lat2, lon2);\n    if (Number.isFinite(dist)) return dist;\n    const dLat = THREE.MathUtils.degToRad(lat2 - lat1);\n    const dLon = THREE.MathUtils.degToRad(lon2 - lon1);\n    const a =\n        Math.sin(dLat / 2) ** 2 +\n        Math.cos(THREE.MathUtils.degToRad(lat1)) *\n        Math.cos(THREE.MathUtils.degToRad(lat2)) *\n        Math.sin(dLon / 2) ** 2;\n    const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));\n    return radius * c;\n}\n\n// Standard floor height in meters (based on residential/commercial average)\nconst METERS_PER_LEVEL = 3.2;\n\n/**\n * Parse building levels from OSM tags\n * @returns {number|null} Number of levels or null if not specified\n */\nfunction parseLevels(tags = {}) {\n    // Check building:levels first (OSM standard), then fallback to levels\n    const raw = tags['building:levels'] || tags.levels;\n    if (raw) {\n        const clean = parseFloat(String(raw).replace(/[^\\d.]/g, ''));\n        if (Number.isFinite(clean) && clean > 0) {\n            return Math.round(THREE.MathUtils.clamp(clean, 1, 50));\n        }\n    }\n    return null;\n}\n\n/**\n * Parse explicit height from OSM tags\n * @returns {number|null} Height in meters or null if not specified\n */\nfunction parseExplicitHeight(tags = {}) {\n    const raw =\n        tags.height ||\n        tags['building:height'] ||\n        tags['roof:height'] ||\n        null;\n    if (raw) {\n        const clean = parseFloat(String(raw).replace(/[^\\d.]/g, ''));\n        if (Number.isFinite(clean) && clean > 0) {\n            return THREE.MathUtils.clamp(clean, 2, 500);\n        }\n    }\n    return null;\n}\n\n/**\n * Calculate building height from OSM tags\n * Priority: explicit height > levels * floor height > default estimate\n * @returns {number} Height in meters (always returns a value)\n */\nfunction parseHeight(tags = {}) {\n    // Try explicit height first\n    const explicitHeight = parseExplicitHeight(tags);\n    if (explicitHeight !== null) {\n        return explicitHeight;\n    }\n\n    // Try calculating from levels\n    const levels = parseLevels(tags);\n    if (levels !== null) {\n        return levels * METERS_PER_LEVEL;\n    }\n\n    // Default: estimate based on building type\n    // Most residential buildings are 2-4 stories (6-13m)\n    // Use a more conservative random range\n    return 6 + Math.random() * 8; // 6-14m (roughly 2-4 stories)\n}\n\n/**\n * Format an address string from OSM building tags\n */\nfunction formatAddress(tags = {}) {\n    if (!tags) return 'Unknown address';\n\n    // Check for full address first\n    const full =\n        tags['addr:full'] ||\n        tags['addr:full:en'] ||\n        tags['addr:full:local'];\n    if (full) return full;\n\n    const segments = [];\n\n    // House name\n    if (tags['addr:housename']) segments.push(tags['addr:housename']);\n\n    // Street address\n    const streetParts = [];\n    if (tags['addr:housenumber']) streetParts.push(tags['addr:housenumber']);\n    if (tags['addr:street']) streetParts.push(tags['addr:street']);\n    if (!segments.length && tags['addr:place']) streetParts.push(tags['addr:place']);\n    if (streetParts.length) segments.push(streetParts.join(' '));\n\n    // Locality\n    const localityParts = [];\n    if (tags['addr:unit']) localityParts.push(`Unit ${tags['addr:unit']}`);\n    if (tags['addr:city']) localityParts.push(tags['addr:city']);\n    if (tags['addr:state']) localityParts.push(tags['addr:state']);\n    if (tags['addr:postcode']) localityParts.push(tags['addr:postcode']);\n    if (localityParts.length) segments.push(localityParts.join(', '));\n\n    // Fallbacks\n    if (!segments.length && tags.name) segments.push(tags.name);\n    if (!segments.length && tags['shop']) segments.push(tags['shop']);\n    if (!segments.length && tags['amenity']) segments.push(tags['amenity']);\n    if (!segments.length && tags['building']) segments.push(tags['building']);\n\n    const text = segments\n        .map((s) => String(s).trim())\n        .filter(Boolean)\n        .join(', ');\n    return text || 'Unknown address';\n}\n\n/**\n * Format a building name from OSM tags\n */\nfunction formatBuildingName(tags = {}) {\n    if (!tags) return '';\n    return tags.name\n        || tags['addr:housename']\n        || tags.amenity\n        || tags.shop\n        || (tags.building && tags.building !== 'yes' ? tags.building : '');\n}\n\nexport class BuildingOverlay {\n    constructor({\n        parentGroup,\n        triTree,\n        camera,\n        motionTracker,\n        surfaceController,\n        planetRadius,\n        overpassUrl,\n        overpassTimeoutMs,\n        osmMapTimeoutMs,\n        maxFeatures,\n        surfaceOffsetM,\n        resnapIntervalMs,\n        resnapBudget,\n        resnapToleranceM,\n        resnapFreezeFrames,\n        tileDrivenResnap,\n        fallbackResnapIntervalMs,\n        maxSamplesPerBuilding,\n        lodDetailRadiusM,\n        lodImpostorRadiusM,\n        lodUpdateIntervalMs,\n        lodBudget,\n        lodHysteresisM,\n        impostorEnabled,\n        impostorMinSizeM,\n        impostorMinHeightM,\n        impostorHeightScale,\n        impostorRebuildBudget,\n        polypEnabled,\n        polypMinPointSpacingM,\n        polypMaxPointsPerFootprint,\n        polypMaxEntriesPerTile,\n        polypHeightScale,\n        polypMinHeightM,\n        polypBakeToTiles,\n        alignToTerrainNormal,\n        motionEnabled,\n        motionMinSpeedMps,\n        motionSpeedRefMps,\n        motionAheadFactor,\n        motionBehindFactor,\n        motionQueryBias,\n        motionRetentionFactor,\n        debugLogs,\n        imageryEnabled,\n        imageryUpdateIntervalMs,\n        photorealFallbackEnabled,\n        photoProbeRaysPerFrame,\n        photoProbeBudgetMs,\n        photoCoverageMinHeightM,\n        photoExteriorMarginM,\n        eventBus,\n        sceneInitializer,\n        perf,\n        perfStart,\n        perfEnd,\n        perfRecord,\n        applySliceMs,\n        applyMinBatch,\n        enabled,\n        terrainMode = 'tritree'\n    } = {}) {\n        this.parentGroup = parentGroup || null;\n        this.triTree = triTree || null;\n        this.camera = camera || null;\n        this.motionTracker = motionTracker || null;\n        this.surfaceController = surfaceController || null;\n        this.planetRadius = Number.isFinite(planetRadius) ? planetRadius : PLANET_RADIUS;\n        this.overpassUrl = overpassUrl || OVERPASS_URL;\n        this.overpassTimeoutMs = Number.isFinite(overpassTimeoutMs)\n            ? Math.max(1000, overpassTimeoutMs)\n            : DEFAULT_OVERPASS_TIMEOUT_MS;\n        this.osmMapTimeoutMs = Number.isFinite(osmMapTimeoutMs)\n            ? Math.max(1000, osmMapTimeoutMs)\n            : DEFAULT_OSM_MAP_TIMEOUT_MS;\n        this.maxFeatures = Number.isFinite(maxFeatures) ? maxFeatures : DEFAULT_MAX_FEATURES;\n        this.eventBus = eventBus || null;\n        this.sceneInitializer = sceneInitializer || null;\n        const start = typeof perfStart === 'function'\n            ? perfStart\n            : (perf && typeof perf.start === 'function' ? perf.start.bind(perf) : null);\n        const end = typeof perfEnd === 'function'\n            ? perfEnd\n            : (perf && typeof perf.end === 'function' ? perf.end.bind(perf) : null);\n        const record = typeof perfRecord === 'function'\n            ? perfRecord\n            : (perf && typeof perf.record === 'function' ? perf.record.bind(perf) : null);\n        this._perfStart = start || (() => {});\n        this._perfEnd = end || (() => {});\n        this._perfRecord = record || (() => {});\n        this._applySeq = 0;\n        this.applySliceMs = Number.isFinite(applySliceMs) ? Math.max(1, applySliceMs) : 6;\n        this.applyMinBatch = Number.isFinite(applyMinBatch) ? Math.max(1, Math.floor(applyMinBatch)) : 10;\n        // Surface offset: 0 = building sits exactly on terrain surface\n        this.surfaceOffsetM = Number.isFinite(surfaceOffsetM) ? surfaceOffsetM : 0;\n        this.resnapIntervalMs = Number.isFinite(resnapIntervalMs) ? resnapIntervalMs : 300;\n        this.resnapBudget = Number.isFinite(resnapBudget) ? resnapBudget : 5;\n        this.resnapToleranceM = Number.isFinite(resnapToleranceM) ? resnapToleranceM : 0.25;\n        this.resnapFreezeFrames = Number.isFinite(resnapFreezeFrames) ? resnapFreezeFrames : 2;\n        this.tileDrivenResnap = tileDrivenResnap !== false;\n        this.fallbackResnapIntervalMs = Number.isFinite(fallbackResnapIntervalMs)\n            ? fallbackResnapIntervalMs\n            : this.resnapIntervalMs;\n        this.maxSamplesPerBuilding = Number.isFinite(maxSamplesPerBuilding) ? maxSamplesPerBuilding : 9;\n        this.lodDetailRadiusM = Number.isFinite(lodDetailRadiusM) ? lodDetailRadiusM : DEFAULT_LOD_DETAIL_RADIUS_M;\n        this.lodImpostorRadiusM = Number.isFinite(lodImpostorRadiusM) ? lodImpostorRadiusM : DEFAULT_LOD_IMPOSTOR_RADIUS_M;\n        this.lodUpdateIntervalMs = Number.isFinite(lodUpdateIntervalMs) ? lodUpdateIntervalMs : DEFAULT_LOD_UPDATE_INTERVAL_MS;\n        this.lodBudget = Number.isFinite(lodBudget) ? lodBudget : DEFAULT_LOD_BUDGET;\n        this.lodHysteresisM = Number.isFinite(lodHysteresisM) ? lodHysteresisM : DEFAULT_LOD_HYSTERESIS_M;\n        this.impostorEnabled = impostorEnabled !== false;\n        this.impostorMinSizeM = Number.isFinite(impostorMinSizeM) ? impostorMinSizeM : DEFAULT_IMPOSTOR_MIN_SIZE_M;\n        this.impostorMinHeightM = Number.isFinite(impostorMinHeightM) ? impostorMinHeightM : DEFAULT_IMPOSTOR_MIN_HEIGHT_M;\n        this.impostorHeightScale = Number.isFinite(impostorHeightScale) ? impostorHeightScale : 1;\n        this.impostorRebuildBudget = Number.isFinite(impostorRebuildBudget)\n            ? impostorRebuildBudget\n            : DEFAULT_IMPOSTOR_REBUILD_BUDGET;\n        this.polypEnabled = polypEnabled === true;\n        this.polypMinPointSpacingM = Number.isFinite(polypMinPointSpacingM)\n            ? polypMinPointSpacingM\n            : DEFAULT_POLYP_MIN_POINT_SPACING_M;\n        this.polypMaxPointsPerFootprint = Number.isFinite(polypMaxPointsPerFootprint)\n            ? polypMaxPointsPerFootprint\n            : DEFAULT_POLYP_MAX_POINTS;\n        this.polypMaxEntriesPerTile = Number.isFinite(polypMaxEntriesPerTile)\n            ? polypMaxEntriesPerTile\n            : DEFAULT_POLYP_MAX_ENTRIES_PER_TILE;\n        this.polypHeightScale = Number.isFinite(polypHeightScale)\n            ? polypHeightScale\n            : DEFAULT_POLYP_HEIGHT_SCALE;\n        this.polypMinHeightM = Number.isFinite(polypMinHeightM)\n            ? polypMinHeightM\n            : DEFAULT_POLYP_MIN_HEIGHT_M;\n        this.polypBakeToTiles = polypBakeToTiles === true;\n        this.alignToTerrainNormal = alignToTerrainNormal === true;\n        this.motionEnabled = motionEnabled !== false;\n        this.motionMinSpeedMps = Number.isFinite(motionMinSpeedMps)\n            ? motionMinSpeedMps\n            : DEFAULT_MOTION_MIN_SPEED_MPS;\n        this.motionSpeedRefMps = Number.isFinite(motionSpeedRefMps)\n            ? motionSpeedRefMps\n            : DEFAULT_MOTION_SPEED_REF_MPS;\n        this.motionAheadFactor = Number.isFinite(motionAheadFactor)\n            ? motionAheadFactor\n            : DEFAULT_MOTION_AHEAD_FACTOR;\n        this.motionBehindFactor = Number.isFinite(motionBehindFactor)\n            ? motionBehindFactor\n            : DEFAULT_MOTION_BEHIND_FACTOR;\n        this.motionQueryBias = Number.isFinite(motionQueryBias)\n            ? motionQueryBias\n            : DEFAULT_MOTION_QUERY_BIAS;\n        this.motionRetentionFactor = Number.isFinite(motionRetentionFactor)\n            ? motionRetentionFactor\n            : DEFAULT_MOTION_RETENTION_FACTOR;\n        this.debugLogs = debugLogs === true;\n        this.imageryEnabled = imageryEnabled === true;\n        this.imageryUpdateIntervalMs = Number.isFinite(imageryUpdateIntervalMs)\n            ? imageryUpdateIntervalMs\n            : DEFAULT_IMAGERY_UPDATE_INTERVAL_MS;\n        this.photorealFallbackEnabled = photorealFallbackEnabled === true;\n        this.photoProbeRaysPerFrame = Number.isFinite(photoProbeRaysPerFrame)\n            ? Math.max(1, Math.floor(photoProbeRaysPerFrame))\n            : DEFAULT_PHOTO_PROBE_RAYS_PER_FRAME;\n        this.photoProbeBudgetMs = Number.isFinite(photoProbeBudgetMs)\n            ? Math.max(0.25, photoProbeBudgetMs)\n            : DEFAULT_PHOTO_PROBE_BUDGET_MS;\n        this.photoCoverageMinHeightM = Number.isFinite(photoCoverageMinHeightM)\n            ? Math.max(1, photoCoverageMinHeightM)\n            : DEFAULT_PHOTO_COVERAGE_MIN_HEIGHT_M;\n        this.photoExteriorMarginM = Number.isFinite(photoExteriorMarginM)\n            ? Math.max(1, photoExteriorMarginM)\n            : DEFAULT_PHOTO_EXTERIOR_MARGIN_M;\n        this._photorealFallbackMode = false;\n        this._photoSurfaceQualityReady = false;\n\n        // User preference cannot bypass terrain ownership, including through\n        // old saved settings, the scene API or a direct config event.\n        this._terrainMode = terrainMode;\n        this._requestedEnabled = enabled !== false;\n        this.enabled = terrainMode === 'tritree' && this._requestedEnabled;\n\n        this.group = new THREE.Group();\n        this.group.name = 'BuildingOverlay';\n        this.group.visible = this.enabled;\n        this.parentGroup?.add(this.group);\n\n        // Register building group to be excluded from atmosphere depth passes\n        if (this.sceneInitializer && typeof this.sceneInitializer.addDepthPassExclude === 'function') {\n            this.sceneInitializer.addDepthPassExclude(this.group);\n        }\n\n        this.baseMaterial = new THREE.MeshStandardMaterial({\n            color: 0x8b919a,\n            roughness: 0.9,\n            metalness: 0.02,\n            transparent: true,\n            opacity: 1,\n            polygonOffset: true,\n            polygonOffsetFactor: 1,\n            polygonOffsetUnits: 1\n        });\n        this.baseLineMaterial = new THREE.LineBasicMaterial({\n            color: 0x535a66,\n            transparent: true,\n            opacity: 0.5\n        });\n\n        this._center = null;\n        this._radiusM = 2000;\n        this._falloffStartM = 1500;\n        this._refreshDistanceM = DEFAULT_REFRESH_DISTANCE_M;\n        this._refreshQueued = false;\n        this._cachedBuildings = [];\n        this._inflight = false;\n        this._fetchSeq = 0;\n        this._fetchAbortController = null;\n        this._viewshed = null;\n        this._retryTimer = null;\n        this._retryFailures = 0;\n        this._retryBaseDelayMs = 3000;\n        this._retryMaxDelayMs = 30000;\n        this._instances = [];\n        this._entryMap = new Map();\n        this._resnapTimer = 0;\n        this._resnapSweepIndex = 0;\n        this._tileToEntries = new Map();\n        this._tileGroups = new Map();\n        this._tileGroupByTile = new WeakMap();\n        this._tileSampleCache = new WeakMap();\n        this._pendingEntries = new Set();\n        this._fallbackEntries = new Set();\n        this._dirtyTiles = new Set();\n        this._dirtyTileStamp = new WeakMap();\n        this._dirtyTileCooldownMs = 120;\n        this._pendingTileGroupCleanup = new Set();\n        this._lodTimer = 0;\n        this._lodSweepIndex = 0;\n        this._lodDirtyEntries = new Set();\n        this._impostorMeshes = new Map();\n        this._impostorDirtyTiles = new Set();\n        this._polypMeshes = new Map();\n        this._imageryTimer = 0;\n        this._imageryPendingEntries = new Set();\n        this._photoCoverageQueue = new Set();\n        this._photoCoverageRetryEntries = new Set();\n        this._elevationListener = null;\n        this._tileListener = null;\n        this._tmpQuat = new THREE.Quaternion();\n        this._tmpDir = new THREE.Vector3();\n        this._tmpVec3 = new THREE.Vector3();\n        this._tmpMotionDir = new THREE.Vector3();\n        this._tmpSurfaceVec = new THREE.Vector3();\n        this._tmpTerrainA = new THREE.Vector3();\n        this._tmpTerrainB = new THREE.Vector3();\n        this._tmpTerrainC = new THREE.Vector3();\n        this._tmpMatrix = new THREE.Matrix4();\n        this._tmpScale = new THREE.Vector3();\n        this._tmpPosition = new THREE.Vector3();\n        this._tmpPolypA = new THREE.Vector3();\n        this._tmpPolypB = new THREE.Vector3();\n        this._tmpPolypC = new THREE.Vector3();\n        this._tmpPolypEdge = new THREE.Vector3();\n        this._tmpPolypNormal = new THREE.Vector3();\n        this._tmpPolypUp = new THREE.Vector3();\n        this._tmpPolypLocal = new THREE.Vector3();\n\n        this._impostorGeometry = new THREE.BoxGeometry(1, 1, 1);\n        this._impostorGeometry.translate(0, 0, 0.5);\n        this._impostorGeometry.userData.shared = true;\n        this._impostorMaterial = new THREE.MeshStandardMaterial({\n            color: this.baseMaterial.color.clone(),\n            roughness: 0.95,\n            metalness: 0.02,\n            transparent: true,\n            opacity: 0.85\n        });\n        this._impostorMaterial.userData.shared = true;\n        this._polypMaterial = new THREE.MeshStandardMaterial({\n            color: this.baseMaterial.color.clone(),\n            roughness: 0.95,\n            metalness: 0.02,\n            flatShading: true,\n            transparent: true,\n            opacity: 0.85\n        });\n        this._polypMaterial.userData.shared = true;\n\n        // Hover system\n        this._hoverGroup = new THREE.Group();\n        this._hoverGroup.name = 'building-hover';\n        this._hoverGroup.visible = false;\n        this.group.add(this._hoverGroup);\n\n        this._hoverEdges = null;\n        this._hoverInfo = null;\n        this._pickerRoot = new THREE.Group();\n        this._pickerRoot.name = 'building-picker';\n        this.group.add(this._pickerRoot);\n\n        // Materials for hover highlighting\n        this._highlightEdgeMaterial = new THREE.LineBasicMaterial({\n            color: 0x00ffff,\n            linewidth: 2,\n            transparent: true,\n            opacity: 0.9,\n            depthTest: false\n        });\n\n        // HTML overlay elements (will be lazily created)\n        this._hoverOverlayRoot = null;\n        this._hoverOverlaySvg = null;\n        this._hoverOverlayLine = null;\n        this._hoverCard = null;\n        this._hoverCardName = null;\n        this._hoverCardAddress = null;\n\n        // Address toast elements\n        this._addressToast = null;\n        this._addressToastNameEl = null;\n        this._addressToastAddrEl = null;\n        this._addressToastHideTimer = null;\n        this._motionState = null;\n        this._motionListener = null;\n\n        this._labelSystem = null;\n        this._labelsEnabled = true;\n        this._geometryVisible = true;\n        this._tmpLabelVec = new THREE.Vector3();\n\n        this._bindTileListeners();\n        this._bindConfigListener();\n        this._bindMotionListener();\n    }\n\n    applyWireframeStyle({ fill, line } = {}) {\n        const hasFill = typeof fill === 'string' || typeof fill === 'number';\n        const hasLine = typeof line === 'string' || typeof line === 'number';\n        if (!hasFill && !hasLine) return;\n\n        if (hasFill) {\n            this.baseMaterial.color.set(fill);\n            this.baseMaterial.needsUpdate = true;\n            this._impostorMaterial.color.set(fill);\n            this._impostorMaterial.needsUpdate = true;\n            this._polypMaterial.color.set(fill);\n            this._polypMaterial.needsUpdate = true;\n        }\n        if (hasLine) {\n            this.baseLineMaterial.color.set(line);\n            this.baseLineMaterial.needsUpdate = true;\n        }\n\n        if (!this._instances || !this._instances.length) return;\n        for (const entry of this._instances) {\n            if (hasFill && entry?.mesh?.material) {\n                if (!entry.mesh.material.map) {\n                    entry.mesh.material.color.set(fill);\n                    entry.mesh.material.needsUpdate = true;\n                }\n            }\n            if (hasLine && entry?.outline?.material) {\n                entry.outline.material.color.set(line);\n                entry.outline.material.needsUpdate = true;\n            }\n        }\n    }\n\n    setLabelsEnabled(enabled) {\n        this._labelsEnabled = !!enabled;\n        if (!enabled) {\n            for (const entry of this._instances) {\n                if (entry.labelHandle) {\n                    if (entry.labelHandle.group) this.group.remove(entry.labelHandle.group);\n                    entry.labelHandle.dispose();\n                    entry.labelHandle = null;\n                }\n            }\n        }\n    }\n\n    /**\n     * Hide/show building geometry without disabling the overlay.\n     * When false, meshes/outlines/pickers/impostors are hidden but labels\n     * and the data pipeline (Overpass fetches, entry creation) remain active.\n     * Used by photorealistic tile mode where Cesium tiles provide buildings\n     * but we still want OSM-sourced name labels.\n     */\n    setGeometryVisible(visible) {\n        this._geometryVisible = !!visible;\n        for (const entry of this._instances) {\n            this._syncEntryVisibility(entry);\n        }\n        // Hide/show impostor and polyp tile meshes\n        for (const mesh of this._impostorMeshes.values()) {\n            const target = mesh?.mesh || mesh;\n            if (target) target.visible = visible && !this._photorealFallbackMode;\n        }\n        for (const mesh of this._polypMeshes.values()) {\n            const target = mesh?.mesh || mesh;\n            if (target) target.visible = visible && !this._photorealFallbackMode;\n        }\n    }\n\n    setSurfaceController(surfaceController) {\n        if (this.surfaceController === surfaceController) return;\n        this.surfaceController = surfaceController || null;\n        if (this._photorealFallbackMode && this.photorealFallbackEnabled) {\n            this._queueAllPhotoCoverage({ reset: true, preserveResolved: true });\n        }\n    }\n\n    setPhotorealSurfaceQualityReady(ready) {\n        const next = ready === true;\n        if (this._photoSurfaceQualityReady === next) return;\n        this._photoSurfaceQualityReady = next;\n        if (!next || !this._photorealFallbackMode || !this.photorealFallbackEnabled) return;\n        for (const entry of this._instances) {\n            if (entry.photoCoverageState === 'pending'\n                || entry.photoCoverageState === 'unresolved') {\n                entry.photoCoverageRetryCount = 0;\n                this._queuePhotoCoverage(entry, { reset: true });\n            }\n        }\n    }\n\n    /**\n     * Photoreal mode is a sparse coverage-repair mode. Every OSM solid starts\n     * hidden and becomes visible only after bounded surface probes prove that\n     * the currently rendered Cesium mesh is ground-only at that footprint.\n     */\n    setPhotorealFallbackMode(enabled) {\n        const next = enabled === true;\n        if (this._photorealFallbackMode === next) return;\n        this._photorealFallbackMode = next;\n        this._photoSurfaceQualityReady = false;\n        this._clearPolypMeshes();\n        for (const entry of this._instances) {\n            entry.group?.parent?.remove?.(entry.group);\n            this._attachEntryGroup(entry);\n            if (next && this.photorealFallbackEnabled) {\n                this._queuePhotoCoverage(entry, { reset: true });\n            } else {\n                entry.photoCoverageState = null;\n                entry.photoCoverageProbe = null;\n                entry.photoSurfaceResolved = false;\n                entry.photoCoverageRevalidation = false;\n                entry.pendingVisibility = false;\n                this._clearPhotoTextureProjection(entry);\n                if (this.imageryEnabled) this._imageryPendingEntries.add(entry);\n                this._queueEntryForResnap(entry, { refreshTiles: true });\n                this._queueEntryForLod(entry);\n            }\n            this._syncEntryVisibility(entry);\n        }\n        if (!next) {\n            this._photoCoverageQueue.clear();\n            this._photoCoverageRetryEntries.clear();\n        }\n    }\n\n    _isPhotoFallbackVisible(entry) {\n        if (!this._photorealFallbackMode) return true;\n        return this.photorealFallbackEnabled\n            && entry?.photoCoverageState === 'missing';\n    }\n\n    _hasStablePhotoCoverage(entry) {\n        return entry?.photoSurfaceResolved === true\n            && (entry.photoCoverageState === 'missing'\n                || entry.photoCoverageState === 'present');\n    }\n\n    _syncEntryVisibility(entry) {\n        if (!entry) return;\n        const visible = this._geometryVisible\n            && entry.lod !== 'hidden'\n            && entry.pendingVisibility !== true\n            && this._isPhotoFallbackVisible(entry);\n        if (entry.group) entry.group.visible = visible;\n        if (entry.pickerMesh) entry.pickerMesh.visible = visible;\n        if (entry.labelHandle?.group) {\n            entry.labelHandle.group.visible = !this._photorealFallbackMode\n                || (this.photorealFallbackEnabled\n                    && entry.photoCoverageState === 'missing');\n        }\n    }\n\n    _queuePhotoCoverage(entry, { reset = false, preserveResolved = false } = {}) {\n        if (!entry || !this._photorealFallbackMode || !this.photorealFallbackEnabled) return;\n        if (reset) {\n            const retainStableResult = preserveResolved === true\n                && this._hasStablePhotoCoverage(entry);\n            entry.photoCoverageProbe = null;\n            entry.photoCoverageRestart = false;\n            entry.photoCoverageRevalidation = retainStableResult;\n            if (!retainStableResult) {\n                entry.photoCoverageState = 'pending';\n                entry.photoSurfaceResolved = false;\n            }\n            if (!Number.isFinite(entry.photoCoverageRetryCount)) {\n                entry.photoCoverageRetryCount = 0;\n            }\n        }\n        // A proven repair remains the presentation owner while a replacement\n        // tile hierarchy is classified. The new verdict commits atomically in\n        // _finishPhotoCoverageProbe; no pending gap is exposed to rendering.\n        entry.pendingVisibility = !this._hasStablePhotoCoverage(entry);\n        this._photoCoverageQueue.add(entry);\n        this._syncEntryVisibility(entry);\n    }\n\n    _queueAllPhotoCoverage({ reset = false } = {}) {\n        for (const entry of this._instances) {\n            this._queuePhotoCoverage(entry, { reset });\n        }\n    }\n\n    refreshTerrainAnchors(changes) {\n        if (!this._photorealFallbackMode\n            || !Array.isArray(changes) || changes.length === 0) return 0;\n        let queued = 0;\n        for (const entry of this._instances) {\n            if (!Number.isFinite(entry?.center?.lat) || !Number.isFinite(entry?.center?.lon)) continue;\n            if (!terrainSurfaceChangesAffectLatLon(\n                changes,\n                entry.center.lat,\n                entry.center.lon\n            )) continue;\n            // Do not restart a half-complete bounded probe on every child tile\n            // event. Mark it dirty and requeue once at completion against the\n            // settled hierarchy. This prevents refinement bursts from\n            // starving every footprint at probe zero.\n            if (this._photoCoverageQueue.has(entry) && entry.photoCoverageProbe) {\n                entry.photoCoverageRestart = true;\n                entry.photoCoverageRevalidation = this._hasStablePhotoCoverage(entry);\n                entry.pendingVisibility = !entry.photoCoverageRevalidation;\n                this._syncEntryVisibility(entry);\n            } else {\n                entry.photoCoverageRetryCount = 0;\n                this._photoCoverageRetryEntries.delete(entry);\n                this._queuePhotoCoverage(entry, {\n                    reset: true,\n                    preserveResolved: true,\n                });\n            }\n            queued += 1;\n        }\n        return queued;\n    }\n\n    _ensureLabelSystem() {\n        if (!this._labelSystem) {\n            try {\n                this._labelSystem = getLabelSystem({ planetRadius: this.planetRadius });\n            } catch { /* Label system not available */ }\n        }\n        return this._labelSystem;\n    }\n\n    async load({ center, radiusM = 1000, falloffStartM } = {}) {\n        if (!center || !Number.isFinite(center.lat) || !Number.isFinite(center.lon)) return false;\n        this._radiusM = radiusM;\n        this._falloffStartM = Number.isFinite(falloffStartM)\n            ? falloffStartM\n            : radiusM * 0.7;\n        this._center = { lat: center.lat, lon: center.lon };\n        this._viewshed = null;\n        const window = this._resolveMotionWindow(center.lat, center.lon);\n        return this._fetch(center.lat, center.lon, {\n            queryLat: window.queryLat,\n            queryLon: window.queryLon,\n            radiusM: window.queryRadius,\n            motionWindow: window\n        });\n    }\n\n    async setCenter(lat, lon, opts = {}) {\n        if (!this.enabled) return false;\n        if (!Number.isFinite(lat) || !Number.isFinite(lon)) return false;\n        const nextViewshed = opts.viewshedDriven === true\n            ? buildBuildingViewshed({\n                lat,\n                lon,\n                headingDeg: opts.headingDeg,\n                horizontalFovDeg: opts.horizontalFovDeg,\n                nearRadiusM: opts.nearRadiusM,\n                farRadiusM: opts.radiusM,\n            })\n            : null;\n        const nextCenter = { lat, lon };\n        const dist = this._center\n            ? haversine(lat, lon, this._center.lat, this._center.lon)\n            : Infinity;\n        const refreshDistance = opts.refreshDistanceM || this._refreshDistanceM;\n        const headingThreshold = Number.isFinite(opts.headingRefreshDeg)\n            ? Math.max(3, opts.headingRefreshDeg)\n            : 18;\n        const viewshedChanged = !!nextViewshed !== !!this._viewshed\n            || (nextViewshed && (\n                angularDistanceDeg(nextViewshed.headingDeg, this._viewshed?.headingDeg) >= headingThreshold\n                || Math.abs(nextViewshed.farRadiusM - (this._viewshed?.farRadiusM || 0)) >= 75\n                || Math.abs(nextViewshed.horizontalFovDeg - (this._viewshed?.horizontalFovDeg || 0)) >= 10\n            ));\n        if (dist < refreshDistance && !this._refreshQueued\n            && opts.forceRefresh !== true && !viewshedChanged) return true;\n        this._refreshQueued = false;\n        this._center = nextCenter;\n        if (Number.isFinite(opts.radiusM)) this._radiusM = opts.radiusM;\n        if (Number.isFinite(opts.falloffStartM)) {\n            this._falloffStartM = opts.falloffStartM;\n        }\n        this._viewshed = nextViewshed;\n        const window = this._resolveMotionWindow(lat, lon);\n        window.viewshed = nextViewshed;\n        return this._fetch(lat, lon, {\n            queryLat: window.queryLat,\n            queryLon: window.queryLon,\n            radiusM: window.queryRadius,\n            motionWindow: window,\n            viewshed: nextViewshed,\n        });\n    }\n\n    async refresh() {\n        if (!this.enabled) return false;\n        if (!this._center) return false;\n        const window = this._resolveMotionWindow(this._center.lat, this._center.lon);\n        window.viewshed = this._viewshed;\n        return this._fetch(this._center.lat, this._center.lon, {\n            queryLat: window.queryLat,\n            queryLon: window.queryLon,\n            radiusM: window.queryRadius,\n            motionWindow: window,\n            viewshed: this._viewshed,\n        });\n    }\n\n    clear() {\n        this._applySeq += 1;\n        this._cancelApplyBuildings?.();\n        this._fetchSeq += 1;\n        this._fetchAbortController?.abort?.();\n        this._fetchAbortController = null;\n        this._inflight = false;\n        if (this._retryTimer != null) clearTimeout(this._retryTimer);\n        this._retryTimer = null;\n        // Clear hover state first\n        this.clearHover();\n        this._clearPolypMeshes();\n\n        // Dispose labels\n        for (const entry of this._instances) {\n            if (entry.labelHandle) {\n                if (entry.labelHandle.group) this.group.remove(entry.labelHandle.group);\n                entry.labelHandle.dispose();\n                entry.labelHandle = null;\n            }\n        }\n\n        // Clear picker root children\n        while (this._pickerRoot.children.length) {\n            const child = this._pickerRoot.children.pop();\n            this._pickerRoot.remove(child);\n            if (child.geometry) child.geometry.dispose();\n            if (child.material) child.material.dispose?.();\n        }\n\n        // Clear building groups (skip hover group and picker root which are permanent)\n        const permanentChildren = [this._hoverGroup, this._pickerRoot];\n        const toRemove = this.group.children.filter(c => !permanentChildren.includes(c));\n        for (const child of toRemove) {\n            this.group.remove(child);\n            child.traverse?.((node) => {\n                if (node.geometry && !node.geometry.userData?.shared) {\n                    node.geometry.dispose();\n                }\n                if (node.material) {\n                    if (Array.isArray(node.material)) {\n                        node.material.forEach((mat) => {\n                            if (!mat?.userData?.shared) mat.dispose?.();\n                        });\n                    } else {\n                        if (!node.material.userData?.shared) {\n                            node.material.dispose?.();\n                        }\n                    }\n                }\n            });\n        }\n\n        this._cachedBuildings = [];\n        this._instances = [];\n        this._entryMap.clear();\n        this._tileToEntries.clear();\n        this._tileGroups.clear();\n        this._tileGroupByTile = new WeakMap();\n        this._tileSampleCache = new WeakMap();\n        this._pendingEntries.clear();\n        this._fallbackEntries.clear();\n        this._dirtyTiles.clear();\n        this._dirtyTileStamp = new WeakMap();\n        this._pendingTileGroupCleanup.clear();\n        this._lodTimer = 0;\n        this._lodSweepIndex = 0;\n        this._lodDirtyEntries.clear();\n        this._impostorMeshes.clear();\n        this._impostorDirtyTiles.clear();\n        this._imageryTimer = 0;\n        this._imageryPendingEntries.clear();\n        this._photoCoverageQueue.clear();\n        this._photoCoverageRetryEntries.clear();\n        this._resnapTimer = 0;\n        this._resnapSweepIndex = 0;\n        this._refreshQueued = false;\n    }\n\n    dispose() {\n        this.clear();\n        if (this._retryTimer) {\n            clearTimeout(this._retryTimer);\n            this._retryTimer = null;\n        }\n        this._unbindTileListeners();\n        this._unbindConfigListener();\n        this._unbindMotionListener();\n        if (this.group.parent) {\n            this.group.parent.remove(this.group);\n        }\n    }\n\n    _clearPolypMeshes() {\n        for (const meshInfo of this._polypMeshes.values()) {\n            if (meshInfo?.tile?.applyBuildingFootprints) {\n                meshInfo.tile.applyBuildingFootprints(null);\n            }\n            if (meshInfo?.tile?.setBuildingExtrusions) {\n                meshInfo.tile.setBuildingExtrusions(null);\n            }\n            const mesh = meshInfo?.mesh || null;\n            if (mesh?.parent) {\n                mesh.parent.remove(mesh);\n            }\n            if (mesh?.geometry) {\n                mesh.geometry.dispose();\n            }\n        }\n        this._polypMeshes.clear();\n    }\n\n    _scheduleRetry() {\n        if (this._retryTimer || !this.enabled) return;\n        const failures = Number.isFinite(this._retryFailures) ? this._retryFailures : 0;\n        const delay = Math.min(this._retryBaseDelayMs * (2 ** failures), this._retryMaxDelayMs);\n        this._retryTimer = setTimeout(() => {\n            this._retryTimer = null;\n            if (!this.enabled || !this._center) return;\n            this._refreshQueued = true;\n            this.refresh();\n        }, delay);\n    }\n\n    async _fetchTextWithTimeout(url, init, timeoutMs, requestSignal) {\n        const controller = new AbortController();\n        const relayAbort = () => controller.abort();\n        if (requestSignal?.aborted) controller.abort();\n        else requestSignal?.addEventListener?.('abort', relayAbort, { once: true });\n        const timer = setTimeout(() => controller.abort(), timeoutMs);\n        try {\n            const harness = getAsyncHarness?.();\n            const fetchQueue = harness?.fetchQueue || getFetchQueue();\n            return await fetchQueue.fetchText(url, {\n                ...init,\n                signal: controller.signal,\n            });\n        } finally {\n            clearTimeout(timer);\n            requestSignal?.removeEventListener?.('abort', relayAbort);\n        }\n    }\n\n    async _parseOverpassText(text, signal) {\n        signal?.throwIfAborted();\n        const harness = getAsyncHarness?.();\n        const workerPool = harness?.workerPool || null;\n        const useWorkerParse = !!(harness?.flags?.workerOverpass && workerPool);\n        if (useWorkerParse && text.length >= 8 * 1024) {\n            try {\n                const parsed = await workerPool.run(\n                    'parser-worker',\n                    'parseJSON',\n                    { text },\n                    { timeoutMs: 15000, signal }\n                );\n                if (parsed?.ok) return parsed.data;\n            } catch {\n                signal?.throwIfAborted();\n                // Inline parsing remains the fail-safe for worker churn.\n            }\n        }\n        signal?.throwIfAborted();\n        return JSON.parse(text);\n    }\n\n    _parseOsmMapXml(text) {\n        if (typeof DOMParser === 'undefined') {\n            throw new Error('OSM XML parser unavailable');\n        }\n        const document = new DOMParser().parseFromString(text, 'application/xml');\n        if (document.querySelector('parsererror')) {\n            throw new Error('OSM map returned malformed XML');\n        }\n        const elements = [];\n        for (const node of document.querySelectorAll('node')) {\n            const id = Number(node.getAttribute('id'));\n            const lat = Number(node.getAttribute('lat'));\n            const lon = Number(node.getAttribute('lon'));\n            if (!Number.isFinite(id) || !Number.isFinite(lat) || !Number.isFinite(lon)) continue;\n            elements.push({ type: 'node', id, lat, lon });\n        }\n        for (const way of document.querySelectorAll('way')) {\n            const id = Number(way.getAttribute('id'));\n            if (!Number.isFinite(id)) continue;\n            const nodes = Array.from(way.querySelectorAll(':scope > nd'))\n                .map((node) => Number(node.getAttribute('ref')))\n                .filter(Number.isFinite);\n            const tags = {};\n            for (const tag of way.querySelectorAll(':scope > tag')) {\n                const key = tag.getAttribute('k');\n                if (key) tags[key] = tag.getAttribute('v') || '';\n            }\n            if (nodes.length >= 3 && tags.building) {\n                elements.push({ type: 'way', id, nodes, tags });\n            }\n        }\n        return { version: 0.6, generator: 'openstreetmap-map-fallback', elements };\n    }\n\n    async _fetchOverpassEndpoint(url, query, requestSignal) {\n        try {\n            const result = await this._fetchTextWithTimeout(url, {\n                method: 'POST',\n                headers: {\n                    'Content-Type': 'text/plain',\n                    Accept: 'application/json',\n                },\n                body: query,\n            }, this.overpassTimeoutMs, requestSignal);\n            if (!result?.ok) {\n                return {\n                    ok: false,\n                    error: `Overpass ${result?.status || ''}: ${(result?.text || '').slice(0, 200)}`,\n                };\n            }\n            const text = result.text || '';\n            return { ok: true, data: await this._parseOverpassText(text, requestSignal) };\n        } catch (error) {\n            if (requestSignal?.aborted) throw error;\n            return { ok: false, error: `Overpass request failed: ${error?.message || error}` };\n        }\n    }\n\n    async _fetchOsmMapFallback(queryLat, queryLon, queryRadius, requestSignal) {\n        if (!Number.isFinite(queryRadius) || queryRadius > MAX_OSM_MAP_FALLBACK_RADIUS_M) {\n            return { ok: false, error: 'OSM map fallback window exceeds safety limit' };\n        }\n        try {\n            const latRad = THREE.MathUtils.degToRad(queryLat);\n            const dLat = queryRadius / metersPerDegLat(latRad);\n            const dLon = queryRadius / metersPerDegLon(latRad);\n            const params = new URLSearchParams({\n                bbox: [\n                    (queryLon - dLon).toFixed(6),\n                    (queryLat - dLat).toFixed(6),\n                    (queryLon + dLon).toFixed(6),\n                    (queryLat + dLat).toFixed(6),\n                ].join(','),\n            });\n            const result = await this._fetchTextWithTimeout(\n                `${OSM_MAP_URL}?${params}`,\n                { method: 'GET', headers: { Accept: 'application/xml,text/xml' } },\n                this.osmMapTimeoutMs,\n                requestSignal\n            );\n            if (!result?.ok) {\n                return {\n                    ok: false,\n                    error: `OSM map ${result?.status || ''}: ${(result?.text || '').slice(0, 200)}`,\n                };\n            }\n            const text = result.text || '';\n            if (text.length > 24 * 1024 * 1024) {\n                return { ok: false, error: 'OSM map fallback exceeded 24 MB safety limit' };\n            }\n            return { ok: true, data: this._parseOsmMapXml(text) };\n        } catch (error) {\n            if (requestSignal?.aborted) throw error;\n            return { ok: false, error: `OSM map request failed: ${error?.message || error}` };\n        }\n    }\n\n    async _fetch(lat, lon, opts = {}) {\n        if (!this.enabled) return false;\n        const seq = ++this._fetchSeq;\n        this._fetchAbortController?.abort?.();\n        const requestController = new AbortController();\n        this._fetchAbortController = requestController;\n        this._inflight = true;\n        try {\n            const queryLat = Number.isFinite(opts.queryLat) ? opts.queryLat : lat;\n            const queryLon = Number.isFinite(opts.queryLon) ? opts.queryLon : lon;\n            const queryRadius = Number.isFinite(opts.radiusM) ? opts.radiusM : this._radiusM;\n            const viewshed = opts.viewshed || null;\n            const query = buildBuildingOverpassQuery({\n                queryLat,\n                queryLon,\n                queryRadius,\n                viewshed,\n            });\n\n            const urls = [this.overpassUrl, ...OVERPASS_FALLBACK_URLS]\n                .filter(Boolean)\n                .filter((value, index, arr) => arr.indexOf(value) === index);\n\n            let result = null;\n            const primaryUrl = urls.shift();\n            if (primaryUrl) {\n                result = await this._fetchOverpassEndpoint(\n                    primaryUrl,\n                    query,\n                    requestController.signal\n                );\n            }\n            if (!result?.ok && viewshed && this.overpassUrl !== OVERPASS_URL) {\n                result = await this._fetchOsmMapFallback(\n                    viewshed.centerLat,\n                    viewshed.centerLon,\n                    viewshed.farRadiusM,\n                    requestController.signal\n                );\n            }\n            for (const url of urls) {\n                if (result?.ok) break;\n                result = await this._fetchOverpassEndpoint(url, query, requestController.signal);\n                if (this.debugLogs) {\n                    console.warn('[BuildingOverlay] Overpass fetch failed:', result.error, 'url:', url);\n                }\n            }\n\n            if (!result || !result.ok) {\n                throw new Error(result?.error || 'Overpass request failed');\n            }\n\n            const json = result.data;\n            if (seq !== this._fetchSeq || requestController.signal.aborted) return false;\n            this._retryFailures = 0;\n            await this._applyBuildings(json, lat, lon, opts.motionWindow || null);\n            if (seq !== this._fetchSeq || requestController.signal.aborted) return false;\n            return true;\n        } catch (error) {\n            if (seq !== this._fetchSeq || requestController.signal.aborted) return false;\n            console.warn('Building fetch failed', error);\n            this.eventBus?.emit('buildings:error', { error });\n            this._retryFailures = (this._retryFailures || 0) + 1;\n            this._refreshQueued = true;\n            this._scheduleRetry();\n            return false;\n        } finally {\n            if (seq === this._fetchSeq) {\n                this._inflight = false;\n                if (this._fetchAbortController === requestController) {\n                    this._fetchAbortController = null;\n                }\n            }\n        }\n    }\n\n    _getMotionState() {\n        if (this._motionState) return this._motionState;\n        if (this.motionTracker && typeof this.motionTracker.getState === 'function') {\n            return this.motionTracker.getState();\n        }\n        return null;\n    }\n\n    _resolveMotionWindow(centerLat, centerLon) {\n        const baseRadius = Number.isFinite(this._radiusM) ? this._radiusM : 0;\n        const centerDir = latLonToLocalDir(centerLat, centerLon).normalize();\n        const falloffRatio = baseRadius > 0\n            ? THREE.MathUtils.clamp(this._falloffStartM / baseRadius, 0.05, 0.95)\n            : 0.7;\n        const window = {\n            centerLat,\n            centerLon,\n            centerDir,\n            queryLat: centerLat,\n            queryLon: centerLon,\n            queryRadius: baseRadius,\n            aheadRadius: baseRadius,\n            behindRadius: baseRadius,\n            falloffRatio,\n            motionDir: null,\n            motionAlpha: 0\n        };\n\n        if (!this.motionEnabled || baseRadius <= 0) {\n            return window;\n        }\n\n        const motion = this._getMotionState();\n        if (!motion?.tangentDir) {\n            return window;\n        }\n\n        const speed = Number.isFinite(motion.speedMps) ? motion.speedMps : 0;\n        const minSpeed = Number.isFinite(this.motionMinSpeedMps) ? this.motionMinSpeedMps : 0;\n        if (speed <= minSpeed) {\n            return window;\n        }\n\n        const speedRef = Number.isFinite(this.motionSpeedRefMps)\n            ? Math.max(this.motionSpeedRefMps, minSpeed + 0.01)\n            : DEFAULT_MOTION_SPEED_REF_MPS;\n        const motionAlpha = THREE.MathUtils.clamp((speed - minSpeed) / speedRef, 0, 1);\n        window.motionAlpha = motionAlpha;\n        window.aheadRadius = baseRadius * THREE.MathUtils.lerp(1, this.motionAheadFactor, motionAlpha);\n        window.behindRadius = baseRadius * THREE.MathUtils.lerp(1, this.motionBehindFactor, motionAlpha);\n\n        const rawMotionDir = this._tmpMotionDir.copy(motion.tangentDir).normalize();\n        const radialComponent = rawMotionDir.dot(centerDir);\n        rawMotionDir.addScaledVector(centerDir, -radialComponent);\n        if (rawMotionDir.lengthSq() < 1e-6) {\n            return window;\n        }\n        rawMotionDir.normalize();\n        window.motionDir = rawMotionDir.clone();\n\n        const bias = Number.isFinite(this.motionQueryBias) ? this.motionQueryBias : DEFAULT_MOTION_QUERY_BIAS;\n        const biasDistance = baseRadius * THREE.MathUtils.clamp(bias, 0, 1) * motionAlpha;\n        if (biasDistance > 0) {\n            const shifted = this._tmpVec3.copy(centerDir).multiplyScalar(this.planetRadius)\n                .add(this._tmpSurfaceVec.copy(rawMotionDir).multiplyScalar(biasDistance))\n                .normalize();\n            const shiftedLatLon = dirToLatLonLocal(shifted);\n            if (shiftedLatLon && Number.isFinite(shiftedLatLon.lat) && Number.isFinite(shiftedLatLon.lon)) {\n                window.queryLat = shiftedLatLon.lat;\n                window.queryLon = shiftedLatLon.lon;\n            }\n        }\n\n        const queryRadius = Math.max(window.aheadRadius, window.behindRadius, baseRadius + biasDistance);\n        window.queryRadius = queryRadius;\n\n        return window;\n    }\n\n    _computeDirectionalDot(centerDir, entryDir, motionDir) {\n        if (!motionDir || !centerDir || !entryDir) return 0;\n        const radial = entryDir.dot(centerDir);\n        this._tmpSurfaceVec.copy(entryDir).addScaledVector(centerDir, -radial);\n        if (this._tmpSurfaceVec.lengthSq() < 1e-8) return 0;\n        this._tmpSurfaceVec.normalize();\n        return THREE.MathUtils.clamp(this._tmpSurfaceVec.dot(motionDir), -1, 1);\n    }\n\n    _isInsideViewshed(lat, lon, distanceM, viewshed) {\n        if (!viewshed) return true;\n        if (distanceM <= viewshed.nearRadiusM) return true;\n        if (distanceM > viewshed.farRadiusM) return false;\n        const centerLatRad = THREE.MathUtils.degToRad(viewshed.centerLat);\n        const northM = (lat - viewshed.centerLat) * metersPerDegLat(centerLatRad);\n        const eastM = (lon - viewshed.centerLon) * metersPerDegLon(centerLatRad);\n        const bearing = ((THREE.MathUtils.radToDeg(Math.atan2(eastM, northM)) % 360) + 360) % 360;\n        return angularDistanceDeg(bearing, viewshed.headingDeg)\n            <= viewshed.horizontalFovDeg * 0.5 + 4;\n    }\n\n    _computeEntryMetrics(entry, centerLat, centerLon, window) {\n        const center = entry?.center || entry?.info?.center;\n        if (!center) return { distance: Infinity, falloff: 0, dirRadius: window?.behindRadius || this._radiusM };\n        const distance = haversine(center.lat, center.lon, centerLat, centerLon);\n        let dirRadius = this._radiusM;\n        let falloffStart = this._falloffStartM;\n        if (window?.motionDir) {\n            const entryDir = entry.dir || latLonToLocalDir(center.lat, center.lon).normalize();\n            const dot = this._computeDirectionalDot(window.centerDir, entryDir, window.motionDir);\n            const bias = (dot + 1) * 0.5;\n            dirRadius = THREE.MathUtils.lerp(window.behindRadius, window.aheadRadius, bias);\n            falloffStart = dirRadius * window.falloffRatio;\n        }\n        const falloff = this._falloffFactor(distance, dirRadius, falloffStart);\n        return { distance, falloff, dirRadius };\n    }\n\n    _applyEntryFalloff(entry, falloff) {\n        if (!entry) return;\n        entry.falloff = falloff;\n        if (entry.mesh?.material) {\n            entry.mesh.material.opacity = this.baseMaterial.opacity * falloff;\n            entry.mesh.material.needsUpdate = true;\n        }\n        if (entry.outline?.material) {\n            entry.outline.material.opacity = this.baseLineMaterial.opacity * falloff;\n            entry.outline.material.needsUpdate = true;\n        }\n    }\n\n    /**\n     * Check if entry has valid terrain data for reliable positioning.\n     * Buildings should NEVER render unless mated to actual terrain.\n     * This is the final gate before visibility - checks terrain across footprint.\n     * @returns {boolean} true if terrain data is valid and reliable\n     */\n    _hasValidTerrainForEntry(entry) {\n        if (!entry?.dir) return false;\n\n        if (this._photorealFallbackMode) {\n            return this.photorealFallbackEnabled\n                && entry.photoCoverageState === 'missing'\n                && entry.photoSurfaceResolved === true\n                && Number.isFinite(entry.surfaceRadius)\n                && Number.isFinite(entry.maxRadius);\n        }\n\n        // Verify surfaceRadius has been set to a valid value\n        const surfaceR = entry.surfaceRadius;\n        if (!Number.isFinite(surfaceR) || surfaceR <= 0) return false;\n\n        // Must have maxRadius set (used for positioning)\n        const maxR = entry.maxRadius;\n        if (!Number.isFinite(maxR) || maxR <= 0) return false;\n\n        // The tile covering this entry must have elevation data\n        const tile = entry.primaryTile;\n        if (!tile || tile.elevationHasData !== true) return false;\n\n        // Check multiple sample points across footprint, not just center\n        // This ensures the ENTIRE footprint has valid terrain, not just center\n        const sampleDirs = entry.sampleDirs;\n        if (Array.isArray(sampleDirs) && sampleDirs.length > 0) {\n            // Check center + corners (up to 5 points for performance)\n            const checkDirs = sampleDirs.length <= 5\n                ? sampleDirs\n                : [\n                    sampleDirs[0], // center\n                    sampleDirs[Math.floor(sampleDirs.length * 0.25)],\n                    sampleDirs[Math.floor(sampleDirs.length * 0.5)],\n                    sampleDirs[Math.floor(sampleDirs.length * 0.75)],\n                    sampleDirs[sampleDirs.length - 1]\n                ].filter(Boolean);\n\n            for (const dir of checkDirs) {\n                if (!dir) continue;\n                const sample = this._sampleTerrainRadiusForDir(dir, tile, false);\n                if (!sample.hasData) return false;\n                if (!Number.isFinite(sample.radius) || sample.radius <= 0) return false;\n            }\n        } else {\n            // Fallback to center-only check\n            const sample = this._sampleTerrainRadiusForDir(entry.dir, tile, false);\n            if (!sample.hasData) return false;\n            if (!Number.isFinite(sample.radius) || sample.radius <= 0) return false;\n        }\n\n        return true;\n    }\n\n    _sampleTerrainRadiusForDir(localDir, tile = null, allowRaycast = true) {\n        if (!localDir) {\n            return { radius: this.planetRadius, hasData: false };\n        }\n        const ellipsoidR = ellipsoidRadiusForLocalDir(localDir);\n        const worldDir = this._tmpDir.copy(localDir).normalize();\n        const worldQuat = this.parentGroup?.getWorldQuaternion?.(this._tmpQuat)\n            || this.triTree?.group?.getWorldQuaternion?.(this._tmpQuat)\n            || null;\n        if (worldQuat) worldDir.applyQuaternion(worldQuat);\n\n        if (this.surfaceController?.photoTileGroup\n            && typeof this.surfaceController.sampleTerrainRadiusForDir === 'function') {\n            const radius = this.surfaceController.sampleTerrainRadiusForDir(worldDir, {\n                mutateCache: false,\n                requireFreshPhotoHit: true,\n                allowTriTreeFallback: false,\n                skipWorldMatrixUpdate: true,\n            });\n            return Number.isFinite(radius) && radius > 0\n                ? { radius, hasData: true }\n                : { radius: ellipsoidR, hasData: false };\n        }\n\n        if (!this.triTree) {\n            return { radius: ellipsoidR, hasData: false };\n        }\n        const leaf = tile || this.triTree.findLeafTileForWorldDir?.(worldDir);\n        if (!leaf?.elevationHasData) {\n            return { radius: ellipsoidR, hasData: false };\n        }\n        let radius = null;\n        if (allowRaycast && typeof this.triTree.sampleTerrainRadiusForDir === 'function') {\n            radius = this.triTree.sampleTerrainRadiusForDir(worldDir);\n        }\n        if (!Number.isFinite(radius) || radius <= 0) {\n            radius = this.triTree.getSurfaceRadiusAtDir?.(worldDir);\n        }\n        if (!Number.isFinite(radius) || radius <= 0) {\n            return { radius: ellipsoidR, hasData: false };\n        }\n        return { radius, hasData: true };\n    }\n\n    _applyTerrainFrame(entry, centerSample = null, allowRaycast = true) {\n        if (!entry?.center || !entry?.dir || !entry?.baseEast || !entry?.baseNorth) return false;\n        const centerInfo = centerSample || this._sampleTerrainRadiusForDir(entry.dir, null, allowRaycast);\n        const hasCenterRadius = centerInfo && Number.isFinite(centerInfo.radius);\n        if (!hasCenterRadius && this.alignToTerrainNormal) return false;\n\n        if (!this.alignToTerrainNormal) {\n            const up = this._tmpSurfaceVec.copy(entry.dir).normalize();\n            let east = this._tmpVec3.copy(entry.baseEast);\n            east.addScaledVector(up, -east.dot(up));\n            if (east.lengthSq() < 1e-6) {\n                east.copy(entry.baseNorth);\n                east.addScaledVector(up, -east.dot(up));\n            }\n            if (east.lengthSq() < 1e-6) {\n                return false;\n            }\n            east.normalize();\n            const north = this._tmpTerrainA.copy(up).cross(east).normalize();\n\n            this._tmpMatrix.makeBasis(east, north, up);\n            const quat = this._tmpQuat.setFromRotationMatrix(this._tmpMatrix);\n            entry.group.quaternion.copy(quat);\n            entry.terrainNormal = entry.terrainNormal || new THREE.Vector3();\n            entry.terrainNormal.copy(up);\n\n            const lift = Number.isFinite(this.surfaceOffsetM) ? this.surfaceOffsetM : 0;\n            const baseRadius = Number.isFinite(entry.surfaceRadius)\n                ? entry.surfaceRadius\n                : (Number.isFinite(entry.maxRadius)\n                    ? entry.maxRadius\n                    : (hasCenterRadius ? centerInfo.radius : this.planetRadius));\n            entry.group.position.copy(up).multiplyScalar(baseRadius + lift);\n\n            if (entry.pickerMesh) {\n                entry.pickerMesh.quaternion.copy(quat);\n                entry.pickerMesh.position.copy(entry.group.position);\n            }\n\n            if (entry.group?.userData) {\n                if (entry.group.userData.surfaceDir?.isVector3) {\n                    entry.group.userData.surfaceDir.copy(up);\n                } else {\n                    entry.group.userData.surfaceDir = up.clone();\n                }\n            }\n\n            return true;\n        }\n\n        if (!centerInfo?.hasData || !Number.isFinite(centerInfo.radius)) return false;\n        const latRad = THREE.MathUtils.degToRad(entry.center.lat);\n        const metersLat = Math.max(0.0001, metersPerDegLat(latRad));\n        const metersLon = Math.max(0.0001, metersPerDegLon(latRad));\n        const bounds = entry.bounds || {};\n        const span = Math.max(\n            8,\n            Math.min(40, Math.max(bounds.width || 0, bounds.depth || 0) * 0.25 || 12)\n        );\n        const dLat = span / metersLat;\n        const dLon = span / metersLon;\n\n        const eastDir = latLonToLocalDir(entry.center.lat, entry.center.lon + dLon).normalize();\n        const northDir = latLonToLocalDir(entry.center.lat + dLat, entry.center.lon).normalize();\n\n        const eastSample = this._sampleTerrainRadiusForDir(eastDir, null, allowRaycast);\n        const northSample = this._sampleTerrainRadiusForDir(northDir, null, allowRaycast);\n\n        if (!eastSample.hasData || !northSample.hasData) return false;\n\n        const centerPos = this._tmpTerrainA.copy(entry.dir).multiplyScalar(centerInfo.radius);\n        const eastPos = this._tmpTerrainB.copy(eastDir).multiplyScalar(eastSample.radius);\n        const northPos = this._tmpTerrainC.copy(northDir).multiplyScalar(northSample.radius);\n\n        const vEast = eastPos.sub(centerPos);\n        const vNorth = northPos.sub(centerPos);\n        if (vEast.lengthSq() < 1e-6 || vNorth.lengthSq() < 1e-6) return false;\n\n        const normal = vEast.cross(vNorth).normalize();\n        if (normal.dot(entry.dir) < 0) {\n            normal.negate();\n        }\n\n        let east = this._tmpVec3.copy(entry.baseEast);\n        east.addScaledVector(normal, -east.dot(normal));\n        if (east.lengthSq() < 1e-6) {\n            east.copy(vEast).normalize();\n        } else {\n            east.normalize();\n        }\n        const north = this._tmpSurfaceVec.copy(normal).cross(east).normalize();\n\n        this._tmpMatrix.makeBasis(east, north, normal);\n        const quat = this._tmpQuat.setFromRotationMatrix(this._tmpMatrix);\n        entry.group.quaternion.copy(quat);\n        entry.terrainNormal = entry.terrainNormal || new THREE.Vector3();\n        entry.terrainNormal.copy(normal);\n\n        const lift = Number.isFinite(this.surfaceOffsetM) ? this.surfaceOffsetM : 0;\n        entry.group.position.copy(centerPos).addScaledVector(normal, lift);\n\n        if (entry.pickerMesh) {\n            entry.pickerMesh.quaternion.copy(quat);\n            entry.pickerMesh.position.copy(entry.group.position);\n        }\n\n        if (entry.group?.userData) {\n            if (entry.group.userData.surfaceDir?.isVector3) {\n                entry.group.userData.surfaceDir.copy(normal);\n            } else {\n                entry.group.userData.surfaceDir = normal.clone();\n            }\n        }\n\n        // Update label position at top of building\n        if (entry.labelHandle) {\n            const bldgHeight = Number.isFinite(entry.info?.height) ? entry.info.height : 10;\n            this._tmpLabelVec.copy(entry.group.position).addScaledVector(normal, bldgHeight);\n            const ls = this._ensureLabelSystem();\n            if (ls) ls.updatePosition(entry.labelHandle, this._tmpLabelVec);\n        }\n\n        return true;\n    }\n\n    _removeEntry(entry) {\n        if (!entry) return;\n        if (entry.labelHandle) {\n            if (entry.labelHandle.group) this.group.remove(entry.labelHandle.group);\n            entry.labelHandle.dispose();\n            entry.labelHandle = null;\n        }\n        if (entry.pickerMesh && entry.pickerMesh.parent) {\n            entry.pickerMesh.parent.remove(entry.pickerMesh);\n            entry.pickerMesh.geometry?.dispose?.();\n            entry.pickerMesh.material?.dispose?.();\n        }\n        if (entry.group?.parent) {\n            entry.group.parent.remove(entry.group);\n        }\n        entry.group?.traverse?.((node) => {\n            if (node.geometry && !node.geometry.userData?.shared) {\n                node.geometry.dispose();\n            }\n            if (node.material) {\n                if (Array.isArray(node.material)) {\n                    node.material.forEach((mat) => mat?.dispose?.());\n                } else {\n                    node.material.dispose?.();\n                }\n            }\n        });\n\n        if (entry.tiles) {\n            for (const tile of entry.tiles) {\n                const bucket = this._tileToEntries.get(tile);\n                if (bucket) {\n                    bucket.delete(entry);\n                    if (!bucket.size) this._tileToEntries.delete(tile);\n                }\n            }\n        }\n        if (entry.primaryTile) {\n            this._queueTileForImpostorRebuild(entry.primaryTile);\n            this._queueTileGroupCleanup(entry.primaryTile);\n        }\n        this._pendingEntries.delete(entry);\n        this._fallbackEntries.delete(entry);\n        this._lodDirtyEntries.delete(entry);\n        this._imageryPendingEntries.delete(entry);\n        this._photoCoverageQueue.delete(entry);\n        this._photoCoverageRetryEntries.delete(entry);\n        if (this.polypBakeToTiles || this.polypEnabled) {\n            this._queueEntryTilesForBake(entry);\n        }\n        const idx = this._instances.indexOf(entry);\n        if (idx >= 0) this._instances.splice(idx, 1);\n    }\n\n    async _applyBuildings(data, centerLat, centerLon, motionWindow = null) {\n        if (!this.enabled) return false;\n        this._cancelApplyBuildings?.();\n        const seq = ++this._applySeq;\n        const now = () => (typeof performance !== 'undefined' && performance.now)\n            ? performance.now()\n            : Date.now();\n        const window = motionWindow || this._resolveMotionWindow(centerLat, centerLon);\n        this._perfStart('cpu.buildings.apply.prepare');\n        let candidates = [];\n        try {\n            if (this.debugLogs) {\n                console.log(`[BuildingOverlay] _applyBuildings called: center=${centerLat.toFixed(4)},${centerLon.toFixed(4)}, elements=${data?.elements?.length || 0}`);\n            }\n            this._cachedBuildings = [];\n            const nodes = new Map();\n            for (const el of data.elements || []) {\n                if (el.type === 'node') nodes.set(el.id, el);\n            }\n\n            candidates = [];\n            for (const el of data.elements || []) {\n                if (el.type !== 'way' || !el.nodes || !el.tags || !el.tags.building) continue;\n                const footprint = [];\n                for (const nodeId of el.nodes) {\n                    const node = nodes.get(nodeId);\n                    if (!node) continue;\n                    footprint.push([node.lat, node.lon]);\n                }\n                if (footprint.length < 3) continue;\n                const center = this._averageLatLon(footprint);\n                if (!center) continue;\n                const distance = haversine(center.lat, center.lon, centerLat, centerLon);\n                if (!this._isInsideViewshed(center.lat, center.lon, distance, window?.viewshed)) {\n                    continue;\n                }\n                let dirRadius = this._radiusM;\n                let falloffStart = this._falloffStartM;\n                if (window?.motionDir) {\n                    const entryDir = latLonToLocalDir(center.lat, center.lon).normalize();\n                    const dot = this._computeDirectionalDot(window.centerDir, entryDir, window.motionDir);\n                    const bias = (dot + 1) * 0.5;\n                    dirRadius = THREE.MathUtils.lerp(window.behindRadius, window.aheadRadius, bias);\n                    falloffStart = dirRadius * window.falloffRatio;\n                }\n                if (distance > dirRadius) continue;\n                const falloff = this._falloffFactor(distance, dirRadius, falloffStart);\n                if (falloff <= 0.01) continue;\n                candidates.push({\n                    id: el.id,\n                    center,\n                    distance,\n                    falloff,\n                    footprint,\n                    tags: el.tags\n                });\n            }\n        } finally {\n            this._perfEnd('cpu.buildings.apply.prepare');\n        }\n\n        candidates.sort((a, b) => {\n            if (a.distance !== b.distance) return a.distance - b.distance;\n            if (Number.isFinite(a.id) && Number.isFinite(b.id)) return a.id - b.id;\n            return 0;\n        });\n\n        const maxCount = Number.isFinite(this.maxFeatures)\n            ? Math.max(0, Math.floor(this.maxFeatures))\n            : Infinity;\n        const limitedCandidates = Number.isFinite(maxCount)\n            ? candidates.slice(0, maxCount)\n            : candidates;\n\n        let index = 0;\n        const seen = new Set();\n\n        // requestIdleCallback may starve behind a continuously active WebGL\n        // and 3D Tiles workload. A zero-delay task with the same strict clock\n        // budget makes deterministic progress and still yields between every\n        // bounded mesh batch.\n        const applied = await new Promise((resolve) => {\n            let timer = null;\n            const finish = (value) => {\n                if (timer != null) clearTimeout(timer);\n                timer = null;\n                if (this._cancelApplyBuildings === cancel) this._cancelApplyBuildings = null;\n                resolve(value);\n            };\n            const cancel = () => finish(false);\n            this._cancelApplyBuildings = cancel;\n            const schedule = (fn) => { timer = setTimeout(() => { timer = null; fn(null); }, 0); };\n            const step = (deadline) => {\n                if (seq !== this._applySeq || !this.enabled) return finish(false);\n                this._perfStart('cpu.buildings.apply');\n                try {\n                    const sliceStart = now();\n                    let processed = 0;\n                    const sliceEntries = [];\n                    while (index < limitedCandidates.length) {\n                        const candidate = limitedCandidates[index];\n                        index += 1;\n                        const key = String(candidate.id);\n                        const existing = this._entryMap.get(key) || null;\n                        if (existing) {\n                            existing.tags = candidate.tags;\n                            if (existing.info) existing.info.tags = { ...candidate.tags };\n                            existing.center = candidate.center;\n                            this._applyEntryFalloff(existing, candidate.falloff);\n                            seen.add(key);\n                        } else {\n                            const entry = this._meshingFromFootprint(\n                                candidate.footprint,\n                                candidate.tags,\n                                candidate.falloff\n                            );\n                            if (entry) {\n                                entry.osmId = candidate.id;\n                                entry.entryKey = key;\n                                entry.center = candidate.center;\n                                this._applyEntryFalloff(entry, candidate.falloff);\n                                this._entryMap.set(key, entry);\n                                sliceEntries.push(entry);\n                                this._cachedBuildings.push({ footprint: candidate.footprint, tags: candidate.tags });\n                                seen.add(key);\n                            }\n                        }\n                        processed += 1;\n                        if (processed >= this.applyMinBatch &&\n                            (now() - sliceStart) >= this.applySliceMs) {\n                            break;\n                        }\n                        if (deadline && typeof deadline.timeRemaining === 'function' &&\n                            deadline.timeRemaining() <= 0) {\n                            break;\n                        }\n                    }\n                    if (sliceEntries.length) {\n                        this._appendEntries(sliceEntries);\n                    }\n                } finally {\n                    this._perfEnd('cpu.buildings.apply');\n                }\n                if (seq !== this._applySeq || !this.enabled) return finish(false);\n                if (index < limitedCandidates.length) {\n                    schedule(step);\n                    return;\n                }\n                finish(true);\n            };\n            schedule(step);\n        });\n        if (!applied || seq !== this._applySeq || !this.enabled) return false;\n\n        const retention = Number.isFinite(this.motionRetentionFactor)\n            ? Math.max(this.motionRetentionFactor, 1)\n            : DEFAULT_MOTION_RETENTION_FACTOR;\n        const removals = [];\n        for (const [key, entry] of this._entryMap.entries()) {\n            if (seen.has(key)) continue;\n            const metrics = this._computeEntryMetrics(entry, centerLat, centerLon, window);\n            const limit = metrics.dirRadius * retention;\n            if (!Number.isFinite(metrics.distance) || metrics.distance > limit) {\n                removals.push(key);\n                continue;\n            }\n            this._applyEntryFalloff(entry, metrics.falloff);\n        }\n        for (const key of removals) {\n            const entry = this._entryMap.get(key);\n            if (entry) {\n                this._removeEntry(entry);\n                this._entryMap.delete(key);\n            }\n        }\n\n        if (Number.isFinite(maxCount) && this._entryMap.size > maxCount) {\n            const overflow = this._entryMap.size - maxCount;\n            if (overflow > 0) {\n                const distances = [];\n                for (const entry of this._entryMap.values()) {\n                    const metrics = this._computeEntryMetrics(entry, centerLat, centerLon, window);\n                    distances.push({ entry, distance: metrics.distance });\n                }\n                distances.sort((a, b) => b.distance - a.distance);\n                for (let i = 0; i < distances.length && this._entryMap.size > maxCount; i += 1) {\n                    const entry = distances[i].entry;\n                    if (!entry) continue;\n                    const key = entry.entryKey || String(entry.osmId ?? '');\n                    this._removeEntry(entry);\n                    if (key) this._entryMap.delete(key);\n                }\n            }\n        }\n\n        this._appendEntries([], { final: true });\n        const count = this._instances.length;\n        if (this.debugLogs) {\n            console.log(`[BuildingOverlay] Created ${count} building entries, polypBakeToTiles=${this.polypBakeToTiles}`);\n        }\n    }\n\n    _falloffFactor(distance, radius = this._radiusM, falloffStart = this._falloffStartM) {\n        if (distance <= falloffStart) return 1;\n        if (distance >= radius) return 0;\n        const t = (radius - distance) / (radius - falloffStart);\n        return THREE.MathUtils.clamp(t, 0, 1);\n    }\n\n    _buildSampleDirs(latLonPairs, center) {\n        const pairs = Array.isArray(latLonPairs) ? latLonPairs : [];\n        const maxSamples = Math.max(1, Math.floor(this.maxSamplesPerBuilding || 1));\n        const hasCenter = center && Number.isFinite(center.lat) && Number.isFinite(center.lon);\n        const samples = [];\n        const seen = new Set();\n\n        const pushPair = (lat, lon) => {\n            if (!Number.isFinite(lat) || !Number.isFinite(lon)) return;\n            if (samples.length >= maxSamples) return;\n            const key = `${lat.toFixed(6)},${lon.toFixed(6)}`;\n            if (seen.has(key)) return;\n            seen.add(key);\n            samples.push(latLonToLocalDir(lat, lon).normalize());\n        };\n\n        if (pairs.length) {\n            let minLatPair = null;\n            let maxLatPair = null;\n            let minLonPair = null;\n            let maxLonPair = null;\n            for (const pair of pairs) {\n                if (!pair) continue;\n                const lat = pair[0];\n                const lon = pair[1];\n                if (!Number.isFinite(lat) || !Number.isFinite(lon)) continue;\n                if (!minLatPair || lat < minLatPair[0]) minLatPair = pair;\n                if (!maxLatPair || lat > maxLatPair[0]) maxLatPair = pair;\n                if (!minLonPair || lon < minLonPair[1]) minLonPair = pair;\n                if (!maxLonPair || lon > maxLonPair[1]) maxLonPair = pair;\n            }\n            if (minLatPair) pushPair(minLatPair[0], minLatPair[1]);\n            if (maxLatPair) pushPair(maxLatPair[0], maxLatPair[1]);\n            if (minLonPair) pushPair(minLonPair[0], minLonPair[1]);\n            if (maxLonPair) pushPair(maxLonPair[0], maxLonPair[1]);\n        }\n\n        const budget = Math.max(0, maxSamples - samples.length - (hasCenter ? 1 : 0));\n\n        if (pairs.length && budget > 0) {\n            if (pairs.length <= budget) {\n                for (const pair of pairs) {\n                    if (!pair) continue;\n                    const lat = pair[0];\n                    const lon = pair[1];\n                    pushPair(lat, lon);\n                }\n            } else {\n                const stride = pairs.length / budget;\n                for (let i = 0; i < budget; i++) {\n                    const idx = Math.floor(i * stride);\n                    const pair = pairs[idx];\n                    if (!pair) continue;\n                    const lat = pair[0];\n                    const lon = pair[1];\n                    pushPair(lat, lon);\n                }\n            }\n        }\n\n        if (hasCenter) {\n            pushPair(center.lat, center.lon);\n        }\n\n        return samples;\n    }\n\n    _photoProbeDir(entry, x, y) {\n        const center = entry?.center;\n        if (!center) return null;\n        const latRad = THREE.MathUtils.degToRad(center.lat);\n        const mLat = Math.max(0.0001, metersPerDegLat(latRad));\n        const mLon = Math.max(0.0001, metersPerDegLon(latRad));\n        return latLonToLocalDir(\n            center.lat + (y / mLat),\n            center.lon + (x / mLon)\n        ).normalize();\n    }\n\n    _createPhotoCoverageProbe(entry) {\n        const footprint = Array.isArray(entry?.footprintLocal)\n            ? entry.footprintLocal.filter((p) => Number.isFinite(p?.x) && Number.isFinite(p?.y))\n            : [];\n        if (footprint.length < 3) return null;\n\n        // Four well-spaced rays inside the footprint plus four just outside\n        // it provide a roof-vs-ground signature without scaling with polygon\n        // vertex count. The queue executes only a couple of these per frame.\n        const selected = [];\n        const count = Math.min(4, footprint.length);\n        for (let i = 0; i < count; i += 1) {\n            selected.push(footprint[Math.floor((i * footprint.length) / count)]);\n        }\n        const probes = [{ kind: 'inside', x: 0, y: 0 }];\n        for (const point of selected) {\n            probes.push({ kind: 'inside', x: point.x * 0.55, y: point.y * 0.55 });\n        }\n        const span = Math.max(entry?.bounds?.width || 0, entry?.bounds?.depth || 0);\n        // A five-metre ring often lands on the adjacent roof in dense cities,\n        // falsely making an existing block look flat. Move the fixed four\n        // exterior rays beyond a footprint-scaled apron (bounded at 35 m) so\n        // they are much more likely to establish street/ground elevation\n        // without increasing ray count.\n        const margin = Math.max(\n            this.photoExteriorMarginM,\n            Math.min(35, span * 0.75 + 4)\n        );\n        for (const point of selected) {\n            const length = Math.hypot(point.x, point.y);\n            if (length < 0.25) continue;\n            const scale = (length + margin) / length;\n            probes.push({ kind: 'outside', x: point.x * scale, y: point.y * scale });\n        }\n        for (const probe of probes) probe.dir = this._photoProbeDir(entry, probe.x, probe.y);\n        return {\n            probes: probes.filter((probe) => probe.dir),\n            cursor: 0,\n            modelSeq: this.surfaceController?.photoTileGroup?.userData?.photoModelChangeSeq | 0,\n        };\n    }\n\n    _samplePhotoCoverageProbe(probe, worldQuat) {\n        const sampler = this.surfaceController?.samplePhotorealSurfaceForDir;\n        if (typeof sampler !== 'function' || !this.surfaceController?.photoTileGroup) return null;\n        const worldDir = this._tmpDir.copy(probe.dir).normalize();\n        if (worldQuat) worldDir.applyQuaternion(worldQuat).normalize();\n        return sampler.call(this.surfaceController, worldDir, {\n            skipWorldMatrixUpdate: true,\n        });\n    }\n\n    _applyPhotoTextureProjection(entry, samples) {\n        if (!entry?.mesh?.geometry || !Array.isArray(samples)) return false;\n        const byTexture = new Map();\n        for (const sample of samples) {\n            const texture = sample?.hit?.texture;\n            const uv = sample?.hit?.uv;\n            if (!texture || !Number.isFinite(uv?.x) || !Number.isFinite(uv?.y)) continue;\n            let bucket = byTexture.get(texture);\n            if (!bucket) {\n                bucket = [];\n                byTexture.set(texture, bucket);\n            }\n            bucket.push(sample);\n        }\n        let texture = null;\n        let textureSamples = null;\n        for (const [candidate, bucket] of byTexture) {\n            if (!textureSamples || bucket.length > textureSamples.length) {\n                texture = candidate;\n                textureSamples = bucket;\n            }\n        }\n        if (!texture || !textureSamples || textureSamples.length < 3) return false;\n\n        const uPlane = fitAffinePlane(textureSamples, (sample) => sample.hit.uv.x);\n        const vPlane = fitAffinePlane(textureSamples, (sample) => sample.hit.uv.y);\n        if (!uPlane || !vPlane) return false;\n        const geometry = entry.mesh.geometry;\n        const position = geometry.getAttribute('position');\n        if (!position) return false;\n        const uv = new Float32Array(position.count * 2);\n        for (let i = 0; i < position.count; i += 1) {\n            // Deliberately ignore Z: the real ground photograph beneath the\n            // footprint is projected vertically up the repaired solid.\n            uv[i * 2] = evaluateAffinePlane(uPlane, position.getX(i), position.getY(i));\n            uv[i * 2 + 1] = evaluateAffinePlane(vPlane, position.getX(i), position.getY(i));\n        }\n        geometry.setAttribute('uv', new THREE.BufferAttribute(uv, 2));\n        geometry.attributes.uv.needsUpdate = true;\n        entry.mesh.material.map = texture;\n        entry.mesh.material.color.set(0xffffff);\n        entry.mesh.material.needsUpdate = true;\n        entry.photoProjectedTexture = texture;\n        return true;\n    }\n\n    _clearPhotoTextureProjection(entry) {\n        if (!entry?.mesh?.material || !entry.photoProjectedTexture) return;\n        if (entry.mesh.material.map === entry.photoProjectedTexture) {\n            entry.mesh.material.map = null;\n            entry.mesh.material.color.copy(this.baseMaterial.color);\n            entry.mesh.material.needsUpdate = true;\n        }\n        entry.photoProjectedTexture = null;\n    }\n\n    _markPhotoCoverageUnresolved(entry, reason, insideSamples = 0, outsideSamples = 0) {\n        const retainsStableResult = entry.photoCoverageRevalidation === true\n            && this._hasStablePhotoCoverage(entry);\n        if (retainsStableResult) {\n            entry.info.photoCoverageRevalidation = {\n                state: 'retrying',\n                reason,\n                insideSamples,\n                outsideSamples,\n            };\n        } else {\n            entry.photoCoverageState = 'unresolved';\n            entry.photoSurfaceResolved = false;\n            entry.info.photoCoverage = {\n                state: 'unresolved',\n                reason,\n                insideSamples,\n                outsideSamples,\n            };\n        }\n        entry.photoCoverageProbe = null;\n        entry.photoCoverageRestart = false;\n        entry.pendingVisibility = !retainsStableResult;\n        const retries = entry.photoCoverageRetryCount || 0;\n        if (retries < 2) {\n            entry.photoCoverageRetryCount = retries + 1;\n            entry.photoCoverageRetryAt = (\n                (typeof performance !== 'undefined' && performance.now)\n                    ? performance.now()\n                    : Date.now()\n            ) + 1000;\n            this._photoCoverageRetryEntries.add(entry);\n        }\n        this._syncEntryVisibility(entry);\n    }\n\n    _finishPhotoCoverageProbe(entry, probe) {\n        // Tile replacement can land while this bounded probe is in flight.\n        // Discarding the completed probe starves new repairs during sustained\n        // refinement. Commit this complete verdict first, then revalidate it\n        // against the latest hierarchy without a presentation gap.\n        const revalidateAfterCommit = entry.photoCoverageRestart === true;\n        entry.photoCoverageRestart = false;\n        const samples = probe.probes.filter((sample) => Number.isFinite(sample?.hit?.radius));\n        const inside = samples.filter((sample) => sample.kind === 'inside');\n        const outside = samples.filter((sample) => sample.kind === 'outside');\n        if (!inside.length || outside.length < 3) {\n            this._markPhotoCoverageUnresolved(\n                entry,\n                'insufficient-renderable-surface',\n                inside.length,\n                outside.length\n            );\n            return;\n        }\n\n        // Regress the exterior samples into a local terrain plane. Comparing\n        // roof samples with that plane is robust on hills, unlike comparing\n        // raw radius min/max values across a sloped city block.\n        const radiusReference = outside[0].hit.radius;\n        const groundPlaneRelative = fitAffinePlane(\n            outside,\n            (sample) => sample.hit.radius - radiusReference\n        );\n        if (!groundPlaneRelative) {\n            this._markPhotoCoverageUnresolved(\n                entry,\n                'degenerate-exterior-plane',\n                inside.length,\n                outside.length\n            );\n            return;\n        }\n        const groundPlane = {\n            a: groundPlaneRelative.a,\n            b: groundPlaneRelative.b,\n            c: groundPlaneRelative.c + radiusReference,\n        };\n        const residuals = inside.map((sample) => (\n            sample.hit.radius - evaluateAffinePlane(groundPlane, sample.x, sample.y)\n        ));\n        const outsideResiduals = outside.map((sample) => Math.abs(\n            sample.hit.radius - evaluateAffinePlane(groundPlane, sample.x, sample.y)\n        )).sort((a, b) => a - b);\n        const noise = outsideResiduals[Math.floor(outsideResiduals.length / 2)] || 0;\n        const osmHeight = Number.isFinite(entry.info?.height) ? entry.info.height : 10;\n        const classification = classifyPhotorealBuildingPresence(\n            inside.map((sample, index) => ({\n                residualM: residuals[index],\n                radialNormalDot: sample.hit.radialNormalDot,\n            })),\n            {\n                minimumHeightM: this.photoCoverageMinHeightM,\n                expectedHeightM: osmHeight,\n                exteriorNoiseM: noise,\n            }\n        );\n        const roofThreshold = classification.roofThresholdM;\n        const raised = classification.raisedSamples;\n        const photoHasBuilding = classification.present;\n\n        if (photoHasBuilding) {\n            entry.photoCoverageProbe = null;\n            entry.photoCoverageState = 'present';\n            entry.photoCoverageModelSeq = probe.modelSeq;\n            entry.pendingVisibility = false;\n            entry.photoSurfaceResolved = true;\n            entry.photoCoverageRevalidation = false;\n            entry.photoCoverageRetryCount = 0;\n            this._photoCoverageRetryEntries.delete(entry);\n            delete entry.info.photoCoverageRevalidation;\n            entry.info.photoCoverage = {\n                state: 'present',\n                roofThresholdM: roofThreshold,\n                raisedSamples: raised,\n                protrusionSamples: classification.protrusionSamples,\n                normalSamples: classification.normalSamples,\n                maximumProtrusionStrength: classification.maximumStrength,\n                insideSamples: inside.length,\n            };\n            this._clearPhotoTextureProjection(entry);\n            entry.lod = 'hidden';\n            this._syncEntryVisibility(entry);\n            if (revalidateAfterCommit) {\n                this._queuePhotoCoverage(entry, {\n                    reset: true,\n                    preserveResolved: true,\n                });\n            }\n            return;\n        }\n\n        let minRadius = Infinity;\n        let maxRadius = -Infinity;\n        for (const point of entry.footprintLocal) {\n            const radius = evaluateAffinePlane(groundPlane, point.x, point.y);\n            if (!Number.isFinite(radius)) continue;\n            minRadius = Math.min(minRadius, radius);\n            maxRadius = Math.max(maxRadius, radius);\n        }\n        const centerRadius = evaluateAffinePlane(groundPlane, 0, 0);\n        if (!Number.isFinite(minRadius) || !Number.isFinite(maxRadius)\n            || !Number.isFinite(centerRadius)) {\n            this._markPhotoCoverageUnresolved(\n                entry,\n                'invalid-ground-plane',\n                inside.length,\n                outside.length\n            );\n            return;\n        }\n\n        // Commit the replacement verdict only after its complete ground plane\n        // is valid. Until this point the previous proven repair (if any) has\n        // remained visible and mated to its previous tile surface.\n        entry.photoCoverageProbe = null;\n        entry.photoCoverageState = 'missing';\n        entry.photoCoverageModelSeq = probe.modelSeq;\n        entry.pendingVisibility = false;\n        entry.photoSurfaceResolved = true;\n        entry.photoCoverageRevalidation = false;\n        entry.photoCoverageRetryCount = 0;\n        this._photoCoverageRetryEntries.delete(entry);\n        delete entry.info.photoCoverageRevalidation;\n        entry.info.photoCoverage = {\n            state: 'missing',\n            roofThresholdM: roofThreshold,\n            raisedSamples: raised,\n            protrusionSamples: classification.protrusionSamples,\n            normalSamples: classification.normalSamples,\n            maximumProtrusionStrength: classification.maximumStrength,\n            insideSamples: inside.length,\n        };\n        entry.centerRadius = centerRadius;\n        entry.surfaceRadius = maxRadius;\n        entry.minRadius = minRadius;\n        entry.maxRadius = maxRadius;\n        entry._wasFallback = false;\n        entry.resnapFrozen = true;\n        entry.resnapStableFrames = this.resnapFreezeFrames;\n        const nextEmbed = this._computeEmbed(osmHeight, minRadius, maxRadius);\n        if (Number.isFinite(nextEmbed) && Math.abs(nextEmbed - (entry.embed || 0)) > 0.05) {\n            this._updateEntryGeometry(entry, nextEmbed);\n        }\n        this._applyTerrainFrame(entry, { radius: centerRadius, hasData: true }, false);\n        // Applying a new projection overwrites the old map atomically. If the\n        // replacement tile has no usable texture samples, retain the last\n        // projection rather than flashing back to an untextured repair.\n        this._applyPhotoTextureProjection(entry, samples);\n        this._attachEntryGroup(entry);\n        entry.lod = 'detail';\n        this._queueEntryForLod(entry);\n        this._syncEntryVisibility(entry);\n        if (revalidateAfterCommit) {\n            this._queuePhotoCoverage(entry, {\n                reset: true,\n                preserveResolved: true,\n            });\n        }\n    }\n\n    _updatePhotoCoverage(nowMs) {\n        if (!this._photorealFallbackMode || !this.photorealFallbackEnabled\n            || !this._photoSurfaceQualityReady || !this.surfaceController?.photoTileGroup) return;\n        if (this._photoCoverageRetryEntries.size) {\n            for (const entry of this._photoCoverageRetryEntries) {\n                if (!Number.isFinite(entry?.photoCoverageRetryAt)\n                    || nowMs < entry.photoCoverageRetryAt) continue;\n                this._photoCoverageRetryEntries.delete(entry);\n                this._queuePhotoCoverage(entry, {\n                    reset: true,\n                    preserveResolved: true,\n                });\n                break;\n            }\n        }\n        if (!this._photoCoverageQueue.size) return;\n        const start = (typeof performance !== 'undefined' && performance.now)\n            ? performance.now()\n            : nowMs;\n        const deadline = start + this.photoProbeBudgetMs;\n        let rays = 0;\n        this.surfaceController.prepareTerrainSamplingBatch?.();\n        const worldQuat = this.parentGroup?.getWorldQuaternion?.(this._tmpQuat) || null;\n\n        for (const entry of this._photoCoverageQueue) {\n            if (rays >= this.photoProbeRaysPerFrame) break;\n            const clock = (typeof performance !== 'undefined' && performance.now)\n                ? performance.now()\n                : nowMs;\n            if (rays > 0 && clock >= deadline) break;\n            if (!entry?.group) {\n                this._photoCoverageQueue.delete(entry);\n                continue;\n            }\n            let probe = entry.photoCoverageProbe;\n            if (!probe) {\n                probe = this._createPhotoCoverageProbe(entry);\n                entry.photoCoverageProbe = probe;\n            }\n            if (!probe?.probes?.length) {\n                this._photoCoverageQueue.delete(entry);\n                this._markPhotoCoverageUnresolved(entry, 'invalid-footprint');\n                continue;\n            }\n            const sample = probe.probes[probe.cursor];\n            sample.hit = this._samplePhotoCoverageProbe(sample, worldQuat);\n            probe.cursor += 1;\n            rays += 1;\n            if (probe.cursor >= probe.probes.length) {\n                this._photoCoverageQueue.delete(entry);\n                this._finishPhotoCoverageProbe(entry, probe);\n            }\n        }\n    }\n\n    _meshingFromFootprint(latLonPairs, tags, falloff) {\n        const center = this._averageLatLon(latLonPairs);\n        if (!center) return null;\n        const latRad = THREE.MathUtils.degToRad(center.lat);\n        const lonRad = THREE.MathUtils.degToRad(center.lon);\n        const adjustedLon = lonRad - (EARTH_PRIME_MERIDIAN_OFFSET_RAD || 0);\n        const east = new THREE.Vector3(Math.cos(adjustedLon), 0, -Math.sin(adjustedLon)).normalize();\n        const upVec = latLonToLocalDir(center.lat, center.lon).normalize();\n        const north = new THREE.Vector3().crossVectors(upVec, east).normalize();\n        const metersLat = metersPerDegLat(latRad);\n        const metersLon = metersPerDegLon(latRad);\n\n        const shapePts = [];\n        let minX = Infinity;\n        let maxX = -Infinity;\n        let minY = Infinity;\n        let maxY = -Infinity;\n        for (const [lat, lon] of latLonPairs) {\n            const dx = (lon - center.lon) * metersLon;\n            const dy = (lat - center.lat) * metersLat;\n            if (!Number.isFinite(dx) || !Number.isFinite(dy)) continue;\n            shapePts.push(new THREE.Vector2(dx, dy));\n            if (dx < minX) minX = dx;\n            if (dx > maxX) maxX = dx;\n            if (dy < minY) minY = dy;\n            if (dy > maxY) maxY = dy;\n        }\n        if (shapePts.length < 3) return null;\n        const polypFootprint = this._buildPolypFootprint(shapePts);\n        const boundsWidth = Number.isFinite(minX) && Number.isFinite(maxX) ? Math.max(0, maxX - minX) : 0;\n        const boundsDepth = Number.isFinite(minY) && Number.isFinite(maxY) ? Math.max(0, maxY - minY) : 0;\n\n        // Get the actual building height from OSM data (levels * 3.4m or explicit height)\n        const baseHeight = parseHeight(tags);\n        // Apply falloff to reduce height at edges of loaded area\n        const height = baseHeight * (0.65 + 0.35 * falloff);\n\n        // Sample terrain to find min/max radii under footprint\n        // This determines how deep to embed and where to position\n        const sampleDirs = this._buildSampleDirs(latLonPairs, center);\n        const primaryTile = this._photorealFallbackMode\n            ? null\n            : this._resolvePrimaryTile({ dir: upVec, sampleDirs });\n        const fastSample = this.polypBakeToTiles === true;\n        // Creating hundreds of streamed footprints must stay CPU-only. In\n        // photoreal mode the incremental coverage queue owns all tile rays;\n        // doing them here would turn an Overpass response into a long render\n        // stall and would also classify against half-loaded parent LODs.\n        const sampleResult = this._photorealFallbackMode\n            ? {\n                minRadius: ellipsoidRadiusForLocalDir(upVec),\n                maxRadius: ellipsoidRadiusForLocalDir(upVec),\n                usingFallback: true,\n            }\n            : this._sampleTerrainMinMax(\n                sampleDirs,\n                primaryTile,\n                fastSample,\n                !fastSample\n            );\n        const minRadius = sampleResult?.minRadius;\n        const maxRadius = sampleResult?.maxRadius;\n        const usingFallback = sampleResult?.usingFallback === true;\n        const pendingVisibility = !this.polypBakeToTiles && usingFallback;\n\n        // Calculate embed depth: only go as deep as needed to reach lowest terrain point\n        // The building base should sit at maxRadius (highest terrain point)\n        // Embed extends down to minRadius (lowest terrain point)\n        const embed = this._computeEmbed(height, minRadius, maxRadius);\n        const impostorWidth = Math.max(boundsWidth, this.impostorMinSizeM || 0);\n        const impostorDepth = Math.max(boundsDepth, this.impostorMinSizeM || 0);\n        const impostorHeight = Math.max(height * (this.impostorHeightScale || 1), this.impostorMinHeightM || 0);\n\n        const basis = new THREE.Matrix4().makeBasis(east, north, upVec);\n        const quat = new THREE.Quaternion().setFromRotationMatrix(basis);\n        const group = new THREE.Group();\n        group.quaternion.copy(quat);\n        group.userData.surfaceDir = upVec.clone();\n        group.userData.surfaceEmbed = embed;\n        group.userData.surfaceMaxRadius = maxRadius;\n\n        let mesh = null;\n        let outline = null;\n        let pickerMesh = null;\n\n        if (!this.polypBakeToTiles) {\n            const shape = new THREE.Shape(shapePts);\n            // Total extrusion depth: building height above terrain + embed below\n            const geometry = new THREE.ExtrudeGeometry(shape, {\n                depth: height + embed,\n                bevelEnabled: false\n            });\n            // Translate so the \"base\" of the visible building is at z=0, embed goes negative\n            geometry.translate(0, 0, -embed);\n\n            const fillMaterial = this.baseMaterial.clone();\n            fillMaterial.opacity = this.baseMaterial.opacity * falloff;\n\n            mesh = new THREE.Mesh(geometry, fillMaterial);\n            mesh.castShadow = true;\n            mesh.receiveShadow = true;\n            mesh.name = tags.name || 'building';\n\n            const edges = new THREE.EdgesGeometry(geometry, 15);\n            const lineMaterial = this.baseLineMaterial.clone();\n            lineMaterial.opacity = this.baseLineMaterial.opacity * falloff;\n            outline = new THREE.LineSegments(edges, lineMaterial);\n            outline.name = 'building-outline';\n\n            group.add(mesh);\n            group.add(outline);\n\n            // Create picker mesh for hover detection (invisible, only for raycasting)\n            pickerMesh = new THREE.Mesh(geometry.clone(), new THREE.MeshBasicMaterial({\n                visible: false,\n                side: THREE.DoubleSide\n            }));\n            pickerMesh.name = 'building-picker';\n        }\n\n        // Build info object for hover display\n        const address = formatAddress(tags);\n        // Extract explicit values for HUD display\n        const explicitHeight = parseExplicitHeight(tags);\n        const explicitLevels = parseLevels(tags);\n        // If we have levels but no explicit height, estimate levels from calculated height\n        const displayLevels = explicitLevels !== null\n            ? explicitLevels\n            : (explicitHeight === null ? Math.round(height / METERS_PER_LEVEL) : null);\n\n        const info = {\n            id: `${center.lat.toFixed(6)}_${center.lon.toFixed(6)}`,\n            address,\n            tags: { ...tags },\n            center,\n            footprint: latLonPairs,\n            height,                           // Calculated/display height (always present)\n            heightExplicit: explicitHeight,   // Explicit OSM height (may be null)\n            levels: displayLevels,            // Number of levels (may be null for estimated buildings)\n            levelsExplicit: explicitLevels,   // Explicit OSM levels (may be null)\n            embed\n        };\n        if (pickerMesh) {\n            pickerMesh.userData.buildingInfo = info;\n        }\n        group.userData.buildingInfo = info;\n\n        const entry = {\n            group,\n            pickerMesh,\n            dir: upVec,\n            baseEast: east.clone(),\n            baseNorth: north.clone(),\n            baseUp: upVec.clone(),\n            terrainNormal: upVec.clone(),\n            embed,\n            maxRadius,\n            minRadius,\n            falloff,\n            bounds: { minX, maxX, minY, maxY, width: boundsWidth, depth: boundsDepth },\n            impostorSize: { width: impostorWidth, depth: impostorDepth, height: impostorHeight },\n            footprint: latLonPairs,\n            footprintLocal: shapePts,\n            polypFootprint,\n            center,\n            sampleDirs,\n            surfaceRadius: null,\n            resnapStableFrames: 0,\n            resnapFrozen: false,\n            primaryTile: null,\n            tileKey: null,\n            lastElevationVersion: 0,\n            needsTileRefresh: false,\n            nextFallbackResnapAt: null,\n            lod: pendingVisibility ? 'hidden' : 'detail',\n            imageryAtlasKey: null,\n            imageryVersion: null,\n            info,\n            mesh,\n            outline,\n            pendingVisibility,\n            _wasFallback: usingFallback,\n            labelHandle: null\n        };\n        entry.photoCoverageState = this._photorealFallbackMode ? 'pending' : null;\n        entry.photoCoverageProbe = null;\n        entry.photoSurfaceResolved = false;\n        entry.photoCoverageRevalidation = false;\n\n        entry.primaryTile = primaryTile;\n        entry.tileKey = this._getTileKey(entry.primaryTile);\n        if (Number.isFinite(entry.primaryTile?.elevationVersion)) {\n            entry.lastElevationVersion = entry.primaryTile.elevationVersion;\n        }\n\n        const centerSample = this._sampleTerrainRadiusForDir(upVec, primaryTile, !fastSample);\n        const centerRadius = centerSample.hasData ? centerSample.radius : maxRadius;\n        entry.centerRadius = centerRadius;\n        entry.surfaceRadius = centerRadius;\n\n        if (!this._applyTerrainFrame(entry, centerSample, !fastSample)) {\n            // Position building so its base sits at max terrain radius\n            const lift = this.surfaceOffsetM;\n            const baseRadius = Number.isFinite(entry.surfaceRadius) ? entry.surfaceRadius : centerRadius;\n            group.position.copy(upVec).multiplyScalar(baseRadius + lift);\n        }\n\n        // Position picker mesh to match building group\n        if (pickerMesh) {\n            pickerMesh.quaternion.copy(group.quaternion);\n            pickerMesh.position.copy(group.position);\n        }\n        if (this.polypBakeToTiles || pendingVisibility || !this._geometryVisible) {\n            group.visible = false;\n            if (pickerMesh) pickerMesh.visible = false;\n        }\n\n        // Create label for buildings with a name or address\n        const labelPrimary = tags.name || info.address || null;\n        if (this._labelsEnabled && labelPrimary && labelPrimary !== 'Unknown address') {\n            const ls = this._ensureLabelSystem();\n            if (ls) {\n                const labelRadius = (Number.isFinite(entry.surfaceRadius) ? entry.surfaceRadius : centerRadius)\n                    + this.surfaceOffsetM + height;\n                this._tmpLabelVec.copy(upVec).multiplyScalar(labelRadius);\n                const subText = tags.name && info.address && info.address !== 'Unknown address'\n                    ? info.address\n                    : (Number.isFinite(height) ? `${Math.round(height)}m` : '');\n                entry.labelHandle = ls.createLabel(labelPrimary, {\n                    position: this._tmpLabelVec,\n                    type: 'building',\n                    objectRadius: Math.max(5, boundsWidth * 0.5),\n                    subText,\n                });\n                if (entry.labelHandle?.group) {\n                    this.group.add(entry.labelHandle.group);\n                    if (this._photorealFallbackMode) entry.labelHandle.group.visible = false;\n                }\n            }\n        }\n\n        return entry;\n    }\n\n    _buildPolypFootprint(points) {\n        if (!Array.isArray(points) || points.length < 3) return null;\n        const minSpacing = Math.max(0, Number.isFinite(this.polypMinPointSpacingM)\n            ? this.polypMinPointSpacingM\n            : 0);\n        const maxPoints = Number.isFinite(this.polypMaxPointsPerFootprint)\n            ? Math.max(0, Math.floor(this.polypMaxPointsPerFootprint))\n            : 0;\n        const minSpacingSq = minSpacing * minSpacing;\n        const epsilonSq = 1e-8;\n        let filtered = [];\n        for (const point of points) {\n            if (!Number.isFinite(point?.x) || !Number.isFinite(point?.y)) continue;\n            if (!filtered.length) {\n                filtered.push(point.clone());\n                continue;\n            }\n            const last = filtered[filtered.length - 1];\n            const distSq = last.distanceToSquared(point);\n            if (distSq <= epsilonSq) continue;\n            if (!minSpacing || distSq >= minSpacingSq) {\n                filtered.push(point.clone());\n            }\n        }\n        if (filtered.length > 2 && minSpacing) {\n            const first = filtered[0];\n            const last = filtered[filtered.length - 1];\n            if (first.distanceToSquared(last) <= minSpacingSq) {\n                filtered.pop();\n            }\n        }\n        if (filtered.length < 3) return null;\n        if (maxPoints && filtered.length > maxPoints) {\n            const step = Math.ceil(filtered.length / maxPoints);\n            const decimated = [];\n            for (let i = 0; i < filtered.length; i += step) {\n                decimated.push(filtered[i]);\n            }\n            filtered = decimated;\n        }\n        if (filtered.length < 3) return null;\n        if (this._footprintSignedArea(filtered) < 0) {\n            filtered.reverse();\n        }\n        if (this._hasFootprintSelfIntersections(filtered)) {\n            const hull = this._buildFootprintConvexHull(filtered);\n            if (!hull || hull.length < 3) return null;\n            filtered = hull;\n        }\n        return filtered;\n    }\n\n    _hasFootprintSelfIntersections(points) {\n        const count = points.length;\n        if (count < 4) return false;\n        const intersects = (a, b, c, d) => {\n            const orient = (p, q, r) => {\n                const val = (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);\n                if (Math.abs(val) < 1e-9) return 0;\n                return val > 0 ? 1 : 2;\n            };\n            const onSegment = (p, q, r) => {\n                return q.x <= Math.max(p.x, r.x) + 1e-9 &&\n                    q.x + 1e-9 >= Math.min(p.x, r.x) &&\n                    q.y <= Math.max(p.y, r.y) + 1e-9 &&\n                    q.y + 1e-9 >= Math.min(p.y, r.y);\n            };\n            const o1 = orient(a, b, c);\n            const o2 = orient(a, b, d);\n            const o3 = orient(c, d, a);\n            const o4 = orient(c, d, b);\n            if (o1 !== o2 && o3 !== o4) return true;\n            if (o1 === 0 && onSegment(a, c, b)) return true;\n            if (o2 === 0 && onSegment(a, d, b)) return true;\n            if (o3 === 0 && onSegment(c, a, d)) return true;\n            if (o4 === 0 && onSegment(c, b, d)) return true;\n            return false;\n        };\n\n        for (let i = 0; i < count; i += 1) {\n            const a1 = points[i];\n            const a2 = points[(i + 1) % count];\n            for (let j = i + 1; j < count; j += 1) {\n                const jNext = (j + 1) % count;\n                if (i === j || jNext === i || (i + 1) % count === j) continue;\n                const b1 = points[j];\n                const b2 = points[jNext];\n                if (intersects(a1, a2, b1, b2)) {\n                    return true;\n                }\n            }\n        }\n        return false;\n    }\n\n    _buildFootprintConvexHull(points) {\n        if (!Array.isArray(points) || points.length < 3) return null;\n        const pts = points.map((p) => ({ x: p.x, y: p.y, ref: p }));\n        pts.sort((a, b) => (a.x === b.x ? a.y - b.y : a.x - b.x));\n        const cross = (o, a, b) => (a.x - o.x) * (b.y - o.y) - (a.y - o.y) * (b.x - o.x);\n        const lower = [];\n        for (const p of pts) {\n            while (lower.length >= 2 &&\n                cross(lower[lower.length - 2], lower[lower.length - 1], p) <= 0) {\n                lower.pop();\n            }\n            lower.push(p);\n        }\n        const upper = [];\n        for (let i = pts.length - 1; i >= 0; i -= 1) {\n            const p = pts[i];\n            while (upper.length >= 2 &&\n                cross(upper[upper.length - 2], upper[upper.length - 1], p) <= 0) {\n                upper.pop();\n            }\n            upper.push(p);\n        }\n        upper.pop();\n        lower.pop();\n        const hull = lower.concat(upper).map((p) => p.ref.clone());\n        if (hull.length < 3) return null;\n        if (this._footprintSignedArea(hull) < 0) {\n            hull.reverse();\n        }\n        return hull;\n    }\n\n    _footprintSignedArea(points) {\n        let area = 0;\n        const count = points.length;\n        for (let i = 0; i < count; i += 1) {\n            const a = points[i];\n            const b = points[(i + 1) % count];\n            area += (a.x * b.y) - (b.x * a.y);\n        }\n        return area * 0.5;\n    }\n\n    update(dt) {\n        if (!this.enabled) {\n            if (!this._loggedDisabled) {\n                if (this.debugLogs) {\n                    console.log('[BuildingOverlay] update skipped - disabled');\n                }\n                this._loggedDisabled = true;\n            }\n            return;\n        }\n        this._loggedDisabled = false;\n        this._perfStart('cpu.buildings.update');\n        try {\n            if (!this._instances.length) return;\n            const interval = Number.isFinite(this.resnapIntervalMs) ? this.resnapIntervalMs : 0;\n            if (interval > 0) {\n                this._resnapTimer += dt * 1000;\n            }\n            const allowSweep = interval <= 0 || this._resnapTimer >= interval;\n            if (allowSweep) this._resnapTimer = 0;\n\n            const nowMs = (typeof performance !== 'undefined' && performance.now)\n                ? performance.now()\n                : Date.now();\n            this._updatePhotoCoverage(nowMs);\n\n            let budget = Number.isFinite(this.resnapBudget)\n                ? Math.max(1, Math.floor(this.resnapBudget))\n                : 1;\n\n            this._perfStart('cpu.buildings.resnap');\n            if (!this._photorealFallbackMode && this._dirtyTiles.size) {\n                const tileBudget = Math.min(budget, this._dirtyTiles.size);\n                let tilesProcessed = 0;\n                for (const tile of this._dirtyTiles) {\n                    this._dirtyTiles.delete(tile);\n                    this._queueEntriesForTile(tile);\n                    tilesProcessed += 1;\n                    if (tilesProcessed >= tileBudget) break;\n                }\n            }\n\n            if (!this._photorealFallbackMode && this._pendingEntries.size && budget > 0) {\n                const entryBudget = Math.min(budget, this._pendingEntries.size);\n                let processed = 0;\n                for (const entry of this._pendingEntries) {\n                    this._pendingEntries.delete(entry);\n                    this._updateEntryPosition(entry, null, nowMs);\n                    if (entry?.needsTileRefresh) {\n                        entry.needsTileRefresh = false;\n                        this._refreshEntryTiles(entry);\n                    }\n                    processed += 1;\n                    if (processed >= entryBudget) break;\n                }\n                budget -= processed;\n            }\n\n            if (!this._photorealFallbackMode && allowSweep && budget > 0 && this._fallbackEntries.size) {\n                const entries = Array.from(this._fallbackEntries);\n                const total = entries.length;\n                let processed = 0;\n                let attempts = 0;\n                while (processed < budget && attempts < total) {\n                    const entry = entries[this._resnapSweepIndex % total];\n                    this._resnapSweepIndex = (this._resnapSweepIndex + 1) % total;\n                    attempts += 1;\n                    if (!entry) continue;\n                    if (Number.isFinite(entry.nextFallbackResnapAt) && nowMs < entry.nextFallbackResnapAt) {\n                        continue;\n                    }\n                    this._updateEntryPosition(entry, null, nowMs);\n                    if (entry?.needsTileRefresh) {\n                        entry.needsTileRefresh = false;\n                        this._refreshEntryTiles(entry);\n                    }\n                    processed += 1;\n                }\n                budget -= processed;\n            }\n\n            if (!this._photorealFallbackMode && !this.tileDrivenResnap && allowSweep && budget > 0) {\n                this._runResnapSweep(budget, nowMs);\n            }\n            this._perfEnd('cpu.buildings.resnap');\n\n            this._perfStart('cpu.buildings.cleanup');\n            this._flushTileGroupCleanup();\n            this._perfEnd('cpu.buildings.cleanup');\n            this._perfStart('cpu.buildings.imagery');\n            this._updateImagery(dt, nowMs);\n            this._perfEnd('cpu.buildings.imagery');\n            this._perfStart('cpu.buildings.lod');\n            this._updateLod(dt, nowMs);\n            this._perfEnd('cpu.buildings.lod');\n            this._perfStart('cpu.buildings.impostor');\n            this._processImpostorRebuilds();\n            this._perfEnd('cpu.buildings.impostor');\n        } finally {\n            this._perfEnd('cpu.buildings.update');\n        }\n    }\n\n    _runResnapSweep(budget, nowMs) {\n        if (!this._instances.length || budget <= 0) return;\n        const total = this._instances.length;\n        let processed = 0;\n        let attempts = 0;\n        while (processed < budget && attempts < total) {\n            const entry = this._instances[this._resnapSweepIndex % total];\n            this._resnapSweepIndex = (this._resnapSweepIndex + 1) % total;\n            attempts += 1;\n            if (!entry) continue;\n            this._updateEntryPosition(entry, null, nowMs);\n            if (entry?.needsTileRefresh) {\n                entry.needsTileRefresh = false;\n                this._refreshEntryTiles(entry);\n            }\n            processed += 1;\n        }\n    }\n\n    _flushTileGroupCleanup() {\n        if (!this._pendingTileGroupCleanup.size) return;\n        for (const group of this._pendingTileGroupCleanup) {\n            if (!group || group.children.length) continue;\n            this._pendingTileGroupCleanup.delete(group);\n            const tileKey = group.userData?.tileKey || null;\n            if (group.parent) group.parent.remove(group);\n            if (tileKey) {\n                this._tileGroups.delete(tileKey);\n                const impostor = this._impostorMeshes.get(tileKey);\n                if (impostor?.mesh?.parent) {\n                    impostor.mesh.parent.remove(impostor.mesh);\n                }\n                this._impostorMeshes.delete(tileKey);\n                const polyp = this._polypMeshes.get(tileKey);\n                if (polyp?.tile?.setBuildingExtrusions) {\n                    polyp.tile.setBuildingExtrusions(null);\n                }\n                if (polyp?.mesh?.parent) {\n                    polyp.mesh.parent.remove(polyp.mesh);\n                }\n                if (polyp?.mesh?.geometry) {\n                    polyp.mesh.geometry.dispose();\n                }\n                this._polypMeshes.delete(tileKey);\n            }\n        }\n    }\n\n    _updateImagery(dt, nowMs) {\n        if (this._photorealFallbackMode || !this.imageryEnabled\n            || this.polypBakeToTiles || !this._imageryPendingEntries.size) return;\n        const interval = Number.isFinite(this.imageryUpdateIntervalMs) ? this.imageryUpdateIntervalMs : 0;\n        if (interval > 0) {\n            this._imageryTimer += dt * 1000;\n        }\n        const allowSweep = interval <= 0 || this._imageryTimer >= interval;\n        if (!allowSweep) return;\n        this._imageryTimer = 0;\n\n        const maxChecks = Math.max(4, Math.floor((this.lodBudget || DEFAULT_LOD_BUDGET) / 2));\n        let processed = 0;\n        for (const entry of this._imageryPendingEntries) {\n            this._imageryPendingEntries.delete(entry);\n            if (!entry || entry.lod !== 'detail') continue;\n            if (!this._applyEntryImagery(entry, entry.primaryTile, { nowMs })) {\n                this._imageryPendingEntries.add(entry);\n            }\n            processed += 1;\n            if (processed >= maxChecks) break;\n        }\n    }\n\n    _updateLod(dt, nowMs) {\n        if (!this.camera || !this._instances.length) return;\n        const interval = Number.isFinite(this.lodUpdateIntervalMs) ? this.lodUpdateIntervalMs : 0;\n        if (interval > 0) {\n            this._lodTimer += dt * 1000;\n        }\n        const allowSweep = interval <= 0 || this._lodTimer >= interval;\n        if (!allowSweep) return;\n        this._lodTimer = 0;\n\n        let budget = Number.isFinite(this.lodBudget) ? Math.max(1, Math.floor(this.lodBudget)) : 0;\n\n        if (this._lodDirtyEntries.size && budget > 0) {\n            const entryBudget = Math.min(budget, this._lodDirtyEntries.size);\n            let processed = 0;\n            for (const entry of this._lodDirtyEntries) {\n                this._lodDirtyEntries.delete(entry);\n                this._updateEntryLod(entry, nowMs);\n                processed += 1;\n                if (processed >= entryBudget) break;\n            }\n            budget -= processed;\n        }\n\n        if (budget > 0) {\n            const total = this._instances.length;\n            let processed = 0;\n            let attempts = 0;\n            while (processed < budget && attempts < total) {\n                const entry = this._instances[this._lodSweepIndex % total];\n                this._lodSweepIndex = (this._lodSweepIndex + 1) % total;\n                attempts += 1;\n                if (!entry) continue;\n                this._updateEntryLod(entry, nowMs);\n                processed += 1;\n            }\n        }\n    }\n\n    _processImpostorRebuilds() {\n        if (!this._impostorDirtyTiles.size) return;\n        const budget = Number.isFinite(this.impostorRebuildBudget)\n            ? Math.max(1, Math.floor(this.impostorRebuildBudget))\n            : DEFAULT_IMPOSTOR_REBUILD_BUDGET;\n        let processed = 0;\n        for (const tile of this._impostorDirtyTiles) {\n            this._impostorDirtyTiles.delete(tile);\n            this._rebuildImpostorsForTile(tile);\n            processed += 1;\n            if (processed >= budget) break;\n        }\n    }\n\n    _updateEntryPosition(entry, sample = null, nowMs = null) {\n        if (!entry?.group || !entry.dir) return;\n        const tile = entry.primaryTile;\n        const tileVersion = Number.isFinite(tile?.elevationVersion) ? tile.elevationVersion : null;\n        if (entry.resnapFrozen &&\n            !entry.needsTileRefresh &&\n            (tileVersion === null || tileVersion === entry.lastElevationVersion)) {\n            return;\n        }\n\n        // Sample terrain to get min/max radii under footprint\n        // Use fast mode (vertex sampling only) for incremental resnaps\n        const sampleResult = sample || this._sampleTerrainMinMax(entry.sampleDirs, tile, true);\n        const minRadius = sampleResult?.minRadius;\n        const maxRadius = sampleResult?.maxRadius;\n        if (!Number.isFinite(maxRadius)) return;\n\n        // Check if we're still using fallback planet radius (no terrain data)\n        const usingFallback = sampleResult?.usingFallback ?? false;\n\n        const allowRaycast = !usingFallback;\n        const centerSample = this._sampleTerrainRadiusForDir(entry.dir, tile, allowRaycast);\n        const centerRadius = centerSample.hasData ? centerSample.radius : maxRadius;\n\n        // For upright buildings (alignToTerrainNormal=false), surfaceRadius uses maxRadius\n        // For tilted buildings (alignToTerrainNormal=true), surfaceRadius uses centerRadius\n        const nextSurfaceRadius = this.alignToTerrainNormal ? centerRadius : maxRadius;\n        const prevRadius = entry.surfaceRadius;\n        const delta = Number.isFinite(prevRadius) ? Math.abs(prevRadius - nextSurfaceRadius) : Infinity;\n        const tolerance = Number.isFinite(this.resnapToleranceM)\n            ? Math.max(this.resnapToleranceM, MIN_RESNAP_TOLERANCE_M)\n            : MIN_RESNAP_TOLERANCE_M;\n\n        // Only stabilize/freeze when we have REAL terrain data (not fallback)\n        const prevWasFallback = entry._wasFallback ?? false;\n\n        if (usingFallback) {\n            // Still using fallback - don't freeze, keep checking for real elevation\n            entry.resnapStableFrames = 0;\n            entry.resnapFrozen = false;\n            entry._wasFallback = true;\n            const now = Number.isFinite(nowMs)\n                ? nowMs\n                : ((typeof performance !== 'undefined' && performance.now) ? performance.now() : Date.now());\n            const nextAt = Number.isFinite(this.fallbackResnapIntervalMs)\n                ? now + this.fallbackResnapIntervalMs\n                : now + 500;\n            entry.nextFallbackResnapAt = nextAt;\n            this._fallbackEntries.add(entry);\n        } else if (!prevWasFallback && Number.isFinite(prevRadius) && delta <= tolerance) {\n            // Have real data and position is stable - increment stability counter\n            if (tileVersion !== null && tileVersion !== entry.lastElevationVersion) {\n                entry.resnapStableFrames = 0;\n                entry.resnapFrozen = false;\n            } else {\n                entry.resnapStableFrames = (entry.resnapStableFrames || 0) + 1;\n                if (Number.isFinite(this.resnapFreezeFrames) && this.resnapFreezeFrames > 0 &&\n                    entry.resnapStableFrames >= this.resnapFreezeFrames) {\n                    entry.resnapFrozen = true;\n                }\n                entry.lastElevationVersion = tileVersion ?? entry.lastElevationVersion;\n                this._fallbackEntries.delete(entry);\n                entry.nextFallbackResnapAt = null;\n                return; // Position already correct, no need to update\n            }\n        } else {\n            // Position changed significantly or transitioning from fallback to real data\n            entry.resnapStableFrames = 0;\n            entry.resnapFrozen = false;\n            entry._wasFallback = false;\n        }\n\n        if (!usingFallback && entry.pendingVisibility) {\n            entry.pendingVisibility = false;\n            this._queueEntryForLod(entry);\n        }\n\n        // Update stored radii\n        entry.centerRadius = centerRadius;\n        entry.surfaceRadius = this.alignToTerrainNormal ? centerRadius : maxRadius;\n        entry.maxRadius = maxRadius;\n        entry.minRadius = minRadius;\n        if (entry.group?.userData) {\n            entry.group.userData.surfaceMaxRadius = maxRadius;\n        }\n        entry.lastElevationVersion = tileVersion ?? entry.lastElevationVersion;\n        this._fallbackEntries.delete(entry);\n        entry.nextFallbackResnapAt = null;\n\n        const height = Number.isFinite(entry.info?.height) ? entry.info.height : null;\n        if (Number.isFinite(height)) {\n            const nextEmbed = this._computeEmbed(height, minRadius, maxRadius);\n            if (Number.isFinite(nextEmbed) && nextEmbed > (entry.embed || 0) + 0.05) {\n                this._updateEntryGeometry(entry, nextEmbed);\n            }\n        }\n\n        // Position building so base sits at maxRadius (highest terrain point)\n        // The pre-calculated embed extends downward to cover lower terrain\n        if (!this._applyTerrainFrame(entry, centerSample, allowRaycast)) {\n            const lift = this.surfaceOffsetM;\n            const baseRadius = Number.isFinite(entry.surfaceRadius) ? entry.surfaceRadius : centerRadius;\n            entry.group.position.copy(entry.dir).multiplyScalar(baseRadius + lift);\n            if (entry.pickerMesh) {\n                entry.pickerMesh.quaternion.copy(entry.group.quaternion);\n                entry.pickerMesh.position.copy(entry.group.position);\n            }\n        }\n        if (this.polypBakeToTiles) {\n            this._queueEntryTilesForBake(entry);\n        }\n        if (entry.lod === 'impostor') {\n            this._queueTileForImpostorRebuild(entry.primaryTile);\n        }\n        this._queueEntryForLod(entry);\n    }\n\n    /**\n     * Sample terrain at multiple points to find min and max radii\n     * Used to determine embed depth and positioning\n     * @param {boolean} fastMode - Use fewer sample points (faster but less accurate)\n     * @param {boolean} allowRaycast - Allow raycast sampling (more accurate but expensive)\n     */\n    _sampleTerrainMinMax(sampleDirs, tile = null, fastMode = false, allowRaycast = true) {\n        let minRadius = Infinity;\n        let maxRadius = -Infinity;\n        let found = false;\n        let hasElevationSample = false;\n\n        if (!sampleDirs?.length) {\n            return { minRadius: this.planetRadius, maxRadius: this.planetRadius, usingFallback: true };\n        }\n\n        const tileVersion = Number.isFinite(tile?.elevationVersion) ? tile.elevationVersion : null;\n        if (tile && tileVersion !== null) {\n            const cached = this._tileSampleCache.get(tile);\n            if (cached && cached.version === tileVersion) {\n                return cached.sample;\n            }\n        }\n\n        const worldQuat = this.triTree?.group?.getWorldQuaternion(this._tmpQuat) || null;\n        const hasElevationForDir = (worldDir) => {\n            const leaf = this.triTree?.findLeafTileForWorldDir?.(worldDir);\n            return leaf?.elevationHasData === true;\n        };\n\n        // PRIMARY: Use raycast terrain sampling for accuracy\n        // Sample a subset of points for performance (center + corners)\n        const raycastRadius = allowRaycast\n            ? this.triTree?.sampleTerrainRadiusForDir?.bind(this.triTree)\n            : null;\n        if (raycastRadius) {\n            const samplesToCheck = fastMode && sampleDirs.length > 3\n                ? [sampleDirs[0], sampleDirs[Math.floor(sampleDirs.length / 2)], sampleDirs[sampleDirs.length - 1]].filter(Boolean)\n                : sampleDirs.length <= 5 ? sampleDirs : [\n                    sampleDirs[0], // center\n                    sampleDirs[Math.floor(sampleDirs.length * 0.25)],\n                    sampleDirs[Math.floor(sampleDirs.length * 0.5)],\n                    sampleDirs[Math.floor(sampleDirs.length * 0.75)],\n                    sampleDirs[sampleDirs.length - 1]\n                ].filter(Boolean);\n\n            for (const sample of samplesToCheck) {\n                if (!sample) continue;\n                const worldDir = this._tmpDir.copy(sample).normalize();\n                if (worldQuat) worldDir.applyQuaternion(worldQuat);\n                if (!hasElevationForDir(worldDir)) {\n                    continue;\n                }\n                const radius = raycastRadius(worldDir);\n                if (!Number.isFinite(radius) || radius <= 0) continue;\n                hasElevationSample = true;\n                found = true;\n                if (radius < minRadius) minRadius = radius;\n                if (radius > maxRadius) maxRadius = radius;\n            }\n        }\n\n        // FALLBACK: Use vertex-based sampling if raycast failed\n        if (!found) {\n            const getRadius = this.triTree?.getSurfaceRadiusAtDir?.bind(this.triTree);\n            if (getRadius) {\n                for (const sample of sampleDirs) {\n                    if (!sample) continue;\n                    const worldDir = this._tmpDir.copy(sample).normalize();\n                    if (worldQuat) worldDir.applyQuaternion(worldQuat);\n                    if (!hasElevationForDir(worldDir)) {\n                        continue;\n                    }\n                    const radius = getRadius(worldDir);\n                    if (!Number.isFinite(radius) || radius <= 0) continue;\n                    hasElevationSample = true;\n                    found = true;\n                    if (radius < minRadius) minRadius = radius;\n                    if (radius > maxRadius) maxRadius = radius;\n                }\n            }\n        }\n\n        if (found) {\n            const sample = { minRadius, maxRadius, usingFallback: !hasElevationSample };\n            if (tile && tileVersion !== null) {\n                this._tileSampleCache.set(tile, { version: tileVersion, sample });\n            }\n            return sample;\n        }\n\n        // No terrain data available yet\n        const sample = { minRadius: this.planetRadius, maxRadius: this.planetRadius, usingFallback: true };\n        if (tile && tileVersion !== null) {\n            this._tileSampleCache.set(tile, { version: tileVersion, sample });\n        }\n        return sample;\n    }\n\n    _computeEmbed(height, minRadius, maxRadius) {\n        if (!Number.isFinite(height) || !Number.isFinite(minRadius) || !Number.isFinite(maxRadius)) {\n            return 0;\n        }\n        const terrainVariation = Math.max(0, maxRadius - minRadius);\n        const minEmbed = Math.max(0.5, height * 0.15);\n        return Math.max(terrainVariation + 0.5, minEmbed);\n    }\n\n    _updateEntryGeometry(entry, embed) {\n        if (!entry?.group || !entry.footprint || !entry.center) return;\n        if (this.polypBakeToTiles && !entry.mesh) {\n            entry.embed = embed;\n            if (entry.info) entry.info.embed = embed;\n            if (entry.group.userData) entry.group.userData.surfaceEmbed = embed;\n            return;\n        }\n        const height = Number.isFinite(entry.info?.height) ? entry.info.height : null;\n        if (!Number.isFinite(height) || !Number.isFinite(embed)) return;\n\n        const center = entry.center;\n        const latRad = THREE.MathUtils.degToRad(center.lat);\n        const metersLat = Math.max(0.0001, metersPerDegLat(latRad));\n        const metersLon = Math.max(0.0001, metersPerDegLon(latRad));\n\n        const shapePts = [];\n        for (const pair of entry.footprint) {\n            if (!pair) continue;\n            const lat = pair[0];\n            const lon = pair[1];\n            if (!Number.isFinite(lat) || !Number.isFinite(lon)) continue;\n            const dx = (lon - center.lon) * metersLon;\n            const dy = (lat - center.lat) * metersLat;\n            if (!Number.isFinite(dx) || !Number.isFinite(dy)) continue;\n            shapePts.push(new THREE.Vector2(dx, dy));\n        }\n        if (shapePts.length < 3) return;\n\n        const geometry = new THREE.ExtrudeGeometry(new THREE.Shape(shapePts), {\n            depth: height + embed,\n            bevelEnabled: false\n        });\n        geometry.translate(0, 0, -embed);\n\n        const mesh = entry.mesh || entry.group.children.find(c => c?.isMesh);\n        if (mesh?.geometry) {\n            mesh.geometry.dispose();\n        }\n        if (mesh) {\n            mesh.geometry = geometry;\n        }\n\n        const outline = entry.outline || entry.group.children.find(c => c?.name === 'building-outline');\n        if (outline) {\n            if (outline.geometry) outline.geometry.dispose();\n            outline.geometry = new THREE.EdgesGeometry(geometry, 15);\n        }\n\n        if (entry.pickerMesh) {\n            if (entry.pickerMesh.geometry) entry.pickerMesh.geometry.dispose();\n            entry.pickerMesh.geometry = geometry.clone();\n        }\n\n        entry.embed = embed;\n        if (entry.info) entry.info.embed = embed;\n        if (entry.group.userData) entry.group.userData.surfaceEmbed = embed;\n        if (this.imageryEnabled && !this._photorealFallbackMode && entry.lod === 'detail') {\n            this._applyEntryImagery(entry, entry.primaryTile, { force: true });\n        }\n    }\n\n    _sampleEntrySurface(entry) {\n        if (!entry?.group) return null;\n        const samples = Array.isArray(entry.sampleDirs) && entry.sampleDirs.length\n            ? entry.sampleDirs\n            : (entry.dir ? [entry.dir] : []);\n        if (!samples.length) return null;\n\n        const sample = this._sampleTerrainMinMax(samples, entry.primaryTile);\n        if (!sample || !Number.isFinite(sample.maxRadius)) return sample || null;\n\n        const lift = Number.isFinite(this.surfaceOffsetM) ? this.surfaceOffsetM : 0;\n        const currentRadius = entry.group.position?.length?.();\n        const baseRadius = Number.isFinite(currentRadius) ? (currentRadius - lift) : null;\n        const delta = (Number.isFinite(baseRadius) && Number.isFinite(sample.maxRadius))\n            ? Math.abs(baseRadius - sample.maxRadius)\n            : null;\n\n        return {\n            ...sample,\n            baseRadius,\n            delta\n        };\n    }\n\n    _resolveSurfaceRadiusForEntry(entry) {\n        const samples = Array.isArray(entry?.sampleDirs) && entry.sampleDirs.length\n            ? entry.sampleDirs\n            : (entry?.dir ? [entry.dir] : []);\n        if (!samples.length) return this.planetRadius;\n\n        const worldQuat = this.triTree?.group?.getWorldQuaternion(this._tmpQuat) || null;\n        let best = Infinity;\n        let found = false;\n\n        // PRIMARY: Use raycast terrain sampling - most accurate for actual surface position\n        // Raycast finds the exact intersection point with the terrain mesh\n        const raycastRadius = this.triTree?.sampleTerrainRadiusForDir?.bind(this.triTree);\n        if (raycastRadius) {\n            for (const sample of samples) {\n                if (!sample) continue;\n                const worldDir = this._tmpDir.copy(sample).normalize();\n                if (worldQuat) worldDir.applyQuaternion(worldQuat);\n                const radius = raycastRadius(worldDir);\n                if (!Number.isFinite(radius) || radius <= 0) continue;\n                found = true;\n                if (radius < best) best = radius;\n            }\n        }\n\n        if (found) return best;\n\n        // FALLBACK: Use vertex-based sampling if raycast didn't work\n        // This finds the closest vertex which is less accurate but works when\n        // the mesh isn't ready for raycasting\n        const getRadius = this.triTree?.getSurfaceRadiusAtDir?.bind(this.triTree);\n        if (getRadius) {\n            for (const sample of samples) {\n                if (!sample) continue;\n                const worldDir = this._tmpDir.copy(sample).normalize();\n                if (worldQuat) worldDir.applyQuaternion(worldQuat);\n                const radius = getRadius(worldDir);\n                if (!Number.isFinite(radius) || radius <= 0) continue;\n                found = true;\n                if (radius < best) best = radius;\n            }\n        }\n\n        if (found) return best;\n\n        // Mark that we didn't find valid terrain - building should resnap later\n        // when elevation data becomes available\n        entry.resnapFrozen = false;\n        entry.resnapStableFrames = 0;\n\n        // Return planet radius as fallback, but don't freeze -\n        // the resnap system will keep trying\n        const fallbackDir = samples.find(Boolean);\n        if (fallbackDir) {\n            return ellipsoidRadiusForLocalDir(fallbackDir);\n        }\n        return this.planetRadius;\n    }\n\n    _resolveSurfaceRadius(localDir) {\n        const dir = localDir.clone().normalize();\n        if (this.triTree?.group) {\n            const worldQuat = this.triTree.group.getWorldQuaternion(new THREE.Quaternion());\n            const worldDir = dir.clone().applyQuaternion(worldQuat).normalize();\n            // PRIMARY: Use raycast for accurate surface position\n            const raycastR = this.triTree.sampleTerrainRadiusForDir?.(worldDir);\n            if (Number.isFinite(raycastR) && raycastR > 0) {\n                return raycastR;\n            }\n            // FALLBACK: Use vertex sampling\n            const vertexR = this.triTree.getSurfaceRadiusAtDir?.(worldDir);\n            if (Number.isFinite(vertexR)) {\n                return vertexR;\n            }\n        }\n        return ellipsoidRadiusForLocalDir(localDir);\n    }\n\n    _resolveSurfacePosition(localDir, embed = 0) {\n        const radius = this._resolveSurfaceRadius(localDir);\n        const lift = embed + this.surfaceOffsetM;\n        return localDir.clone().normalize().multiplyScalar(radius + lift);\n    }\n\n    _averageLatLon(points) {\n        if (!points.length) return null;\n        let lat = 0;\n        let lon = 0;\n        let n = 0;\n        for (const pair of points) {\n            if (!pair) continue;\n            lat += pair[0];\n            lon += pair[1];\n            n++;\n        }\n        if (!n) return null;\n        return { lat: lat / n, lon: lon / n };\n    }\n\n    _getTileKey(tile) {\n        if (!tile) return null;\n        if (typeof tile.getTileId === 'function') return tile.getTileId();\n        return null;\n    }\n\n    _getTileGroup(tile) {\n        if (!tile) return null;\n        const key = this._getTileKey(tile);\n        if (!key) return null;\n        return this._tileGroups.get(key) || null;\n    }\n\n    _ensureTileGroup(tile) {\n        if (!tile) return this.group;\n        const key = this._getTileKey(tile);\n        if (!key) return this.group;\n        let group = this._tileGroups.get(key);\n        if (!group) {\n            group = new THREE.Group();\n            group.name = `BuildingTile:${key}`;\n            group.userData.tileKey = key;\n            this._tileGroups.set(key, group);\n            this.group.add(group);\n        }\n        group.userData.tile = tile;\n        this._tileGroupByTile.set(tile, group);\n        return group;\n    }\n\n    _attachEntryGroup(entry) {\n        if (!entry?.group) return;\n        // Photoreal tiles and BuildingOverlay are siblings under the rotating\n        // planet group. Hosting repair solids directly here keeps them alive\n        // when TriTree tile groups are intentionally presentation-suppressed.\n        const host = this._photorealFallbackMode\n            ? this.group\n            : (entry.primaryTile ? this._ensureTileGroup(entry.primaryTile) : this.group);\n        if (entry.group.parent !== host) {\n            entry.group.parent?.remove(entry.group);\n            host.add(entry.group);\n        }\n    }\n\n    _resolvePrimaryTile(entry) {\n        if (!entry || !this.triTree || typeof this.triTree.findLeafTileForWorldDir !== 'function') {\n            return null;\n        }\n        const dir = this._tmpDir.copy(entry.dir || entry.sampleDirs?.[0] || new THREE.Vector3(0, 1, 0)).normalize();\n        const worldQuat = this.triTree.group?.getWorldQuaternion(this._tmpQuat) || null;\n        if (worldQuat) dir.applyQuaternion(worldQuat);\n        return this.triTree.findLeafTileForWorldDir(dir);\n    }\n\n    _updateEntryPrimaryTile(entry, tiles = null) {\n        if (!entry) return;\n        const nextPrimary = this._resolvePrimaryTile(entry) || (tiles ? tiles.values().next().value : null);\n        if (nextPrimary === entry.primaryTile) return;\n        const prevTile = entry.primaryTile;\n        entry.primaryTile = nextPrimary;\n        entry.tileKey = this._getTileKey(nextPrimary);\n        if (Number.isFinite(nextPrimary?.elevationVersion)) {\n            entry.lastElevationVersion = nextPrimary.elevationVersion;\n        }\n        this._attachEntryGroup(entry);\n        if (prevTile) {\n            this._queueTileForImpostorRebuild(prevTile);\n            this._queueTileGroupCleanup(prevTile);\n        }\n        if (nextPrimary) this._queueTileForImpostorRebuild(nextPrimary);\n    }\n\n    _bindTileListeners() {\n        if (!this.triTree || typeof this.triTree.addTileListener !== 'function') return;\n        if (this._tileListener) return;\n        this._tileListener = (payload) => this._handleTileEvent(payload);\n        this.triTree.addTileListener(this._tileListener);\n    }\n\n    _unbindTileListeners() {\n        if (!this.triTree || typeof this.triTree.removeTileListener !== 'function') return;\n        if (!this._tileListener) return;\n        this.triTree.removeTileListener(this._tileListener);\n        this._tileListener = null;\n    }\n\n    _bindConfigListener() {\n        if (!this.eventBus || typeof this.eventBus.on !== 'function') return;\n        this._configListener = (config) => this._handleConfigUpdate(config);\n        this.eventBus.on('buildings:config', this._configListener);\n    }\n\n    _unbindConfigListener() {\n        if (!this.eventBus || typeof this.eventBus.off !== 'function') return;\n        if (!this._configListener) return;\n        this.eventBus.off('buildings:config', this._configListener);\n        this._configListener = null;\n    }\n\n    _bindMotionListener() {\n        if (!this.eventBus || typeof this.eventBus.on !== 'function') return;\n        if (this._motionListener) return;\n        this._motionListener = (state) => {\n            this._motionState = state || null;\n        };\n        this.eventBus.on('motion:update', this._motionListener);\n    }\n\n    _unbindMotionListener() {\n        if (!this.eventBus || typeof this.eventBus.off !== 'function') return;\n        if (!this._motionListener) return;\n        this.eventBus.off('motion:update', this._motionListener);\n        this._motionListener = null;\n    }\n\n    setTerrainMode(mode) {\n        if (this._terrainMode === mode) return;\n        this._terrainMode = mode;\n        this._handleConfigUpdate({ enabled: this._requestedEnabled });\n    }\n\n    _handleConfigUpdate(config) {\n        if (!config) return;\n\n        // Update internal properties from config\n        const prevImageryEnabled = this.imageryEnabled;\n        let resnapNeedsUpdate = false;\n        let lodNeedsUpdate = false;\n        let impostorNeedsUpdate = false;\n        let polypNeedsUpdate = false;\n        let rebuildSampleDirs = false;\n\n        if (typeof config.enabled === 'boolean') {\n            const wasEnabled = this.enabled;\n            this._requestedEnabled = config.enabled;\n            this.enabled = this._terrainMode === 'tritree' && this._requestedEnabled;\n            this.group.visible = this.enabled;\n            // Clear all data when disabled to prevent viewshed churn\n            if (wasEnabled && !this.enabled) {\n                this.clear();\n                return; // Skip other config updates when disabling\n            }\n        }\n\n        // Skip all updates if disabled\n        if (!this.enabled) return;\n\n        let refreshNeeded = false;\n        if (Number.isFinite(config.maxFeatures)) {\n            this.maxFeatures = config.maxFeatures;\n            refreshNeeded = true;\n        }\n        if (Number.isFinite(config.applySliceMs)) {\n            this.applySliceMs = Math.max(1, config.applySliceMs);\n        }\n        if (Number.isFinite(config.applyMinBatch)) {\n            this.applyMinBatch = Math.max(1, Math.floor(config.applyMinBatch));\n        }\n        if (Number.isFinite(config.overpassTimeoutMs)) {\n            this.overpassTimeoutMs = Math.max(1000, config.overpassTimeoutMs);\n        }\n        if (Number.isFinite(config.osmMapTimeoutMs)) {\n            this.osmMapTimeoutMs = Math.max(1000, config.osmMapTimeoutMs);\n        }\n        if (Number.isFinite(config.surfaceOffsetM)) {\n            this.surfaceOffsetM = config.surfaceOffsetM;\n            resnapNeedsUpdate = true;\n        }\n        if (Number.isFinite(config.resnapIntervalMs)) {\n            this.resnapIntervalMs = config.resnapIntervalMs;\n        }\n        if (Number.isFinite(config.resnapBudget)) {\n            this.resnapBudget = config.resnapBudget;\n        }\n        if (Number.isFinite(config.resnapToleranceM)) {\n            this.resnapToleranceM = config.resnapToleranceM;\n            resnapNeedsUpdate = true;\n        }\n        if (Number.isFinite(config.resnapFreezeFrames)) {\n            this.resnapFreezeFrames = config.resnapFreezeFrames;\n            resnapNeedsUpdate = true;\n        }\n        if (typeof config.tileDrivenResnap === 'boolean') {\n            this.tileDrivenResnap = config.tileDrivenResnap;\n            resnapNeedsUpdate = true;\n        }\n        if (Number.isFinite(config.fallbackResnapIntervalMs)) {\n            this.fallbackResnapIntervalMs = config.fallbackResnapIntervalMs;\n        }\n        if (typeof config.alignToTerrainNormal === 'boolean') {\n            const prevAlign = this.alignToTerrainNormal;\n            this.alignToTerrainNormal = config.alignToTerrainNormal;\n            if (prevAlign !== this.alignToTerrainNormal) {\n                resnapNeedsUpdate = true;\n            }\n        }\n        if (Number.isFinite(config.maxSamplesPerBuilding)) {\n            this.maxSamplesPerBuilding = config.maxSamplesPerBuilding;\n            rebuildSampleDirs = true;\n        }\n        if (Number.isFinite(config.radiusM)) {\n            this._radiusM = config.radiusM;\n            refreshNeeded = true;\n        }\n        if (Number.isFinite(config.falloffStartM)) {\n            this._falloffStartM = config.falloffStartM;\n            refreshNeeded = true;\n        }\n        if (typeof config.motionEnabled === 'boolean') {\n            this.motionEnabled = config.motionEnabled;\n            refreshNeeded = true;\n        }\n        if (Number.isFinite(config.motionMinSpeedMps)) {\n            this.motionMinSpeedMps = config.motionMinSpeedMps;\n            refreshNeeded = true;\n        }\n        if (Number.isFinite(config.motionSpeedRefMps)) {\n            this.motionSpeedRefMps = config.motionSpeedRefMps;\n            refreshNeeded = true;\n        }\n        if (Number.isFinite(config.motionAheadFactor)) {\n            this.motionAheadFactor = config.motionAheadFactor;\n            refreshNeeded = true;\n        }\n        if (Number.isFinite(config.motionBehindFactor)) {\n            this.motionBehindFactor = config.motionBehindFactor;\n            refreshNeeded = true;\n        }\n        if (Number.isFinite(config.motionQueryBias)) {\n            this.motionQueryBias = config.motionQueryBias;\n            refreshNeeded = true;\n        }\n        if (Number.isFinite(config.motionRetentionFactor)) {\n            this.motionRetentionFactor = config.motionRetentionFactor;\n        }\n        if (Number.isFinite(config.lodDetailRadiusM)) {\n            this.lodDetailRadiusM = config.lodDetailRadiusM;\n            lodNeedsUpdate = true;\n        }\n        if (Number.isFinite(config.lodImpostorRadiusM)) {\n            this.lodImpostorRadiusM = config.lodImpostorRadiusM;\n            lodNeedsUpdate = true;\n        }\n        if (Number.isFinite(config.lodUpdateIntervalMs)) {\n            this.lodUpdateIntervalMs = config.lodUpdateIntervalMs;\n        }\n        if (Number.isFinite(config.lodBudget)) {\n            this.lodBudget = config.lodBudget;\n        }\n        if (Number.isFinite(config.lodHysteresisM)) {\n            this.lodHysteresisM = config.lodHysteresisM;\n            lodNeedsUpdate = true;\n        }\n        if (typeof config.impostorEnabled === 'boolean') {\n            this.impostorEnabled = config.impostorEnabled;\n            lodNeedsUpdate = true;\n            impostorNeedsUpdate = true;\n        }\n        if (Number.isFinite(config.impostorMinSizeM)) {\n            this.impostorMinSizeM = config.impostorMinSizeM;\n            impostorNeedsUpdate = true;\n        }\n        if (Number.isFinite(config.impostorMinHeightM)) {\n            this.impostorMinHeightM = config.impostorMinHeightM;\n            impostorNeedsUpdate = true;\n        }\n        if (Number.isFinite(config.impostorHeightScale)) {\n            this.impostorHeightScale = config.impostorHeightScale;\n            impostorNeedsUpdate = true;\n        }\n        if (Number.isFinite(config.impostorRebuildBudget)) {\n            this.impostorRebuildBudget = config.impostorRebuildBudget;\n        }\n        if (typeof config.polypBakeToTiles === 'boolean') {\n            const prev = this.polypBakeToTiles;\n            this.polypBakeToTiles = config.polypBakeToTiles;\n            polypNeedsUpdate = true;\n            lodNeedsUpdate = true;\n            if (prev !== this.polypBakeToTiles) {\n                if (this.polypBakeToTiles) {\n                    for (const entry of this._instances) {\n                        if (entry?.group) entry.group.visible = false;\n                        if (entry?.pickerMesh) entry.pickerMesh.visible = false;\n                    }\n                    while (this._pickerRoot.children.length) {\n                        const child = this._pickerRoot.children.pop();\n                        if (child) this._pickerRoot.remove(child);\n                    }\n                } else {\n                    for (const entry of this._instances) {\n                        if (entry?.pickerMesh && entry.pickerMesh.parent !== this._pickerRoot) {\n                            this._pickerRoot.add(entry.pickerMesh);\n                        }\n                    }\n                    this._clearPolypMeshes();\n                }\n            }\n        }\n        if (typeof config.polypEnabled === 'boolean') {\n            const prev = this.polypEnabled;\n            this.polypEnabled = config.polypEnabled;\n            polypNeedsUpdate = true;\n            if (prev !== this.polypEnabled) {\n                if (this.polypEnabled) {\n                    for (const meshInfo of this._impostorMeshes.values()) {\n                        if (meshInfo?.mesh?.parent) meshInfo.mesh.parent.remove(meshInfo.mesh);\n                    }\n                    this._impostorMeshes.clear();\n                } else {\n                    this._clearPolypMeshes();\n                }\n            }\n        }\n        if (Number.isFinite(config.polypMinPointSpacingM)) {\n            this.polypMinPointSpacingM = config.polypMinPointSpacingM;\n            polypNeedsUpdate = true;\n        }\n        if (Number.isFinite(config.polypMaxPointsPerFootprint)) {\n            this.polypMaxPointsPerFootprint = config.polypMaxPointsPerFootprint;\n            polypNeedsUpdate = true;\n        }\n        if (Number.isFinite(config.polypMaxEntriesPerTile)) {\n            this.polypMaxEntriesPerTile = config.polypMaxEntriesPerTile;\n            polypNeedsUpdate = true;\n        }\n        if (Number.isFinite(config.polypHeightScale)) {\n            this.polypHeightScale = config.polypHeightScale;\n            polypNeedsUpdate = true;\n        }\n        if (Number.isFinite(config.polypMinHeightM)) {\n            this.polypMinHeightM = config.polypMinHeightM;\n            polypNeedsUpdate = true;\n        }\n        if (typeof config.imageryEnabled === 'boolean') {\n            this.imageryEnabled = config.imageryEnabled;\n        }\n        if (Number.isFinite(config.imageryUpdateIntervalMs)) {\n            this.imageryUpdateIntervalMs = config.imageryUpdateIntervalMs;\n        }\n        if (typeof config.photorealFallbackEnabled === 'boolean') {\n            const changed = this.photorealFallbackEnabled !== config.photorealFallbackEnabled;\n            this.photorealFallbackEnabled = config.photorealFallbackEnabled;\n            if (changed && this._photorealFallbackMode) {\n                if (this.photorealFallbackEnabled) this._queueAllPhotoCoverage({ reset: true });\n                else {\n                    this._photoCoverageQueue.clear();\n                    this._photoCoverageRetryEntries.clear();\n                    for (const entry of this._instances) this._syncEntryVisibility(entry);\n                }\n            }\n        }\n        if (Number.isFinite(config.photoProbeRaysPerFrame)) {\n            this.photoProbeRaysPerFrame = Math.max(1, Math.floor(config.photoProbeRaysPerFrame));\n        }\n        if (Number.isFinite(config.photoProbeBudgetMs)) {\n            this.photoProbeBudgetMs = Math.max(0.25, config.photoProbeBudgetMs);\n        }\n        if (Number.isFinite(config.photoCoverageMinHeightM)) {\n            this.photoCoverageMinHeightM = Math.max(1, config.photoCoverageMinHeightM);\n            if (this._photorealFallbackMode) this._queueAllPhotoCoverage({ reset: true });\n        }\n        if (Number.isFinite(config.photoExteriorMarginM)) {\n            this.photoExteriorMarginM = Math.max(1, config.photoExteriorMarginM);\n            if (this._photorealFallbackMode) this._queueAllPhotoCoverage({ reset: true });\n        }\n\n        if (rebuildSampleDirs) {\n            for (const entry of this._instances) {\n                if (!entry?.footprint || !entry.center) continue;\n                entry.sampleDirs = this._buildSampleDirs(entry.footprint, entry.center);\n                this._queueEntryForResnap(entry, { refreshTiles: true });\n            }\n        }\n\n        if (impostorNeedsUpdate) {\n            for (const entry of this._instances) {\n                this._recomputeImpostorSize(entry);\n            }\n            this._queueAllImpostorRebuilds();\n        }\n\n        if (polypNeedsUpdate) {\n            for (const entry of this._instances) {\n                if (!entry?.footprintLocal?.length) continue;\n                entry.polypFootprint = this._buildPolypFootprint(entry.footprintLocal);\n            }\n            this._queueAllImpostorRebuilds();\n        }\n\n        if (lodNeedsUpdate) {\n            this._queueAllEntriesForLod();\n        }\n\n        if (resnapNeedsUpdate) {\n            this._queueAllEntriesForResnap();\n        }\n\n        if (prevImageryEnabled !== this.imageryEnabled && !this._photorealFallbackMode) {\n            if (this.imageryEnabled) {\n                for (const entry of this._instances) {\n                    if (entry?.lod === 'detail') {\n                        this._applyEntryImagery(entry, entry.primaryTile);\n                    } else if (entry) {\n                        this._imageryPendingEntries.add(entry);\n                    }\n                }\n            } else {\n                for (const entry of this._instances) {\n                    this._clearEntryImagery(entry);\n                }\n            }\n        }\n\n        // If we have a center and config changed significantly, refresh buildings\n        if (this._center && refreshNeeded) {\n            // Queue a refresh on next setCenter call\n            this._refreshQueued = true;\n        }\n    }\n\n    _handleTileEvent(payload) {\n        if (!this.enabled) return;\n        if (!payload || !payload.tile) return;\n        const tile = payload.tile;\n        switch (payload.type) {\n            case 'elevation':\n                // CRITICAL: Terrain changed - immediately hide and resnap ALL affected buildings\n                // Buildings must NEVER be visible with stale terrain positioning\n                this._immediateTerrainResnap(tile);\n                this._queueTileForImpostorRebuild(tile);\n                break;\n            case 'split':\n            case 'merge':\n                this._markTileDirty(tile, { force: true });\n                this._queueEntriesForTile(tile, { refreshTiles: true });\n                this._queueTileForImpostorRebuild(tile);\n                if (Array.isArray(payload.children)) {\n                    for (const child of payload.children) {\n                        this._queueTileForImpostorRebuild(child);\n                    }\n                }\n                break;\n            case 'visible-added':\n                this._setTileGroupVisibility(tile, true);\n                if ((this.polypBakeToTiles || this.polypEnabled) &&\n                    this._tileToEntries.get(tile)?.size) {\n                    this._queueTileForImpostorRebuild(tile);\n                }\n                break;\n            case 'visible-removed':\n                this._setTileGroupVisibility(tile, false);\n                break;\n            default:\n                break;\n        }\n    }\n\n    _markTileDirty(tile, { force = false } = {}) {\n        if (!tile) return;\n        const now = (typeof performance !== 'undefined' && performance.now) ? performance.now() : Date.now();\n        const last = this._dirtyTileStamp.get(tile) || 0;\n        if (!force && now - last < this._dirtyTileCooldownMs) return;\n        this._dirtyTileStamp.set(tile, now);\n        this._dirtyTiles.add(tile);\n    }\n\n    _setTileGroupVisibility(tile, visible) {\n        const group = this._getTileGroup(tile);\n        if (group) group.visible = !!visible;\n    }\n\n    _queueTileGroupCleanup(tile) {\n        const group = this._getTileGroup(tile);\n        if (group) this._pendingTileGroupCleanup.add(group);\n    }\n\n    _queueEntryForResnap(entry, { refreshTiles = false } = {}) {\n        if (!entry) return;\n        entry.resnapFrozen = false;\n        entry.resnapStableFrames = 0;\n        if (refreshTiles) entry.needsTileRefresh = true;\n        this._pendingEntries.add(entry);\n    }\n\n    _queueAllEntriesForResnap({ refreshTiles = false } = {}) {\n        for (const entry of this._instances) {\n            this._queueEntryForResnap(entry, { refreshTiles });\n        }\n    }\n\n    _queueFallbackEntriesForTile(tile) {\n        if (!tile || !this._fallbackEntries.size) return;\n        if (!this.triTree || typeof this.triTree.findLeafTileForWorldDir !== 'function') return;\n        const worldQuat = this.triTree.group?.getWorldQuaternion(this._tmpQuat) || null;\n        for (const entry of this._fallbackEntries) {\n            if (!entry?.dir) continue;\n            const dir = this._tmpDir.copy(entry.dir).normalize();\n            if (worldQuat) dir.applyQuaternion(worldQuat);\n            const leaf = this.triTree.findLeafTileForWorldDir(dir);\n            if (leaf === tile || this._isTileAncestor(tile, leaf)) {\n                // Reset the resnap timer so it gets processed immediately\n                entry.nextFallbackResnapAt = null;\n                this._queueEntryForResnap(entry, { refreshTiles: false });\n            }\n        }\n    }\n\n    /**\n     * IMMEDIATELY hide and resnap all buildings affected by terrain change.\n     * This bypasses the normal budget system - terrain changes require instant response.\n     * Buildings must NEVER be visible with incorrect terrain positioning.\n     */\n    _immediateTerrainResnap(tile) {\n        if (!tile) return;\n\n        // Invalidate cached terrain samples for this tile - we need fresh data\n        this._tileSampleCache.delete(tile);\n\n        const nowMs = (typeof performance !== 'undefined' && performance.now)\n            ? performance.now()\n            : Date.now();\n\n        // Get all entries for this tile\n        const entries = this._tileToEntries.get(tile);\n        if (entries && entries.size) {\n            for (const entry of entries) {\n                // IMMEDIATELY hide - no exceptions\n                if (entry.group) entry.group.visible = false;\n                if (entry.pickerMesh) entry.pickerMesh.visible = false;\n                entry.pendingVisibility = true;\n                entry._wasFallback = true;\n                entry.resnapFrozen = false;\n                entry.resnapStableFrames = 0;\n\n                // Immediately update position (bypass budget)\n                this._updateEntryPosition(entry, null, nowMs);\n\n                // Queue for LOD to potentially re-show if terrain is now valid\n                this._queueEntryForLod(entry);\n            }\n        }\n\n        // Also handle fallback entries that might overlap this tile\n        if (this._fallbackEntries.size) {\n            const worldQuat = this.triTree?.group?.getWorldQuaternion(this._tmpQuat) || null;\n            for (const entry of this._fallbackEntries) {\n                if (!entry?.dir) continue;\n                const dir = this._tmpDir.copy(entry.dir).normalize();\n                if (worldQuat) dir.applyQuaternion(worldQuat);\n                const leaf = this.triTree?.findLeafTileForWorldDir?.(dir);\n                if (leaf === tile || this._isTileAncestor(tile, leaf)) {\n                    // Hide and update immediately\n                    if (entry.group) entry.group.visible = false;\n                    if (entry.pickerMesh) entry.pickerMesh.visible = false;\n                    entry.nextFallbackResnapAt = null;\n                    entry.resnapFrozen = false;\n                    entry.resnapStableFrames = 0;\n\n                    this._updateEntryPosition(entry, null, nowMs);\n                    this._queueEntryForLod(entry);\n                }\n            }\n        }\n\n        // Clear from dirty tiles since we handled it immediately\n        this._dirtyTiles.delete(tile);\n        this._dirtyTileStamp.delete(tile);\n    }\n\n    _queueAllEntriesForLod() {\n        for (const entry of this._instances) {\n            this._queueEntryForLod(entry);\n        }\n    }\n\n    _queueAllImpostorRebuilds() {\n        for (const tile of this._tileToEntries.keys()) {\n            if (tile) this._impostorDirtyTiles.add(tile);\n        }\n    }\n\n    _recomputeImpostorSize(entry) {\n        if (!entry) return;\n        const bounds = entry.bounds || {};\n        const width = Math.max(Number.isFinite(bounds.width) ? bounds.width : 0, this.impostorMinSizeM || 0);\n        const depth = Math.max(Number.isFinite(bounds.depth) ? bounds.depth : 0, this.impostorMinSizeM || 0);\n        const baseHeight = Number.isFinite(entry.info?.height)\n            ? entry.info.height\n            : (Number.isFinite(entry.impostorSize?.height) ? entry.impostorSize.height : 1);\n        const height = Math.max(baseHeight * (this.impostorHeightScale || 1), this.impostorMinHeightM || 0);\n        entry.impostorSize = { width, depth, height };\n    }\n\n    _queueEntriesForTile(tile, { refreshTiles = false } = {}) {\n        const entries = this._tileToEntries.get(tile);\n        if (entries && entries.size) {\n            for (const entry of entries) {\n                this._queueEntryForResnap(entry, { refreshTiles });\n            }\n            return;\n        }\n        if (!this.triTree || typeof this.triTree.findLeafTileForWorldDir !== 'function') return;\n        const worldQuat = this.triTree.group?.getWorldQuaternion(this._tmpQuat) || null;\n        for (const entry of this._instances) {\n            const samples = Array.isArray(entry?.sampleDirs) && entry.sampleDirs.length\n                ? entry.sampleDirs\n                : (entry?.dir ? [entry.dir] : []);\n            if (!samples.length) continue;\n            for (const sample of samples) {\n                if (!sample) continue;\n                const dir = this._tmpDir.copy(sample).normalize();\n                if (worldQuat) dir.applyQuaternion(worldQuat);\n                const leaf = this.triTree.findLeafTileForWorldDir(dir);\n                if (leaf === tile || this._isTileAncestor(tile, leaf)) {\n                    this._queueEntryForResnap(entry, { refreshTiles });\n                    break;\n                }\n            }\n        }\n    }\n\n    _queueEntryForLod(entry) {\n        if (!entry) return;\n        this._lodDirtyEntries.add(entry);\n    }\n\n    _queueTileForImpostorRebuild(tile) {\n        if (!tile) return;\n        this._impostorDirtyTiles.add(tile);\n    }\n\n    _queueEntryTilesForBake(entry) {\n        if (!entry) return;\n        if (entry.tiles && entry.tiles.size) {\n            for (const tile of entry.tiles) {\n                if (tile) this._queueTileForImpostorRebuild(tile);\n            }\n            return;\n        }\n        if (entry.primaryTile) this._queueTileForImpostorRebuild(entry.primaryTile);\n    }\n\n    _getEntryDistance(entry) {\n        if (!this.camera || !entry?.group?.position) return Infinity;\n        const worldPos = entry.group.getWorldPosition(this._tmpVec3);\n        return this.camera.position.distanceTo(worldPos);\n    }\n\n    _updateEntryLod(entry, nowMs = null) {\n        if (!entry?.group) return;\n        if (entry.pendingVisibility) return;\n        const dist = this._getEntryDistance(entry);\n        if (!Number.isFinite(dist)) return;\n\n        const hysteresis = Number.isFinite(this.lodHysteresisM) ? this.lodHysteresisM : 0;\n        const detailRadius = Number.isFinite(this.lodDetailRadiusM)\n            ? this.lodDetailRadiusM\n            : this._radiusM;\n        const maxVisibleRadius = Number.isFinite(this.lodImpostorRadiusM)\n            ? this.lodImpostorRadiusM\n            : this._radiusM;\n        // Repair solids retain their true arbitrary footprint geometry. Box /\n        // polyp impostors are TriTree-hosted and would both duplicate Cesium\n        // content and erase the per-footprint coverage decision.\n        const allowImpostor = this.impostorEnabled === true && !this._photorealFallbackMode;\n\n        let nextLod = entry.lod || 'detail';\n\n        if (!allowImpostor) {\n            nextLod = dist <= maxVisibleRadius ? 'detail' : 'hidden';\n        } else if (nextLod === 'detail') {\n            if (dist > detailRadius + hysteresis) {\n                nextLod = dist <= maxVisibleRadius + hysteresis ? 'impostor' : 'hidden';\n            }\n        } else if (nextLod === 'impostor') {\n            if (dist <= detailRadius) {\n                nextLod = 'detail';\n            } else if (dist > maxVisibleRadius + hysteresis) {\n                nextLod = 'hidden';\n            }\n        } else {\n            if (dist <= detailRadius) {\n                nextLod = 'detail';\n            } else if (dist <= maxVisibleRadius) {\n                nextLod = 'impostor';\n            }\n        }\n\n        const showDetail = nextLod === 'detail'\n            && !this.polypBakeToTiles\n            && this._isPhotoFallbackVisible(entry);\n        const needsVisibilitySync = (entry.group && entry.group.visible !== showDetail) ||\n            (entry.pickerMesh && entry.pickerMesh.visible !== showDetail);\n        if (nextLod !== entry.lod || needsVisibilitySync) {\n            this._setEntryLod(entry, nextLod, { nowMs });\n        }\n    }\n\n    _setEntryLod(entry, lod, { nowMs = null } = {}) {\n        if (!entry) return;\n\n        const wantsVisible = lod === 'detail'\n            && !this.polypBakeToTiles\n            && this._isPhotoFallbackVisible(entry);\n\n        // CRITICAL: Never show a building without valid terrain data\n        if (wantsVisible && !this._hasValidTerrainForEntry(entry)) {\n            // Keep hidden and queue for resnap when terrain arrives\n            entry.lod = 'hidden';\n            if (entry.group) entry.group.visible = false;\n            if (entry.pickerMesh) entry.pickerMesh.visible = false;\n            entry.pendingVisibility = true;\n            entry._wasFallback = true;\n            this._fallbackEntries.add(entry);\n            return;\n        }\n\n        entry.lod = lod;\n        const showDetail = wantsVisible && this._geometryVisible;\n        if (entry.group) entry.group.visible = showDetail;\n        if (entry.pickerMesh) entry.pickerMesh.visible = showDetail;\n        if (entry.labelHandle?.group) {\n            entry.labelHandle.group.visible = showDetail || !this._photorealFallbackMode;\n        }\n\n        if (showDetail && this.imageryEnabled && !this._photorealFallbackMode) {\n            this._applyEntryImagery(entry, entry.primaryTile, { nowMs });\n        }\n\n        const tile = entry.primaryTile;\n        if (tile) this._queueTileForImpostorRebuild(tile);\n    }\n\n    _isTileAncestor(ancestor, tile) {\n        if (!ancestor || !tile) return false;\n        let cursor = tile;\n        while (cursor) {\n            if (cursor === ancestor) return true;\n            cursor = cursor.parent || null;\n        }\n        return false;\n    }\n\n    _resolveTilesForEntry(entry) {\n        const tiles = new Set();\n        if (!this.triTree || typeof this.triTree.findLeafTileForWorldDir !== 'function') {\n            return tiles;\n        }\n        const worldQuat = this.triTree.group?.getWorldQuaternion(this._tmpQuat) || null;\n        const samples = Array.isArray(entry?.sampleDirs) && entry.sampleDirs.length\n            ? entry.sampleDirs\n            : (entry?.dir ? [entry.dir] : []);\n        for (const sample of samples) {\n            if (!sample) continue;\n            const dir = this._tmpDir.copy(sample).normalize();\n            if (worldQuat) dir.applyQuaternion(worldQuat);\n            const tile = this.triTree.findLeafTileForWorldDir(dir);\n            if (tile) tiles.add(tile);\n        }\n        return tiles;\n    }\n\n    _setEntryTiles(entry, tiles) {\n        if (entry.tiles) {\n            for (const tile of entry.tiles) {\n                const bucket = this._tileToEntries.get(tile);\n                if (bucket) {\n                    bucket.delete(entry);\n                    if (!bucket.size) this._tileToEntries.delete(tile);\n                }\n            }\n        }\n        entry.tiles = tiles;\n        for (const tile of tiles) {\n            let bucket = this._tileToEntries.get(tile);\n            if (!bucket) {\n                bucket = new Set();\n                this._tileToEntries.set(tile, bucket);\n            }\n            bucket.add(entry);\n        }\n    }\n\n    _refreshEntryTiles(entry) {\n        if (!entry) return;\n        const tiles = this._resolveTilesForEntry(entry);\n        this._setEntryTiles(entry, tiles);\n        this._updateEntryPrimaryTile(entry, tiles);\n        if (this.imageryEnabled && !this._photorealFallbackMode && entry.lod === 'detail') {\n            this._applyEntryImagery(entry, entry.primaryTile);\n        }\n        this._queueEntryForLod(entry);\n    }\n\n    _rebuildImpostorsForTile(tile) {\n        if (this.polypEnabled || this.polypBakeToTiles) {\n            this._rebuildPolypsForTile(tile);\n            return;\n        }\n        this._rebuildImpostorBoxesForTile(tile);\n    }\n\n    _rebuildImpostorBoxesForTile(tile) {\n        if (!tile) return;\n        const tileKey = this._getTileKey(tile);\n        if (!tileKey) return;\n        const host = this._getTileGroup(tile);\n        if (!host) return;\n\n        const entries = this._tileToEntries.get(tile);\n        const impostorEntries = [];\n        if (entries && entries.size) {\n            for (const entry of entries) {\n                if (entry?.lod === 'impostor') impostorEntries.push(entry);\n            }\n        }\n\n        if (!this.impostorEnabled || impostorEntries.length === 0) {\n            const existing = this._impostorMeshes.get(tileKey);\n            if (existing?.mesh?.parent) {\n                existing.mesh.parent.remove(existing.mesh);\n            }\n            this._impostorMeshes.delete(tileKey);\n            return;\n        }\n\n        const required = impostorEntries.length;\n        let meshInfo = this._impostorMeshes.get(tileKey) || null;\n        let mesh = meshInfo?.mesh || null;\n        if (!mesh || mesh.count < required) {\n            if (mesh?.parent) mesh.parent.remove(mesh);\n            mesh = new THREE.InstancedMesh(this._impostorGeometry, this._impostorMaterial, required);\n            mesh.name = `BuildingImpostors:${tileKey}`;\n            mesh.instanceMatrix.setUsage(THREE.DynamicDrawUsage);\n            host.add(mesh);\n            meshInfo = { mesh };\n            this._impostorMeshes.set(tileKey, meshInfo);\n        }\n\n        mesh.count = required;\n        let idx = 0;\n        for (const entry of impostorEntries) {\n            const size = entry.impostorSize || {};\n            const width = Math.max(\n                Number.isFinite(size.width) ? size.width : 1,\n                this.impostorMinSizeM || 0\n            );\n            const depth = Math.max(\n                Number.isFinite(size.depth) ? size.depth : 1,\n                this.impostorMinSizeM || 0\n            );\n            let height = Number.isFinite(size.height) ? size.height : 1;\n            height = Math.max(height, this.impostorMinHeightM || 0);\n\n            this._tmpScale.set(width, depth, height);\n            const position = entry.group?.position\n                ? entry.group.position\n                : this._tmpPosition.copy(entry.dir).multiplyScalar(entry.surfaceRadius || this.planetRadius);\n            const quat = entry.group?.quaternion || this._tmpQuat.identity();\n            this._tmpMatrix.compose(position, quat, this._tmpScale);\n            mesh.setMatrixAt(idx, this._tmpMatrix);\n            idx += 1;\n        }\n\n        mesh.instanceMatrix.needsUpdate = true;\n        mesh.visible = host.visible;\n    }\n\n    _rebuildPolypsForTile(tile) {\n        if (!tile) return;\n        const tileKey = this._getTileKey(tile);\n        if (!tileKey) return;\n        const host = this._getTileGroup(tile);\n        if (!host) return;\n\n        this._perfStart('cpu.buildings.polyp.rebuild');\n        try {\n            const impostor = this._impostorMeshes.get(tileKey);\n            if (impostor?.mesh?.parent) {\n                impostor.mesh.parent.remove(impostor.mesh);\n            }\n            this._impostorMeshes.delete(tileKey);\n\n            const entries = this._tileToEntries.get(tile);\n            const existingPolyp = this._polypMeshes.get(tileKey) || null;\n            const polypEntries = [];\n            if (entries && entries.size) {\n                for (const entry of entries) {\n                    const allowEntry = this.polypBakeToTiles\n                        ? entry?.lod !== 'hidden'\n                        : entry?.lod === 'impostor';\n                    if (allowEntry && entry?.polypFootprint?.length >= 3) {\n                        polypEntries.push(entry);\n                        if (Number.isFinite(this.polypMaxEntriesPerTile) &&\n                            this.polypMaxEntriesPerTile > 0 &&\n                            polypEntries.length >= this.polypMaxEntriesPerTile) {\n                            break;\n                        }\n                    }\n                }\n            }\n            if (this.debugLogs) {\n                console.log(`[BuildingOverlay] _rebuildPolypsForTile: tile level=${tile.level}, entries=${entries?.size || 0}, polypEntries=${polypEntries.length}, impostorEnabled=${this.impostorEnabled}, polypBakeToTiles=${this.polypBakeToTiles}`);\n            }\n\n            const clearPolypEntry = () => {\n                // Clear new footprint-based modifications\n                if (tile?.applyBuildingFootprints) {\n                    tile.applyBuildingFootprints(null);\n                }\n                // Clear old extrusion-based modifications\n                if (tile?.setBuildingExtrusions) {\n                    tile.setBuildingExtrusions(null);\n                }\n                if (existingPolyp?.useFootprints && existingPolyp?.tile?.applyBuildingFootprints) {\n                    existingPolyp.tile.applyBuildingFootprints(null);\n                }\n                if (existingPolyp?.tile?.setBuildingExtrusions) {\n                    existingPolyp.tile.setBuildingExtrusions(null);\n                }\n                if (existingPolyp?.mesh?.parent) {\n                    existingPolyp.mesh.parent.remove(existingPolyp.mesh);\n                }\n                if (existingPolyp?.mesh?.geometry) {\n                    existingPolyp.mesh.geometry.dispose();\n                }\n                this._polypMeshes.delete(tileKey);\n            };\n\n            // For bake-to-tiles mode, we don't require impostorEnabled\n            const requiresImpostor = !this.polypBakeToTiles && !this.impostorEnabled;\n            const hasAppliedFootprints = !!existingPolyp || !!tile?._buildingFootprints || tile?._buildingModified;\n            if (requiresImpostor || polypEntries.length === 0) {\n                if (hasAppliedFootprints) {\n                    clearPolypEntry();\n                }\n                return;\n            }\n\n            const tileCenter = tile.center || null;\n            const positions = [];\n\n            if (this.polypBakeToTiles) {\n                // Use new vertex extrusion approach if available\n                if (typeof tile.applyBuildingFootprints === 'function') {\n                    const buildings = [];\n                    for (const entry of polypEntries) {\n                        if (!entry?.polypFootprint || entry.polypFootprint.length < 3) continue;\n                        const baseHeight = Number.isFinite(entry.info?.height) ? entry.info.height : 10;\n                        const height = Math.max(baseHeight * (this.polypHeightScale || 1), this.polypMinHeightM || 0);\n                        if (!Number.isFinite(height) || height <= 0) continue;\n\n                        // Ensure basePosition is valid\n                        const basePosition = entry.group?.position;\n                        if (!basePosition || !Number.isFinite(basePosition.x)) {\n                            if (this.debugLogs) {\n                                console.warn('[BuildingOverlay] Skipping building - no valid basePosition');\n                            }\n                            continue;\n                        }\n\n                        buildings.push({\n                            footprint: entry.polypFootprint, // Array<{x, y}> in local frame\n                            height: height,\n                            quaternion: entry.group?.quaternion || null,\n                            basePosition: basePosition.clone(),\n                            embed: Number.isFinite(entry.embed) ? entry.embed : 0,\n                            center: entry.center || null\n                        });\n                    }\n\n                    if (this.debugLogs) {\n                        console.log(`[BuildingOverlay] applyBuildingFootprints: ${buildings.length} buildings for tile level ${tile.level}, tile.applyBuildingFootprints exists: ${typeof tile.applyBuildingFootprints}`);\n                    }\n\n                    if (buildings.length === 0) {\n                        clearPolypEntry();\n                        return;\n                    }\n\n                    // Calculate LOD factor based on tile level (higher level = closer = more detail)\n                    const lodFactor = Math.min(1, Math.max(0.1, tile.level / 18));\n\n                    this._perfStart('cpu.buildings.polyp.apply');\n                    try {\n                        tile.applyBuildingFootprints(buildings, {\n                            lodFactor: lodFactor,\n                            maxSubdivisions: Math.max(1, Math.floor(lodFactor * 4)),\n                            debugLogs: this.debugLogs\n                        });\n                        if (this.debugLogs) {\n                            console.log(`[BuildingOverlay] applyBuildingFootprints completed for tile level ${tile.level}`);\n                        }\n                    } catch (err) {\n                        console.error(`[BuildingOverlay] applyBuildingFootprints error:`, err);\n                    } finally {\n                        this._perfEnd('cpu.buildings.polyp.apply');\n                    }\n\n                    this._polypMeshes.set(tileKey, { tile, useFootprints: true });\n                    return;\n                }\n\n                // Fallback to old separate geometry approach\n                for (const entry of polypEntries) {\n                    this._appendPolypGeometry(entry, tileCenter, positions, null);\n                }\n\n                if (!positions.length) {\n                    clearPolypEntry();\n                    return;\n                }\n\n                if (typeof tile.setBuildingExtrusions === 'function') {\n                    tile.setBuildingExtrusions({ positions: new Float32Array(positions) });\n                }\n\n                const existing = this._polypMeshes.get(tileKey);\n                if (existing?.mesh?.parent) {\n                    existing.mesh.parent.remove(existing.mesh);\n                }\n                if (existing?.mesh?.geometry) {\n                    existing.mesh.geometry.dispose();\n                }\n                this._polypMeshes.set(tileKey, { tile });\n                return;\n            }\n\n            const normals = [];\n            for (const entry of polypEntries) {\n                this._appendPolypGeometry(entry, tileCenter, positions, normals);\n            }\n\n            if (!positions.length) {\n                clearPolypEntry();\n                return;\n            }\n\n            const previous = this._polypMeshes.get(tileKey);\n            if (tile?.setBuildingExtrusions) {\n                tile.setBuildingExtrusions(null);\n            }\n            if (previous?.tile?.setBuildingExtrusions) {\n                previous.tile.setBuildingExtrusions(null);\n            }\n\n            const geometry = new THREE.BufferGeometry();\n            geometry.setAttribute('position', new THREE.BufferAttribute(new Float32Array(positions), 3));\n            geometry.setAttribute('normal', new THREE.BufferAttribute(new Float32Array(normals), 3));\n            geometry.computeBoundingSphere();\n\n            let meshInfo = previous || null;\n            let mesh = meshInfo?.mesh || null;\n            if (!mesh) {\n                mesh = new THREE.Mesh(geometry, this._polypMaterial);\n                mesh.name = `BuildingPolyps:${tileKey}`;\n                host.add(mesh);\n                meshInfo = { mesh };\n                this._polypMeshes.set(tileKey, meshInfo);\n            } else {\n                if (mesh.geometry) {\n                    mesh.geometry.dispose();\n                }\n                mesh.geometry = geometry;\n                meshInfo.tile = null;\n            }\n\n            if (tileCenter) {\n                mesh.position.copy(tileCenter);\n            } else {\n                mesh.position.set(0, 0, 0);\n            }\n            mesh.visible = host.visible;\n        } finally {\n            this._perfEnd('cpu.buildings.polyp.rebuild');\n        }\n    }\n\n    _appendPolypGeometry(entry, tileCenter, positions, normals) {\n        const footprint = entry?.polypFootprint;\n        if (!footprint || footprint.length < 3) return;\n        const baseHeight = Number.isFinite(entry.info?.height) ? entry.info.height : 0;\n        const height = Math.max(baseHeight * (this.polypHeightScale || 1), this.polypMinHeightM || 0);\n        if (!Number.isFinite(height) || height <= 0) return;\n\n        const basePos = entry.group?.position\n            ? entry.group.position\n            : this._tmpPosition.copy(entry.dir).multiplyScalar(entry.surfaceRadius || this.planetRadius);\n        const quat = entry.group?.quaternion || null;\n        const embed = Number.isFinite(entry.embed) ? entry.embed : 0;\n        const tileCx = tileCenter?.x || 0;\n        const tileCy = tileCenter?.y || 0;\n        const tileCz = tileCenter?.z || 0;\n\n        const up = this._tmpPolypUp.set(0, 0, 1);\n        if (quat) {\n            up.applyQuaternion(quat);\n        } else if (entry?.dir) {\n            up.copy(entry.dir).normalize();\n        }\n\n        const ground = new Array(footprint.length * 3);\n        const top = new Array(footprint.length * 3);\n        const lift = height + embed;\n        for (let i = 0; i < footprint.length; i += 1) {\n            const point = footprint[i];\n            this._tmpPolypLocal.set(point.x, point.y, 0);\n            if (quat) {\n                this._tmpPolypLocal.applyQuaternion(quat);\n            }\n            const gx = basePos.x + this._tmpPolypLocal.x - up.x * embed;\n            const gy = basePos.y + this._tmpPolypLocal.y - up.y * embed;\n            const gz = basePos.z + this._tmpPolypLocal.z - up.z * embed;\n            ground[i * 3] = gx;\n            ground[i * 3 + 1] = gy;\n            ground[i * 3 + 2] = gz;\n            top[i * 3] = gx + up.x * lift;\n            top[i * 3 + 1] = gy + up.y * lift;\n            top[i * 3 + 2] = gz + up.z * lift;\n        }\n\n        const triangles = THREE.ShapeUtils.triangulateShape(footprint, []);\n        for (const tri of triangles) {\n            const a = tri[0];\n            const b = tri[1];\n            const c = tri[2];\n            this._pushPolypTriangle(\n                positions,\n                normals,\n                top[a * 3] - tileCx,\n                top[a * 3 + 1] - tileCy,\n                top[a * 3 + 2] - tileCz,\n                top[b * 3] - tileCx,\n                top[b * 3 + 1] - tileCy,\n                top[b * 3 + 2] - tileCz,\n                top[c * 3] - tileCx,\n                top[c * 3 + 1] - tileCy,\n                top[c * 3 + 2] - tileCz\n            );\n        }\n\n        const count = footprint.length;\n        for (let i = 0; i < count; i += 1) {\n            const j = (i + 1) % count;\n            const gax = ground[i * 3] - tileCx;\n            const gay = ground[i * 3 + 1] - tileCy;\n            const gaz = ground[i * 3 + 2] - tileCz;\n            const gbx = ground[j * 3] - tileCx;\n            const gby = ground[j * 3 + 1] - tileCy;\n            const gbz = ground[j * 3 + 2] - tileCz;\n            const tax = top[i * 3] - tileCx;\n            const tay = top[i * 3 + 1] - tileCy;\n            const taz = top[i * 3 + 2] - tileCz;\n            const tbx = top[j * 3] - tileCx;\n            const tby = top[j * 3 + 1] - tileCy;\n            const tbz = top[j * 3 + 2] - tileCz;\n\n            this._pushPolypTriangle(\n                positions,\n                normals,\n                gax, gay, gaz,\n                gbx, gby, gbz,\n                tbx, tby, tbz\n            );\n            this._pushPolypTriangle(\n                positions,\n                normals,\n                gax, gay, gaz,\n                tbx, tby, tbz,\n                tax, tay, taz\n            );\n        }\n    }\n\n    _pushPolypTriangle(positions, normals, ax, ay, az, bx, by, bz, cx, cy, cz) {\n        positions.push(ax, ay, az, bx, by, bz, cx, cy, cz);\n        if (!normals) return;\n        this._tmpPolypA.set(ax, ay, az);\n        this._tmpPolypB.set(bx, by, bz);\n        this._tmpPolypC.set(cx, cy, cz);\n        this._tmpPolypNormal.subVectors(this._tmpPolypB, this._tmpPolypA);\n        this._tmpPolypEdge.subVectors(this._tmpPolypC, this._tmpPolypA);\n        this._tmpPolypNormal.cross(this._tmpPolypEdge).normalize();\n        normals.push(\n            this._tmpPolypNormal.x, this._tmpPolypNormal.y, this._tmpPolypNormal.z,\n            this._tmpPolypNormal.x, this._tmpPolypNormal.y, this._tmpPolypNormal.z,\n            this._tmpPolypNormal.x, this._tmpPolypNormal.y, this._tmpPolypNormal.z\n        );\n    }\n\n    _clearEntryImagery(entry) {\n        if (!entry?.mesh?.material) return;\n        entry.mesh.material.map = null;\n        entry.mesh.material.color.copy(this.baseMaterial.color);\n        entry.mesh.material.needsUpdate = true;\n        entry.imageryAtlasKey = null;\n        entry.imageryVersion = null;\n        this._imageryPendingEntries.delete(entry);\n    }\n\n    _applyEntryImagery(entry, tile, { force = false, nowMs = null } = {}) {\n        if (!entry?.mesh?.geometry || !entry.center) return false;\n        if (!this.imageryEnabled) {\n            this._clearEntryImagery(entry);\n            return false;\n        }\n\n        const imageryTile = tile || entry.primaryTile;\n        const texture = imageryTile?.imageryTexture || null;\n        const atlasKey = imageryTile?.imageryAtlasKey || null;\n        const atlasZoom = Number.isFinite(imageryTile?.imageryAtlasZoom)\n            ? imageryTile.imageryAtlasZoom\n            : imageryTile?.imageryZoom;\n        const minX = imageryTile?.imageryAtlasMinX;\n        const minY = imageryTile?.imageryAtlasMinY;\n        const wTiles = imageryTile?.imageryAtlasW;\n        const hTiles = imageryTile?.imageryAtlasH;\n        if (!texture || !atlasKey || !Number.isFinite(atlasZoom) ||\n            !Number.isFinite(minX) || !Number.isFinite(minY) ||\n            !Number.isFinite(wTiles) || !Number.isFinite(hTiles)) {\n            this._imageryPendingEntries.add(entry);\n            return false;\n        }\n\n        const version = imageryTile?.imageryVersion || null;\n        if (!force && entry.imageryAtlasKey === atlasKey && entry.imageryVersion === version) {\n            return true;\n        }\n\n        const imageryManager = imageryTile?.imageryManager || this.triTree?.imageryManager || null;\n        const tileSize = imageryManager?.tileSize || 256;\n        const atlasWidth = wTiles * tileSize;\n        const atlasHeight = hTiles * tileSize;\n        if (!atlasWidth || !atlasHeight) {\n            this._imageryPendingEntries.add(entry);\n            return false;\n        }\n\n        const halfPixelU = 0.5 / atlasWidth;\n        const halfPixelV = 0.5 / atlasHeight;\n        const center = entry.center;\n        const latRad = THREE.MathUtils.degToRad(center.lat);\n        const metersLat = metersPerDegLat(latRad);\n        const metersLon = metersPerDegLon(latRad);\n\n        const geometry = entry.mesh.geometry;\n        const positionAttr = geometry.getAttribute('position');\n        if (!positionAttr) return false;\n\n        const uvArray = new Float32Array(positionAttr.count * 2);\n        for (let i = 0; i < positionAttr.count; i++) {\n            const x = positionAttr.getX(i);\n            const y = positionAttr.getY(i);\n            const lat = center.lat + (y / metersLat);\n            const lon = center.lon + (x / metersLon);\n            const coords = lonLatToTileCoords(lon, lat, atlasZoom);\n            const u = ((coords.cx - minX) * tileSize + 0.5) / atlasWidth;\n            const v = ((coords.cy - minY) * tileSize + 0.5) / atlasHeight;\n            uvArray[i * 2 + 0] = THREE.MathUtils.clamp(u, halfPixelU, 1 - halfPixelU);\n            uvArray[i * 2 + 1] = 1 - THREE.MathUtils.clamp(v, halfPixelV, 1 - halfPixelV);\n        }\n\n        geometry.setAttribute('uv', new THREE.BufferAttribute(uvArray, 2));\n        geometry.attributes.uv.needsUpdate = true;\n\n        entry.mesh.material.map = texture;\n        entry.mesh.material.color.set(0xffffff);\n        entry.mesh.material.needsUpdate = true;\n        entry.imageryAtlasKey = atlasKey;\n        entry.imageryVersion = version;\n        this._imageryPendingEntries.delete(entry);\n        return true;\n    }\n\n    _appendEntries(entries, { final = false } = {}) {\n        const hasEntries = Array.isArray(entries) && entries.length > 0;\n        if (hasEntries) {\n            for (const entry of entries) {\n                this._instances.push(entry);\n                // Add picker mesh to picker root for hover detection\n                if (entry.pickerMesh && !this.polypBakeToTiles) {\n                    this._pickerRoot.add(entry.pickerMesh);\n                }\n                this._refreshEntryTiles(entry);\n                this._attachEntryGroup(entry);\n                this._queueEntryForLod(entry);\n                if (this._photorealFallbackMode) {\n                    this._queuePhotoCoverage(entry, { reset: true });\n                } else if (this.imageryEnabled &&\n                    entry.lod === 'detail' &&\n                    !this.polypBakeToTiles &&\n                    !entry.pendingVisibility) {\n                    this._applyEntryImagery(entry, entry.primaryTile);\n                }\n                if (!this._photorealFallbackMode && (this.polypBakeToTiles || this.polypEnabled)) {\n                    this._queueEntryTilesForBake(entry);\n                }\n            }\n        }\n        if (final && !this._photorealFallbackMode && (this.polypBakeToTiles || this.polypEnabled)) {\n            this._queueAllImpostorRebuilds();\n        }\n    }\n\n    _replaceMeshes(entries) {\n        this.clear();\n        this._appendEntries(entries, { final: true });\n    }\n\n    /* ========================================================================\n     * HOVER SYSTEM - Building hover detection and display\n     * ======================================================================== */\n\n    /**\n     * Update hover state based on raycaster intersection\n     * @param {THREE.Raycaster} raycaster - The raycaster to use for intersection\n     * @param {THREE.Camera} camera - The camera for projection\n     * @param {Object} opts - Options including pointer position\n     */\n    updateHover(raycaster, camera, opts = {}) {\n        if (this.polypBakeToTiles || !this._pickerRoot.children.length) {\n            this.clearHover();\n            return;\n        }\n\n        const intersects = raycaster.intersectObjects(this._pickerRoot.children, false);\n        if (!intersects.length) {\n            this.clearHover();\n            return;\n        }\n\n        const hit = intersects[0];\n        const info = hit.object.userData.buildingInfo;\n        if (!info) {\n            this.clearHover();\n            return;\n        }\n\n        this._showHover(info, hit.point, camera, opts);\n    }\n\n    /**\n     * Clear any active hover state\n     */\n    clearHover() {\n        if (this._hoverEdges) {\n            this._hoverEdges.geometry.dispose();\n            this._hoverEdges.geometry = new THREE.BufferGeometry();\n            this._hoverEdges.visible = false;\n        }\n        if (this._hoverGroup) this._hoverGroup.visible = false;\n        this._hoverInfo = null;\n        this._hideHoverOverlay();\n        this._hideAddressToast();\n    }\n\n    /**\n     * Show hover highlight and info for a building\n     */\n    _showHover(info, point, camera, opts = {}) {\n        this._ensureHoverArtifacts();\n\n        // Update highlight edges once per target\n        if (this._hoverInfo !== info) {\n            const highlightGeom = this._buildHighlightGeometry(info);\n            this._hoverEdges.geometry.dispose();\n            this._hoverEdges.geometry = highlightGeom;\n\n            this._hoverInfo = info;\n        }\n\n        this._hoverGroup.visible = true;\n        this._hoverEdges.visible = true;\n\n        // Find the building entry to get anchor position\n        const entry = this._instances.find(e => e.info === info);\n        const anchorTop = entry?.group?.position?.clone() || point.clone();\n\n        // Update HTML overlay\n        this._updateHoverOverlay(info, anchorTop, camera, opts.pointer || {});\n\n        // Show toast\n        this._showAddressToast(info);\n    }\n\n    /**\n     * Ensure hover artifacts are created\n     */\n    _ensureHoverArtifacts() {\n        if (this._hoverEdges) return;\n\n        this._hoverEdges = new THREE.LineSegments(\n            new THREE.BufferGeometry(),\n            this._highlightEdgeMaterial\n        );\n        this._hoverEdges.visible = false;\n        this._hoverEdges.renderOrder = 100;\n\n        this._hoverGroup.add(this._hoverEdges);\n    }\n\n    /**\n     * Build highlight geometry for a building\n     */\n    _buildHighlightGeometry(info) {\n        if (!info?.footprint?.length) {\n            return new THREE.BufferGeometry();\n        }\n\n        // Find the entry for this building to get proper transform\n        const entry = this._instances.find(e => e.info === info);\n        if (!entry?.group) return new THREE.BufferGeometry();\n\n        // Get the outline from the building group\n        const outline = entry.group.children.find(c => c.name === 'building-outline');\n        if (outline?.geometry) {\n            // Clone the outline geometry and transform it to match building position\n            const geo = outline.geometry.clone();\n            geo.applyMatrix4(entry.group.matrixWorld);\n            return geo;\n        }\n\n        return new THREE.BufferGeometry();\n    }\n\n    /* ========================================================================\n     * HTML OVERLAY SYSTEM - Address toast and hover card\n     * ======================================================================== */\n\n    _ensureHoverOverlay() {\n        if (this._hoverOverlayRoot || typeof document === 'undefined') {\n            if (this._hoverOverlayRoot && !this._hoverOverlayLine) {\n                this._hoverOverlayLine = this._hoverOverlayRoot.querySelector('line');\n                this._hoverCard = this._hoverOverlayRoot.querySelector('.building-hover-card');\n                this._hoverCardName = this._hoverOverlayRoot.querySelector('.building-hover-card-name');\n                this._hoverCardAddress = this._hoverOverlayRoot.querySelector('.building-hover-card-address');\n                this._hoverOverlaySvg = this._hoverOverlayRoot.querySelector('svg');\n            }\n            return this._hoverOverlayRoot;\n        }\n        const root = document.getElementById('buildingHoverOverlay');\n        if (!root) return null;\n        this._hoverOverlayRoot = root;\n        this._hoverOverlaySvg = root.querySelector('svg');\n        this._hoverOverlayLine = root.querySelector('line');\n        this._hoverCard = root.querySelector('.building-hover-card');\n        this._hoverCardName = root.querySelector('.building-hover-card-name');\n        this._hoverCardAddress = root.querySelector('.building-hover-card-address');\n        return root;\n    }\n\n    _hideHoverOverlay() {\n        const root = this._hoverOverlayRoot || this._ensureHoverOverlay();\n        if (!root) return;\n        root.hidden = true;\n    }\n\n    _updateHoverOverlay(info, anchorWorld, camera, pointer = {}) {\n        const root = this._hoverOverlayRoot || this._ensureHoverOverlay();\n        if (!root) return;\n\n        const { valid, screenX, screenY, canvasRect } = pointer || {};\n        if (!valid || !canvasRect || !Number.isFinite(screenX) || !Number.isFinite(screenY)) {\n            root.hidden = true;\n            return;\n        }\n\n        const width = window.innerWidth || canvasRect.right;\n        const height = window.innerHeight || canvasRect.bottom;\n        if (this._hoverOverlaySvg) {\n            this._hoverOverlaySvg.setAttribute('width', String(width));\n            this._hoverOverlaySvg.setAttribute('height', String(height));\n        }\n\n        const projected = this._tmpVec3.copy(anchorWorld).project(camera);\n        if (projected.z > 1 || projected.z < -1) {\n            root.hidden = true;\n            return;\n        }\n        const ax = canvasRect.left + (projected.x * 0.5 + 0.5) * canvasRect.width;\n        const ay = canvasRect.top + (-projected.y * 0.5 + 0.5) * canvasRect.height;\n\n        const pointerRadius = Number.isFinite(pointer.radius) ? pointer.radius : 10;\n        const pointerGap = pointerRadius + 8;\n        if (root && typeof pointerGap === 'number') {\n            root.style.setProperty('--hover-card-gap', `${pointerGap}px`);\n        }\n\n        if (this._hoverOverlayLine) {\n            this._hoverOverlayLine.setAttribute('x1', String(ax));\n            this._hoverOverlayLine.setAttribute('y1', String(ay));\n            this._hoverOverlayLine.setAttribute('x2', String(screenX));\n            this._hoverOverlayLine.setAttribute('y2', String(screenY));\n        }\n\n        if (this._hoverCard) {\n            const clampMargin = 18;\n            const clampedX = Math.min(width - clampMargin, Math.max(clampMargin, screenX));\n            const clampedY = Math.min(height - clampMargin, Math.max(clampMargin, screenY));\n            this._hoverCard.style.left = `${clampedX}px`;\n            this._hoverCard.style.top = `${clampedY}px`;\n\n            const name = formatBuildingName(info?.tags);\n            if (this._hoverCardName) {\n                if (name) {\n                    this._hoverCardName.textContent = name;\n                    this._hoverCardName.hidden = false;\n                } else {\n                    this._hoverCardName.hidden = true;\n                }\n            }\n            if (this._hoverCardAddress) {\n                this._hoverCardAddress.textContent = info?.address || 'Unknown address';\n            }\n        }\n\n        root.hidden = false;\n    }\n\n    _ensureAddressToast() {\n        if (this._addressToast || typeof document === 'undefined') return this._addressToast;\n        const el = document.getElementById('buildingHoverToast');\n        if (!el) return null;\n        this._addressToast = el;\n        this._addressToastNameEl = el.querySelector('[data-role=\"toast-name\"]') || null;\n        this._addressToastAddrEl = el.querySelector('[data-role=\"toast-address\"]') || null;\n        return this._addressToast;\n    }\n\n    _showAddressToast(info) {\n        const toast = this._ensureAddressToast();\n        if (!toast) return;\n\n        if (this._addressToastHideTimer) {\n            clearTimeout(this._addressToastHideTimer);\n            this._addressToastHideTimer = null;\n        }\n\n        const name = formatBuildingName(info?.tags);\n        if (this._addressToastNameEl) {\n            if (name) {\n                this._addressToastNameEl.textContent = name;\n                this._addressToastNameEl.hidden = false;\n            } else {\n                this._addressToastNameEl.textContent = '';\n                this._addressToastNameEl.hidden = true;\n            }\n        }\n        if (this._addressToastAddrEl) {\n            this._addressToastAddrEl.textContent = info?.address || 'Unknown address';\n        }\n        toast.removeAttribute('hidden');\n        void toast.offsetWidth;\n        toast.classList.add('show');\n    }\n\n    _hideAddressToast(immediate = false) {\n        const toast = this._ensureAddressToast();\n        if (!toast) return;\n\n        if (this._addressToastHideTimer) {\n            clearTimeout(this._addressToastHideTimer);\n            this._addressToastHideTimer = null;\n        }\n\n        const finalize = () => {\n            toast.setAttribute('hidden', '');\n        };\n\n        toast.classList.remove('show');\n        if (immediate) {\n            finalize();\n            return;\n        }\n\n        this._addressToastHideTimer = setTimeout(() => {\n            finalize();\n            this._addressToastHideTimer = null;\n        }, 180);\n    }\n\n    /**\n     * Get the currently hovered building info, if any\n     */\n    getHoveredBuilding() {\n        return this._hoverInfo;\n    }\n\n    getEntriesSnapshot() {\n        if (!this._instances || !this._instances.length) return [];\n        const entries = [];\n        for (const entry of this._instances) {\n            const center = entry.center || entry.info?.center;\n            const lat = center?.lat;\n            const lon = center?.lon;\n            if (!Number.isFinite(lat) || !Number.isFinite(lon)) continue;\n            const tags = entry.info?.tags || null;\n            const name = tags?.name || tags?.building || 'Building';\n            const address = entry.info?.address || null;\n            const surfaceRadius = Number.isFinite(entry.surfaceRadius)\n                ? entry.surfaceRadius\n                : (Number.isFinite(entry.maxRadius) ? entry.maxRadius : null);\n            entries.push({\n                id: entry.info?.id || null,\n                name,\n                address,\n                lat,\n                lon,\n                height: entry.info?.height ?? null,\n                levels: entry.info?.levels ?? null,\n                surfaceRadius,\n                tags\n            });\n        }\n        return entries;\n    }\n\n    /**\n     * Get building at a specific lat/lon position (point-in-polygon test)\n     * @param {number} lat - Latitude in degrees\n     * @param {number} lon - Longitude in degrees\n     * @returns {Object|null} Building info if position is inside a building footprint\n     */\n    getBuildingAtLatLon(lat, lon) {\n        if (!this._instances || !this._instances.length) return null;\n\n        for (const entry of this._instances) {\n            if (!entry.info || !entry.footprint || entry.footprint.length < 3) continue;\n\n            // Point-in-polygon test using ray casting algorithm\n            const polygon = entry.footprint;\n            let inside = false;\n            for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {\n                const xi = polygon[i][1]; // lon\n                const yi = polygon[i][0]; // lat\n                const xj = polygon[j][1];\n                const yj = polygon[j][0];\n\n                const intersect = ((yi > lat) !== (yj > lat)) &&\n                    (lon < (xj - xi) * (lat - yi) / (yj - yi) + xi);\n                if (intersect) inside = !inside;\n            }\n\n            if (inside) return entry.info;\n        }\n\n        return null;\n    }\n}\n","import * as THREE from 'three';\n\nconst DEFAULT_RADIUS_M = 1000;\nconst DEFAULT_FALLOFF_M = 700;\nconst DEFAULT_MAX_FEATURES = 180;\nconst DEFAULT_RING_COLOR = '#60a5fa';\nconst DEFAULT_FALLOFF_COLOR = '#38bdf8';\nconst DEFAULT_OPACITY = 0.6;\n\nconst resolveNumber = (value, fallback) => (Number.isFinite(value) ? value : fallback);\n\nconst getLatLon = (item) => {\n    const coords = item?.current?.geom?.coordinates;\n    if (!Array.isArray(coords) || coords.length < 2) return null;\n    const lon = coords[0];\n    const lat = coords[1];\n    if (!Number.isFinite(lat) || !Number.isFinite(lon)) return null;\n    return { lat, lon };\n};\n\nexport const createBuildingOverlayItem = (item, buildingOverlay) => {\n    const group = new THREE.Group();\n    group.name = `OverlayBuildingOverlay:${item?.item_id || 'building'}`;\n    group.userData.itemId = item?.item_id || null;\n    group.userData.buildingOverlayItem = true;\n\n    const ringMaterial = new THREE.MeshBasicMaterial({\n        color: DEFAULT_RING_COLOR,\n        transparent: true,\n        opacity: DEFAULT_OPACITY,\n        side: THREE.DoubleSide,\n        depthWrite: false\n    });\n    const falloffMaterial = new THREE.MeshBasicMaterial({\n        color: DEFAULT_FALLOFF_COLOR,\n        transparent: true,\n        opacity: DEFAULT_OPACITY * 0.8,\n        side: THREE.DoubleSide,\n        depthWrite: false\n    });\n\n    const ringGeometry = new THREE.RingGeometry(0.94, 1, 64);\n    const falloffGeometry = new THREE.RingGeometry(0.94, 1, 48);\n    const ringMesh = new THREE.Mesh(ringGeometry, ringMaterial);\n    const falloffMesh = new THREE.Mesh(falloffGeometry, falloffMaterial);\n    ringMesh.name = 'BuildingOverlayRing';\n    falloffMesh.name = 'BuildingOverlayFalloff';\n\n    const markerMaterial = new THREE.MeshBasicMaterial({ color: 0xffffff });\n    const marker = new THREE.Mesh(new THREE.SphereGeometry(50, 12, 12), markerMaterial);\n    marker.name = 'BuildingOverlayCenter';\n\n    group.add(falloffMesh);\n    group.add(ringMesh);\n    group.add(marker);\n\n    const applyVisuals = (nextItem) => {\n        const props = nextItem?.current?.properties || {};\n        const radiusM = resolveNumber(props.radius_m, DEFAULT_RADIUS_M);\n        const falloffM = resolveNumber(props.falloff_start_m, DEFAULT_FALLOFF_M);\n        const opacity = resolveNumber(props.opacity, DEFAULT_OPACITY);\n        const ringColor = props.ring_color || props.color || DEFAULT_RING_COLOR;\n        const falloffColor = props.falloff_color || DEFAULT_FALLOFF_COLOR;\n        const showMarker = props.show_marker !== false;\n\n        ringMesh.scale.set(radiusM, radiusM, 1);\n        falloffMesh.scale.set(falloffM, falloffM, 1);\n        ringMaterial.color.set(ringColor);\n        falloffMaterial.color.set(falloffColor);\n        ringMaterial.opacity = opacity;\n        falloffMaterial.opacity = opacity * 0.8;\n        ringMaterial.needsUpdate = true;\n        falloffMaterial.needsUpdate = true;\n        ringMesh.visible = showMarker;\n        falloffMesh.visible = showMarker;\n        marker.visible = showMarker;\n    };\n\n    const applyConfig = (nextItem) => {\n        if (!buildingOverlay || !nextItem) return;\n        const props = nextItem.current?.properties || {};\n        const center = getLatLon(nextItem);\n        if (!center) return;\n        const resolveBool = (value, fallback) => (typeof value === 'boolean' ? value : fallback);\n\n        const config = {\n            lat: center.lat,\n            lon: center.lon,\n            radiusM: resolveNumber(props.radius_m, DEFAULT_RADIUS_M),\n            falloffStartM: resolveNumber(props.falloff_start_m, DEFAULT_FALLOFF_M),\n            maxFeatures: resolveNumber(props.max_features, DEFAULT_MAX_FEATURES),\n            overpassUrl: props.overpass_url || buildingOverlay.overpassUrl || null,\n            surfaceOffsetM: resolveNumber(props.surface_offset_m, buildingOverlay.surfaceOffsetM || 0),\n            resnapIntervalMs: resolveNumber(props.resnap_interval_ms, buildingOverlay.resnapIntervalMs || 0),\n            resnapBudget: resolveNumber(props.resnap_budget, buildingOverlay.resnapBudget || 0),\n            resnapToleranceM: resolveNumber(props.resnap_tolerance_m, buildingOverlay.resnapToleranceM || 0),\n            resnapFreezeFrames: resolveNumber(props.resnap_freeze_frames, buildingOverlay.resnapFreezeFrames || 0),\n            maxSamplesPerBuilding: resolveNumber(props.max_samples_per_building, buildingOverlay.maxSamplesPerBuilding || 0),\n            tileDrivenResnap: resolveBool(props.tile_driven_resnap, buildingOverlay.tileDrivenResnap),\n            fallbackResnapIntervalMs: resolveNumber(\n                props.fallback_resnap_interval_ms,\n                buildingOverlay.fallbackResnapIntervalMs || 0\n            ),\n            lodDetailRadiusM: resolveNumber(props.lod_detail_radius_m, buildingOverlay.lodDetailRadiusM || 0),\n            lodImpostorRadiusM: resolveNumber(props.lod_impostor_radius_m, buildingOverlay.lodImpostorRadiusM || 0),\n            lodUpdateIntervalMs: resolveNumber(props.lod_update_interval_ms, buildingOverlay.lodUpdateIntervalMs || 0),\n            lodBudget: resolveNumber(props.lod_budget, buildingOverlay.lodBudget || 0),\n            lodHysteresisM: resolveNumber(props.lod_hysteresis_m, buildingOverlay.lodHysteresisM || 0),\n            impostorEnabled: resolveBool(props.impostor_enabled, buildingOverlay.impostorEnabled),\n            impostorMinSizeM: resolveNumber(props.impostor_min_size_m, buildingOverlay.impostorMinSizeM || 0),\n            impostorMinHeightM: resolveNumber(props.impostor_min_height_m, buildingOverlay.impostorMinHeightM || 0),\n            impostorHeightScale: resolveNumber(props.impostor_height_scale, buildingOverlay.impostorHeightScale || 0),\n            imageryEnabled: resolveBool(props.imagery_enabled, buildingOverlay.imageryEnabled),\n            imageryUpdateIntervalMs: resolveNumber(\n                props.imagery_update_interval_ms,\n                buildingOverlay.imageryUpdateIntervalMs || 0\n            )\n        };\n\n        const key = JSON.stringify(config);\n        if (group.userData.configKey === key) return;\n        group.userData.configKey = key;\n\n        if (config.overpassUrl) buildingOverlay.overpassUrl = config.overpassUrl;\n        if (Number.isFinite(config.maxFeatures)) buildingOverlay.maxFeatures = config.maxFeatures;\n        if (Number.isFinite(config.surfaceOffsetM)) buildingOverlay.surfaceOffsetM = config.surfaceOffsetM;\n        if (Number.isFinite(config.resnapIntervalMs)) buildingOverlay.resnapIntervalMs = config.resnapIntervalMs;\n        if (Number.isFinite(config.resnapBudget)) buildingOverlay.resnapBudget = config.resnapBudget;\n        if (Number.isFinite(config.resnapToleranceM)) buildingOverlay.resnapToleranceM = config.resnapToleranceM;\n        if (Number.isFinite(config.resnapFreezeFrames)) buildingOverlay.resnapFreezeFrames = config.resnapFreezeFrames;\n        if (Number.isFinite(config.maxSamplesPerBuilding)) {\n            buildingOverlay.maxSamplesPerBuilding = config.maxSamplesPerBuilding;\n        }\n        if (typeof config.tileDrivenResnap === 'boolean') {\n            buildingOverlay.tileDrivenResnap = config.tileDrivenResnap;\n        }\n        if (Number.isFinite(config.fallbackResnapIntervalMs)) {\n            buildingOverlay.fallbackResnapIntervalMs = config.fallbackResnapIntervalMs;\n        }\n        if (Number.isFinite(config.lodDetailRadiusM)) buildingOverlay.lodDetailRadiusM = config.lodDetailRadiusM;\n        if (Number.isFinite(config.lodImpostorRadiusM)) buildingOverlay.lodImpostorRadiusM = config.lodImpostorRadiusM;\n        if (Number.isFinite(config.lodUpdateIntervalMs)) buildingOverlay.lodUpdateIntervalMs = config.lodUpdateIntervalMs;\n        if (Number.isFinite(config.lodBudget)) buildingOverlay.lodBudget = config.lodBudget;\n        if (Number.isFinite(config.lodHysteresisM)) buildingOverlay.lodHysteresisM = config.lodHysteresisM;\n        if (typeof config.impostorEnabled === 'boolean') buildingOverlay.impostorEnabled = config.impostorEnabled;\n        if (Number.isFinite(config.impostorMinSizeM)) buildingOverlay.impostorMinSizeM = config.impostorMinSizeM;\n        if (Number.isFinite(config.impostorMinHeightM)) buildingOverlay.impostorMinHeightM = config.impostorMinHeightM;\n        if (Number.isFinite(config.impostorHeightScale)) buildingOverlay.impostorHeightScale = config.impostorHeightScale;\n        if (typeof config.imageryEnabled === 'boolean') buildingOverlay.imageryEnabled = config.imageryEnabled;\n        if (Number.isFinite(config.imageryUpdateIntervalMs)) {\n            buildingOverlay.imageryUpdateIntervalMs = config.imageryUpdateIntervalMs;\n        }\n\n        buildingOverlay.__activeItemId = nextItem.item_id;\n        buildingOverlay.load({\n            center: { lat: config.lat, lon: config.lon },\n            radiusM: config.radiusM,\n            falloffStartM: config.falloffStartM\n        });\n    };\n\n    group.userData.updateItem = (nextItem) => {\n        applyVisuals(nextItem);\n        applyConfig(nextItem);\n    };\n\n    group.userData.onRemove = (removedItem) => {\n        if (!buildingOverlay) return;\n        if (buildingOverlay.__activeItemId && removedItem?.item_id === buildingOverlay.__activeItemId) {\n            buildingOverlay.clear();\n            buildingOverlay.__activeItemId = null;\n        }\n    };\n\n    applyVisuals(item);\n    applyConfig(item);\n\n    return group;\n};\n","/**\n * TheaterSourceManager\n *\n * Abstracts different video source types into a unified interface\n * that provides a video element (or canvas texture) and an audio element.\n *\n * Supported source types:\n *   - stream_id:  Legacy comms path (PCM + canvas texture via CommsSystem)\n *   - hls:        HLS/LL-HLS via native <video> or hls.js\n *   - embed_url:  Direct media URL (mp4/webm/m3u8) or provider embed URL\n *                 Provider embeds (YouTube/Twitch/Vimeo) are not renderable as WebGL textures\n *                 without a dedicated DOM iframe overlay pipeline.\n *   - rtmp:       Uses the playback_hls_url or playback_whep_url from the channel\n */\n\nconst SOURCE_TYPE = {\n  STREAM_ID: 'stream_id',\n  HLS: 'hls',\n  EMBED_URL: 'embed_url',\n  RTMP: 'rtmp',\n};\n\nconst DIRECT_VIDEO_EXTENSIONS = ['.mp4', '.webm', '.ogg', '.ogv', '.m4v', '.mov'];\n\nfunction parseUrlLike(value) {\n  if (!value || typeof value !== 'string') return null;\n  try {\n    const base = (typeof window !== 'undefined' && window.location?.href)\n      ? window.location.href\n      : 'http://localhost/';\n    return new URL(value, base);\n  } catch {\n    return null;\n  }\n}\n\nfunction looksLikeHlsUrl(url) {\n  const parsed = parseUrlLike(url);\n  if (!parsed) return false;\n  const path = parsed.pathname.toLowerCase();\n  if (path.endsWith('.m3u8')) return true;\n  const fmt = parsed.searchParams.get('format');\n  if (fmt && String(fmt).toLowerCase() === 'm3u8') return true;\n  return false;\n}\n\nfunction looksLikeDirectVideoUrl(url) {\n  if (looksLikeHlsUrl(url)) return true;\n  const parsed = parseUrlLike(url);\n  if (!parsed) return false;\n  if (parsed.protocol === 'blob:') return true; // a local file the viewer dropped in\n  const path = parsed.pathname.toLowerCase();\n  if (DIRECT_VIDEO_EXTENSIONS.some((ext) => path.endsWith(ext))) return true;\n  const type = parsed.searchParams.get('type');\n  if (type && /video|mp4|webm|ogg/i.test(type)) return true;\n  return false;\n}\n\nfunction looksLikeProviderEmbedUrl(url) {\n  const parsed = parseUrlLike(url);\n  if (!parsed) return false;\n  const host = parsed.hostname.toLowerCase();\n  return host.includes('youtube.com')\n    || host.includes('youtu.be')\n    || host.includes('twitch.tv')\n    || host.includes('vimeo.com');\n}\n\nfunction extractIframeSrc(input) {\n  const raw = String(input || '').trim();\n  if (!raw) return '';\n  const iframeMatch = raw.match(/<iframe[^>]*\\s+src=([\"'])(.*?)\\1/i);\n  if (iframeMatch?.[2]) return String(iframeMatch[2]).trim();\n  if (/^https?:\\/\\//i.test(raw)) return raw;\n  if (/^\\/\\//.test(raw)) return `https:${raw}`;\n  return '';\n}\n\nfunction resolveEmbedCandidateUrl(props) {\n  const embedUrl = String(props?.embed_url || '').trim();\n  if (embedUrl) return embedUrl;\n  const iframeSrc = extractIframeSrc(props?.iframe_embed);\n  if (iframeSrc) return iframeSrc;\n  return null;\n}\n\n/**\n * Resolve which source type to use from item properties.\n */\nfunction resolveSourceType(props) {\n  if (props.source_type) return props.source_type;\n  if (props.embed_url || extractIframeSrc(props.iframe_embed)) return SOURCE_TYPE.EMBED_URL;\n  if (props.hls_url || props.playback_hls_url) return SOURCE_TYPE.HLS;\n  if (props.video_stream || props.stream_id) return SOURCE_TYPE.STREAM_ID;\n  if (props.channel_id) return SOURCE_TYPE.RTMP;\n  return null;\n}\n\n/**\n * Create a TheaterSourceManager for a given item.\n *\n * Returns an object with:\n *   - getTexture()        → THREE.VideoTexture | THREE.Texture | null\n *   - getAudioElement()   → HTMLMediaElement | null (for HLS/RTMP, not stream_id)\n *   - getSourceType()     → string\n *   - getEmbedUrl()       → string | null (for iframe embed)\n *   - update(nextProps)   → void\n *   - dispose()           → void\n */\nexport function createTheaterSourceManager(THREE, commsSystem, { onMediaElement = null } = {}) {\n  let _sourceType = null;\n  let _videoEl = null;\n  let _videoTexture = null;\n  let _hlsInstance = null;\n  let _embedUrl = null;\n  let _streamIdTexture = null;\n  let _currentProps = {};\n\n  function _createVideoElement() {\n    const el = document.createElement('video');\n    el.crossOrigin = 'anonymous';\n    el.playsInline = true;\n    el.muted = true; // Start muted, spatial audio will handle volume\n    // With a playback controller, it decides when media plays.\n    el.autoplay = !onMediaElement;\n    el.style.display = 'none';\n    document.body.appendChild(el);\n    return el;\n  }\n\n  function _createVideoTexture(videoEl) {\n    const tex = new THREE.VideoTexture(videoEl);\n    tex.minFilter = THREE.LinearFilter;\n    tex.magFilter = THREE.LinearFilter;\n    tex.colorSpace = THREE.SRGBColorSpace;\n    return tex;\n  }\n\n  async function _setupHls(url, props) {\n    _disposeMedia();\n\n    _videoEl = _createVideoElement();\n    _videoEl.loop = !!props.loop;\n\n    // Try native HLS support first (Safari)\n    if (_videoEl.canPlayType('application/vnd.apple.mpegurl')) {\n      _videoEl.src = url;\n      _videoTexture = _createVideoTexture(_videoEl);\n      _startPlayback();\n      return;\n    }\n\n    // Fall back to hls.js\n    try {\n      const Hls = (await import('hls.js')).default;\n      if (Hls.isSupported()) {\n        _hlsInstance = new Hls({\n          enableWorker: true,\n          lowLatencyMode: true,\n          backBufferLength: 30,\n        });\n        _hlsInstance.loadSource(url);\n        _hlsInstance.attachMedia(_videoEl);\n        _hlsInstance.on(Hls.Events.MANIFEST_PARSED, () => {\n          _startPlayback();\n        });\n        _videoTexture = _createVideoTexture(_videoEl);\n      } else {\n        console.warn('[TheaterSource] HLS not supported in this browser');\n      }\n    } catch (err) {\n      console.warn('[TheaterSource] Failed to load hls.js:', err);\n      // Last resort: try direct\n      _videoEl.src = url;\n      _videoTexture = _createVideoTexture(_videoEl);\n      _startPlayback();\n    }\n  }\n\n  function _setupDirectVideo(url, props) {\n    _disposeMedia();\n    _videoEl = _createVideoElement();\n    _videoEl.loop = !!props.loop;\n    _videoEl.src = url;\n    _videoTexture = _createVideoTexture(_videoEl);\n    _startPlayback();\n  }\n\n  function _startPlayback() {\n    if (!_videoEl) return;\n    if (onMediaElement) onMediaElement(_videoEl);\n    else _videoEl.play().catch(() => {});\n  }\n\n  function _setupStreamId(props) {\n    _disposeMedia();\n    const videoStreamId = props.video_stream || props.stream_id || null;\n    if (videoStreamId && commsSystem?.getVideoTexture) {\n      _streamIdTexture = commsSystem.getVideoTexture(videoStreamId);\n    }\n  }\n\n  function _setupEmbed(url) {\n    _disposeMedia();\n    _embedUrl = url;\n  }\n\n  function _disposeMedia() {\n    if (_hlsInstance) {\n      _hlsInstance.destroy();\n      _hlsInstance = null;\n    }\n    if (_videoEl) {\n      onMediaElement?.(null);\n      _videoEl.pause();\n      _videoEl.removeAttribute('src');\n      _videoEl.load();\n      if (_videoEl.parentNode) {\n        _videoEl.parentNode.removeChild(_videoEl);\n      }\n      _videoEl = null;\n    }\n    if (_videoTexture) {\n      _videoTexture.dispose();\n      _videoTexture = null;\n    }\n    _streamIdTexture = null;\n    _embedUrl = null;\n  }\n\n  function update(props) {\n    const nextType = resolveSourceType(props);\n    const typeChanged = nextType !== _sourceType;\n\n    // Determine the URL/stream for the resolved type\n    let nextUrl = null;\n    if (nextType === SOURCE_TYPE.HLS) {\n      nextUrl = props.hls_url || props.playback_hls_url;\n    } else if (nextType === SOURCE_TYPE.RTMP) {\n      nextUrl = props.playback_hls_url; // RTMP channels provide HLS playback\n    } else if (nextType === SOURCE_TYPE.EMBED_URL) {\n      nextUrl = resolveEmbedCandidateUrl(props);\n    } else if (nextType === SOURCE_TYPE.STREAM_ID) {\n      nextUrl = props.video_stream || props.stream_id;\n    }\n\n    const prevUrl = _getActiveUrl();\n    const urlChanged = nextUrl !== prevUrl;\n\n    if (!typeChanged && !urlChanged) {\n      // Update playback properties without re-creating\n      if (_videoEl) {\n        _videoEl.loop = !!props.loop;\n        if (!onMediaElement && props.autoplay === false) {\n          _videoEl.pause();\n        }\n      }\n      _currentProps = props;\n      return;\n    }\n\n    _sourceType = nextType;\n    _currentProps = props;\n\n    if (!nextType || !nextUrl) {\n      _disposeMedia();\n      return;\n    }\n\n    switch (nextType) {\n      case SOURCE_TYPE.HLS:\n      case SOURCE_TYPE.RTMP:\n        _setupHls(nextUrl, props);\n        break;\n      case SOURCE_TYPE.STREAM_ID:\n        _setupStreamId(props);\n        break;\n      case SOURCE_TYPE.EMBED_URL: {\n        if (looksLikeHlsUrl(nextUrl)) {\n          _setupHls(nextUrl, props);\n          break;\n        }\n        if (looksLikeDirectVideoUrl(nextUrl)) {\n          _setupDirectVideo(nextUrl, props);\n          break;\n        }\n        _setupEmbed(nextUrl);\n        if (looksLikeProviderEmbedUrl(nextUrl)) {\n          console.warn('[TheaterSource] Provider page URLs cannot be sampled into a Three.js texture in-browser. Use RTMP/HLS/direct media URL for in-scene playback.');\n        } else {\n          console.warn('[TheaterSource] URL is not a direct media stream/file. In-scene theater playback expects mp4/webm/m3u8 or RTMP playback HLS.');\n        }\n        break;\n      }\n    }\n  }\n\n  function _getActiveUrl() {\n    if (_sourceType === SOURCE_TYPE.HLS || _sourceType === SOURCE_TYPE.RTMP) {\n      return _videoEl?.src || _currentProps.hls_url || _currentProps.playback_hls_url || null;\n    }\n    if (_sourceType === SOURCE_TYPE.EMBED_URL) {\n      return _videoEl?.src || _embedUrl;\n    }\n    if (_sourceType === SOURCE_TYPE.STREAM_ID) {\n      return _currentProps.video_stream || _currentProps.stream_id || null;\n    }\n    return null;\n  }\n\n  return {\n    getTexture() {\n      if (_sourceType === SOURCE_TYPE.STREAM_ID) return _streamIdTexture || null;\n      return _videoTexture || null;\n    },\n\n    getAudioElement() {\n      // Any active video element can carry audio (HLS/RTMP/direct embed media URL)\n      if (_videoEl) {\n        return _videoEl;\n      }\n      return null;\n    },\n\n    getSourceType() {\n      return _sourceType;\n    },\n\n    getEmbedUrl() {\n      return _sourceType === SOURCE_TYPE.EMBED_URL ? _embedUrl : null;\n    },\n\n    isMediaElement() {\n      return !!_videoEl;\n    },\n\n    update,\n\n    dispose() {\n      _disposeMedia();\n      _sourceType = null;\n      _currentProps = {};\n    },\n  };\n}\n\nexport { SOURCE_TYPE };\n","/**\n * MediaPlaybackController — decides when an in-scene media element plays and\n * whose timeline it follows.\n *\n * Authored item properties:\n *   playback_trigger  'always' | 'proximity' | 'interaction'\n *                     (legacy `autoplay: false` maps to 'interaction')\n *   playback_range_m  proximity radius in metres (default 150)\n *   playback_exit     'pause' | 'stop' | 'continue' — what leaving range does\n *   playback_sync     'personal' — each viewer has their own playback\n *                     'shared'   — every viewer sees the same moment\n *   playback_epoch_ms shared timeline anchor (wall clock ms at position 0)\n *\n * Shared + always/proximity follows a deterministic wall-clock timeline, so no\n * messages are needed and late arrivals land on the same frame. Shared +\n * interaction relays play/pause with the playback position through the\n * overlay channel (see `setBroadcaster` / `receive`). Live streams have no\n * seekable timeline and are inherently shared; only play/pause applies.\n */\nexport const PLAYBACK_TRIGGERS = Object.freeze(['always', 'proximity', 'interaction']);\nexport const PLAYBACK_EXITS = Object.freeze(['pause', 'stop', 'continue']);\nexport const PLAYBACK_SYNC_MODES = Object.freeze(['personal', 'shared']);\nexport const DEFAULT_PLAYBACK_RANGE_M = 150;\nconst DRIFT_TOLERANCE_S = 1.5;\n\nexport function resolvePlaybackConfig(props = {}) {\n  const trigger = PLAYBACK_TRIGGERS.includes(props.playback_trigger)\n    ? props.playback_trigger\n    : (props.autoplay === false ? 'interaction' : 'always');\n  const range = Number(props.playback_range_m);\n  const epoch = Number(props.playback_epoch_ms);\n  return {\n    trigger,\n    rangeM: Number.isFinite(range) && range > 0 ? range : DEFAULT_PLAYBACK_RANGE_M,\n    exit: PLAYBACK_EXITS.includes(props.playback_exit) ? props.playback_exit : 'pause',\n    sync: PLAYBACK_SYNC_MODES.includes(props.playback_sync) ? props.playback_sync : 'personal',\n    epochMs: Number.isFinite(epoch) ? epoch : 0,\n    loop: props.loop === true,\n  };\n}\n\n/**\n * Position on a shared timeline that started at `anchorMs`.\n * Returns { position, ended } or null when the media has no finite duration.\n */\nexport function sharedTimelinePosition(anchorMs, nowMs, duration, loop) {\n  if (!Number.isFinite(duration) || duration <= 0) return null;\n  const elapsed = Math.max(0, (nowMs - anchorMs) / 1000);\n  if (loop) return { position: elapsed % duration, ended: false };\n  if (elapsed >= duration) return { position: duration, ended: true };\n  return { position: elapsed, ended: false };\n}\n\nexport function createMediaPlaybackController({ now = () => Date.now() } = {}) {\n  let config = resolvePlaybackConfig({});\n  let media = null;\n  let broadcaster = null;\n  let inRange = false;\n  let enteredOnce = false;\n  let personalPlaying = false;\n  // Shared interaction state, relayed between viewers.\n  let remote = { playing: false, anchorMs: 0, pausedAt: 0 };\n  const listeners = new Set();\n  const loadListeners = new Set();\n  let lastNotified = null;\n  let blocked = false;\n  const notify = () => {\n    const active = isActive();\n    const key = `${active}|${blocked}`;\n    if (key === lastNotified) return;\n    lastNotified = key;\n    for (const fn of listeners) { try { fn(active); } catch { /* listener errors stay local */ } }\n  };\n\n  const isActive = () => {\n    if (config.trigger === 'always') return true;\n    if (config.trigger === 'proximity') return inRange || (config.exit === 'continue' && enteredOnce);\n    return config.sync === 'shared' ? remote.playing : personalPlaying;\n  };\n\n  const sharedAnchor = () => (config.trigger === 'interaction' ? remote.anchorMs : config.epochMs);\n\n  const seekTo = (position, tolerance = DRIFT_TOLERANCE_S) => {\n    if (!media || !Number.isFinite(position)) return;\n    if (Math.abs((media.currentTime || 0) - position) > tolerance) {\n      try { media.currentTime = position; } catch { /* not seekable yet */ }\n    }\n  };\n\n  // Browsers refuse unmuted playback before the viewer interacts; remember\n  // that so the surface can ask for a click, which retries with a gesture.\n  const play = () => {\n    const target = media;\n    const attempt = target?.play?.();\n    attempt?.then?.(() => {\n      if (target === media && blocked) { blocked = false; notify(); }\n    }, (error) => {\n      if (target === media && error?.name === 'NotAllowedError' && !blocked) { blocked = true; notify(); }\n    });\n  };\n  const pause = () => { if (media && !media.paused) media.pause(); };\n\n  const apply = () => {\n    notify();\n    if (!media) return;\n    media.loop = config.loop && config.sync !== 'shared';\n    if (!isActive()) {\n      // A shared pause lands everyone on the same frame.\n      if (config.sync === 'shared' && config.trigger === 'interaction') seekTo(remote.pausedAt, 0.05);\n      pause();\n      return;\n    }\n    if (config.sync === 'shared') {\n      const shared = sharedTimelinePosition(sharedAnchor(), now(), media.duration, config.loop);\n      if (shared) {\n        seekTo(shared.position);\n        if (shared.ended) { pause(); return; }\n      }\n    }\n    play();\n  };\n\n  const onTimeUpdate = () => {\n    if (config.sync !== 'shared' || !media || media.paused || !isActive()) return;\n    const shared = sharedTimelinePosition(sharedAnchor(), now(), media.duration, config.loop);\n    if (!shared) return;\n    if (shared.ended) pause();\n    else seekTo(shared.position);\n  };\n  const onEnded = () => { if (config.sync === 'shared' && config.loop) apply(); };\n\n  const detachMedia = () => {\n    media?.removeEventListener?.('loadedmetadata', apply);\n    media?.removeEventListener?.('timeupdate', onTimeUpdate);\n    media?.removeEventListener?.('ended', onEnded);\n  };\n\n  return {\n    get config() { return config; },\n    get active() { return isActive(); },\n    get blocked() { return blocked; },\n\n    configure(props) {\n      const prev = config;\n      config = resolvePlaybackConfig(props);\n      if (prev.trigger !== config.trigger || prev.sync !== config.sync) {\n        enteredOnce = false;\n        personalPlaying = false;\n      }\n      apply();\n    },\n\n    /** Attach the media element that playback decisions drive. */\n    setMedia(next) {\n      if (next === media) return;\n      detachMedia();\n      media = next || null;\n      blocked = false;\n      if (!media) return;\n      media.autoplay = false;\n      media.addEventListener?.('loadedmetadata', apply);\n      media.addEventListener?.('timeupdate', onTimeUpdate);\n      media.addEventListener?.('ended', onEnded);\n      apply();\n    },\n\n    /** Called with the new active state whenever it changes. */\n    subscribe(fn) {\n      listeners.add(fn);\n      return () => listeners.delete(fn);\n    },\n\n    setBroadcaster(fn) { broadcaster = typeof fn === 'function' ? fn : null; },\n\n    /** Proximity trigger edge from the scene's proximity manager. */\n    setInRange(next) {\n      const wasActive = isActive();\n      inRange = next === true;\n      if (inRange) enteredOnce = true;\n      if (!inRange && wasActive && !isActive() && config.exit === 'stop' && config.sync !== 'shared' && media) {\n        try { media.currentTime = 0; } catch { /* not seekable */ }\n      }\n      apply();\n    },\n\n    /** The viewer clicked or tapped the media surface. */\n    interact() {\n      if (config.trigger !== 'interaction') {\n        // Not a click trigger: a click only unblocks a refused autoplay.\n        if (blocked && isActive()) play();\n        return;\n      }\n      if (blocked && isActive()) { play(); return; }\n      if (config.sync === 'shared') {\n        const position = media?.currentTime || 0;\n        const message = remote.playing\n          ? { action: 'pause', positionSec: position }\n          : { action: 'play', positionSec: position };\n        this.receive(message);\n        broadcaster?.(message);\n        return;\n      }\n      personalPlaying = !personalPlaying;\n      apply();\n    },\n\n    /** Shared theaters: tell everyone to switch to `url` (routed link, Up next pick). */\n    broadcastLoad(url) {\n      if (config.sync !== 'shared' || !broadcaster || !url) return false;\n      broadcaster({ action: 'load', url: String(url), atMs: now() });\n      return true;\n    },\n\n    /** Called with the URL when another viewer switches a shared theater's media. */\n    onRemoteLoad(fn) {\n      loadListeners.add(fn);\n      return () => loadListeners.delete(fn);\n    },\n\n    /** Shared interaction state from another viewer (or this one). */\n    receive(message) {\n      if (message?.action === 'load') {\n        if (config.sync === 'shared' && message.url) for (const fn of loadListeners) fn(String(message.url));\n        return;\n      }\n      if (!message || config.sync !== 'shared' || config.trigger !== 'interaction') return;\n      const position = Math.max(0, Number(message.positionSec) || 0);\n      if (message.action === 'play') {\n        remote = { playing: true, anchorMs: now() - position * 1000, pausedAt: position };\n      } else if (message.action === 'pause') {\n        remote = { playing: false, anchorMs: remote.anchorMs, pausedAt: position };\n      } else {\n        return;\n      }\n      apply();\n    },\n\n    dispose() {\n      detachMedia();\n      media = null;\n      broadcaster = null;\n      loadListeners.clear();\n    },\n  };\n}\n","/**\n * TheaterIframePresenter — shows media that WebGL cannot sample (YouTube /\n * Twitch / Vimeo players, iframe embeds, media hosts without CORS) as a real\n * DOM iframe pinned onto the theater screen.\n *\n * Each frame the screen's four corners are projected in double precision and\n * the iframe gets the CSS homography (matrix3d) that maps its rectangle onto\n * that quad, so it tracks perspective without CSS3DRenderer's float32 jitter at\n * planetary coordinates. It hides when the screen is behind the camera, faces\n * away, is off-canvas, or is too small to use.\n */\nimport * as THREE from 'three';\nimport { hasSceneOcclusionProbe, isSceneSegmentOccluded, prepareSceneOcclusion } from '../render/SceneOcclusion.js';\n\nconst LAYER_CLASS = 'nca-theater-iframes';\nconst MIN_SCREEN_PX = 48;\n// Occlusion mask: the iframe sits above the WebGL canvas, so the depth buffer\n// cannot hide it. A grid of camera rays finds which parts of the screen are\n// behind photoreal geometry; those cells are masked out (scaled smoothly, so\n// silhouettes stay soft). ~96 rays per frame, a full refresh every 6 frames.\nconst MASK_COLS = 32;\nconst MASK_ROWS = 18;\nconst MASK_RAYS_PER_FRAME = 96;\n\n/** Build a CSS mask from per-cell visibility (1 = visible). Exported for tests. */\nexport function occlusionMaskState(cells) {\n  let visible = 0;\n  for (const c of cells) visible += c ? 1 : 0;\n  if (visible === cells.length) return 'clear';\n  if (visible === 0) return 'hidden';\n  return 'partial';\n}\n\n/** Turn provider page URLs into their embeddable player URLs. */\nexport function toEmbeddablePlayerUrl(input, { host = globalThis.location?.hostname || 'localhost', autoplay = true } = {}) {\n  let url;\n  try { url = new URL(String(input || '').trim(), globalThis.location?.href || 'https://localhost/'); } catch { return ''; }\n  const h = url.hostname.replace(/^www\\.|^m\\./, '');\n  const flag = autoplay ? '1' : '0';\n  if (h === 'youtu.be' || h.endsWith('youtube.com') || h.endsWith('youtube-nocookie.com')) {\n    const id = h === 'youtu.be'\n      ? url.pathname.slice(1).split('/')[0]\n      : url.searchParams.get('v') || (url.pathname.match(/\\/(?:embed|shorts|live)\\/([^/?#]+)/) || [])[1];\n    if (!id) return url.href;\n    const out = new URL(`https://www.youtube.com/embed/${id}`);\n    out.searchParams.set('autoplay', flag);\n    out.searchParams.set('playsinline', '1');\n    const start = url.searchParams.get('t') || url.searchParams.get('start');\n    if (start) out.searchParams.set('start', String(parseInt(start, 10) || 0));\n    return out.href;\n  }\n  if (h === 'twitch.tv' || h === 'player.twitch.tv') {\n    if (h === 'player.twitch.tv') { url.searchParams.set('parent', host); return url.href; }\n    const [first, second] = url.pathname.split('/').filter(Boolean);\n    const out = new URL('https://player.twitch.tv/');\n    if (first === 'videos' && second) out.searchParams.set('video', second);\n    else if (first) out.searchParams.set('channel', first);\n    out.searchParams.set('parent', host);\n    out.searchParams.set('autoplay', autoplay ? 'true' : 'false');\n    return out.href;\n  }\n  if (h === 'vimeo.com') {\n    const id = url.pathname.split('/').filter(Boolean).find((part) => /^\\d+$/.test(part));\n    if (!id) return url.href;\n    return `https://player.vimeo.com/video/${id}?autoplay=${flag}`;\n  }\n  return url.href;\n}\n\n// --- 2D homography (rectangle → projected quad) ---------------------------\nconst adj = (m) => [\n  m[4] * m[8] - m[5] * m[7], m[2] * m[7] - m[1] * m[8], m[1] * m[5] - m[2] * m[4],\n  m[5] * m[6] - m[3] * m[8], m[0] * m[8] - m[2] * m[6], m[2] * m[3] - m[0] * m[5],\n  m[3] * m[7] - m[4] * m[6], m[1] * m[6] - m[0] * m[7], m[0] * m[4] - m[1] * m[3],\n];\nconst mulMM = (a, b) => {\n  const c = new Array(9);\n  for (let i = 0; i < 3; i++) for (let j = 0; j < 3; j++) {\n    let sum = 0;\n    for (let k = 0; k < 3; k++) sum += a[3 * i + k] * b[3 * k + j];\n    c[3 * i + j] = sum;\n  }\n  return c;\n};\nconst mulMV = (m, v) => [\n  m[0] * v[0] + m[1] * v[1] + m[2] * v[2],\n  m[3] * v[0] + m[4] * v[1] + m[5] * v[2],\n  m[6] * v[0] + m[7] * v[1] + m[8] * v[2],\n];\nconst basis = (p) => {\n  const m = [p[0][0], p[1][0], p[2][0], p[0][1], p[1][1], p[2][1], 1, 1, 1];\n  const v = mulMV(adj(m), [p[3][0], p[3][1], 1]);\n  return mulMM(m, [v[0], 0, 0, 0, v[1], 0, 0, 0, v[2]]);\n};\n\n/** CSS matrix3d mapping a w×h box (origin top-left) onto quad tl,tr,bl,br. */\nexport function quadToCssMatrix(w, h, [tl, tr, bl, br]) {\n  const s = basis([[0, 0], [w, 0], [0, h], [w, h]]);\n  const d = basis([tl, tr, bl, br]);\n  const t = mulMM(d, adj(s));\n  if (!Number.isFinite(t[8]) || Math.abs(t[8]) < 1e-12) return null;\n  const n = t.map((value) => value / t[8]);\n  return `matrix3d(${n[0]},${n[3]},0,${n[6]},${n[1]},${n[4]},0,${n[7]},0,0,1,0,${n[2]},${n[5]},0,${n[8]})`;\n}\n\nfunction ensureLayer(canvas) {\n  const parent = canvas?.parentElement || document.body;\n  let layer = parent.querySelector(`:scope > .${LAYER_CLASS}`);\n  if (!layer) {\n    layer = document.createElement('div');\n    layer.className = LAYER_CLASS;\n    Object.assign(layer.style, { position: 'absolute', inset: '0', overflow: 'hidden', pointerEvents: 'none', zIndex: '1' });\n    if (getComputedStyle(parent).position === 'static') parent.style.position = 'relative';\n    canvas.insertAdjacentElement('afterend', layer);\n  }\n  return layer;\n}\n\n/**\n * @param {THREE.Mesh} screen  unit plane, local corners (±0.5, 0..1 after its y offset)\n * @param {{ onMount?: (iframe, overlay) => void, onUnmount?: () => void }} [hooks]\n */\nexport function createTheaterIframePresenter(screen, { onMount = null, onUnmount = null } = {}) {\n  let surface = null;   // transformed container: iframe + overlay slot\n  let frame = null;\n  let overlay = null;\n  let src = '';\n  let interactive = true;\n  let size = { w: 960, h: 540 };\n  let lastSeen = 0;\n  let hideTimer = 0;\n  const corners = [new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3()];\n  const local = [[-0.5, 0.5], [0.5, 0.5], [-0.5, -0.5], [0.5, -0.5]];\n  const normal = new THREE.Vector3();\n  const toCamera = new THREE.Vector3();\n  const center = new THREE.Vector3();\n\n  const hide = () => { if (surface) surface.style.visibility = 'hidden'; };\n\n  // --- occlusion mask state ---\n  const cells = new Uint8Array(MASK_COLS * MASK_ROWS).fill(1);\n  let maskCursor = 0;\n  let maskKey = '';\n  let maskState = 'clear';\n  let maskCanvas = null;\n  const cameraWorld = new THREE.Vector3();\n  const samplePoint = new THREE.Vector3();\n  const applyMask = () => {\n    const key = cells.join('');\n    if (key === maskKey) return;\n    maskKey = key;\n    maskState = occlusionMaskState(cells);\n    if (!surface) return;\n    if (maskState !== 'partial') {\n      surface.style.maskImage = '';\n      surface.style.webkitMaskImage = '';\n      return;\n    }\n    maskCanvas ||= Object.assign(document.createElement('canvas'), { width: MASK_COLS, height: MASK_ROWS });\n    const ctx = maskCanvas.getContext('2d');\n    ctx.clearRect(0, 0, MASK_COLS, MASK_ROWS);\n    ctx.fillStyle = '#fff';\n    for (let k = 0; k < cells.length; k++) if (cells[k]) ctx.fillRect(k % MASK_COLS, Math.floor(k / MASK_COLS), 1, 1);\n    const url = `url(${maskCanvas.toDataURL()})`;\n    for (const [prop, value] of [['maskImage', url], ['maskSize', '100% 100%'], ['maskRepeat', 'no-repeat'],\n      ['webkitMaskImage', url], ['webkitMaskSize', '100% 100%'], ['webkitMaskRepeat', 'no-repeat']]) surface.style[prop] = value;\n  };\n  const sampleOcclusion = (camera) => {\n    if (!hasSceneOcclusionProbe()) return;\n    if (maskCursor === 0) prepareSceneOcclusion();\n    camera.getWorldPosition(cameraWorld);\n    const end = Math.min(cells.length, maskCursor + MASK_RAYS_PER_FRAME);\n    for (; maskCursor < end; maskCursor++) {\n      const u = ((maskCursor % MASK_COLS) + 0.5) / MASK_COLS - 0.5;\n      const v = 0.5 - (Math.floor(maskCursor / MASK_COLS) + 0.5) / MASK_ROWS;\n      samplePoint.set(u, v, 0).applyMatrix4(screen.matrixWorld);\n      cells[maskCursor] = isSceneSegmentOccluded(cameraWorld, samplePoint) ? 0 : 1;\n    }\n    if (maskCursor >= cells.length) { maskCursor = 0; applyMask(); }\n  };\n\n  const mount = (canvas) => {\n    if (surface || !src) return;\n    surface = document.createElement('div');\n    surface.className = 'nca-theater-surface';\n    Object.assign(surface.style, {\n      position: 'absolute', left: '0', top: '0', transformOrigin: '0 0',\n      visibility: 'hidden', willChange: 'transform', background: '#000',\n    });\n    frame = document.createElement('iframe');\n    frame.className = 'nca-theater-iframe';\n    // No allow-popups: links inside the player can never open a new tab;\n    // the theater routes playback into this screen instead.\n    frame.setAttribute('sandbox', 'allow-scripts allow-same-origin allow-presentation allow-forms');\n    frame.src = src;\n    frame.allow = 'autoplay; encrypted-media; picture-in-picture; fullscreen';\n    frame.referrerPolicy = 'strict-origin-when-cross-origin';\n    frame.setAttribute('allowfullscreen', '');\n    frame.title = 'Theater screen';\n    Object.assign(frame.style, { position: 'absolute', inset: '0', width: '100%', height: '100%', border: '0', background: '#000' });\n    overlay = document.createElement('div');\n    overlay.className = 'nca-theater-overlay';\n    Object.assign(overlay.style, { position: 'absolute', inset: '0', pointerEvents: 'none' });\n    surface.append(frame, overlay);\n    ensureLayer(canvas).appendChild(surface);\n    onMount?.(frame, overlay);\n  };\n\n  const unmount = () => {\n    if (!surface) return;\n    maskKey = '';\n    maskState = 'clear';\n    cells.fill(1);\n    maskCursor = 0;\n    surface.remove();\n    surface = null; frame = null; overlay = null;\n    onUnmount?.();\n  };\n\n  // Watchdog: when the screen stops rendering (culled / removed), hide.\n  const watch = () => {\n    hideTimer = 0;\n    if (!surface) return;\n    if (performance.now() - lastSeen > 150) hide();\n    else hideTimer = setTimeout(watch, 150);\n  };\n\n  const place = (renderer, camera) => {\n    if (!camera?.isPerspectiveCamera || !renderer?.domElement) return;\n    if (!surface) { if (!src) return; mount(renderer.domElement); }\n    lastSeen = performance.now();\n    if (!hideTimer) hideTimer = setTimeout(watch, 150);\n    const canvas = renderer.domElement;\n    const rectW = canvas.clientWidth;\n    const rectH = canvas.clientHeight;\n    screen.updateWorldMatrix(true, false);\n    normal.set(0, 0, 1).transformDirection(screen.matrixWorld);\n    center.set(0, 0, 0).applyMatrix4(screen.matrixWorld);\n    camera.getWorldPosition(toCamera).sub(center);\n    if (normal.dot(toCamera) <= 0) { hide(); return; }\n    const pts = [];\n    for (let i = 0; i < 4; i++) {\n      const p = corners[i].set(local[i][0], local[i][1], 0).applyMatrix4(screen.matrixWorld);\n      p.applyMatrix4(camera.matrixWorldInverse);\n      if (p.z >= -camera.near) { hide(); return; }\n      p.applyMatrix4(camera.projectionMatrix);\n      pts.push([(p.x * 0.5 + 0.5) * rectW, (-p.y * 0.5 + 0.5) * rectH]);\n    }\n    const xs = pts.map((p) => p[0]); const ys = pts.map((p) => p[1]);\n    const spanX = Math.max(...xs) - Math.min(...xs); const spanY = Math.max(...ys) - Math.min(...ys);\n    if (Math.max(...xs) < 0 || Math.min(...xs) > rectW || Math.max(...ys) < 0 || Math.min(...ys) > rectH\n      || Math.max(spanX, spanY) < MIN_SCREEN_PX) { hide(); return; }\n    const matrix = quadToCssMatrix(size.w, size.h, pts);\n    if (!matrix) { hide(); return; }\n    surface.style.width = `${size.w}px`;\n    surface.style.height = `${size.h}px`;\n    surface.style.transform = matrix;\n    sampleOcclusion(camera);\n    if (maskState === 'hidden') { hide(); return; }\n    frame.style.pointerEvents = interactive ? 'auto' : 'none';\n    surface.style.visibility = 'visible';\n  };\n\n  return {\n    get active() { return !!surface; },\n    get src() { return src; },\n    get iframe() { return frame; },\n    get overlay() { return overlay; },\n    /** Show `url` (or hide with ''). */\n    set({ url = '', width = 960, height = 540, isInteractive = true, canvas = null } = {}) {\n      size = { w: Math.max(64, Number(width) || 960), h: Math.max(64, Number(height) || 540) };\n      interactive = isInteractive !== false;\n      if (url !== src) { unmount(); src = url; }\n      if (src && canvas) mount(canvas);\n      if (!src) unmount();\n    },\n    /** The player switched video itself (bridge loadVideo): track it without a reload. */\n    adoptSrc(url) { src = url; },\n    place,\n    dispose() { clearTimeout(hideTimer); unmount(); src = ''; },\n  };\n}\n","/**\n * TheaterScreenBadge — what an idle theater screen shows, so viewers can tell\n * it is media and how to start it (click, come closer, or loading).\n */\nimport * as THREE from 'three';\n\nconst cache = new Map();\n\nexport function theaterBadgeHint(trigger, { embedded = false, blocked = false } = {}) {\n  if (blocked) return 'Click to play';\n  if (trigger === 'interaction') return 'Click to play';\n  if (trigger === 'proximity') return 'Come closer to play';\n  return embedded ? 'Loading player' : 'Loading';\n}\n\n/** Shared CanvasTexture: a play glyph over the hint text. */\nexport function getTheaterBadgeTexture(hint, { hovered = false } = {}) {\n  const key = `${hint}|${hovered ? 1 : 0}`;\n  if (cache.has(key)) return cache.get(key);\n  if (typeof document === 'undefined') return null;\n  const canvas = document.createElement('canvas');\n  canvas.width = 1024;\n  canvas.height = 576;\n  const ctx = canvas.getContext('2d');\n  if (!ctx) return null;\n  const grad = ctx.createLinearGradient(0, 0, 0, canvas.height);\n  grad.addColorStop(0, hovered ? '#1d2027' : '#0e1116');\n  grad.addColorStop(1, hovered ? '#121419' : '#07090c');\n  ctx.fillStyle = grad;\n  ctx.fillRect(0, 0, canvas.width, canvas.height);\n\n  const accent = hovered ? '#facc15' : 'rgba(255,255,255,0.85)';\n  const cx = canvas.width / 2;\n  const cy = canvas.height / 2 - 40;\n  ctx.lineWidth = 10;\n  ctx.strokeStyle = accent;\n  ctx.beginPath();\n  ctx.arc(cx, cy, 104, 0, Math.PI * 2);\n  ctx.stroke();\n  ctx.fillStyle = accent;\n  ctx.beginPath();\n  ctx.moveTo(cx - 34, cy - 54);\n  ctx.lineTo(cx + 62, cy);\n  ctx.lineTo(cx - 34, cy + 54);\n  ctx.closePath();\n  ctx.fill();\n\n  ctx.font = '600 52px \"Inter\", \"Segoe UI\", system-ui, sans-serif';\n  ctx.textAlign = 'center';\n  ctx.textBaseline = 'middle';\n  ctx.fillStyle = hovered ? '#facc15' : 'rgba(255,255,255,0.78)';\n  ctx.fillText(hint.toUpperCase(), cx, cy + 170);\n\n  const texture = new THREE.CanvasTexture(canvas);\n  texture.colorSpace = THREE.SRGBColorSpace;\n  texture.minFilter = THREE.LinearFilter;\n  texture.magFilter = THREE.LinearFilter;\n  texture.generateMipmaps = false;\n  cache.set(key, texture);\n  return texture;\n}\n","/**\n * EmbedPlayerBridge — talks to YouTube / Vimeo players inside a cross-origin\n * iframe over their postMessage APIs: volume (for distance / facing /\n * occlusion attenuation), play / pause, loading another video in place, and\n * player state (ended → advance the queue, paused → show Up next).\n */\n\nconst YT_ORIGIN = 'https://www.youtube.com';\nconst VIMEO_ORIGIN = 'https://player.vimeo.com';\n\nexport const PLAYER_STATE = { UNSTARTED: -1, ENDED: 0, PLAYING: 1, PAUSED: 2, BUFFERING: 3, CUED: 5 };\n\nconst parse = (input) => {\n  try { return new URL(String(input || ''), globalThis.location?.href || 'https://localhost/'); } catch { return null; }\n};\n\n/** 'youtube' | 'vimeo' | null for an embeddable player URL. */\nexport function bridgeProvider(url) {\n  const u = parse(url);\n  if (!u) return null;\n  if (/(^|\\.)youtube(-nocookie)?\\.com$/.test(u.hostname) && u.pathname.startsWith('/embed/')) return 'youtube';\n  if (u.hostname === 'player.vimeo.com') return 'vimeo';\n  return null;\n}\n\n/** YouTube video id from any YouTube URL form. */\nexport function youTubeVideoId(url) {\n  const u = parse(url);\n  if (!u) return '';\n  const h = u.hostname.replace(/^www\\.|^m\\./, '');\n  if (h === 'youtu.be') return u.pathname.slice(1).split('/')[0] || '';\n  if (!/youtube(-nocookie)?\\.com$/.test(h)) return '';\n  return u.searchParams.get('v') || (u.pathname.match(/\\/(?:embed|shorts|live|v)\\/([^/?#]+)/) || [])[1] || '';\n}\n\n/** Add the API flags a player needs before it will answer postMessage. */\nexport function withBridgeParams(url, origin = globalThis.location?.origin || '') {\n  const provider = bridgeProvider(url);\n  const u = parse(url);\n  if (!provider || !u) return url;\n  if (provider === 'youtube') {\n    u.searchParams.set('enablejsapi', '1');\n    u.searchParams.set('rel', '0');\n    if (origin && origin !== 'null') u.searchParams.set('origin', origin);\n  } else {\n    u.searchParams.set('api', '1');\n  }\n  return u.href;\n}\n\n/**\n * @param {HTMLIFrameElement} iframe\n * @param {'youtube'|'vimeo'} provider\n * @param {{ onState?: (state) => void }} [o]\n */\nexport function createEmbedPlayerBridge(iframe, provider, { onState = null } = {}) {\n  const origin = provider === 'youtube' ? YT_ORIGIN : VIMEO_ORIGIN;\n  const state = { ready: false, playerState: PLAYER_STATE.UNSTARTED, videoId: '', currentTime: 0, duration: 0, title: '' };\n  let lastVolume = -1;\n  let lastMuted = null;\n  let pinger = 0;\n\n  const post = (payload) => {\n    try { iframe.contentWindow?.postMessage(provider === 'youtube' ? JSON.stringify(payload) : payload, origin); } catch { /* frame gone */ }\n  };\n  const command = (func, args = []) => {\n    if (provider === 'youtube') post({ event: 'command', func, args, id: 1, channel: 'widget' });\n  };\n  const vimeo = (method, value) => post(value === undefined ? { method } : { method, value });\n  const emit = () => onState?.({ ...state });\n\n  const onMessage = (event) => {\n    if (event.source !== iframe.contentWindow) return;\n    let data = event.data;\n    if (typeof data === 'string') { try { data = JSON.parse(data); } catch { return; } }\n    if (!data || typeof data !== 'object') return;\n    if (provider === 'youtube') {\n      const info = data.info && typeof data.info === 'object' ? data.info : null;\n      if (data.event === 'onReady' || data.event === 'initialDelivery') state.ready = true;\n      if (data.event === 'onStateChange' && Number.isFinite(data.info)) state.playerState = data.info;\n      if (info) {\n        if (Number.isFinite(info.playerState)) state.playerState = info.playerState;\n        if (Number.isFinite(info.currentTime)) state.currentTime = info.currentTime;\n        if (Number.isFinite(info.duration)) state.duration = info.duration;\n        if (info.videoData?.video_id) { state.videoId = info.videoData.video_id; state.title = info.videoData.title || state.title; }\n      }\n    } else {\n      if (data.event === 'ready') {\n        state.ready = true;\n        for (const name of ['play', 'pause', 'ended', 'timeupdate']) vimeo('addEventListener', name);\n      }\n      if (data.event === 'play') state.playerState = PLAYER_STATE.PLAYING;\n      if (data.event === 'pause') state.playerState = PLAYER_STATE.PAUSED;\n      if (data.event === 'ended') state.playerState = PLAYER_STATE.ENDED;\n      if (data.event === 'timeupdate' && data.data) { state.currentTime = data.data.seconds; state.duration = data.data.duration; }\n    }\n    if (state.ready && pinger) { clearInterval(pinger); pinger = 0; }\n    emit();\n  };\n  window.addEventListener('message', onMessage);\n\n  // The player only starts talking after it hears from us.\n  const ping = () => (provider === 'youtube' ? post({ event: 'listening', id: 1, channel: 'widget' }) : vimeo('ping'));\n  pinger = setInterval(() => { if (state.ready) { clearInterval(pinger); pinger = 0; } else ping(); }, 300);\n  iframe.addEventListener('load', ping);\n\n  return {\n    get state() { return state; },\n    /** 0..1; skips redundant posts. */\n    setVolume(volume) {\n      const v = Math.round(Math.min(1, Math.max(0, volume)) * 100);\n      if (Math.abs(v - lastVolume) < 1 || !state.ready) return;\n      lastVolume = v;\n      if (provider === 'youtube') command('setVolume', [v]); else vimeo('setVolume', v / 100);\n    },\n    setMuted(muted) {\n      if (muted === lastMuted || !state.ready) return;\n      lastMuted = muted;\n      if (provider === 'youtube') command(muted ? 'mute' : 'unMute'); else vimeo('setMuted', muted);\n    },\n    play() { if (provider === 'youtube') command('playVideo'); else vimeo('play'); },\n    pause() { if (provider === 'youtube') command('pauseVideo'); else vimeo('pause'); },\n    seek(seconds) { if (provider === 'youtube') command('seekTo', [seconds, true]); else vimeo('setCurrentTime', seconds); },\n    /** Load another YouTube video in the same player (keeps the iframe). */\n    loadVideo(videoId, startSeconds = 0) {\n      if (provider !== 'youtube' || !videoId) return false;\n      command('loadVideoById', [{ videoId, startSeconds }]);\n      return true;\n    },\n    dispose() {\n      clearInterval(pinger);\n      window.removeEventListener('message', onMessage);\n      iframe.removeEventListener('load', ping);\n    },\n  };\n}\n","/**\n * MediaAspect — the width/height ratio of a theater's media, so the screen\n * (or projector throw) can match it: video elements report their intrinsic\n * size; provider players are looked up via oEmbed (CORS-enabled).\n */\nimport { youTubeVideoId } from './EmbedPlayerBridge.js';\n\nconst cache = new Map();\nconst MIN = 0.25;\nconst MAX = 4;\n\nexport const clampAspect = (value) => (Number.isFinite(value) && value > 0 ? Math.min(MAX, Math.max(MIN, value)) : null);\n\n/** Intrinsic aspect of a loaded <video>, or null before metadata. */\nexport function aspectFromVideo(el) {\n  return el && el.videoWidth > 0 && el.videoHeight > 0 ? clampAspect(el.videoWidth / el.videoHeight) : null;\n}\n\nfunction oEmbedEndpoint(url) {\n  let u;\n  try { u = new URL(url); } catch { return null; }\n  const h = u.hostname.replace(/^www\\.|^m\\./, '');\n  const ytId = youTubeVideoId(url);\n  if (ytId) return `https://www.youtube.com/oembed?format=json&url=${encodeURIComponent(`https://www.youtube.com/watch?v=${ytId}`)}`;\n  if (h === 'vimeo.com' || h === 'player.vimeo.com') {\n    const id = u.pathname.split('/').filter(Boolean).find((p) => /^\\d+$/.test(p));\n    return id ? `https://vimeo.com/api/oembed.json?url=${encodeURIComponent(`https://vimeo.com/${id}`)}` : null;\n  }\n  return null;\n}\n\n/** Best immediate guess without a network round trip. */\nexport function guessAspect(url) {\n  return /youtube\\.com\\/shorts\\//i.test(String(url || '')) ? 9 / 16 : null;\n}\n\n/** Aspect of a provider URL (cached); resolves null when unknown. */\nexport function fetchEmbedAspect(url, { fetchImpl = globalThis.fetch } = {}) {\n  const endpoint = oEmbedEndpoint(url);\n  if (!endpoint || typeof fetchImpl !== 'function') return Promise.resolve(guessAspect(url));\n  if (cache.has(endpoint)) return cache.get(endpoint);\n  const pending = fetchImpl(endpoint)\n    .then((res) => (res.ok ? res.json() : null))\n    .then((data) => clampAspect(Number(data?.width) / Number(data?.height)) || guessAspect(url))\n    .catch(() => guessAspect(url));\n  cache.set(endpoint, pending);\n  return pending;\n}\n\n/** oEmbed title + thumbnail for Up next rows (cached with the aspect). */\nconst metaCache = new Map();\nexport function fetchEmbedMeta(url, { fetchImpl = globalThis.fetch } = {}) {\n  const endpoint = oEmbedEndpoint(url);\n  const ytId = youTubeVideoId(url);\n  const fallback = { title: '', thumbnail: ytId ? `https://i.ytimg.com/vi/${ytId}/mqdefault.jpg` : '' };\n  if (!endpoint || typeof fetchImpl !== 'function') return Promise.resolve(fallback);\n  if (!metaCache.has(endpoint)) {\n    metaCache.set(endpoint, fetchImpl(endpoint)\n      .then((res) => (res.ok ? res.json() : null))\n      .then((data) => ({ title: String(data?.title || ''), thumbnail: fallback.thumbnail || String(data?.thumbnail_url || '') }))\n      .catch(() => fallback));\n  }\n  return metaCache.get(endpoint);\n}\n","/**\n * TheaterUpNextCard — our own pause / end screen drawn over an embedded\n * player. It covers the provider's suggestion overlay (whose links would open\n * a new tab) with suggestions that play *in this screen*: the theater queue,\n * the authored playlist and recently played media, plus a paste-a-link field.\n */\nimport { fetchEmbedMeta } from './MediaAspect.js';\n\nconst STYLE_ID = 'nca-theater-upnext-style';\nconst CSS = `\n.nca-upnext{position:absolute;inset:0;display:flex;flex-direction:column;gap:18px;padding:34px 40px;\n  background:linear-gradient(180deg,rgba(6,8,12,.86),rgba(6,8,12,.94));color:#f4f4f5;\n  font:500 22px/1.25 Inter,\"Segoe UI\",system-ui,sans-serif;pointer-events:auto;box-sizing:border-box}\n.nca-upnext__head{display:flex;align-items:center;gap:18px}\n.nca-upnext__resume{all:unset;cursor:pointer;width:84px;height:84px;border-radius:50%;border:5px solid #facc15;\n  display:grid;place-items:center;flex:none}\n.nca-upnext__resume:hover{background:rgba(250,204,21,.16)}\n.nca-upnext__resume svg{width:34px;height:34px;fill:#facc15;margin-left:6px}\n.nca-upnext__title{font-size:30px;font-weight:700;letter-spacing:.02em}\n.nca-upnext__sub{opacity:.7;font-size:19px}\n.nca-upnext__list{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;min-height:0;flex:1;overflow:hidden}\n.nca-upnext__item{all:unset;cursor:pointer;display:flex;flex-direction:column;gap:8px;min-width:0}\n.nca-upnext__item img{width:100%;aspect-ratio:16/9;object-fit:cover;border-radius:10px;background:#1f2329;border:3px solid transparent}\n.nca-upnext__item:hover img,.nca-upnext__item:focus-visible img{border-color:#facc15}\n.nca-upnext__item span{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;font-size:20px}\n.nca-upnext__form{display:flex;gap:12px}\n.nca-upnext__form input{flex:1;min-width:0;font:inherit;font-size:20px;padding:12px 16px;border-radius:10px;border:2px solid #3f444c;background:#0d1015;color:#fff}\n.nca-upnext__form button{all:unset;cursor:pointer;padding:12px 22px;border-radius:10px;background:#facc15;color:#111;font-weight:700}\n`;\n\nfunction ensureStyle() {\n  if (typeof document === 'undefined' || document.getElementById(STYLE_ID)) return;\n  const style = document.createElement('style');\n  style.id = STYLE_ID;\n  style.textContent = CSS;\n  document.head.appendChild(style);\n}\n\nconst shortLabel = (url) => {\n  try { const u = new URL(url); return `${u.hostname.replace(/^www\\./, '')}${u.pathname}`.slice(0, 60); } catch { return String(url).slice(0, 60); }\n};\n\n/**\n * @param {HTMLElement} slot  the presenter overlay element\n * @param {{ onPlay: (url) => void, onResume: () => void }} actions\n */\nexport function createTheaterUpNextCard(slot, { onPlay, onResume }) {\n  ensureStyle();\n  let root = null;\n  let key = '';\n\n  const hide = () => { root?.remove(); root = null; key = ''; };\n\n  /** @param {{ mode: 'paused'|'ended', items: string[] }} view */\n  const show = ({ mode, items }) => {\n    const nextKey = `${mode}|${items.join('|')}`;\n    if (root && key === nextKey) return;\n    hide();\n    key = nextKey;\n    root = document.createElement('div');\n    root.className = 'nca-upnext';\n    root.innerHTML = `\n      <div class=\"nca-upnext__head\">\n        <button class=\"nca-upnext__resume\" type=\"button\" aria-label=\"${mode === 'ended' ? 'Replay' : 'Resume'}\">\n          <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path d=\"M6 4l15 8-15 8z\"/></svg></button>\n        <div><div class=\"nca-upnext__title\">${mode === 'ended' ? 'Up next' : 'Paused'}</div>\n          <div class=\"nca-upnext__sub\">${items.length ? 'Pick something to play on this screen' : 'Paste a video link, or click one anywhere in NOCLIP, to play it here'}</div></div>\n      </div>\n      <div class=\"nca-upnext__list\"></div>\n      <form class=\"nca-upnext__form\"><input type=\"url\" placeholder=\"YouTube, Vimeo, Twitch or video file URL\" aria-label=\"Video URL\"><button type=\"submit\">Play here</button></form>`;\n    root.querySelector('.nca-upnext__resume').addEventListener('click', (e) => { e.stopPropagation(); onResume(); });\n    root.querySelector('form').addEventListener('submit', (e) => {\n      e.preventDefault();\n      const value = root.querySelector('input').value.trim();\n      if (value) onPlay(value);\n    });\n    const list = root.querySelector('.nca-upnext__list');\n    for (const url of items.slice(0, 6)) {\n      const item = document.createElement('button');\n      item.type = 'button';\n      item.className = 'nca-upnext__item';\n      item.innerHTML = '<img alt=\"\"><span></span>';\n      item.querySelector('span').textContent = shortLabel(url);\n      item.addEventListener('click', (e) => { e.stopPropagation(); onPlay(url); });\n      list.appendChild(item);\n      fetchEmbedMeta(url).then(({ title, thumbnail }) => {\n        if (title) item.querySelector('span').textContent = title;\n        if (thumbnail) item.querySelector('img').src = thumbnail;\n      });\n    }\n    // Keep keystrokes in the URL field away from the scene's movement keys.\n    root.addEventListener('keydown', (e) => e.stopPropagation());\n    slot.appendChild(root);\n  };\n\n  return { show, hide, get visible() { return !!root; }, dispose: hide };\n}\n","/**\n * TheaterEmbedSession — an embedded provider player on a theater screen:\n * the pinned iframe (TheaterIframePresenter), its control bridge, distance /\n * facing / occlusion volume, in-place video switching and our Up next card\n * over the player's own pause and end screens.\n */\nimport { createTheaterIframePresenter } from './TheaterIframePresenter.js';\nimport { bridgeProvider, createEmbedPlayerBridge, PLAYER_STATE, withBridgeParams, youTubeVideoId } from './EmbedPlayerBridge.js';\nimport { createTheaterUpNextCard } from './TheaterUpNextCard.js';\n\nconst VOLUME_TICK_MS = 150;\n\n/**\n * @param {THREE.Mesh} screen\n * @param {object} hooks\n * @param {() => number} hooks.listenerGain    0..1 from the acoustic model\n * @param {() => boolean} hooks.muted\n * @param {() => string[]} hooks.upcoming      Up next entries\n * @param {() => string} hooks.onEnded         advance the queue; returns next URL or ''\n * @param {(url: string) => void} hooks.onPick a viewer picked / pasted a URL\n * @param {() => void} hooks.onResume\n */\nexport function createTheaterEmbedSession(screen, hooks) {\n  let bridge = null;\n  let card = null;\n  let wantActive = false;\n  let lastState = PLAYER_STATE.UNSTARTED;\n  let volumeTimer = 0;\n\n  const syncCard = (state) => {\n    if (!card) return;\n    const paused = state.playerState === PLAYER_STATE.PAUSED;\n    const ended = state.playerState === PLAYER_STATE.ENDED;\n    if (wantActive && (paused || ended)) card.show({ mode: ended ? 'ended' : 'paused', items: hooks.upcoming() });\n    else card.hide();\n  };\n\n  const onState = (state) => {\n    if (state.playerState !== lastState) {\n      const endedNow = state.playerState === PLAYER_STATE.ENDED;\n      lastState = state.playerState;\n      if (endedNow && hooks.onEnded()) return; // next video loads; card stays hidden\n    }\n    syncCard(state);\n  };\n\n  const presenter = createTheaterIframePresenter(screen, {\n    onMount(iframe, overlay) {\n      const provider = bridgeProvider(iframe.src);\n      if (provider) bridge = createEmbedPlayerBridge(iframe, provider, { onState });\n      card = createTheaterUpNextCard(overlay, {\n        onPlay: (url) => hooks.onPick(url),\n        onResume: () => {\n          if (lastState === PLAYER_STATE.ENDED) bridge?.seek(0);\n          bridge?.play();\n          hooks.onResume();\n        },\n      });\n      clearInterval(volumeTimer);\n      volumeTimer = setInterval(() => {\n        if (!bridge) return;\n        bridge.setMuted(hooks.muted());\n        bridge.setVolume(hooks.listenerGain());\n      }, VOLUME_TICK_MS);\n    },\n    onUnmount() {\n      clearInterval(volumeTimer);\n      bridge?.dispose(); bridge = null;\n      card?.dispose(); card = null;\n      lastState = PLAYER_STATE.UNSTARTED;\n    },\n  });\n\n  return {\n    get active() { return presenter.active; },\n    get bridged() { return !!bridge; },\n    get playerState() { return lastState; },\n    /**\n     * @param {{ url: string, active: boolean, width: number, height: number, isInteractive: boolean }} o\n     */\n    set({ url, active, width, height, isInteractive }) {\n      const target = url ? withBridgeParams(url) : '';\n      const wasActive = wantActive;\n      wantActive = !!active;\n      // Same YouTube player, different video: switch in place, no reload.\n      if (target && presenter.active && bridge?.state.ready && target !== presenter.src\n        && bridgeProvider(target) === 'youtube' && bridgeProvider(presenter.src) === 'youtube') {\n        const id = youTubeVideoId(target);\n        if (id && bridge.loadVideo(id)) presenter.adoptSrc(target);\n      }\n      // A bridged player keeps its place when paused; others unload.\n      const keep = !!target && (wantActive || (presenter.active && !!bridge && presenter.src === target));\n      presenter.set({ url: keep ? target : '', width, height, isInteractive });\n      if (bridge && wasActive !== wantActive) (wantActive ? bridge.play() : bridge.pause());\n      if (bridge) syncCard(bridge.state);\n    },\n    /** Refresh the Up next card's contents (queue changed). */\n    refreshCard() { if (bridge) { card?.hide(); syncCard(bridge.state); } },\n    place: (renderer, camera) => presenter.place(renderer, camera),\n    dispose() { clearInterval(volumeTimer); presenter.dispose(); },\n  };\n}\n","/**\n * TheaterQueue — what a theater screen is playing and what plays next.\n *\n * The authored source (Content Studio) is the base; links routed in from the\n * interface or picked from Up next play now or queue behind it. Ended media\n * advances to the next entry; the authored playlist repeats when `loop`.\n */\nconst norm = (url) => String(url || '').trim();\n\nexport function createTheaterQueue() {\n  let authored = [];      // [base, ...playlist]\n  let upNext = [];        // user / routed entries, played before authored ones\n  let current = '';       // '' → the authored base source\n  let authoredIndex = 0;\n  let loop = false;\n  const history = [];\n\n  const authoredAt = (i) => authored[((i % authored.length) + authored.length) % authored.length] || '';\n\n  return {\n    /** Content Studio source + optional playlist (array or newline list). */\n    configure({ base = '', playlist = [], loop: nextLoop = false } = {}) {\n      const list = (Array.isArray(playlist) ? playlist : String(playlist || '').split(/\\s*\\n\\s*/)).map(norm).filter(Boolean);\n      const next = [norm(base), ...list].filter(Boolean);\n      if (next.join('\\n') !== authored.join('\\n')) { authored = next; authoredIndex = 0; }\n      loop = !!nextLoop;\n    },\n    /** The URL that should be on screen now ('' = nothing authored). */\n    get current() { return current || authoredAt(authoredIndex); },\n    get overridden() { return !!current; },\n    get history() { return history.slice(-12); },\n    /** Upcoming entries, for the Up next card. */\n    upcoming(limit = 6) {\n      const out = [...upNext];\n      for (let i = 1; out.length < limit && i < authored.length + (loop ? authored.length : 0); i++) {\n        const idx = authoredIndex + i;\n        if (!loop && idx >= authored.length) break;\n        out.push(authoredAt(idx));\n      }\n      return out.slice(0, limit).filter((url) => url && url !== this.current);\n    },\n    playNow(url) {\n      const u = norm(url);\n      if (!u) return false;\n      if (this.current) history.push(this.current);\n      upNext = upNext.filter((x) => x !== u);\n      const authoredIdx = authored.indexOf(u);\n      if (authoredIdx >= 0) { authoredIndex = authoredIdx; current = ''; } else current = u;\n      return true;\n    },\n    enqueue(url) {\n      const u = norm(url);\n      if (!u || upNext.includes(u)) return false;\n      upNext.push(u);\n      return true;\n    },\n    /** Advance after the current media ended. Returns the new URL or ''. */\n    advance() {\n      if (upNext.length) { this.playNow(upNext.shift()); return this.current; }\n      if (authored.length > 1 && (loop || authoredIndex + (current ? 0 : 1) < authored.length)) {\n        if (this.current) history.push(this.current);\n        authoredIndex = current ? authoredIndex : authoredIndex + 1;\n        current = '';\n        return this.current;\n      }\n      return '';\n    },\n    /** Return to the authored source (e.g. its properties were edited). */\n    reset() { current = ''; upNext = []; },\n  };\n}\n","/**\n * TheaterProjector — a small projector box that throws the theater's video\n * onto whatever surfaces lie inside its field of view and throw distance.\n *\n * The lens is a PerspectiveCamera (never rendered from). A grid of rays is\n * cast through it, a few per frame, against the visible scene meshes; the\n * hits become a surface-conforming mesh (child of the lens, so its vertices\n * stay small and jitter-free at planetary coordinates) textured with the\n * frame, with UV = the ray's position in the image. Brightness falls off with\n * the inverse square of the throw and with the angle of incidence; triangles\n * spanning a depth jump (an edge with a far wall behind) are dropped.\n */\nimport * as THREE from 'three';\nimport { MeshBVH } from 'three-mesh-bvh';\n\n// Our own BVHs, keyed by geometry: other systems' meshes are never modified.\nconst bvhCache = new WeakMap();\n\nconst SKIP_NAME = /sky|atmos|cloud|star|sun|moon|halo|glow|aurora|precip|rain|snow/i;\nconst MAX_RADIUS_M = 200_000;\nconst RAYS_PER_FRAME = 96;\nconst REBUILD_EVERY_MS = 1500;\nconst BVH_BUILDS_PER_PASS = 2;\nconst BVH_MIN_TRIANGLES = 1500;\n\nexport const DEFAULT_PROJECTOR = { fovDeg: 40, distanceM: 60, heightM: 1.4, pitchDeg: 0, brightness: 1, aspect: 16 / 9, cols: 32 };\n\n/** Throw → brightness: flat to a third of the range, inverse-square after, faded out at the limit. */\nexport function projectorFalloff(distanceM, rangeM) {\n  if (!(distanceM > 0) || !(rangeM > 0) || distanceM > rangeM) return 0;\n  const knee = rangeM / 3;\n  const inverseSquare = distanceM <= knee ? 1 : (knee / distanceM) ** 2;\n  const edge = Math.min(1, (rangeM - distanceM) / (rangeM * 0.12));\n  return Math.max(0.18, inverseSquare) * edge;\n}\n\n/** Vertical FOV (deg) from a horizontal throw angle and image aspect. */\nexport function verticalFov(horizontalDeg, aspect) {\n  const h = THREE.MathUtils.degToRad(Math.min(150, Math.max(2, horizontalDeg)));\n  return THREE.MathUtils.radToDeg(2 * Math.atan(Math.tan(h / 2) / Math.max(0.1, aspect)));\n}\n\nexport function createTheaterProjector({ ignoreRoot = null } = {}) {\n  let cfg = { ...DEFAULT_PROJECTOR };\n  const root = new THREE.Group();\n  root.name = 'TheaterProjector';\n\n  const bodyMaterial = new THREE.MeshBasicMaterial({ color: '#2a2f36' });\n  const stand = new THREE.Mesh(new THREE.CylinderGeometry(0.025, 0.04, 1, 10), bodyMaterial);\n  stand.name = 'ProjectorStand';\n  const body = new THREE.Group();\n  const box = new THREE.Mesh(new THREE.BoxGeometry(0.36, 0.2, 0.42), bodyMaterial);\n  box.name = 'ProjectorBody';\n  const lensMaterial = new THREE.MeshBasicMaterial({ color: '#e8f1ff' });\n  const lensMesh = new THREE.Mesh(new THREE.CylinderGeometry(0.06, 0.07, 0.06, 20), lensMaterial);\n  lensMesh.rotation.x = Math.PI / 2;\n  lensMesh.position.set(0.08, 0, 0.23);\n  body.add(box, lensMesh);\n  root.add(stand, body);\n\n  const lens = new THREE.PerspectiveCamera(30, cfg.aspect, 0.05, cfg.distanceM);\n  lens.name = 'ProjectorLens';\n  lens.rotation.y = Math.PI; // cameras look down -Z; throw along the item's +Z\n  lens.position.set(0.08, 0, 0.26);\n  body.add(lens);\n\n  const surfaceMaterial = new THREE.MeshBasicMaterial({ vertexColors: true, side: THREE.DoubleSide, toneMapped: false });\n  const surface = new THREE.Mesh(new THREE.BufferGeometry(), surfaceMaterial);\n  surface.name = 'ProjectorSurface';\n  surface.frustumCulled = false;\n  surface.userData.noProjection = true;\n  lens.add(surface);\n\n  const raycaster = new THREE.Raycaster();\n  const frustum = new THREE.Frustum();\n  const projScreen = new THREE.Matrix4();\n  const sphere = new THREE.Sphere();\n  const ndc = new THREE.Vector2();\n  const normalMatrix = new THREE.Matrix3();\n  const tmpNormal = new THREE.Vector3();\n  const lensWorld = new THREE.Vector3();\n  const lastMatrix = new THREE.Matrix4();\n  const centroidLocal = new THREE.Vector3();\n\n  let grid = null;       // { cols, rows, dist: Float32Array, pos: Float32Array, shade: Float32Array }\n  let cursor = 0;\n  let candidates = [];\n  let passStartedAt = 0;\n  let dirty = true;\n  let hasSurface = false;\n\n  const sceneRoot = () => { let r = root; while (r.parent) r = r.parent; return r; };\n  const ignored = (obj) => {\n    for (let o = obj; o; o = o.parent) if (o === root || o === ignoreRoot || o.userData?.noProjection) return true;\n    return false;\n  };\n\n  const collectCandidates = () => {\n    lens.updateWorldMatrix(true, false);\n    projScreen.multiplyMatrices(lens.projectionMatrix, lens.matrixWorldInverse);\n    frustum.setFromProjectionMatrix(projScreen);\n    const out = [];\n    let builds = 0;\n    sceneRoot().traverseVisible((obj) => {\n      if (!obj.isMesh || obj.isSkinnedMesh || obj.isInstancedMesh || ignored(obj)) return;\n      const mat = Array.isArray(obj.material) ? obj.material[0] : obj.material;\n      if (!mat || mat.visible === false || mat.side === THREE.BackSide || (mat.transparent && mat.opacity < 0.35)) return;\n      if (SKIP_NAME.test(obj.name || '')) return;\n      const geo = obj.geometry;\n      if (!geo?.attributes?.position) return;\n      if (!geo.boundingSphere) geo.computeBoundingSphere();\n      sphere.copy(geo.boundingSphere).applyMatrix4(obj.matrixWorld);\n      if (sphere.radius > MAX_RADIUS_M || !frustum.intersectsSphere(sphere)) return;\n      const triangles = (geo.index ? geo.index.count : geo.attributes.position.count) / 3;\n      let bvh = geo.boundsTree || bvhCache.get(geo) || null;\n      if (!bvh && triangles > BVH_MIN_TRIANGLES && obj.raycast === THREE.Mesh.prototype.raycast) {\n        if (builds >= BVH_BUILDS_PER_PASS) return; // picked up on a later pass\n        try { bvh = new MeshBVH(geo, { indirect: true }); bvhCache.set(geo, bvh); builds++; } catch { return; }\n      }\n      out.push({ mesh: obj, bvh: obj.raycast === THREE.Mesh.prototype.raycast ? bvh : null, side: mat.side, inv: new THREE.Matrix4().copy(obj.matrixWorld).invert() });\n    });\n    return out;\n  };\n\n  const startPass = () => {\n    const cols = Math.max(8, Math.min(64, Math.round(cfg.cols)));\n    const rows = Math.max(5, Math.round(cols / Math.max(0.25, cfg.aspect)));\n    const n = cols * rows;\n    if (!grid || grid.cols !== cols || grid.rows !== rows) {\n      grid = { cols, rows, dist: new Float32Array(n), pos: new Float32Array(n * 3), shade: new Float32Array(n) };\n    }\n    grid.dist.fill(-1);\n    candidates = collectCandidates();\n    cursor = 0;\n    passStartedAt = performance.now();\n    lastMatrix.copy(lens.matrixWorld);\n    dirty = false;\n  };\n\n  const localRay = new THREE.Ray();\n  const firstHit = (rc) => {\n    let best = null;\n    for (const c of candidates) {\n      let hit = null;\n      if (c.bvh) {\n        localRay.copy(rc.ray).applyMatrix4(c.inv);\n        const h = c.bvh.raycastFirst(localRay, c.side);\n        if (h) {\n          h.point.applyMatrix4(c.mesh.matrixWorld);\n          h.distance = h.point.distanceTo(rc.ray.origin);\n          h.object = c.mesh;\n          if (h.distance >= rc.near && h.distance <= rc.far) hit = h;\n        }\n      } else {\n        hit = rc.intersectObject(c.mesh, false)[0] || null;\n      }\n      if (hit && (!best || hit.distance < best.distance)) best = hit;\n    }\n    return best;\n  };\n\n  const castSome = () => {\n    const { cols, rows, dist, pos, shade } = grid;\n    const end = Math.min(cols * rows, cursor + RAYS_PER_FRAME);\n    lens.getWorldPosition(lensWorld);\n    raycaster.near = 0.05;\n    raycaster.far = cfg.distanceM;\n    for (; cursor < end; cursor++) {\n      const i = cursor % cols;\n      const j = Math.floor(cursor / cols);\n      ndc.set((i / (cols - 1)) * 2 - 1, (j / (rows - 1)) * 2 - 1);\n      raycaster.setFromCamera(ndc, lens);\n      const hit = firstHit(raycaster);\n      if (!hit) continue;\n      let lambert = 1;\n      if (hit.face?.normal) {\n        tmpNormal.copy(hit.face.normal).applyNormalMatrix(normalMatrix.getNormalMatrix(hit.object.matrixWorld)).normalize();\n        lambert = Math.abs(tmpNormal.dot(raycaster.ray.direction));\n      }\n      // Lift off the surface toward the lens so it never z-fights.\n      const p = hit.point.addScaledVector(raycaster.ray.direction, -Math.max(0.03, hit.distance * 0.002));\n      lens.worldToLocal(p);\n      pos.set([p.x, p.y, p.z], cursor * 3);\n      dist[cursor] = hit.distance;\n      shade[cursor] = cfg.brightness * projectorFalloff(hit.distance, cfg.distanceM) * (0.35 + 0.65 * lambert);\n    }\n  };\n\n  const buildSurface = () => {\n    const { cols, rows, dist, pos, shade } = grid;\n    const positions = new Float32Array(cols * rows * 3);\n    const uvs = new Float32Array(cols * rows * 2);\n    const colors = new Float32Array(cols * rows * 3);\n    const index = [];\n    centroidLocal.set(0, 0, 0);\n    let hits = 0;\n    for (let k = 0; k < cols * rows; k++) {\n      positions.set(pos.subarray(k * 3, k * 3 + 3), k * 3);\n      uvs[k * 2] = (k % cols) / (cols - 1);\n      uvs[k * 2 + 1] = Math.floor(k / cols) / (rows - 1);\n      colors.fill(Math.max(0, shade[k]), k * 3, k * 3 + 3);\n      if (dist[k] > 0) { hits++; centroidLocal.x += pos[k * 3]; centroidLocal.y += pos[k * 3 + 1]; centroidLocal.z += pos[k * 3 + 2]; }\n    }\n    if (hits) centroidLocal.multiplyScalar(1 / hits);\n    const ok = (...ks) => {\n      let lo = Infinity; let hi = -Infinity;\n      for (const k of ks) { if (dist[k] <= 0) return false; lo = Math.min(lo, dist[k]); hi = Math.max(hi, dist[k]); }\n      return hi - lo <= 0.4 + 0.12 * lo; // depth jump → separate surfaces\n    };\n    for (let j = 0; j < rows - 1; j++) {\n      for (let i = 0; i < cols - 1; i++) {\n        const a = j * cols + i; const b = a + 1; const c = a + cols; const d = c + 1;\n        if (ok(a, b, d)) index.push(a, b, d);\n        if (ok(a, d, c)) index.push(a, d, c);\n      }\n    }\n    const geo = new THREE.BufferGeometry();\n    geo.setAttribute('position', new THREE.BufferAttribute(positions, 3));\n    geo.setAttribute('uv', new THREE.BufferAttribute(uvs, 2));\n    geo.setAttribute('color', new THREE.BufferAttribute(colors, 3));\n    geo.setIndex(index);\n    surface.geometry.dispose();\n    surface.geometry = geo;\n    hasSurface = index.length > 0;\n  };\n\n  return {\n    root,\n    surface,\n    lens,\n    /** @param {Partial<typeof DEFAULT_PROJECTOR>} next */\n    configure(next = {}) {\n      const merged = { ...cfg };\n      for (const [k, v] of Object.entries(next)) if (Number.isFinite(v)) merged[k] = v;\n      merged.distanceM = Math.max(1, Math.min(2000, merged.distanceM));\n      if (JSON.stringify(merged) !== JSON.stringify(cfg)) dirty = true;\n      cfg = merged;\n      stand.scale.y = Math.max(0.05, cfg.heightM);\n      stand.position.y = stand.scale.y / 2;\n      body.position.y = cfg.heightM + 0.1;\n      body.rotation.x = -THREE.MathUtils.degToRad(cfg.pitchDeg);\n      lens.fov = verticalFov(cfg.fovDeg, cfg.aspect);\n      lens.aspect = cfg.aspect;\n      lens.far = cfg.distanceM;\n      lens.updateProjectionMatrix();\n    },\n    setTexture(texture) {\n      if (surfaceMaterial.map === texture) return;\n      surfaceMaterial.map = texture || null;\n      surfaceMaterial.needsUpdate = true;\n    },\n    setHovered(hovered) { bodyMaterial.color.set(hovered ? '#facc15' : '#2a2f36'); },\n    setLensLit(lit) { lensMaterial.color.set(lit ? '#ffffff' : '#5d6672'); },\n    /** Where the picture lands, in the projector root's space (for audio). */\n    imageCenter(target = new THREE.Vector3()) {\n      if (!hasSurface) return target.set(0, cfg.heightM, 0);\n      target.copy(centroidLocal);\n      lens.localToWorld(target);\n      return root.worldToLocal(target);\n    },\n    get ready() { return hasSurface; },\n    /** Call every frame; spreads the ray casting over frames. */\n    update() {\n      if (!root.parent) return;\n      lens.updateWorldMatrix(true, false);\n      if (!grid || cursor >= grid.cols * grid.rows) {\n        const moved = !lens.matrixWorld.equals(lastMatrix);\n        if (dirty || moved || performance.now() - passStartedAt > REBUILD_EVERY_MS) startPass();\n        else return;\n      }\n      castSome();\n      if (cursor >= grid.cols * grid.rows) buildSurface();\n    },\n    dispose() {\n      surface.geometry.dispose();\n      for (const m of [bodyMaterial, lensMaterial, surfaceMaterial]) m.dispose();\n      root.removeFromParent();\n      candidates = [];\n    },\n  };\n}\n","/**\n * TheaterMediaRouter — sends media links clicked anywhere in the NOCLIP\n * interface (chat, notes, search results, docs, window.open calls) to the\n * theater screen the viewer is using instead of a new browser tab.\n *\n * Target: the theater the viewer last clicked / hovered (for 15 minutes) if\n * they are still near it, otherwise the nearest theater in range. With no\n * theater nearby, or with a modifier key / middle click, links behave\n * normally.\n */\nconst FOCUS_TTL_MS = 15 * 60 * 1000;\nconst DIRECT_MEDIA = /\\.(mp4|webm|ogv|ogg|m4v|mov|m3u8)(\\?|#|$)/i;\n\nconst theaters = new Set();\nlet focused = null;\nlet focusedAt = 0;\nlet installed = null;\n\n/** True for URLs a theater can play: provider pages/embeds or media files. */\nexport function isRoutableMediaUrl(input) {\n  let u;\n  try { u = new URL(String(input || ''), globalThis.location?.href || 'https://localhost/'); } catch { return false; }\n  if (!/^https?:$/.test(u.protocol)) return false;\n  const h = u.hostname.replace(/^www\\.|^m\\./, '');\n  if (h === 'youtu.be') return u.pathname.length > 1;\n  if (/youtube(-nocookie)?\\.com$/.test(h)) return !!(u.searchParams.get('v') || /^\\/(embed|shorts|live)\\//.test(u.pathname));\n  if (h === 'vimeo.com' || h === 'player.vimeo.com') return /\\/\\d+/.test(u.pathname);\n  if (h === 'twitch.tv' || h === 'player.twitch.tv') return u.pathname.length > 1 || u.searchParams.has('channel') || u.searchParams.has('video');\n  return DIRECT_MEDIA.test(u.pathname);\n}\n\n/**\n * @param {{ playUrl(url, o?): boolean, distanceToViewer(): number, rangeM(): number }} theater\n * @returns {() => void} unregister\n */\nexport function registerTheater(theater) {\n  theaters.add(theater);\n  return () => { theaters.delete(theater); if (focused === theater) focused = null; };\n}\n\nexport function focusTheater(theater) {\n  if (!theaters.has(theater)) return;\n  focused = theater;\n  focusedAt = Date.now();\n}\n\nexport function pickTheater(now = Date.now()) {\n  const near = (t) => { const d = t.distanceToViewer(); return Number.isFinite(d) && d <= t.rangeM(); };\n  if (focused && now - focusedAt < FOCUS_TTL_MS && near(focused)) return focused;\n  let best = null;\n  let bestDistance = Infinity;\n  for (const t of theaters) {\n    const d = t.distanceToViewer();\n    if (near(t) && d < bestDistance) { best = t; bestDistance = d; }\n  }\n  return best;\n}\n\n/** Play `url` on the chosen theater. Returns true when it was taken. */\nexport function routeMediaUrl(url, { queue = false } = {}) {\n  if (!isRoutableMediaUrl(url)) return false;\n  const theater = pickTheater();\n  if (!theater) return false;\n  return theater.playUrl(url, { queue }) !== false;\n}\n\n/** Install the document click + window.open interception once. */\nexport function installMediaLinkRouter(win = globalThis.window) {\n  if (installed || !win?.document) return () => {};\n  const onClick = (event) => {\n    if (event.defaultPrevented || event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return;\n    const anchor = event.target?.closest?.('a[href]');\n    if (!anchor || anchor.hasAttribute('download') || anchor.dataset.noTheater !== undefined) return;\n    if (routeMediaUrl(anchor.href)) {\n      event.preventDefault();\n      event.stopPropagation();\n    }\n  };\n  const originalOpen = win.open;\n  const patchedOpen = function open(url, ...rest) {\n    if (url && routeMediaUrl(String(url))) return null;\n    return originalOpen.call(this, url, ...rest);\n  };\n  win.document.addEventListener('click', onClick, true);\n  win.open = patchedOpen;\n  installed = () => {\n    win.document.removeEventListener('click', onClick, true);\n    if (win.open === patchedOpen) win.open = originalOpen;\n    installed = null;\n  };\n  return installed;\n}\n","/**\n * TheaterListenerAudio — where the viewer is relative to a theater and how\n * loud its media should be for them: distance, which side of the screen they\n * are on, and whether terrain/buildings block the path. Web Audio media gets\n * this from AcousticEmitter; iframe players get the one-number estimate.\n */\nimport * as THREE from 'three';\nimport { estimateEmitterGain } from '../audio/AcousticEmitter.js';\n\nconst num = (value, fallback) => (Number.isFinite(value) ? value : fallback);\n\nexport function createTheaterListenerAudio({ group, audioAnchor, audioSystem, lastCameraWorld, getProps, isProjector, cone, defaultWidthM }) {\n  const listenerWorld = new THREE.Vector3();\n  const anchorWorld = new THREE.Vector3();\n  const facing = new THREE.Vector3();\n  const toViewer = new THREE.Vector3();\n  const acousticPath = {};\n  let occlusion = { gain: 1, at: 0 };\n\n  const size = () => (isProjector()\n    ? num(getProps().projector_distance_m, 60) * 0.5\n    : num(getProps().width_m, defaultWidthM));\n\n  const viewerPosition = () => {\n    const listener = audioSystem?.listener;\n    if (listener?.getWorldPosition) return listener.getWorldPosition(listenerWorld);\n    return Number.isFinite(lastCameraWorld.x) ? listenerWorld.copy(lastCameraWorld) : null;\n  };\n  /** Metres at which the media fades out entirely. */\n  const audioReach = () => num(getProps().audio_max_distance, Math.max(120, size() * 12));\n  /** Metres within which the media plays at full level. */\n  const audioRef = () => num(getProps().audio_ref_distance, Math.max(3, size() * 0.5));\n\n  const listenerGain = () => {\n    const viewer = viewerPosition();\n    if (!viewer) return 0;\n    const props = getProps();\n    audioAnchor.getWorldPosition(anchorWorld);\n    const distanceM = anchorWorld.distanceTo(viewer);\n    facing.set(0, 0, 1).transformDirection(group.matrixWorld);\n    toViewer.copy(viewer).sub(anchorWorld).normalize();\n    const now = performance.now();\n    if (now - occlusion.at > 300 && audioSystem?.sampleAcousticPath) {\n      const path = audioSystem.sampleAcousticPath(anchorWorld, viewer, acousticPath);\n      occlusion = { gain: path?.occluded ? Math.max(0.15, Number(path.directGain) * 2.2) : 1, at: now };\n    }\n    return estimateEmitterGain({\n      distanceM,\n      facingAngleRad: isProjector() ? 0 : facing.angleTo(toViewer),\n      occlusionGain: occlusion.gain,\n      refDistance: audioRef(),\n      rolloff: num(props.audio_rolloff, 1),\n      maxDistance: audioReach(),\n      cone,\n    }) * Math.min(1, num(props.audio_gain, 0.9));\n  };\n\n  return { viewerPosition, audioReach, audioRef, listenerGain };\n}\n","/**\n * TheaterStatusProps — fold a theater channel status update (live / idle,\n * HLS / WHEP playback URLs, stream ids) into the item's properties.\n */\nexport function applyTheaterStatus(baseProps, statusPayload) {\n  const props = { ...(baseProps || {}) };\n\n  if (statusPayload.status === 'live') {\n    if (statusPayload.playback_hls_url) {\n      props.playback_hls_url = statusPayload.playback_hls_url;\n    }\n    if (statusPayload.playback_whep_url) {\n      props.playback_whep_url = statusPayload.playback_whep_url;\n    }\n    props.source_type = 'rtmp';\n    if (statusPayload.video_stream || statusPayload.stream_id) {\n      props.video_stream = statusPayload.video_stream || statusPayload.stream_id;\n    }\n    if (statusPayload.audio_stream) {\n      props.audio_stream = statusPayload.audio_stream;\n    }\n  } else if (statusPayload.status === 'idle') {\n    props.playback_hls_url = null;\n    props.playback_whep_url = null;\n    if (statusPayload.clear_streams) {\n      props.video_stream = null;\n      props.audio_stream = null;\n    }\n  }\n\n  if (statusPayload.source_type) {\n    props.source_type = statusPayload.source_type;\n  }\n  if (statusPayload.hls_url) {\n    props.source_type = statusPayload.source_type || 'hls';\n    props.hls_url = statusPayload.hls_url;\n    props.playback_hls_url = statusPayload.hls_url;\n  }\n  if (statusPayload.embed_url) {\n    props.source_type = statusPayload.source_type || 'embed_url';\n    props.embed_url = statusPayload.embed_url;\n  }\n  if (statusPayload.video_stream || statusPayload.stream_id) {\n    props.video_stream = statusPayload.video_stream || statusPayload.stream_id;\n    if (!props.source_type) props.source_type = 'stream_id';\n  }\n  if (statusPayload.audio_stream) {\n    props.audio_stream = statusPayload.audio_stream;\n  }\n\n  return props;\n}\n","import * as THREE from 'three';\nimport { createTheaterSourceManager, SOURCE_TYPE } from './TheaterSourceManager.js';\nimport { createMediaPlaybackController } from './MediaPlaybackController.js';\nimport { toEmbeddablePlayerUrl } from './TheaterIframePresenter.js';\nimport { getTheaterBadgeTexture, theaterBadgeHint } from './TheaterScreenBadge.js';\nimport { markPhotorealMaskOccluder } from '../render/PhotorealAssetLighting.js';\nimport { createTheaterEmbedSession } from './TheaterEmbedSession.js';\nimport { createTheaterQueue } from './TheaterQueue.js';\nimport { createTheaterProjector } from './TheaterProjector.js';\nimport { aspectFromVideo, fetchEmbedAspect, guessAspect } from './MediaAspect.js';\nimport { focusTheater, installMediaLinkRouter, registerTheater } from './TheaterMediaRouter.js';\nimport { createTheaterListenerAudio } from './TheaterListenerAudio.js';\nimport { applyTheaterStatus } from './TheaterStatusProps.js';\n\nconst HOVER_FRAME_COLOR = '#facc15';\nconst SCREEN_CONE = { inner: 150, outer: 300, outerGain: 0.3 };\nconst PROJECTOR_HINT = 'Projector needs a video file';\nconst noRaycast = () => {};\n\n/** URL the Content Studio authored as this theater's source. */\nconst authoredSourceUrl = (props = {}) => String(props.embed_url || extractIframeSrc(props.iframe_embed) || props.hls_url || props.playback_hls_url || '').trim();\n\nconst extractIframeSrc = (input) => {\n  const raw = String(input || '').trim();\n  const match = raw.match(/<iframe[^>]*\\s+src=([\"'])(.*?)\\1/i);\n  if (match?.[2]) return match[2].trim();\n  if (/^https?:\\/\\//i.test(raw)) return raw;\n  return '';\n};\n\nconst DEFAULT_WIDTH_M = 400;\nconst DEFAULT_HEIGHT_M = 225;\nconst DEFAULT_FRAME_COLOR = '#20242a';\nconst DEFAULT_SCREEN_COLOR = '#0b0f14';\n\nconst resolveNumber = (value, fallback) => (Number.isFinite(value) ? value : fallback);\n\nconst deriveAudioStream = (videoStream) => {\n  if (!videoStream || typeof videoStream !== 'string') return null;\n  if (videoStream.startsWith('comms:call:video:')) {\n    return videoStream.replace('comms:call:video:', 'comms:call:audio:');\n  }\n  if (videoStream.startsWith('comms:overlay:video:')) {\n    return videoStream.replace('comms:overlay:video:', 'comms:overlay:audio:');\n  }\n  if (videoStream.includes(':video:')) {\n    return videoStream.replace(':video:', ':audio:');\n  }\n  return null;\n};\n\nconst resolveIngressTarget = (props = {}, item = {}) => ({\n  overlayId: props.overlay_id || props.overlayId || item.overlay_id || item.overlayId || '',\n  itemId: props.item_id || props.itemId || item.item_id || item.itemId || '',\n  sessionId: props.session_id || props.sessionId || ''\n});\n\nexport const createTheaterOverlayItem = (item, commsSystem, audioSystem) => {\n  const group = new THREE.Group();\n  group.name = `OverlayTheater:${item?.item_id || 'theater'}`;\n  group.userData.itemId = item?.item_id || null;\n  group.userData.theaterOverlayItem = true;\n\n  // Front face only: the back of the panel is the frame's back plate. No two\n  // visible faces overlap, so nothing z-fights at range.\n  const screenMaterial = new THREE.MeshBasicMaterial({\n    color: DEFAULT_SCREEN_COLOR,\n    side: THREE.FrontSide,\n  });\n  const frameMaterial = new THREE.MeshBasicMaterial({\n    color: DEFAULT_FRAME_COLOR,\n    side: THREE.DoubleSide,\n  });\n  const backMaterial = new THREE.MeshBasicMaterial({\n    color: DEFAULT_FRAME_COLOR,\n    side: THREE.BackSide,\n  });\n\n  const screenGeometry = new THREE.PlaneGeometry(1, 1);\n  // Border ring around the screen (outer 1.08, hole 1.0) plus a back plate.\n  const ring = new THREE.Shape();\n  ring.moveTo(-0.54, -0.54); ring.lineTo(0.54, -0.54); ring.lineTo(0.54, 0.54); ring.lineTo(-0.54, 0.54); ring.closePath();\n  const hole = new THREE.Path();\n  hole.moveTo(-0.5, -0.5); hole.lineTo(-0.5, 0.5); hole.lineTo(0.5, 0.5); hole.lineTo(0.5, -0.5); hole.closePath();\n  ring.holes.push(hole);\n  const frameGeometry = new THREE.ShapeGeometry(ring);\n  const backGeometry = new THREE.PlaneGeometry(1.08, 1.08);\n  const frame = new THREE.Mesh(frameGeometry, frameMaterial);\n  const back = new THREE.Mesh(backGeometry, backMaterial);\n  const screen = new THREE.Mesh(screenGeometry, screenMaterial);\n\n  frame.name = 'TheaterFrame';\n  back.name = 'TheaterBack';\n  screen.name = 'TheaterScreen';\n\n  // Keep screen upright and anchored so the panel base sits on terrain.\n  frame.position.y = 0.5;\n  back.position.y = 0.5;\n  screen.position.y = 0.5;\n  frame.renderOrder = 1;\n  screen.renderOrder = 2;\n\n  group.add(frame);\n  group.add(back);\n  group.add(screen);\n  // A screen is a light source, not a lit surface: keep it forward-lit but\n  // occluding the photoreal mask so sky/terrain never composite through it.\n  markPhotorealMaskOccluder(group);\n\n  const lastCameraWorld = new THREE.Vector3(NaN, NaN, NaN);\n  let embed = null;\n  screen.onBeforeRender = (renderer, _scene, camera) => {\n    camera.getWorldPosition(lastCameraWorld);\n    embed?.place(renderer, camera);\n  };\n  let hovered = false;\n  let mediaAspect = null;\n  let aspectFor = '';\n  const queue = createTheaterQueue();\n  const projector = createTheaterProjector({ ignoreRoot: group });\n  markPhotorealMaskOccluder(projector.root);\n  let projectorLoop = 0;\n  let blockedMediaUrl = '';\n  let baseFrameColor = DEFAULT_FRAME_COLOR;\n  let baseScreenColor = DEFAULT_SCREEN_COLOR;\n  let latestProps = item?.current?.properties || {};\n\n  const audioAnchor = new THREE.Object3D();\n  audioAnchor.name = `AudioAnchor:${item?.item_id || 'theater'}`;\n  audioAnchor.position.set(0, 0.5, 0);\n  group.add(audioAnchor);\n  group.userData.audioAnchor = audioAnchor;\n\n  const playback = createMediaPlaybackController();\n  playback.configure(item?.current?.properties || {});\n  group.userData.mediaPlayback = playback;\n\n  let refreshScreen = () => {};\n  let watchedMedia = null;\n  const onMediaState = () => {\n    const aspect = aspectFromVideo(watchedMedia);\n    if (aspect && aspect !== mediaAspect) { mediaAspect = aspect; applyVisuals(); }\n    refreshScreen();\n  };\n  const onMediaError = () => {\n    // Usually a host without CORS headers: WebGL may not sample it, but the\n    // browser's own player can still show it in the embedded frame.\n    const src = watchedMedia?.currentSrc || watchedMedia?.src || '';\n    if (src && !blockedMediaUrl) { blockedMediaUrl = src; refreshScreen(); }\n  };\n  // A finished file / stream moves on to Up next (looping media never ends).\n  const onMediaEnded = () => {\n    const next = queue.advance();\n    if (next) { reloadSource(); playback.broadcastLoad(next); }\n  };\n  const watchMedia = (el) => {\n    for (const type of ['playing', 'pause', 'loadeddata', 'loadedmetadata']) watchedMedia?.removeEventListener?.(type, onMediaState);\n    watchedMedia?.removeEventListener?.('error', onMediaError);\n    watchedMedia?.removeEventListener?.('ended', onMediaEnded);\n    watchedMedia = el || null;\n    for (const type of ['playing', 'pause', 'loadeddata', 'loadedmetadata']) watchedMedia?.addEventListener?.(type, onMediaState);\n    watchedMedia?.addEventListener?.('error', onMediaError);\n    watchedMedia?.addEventListener?.('ended', onMediaEnded);\n  };\n  const sourceManager = createTheaterSourceManager(THREE, commsSystem, {\n    onMediaElement: (el) => { watchMedia(el); playback.setMedia(el); refreshScreen(); },\n  });\n\n  // What actually plays: the authored source unless the queue moved on\n  // (routed link, Up next pick, playlist advance).\n  const effectiveProps = () => {\n    const url = queue.current;\n    return url && url !== authoredSourceUrl(latestProps)\n      ? { ...latestProps, source_type: 'embed_url', embed_url: url, hls_url: '', iframe_enabled: false }\n      : latestProps;\n  };\n  const isProjector = () => latestProps.display_mode === 'projector';\n\n  const embeddedUrl = () => {\n    const props = effectiveProps();\n    const raw = blockedMediaUrl\n      || sourceManager.getEmbedUrl()\n      || (props.iframe_enabled === true ? extractIframeSrc(props.iframe_embed) || extractIframeSrc(props.embed_url) : '');\n    return raw ? toEmbeddablePlayerUrl(raw) : '';\n  };\n\n  const iframeSize = () => {\n    const a = mediaAspect || 16 / 9;\n    const base = latestProps.iframe_width_px ?? 960;\n    return a >= 1 ? { width: base, height: Math.round(base / a) } : { width: Math.round(base * a), height: base };\n  };\n\n  refreshScreen = () => {\n    const props = latestProps;\n    const projectorMode = isProjector();\n    const embedded = embeddedUrl();\n    const active = playback.active;\n    const size = props.fit_media_aspect === false\n      ? { width: props.iframe_width_px ?? 960, height: props.iframe_height_px ?? 540 }\n      : iframeSize();\n    embed?.set({\n      url: embedded && !projectorMode ? embedded : '',\n      active,\n      ...size,\n      isInteractive: props.iframe_interactive !== false,\n    });\n    const media = sourceManager.getAudioElement();\n    const videoTexture = embedded ? null : sourceManager.getTexture();\n    const hasFrames = !media || media.readyState >= 2;\n    const showVideo = !!videoTexture && hasFrames && !playback.blocked && (active || (media && media.currentTime > 0));\n    const hint = projectorMode && embedded\n      ? PROJECTOR_HINT\n      : theaterBadgeHint(playback.config.trigger, { embedded: !!embedded, blocked: playback.blocked });\n    const map = showVideo ? videoTexture : getTheaterBadgeTexture(hint, { hovered });\n    if (map !== screenMaterial.map) {\n      screenMaterial.map = map || null;\n      screenMaterial.needsUpdate = true;\n    }\n    // Basic material colour multiplies the map: only tint an empty screen.\n    screenMaterial.color.set(map ? '#ffffff' : baseScreenColor);\n    frameMaterial.color.set(hovered ? HOVER_FRAME_COLOR : baseFrameColor);\n    backMaterial.color.set(baseFrameColor);\n    projector.setTexture(map);\n    projector.setHovered(hovered);\n    projector.setLensLit(showVideo);\n  };\n  playback.subscribe(() => refreshScreen());\n  group.userData.onHoverChange = (next) => {\n    hovered = next === true;\n    if (hovered) focusTheater(theaterApi);\n    refreshScreen();\n  };\n\n  const { viewerPosition, audioReach, audioRef, listenerGain } = createTheaterListenerAudio({\n    group, audioAnchor, audioSystem, lastCameraWorld,\n    getProps: () => latestProps,\n    isProjector,\n    cone: SCREEN_CONE,\n    defaultWidthM: DEFAULT_WIDTH_M,\n  });\n\n  // --- Queue / routing ---\n  const reloadSource = () => {\n    sourceManager.update(effectiveProps());\n    group.userData.embedUrl = sourceManager.getEmbedUrl();\n    attachMediaAudio();\n    updateAspectFor(queue.current);\n    refreshScreen();\n  };\n  const playUrl = (url, { queue: toQueue = false, broadcast = true } = {}) => {\n    const next = String(url || '').trim();\n    if (!next) return false;\n    if (toQueue) { queue.enqueue(next); embed?.refreshCard(); return true; }\n    if (next === queue.current) { if (!playback.active && playback.config.trigger === 'interaction') playback.interact(); return true; }\n    queue.playNow(next);\n    blockedMediaUrl = '';\n    reloadSource();\n    if (!playback.active && playback.config.trigger === 'interaction') playback.interact();\n    if (broadcast) playback.broadcastLoad(next);\n    return true;\n  };\n  playback.onRemoteLoad((url) => playUrl(url, { broadcast: false }));\n  const theaterApi = {\n    id: item?.item_id || null,\n    playUrl,\n    distanceToViewer: () => {\n      const viewer = viewerPosition();\n      if (!viewer) return Infinity;\n      return group.getWorldPosition(new THREE.Vector3()).distanceTo(viewer);\n    },\n    rangeM: () => (playback.config.trigger === 'proximity' ? playback.config.rangeM : Math.max(150, audioReach() * 0.5)),\n  };\n  const unregisterTheater = registerTheater(theaterApi);\n  installMediaLinkRouter();\n  group.userData.theater = theaterApi;\n\n  embed = createTheaterEmbedSession(screen, {\n    listenerGain,\n    muted: () => latestProps.muted === true,\n    upcoming: () => [...queue.upcoming(6), ...queue.history.reverse()].filter((u, i, all) => u && u !== queue.current && all.indexOf(u) === i).slice(0, 6),\n    onEnded: () => { const next = queue.advance(); if (next) { reloadSource(); playback.broadcastLoad(next); } return next; },\n    onPick: (url) => playUrl(url),\n    onResume: () => { if (!playback.active && playback.config.trigger === 'interaction') playback.interact(); },\n  });\n\n  function updateAspectFor(url) {\n    if (!url || url === aspectFor) return;\n    aspectFor = url;\n    const guess = guessAspect(url);\n    if (guess) { mediaAspect = guess; applyVisuals(); }\n    if (sourceManager.isMediaElement()) return; // the <video> reports its own size\n    fetchEmbedAspect(url).then((aspect) => {\n      if (aspect && aspectFor === url && aspect !== mediaAspect) { mediaAspect = aspect; applyVisuals(); refreshScreen(); }\n    });\n  }\n\n\n  function _detachAudio() {\n    if (group.userData.audioHandleId && audioSystem?.detach) {\n      audioSystem.detach(group.userData.audioHandleId);\n    }\n    group.userData.audioHandleId = null;\n    group.userData.audioStreamId = null;\n    group.userData.attachedMediaEl = null;\n  }\n\n  const setScreenVisible = (visible) => {\n    for (const mesh of [frame, back, screen]) {\n      mesh.visible = visible;\n      mesh.raycast = visible ? THREE.Mesh.prototype.raycast : noRaycast;\n    }\n  };\n\n  const tickProjector = () => {\n    projectorLoop = 0;\n    if (!isProjector()) return;\n    projector.update();\n    if (projector.ready) projector.imageCenter(audioAnchor.position);\n    projectorLoop = requestAnimationFrame(tickProjector);\n  };\n\n  const applyVisuals = (nextItem = null) => {\n    const props = nextItem?.current?.properties || latestProps;\n    const widthM = resolveNumber(props.width_m, DEFAULT_WIDTH_M);\n    const fit = props.fit_media_aspect !== false && mediaAspect;\n    const heightM = fit ? widthM / mediaAspect : resolveNumber(props.height_m, DEFAULT_HEIGHT_M);\n    baseFrameColor = props.frame_color || DEFAULT_FRAME_COLOR;\n    baseScreenColor = props.screen_color || DEFAULT_SCREEN_COLOR;\n\n    if (props.display_mode === 'projector') {\n      group.scale.set(1, 1, 1);\n      setScreenVisible(false);\n      if (projector.root.parent !== group) group.add(projector.root);\n      projector.configure({\n        fovDeg: Number(props.projector_fov_deg),\n        distanceM: Number(props.projector_distance_m),\n        heightM: Number(props.projector_height_m),\n        pitchDeg: Number(props.projector_pitch_deg),\n        brightness: Number(props.projector_brightness),\n        aspect: props.fit_media_aspect !== false && mediaAspect ? mediaAspect : 16 / 9,\n      });\n      if (!projectorLoop && typeof requestAnimationFrame === 'function') projectorLoop = requestAnimationFrame(tickProjector);\n    } else {\n      if (projectorLoop) { cancelAnimationFrame(projectorLoop); projectorLoop = 0; }\n      projector.root.removeFromParent();\n      setScreenVisible(true);\n      group.scale.set(widthM, heightM, 1);\n      audioAnchor.position.set(0, 0.5, 0);\n    }\n    refreshScreen();\n  };\n\n  function attachMediaAudio() {\n    const props = latestProps;\n    if (!sourceManager.isMediaElement()) {\n      if (group.userData.attachedMediaEl) _detachAudio();\n      return;\n    }\n    const audioEl = sourceManager.getAudioElement();\n    if (!audioEl || audioEl === group.userData.attachedMediaEl) return;\n    _detachAudio();\n    const handle = audioSystem?.attachToObject?.(audioAnchor, audioEl, {\n      sourceType: 'media-element',\n      gain: resolveNumber(props.audio_gain, 0.9),\n      refDistance: audioRef(),\n      maxDistance: audioReach(),\n      rolloff: resolveNumber(props.audio_rolloff, 1),\n      // Sound leaves the screen into the world: directivity, air absorption,\n      // terrain/building occlusion, ground reflection, ambient reverb.\n      acoustics: { cone: isProjector() ? null : SCREEN_CONE, reverb: 0.2 },\n    });\n    group.userData.audioHandleId = handle?.handleId || null;\n    group.userData.attachedMediaEl = audioEl;\n    audioEl.muted = !!props.muted;\n  }\n\n  const applyStreams = (nextItem) => {\n    const props = nextItem?.current?.properties || {};\n    const ingressTarget = resolveIngressTarget(props, nextItem || item);\n    const routedStreams = commsSystem?.getOverlayStreamIds?.(ingressTarget) || {};\n    const prevSource = `${latestProps.source_type}|${latestProps.embed_url}|${latestProps.hls_url}|${latestProps.iframe_embed}`;\n    latestProps = props;\n    if (prevSource !== `${props.source_type}|${props.embed_url}|${props.hls_url}|${props.iframe_embed}`) {\n      blockedMediaUrl = '';\n      queue.reset();\n    }\n    queue.configure({ base: authoredSourceUrl(props), playlist: props.playlist, loop: props.loop === true });\n    playback.configure(props);\n    const effective = effectiveProps();\n    sourceManager.update(effective);\n    group.userData.embedUrl = sourceManager.getEmbedUrl();\n    updateAspectFor(queue.current || authoredSourceUrl(props));\n    refreshScreen();\n\n    const currentSourceType = sourceManager.getSourceType();\n\n    if (currentSourceType === SOURCE_TYPE.STREAM_ID) {\n      const videoStreamId = props.video_stream || props.stream_id || routedStreams.videoStreamId || null;\n      const derivedAudio = deriveAudioStream(videoStreamId);\n      const audioStreamId = props.audio_stream || routedStreams.audioStreamId || derivedAudio || null;\n\n      if (audioStreamId !== group.userData.audioStreamId) {\n        _detachAudio();\n        if (audioStreamId) {\n          const handle = audioSystem?.attachToObject?.(audioAnchor, audioStreamId, {\n            sourceType: 'pcm',\n            gain: resolveNumber(props.audio_gain, 0.9),\n            refDistance: audioRef(),\n            maxDistance: audioReach(),\n            rolloff: resolveNumber(props.audio_rolloff, 1),\n            acoustics: { cone: isProjector() ? null : SCREEN_CONE, reverb: 0.2 },\n          });\n          group.userData.audioHandleId = handle?.handleId || null;\n        }\n        group.userData.audioStreamId = audioStreamId || null;\n      }\n      return;\n    }\n\n    attachMediaAudio();\n  };\n\n  group.userData.updateItem = (nextItem) => {\n    applyVisuals(nextItem);\n    applyStreams(nextItem);\n  };\n\n  group.userData.onRemove = () => {\n    _detachAudio();\n    watchMedia(null);\n    sourceManager.dispose();\n    playback.dispose();\n    embed.dispose();\n    if (projectorLoop) cancelAnimationFrame(projectorLoop);\n    projector.dispose();\n    unregisterTheater();\n  };\n\n  group.userData.onTheaterStatus = (statusPayload) => {\n    if (!statusPayload) return;\n    const props = applyTheaterStatus(item?.current?.properties, statusPayload);\n    applyStreams({ ...item, current: { ...(item?.current || {}), properties: props } });\n  };\n\n  applyVisuals(item);\n  applyStreams(item);\n\n  return group;\n};\n","/**\n * ModelFirstDrawPrep — get a freshly loaded model ready before its first draw\n * so that draw does not stall the render loop:\n *   1. textures larger than needed are downscaled off the main thread\n *      (createImageBitmap resize), e.g. the airliner's 4096² livery → 1024²;\n *   2. textures are uploaded to the GPU one per idle slot;\n *   3. its shader programs are compiled asynchronously (compileAsync), so the\n *      first frame does not wait on a program link.\n * Every step is best-effort: on failure the model still draws normally.\n */\nimport * as THREE from 'three';\n\nconst TEXTURE_SLOTS = ['map', 'normalMap', 'roughnessMap', 'metalnessMap', 'aoMap', 'emissiveMap', 'alphaMap', 'bumpMap', 'specularMap'];\n\nconst whenIdle = () => new Promise((resolve) => (typeof requestIdleCallback === 'function'\n  ? requestIdleCallback(() => resolve(), { timeout: 1000 })\n  : setTimeout(resolve, 16)));\n\n/** Unique textures used by meshes under `root`. */\nexport function collectModelTextures(root) {\n  const textures = new Set();\n  root?.traverse?.((node) => {\n    if (!node.isMesh) return;\n    for (const material of Array.isArray(node.material) ? node.material : [node.material]) {\n      for (const slot of TEXTURE_SLOTS) if (material?.[slot]?.isTexture) textures.add(material[slot]);\n    }\n  });\n  return [...textures];\n}\n\n/** Target size keeping aspect, longest side ≤ maxSize (null when already small). */\nexport function downscaleTarget(width, height, maxSize) {\n  if (!(width > 0 && height > 0) || Math.max(width, height) <= maxSize) return null;\n  const scale = maxSize / Math.max(width, height);\n  return { width: Math.max(1, Math.round(width * scale)), height: Math.max(1, Math.round(height * scale)) };\n}\n\nasync function downscaleTexture(texture, maxSize) {\n  const image = texture.image;\n  const width = image?.width || image?.naturalWidth;\n  const height = image?.height || image?.naturalHeight;\n  const target = downscaleTarget(width, height, maxSize);\n  if (!target || typeof createImageBitmap !== 'function') return;\n  // Same orientation as the source: an ImageBitmap stays as decoded.\n  const bitmap = await createImageBitmap(image, { resizeWidth: target.width, resizeHeight: target.height, resizeQuality: 'high' });\n  image.close?.();\n  texture.image = bitmap;\n  texture.needsUpdate = true;\n}\n\n/**\n * @param {THREE.Object3D} root\n * @param {{ renderer?, camera?, scene?, maxTextureSize?: number }} o\n */\nexport async function prepareModelForFirstDraw(root, { renderer = null, camera = null, scene = null, maxTextureSize = 1024 } = {}) {\n  const textures = collectModelTextures(root);\n  for (const texture of textures) {\n    try { await downscaleTexture(texture, maxTextureSize); } catch { /* keep the original */ }\n  }\n  if (renderer?.initTexture) {\n    for (const texture of textures) {\n      await whenIdle();\n      try { renderer.initTexture(texture); } catch { /* uploads on first draw */ }\n    }\n  }\n  if (renderer?.compileAsync && camera) {\n    try { await renderer.compileAsync(root, camera, scene || undefined); } catch { /* compiles on first draw */ }\n  }\n}\n\n/**\n * A gate that answers \"may objects using this material be shown yet?\":\n * the first ask starts an async program compile (parallel on drivers with\n * KHR_parallel_shader_compile) and later asks return true once it is linked.\n * Without a renderer/camera everything is ready immediately.\n */\nexport function createProgramGate({ renderer = null, camera = null, scene = null } = {}) {\n  const ready = new WeakSet();\n  const compiling = new WeakMap();\n  return {\n    ready(material, geometry) {\n      if (!material || ready.has(material)) return true;\n      const r = typeof renderer === 'function' ? renderer() : renderer;\n      const c = typeof camera === 'function' ? camera() : camera;\n      if (!r?.compileAsync || !c) { ready.add(material); return true; }\n      if (!compiling.has(material)) {\n        const probe = new THREE.Mesh(geometry, material);\n        const s = typeof scene === 'function' ? scene() : scene;\n        compiling.set(material, Promise.resolve()\n          .then(() => r.compileAsync(probe, c, s || undefined))\n          .catch(() => {})\n          .finally(() => { ready.add(material); compiling.delete(material); }));\n      }\n      return false;\n    },\n  };\n}\n","import { geodesicDestinationWGS84 } from '../../modules/geometry-utils.js';\nconst A=6378137,E2=6.6943799901413165e-3,DEG=Math.PI/180;\nconst before=new Float64Array(3),after=new Float64Array(3);\nexport const AIRCRAFT_FRAME_SECONDS=16;\nexport const AIRCRAFT_CORRECTION_SECONDS=1.5;\nexport const AIRCRAFT_MAX_AGE_MS=60_000;\nexport function aircraftIdentity(record) {\n const raw=String(record?.id??record?.icao24??record?.hex??'').trim().toLowerCase();\n if(!raw||raw.length>80)return null;\n return /^[0-9a-f]{6}$/.test(raw)?`icao:${raw}`:`${record.source||'unknown'}:${raw}`;\n}\nexport function observationTime(record) {\n const value=record?.positionTime??record?.lastContact;\n if(typeof value==='number')return Math.abs(value)<1e11?value*1000:value;\n return Date.parse(value||'');\n}\nexport function aircraftScenePosition(lat,lon,altitude,out=new Float64Array(3)) {\n const phi=lat*DEG,lambda=lon*DEG,s=Math.sin(phi),c=Math.cos(phi),n=A/Math.sqrt(1-E2*s*s);\n out[0]=(n+altitude)*c*Math.sin(lambda);out[1]=(n*(1-E2)+altitude)*s;out[2]=(n+altitude)*c*Math.cos(lambda);return out;\n}\nfunction positionAt(record,at,out) {\n const epoch=observationTime(record),seconds=Math.max(0,Math.min(90,(at-epoch)/1000));\n const speed=Number.isFinite(record.velocityMps)?Math.max(0,Math.min(2000,record.velocityMps)):0;\n const heading=Number.isFinite(record.headingDeg)?record.headingDeg:0;\n const altitude=Number.isFinite(record.altitudeM)?record.altitudeM:0;\n const rate=record.onGround?0:Number.isFinite(record.verticalRateMps)?Math.max(-150,Math.min(150,record.verticalRateMps)):0;\n const point=speed&&seconds?geodesicDestinationWGS84(record.lat,record.lon,heading,speed*seconds):null;\n return aircraftScenePosition(point?.latDeg??record.lat,point?.lonDeg??record.lon,altitude+rate*seconds,out);\n}\nexport function aircraftStateAt(record,at,out=new Float64Array(6)) {\n positionAt(record,at,out);\n const epoch=observationTime(record);\n const left=Math.max(epoch,at-125),right=Math.min(epoch+90_000,at+125);\n if(right>left){positionAt(record,left,before);positionAt(record,right,after);for(let i=0;i<3;i++)out[i+3]=(after[i]-before[i])*1000/(right-left);}\n else out.fill(0,3,6);\n return out;\n}\nexport function updateAircraftTrack(previous,record,now) {\n const epoch=observationTime(record),id=aircraftIdentity(record);\n if(!id||!Number.isFinite(record.lat)||Math.abs(record.lat)>90||!Number.isFinite(record.lon)||Math.abs(record.lon)>180\n   ||!Number.isFinite(epoch)||epoch>now+5000||now-epoch>AIRCRAFT_MAX_AGE_MS\n   ||(!Number.isFinite(record.altitudeM)&&record.onGround!==true))return previous||null;\n if(previous&&epoch<observationTime(previous.record))return previous;\n const changed=!previous||['lat','lon','altitudeM','velocityMps','headingDeg','verticalRateMps','onGround'].some(k=>previous.record[k]!==record[k])||epoch!==observationTime(previous.record);\n if(previous&&!changed){previous.record=record;return previous;}\n const next={id,record,correction:new Float64Array(6),correctionAt:now,history:previous?.history||[]};\n if(previous&&now-observationTime(previous.record)<=AIRCRAFT_MAX_AGE_MS){const old=sampleAircraftTrack(previous,now),fresh=aircraftStateAt(record,now);for(let i=0;i<6;i++)next.correction[i]=old[i]-fresh[i];}\n const last=next.history.at(-1);\n if(!last||epoch>last.timeMs){next.history.push({lat:record.lat,lon:record.lon,altM:record.altitudeM,timeMs:epoch,source:record.source,measured:true});if(next.history.length>256)next.history.splice(0,next.history.length-256);}\n return next;\n}\nexport function sampleAircraftTrack(track,at,out=new Float64Array(6)) {\n aircraftStateAt(track.record,at,out);\n const t=Math.max(0,Math.min(1,(at-track.correctionAt)/1000/AIRCRAFT_CORRECTION_SECONDS));\n if(t<1){const t2=t*t,t3=t2*t,d=AIRCRAFT_CORRECTION_SECONDS;\n  for(let i=0;i<3;i++){out[i]+=(2*t3-3*t2+1)*track.correction[i]+(t3-2*t2+t)*d*track.correction[i+3];out[i+3]+=(6*t2-6*t)/d*track.correction[i]+(3*t2-4*t+1)*track.correction[i+3];}}\n return out;\n}\n/** CPU counterpart of the point shader, shared by picking, near models and labels. */\nexport function sampleAircraftFrame(frame,index,at,out=new Float64Array(6)) {\n const t=Math.max(0,Math.min(1,(at-frame.at)/(frame.interval*1000))),t2=t*t,t3=t2*t,k=index*12,d=frame.data;\n for(let i=0;i<3;i++){\n  out[i]=d[k+i]+(-2*t3+3*t2)*(d[k+6+i]-d[k+i])+(t3-2*t2+t)*frame.interval*d[k+3+i]+(t3-t2)*frame.interval*d[k+9+i];\n  out[i+3]=(-6*t2+6*t)/frame.interval*(d[k+6+i]-d[k+i])+(3*t2-4*t+1)*d[k+3+i]+(3*t2-2*t)*d[k+9+i];\n }\n const c=frame.corrections,j=index*7,u=Math.max(0,Math.min(1,((at-frame.at)/1000-c[j+6])/AIRCRAFT_CORRECTION_SECONDS)),u2=u*u,u3=u2*u;\n if(u<1)for(let i=0;i<3;i++){\n  out[i]+=(2*u3-3*u2+1)*c[j+i]+(u3-2*u2+u)*AIRCRAFT_CORRECTION_SECONDS*c[j+3+i];\n  out[i+3]+=(6*u2-6*u)/AIRCRAFT_CORRECTION_SECONDS*c[j+i]+(3*u2-4*u+1)*c[j+3+i];\n }\n return out;\n}\n","import * as THREE from 'three';\nimport {getLabelSystem} from '../labels/LabelSystem.js';\nimport {CAMERA_FAR} from '../../modules/constants.js';\nimport {sampleAircraftFrame,observationTime,aircraftIdentity} from './AircraftMotion.js';\nimport {satelliteGeodetic} from '../satellites/SatellitePicking.js';\nimport {createSatelliteTaskYield} from '../satellites/SatelliteTaskYield.js';\nconst CAPACITY=30000,TRACK_VERTICES=600,TRACK_SLOTS=5;\nconst vertexShader=`\nattribute vec3 positionLow,nextDelta,velocity,nextVelocity,correction,correctionVelocity;\nattribute float correctionTime,age,available;\nuniform float elapsed,interval,pointSize,hoverIndex;\nvarying float alpha,selected,height;\n#include <common>\n#include <logdepthbuf_pars_vertex>\nvoid main(){\n float t=clamp(elapsed/interval,0.,1.),t2=t*t,t3=t2*t;\n vec3 offset=positionLow+(-2.*t3+3.*t2)*nextDelta+(t3-2.*t2+t)*interval*velocity+(t3-t2)*interval*nextVelocity;\n float u=clamp((elapsed-correctionTime)/1.5,0.,1.),u2=u*u,u3=u2*u;\n offset+=(2.*u3-3.*u2+1.)*correction+(u3-2.*u2+u)*1.5*correctionVelocity;\n vec4 mvPosition=modelViewMatrix*vec4(position,1.)+modelViewMatrix*vec4(offset,0.);\n gl_Position=projectionMatrix*mvPosition;\n selected=abs(float(gl_VertexID)-hoverIndex)<.5?1.:0.;\n alpha=available*(1.-smoothstep(45.,60.,age+elapsed));\n vec3 p=position+offset,axis=normalize(p)/vec3(6378137.,6356752.314245,6378137.);\n height=clamp((length(p)-inversesqrt(dot(axis,axis)))/15000.,0.,1.);\n gl_PointSize=alpha>0.?mix(pointSize,3.,selected):0.;\n #include <logdepthbuf_vertex>\n}`;\nconst fragmentShader=`\nvarying float alpha,selected,height;\n#include <logdepthbuf_pars_fragment>\nvoid main(){float r=length(gl_PointCoord-.5);if(alpha<=0.||r>.5)discard;\n #include <logdepthbuf_fragment>\n vec3 color=mix(mix(vec3(1.,.2,.12),vec3(.2,.58,1.),height),vec3(1.,.8,.3),selected);\n gl_FragColor=vec4(color,alpha*(1.-smoothstep(.35,.5,r)));\n #include <colorspace_fragment>\n}`;\nconst fields={position:3,positionLow:3,nextDelta:3,velocity:3,nextVelocity:3,correction:3,correctionVelocity:3,correctionTime:1,age:1,available:1};\n/** One point batch and worker clock for the entire merged fleet. Only the\n * nearby 200 models, admitted 127 labels and five trajectory slots touch the\n * main scene clock; catalog size does not multiply scene objects or RAFs.\n */\nexport class AircraftCatalogLayer {\n constructor({parentGroup,sceneInitializer,eventBus,onNear,fetchHistory}){\n  this.sceneInitializer=sceneInitializer;this.eventBus=eventBus;this.onNear=onNear;this.fetchHistory=fetchHistory;\n  this.group=new THREE.Group();this.group.name='AircraftCatalog';parentGroup.add(this.group);\n  this.generation=1;this.labels=new Map();this.near=new Map();this.indices=new Map();this.enabled=true;this.showPaths=true;this.labelsEnabled=true;\n  this.geometry=new THREE.BufferGeometry();this.buffers=[{},{}];\n  for(const[name,size]of Object.entries(fields)){for(const slot of this.buffers)slot[name]=new Float32Array(CAPACITY*size);this.geometry.setAttribute(name,new THREE.BufferAttribute(this.buffers[0][name],size).setUsage(THREE.DynamicDrawUsage));}\n  this.geometry.setDrawRange(0,0);this.front=0;\n  this.material=new THREE.ShaderMaterial({vertexShader,fragmentShader,transparent:true,depthWrite:false,toneMapped:false,\n   uniforms:{elapsed:{value:0},interval:{value:16},pointSize:{value:1.75},hoverIndex:{value:-1}}});\n  this.points=new THREE.Points(this.geometry,this.material);this.points.frustumCulled=false;this.points.raycast=()=>{};this.group.add(this.points);\n  this.slots=Array.from({length:TRACK_SLOTS},()=>{\n   const geometry=new THREE.BufferGeometry();geometry.setAttribute('position',new THREE.BufferAttribute(new Float32Array(TRACK_VERTICES*3),3));geometry.setAttribute('color',new THREE.BufferAttribute(new Float32Array(TRACK_VERTICES*3),3));geometry.setDrawRange(0,0);\n   const material=new THREE.LineBasicMaterial({vertexColors:true,transparent:true,opacity:0,depthWrite:false,toneMapped:false});\n   const line=new THREE.LineSegments(geometry,material);line.visible=false;line.frustumCulled=false;line.raycast=()=>{};this.group.add(line);return{line,id:null,opacity:0,target:0};\n  });\n  this.trackCache=new Map();this.historyCache=new Map();this.pendingHistory=new Set();this.sequence=0;this.trackSequence=0;this.payloadSequence=0;\n  this.yieldTask=createSatelliteTaskYield();this.worker=new Worker(new URL('./aircraft-catalog.worker.js',import.meta.url),{type:'module'});\n  this.worker.onmessage=event=>void this._receive(event.data);this.worker.onerror=()=>{this.admission?.reject(Error('Aircraft worker failed'));this.admission=null;};this.worker.postMessage({type:'reset',generation:this.generation});\n  this.canvas=sceneInitializer?.renderer?.domElement;\n  this.leave=()=>{this.pointer=null;this.nearby=[];if(!this.pinnedId)this._setHovered(null);};this.canvas?.addEventListener('pointerleave',this.leave);\n  this.presentation=()=>{const active=globalThis.window?.__noclipMapMode!=='2d'&&!globalThis.document?.hidden;this.worker?.postMessage({type:'active',generation:this.generation,active});if(!active){this.pointer=null;this.nearby=[];if(!this.pinnedId)this._setHovered(null);}};\n  globalThis.window?.addEventListener('noclip:map-mode-change',this.presentation);globalThis.document?.addEventListener('visibilitychange',this.presentation);\n  this.labelHover=event=>{if(this.settingHover)return;const id=event.detail?.metadata?.aircraftCatalogId;if(this.pinnedId)return;if(id&&this.labels.has(id)){this._setHovered(this.labels.get(id));this.fromLabel=true;}else if(this.fromLabel){this.fromLabel=false;this._setHovered(null);}};\n  globalThis.document?.addEventListener('noclip:scene-label-hover',this.labelHover);\n }\n submit(buffer){\n  if(this.admission)return this.admission.promise;\n  const token=++this.payloadSequence;let resolve,reject;const promise=new Promise((a,b)=>{resolve=a;reject=b;});this.admission={token,promise,resolve,reject};\n  this.worker.postMessage({type:'payload',generation:this.generation,token,buffer},[buffer]);return promise;\n }\n async _receive(message){\n  if(message.generation!==this.generation)return;\n  if(message.type==='admitted'){this.summary=message.summary;const current=this.admission;this.admission=null;current?.resolve(message.summary);this.eventBus?.emit('flights:status',message.summary);return;}\n  if(message.type==='error'){this.admission?.reject(Error(message.error));this.admission=null;return;}\n  if(message.type==='frame'){\n   const slot=this.buffers[1-this.front],count=message.count,data=message.data,c=message.corrections;\n   for(let i=0;i<count;i++){\n    if(i&&i%512===0){await this.yieldTask();if(message.generation!==this.generation)return;}\n    const k=i*12,j=i*3,q=i*7;\n    for(let a=0;a<3;a++){const high=Math.fround(data[k+a]);slot.position[j+a]=high;slot.positionLow[j+a]=data[k+a]-high;slot.nextDelta[j+a]=data[k+6+a]-data[k+a];slot.velocity[j+a]=data[k+3+a];slot.nextVelocity[j+a]=data[k+9+a];slot.correction[j+a]=c[q+a];slot.correctionVelocity[j+a]=c[q+3+a];}\n    slot.correctionTime[i]=c[q+6];slot.age[i]=message.ages[i];slot.available[i]=message.valid[i];\n   }\n   if(message.generation!==this.generation)return;\n   // Commit an entirely prepared back buffer between frames. The displayed\n   // batch never contains a half-admitted catalog with mismatched indices.\n   for(const[name,size]of Object.entries(fields)){const a=this.geometry.attributes[name];a.array=slot[name];a.clearUpdateRanges();a.addUpdateRange(0,count*size);a.needsUpdate=true;}\n   this.front=1-this.front;this.frame=message;this.geometry.setDrawRange(0,count);this.material.uniforms.interval.value=message.interval;\n   this.indices=new Map(message.bindings||[]);this.maskedModels=[];for(const id of this.modelIds||[]){const index=this.indices.get(id);if(index!=null){slot.available[index]=0;this.maskedModels.push(index);}}\n   this.material.uniforms.hoverIndex.value=this.indices.get(this.hovered?.id)??-1;\n   this.worker.postMessage({type:'ack',generation:this.generation});this.nextView=0;this._sendPick();return;\n  }\n  if(message.type==='view'){\n   if(message.frameAt!==this.frame?.at)return;\n   this.indices=new Map(message.near.map(row=>[row.id,row.index]));this.near=new Map(message.near.map(row=>[row.id,row]));const modelIds=this.modelIds=this.onNear?.(message.near)||new Set();\n   const available=this.geometry.attributes.available;for(const i of this.maskedModels||[])if(i<this.frame.count)available.array[i]=this.frame.valid[i];\n   this.maskedModels=[];for(const row of message.near)if(modelIds.has(row.id)){available.array[row.index]=0;this.maskedModels.push(row.index);}\n   if(this.maskedModels.length||this.hadMaskedModels){available.needsUpdate=true;}this.hadMaskedModels=this.maskedModels.length>0;\n   const keep=new Set();for(const row of message.labels){if(row){keep.add(row.id);this._ensureLabel(row);}}\n   if(this.hovered)keep.add(this.hovered.id);if(this.pinnedId)keep.add(this.pinnedId);\n   for(const[id,entry]of this.labels)if(!keep.has(id)){entry.labelHandle?.dispose();entry.labelHandle?.group?.removeFromParent();this.labels.delete(id);}\n   if(this.pinnedId){const entry=this.labels.get(this.pinnedId);if(entry){this.hovered=entry;this.material.uniforms.hoverIndex.value=message.selectedIndex;}}\n   return;\n  }\n  if(message.type==='pick'){\n   if(message.requestId!==this.sequence||message.frameAt!==this.frame?.at)return;\n   this.nearby=message.nearby||[];if(!this.pinnedId)this._setHovered(message.entry);\n   if(this.click){const pending=this.click;this.click=null;clearTimeout(pending.timer);if(message.entry){this.pin(message.entry.id);pending.resolve(true);}else{this.clearSelection();pending.resolve(false);}}\n   return;\n  }\n  if(message.type==='trajectory'){\n   const wanted=this.slots.some(slot=>slot.id===message.id);if(!wanted)return;\n   this.trackCache.delete(message.id);this.trackCache.set(message.id,message);while(this.trackCache.size>8)this.trackCache.delete(this.trackCache.keys().next().value);\n   for(const slot of this.slots)if(slot.id===message.id)this._applyTrack(slot,message);return;\n  }\n }\n _ensureLabel(row){\n  if(!row)return null;\n  let entry=this.labels.get(row.id);if(!entry){entry={...row,position:new THREE.Vector3()};this.labels.set(row.id,entry);}else Object.assign(entry,row);\n  this.indices.set(row.id,row.index);if(this.position(row.id,entry.position))entry.geo=satelliteGeodetic(entry.position,entry.geo||{});\n  if(!this.labelSystem){try{this.labelSystem=getLabelSystem();}catch{return entry;}}\n  if(this.labelsEnabled&&!entry.labelHandle){\n   entry.labelHandle=this.labelSystem.createLabel(row.callsign||row.registration||row.id,{position:entry.position,type:'aircraft',objectRadius:20,maxDistance:CAMERA_FAR,\n    metadata:this._metadata(entry),onSelect:()=>this.pin(row.id),onDeselect:()=>{if(this.pinnedId===row.id)this.clearSelection();}});\n   if(entry.labelHandle?.group)this.group.add(entry.labelHandle.group);\n  }\n  return entry;\n }\n _metadata(entry){\n  const geo=entry.geo||{};return{entityType:'aircraft',aircraftCatalogId:entry.id,id:entry.id,rawId:entry.recordId||entry.id.replace(/^icao:/,''),\n   callsign:entry.callsign,name:entry.callsign||entry.registration||entry.id,registration:entry.registration,aircraftType:entry.aircraftType,\n   lat:geo.lat??entry.lat,lon:geo.lon??entry.lon,altitudeM:Number.isFinite(entry.altitudeM)?(geo.altitudeM??entry.altitudeM):null,\n   velocityMps:entry.velocityMps,headingDeg:entry.headingDeg,verticalRateMps:entry.verticalRateMps,onGround:entry.onGround,\n   source:entry.source,sources:(entry.sources||[]).map(s=>s.source).join(', '),positionTime:entry.positionTime||entry.lastContact,\n   altitudeReference:entry.altitudeReference||'unknown',positionSource:entry.positionSource||'unknown',\n   calculatedAt:new Date().toISOString(),positionModel:'Ground-track estimate from latest observation',\n   trajectory:this.showPaths?'Observed history · dashed velocity prediction up to 60 s':'Hidden',trackable:true,listKey:'viewshed.aircraft'};\n }\n _setHovered(row){\n  if(this.pinnedId&&!row)return;\n  this.hovered=row?this._ensureLabel(row):null;this.material.uniforms.hoverIndex.value=row?.index??-1;\n  this.settingHover=true;try{this.labelSystem?.setExternalHoveredLabel?.(this.hovered?.labelHandle||null);}finally{this.settingHover=false;}\n  this.worker?.postMessage({type:'focus',generation:this.generation,id:row?.id||null});\n }\n pin(id){\n  const entry=this.labels.get(id)||this._ensureLabel(this.near.get(id)||this.hovered);\n  if(!entry)return;this.pinnedId=id;this.hovered=entry;this.worker.postMessage({type:'select',generation:this.generation,id});\n  if(entry.labelHandle)this.labelSystem?.setExternalSelectedLabel?.(entry.labelHandle);\n }\n clearSelection(){\n  const handle=this.hovered?.labelHandle;this.pinnedId=null;this.hovered=null;this.material.uniforms.hoverIndex.value=-1;this.worker?.postMessage({type:'select',generation:this.generation,id:null});\n  if(handle&&this.labelSystem?._externalSelectedLabel===handle)this.labelSystem.setExternalSelectedLabel(null);\n }\n selectAtClient(x,y){\n  if(!this.frame||!this.enabled)return null;this.pointer={x,y};this.rect=this.canvas.getBoundingClientRect();\n  if(this.click){clearTimeout(this.click.timer);this.click.resolve(false);}\n  return new Promise(resolve=>{const timer=setTimeout(()=>{if(this.click?.resolve===resolve){this.click=null;resolve(false);}},1000);this.click={resolve,timer};this._sendPick();});\n }\n updateHover(_ray,camera,{pointer,rect}={}){if(!pointer||!rect)return;this.pointer=pointer;this.rect=rect;this.nextPick=0;this._sendPick(camera);}\n _view(camera=this.sceneInitializer?.camera){\n  if(!camera)return null;this.group.updateWorldMatrix(true,false);camera.updateMatrixWorld();\n  this.viewMatrix||=new THREE.Matrix4();this.localCamera||=new THREE.Vector3();\n  this.viewMatrix.multiplyMatrices(camera.projectionMatrix,camera.matrixWorldInverse).multiply(this.group.matrixWorld);\n  this.localCamera.copy(camera.getWorldPosition(this.localCamera));this.group.worldToLocal(this.localCamera);\n  return{matrix:this.viewMatrix.toArray(),camera:this.localCamera.toArray()};\n }\n _sendPick(camera){\n  if(!this.pointer||!this.rect?.width||!this.frame||Date.now()<(this.nextPick||0))return;\n  const view=this._view(camera);if(!view)return;this.nextPick=Date.now()+100;\n  this.worker.postMessage({type:'pick',generation:this.generation,requestId:++this.sequence,frameAt:this.frame.at,at:Date.now(),...view,\n   pointer:[(this.pointer.x-this.rect.left)/this.rect.width*2-1,1-(this.pointer.y-this.rect.top)/this.rect.height*2],viewport:[this.rect.width,this.rect.height]});\n }\n position(id,target=new THREE.Vector3()){\n  const index=this.indices.get(id),frame=this.frame;if(index==null||!frame||!frame.valid[index]||frame.ages[index]+(Date.now()-frame.at)/1000>60)return null;\n  this.sample||=new Float64Array(6);sampleAircraftFrame(frame,index,Date.now(),this.sample);return target.fromArray(this.sample);\n }\n update(){\n  if(!this.enabled||!this.frame)return;\n  const now=Date.now(),elapsed=(now-this.frame.at)/1000;this.material.uniforms.elapsed.value=Math.max(0,Math.min(this.frame.interval,elapsed));this.points.visible=elapsed<=this.frame.interval;\n  if(now>=(this.nextView||0)){this.nextView=now+250;const view=this._view();if(view)this.worker.postMessage({type:'view',generation:this.generation,...view});}\n  this._sendPick();\n  for(const entry of this.labels.values()){\n   if(!entry.labelHandle)continue;const p=this.position(entry.id,entry.position);entry.labelHandle.sourceVisible=!!p&&this.points.visible&&this.labelsEnabled;\n   if(!p)continue;this.labelSystem.updatePosition(entry.labelHandle,p);\n   if(now>=(this.nextMetadata||0)){entry.geo=satelliteGeodetic(p,entry.geo||{});entry.predictedLat=entry.geo.lat;entry.predictedLon=entry.geo.lon;entry.predictedAlt=entry.geo.altitudeM;entry.rawId=entry.recordId||entry.id.replace(/^icao:/,'');this.labelSystem.updateMetadata?.(entry.labelHandle,this._metadata(entry));this.labelSystem.updateText?.(entry.labelHandle,entry.callsign||entry.registration||entry.id,`${entry.onGround?'Ground':Number.isFinite(entry.altitudeM)?Math.round(entry.geo.altitudeM*3.28084)+' ft':'Altitude unavailable'} · ${Math.round((entry.velocityMps||0)*1.94384)} kt`);}\n   entry.labelHandle.labelPriority=this.hovered?.id===entry.id?1000:0;\n  }\n  if(now>=(this.nextMetadata||0))this.nextMetadata=now+250;\n  this._updateTrajectories(now);\n }\n _updateTrajectories(now){\n  const wanted=this.showPaths?[...(this.hovered?[{...this.hovered,distance:0}]:[]),...(this.nearby||[])].filter((e,i,a)=>a.findIndex(v=>v.id===e.id)===i).slice(0,5):[];\n  for(const slot of this.slots){slot.target=0;if(slot.id&&wanted.some(e=>e.id===slot.id)){const e=wanted.find(e=>e.id===slot.id);slot.target=this.hovered?.id===slot.id?1:Math.max(0,1-e.distance/96);}}\n  for(const entry of wanted){let slot=this.slots.find(s=>s.id===entry.id);if(!slot){slot=this.slots.find(s=>!wanted.some(e=>e.id===s.id));if(!slot)continue;slot.id=entry.id;slot.opacity=0;slot.nextUpdate=0;slot.line.geometry.setDrawRange(0,0);slot.target=this.hovered?.id===entry.id?1:Math.max(0,1-entry.distance/96);const cached=this.trackCache.get(entry.id);if(cached)this._applyTrack(slot,cached);}\n   if(now>=(slot.nextUpdate||0)){slot.nextUpdate=now+2000;this.worker.postMessage({type:'trajectory',generation:this.generation,id:entry.id,requestId:++this.trackSequence});this._requestHistory(entry);}\n  }\n  const dt=Math.min(.1,Math.max(0,(now-(this.lastTrajectoryAt||now))/1000));this.lastTrajectoryAt=now;\n  for(const slot of this.slots){slot.opacity+=(slot.target-slot.opacity)*(1-Math.exp(-dt*10));slot.line.material.opacity=slot.opacity*.9;slot.line.visible=this.showPaths&&slot.opacity>.005&&slot.line.geometry.drawRange.count>0;}\n }\n _applyTrack(slot,track){\n  const g=slot.line.geometry,count=Math.min(TRACK_VERTICES,track.data.length/3);g.attributes.position.array.fill(0);g.attributes.position.array.set(track.data.subarray(0,count*3));\n  for(let i=0;i<count;i++){const k=i*3,r=Math.hypot(track.data[k],track.data[k+1],track.data[k+2]),ellipsoid=1/Math.hypot(track.data[k]/r/6378137,track.data[k+1]/r/6356752.314245,track.data[k+2]/r/6378137),h=THREE.MathUtils.clamp((r-ellipsoid)/15000,0,1);const color=new THREE.Color().setRGB(1-.8*h,.2+.38*h,.12+.88*h);if(track.kind[i])color.multiplyScalar(.7);g.attributes.color.setXYZ(i,color.r,color.g,color.b);}\n  g.attributes.position.needsUpdate=true;g.attributes.color.needsUpdate=true;g.setDrawRange(0,count);\n }\n async _requestHistory(entry){\n  if(!this.fetchHistory||this.pendingHistory.size||Date.now()<(this.historyCache.get(entry.id)||0))return;\n  this.pendingHistory.add(entry.id);this.historyCache.delete(entry.id);this.historyCache.set(entry.id,Date.now()+30_000);while(this.historyCache.size>8)this.historyCache.delete(this.historyCache.keys().next().value);\n  const generation=this.generation,controller=this.historyController=new AbortController();\n  try{const points=await this.fetchHistory(entry,{signal:controller.signal});if(generation===this.generation&&this.worker&&points?.length)this.worker.postMessage({type:'history',generation,id:entry.id,points});}catch{}finally{this.pendingHistory.delete(entry.id);}\n }\n getEntriesSnapshot(){return[...new Map([...this.near.values(),...this.labels.values()].map(e=>[e.id,e])).values()].map(e=>{const p=this.position(e.id);const geo=p?satelliteGeodetic(p):{};return{...e,...geo,altitudeM:Number.isFinite(e.altitudeM)?geo.altitudeM??e.altitudeM:null,rawId:e.recordId||e.id.replace(/^icao:/,''),labelHandle:undefined,position:undefined};});}\n clear(){\n  this.historyController?.abort();this.generation++;this.worker?.postMessage({type:'reset',generation:this.generation});this.admission?.reject(Error('Aircraft scope replaced'));this.admission=null;\n  for(const entry of this.labels.values()){entry.labelHandle?.dispose();entry.labelHandle?.group?.removeFromParent();}this.labels.clear();this.near.clear();this.indices.clear();this.frame=null;this.geometry.setDrawRange(0,0);this.material.uniforms.hoverIndex.value=-1;this.hovered=null;this.pinnedId=null;this.nearby=[];this.trackCache.clear();this.historyCache.clear();this.maskedModels=[];this.modelIds=new Set();this.hadMaskedModels=false;\n  for(const slot of this.slots){slot.id=null;slot.opacity=0;slot.line.visible=false;slot.line.geometry.setDrawRange(0,0);}if(this.click){clearTimeout(this.click.timer);this.click.resolve(false);this.click=null;}\n }\n dispose(){this.clear();this.worker?.terminate();this.worker=null;this.yieldTask.dispose();this.canvas?.removeEventListener('pointerleave',this.leave);globalThis.window?.removeEventListener('noclip:map-mode-change',this.presentation);globalThis.document?.removeEventListener('visibilitychange',this.presentation);globalThis.document?.removeEventListener('noclip:scene-label-hover',this.labelHover);this.geometry.dispose();this.material.dispose();for(const slot of this.slots){slot.line.geometry.dispose();slot.line.material.dispose();}this.group.removeFromParent();}\n}\nexport {vertexShader as AIRCRAFT_CATALOG_VERTEX_SHADER,fragmentShader as AIRCRAFT_CATALOG_FRAGMENT_SHADER};\n","/**\n * FlightApiService\n *\n * Browser client for the canonical NOCLIP flight relay. Upstream ADS-B\n * providers, normalization, throttling, caching, and replay are backend-owned;\n * this module must never fall back to contacting providers from each browser.\n */\n\nimport { getAuthService } from '../auth/AuthService.js';\nimport { getBackendApiBase } from '../shared/backend.js';\n\nconst API_BASE = getBackendApiBase();\n\nasync function readJson(response, fallbackMessage) {\n  const data = await response.json().catch(() => ({}));\n  if (!response.ok) throw new Error(data.error || fallbackMessage);\n  return data;\n}\n\nexport class FlightApiService {\n  constructor() {\n    this.authService = getAuthService();\n  }\n\n  async listProviders() {\n    const response = await this.authService.authenticatedFetch(`${API_BASE}/flights/providers`);\n    const data = await readJson(response, 'Failed to load flight providers');\n    return data.providers || [];\n  }\n\n  async getFlights(params = {}, {signal} = {}) {\n    const search = new URLSearchParams();\n    Object.entries(params).forEach(([key, value]) => {\n      if (value === undefined || value === null || value === '') return;\n      search.set(key, String(value));\n    });\n    const suffix = search.size ? `?${search.toString()}` : '';\n    const response = await this.authService.authenticatedFetch(`${API_BASE}/flights/near${suffix}`, {\n      governanceLane: 'scene', signal,\n    });\n    return readJson(response, 'Failed to fetch flights');\n  }\n  async getFlightPayload(params = {}, {signal} = {}) {\n    const search=new URLSearchParams();for(const[key,value]of Object.entries(params))if(value!==undefined&&value!==null&&value!=='')search.set(key,String(value));\n    const response=await this.authService.authenticatedFetch(`${API_BASE}/flights/near?${search}`,{governanceLane:'scene',signal});\n    if(!response.ok)throw new Error(`Aircraft relay ${response.status}`);\n    const max=32*1024*1024,reader=response.body?.getReader();if(!reader)throw new Error('Aircraft response unavailable');\n    if(Number(response.headers.get('content-length')||0)>max){await reader.cancel();throw new Error('Aircraft response exceeds 32 MiB');}\n    const chunks=[];let size=0;\n    try{for(;;){const value=await reader.read();if(value.done)break;size+=value.value.byteLength;if(size>max)throw new Error('Aircraft response exceeds 32 MiB');chunks.push(value.value);}}\n    finally{if(size>max||signal?.aborted)await reader.cancel().catch(()=>{});reader.releaseLock();}\n    const bytes=new Uint8Array(size);let offset=0;for(const chunk of chunks){bytes.set(chunk,offset);offset+=chunk.byteLength;}\n    return bytes.buffer;\n  }\n\n}\n\nlet flightApiServiceInstance = null;\n\nexport function getFlightApiService() {\n  if (!flightApiServiceInstance) flightApiServiceInstance = new FlightApiService();\n  return flightApiServiceInstance;\n}\n","/**\n * AircraftOverlay\n *\n * Fetches flight states from backend and renders aircraft models overhead.\n * Uses high-precision direction * radius positioning to avoid jitter.\n */\n\nimport * as THREE from 'three';\nimport { prepareModelForFirstDraw } from '../render/ModelFirstDrawPrep.js';\nimport { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';\nimport * as SkeletonUtils from 'three/addons/utils/SkeletonUtils.js';\nimport { latLonToLocalDir, geodesicDestinationWGS84, ellipsoidRadiusForLocalDir, updateTrailAttributes } from '../../modules/geometry-utils.js';\nimport { PLANET_RADIUS } from '../../modules/constants.js';\nimport { AircraftCatalogLayer } from '../flights/AircraftCatalogLayer.js';\nimport { aircraftIdentity, aircraftStateAt } from '../flights/AircraftMotion.js';\nimport { satelliteGeodetic } from '../satellites/SatellitePicking.js';\nimport { getFlightApiService } from '../flights/FlightApiService.js';\nimport {\n  TOKENS,\n  resolveColor\n} from '../ui/DesignSystem.js';\nimport { getLabelSystem } from '../labels/LabelSystem.js';\n\nconst DEFAULT_MODEL_URL = './refactor/data/models/a330-300.glb';\nconst DEFAULT_POLL_INTERVAL_MS = 2000;\nconst DEFAULT_STALE_MS = 30000;  // 30s — remove aircraft with no data for 30s\nconst DEFAULT_PREDICT_MS = 60000; // Cover the default source-freshness window without a visible stop.\nconst MAX_FUTURE_OBSERVATION_MS = 5 * 60 * 1000;\nconst DEFAULT_MODEL_SCALE = 0.125;\nconst DEFAULT_HEADING_OFFSET_DEG = 180;\nconst DEFAULT_TERRAIN_CLAMP_MAX_M = 2000;\nconst DEFAULT_TERRAIN_SAMPLE_INTERVAL_MS = 1500;\nconst DEFAULT_TERRAIN_CLEARANCE_M = 0;\nconst DEFAULT_SMOOTH_MS = 1500;\nconst DEFAULT_ACCEL_MPS2 = 2.5;\nconst DEFAULT_VERTICAL_ACCEL_MPS2 = 1.5;\nconst DEFAULT_HEADING_ACCEL_DEG = 90;\nconst DEFAULT_ACCEL_ESTIMATE_MAX_MPS2 = 6;\nconst DEFAULT_VERTICAL_ACCEL_ESTIMATE_MAX_MPS2 = 4;\nconst ACCEL_ESTIMATE_BLEND = 0.35;\nconst DEFAULT_LOW_LOD_DISTANCE_M = 60000;\nconst DEFAULT_LOW_LOD_HYSTERESIS_M = 5000;\nconst DEFAULT_LOW_LOD_SCALE_MULTIPLIER = 0.3;\n// NOTE: do NOT read TOKENS at module-init time — TOKENS is imported from\n// refactor/ui/DesignSystem.js which after the Phase-6 chunk split lives in\n// the ui-panels chunk while this file lives in the overlays chunk. Rollup\n// generates cross-chunk imports for TOKENS, and there is a latent cycle\n// (ui-panels -> overlays) that can leave the TOKENS binding in the TDZ\n// when overlays' top-level body runs. Reading through a getter defers\n// access until first call-site use, by which point both chunks are live.\nconst getDefaultLowLodColor = () => TOKENS.colors.text;\nconst getPathColor = () => TOKENS.colors.accentActive;\nconst METERS_PER_NM = 1852;\nconst DEFAULT_CULL_HYSTERESIS_M = 10000;\nconst DEFAULT_SHOW_PATHS = false;\nconst DEFAULT_PATH_HOURS = 24;\nconst DEFAULT_PATH_MAX_POINTS = 120;\nconst PATH_DASH_SIZE = 20;\nconst PATH_GAP_SIZE = 10;\nconst PATH_DASH_TAPER_POWER = 2.2;\nconst PATH_DASH_TAPER_MIN_SCALE = 0.12;\nconst PATH_GAP_TAPER_MAX_SCALE = 4;\nconst PATH_SAMPLE_INTERVAL_MS = 1000;\nconst PATH_SUBDIVISIONS_PER_SEGMENT = 4;\nconst PATH_ALT_MIN_M = 0;\nconst PATH_ALT_MAX_M = 12000;\nconst PATH_ALT_RANGE_M = PATH_ALT_MAX_M - PATH_ALT_MIN_M;\nconst PATH_ALPHA_POWER = 1.4;\nconst PATH_COLOR_LOW = new THREE.Color(0xff4dbf);\nconst PATH_COLOR_HIGH = new THREE.Color(0x1fd4c9);\nconst PATH_MAX_GAP_MS = 15 * 60 * 1000;\nconst PATH_MAX_GROUND_SPEED_MPS = 450;\nconst PATH_DISTANCE_BUFFER_M = 10_000;\nconst PATH_MAX_VERTICAL_RATE_MPS = 100;\nconst PATH_ALTITUDE_BUFFER_M = 1_500;\nconst TERRAIN_CACHE_DISTANCE_M = 250;\n\n// A tiny, shared aircraft silhouette keeps a flight visible while the default\n// GLB and its texture are decoding. It is replaced by the model bucket as soon\n// as that bucket is ready.\nconst FALLBACK_AIRCRAFT_GEOMETRY = new THREE.BufferGeometry();\nFALLBACK_AIRCRAFT_GEOMETRY.setAttribute('position', new THREE.Float32BufferAttribute([\n  0, 0.25, 2.4,    -0.42, 0, 1.1,    0.42, 0, 1.1,\n  -2.2, 0, 0.1,    2.2, 0, 0.1,      -0.48, 0, -1.9,\n  0.48, 0, -1.9,   -0.28, 0.6, -1.45, 0.28, 0.6, -1.45,\n], 3));\nFALLBACK_AIRCRAFT_GEOMETRY.setIndex([\n  0, 1, 2,\n  1, 3, 5, 1, 5, 6,\n  2, 6, 4, 2, 5, 6,\n  5, 7, 8, 5, 8, 6,\n]);\nFALLBACK_AIRCRAFT_GEOMETRY.computeVertexNormals();\nconst FALLBACK_AIRCRAFT_MATERIAL = new THREE.MeshStandardMaterial({\n  color: 0xe6edf5,\n  metalness: 0.35,\n  roughness: 0.6,\n  side: THREE.DoubleSide,\n});\n\nconst toNumber = (value) => (Number.isFinite(value) ? value : null);\nconst clamp01 = (value) => Math.min(1, Math.max(0, value));\n\n/**\n * Build a smooth, surface-conforming aircraft trail without interpolating\n * through the Earth. Catmull-Rom operates on unit WGS84 directions, then each\n * sample is normalized before its ellipsoid radius is restored by the caller.\n * This also crosses the antimeridian cleanly because longitude is never\n * interpolated as a wrapped scalar.\n *\n * Each output sample is [direction.x, direction.y, direction.z, altitudeM].\n */\nexport function buildSmoothedAircraftPathSamples(\n  pathHistory,\n  subdivisionsPerSegment = PATH_SUBDIVISIONS_PER_SEGMENT\n) {\n  if (!Array.isArray(pathHistory)) return new Float64Array();\n  const points = pathHistory.filter(point => (\n    Number.isFinite(point?.lat) && Number.isFinite(point?.lon)\n  ));\n  if (points.length < 2) return new Float64Array();\n\n  const subdivisions = Math.max(1, Math.min(8, Math.round(subdivisionsPerSegment) || 1));\n  const directions = points.map(point => latLonToLocalDir(point.lat, point.lon));\n  const curve = new THREE.CatmullRomCurve3(directions, false, 'centripetal', 0.5);\n  const segmentCount = points.length - 1;\n  const sampleCount = segmentCount * subdivisions + 1;\n  const samples = new Float64Array(sampleCount * 4);\n  const direction = new THREE.Vector3();\n\n  for (let sampleIndex = 0; sampleIndex < sampleCount; sampleIndex += 1) {\n    const isLast = sampleIndex === sampleCount - 1;\n    const segmentIndex = isLast\n      ? segmentCount - 1\n      : Math.floor(sampleIndex / subdivisions);\n    const segmentT = isLast ? 1 : (sampleIndex % subdivisions) / subdivisions;\n    const curveT = (segmentIndex + segmentT) / segmentCount;\n    curve.getPoint(curveT, direction).normalize();\n\n    const p0 = Number.isFinite(points[Math.max(0, segmentIndex - 1)]?.altM)\n      ? points[Math.max(0, segmentIndex - 1)].altM\n      : 0;\n    const p1 = Number.isFinite(points[segmentIndex]?.altM)\n      ? points[segmentIndex].altM\n      : 0;\n    const p2 = Number.isFinite(points[Math.min(points.length - 1, segmentIndex + 1)]?.altM)\n      ? points[Math.min(points.length - 1, segmentIndex + 1)].altM\n      : 0;\n    const p3 = Number.isFinite(points[Math.min(points.length - 1, segmentIndex + 2)]?.altM)\n      ? points[Math.min(points.length - 1, segmentIndex + 2)].altM\n      : 0;\n    const t2 = segmentT * segmentT;\n    const t3 = t2 * segmentT;\n    const interpolatedAltitude = 0.5 * (\n      (2 * p1)\n      + (-p0 + p2) * segmentT\n      + (2 * p0 - 5 * p1 + 4 * p2 - p3) * t2\n      + (-p0 + 3 * p1 - 3 * p2 + p3) * t3\n    );\n    const altitude = THREE.MathUtils.clamp(\n      interpolatedAltitude,\n      Math.min(p0, p1, p2, p3),\n      Math.max(p0, p1, p2, p3)\n    );\n\n    const offset = sampleIndex * 4;\n    samples[offset] = direction.x;\n    samples[offset + 1] = direction.y;\n    samples[offset + 2] = direction.z;\n    samples[offset + 3] = altitude;\n  }\n\n  return samples;\n}\n\nconst normalizeAircraftType = (value) => {\n  if (typeof value !== 'string') return null;\n  const trimmed = value.trim();\n  return trimmed ? trimmed.toUpperCase() : null;\n};\n\nconst degToRad = (deg) => (deg * Math.PI) / 180;\nconst radToDeg = (rad) => (rad * 180) / Math.PI;\nconst wrapAngleDeg = (deg) => {\n  const wrapped = ((deg + 180) % 360 + 360) % 360 - 180;\n  return wrapped;\n};\nconst clampAbs = (value, maxAbs) => {\n  if (!Number.isFinite(value)) return 0;\n  const limit = Number.isFinite(maxAbs) ? Math.abs(maxAbs) : 0;\n  if (!limit) return 0;\n  return Math.max(-limit, Math.min(limit, value));\n};\nconst blendValue = (current, next, alpha) => {\n  if (!Number.isFinite(next)) return current;\n  if (!Number.isFinite(current)) return next;\n  return current + (next - current) * alpha;\n};\nconst approach = (current, target, maxDelta) => {\n  if (!Number.isFinite(current)) return target;\n  const delta = target - current;\n  if (Math.abs(delta) <= maxDelta) return target;\n  return current + Math.sign(delta) * maxDelta;\n};\nconst approachAngleDeg = (current, target, maxDelta) => {\n  if (!Number.isFinite(current)) return target;\n  const delta = wrapAngleDeg(target - current);\n  if (Math.abs(delta) <= maxDelta) return target;\n  return current + Math.sign(delta) * maxDelta;\n};\nexport const parseTimeMs = (value, fallback) => {\n  if (value === null || value === undefined) return fallback;\n  if (typeof value === 'string' && value.trim() !== '') {\n    const numericValue = Number(value);\n    if (Number.isFinite(numericValue)) return parseTimeMs(numericValue, fallback);\n  }\n  if (typeof value === 'number' && Number.isFinite(value)) {\n    // Flight feeds commonly encode Unix seconds while browser timestamps use\n    // milliseconds. Treat values before 1973 as seconds; it also keeps an\n    // explicit epoch timestamp at 0 valid.\n    return Math.abs(value) > 0 && Math.abs(value) < 1e11 ? value * 1000 : value;\n  }\n  if (value instanceof Date) {\n    const ts = value.getTime();\n    return Number.isFinite(ts) ? ts : fallback;\n  }\n  const parsed = Date.parse(value);\n  return Number.isFinite(parsed) ? parsed : fallback;\n};\n\nconst pathDistanceMeters = (a, b) => {\n  const aDir = latLonToLocalDir(a.lat, a.lon);\n  const bDir = latLonToLocalDir(b.lat, b.lon);\n  const angle = Math.acos(THREE.MathUtils.clamp(aDir.dot(bDir), -1, 1));\n  return angle * PLANET_RADIUS;\n};\n\n/**\n * Normalize provider history into the latest continuous flight segment.\n *\n * Backends can return a full day for one ICAO address, including separate\n * flights, sparse coverage, and records without altitude. Connecting those\n * records into one spline creates globe-spanning and sea-level spikes. Missing\n * altitudes inherit the nearest known flight altitude (or the live fallback),\n * while implausible time/distance/vertical jumps begin a new segment.\n */\nexport function normalizeAircraftPathHistory(points, fallbackAltitudeM = null) {\n  if (!Array.isArray(points)) return [];\n\n  const normalized = points\n    .filter(point => Number.isFinite(point?.lat) && Number.isFinite(point?.lon))\n    .map(point => ({\n      lat: point.lat,\n      lon: point.lon,\n      altM: Number.isFinite(point.altM)\n        ? point.altM\n        : (Number.isFinite(point.altitudeM) ? point.altitudeM : null),\n      timeMs: parseTimeMs(point.timeMs ?? point.timestamp, null),\n    }))\n    .filter(point => Number.isFinite(point.timeMs))\n    .sort((a, b) => a.timeMs - b.timeMs);\n\n  if (!normalized.length) return [];\n\n  // Keep one observation per timestamp so a repeated cached packet cannot\n  // produce a zero-duration discontinuity.\n  const deduplicated = [];\n  for (const point of normalized) {\n    if (deduplicated.at(-1)?.timeMs === point.timeMs) {\n      deduplicated[deduplicated.length - 1] = point;\n    } else {\n      deduplicated.push(point);\n    }\n  }\n\n  let carriedAltitude = null;\n  for (const point of deduplicated) {\n    if (Number.isFinite(point.altM)) carriedAltitude = point.altM;\n    else if (Number.isFinite(carriedAltitude)) point.altM = carriedAltitude;\n  }\n  carriedAltitude = Number.isFinite(fallbackAltitudeM) ? fallbackAltitudeM : null;\n  for (let index = deduplicated.length - 1; index >= 0; index -= 1) {\n    const point = deduplicated[index];\n    if (Number.isFinite(point.altM)) carriedAltitude = point.altM;\n    else if (Number.isFinite(carriedAltitude)) point.altM = carriedAltitude;\n  }\n  for (const point of deduplicated) {\n    if (!Number.isFinite(point.altM)) point.altM = 0;\n  }\n\n  let latestSegment = [];\n  for (const point of deduplicated) {\n    const previous = latestSegment.at(-1);\n    if (previous) {\n      const deltaMs = point.timeMs - previous.timeMs;\n      const deltaSec = deltaMs / 1000;\n      const maxDistance = PATH_DISTANCE_BUFFER_M + PATH_MAX_GROUND_SPEED_MPS * deltaSec;\n      const maxAltitudeDelta = PATH_ALTITUDE_BUFFER_M + PATH_MAX_VERTICAL_RATE_MPS * deltaSec;\n      const discontinuous = deltaMs <= 0\n        || deltaMs > PATH_MAX_GAP_MS\n        || pathDistanceMeters(previous, point) > maxDistance\n        || Math.abs(point.altM - previous.altM) > maxAltitudeDelta;\n      if (discontinuous) latestSegment = [];\n    }\n    latestSegment.push(point);\n  }\n\n  return latestSegment;\n}\n\nexport const resolvePredictionWindowMs = ({\n  predictionMaxMs,\n  pollIntervalMs,\n  staleAfterMs,\n} = {}) => {\n  const requestedMs = Number.isFinite(predictionMaxMs)\n    ? Math.max(0, predictionMaxMs)\n    : DEFAULT_PREDICT_MS;\n  // Zero remains an intentional \"do not extrapolate\" setting. Otherwise an\n  // airborne track needs to span its entire accepted freshness window. A\n  // provider cache can repeat the same measured packet for several polls;\n  // stopping at two polls made healthy aircraft visibly freeze while their\n  // speed, track, and vertical-rate data were still valid.\n  if (requestedMs === 0) return 0;\n  const pollMs = Number.isFinite(pollIntervalMs)\n    ? Math.max(0, pollIntervalMs)\n    : DEFAULT_POLL_INTERVAL_MS;\n  const staleMs = Number.isFinite(staleAfterMs)\n    ? Math.max(0, staleAfterMs)\n    : DEFAULT_STALE_MS;\n  const continuityMs = pollMs > 0 ? pollMs * 2 : 0;\n  const freshnessWindowMs = staleMs > 0 ? staleMs : continuityMs;\n  return Math.max(requestedMs, freshnessWindowMs);\n};\n\nconst resolveObservationTimeMs = (value, fallback, now = Date.now()) => {\n  const timestamp = parseTimeMs(value, fallback);\n  // A bad upstream seconds/milliseconds conversion can produce dates tens of\n  // thousands of years ahead. Never let that pin a predicted flight at a\n  // future observation time; receipt time remains a safe integration anchor.\n  if (!Number.isFinite(timestamp) || timestamp > now + MAX_FUTURE_OBSERVATION_MS) {\n    return fallback;\n  }\n  return timestamp;\n};\n\nconst enableTaperedDashes = (material) => {\n  if (!material || material.userData?.dashTapered) return;\n  if (!material.userData) material.userData = {};\n  material.userData.dashTapered = true;\n  const baseCacheKey = typeof material.customProgramCacheKey === 'function'\n    ? material.customProgramCacheKey.bind(material)\n    : null;\n  material.customProgramCacheKey = () => {\n    const baseKey = baseCacheKey ? baseCacheKey() : '';\n    return `dash-taper:${baseKey}`;\n  };\n  const baseOnBeforeCompile = material.onBeforeCompile;\n  material.onBeforeCompile = (shader) => {\n    if (baseOnBeforeCompile) baseOnBeforeCompile(shader);\n    shader.vertexShader = shader.vertexShader\n      .replace(\n        'attribute float lineDistance;',\n        'attribute float lineDistance;\\nattribute float dashScale;\\nattribute float gapScale;\\nattribute float alpha;'\n      )\n      .replace(\n        'varying float vLineDistance;',\n        'varying float vLineDistance;\\nvarying float vDashScale;\\nvarying float vGapScale;\\nvarying float vAlpha;'\n      )\n      .replace(\n        'vLineDistance = lineDistance;',\n        'vLineDistance = lineDistance;\\n  vDashScale = dashScale;\\n  vGapScale = gapScale;\\n  vAlpha = alpha;'\n      );\n    shader.fragmentShader = shader.fragmentShader\n      .replace(\n        'varying float vLineDistance;',\n        'varying float vLineDistance;\\nvarying float vDashScale;\\nvarying float vGapScale;\\nvarying float vAlpha;'\n      );\n    const dashPhase = shader.fragmentShader.includes('dashOffset')\n      ? 'vLineDistance + dashOffset'\n      : 'vLineDistance';\n    const dashReplace = [\n      'float dashSizeScaled = dashSize * max(vDashScale, 0.0);',\n      'float gapSizeScaled = gapSize * max(vGapScale, 0.0);',\n      'float totalSize = dashSizeScaled + gapSizeScaled;',\n      'if ( totalSize > 0.0 ) {',\n      `  float dash = mod( ${dashPhase}, totalSize );`,\n      '  if ( dash > dashSizeScaled ) discard;',\n      '} else {',\n      '  discard;',\n      '}'\n    ].join('\\n');\n    shader.fragmentShader = shader.fragmentShader\n      .replace(\n        /if\\s*\\(\\s*mod\\s*\\(\\s*vLineDistance\\s*\\+\\s*dashOffset\\s*,\\s*dashSize\\s*\\+\\s*gapSize\\s*\\)\\s*>\\s*dashSize\\s*\\)\\s*discard;/,\n        dashReplace\n      )\n      .replace(\n        /if\\s*\\(\\s*mod\\s*\\(\\s*vLineDistance\\s*,\\s*dashSize\\s*\\+\\s*gapSize\\s*\\)\\s*>\\s*dashSize\\s*\\)\\s*discard;/,\n        dashReplace\n      );\n    shader.fragmentShader = shader.fragmentShader\n      .replace(\n        'gl_FragColor = vec4( diffuse, opacity );',\n        'gl_FragColor = vec4( diffuse, opacity * vAlpha );'\n      )\n      .replace(\n        'gl_FragColor = vec4( outgoingLight, diffuseColor.a );',\n        'gl_FragColor = vec4( outgoingLight, diffuseColor.a * vAlpha );'\n      )\n      .replace(\n        'gl_FragColor = vec4( outgoingLight, opacity );',\n        'gl_FragColor = vec4( outgoingLight, opacity * vAlpha );'\n      );\n  };\n  material.needsUpdate = true;\n};\n\nconst advanceLatLon = (latDeg, lonDeg, headingDeg, distanceM, radiusM = PLANET_RADIUS) => {\n  const dest = geodesicDestinationWGS84(latDeg, lonDeg, headingDeg, distanceM);\n  if (dest) {\n    return { lat: dest.latDeg, lon: dest.lonDeg };\n  }\n  const angularDistance = distanceM / Math.max(1, radiusM);\n  const lat1 = degToRad(latDeg);\n  const lon1 = degToRad(lonDeg);\n  const heading = degToRad(headingDeg);\n\n  const sinLat1 = Math.sin(lat1);\n  const cosLat1 = Math.cos(lat1);\n  const sinAd = Math.sin(angularDistance);\n  const cosAd = Math.cos(angularDistance);\n\n  const lat2 = Math.asin(\n    sinLat1 * cosAd + cosLat1 * sinAd * Math.cos(heading)\n  );\n  const lon2 = lon1 + Math.atan2(\n    Math.sin(heading) * sinAd * cosLat1,\n    cosAd - sinLat1 * Math.sin(lat2)\n  );\n\n  return {\n    lat: radToDeg(lat2),\n    lon: radToDeg(lon2),\n  };\n};\n\nconst integrateVelocity = (velocity, accel, dt, allowNegative = true) => {\n  if (!Number.isFinite(velocity) || !Number.isFinite(dt) || dt <= 0) {\n    return { delta: 0, nextVelocity: velocity };\n  }\n  const safeAccel = Number.isFinite(accel) ? accel : 0;\n  if (!safeAccel) {\n    const nextVelocity = allowNegative ? velocity : Math.max(0, velocity);\n    return { delta: velocity * dt, nextVelocity };\n  }\n  let nextVelocity = velocity + safeAccel * dt;\n  if (!allowNegative) {\n    if (velocity <= 0) {\n      return { delta: 0, nextVelocity: 0 };\n    }\n    if (nextVelocity < 0) {\n      const tStop = velocity / -safeAccel;\n      const delta = velocity * tStop + 0.5 * safeAccel * tStop * tStop;\n      return { delta, nextVelocity: 0 };\n    }\n    nextVelocity = Math.max(0, nextVelocity);\n  }\n  const delta = velocity * dt + 0.5 * safeAccel * dt * dt;\n  return { delta, nextVelocity };\n};\n\nexport class AircraftOverlay {\n  constructor({\n    parentGroup,\n    planetRadius,\n    eventBus,\n    sceneInitializer,\n    modelUrl,\n    modelScale,\n    pollIntervalMs,\n    staleAfterMs,\n    predictionMaxMs,\n    maxAircraft,\n    coneAngleDeg,\n    radiusNm,\n    provider,\n    queryMode,\n    queryValue,\n    headingOffsetDeg,\n    altitudeOffsetM,\n    surfaceController,\n    terrainSampler,\n    terrainClampMaxM,\n    terrainSampleIntervalMs,\n    terrainClearanceM,\n    smoothingMs,\n    accelMps2,\n    verticalAccelMps2,\n    headingAccelDeg,\n    showPaths,\n    pathHours,\n    pathMaxPoints,\n    lowLodEnabled,\n    lowLodDistanceM,\n    lowLodHysteresisM,\n    lowLodScaleMultiplier,\n    lowLodScale,\n    lowLodColor,\n    cullDistanceM,\n    cullHysteresisM,\n    enabled,\n  } = {}) {\n    this.parentGroup = parentGroup || null;\n    this.planetRadius = Number.isFinite(planetRadius) ? planetRadius : PLANET_RADIUS;\n    this.eventBus = eventBus || null;\n    this.sceneInitializer = sceneInitializer || null;\n\n    this.enabled = enabled === true;\n    this.provider = provider || 'unified';\n    this.queryMode = queryMode || 'catalog';\n    this.queryValue = queryValue || '';\n    this.radiusNm = Number.isFinite(radiusNm) ? radiusNm : 80;\n    this.coneAngleDeg = Number.isFinite(coneAngleDeg) ? coneAngleDeg : 170;\n    this.maxAircraft = Number.isFinite(maxAircraft) ? maxAircraft : 200;\n    this.pollIntervalMs = Number.isFinite(pollIntervalMs) ? pollIntervalMs : DEFAULT_POLL_INTERVAL_MS;\n    this.staleAfterMs = Number.isFinite(staleAfterMs) ? staleAfterMs : DEFAULT_STALE_MS;\n    this.predictionMaxMs = resolvePredictionWindowMs({\n      predictionMaxMs,\n      pollIntervalMs: this.pollIntervalMs,\n      staleAfterMs: this.staleAfterMs,\n    });\n    this.modelUrl = modelUrl || DEFAULT_MODEL_URL;\n    this.modelScale = Number.isFinite(modelScale) ? modelScale : DEFAULT_MODEL_SCALE;\n    this.headingOffsetDeg = Number.isFinite(headingOffsetDeg)\n      ? headingOffsetDeg\n      : DEFAULT_HEADING_OFFSET_DEG;\n    this.altitudeOffsetM = Number.isFinite(altitudeOffsetM) ? altitudeOffsetM : 0;\n    this.smoothingMs = Number.isFinite(smoothingMs) ? smoothingMs : DEFAULT_SMOOTH_MS;\n    this.accelMps2 = Number.isFinite(accelMps2) ? accelMps2 : DEFAULT_ACCEL_MPS2;\n    this.verticalAccelMps2 = Number.isFinite(verticalAccelMps2) ? verticalAccelMps2 : DEFAULT_VERTICAL_ACCEL_MPS2;\n    this.headingAccelDeg = Number.isFinite(headingAccelDeg) ? headingAccelDeg : DEFAULT_HEADING_ACCEL_DEG;\n    this.surfaceController = surfaceController || null;\n    // Overlay samples must neither contaminate nor inherit the camera's own\n    // underfoot cache. With photogrammetry active, only an exact fresh tile hit\n    // is valid for an aircraft at an arbitrary direction.\n    this._terrainSampler = typeof terrainSampler === 'function'\n      ? terrainSampler\n      : (this.surfaceController?.sampleTerrainRadiusForDir\n        ? (dir) => {\n            const photoTilesActive = !!this.surfaceController?.photoTileGroup;\n            return this.surfaceController.sampleTerrainRadiusForDir(dir, {\n              mutateCache: false,\n              requireFreshPhotoHit: photoTilesActive,\n              allowCachedFallback: false,\n              allowTriTreeFallback: !photoTilesActive,\n            });\n          }\n        : null);\n\n    // Photogrammetry-aware raycaster for surface height queries when 3D tiles are active\n    this._photogramRaycaster = new THREE.Raycaster();\n    this._photogramRaycaster.far = 50000; // 50km max ray distance\n    this._photogramEnabled = false;\n    this._photogramGroup = null; // Set via setPhotogrammetryGroup()\n    this.terrainClampMaxM = Number.isFinite(terrainClampMaxM)\n      ? terrainClampMaxM\n      : DEFAULT_TERRAIN_CLAMP_MAX_M;\n    this.terrainSampleIntervalMs = Number.isFinite(terrainSampleIntervalMs)\n      ? terrainSampleIntervalMs\n      : DEFAULT_TERRAIN_SAMPLE_INTERVAL_MS;\n    this.terrainClearanceM = Number.isFinite(terrainClearanceM)\n      ? terrainClearanceM\n      : DEFAULT_TERRAIN_CLEARANCE_M;\n    this.showPaths = showPaths === true;\n    this.pathHours = Number.isFinite(pathHours) ? pathHours : DEFAULT_PATH_HOURS;\n    this.pathMaxPoints = Number.isFinite(pathMaxPoints) ? pathMaxPoints : DEFAULT_PATH_MAX_POINTS;\n    this.pathSampleIntervalMs = PATH_SAMPLE_INTERVAL_MS;\n    // The full aircraft model is the visual default. The geometric low LOD is\n    // retained as an explicit performance option, rather than silently\n    // replacing aircraft with an octahedron at normal viewing distances.\n    this.lowLodEnabled = lowLodEnabled === true;\n    this.lowLodDistanceM = Number.isFinite(lowLodDistanceM) ? lowLodDistanceM : DEFAULT_LOW_LOD_DISTANCE_M;\n    this.lowLodHysteresisM = Number.isFinite(lowLodHysteresisM) ? lowLodHysteresisM : DEFAULT_LOW_LOD_HYSTERESIS_M;\n    this.lowLodScaleMultiplier = Number.isFinite(lowLodScaleMultiplier)\n      ? lowLodScaleMultiplier\n      : DEFAULT_LOW_LOD_SCALE_MULTIPLIER;\n    this.lowLodScale = Number.isFinite(lowLodScale) ? lowLodScale : null;\n    this.lowLodColor = lowLodColor || getDefaultLowLodColor();\n    const fallbackCullDistanceM = Number.isFinite(this.radiusNm)\n      ? this.radiusNm * METERS_PER_NM\n      : null;\n    this.cullDistanceM = Number.isFinite(cullDistanceM) ? cullDistanceM : fallbackCullDistanceM;\n    this.cullHysteresisM = Number.isFinite(cullHysteresisM)\n      ? cullHysteresisM\n      : DEFAULT_CULL_HYSTERESIS_M;\n\n    this._center = null;\n    this._pollElapsedMs = 0;\n    this._refreshQueued = false;\n    this._inflight = false;\n\n    this._modelBuckets = new Map();\n    this._modelDefaultUrl = DEFAULT_MODEL_URL;\n    this._loader = new GLTFLoader();\n    this._api = getFlightApiService();\n\n    this._entries = new Map();\n    this._hoveredEntry = null;\n\n    this._labelSystem = null; // Lazy init\n    this._labelsEnabled = true;\n\n    this._tmpQuat = new THREE.Quaternion();\n    this._tmpVec = new THREE.Vector3();\n    this._tmpVec2 = new THREE.Vector3();\n    this._tmpVec3 = new THREE.Vector3();\n    this._tmpEast = new THREE.Vector3();\n    this._tmpNorth = new THREE.Vector3();\n    this._tmpForward = new THREE.Vector3();\n    this._tmpRight = new THREE.Vector3();\n    this._tmpMat = new THREE.Matrix4();\n    this._tmpMat2 = new THREE.Matrix4();\n    this._tmpScale = new THREE.Vector3(1, 1, 1);\n    this._instancedHideMatrix = new THREE.Matrix4()\n      .makeScale(0, 0, 0)\n      .setPosition(1e9, 1e9, 1e9);\n    this._worldUp = new THREE.Vector3(0, 1, 0);\n    this._observerPosition = new THREE.Vector3();\n    this._observerLocal = new THREE.Vector3();\n    this._observerHasPosition = false;\n    this._lowLodGeometry = null;\n    this._lowLodMaterial = null;\n\n    this.group = new THREE.Group();\n    this.group.name = 'AircraftOverlay';\n    this.group.visible = this.enabled;\n    this.parentGroup?.add(this.group);\n\n    if (this.sceneInitializer && typeof this.sceneInitializer.addDepthPassExclude === 'function') {\n      this.sceneInitializer.addDepthPassExclude(this.group);\n    }\n\n    this._pathMaterial = new THREE.LineDashedMaterial({\n      color: resolveColor(getPathColor()),\n      dashSize: PATH_DASH_SIZE,\n      gapSize: PATH_GAP_SIZE,\n      transparent: true,\n      opacity: 0.7,\n    });\n    this._pathMaterial.vertexColors = true;\n    this._pathMaterial.toneMapped = false;\n    enableTaperedDashes(this._pathMaterial);\n\n    this._scopeEpoch=0;\n    this.catalog=typeof Worker==='function'&&sceneInitializer?.renderer?.domElement&&sceneInitializer?.camera\n      ?new AircraftCatalogLayer({parentGroup:this.group,sceneInitializer,eventBus:this.eventBus,\n        onNear:rows=>this._applyNearStates(rows),fetchHistory:async(entry,{signal}={})=>{\n          const data=await this._api.getFlights({provider:'unified',mode:'hex',queryValue:entry.recordId||entry.id.replace(/^icao:/,''),includePaths:true,maxResults:1,pathHours:this.pathHours,pathMaxPoints:this.pathMaxPoints},{signal});\n          return data.flights?.find(f=>aircraftIdentity(f)===entry.id)?.path||[];\n        }}):null;\n    this.catalog&&(this.catalog.showPaths=this.showPaths);\n    this._bindConfigListener();\n  }\n\n  setCenter(lat, lon, opts = {}) {\n    if (!Number.isFinite(lat) || !Number.isFinite(lon)) return;\n    this._center = { lat, lon };\n    if (Number.isFinite(opts.radiusNm)) this.radiusNm = opts.radiusNm;\n    if (Number.isFinite(opts.coneAngleDeg)) this.coneAngleDeg = opts.coneAngleDeg;\n    if (Number.isFinite(opts.maxAircraft)) this.maxAircraft = opts.maxAircraft;\n    if (Number.isFinite(opts.pollIntervalMs)) this.pollIntervalMs = opts.pollIntervalMs;\n    this._refreshQueued = true;\n  }\n\n  refresh() {\n    this._refreshQueued = true;\n  }\n\n  clear() {\n    this._scopeEpoch++;this._readController?.abort();this._readController=null;this._inflight=false;this.catalog?.clear();\n    for (const entry of this._entries.values()) {\n      this._releaseEntryRenderable(entry);\n      if (entry.pathLine) {\n        this.group.remove(entry.pathLine);\n        entry.pathLine.geometry.dispose();\n        entry.pathLine = null;\n      }\n    }\n    this._entries.clear();\n    this._hoveredEntry = null;\n    this.eventBus?.emit?.('flights:entries', []);\n  }\n\n  dispose() {\n    this.clear();this.catalog?.dispose();this.catalog=null;\n    this._labelSystem = null;\n    for (const bucket of this._modelBuckets.values()) {\n      this._disposeBucket(bucket);\n    }\n    this._modelBuckets.clear();\n    if (this.group && this.group.parent) {\n      this.group.parent.remove(this.group);\n    }\n    if (this._pathMaterial) {\n      this._pathMaterial.dispose();\n      this._pathMaterial = null;\n    }\n    if (this.sceneInitializer && typeof this.sceneInitializer.removeDepthPassExclude === 'function') {\n      this.sceneInitializer.removeDepthPassExclude(this.group);\n    }\n    this._disposeLowLodResources();\n    this._unbindConfigListener();\n  }\n\n  setLabelsEnabled(enabled) {\n    this._labelsEnabled = !!enabled;if(this.catalog)this.catalog.labelsEnabled=!!enabled;\n    if (!enabled) {\n      // Remove all existing labels\n      for (const entry of this._entries.values()) {\n        if (entry.labelHandle) {\n          if (entry.labelHandle.group) {\n            this.group.remove(entry.labelHandle.group);\n          }\n          entry.labelHandle.dispose();\n          entry.labelHandle = null;\n        }\n      }\n    }\n  }\n\n  _ensureLabelSystem() {\n    if (!this._labelSystem) {\n      try {\n        this._labelSystem = getLabelSystem({ planetRadius: this.planetRadius });\n      } catch { /* Label system not available */ }\n    }\n    return this._labelSystem;\n  }\n\n  update(dt, observerPos) {\n    if (!this.enabled) return;\n    this._setObserverPosition(observerPos);\n    this._pollElapsedMs += (Number.isFinite(dt) ? dt : 0) * 1000;\n    if (this._refreshQueued || this._pollElapsedMs >= this.pollIntervalMs) {\n      this._pollElapsedMs = 0;\n      this._refreshQueued = false;\n      this._fetchFlights();\n    }\n    this.catalog?.update();\n    this._updateEntries();\n  }\n\n  _setObserverPosition(observerPos) {\n    if (!observerPos) return;\n    const x = observerPos.x;\n    const y = observerPos.y;\n    const z = observerPos.z;\n    if (!Number.isFinite(x) || !Number.isFinite(y) || !Number.isFinite(z)) return;\n    this._observerPosition.set(x, y, z);\n    this._observerHasPosition = true;\n  }\n\n  async _fetchFlights() {\n    if (this._inflight) return;\n    if (!this.enabled) return;\n    if (!this._center) return;\n\n    this._inflight = true;const epoch=this._scopeEpoch,controller=this._readController=new AbortController();\n    try {\n      const params = {\n        provider: this.provider,\n        mode: this.queryMode,\n        lat: this._center?.lat,\n        lon: this._center?.lon,\n        radiusNm: this.radiusNm,\n        coneAngleDeg: this.coneAngleDeg,\n        maxResults: this.catalog&&['catalog','global'].includes(this.queryMode)?30000:this.maxAircraft,\n        staleAfterMs: this.staleAfterMs,\n        queryValue: this.queryValue || undefined,\n        includePaths: !this.catalog&&this.showPaths || undefined,\n        pathHours: this.showPaths ? this.pathHours : undefined,\n        pathMaxPoints: this.showPaths ? this.pathMaxPoints : undefined,\n      };\n      if(this.catalog){\n        const payload=await this._api.getFlightPayload(params,{signal:controller.signal});\n        if(epoch!==this._scopeEpoch||!this.enabled)return;\n        await this.catalog.submit(payload);\n      }else{\n        const data=await this._api.getFlights(params,{signal:controller.signal});\n        if(epoch!==this._scopeEpoch||!this.enabled)return;\n        this._applyStates(Array.isArray(data?.flights)?data.flights:[]);\n      }\n    } catch (error) {\n      if(!controller.signal.aborted)console.warn('[AircraftOverlay] Flight fetch failed', error);\n    } finally {\n      if(this._readController===controller){this._readController=null;this._inflight=false;}\n    }\n  }\n\n  _applyNearStates(states){\n    if(!this.enabled)return;\n    const selected=states.slice(0,Math.min(200,this.maxAircraft));this._applyStates(selected);\n    const ids=new Set(selected.map(s=>this._buildEntryId(s)));\n    for(const[id,entry]of this._entries)if(!ids.has(id)){this._releaseEntryRenderable(entry);if(entry.pathLine){this.group.remove(entry.pathLine);entry.pathLine.geometry.dispose();}this._entries.delete(id);}\n    return new Set(this._entries.keys());\n  }\n\n  _applyStates(states) {\n    if (!Array.isArray(states)) return;\n\n    const now = Date.now();\n    const seen = new Set();\n\n    for (const state of states) {\n      const id = this._buildEntryId(state);\n      if (!id) continue;\n      seen.add(id);\n      let entry = this._entries.get(id);\n      if (!entry) {\n        entry = this._createEntry(state);\n        this._entries.set(id, entry);\n        if (entry.object) {\n          this.group.add(entry.object);\n        }\n      }\n      this._updateEntry(entry, state, now);\n    }\n\n    for (const entry of this._entries.values()) {\n      if (!seen.has(entry.id)) continue;\n      entry.lastSeenLocal = now;\n    }\n\n    if (this.eventBus && typeof this.eventBus.emit === 'function') {\n      this.eventBus.emit('flights:entries', this.getEntriesSnapshot());\n    }\n  }\n\n  _buildEntryId(state) {\n    return state?.entityId || aircraftIdentity(state);\n  }\n\n  _resolveModelUrl(entry) {\n    const modelUrl = this.modelUrl;\n    if (modelUrl && typeof modelUrl === 'object') {\n      const type = entry?.aircraftType;\n      if (type && typeof modelUrl[type] === 'string') {\n        return modelUrl[type];\n      }\n      if (typeof modelUrl.default === 'string') {\n        return modelUrl.default;\n      }\n    }\n    if (typeof modelUrl === 'string' && modelUrl) {\n      return modelUrl;\n    }\n    return this._modelDefaultUrl;\n  }\n\n  _resolveModelKey(entry) {\n    return this._resolveModelUrl(entry);\n  }\n\n  _getModelBucketForEntry(entry) {\n    const key = this._resolveModelKey(entry);\n    if (!key) return null;\n    let bucket = this._modelBuckets.get(key);\n    if (!bucket) {\n      bucket = this._createModelBucket(key);\n      this._modelBuckets.set(key, bucket);\n    }\n    if (!bucket.loadingPromise && !bucket.ready) {\n      this._ensureModelBucket(bucket);\n    }\n    return bucket;\n  }\n\n  _createEntry(state) {\n    const aircraftType = normalizeAircraftType(state.aircraftType) || null;\n    const entry = {\n      id: this._buildEntryId(state),\n      object: null,\n      modelKey: null,\n      instanceKey: null,\n      instanceId: null,\n      renderPos: null,\n      lod: 'detail',\n      lowObject: null,\n      lat: null,\n      lon: null,\n      altitudeM: null,\n      velocityMps: null,\n      headingDeg: null,\n      verticalRateMps: null,\n      onGround: null,\n      callsign: null,\n      source: null,\n      rawId: null,\n      aircraftType,\n      lastContactMs: null,\n      updatedAtMs: null,\n      lastReceivedAtMs: null,\n      lastSeenLocal: null,\n      predictedLat: null,\n      predictedLon: null,\n      predictedAlt: null,\n      smoothedVelocityMps: null,\n      smoothedHeadingDeg: null,\n      smoothedVerticalRateMps: null,\n      lastVelocitySample: null,\n      lastVelocitySampleAt: 0,\n      estimatedAccelMps2: 0,\n      lastVerticalSample: null,\n      lastVerticalSampleAt: 0,\n      estimatedVerticalAccelMps2: 0,\n      correctionLat: 0,\n      correctionLon: 0,\n      correctionAlt: 0,\n      correctionRemainingMs: 0,\n      lastPredictedAtMs: null,\n      terrainRadius: null,\n      terrainSampleDir: null,\n      lastTerrainSampleMs: 0,\n      pathLine: null,\n      pathHistory: [],\n      lastPathSampleMs: 0,\n      pathSeeded: false,\n      labelHandle: null,\n    };\n    const bucket = this._getModelBucketForEntry(entry);\n    if (bucket?.ready) {\n      entry.modelKey = bucket.key;\n      if (bucket.useInstancing) {\n        this._assignEntryInstance(entry, bucket);\n      } else {\n        entry.object = this._createInstance(bucket);\n        if (entry.object) {\n          this._attachEntryToObject(entry, entry.object);\n          this.group.add(entry.object);\n        }\n      }\n    } else {\n      entry.modelKey = this._resolveModelKey(entry);\n      entry.object = this._createFallbackInstance(entry);\n      if (entry.object) {\n        this.group.add(entry.object);\n      }\n    }\n    return entry;\n  }\n\n  _updateEntry(entry, state, now) {\n    const prevUpdatedAt = entry.updatedAtMs;\n    const previousLastContactMs = entry.lastContactMs;\n    const nextUpdatedAt = resolveObservationTimeMs(state.updatedAt, now, now);\n    const nextLastContactMs = resolveObservationTimeMs(state.positionTime??state.lastContact, entry.lastContactMs, now);\n    const isNewUpdate = nextLastContactMs!==previousLastContactMs\n      ||entry.lat!==state.lat||entry.lon!==state.lon||entry.altitudeM!==state.altitudeM\n      ||entry.velocityMps!==state.velocityMps||entry.headingDeg!==state.headingDeg||entry.verticalRateMps!==state.verticalRateMps;\n\n    const previousLat = entry.lat;\n    const previousLon = entry.lon;\n    const previousAltitudeM = entry.altitudeM;\n    const previousVelocityMps = entry.velocityMps;\n    const previousHeadingDeg = entry.headingDeg;\n\n    entry.lat = toNumber(state.lat);\n    entry.lon = toNumber(state.lon);\n    entry.altitudeM = toNumber(state.altitudeM);\n    entry.velocityMps = toNumber(state.velocityMps);\n    entry.headingDeg = toNumber(state.headingDeg);\n    entry.verticalRateMps = toNumber(state.verticalRateMps);\n    entry.onGround = typeof state.onGround === 'boolean' ? state.onGround : null;\n    entry.callsign = typeof state.callsign === 'string' ? state.callsign : (entry.callsign || null);\n    entry.source = typeof state.source === 'string' ? state.source : (entry.source || null);\n    entry.rawId = state.recordId || state.id || state.icao24 || state.hex || entry.rawId || null;\n    entry.aircraftType = normalizeAircraftType(state.aircraftType) || entry.aircraftType || null;\n    entry.lastContactMs = nextLastContactMs;\n    entry.updatedAtMs = nextUpdatedAt;\n    entry.lastSeenLocal = now;\n\n    // Prediction age is measured from receipt of a genuinely new source state,\n    // not from a provider's already-aged `lastContact` timestamp. A cached\n    // response therefore cannot keep a flight moving forever, while a fresh\n    // packet always gets a full, smooth interpolation window.\n    const sourceContactChanged = Number.isFinite(nextLastContactMs)\n      && nextLastContactMs !== previousLastContactMs;\n    const positionOrMotionChanged = previousLat !== entry.lat\n      || previousLon !== entry.lon\n      || previousAltitudeM !== entry.altitudeM\n      || previousVelocityMps !== entry.velocityMps\n      || previousHeadingDeg !== entry.headingDeg;\n    if (!Number.isFinite(entry.lastReceivedAtMs) || sourceContactChanged || (isNewUpdate && positionOrMotionChanged)) {\n      entry.lastReceivedAtMs = now;\n    }\n\n    this._updateAccelerationEstimate(entry, nextUpdatedAt, isNewUpdate);\n    this._syncEntryModelKey(entry);\n\n    if (!entry.object && !entry.instanceKey && entry.modelKey) {\n      const bucket = this._modelBuckets.get(entry.modelKey);\n      if (bucket?.ready) {\n        if (bucket.useInstancing) {\n          this._assignEntryInstance(entry, bucket);\n        } else {\n          entry.object = this._createInstance(bucket);\n          if (entry.object) {\n            this._attachEntryToObject(entry, entry.object);\n            this.group.add(entry.object);\n          }\n        }\n      }\n    }\n\n    const sourcePositionAtMs = Number.isFinite(entry.lastContactMs)\n      ? entry.lastContactMs\n      : nextUpdatedAt;\n    const initialPredictionAtMs = Number.isFinite(sourcePositionAtMs)\n      ? Math.max(now - this.predictionMaxMs, Math.min(now, sourcePositionAtMs))\n      : now;\n    if (!Number.isFinite(entry.predictedLat) && Number.isFinite(entry.lat)) {\n      entry.predictedLat = entry.lat;\n      entry.lastPredictedAtMs = initialPredictionAtMs;\n    }\n    if (!Number.isFinite(entry.predictedLon) && Number.isFinite(entry.lon)) {\n      entry.predictedLon = entry.lon;\n      entry.lastPredictedAtMs = initialPredictionAtMs;\n    }\n    if (!Number.isFinite(entry.predictedAlt) && Number.isFinite(entry.altitudeM)) {\n      entry.predictedAlt = entry.altitudeM;\n      entry.lastPredictedAtMs = initialPredictionAtMs;\n    }\n\n    if (!Number.isFinite(entry.smoothedVelocityMps) && Number.isFinite(entry.velocityMps)) {\n      entry.smoothedVelocityMps = entry.velocityMps;\n    }\n    if (!Number.isFinite(entry.smoothedHeadingDeg) && Number.isFinite(entry.headingDeg)) {\n      entry.smoothedHeadingDeg = entry.headingDeg;\n    }\n    if (!Number.isFinite(entry.smoothedVerticalRateMps) && Number.isFinite(entry.verticalRateMps)) {\n      entry.smoothedVerticalRateMps = entry.verticalRateMps;\n    }\n\n    if (isNewUpdate &&\n        Number.isFinite(entry.predictedLat) &&\n        Number.isFinite(entry.predictedLon) &&\n        Number.isFinite(entry.lat) &&\n        Number.isFinite(entry.lon)) {\n      let targetLat=entry.lat,targetLon=entry.lon,targetAlt=Number.isFinite(entry.altitudeM)?entry.altitudeM:entry.predictedAlt;\n      if(Number.isFinite(nextLastContactMs)&&Number.isFinite(targetAlt)){\n        const vector=aircraftStateAt({...state,positionTime:new Date(nextLastContactMs).toISOString(),altitudeM:targetAlt},now);\n        const target=satelliteGeodetic({x:vector[0],y:vector[1],z:vector[2]});targetLat=target.lat;targetLon=target.lon;targetAlt=target.altitudeM;\n      }\n      const deltaLat = targetLat - entry.predictedLat;\n      const deltaLon = wrapAngleDeg(targetLon - entry.predictedLon);\n      const deltaAlt = Number.isFinite(targetAlt) && Number.isFinite(entry.predictedAlt)\n        ? targetAlt - entry.predictedAlt\n        : 0;\n      if (Number.isFinite(deltaLat) || Number.isFinite(deltaLon) || Number.isFinite(deltaAlt)) {\n        entry.correctionLat = Number.isFinite(deltaLat) ? deltaLat : 0;\n        entry.correctionLon = Number.isFinite(deltaLon) ? deltaLon : 0;\n        entry.correctionAlt = Number.isFinite(deltaAlt) ? deltaAlt : 0;\n        entry.correctionRemainingMs = Math.max(0, this.smoothingMs);\n      }\n    }\n\n    if (Array.isArray(state.path)) {\n      this._seedPathHistory(entry, state.path);\n    }\n    if (!this.showPaths && entry.pathLine) {\n      entry.pathLine.visible = false;\n    }\n  }\n\n  _updateAccelerationEstimate(entry, sampleTimeMs, isNewUpdate) {\n    if (!entry || !isNewUpdate) return;\n    const timestamp = Number.isFinite(sampleTimeMs) ? sampleTimeMs : Date.now();\n    const maxAccel = Math.max(this.accelMps2 * 2, DEFAULT_ACCEL_ESTIMATE_MAX_MPS2);\n    const maxVerticalAccel = Math.max(this.verticalAccelMps2 * 2, DEFAULT_VERTICAL_ACCEL_ESTIMATE_MAX_MPS2);\n\n    if (Number.isFinite(entry.velocityMps)) {\n      if (Number.isFinite(entry.lastVelocitySample) && Number.isFinite(entry.lastVelocitySampleAt)) {\n        const dtSec = (timestamp - entry.lastVelocitySampleAt) / 1000;\n        if (dtSec > 0) {\n          const rawAccel = (entry.velocityMps - entry.lastVelocitySample) / dtSec;\n          const clamped = clampAbs(rawAccel, maxAccel);\n          entry.estimatedAccelMps2 = blendValue(entry.estimatedAccelMps2, clamped, ACCEL_ESTIMATE_BLEND);\n        }\n      }\n      entry.lastVelocitySample = entry.velocityMps;\n      entry.lastVelocitySampleAt = timestamp;\n    }\n\n    if (entry.onGround === true) {\n      entry.estimatedVerticalAccelMps2 = 0;\n      entry.lastVerticalSample = 0;\n      entry.lastVerticalSampleAt = timestamp;\n      return;\n    }\n\n    if (Number.isFinite(entry.verticalRateMps)) {\n      if (Number.isFinite(entry.lastVerticalSample) && Number.isFinite(entry.lastVerticalSampleAt)) {\n        const dtSec = (timestamp - entry.lastVerticalSampleAt) / 1000;\n        if (dtSec > 0) {\n          const rawAccel = (entry.verticalRateMps - entry.lastVerticalSample) / dtSec;\n          const clamped = clampAbs(rawAccel, maxVerticalAccel);\n          entry.estimatedVerticalAccelMps2 = blendValue(entry.estimatedVerticalAccelMps2, clamped, ACCEL_ESTIMATE_BLEND);\n        }\n      }\n      entry.lastVerticalSample = entry.verticalRateMps;\n      entry.lastVerticalSampleAt = timestamp;\n    }\n  }\n\n  _updateEntries() {\n    const now = Date.now();\n    const maxPredictMs = Math.max(0, this.predictionMaxMs);\n    const dirtyBuckets = new Set();\n    let lodEnabled = this.lowLodEnabled && this._observerHasPosition;\n    let cullEnabled = Number.isFinite(this.cullDistanceM) && this.cullDistanceM > 0 && this._observerHasPosition;\n    let lodOutSq = 0;\n    let lodInSq = 0;\n    let cullOutSq = 0;\n    let cullInSq = 0;\n    let observerLocal = null;\n\n    if (this._observerHasPosition) {\n      this.group.updateMatrixWorld(true);\n      observerLocal = this._observerLocal.copy(this._observerPosition);\n      this.group.worldToLocal(observerLocal);\n    }\n\n    if (lodEnabled && Number.isFinite(this.lowLodDistanceM) && this.lowLodDistanceM > 0) {\n      const hysteresis = Number.isFinite(this.lowLodHysteresisM) ? Math.max(0, this.lowLodHysteresisM) : 0;\n      const switchOut = this.lowLodDistanceM + hysteresis;\n      const switchIn = Math.max(0, this.lowLodDistanceM - hysteresis);\n      lodOutSq = switchOut * switchOut;\n      lodInSq = switchIn * switchIn;\n    } else {\n      lodEnabled = false;\n    }\n\n    if (cullEnabled) {\n      const hysteresis = Number.isFinite(this.cullHysteresisM) ? Math.max(0, this.cullHysteresisM) : 0;\n      const switchOut = this.cullDistanceM + hysteresis;\n      const switchIn = Math.max(0, this.cullDistanceM - hysteresis);\n      cullOutSq = switchOut * switchOut;\n      cullInSq = switchIn * switchIn;\n    } else {\n      cullEnabled = false;\n    }\n\n    for (const [id, entry] of this._entries.entries()) {\n      // lastSeenLocal is refreshed even when the transport repeats a cached\n      // packet. Retire based on the last genuinely changed source state so an\n      // old cache cannot leave a frozen aircraft in the scene indefinitely.\n      const lastSourceUpdate = entry.lastReceivedAtMs || entry.lastContactMs || entry.updatedAtMs || entry.lastSeenLocal || 0;\n      if (this.staleAfterMs > 0 && now - lastSourceUpdate > this.staleAfterMs) {\n        this._releaseEntryRenderable(entry);\n        if (entry.pathLine) {\n          this.group.remove(entry.pathLine);\n          entry.pathLine.geometry.dispose();\n        }\n        this._entries.delete(id);\n        continue;\n      }\n\n      const bucket = entry.instanceKey ? this._modelBuckets.get(entry.instanceKey) : null;\n      if (!entry.object && (!entry.instanceKey || !bucket?.useInstancing)) continue;\n\n      let lat = Number.isFinite(entry.predictedLat) ? entry.predictedLat : entry.lat;\n      let lon = Number.isFinite(entry.predictedLon) ? entry.predictedLon : entry.lon;\n      let trajectoryAlt = Number.isFinite(entry.predictedAlt)\n        ? entry.predictedAlt\n        : (Number.isFinite(entry.altitudeM) ? entry.altitudeM : 0);\n\n      if (!Number.isFinite(lat) || !Number.isFinite(lon)) continue;\n\n      const lastPredictedAt = Number.isFinite(entry.lastPredictedAtMs)\n        ? entry.lastPredictedAtMs\n        : now;\n      let dtMs = Math.max(0, now - lastPredictedAt);\n\n      const predictionStartedAtMs = entry.lastReceivedAtMs || entry.updatedAtMs || now;\n      const predictionAgeMs = Math.max(0, now - predictionStartedAtMs);\n      if (Number.isFinite(this.predictionMaxMs) && this.predictionMaxMs >= 0) {\n        const ageMs = predictionAgeMs;\n        const remainingMs = this.predictionMaxMs - ageMs;\n        if (remainingMs <= 0) {\n          dtMs = 0;\n        } else {\n          dtMs = Math.min(dtMs, remainingMs);\n        }\n      }\n\n      const dtSec = dtMs / 1000;\n      const targetVelocity = Number.isFinite(entry.velocityMps) ? entry.velocityMps : entry.smoothedVelocityMps;\n      // A slow aircraft is not necessarily on the ground (helicopters, climb,\n      // approach, and small aircraft all routinely travel below 70 m/s). Honor\n      // the provider's semantic flag instead of guessing from airspeed.\n      const isOnGround = entry.onGround === true;\n      if (Number.isFinite(targetVelocity)) {\n        if (!Number.isFinite(entry.smoothedVelocityMps)) {\n          entry.smoothedVelocityMps = targetVelocity;\n        } else if (dtSec > 0) {\n          entry.smoothedVelocityMps = approach(entry.smoothedVelocityMps, targetVelocity, this.accelMps2 * dtSec);\n        }\n      }\n\n      const targetHeading = Number.isFinite(entry.headingDeg) ? entry.headingDeg : entry.smoothedHeadingDeg;\n      if (Number.isFinite(targetHeading)) {\n        if (!Number.isFinite(entry.smoothedHeadingDeg)) {\n          entry.smoothedHeadingDeg = targetHeading;\n        } else if (dtSec > 0) {\n          entry.smoothedHeadingDeg = approachAngleDeg(\n            entry.smoothedHeadingDeg,\n            targetHeading,\n            this.headingAccelDeg * dtSec\n          );\n        }\n      }\n\n      const targetVertical = isOnGround\n        ? 0\n        : (Number.isFinite(entry.verticalRateMps) ? entry.verticalRateMps : entry.smoothedVerticalRateMps);\n      if (Number.isFinite(targetVertical)) {\n        if (!Number.isFinite(entry.smoothedVerticalRateMps)) {\n          entry.smoothedVerticalRateMps = targetVertical;\n        } else if (dtSec > 0) {\n          entry.smoothedVerticalRateMps = approach(\n            entry.smoothedVerticalRateMps,\n            targetVertical,\n            this.verticalAccelMps2 * dtSec\n          );\n        }\n      }\n\n      const dirForTerrain = latLonToLocalDir(lat, lon);\n      const baseRadiusForTerrain = ellipsoidRadiusForLocalDir(dirForTerrain);\n      let minAlt = null;\n      const shouldClampTerrain = isOnGround || this._shouldClampToTerrain(entry, trajectoryAlt + this.altitudeOffsetM);\n      if (shouldClampTerrain) {\n        const terrainRadius = this._getTerrainRadius(entry, dirForTerrain, now);\n        if (Number.isFinite(terrainRadius)) {\n          minAlt = (terrainRadius - baseRadiusForTerrain) + this.terrainClearanceM;\n        }\n      }\n      if (isOnGround && !Number.isFinite(minAlt)) {\n        minAlt = 0;\n      }\n\n      const velocity = Number.isFinite(entry.smoothedVelocityMps)\n        ? entry.smoothedVelocityMps\n        : entry.velocityMps;\n      const heading = Number.isFinite(entry.smoothedHeadingDeg)\n        ? entry.smoothedHeadingDeg\n        : entry.headingDeg;\n      const verticalRate = Number.isFinite(entry.smoothedVerticalRateMps)\n        ? entry.smoothedVerticalRateMps\n        : entry.verticalRateMps;\n      const accelMps2 = Number.isFinite(entry.estimatedAccelMps2) ? entry.estimatedAccelMps2 : 0;\n      const verticalAccelMps2 = Number.isFinite(entry.estimatedVerticalAccelMps2) ? entry.estimatedVerticalAccelMps2 : 0;\n\n      // Keep velocity continuous while packets are expected. Only ease it out\n      // in the final fifth of the window, preventing a hard stop if a source\n      // becomes stale without making live aircraft look slow between polls.\n      const fadeStartMs = maxPredictMs * 0.8;\n      const decayFactor = maxPredictMs > 0 && predictionAgeMs > fadeStartMs\n        ? Math.max(0, (maxPredictMs - predictionAgeMs) / Math.max(1, maxPredictMs - fadeStartMs))\n        : 1.0;\n\n      let moveDt = dtSec * decayFactor;\n      if (Number.isFinite(minAlt)) {\n        const altWithOffset = trajectoryAlt + this.altitudeOffsetM;\n        if (altWithOffset <= minAlt) {\n          if (!isOnGround) moveDt = 0;\n        } else if (!isOnGround && Number.isFinite(verticalRate) && verticalRate < 0) {\n          const timeToGround = (altWithOffset - minAlt) / -verticalRate;\n          if (Number.isFinite(timeToGround) && timeToGround >= 0 && timeToGround < moveDt) {\n            moveDt = timeToGround;\n          }\n        }\n      }\n\n      if (moveDt > 0) {\n        if (Number.isFinite(velocity) && Number.isFinite(heading)) {\n          const motion = integrateVelocity(velocity, accelMps2, moveDt, false);\n          if (Number.isFinite(motion.delta) && motion.delta !== 0) {\n            const moved = advanceLatLon(lat, lon, heading, motion.delta, baseRadiusForTerrain + trajectoryAlt);\n            lat = moved.lat;\n            lon = moved.lon;\n          }\n          if (Number.isFinite(motion.nextVelocity)) {\n            entry.smoothedVelocityMps = motion.nextVelocity;\n          }\n        }\n\n        if (!isOnGround && Number.isFinite(verticalRate)) {\n          const motion = integrateVelocity(verticalRate, verticalAccelMps2, moveDt, true);\n          if (Number.isFinite(motion.delta)) {\n            trajectoryAlt += motion.delta;\n          }\n          if (Number.isFinite(motion.nextVelocity)) {\n            entry.smoothedVerticalRateMps = motion.nextVelocity;\n          }\n        }\n      }\n      entry.lastPredictedAtMs = now;\n\n      const predictedDirForTerrain = latLonToLocalDir(lat, lon);\n      const predictedBaseRadiusForTerrain = ellipsoidRadiusForLocalDir(predictedDirForTerrain);\n      if (!Number.isFinite(minAlt) && (isOnGround || this._shouldClampToTerrain(entry, trajectoryAlt + this.altitudeOffsetM))) {\n        const terrainRadius = this._getTerrainRadius(entry, predictedDirForTerrain, now);\n        if (Number.isFinite(terrainRadius)) {\n          minAlt = (terrainRadius - predictedBaseRadiusForTerrain) + this.terrainClearanceM;\n        }\n      }\n      if (isOnGround && !Number.isFinite(minAlt)) {\n        minAlt = 0;\n      }\n\n      if (entry.correctionRemainingMs > 0 && dtMs > 0) {\n        const step = Math.min(1, dtMs / entry.correctionRemainingMs);\n        if (Number.isFinite(entry.correctionLat)) {\n          lat += entry.correctionLat * step;\n          entry.correctionLat -= entry.correctionLat * step;\n        }\n        if (Number.isFinite(entry.correctionLon)) {\n          lon = wrapAngleDeg(lon + entry.correctionLon * step);\n          entry.correctionLon -= entry.correctionLon * step;\n        }\n        if (Number.isFinite(entry.correctionAlt)) {\n          if (isOnGround) {\n            entry.correctionAlt = 0;\n          } else {\n            trajectoryAlt += entry.correctionAlt * step;\n            entry.correctionAlt -= entry.correctionAlt * step;\n          }\n        }\n        entry.correctionRemainingMs = Math.max(0, entry.correctionRemainingMs - dtMs);\n      }\n\n      entry.predictedLat = lat;\n      entry.predictedLon = lon;\n      // Keep provider/predicted altitude as trajectory truth. Terrain is a\n      // presentation constraint and must never feed back into prediction or\n      // historical trail samples when a tile LOD changes beneath the plane.\n      entry.predictedAlt = trajectoryAlt;\n\n      const pathAlt = trajectoryAlt;\n      let renderAlt = trajectoryAlt + this.altitudeOffsetM;\n      if (Number.isFinite(minAlt)) {\n        renderAlt = isOnGround\n          ? minAlt + this.altitudeOffsetM\n          : Math.max(renderAlt, minAlt + this.altitudeOffsetM);\n      }\n      renderAlt = Math.max(renderAlt, 0);\n\n      const dir = latLonToLocalDir(lat, lon);\n      const baseRadius = ellipsoidRadiusForLocalDir(dir);\n      const radius = baseRadius + renderAlt;\n      const pos = this._tmpVec.copy(dir).multiplyScalar(radius);\n      if(this.catalog){\n        const shared=this.catalog.position(entry.id,pos);\n        if(!shared){if(entry.object)entry.object.visible=false;if(entry.lowObject)entry.lowObject.visible=false;if(bucket&&Number.isFinite(entry.instanceId)){this._hideInstance(bucket,entry.instanceId);if(bucket.lowMesh)bucket.lowMesh.setMatrixAt(entry.instanceId,this._instancedHideMatrix);dirtyBuckets.add(bucket);}continue;}\n        const current=satelliteGeodetic(shared);entry.predictedLat=current.lat;entry.predictedLon=current.lon;entry.predictedAlt=current.altitudeM;\n        if(entry.onGround===true&&Number.isFinite(entry.terrainRadius))pos.normalize().multiplyScalar(entry.terrainRadius+this.terrainClearanceM+this.altitudeOffsetM);\n      }\n      const instancedPos = bucket && bucket.useInstancing\n        ? this._applyInstancedAnchor(bucket, pos, observerLocal)\n        : pos;\n\n      const renderHeading = Number.isFinite(heading)\n        ? heading + this.headingOffsetDeg\n        : this.headingOffsetDeg;\n      this._buildSurfaceQuaternion(this._tmpQuat, dir, renderHeading);\n      const distanceSq = observerLocal ? observerLocal.distanceToSquared(pos) : null;\n      const prevCulled = entry.culled === true;\n      let nextCulled = false;\n      if (cullEnabled && Number.isFinite(distanceSq)) {\n        if (prevCulled) {\n          nextCulled = distanceSq > cullInSq;\n        } else {\n          nextCulled = distanceSq >= cullOutSq;\n        }\n      }\n      entry.culled = nextCulled;\n      if (nextCulled) {\n        if (entry.object) {\n          entry.object.visible = false;\n          if (entry.lowObject) entry.lowObject.visible = false;\n        } else if (bucket && Number.isFinite(entry.instanceId)) {\n          this._hideInstance(bucket, entry.instanceId);\n          if (bucket.lowMesh) {\n            bucket.lowMesh.setMatrixAt(entry.instanceId, this._instancedHideMatrix);\n          }\n          dirtyBuckets.add(bucket);\n        }\n        if (entry.pathLine) entry.pathLine.visible = false;\n        if (!entry.renderPos) entry.renderPos = new THREE.Vector3();\n        entry.renderPos.copy(pos);\n        continue;\n      }\n      const prevLod = entry.lod || 'detail';\n      let nextLod = 'detail';\n      if (lodEnabled && observerLocal && Number.isFinite(distanceSq)) {\n        if (prevLod === 'low') {\n          nextLod = distanceSq <= lodInSq ? 'detail' : 'low';\n        } else if (distanceSq >= lodOutSq) {\n          nextLod = 'low';\n        }\n      }\n      if (!this.lowLodEnabled) nextLod = 'detail';\n      if (entry.object?.userData?.isAircraftFallback) nextLod = 'detail';\n      if (!entry.object && nextLod === 'low' && bucket?.useInstancing && !bucket.lowMesh) {\n        this._buildLowLodMesh(bucket);\n      }\n      let effectiveLod = nextLod;\n      if (effectiveLod === 'low' && !entry.object && !(bucket && bucket.lowMesh)) {\n        effectiveLod = 'detail';\n      }\n      const lodChanged = effectiveLod !== prevLod;\n      if (lodChanged) entry.lod = effectiveLod;\n\n      if (entry.object) {\n        entry.object.position.copy(pos);\n        entry.object.quaternion.copy(this._tmpQuat);\n        if (effectiveLod === 'low') {\n          if (!entry.lowObject) {\n            entry.lowObject = this._createLowLodObject(entry);\n            if (entry.lowObject) this.group.add(entry.lowObject);\n          }\n          if (entry.lowObject) {\n            entry.object.visible = false;\n            entry.lowObject.visible = true;\n            entry.lowObject.position.copy(pos);\n            entry.lowObject.quaternion.copy(this._tmpQuat);\n            entry.lowObject.scale.setScalar(this._resolveLowLodScale());\n          } else {\n            entry.object.visible = true;\n            if (entry.lod !== 'detail') entry.lod = 'detail';\n          }\n        } else {\n          entry.object.visible = true;\n          if (entry.lowObject) entry.lowObject.visible = false;\n        }\n      } else if (bucket && Number.isFinite(entry.instanceId)) {\n        if (effectiveLod === 'low' && bucket.lowMesh) {\n          if (lodChanged) {\n            this._hideInstance(bucket, entry.instanceId);\n          }\n          this._tmpScale.setScalar(this._resolveLowLodScale());\n          this._tmpMat.compose(instancedPos, this._tmpQuat, this._tmpScale);\n          bucket.lowMesh.setMatrixAt(entry.instanceId, this._tmpMat);\n          dirtyBuckets.add(bucket);\n        } else {\n          this._tmpScale.setScalar(this.modelScale);\n          this._tmpMat.compose(instancedPos, this._tmpQuat, this._tmpScale);\n          for (const mesh of bucket.meshes) {\n            this._tmpMat2.multiplyMatrices(this._tmpMat, mesh.baseMatrix);\n            mesh.instanced.setMatrixAt(entry.instanceId, this._tmpMat2);\n          }\n          if (bucket.lowMesh && prevLod === 'low') {\n            bucket.lowMesh.setMatrixAt(entry.instanceId, this._instancedHideMatrix);\n          }\n          dirtyBuckets.add(bucket);\n        }\n      }\n      if (!entry.renderPos) entry.renderPos = new THREE.Vector3();\n      entry.renderPos.copy(pos);\n\n      // ── Label management ──\n      if (this._labelsEnabled && !this.catalog && entry.callsign) {\n        const ls = this._ensureLabelSystem();\n        if (ls) {\n          const labelSubText = this._buildAircraftLabelSubText(entry);\n          const labelMetadata = this._buildAircraftLabelMetadata(entry);\n          if (!entry.labelHandle) {\n            entry.labelHandle = ls.createLabel(entry.callsign, {\n              position: entry.renderPos,\n              type: 'aircraft',\n              objectRadius: 50,\n              subText: labelSubText,\n              metadata: labelMetadata,\n            });\n            if (entry.labelHandle?.group) {\n              this.group.add(entry.labelHandle.group);\n            }\n          } else {\n            ls.updatePosition(entry.labelHandle, entry.renderPos);\n            ls.updateText(entry.labelHandle, entry.callsign, labelSubText);\n            ls.updateMetadata?.(entry.labelHandle, labelMetadata);\n          }\n        }\n      } else if (entry.labelHandle) {\n        // Labels disabled or no callsign — remove existing label\n        if (entry.labelHandle.group) {\n          this.group.remove(entry.labelHandle.group);\n        }\n        entry.labelHandle.dispose();\n        entry.labelHandle = null;\n      }\n\n      if(!this.catalog){this._appendPathPoint(entry,lat,lon,pathAlt,now);this._updatePathTail(entry);}\n    }\n\n    if (dirtyBuckets.size) {\n      for (const bucket of dirtyBuckets) {\n        for (const mesh of bucket.meshes) {\n          mesh.instanced.instanceMatrix.needsUpdate = true;\n        }\n        if (bucket.lowMesh) {\n          bucket.lowMesh.instanceMatrix.needsUpdate = true;\n        }\n      }\n    }\n  }\n\n  _applyInstancedAnchor(bucket, worldPos, observerLocal) {\n    if (!bucket || !bucket.group) return worldPos;\n    if (!observerLocal) {\n      if (bucket.anchorValid) {\n        bucket.anchorValid = false;\n        bucket.anchor.set(0, 0, 0);\n        bucket.group.position.set(0, 0, 0);\n      }\n      return worldPos;\n    }\n\n    if (!bucket.anchorValid || !bucket.anchor.equals(observerLocal)) {\n      bucket.anchor.copy(observerLocal);\n      bucket.group.position.copy(observerLocal);\n      bucket.anchorValid = true;\n    }\n\n    return this._tmpVec3.copy(worldPos).sub(bucket.anchor);\n  }\n\n  _buildSurfaceQuaternion(target, upDir, headingDeg) {\n    const up = this._tmpVec2.copy(upDir).normalize();\n    const headingRad = degToRad(headingDeg || 0);\n\n    const east = this._tmpEast.crossVectors(this._worldUp, up);\n    if (east.lengthSq() < 1e-6) {\n      east.set(1, 0, 0);\n    }\n    east.normalize();\n\n    const north = this._tmpNorth.crossVectors(up, east).normalize();\n    const forward = this._tmpForward.set(0, 0, 0);\n    forward.addScaledVector(north, Math.cos(headingRad));\n    forward.addScaledVector(east, Math.sin(headingRad));\n\n    const right = this._tmpRight.crossVectors(forward, up).normalize();\n    this._tmpMat.makeBasis(right, up, forward.negate());\n    target.setFromRotationMatrix(this._tmpMat);\n  }\n\n  _attachEntryToObject(entry, object) {\n    if (!object || !entry) return;\n    object.userData = object.userData || {};\n    object.userData.flightEntry = entry;\n  }\n\n  _resolveEntryFromObject(object) {\n    let current = object;\n    while (current) {\n      if (current.userData?.flightEntry) return current.userData.flightEntry;\n      current = current.parent;\n    }\n    return null;\n  }\n\n  _shouldClampToTerrain(entry, alt) {\n    // Always clamp when photogrammetry is active — buildings can be taller than the\n    // standard terrain clamp threshold, so we need surface-aware placement at all altitudes\n    // below the clamp max.\n    const hasSampler = !!this._terrainSampler || (this._photogramEnabled && this._photogramGroup);\n    if (!hasSampler) return false;\n    if (entry.onGround === true) return true;\n    if (!Number.isFinite(alt)) return false;\n    // With photogrammetry active, raise the clamp threshold to account for tall buildings\n    const clampMax = this._photogramEnabled\n      ? Math.max(this.terrainClampMaxM, 5000)  // 5km when 3D tiles active\n      : this.terrainClampMaxM;\n    if (!Number.isFinite(clampMax)) return false;\n    return alt <= clampMax;\n  }\n\n  /**\n   * Enable photogrammetry-aware altitude.\n   * Call this when photorealistic 3D tiles become active.\n   * @param {THREE.Object3D|null} group The 3D tile group to raycast against\n   */\n  setPhotogrammetryGroup(group) {\n    this._photogramGroup = group || null;\n    this._photogramEnabled = !!group;\n  }\n\n  /**\n   * Sample the surface height at a given direction, accounting for\n   * photogrammetry tiles when they are active.\n   *\n   * When photorealistic 3D tiles are loaded, the terrain surface includes\n   * buildings and terrain mesh displacement. We raycast downward from high above\n   * to find the actual surface, providing correct ground-clamping for aircraft.\n   */\n  _getTerrainRadius(entry, localDir, now) {\n    const hasSampler = !!this._terrainSampler;\n    const hasPhotogram = this._photogramEnabled && this._photogramGroup;\n    if (!hasSampler && !hasPhotogram) return null;\n    if (!localDir) return null;\n\n    const lastSample = entry.lastTerrainSampleMs || 0;\n    const cacheAngle = TERRAIN_CACHE_DISTANCE_M / Math.max(1, this.planetRadius);\n    const cacheDirectionMatches = entry.terrainSampleDir?.isVector3 === true\n      && entry.terrainSampleDir.dot(localDir) >= Math.cos(cacheAngle);\n    if (Number.isFinite(entry.terrainRadius) &&\n        cacheDirectionMatches &&\n        now - lastSample < this.terrainSampleIntervalMs) {\n      return entry.terrainRadius;\n    }\n\n    // Throttle misses as well as hits. Otherwise a low aircraft outside the\n    // loaded tile set can trigger a recursive scene raycast every render frame.\n    entry.lastTerrainSampleMs = now;\n\n    const worldDir = this._tmpVec.copy(localDir).normalize();\n    if (this.parentGroup?.getWorldQuaternion) {\n      this.parentGroup.getWorldQuaternion(this._tmpQuat);\n      worldDir.applyQuaternion(this._tmpQuat);\n    }\n\n    // Try photogrammetry raycast first (highest accuracy with 3D tiles)\n    if (hasPhotogram) {\n      const photogramRadius = this._samplePhotogrammetrySurface(worldDir, localDir);\n      if (Number.isFinite(photogramRadius)) {\n        entry.terrainRadius = photogramRadius;\n        if (!entry.terrainSampleDir) entry.terrainSampleDir = new THREE.Vector3();\n        entry.terrainSampleDir.copy(localDir);\n        return photogramRadius;\n      }\n    }\n\n    // Fall back to standard terrain sampler (DEM-based)\n    if (hasSampler) {\n      const radius = this._terrainSampler(worldDir);\n      if (Number.isFinite(radius)) {\n        entry.terrainRadius = radius;\n        if (!entry.terrainSampleDir) entry.terrainSampleDir = new THREE.Vector3();\n        entry.terrainSampleDir.copy(localDir);\n        return radius;\n      }\n    }\n\n    // A stale sample is safe only while this aircraft remains at the sampled\n    // coordinate. Never reuse the camera/another track position under motion.\n    return cacheDirectionMatches ? entry.terrainRadius : null;\n  }\n\n  /**\n   * Raycast against photogrammetry tiles to find the actual surface height\n   * (including buildings, bridges, terrain mesh) at a given direction.\n   *\n   * @param {THREE.Vector3} worldDir Normalized direction in world space\n   * @param {THREE.Vector3} localDir Normalized direction in local (planet) space\n   * @returns {number|null} Radius from planet center to surface, or null\n   */\n  _samplePhotogrammetrySurface(worldDir, localDir) {\n    if (!this._photogramGroup) return null;\n\n    // Cast ray from high above (ellipsoid + 50km) downward toward center\n    const highAltitude = 50000; // 50km above surface\n    const baseRadius = ellipsoidRadiusForLocalDir(localDir);\n    const origin = this._tmpVec.copy(worldDir).multiplyScalar(baseRadius + highAltitude);\n    const direction = this._tmpVec2\n      ? this._tmpVec2.copy(worldDir).negate()\n      : worldDir.clone().negate();\n\n    this._photogramRaycaster.set(origin, direction);\n    this._photogramRaycaster.far = highAltitude + 1000; // Ray length\n\n    // Raycast against photogrammetry group (recursive)\n    const intersects = this._photogramRaycaster.intersectObject(this._photogramGroup, true);\n    if (intersects.length > 0) {\n      // The hit point distance from origin tells us the surface radius\n      const hitPoint = intersects[0].point;\n      const surfaceRadius = hitPoint.length();\n      if (surfaceRadius > baseRadius - 1000 && surfaceRadius < baseRadius + 10000) {\n        return surfaceRadius;\n      }\n    }\n    return null;\n  }\n\n  _createModelBucket(key) {\n    const bucket = {\n      key,\n      modelUrl: key,\n      ready: false,\n      loadingPromise: null,\n      root: null,\n      groundOffset: 0,\n      useInstancing: true,\n      meshes: [],\n      instancedMeshes: [],\n      lowMesh: null,\n      instances: new Map(),\n      freeList: [],\n      capacity: Math.max(1, this.maxAircraft || 1),\n      group: new THREE.Group(),\n      anchor: new THREE.Vector3(),\n      anchorValid: false,\n    };\n    bucket.group.name = `AircraftBucket:${String(key).split('/').pop()}`;\n    bucket.group.visible = this.enabled;\n    this.group.add(bucket.group);\n    return bucket;\n  }\n\n  _ensureModelBucket(bucket) {\n    if (bucket.loadingPromise) return bucket.loadingPromise;\n    bucket.loadingPromise = new Promise((resolve, reject) => {\n      this._loader.load(\n        bucket.modelUrl,\n        (gltf) => {\n          bucket.root = gltf.scene || null;\n          if (bucket.root) {\n            bucket.root.traverse((node) => {\n              if (node.isMesh) {\n                node.castShadow = true;\n                node.receiveShadow = false;\n              }\n            });\n            bucket.root.updateMatrixWorld(true);\n            const bounds = new THREE.Box3().setFromObject(bucket.root);\n            if (Number.isFinite(bounds.min.y)) {\n              bucket.groundOffset = -bounds.min.y;\n            } else {\n              bucket.groundOffset = 0;\n            }\n          }\n          bucket.useInstancing = !!bucket.root && this._supportsInstancing(bucket.root);\n          if (bucket.useInstancing) {\n            this._buildInstancedMeshes(bucket);\n          }\n          // Downscale the livery (4096² → 1024²), upload in idle time and\n          // compile the drawn (instanced) variant before the first draw: the\n          // first airliner otherwise stalled a frame ~150 ms + ~140 ms.\n          const si = this.sceneInitializer;\n          prepareModelForFirstDraw(bucket.useInstancing ? bucket.group : bucket.root, {\n            renderer: si?.renderer, camera: si?.camera, scene: si?.scene, maxTextureSize: 1024,\n          }).finally(() => {\n            bucket.ready = !!bucket.root;\n            bucket.loadingPromise = null;\n            this._assignBucketEntries(bucket);\n            resolve(bucket.root);\n          });\n        },\n        undefined,\n        (err) => {\n          console.warn('[AircraftOverlay] Failed to load model', err);\n          bucket.ready = false;\n          bucket.loadingPromise = null;\n          reject(err);\n        }\n      );\n    });\n    return bucket.loadingPromise;\n  }\n\n  _supportsInstancing(root) {\n    if (!root) return false;\n    let supported = true;\n    root.traverse((node) => {\n      if (node.isSkinnedMesh) {\n        supported = false;\n      }\n    });\n    return supported;\n  }\n\n  _buildInstancedMeshes(bucket) {\n    if (!bucket.root) return;\n    bucket.meshes = [];\n    bucket.instancedMeshes.forEach((mesh) => bucket.group.remove(mesh));\n    bucket.instancedMeshes = [];\n\n    const rootInv = new THREE.Matrix4().copy(bucket.root.matrixWorld).invert();\n    const offsetMat = new THREE.Matrix4().makeTranslation(0, bucket.groundOffset || 0, 0);\n\n    bucket.root.traverse((node) => {\n      if (!node.isMesh || node.isSkinnedMesh) return;\n      const localMat = new THREE.Matrix4().multiplyMatrices(rootInv, node.matrixWorld);\n      const baseMat = new THREE.Matrix4().multiplyMatrices(offsetMat, localMat);\n      const instanced = new THREE.InstancedMesh(node.geometry, node.material, bucket.capacity);\n      instanced.instanceMatrix.setUsage(THREE.DynamicDrawUsage);\n      instanced.userData.instancedBucketKey = bucket.key;\n      instanced.userData.isAircraftInstanced = true;\n      instanced.castShadow = true;\n      instanced.receiveShadow = false;\n      instanced.count = bucket.capacity;\n      for (let i = 0; i < bucket.capacity; i += 1) {\n        instanced.setMatrixAt(i, this._instancedHideMatrix);\n      }\n      instanced.instanceMatrix.needsUpdate = true;\n      bucket.group.add(instanced);\n      bucket.meshes.push({ baseMatrix: baseMat, instanced });\n      bucket.instancedMeshes.push(instanced);\n    });\n\n    this._buildLowLodMesh(bucket);\n  }\n\n  _ensureLowLodResources() {\n    if (!this._lowLodGeometry) {\n      this._lowLodGeometry = new THREE.OctahedronGeometry(1, 0);\n    }\n    if (!this._lowLodMaterial) {\n      const color = this._resolveLowLodColor(this.lowLodColor);\n      this._lowLodMaterial = new THREE.MeshBasicMaterial({ color });\n      this._lowLodMaterial.toneMapped = false;\n    }\n  }\n\n  _resolveLowLodColor(value) {\n    if (typeof value === 'number') return value;\n    if (typeof value === 'string') return resolveColor(value);\n    return resolveColor(getDefaultLowLodColor());\n  }\n\n  _buildLowLodMesh(bucket) {\n    if (!bucket?.useInstancing) return;\n    if (!this.lowLodEnabled) {\n      if (bucket.lowMesh) bucket.lowMesh.visible = false;\n      return;\n    }\n    this._ensureLowLodResources();\n    if (!this._lowLodGeometry || !this._lowLodMaterial) return;\n\n    if (bucket.lowMesh) {\n      bucket.group.remove(bucket.lowMesh);\n      bucket.lowMesh = null;\n    }\n\n    const instanced = new THREE.InstancedMesh(this._lowLodGeometry, this._lowLodMaterial, bucket.capacity);\n    instanced.instanceMatrix.setUsage(THREE.DynamicDrawUsage);\n    instanced.userData.instancedBucketKey = bucket.key;\n    instanced.userData.isAircraftLowLod = true;\n    instanced.castShadow = false;\n    instanced.receiveShadow = false;\n    instanced.count = bucket.capacity;\n    for (let i = 0; i < bucket.capacity; i += 1) {\n      instanced.setMatrixAt(i, this._instancedHideMatrix);\n    }\n    instanced.instanceMatrix.needsUpdate = true;\n    bucket.group.add(instanced);\n    bucket.lowMesh = instanced;\n  }\n\n  _resolveLowLodScale() {\n    if (Number.isFinite(this.lowLodScale)) {\n      return Math.max(0.0001, this.lowLodScale);\n    }\n    const baseScale = Number.isFinite(this.modelScale) ? this.modelScale : DEFAULT_MODEL_SCALE;\n    const multiplier = Number.isFinite(this.lowLodScaleMultiplier)\n      ? this.lowLodScaleMultiplier\n      : DEFAULT_LOW_LOD_SCALE_MULTIPLIER;\n    return Math.max(0.0001, baseScale * multiplier);\n  }\n\n  _syncLowLodBuckets() {\n    for (const bucket of this._modelBuckets.values()) {\n      if (!bucket?.ready || !bucket.useInstancing) continue;\n      if (this.lowLodEnabled) {\n        if (!bucket.lowMesh) {\n          this._buildLowLodMesh(bucket);\n        } else {\n          bucket.lowMesh.visible = true;\n        }\n      } else if (bucket.lowMesh) {\n        bucket.lowMesh.visible = false;\n      }\n    }\n\n    for (const entry of this._entries.values()) {\n      entry.lod = 'detail';\n      if (entry.lowObject) entry.lowObject.visible = false;\n      if (entry.object) entry.object.visible = true;\n    }\n  }\n\n  _assignBucketEntries(bucket) {\n    if (!bucket?.ready) return;\n    for (const entry of this._entries.values()) {\n      if (entry.modelKey !== bucket.key) continue;\n      if (bucket.useInstancing) {\n        if (!entry.instanceKey) {\n          this._removeFallbackObject(entry);\n          this._assignEntryInstance(entry, bucket);\n        }\n      } else if (!entry.object || entry.object.userData?.isAircraftFallback) {\n        this._removeFallbackObject(entry);\n        entry.object = this._createInstance(bucket);\n        if (entry.object) {\n          this._attachEntryToObject(entry, entry.object);\n          this.group.add(entry.object);\n        }\n      }\n    }\n  }\n\n  _assignEntryInstance(entry, bucket) {\n    if (!bucket?.useInstancing || !bucket.ready) return;\n    let index = bucket.freeList.pop();\n    if (!Number.isFinite(index)) {\n      index = bucket.instances.size;\n      if (index >= bucket.capacity) {\n        return;\n      }\n    }\n    bucket.instances.set(index, entry);\n    entry.instanceKey = bucket.key;\n    entry.instanceId = index;\n    this._hideInstance(bucket, index);\n  }\n\n  _releaseEntryRenderable(entry) {\n    if (!entry) return;\n    if (entry.labelHandle) {\n      if (entry.labelHandle.group) {\n        this.group.remove(entry.labelHandle.group);\n      }\n      entry.labelHandle.dispose();\n      entry.labelHandle = null;\n    }\n    if (entry.object) {\n      this.group.remove(entry.object);\n      this._disposeObject(entry.object);\n      entry.object = null;\n    }\n    if (entry.lowObject) {\n      this.group.remove(entry.lowObject);\n      entry.lowObject = null;\n    }\n    if (entry.instanceKey && Number.isFinite(entry.instanceId)) {\n      const bucket = this._modelBuckets.get(entry.instanceKey);\n      if (bucket) {\n        bucket.instances.delete(entry.instanceId);\n        bucket.freeList.push(entry.instanceId);\n        this._hideInstance(bucket, entry.instanceId);\n      }\n      entry.instanceKey = null;\n      entry.instanceId = null;\n    }\n    entry.lod = 'detail';\n  }\n\n  _removeFallbackObject(entry) {\n    if (!entry?.object?.userData?.isAircraftFallback) return;\n    this.group.remove(entry.object);\n    entry.object = null;\n  }\n\n  _hideInstance(bucket, index) {\n    if (!bucket) return;\n    if (bucket.meshes?.length) {\n      for (const mesh of bucket.meshes) {\n        mesh.instanced.setMatrixAt(index, this._instancedHideMatrix);\n        mesh.instanced.instanceMatrix.needsUpdate = true;\n      }\n    }\n    if (bucket.lowMesh) {\n      bucket.lowMesh.setMatrixAt(index, this._instancedHideMatrix);\n      bucket.lowMesh.instanceMatrix.needsUpdate = true;\n    }\n  }\n\n  _syncEntryModelKey(entry) {\n    const nextKey = this._resolveModelKey(entry);\n    if (!nextKey || entry.modelKey === nextKey) return;\n    this._releaseEntryRenderable(entry);\n    entry.modelKey = nextKey;\n    entry.instanceKey = null;\n    entry.instanceId = null;\n    const bucket = this._getModelBucketForEntry(entry);\n    if (bucket?.ready) {\n      if (bucket.useInstancing) {\n        this._assignEntryInstance(entry, bucket);\n      } else {\n        entry.object = this._createInstance(bucket);\n        if (entry.object) {\n          this._attachEntryToObject(entry, entry.object);\n          this.group.add(entry.object);\n        }\n      }\n    }\n  }\n\n  updateHover(raycaster,camera,options) {\n    if(this.catalog){if(options)this.catalog.updateHover(raycaster,camera,options);return;}\n    if (!raycaster || !this.group?.children?.length) {\n      this._hoveredEntry = null;\n      return;\n    }\n    this.group.updateMatrixWorld(true);\n    const hits = raycaster.intersectObjects(this.group.children, true);\n    if (!hits.length) {\n      this._hoveredEntry = null;\n      return;\n    }\n    const hit = hits[0];\n    let entry = this._resolveEntryFromObject(hit.object);\n    if (!entry && hit?.object?.isInstancedMesh && Number.isFinite(hit.instanceId)) {\n      const bucketKey = hit.object.userData?.instancedBucketKey;\n      const bucket = bucketKey ? this._modelBuckets.get(bucketKey) : null;\n      entry = bucket?.instances?.get(hit.instanceId) || null;\n    }\n    this._hoveredEntry = entry || null;\n  }\n\n  clearHover() {\n    this.catalog?.leave();this._hoveredEntry = null;\n  }\n\n  getHoveredAircraft() {\n    return this.catalog?.hovered || this._hoveredEntry;\n  }\n\n  selectAtClient(x,y){return this.catalog?.selectAtClient(x,y)??null;}\n\n  _buildAircraftLabelSubText(entry) {\n    const altitudeM = Number.isFinite(entry.predictedAlt)\n      ? entry.predictedAlt\n      : (Number.isFinite(entry.altitudeM) ? entry.altitudeM : null);\n    const velocityMps = Number.isFinite(entry.smoothedVelocityMps)\n      ? entry.smoothedVelocityMps\n      : entry.velocityMps;\n    const altitude = Number.isFinite(altitudeM) ? `${Math.round(altitudeM * 3.28084).toLocaleString('en-US')}ft` : '';\n    const speed = Number.isFinite(velocityMps) ? `${Math.round(velocityMps * 1.94384).toLocaleString('en-US')}kt` : '';\n    return [altitude, speed].filter(Boolean).join(' · ');\n  }\n\n  _buildAircraftLabelMetadata(entry) {\n    const lat = Number.isFinite(entry.predictedLat) ? entry.predictedLat : entry.lat;\n    const lon = Number.isFinite(entry.predictedLon) ? entry.predictedLon : entry.lon;\n    const altitudeM = Number.isFinite(entry.predictedAlt)\n      ? entry.predictedAlt\n      : (Number.isFinite(entry.altitudeM) ? entry.altitudeM : null);\n    const velocityMps = Number.isFinite(entry.smoothedVelocityMps)\n      ? entry.smoothedVelocityMps\n      : entry.velocityMps;\n    const headingDeg = Number.isFinite(entry.smoothedHeadingDeg)\n      ? entry.smoothedHeadingDeg\n      : entry.headingDeg;\n    const verticalRateMps = Number.isFinite(entry.smoothedVerticalRateMps)\n      ? entry.smoothedVerticalRateMps\n      : entry.verticalRateMps;\n    return {\n      entityType: 'aircraft',\n      typeLabel: 'Aircraft',\n      trackable: true,\n      listKey: 'viewshed.aircraft',\n      id: entry.id,\n      rawId: entry.rawId,\n      callsign: entry.callsign,\n      name: entry.callsign || entry.rawId || entry.id || 'Aircraft',\n      aircraftType: entry.aircraftType,\n      lat,\n      lon,\n      altitudeM,\n      velocityMps,\n      headingDeg,\n      verticalRateMps,\n      onGround: entry.onGround,\n      source: entry.source,\n      lastContactMs: entry.lastContactMs,\n      updatedAtMs: entry.updatedAtMs,\n    };\n  }\n\n  getEntriesSnapshot() {\n    if(this.catalog)return this.catalog.getEntriesSnapshot();\n    const entries = [];\n    for (const entry of this._entries.values()) {\n      const lat = Number.isFinite(entry.predictedLat) ? entry.predictedLat : entry.lat;\n      const lon = Number.isFinite(entry.predictedLon) ? entry.predictedLon : entry.lon;\n      const altitudeM = Number.isFinite(entry.predictedAlt)\n        ? entry.predictedAlt\n        : (Number.isFinite(entry.altitudeM) ? entry.altitudeM : null);\n      const velocityMps = Number.isFinite(entry.smoothedVelocityMps)\n        ? entry.smoothedVelocityMps\n        : entry.velocityMps;\n      const headingDeg = Number.isFinite(entry.smoothedHeadingDeg)\n        ? entry.smoothedHeadingDeg\n        : entry.headingDeg;\n      const verticalRateMps = Number.isFinite(entry.smoothedVerticalRateMps)\n        ? entry.smoothedVerticalRateMps\n        : entry.verticalRateMps;\n\n      entries.push({\n        id: entry.id,\n        rawId: entry.rawId,\n        callsign: entry.callsign,\n        aircraftType: entry.aircraftType,\n        lat,\n        lon,\n        altitudeM,\n        velocityMps,\n        headingDeg,\n        verticalRateMps,\n        onGround: entry.onGround,\n        source: entry.source,\n        lastContactMs: entry.lastContactMs,\n        updatedAtMs: entry.updatedAtMs,\n      });\n    }\n    return entries;\n  }\n\n  _seedPathHistory(entry, points) {\n    if (!entry || entry.pathSeeded || !Array.isArray(points) || !points.length) return;\n    const fallbackAltitude = Number.isFinite(entry.predictedAlt)\n      ? entry.predictedAlt\n      : entry.altitudeM;\n    const seeded = normalizeAircraftPathHistory(points, fallbackAltitude);\n    if (!seeded.length) return;\n    entry.pathHistory = seeded;\n    entry.pathSeeded = true;\n    entry.lastPathSampleMs = seeded[seeded.length - 1]?.timeMs || Date.now();\n    this._prunePathHistory(entry, entry.lastPathSampleMs);\n    if (this.showPaths) {\n      this._rebuildPathLine(entry);\n    }\n  }\n\n  _appendPathPoint(entry, lat, lon, altM, nowMs) {\n    if (!entry || !Number.isFinite(lat) || !Number.isFinite(lon)) return;\n    if (!entry.pathHistory) entry.pathHistory = [];\n    if (entry.lastPathSampleMs && nowMs - entry.lastPathSampleMs < this.pathSampleIntervalMs) {\n      return;\n    }\n    const nextPoint = {\n      lat,\n      lon,\n      altM: Number.isFinite(altM)\n        ? altM\n        : (Number.isFinite(entry.predictedAlt) ? entry.predictedAlt : entry.altitudeM),\n      timeMs: nowMs,\n    };\n    const previous = entry.pathHistory.at(-1);\n    if (previous) {\n      const continuous = normalizeAircraftPathHistory([previous, nextPoint], nextPoint.altM);\n      if (continuous.length < 2) entry.pathHistory = [];\n    }\n    entry.pathHistory.push(nextPoint);\n    entry.lastPathSampleMs = nowMs;\n    this._prunePathHistory(entry, nowMs);\n    if (this.showPaths) {\n      this._rebuildPathLine(entry);\n    }\n  }\n\n  _prunePathHistory(entry, nowMs) {\n    if (!entry?.pathHistory?.length) return;\n    const windowMs = Number.isFinite(this.pathHours) ? this.pathHours * 60 * 60 * 1000 : 0;\n    if (windowMs > 0) {\n      const cutoff = nowMs - windowMs;\n      while (entry.pathHistory.length && entry.pathHistory[0].timeMs < cutoff) {\n        entry.pathHistory.shift();\n      }\n    }\n    if (Number.isFinite(this.pathMaxPoints) && this.pathMaxPoints > 0 && entry.pathHistory.length > this.pathMaxPoints) {\n      entry.pathHistory.splice(0, entry.pathHistory.length - this.pathMaxPoints);\n    }\n  }\n\n  _rebuildPathLine(entry) {\n    if (!this.showPaths) return;\n    if (!entry?.pathHistory || entry.pathHistory.length < 2) {\n      if (entry?.pathLine) entry.pathLine.visible = false;\n      return;\n    }\n\n    if (!entry.pathLine) {\n      const geometry = new THREE.BufferGeometry();\n      const line = new THREE.Line(geometry, this._pathMaterial);\n      line.name = 'AircraftPath';\n      line.userData.aircraftEntry = entry;\n      entry.pathLine = line;\n      this.group.add(line);\n    }\n\n    const samples = buildSmoothedAircraftPathSamples(entry.pathHistory);\n    const sampleCount = samples.length / 4;\n    if (sampleCount < 2) {\n      entry.pathLine.visible = false;\n      return;\n    }\n    const positions = new Float32Array(sampleCount * 3);\n    const colors = new Float32Array(sampleCount * 3);\n    const alphas = new Float32Array(sampleCount);\n    const dashScales = new Float32Array(sampleCount);\n    const gapScales = new Float32Array(sampleCount);\n    const lowColor = PATH_COLOR_LOW;\n    const highColor = PATH_COLOR_HIGH;\n    const lastIndex = sampleCount - 1;\n    const dir = new THREE.Vector3();\n    for (let i = 0; i < sampleCount; i += 1) {\n      const sampleOffset = i * 4;\n      const altitude = samples[sampleOffset + 3] + this.altitudeOffsetM;\n      dir.set(\n        samples[sampleOffset],\n        samples[sampleOffset + 1],\n        samples[sampleOffset + 2]\n      );\n      const baseRadius = ellipsoidRadiusForLocalDir(dir);\n      positions[i * 3] = dir.x * (baseRadius + altitude);\n      positions[i * 3 + 1] = dir.y * (baseRadius + altitude);\n      positions[i * 3 + 2] = dir.z * (baseRadius + altitude);\n      const t = i / lastIndex;\n      alphas[i] = Math.pow(t, PATH_ALPHA_POWER);\n      const tailEase = Math.pow(1 - t, PATH_DASH_TAPER_POWER);\n      dashScales[i] = 1 - (1 - PATH_DASH_TAPER_MIN_SCALE) * tailEase;\n      gapScales[i] = 1 + (PATH_GAP_TAPER_MAX_SCALE - 1) * tailEase;\n      const altT = PATH_ALT_RANGE_M > 0\n        ? clamp01((altitude - PATH_ALT_MIN_M) / PATH_ALT_RANGE_M)\n        : 0;\n      colors[i * 3] = lowColor.r + (highColor.r - lowColor.r) * altT;\n      colors[i * 3 + 1] = lowColor.g + (highColor.g - lowColor.g) * altT;\n      colors[i * 3 + 2] = lowColor.b + (highColor.b - lowColor.b) * altT;\n    }\n\n    updateTrailAttributes(entry.pathLine.geometry, [\n      { name: 'position', array: positions, itemSize: 3 },\n      { name: 'color', array: colors, itemSize: 3 },\n      { name: 'alpha', array: alphas, itemSize: 1 },\n      { name: 'dashScale', array: dashScales, itemSize: 1 },\n      { name: 'gapScale', array: gapScales, itemSize: 1 },\n    ]);\n    entry.pathLine.geometry.computeBoundingSphere();\n    entry.pathLine.computeLineDistances();\n    entry.pathLine.visible = true;\n  }\n\n  _updatePathTail(entry) {\n    if (!this.showPaths || !entry?.pathLine) return;\n    const positionAttr = entry.pathLine.geometry.getAttribute('position');\n    if (!positionAttr || positionAttr.count < 1) return;\n    const lastIndex = positionAttr.count - 1;\n    const lat = Number.isFinite(entry.predictedLat) ? entry.predictedLat : entry.lat;\n    const lon = Number.isFinite(entry.predictedLon) ? entry.predictedLon : entry.lon;\n    const trajectoryAlt = Number.isFinite(entry.predictedAlt)\n      ? entry.predictedAlt\n      : entry.altitudeM;\n    if (!Number.isFinite(lat) || !Number.isFinite(lon) || !Number.isFinite(trajectoryAlt)) return;\n    const dir = latLonToLocalDir(lat, lon);\n    const baseRadius = ellipsoidRadiusForLocalDir(dir);\n    const pos = this._tmpVec3.copy(dir).multiplyScalar(\n      baseRadius + trajectoryAlt + this.altitudeOffsetM\n    );\n    positionAttr.setXYZ(lastIndex, pos.x, pos.y, pos.z);\n    positionAttr.needsUpdate = true;\n    const lineDistanceAttr = entry.pathLine.geometry.getAttribute('lineDistance');\n    if (lineDistanceAttr?.count === positionAttr.count && lastIndex > 0) {\n      const previousIndex = lastIndex - 1;\n      const dx = pos.x - positionAttr.getX(previousIndex);\n      const dy = pos.y - positionAttr.getY(previousIndex);\n      const dz = pos.z - positionAttr.getZ(previousIndex);\n      lineDistanceAttr.setX(\n        lastIndex,\n        lineDistanceAttr.getX(previousIndex) + Math.hypot(dx, dy, dz)\n      );\n      lineDistanceAttr.needsUpdate = true;\n    }\n  }\n\n  _createLowLodObject(entry) {\n    if (!this.lowLodEnabled) return null;\n    this._ensureLowLodResources();\n    if (!this._lowLodGeometry || !this._lowLodMaterial) return null;\n    const mesh = new THREE.Mesh(this._lowLodGeometry, this._lowLodMaterial);\n    mesh.name = 'AircraftLowLod';\n    mesh.castShadow = false;\n    mesh.receiveShadow = false;\n    mesh.visible = false;\n    if (entry) {\n      this._attachEntryToObject(entry, mesh);\n    }\n    return mesh;\n  }\n\n  _createInstance(bucket) {\n    if (!bucket?.root) return null;\n    const instance = SkeletonUtils.clone(bucket.root);\n    instance.name = 'AircraftModel';\n    const wrapper = new THREE.Group();\n    wrapper.name = 'AircraftInstance';\n    wrapper.userData.isAircraftInstance = true;\n    if (Number.isFinite(bucket.groundOffset) && bucket.groundOffset !== 0) {\n      instance.position.set(0, bucket.groundOffset, 0);\n    }\n    wrapper.add(instance);\n    wrapper.scale.setScalar(this.modelScale);\n    return wrapper;\n  }\n\n  _resolveFallbackAircraftScale() {\n    const modelScale = Number.isFinite(this.modelScale) ? this.modelScale : DEFAULT_MODEL_SCALE;\n    return Math.max(0.01, modelScale * 120);\n  }\n\n  _createFallbackInstance(entry) {\n    const mesh = new THREE.Mesh(FALLBACK_AIRCRAFT_GEOMETRY, FALLBACK_AIRCRAFT_MATERIAL);\n    mesh.name = 'AircraftLoadingFallback';\n    mesh.castShadow = true;\n    mesh.receiveShadow = false;\n    mesh.scale.setScalar(this._resolveFallbackAircraftScale());\n    mesh.userData.isAircraftFallback = true;\n    this._attachEntryToObject(entry, mesh);\n    return mesh;\n  }\n\n  _disposeObject(object) {\n    if (!object) return;\n    if (object.userData?.isAircraftInstance || object.userData?.isAircraftFallback) return;\n    object.traverse((node) => {\n      if (node.geometry) node.geometry.dispose();\n      if (node.material) {\n        if (Array.isArray(node.material)) {\n          node.material.forEach((mat) => mat.dispose && mat.dispose());\n        } else if (node.material.dispose) {\n          node.material.dispose();\n        }\n      }\n    });\n  }\n\n  _disposeBucket(bucket) {\n    if (!bucket) return;\n    if (bucket.group?.parent) {\n      bucket.group.parent.remove(bucket.group);\n    }\n    if (bucket.instancedMeshes?.length) {\n      for (const instanced of bucket.instancedMeshes) {\n        if (instanced.parent) instanced.parent.remove(instanced);\n        if (instanced.geometry) instanced.geometry.dispose();\n        if (instanced.material) {\n          if (Array.isArray(instanced.material)) {\n            instanced.material.forEach((mat) => mat.dispose && mat.dispose());\n          } else if (instanced.material.dispose) {\n            instanced.material.dispose();\n          }\n        }\n      }\n      bucket.instancedMeshes = [];\n      bucket.meshes = [];\n    }\n    if (bucket.lowMesh) {\n      if (bucket.lowMesh.parent) bucket.lowMesh.parent.remove(bucket.lowMesh);\n      bucket.lowMesh = null;\n    }\n    if (bucket.root && !bucket.useInstancing) {\n      this._disposeObject(bucket.root);\n    }\n    bucket.root = null;\n    bucket.instances?.clear?.();\n    bucket.freeList = [];\n  }\n\n  _disposeLowLodResources() {\n    if (this._lowLodGeometry) {\n      this._lowLodGeometry.dispose();\n      this._lowLodGeometry = null;\n    }\n    if (this._lowLodMaterial) {\n      this._lowLodMaterial.dispose();\n      this._lowLodMaterial = null;\n    }\n  }\n\n  _bindConfigListener() {\n    if (!this.eventBus || typeof this.eventBus.on !== 'function') return;\n    this._configListener = (config) => this._handleConfigUpdate(config);\n    this.eventBus.on('flights:config', this._configListener);\n  }\n\n  _unbindConfigListener() {\n    if (!this.eventBus || typeof this.eventBus.off !== 'function') return;\n    if (!this._configListener) return;\n    this.eventBus.off('flights:config', this._configListener);\n    this._configListener = null;\n  }\n\n  _handleConfigUpdate(config = {}) {\n    if(this.catalog){if(typeof config.enabled==='boolean'){this.catalog.enabled=config.enabled;this.catalog.worker?.postMessage({type:'active',generation:this.catalog.generation,active:config.enabled});}if(typeof config.showPaths==='boolean')this.catalog.showPaths=config.showPaths;}\n    if (typeof config.enabled === 'boolean') {\n      this.enabled = config.enabled;\n      this.group.visible = config.enabled;\n      for (const bucket of this._modelBuckets.values()) {\n        bucket.group.visible = config.enabled;\n      }\n      if (!config.enabled) {\n        this.clear();\n      }\n    }\n    if (typeof config.provider === 'string') {\n      if (config.provider !== this.provider) {\n        this.provider = config.provider;\n        this.clear();\n        this._refreshQueued = true;\n      }\n    }\n    if (typeof config.queryMode === 'string') {\n      if (config.queryMode !== this.queryMode) {\n        this.queryMode = config.queryMode;\n        this.clear();\n        this._refreshQueued = true;\n      }\n    }\n    if (typeof config.queryValue === 'string') {\n      if (config.queryValue !== this.queryValue) {\n        this.queryValue = config.queryValue;\n        this.clear();\n        this._refreshQueued = true;\n      }\n    }\n    if (Number.isFinite(config.radiusNm)) this.radiusNm = config.radiusNm;\n    if (Number.isFinite(config.coneAngleDeg)) this.coneAngleDeg = config.coneAngleDeg;\n    if (Number.isFinite(config.maxAircraft)) this.maxAircraft = config.maxAircraft;\n    if (Number.isFinite(config.pollIntervalMs)) this.pollIntervalMs = config.pollIntervalMs;\n    if (Number.isFinite(config.staleAfterMs)) this.staleAfterMs = config.staleAfterMs;\n    if (Number.isFinite(config.predictionMaxMs)) {\n      this.predictionMaxMs = resolvePredictionWindowMs({\n        predictionMaxMs: config.predictionMaxMs,\n        pollIntervalMs: this.pollIntervalMs,\n        staleAfterMs: this.staleAfterMs,\n      });\n    } else if (Number.isFinite(config.pollIntervalMs) || Number.isFinite(config.staleAfterMs)) {\n      this.predictionMaxMs = resolvePredictionWindowMs({\n        predictionMaxMs: this.predictionMaxMs,\n        pollIntervalMs: this.pollIntervalMs,\n        staleAfterMs: this.staleAfterMs,\n      });\n    }\n    if (Number.isFinite(config.modelScale)) {\n      this.modelScale = config.modelScale;\n      for (const entry of this._entries.values()) {\n        if (entry.object) {\n          entry.object.scale.setScalar(entry.object.userData?.isAircraftFallback\n            ? this._resolveFallbackAircraftScale()\n            : this.modelScale);\n        }\n      }\n    }\n    if (Number.isFinite(config.headingOffsetDeg)) this.headingOffsetDeg = config.headingOffsetDeg;\n    if (Number.isFinite(config.altitudeOffsetM)) {\n      this.altitudeOffsetM = config.altitudeOffsetM;\n      if (this.showPaths) this._refreshQueued = true;\n    }\n    if (typeof config.showPaths === 'boolean') {\n      this.showPaths = config.showPaths;\n      if (!this.showPaths) {\n        for (const entry of this._entries.values()) {\n          if (entry.pathLine) {\n            this.group.remove(entry.pathLine);\n            entry.pathLine.geometry.dispose();\n            entry.pathLine = null;\n          }\n        }\n      } else {\n        for (const entry of this._entries.values()) {\n          if (entry.pathHistory?.length) {\n            this._rebuildPathLine(entry);\n          }\n        }\n        this._refreshQueued = true;\n      }\n    }\n    if (Number.isFinite(config.pathHours)) {\n      this.pathHours = config.pathHours;\n      if (this.showPaths) {\n        const now = Date.now();\n        for (const entry of this._entries.values()) {\n          this._prunePathHistory(entry, now);\n          this._rebuildPathLine(entry);\n        }\n      }\n    }\n    if (Number.isFinite(config.pathMaxPoints)) {\n      this.pathMaxPoints = config.pathMaxPoints;\n      if (this.showPaths) {\n        const now = Date.now();\n        for (const entry of this._entries.values()) {\n          this._prunePathHistory(entry, now);\n          this._rebuildPathLine(entry);\n        }\n      }\n    }\n\n    const prevLowLodEnabled = this.lowLodEnabled;\n    let lodConfigChanged = false;\n    if (typeof config.lowLodEnabled === 'boolean') {\n      this.lowLodEnabled = config.lowLodEnabled;\n      lodConfigChanged = true;\n    }\n    if (Number.isFinite(config.lowLodDistanceM)) {\n      this.lowLodDistanceM = config.lowLodDistanceM;\n      lodConfigChanged = true;\n    }\n    if (Number.isFinite(config.lowLodHysteresisM)) {\n      this.lowLodHysteresisM = config.lowLodHysteresisM;\n      lodConfigChanged = true;\n    }\n    if (Number.isFinite(config.lowLodScaleMultiplier)) {\n      this.lowLodScaleMultiplier = config.lowLodScaleMultiplier;\n      lodConfigChanged = true;\n    }\n    if (Number.isFinite(config.lowLodScale)) {\n      this.lowLodScale = config.lowLodScale;\n      lodConfigChanged = true;\n    }\n    if (typeof config.lowLodColor === 'string' || typeof config.lowLodColor === 'number') {\n      this.lowLodColor = config.lowLodColor;\n      if (this._lowLodMaterial) {\n        this._lowLodMaterial.color.set(this._resolveLowLodColor(this.lowLodColor));\n      }\n    }\n    if (Number.isFinite(config.cullDistanceM)) {\n      this.cullDistanceM = config.cullDistanceM;\n    }\n    if (Number.isFinite(config.cullHysteresisM)) {\n      this.cullHysteresisM = config.cullHysteresisM;\n    }\n    if (prevLowLodEnabled !== this.lowLodEnabled) {\n      this._syncLowLodBuckets();\n      lodConfigChanged = true;\n    }\n    if (lodConfigChanged) {\n      for (const entry of this._entries.values()) {\n        entry.lod = 'detail';\n      }\n    }\n\n    if (config.modelUrl && config.modelUrl !== this.modelUrl) {\n      this.modelUrl = config.modelUrl;\n      this.clear();\n      for (const bucket of this._modelBuckets.values()) {\n        this._disposeBucket(bucket);\n      }\n      this._modelBuckets.clear();\n      this._refreshQueued = true;\n    }\n  }\n}\n","/**\n * MaritimeApiService\n *\n * Client for maritime vessel data endpoints.\n */\n\nimport { getAuthService } from '../auth/AuthService.js';\nimport { getBackendApiBase } from '../shared/backend.js';\n\nconst API_BASE = getBackendApiBase();\n\nexport class MaritimeApiService {\n  constructor() {\n    this.authService = getAuthService();\n  }\n\n  async listProviders() {\n    const response = await this.authService.authenticatedFetch(`${API_BASE}/maritime/providers`);\n    const data = await response.json();\n    if (!response.ok) {\n      throw new Error(data.error || 'Failed to load maritime providers');\n    }\n    return data.providers || [];\n  }\n\n  async getVessels(params = {}) {\n    const search = new URLSearchParams();\n    Object.entries(params).forEach(([key, value]) => {\n      if (value === undefined || value === null || value === '') return;\n      search.set(key, String(value));\n    });\n    const url = `${API_BASE}/maritime/near?${search.toString()}`;\n    const response = await this.authService.authenticatedFetch(url);\n    const data = await response.json();\n    if (!response.ok) {\n      throw new Error(data.error || 'Failed to fetch maritime vessels');\n    }\n    return data;\n  }\n}\n\nlet maritimeApiServiceInstance = null;\n\nexport function getMaritimeApiService() {\n  if (!maritimeApiServiceInstance) {\n    maritimeApiServiceInstance = new MaritimeApiService();\n  }\n  return maritimeApiServiceInstance;\n}\n","/**\n * MaritimeOverlay\n *\n * Fetches vessel states from backend and renders maritime markers on the surface.\n * Uses high-precision direction * radius positioning to avoid jitter.\n */\n\nimport * as THREE from 'three';\nimport { latLonToLocalDir, geodesicDestinationWGS84, ellipsoidRadiusForLocalDir, updateTrailAttributes } from '../../modules/geometry-utils.js';\nimport { PLANET_RADIUS } from '../../modules/constants.js';\nimport { getMaritimeApiService } from '../maritime/MaritimeApiService.js';\nimport { getLabelSystem } from '../labels/LabelSystem.js';\n\nconst DEFAULT_POLL_INTERVAL_MS = 60000;\nconst DEFAULT_STALE_MS = 10 * 60 * 1000;\nconst DEFAULT_PREDICT_MS = 60000;\nconst DEFAULT_RADIUS_NM = 80;\nconst DEFAULT_CONE_ANGLE_DEG = 180;\nconst DEFAULT_MAX_VESSELS = 200;\nconst DEFAULT_LOOKBACK_MINUTES = 30;\nconst DEFAULT_MODEL_SCALE = 1;\nconst DEFAULT_HEADING_OFFSET_DEG = 0;\nconst DEFAULT_ALTITUDE_OFFSET_M = 0;\nconst DEFAULT_SMOOTH_MS = 1500;\nconst DEFAULT_SHOW_PATHS = false;\nconst DEFAULT_PATH_HOURS = 24;\nconst DEFAULT_PATH_MAX_POINTS = 120;\nconst PATH_SAMPLE_INTERVAL_MS = 2000;\nconst MARKER_COLOR = 0x39c6ff;\nconst PATH_COLOR = 0x39c6ff;\nconst PATH_DASH_SIZE = 100;\nconst PATH_GAP_SIZE = 60;\n\nconst toNumber = (value) => (Number.isFinite(value) ? value : null);\nconst degToRad = (deg) => (deg * Math.PI) / 180;\nconst wrapAngleDeg = (deg) => ((deg + 180) % 360 + 360) % 360 - 180;\n\nconst parseTimeMs = (value, fallback) => {\n  if (value === null || value === undefined) return fallback;\n  if (typeof value === 'number' && Number.isFinite(value)) return value;\n  if (value instanceof Date) {\n    const ts = value.getTime();\n    return Number.isFinite(ts) ? ts : fallback;\n  }\n  const parsed = Date.parse(value);\n  return Number.isFinite(parsed) ? parsed : fallback;\n};\n\nconst advanceLatLon = (latDeg, lonDeg, headingDeg, distanceM, radiusM = PLANET_RADIUS) => {\n  const dest = geodesicDestinationWGS84(latDeg, lonDeg, headingDeg, distanceM);\n  if (dest) {\n    return { lat: dest.latDeg, lon: dest.lonDeg };\n  }\n  const angularDistance = distanceM / Math.max(1, radiusM);\n  const lat1 = degToRad(latDeg);\n  const lon1 = degToRad(lonDeg);\n  const heading = degToRad(headingDeg);\n\n  const sinLat1 = Math.sin(lat1);\n  const cosLat1 = Math.cos(lat1);\n  const sinAd = Math.sin(angularDistance);\n  const cosAd = Math.cos(angularDistance);\n\n  const lat2 = Math.asin(\n    sinLat1 * cosAd + cosLat1 * sinAd * Math.cos(heading)\n  );\n  const lon2 = lon1 + Math.atan2(\n    Math.sin(heading) * sinAd * cosLat1,\n    cosAd - sinLat1 * Math.sin(lat2)\n  );\n\n  return {\n    lat: (lat2 * 180) / Math.PI,\n    lon: (lon2 * 180) / Math.PI,\n  };\n};\n\nexport class MaritimeOverlay {\n  constructor({\n    parentGroup,\n    planetRadius,\n    eventBus,\n    sceneInitializer,\n    provider,\n    queryMode,\n    queryValue,\n    pollIntervalMs,\n    staleAfterMs,\n    predictionMaxMs,\n    radiusNm,\n    coneAngleDeg,\n    maxVessels,\n    lookbackMinutes,\n    modelScale,\n    headingOffsetDeg,\n    altitudeOffsetM,\n    smoothingMs,\n    showPaths,\n    pathHours,\n    pathMaxPoints,\n    enabled,\n  } = {}) {\n    this.parentGroup = parentGroup || null;\n    this.planetRadius = Number.isFinite(planetRadius) ? planetRadius : PLANET_RADIUS;\n    this.eventBus = eventBus || null;\n    this.sceneInitializer = sceneInitializer || null;\n\n    this.enabled = enabled === true;\n    this.provider = provider || 'digitraffic';\n    this.queryMode = queryMode || 'latest';\n    this.queryValue = queryValue || '';\n    this.radiusNm = Number.isFinite(radiusNm) ? radiusNm : DEFAULT_RADIUS_NM;\n    this.coneAngleDeg = Number.isFinite(coneAngleDeg) ? coneAngleDeg : DEFAULT_CONE_ANGLE_DEG;\n    this.maxVessels = Number.isFinite(maxVessels) ? maxVessels : DEFAULT_MAX_VESSELS;\n    this.pollIntervalMs = Number.isFinite(pollIntervalMs) ? pollIntervalMs : DEFAULT_POLL_INTERVAL_MS;\n    this.staleAfterMs = Number.isFinite(staleAfterMs) ? staleAfterMs : DEFAULT_STALE_MS;\n    this.predictionMaxMs = Number.isFinite(predictionMaxMs) ? predictionMaxMs : DEFAULT_PREDICT_MS;\n    this.lookbackMinutes = Number.isFinite(lookbackMinutes) ? lookbackMinutes : DEFAULT_LOOKBACK_MINUTES;\n    this.modelScale = Number.isFinite(modelScale) ? modelScale : DEFAULT_MODEL_SCALE;\n    this.headingOffsetDeg = Number.isFinite(headingOffsetDeg) ? headingOffsetDeg : DEFAULT_HEADING_OFFSET_DEG;\n    this.altitudeOffsetM = Number.isFinite(altitudeOffsetM) ? altitudeOffsetM : DEFAULT_ALTITUDE_OFFSET_M;\n    this.smoothingMs = Number.isFinite(smoothingMs) ? smoothingMs : DEFAULT_SMOOTH_MS;\n    this.showPaths = showPaths === true ? true : DEFAULT_SHOW_PATHS;\n    this.pathHours = Number.isFinite(pathHours) ? pathHours : DEFAULT_PATH_HOURS;\n    this.pathMaxPoints = Number.isFinite(pathMaxPoints) ? pathMaxPoints : DEFAULT_PATH_MAX_POINTS;\n    this.pathSampleIntervalMs = PATH_SAMPLE_INTERVAL_MS;\n\n    this._center = null;\n    this._pollElapsedMs = 0;\n    this._refreshQueued = false;\n    this._inflight = false;\n\n    this._api = getMaritimeApiService();\n    this._entries = new Map();\n    this._hoveredEntry = null;\n\n    this._labelSystem = null;\n    this._labelsEnabled = true;\n\n    this._worldUp = new THREE.Vector3(0, 1, 0);\n    this._tmpVec = new THREE.Vector3();\n    this._tmpVec2 = new THREE.Vector3();\n    this._tmpMat = new THREE.Matrix4();\n    this._tmpQuat = new THREE.Quaternion();\n    this._tmpEast = new THREE.Vector3();\n    this._tmpNorth = new THREE.Vector3();\n    this._tmpForward = new THREE.Vector3();\n    this._tmpRight = new THREE.Vector3();\n\n    this._markerMaterial = new THREE.MeshBasicMaterial({\n      color: MARKER_COLOR,\n      transparent: true,\n      opacity: 0.95,\n    });\n    this._markerMaterial.toneMapped = false;\n\n    this._hullGeometry = new THREE.BoxGeometry(6, 2, 18);\n    this._bowGeometry = new THREE.ConeGeometry(2, 6, 8);\n\n    this._pathMaterial = new THREE.LineDashedMaterial({\n      color: PATH_COLOR,\n      dashSize: PATH_DASH_SIZE,\n      gapSize: PATH_GAP_SIZE,\n      transparent: true,\n      opacity: 0.85,\n    });\n    this._pathMaterial.vertexColors = true;\n    this._pathMaterial.toneMapped = false;\n\n    this.group = new THREE.Group();\n    this.group.name = 'MaritimeOverlay';\n    this.group.visible = this.enabled;\n    this.parentGroup?.add(this.group);\n\n    if (this.sceneInitializer && typeof this.sceneInitializer.addDepthPassExclude === 'function') {\n      this.sceneInitializer.addDepthPassExclude(this.group);\n    }\n\n    this._bindConfigListener();\n  }\n\n  setCenter(lat, lon, opts = {}) {\n    if (!Number.isFinite(lat) || !Number.isFinite(lon)) return;\n    this._center = { lat, lon };\n    if (Number.isFinite(opts.radiusNm)) this.radiusNm = opts.radiusNm;\n    if (Number.isFinite(opts.coneAngleDeg)) this.coneAngleDeg = opts.coneAngleDeg;\n    if (Number.isFinite(opts.maxVessels)) this.maxVessels = opts.maxVessels;\n    if (Number.isFinite(opts.pollIntervalMs)) this.pollIntervalMs = opts.pollIntervalMs;\n    this._refreshQueued = true;\n  }\n\n  refresh() {\n    this._refreshQueued = true;\n  }\n\n  clear() {\n    for (const entry of this._entries.values()) {\n      this._disposeEntry(entry);\n    }\n    this._entries.clear();\n    this._hoveredEntry = null;\n  }\n\n  dispose() {\n    this.clear();\n    if (this.group && this.group.parent) {\n      this.group.parent.remove(this.group);\n    }\n    this._markerMaterial.dispose();\n    this._hullGeometry.dispose();\n    this._bowGeometry.dispose();\n    this._pathMaterial.dispose();\n    if (this.sceneInitializer && typeof this.sceneInitializer.removeDepthPassExclude === 'function') {\n      this.sceneInitializer.removeDepthPassExclude(this.group);\n    }\n    this._unbindConfigListener();\n    this._labelSystem = null;\n  }\n\n  /**\n   * Set camera altitude for orbit-distance marker scaling.\n   * @param {number} altKm Camera altitude in kilometers\n   */\n  setCameraAltitude(altKm) {\n    const logScale = 1 + Math.log10(1 + Math.max(0.01, altKm) * 0.5) * 2.5;\n    if (Math.abs(logScale - (this._lastOrbitScale || 1)) < 0.1) return; // Avoid thrashing\n    this._lastOrbitScale = logScale;\n    const scaledSize = this.modelScale * logScale;\n    for (const entry of this._entries.values()) {\n      if (entry.object) entry.object.scale.setScalar(scaledSize);\n    }\n  }\n\n  update(dt) {\n    if (!this.enabled) return;\n    const deltaMs = (Number.isFinite(dt) ? dt : 0) * 1000;\n    this._pollElapsedMs += deltaMs;\n    if (this._refreshQueued || this._pollElapsedMs >= this.pollIntervalMs) {\n      this._pollElapsedMs = 0;\n      this._refreshQueued = false;\n      this._fetchVessels();\n    }\n    this._advanceEntries(deltaMs);\n  }\n\n  async _fetchVessels() {\n    if (this._inflight) return;\n    if (!this.enabled) return;\n\n    this._inflight = true;\n    try {\n      const params = {\n        provider: this.provider,\n        mode: this.queryMode,\n        queryValue: this.queryValue,\n        maxResults: this.maxVessels,\n        staleAfterMs: this.staleAfterMs,\n        coneAngleDeg: this.coneAngleDeg,\n        radiusNm: this.radiusNm,\n        lookbackMinutes: this.lookbackMinutes,\n        includePaths: this.showPaths ? true : undefined,\n        pathHours: this.showPaths ? this.pathHours : undefined,\n        pathMaxPoints: this.showPaths ? this.pathMaxPoints : undefined,\n      };\n      if (this._center) {\n        params.lat = this._center.lat;\n        params.lon = this._center.lon;\n      }\n      const response = await this._api.getVessels(params);\n      const vessels = Array.isArray(response?.vessels) ? response.vessels : [];\n      this._applyStates(vessels);\n    } catch (error) {\n      console.warn('[MaritimeOverlay] Failed to fetch vessels', error);\n    } finally {\n      this._inflight = false;\n    }\n  }\n\n  _applyStates(states) {\n    const now = Date.now();\n    const nextIds = new Set();\n\n    states.forEach((state) => {\n      if (!state) return;\n      const id = state.mmsi || state.id || state.rawId;\n      if (!id) return;\n      const key = String(id);\n      nextIds.add(key);\n\n      let entry = this._entries.get(key);\n      if (!entry) {\n        entry = this._createEntry(key, state, now);\n        this._entries.set(key, entry);\n        return;\n      }\n\n      const nextLat = toNumber(state.lat);\n      const nextLon = toNumber(state.lon);\n      if (Number.isFinite(nextLat) && Number.isFinite(nextLon)) {\n        if (Number.isFinite(entry.predictedLat) && Number.isFinite(entry.predictedLon) && this.smoothingMs > 0) {\n          const targetLon = wrapAngleDeg(nextLon - entry.predictedLon);\n          entry.correctionLat = nextLat - entry.predictedLat;\n          entry.correctionLon = targetLon;\n          entry.correctionRemainingMs = this.smoothingMs;\n        }\n        entry.lat = nextLat;\n        entry.lon = nextLon;\n      }\n\n      entry.name = typeof state.name === 'string' ? state.name.trim() : entry.name;\n      entry.speedMps = toNumber(state.speedMps ?? state.velocityMps);\n      entry.courseDeg = toNumber(state.courseDeg ?? state.headingDeg);\n      entry.headingDeg = toNumber(state.headingDeg ?? state.courseDeg);\n      entry.navStatus = typeof state.navStatus === 'string' ? state.navStatus : entry.navStatus;\n      entry.source = state.source || entry.source;\n      entry.lastReportMs = parseTimeMs(state.lastReport ?? state.lastContact, entry.lastReportMs || now);\n      entry.updatedAtMs = parseTimeMs(state.updatedAt, now);\n\n      if (Array.isArray(state.path)) {\n        this._seedPathHistory(entry, state.path);\n      }\n      if (!this.showPaths && entry.pathLine) {\n        entry.pathLine.visible = false;\n      }\n    });\n\n    for (const [id, entry] of this._entries.entries()) {\n      if (!nextIds.has(id)) {\n        this._disposeEntry(entry);\n        this._entries.delete(id);\n      }\n    }\n\n    if (this.eventBus && typeof this.eventBus.emit === 'function') {\n      this.eventBus.emit('maritime:entries', this.getEntriesSnapshot());\n    }\n  }\n\n  _advanceEntries(deltaMs) {\n    const now = Date.now();\n\n    for (const entry of this._entries.values()) {\n      if (!entry?.object) continue;\n      let lat = Number.isFinite(entry.lat) ? entry.lat : entry.predictedLat;\n      let lon = Number.isFinite(entry.lon) ? entry.lon : entry.predictedLon;\n      const heading = Number.isFinite(entry.headingDeg) ? entry.headingDeg\n        : (Number.isFinite(entry.courseDeg) ? entry.courseDeg : null);\n      const speed = Number.isFinite(entry.speedMps) ? entry.speedMps : null;\n      const updatedAtMs = Number.isFinite(entry.updatedAtMs) ? entry.updatedAtMs : now;\n      const ageMs = Math.min(Math.max(0, now - updatedAtMs), this.predictionMaxMs);\n\n      if (Number.isFinite(lat) && Number.isFinite(lon) && Number.isFinite(heading) && Number.isFinite(speed)) {\n        const baseRadius = ellipsoidRadiusForLocalDir(latLonToLocalDir(lat, lon));\n        const distance = (speed * ageMs) / 1000;\n        const moved = advanceLatLon(lat, lon, heading, distance, baseRadius + this.altitudeOffsetM);\n        lat = moved.lat;\n        lon = moved.lon;\n      }\n\n      if (entry.correctionRemainingMs > 0 && deltaMs > 0) {\n        const step = Math.min(1, deltaMs / entry.correctionRemainingMs);\n        if (Number.isFinite(entry.correctionLat)) {\n          lat += entry.correctionLat * step;\n          entry.correctionLat -= entry.correctionLat * step;\n        }\n        if (Number.isFinite(entry.correctionLon)) {\n          lon = wrapAngleDeg(lon + entry.correctionLon * step);\n          entry.correctionLon -= entry.correctionLon * step;\n        }\n        entry.correctionRemainingMs = Math.max(0, entry.correctionRemainingMs - deltaMs);\n      }\n\n      entry.predictedLat = lat;\n      entry.predictedLon = lon;\n\n      if (!Number.isFinite(lat) || !Number.isFinite(lon)) continue;\n\n      const dir = latLonToLocalDir(lat, lon);\n      const baseRadius = ellipsoidRadiusForLocalDir(dir);\n      const radius = baseRadius + this.altitudeOffsetM;\n      entry.object.position.copy(dir.multiplyScalar(radius));\n\n      // Label management\n      if (this._labelsEnabled && entry.name) {\n        const ls = this._ensureLabelSystem();\n        if (ls) {\n          const pos = entry.object.position;\n          if (!entry.labelHandle) {\n            const speedKn = entry.speedMps != null ? `${(entry.speedMps * 1.944).toFixed(0)}kn` : '';\n            entry.labelHandle = ls.createLabel(entry.name, {\n              position: pos,\n              type: 'maritime',\n              objectRadius: 30,\n              subText: speedKn,\n            });\n            if (entry.labelHandle?.group) {\n              this.group.add(entry.labelHandle.group);\n            }\n          } else {\n            ls.updatePosition(entry.labelHandle, pos);\n          }\n        }\n      } else if (entry.labelHandle) {\n        if (entry.labelHandle.group) this.group.remove(entry.labelHandle.group);\n        entry.labelHandle.dispose();\n        entry.labelHandle = null;\n      }\n\n      const renderHeading = Number.isFinite(heading)\n        ? heading + this.headingOffsetDeg\n        : this.headingOffsetDeg;\n      this._buildSurfaceQuaternion(this._tmpQuat, dir, renderHeading);\n      entry.object.quaternion.copy(this._tmpQuat);\n\n      if (this.showPaths) {\n        this._appendPathPoint(entry, lat, lon, 0, now);\n        this._updatePathLine(entry);\n        this._updatePathTail(entry);\n      }\n    }\n  }\n\n  _buildSurfaceQuaternion(target, upDir, headingDeg) {\n    const up = this._tmpVec2.copy(upDir).normalize();\n    const headingRad = degToRad(headingDeg || 0);\n\n    const east = this._tmpEast.crossVectors(this._worldUp, up);\n    if (east.lengthSq() < 1e-6) {\n      east.set(1, 0, 0);\n    }\n    east.normalize();\n\n    const north = this._tmpNorth.crossVectors(up, east).normalize();\n    const forward = this._tmpForward.set(0, 0, 0);\n    forward.addScaledVector(north, Math.cos(headingRad));\n    forward.addScaledVector(east, Math.sin(headingRad));\n\n    const right = this._tmpRight.crossVectors(forward, up).normalize();\n    this._tmpMat.makeBasis(right, up, forward.negate());\n    target.setFromRotationMatrix(this._tmpMat);\n  }\n\n  _createEntry(id, state, now) {\n    const object = this._createMarker();\n    this.group.add(object);\n\n    const entry = {\n      id,\n      mmsi: id,\n      name: typeof state.name === 'string' ? state.name.trim() : null,\n      lat: toNumber(state.lat),\n      lon: toNumber(state.lon),\n      speedMps: toNumber(state.speedMps ?? state.velocityMps),\n      courseDeg: toNumber(state.courseDeg ?? state.headingDeg),\n      headingDeg: toNumber(state.headingDeg ?? state.courseDeg),\n      navStatus: typeof state.navStatus === 'string' ? state.navStatus : null,\n      source: state.source || this.provider,\n      lastReportMs: parseTimeMs(state.lastReport ?? state.lastContact, now),\n      updatedAtMs: parseTimeMs(state.updatedAt, now),\n      predictedLat: null,\n      predictedLon: null,\n      correctionLat: null,\n      correctionLon: null,\n      correctionRemainingMs: 0,\n      object,\n      pathLine: null,\n      pathHistory: [],\n      pathSeeded: false,\n      lastPathSampleMs: 0,\n      labelHandle: null,\n    };\n\n    this._attachEntryToObject(entry, object);\n\n    if (Array.isArray(state.path)) {\n      this._seedPathHistory(entry, state.path);\n    }\n\n    return entry;\n  }\n\n  _createMarker() {\n    const group = new THREE.Group();\n    group.name = 'VesselMarker';\n\n    const hull = new THREE.Mesh(this._hullGeometry, this._markerMaterial);\n    hull.position.set(0, 0, 0);\n    group.add(hull);\n\n    const bow = new THREE.Mesh(this._bowGeometry, this._markerMaterial);\n    bow.rotation.x = Math.PI / 2;\n    bow.position.set(0, 0, 12);\n    group.add(bow);\n\n    group.scale.setScalar(this.modelScale);\n    return group;\n  }\n\n  _disposeEntry(entry) {\n    if (!entry) return;\n    if (entry.labelHandle) {\n      if (entry.labelHandle.group) this.group.remove(entry.labelHandle.group);\n      entry.labelHandle.dispose();\n      entry.labelHandle = null;\n    }\n    if (entry.object && entry.object.parent) {\n      entry.object.parent.remove(entry.object);\n    }\n    if (entry.pathLine) {\n      this.group.remove(entry.pathLine);\n      entry.pathLine.geometry.dispose();\n      entry.pathLine = null;\n    }\n  }\n\n  _attachEntryToObject(entry, object) {\n    if (!object || !entry) return;\n    object.userData = object.userData || {};\n    object.userData.maritimeEntry = entry;\n  }\n\n  _resolveEntryFromObject(object) {\n    let current = object;\n    while (current) {\n      if (current.userData?.maritimeEntry) return current.userData.maritimeEntry;\n      current = current.parent;\n    }\n    return null;\n  }\n\n  updateHover(raycaster) {\n    if (!raycaster || !this.group?.children?.length) {\n      this._hoveredEntry = null;\n      return;\n    }\n    this.group.updateMatrixWorld(true);\n    const hits = raycaster.intersectObjects(this.group.children, true);\n    if (!hits.length) {\n      this._hoveredEntry = null;\n      return;\n    }\n    const entry = this._resolveEntryFromObject(hits[0].object);\n    this._hoveredEntry = entry || null;\n  }\n\n  clearHover() {\n    this._hoveredEntry = null;\n  }\n\n  getHoveredVessel() {\n    return this._hoveredEntry;\n  }\n\n  getEntriesSnapshot() {\n    const entries = [];\n    for (const entry of this._entries.values()) {\n      const lat = Number.isFinite(entry.predictedLat) ? entry.predictedLat : entry.lat;\n      const lon = Number.isFinite(entry.predictedLon) ? entry.predictedLon : entry.lon;\n      entries.push({\n        id: entry.id,\n        mmsi: entry.mmsi,\n        name: entry.name,\n        lat,\n        lon,\n        speedMps: entry.speedMps,\n        courseDeg: entry.courseDeg,\n        headingDeg: entry.headingDeg,\n        navStatus: entry.navStatus,\n        source: entry.source,\n        lastReportMs: entry.lastReportMs,\n        updatedAtMs: entry.updatedAtMs,\n      });\n    }\n    return entries;\n  }\n\n  _seedPathHistory(entry, points) {\n    if (!entry || entry.pathSeeded || !Array.isArray(points) || !points.length) return;\n    const seeded = [];\n    for (const point of points) {\n      if (!Number.isFinite(point?.lat) || !Number.isFinite(point?.lon)) continue;\n      const timestamp = parseTimeMs(point?.timestamp, null);\n      if (!Number.isFinite(timestamp)) continue;\n      seeded.push({\n        lat: point.lat,\n        lon: point.lon,\n        alt: Number.isFinite(point?.altitudeM) ? point.altitudeM : 0,\n        timeMs: timestamp,\n      });\n    }\n    seeded.sort((a, b) => a.timeMs - b.timeMs);\n    entry.pathHistory = seeded;\n    entry.pathSeeded = true;\n  }\n\n  _appendPathPoint(entry, lat, lon, altitudeM, nowMs) {\n    if (!entry.pathHistory) entry.pathHistory = [];\n    if (entry.lastPathSampleMs && nowMs - entry.lastPathSampleMs < this.pathSampleIntervalMs) {\n      return;\n    }\n    entry.lastPathSampleMs = nowMs;\n    entry.pathHistory.push({\n      lat,\n      lon,\n      alt: altitudeM,\n      timeMs: nowMs,\n    });\n  }\n\n  _updatePathLine(entry) {\n    if (!entry?.pathHistory?.length) return;\n    const windowMs = Number.isFinite(this.pathHours) ? this.pathHours * 60 * 60 * 1000 : 0;\n    if (windowMs > 0) {\n      const cutoff = Date.now() - windowMs;\n      while (entry.pathHistory.length && entry.pathHistory[0].timeMs < cutoff) {\n        entry.pathHistory.shift();\n      }\n    }\n    if (Number.isFinite(this.pathMaxPoints) && this.pathMaxPoints > 0 && entry.pathHistory.length > this.pathMaxPoints) {\n      entry.pathHistory.splice(0, entry.pathHistory.length - this.pathMaxPoints);\n    }\n\n    if (!entry?.pathHistory || entry.pathHistory.length < 2) {\n      if (entry?.pathLine) entry.pathLine.visible = false;\n      return;\n    }\n\n    if (!entry.pathLine) {\n      const geometry = new THREE.BufferGeometry();\n      const line = new THREE.Line(geometry, this._pathMaterial);\n      line.name = 'VesselPath';\n      this.group.add(line);\n      entry.pathLine = line;\n    }\n\n    const positions = new Float32Array(entry.pathHistory.length * 3);\n    const colors = new Float32Array(entry.pathHistory.length * 3);\n    const lastIndex = Math.max(1, entry.pathHistory.length - 1);\n    for (let i = 0; i < entry.pathHistory.length; i += 1) {\n      const point = entry.pathHistory[i];\n      const dir = latLonToLocalDir(point.lat, point.lon);\n      const baseRadius = ellipsoidRadiusForLocalDir(dir);\n      const radius = baseRadius + this.altitudeOffsetM + (point.alt || 0) + 0.25;\n      const pos = this._tmpVec.copy(dir).multiplyScalar(radius);\n      positions[i * 3] = pos.x;\n      positions[i * 3 + 1] = pos.y;\n      positions[i * 3 + 2] = pos.z;\n      const t = i / lastIndex;\n      colors[i * 3] = 0.22 + 0.78 * t;\n      colors[i * 3 + 1] = 0.78 + 0.22 * t;\n      colors[i * 3 + 2] = 1.0;\n    }\n\n    updateTrailAttributes(entry.pathLine.geometry, [\n      { name: 'position', array: positions, itemSize: 3 },\n      { name: 'color', array: colors, itemSize: 3 },\n    ]);\n    entry.pathLine.geometry.computeBoundingSphere();\n    entry.pathLine.computeLineDistances();\n    entry.pathLine.visible = true;\n  }\n\n  _updatePathTail(entry) {\n    if (!this.showPaths || !entry?.pathLine || !entry?.object) return;\n    const positionAttr = entry.pathLine.geometry.getAttribute('position');\n    if (!positionAttr || positionAttr.count < 1) return;\n    const lastIndex = positionAttr.count - 1;\n    const pos = entry.object.position;\n    positionAttr.setXYZ(lastIndex, pos.x, pos.y, pos.z);\n    positionAttr.needsUpdate = true;\n  }\n\n  _ensureLabelSystem() {\n    if (!this._labelSystem) {\n      try {\n        this._labelSystem = getLabelSystem({ planetRadius: this.planetRadius });\n      } catch { /* not available */ }\n    }\n    return this._labelSystem;\n  }\n\n  setLabelsEnabled(enabled) {\n    this._labelsEnabled = !!enabled;\n    if (!enabled) {\n      for (const entry of this._entries.values()) {\n        if (entry.labelHandle) {\n          if (entry.labelHandle.group) this.group.remove(entry.labelHandle.group);\n          entry.labelHandle.dispose();\n          entry.labelHandle = null;\n        }\n      }\n    }\n  }\n\n  _bindConfigListener() {\n    if (!this.eventBus || typeof this.eventBus.on !== 'function') return;\n    this._configListener = (config) => this._handleConfigUpdate(config);\n    this.eventBus.on('maritime:config', this._configListener);\n  }\n\n  _unbindConfigListener() {\n    if (!this.eventBus || typeof this.eventBus.off !== 'function') return;\n    if (!this._configListener) return;\n    this.eventBus.off('maritime:config', this._configListener);\n    this._configListener = null;\n  }\n\n  _handleConfigUpdate(config = {}) {\n    if (typeof config.enabled === 'boolean') {\n      this.enabled = config.enabled;\n      this.group.visible = config.enabled;\n      if (!config.enabled) {\n        this.clear();\n      }\n    }\n    if (typeof config.provider === 'string') {\n      if (config.provider !== this.provider) {\n        this.provider = config.provider;\n        this.clear();\n        this._refreshQueued = true;\n      }\n    }\n    if (typeof config.queryMode === 'string') {\n      if (config.queryMode !== this.queryMode) {\n        this.queryMode = config.queryMode;\n        this.clear();\n        this._refreshQueued = true;\n      }\n    }\n    if (typeof config.queryValue === 'string') {\n      if (config.queryValue !== this.queryValue) {\n        this.queryValue = config.queryValue;\n        this.clear();\n        this._refreshQueued = true;\n      }\n    }\n    if (Number.isFinite(config.radiusNm)) this.radiusNm = config.radiusNm;\n    if (Number.isFinite(config.coneAngleDeg)) this.coneAngleDeg = config.coneAngleDeg;\n    if (Number.isFinite(config.maxVessels)) this.maxVessels = config.maxVessels;\n    if (Number.isFinite(config.pollIntervalMs)) this.pollIntervalMs = config.pollIntervalMs;\n    if (Number.isFinite(config.staleAfterMs)) this.staleAfterMs = config.staleAfterMs;\n    if (Number.isFinite(config.predictionMaxMs)) this.predictionMaxMs = config.predictionMaxMs;\n    if (Number.isFinite(config.lookbackMinutes)) this.lookbackMinutes = config.lookbackMinutes;\n    if (Number.isFinite(config.modelScale)) {\n      this.modelScale = config.modelScale;\n      for (const entry of this._entries.values()) {\n        if (entry.object) {\n          entry.object.scale.setScalar(this.modelScale);\n        }\n      }\n    }\n    if (Number.isFinite(config.headingOffsetDeg)) this.headingOffsetDeg = config.headingOffsetDeg;\n    if (Number.isFinite(config.altitudeOffsetM)) this.altitudeOffsetM = config.altitudeOffsetM;\n    if (Number.isFinite(config.smoothingMs)) this.smoothingMs = config.smoothingMs;\n\n    if (typeof config.showPaths === 'boolean') {\n      this.showPaths = config.showPaths;\n      for (const entry of this._entries.values()) {\n        if (entry.pathLine) {\n          entry.pathLine.visible = this.showPaths;\n        }\n        if (this.showPaths) {\n          this._refreshQueued = true;\n        }\n      }\n    }\n    if (Number.isFinite(config.pathHours)) {\n      this.pathHours = config.pathHours;\n    }\n    if (Number.isFinite(config.pathMaxPoints)) {\n      this.pathMaxPoints = config.pathMaxPoints;\n      for (const entry of this._entries.values()) {\n        if (entry.pathHistory?.length) {\n          entry.pathHistory.splice(0, Math.max(0, entry.pathHistory.length - this.pathMaxPoints));\n        }\n      }\n    }\n  }\n}\n","import * as THREE from 'three';\n\nimport {\n  ellipsoidRadiusForLocalDir,\n  latLonToLocalDir,\n} from '../../modules/geometry-utils.js';\nimport { terrainSurfaceChangesAffectLatLon } from '../scene/TerrainSurfaceChange.js';\nimport { getSurfaceLightRegistry } from '../render/SurfaceLightRegistry.js';\n\nconst MAX_FOOTPRINT_POINTS = 96;\nconst DEFAULT_HEIGHT_M = 24;\n// Shared visual contract for a deliberate surface selection and a normal\n// incident marker. Keeping this in the shared marker module prevents clicked\n// buildings/locations from silently growing a much taller presentation.\nexport const DEFAULT_INCIDENT_SPIRE_HEIGHT_M = 60;\nconst DEFAULT_EMBED_M = 1.5;\nconst DEFAULT_FALLBACK_SIZE_M = 14;\nconst DEFAULT_RESOLVING_RADIUS_M = 5;\nconst DEFAULT_RESOLVING_SEGMENTS = 24;\nconst DEFAULT_GROW_DURATION_MS = 320;\nconst DEFAULT_MORPH_DURATION_MS = 520;\nconst ACTIVE_SURFACE_MARKER_LIGHTS = new Map();\nlet unregisterSurfaceMarkerLights = null;\n\nconst ensureSurfaceMarkerLightProvider = () => {\n  if (unregisterSurfaceMarkerLights) return;\n  unregisterSurfaceMarkerLights = getSurfaceLightRegistry().registerProvider(\n    'surface-footprint-markers',\n    () => ACTIVE_SURFACE_MARKER_LIGHTS.values(),\n    { budget: 6 },\n  );\n};\n\nconst releaseSurfaceMarkerLightProviderIfEmpty = () => {\n  if (ACTIVE_SURFACE_MARKER_LIGHTS.size || !unregisterSurfaceMarkerLights) return;\n  unregisterSurfaceMarkerLights();\n  unregisterSurfaceMarkerLights = null;\n};\n\nconst samePoint = (a, b) => (\n  Array.isArray(a)\n  && Array.isArray(b)\n  && Math.abs(Number(a[0]) - Number(b[0])) < 1e-10\n  && Math.abs(Number(a[1]) - Number(b[1])) < 1e-10\n);\n\nconst signedRingArea = (ring) => {\n  let area = 0;\n  for (let i = 0, j = ring.length - 1; i < ring.length; j = i++) {\n    area += Number(ring[j][0]) * Number(ring[i][1])\n      - Number(ring[i][0]) * Number(ring[j][1]);\n  }\n  return area * 0.5;\n};\n\nconst sanitizeRing = (ring) => {\n  if (!Array.isArray(ring)) return [];\n  let points = ring\n    .map((point) => [Number(point?.[0]), Number(point?.[1])])\n    .filter(([lon, lat]) => Number.isFinite(lon) && Number.isFinite(lat));\n  if (points.length > 1 && samePoint(points[0], points[points.length - 1])) {\n    points = points.slice(0, -1);\n  }\n  if (points.length > MAX_FOOTPRINT_POINTS) {\n    const step = points.length / MAX_FOOTPRINT_POINTS;\n    const decimated = [];\n    for (let i = 0; i < MAX_FOOTPRINT_POINTS; i += 1) {\n      decimated.push(points[Math.floor(i * step)]);\n    }\n    points = decimated;\n  }\n  if (points.length >= 3 && signedRingArea(points) < 0) points.reverse();\n  return points;\n};\n\nexport function normalizeSurfaceFootprint(footprint) {\n  if (!footprint) return [];\n  if (Array.isArray(footprint)) {\n    // BuildingOverlay uses [lat, lon]; GeoJSON uses [lon, lat]. Accept an\n    // explicit object for the former and retain arrays as GeoJSON convention.\n    return sanitizeRing(footprint);\n  }\n  if (Array.isArray(footprint.latLonPairs)) {\n    return sanitizeRing(footprint.latLonPairs.map(([lat, lon]) => [lon, lat]));\n  }\n  if (footprint.type === 'Feature') {\n    return normalizeSurfaceFootprint(footprint.geometry);\n  }\n  if (footprint.type === 'Polygon') {\n    return sanitizeRing(footprint.coordinates?.[0]);\n  }\n  if (footprint.type === 'MultiPolygon') {\n    const rings = (footprint.coordinates || [])\n      .map((polygon) => sanitizeRing(polygon?.[0]))\n      .filter((ring) => ring.length >= 3);\n    rings.sort((a, b) => Math.abs(signedRingArea(b)) - Math.abs(signedRingArea(a)));\n    return rings[0] || [];\n  }\n  return [];\n}\n\nexport function createFallbackSurfaceFootprint(lat, lon, sizeM = DEFAULT_FALLBACK_SIZE_M) {\n  if (!Number.isFinite(lat) || !Number.isFinite(lon)) return [];\n  const half = Math.max(2, Number(sizeM) || DEFAULT_FALLBACK_SIZE_M) * 0.5;\n  const latRad = THREE.MathUtils.degToRad(lat);\n  const dLat = half / 111132.954;\n  const dLon = half / Math.max(1000, 111132.954 * Math.cos(latRad));\n  return [\n    [lon - dLon, lat - dLat],\n    [lon + dLon, lat - dLat],\n    [lon + dLon, lat + dLat],\n    [lon - dLon, lat + dLat],\n  ];\n}\n\nexport function createResolvingSurfaceFootprint(\n  lat,\n  lon,\n  radiusM = DEFAULT_RESOLVING_RADIUS_M,\n  segments = DEFAULT_RESOLVING_SEGMENTS,\n) {\n  if (!Number.isFinite(lat) || !Number.isFinite(lon)) return [];\n  const radius = Math.max(1, Number(radiusM) || DEFAULT_RESOLVING_RADIUS_M);\n  const count = THREE.MathUtils.clamp(\n    Math.round(Number(segments) || DEFAULT_RESOLVING_SEGMENTS),\n    12,\n    MAX_FOOTPRINT_POINTS,\n  );\n  const latRad = THREE.MathUtils.degToRad(lat);\n  const metersPerLatDeg = 111132.954;\n  const metersPerLonDeg = Math.max(1000, metersPerLatDeg * Math.cos(latRad));\n  const ring = [];\n  for (let i = 0; i < count; i += 1) {\n    const angle = (i / count) * Math.PI * 2;\n    const eastM = Math.sin(angle) * radius;\n    const northM = Math.cos(angle) * radius;\n    ring.push([\n      lon + eastM / metersPerLonDeg,\n      lat + northM / metersPerLatDeg,\n    ]);\n  }\n  return ring;\n}\n\nconst ringDistanceM = (a, b) => {\n  const meanLat = THREE.MathUtils.degToRad((Number(a?.[1]) + Number(b?.[1])) * 0.5);\n  const dx = (Number(b?.[0]) - Number(a?.[0])) * 111132.954 * Math.cos(meanLat);\n  const dy = (Number(b?.[1]) - Number(a?.[1])) * 111132.954;\n  return Math.hypot(dx, dy);\n};\n\nconst resampleRing = (ring, count) => {\n  if (!Array.isArray(ring) || ring.length < 3 || count < 3) return [];\n  const lengths = new Float64Array(ring.length);\n  let perimeter = 0;\n  for (let i = 0; i < ring.length; i += 1) {\n    const length = ringDistanceM(ring[i], ring[(i + 1) % ring.length]);\n    lengths[i] = length;\n    perimeter += length;\n  }\n  if (!(perimeter > 0)) return ring.slice(0, count).map((point) => [...point]);\n  const sampled = [];\n  let edge = 0;\n  let edgeStart = 0;\n  for (let i = 0; i < count; i += 1) {\n    const distance = perimeter * i / count;\n    while (edge < ring.length - 1 && distance > edgeStart + lengths[edge]) {\n      edgeStart += lengths[edge];\n      edge += 1;\n    }\n    const a = ring[edge];\n    const b = ring[(edge + 1) % ring.length];\n    const t = lengths[edge] > 0 ? (distance - edgeStart) / lengths[edge] : 0;\n    sampled.push([\n      THREE.MathUtils.lerp(a[0], b[0], t),\n      THREE.MathUtils.lerp(a[1], b[1], t),\n    ]);\n  }\n  return sampled;\n};\n\nconst alignRingSamples = (from, to) => {\n  if (from.length !== to.length || from.length < 2) return to;\n  let bestOffset = 0;\n  let bestCost = Infinity;\n  const meanLat = THREE.MathUtils.degToRad(averageRing(from).lat);\n  const lonScale = Math.max(0.01, Math.cos(meanLat));\n  for (let offset = 0; offset < to.length; offset += 1) {\n    let cost = 0;\n    for (let i = 0; i < from.length; i += 1) {\n      const target = to[(i + offset) % to.length];\n      const dx = (from[i][0] - target[0]) * lonScale;\n      const dy = from[i][1] - target[1];\n      cost += dx * dx + dy * dy;\n    }\n    if (cost < bestCost) {\n      bestCost = cost;\n      bestOffset = offset;\n    }\n  }\n  return to.map((_, index) => to[(index + bestOffset) % to.length]);\n};\n\nconst animationNow = () => (\n  typeof performance !== 'undefined' && typeof performance.now === 'function'\n    ? performance.now()\n    : Date.now()\n);\n\nconst smoothstep = (value) => value * value * (3 - 2 * value);\n\nconst averageRing = (ring) => {\n  let lat = 0;\n  let lon = 0;\n  for (const point of ring) {\n    lon += point[0];\n    lat += point[1];\n  }\n  const count = ring.length || 1;\n  return {\n    lat: lat / count,\n    lon: lon / count,\n  };\n};\n\nexport class SurfaceFootprintMarker {\n  constructor({\n    parentGroup = null,\n    presentation = 'column',\n    surfaceController = null,\n    color = 0xfacc15,\n    heightM = DEFAULT_HEIGHT_M,\n    embedM = DEFAULT_EMBED_M,\n    opacity = 0.75,\n    outlineOpacity = 0.92,\n    renderOrder = 5,\n    name = 'SurfaceFootprintMarker',\n    lightChannel = 'surface-marker',\n    lightPriority = 90,\n    lightRadiusM = null,\n    lightIntensityScale = 1.35,\n    lightPulseHz = 0.72,\n    lightPhase = 0,\n    lightShadowStrength = 0.86,\n  } = {}) {\n    this.parentGroup = parentGroup;\n    this.presentation = presentation;\n    this.surfaceController = surfaceController;\n    this.heightM = Math.max(1, Number(heightM) || DEFAULT_HEIGHT_M);\n    this.embedM = Math.max(0.25, Number(embedM) || DEFAULT_EMBED_M);\n    this.renderOrder = renderOrder;\n    this._surfaceLightId = `surface-marker:${THREE.MathUtils.generateUUID()}`;\n    this._surfaceLight = {\n      id: this._surfaceLightId,\n      channel: String(lightChannel || 'surface-marker'),\n      active: false,\n      lat: 0,\n      lon: 0,\n      color: new THREE.Color(color),\n      radiusM: Number.isFinite(Number(lightRadiusM))\n        ? Math.max(8, Number(lightRadiusM))\n        : THREE.MathUtils.clamp(this.heightM * 3, 85, 420),\n      heightM: THREE.MathUtils.clamp(this.heightM * 0.42, 4, 90),\n      altitudeM: THREE.MathUtils.clamp(this.heightM * 0.42, 4, 90),\n      intensity: 1.85 * Math.max(0.1, Number(lightIntensityScale) || 1.35),\n      pulseHz: Math.max(0, Number(lightPulseHz) || 0),\n      phase: Number(lightPhase) || 0,\n      shadowStrength: THREE.MathUtils.clamp(Number(lightShadowStrength) || 0, 0, 1),\n      priority: Number(lightPriority) || 0,\n    };\n    this._surfaceLightIntensityScale = Math.max(0.1, Number(lightIntensityScale) || 1.35);\n    this._requestedVisible = true;\n    this._ring = [];\n    this._heightScale = 1;\n    this._growthAnimation = null;\n    this._morphAnimation = null;\n    this._surfaceLocalPositions = null;\n    this._anchorRadius = null;\n    this._anchorMated = false;\n    this._anchorLocked = false;\n    this._lat = null;\n    this._lon = null;\n    this._source = 'none';\n    this._centerRadius = null;\n    this._centerDir = new THREE.Vector3(0, 1, 0);\n    this._tmpWorldDir = new THREE.Vector3();\n    this._tmpQuat = new THREE.Quaternion();\n    this._tmpPoint = new THREE.Vector3();\n    this._tmpBase = new THREE.Vector3();\n    this._tmpSurface = new THREE.Vector3();\n    this._tmpTop = new THREE.Vector3();\n    this._tmpVertexDir = new THREE.Vector3();\n\n    this.group = new THREE.Group();\n    this.group.name = name;\n    this.group.userData.surfaceFootprintMarker = this;\n\n    this.wallMaterial = new THREE.ShaderMaterial({\n      uniforms: {\n        uColor: { value: new THREE.Color(color) },\n        uOpacity: { value: opacity },\n        uGradientPower: { value: 1.3 },\n        uEmission: { value: 1.85 },\n        uDesaturation: { value: 0 },\n      },\n      vertexShader: `\n        #include <common>\n        #include <logdepthbuf_pars_vertex>\n        attribute float markerHeight;\n        varying float vMarkerHeight;\n        void main() {\n          vMarkerHeight = markerHeight;\n          gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n          #include <logdepthbuf_vertex>\n        }\n      `,\n      fragmentShader: `\n        #include <logdepthbuf_pars_fragment>\n        varying float vMarkerHeight;\n        uniform vec3 uColor;\n        uniform float uOpacity;\n        uniform float uGradientPower;\n        uniform float uEmission;\n        uniform float uDesaturation;\n        void main() {\n          #include <logdepthbuf_fragment>\n          float t = clamp(1.0 - vMarkerHeight, 0.0, 1.0);\n          float alpha = uOpacity * pow(t, uGradientPower);\n          if (alpha <= 0.002) discard;\n          float hotCore = pow(t, 2.2);\n          vec3 emittedColor = uColor * mix(1.0, uEmission, hotCore);\n          float luminance = dot(emittedColor, vec3(0.2126, 0.7152, 0.0722));\n          emittedColor = mix(emittedColor, vec3(luminance), uDesaturation);\n          gl_FragColor = vec4(emittedColor, alpha);\n        }\n      `,\n      transparent: true,\n      depthWrite: false,\n      depthTest: true,\n      side: THREE.DoubleSide,\n      toneMapped: false,\n    });\n    this.outlineMaterial = new THREE.LineBasicMaterial({\n      color,\n      transparent: true,\n      opacity: outlineOpacity,\n      depthWrite: false,\n      depthTest: true,\n      toneMapped: false,\n    });\n    this.topOutlineMaterial = new THREE.LineBasicMaterial({\n      color,\n      transparent: true,\n      opacity: outlineOpacity * 0.47,\n      depthWrite: false,\n      depthTest: true,\n      toneMapped: false,\n    });\n    this.wallMesh = new THREE.Mesh(new THREE.BufferGeometry(), this.wallMaterial);\n    this.wallMesh.name = `${name}:walls`;\n    this.wallMesh.renderOrder = renderOrder;\n    this.wallMesh.userData.surfaceFootprintMarker = this;\n    this.outline = new THREE.LineSegments(new THREE.BufferGeometry(), this.outlineMaterial);\n    this.outline.name = `${name}:outline`;\n    this.outline.renderOrder = renderOrder + 0.01;\n    this.outline.userData.surfaceFootprintMarker = this;\n    this.topOutline = new THREE.LineSegments(\n      new THREE.BufferGeometry(),\n      this.topOutlineMaterial,\n    );\n    this.topOutline.name = `${name}:top-outline`;\n    this.topOutline.renderOrder = renderOrder + 0.01;\n    this.topOutline.userData.surfaceFootprintMarker = this;\n    this.wallMesh.frustumCulled = false;\n    this.outline.frustumCulled = false;\n    this.topOutline.frustumCulled = false;\n    this.group.add(this.wallMesh, this.outline, this.topOutline);\n    // Opaque scene depth is authoritative. Never draw a second pass through\n    // buildings/terrain, including the embedded base of a footprint.\n    for (const object of [this.wallMesh,this.outline,this.topOutline]) object.material.depthFunc = THREE.LessEqualDepth;\n    if (presentation === 'selection') {\n      this.wallMesh.visible = false; this.topOutline.visible = false;\n      this.selectionLine = new THREE.Line(new THREE.BufferGeometry().setAttribute('position',\n        new THREE.Float32BufferAttribute(new Float32Array(6),3)),\n        new THREE.LineBasicMaterial({color,transparent:true,opacity:.42,depthTest:true,\n          depthWrite:false,depthFunc:THREE.LessEqualDepth,toneMapped:false}));\n      this.selectionLine.name = `${name}:leader`; this.selectionLine.frustumCulled = false;\n      this.selectionLine.renderOrder = renderOrder; this.group.add(this.selectionLine);\n    }\n    this.parentGroup?.add?.(this.group);\n    this.group.visible = false;\n    ensureSurfaceMarkerLightProvider();\n    ACTIVE_SURFACE_MARKER_LIGHTS.set(this._surfaceLightId, this._surfaceLight);\n    getSurfaceLightRegistry().touch();\n  }\n\n  _syncSurfaceLight() {\n    const active = this.presentation !== 'selection' && this._requestedVisible\n      && this.group.visible\n      && this.isTerrainMated()\n      && Number.isFinite(this._lat)\n      && Number.isFinite(this._lon);\n    this._surfaceLight.active = active;\n    this._surfaceLight.lat = Number(this._lat) || 0;\n    this._surfaceLight.lon = Number(this._lon) || 0;\n    this._surfaceLight.heightM = THREE.MathUtils.clamp(this.heightM * 0.42, 4, 90);\n    const surfaceDirection = latLonToLocalDir(this._surfaceLight.lat, this._surfaceLight.lon);\n    const ellipsoidRadius = ellipsoidRadiusForLocalDir(surfaceDirection);\n    const surfaceElevationM = Number.isFinite(this._anchorRadius)\n      && Number.isFinite(ellipsoidRadius)\n      ? this._anchorRadius - ellipsoidRadius\n      : 0;\n    this._surfaceLight.altitudeM = surfaceElevationM + this._surfaceLight.heightM;\n    this._surfaceLight.intensity = this.wallMaterial.uniforms.uEmission.value\n      * this._surfaceLightIntensityScale;\n    getSurfaceLightRegistry().touch();\n  }\n\n  setFootprint(footprint, {\n    lat = null,\n    lon = null,\n    source = 'overpass',\n    anchorRadius = null,\n    anchorSource = '',\n  } = {}) {\n    const ring = normalizeSurfaceFootprint(footprint);\n    if (ring.length < 3) return false;\n    this._growthAnimation = null;\n    this._morphAnimation = null;\n    this._heightScale = 1;\n    this._ring = ring;\n    // The polygon owns its projection origin. Incident/address coordinates\n    // often land on the road beside the selected building; using that point as\n    // the marker origin sampled the wrong surface and left the label floating\n    // away from the actual outline.\n    const center = averageRing(ring);\n    this._lat = center.lat;\n    this._lon = center.lon;\n    this.group.userData.sourceLat = lat == null ? null : Number(lat);\n    this.group.userData.sourceLon = lon == null ? null : Number(lon);\n    this._source = source;\n    const exactRadius = Number(anchorRadius);\n    this._anchorRadius = Number.isFinite(exactRadius) && exactRadius > 0\n      ? exactRadius\n      : null;\n    this._anchorMated = Number.isFinite(this._anchorRadius);\n    this._anchorLocked = this._anchorMated;\n    if (this._anchorLocked && Number.isFinite(lat) && Number.isFinite(lon)) {\n      this._lat = lat;\n      this._lon = lon;\n    }\n    this.group.userData.footprintSource = source;\n    this.group.userData.surfaceAnchorSource = this._anchorLocked\n      ? String(anchorSource || 'authoritative-pick')\n      : '';\n    this.refreshTerrain();\n    return true;\n  }\n\n  setFallback(lat, lon, sizeM = DEFAULT_FALLBACK_SIZE_M) {\n    return this.setFootprint(createFallbackSurfaceFootprint(lat, lon, sizeM), {\n      lat,\n      lon,\n      source: 'fallback',\n    });\n  }\n\n  setResolvingSpire(lat, lon, {\n    radiusM = DEFAULT_RESOLVING_RADIUS_M,\n    segments = DEFAULT_RESOLVING_SEGMENTS,\n    growDurationMs = DEFAULT_GROW_DURATION_MS,\n    nowMs = animationNow(),\n    anchorRadius = null,\n    anchorSource = '',\n  } = {}) {\n    const ring = createResolvingSurfaceFootprint(lat, lon, radiusM, segments);\n    if (!this.setFootprint(ring, {\n      lat,\n      lon,\n      source: 'resolving',\n      anchorRadius,\n      anchorSource,\n    })) return false;\n    this._heightScale = 0.001;\n    this._growthAnimation = {\n      startMs: Number(nowMs) || 0,\n      durationMs: Math.max(1, Number(growDurationMs) || DEFAULT_GROW_DURATION_MS),\n    };\n    this._writeGeometryPositions();\n    return true;\n  }\n\n  transitionToFootprint(footprint, {\n    lat = null,\n    lon = null,\n    source = 'overpass',\n    durationMs = DEFAULT_MORPH_DURATION_MS,\n    nowMs = animationNow(),\n  } = {}) {\n    const targetRing = normalizeSurfaceFootprint(footprint);\n    if (targetRing.length < 3) return false;\n    if (this._ring.length < 3 || !(Number(durationMs) > 0)) {\n      return this.setFootprint(targetRing, { lat, lon, source,\n        anchorRadius: this._anchorLocked ? this._anchorRadius : null,\n        anchorSource: this.group.userData.surfaceAnchorSource });\n    }\n\n    const count = THREE.MathUtils.clamp(\n      Math.max(DEFAULT_RESOLVING_SEGMENTS, this._ring.length, targetRing.length),\n      3,\n      MAX_FOOTPRINT_POINTS,\n    );\n    const from = resampleRing(this._ring, count);\n    const to = alignRingSamples(from, resampleRing(targetRing, count));\n    if (from.length !== count || to.length !== count) return false;\n\n    this._ring = from.map((point) => [...point]);\n    const center = averageRing(this._ring);\n    if (!this._anchorLocked) {\n      this._lat = center.lat;\n      this._lon = center.lon;\n    }\n    this.group.userData.sourceLat = lat == null ? null : Number(lat);\n    this.group.userData.sourceLon = lon == null ? null : Number(lon);\n    this._source = source;\n    this.group.userData.footprintSource = source;\n    this._morphAnimation = {\n      from,\n      to,\n      targetRing,\n      startMs: Number(nowMs) || 0,\n      durationMs: Math.max(1, Number(durationMs) || DEFAULT_MORPH_DURATION_MS),\n    };\n    this._rebuildGeometry();\n    this.refreshTerrain();\n    return true;\n  }\n\n  update(nowMs = animationNow()) {\n    let changed = false;\n    let morphCompleted = false;\n    const now = Number(nowMs) || 0;\n    if (this._growthAnimation) {\n      const elapsed = now - this._growthAnimation.startMs;\n      const progress = THREE.MathUtils.clamp(\n        elapsed / this._growthAnimation.durationMs,\n        0,\n        1,\n      );\n      this._heightScale = Math.max(0.001, smoothstep(progress));\n      changed = true;\n      if (progress >= 1) {\n        this._heightScale = 1;\n        this._growthAnimation = null;\n      }\n    }\n    if (this._morphAnimation) {\n      const elapsed = now - this._morphAnimation.startMs;\n      const progress = THREE.MathUtils.clamp(\n        elapsed / this._morphAnimation.durationMs,\n        0,\n        1,\n      );\n      const eased = smoothstep(progress);\n      for (let i = 0; i < this._ring.length; i += 1) {\n        this._ring[i][0] = THREE.MathUtils.lerp(\n          this._morphAnimation.from[i][0],\n          this._morphAnimation.to[i][0],\n          eased,\n        );\n        this._ring[i][1] = THREE.MathUtils.lerp(\n          this._morphAnimation.from[i][1],\n          this._morphAnimation.to[i][1],\n          eased,\n        );\n      }\n      const center = averageRing(this._ring);\n      if (!this._anchorLocked) {\n        this._lat = center.lat;\n        this._lon = center.lon;\n      }\n      changed = true;\n      if (progress >= 1) {\n        // Interpolated equal-length samples need not land on every original\n        // corner. Finish with the actual normalized ring, not a rounded proxy.\n        this._ring = this._morphAnimation.targetRing;\n        if (!this._anchorLocked) {\n          const finalCenter = averageRing(this._ring);\n          this._lat = finalCenter.lat;\n          this._lon = finalCenter.lon;\n        }\n        this._morphAnimation = null;\n        this._rebuildGeometry();\n        morphCompleted = true;\n      }\n    }\n    if (changed) this._writeGeometryPositions();\n    // The provisional cylinder may be centered on the road-side click while\n    // the authoritative ring is centered on the building. Adopt that final\n    // terrain plane only after the visual interpolation reaches the building.\n    if (morphCompleted) this.refreshTerrain();\n    return changed;\n  }\n\n  isAnimating() {\n    return !!(this._growthAnimation || this._morphAnimation);\n  }\n\n  setHeight(heightM) {\n    const next = Math.max(1, Number(heightM) || DEFAULT_HEIGHT_M);\n    if (Math.abs(next - this.heightM) < 0.05) return;\n    this.heightM = next;\n    if (this._ring.length >= 3) this._writeGeometryPositions();\n    this._syncSurfaceLight();\n  }\n\n  setColor(color) {\n    this.wallMaterial.uniforms.uColor.value.set(color);\n    this.outlineMaterial.color.set(color);\n    this.topOutlineMaterial.color.set(color);\n    this.selectionLine?.material.color.set(color);\n    this._surfaceLight.color.set(color);\n    this._syncSurfaceLight();\n  }\n\n  setOpacity(opacity, outlineOpacity = null) {\n    if (Number.isFinite(opacity)) this.wallMaterial.uniforms.uOpacity.value = opacity;\n    if (Number.isFinite(outlineOpacity)) {\n      this.outlineMaterial.opacity = outlineOpacity;\n      this.topOutlineMaterial.opacity = outlineOpacity * 0.47;\n    }\n  }\n\n  setEmissionIntensity(intensity) {\n    if (!Number.isFinite(intensity)) return;\n    this.wallMaterial.uniforms.uEmission.value = THREE.MathUtils.clamp(intensity, 1, 8);\n  }\n\n  setVisible(visible) {\n    const requested = !!visible;\n    const nextVisible = requested && this.isTerrainMated();\n    if (this._requestedVisible === requested && this.group.visible === nextVisible) return;\n    this._requestedVisible = requested;\n    this.group.visible = nextVisible;\n    this._syncSurfaceLight();\n  }\n\n  isTerrainMated() {\n    return this._ring.length >= 3\n      && Number.isFinite(this._anchorRadius)\n      && this._anchorMated;\n  }\n\n  get centerRadius() {\n    return this._centerRadius;\n  }\n\n  get source() {\n    return this._source;\n  }\n\n  getCenterDirection(out = new THREE.Vector3()) {\n    if (!this.isTerrainMated()) return null;\n    return out.copy(this._centerDir);\n  }\n\n  refreshTerrain(changes = null) {\n    if (this._ring.length < 3) return false;\n    if (Array.isArray(changes) && changes.length) {\n      const affected = terrainSurfaceChangesAffectLatLon(changes, this._lat, this._lon)\n        || this._ring.some(([lon, lat]) => terrainSurfaceChangesAffectLatLon(changes, lat, lon));\n      if (!affected) return false;\n    }\n\n    // A deliberate screen pick already supplied the exact radius of the\n    // rendered mesh intersection (tree, roof, facade, or terrain). Recasting\n    // a radial ray at its lat/lon can hit a different surface and introduces\n    // precisely the offset/jitter this anchor is intended to prevent.\n    if (this._anchorLocked && Number.isFinite(this._anchorRadius)) {\n      if (!this.wallMesh.geometry.getAttribute('position')) this._rebuildGeometry();\n      this.group.visible = this._requestedVisible && this.isTerrainMated();\n      this._syncSurfaceLight();\n      return false;\n    }\n\n    const photoRequired = !!this.surfaceController?.photoTileGroup;\n    const worldQuat = this.parentGroup?.getWorldQuaternion?.(this._tmpQuat) || null;\n    const localDir = latLonToLocalDir(this._lat, this._lon);\n    this._tmpWorldDir.copy(localDir);\n    if (worldQuat) this._tmpWorldDir.applyQuaternion(worldQuat);\n    this._tmpWorldDir.normalize();\n    let changed = false;\n    let sampled = null;\n    if (this.surfaceController?.sampleTerrainRadiusForDir) {\n      sampled = this.surfaceController.sampleTerrainRadiusForDir(this._tmpWorldDir, {\n        mutateCache: false,\n        requireFreshPhotoHit: photoRequired,\n        allowTriTreeFallback: !photoRequired,\n        skipWorldMatrixUpdate: true,\n      });\n    }\n    if (Number.isFinite(sampled) && sampled > 0) {\n      if (!Number.isFinite(this._anchorRadius)\n        || Math.abs(this._anchorRadius - sampled) > 0.02) {\n        this._anchorRadius = sampled;\n        changed = true;\n      }\n      this._anchorMated = true;\n    } else if (!photoRequired && !Number.isFinite(this._anchorRadius)) {\n      this._anchorRadius = ellipsoidRadiusForLocalDir(localDir);\n      this._anchorMated = true;\n      changed = true;\n    }\n    // A photoreal replacement gap holds the last valid center plane. It never\n    // substitutes an ellipsoid or camera-owned ground cache.\n\n    if (!this.wallMesh.geometry.getAttribute('position')) {\n      this._rebuildGeometry();\n    } else if (changed) {\n      this._writeGeometryPositions();\n    }\n    this.group.visible = this._requestedVisible && this.isTerrainMated();\n    this._syncSurfaceLight();\n    return changed;\n  }\n\n  getTopPosition(out = new THREE.Vector3(), extraM = 0) {\n    if (!Number.isFinite(this._centerRadius)) return null;\n    return out.copy(this._centerDir)\n      .multiplyScalar(\n        this._centerRadius\n        + this.heightM * this._heightScale\n        + Math.max(0, Number(extraM) || 0),\n      );\n  }\n\n  getTopLocalPosition(out = new THREE.Vector3(), extraM = 0) {\n    if (!Number.isFinite(this._centerRadius)) return null;\n    return out.copy(this._centerDir)\n      .multiplyScalar(this.heightM * this._heightScale + Math.max(0, Number(extraM) || 0));\n  }\n\n  _rebuildGeometry() {\n    if (!this.isTerrainMated()) return;\n    const count = this._ring.length;\n    const wallPositions = new Float32Array(count * 2 * 3);\n    const wallHeights = new Float32Array(count * 2);\n    const wallIndices = [];\n    const baseOutlinePositions = new Float32Array(count * 2 * 3);\n    const topOutlinePositions = new Float32Array(count * 2 * 3);\n    this._surfaceLocalPositions = new Float64Array(count * 3);\n    for (let i = 0; i < count; i += 1) {\n      const j = (i + 1) % count;\n      const aBase = i * 2;\n      const aTop = aBase + 1;\n      const bBase = j * 2;\n      const bTop = bBase + 1;\n      wallIndices.push(\n        aBase, bBase, bTop,\n        aBase, bTop, aTop,\n      );\n      wallHeights[aBase] = 0;\n      wallHeights[aTop] = 1;\n    }\n\n    const wallGeometry = new THREE.BufferGeometry();\n    wallGeometry.setAttribute(\n      'position',\n      new THREE.BufferAttribute(wallPositions, 3),\n    );\n    wallGeometry.setAttribute(\n      'markerHeight',\n      new THREE.BufferAttribute(wallHeights, 1),\n    );\n    wallGeometry.setIndex(wallIndices);\n\n    const outlineGeometry = new THREE.BufferGeometry();\n    outlineGeometry.setAttribute(\n      'position',\n      new THREE.BufferAttribute(baseOutlinePositions, 3),\n    );\n    const topOutlineGeometry = new THREE.BufferGeometry();\n    topOutlineGeometry.setAttribute(\n      'position',\n      new THREE.BufferAttribute(topOutlinePositions, 3),\n    );\n\n    this.wallMesh.geometry.dispose();\n    this.outline.geometry.dispose();\n    this.topOutline.geometry.dispose();\n    this.wallMesh.geometry = wallGeometry;\n    this.outline.geometry = outlineGeometry;\n    this.topOutline.geometry = topOutlineGeometry;\n    this._writeGeometryPositions({ computeBounds: true });\n  }\n\n  _writeGeometryPositions({ computeBounds = false } = {}) {\n    if (!this.isTerrainMated()) return false;\n    const count = this._ring.length;\n    const wallAttr = this.wallMesh.geometry.getAttribute('position');\n    const baseAttr = this.outline.geometry.getAttribute('position');\n    const topAttr = this.topOutline.geometry.getAttribute('position');\n    if (wallAttr?.count !== count * 2\n      || baseAttr?.count !== count * 2\n      || topAttr?.count !== count * 2\n      || this._surfaceLocalPositions?.length !== count * 3) {\n      this._rebuildGeometry();\n      return true;\n    }\n\n    const center = this._anchorLocked ? { lat: this._lat, lon: this._lon } : averageRing(this._ring);\n    this._centerDir.copy(latLonToLocalDir(center.lat, center.lon)).normalize();\n    this._centerRadius = this._anchorRadius;\n    const origin = this._tmpPoint.copy(this._centerDir).multiplyScalar(this._centerRadius);\n    this.group.position.copy(origin);\n    const radius = this._anchorRadius;\n    const topRadius = radius + this.heightM * this._heightScale;\n    if (this.selectionLine) {\n      const attribute = this.selectionLine.geometry.attributes.position;\n      attribute.setXYZ(0,this._centerDir.x*.08,this._centerDir.y*.08,this._centerDir.z*.08);\n      attribute.setXYZ(1,this._centerDir.x*this.heightM*this._heightScale,\n        this._centerDir.y*this.heightM*this._heightScale,this._centerDir.z*this.heightM*this._heightScale);\n      attribute.needsUpdate=true;\n    }\n    for (let i = 0; i < count; i += 1) {\n      const [lon, lat] = this._ring[i];\n      const dir = latLonToLocalDir(lat, lon, this._tmpVertexDir).normalize();\n      this._tmpBase.copy(dir).multiplyScalar(radius - this.embedM).sub(origin);\n      this._tmpSurface.copy(dir).multiplyScalar(radius + 0.08).sub(origin);\n      this._tmpTop.copy(dir).multiplyScalar(topRadius).sub(origin);\n      wallAttr.setXYZ(i * 2, this._tmpBase.x, this._tmpBase.y, this._tmpBase.z);\n      wallAttr.setXYZ(i * 2 + 1, this._tmpTop.x, this._tmpTop.y, this._tmpTop.z);\n      this._surfaceLocalPositions[i * 3] = this._tmpSurface.x;\n      this._surfaceLocalPositions[i * 3 + 1] = this._tmpSurface.y;\n      this._surfaceLocalPositions[i * 3 + 2] = this._tmpSurface.z;\n    }\n    for (let i = 0; i < count; i += 1) {\n      const next = (i + 1) % count;\n      baseAttr.setXYZ(\n        i * 2,\n        this._surfaceLocalPositions[i * 3],\n        this._surfaceLocalPositions[i * 3 + 1],\n        this._surfaceLocalPositions[i * 3 + 2],\n      );\n      baseAttr.setXYZ(\n        i * 2 + 1,\n        this._surfaceLocalPositions[next * 3],\n        this._surfaceLocalPositions[next * 3 + 1],\n        this._surfaceLocalPositions[next * 3 + 2],\n      );\n      topAttr.setXYZ(\n        i * 2,\n        wallAttr.getX(i * 2 + 1),\n        wallAttr.getY(i * 2 + 1),\n        wallAttr.getZ(i * 2 + 1),\n      );\n      topAttr.setXYZ(\n        i * 2 + 1,\n        wallAttr.getX(next * 2 + 1),\n        wallAttr.getY(next * 2 + 1),\n        wallAttr.getZ(next * 2 + 1),\n      );\n    }\n    wallAttr.needsUpdate = true;\n    baseAttr.needsUpdate = true;\n    topAttr.needsUpdate = true;\n    if (computeBounds) {\n      this.wallMesh.geometry.computeBoundingSphere();\n      this.outline.geometry.computeBoundingSphere();\n      this.topOutline.geometry.computeBoundingSphere();\n    }\n    return true;\n  }\n\n  dispose() {\n    ACTIVE_SURFACE_MARKER_LIGHTS.delete(this._surfaceLightId);\n    getSurfaceLightRegistry().touch();\n    releaseSurfaceMarkerLightProviderIfEmpty();\n    this.group.parent?.remove?.(this.group);\n    this.wallMesh.geometry.dispose();\n    this.outline.geometry.dispose();\n    this.topOutline.geometry.dispose();\n    this.wallMaterial.dispose();\n    this.outlineMaterial.dispose();\n    this.topOutlineMaterial.dispose();\n    this.selectionLine?.geometry.dispose();\n    this.selectionLine?.material.dispose();\n    this.group.clear();\n  }\n}\n\nexport default SurfaceFootprintMarker;\n","/**\n * IncidentOverlay\n *\n * Fetches PulsePoint incidents from the backend and renders markers on the surface.\n */\n\nimport * as THREE from 'three';\nimport { latLonToLocalDir, ellipsoidRadiusForLocalDir } from '../../modules/geometry-utils.js';\nimport { PLANET_RADIUS } from '../../modules/constants.js';\nimport { getIncidentApiService } from '../incidents/IncidentApiService.js';\nimport {\n  formatIncidentTypeLabel,\n  isActiveFireIncident,\n  isVegetationFireIncident,\n  resolveIncidentColor,\n} from '../incidents/IncidentTypes.js';\nimport { buildIncidentPresentation } from '../incidents/IncidentPresentation.js';\nimport { SurfaceFlameField } from '../environment/SurfaceFlameField.js';\nimport { getLabelSystem } from '../labels/LabelSystem.js';\nimport { terrainSurfaceChangesAffectLatLon } from '../scene/TerrainSurfaceChange.js';\nimport {\n  DEFAULT_INCIDENT_SPIRE_HEIGHT_M,\n  SurfaceFootprintMarker,\n} from './SurfaceFootprintMarker.js';\nimport {\n  eventRecencyBaseOpacity,\n  eventRecencyOpacity,\n  eventRecencySaturation,\n  recencyPhaseForIdentity,\n} from '../shared/EventRecency.js';\n\nconst DEFAULT_POLL_INTERVAL_MS = 60000;\nconst DEFAULT_RADIUS_M = 150000;\nconst DEFAULT_MAX_INCIDENTS = 200;\nconst DEFAULT_SPIRE_HEIGHT_M = DEFAULT_INCIDENT_SPIRE_HEIGHT_M;\nconst DEFAULT_SPIRE_RADIUS_M = 4;\nconst DEFAULT_SURFACE_OFFSET_M = -5; // Negative to push spire base slightly below terrain surface so it's flush\nconst DEFAULT_MARKER_OPACITY = 0.9;\nconst DEFAULT_LABEL_ENABLED = true;\nconst DEFAULT_LABEL_OFFSET_M = 1;\nconst DEFAULT_LABEL_MAX_CHARS = 64;\nconst DEFAULT_LABEL_VIEW_CONE_DEG = 60;\nconst SPIRE_RENDER_BIAS_M = 0; // No upward bias — spire should start at/below surface\nconst DEFAULT_VISIBILITY_UPDATE_MS = 100;\nconst DEFAULT_CULL_HYSTERESIS_M = 2000;\nconst SPIRE_HEIGHT_MIN_M = 5;\nconst SPIRE_HEIGHT_MAX_M = 300;\nconst SPIRE_RADIUS_MIN_M = 0.5;\nconst SPIRE_RADIUS_MAX_M = 40;\nconst PLACE_LOOKUP_RADIUS_M = 90;\nconst PLACE_LOOKUP_CONCURRENCY = 2;\nconst PLACE_LOOKUP_CACHE_TTL_MS = 15 * 60 * 1000;\nconst PLACE_LOOKUP_CACHE_LIMIT = 240;\nconst PLACE_LOOKUP_QUEUE_LIMIT = 80;\nconst FOOTPRINT_LOOKUP_RADIUS_M = 90;\nconst FOOTPRINT_BATCH_DELAY_MS = 1600;\nconst DESKTOP_ACTIVE_FIRE_LIMIT = 32;\nconst MOBILE_ACTIVE_FIRE_LIMIT = 16;\n\nconst toNumber = (value) => (Number.isFinite(value) ? value : null);\nconst clampSpireHeight = (value) => Math.min(SPIRE_HEIGHT_MAX_M, Math.max(SPIRE_HEIGHT_MIN_M, value));\nconst clampSpireRadius = (value) => Math.min(SPIRE_RADIUS_MAX_M, Math.max(SPIRE_RADIUS_MIN_M, value));\n\nconst truncateLabel = (value, maxChars) => {\n  if (!value) return '';\n  const text = String(value);\n  if (text.length <= maxChars) return text;\n  return `${text.slice(0, Math.max(0, maxChars - 3)).trim()}...`;\n};\n\nconst buildIncidentLabel = (entry) => {\n  const { title, subheader } = buildIncidentPresentation(entry);\n  const primary = truncateLabel(title, DEFAULT_LABEL_MAX_CHARS);\n  const secondary = truncateLabel(subheader, DEFAULT_LABEL_MAX_CHARS);\n  return secondary ? `${primary}\\n${secondary}` : primary;\n};\n\nconst placeLookupKey = (lat, lon) => (\n  Number.isFinite(lat) && Number.isFinite(lon)\n    ? `${lat.toFixed(4)}:${lon.toFixed(4)}`\n    : ''\n);\n\nconst normalizeAgencyIds = (value) => {\n  if (Array.isArray(value)) {\n    return value.map((entry) => String(entry).trim()).filter(Boolean);\n  }\n  if (typeof value === 'string') {\n    return value.split(',').map((entry) => entry.trim()).filter(Boolean);\n  }\n  return [];\n};\n\nconst parseIncidentTimestamp = (value) => {\n  if (Number.isFinite(value)) {\n    const num = Number(value);\n    if (num > 1e12) return num;\n    if (num > 1e9) return num * 1000;\n    return num;\n  }\n  if (typeof value === 'string') {\n    const parsed = Date.parse(value);\n    return Number.isFinite(parsed) ? parsed : null;\n  }\n  return null;\n};\n\nexport class IncidentOverlay {\n  constructor({\n    parentGroup,\n    planetRadius,\n    eventBus,\n    sceneInitializer,\n    surfaceController,\n    camera,\n    terrainSampler,\n    buildingResolver,\n    footprintResolver,\n    footprintBatchDelayMs,\n    enabled,\n    pollIntervalMs,\n    radiusM,\n    maxIncidents,\n    markerScaleM,\n    spireHeightM,\n    spireRadiusM,\n    surfaceOffsetM,\n    showLabels,\n    labelScaleM,\n    labelOffsetM,\n    labelViewConeDeg,\n    includeRecent,\n    includeAlerts,\n    publicOnly,\n    hideMedical,\n    agencyIds,\n    cullDistanceM,\n    cullHysteresisM,\n    mobile = false,\n  } = {}) {\n    this.parentGroup = parentGroup || null;\n    this.planetRadius = Number.isFinite(planetRadius) ? planetRadius : PLANET_RADIUS;\n    this.eventBus = eventBus || null;\n    this.sceneInitializer = sceneInitializer || null;\n    this.surfaceController = surfaceController || null;\n    this.camera = camera || null;\n    this.mobile = !!mobile;\n    this._buildingResolver = typeof buildingResolver === 'function' ? buildingResolver : null;\n    this._footprintResolver = typeof footprintResolver === 'function' ? footprintResolver : null;\n    this._footprintBatchDelayMs = Number.isFinite(footprintBatchDelayMs)\n      ? Math.max(0, Number(footprintBatchDelayMs))\n      : FOOTPRINT_BATCH_DELAY_MS;\n\n    this.enabled = enabled === true;\n    this.pollIntervalMs = Number.isFinite(pollIntervalMs) ? pollIntervalMs : DEFAULT_POLL_INTERVAL_MS;\n    this.radiusM = Number.isFinite(radiusM) ? radiusM : DEFAULT_RADIUS_M;\n    const fallbackCullDistanceM = Number.isFinite(this.radiusM) ? this.radiusM : DEFAULT_RADIUS_M;\n    this.cullDistanceM = Number.isFinite(cullDistanceM) ? cullDistanceM : fallbackCullDistanceM;\n    this.cullHysteresisM = Number.isFinite(cullHysteresisM)\n      ? cullHysteresisM\n      : DEFAULT_CULL_HYSTERESIS_M;\n    this.maxIncidents = Number.isFinite(maxIncidents) ? maxIncidents : DEFAULT_MAX_INCIDENTS;\n    const nextHeight = Number.isFinite(spireHeightM)\n      ? spireHeightM\n      : (Number.isFinite(markerScaleM) ? markerScaleM : DEFAULT_SPIRE_HEIGHT_M);\n    this.spireHeightM = clampSpireHeight(nextHeight);\n    this.markerScaleM = this.spireHeightM;\n    const nextRadius = Number.isFinite(spireRadiusM) ? spireRadiusM : DEFAULT_SPIRE_RADIUS_M;\n    this.spireRadiusM = clampSpireRadius(nextRadius);\n    this.surfaceOffsetM = DEFAULT_SURFACE_OFFSET_M;\n    this.showLabels = typeof showLabels === 'boolean' ? showLabels : DEFAULT_LABEL_ENABLED;\n    this.labelScaleM = Number.isFinite(labelScaleM) ? labelScaleM : null;\n    this.labelOffsetM = Number.isFinite(labelOffsetM) ? labelOffsetM : DEFAULT_LABEL_OFFSET_M;\n    this.labelViewConeDeg = Number.isFinite(labelViewConeDeg) ? labelViewConeDeg : DEFAULT_LABEL_VIEW_CONE_DEG;\n    this.includeRecent = includeRecent === true;\n    this.includeAlerts = includeAlerts === true;\n    this.publicOnly = publicOnly === true;\n    this.hideMedical = hideMedical === true;\n    this.agencyIds = normalizeAgencyIds(agencyIds);\n\n    // Pass mutateCache:false to prevent overlay samples from contaminating\n    // the camera's terrain clamp state (was causing camera altitude jumps).\n    this._terrainSampler = typeof terrainSampler === 'function'\n      ? terrainSampler\n      : (this.surfaceController?.sampleTerrainRadiusForDir\n        ? (dir, options = {}) => this.surfaceController.sampleTerrainRadiusForDir(dir, {\n            mutateCache: false,\n            ...options,\n          })\n        : null);\n\n    this._api = getIncidentApiService();\n    this._entries = new Map();\n    this._center = null;\n    this._pollElapsedMs = 0;\n    this._refreshQueued = false;\n    this._inflight = false;\n    this._pollTimer = null;\n\n    this.group = new THREE.Group();\n    this.group.name = 'IncidentOverlay';\n    this.group.visible = this.enabled;\n    this.parentGroup?.add(this.group);\n\n    this._fireField = new SurfaceFlameField({\n      parentGroup: this.group,\n      maxAnchors: this.mobile ? MOBILE_ACTIVE_FIRE_LIMIT : DESKTOP_ACTIVE_FIRE_LIMIT,\n      mobile: this.mobile,\n      name: 'Active incident flames',\n      renderOrder: 15,\n    });\n    this._fireAnchors = [];\n    this._fireEffectsDirty = true;\n    this._lastFireRecencyRefreshMs = 0;\n\n    if (this.sceneInitializer && typeof this.sceneInitializer.addDepthPassExclude === 'function') {\n      this.sceneInitializer.addDepthPassExclude(this.group);\n    }\n\n    this._tmpVec = new THREE.Vector3();\n    this._tmpQuat = new THREE.Quaternion();\n    this._worldUp = new THREE.Vector3(0, 1, 0);\n    this._tmpCamPos = new THREE.Vector3();\n    this._tmpCamDir = new THREE.Vector3();\n    this._tmpLabelVec = new THREE.Vector3();\n    this._tmpObserverLocal = new THREE.Vector3();\n    this._tmpFireDirection = new THREE.Vector3();\n    this._tmpRecencyHsl = { h: 0, s: 0, l: 0 };\n    this._hoveredEntry = null;\n    this._labelSystem = null;\n    this._visibilityElapsedMs = DEFAULT_VISIBILITY_UPDATE_MS;\n    this._placeLookupQueue = [];\n    this._queuedPlaceLookupKeys = new Set();\n    this._placeLookupCache = new Map();\n    this._activePlaceLookups = 0;\n    this._placeLookupControllers = new Map();\n    this._placeResolverPromise = null;\n    this._footprintResolverPromise = null;\n    this._footprintBatchTimer = null;\n    this._footprintBatchController = null;\n    this._footprintBatchSeq = 0;\n    this._footprintBatchBusy = false;\n    this._disposed = false;\n\n    this._bindConfigListener();\n    if (this.enabled && this.agencyIds.length) this._scheduleIncidentFetch(0);\n  }\n\n  setCenter(lat, lon, opts = {}) {\n    if (!Number.isFinite(lat) || !Number.isFinite(lon)) return;\n    this._center = { lat, lon };\n    if (Number.isFinite(opts.radiusM)) this.radiusM = opts.radiusM;\n    if (Number.isFinite(opts.maxIncidents)) this.maxIncidents = opts.maxIncidents;\n    if (Number.isFinite(opts.pollIntervalMs)) this.pollIntervalMs = opts.pollIntervalMs;\n    this.refresh();\n  }\n\n  refresh() {\n    this._refreshQueued = true;\n    this._scheduleIncidentFetch(0);\n  }\n\n  clear() {\n    this._cancelFootprintBatch();\n    for (const entry of this._entries.values()) {\n      this._disposeEntry(entry);\n    }\n    this._entries.clear();\n    this._fireField?.clear?.();\n    this._fireEffectsDirty = false;\n  }\n\n  dispose() {\n    this._disposed = true;\n    this._stopIncidentFetchSchedule();\n    this.clear();\n    this._placeLookupQueue.length = 0;\n    this._queuedPlaceLookupKeys.clear();\n    for (const controller of this._placeLookupControllers.values()) controller.abort();\n    this._placeLookupControllers.clear();\n    this._placeLookupCache.clear();\n    this._cancelFootprintBatch();\n    this._fireField?.dispose?.();\n    this._fireField = null;\n    if (this.group && this.group.parent) {\n      this.group.parent.remove(this.group);\n    }\n    if (this.sceneInitializer && typeof this.sceneInitializer.removeDepthPassExclude === 'function') {\n      this.sceneInitializer.removeDepthPassExclude(this.group);\n    }\n    this._unbindConfigListener();\n    this._labelSystem = null;\n  }\n\n  update(dt) {\n    if (!this.enabled) return;\n    const deltaMs = (Number.isFinite(dt) ? dt : 0) * 1000;\n    const now = Date.now();\n    this._fireField?.update?.(now / 1000);\n    if (now - this._lastFireRecencyRefreshMs >= 60_000) this._fireEffectsDirty = true;\n    this._visibilityElapsedMs += deltaMs;\n    this._updateMarkerPulse();\n    if (this._visibilityElapsedMs >= DEFAULT_VISIBILITY_UPDATE_MS) {\n      this._visibilityElapsedMs = 0;\n      this._updateCullState();\n    }\n    if (this._fireEffectsDirty) this._syncFireEffects();\n  }\n\n  getEntriesSnapshot() {\n    const entries = [];\n    for (const entry of this._entries.values()) {\n      entries.push({\n        id: entry.id,\n        agencyId: entry.agencyId,\n        callType: entry.callType,\n        lat: entry.lat,\n        lon: entry.lon,\n        address: entry.address,\n        placeName: entry.placeName,\n        placeType: entry.placeType,\n        receivedAt: entry.receivedAt,\n        distanceM: entry.distanceM,\n      });\n    }\n    return entries;\n  }\n\n  async _fetchIncidents() {\n    if (this._inflight) return;\n    if (!this.enabled) return;\n    if (!this.agencyIds.length) {\n      this.clear();\n      return;\n    }\n\n    this._inflight = true;\n    try {\n      const params = {\n        agencyIds: this.agencyIds,\n        maxResults: this.maxIncidents,\n        radiusM: this.radiusM,\n        includeRecent: this.includeRecent || undefined,\n        includeAlerts: this.includeAlerts || undefined,\n        publicOnly: this.publicOnly || undefined,\n        hideMedical: this.hideMedical || undefined,\n      };\n      if (this._center) {\n        params.lat = this._center.lat;\n        params.lon = this._center.lon;\n      }\n      const response = await this._api.getIncidents(params);\n      const incidents = Array.isArray(response?.incidents) ? response.incidents : [];\n      this._applyIncidents(incidents);\n    } catch (error) {\n      console.warn('[IncidentOverlay] Failed to fetch incidents', error);\n    } finally {\n      this._inflight = false;\n      if (!this._disposed && this.enabled) this._scheduleIncidentFetch(this.pollIntervalMs);\n    }\n  }\n\n  _scheduleIncidentFetch(delayMs = this.pollIntervalMs) {\n    if (this._disposed || !this.enabled || !Number.isFinite(delayMs)) return;\n    if (this._pollTimer) clearTimeout(this._pollTimer);\n    this._pollTimer = setTimeout(() => {\n      this._pollTimer = null;\n      this._refreshQueued = false;\n      void this._fetchIncidents();\n    }, Math.max(0, delayMs));\n  }\n\n  _stopIncidentFetchSchedule() {\n    if (!this._pollTimer) return;\n    clearTimeout(this._pollTimer);\n    this._pollTimer = null;\n  }\n\n  _applyIncidents(incidents) {\n    const nextIds = new Set();\n    const placeEnrichmentEntries = [];\n\n    incidents.forEach((incident) => {\n      if (!incident) return;\n      const id = incident.id || incident.ID || incident.IncidentID;\n      if (!id) return;\n      const key = String(id);\n      nextIds.add(key);\n\n      let entry = this._entries.get(key);\n      if (!entry) {\n        entry = this._createEntry(key, incident);\n        this._entries.set(key, entry);\n        if (entry.object && !entry.object.parent) {\n          this.group.add(entry.object);\n        }\n      }\n\n      entry.agencyId = incident.agencyId || entry.agencyId;\n      entry.callType = incident.callType || entry.callType;\n      const nextLat = toNumber(incident.lat);\n      const nextLon = toNumber(incident.lon);\n      const placeChanged = entry.lat !== nextLat || entry.lon !== nextLon;\n      entry.lat = nextLat;\n      entry.lon = nextLon;\n      entry.address = incident.address || entry.address;\n      entry.receivedAt = incident.receivedAt || entry.receivedAt;\n      entry.receivedAtMs = parseIncidentTimestamp(entry.receivedAt);\n      entry.distanceM = toNumber(incident.distanceM);\n      if (placeChanged) {\n        entry.placeName = null;\n        entry.placeType = null;\n        entry.placeAddress = null;\n        entry.placeLookupKey = null;\n        entry.localFootprintLookupKey = null;\n        entry.marker?.setFallback(nextLat, nextLon, this.spireRadiusM * 2);\n      }\n      if (incident.placeName) entry.placeName = String(incident.placeName).trim();\n      if (incident.placeType) entry.placeType = String(incident.placeType).trim();\n      if (incident.placeAddress) entry.placeAddress = String(incident.placeAddress).trim();\n\n      const nextColor = resolveIncidentColor(entry.callType);\n      if (entry.baseColor) {\n        entry.baseColor.setHex(nextColor);\n      }\n      if (entry.material?.uniforms?.uColor) {\n        entry.material.uniforms.uColor.value.setHex(nextColor);\n      }\n      entry.marker?.setColor?.(nextColor);\n\n      this._updateEntryLabel(entry);\n      this._updateEntryPosition(entry);\n      placeEnrichmentEntries.push(entry);\n    });\n\n    for (const [id, entry] of this._entries.entries()) {\n      if (!nextIds.has(id)) {\n        this._disposeEntry(entry);\n        this._entries.delete(id);\n        this._cancelPlaceLookupForKey(entry.placeLookupKey);\n      }\n    }\n\n    this._scheduleFootprintBatch();\n    // Geometry is the primary incident presentation. Queue human-readable\n    // place enrichment only after the footprint gate is active so dozens of\n    // optional named-place requests cannot strand the spires behind them.\n    for (const entry of placeEnrichmentEntries) {\n      this._queuePlaceEnrichment(entry);\n    }\n    this._fireEffectsDirty = true;\n    this._syncFireEffects();\n    this._emitEntriesSnapshot();\n  }\n\n  _createEntry(id, incident) {\n    const color = resolveIncidentColor(incident?.callType);\n    const pulsePhase = recencyPhaseForIdentity(id);\n    const baseHeightM = this.spireHeightM;\n    const baseRadiusM = this.spireRadiusM;\n    const marker = new SurfaceFootprintMarker({\n      parentGroup: this.group,\n      surfaceController: this.surfaceController,\n      color,\n      heightM: baseHeightM,\n      embedM: Math.max(1.5, Math.min(4, baseHeightM * 0.08)),\n      opacity: DEFAULT_MARKER_OPACITY,\n      outlineOpacity: 0.94,\n      renderOrder: 5,\n      name: `IncidentFootprint:${id}`,\n      lightChannel: 'incidents',\n      lightPriority: isActiveFireIncident(incident?.callType) ? 145 : 125,\n      lightRadiusM: isVegetationFireIncident(incident?.callType)\n        ? 360\n        : (isActiveFireIncident(incident?.callType) ? 250 : 145),\n      lightIntensityScale: isActiveFireIncident(incident?.callType) ? 1.55 : 1.35,\n      lightPulseHz: isActiveFireIncident(incident?.callType) ? 1.25 : 0.72,\n      lightPhase: pulsePhase,\n      lightShadowStrength: 0.88,\n    });\n    const mesh = marker.group;\n\n    const entry = {\n      id,\n      agencyId: incident?.agencyId || null,\n      callType: incident?.callType || null,\n      lat: toNumber(incident?.lat),\n      lon: toNumber(incident?.lon),\n      address: incident?.address || null,\n      placeName: incident?.placeName ? String(incident.placeName).trim() : null,\n      placeType: incident?.placeType ? String(incident.placeType).trim() : null,\n      placeAddress: incident?.placeAddress ? String(incident.placeAddress).trim() : null,\n      placeLookupKey: null,\n      receivedAt: incident?.receivedAt || null,\n      receivedAtMs: parseIncidentTimestamp(incident?.receivedAt),\n      distanceM: toNumber(incident?.distanceM),\n      object: mesh,\n      marker,\n      material: marker.wallMaterial,\n      baseColor: new THREE.Color(color),\n      recencyColor: new THREE.Color(color),\n      pulsePhase,\n      baseHeightM,\n      baseRadiusM,\n      heightM: baseHeightM,\n      radiusM: baseRadiusM,\n      label: null,\n      labelMaterial: null,\n      labelTexture: null,\n      labelText: '',\n      labelReceivedAt: null,\n      labelAspect: null,\n    };\n    marker.setFallback(entry.lat, entry.lon, baseRadiusM * 2);\n    this._applySpireScale(entry);\n    mesh.userData.incidentEntry = entry;\n    marker.wallMesh.userData.incidentEntry = entry;\n    marker.outline.userData.incidentEntry = entry;\n    return entry;\n  }\n\n  _disposeEntry(entry) {\n    if (!entry) return;\n    this._disposeLabel(entry);\n    if (entry.marker) entry.marker.dispose();\n    else if (entry.object?.parent) entry.object.parent.remove(entry.object);\n  }\n\n  _emitEntriesSnapshot() {\n    if (this.eventBus && typeof this.eventBus.emit === 'function') {\n      this.eventBus.emit('incidents:entries', this.getEntriesSnapshot());\n    }\n  }\n\n  _queuePlaceEnrichment(entry) {\n    if (!entry || !Number.isFinite(entry.lat) || !Number.isFinite(entry.lon)) return;\n    if (entry.placeName && entry.marker?.source !== 'fallback') return;\n    const key = placeLookupKey(entry.lat, entry.lon);\n    if (!key) return;\n    entry.placeLookupKey = key;\n\n    const cached = this._placeLookupCache.get(key);\n    if (cached && cached.expiresAt > Date.now()) {\n      this._applyPlaceContext(key, cached.value);\n      return;\n    }\n    if (cached) this._placeLookupCache.delete(key);\n    if (this._queuedPlaceLookupKeys.has(key)) return;\n    if (this._placeLookupQueue.length >= PLACE_LOOKUP_QUEUE_LIMIT) return;\n\n    this._queuedPlaceLookupKeys.add(key);\n    this._placeLookupQueue.push({\n      key,\n      lat: entry.lat,\n      lon: entry.lon,\n      address: entry.address || '',\n    });\n    this._drainPlaceLookupQueue();\n  }\n\n  _drainPlaceLookupQueue() {\n    while (!this._disposed\n      && !this._footprintBatchBusy\n      && this._activePlaceLookups < PLACE_LOOKUP_CONCURRENCY\n      && this._placeLookupQueue.length) {\n      const task = this._placeLookupQueue.shift();\n      this._activePlaceLookups += 1;\n      const controller = new AbortController();\n      this._placeLookupControllers.set(task.key, controller);\n      this._resolveIncidentPlace({ ...task, signal: controller.signal })\n        .catch(() => null)\n        .then((place) => {\n          if (this._disposed) return;\n          this._placeLookupCache.set(task.key, {\n            value: place || null,\n            expiresAt: Date.now() + PLACE_LOOKUP_CACHE_TTL_MS,\n          });\n          if (this._placeLookupCache.size > PLACE_LOOKUP_CACHE_LIMIT) {\n            const oldestKey = this._placeLookupCache.keys().next().value;\n            if (oldestKey) this._placeLookupCache.delete(oldestKey);\n          }\n          this._applyPlaceContext(task.key, place || null);\n        })\n        .finally(() => {\n          if (this._placeLookupControllers.get(task.key) === controller) {\n            this._placeLookupControllers.delete(task.key);\n          }\n          this._activePlaceLookups = Math.max(0, this._activePlaceLookups - 1);\n          this._queuedPlaceLookupKeys.delete(task.key);\n          this._drainPlaceLookupQueue();\n        });\n    }\n  }\n\n  async _resolveIncidentPlace({ lat, lon, address, signal }) {\n    if (!this._placeResolverPromise) {\n      this._placeResolverPromise = import('../../modules/geocoding-service.js')\n        .then((module) => module.fetchOsmPlaceDetails);\n    }\n    const resolvePlace = await this._placeResolverPromise;\n    if (typeof resolvePlace !== 'function') return null;\n    return resolvePlace(lat, lon, {\n      address,\n      radiusM: PLACE_LOOKUP_RADIUS_M,\n      timeoutMs: 9000,\n      signal,\n    });\n  }\n\n  _cancelPlaceLookupForKey(key) {\n    if (!key) return;\n    if ([...this._entries.values()].some((entry) => entry.placeLookupKey === key)) return;\n    this._placeLookupQueue = this._placeLookupQueue.filter((task) => task.key !== key);\n    this._queuedPlaceLookupKeys.delete(key);\n    this._placeLookupControllers.get(key)?.abort?.();\n  }\n\n  _scheduleFootprintBatch() {\n    if (this._disposed) return;\n    const hasPending = [...this._entries.values()].some((entry) => (\n      entry?.marker?.source === 'fallback'\n      && Number.isFinite(entry.lat)\n      && Number.isFinite(entry.lon)\n    ));\n    if (!hasPending) {\n      this._footprintBatchBusy = false;\n      this._drainPlaceLookupQueue();\n      return;\n    }\n    this._footprintBatchBusy = true;\n    // A later incident refresh can arrive while secondary place enrichment is\n    // active. Relinquish that shared Overpass lane so the new geometry remains\n    // the first request admitted for the refreshed set.\n    for (const controller of this._placeLookupControllers.values()) {\n      controller.abort();\n    }\n    if (this._footprintBatchTimer) clearTimeout(this._footprintBatchTimer);\n    this._footprintBatchTimer = setTimeout(() => {\n      this._footprintBatchTimer = null;\n      void this._resolveFootprintBatch();\n    }, this._footprintBatchDelayMs);\n  }\n\n  _cancelFootprintBatch() {\n    this._footprintBatchSeq += 1;\n    if (this._footprintBatchTimer) clearTimeout(this._footprintBatchTimer);\n    this._footprintBatchTimer = null;\n    this._footprintBatchController?.abort?.();\n    this._footprintBatchController = null;\n    this._footprintBatchBusy = false;\n  }\n\n  async _resolveFootprintBatch() {\n    if (this._disposed) return;\n    const pending = [...this._entries.values()].filter((entry) => (\n      entry?.marker?.source === 'fallback'\n      && Number.isFinite(entry.lat)\n      && Number.isFinite(entry.lon)\n    ));\n    if (!pending.length) {\n      this._footprintBatchBusy = false;\n      this._drainPlaceLookupQueue();\n      return;\n    }\n\n    if (!this._footprintResolverPromise) {\n      this._footprintResolverPromise = this._footprintResolver\n        ? Promise.resolve(this._footprintResolver)\n        : import('../../modules/geocoding-service.js')\n            .then((module) => module.fetchBuildingFootprintsForPoints);\n    }\n    let resolver = null;\n    try {\n      resolver = await this._footprintResolverPromise;\n    } catch (error) {\n      this._footprintBatchBusy = false;\n      this._drainPlaceLookupQueue();\n      if (!this._disposed) {\n        console.warn('[IncidentOverlay] Building footprint resolver unavailable', error);\n      }\n      return;\n    }\n    if (typeof resolver !== 'function' || this._disposed) {\n      this._footprintBatchBusy = false;\n      this._drainPlaceLookupQueue();\n      return;\n    }\n\n    const seq = ++this._footprintBatchSeq;\n    this._footprintBatchController?.abort?.();\n    const controller = new AbortController();\n    this._footprintBatchController = controller;\n    try {\n      const resolved = await resolver(\n        pending.map((entry) => ({ id: entry.id, lat: entry.lat, lon: entry.lon })),\n        {\n          radiusM: FOOTPRINT_LOOKUP_RADIUS_M,\n          timeoutMs: 9000,\n          signal: controller.signal,\n        },\n      );\n      if (this._disposed || controller.signal.aborted || seq !== this._footprintBatchSeq) return;\n      const byId = new Map(\n        (Array.isArray(resolved) ? resolved : [])\n          .map((item) => [String(item?.id), item?.footprint || null]),\n      );\n      let changed = false;\n      for (const entry of pending) {\n        if (this._entries.get(entry.id) !== entry || entry.marker?.source !== 'fallback') continue;\n        const footprint = byId.get(String(entry.id));\n        if (!footprint) continue;\n        if (!entry.marker.setFootprint(footprint, {\n          lat: entry.lat,\n          lon: entry.lon,\n          source: 'overpass',\n        })) continue;\n        this._updateEntryPosition(entry);\n        changed = true;\n      }\n      if (changed) this._emitEntriesSnapshot();\n    } catch (error) {\n      if (error?.name !== 'AbortError' && !controller.signal.aborted) {\n        console.warn('[IncidentOverlay] Building footprint batch failed', error);\n      }\n    } finally {\n      if (this._footprintBatchController === controller) {\n        this._footprintBatchController = null;\n        this._footprintBatchBusy = false;\n        this._drainPlaceLookupQueue();\n      }\n    }\n  }\n\n  _applyPlaceContext(key, resolved) {\n    const place = resolved?.place ?? resolved;\n    let changed = false;\n    for (const entry of this._entries.values()) {\n      if (!entry || entry.placeLookupKey !== key) continue;\n      if (entry.placeName) continue;\n      const placeName = place?.name ? String(place.name).trim() : '';\n      if (!placeName) continue;\n      entry.placeName = placeName;\n      entry.placeType = place?.type ? String(place.type).trim() : null;\n      entry.placeAddress = place?.address ? String(place.address).trim() : null;\n      this._updateEntryLabel(entry);\n      changed = true;\n    }\n    if (changed) this._emitEntriesSnapshot();\n  }\n\n  _applySpireScale(entry) {\n    if (!entry?.object) return;\n    entry.baseHeightM = this.spireHeightM;\n    entry.baseRadiusM = this.spireRadiusM;\n    entry.heightM = entry.baseHeightM;\n    entry.radiusM = entry.baseRadiusM;\n    if (entry.marker) {\n      entry.marker.setHeight(entry.heightM);\n      if (entry.marker.source === 'fallback') {\n        entry.marker.setFallback(entry.lat, entry.lon, entry.radiusM * 2);\n      }\n    }\n  }\n\n  setLabelsEnabled(enabled) {\n    this.showLabels = !!enabled;\n    for (const entry of this._entries.values()) {\n      this._updateEntryLabel(entry);\n      this._updateEntryPosition(entry);\n    }\n  }\n\n  _ensureLabelSystem() {\n    if (!this._labelSystem) {\n      try {\n        this._labelSystem = getLabelSystem({ planetRadius: this.planetRadius });\n      } catch { /* Label system not available */ }\n    }\n    return this._labelSystem;\n  }\n\n  _disposeLabel(entry) {\n    if (!entry) return;\n    if (entry.labelHandle) {\n      entry.labelHandle.group?.parent?.remove?.(entry.labelHandle.group);\n      const ls = this._ensureLabelSystem();\n      if (ls) ls.removeLabel(entry.labelHandle);\n      entry.labelHandle = null;\n    }\n    entry.labelCallType = null;\n    // Legacy fields cleanup\n    entry.label = null;\n    entry.labelMaterial = null;\n    entry.labelTexture = null;\n    entry.labelText = '';\n    entry.labelReceivedAt = null;\n    entry.labelAspect = null;\n  }\n\n  _updateEntryLabel(entry) {\n    if (!entry) return;\n    if (!this.showLabels) {\n      this._disposeLabel(entry);\n      return;\n    }\n    const nextText = buildIncidentLabel(entry);\n    if (!nextText) {\n      this._disposeLabel(entry);\n      return;\n    }\n    if (\n      entry.labelHandle\n      && entry.labelText === nextText\n      && entry.labelCallType === entry.callType\n      && entry.labelReceivedAt === entry.receivedAt\n    ) return;\n    this._disposeLabel(entry);\n    const ls = this._ensureLabelSystem();\n    if (!ls) return;\n    // Split text into primary + subtext on newline\n    const lines = nextText.split('\\n');\n    const primary = lines[0] || nextText;\n    const subText = lines.length > 1 ? lines.slice(1).join(' ') : '';\n    // A fallback footprint is intentionally never rendered as presentation\n    // geometry. Keep its label in the overlay root so calls remain visible\n    // while an accurate building outline is resolving (or when an outdoor\n    // incident has no building footprint at all). Once real geometry arrives,\n    // ownership moves atomically to the marker.\n    const markerOwned = !!entry.marker && entry.marker.source !== 'fallback';\n    const pos = new THREE.Vector3();\n    this._resolveEntryLabelPosition(entry, pos, { markerLocal: markerOwned });\n    entry.labelHandle = ls.createLabel(primary, {\n      position: pos,\n      type: 'incident',\n      color: resolveIncidentColor(entry.callType),\n      objectRadius: Math.max(4, this.spireRadiusM),\n      subText,\n      occurredAt: entry.receivedAt,\n      recencyAnimated: Number.isFinite(entry.receivedAtMs),\n      recencyPhase: entry.pulsePhase,\n      sourceVisible: entry.culled !== true,\n      metadata: {\n        id: entry.id,\n        agencyId: entry.agencyId,\n        callType: entry.callType,\n        callTypeLabel: formatIncidentTypeLabel(entry.callType, { includeCode: true, fallback: '' }),\n        address: entry.address,\n        placeName: entry.placeName,\n        placeType: entry.placeType,\n        placeAddress: entry.placeAddress,\n        receivedAt: entry.receivedAt,\n        lat: entry.lat,\n        lon: entry.lon,\n        distanceM: entry.distanceM,\n      },\n    });\n    if (entry.labelHandle?.group) {\n      (markerOwned ? entry.marker.group : this.group).add(entry.labelHandle.group);\n    }\n    entry.labelText = nextText;\n    entry.labelCallType = entry.callType;\n    entry.labelReceivedAt = entry.receivedAt;\n  }\n\n  _resolveLabelOffsetM(entry) {\n    const extra = Number.isFinite(this.labelOffsetM) ? this.labelOffsetM : DEFAULT_LABEL_OFFSET_M;\n    const markerHeight = Number.isFinite(entry?.heightM) ? entry.heightM : DEFAULT_SPIRE_HEIGHT_M;\n    return Math.max(0, markerHeight) + Math.max(1, extra);\n  }\n\n  _resolveEntryLabelPosition(entry, out, { markerLocal = false } = {}) {\n    const markerOwnsLabel = markerLocal\n      || entry?.labelHandle?.group?.parent === entry?.marker?.group;\n    if (markerOwnsLabel\n      && entry?.marker?.getTopLocalPosition(out, Math.max(1, this.labelOffsetM))) {\n      return out;\n    }\n    if (entry?.marker?.getTopPosition(out, Math.max(1, this.labelOffsetM))) {\n      return out;\n    }\n    const dir = (entry?.lat != null && entry?.lon != null)\n      ? latLonToLocalDir(entry.lat, entry.lon)\n      : null;\n    if (dir && entry?.object) {\n      const surfaceRadius = Number.isFinite(entry._stableRadius)\n        ? entry._stableRadius\n        : this._resolveSurfaceSample(dir).radius;\n      const radius = surfaceRadius + this.surfaceOffsetM + SPIRE_RENDER_BIAS_M;\n      return out.copy(dir).multiplyScalar(radius + this._resolveLabelOffsetM(entry));\n    }\n    if (entry?.object) return out.copy(entry.object.position);\n    return out.set(0, 0, 0);\n  }\n\n  _syncEntryLabelOwner(entry) {\n    const labelGroup = entry?.labelHandle?.group;\n    if (!labelGroup) return;\n    const markerOwned = !!entry.marker && entry.marker.source !== 'fallback';\n    const owner = markerOwned ? entry.marker.group : this.group;\n    if (labelGroup.parent !== owner) owner.add(labelGroup);\n    entry.labelHandle.sourceVisible = entry.culled !== true;\n    this._resolveEntryLabelPosition(entry, this._tmpLabelVec, { markerLocal: markerOwned });\n    this._ensureLabelSystem()?.updatePosition(entry.labelHandle, this._tmpLabelVec);\n  }\n\n  _resolveSurfaceSample(localDir) {\n    if (!localDir) return { radius: this.planetRadius, authoritative: false };\n    const ellipsoidR = ellipsoidRadiusForLocalDir(localDir);\n    if (!this._terrainSampler) return { radius: ellipsoidR, authoritative: false };\n    const worldDir = this._tmpVec.copy(localDir).normalize();\n    if (this.parentGroup && this.parentGroup.getWorldQuaternion) {\n      this.parentGroup.getWorldQuaternion(this._tmpQuat);\n      worldDir.applyQuaternion(this._tmpQuat);\n    }\n    const requireFreshPhotoHit = !!this.surfaceController?.photoTileGroup;\n    const sampled = this._terrainSampler(worldDir, {\n      mutateCache: false,\n      requireFreshPhotoHit,\n      allowTriTreeFallback: !requireFreshPhotoHit,\n      skipWorldMatrixUpdate: true,\n    });\n    return Number.isFinite(sampled)\n      ? { radius: sampled, authoritative: true }\n      : { radius: ellipsoidR, authoritative: false };\n  }\n\n  _updateEntryPosition(entry) {\n    if (!entry?.object) return;\n    if (!Number.isFinite(entry.lat) || !Number.isFinite(entry.lon)) return;\n    if (entry.marker) {\n      const localLookupKey = placeLookupKey(entry.lat, entry.lon);\n      if (entry.marker.source === 'fallback'\n        && this._buildingResolver\n        && entry.localFootprintLookupKey !== localLookupKey) {\n        entry.localFootprintLookupKey = localLookupKey;\n        const building = this._buildingResolver(entry.lat, entry.lon);\n        if (building?.footprint?.length >= 3) {\n          entry.marker.setFootprint({ latLonPairs: building.footprint }, {\n            lat: entry.lat,\n            lon: entry.lon,\n            source: 'building-overlay',\n          });\n        }\n      }\n      entry.marker.refreshTerrain();\n      if (Number.isFinite(entry.marker.centerRadius)) {\n        entry._stableRadius = entry.marker.centerRadius;\n      }\n      entry._terrainMated = entry.marker.isTerrainMated();\n      // A square is only a lookup placeholder, never a presentation shape.\n      // The marker/label entity appears atomically once a real building ring\n      // has been resolved and terrain-mated.\n      entry.marker.setVisible(!entry.culled && entry.marker.source !== 'fallback');\n      if (entry.labelHandle) {\n        this._syncEntryLabelOwner(entry);\n      }\n      this._fireEffectsDirty = true;\n      return;\n    }\n    const dir = latLonToLocalDir(entry.lat, entry.lon);\n    const ellipsoidR = ellipsoidRadiusForLocalDir(dir);\n    const sample = this._resolveSurfaceSample(dir);\n\n    // A fresh ray against the currently rendered tile is authoritative in\n    // both directions. Never ease a visible LOD correction: doing so made all\n    // incidents climb 5% per one-second poll for nearly a minute. If a tile\n    // temporarily disappears during replacement, hold the last mated radius\n    // until the replacement's regional visibility event supplies a fresh hit.\n    let stableR = Number.isFinite(entry._stableRadius) ? entry._stableRadius : ellipsoidR;\n    if (sample.authoritative) {\n      stableR = sample.radius;\n      entry._stableRadius = stableR;\n      entry._terrainMated = true;\n    }\n\n    const radius = stableR + this.surfaceOffsetM + SPIRE_RENDER_BIAS_M;\n    entry.object.position.copy(dir).multiplyScalar(radius);\n    entry.object.quaternion.setFromUnitVectors(this._worldUp, dir);\n    if (entry.labelHandle) {\n      const labelRadius = radius + this._resolveLabelOffsetM(entry);\n      this._tmpLabelVec.copy(dir).multiplyScalar(labelRadius);\n      const ls = this._ensureLabelSystem();\n      if (ls) ls.updatePosition(entry.labelHandle, this._tmpLabelVec);\n    }\n    this._fireEffectsDirty = true;\n  }\n\n  /**\n   * Native photoreal traversal calls this only when a tile changes ownership.\n   * Already-mated incidents outside the changed footprints do zero work.\n   */\n  refreshTerrainAnchors(changes) {\n    if (!Array.isArray(changes) || changes.length === 0) return 0;\n    let updated = 0;\n    for (const entry of this._entries.values()) {\n      if (entry.marker) {\n        if (!entry.marker.refreshTerrain(changes)) continue;\n        entry._stableRadius = entry.marker.centerRadius;\n        entry._terrainMated = entry.marker.isTerrainMated();\n        if (entry.labelHandle) {\n          this._resolveEntryLabelPosition(entry, this._tmpLabelVec);\n          this._ensureLabelSystem()?.updatePosition(entry.labelHandle, this._tmpLabelVec);\n        }\n        updated += 1;\n        continue;\n      }\n      if (!terrainSurfaceChangesAffectLatLon(changes, entry.lat, entry.lon)) continue;\n      this._updateEntryPosition(entry);\n      updated += 1;\n    }\n    if (updated > 0) {\n      this._fireEffectsDirty = true;\n      this._syncFireEffects();\n    }\n    return updated;\n  }\n\n  _updateCullState() {\n    const distanceM = Number.isFinite(this.cullDistanceM) ? this.cullDistanceM : null;\n    const cullEnabled = !!distanceM && distanceM > 0 && this.camera;\n\n    if (!cullEnabled) {\n      for (const entry of this._entries.values()) {\n        if (entry?.culled) {\n          entry.culled = false;\n          if (entry.labelHandle) entry.labelHandle.sourceVisible = true;\n          if (entry.marker) entry.marker.setVisible(entry.marker.source !== 'fallback');\n          else if (entry.object) entry.object.visible = true;\n          this._fireEffectsDirty = true;\n        }\n      }\n      return;\n    }\n\n    if (!this.group?.updateMatrixWorld || !this.camera?.getWorldPosition) return;\n    this.group.updateMatrixWorld(true);\n    this.camera.getWorldPosition(this._tmpCamPos);\n    const observerLocal = this._tmpObserverLocal.copy(this._tmpCamPos);\n    this.group.worldToLocal(observerLocal);\n\n    const hysteresis = Number.isFinite(this.cullHysteresisM) ? Math.max(0, this.cullHysteresisM) : 0;\n    const switchOut = distanceM + hysteresis;\n    const switchIn = Math.max(0, distanceM - hysteresis);\n    const outSq = switchOut * switchOut;\n    const inSq = switchIn * switchIn;\n\n    for (const entry of this._entries.values()) {\n      if (!entry?.object) continue;\n      const distSq = observerLocal.distanceToSquared(entry.object.position);\n      const prevCulled = entry.culled === true;\n      let nextCulled = false;\n      if (prevCulled) {\n        nextCulled = distSq > inSq;\n      } else {\n        nextCulled = distSq >= outSq;\n      }\n      entry.culled = nextCulled;\n      if (nextCulled !== prevCulled) this._fireEffectsDirty = true;\n      if (entry.labelHandle) entry.labelHandle.sourceVisible = !nextCulled;\n      if (entry.marker) {\n        entry.marker.setVisible(!nextCulled && entry.marker.source !== 'fallback');\n      }\n      else entry.object.visible = !nextCulled;\n    }\n  }\n\n  _syncFireEffects() {\n    this._fireEffectsDirty = false;\n    this._lastFireRecencyRefreshMs = Date.now();\n    if (!this.enabled || !this._fireField) {\n      this._fireField?.clear?.();\n      return;\n    }\n\n    let count = 0;\n    const now = Date.now();\n    for (const entry of this._entries.values()) {\n      if (count >= this._fireField.maxAnchors) break;\n      if (!entry || entry.culled || !isActiveFireIncident(entry.callType)) continue;\n      if (!entry.marker?.isTerrainMated?.()) continue;\n      const centerRadius = Number(entry.marker.centerRadius);\n      if (!Number.isFinite(centerRadius)) continue;\n      const direction = entry.marker.getCenterDirection?.(this._tmpFireDirection);\n      if (!direction) continue;\n      const recencyOpacity = eventRecencyBaseOpacity(entry.receivedAtMs, now);\n      if (recencyOpacity <= 0) continue;\n\n      const vegetationFire = isVegetationFireIncident(entry.callType);\n      let anchor = this._fireAnchors[count];\n      if (!anchor) {\n        anchor = {\n          position: new THREE.Vector3(),\n          up: new THREE.Vector3(),\n        };\n        this._fireAnchors[count] = anchor;\n      }\n      anchor.position.copy(direction).multiplyScalar(centerRadius + 0.16);\n      anchor.up.copy(direction);\n      anchor.identity = `incident:${entry.id}`;\n      anchor.radiusM = vegetationFire\n        ? THREE.MathUtils.clamp(entry.radiusM * 2.4, 7, 18)\n        : THREE.MathUtils.clamp(entry.radiusM * 1.25, 2.5, 9);\n      anchor.heightM = vegetationFire\n        ? THREE.MathUtils.clamp(entry.heightM * 0.45, 12, 38)\n        : THREE.MathUtils.clamp(entry.heightM * 0.32, 7, 26);\n      anchor.spreadM = vegetationFire ? anchor.radiusM * 1.3 : anchor.radiusM * 0.7;\n      anchor.tongues = vegetationFire ? (this.mobile ? 3 : 5) : (this.mobile ? 2 : 4);\n      anchor.intensity = THREE.MathUtils.clamp(0.45 + recencyOpacity * 0.55, 0, 1);\n      count += 1;\n    }\n    this._fireField.setAnchors(this._fireAnchors, count);\n  }\n\n  _updateMarkerPulse() {\n    if (!this._entries.size) return;\n    const now = Date.now();\n    for (const entry of this._entries.values()) {\n      if (!entry?.object || !entry?.material || entry.culled) continue;\n      const recencyOpacity = eventRecencyOpacity(entry.receivedAtMs, now, entry.pulsePhase);\n      const recencySaturation = eventRecencySaturation(entry.receivedAtMs, now);\n      const opacity = DEFAULT_MARKER_OPACITY * recencyOpacity;\n      const baseColor = entry.baseColor || entry.material.uniforms?.uColor?.value;\n      const color = entry.recencyColor || (entry.recencyColor = new THREE.Color());\n      color.copy(baseColor);\n      color.getHSL(this._tmpRecencyHsl);\n      color.setHSL(\n        this._tmpRecencyHsl.h,\n        this._tmpRecencyHsl.s * recencySaturation,\n        this._tmpRecencyHsl.l,\n      );\n\n      if (entry.material.uniforms?.uColor) {\n        entry.material.uniforms.uColor.value.copy(color);\n      }\n      if (entry.material.uniforms?.uOpacity) {\n        entry.material.uniforms.uOpacity.value = opacity;\n      }\n      if (entry.material.uniforms?.uEmission) {\n        const fireBoost = isActiveFireIncident(entry.callType) ? 1.25 : 1;\n        entry.material.uniforms.uEmission.value = (1.45 + recencyOpacity * 1.15) * fireBoost;\n      }\n      if (entry.marker?.outlineMaterial) {\n        entry.marker.outlineMaterial.color.copy(color);\n        entry.marker.outlineMaterial.opacity = 0.94 * recencyOpacity;\n        entry.marker.topOutlineMaterial.color.copy(color);\n        entry.marker.topOutlineMaterial.opacity = entry.marker.outlineMaterial.opacity * 0.47;\n      }\n    }\n  }\n\n  updateHover(raycaster) {\n    if (!raycaster || !this.group?.children?.length) {\n      this._hoveredEntry = null;\n      return;\n    }\n    this.group.updateMatrixWorld(true);\n    const hits = raycaster.intersectObjects(this.group.children, true);\n    if (!hits.length) {\n      this._hoveredEntry = null;\n      return;\n    }\n    const entry = this._resolveEntryFromObject(hits[0].object);\n    this._hoveredEntry = entry || null;\n  }\n\n  clearHover() {\n    this._hoveredEntry = null;\n  }\n\n  getHoveredIncident() {\n    return this._hoveredEntry;\n  }\n\n  _resolveEntryFromObject(object) {\n    let current = object;\n    while (current) {\n      if (current.userData?.incidentEntry) return current.userData.incidentEntry;\n      current = current.parent;\n    }\n    return null;\n  }\n\n  _bindConfigListener() {\n    if (!this.eventBus || typeof this.eventBus.on !== 'function') return;\n    this._configListener = (config) => this._handleConfigUpdate(config);\n    this.eventBus.on('incidents:config', this._configListener);\n  }\n\n  _unbindConfigListener() {\n    if (!this.eventBus || typeof this.eventBus.off !== 'function') return;\n    if (!this._configListener) return;\n    this.eventBus.off('incidents:config', this._configListener);\n    this._configListener = null;\n  }\n\n  _handleConfigUpdate(config = {}) {\n    if (typeof config.enabled === 'boolean') {\n      this.enabled = config.enabled;\n      this.group.visible = config.enabled;\n      if (config.enabled) {\n        this.refresh();\n      } else {\n        this._stopIncidentFetchSchedule();\n        for (const controller of this._placeLookupControllers.values()) controller.abort();\n        this._placeLookupControllers.clear();\n        this.clear();\n      }\n    }\n    if (Array.isArray(config.agencyIds)) {\n      this.agencyIds = normalizeAgencyIds(config.agencyIds);\n      this.refresh();\n    }\n    if (Number.isFinite(config.radiusM)) {\n      this.radiusM = config.radiusM;\n      this.refresh();\n    }\n    if (Number.isFinite(config.maxIncidents)) {\n      this.maxIncidents = config.maxIncidents;\n      this.refresh();\n    }\n    if (Number.isFinite(config.pollIntervalMs)) {\n      this.pollIntervalMs = config.pollIntervalMs;\n      this._scheduleIncidentFetch(this.pollIntervalMs);\n    }\n    const nextHeight = Number.isFinite(config.spireHeightM)\n      ? config.spireHeightM\n      : (Number.isFinite(config.markerScaleM) ? config.markerScaleM : null);\n    if (Number.isFinite(nextHeight)) {\n      this.spireHeightM = clampSpireHeight(nextHeight);\n      this.markerScaleM = this.spireHeightM;\n      for (const entry of this._entries.values()) {\n        this._applySpireScale(entry);\n        this._updateEntryPosition(entry);\n      }\n    }\n    if (Number.isFinite(config.spireRadiusM)) {\n      this.spireRadiusM = clampSpireRadius(config.spireRadiusM);\n      for (const entry of this._entries.values()) {\n        this._applySpireScale(entry);\n        this._updateEntryPosition(entry);\n      }\n    }\n    if (Number.isFinite(config.labelScaleM)) {\n      this.labelScaleM = config.labelScaleM;\n      // LabelSystem handles viewport-stable scaling automatically\n      for (const entry of this._entries.values()) {\n        this._updateEntryPosition(entry);\n      }\n    }\n    if (typeof config.showLabels === 'boolean') {\n      this.showLabels = config.showLabels;\n      for (const entry of this._entries.values()) {\n        this._updateEntryLabel(entry);\n        this._updateEntryPosition(entry);\n      }\n    }\n    if (Number.isFinite(config.labelViewConeDeg)) {\n      this.labelViewConeDeg = config.labelViewConeDeg;\n    }\n    if (typeof config.includeRecent === 'boolean') {\n      this.includeRecent = config.includeRecent;\n      this.refresh();\n    }\n    if (typeof config.includeAlerts === 'boolean') {\n      this.includeAlerts = config.includeAlerts;\n      this.refresh();\n    }\n    if (typeof config.publicOnly === 'boolean') {\n      this.publicOnly = config.publicOnly;\n      this.refresh();\n    }\n    if (typeof config.hideMedical === 'boolean') {\n      this.hideMedical = config.hideMedical;\n      this.refresh();\n    }\n    if (Number.isFinite(config.cullDistanceM)) {\n      this.cullDistanceM = config.cullDistanceM;\n    }\n    if (Number.isFinite(config.cullHysteresisM)) {\n      this.cullHysteresisM = config.cullHysteresisM;\n    }\n  }\n}\n","/**\n * Autonomous traffic-camera discovery client.\n *\n * The Omnius backend resolves the jurisdiction, discovers official providers,\n * verifies/fetches inventories server-side, and returns one normalized camera\n * contract. Keeping arbitrary provider fetches off the browser avoids CORS and\n * ensures every source passes the same URL, payload, coordinate, provenance,\n * radius, and deduplication checks before scene deployment.\n */\n\nimport { resolveBackendApiUrl } from '../shared/backend.js';\nimport { getNoclipGovernanceClient } from '../shared/NoclipGovernanceClient.js';\n\nconst CACHE_TTL_MS = 5 * 60 * 1000;\nconst MAX_CACHE_ENTRIES = 30;\nconst MAX_CAMERAS = 1200;\nconst discoveryCache = new Map();\n\nconst cleanText = (value, max = 240) => String(value ?? '')\n  .replace(/\\s+/g, ' ')\n  .trim()\n  .slice(0, max);\n\nconst secureUrl = (value) => {\n  const raw = cleanText(value, 2048);\n  if (!raw) return '';\n  try {\n    const url = new URL(raw);\n    if (url.protocol === 'http:') url.protocol = 'https:';\n    return url.protocol === 'https:' ? url.toString() : '';\n  } catch {\n    return '';\n  }\n};\n\nconst isFiniteCoordinate = (lat, lon) => (\n  Number.isFinite(lat) && Number.isFinite(lon) && Math.abs(lat) <= 90 && Math.abs(lon) <= 180\n);\n\nconst normalizeProvider = (raw) => {\n  if (!raw || typeof raw !== 'object') return null;\n  const id = cleanText(raw.id, 120);\n  if (!id) return null;\n  return {\n    id,\n    name: cleanText(raw.name || raw.authority || id, 160),\n    authority: cleanText(raw.authority || raw.name || id, 160),\n    sourceUrl: secureUrl(raw.sourceUrl),\n    inventoryUrl: secureUrl(raw.inventoryUrl),\n    discoveryMethod: ['agent', 'verified-seed', 'community'].includes(raw.discoveryMethod)\n      ? raw.discoveryMethod\n      : 'agent',\n    agentConfirmed: raw.agentConfirmed === true,\n    verified: raw.verified === true,\n    cameraCount: Math.max(0, Number(raw.cameraCount) || 0),\n    error: cleanText(raw.error, 300),\n  };\n};\n\nconst normalizeCamera = (raw, index) => {\n  if (!raw || typeof raw !== 'object') return null;\n  const lat = Number(raw.lat);\n  const lon = Number(raw.lon);\n  if (!isFiniteCoordinate(lat, lon)) return null;\n  const providerId = cleanText(raw.providerId || raw.provenance?.authority || 'public-camera', 120);\n  const id = cleanText(raw.id || `${providerId}:${lat.toFixed(6)}:${lon.toFixed(6)}:${index}`, 220);\n  if (!id) return null;\n  const kind = raw.kind === 'flock' ? 'flock' : 'traffic';\n  const source = cleanText(raw.source || raw.provenance?.authority || providerId, 160);\n  const title = cleanText(raw.title || `${source} camera`, 200);\n  const discoveryMethod = ['agent', 'verified-seed', 'community'].includes(raw.provenance?.discoveryMethod)\n    ? raw.provenance.discoveryMethod\n    : 'agent';\n  return {\n    id,\n    kind,\n    lat,\n    lon,\n    title,\n    label: cleanText(raw.label || `${source.toUpperCase()} CAM · ${title}`, 260),\n    source,\n    sourceUrl: secureUrl(raw.sourceUrl),\n    imageUrl: secureUrl(raw.imageUrl),\n    streamUrl: secureUrl(raw.streamUrl),\n    route: cleanText(raw.route, 120),\n    direction: cleanText(raw.direction, 120),\n    status: cleanText(raw.status, 160),\n    live: raw.live === true,\n    distanceM: Math.max(0, Number(raw.distanceM) || 0),\n    providerId,\n    provenance: {\n      authority: cleanText(raw.provenance?.authority || source, 160),\n      inventoryUrl: secureUrl(raw.provenance?.inventoryUrl),\n      discoveryMethod,\n      verifiedAt: cleanText(raw.provenance?.verifiedAt, 80),\n    },\n    metadata: raw.metadata && typeof raw.metadata === 'object' ? { ...raw.metadata } : {},\n  };\n};\n\nconst normalizePayload = (raw, context) => {\n  const providers = (Array.isArray(raw?.providers) ? raw.providers : [])\n    .map(normalizeProvider)\n    .filter(Boolean);\n  const seen = new Set();\n  const cameras = (Array.isArray(raw?.cameras) ? raw.cameras : [])\n    .slice(0, MAX_CAMERAS)\n    .map(normalizeCamera)\n    .filter((camera) => {\n      if (!camera || seen.has(camera.id)) return false;\n      seen.add(camera.id);\n      return true;\n    })\n    .sort((a, b) => a.distanceM - b.distanceM);\n  return {\n    region: cleanText(raw?.region || context.place || `${context.lat}, ${context.lon}`, 240),\n    generatedAt: cleanText(raw?.generatedAt, 80) || new Date().toISOString(),\n    cached: raw?.cached === true,\n    model: cleanText(raw?.model, 160),\n    agentAttempted: raw?.agentAttempted === true,\n    agentSucceeded: raw?.agentSucceeded === true,\n    providers,\n    cameras,\n    diagnostics: raw?.diagnostics && typeof raw.diagnostics === 'object'\n      ? { ...raw.diagnostics }\n      : {},\n  };\n};\n\nconst cacheKey = (context, options) => [\n  Number(context.lat).toFixed(1),\n  Number(context.lon).toFixed(1),\n  Math.round((Number(options.radiusM) || 180_000) / 10_000),\n  options.includeFlock === false ? 0 : 1,\n].join(':');\n\nexport function buildTrafficCameraDiscoveryPrompt(context = {}) {\n  const place = cleanText(context.place || context.region || 'the active scene');\n  const country = cleanText(context.country);\n  return `Autonomously discover, verify, normalize, and deploy public traffic-camera inventories near ${place}${country ? `, ${country}` : ''}.`;\n}\n\n/**\n * Discover and fetch normalized public camera records without any chat-panel\n * interaction. The browser never fetches a model-supplied provider URL.\n */\nexport async function discoverTrafficCameras(context = {}, {\n  force = false,\n  signal,\n  includeFlock = true,\n  radiusM = 180_000,\n  maxCameras = 720,\n  onProgress,\n} = {}) {\n  const lat = Number(context.lat);\n  const lon = Number(context.lon);\n  if (!isFiniteCoordinate(lat, lon)) throw new Error('Valid scene coordinates are required for camera discovery');\n  const options = {\n    includeFlock: includeFlock !== false,\n    radiusM: Math.max(5_000, Math.min(500_000, Number(radiusM) || 180_000)),\n    maxCameras: Math.max(1, Math.min(MAX_CAMERAS, Math.floor(Number(maxCameras) || 720))),\n  };\n  const key = cacheKey({ lat, lon }, options);\n  const cached = discoveryCache.get(key);\n  if (!force && cached && Date.now() - cached.at < CACHE_TTL_MS) return cached.payload;\n\n  onProgress?.('Omnius is discovering and verifying public camera providers');\n  const response = await getNoclipGovernanceClient().request(resolveBackendApiUrl('/agent/traffic-cameras/discover'), {\n    method: 'POST',\n    governanceLane: 'scene',\n    signal,\n    headers: { 'Content-Type': 'application/json' },\n    body: JSON.stringify({\n      lat,\n      lon,\n      place: cleanText(context.place || context.region, 200),\n      country: cleanText(context.country, 120),\n      includeFlock: options.includeFlock,\n      radiusM: options.radiusM,\n      maxCameras: options.maxCameras,\n      force,\n    }),\n  });\n  let data = null;\n  try { data = await response.json(); } catch { data = null; }\n  if (!response.ok) {\n    throw new Error(cleanText(data?.detail || data?.error, 300) || `Traffic-camera discovery failed (${response.status})`);\n  }\n  const payload = normalizePayload(data, { ...context, lat, lon });\n  discoveryCache.set(key, { at: Date.now(), payload });\n  if (discoveryCache.size > MAX_CACHE_ENTRIES) {\n    const oldest = discoveryCache.keys().next().value;\n    if (oldest) discoveryCache.delete(oldest);\n  }\n  return payload;\n}\n\n/** Backward-compatible provider-only view for diagnostics. */\nexport async function discoverTrafficCameraProviders(context = {}, options = {}) {\n  const result = await discoverTrafficCameras(context, options);\n  return {\n    region: result.region,\n    providers: result.providers,\n    generatedAt: result.generatedAt,\n    model: result.model,\n    agentAttempted: result.agentAttempted,\n    agentSucceeded: result.agentSucceeded,\n  };\n}\n\nexport function clearTrafficCameraDiscoveryCache() {\n  discoveryCache.clear();\n}\n","/**\n * TrafficCameraOverlay\n *\n * Presents public traffic-camera, safety-camera, and explicitly Flock-tagged\n * ALPR anchors. Camera inventories arrive through the context-driven source\n * discovery service; each source is normalized before reaching this renderer.\n * The 3D anchors use a pointer-up (not pointer-down) pick so camera drags are\n * never consumed by an annotation.\n */\n\nimport { createProgramGate } from '../render/ModelFirstDrawPrep.js';\nimport * as THREE from 'three';\nimport { PLANET_RADIUS } from '../../modules/constants.js';\nimport { dirToLatLonLocal, ellipsoidRadiusForLocalDir, latLonToLocalDir } from '../../modules/geometry-utils.js';\nimport { getLabelSystem } from '../labels/LabelSystem.js';\nimport { terrainSurfaceChangesAffectLatLon } from '../scene/TerrainSurfaceChange.js';\nimport { discoverTrafficCameras } from '../traffic/TrafficCameraDiscoveryService.js';\n\nconst DEFAULT_CULL_DISTANCE_M = 180_000;\nconst DEFAULT_MAX_CAMERAS = 720;\nconst DEFAULT_VISUAL_UPDATE_MS = 100;\nconst CONTEXT_REFRESH_MS = 6 * 60 * 60 * 1000;\nconst CONTEXT_MOVE_METERS = 35_000;\nconst CONTEXT_FAILURE_RETRY_MS = 2 * 60 * 1000;\nconst CLICK_SLOP_PX = 7;\nconst VISUAL_ACTIVATION_DELAY_MS = 1200;\nconst VISUAL_ACTIVATION_BATCH_SIZE = 8;\nconst CAMERA_PREVIEW_CENTER_RADIUS_NDC = 0.24;\nconst CAMERA_PREVIEW_REFRESH_MS = 60_000;\n\nconst COLORS = {\n  traffic: 0x4fb4ff,\n  speed: 0xffba4c,\n  intersection: 0xff8e5c,\n  flock: 0xb078ff,\n};\nconst LABEL_COLOR = 0xffd64a;\n\n// Camera discovery can complete before photoreal boot. A camera marker was\n// therefore the first material reached on the live r185 ANGLE renderer; even\n// a ShaderMaterial still received Three's generated prefixes and its first\n// GL_ACTIVE_UNIFORMS query blocked for 17 seconds. This must stay a raw solid\n// colour program: do not replace it with MeshBasicMaterial or ShaderMaterial.\nconst TRAFFIC_CAMERA_MARKER_VERTEX_SHADER = /* glsl */`\n#define NCA_TRAFFIC_CAMERA_MARKER_R185\nprecision highp float;\nuniform mat4 modelViewMatrix;\nuniform mat4 projectionMatrix;\nattribute vec3 position;\nvoid main() {\n  gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n}\n`;\nconst TRAFFIC_CAMERA_MARKER_FRAGMENT_SHADER = /* glsl */`\n#define NCA_TRAFFIC_CAMERA_MARKER_R185\nprecision highp float;\nuniform vec3 uColor;\nuniform float uOpacity;\nvoid main() {\n  gl_FragColor = vec4( uColor, uOpacity );\n}\n`;\n\nconst cleanText = (value) => String(value ?? '').replace(/\\s+/g, ' ').trim();\nconst isAbortError = (error) => error?.name === 'AbortError';\nconst debugTraffic = (...args) => {\n  if (globalThis.__noclipDebugTraffic === true) console.debug(...args);\n};\n\nconst distanceMeters = (a, b) => {\n  if (!a || !b) return Infinity;\n  const dLat = (a.lat - b.lat) * 111_132;\n  const dLon = (a.lon - b.lon) * 111_132 * Math.cos(a.lat * Math.PI / 180);\n  return Math.hypot(dLat, dLon);\n};\n\nconst cameraPreviewUrl = (value, now = Date.now()) => {\n  try {\n    const url = new URL(String(value || ''));\n    if (url.protocol !== 'https:') return '';\n    url.searchParams.set('_noclip_preview', String(Math.floor(now / CAMERA_PREVIEW_REFRESH_MS)));\n    return url.toString();\n  } catch {\n    return '';\n  }\n};\n\nexport function selectCenteredTrafficCameraPreview(candidates, radius = CAMERA_PREVIEW_CENTER_RADIUS_NDC) {\n  const radiusSq = Math.max(0, Number(radius) || 0) ** 2;\n  let selected = null;\n  let selectedDistanceSq = Infinity;\n  for (const candidate of candidates || []) {\n    if (!candidate?.entry || candidate.visible !== true || !candidate.imageUrl) continue;\n    const x = Number(candidate.x);\n    const y = Number(candidate.y);\n    const z = Number(candidate.z);\n    if (!Number.isFinite(x) || !Number.isFinite(y) || !Number.isFinite(z) || z < -1 || z > 1) continue;\n    const distanceSq = x * x + y * y;\n    if (distanceSq > radiusSq) continue;\n    if (distanceSq < selectedDistanceSq\n      || (distanceSq === selectedDistanceSq && String(candidate.entry.id).localeCompare(String(selected?.id || '')) < 0)) {\n      selected = candidate.entry;\n      selectedDistanceSq = distanceSq;\n    }\n  }\n  return selected;\n}\n\nclass TrafficCameraViewer {\n  constructor() {\n    this.element = null;\n    this.image = null;\n    this.entry = null;\n    this._refreshTimer = null;\n  }\n\n  _ensureElement() {\n    if (this.element?.isConnected || typeof document === 'undefined') return this.element;\n    const styleId = 'traffic-camera-viewer-styles';\n    if (!document.getElementById(styleId)) {\n      const style = document.createElement('style');\n      style.id = styleId;\n      style.textContent = `\n        .nc-traffic-camera-viewer { position:fixed; z-index:2200; right:18px; bottom:18px; width:min(410px, calc(100vw - 28px)); color:#eef5fb; background:rgba(5,9,13,.92); border:1px solid rgba(154,193,219,.32); box-shadow:0 20px 60px rgba(0,0,0,.55); font:500 12px/1.35 'Rajdhani',system-ui,sans-serif; }\n        .nc-traffic-camera-viewer[hidden] { display:none; }\n        .nc-traffic-camera-viewer__head { display:flex; align-items:flex-start; gap:12px; padding:12px 13px 10px; border-bottom:1px solid rgba(154,193,219,.18); }\n        .nc-traffic-camera-viewer__title { flex:1; font-weight:700; letter-spacing:.08em; text-transform:uppercase; }\n        .nc-traffic-camera-viewer__meta { margin-top:3px; color:rgba(222,237,247,.62); font:500 10px/1.35 ui-monospace,monospace; letter-spacing:.04em; }\n        .nc-traffic-camera-viewer__close { width:26px; height:24px; padding:0; border:0; background:transparent; color:rgba(238,245,251,.72); cursor:pointer; font:700 18px/1 sans-serif; }\n        .nc-traffic-camera-viewer__body { padding:12px 13px 14px; }\n        .nc-traffic-camera-viewer__image { display:block; width:100%; min-height:120px; max-height:300px; object-fit:contain; background:#020406; }\n        .nc-traffic-camera-viewer__image[hidden] { display:none; }\n        .nc-traffic-camera-viewer__notice { color:rgba(225,235,242,.70); }\n        .nc-traffic-camera-viewer__rows { display:grid; grid-template-columns:max-content 1fr; gap:4px 10px; margin-top:10px; font:500 10px/1.35 ui-monospace,monospace; }\n        .nc-traffic-camera-viewer__rows dt { color:rgba(174,202,220,.55); text-transform:uppercase; letter-spacing:.06em; }\n        .nc-traffic-camera-viewer__rows dd { margin:0; color:rgba(240,247,251,.82); overflow-wrap:anywhere; }\n        .nc-traffic-camera-viewer__source { display:inline-block; margin-top:11px; color:#8bc8ff; font-weight:700; letter-spacing:.06em; text-transform:uppercase; text-decoration:none; }\n      `;\n      document.head.appendChild(style);\n    }\n    const el = document.createElement('section');\n    el.className = 'nc-traffic-camera-viewer';\n    el.hidden = true;\n    el.setAttribute('aria-live', 'polite');\n    const head = document.createElement('header');\n    head.className = 'nc-traffic-camera-viewer__head';\n    const titleBlock = document.createElement('div');\n    const title = document.createElement('div');\n    title.className = 'nc-traffic-camera-viewer__title';\n    const meta = document.createElement('div');\n    meta.className = 'nc-traffic-camera-viewer__meta';\n    titleBlock.append(title, meta);\n    const close = document.createElement('button');\n    close.className = 'nc-traffic-camera-viewer__close';\n    close.type = 'button';\n    close.textContent = '×';\n    close.setAttribute('aria-label', 'Close camera viewer');\n    close.addEventListener('click', () => this.hide());\n    head.append(titleBlock, close);\n    const body = document.createElement('div');\n    body.className = 'nc-traffic-camera-viewer__body';\n    const image = document.createElement('img');\n    image.className = 'nc-traffic-camera-viewer__image';\n    image.alt = '';\n    image.loading = 'eager';\n    const notice = document.createElement('div');\n    notice.className = 'nc-traffic-camera-viewer__notice';\n    const rows = document.createElement('dl');\n    rows.className = 'nc-traffic-camera-viewer__rows';\n    const source = document.createElement('a');\n    source.className = 'nc-traffic-camera-viewer__source';\n    source.target = '_blank';\n    source.rel = 'noopener noreferrer';\n    source.textContent = 'Open source';\n    body.append(image, notice, rows, source);\n    el.append(head, body);\n    el._title = title;\n    el._meta = meta;\n    el._image = image;\n    el._notice = notice;\n    el._rows = rows;\n    el._source = source;\n    document.body.appendChild(el);\n    this.element = el;\n    this.image = image;\n    return el;\n  }\n\n  _setImage(url) {\n    const image = this.element?._image;\n    if (!image) return;\n    if (!url) {\n      image.hidden = true;\n      image.removeAttribute('src');\n      return;\n    }\n    const source = new URL(url);\n    source.searchParams.set('_noclip', String(Date.now()));\n    image.hidden = false;\n    image.src = source.toString();\n  }\n\n  show(entry) {\n    const el = this._ensureElement();\n    if (!el || !entry) return;\n    this.entry = entry;\n    el.hidden = false;\n    el._title.textContent = entry.title || 'Camera';\n    el._meta.textContent = [entry.source, entry.live ? 'PUBLIC LATEST FRAME' : 'PUBLIC LOCATION RECORD'].filter(Boolean).join(' · ');\n    const imageUrl = entry.imageUrl || entry.streamUrl || '';\n    this._setImage(imageUrl);\n    const notice = entry.live && imageUrl\n      ? 'Latest public image. Refreshes automatically while this viewer is open.'\n      : (entry.kind === 'flock'\n        ? 'Location metadata only. This source does not provide public live imagery or plate-read data.'\n        : 'Location metadata only. This source does not provide a public live image.');\n    el._notice.textContent = notice;\n    const rows = [\n      ['Source', entry.source],\n      ['Status', entry.status],\n      ['Direction', entry.direction],\n      ['Route', entry.route],\n      ['Coordinates', `${Number(entry.lat).toFixed(5)}, ${Number(entry.lon).toFixed(5)}`],\n      ...Object.entries(entry.metadata || {}).filter(([, value]) => cleanText(value)),\n    ];\n    el._rows.replaceChildren();\n    const labels = new Set();\n    for (const [rawLabel, rawValue] of rows) {\n      const value = cleanText(rawValue);\n      const label = cleanText(rawLabel);\n      if (!label || !value || labels.has(label.toLowerCase())) continue;\n      labels.add(label.toLowerCase());\n      const dt = document.createElement('dt');\n      dt.textContent = label;\n      const dd = document.createElement('dd');\n      dd.textContent = value;\n      el._rows.append(dt, dd);\n    }\n    if (entry.sourceUrl) {\n      el._source.href = entry.sourceUrl;\n      el._source.hidden = false;\n    } else {\n      el._source.hidden = true;\n      el._source.removeAttribute('href');\n    }\n    if (this._refreshTimer) clearInterval(this._refreshTimer);\n    this._refreshTimer = imageUrl ? setInterval(() => this._setImage(imageUrl), 60_000) : null;\n  }\n\n  hide() {\n    if (this._refreshTimer) clearInterval(this._refreshTimer);\n    this._refreshTimer = null;\n    this.entry = null;\n    if (this.element) this.element.hidden = true;\n  }\n\n  dispose() {\n    this.hide();\n    this.element?.remove();\n    this.element = null;\n  }\n}\n\nexport class TrafficCameraOverlay {\n  constructor({\n    parentGroup,\n    camera,\n    domElement,\n    surfaceController,\n    sceneInitializer,\n    eventBus,\n    planetRadius = PLANET_RADIUS,\n    enabled = true,\n    showLabels = true,\n    includeFlock = true,\n    discoveryRadiusM = DEFAULT_CULL_DISTANCE_M,\n    cullDistanceM = DEFAULT_CULL_DISTANCE_M,\n    maxCameras = DEFAULT_MAX_CAMERAS,\n    deferUntilInteractive = false,\n  } = {}) {\n    this.parentGroup = parentGroup || null;\n    this.camera = camera || null;\n    this.domElement = domElement || null;\n    this.surfaceController = surfaceController || null;\n    this.sceneInitializer = sceneInitializer || null;\n    this.eventBus = eventBus || null;\n    this.planetRadius = Number.isFinite(planetRadius) ? planetRadius : PLANET_RADIUS;\n    this.enabled = enabled !== false;\n    this.showLabels = showLabels !== false;\n    this.includeFlock = includeFlock !== false;\n    this.discoveryRadiusM = Number.isFinite(discoveryRadiusM)\n      ? Math.max(5_000, Math.min(500_000, discoveryRadiusM))\n      : DEFAULT_CULL_DISTANCE_M;\n    this.cullDistanceM = Number.isFinite(cullDistanceM) ? cullDistanceM : DEFAULT_CULL_DISTANCE_M;\n    this.maxCameras = Number.isFinite(maxCameras) ? maxCameras : DEFAULT_MAX_CAMERAS;\n    this._interactiveReady = deferUntilInteractive !== true;\n    this._visualActivationAt = this._interactiveReady ? 0 : Infinity;\n\n    this.group = new THREE.Group();\n    this.group.name = 'TrafficCameraOverlay';\n    this.group.visible = this.enabled;\n    this.parentGroup?.add(this.group);\n    this.sceneInitializer?.addDepthPassExclude?.(this.group);\n\n    this._entries = new Map();\n    this._sourceEntryIds = new Map();\n    this._markerGeometry = new THREE.ConeGeometry(4, 14, 4, 1, false);\n    this._materials = new Map();\n    this._labelSystem = null;\n    this._viewer = new TrafficCameraViewer();\n    this._visualElapsedMs = DEFAULT_VISUAL_UPDATE_MS;\n    this._contextCenter = null;\n    this._contextLoadedAt = 0;\n    this._contextNextRetryAt = 0;\n    this._contextInflight = false;\n    this._contextAbort = null;\n    this._queuedContextRefresh = null;\n    this._discoveryStatus = {\n      phase: 'idle',\n      region: '',\n      providerCount: 0,\n      verifiedProviderCount: 0,\n      cameraCount: 0,\n      agentAttempted: false,\n      agentSucceeded: false,\n      model: '',\n      updatedAt: 0,\n      error: '',\n      providers: [],\n      diagnostics: {},\n    };\n    this._disposed = false;\n    this._pointerDown = null;\n    this._raycaster = new THREE.Raycaster();\n    this._pointer = new THREE.Vector2();\n    this._tmpDir = new THREE.Vector3();\n    this._tmpPosition = new THREE.Vector3();\n    this._tmpProjected = new THREE.Vector3();\n    this._tmpObserver = new THREE.Vector3();\n    this._tmpObserverDir = new THREE.Vector3();\n    this._tmpWorldUp = new THREE.Vector3(0, 1, 0);\n    this._tmpQuat = new THREE.Quaternion();\n    this._activePreviewEntryId = null;\n    this._lastPreviewRefreshAt = 0;\n\n    this._onPointerDown = this._onPointerDown.bind(this);\n    this._onPointerUp = this._onPointerUp.bind(this);\n    this.domElement?.addEventListener?.('pointerdown', this._onPointerDown, { passive: true });\n    this.domElement?.addEventListener?.('pointerup', this._onPointerUp, { passive: true });\n  }\n\n  setEnabled(enabled) {\n    const wasEnabled = this.enabled;\n    this.enabled = !!enabled;\n    this.group.visible = this.enabled;\n    if (this.enabled && !wasEnabled) this._requestContextRefresh(true);\n    else {\n      this._contextAbort?.abort?.();\n      this._viewer.hide();\n      this._setCameraPreview(null);\n    }\n  }\n\n  setLabelsEnabled(enabled) {\n    this.showLabels = !!enabled;\n    if (!this.showLabels) this._setCameraPreview(null);\n    for (const entry of this._entries.values()) this._syncLabel(entry);\n  }\n\n  /**\n   * Release visual objects only after native photoreal coverage has opened the\n   * scene. Discovery deliberately continues while this gate is closed, so the\n   * autonomous provider result is ready without competing with r185's initial\n   * tileset shader work. Hydration remains frame-budgeted in update().\n   */\n  setInteractiveReady(ready = true) {\n    const next = ready === true;\n    if (next === this._interactiveReady) return;\n    this._interactiveReady = next;\n    this._visualActivationAt = next\n      ? performance.now() + VISUAL_ACTIVATION_DELAY_MS\n      : Infinity;\n    if (!next) {\n      for (const entry of this._entries.values()) this._releaseEntryVisual(entry);\n    }\n  }\n\n  applyConfig(config = {}) {\n    const wasEnabled = this.enabled;\n    const discoveryChanged = (\n      (typeof config.includeFlock === 'boolean' && config.includeFlock !== this.includeFlock)\n      || (Number.isFinite(config.discoveryRadiusM) && config.discoveryRadiusM !== this.discoveryRadiusM)\n    );\n    if (typeof config.showLabels === 'boolean') this.setLabelsEnabled(config.showLabels);\n    if (typeof config.includeFlock === 'boolean') this.includeFlock = config.includeFlock;\n    if (Number.isFinite(config.discoveryRadiusM)) {\n      this.discoveryRadiusM = Math.max(5_000, Math.min(500_000, config.discoveryRadiusM));\n    }\n    if (Number.isFinite(config.cullDistanceM)) this.cullDistanceM = Math.max(5_000, config.cullDistanceM);\n    if (Number.isFinite(config.maxCameras)) this.maxCameras = Math.max(10, Math.floor(config.maxCameras));\n    if (typeof config.enabled === 'boolean') this.setEnabled(config.enabled);\n    if (discoveryChanged && this.enabled && wasEnabled) this._requestContextRefresh(true);\n  }\n\n  update(dt) {\n    if (!this.enabled) return;\n    const deltaMs = Math.max(0, Number(dt) || 0) * 1000;\n    this._visualElapsedMs += deltaMs;\n    // Context checks and marker culling are camera-driven but not animation\n    // driven. Ten Hz keeps a camera drag visually current without traversing\n    // hundreds of optional markers every render frame.\n    if (this._visualElapsedMs < DEFAULT_VISUAL_UPDATE_MS) return;\n    this._visualElapsedMs = 0;\n    this._updateContextFromCamera();\n    if (this._interactiveReady && performance.now() >= this._visualActivationAt) {\n      this._hydratePendingEntries(VISUAL_ACTIVATION_BATCH_SIZE);\n    }\n    this._updateMarkerScaleAndCull();\n  }\n\n  getEntriesSnapshot() {\n    return [...this._entries.values()].map(({ marker, labelHandle, ...entry }) => ({ ...entry }));\n  }\n\n  getDiscoverySnapshot() {\n    return {\n      ...this._discoveryStatus,\n      providers: (this._discoveryStatus.providers || []).map((provider) => ({ ...provider })),\n    };\n  }\n\n  refresh() {\n    this._requestContextRefresh(true);\n  }\n\n  dispose() {\n    this._disposed = true;\n    this._setCameraPreview(null);\n    this._contextAbort?.abort?.();\n    this._queuedContextRefresh = null;\n    this.domElement?.removeEventListener?.('pointerdown', this._onPointerDown);\n    this.domElement?.removeEventListener?.('pointerup', this._onPointerUp);\n    this._viewer.dispose();\n    for (const entry of this._entries.values()) this._disposeEntry(entry);\n    this._entries.clear();\n    this._sourceEntryIds.clear();\n    this._markerGeometry.dispose();\n    for (const material of this._materials.values()) material.dispose();\n    this._materials.clear();\n    this.group.parent?.remove(this.group);\n    this.sceneInitializer?.removeDepthPassExclude?.(this.group);\n  }\n\n  _ensureLabelSystem() {\n    if (!this._labelSystem) this._labelSystem = getLabelSystem({ planetRadius: this.planetRadius });\n    return this._labelSystem;\n  }\n\n  _materialFor(kind) {\n    const key = COLORS[kind] ? kind : 'traffic';\n    if (!this._materials.has(key)) {\n      this._materials.set(key, new THREE.RawShaderMaterial({\n        name: `TrafficCameraMarkerMaterial:${key}`,\n        uniforms: {\n          uColor: { value: new THREE.Color(COLORS[key]) },\n          uOpacity: { value: 0.9 },\n        },\n        vertexShader: TRAFFIC_CAMERA_MARKER_VERTEX_SHADER,\n        fragmentShader: TRAFFIC_CAMERA_MARKER_FRAGMENT_SHADER,\n        transparent: true,\n        depthTest: true,\n        depthWrite: false,\n        toneMapped: false,\n      }));\n    }\n    return this._materials.get(key);\n  }\n\n  _updateContextFromCamera() {\n    if (!this.camera || !this.group) return;\n    this.group.updateMatrixWorld(true);\n    this.camera.getWorldPosition(this._tmpObserver);\n    this.group.worldToLocal(this._tmpObserver);\n    if (this._tmpObserver.lengthSq() < 1) return;\n    const coords = dirToLatLonLocal(this._tmpObserver.normalize());\n    const center = { lat: coords.latDeg, lon: coords.lonDeg };\n    const moved = distanceMeters(center, this._contextCenter);\n    const stale = Date.now() - this._contextLoadedAt >= CONTEXT_REFRESH_MS;\n    if (!this._contextCenter || moved >= CONTEXT_MOVE_METERS || stale) {\n      this._contextCenter = center;\n      this._requestContextRefresh(false);\n    }\n  }\n\n  _requestContextRefresh(force) {\n    if (this._disposed || !this.enabled || !this._contextCenter) return;\n    if (this._contextInflight) {\n      const queuedCenter = { ...this._contextCenter };\n      const moved = distanceMeters(queuedCenter, this._queuedContextRefresh?.center);\n      if (force || !this._queuedContextRefresh || moved >= CONTEXT_MOVE_METERS) {\n        this._queuedContextRefresh = {\n          center: queuedCenter,\n          force: force || this._queuedContextRefresh?.force === true,\n        };\n      }\n      return;\n    }\n    const now = Date.now();\n    if (!force && now < this._contextNextRetryAt) return;\n    if (!force && this._contextLoadedAt && now - this._contextLoadedAt < 15_000) return;\n    const center = { ...this._contextCenter };\n    this._loadContextSources(center, { force }).catch((error) => {\n      if (isAbortError(error)) return;\n      this._contextNextRetryAt = Date.now() + CONTEXT_FAILURE_RETRY_MS;\n      debugTraffic('[TrafficCameraOverlay] Context camera refresh failed', error);\n    });\n  }\n\n  async _loadContextSources(center, { force = false } = {}) {\n    if (this._contextInflight) return;\n    this._contextInflight = true;\n    this._contextAbort?.abort?.();\n    const controller = new AbortController();\n    this._contextAbort = controller;\n    this._setDiscoveryStatus({ phase: 'discovering', error: '' });\n    try {\n      const discovery = await discoverTrafficCameras(center, {\n        force,\n        signal: controller.signal,\n        includeFlock: this.includeFlock,\n        radiusM: this.discoveryRadiusM,\n        maxCameras: this.maxCameras,\n      });\n      if (controller.signal.aborted) return;\n      this._replaceSourceEntries('autonomous:context', discovery.cameras || []);\n      for (const sourceKey of [...this._sourceEntryIds.keys()]) {\n        if (sourceKey !== 'autonomous:context') this._replaceSourceEntries(sourceKey, []);\n      }\n      this._contextLoadedAt = Date.now();\n      this._contextNextRetryAt = 0;\n      const providers = discovery.providers || [];\n      const verifiedProviderCount = providers.filter((provider) => provider.verified).length;\n      this._setDiscoveryStatus({\n        phase: verifiedProviderCount > 0 ? 'ready' : 'degraded',\n        region: discovery.region || '',\n        providerCount: providers.length,\n        verifiedProviderCount,\n        cameraCount: discovery.cameras?.length || 0,\n        agentAttempted: discovery.agentAttempted === true,\n        agentSucceeded: discovery.agentSucceeded === true,\n        model: discovery.model || '',\n        updatedAt: this._contextLoadedAt,\n        error: verifiedProviderCount > 0 ? '' : 'No public camera provider was verified for this scene.',\n        providers,\n        diagnostics: discovery.diagnostics || {},\n      });\n    } catch (error) {\n      if (!isAbortError(error)) {\n        this._contextNextRetryAt = Date.now() + CONTEXT_FAILURE_RETRY_MS;\n        this._setDiscoveryStatus({\n          phase: this._entries.size ? 'degraded' : 'error',\n          error: cleanText(error?.message || error),\n          updatedAt: Date.now(),\n        });\n      }\n      throw error;\n    } finally {\n      if (this._contextAbort === controller) this._contextAbort = null;\n      this._contextInflight = false;\n      const queued = this._queuedContextRefresh;\n      this._queuedContextRefresh = null;\n      if (queued && !this._disposed && this.enabled) {\n        this._contextCenter = queued.center;\n        queueMicrotask(() => this._requestContextRefresh(queued.force));\n      }\n    }\n  }\n\n  _setDiscoveryStatus(patch) {\n    this._discoveryStatus = { ...this._discoveryStatus, ...(patch || {}) };\n    this.eventBus?.emit?.('trafficCameras:status', this.getDiscoverySnapshot());\n  }\n\n  _replaceSourceEntries(sourceKey, items) {\n    const oldIds = this._sourceEntryIds.get(sourceKey) || new Set();\n    // A refresh mostly returns the same cameras: keep those entries (marker,\n    // label DOM) and rebuild only what changed. Disposing and recreating every\n    // entry in one task cost ~380 ms on a 700-camera refresh.\n    const incoming = new Map();\n    for (const item of items) if (item?.id) incoming.set(item.id, item);\n    const kept = new Map();\n    for (const id of oldIds) {\n      const entry = this._entries.get(id);\n      const next = incoming.get(id);\n      if (entry && next && next.lat === entry.lat && next.lon === entry.lon\n        && (next.label || next.title) === (entry.label || entry.title) && next.kind === entry.kind) {\n        kept.set(id, entry);\n        continue;\n      }\n      if (entry) this._disposeEntry(entry);\n      this._entries.delete(id);\n    }\n    const ids = new Set();\n    const rankedItems = [...items].sort((a, b) => {\n      const distanceA = Number(a.distanceM);\n      const distanceB = Number(b.distanceM);\n      return (Number.isFinite(distanceA) ? distanceA : Infinity) - (Number.isFinite(distanceB) ? distanceB : Infinity);\n    });\n    for (const item of rankedItems.slice(0, this.maxCameras)) {\n      if (!item?.id || !Number.isFinite(item.lat) || !Number.isFinite(item.lon)) continue;\n      const reuse = kept.get(item.id);\n      if (reuse) {\n        // Refresh non-visual fields (status, URLs, provenance) in place.\n        for (const key of ['status', 'live', 'imageUrl', 'streamUrl', 'sourceUrl', 'distanceM', 'provenance', 'metadata', 'route', 'direction']) {\n          if (key in item) reuse[key] = item[key];\n        }\n        ids.add(item.id);\n        kept.delete(item.id);\n        continue;\n      }\n      if (this._entries.size >= this.maxCameras) break;\n      const entry = this._createEntry(item);\n      this._entries.set(entry.id, entry);\n      ids.add(entry.id);\n    }\n    // Kept entries that fell past maxCameras are released.\n    for (const entry of kept.values()) { this._disposeEntry(entry); this._entries.delete(entry.id); }\n    this._sourceEntryIds.set(sourceKey, ids);\n  }\n\n  _createEntry(item) {\n    const entry = {\n      ...item,\n      marker: null,\n      labelHandle: null,\n      normal: new THREE.Vector3(),\n      surfaceRadius: this.planetRadius,\n      culled: false,\n    };\n    // Markers and labels are built by the per-update hydration budget\n    // (_hydratePendingEntries), never all at once in the arrival task.\n    return entry;\n  }\n\n  _hydratePendingEntries(limit) {\n    let remaining = Math.max(1, Math.floor(limit) || 1);\n    for (const entry of this._entries.values()) {\n      if (entry.marker) continue;\n      this._hydrateEntry(entry);\n      remaining -= 1;\n      if (remaining <= 0) break;\n    }\n  }\n\n  _hydrateEntry(entry) {\n    if (!entry || entry.marker || !this._interactiveReady) return;\n    // Show a marker kind only once its program is linked (compiled async);\n    // the first marker otherwise blocked a frame on the link (~140 ms live,\n    // up to seconds on a cold driver). Deferred entries retry at 10 Hz.\n    this._programGate ||= createProgramGate({\n      renderer: () => this.sceneInitializer?.renderer,\n      camera: () => this.camera,\n      scene: () => this.sceneInitializer?.scene,\n    });\n    if (!this._programGate.ready(this._materialFor(entry.kind), this._markerGeometry)) return;\n    const marker = new THREE.Mesh(this._markerGeometry, this._materialFor(entry.kind));\n    marker.name = `TrafficCamera:${entry.id}`;\n    marker.renderOrder = 8;\n    marker.userData.trafficCameraId = entry.id;\n    entry.marker = marker;\n    this.group.add(marker);\n    this._positionEntry(entry);\n    this._syncLabel(entry);\n  }\n\n  _releaseEntryVisual(entry) {\n    if (!entry) return;\n    if (entry.id === this._activePreviewEntryId) {\n      this._activePreviewEntryId = null;\n      this._lastPreviewRefreshAt = 0;\n    }\n    if (entry.labelHandle) this._ensureLabelSystem().removeLabel(entry.labelHandle);\n    entry.labelHandle = null;\n    entry.marker?.parent?.remove(entry.marker);\n    entry.marker = null;\n  }\n\n  _disposeEntry(entry) {\n    this._releaseEntryVisual(entry);\n  }\n\n  _resolveSurfaceSample(dir) {\n    const ellipsoid = ellipsoidRadiusForLocalDir(dir);\n    const sampler = this.surfaceController?.sampleTerrainRadiusForDir;\n    if (typeof sampler !== 'function') return { radius: ellipsoid, authoritative: false };\n    const worldDir = this._tmpDir.copy(dir);\n    this.parentGroup?.getWorldQuaternion?.(this._tmpQuat);\n    if (this.parentGroup?.getWorldQuaternion) worldDir.applyQuaternion(this._tmpQuat);\n    const requireFreshPhotoHit = !!this.surfaceController?.photoTileGroup;\n    const sampled = sampler.call(this.surfaceController, worldDir, {\n      mutateCache: false,\n      requireFreshPhotoHit,\n      allowTriTreeFallback: !requireFreshPhotoHit,\n      skipWorldMatrixUpdate: true,\n    });\n    return Number.isFinite(sampled)\n      ? { radius: sampled, authoritative: true }\n      : { radius: ellipsoid, authoritative: false };\n  }\n\n  _positionEntry(entry) {\n    if (!entry?.marker) return;\n    const dir = latLonToLocalDir(entry.lat, entry.lon);\n    entry.normal.copy(dir);\n    const sample = this._resolveSurfaceSample(dir);\n    if (sample.authoritative || !Number.isFinite(entry.surfaceRadius)) {\n      entry.surfaceRadius = sample.radius;\n    }\n    if (sample.authoritative) entry._terrainMated = true;\n    entry.marker.quaternion.setFromUnitVectors(this._tmpWorldUp, dir);\n    this._updateEntryTransform(entry);\n  }\n\n  refreshTerrainAnchors(changes) {\n    if (!Array.isArray(changes) || changes.length === 0) return 0;\n    let updated = 0;\n    for (const entry of this._entries.values()) {\n      if (!entry.marker) continue;\n      if (!terrainSurfaceChangesAffectLatLon(changes, entry.lat, entry.lon)) continue;\n      this._positionEntry(entry);\n      updated += 1;\n    }\n    return updated;\n  }\n\n  _updateEntryTransform(entry) {\n    if (!entry?.marker) return;\n    const scale = Number.isFinite(entry._markerScale) ? entry._markerScale : 1;\n    const height = 14 * scale;\n    entry.marker.scale.setScalar(scale);\n    entry.marker.position.copy(entry.normal).multiplyScalar(entry.surfaceRadius + height * 0.5 + 1);\n    if (entry.labelHandle) {\n      this._tmpPosition.copy(entry.normal).multiplyScalar(entry.surfaceRadius + height + 5);\n      this._ensureLabelSystem().updatePosition(entry.labelHandle, this._tmpPosition);\n    }\n  }\n\n  _syncLabel(entry) {\n    if (!entry || !entry.marker || !this._interactiveReady) return;\n    if (!this.showLabels) {\n      if (entry.labelHandle) this._ensureLabelSystem().removeLabel(entry.labelHandle);\n      entry.labelHandle = null;\n      return;\n    }\n    if (entry.labelHandle) return;\n    this._tmpPosition.copy(entry.normal).multiplyScalar(entry.surfaceRadius + 20);\n    const subText = [entry.source, entry.status || (entry.live ? 'Latest public frame' : 'Location record')]\n      .filter(Boolean).join(' · ');\n    entry.labelHandle = this._ensureLabelSystem().createLabel(entry.label || entry.title, {\n      position: this._tmpPosition,\n      type: 'traffic-camera',\n      color: LABEL_COLOR,\n      objectRadius: 5,\n      subText,\n      maxDistance: this.cullDistanceM,\n      metadata: {\n        source: entry.source,\n        sourceUrl: entry.sourceUrl,\n        imageUrl: entry.imageUrl,\n        streamUrl: entry.streamUrl,\n        status: entry.status,\n        direction: entry.direction,\n        route: entry.route,\n        lat: entry.lat,\n        lon: entry.lon,\n        kind: entry.kind,\n      },\n    });\n    this.group.add(entry.labelHandle.group);\n  }\n\n  _updateMarkerScaleAndCull() {\n    if (!this.camera || !this.group) return;\n    this.group.updateMatrixWorld(true);\n    this.camera.getWorldPosition(this._tmpObserver);\n    this.group.worldToLocal(this._tmpObserver);\n    const cameraRadius = this._tmpObserver.length();\n    if (!(cameraRadius > 0)) return;\n    const altitudeKm = Math.max(0, (cameraRadius - this.planetRadius) / 1000);\n    const scale = Math.min(24, Math.max(1, 1 + Math.log10(1 + altitudeKm) * 1.8));\n    const cullSq = this.cullDistanceM * this.cullDistanceM;\n    const observerDirection = this._tmpObserverDir.copy(this._tmpObserver).normalize();\n    const previewCandidates = [];\n    for (const entry of this._entries.values()) {\n      if (!entry.marker) continue;\n      const distSq = this._tmpObserver.distanceToSquared(entry.marker.position);\n      const sameHemisphere = observerDirection.dot(entry.normal) > -0.02;\n      const visible = distSq <= cullSq && sameHemisphere;\n      entry.culled = !visible;\n      entry.marker.visible = visible;\n      if (entry._markerScale !== scale) {\n        entry._markerScale = scale;\n        this._updateEntryTransform(entry);\n      }\n      if (visible && this.showLabels && entry.labelHandle) {\n        const imageUrl = cameraPreviewUrl(entry.imageUrl, this._lastPreviewRefreshAt || Date.now());\n        if (imageUrl) {\n          this._tmpProjected.copy(entry.marker.position);\n          this.group.localToWorld(this._tmpProjected);\n          this._tmpProjected.project(this.camera);\n          previewCandidates.push({\n            entry,\n            visible: true,\n            imageUrl,\n            x: this._tmpProjected.x,\n            y: this._tmpProjected.y,\n            z: this._tmpProjected.z,\n          });\n        }\n      }\n    }\n    this._setCameraPreview(selectCenteredTrafficCameraPreview(previewCandidates));\n  }\n\n  _setCameraPreview(entry) {\n    const nextId = entry?.id || null;\n    const now = Date.now();\n    const refresh = nextId && nextId === this._activePreviewEntryId\n      && now - this._lastPreviewRefreshAt >= CAMERA_PREVIEW_REFRESH_MS;\n    if (nextId === this._activePreviewEntryId && !refresh) return;\n    const labels = this._labelSystem;\n    const previous = this._activePreviewEntryId ? this._entries.get(this._activePreviewEntryId) : null;\n    if (previous?.labelHandle && labels) {\n      const metadata = { ...(previous.labelHandle.metadata || {}) };\n      delete metadata.cameraPreviewActive;\n      delete metadata.cameraPreviewUrl;\n      delete metadata.cameraPreviewRevision;\n      labels.updateMetadata(previous.labelHandle, metadata);\n    }\n    this._activePreviewEntryId = nextId;\n    this._lastPreviewRefreshAt = nextId ? now : 0;\n    if (!entry?.labelHandle || !labels) return;\n    const previewUrl = cameraPreviewUrl(entry.imageUrl, now);\n    if (!previewUrl) {\n      this._activePreviewEntryId = null;\n      this._lastPreviewRefreshAt = 0;\n      return;\n    }\n    labels.updateMetadata(entry.labelHandle, {\n      ...(entry.labelHandle.metadata || {}),\n      cameraPreviewActive: true,\n      cameraPreviewUrl: previewUrl,\n      cameraPreviewRevision: Math.floor(now / CAMERA_PREVIEW_REFRESH_MS),\n    });\n  }\n\n  _onPointerDown(event) {\n    if (event.button !== 0) return;\n    this._pointerDown = { id: event.pointerId, x: event.clientX, y: event.clientY };\n  }\n\n  _onPointerUp(event) {\n    const start = this._pointerDown;\n    this._pointerDown = null;\n    if (!start || event.button !== 0 || start.id !== event.pointerId) return;\n    if (Math.hypot(event.clientX - start.x, event.clientY - start.y) > CLICK_SLOP_PX) return;\n    this._pickAt(event);\n  }\n\n  _pickAt(event) {\n    if (!this.camera || !this.domElement) return;\n    const rect = this.domElement.getBoundingClientRect();\n    if (!rect.width || !rect.height) return;\n    this._pointer.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;\n    this._pointer.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;\n    this._raycaster.setFromCamera(this._pointer, this.camera);\n    const targets = [...this._entries.values()]\n      .filter((entry) => entry.marker?.visible)\n      .map((entry) => entry.marker);\n    const hit = this._raycaster.intersectObjects(targets, false)[0];\n    const id = hit?.object?.userData?.trafficCameraId;\n    const entry = id ? this._entries.get(id) : null;\n    if (entry) this._viewer.show(entry);\n  }\n}\n","import { resolveBackendApiUrl } from '../shared/backend.js';\nimport { getNoclipGovernanceClient } from '../shared/NoclipGovernanceClient.js';\n\nconst CACHE_TTL_MS = 30_000;\nconst MAX_CACHE_ENTRIES = 24;\nconst MAX_SEGMENTS = 600;\nconst MAX_EVENTS = 500;\nconst MAX_COORDS_PER_LINE = 512;\nconst cache = new Map();\n\nconst cleanText = (value, max = 280) => String(value ?? '')\n  .replace(/\\s+/g, ' ')\n  .trim()\n  .slice(0, max);\n\nconst finiteCoord = (coord) => (\n  Array.isArray(coord)\n  && Number.isFinite(Number(coord[0]))\n  && Number.isFinite(Number(coord[1]))\n  && Math.abs(Number(coord[0])) <= 180\n  && Math.abs(Number(coord[1])) <= 90\n);\n\nconst secureUrl = (value) => {\n  const raw = cleanText(value, 2048);\n  if (!raw) return '';\n  try {\n    const url = new URL(raw);\n    return url.protocol === 'https:' ? url.toString() : '';\n  } catch {\n    return '';\n  }\n};\n\nconst finiteOrNull = (value) => Number.isFinite(Number(value)) ? Number(value) : null;\n\nexport function normalizeRoadTrafficRecord(raw, index = 0) {\n  if (!raw || typeof raw !== 'object') return null;\n  const rawGeometry = raw.geometry || {};\n  let geometry = null;\n  if (rawGeometry.type === 'Point' && finiteCoord(rawGeometry.coordinates)) {\n    geometry = {\n      type: 'Point',\n      coordinates: [Number(rawGeometry.coordinates[0]), Number(rawGeometry.coordinates[1])],\n    };\n  } else if (rawGeometry.type === 'LineString') {\n    const coordinates = (Array.isArray(rawGeometry.coordinates) ? rawGeometry.coordinates : [])\n      .slice(0, MAX_COORDS_PER_LINE)\n      .filter(finiteCoord)\n      .map((coord) => [Number(coord[0]), Number(coord[1])]);\n    if (coordinates.length >= 2) geometry = { type: 'LineString', coordinates };\n  }\n  if (!geometry) return null;\n  const kind = ['flow', 'incident', 'closure', 'roadwork', 'hazard'].includes(raw.kind)\n    ? raw.kind\n    : 'incident';\n  const id = cleanText(raw.id || `${kind}:${index}`, 220);\n  if (!id) return null;\n  return {\n    id,\n    kind,\n    geometry,\n    title: cleanText(raw.title || raw.roadName || 'Road traffic'),\n    roadName: cleanText(raw.roadName, 160),\n    direction: cleanText(raw.direction, 80),\n    speedKph: finiteOrNull(raw.speedKph),\n    freeflowKph: finiteOrNull(raw.freeflowKph),\n    vehicleFlowVph: finiteOrNull(raw.vehicleFlowVph),\n    occupancy: finiteOrNull(raw.occupancy),\n    congestion: finiteOrNull(raw.congestion),\n    severity: ['unknown', 'low', 'medium', 'high', 'critical'].includes(raw.severity)\n      ? raw.severity\n      : 'unknown',\n    lanesClosed: finiteOrNull(raw.lanesClosed),\n    observedAt: cleanText(raw.observedAt, 80),\n    validUntil: cleanText(raw.validUntil, 80),\n    source: cleanText(raw.source, 160),\n    sourceUrl: secureUrl(raw.sourceUrl),\n    confidence: Math.max(0, Math.min(1, finiteOrNull(raw.confidence) ?? 0.7)),\n    distanceM: Math.max(0, finiteOrNull(raw.distanceM) ?? 0),\n    metadata: raw.metadata && typeof raw.metadata === 'object' ? { ...raw.metadata } : {},\n  };\n}\n\nexport function normalizeRoadTrafficPayload(raw, center) {\n  const seen = new Set();\n  const normalizeList = (items, max) => (Array.isArray(items) ? items : [])\n    .slice(0, max)\n    .map(normalizeRoadTrafficRecord)\n    .filter((record) => {\n      if (!record || seen.has(record.id)) return false;\n      seen.add(record.id);\n      return true;\n    });\n  return {\n    generatedAt: cleanText(raw?.generatedAt, 80) || new Date().toISOString(),\n    cached: raw?.cached === true,\n    center: {\n      lat: Number(raw?.center?.lat ?? center.lat),\n      lon: Number(raw?.center?.lon ?? center.lon),\n      radiusM: Number(raw?.center?.radiusM) || Number(center.radiusM) || 80_000,\n    },\n    segments: normalizeList(raw?.segments, MAX_SEGMENTS),\n    events: normalizeList(raw?.events, MAX_EVENTS),\n    sources: (Array.isArray(raw?.sources) ? raw.sources : []).slice(0, 32).map((source) => ({\n      id: cleanText(source?.id, 120),\n      name: cleanText(source?.name, 160),\n      kind: cleanText(source?.kind, 40),\n      status: cleanText(source?.status, 40),\n      recordCount: Math.max(0, Number(source?.recordCount) || 0),\n      updatedAt: cleanText(source?.updatedAt, 80),\n      error: cleanText(source?.error, 240),\n    })),\n  };\n}\n\nconst cacheKey = (center, options) => [\n  Number(center.lat).toFixed(2),\n  Number(center.lon).toFixed(2),\n  Math.round(options.radiusM / 10_000),\n  options.maxSegments,\n  options.maxEvents,\n].join(':');\n\nexport async function fetchNearbyRoadTraffic(center = {}, {\n  signal,\n  force = false,\n  radiusM = 80_000,\n  maxSegments = 240,\n  maxEvents = 180,\n} = {}) {\n  const lat = Number(center.lat);\n  const lon = Number(center.lon);\n  if (!Number.isFinite(lat) || !Number.isFinite(lon) || Math.abs(lat) > 90 || Math.abs(lon) > 180) {\n    throw new Error('Valid scene coordinates are required for road traffic');\n  }\n  const options = {\n    radiusM: Math.max(5_000, Math.min(350_000, Math.round(Number(radiusM) || 80_000))),\n    maxSegments: Math.max(1, Math.min(MAX_SEGMENTS, Math.round(Number(maxSegments) || 240))),\n    maxEvents: Math.max(1, Math.min(MAX_EVENTS, Math.round(Number(maxEvents) || 180))),\n  };\n  const key = cacheKey({ lat, lon }, options);\n  const cached = cache.get(key);\n  if (!force && cached && Date.now() - cached.at < CACHE_TTL_MS) return cached.payload;\n\n  const query = new URLSearchParams({\n    lat: lat.toFixed(6),\n    lon: lon.toFixed(6),\n    radiusM: String(options.radiusM),\n    maxSegments: String(options.maxSegments),\n    maxEvents: String(options.maxEvents),\n  });\n  const response = await getNoclipGovernanceClient().request(\n    resolveBackendApiUrl(`/traffic/nearby?${query}`),\n    { signal, governanceLane: 'scene' },\n  );\n  let data = null;\n  try { data = await response.json(); } catch { data = null; }\n  if (!response.ok) {\n    throw new Error(cleanText(data?.detail || data?.error, 300) || `Road traffic request failed (${response.status})`);\n  }\n  const payload = normalizeRoadTrafficPayload(data, { lat, lon, radiusM: options.radiusM });\n  cache.set(key, { at: Date.now(), payload });\n  if (cache.size > MAX_CACHE_ENTRIES) cache.delete(cache.keys().next().value);\n  return payload;\n}\n\nexport function clearRoadTrafficCache() {\n  cache.clear();\n}\n","/**\n * Regional road traffic overlay.\n *\n * Official detector and event geometry is rendered as one bounded ribbon\n * mesh. Every coordinate is progressively mated to the same photoreal/TriTree\n * surface sampler as navigation, but traffic uses a strict 1–5 m lift and\n * never falls back to the navigation ribbon's elevated 35 m bootstrap.\n */\nimport * as THREE from 'three';\nimport { PLANET_RADIUS } from '../../modules/constants.js';\nimport { dirToLatLonLocal, ellipsoidRadiusForLocalDir, latLonToLocalDir } from '../../modules/geometry-utils.js';\nimport { getLabelSystem } from '../labels/LabelSystem.js';\nimport { terrainSurfaceChangesAffectLatLon } from '../scene/TerrainSurfaceChange.js';\nimport { fetchNearbyRoadTraffic } from '../traffic/RoadTrafficApiService.js';\n\nconst DEFAULT_RADIUS_M = 80_000;\nconst DEFAULT_MAX_SEGMENTS = 240;\nconst DEFAULT_MAX_EVENTS = 180;\nconst DEFAULT_LIFT_M = 3;\nconst DEFAULT_WIDTH_M = 5.5;\nconst CONTEXT_MOVE_M = 18_000;\nconst CONTEXT_REFRESH_MS = 60_000;\nconst CONTEXT_FAILURE_RETRY_MS = 90_000;\nconst DRAPE_INTERVAL_MS = 250;\nconst DRAPE_BUDGET = 48;\nconst MAX_COORDS = 8_000;\nconst MAX_LABELS = 64;\n\nconst VERTEX_SHADER = /* glsl */`\nprecision highp float;\nuniform mat4 modelViewMatrix;\nuniform mat4 projectionMatrix;\nattribute vec3 position;\nattribute vec3 color;\nattribute float aAlong;\nattribute float aFlow;\nattribute float aReady;\nvarying vec3 vColor;\nvarying float vAlong;\nvarying float vFlow;\nvarying float vReady;\nvoid main() {\n  vColor = color;\n  vAlong = aAlong;\n  vFlow = aFlow;\n  vReady = aReady;\n  gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n}\n`;\n\nconst FRAGMENT_SHADER = /* glsl */`\nprecision highp float;\nuniform float uTime;\nuniform float uOpacity;\nvarying vec3 vColor;\nvarying float vAlong;\nvarying float vFlow;\nvarying float vReady;\nvoid main() {\n  float movingBand = smoothstep(0.08, 0.20, fract(vAlong - uTime * 0.42));\n  float flowPulse = mix(1.0, 0.68 + 0.32 * movingBand, step(0.5, vFlow));\n  float edgeFade = clamp(vReady, 0.0, 1.0);\n  gl_FragColor = vec4(vColor * flowPulse, uOpacity * edgeFade);\n}\n`;\n\nconst COLORS = Object.freeze({\n  free: new THREE.Color(0x39e57c),\n  moderate: new THREE.Color(0xffd24a),\n  slow: new THREE.Color(0xff5b45),\n  unknown: new THREE.Color(0x42cfff),\n  incident: new THREE.Color(0xff7a45),\n  closure: new THREE.Color(0xff2366),\n  roadwork: new THREE.Color(0xffb020),\n  hazard: new THREE.Color(0xb06cff),\n});\n\nconst cleanText = (value) => String(value ?? '').replace(/\\s+/g, ' ').trim();\nconst distanceMeters = (a, b) => {\n  if (!a || !b) return Infinity;\n  const dLat = (a.lat - b.lat) * 111_132;\n  const dLon = (a.lon - b.lon) * 111_132 * Math.cos(a.lat * Math.PI / 180);\n  return Math.hypot(dLat, dLon);\n};\n\nconst recordColor = (record) => {\n  if (record.kind !== 'flow') return COLORS[record.kind] || COLORS.incident;\n  if (Number.isFinite(record.congestion)) {\n    if (record.congestion >= 0.66) return COLORS.slow;\n    if (record.congestion >= 0.33) return COLORS.moderate;\n    return COLORS.free;\n  }\n  if (!Number.isFinite(record.speedKph)) return COLORS.unknown;\n  if (record.speedKph < 25) return COLORS.slow;\n  if (record.speedKph < 55) return COLORS.moderate;\n  return COLORS.free;\n};\n\nconst recordSummary = (record) => {\n  if (record.kind === 'flow') {\n    return [\n      Number.isFinite(record.speedKph) ? `${Math.round(record.speedKph)} km/h` : '',\n      Number.isFinite(record.vehicleFlowVph) ? `${Math.round(record.vehicleFlowVph)} veh/h` : '',\n      record.direction,\n    ].filter(Boolean).join(' · ');\n  }\n  return [record.roadName, record.severity !== 'unknown' ? record.severity : '', record.source]\n    .filter(Boolean).join(' · ');\n};\n\nexport class RoadTrafficOverlay {\n  constructor({\n    parentGroup,\n    camera,\n    surfaceController,\n    sceneInitializer,\n    eventBus,\n    planetRadius = PLANET_RADIUS,\n    enabled = true,\n    showLabels = true,\n    radiusM = DEFAULT_RADIUS_M,\n    maxSegments = DEFAULT_MAX_SEGMENTS,\n    maxEvents = DEFAULT_MAX_EVENTS,\n    surfaceLiftM = DEFAULT_LIFT_M,\n    ribbonWidthM = DEFAULT_WIDTH_M,\n    deferUntilInteractive = true,\n  } = {}) {\n    this.parentGroup = parentGroup || null;\n    this.camera = camera || null;\n    this.surfaceController = surfaceController || null;\n    this.sceneInitializer = sceneInitializer || null;\n    this.eventBus = eventBus || null;\n    this.planetRadius = Number.isFinite(planetRadius) ? planetRadius : PLANET_RADIUS;\n    this.enabled = enabled !== false;\n    this.showLabels = showLabels !== false;\n    this.radiusM = Math.max(5_000, Math.min(350_000, Number(radiusM) || DEFAULT_RADIUS_M));\n    this.maxSegments = Math.max(1, Math.min(600, Math.floor(Number(maxSegments) || DEFAULT_MAX_SEGMENTS)));\n    this.maxEvents = Math.max(1, Math.min(500, Math.floor(Number(maxEvents) || DEFAULT_MAX_EVENTS)));\n    this.surfaceLiftM = Math.max(1, Math.min(5, Number(surfaceLiftM) || DEFAULT_LIFT_M));\n    this.ribbonWidthM = Math.max(2, Math.min(14, Number(ribbonWidthM) || DEFAULT_WIDTH_M));\n    this._interactiveReady = deferUntilInteractive !== true;\n\n    this.group = new THREE.Group();\n    this.group.name = 'RoadTrafficOverlay';\n    this.group.visible = this.enabled && this._interactiveReady;\n    this.parentGroup?.add(this.group);\n    this.sceneInitializer?.addDepthPassExclude?.(this.group);\n\n    this._material = new THREE.RawShaderMaterial({\n      name: 'RoadTrafficRibbonMaterial',\n      uniforms: { uTime: { value: 0 }, uOpacity: { value: 0.86 } },\n      vertexShader: VERTEX_SHADER,\n      fragmentShader: FRAGMENT_SHADER,\n      vertexColors: true,\n      transparent: true,\n      depthTest: true,\n      depthWrite: false,\n      polygonOffset: true,\n      polygonOffsetFactor: -1,\n      polygonOffsetUnits: -1,\n      side: THREE.DoubleSide,\n      toneMapped: false,\n    });\n    this._mesh = null;\n    this._records = [];\n    this._events = [];\n    this._coordEntries = [];\n    this._labels = [];\n    this._labelSystem = null;\n    this._origin = new THREE.Vector3();\n    this._contextCenter = null;\n    this._loadedCenter = null;\n    this._loadedAt = 0;\n    this._nextRetryAt = 0;\n    this._inflight = false;\n    this._abort = null;\n    this._drapeCursor = 0;\n    this._drapeElapsedMs = DRAPE_INTERVAL_MS;\n    this._contextElapsedMs = 0;\n    this._disposed = false;\n    this._status = { phase: 'idle', generatedAt: '', segmentCount: 0, eventCount: 0, sources: [], error: '' };\n\n    this._tmpObserver = new THREE.Vector3();\n    this._tmpDir = new THREE.Vector3();\n    this._tmpWorldDir = new THREE.Vector3();\n    this._tmpTangent = new THREE.Vector3();\n    this._tmpSide = new THREE.Vector3();\n    this._tmpWorldQuat = new THREE.Quaternion();\n    this._tmpPosition = new THREE.Vector3();\n  }\n\n  setInteractiveReady(ready = true) {\n    this._interactiveReady = ready === true;\n    this.group.visible = this.enabled && this._interactiveReady;\n    if (this._interactiveReady && this.enabled) this._updateContextFromCamera(true);\n    if (!this._interactiveReady) this._clearLabels();\n  }\n\n  setEnabled(enabled) {\n    this.enabled = !!enabled;\n    this.group.visible = this.enabled && this._interactiveReady;\n    if (this.enabled && this._interactiveReady) this._updateContextFromCamera(true);\n    else {\n      this._abort?.abort?.();\n      this.eventBus?.emit?.('roadTraffic:entries', []);\n    }\n  }\n\n  setLabelsEnabled(enabled) {\n    this.showLabels = !!enabled;\n    this._syncLabels();\n  }\n\n  applyConfig(config = {}) {\n    const previousLiftM = this.surfaceLiftM;\n    const fetchChanged = (\n      (Number.isFinite(config.radiusM) && Number(config.radiusM) !== this.radiusM)\n      || (Number.isFinite(config.maxSegments) && Number(config.maxSegments) !== this.maxSegments)\n      || (Number.isFinite(config.maxEvents) && Number(config.maxEvents) !== this.maxEvents)\n    );\n    if (Number.isFinite(config.radiusM)) this.radiusM = Math.max(5_000, Math.min(350_000, Number(config.radiusM)));\n    if (Number.isFinite(config.maxSegments)) this.maxSegments = Math.max(1, Math.min(600, Math.floor(Number(config.maxSegments))));\n    if (Number.isFinite(config.maxEvents)) this.maxEvents = Math.max(1, Math.min(500, Math.floor(Number(config.maxEvents))));\n    if (Number.isFinite(config.surfaceLiftM)) this.surfaceLiftM = Math.max(1, Math.min(5, Number(config.surfaceLiftM)));\n    if (Number.isFinite(config.ribbonWidthM)) this.ribbonWidthM = Math.max(2, Math.min(14, Number(config.ribbonWidthM)));\n    if (typeof config.showLabels === 'boolean') this.setLabelsEnabled(config.showLabels);\n    if (typeof config.enabled === 'boolean') this.setEnabled(config.enabled);\n    if (this.surfaceLiftM !== previousLiftM) {\n      const liftDelta = this.surfaceLiftM - previousLiftM;\n      for (const entry of this._coordEntries) entry.radius += liftDelta;\n    }\n    if (fetchChanged && this.enabled && this._interactiveReady) this.refresh();\n    else if (Number.isFinite(config.surfaceLiftM) || Number.isFinite(config.ribbonWidthM)) this._rebuildGeometry();\n  }\n\n  update(dt = 0.016) {\n    if (!this.enabled || !this._interactiveReady) return;\n    const delta = Math.max(0, Number(dt) || 0);\n    this._material.uniforms.uTime.value += delta;\n    this._contextElapsedMs += delta * 1000;\n    this._drapeElapsedMs += delta * 1000;\n    if (this._contextElapsedMs >= 500) {\n      this._contextElapsedMs = 0;\n      this._updateContextFromCamera(false);\n    }\n    if (this._drapeElapsedMs >= DRAPE_INTERVAL_MS && this._coordEntries.length) {\n      this._drapeElapsedMs = 0;\n      this._drapeStep();\n    }\n  }\n\n  refresh() {\n    if (!this._contextCenter) this._updateContextFromCamera(true);\n    else void this._loadContext(this._contextCenter, true);\n  }\n\n  getEntriesSnapshot() {\n    return this._records.map((record) => {\n      const { _coords, _labelHandle, ...publicRecord } = record;\n      return {\n        ...publicRecord,\n        geometry: { ...record.geometry, coordinates: record.geometry.coordinates.map((coord) => [...coord]) },\n        metadata: { ...(record.metadata || {}) },\n      };\n    });\n  }\n\n  getEventsSnapshot() {\n    return this._events.map((record) => ({ ...record, geometry: { ...record.geometry, coordinates: Array.isArray(record.geometry.coordinates?.[0]) ? record.geometry.coordinates.map((coord) => [...coord]) : [...record.geometry.coordinates] } }));\n  }\n\n  getStatusSnapshot() {\n    return { ...this._status, sources: this._status.sources.map((source) => ({ ...source })) };\n  }\n\n  getMiniMapSegments() {\n    return this._records.map((record) => ({\n      id: record.id,\n      kind: record.kind,\n      title: record.title,\n      roadName: record.roadName,\n      summary: recordSummary(record),\n      color: `#${recordColor(record).getHexString()}`,\n      coords: record.geometry.coordinates.map(([lon, lat]) => [lat, lon]),\n    }));\n  }\n\n  dispose() {\n    this._disposed = true;\n    this._abort?.abort?.();\n    this.eventBus?.emit?.('roadTraffic:entries', []);\n    this._clearLabels();\n    this._disposeMesh();\n    this._material.dispose();\n    this.group.parent?.remove(this.group);\n    this.sceneInitializer?.removeDepthPassExclude?.(this.group);\n  }\n\n  _ensureLabelSystem() {\n    if (!this._labelSystem) this._labelSystem = getLabelSystem({ planetRadius: this.planetRadius });\n    return this._labelSystem;\n  }\n\n  _updateContextFromCamera(force) {\n    if (!this.camera || !this.parentGroup || this._inflight) return;\n    this.parentGroup.updateMatrixWorld?.(true);\n    this.camera.getWorldPosition(this._tmpObserver);\n    this.parentGroup.worldToLocal(this._tmpObserver);\n    if (this._tmpObserver.lengthSq() < 1) return;\n    const coords = dirToLatLonLocal(this._tmpObserver.normalize());\n    const center = { lat: coords.latDeg, lon: coords.lonDeg };\n    const moved = distanceMeters(center, this._loadedCenter);\n    const stale = Date.now() - this._loadedAt >= CONTEXT_REFRESH_MS;\n    this._contextCenter = center;\n    if (force || !this._loadedCenter || moved >= CONTEXT_MOVE_M || stale) void this._loadContext(center, force);\n  }\n\n  async _loadContext(center, force = false) {\n    if (this._disposed || this._inflight || Date.now() < this._nextRetryAt) return;\n    this._inflight = true;\n    this._abort?.abort?.();\n    const controller = new AbortController();\n    this._abort = controller;\n    this._status = { ...this._status, phase: 'loading', error: '' };\n    try {\n      const payload = await fetchNearbyRoadTraffic(center, {\n        signal: controller.signal,\n        force,\n        radiusM: this.radiusM,\n        maxSegments: this.maxSegments,\n        maxEvents: this.maxEvents,\n      });\n      if (controller.signal.aborted || this._disposed) return;\n      this._records = (payload.segments || []).filter((record) => record.geometry.type === 'LineString');\n      this._events = payload.events || [];\n      this._loadedCenter = { ...center };\n      this._loadedAt = Date.now();\n      this._nextRetryAt = 0;\n      this._status = {\n        phase: 'ready',\n        generatedAt: payload.generatedAt,\n        segmentCount: this._records.length,\n        eventCount: this._events.length,\n        sources: payload.sources || [],\n        error: '',\n      };\n      this._buildRecordCoordinates();\n      this._drapeStep(Math.min(96, this._coordEntries.length));\n      this._syncLabels();\n      globalThis.document?.dispatchEvent?.(new CustomEvent('noclip:map-overlays-updated', { detail: { source: 'road-traffic' } }));\n      this.eventBus?.emit?.('roadTraffic:status', this.getStatusSnapshot());\n      this.eventBus?.emit?.('roadTraffic:entries', this.getEntriesSnapshot());\n    } catch (error) {\n      if (error?.name === 'AbortError') return;\n      this._nextRetryAt = Date.now() + CONTEXT_FAILURE_RETRY_MS;\n      this._status = { ...this._status, phase: 'error', error: cleanText(error?.message || error) };\n      this.eventBus?.emit?.('roadTraffic:status', this.getStatusSnapshot());\n    } finally {\n      if (this._abort === controller) this._abort = null;\n      this._inflight = false;\n    }\n  }\n\n  _buildRecordCoordinates() {\n    this._coordEntries = [];\n    let remaining = MAX_COORDS;\n    for (const record of this._records) {\n      const coords = record.geometry.coordinates.slice(0, remaining);\n      record._coords = [];\n      for (const [lon, lat] of coords) {\n        const dir = latLonToLocalDir(lat, lon);\n        record._coords.push({\n          lon,\n          lat,\n          dir,\n          radius: ellipsoidRadiusForLocalDir(dir) + this.surfaceLiftM,\n          ready: !this.surfaceController,\n        });\n      }\n      if (record._coords.length < 2) record._coords = [];\n      this._coordEntries.push(...record._coords);\n      remaining -= record._coords.length;\n      if (remaining <= 0) break;\n    }\n    this._records = this._records.filter((record) => record._coords?.length >= 2);\n    const first = this._coordEntries[0];\n    if (first) this._origin.copy(first.dir).multiplyScalar(first.radius);\n    else this._origin.set(0, 0, 0);\n    this.group.position.copy(this._origin);\n    this._drapeCursor = 0;\n    this._rebuildGeometry();\n  }\n\n  _resolveSurface(dir) {\n    if (!this.surfaceController?.sampleTerrainRadiusForDir) {\n      return { radius: ellipsoidRadiusForLocalDir(dir), authoritative: true };\n    }\n    this.parentGroup?.getWorldQuaternion?.(this._tmpWorldQuat);\n    this._tmpWorldDir.copy(dir);\n    if (this.parentGroup?.getWorldQuaternion) this._tmpWorldDir.applyQuaternion(this._tmpWorldQuat);\n    const requireFreshPhotoHit = !!this.surfaceController.photoTileGroup;\n    const sampled = this.surfaceController.sampleTerrainRadiusForDir(this._tmpWorldDir, {\n      mutateCache: false,\n      requireFreshPhotoHit,\n      allowTriTreeFallback: !requireFreshPhotoHit,\n      skipWorldMatrixUpdate: true,\n    });\n    return Number.isFinite(sampled)\n      ? { radius: sampled, authoritative: true }\n      : { radius: ellipsoidRadiusForLocalDir(dir), authoritative: false };\n  }\n\n  _drapeStep(explicitBudget = DRAPE_BUDGET) {\n    if (!this._coordEntries.length) return;\n    this.surfaceController?.prepareTerrainSamplingBatch?.();\n    const count = Math.min(explicitBudget, this._coordEntries.length);\n    let changed = false;\n    for (let i = 0; i < count; i += 1) {\n      const index = (this._drapeCursor + i) % this._coordEntries.length;\n      const entry = this._coordEntries[index];\n      const sample = this._resolveSurface(entry.dir);\n      if (!sample.authoritative) continue;\n      const radius = sample.radius + this.surfaceLiftM;\n      if (!entry.ready || Math.abs(entry.radius - radius) > 0.03) {\n        entry.radius = radius;\n        entry.ready = true;\n        changed = true;\n      }\n    }\n    this._drapeCursor = (this._drapeCursor + count) % this._coordEntries.length;\n    if (changed) {\n      this._updateGeometryPositions();\n      this._updateDrapedLabelPositions();\n    }\n  }\n\n  refreshTerrainAnchors(changes) {\n    if (!Array.isArray(changes) || !changes.length || !this._coordEntries.length) return 0;\n    this.surfaceController?.prepareTerrainSamplingBatch?.();\n    let changed = 0;\n    for (const entry of this._coordEntries) {\n      if (!terrainSurfaceChangesAffectLatLon(changes, entry.lat, entry.lon)) continue;\n      const sample = this._resolveSurface(entry.dir);\n      if (!sample.authoritative) continue;\n      entry.radius = sample.radius + this.surfaceLiftM;\n      entry.ready = true;\n      changed += 1;\n    }\n    if (changed) {\n      this._updateGeometryPositions();\n      this._syncLabels();\n    }\n    return changed;\n  }\n\n  _rebuildGeometry() {\n    this._disposeMesh();\n    if (!this._records.length) return;\n    let vertexCount = 0;\n    let triangleCount = 0;\n    for (const record of this._records) {\n      vertexCount += record._coords.length * 2;\n      triangleCount += (record._coords.length - 1) * 2;\n    }\n    if (!vertexCount || !triangleCount) return;\n    const positions = new Float32Array(vertexCount * 3);\n    const colors = new Float32Array(vertexCount * 3);\n    const along = new Float32Array(vertexCount);\n    const flow = new Float32Array(vertexCount);\n    const ready = new Float32Array(vertexCount);\n    const indices = vertexCount > 65_535 ? new Uint32Array(triangleCount * 3) : new Uint16Array(triangleCount * 3);\n    let vertex = 0;\n    let index = 0;\n    const halfWidth = this.ribbonWidthM * 0.5;\n    for (const record of this._records) {\n      const color = recordColor(record);\n      let cumulative = 0;\n      for (let i = 0; i < record._coords.length; i += 1) {\n        const coord = record._coords[i];\n        coord._vertexStart = vertex;\n        const prev = record._coords[Math.max(0, i - 1)];\n        const next = record._coords[Math.min(record._coords.length - 1, i + 1)];\n        if (i > 0) {\n          const dLat = (coord.lat - prev.lat) * 111_132;\n          const dLon = (coord.lon - prev.lon) * 111_132 * Math.cos(coord.lat * Math.PI / 180);\n          cumulative += Math.hypot(dLat, dLon);\n        }\n        this._tmpTangent.copy(next.dir).multiplyScalar(next.radius)\n          .sub(this._tmpPosition.copy(prev.dir).multiplyScalar(prev.radius));\n        this._tmpSide.copy(this._tmpTangent).cross(coord.dir).normalize();\n        if (this._tmpSide.lengthSq() < 0.5) this._tmpSide.set(0, 1, 0).cross(coord.dir).normalize();\n        const center = this._tmpPosition.copy(coord.dir).multiplyScalar(coord.radius).sub(this._origin);\n        for (let sideIndex = 0; sideIndex < 2; sideIndex += 1) {\n          const sign = sideIndex === 0 ? -1 : 1;\n          const offset = vertex * 3;\n          positions[offset] = center.x + this._tmpSide.x * halfWidth * sign;\n          positions[offset + 1] = center.y + this._tmpSide.y * halfWidth * sign;\n          positions[offset + 2] = center.z + this._tmpSide.z * halfWidth * sign;\n          colors[offset] = color.r;\n          colors[offset + 1] = color.g;\n          colors[offset + 2] = color.b;\n          along[vertex] = cumulative / 38;\n          flow[vertex] = record.kind === 'flow' ? 1 : 0;\n          ready[vertex] = coord.ready ? 1 : 0;\n          vertex += 1;\n        }\n      }\n      const start = vertex - record._coords.length * 2;\n      for (let i = 0; i < record._coords.length - 1; i += 1) {\n        const a = start + i * 2;\n        const b = a + 1;\n        const c = a + 2;\n        const d = a + 3;\n        indices[index++] = a; indices[index++] = c; indices[index++] = b;\n        indices[index++] = b; indices[index++] = c; indices[index++] = d;\n      }\n    }\n    const geometry = new THREE.BufferGeometry();\n    geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));\n    geometry.setAttribute('color', new THREE.BufferAttribute(colors, 3));\n    geometry.setAttribute('aAlong', new THREE.BufferAttribute(along, 1));\n    geometry.setAttribute('aFlow', new THREE.BufferAttribute(flow, 1));\n    geometry.setAttribute('aReady', new THREE.BufferAttribute(ready, 1));\n    geometry.setIndex(new THREE.BufferAttribute(indices, 1));\n    geometry.computeBoundingSphere();\n    this._mesh = new THREE.Mesh(geometry, this._material);\n    this._mesh.name = 'RoadTrafficRibbons';\n    // The floating origin is regional and the ribbon is one bounded draw call.\n    // Terrain re-mating can move vertices after the initial bounding sphere;\n    // avoid recomputing that sphere every 250 ms.\n    this._mesh.frustumCulled = false;\n    this._mesh.renderOrder = 14;\n    this.group.add(this._mesh);\n  }\n\n  _updateGeometryPositions() {\n    const positionAttribute = this._mesh?.geometry?.getAttribute?.('position');\n    const readyAttribute = this._mesh?.geometry?.getAttribute?.('aReady');\n    if (!positionAttribute || !readyAttribute) return;\n    const positions = positionAttribute.array;\n    const ready = readyAttribute.array;\n    const halfWidth = this.ribbonWidthM * 0.5;\n    for (const record of this._records) {\n      for (let i = 0; i < record._coords.length; i += 1) {\n        const coord = record._coords[i];\n        const vertex = coord._vertexStart;\n        if (!Number.isFinite(vertex)) continue;\n        const prev = record._coords[Math.max(0, i - 1)];\n        const next = record._coords[Math.min(record._coords.length - 1, i + 1)];\n        this._tmpTangent.copy(next.dir).multiplyScalar(next.radius)\n          .sub(this._tmpPosition.copy(prev.dir).multiplyScalar(prev.radius));\n        this._tmpSide.copy(this._tmpTangent).cross(coord.dir).normalize();\n        if (this._tmpSide.lengthSq() < 0.5) this._tmpSide.set(0, 1, 0).cross(coord.dir).normalize();\n        const center = this._tmpPosition.copy(coord.dir).multiplyScalar(coord.radius).sub(this._origin);\n        for (let sideIndex = 0; sideIndex < 2; sideIndex += 1) {\n          const sideVertex = vertex + sideIndex;\n          const sign = sideIndex === 0 ? -1 : 1;\n          const offset = sideVertex * 3;\n          positions[offset] = center.x + this._tmpSide.x * halfWidth * sign;\n          positions[offset + 1] = center.y + this._tmpSide.y * halfWidth * sign;\n          positions[offset + 2] = center.z + this._tmpSide.z * halfWidth * sign;\n          ready[sideVertex] = coord.ready ? 1 : 0;\n        }\n      }\n    }\n    positionAttribute.needsUpdate = true;\n    readyAttribute.needsUpdate = true;\n  }\n\n  _disposeMesh() {\n    if (!this._mesh) return;\n    this._mesh.parent?.remove(this._mesh);\n    this._mesh.geometry?.dispose?.();\n    this._mesh = null;\n  }\n\n  _clearLabels() {\n    if (this._labelSystem) {\n      for (const handle of this._labels) this._labelSystem.removeLabel(handle);\n    }\n    for (const record of [...this._events, ...this._records]) record._labelHandle = null;\n    this._labels = [];\n  }\n\n  _syncLabels() {\n    this._clearLabels();\n    if (!this.showLabels || !this._interactiveReady) return;\n    const candidates = [...this._events, ...this._records.slice(0, 24)]\n      .sort((a, b) => a.distanceM - b.distanceM)\n      .slice(0, MAX_LABELS);\n    const labels = this._ensureLabelSystem();\n    for (const record of candidates) {\n      const rawCoords = record.geometry.type === 'Point'\n        ? [record.geometry.coordinates]\n        : record.geometry.coordinates;\n      const coord = rawCoords[Math.floor(rawCoords.length / 2)];\n      if (!coord) continue;\n      const dir = latLonToLocalDir(coord[1], coord[0]);\n      const matching = record._coords?.[Math.floor(record._coords.length / 2)];\n      let radius = matching?.ready ? matching.radius : null;\n      if (!Number.isFinite(radius)) {\n        const sample = this._resolveSurface(dir);\n        radius = sample.authoritative\n          ? sample.radius + this.surfaceLiftM\n          : ellipsoidRadiusForLocalDir(dir) + this.surfaceLiftM;\n      }\n      const position = dir.clone().multiplyScalar(radius + 5).sub(this._origin);\n      const handle = labels.createLabel(record.title || record.roadName || 'Road traffic', {\n        position,\n        type: 'road-traffic',\n        color: recordColor(record).getHex(),\n        objectRadius: 4,\n        subText: recordSummary(record),\n        maxDistance: this.radiusM,\n        metadata: {\n          kind: record.kind,\n          source: record.source,\n          sourceUrl: record.sourceUrl,\n          roadName: record.roadName,\n          direction: record.direction,\n          speedKph: record.speedKph,\n          freeflowKph: record.freeflowKph,\n          vehicleFlowVph: record.vehicleFlowVph,\n          severity: record.severity,\n          lanesClosed: record.lanesClosed,\n          observedAt: record.observedAt,\n          validUntil: record.validUntil,\n          confidence: record.confidence,\n          lat: coord[1],\n          lon: coord[0],\n          ...record.metadata,\n        },\n      });\n      this.group.add(handle.group);\n      record._labelHandle = handle;\n      this._labels.push(handle);\n    }\n  }\n\n  _updateDrapedLabelPositions() {\n    if (!this._labelSystem) return;\n    for (const record of this._records) {\n      const handle = record._labelHandle;\n      if (!handle || !record._coords?.length) continue;\n      const coord = record._coords[Math.floor(record._coords.length / 2)];\n      if (!coord?.ready) continue;\n      this._tmpPosition.copy(coord.dir).multiplyScalar(coord.radius + 5).sub(this._origin);\n      this._labelSystem.updatePosition(handle, this._tmpPosition);\n    }\n  }\n}\n","import { getBackendApiBase } from '../shared/backend.js';\nimport { getNoclipGovernanceClient } from '../shared/NoclipGovernanceClient.js';\n\nexport const RADIO_DATA_FEEDS = Object.freeze([\n  'receivers',\n  'propagation',\n  'satellite-rf',\n  'balloons',\n  'broadcast',\n]);\n\nexport const RADIO_DATA_BANDS = Object.freeze([\n  '160m', '80m', '60m', '40m', '30m', '20m', '17m', '15m', '12m', '10m', '6m',\n]);\n\nconst stableQuery = (params = {}) => {\n  const query = new URLSearchParams();\n  Object.entries(params)\n    .filter(([, value]) => value !== null && value !== undefined && value !== '')\n    .sort(([left], [right]) => left.localeCompare(right))\n    .forEach(([key, value]) => query.set(key, String(value)));\n  return query.toString();\n};\n\nexport class RadioDataApiService {\n  constructor({ fetchImpl = null } = {}) {\n    this._fetch = fetchImpl || getNoclipGovernanceClient().request.bind(getNoclipGovernanceClient());\n    this._cache = new Map();\n    this._inflight = new Map();\n  }\n\n  async _json(path, params = {}, ttlMs = 30_000, signal) {\n    if (!this._fetch) throw new Error('Fetch is unavailable');\n    const query = stableQuery(params);\n    const url = `${getBackendApiBase()}${path}${query ? `?${query}` : ''}`;\n    const cached = this._cache.get(url);\n    if (cached?.expiresAt > Date.now()) return cached.value;\n    if (this._inflight.has(url)) return this._inflight.get(url);\n    const request = this._fetch(url, {\n      signal,\n      governanceLane: 'scene',\n      headers: { Accept: 'application/json' },\n    }).then(async (response) => {\n      const payload = await response.json().catch(() => null);\n      if (!response.ok) throw new Error(payload?.message || `Radio data API returned HTTP ${response.status}`);\n      this._cache.set(url, { value: payload, expiresAt: Date.now() + ttlMs });\n      return payload;\n    }).finally(() => this._inflight.delete(url));\n    this._inflight.set(url, request);\n    return request;\n  }\n\n  contract({ signal } = {}) {\n    return this._json('/v1/radio/contract', {}, 24 * 60 * 60_000, signal);\n  }\n\n  scene({\n    lat,\n    lon,\n    radiusKm = 500,\n    feeds = RADIO_DATA_FEEDS,\n    band = '20m',\n    country = '',\n    limit = 150,\n    signal,\n  } = {}) {\n    const selectedFeeds = RADIO_DATA_FEEDS.filter((feed) => feeds?.includes?.(feed));\n    return this._json('/v1/radio/scene', {\n      lat,\n      lon,\n      radiusKm,\n      feeds: selectedFeeds.join(','),\n      band: RADIO_DATA_BANDS.includes(band) ? band : '20m',\n      country,\n      limit,\n    }, 30_000, signal);\n  }\n\n  clear() {\n    this._cache.clear();\n  }\n}\n\nlet instance = null;\nexport function getRadioDataApiService() {\n  if (!instance) instance = new RadioDataApiService();\n  return instance;\n}\n","// Normalized far-field diagrams, not a link-budget or measured coverage model.\nexport const RADIO_LIGHT_SPEED_MPS = 299792458;\nexport const RADIO_REFERENCE_LOSS_DB = 80;\nconst finite = value => value !== null && value !== undefined && value !== ''\n  && Number.isFinite(Number(value)) ? Number(value) : null;\nconst radians = degrees => degrees * Math.PI / 180;\n\nexport function radioWavelengthMeters(frequencyHz) {\n  const frequency = finite(frequencyHz);\n  return frequency > 0 ? RADIO_LIGHT_SPEED_MPS / frequency : null;\n}\n\nfunction wireAmplitude(cosTheta, lengthWavelengths) {\n  const c = Math.max(-1, Math.min(1, cosTheta));\n  const sinTheta = Math.sqrt(Math.max(0, 1 - c * c));\n  if (sinTheta < 1e-6) return 0;\n  if (lengthWavelengths < 0.01) return sinTheta;\n  const k = Math.PI * lengthWavelengths;\n  return Math.abs((Math.cos(k * c) - Math.cos(k)) / sinTheta);\n}\n\nexport function radioPatternAmplitude(model, cosTheta) {\n  const c = Math.max(-1, Math.min(1, cosTheta));\n  if (model.pattern === 'beam') {\n    if (c <= 0) return 0;\n    const theta = Math.acos(c), width = radians(model.beamwidthDeg);\n    return Math.exp(-2 * Math.LN2 * (theta / width) ** 2);\n  }\n  if (model.pattern === 'isotropic') return 1;\n  if (model.pattern === 'monopole' && c < 0) return 0;\n  return Math.min(1, wireAmplitude(c, model.electricalLength) / model.peakAmplitude);\n}\n\n/** Metadata is evidence, never inferred transmitter power or a fabricated beam.\n * Unknown antennas use an explicit isotropic reference. A recognized wire with\n * missing length/orientation uses a qualified resonant/vertical reference.\n */\nexport function describeRadioField(item = {}) {\n  const meta = item.metadata || {};\n  const antenna = item.antenna ?? meta.antenna;\n  const record = antenna && typeof antenna === 'object' ? antenna : {};\n  const text = String(typeof antenna === 'string' ? antenna : record.type || meta.antennaType || '').toLowerCase();\n  const frequencyHz = finite(item.frequencyHz), wavelengthM = radioWavelengthMeters(frequencyHz);\n  const lengthM = finite(record.lengthM ?? meta.antennaLengthM);\n  const beamwidthDeg = finite(record.beamwidthDeg ?? meta.antennaBeamwidthDeg);\n  const azimuthDeg = finite(record.azimuthDeg ?? meta.antennaAzimuthDeg);\n  const elevation = finite(record.elevationDeg ?? meta.antennaElevationDeg);\n  const elevationDeg = elevation !== null && Math.abs(elevation) <= 90 ? elevation : null;\n  const dipole = /\\b(dipole|doublet)\\b/.test(text);\n  const monopole = /\\b(monopole|vertical|whip|ground[- ]plane)\\b/.test(text) && !dipole;\n  const directional = /\\b(dish|parabolic|yagi|directional|beam|horn)\\b/.test(text);\n  let pattern = 'isotropic', electricalLength = 0.5, assumptions = [];\n  if (directional && beamwidthDeg > 0 && beamwidthDeg <= 180 && azimuthDeg !== null && elevationDeg !== null) {\n    pattern = 'beam';\n    assumptions.push('Gaussian main-lobe approximation; sidelobes unknown');\n  } else if (dipole || monopole) {\n    pattern = monopole ? 'monopole' : 'dipole';\n    if (lengthM > 0 && wavelengthM) electricalLength = lengthM * (monopole ? 2 : 1) / wavelengthM;\n    else assumptions.push(monopole ? 'Quarter-wave vertical reference' : 'Half-wave dipole reference');\n    if (electricalLength > 4) {\n      pattern = 'isotropic'; assumptions.push('Wire exceeds supported four-wavelength model');\n    }\n    if (azimuthDeg === null || elevationDeg === null) assumptions.push('Vertical reference axis; actual orientation unavailable');\n  } else {\n    assumptions.push(directional ? 'Antenna beamwidth/pointing unavailable; isotropic reference' : 'Antenna pattern unavailable; isotropic reference');\n  }\n  let peakAmplitude = 1;\n  if (pattern === 'dipole' || pattern === 'monopole') {\n    peakAmplitude = 1e-12;\n    for (let i = 0; i <= 128; i++) peakAmplitude = Math.max(peakAmplitude, wireAmplitude(Math.cos(i * Math.PI / 128), electricalLength));\n  }\n  const referenceRadiusM = wavelengthM\n    ? wavelengthM / (4 * Math.PI) * 10 ** (RADIO_REFERENCE_LOSS_DB / 20) : null;\n  const displayRadiusM = Math.min(5000, referenceRadiusM ?? 350);\n  if (referenceRadiusM === null) assumptions.push('Frequency unavailable; normalized 350 m diagram');\n  if (referenceRadiusM > displayRadiusM) assumptions.push('Display extent limited to 5 km');\n  const receiverOnly = ['radio-receiver', 'satellite-ground-station', 'radio-propagation'].includes(item.type);\n  const orientationKnown = azimuthDeg !== null && elevationDeg !== null;\n  return {\n    pattern, electricalLength, peakAmplitude, beamwidthDeg: beamwidthDeg || 90,\n    azimuthDeg: orientationKnown ? azimuthDeg : 0,\n    elevationDeg: orientationKnown ? elevationDeg : 90,\n    frequencyHz, wavelengthM, referenceRadiusM, displayRadiusM,\n    role: receiverOnly ? 'Reciprocal receive-sensitivity diagram' : 'Normalized radiation diagram',\n    semantics: `${receiverOnly ? 'Receive sensitivity' : 'Radiation'} · ${pattern === 'isotropic' ? 'isotropic reference' : pattern === 'beam' ? 'main-lobe estimate' : pattern + ' reference'}; ${assumptions.join('; ')}. `\n      + '80 dB free-space attenuation reference; not measured coverage. Power, terrain, buildings and ionospheric propagation are not supplied.',\n  };\n}\n","import * as THREE from 'three';\nimport { describeRadioField } from './RadioFieldModel.js';\nconst MAX_FIELDS = 500, SHELLS = [Math.sqrt(0.1), 1];\nconst patternIndex = { isotropic: 0, dipole: 1, monopole: 2, beam: 3 };\nconst vertexShader = `\nattribute float fieldPattern, electricalLength, peakAmplitude, beamwidth, fieldOpacity;\nvarying vec3 vColor,vViewPosition;\nvarying float vOpacity;\n#include <common>\n#include <logdepthbuf_pars_vertex>\nvoid main(){\n vec3 direction=normalize(position);float c=clamp(direction.y,-1.,1.),s=sqrt(max(0.,1.-c*c)),gain=1.;\n if(fieldPattern>2.5){float angle=acos(c);gain=c>0.?exp(-2.*0.69314718056*pow(angle/beamwidth,2.)):0.;}\n else if(fieldPattern>.5){\n  gain=s<.000001?0.:electricalLength<.01?s:abs((cos(3.14159265359*electricalLength*c)-cos(3.14159265359*electricalLength))/s)/peakAmplitude;\n  if(fieldPattern>1.5&&c<0.)gain=0.;\n }\n gain=clamp(gain,0.,1.);\n vec4 mvPosition=modelViewMatrix*instanceMatrix*vec4(direction*gain,1.);\n vViewPosition=mvPosition.xyz;vColor=instanceColor;vOpacity=fieldOpacity;\n gl_Position=projectionMatrix*mvPosition;\n #include <logdepthbuf_vertex>\n}`;\nconst fragmentShader = `\nvarying vec3 vColor,vViewPosition;\nvarying float vOpacity;\n#include <logdepthbuf_pars_fragment>\nvoid main(){\n vec3 n=normalize(cross(dFdx(vViewPosition),dFdy(vViewPosition)));\n float rim=pow(1.-abs(dot(n,normalize(-vViewPosition))),2.);\n float alpha=vOpacity*(.1+.9*rim);if(alpha<.002)discard;\n gl_FragColor=vec4(vColor*(.8+.6*rim),alpha);\n #include <logdepthbuf_fragment>\n #include <colorspace_fragment>\n}`;\n\n/** Two normalized isosurfaces per antenna in one reusable instanced batch.\n * No path tubes, per-station materials, texture samplers, timer or own RAF.\n */\nexport class RadioFieldVisualization {\n  constructor({ parentGroup, maxSignals = MAX_FIELDS, frequencyColor = () => 0x38bdf8 } = {}) {\n    this.maxSignals = Math.max(1, Math.min(MAX_FIELDS, maxSignals));\n    this.frequencyColor = frequencyColor;\n    this.group = new THREE.Group(); this.group.name = 'RadioFieldVolumes';\n    parentGroup?.add(this.group);\n    const geometry = new THREE.SphereGeometry(1, 24, 12);\n    for (const name of ['fieldPattern', 'electricalLength', 'peakAmplitude', 'beamwidth', 'fieldOpacity']) {\n      geometry.setAttribute(name, new THREE.InstancedBufferAttribute(new Float32Array(MAX_FIELDS * SHELLS.length), 1));\n    }\n    const material = new THREE.ShaderMaterial({ vertexShader, fragmentShader,\n      transparent: true, depthTest: true, depthWrite: false, side: THREE.DoubleSide,\n      forceSinglePass: true, blending: THREE.AdditiveBlending, toneMapped: false });\n    this.mesh = new THREE.InstancedMesh(geometry, material, MAX_FIELDS * SHELLS.length);\n    this.mesh.name = 'RadioFieldBulbs'; this.mesh.count = 0; this.mesh.frustumCulled = false;\n    this.mesh.raycast = () => {}; this.mesh.renderOrder = 3;\n    this.mesh.userData.semantic = 'normalized-far-field-reference-not-measured-coverage';\n    this.mesh.instanceMatrix.setUsage(THREE.DynamicDrawUsage); this.group.add(this.mesh);\n    this.entries = new Map(); this.matrix = new THREE.Matrix4(); this.scale = new THREE.Vector3();\n    this.rotation = new THREE.Quaternion(); this.up = new THREE.Vector3(0, 1, 0);\n  }\n\n  rebuild(entries = []) {\n    this.entries.clear(); let index = 0;\n    for (const entry of entries.slice(0, this.maxSignals)) {\n      if (!entry?.item || !entry.position) continue;\n      const model = describeRadioField(entry.item), item = entry.item;\n      const lat = item.lat * Math.PI / 180, lon = item.lon * Math.PI / 180;\n      const normal = new THREE.Vector3(Math.cos(lat)*Math.sin(lon),Math.sin(lat),Math.cos(lat)*Math.cos(lon));\n      const east = new THREE.Vector3(Math.cos(lon),0,-Math.sin(lon));\n      const north = new THREE.Vector3().crossVectors(normal,east).normalize();\n      const az = model.azimuthDeg*Math.PI/180,el=model.elevationDeg*Math.PI/180;\n      const axis=normal.multiplyScalar(Math.sin(el)).addScaledVector(north,Math.cos(el)*Math.cos(az)).addScaledVector(east,Math.cos(el)*Math.sin(az)).normalize();\n      this.rotation.setFromUnitVectors(this.up,axis);\n      const indices=[];\n      for (const fraction of SHELLS) {\n        this.scale.setScalar(model.displayRadiusM*fraction);\n        this.matrix.compose(entry.position,this.rotation,this.scale);this.mesh.setMatrixAt(index,this.matrix);\n        this.mesh.setColorAt(index,new THREE.Color(this.frequencyColor(item.frequencyHz)));\n        for(const[name,value]of Object.entries({fieldPattern:patternIndex[model.pattern],electricalLength:model.electricalLength,\n          peakAmplitude:model.peakAmplitude,beamwidth:model.beamwidthDeg*Math.PI/180,fieldOpacity:fraction<1?.13:.065}))this.mesh.geometry.attributes[name].setX(index,value);\n        indices.push(index++);\n      }\n      this.entries.set(item.id,{indices,model});\n    }\n    this.mesh.count=index;this.mesh.instanceMatrix.needsUpdate=true;\n    if(this.mesh.instanceColor)this.mesh.instanceColor.needsUpdate=true;\n    for(const name of ['fieldPattern','electricalLength','peakAmplitude','beamwidth','fieldOpacity'])this.mesh.geometry.attributes[name].needsUpdate=true;\n  }\n\n  updatePosition(id,position) {\n    const entry=this.entries.get(id);if(!entry)return;\n    for(const index of entry.indices){this.mesh.getMatrixAt(index,this.matrix);this.matrix.setPosition(position);this.mesh.setMatrixAt(index,this.matrix);}\n    this.mesh.instanceMatrix.needsUpdate=true;\n  }\n  update() {} // The radio overlay uses the scene clock; fields are time-averaged.\n  clear(){this.mesh.count=0;this.entries.clear();}\n  dispose(){this.clear();this.mesh.geometry.dispose();this.mesh.material.dispose();this.group.removeFromParent();}\n}\nexport { vertexShader as RADIO_FIELD_VERTEX_SHADER, fragmentShader as RADIO_FIELD_FRAGMENT_SHADER };\n","import * as THREE from 'three';\nimport { RadioFieldVisualization } from '../radio/RadioFieldVisualization.js';\nimport { latLonToLocalDir } from '../../modules/geometry-utils.js';\n\nconst EARTH_MEAN_RADIUS_M = 6_371_008.8;\nconst RADIO_REFRACTION_EARTH_FACTOR = 4 / 3;\nconst cleanNumber = (value) => value !== null && value !== undefined && value !== '' && Number.isFinite(Number(value)) ? Number(value) : null;\n\nexport const RADIOSONDE_FREQUENCY_STYLES = Object.freeze([\n  { id: 'hf', label: 'HF', minimumHz: 0, maximumHz: 30_000_000, color: 0x34d399 },\n  { id: 'vhf-amateur', label: 'VHF amateur', minimumHz: 144_000_000, maximumHz: 148_000_000, color: 0x22d3ee },\n  { id: 'vhf', label: 'VHF', minimumHz: 30_000_000, maximumHz: 300_000_000, color: 0x38bdf8 },\n  { id: 'met-aids-400', label: 'Meteorological aids 400 MHz', minimumHz: 400_000_000, maximumHz: 406_100_000, color: 0xfb7185 },\n  { id: 'uhf-amateur', label: 'UHF amateur', minimumHz: 420_000_000, maximumHz: 450_000_000, color: 0xc084fc },\n  { id: 'uhf', label: 'UHF', minimumHz: 300_000_000, maximumHz: 1_000_000_000, color: 0xa78bfa },\n  { id: 'met-aids-l', label: 'Meteorological aids L-band', minimumHz: 1_668_400_000, maximumHz: 1_700_000_000, color: 0xfbbf24 },\n  { id: 'l-band', label: 'L-band', minimumHz: 1_000_000_000, maximumHz: 2_000_000_000, color: 0xf59e0b },\n  { id: 's-band', label: 'S-band', minimumHz: 2_000_000_000, maximumHz: 4_000_000_000, color: 0xf97316 },\n  { id: 'microwave', label: 'Microwave', minimumHz: 4_000_000_000, maximumHz: Infinity, color: 0xef4444 },\n]);\n\nconst UNKNOWN_FREQUENCY_STYLE = Object.freeze({\n  id: 'unknown',\n  label: 'Frequency unknown',\n  minimumHz: null,\n  maximumHz: null,\n  color: 0xe5e7eb,\n});\n\nexport function resolveRadiosondeFrequencyStyle(frequencyHz) {\n  const frequency = cleanNumber(frequencyHz);\n  if (frequency === null || frequency <= 0) return UNKNOWN_FREQUENCY_STYLE;\n  // Allocation-specific ranges intentionally precede their broad ITU bands.\n  return RADIOSONDE_FREQUENCY_STYLES.find((style) => (\n    frequency >= style.minimumHz && frequency <= style.maximumHz\n  )) || UNKNOWN_FREQUENCY_STYLE;\n}\n\n/** Standard 4/3-Earth radio-horizon slant range for a sea-level receiver. */\nexport function radiosondeRadioHorizonMeters(altitudeM) {\n  const height = THREE.MathUtils.clamp(cleanNumber(altitudeM) || 0, 0, 60_000);\n  if (height <= 0) return 0;\n  const effectiveRadius = EARTH_MEAN_RADIUS_M * RADIO_REFRACTION_EARTH_FACTOR;\n  return Math.sqrt((effectiveRadius + height) ** 2 - effectiveRadius ** 2);\n}\n\n/** Free-space path loss; useful as link context, never a received-power claim. */\nexport function freeSpacePathLossDb(distanceM, frequencyHz) {\n  const distanceKm = Math.max(0.001, (cleanNumber(distanceM) || 0) / 1_000);\n  const frequencyMhz = Math.max(0.001, (cleanNumber(frequencyHz) || 0) / 1_000_000);\n  return 32.44 + 20 * Math.log10(distanceKm) + 20 * Math.log10(frequencyMhz);\n}\n\nexport function inverseSquarePowerRatio(distanceM, referenceDistanceM = 1_000) {\n  const distance = Math.max(1, cleanNumber(distanceM) || 1);\n  const reference = Math.max(1, cleanNumber(referenceDistanceM) || 1_000);\n  return Math.min(1, (reference * reference) / (distance * distance));\n}\n\nfunction centralAngle(from, to) {\n  return Math.acos(THREE.MathUtils.clamp(from.dot(to), -1, 1));\n}\n\nfunction receiverFromItem(item) {\n  const receiver = item?.receiver;\n  const lat = cleanNumber(receiver?.lat);\n  const lon = cleanNumber(receiver?.lon);\n  if (lat === null || lon === null || lat < -90 || lat > 90 || lon < -180 || lon > 180) return null;\n  return {\n    ...receiver,\n    lat,\n    lon,\n    altitudeM: THREE.MathUtils.clamp(cleanNumber(receiver?.altitudeM) || 0, -500, 10_000),\n  };\n}\n\nfunction observedLinkQuality(item) {\n  const receiver = item?.receiver || {};\n  const snr = cleanNumber(receiver.snrDb ?? item?.snrDb);\n  if (snr !== null) return THREE.MathUtils.clamp((snr + 10) / 30, 0.15, 1);\n  const rssi = cleanNumber(receiver.rssiDbm ?? item?.metadata?.receivedRssiDbm);\n  if (rssi !== null) return THREE.MathUtils.clamp((rssi + 125) / 65, 0.12, 1);\n  return 0.42;\n}\n\nexport function describeRadiosondeSignal(item) {\n  const altitudeM = THREE.MathUtils.clamp(cleanNumber(item?.altitudeM) || 0, 0, 60_000);\n  const receiver = receiverFromItem(item);\n  const from = Number.isFinite(item?.lat) && Number.isFinite(item?.lon)\n    ? latLonToLocalDir(item.lat, item.lon).normalize()\n    : null;\n  const to = receiver ? latLonToLocalDir(receiver.lat, receiver.lon).normalize() : null;\n  const linkDistanceM = from && to ? centralAngle(from, to) * EARTH_MEAN_RADIUS_M : null;\n  return {\n    frequency: resolveRadiosondeFrequencyStyle(item?.frequencyHz),\n    altitudeM,\n    radioHorizonM: radiosondeRadioHorizonMeters(altitudeM),\n    receiver,\n    linkDistanceM,\n    freeSpacePathLossDb: linkDistanceM === null || !(cleanNumber(item?.frequencyHz) > 0)\n      ? null\n      : freeSpacePathLossDb(linkDistanceM, item?.frequencyHz),\n    observedLinkQuality: observedLinkQuality(item),\n  };\n}\n\n/** Compatibility facade: radiosondes now use the same bounded field bulbs as\n * all other radio products; observed receiver links remain metadata. */\nexport class RadiosondeSignalVisualization extends RadioFieldVisualization {\n  constructor(options = {}) {\n    super({ ...options, frequencyColor: frequency => resolveRadiosondeFrequencyStyle(frequency).color });\n  }\n}\n","import * as THREE from 'three';\nimport { ellipsoidRadiusForLocalDir, latLonToLocalDir } from '../../modules/geometry-utils.js';\nimport { getLabelSystem } from '../labels/LabelSystem.js';\nimport { terrainSurfaceChangesAffectLatLon } from '../scene/TerrainSurfaceChange.js';\nimport { getRadioDataApiService, RADIO_DATA_FEEDS } from '../radio/RadioDataApiService.js';\nimport {\n  describeRadiosondeSignal,\n  resolveRadiosondeFrequencyStyle,\n} from './RadioSignalVisualization.js';\n\nimport { RadioFieldVisualization } from '../radio/RadioFieldVisualization.js';\nimport { describeRadioField } from '../radio/RadioFieldModel.js';\n\nconst FEED_COLORS = Object.freeze({\n  receivers: 0x38bdf8,\n  propagation: 0xf59e0b,\n  'satellite-rf': 0xa78bfa,\n  balloons: 0xfb7185,\n  broadcast: 0x34d399,\n});\n\nconst TYPE_LABELS = Object.freeze({\n  'radio-receiver': 'Public SDR receiver',\n  'radio-propagation': 'RF reception report',\n  'satellite-ground-station': 'Satellite ground station',\n  radiosonde: 'Radiosonde',\n  'amateur-balloon': 'Amateur balloon',\n  'broadcast-radio': 'Broadcast radio',\n});\n\nconst AIRBORNE_TYPES = new Set(['radiosonde', 'amateur-balloon']);\nconst EARTH_MEAN_RADIUS_M = 6_371_008.8;\nconst VHF_MIN_HZ = 30_000_000;\nexport const RADIO_SURFACE_MAX_QUERY_RADIUS_KM = 160;\nexport const RADIO_SURFACE_DISTANCE_LIMITS_M = Object.freeze({\n  airborne: 120_000,\n  vhfReceiver: 80_000,\n  receiver: 120_000,\n  propagation: 160_000,\n  satelliteGroundStation: 160_000,\n  broadcast: 100_000,\n  fallback: 120_000,\n});\nconst clean = (value) => String(value ?? '').replace(/\\s+/g, ' ').trim();\nconst finite = (value) => value !== null && value !== undefined && value !== '' && Number.isFinite(Number(value)) ? Number(value) : null;\n\nexport const radioDistanceMeters = (a, b) => {\n  const latA = finite(a?.lat);\n  const lonA = finite(a?.lon);\n  const latB = finite(b?.lat);\n  const lonB = finite(b?.lon);\n  if ([latA, lonA, latB, lonB].some((value) => value === null)) return Infinity;\n  const toRadians = Math.PI / 180;\n  const phiA = latA * toRadians;\n  const phiB = latB * toRadians;\n  const dPhi = (latB - latA) * toRadians;\n  const dLambda = ((((lonB - lonA) + 540) % 360) - 180) * toRadians;\n  const sinPhi = Math.sin(dPhi * 0.5);\n  const sinLambda = Math.sin(dLambda * 0.5);\n  const haversine = sinPhi * sinPhi\n    + Math.cos(phiA) * Math.cos(phiB) * sinLambda * sinLambda;\n  return 2 * EARTH_MEAN_RADIUS_M * Math.asin(Math.sqrt(Math.min(1, haversine)));\n};\n\nexport function resolveSurfaceRadioDistanceLimitM(item = {}) {\n  if (AIRBORNE_TYPES.has(item.type)) return RADIO_SURFACE_DISTANCE_LIMITS_M.airborne;\n  if (item.type === 'radio-receiver') {\n    const frequencyHz = finite(item.frequencyHz);\n    return frequencyHz !== null && frequencyHz >= VHF_MIN_HZ\n      ? RADIO_SURFACE_DISTANCE_LIMITS_M.vhfReceiver\n      : RADIO_SURFACE_DISTANCE_LIMITS_M.receiver;\n  }\n  if (item.type === 'radio-propagation') return RADIO_SURFACE_DISTANCE_LIMITS_M.propagation;\n  if (item.type === 'satellite-ground-station') return RADIO_SURFACE_DISTANCE_LIMITS_M.satelliteGroundStation;\n  if (item.type === 'broadcast-radio') return RADIO_SURFACE_DISTANCE_LIMITS_M.broadcast;\n  return RADIO_SURFACE_DISTANCE_LIMITS_M.fallback;\n}\n\nexport function shouldDisplayRadioItem(item, center, {\n  surfaceMode = false,\n  radiusKm = 500,\n} = {}) {\n  const distanceM = radioDistanceMeters(center, item);\n  if (!Number.isFinite(distanceM)) return false;\n  const configuredLimitM = Math.max(10, Math.min(2_000, Number(radiusKm) || 500)) * 1_000;\n  const limitM = surfaceMode\n    ? Math.min(configuredLimitM, resolveSurfaceRadioDistanceLimitM(item))\n    : configuredLimitM;\n  return distanceM <= limitM;\n}\n\nconst formatFrequency = (frequencyHz) => {\n  const value = finite(frequencyHz);\n  if (value === null) return '';\n  if (value >= 1e9) return `${(value / 1e9).toFixed(3)} GHz`;\n  if (value >= 1e6) return `${(value / 1e6).toFixed(3)} MHz`;\n  if (value >= 1e3) return `${(value / 1e3).toFixed(1)} kHz`;\n  return `${Math.round(value)} Hz`;\n};\n\nexport class RadioDataOverlay {\n  constructor({\n    parentGroup,\n    surfaceController = null,\n    sceneInitializer = null,\n    eventBus = null,\n    apiService = getRadioDataApiService(),\n    enabled = false,\n    feeds = {},\n    radiusKm = 500,\n    band = '20m',\n    maxItems = 150,\n  } = {}) {\n    this.parentGroup = parentGroup || null;\n    this.surfaceController = surfaceController;\n    this.sceneInitializer = sceneInitializer;\n    this.eventBus = eventBus;\n    this.api = apiService;\n    this.enabled = !!enabled;\n    this.feeds = Object.fromEntries(RADIO_DATA_FEEDS.map((feed) => [feed, feeds?.[feed] === true]));\n    this.radiusKm = Math.max(10, Math.min(2_000, Number(radiusKm) || 500));\n    this.band = clean(band) || '20m';\n    this.maxItems = Math.max(1, Math.min(500, Number(maxItems) || 150));\n    this.group = new THREE.Group();\n    this.group.name = 'RadioDataOverlay';\n    this.group.visible = this.enabled;\n    this.parentGroup?.add(this.group);\n    // Match incident spire ownership: radio field bulbs are transparent\n    // scene overlays, never terrain contributors in the atmosphere depth pass.\n    // Letting field geometry enter that pass makes the atmosphere\n    // compositor erase the same geometry against photoreal tiles.\n    this.sceneInitializer?.addDepthPassExclude?.(this.group);\n    this._entries = new Map();\n    this._pathGroup = new THREE.Group();\n    this._pathGroup.name = 'RadioPropagationPaths';\n    this.group.add(this._pathGroup);\n    this._fieldBulbs = new RadioFieldVisualization({\n      parentGroup: this.group,\n      maxSignals: this.maxItems,\n      frequencyColor: frequency => resolveRadiosondeFrequencyStyle(frequency).color,\n    });\n    this._snapshot = { items: [], paths: [], providers: [], notices: [], generatedAt: null };\n    this._center = null;\n    this._visualCenter = null;\n    this._country = '';\n    this._surfaceMode = false;\n    this._abort = null;\n    this._sequence = 0;\n    this._inflight = null;\n    this._tmpWorldDir = new THREE.Vector3();\n    this._tmpQuat = new THREE.Quaternion();\n  }\n\n  applyConfig(config = {}) {\n    if (typeof config.enabled === 'boolean') this.enabled = config.enabled;\n    if (config.feeds && typeof config.feeds === 'object') {\n      for (const feed of RADIO_DATA_FEEDS) {\n        if (typeof config.feeds[feed] === 'boolean') this.feeds[feed] = config.feeds[feed];\n      }\n    }\n    if (Number.isFinite(config.radiusKm)) this.radiusKm = Math.max(10, Math.min(2_000, config.radiusKm));\n    if (Number.isFinite(config.maxItems)) this.maxItems = Math.max(1, Math.min(500, Math.round(config.maxItems)));\n    if (this._fieldBulbs) this._fieldBulbs.maxSignals = this.maxItems;\n    if (clean(config.band)) this.band = clean(config.band);\n    this.group.visible = this.enabled;\n    if (!this.enabled || !this._enabledFeeds().length) this.clear();\n    else if (this._center) void this.refresh({ force: true });\n    this.eventBus?.emit?.('radio:data:config', this.getConfig());\n  }\n\n  getConfig() {\n    return {\n      enabled: this.enabled,\n      feeds: { ...this.feeds },\n      radiusKm: this.radiusKm,\n      band: this.band,\n      maxItems: this.maxItems,\n    };\n  }\n\n  _enabledFeeds() {\n    return RADIO_DATA_FEEDS.filter((feed) => this.feeds[feed]);\n  }\n\n  setCenter(lat, lon, { country = '', force = false, refresh = true } = {}) {\n    if (!Number.isFinite(lat) || !Number.isFinite(lon)) return;\n    const next = { lat, lon };\n    const moved = radioDistanceMeters(this._center, next);\n    const visualMoved = radioDistanceMeters(this._visualCenter, next);\n    const countryChanged = clean(country) !== this._country;\n    this._center = next;\n    this._country = clean(country);\n    if (!refresh && this._snapshot.generatedAt && visualMoved >= 1_000) {\n      this._syncVisuals();\n    }\n    if (refresh && this.enabled && this._enabledFeeds().length && (force || moved >= 25_000 || countryChanged || !this._snapshot.generatedAt)) {\n      void this.refresh({ force: true });\n    }\n  }\n\n  setSurfaceMode(enabled) {\n    const next = enabled === true;\n    if (this._surfaceMode === next) return;\n    this._surfaceMode = next;\n    // Reconcile the existing snapshot immediately, before the bounded request\n    // returns, so a mode transition cannot leave distant labels/volumes alive.\n    this._syncVisuals();\n    if (this.enabled && this._center && this._enabledFeeds().length) {\n      void this.refresh({ force: true });\n    }\n  }\n\n  async refresh({ force = false } = {}) {\n    if (!this.enabled || !this._center || !this._enabledFeeds().length) return this._snapshot;\n    if (this._inflight && !force) return this._inflight;\n    this._abort?.abort?.();\n    this._abort = new AbortController();\n    const sequence = ++this._sequence;\n    this.eventBus?.emit?.('radio:data:status', { state: 'loading', center: { ...this._center } });\n    const request = this.api.scene({\n      ...this._center,\n      radiusKm: this._surfaceMode\n        ? Math.min(this.radiusKm, RADIO_SURFACE_MAX_QUERY_RADIUS_KM)\n        : this.radiusKm,\n      feeds: this._enabledFeeds(),\n      band: this.band,\n      country: this._country,\n      limit: this.maxItems,\n      signal: this._abort.signal,\n    }).then((payload) => {\n      if (sequence !== this._sequence) return this._snapshot;\n      this._snapshot = {\n        items: Array.isArray(payload?.items) ? payload.items : [],\n        paths: Array.isArray(payload?.paths) ? payload.paths : [],\n        providers: Array.isArray(payload?.providers) ? payload.providers : [],\n        notices: Array.isArray(payload?.notices) ? payload.notices : [],\n        generatedAt: payload?.generatedAt || new Date().toISOString(),\n        query: payload?.query || null,\n      };\n      this._syncVisuals();\n      this.eventBus?.emit?.('radio:data', this.getSnapshot());\n      this.eventBus?.emit?.('radio:data:status', { state: 'ready', ...this.getSnapshot() });\n      return this._snapshot;\n    }).catch((error) => {\n      if (error?.name !== 'AbortError' && sequence === this._sequence) {\n        this.eventBus?.emit?.('radio:data:status', { state: 'error', error: error?.message || String(error) });\n      }\n      return this._snapshot;\n    }).finally(() => {\n      if (sequence === this._sequence) {\n        this._inflight = null;\n        this._abort = null;\n      }\n    });\n    this._inflight = request;\n    return request;\n  }\n\n  _sampleSurface(entry) {\n    const ellipsoid = ellipsoidRadiusForLocalDir(entry.dir);\n    const sampler = this.surfaceController?.sampleTerrainRadiusForDir;\n    if (typeof sampler !== 'function') return { radius: ellipsoid, authoritative: false };\n    this._tmpWorldDir.copy(entry.dir);\n    this.parentGroup?.getWorldQuaternion?.(this._tmpQuat);\n    if (this.parentGroup?.getWorldQuaternion) this._tmpWorldDir.applyQuaternion(this._tmpQuat).normalize();\n    const requireFreshPhotoHit = !!this.surfaceController?.photoTileGroup;\n    const radius = sampler.call(this.surfaceController, this._tmpWorldDir, {\n      mutateCache: false,\n      requireFreshPhotoHit,\n      allowTriTreeFallback: !requireFreshPhotoHit,\n      skipWorldMatrixUpdate: true,\n    });\n    return Number.isFinite(radius)\n      ? { radius, authoritative: true }\n      : { radius: ellipsoid, authoritative: false };\n  }\n\n  _positionEntry(entry) {\n    const airborne = AIRBORNE_TYPES.has(entry.item.type);\n    if (airborne) {\n      // SondeHub altitude is observed airborne altitude, not terrain-relative\n      // AGL. Adding it to the local terrain radius double-counted mountain\n      // height and distorted the 3D reception geometry.\n      const radius = ellipsoidRadiusForLocalDir(entry.dir);\n      const altitude = THREE.MathUtils.clamp(finite(entry.item.altitudeM) || 0, 0, 60_000);\n      entry.position.copy(entry.dir).multiplyScalar(radius + altitude);\n    } else {\n      const sample = this._sampleSurface(entry);\n      if (sample.authoritative || !Number.isFinite(entry.stableRadius)) entry.stableRadius = sample.radius;\n      entry.position.copy(entry.dir).multiplyScalar(entry.stableRadius + 12);\n    }\n    if (entry.labelHandle) getLabelSystem().updatePosition(entry.labelHandle, entry.position);\n    this._fieldBulbs?.updatePosition(entry.item.id, entry.position);\n  }\n\n  _metadata(item) {\n    const airborneSignal = AIRBORNE_TYPES.has(item.type) ? describeRadiosondeSignal(item) : null;\n    const field = describeRadioField(item);\n    return {\n      ...(item.metadata || {}),\n      id: item.id,\n      entityType: item.type,\n      typeLabel: TYPE_LABELS[item.type] || 'Radio network data',\n      source: item.provider,\n      provider: item.provider,\n      lat: item.lat,\n      lon: item.lon,\n      altitudeM: finite(item.altitudeM),\n      observedAt: item.observedAt || null,\n      frequencyHz: finite(item.frequencyHz),\n      frequencyLabel: formatFrequency(item.frequencyHz),\n      band: clean(item.band),\n      mode: clean(item.mode),\n      snrDb: finite(item.snrDb),\n      streamUrl: clean(item.streamUrl),\n      waterfallUrl: clean(item.waterfallUrl),\n      website: clean(item.websiteUrl),\n      websiteUrl: clean(item.websiteUrl),\n      receiver: item.receiver ? { ...item.receiver } : null,\n      frequencyClass: airborneSignal?.frequency?.label || null,\n      modeledRadioHorizonKm: Number.isFinite(airborneSignal?.radioHorizonM)\n        ? airborneSignal.radioHorizonM / 1_000\n        : null,\n      observedReceiverDistanceKm: Number.isFinite(airborneSignal?.linkDistanceM)\n        ? airborneSignal.linkDistanceM / 1_000\n        : null,\n      freeSpacePathLossDb: Number.isFinite(airborneSignal?.freeSpacePathLossDb)\n        ? airborneSignal.freeSpacePathLossDb\n        : null,\n      signalVisualSemantics: field.semantics,\n      signalPattern: field.pattern,\n      signalRole: field.role,\n      wavelengthM: field.wavelengthM,\n      signalReferenceRadiusM: field.referenceRadiusM,\n      signalDisplayRadiusM: field.displayRadiusM,\n    };\n  }\n\n  _createEntry(item) {\n    const entry = {\n      item,\n      dir: latLonToLocalDir(item.lat, item.lon).normalize(),\n      position: new THREE.Vector3(),\n      stableRadius: null,\n      labelHandle: null,\n    };\n    this._positionEntry(entry);\n    const subText = [formatFrequency(item.frequencyHz), clean(item.band), clean(item.mode), clean(item.detail)]\n      .filter(Boolean).join(' · ');\n    const color = AIRBORNE_TYPES.has(item.type)\n      ? resolveRadiosondeFrequencyStyle(item.frequencyHz).color\n      : FEED_COLORS[item.feed];\n    entry.labelHandle = getLabelSystem().createLabel(clean(item.title) || TYPE_LABELS[item.type] || 'Radio', {\n      position: entry.position,\n      type: item.type,\n      color,\n      objectRadius: AIRBORNE_TYPES.has(item.type) ? 24 : 10,\n      subText,\n      occurredAt: item.observedAt || null,\n      recencyAnimated: ['radio-propagation', 'radiosonde', 'amateur-balloon'].includes(item.type),\n      metadata: this._metadata(item),\n      labelPriority: item.streamUrl || item.waterfallUrl ? 22 : 8,\n      maxDistance: this._surfaceMode\n        ? Math.min(this.radiusKm * 1_000, resolveSurfaceRadioDistanceLimitM(item))\n        : (AIRBORNE_TYPES.has(item.type) ? 1_500_000 : Math.max(120_000, this.radiusKm * 1_000)),\n    });\n    if (entry.labelHandle?.group) this.group.add(entry.labelHandle.group);\n    return entry;\n  }\n\n  _syncVisuals() {\n    const active = new Set();\n    for (const item of this._snapshot.items) {\n      if (!Number.isFinite(item?.lat) || !Number.isFinite(item?.lon) || !this.feeds[item.feed]) continue;\n      if (!shouldDisplayRadioItem(item, this._center, {\n        surfaceMode: this._surfaceMode,\n        radiusKm: this.radiusKm,\n      })) continue;\n      const id = clean(item.id);\n      if (!id) continue;\n      active.add(id);\n      const existing = this._entries.get(id);\n      if (!existing) {\n        this._entries.set(id, this._createEntry(item));\n        continue;\n      }\n      existing.item = item;\n      existing.dir.copy(latLonToLocalDir(item.lat, item.lon)).normalize();\n      this._positionEntry(existing);\n      if (existing.labelHandle) {\n        getLabelSystem().updateText(existing.labelHandle, clean(item.title), [formatFrequency(item.frequencyHz), clean(item.band), clean(item.mode), clean(item.detail)].filter(Boolean).join(' · '));\n        getLabelSystem().updateMetadata(existing.labelHandle, this._metadata(item));\n        existing.labelHandle.maxDistance = this._surfaceMode\n          ? Math.min(this.radiusKm * 1_000, resolveSurfaceRadioDistanceLimitM(item))\n          : (AIRBORNE_TYPES.has(item.type) ? 1_500_000 : Math.max(120_000, this.radiusKm * 1_000));\n      }\n    }\n    for (const [id, entry] of this._entries) {\n      if (active.has(id)) continue;\n      getLabelSystem().removeLabel?.(entry.labelHandle);\n      this._entries.delete(id);\n    }\n    this._syncPaths();\n    this._fieldBulbs.rebuild([...this._entries.values()]);\n    this._visualCenter = this._center ? { ...this._center } : null;\n    this.group.visible = this.enabled;\n  }\n\n  _syncPaths() {\n    for (const child of [...this._pathGroup.children]) {\n      this._pathGroup.remove(child);\n      child.geometry?.dispose?.();\n      child.material?.dispose?.();\n    }\n    // Reported TX/RX endpoints do not establish a ray path or ionospheric hop.\n    // Preserve them in the snapshot/details; normalized field bulbs own geometry.\n  }\n\n  refreshTerrainAnchors(changes) {\n    for (const entry of this._entries.values()) {\n      if (AIRBORNE_TYPES.has(entry.item.type)) continue;\n      if (!terrainSurfaceChangesAffectLatLon(changes, entry.item.lat, entry.item.lon)) continue;\n      this._positionEntry(entry);\n    }\n  }\n\n  update(deltaTime) {\n    this._fieldBulbs?.update?.(deltaTime);\n  }\n\n  getSnapshot() {\n    return {\n      ...this._snapshot,\n      items: this._snapshot.items.map((item) => ({\n        ...item,\n        receiver: item.receiver ? { ...item.receiver } : null,\n        metadata: { ...(item.metadata || {}) },\n      })),\n      paths: this._snapshot.paths.map((path) => ({ ...path })),\n      config: this.getConfig(),\n    };\n  }\n\n  clear() {\n    this._sequence += 1;\n    this._abort?.abort?.();\n    this._abort = null;\n    this._inflight = null;\n    for (const entry of this._entries.values()) getLabelSystem().removeLabel?.(entry.labelHandle);\n    this._entries.clear();\n    this._snapshot = { items: [], paths: [], providers: [], notices: [], generatedAt: null };\n    this._syncPaths();\n    this._fieldBulbs?.clear?.();\n    this.eventBus?.emit?.('radio:data', this.getSnapshot());\n  }\n\n  dispose() {\n    this.clear();\n    this._fieldBulbs?.dispose?.();\n    this.parentGroup?.remove?.(this.group);\n    this.sceneInitializer?.removeDepthPassExclude?.(this.group);\n  }\n}\n","import { getBackendApiBase } from '../shared/backend.js';\nimport { getNoclipGovernanceClient } from '../shared/NoclipGovernanceClient.js';\n\nexport const GEOCACHE_TYPES = Object.freeze([\n  'traditional', 'multi', 'quiz', 'moving', 'virtual', 'webcam', 'other', 'event', 'own', 'podcast',\n]);\nexport const GEOCACHE_STATUSES = Object.freeze([\n  'available', 'temporarily-unavailable', 'archived',\n]);\nexport const GEOCACHE_SIZES = Object.freeze([\n  'none', 'nano', 'micro', 'small', 'regular', 'large', 'xlarge', 'other',\n]);\n\nconst stableQuery = (params = {}) => {\n  const query = new URLSearchParams();\n  Object.entries(params)\n    .filter(([, value]) => value !== null && value !== undefined && value !== '')\n    .sort(([left], [right]) => left.localeCompare(right))\n    .forEach(([key, value]) => query.set(key, String(value)));\n  return query.toString();\n};\n\nconst supported = (values, allowlist) => {\n  const selected = Array.isArray(values) ? values : [];\n  return allowlist.filter((value) => selected.includes(value));\n};\n\nexport class GeocacheApiService {\n  constructor({ fetchImpl = null } = {}) {\n    const client = getNoclipGovernanceClient();\n    this._fetch = fetchImpl || client.request.bind(client);\n    this._cache = new Map();\n    this._inflight = new Map();\n  }\n\n  async _json(path, params = {}, ttlMs = 60_000, signal) {\n    if (!this._fetch) throw new Error('Fetch is unavailable');\n    const query = stableQuery(params);\n    const url = `${getBackendApiBase()}${path}${query ? `?${query}` : ''}`;\n    const cached = this._cache.get(url);\n    if (cached?.expiresAt > Date.now()) return cached.value;\n    if (this._inflight.has(url)) return this._inflight.get(url);\n    const request = this._fetch(url, {\n      signal,\n      governanceLane: 'scene',\n      headers: { Accept: 'application/json' },\n    }).then(async (response) => {\n      const payload = await response.json().catch(() => null);\n      if (!response.ok) throw new Error(payload?.message || `Geocache API returned HTTP ${response.status}`);\n      this._cache.set(url, { value: payload, expiresAt: Date.now() + ttlMs });\n      return payload;\n    }).finally(() => this._inflight.delete(url));\n    this._inflight.set(url, request);\n    return request;\n  }\n\n  contract({ signal } = {}) {\n    return this._json('/v1/geocaches/contract', {}, 24 * 60 * 60_000, signal);\n  }\n\n  scene({\n    lat,\n    lon,\n    radiusKm = 50,\n    limit = 150,\n    sources = [],\n    types = [],\n    statuses = ['available', 'temporarily-unavailable'],\n    sizes = [],\n    difficultyMin = 1,\n    difficultyMax = 5,\n    terrainMin = 1,\n    terrainMax = 5,\n    signal,\n  } = {}) {\n    return this._json('/v1/geocaches/scene', {\n      lat,\n      lon,\n      radiusKm: Math.max(1, Math.min(250, Number(radiusKm) || 50)),\n      limit: Math.max(1, Math.min(250, Math.round(Number(limit) || 150))),\n      sources: Array.isArray(sources) ? sources.filter(Boolean).join(',') : '',\n      types: supported(types, GEOCACHE_TYPES).join(','),\n      statuses: supported(statuses, GEOCACHE_STATUSES).join(','),\n      sizes: supported(sizes, GEOCACHE_SIZES).join(','),\n      difficultyMin,\n      difficultyMax,\n      terrainMin,\n      terrainMax,\n    }, 60_000, signal);\n  }\n\n  clear() {\n    this._cache.clear();\n  }\n}\n\nlet instance = null;\nexport function getGeocacheApiService() {\n  if (!instance) instance = new GeocacheApiService();\n  return instance;\n}\n","import * as THREE from 'three';\nimport { ellipsoidRadiusForLocalDir, latLonToLocalDir } from '../../modules/geometry-utils.js';\nimport { getLabelSystem } from '../labels/LabelSystem.js';\nimport { terrainSurfaceChangesAffectLatLon } from '../scene/TerrainSurfaceChange.js';\nimport {\n  GEOCACHE_SIZES,\n  GEOCACHE_STATUSES,\n  GEOCACHE_TYPES,\n  getGeocacheApiService,\n} from './GeocacheApiService.js';\n\nconst TYPE_COLORS = Object.freeze({\n  traditional: 0x22c55e,\n  multi: 0xf97316,\n  quiz: 0xa855f7,\n  moving: 0x38bdf8,\n  virtual: 0x06b6d4,\n  webcam: 0x60a5fa,\n  event: 0xef4444,\n  own: 0xfacc15,\n  podcast: 0xec4899,\n  other: 0xd4a72c,\n});\nconst RECORD_SIZES = Object.freeze([...GEOCACHE_SIZES, 'unknown']);\n\nconst clean = (value) => String(value ?? '').replace(/\\s+/g, ' ').trim();\nconst finite = (value) => {\n  if (value === null || value === undefined || String(value).trim() === '') return null;\n  return Number.isFinite(Number(value)) ? Number(value) : null;\n};\nconst list = (value, allowlist) => {\n  const selected = Array.isArray(value) ? value : [];\n  return allowlist.filter((item) => selected.includes(item));\n};\nconst rating = (value) => Number.isFinite(Number(value)) ? Number(value).toFixed(1) : '';\nconst titleCase = (value) => clean(value).replace(/(^|[-\\s])\\w/g, (match) => match.toUpperCase());\nconst integer = (value) => {\n  const parsed = finite(value);\n  return parsed === null ? null : Math.max(0, Math.round(parsed));\n};\nconst row = (label, value, href = '') => clean(value) ? { label, value: clean(value), ...(href ? { href } : {}) } : null;\n\nexport function normalizeGeocacheRecord(record = {}) {\n  const lat = finite(record.lat);\n  const lon = finite(record.lon);\n  const id = clean(record.id);\n  const name = clean(record.name);\n  const url = clean(record.url);\n  const attributionNote = clean(record.attributionNote);\n  if (!id || !name || !url || !attributionNote\n    || lat === null || lon === null || lat < -90 || lat > 90 || lon < -180 || lon > 180) return null;\n  const type = GEOCACHE_TYPES.includes(record.type) ? record.type : 'other';\n  const status = GEOCACHE_STATUSES.includes(record.status) ? record.status : 'archived';\n  const size = RECORD_SIZES.includes(record.size) ? record.size : 'unknown';\n  return {\n    ...record,\n    id,\n    name,\n    lat,\n    lon,\n    type,\n    typeLabel: clean(record.typeLabel) || titleCase(type),\n    status,\n    statusLabel: clean(record.statusLabel) || titleCase(status),\n    size,\n    code: clean(record.code),\n    sourceId: clean(record.sourceId),\n    sourceName: clean(record.sourceName),\n    url,\n    attributionNote,\n    difficulty: finite(record.difficulty),\n    terrain: finite(record.terrain),\n    distanceKm: finite(record.distanceKm),\n    recommendations: integer(record.recommendations),\n    foundCount: integer(record.foundCount),\n    notFoundCount: integer(record.notFoundCount),\n    trackablesCount: integer(record.trackablesCount),\n    needsMaintenance: record.needsMaintenance === true,\n  };\n}\n\nexport function buildGeocacheMetadata(record = {}) {\n  const item = normalizeGeocacheRecord(record);\n  if (!item) return null;\n  const details = [\n    row('Cache code', item.code),\n    row('Status', item.statusLabel),\n    row('Container', titleCase(item.size)),\n    row('Difficulty', rating(item.difficulty)),\n    row('Terrain', rating(item.terrain)),\n    row('Owner', item.ownerName, item.ownerUrl),\n    row('Description', item.shortDescription),\n    row('Finds', item.foundCount === null ? '' : String(item.foundCount)),\n    row('Did not find', item.notFoundCount === null ? '' : String(item.notFoundCount)),\n    row('Recommendations', item.recommendations === null ? '' : String(item.recommendations)),\n    row('Trackables', item.trackablesCount === null ? '' : String(item.trackablesCount)),\n    row('Maintenance', item.needsMaintenance ? 'Owner attention requested' : ''),\n    row('Hidden', item.hiddenAt),\n    row('Last found', item.lastFoundAt),\n    row('Region', item.region),\n    row('Attribution', item.attributionNote),\n  ].filter(Boolean);\n  return {\n    id: item.id,\n    entityType: 'geocache',\n    cacheType: item.type,\n    typeLabel: `${item.typeLabel} geocache`,\n    source: item.sourceName,\n    provider: item.sourceName,\n    sourceId: item.sourceId,\n    sourceUrl: item.url,\n    website: item.url,\n    websiteUrl: item.url,\n    country: clean(item.country),\n    lat: item.lat,\n    lon: item.lon,\n    detailRows: details,\n    attributionNote: item.attributionNote,\n  };\n}\n\nconst summaryText = (item) => [\n  item.typeLabel,\n  rating(item.difficulty) ? `D ${rating(item.difficulty)}` : '',\n  rating(item.terrain) ? `T ${rating(item.terrain)}` : '',\n  titleCase(item.size),\n  item.status === 'available' ? '' : item.statusLabel,\n].filter(Boolean).join(' · ');\n\nconst providerState = (payload) => {\n  const providers = Array.isArray(payload?.providers) ? payload.providers : [];\n  if (providers.length && providers.every((provider) => provider?.state === 'unconfigured')) return 'unconfigured';\n  if (payload?.partial === true) return 'partial';\n  return 'ready';\n};\n\nexport class GeocacheLayer {\n  constructor({\n    parentGroup,\n    surfaceController = null,\n    eventBus = null,\n    apiService = getGeocacheApiService(),\n    enabled = false,\n    radiusKm = 50,\n    maxItems = 150,\n    sources = [],\n    types = [],\n    statuses = ['available', 'temporarily-unavailable'],\n    sizes = [],\n    difficultyMin = 1,\n    difficultyMax = 5,\n    terrainMin = 1,\n    terrainMax = 5,\n  } = {}) {\n    this.parentGroup = parentGroup || null;\n    this.surfaceController = surfaceController;\n    this.eventBus = eventBus;\n    this.api = apiService;\n    this.enabled = enabled === true;\n    this.radiusKm = Math.max(1, Math.min(250, Number(radiusKm) || 50));\n    this.maxItems = Math.max(1, Math.min(250, Math.round(Number(maxItems) || 150)));\n    this.sources = Array.isArray(sources) ? sources.filter(Boolean) : [];\n    this.types = list(types, GEOCACHE_TYPES);\n    this.statuses = list(statuses, GEOCACHE_STATUSES);\n    this.sizes = list(sizes, GEOCACHE_SIZES);\n    this.difficultyMin = THREE.MathUtils.clamp(Number(difficultyMin) || 1, 1, 5);\n    this.difficultyMax = THREE.MathUtils.clamp(Number(difficultyMax) || 5, this.difficultyMin, 5);\n    this.terrainMin = THREE.MathUtils.clamp(Number(terrainMin) || 1, 1, 5);\n    this.terrainMax = THREE.MathUtils.clamp(Number(terrainMax) || 5, this.terrainMin, 5);\n    this.group = new THREE.Group();\n    this.group.name = 'GeocacheLayer';\n    this.group.visible = this.enabled;\n    this.parentGroup?.add?.(this.group);\n    this._entries = new Map();\n    this._snapshot = {\n      schema: 'noclip.geocaches.scene.v1', records: [], providers: [], count: 0,\n      partial: false, truncated: false, attribution: '', generatedAt: null, query: null,\n    };\n    this._center = null;\n    this._abort = null;\n    this._sequence = 0;\n    this._inflight = null;\n    this._tmpWorldDir = new THREE.Vector3();\n    this._tmpQuat = new THREE.Quaternion();\n    this._emitStatus(this.enabled ? 'idle' : 'disabled');\n  }\n\n  getConfig() {\n    return {\n      enabled: this.enabled,\n      radiusKm: this.radiusKm,\n      maxItems: this.maxItems,\n      sources: [...this.sources],\n      types: [...this.types],\n      statuses: [...this.statuses],\n      sizes: [...this.sizes],\n      difficultyMin: this.difficultyMin,\n      difficultyMax: this.difficultyMax,\n      terrainMin: this.terrainMin,\n      terrainMax: this.terrainMax,\n    };\n  }\n\n  applyConfig(config = {}) {\n    if (typeof config.enabled === 'boolean') this.enabled = config.enabled;\n    if (Number.isFinite(config.radiusKm)) this.radiusKm = Math.max(1, Math.min(250, config.radiusKm));\n    if (Number.isFinite(config.maxItems)) this.maxItems = Math.max(1, Math.min(250, Math.round(config.maxItems)));\n    if (Array.isArray(config.sources)) this.sources = config.sources.filter(Boolean);\n    if (Array.isArray(config.types)) this.types = list(config.types, GEOCACHE_TYPES);\n    if (Array.isArray(config.statuses)) this.statuses = list(config.statuses, GEOCACHE_STATUSES);\n    if (Array.isArray(config.sizes)) this.sizes = list(config.sizes, GEOCACHE_SIZES);\n    if (Number.isFinite(config.difficultyMin)) this.difficultyMin = THREE.MathUtils.clamp(config.difficultyMin, 1, 5);\n    if (Number.isFinite(config.difficultyMax)) this.difficultyMax = THREE.MathUtils.clamp(config.difficultyMax, this.difficultyMin, 5);\n    if (Number.isFinite(config.terrainMin)) this.terrainMin = THREE.MathUtils.clamp(config.terrainMin, 1, 5);\n    if (Number.isFinite(config.terrainMax)) this.terrainMax = THREE.MathUtils.clamp(config.terrainMax, this.terrainMin, 5);\n    this.group.visible = this.enabled;\n    if (!this.enabled) this.clear({ state: 'disabled' });\n    else if (this._center) void this.refresh({ force: true });\n    else this._emitStatus('idle');\n    this.eventBus?.emit?.('geocaches:data:config', this.getConfig());\n  }\n\n  setCenter(lat, lon, { force = false, refresh = true } = {}) {\n    if (!Number.isFinite(lat) || !Number.isFinite(lon)) return;\n    const moved = this._center\n      ? Math.hypot(\n        (lat - this._center.lat) * 111_000,\n        (lon - this._center.lon) * 111_000 * Math.cos(lat * Math.PI / 180),\n      )\n      : Infinity;\n    this._center = { lat, lon };\n    if (refresh && this.enabled && (force || moved >= 5_000 || !this._snapshot.generatedAt)) {\n      void this.refresh({ force: true });\n    }\n  }\n\n  async refresh({ force = false } = {}) {\n    if (!this.enabled || !this._center) return this.getSnapshot();\n    if (this._inflight) {\n      if (!force) return this._inflight;\n      const previous = this._inflight;\n      this._sequence += 1;\n      this._abort?.abort?.();\n      await previous;\n      if (!this.enabled || !this._center) return this.getSnapshot();\n    }\n    this._abort?.abort?.();\n    this._abort = new AbortController();\n    const sequence = ++this._sequence;\n    this._emitStatus('loading');\n    const request = this.api.scene({\n      ...this._center,\n      ...this.getConfig(),\n      limit: this.maxItems,\n      signal: this._abort.signal,\n    }).then((payload) => {\n      if (sequence !== this._sequence) return this.getSnapshot();\n      const records = (Array.isArray(payload?.records) ? payload.records : [])\n        .map(normalizeGeocacheRecord)\n        .filter(Boolean)\n        .slice(0, this.maxItems);\n      this._snapshot = {\n        schema: 'noclip.geocaches.scene.v1',\n        records,\n        providers: Array.isArray(payload?.providers) ? payload.providers.map((provider) => ({ ...provider })) : [],\n        count: records.length,\n        partial: payload?.partial === true,\n        truncated: payload?.truncated === true,\n        attribution: clean(payload?.attribution),\n        generatedAt: payload?.generatedAt || new Date().toISOString(),\n        query: payload?.query || null,\n      };\n      this._syncVisuals();\n      this.eventBus?.emit?.('geocaches:data', this.getSnapshot());\n      this._emitStatus(providerState(payload));\n      return this.getSnapshot();\n    }).catch((error) => {\n      if (error?.name !== 'AbortError' && sequence === this._sequence) {\n        this._emitStatus('error', { error: error?.message || String(error) });\n      }\n      return this.getSnapshot();\n    }).finally(() => {\n      if (sequence === this._sequence) {\n        this._abort = null;\n        this._inflight = null;\n      }\n    });\n    this._inflight = request;\n    return request;\n  }\n\n  _sampleSurface(entry) {\n    const ellipsoid = ellipsoidRadiusForLocalDir(entry.dir);\n    const sampler = this.surfaceController?.sampleTerrainRadiusForDir;\n    if (typeof sampler !== 'function') return { radius: ellipsoid, authoritative: false };\n    this._tmpWorldDir.copy(entry.dir);\n    this.parentGroup?.getWorldQuaternion?.(this._tmpQuat);\n    if (this.parentGroup?.getWorldQuaternion) this._tmpWorldDir.applyQuaternion(this._tmpQuat).normalize();\n    const requireFreshPhotoHit = !!this.surfaceController?.photoTileGroup;\n    const radius = sampler.call(this.surfaceController, this._tmpWorldDir, {\n      mutateCache: false,\n      requireFreshPhotoHit,\n      allowTriTreeFallback: !requireFreshPhotoHit,\n      skipWorldMatrixUpdate: true,\n    });\n    return Number.isFinite(radius) ? { radius, authoritative: true } : { radius: ellipsoid, authoritative: false };\n  }\n\n  _positionEntry(entry) {\n    const sample = this._sampleSurface(entry);\n    if (sample.authoritative || !Number.isFinite(entry.stableRadius)) entry.stableRadius = sample.radius;\n    entry.position.copy(entry.dir).multiplyScalar(entry.stableRadius + 8);\n    if (entry.labelHandle) getLabelSystem().updatePosition(entry.labelHandle, entry.position);\n  }\n\n  _createEntry(item) {\n    const entry = {\n      item,\n      dir: latLonToLocalDir(item.lat, item.lon).normalize(),\n      position: new THREE.Vector3(),\n      stableRadius: null,\n      labelHandle: null,\n    };\n    this._positionEntry(entry);\n    entry.labelHandle = getLabelSystem().createLabel(item.name, {\n      position: entry.position,\n      type: 'geocache',\n      color: TYPE_COLORS[item.type] || TYPE_COLORS.other,\n      objectRadius: 8,\n      subText: summaryText(item),\n      occurredAt: item.lastFoundAt || item.hiddenAt || null,\n      metadata: buildGeocacheMetadata(item),\n      labelPriority: item.status === 'available' ? 14 : 6,\n      maxDistance: Math.max(20_000, this.radiusKm * 1_000),\n    });\n    if (entry.labelHandle?.group) this.group.add(entry.labelHandle.group);\n    return entry;\n  }\n\n  _syncVisuals() {\n    const active = new Set();\n    for (const item of this._snapshot.records) {\n      active.add(item.id);\n      const existing = this._entries.get(item.id);\n      if (!existing) {\n        this._entries.set(item.id, this._createEntry(item));\n        continue;\n      }\n      if (existing.item.type !== item.type) {\n        getLabelSystem().removeLabel?.(existing.labelHandle);\n        this._entries.set(item.id, this._createEntry(item));\n        continue;\n      }\n      existing.item = item;\n      existing.dir.copy(latLonToLocalDir(item.lat, item.lon)).normalize();\n      this._positionEntry(existing);\n      if (existing.labelHandle) {\n        getLabelSystem().updateText(existing.labelHandle, item.name, summaryText(item));\n        getLabelSystem().updateMetadata(existing.labelHandle, buildGeocacheMetadata(item));\n        existing.labelHandle.maxDistance = Math.max(20_000, this.radiusKm * 1_000);\n      }\n    }\n    for (const [id, entry] of this._entries) {\n      if (active.has(id)) continue;\n      getLabelSystem().removeLabel?.(entry.labelHandle);\n      this._entries.delete(id);\n    }\n    this.group.visible = this.enabled;\n  }\n\n  refreshTerrainAnchors(changes) {\n    for (const entry of this._entries.values()) {\n      if (!terrainSurfaceChangesAffectLatLon(changes, entry.item.lat, entry.item.lon)) continue;\n      this._positionEntry(entry);\n    }\n  }\n\n  _emitStatus(state, extra = {}) {\n    const providers = this._snapshot.providers.map((provider) => ({ ...provider }));\n    this.eventBus?.emit?.('geocaches:status', {\n      state,\n      loadedCount: this._snapshot.records.length,\n      providers,\n      configuredProviders: providers.filter((provider) => provider.configured === true).length,\n      readyProviders: providers.filter((provider) => provider.ok === true).length,\n      partial: this._snapshot.partial,\n      truncated: this._snapshot.truncated,\n      generatedAt: this._snapshot.generatedAt,\n      attribution: this._snapshot.attribution,\n      ...extra,\n    });\n  }\n\n  getSnapshot() {\n    return {\n      ...this._snapshot,\n      records: this._snapshot.records.map((record) => ({ ...record })),\n      providers: this._snapshot.providers.map((provider) => ({ ...provider })),\n      config: this.getConfig(),\n    };\n  }\n\n  clear({ state = this.enabled ? 'idle' : 'disabled' } = {}) {\n    this._sequence += 1;\n    this._abort?.abort?.();\n    this._abort = null;\n    this._inflight = null;\n    for (const entry of this._entries.values()) getLabelSystem().removeLabel?.(entry.labelHandle);\n    this._entries.clear();\n    this._snapshot = {\n      schema: 'noclip.geocaches.scene.v1', records: [], providers: [], count: 0,\n      partial: false, truncated: false, attribution: '', generatedAt: null, query: null,\n    };\n    this.eventBus?.emit?.('geocaches:data', this.getSnapshot());\n    this._emitStatus(state);\n  }\n\n  dispose() {\n    this.clear({ state: 'disabled' });\n    this.parentGroup?.remove?.(this.group);\n  }\n}\n","/**\n * AddressHoverOverlay — terrain-mated building footprint for address picks.\n *\n * A deliberate pick creates an immediate terrain-mated footprint selection.\n * Once local building or Overpass geometry arrives, the temporary selection\n * is atomically replaced by translucent walls that trace the real footprint.\n */\nimport * as THREE from 'three';\nimport { latLonToLocalDir, ellipsoidRadiusForLocalDir } from '../../modules/geometry-utils.js';\nimport { PLANET_RADIUS } from '../../modules/constants.js';\nimport { getLabelSystem } from '../labels/LabelSystem.js';\nimport { buildingFootprintContains } from '../geo/BuildingFootprint.js';\nimport {\n  DEFAULT_INCIDENT_SPIRE_HEIGHT_M,\n  SurfaceFootprintMarker,\n  normalizeSurfaceFootprint,\n} from './SurfaceFootprintMarker.js';\n\nconst TARGET_COLOR = new THREE.Color('#facc15');\n// A pinned target moves from the NCLP telemetry yellow to the ready/confirmed\n// state, matching the rest of the operator UI.\nconst TARGET_COLOR_PINNED = new THREE.Color('#8ef6c8');\nconst TARGET_LEADER_COLOR = new THREE.Color('#facc15');\nconst TARGET_LEADER_GROUND_OFFSET_M = 2;\nconst TARGET_LEADER_MIN_HEIGHT_M = 6;\nconst TARGET_LEADER_MAX_HEIGHT_M = 72;\nconst TARGET_LEADER_MAX_DISTANCE_RATIO = 0.18;\nconst TARGET_LABEL_MIN_OFFSET_M = 4;\nconst TARGET_LABEL_MAX_OFFSET_M = 12;\nconst TARGET_FOOTPRINT_EMBED_M = 1.75;\nconst TARGET_FALLBACK_FOOTPRINT_SIZE_M = 18;\nconst BUILDING_GEOMETRY_TYPES = new Set([\n  'apartments',\n  'building',\n  'commercial',\n  'detached',\n  'garage',\n  'house',\n  'industrial',\n  'office',\n  'residential',\n  'retail',\n  'school',\n  'warehouse',\n  'yes',\n]);\n\nexport function resolveBuildingQualifiedGeoJson(data) {\n  if (normalizeSurfaceFootprint(data?.geojson).length < 3) return null;\n  const category = String(data?.category || '').trim().toLowerCase();\n  const type = String(data?.type || data?.addressType || '').trim().toLowerCase();\n  if (category !== 'building' && !BUILDING_GEOMETRY_TYPES.has(type)) return null;\n  return data.geojson;\n}\n\n/**\n * Resolve a surface-leader height against the camera's centre/focal ray.\n *\n * The leader's top is the closest point on the surface-normal line to the\n * camera's centre ray. That makes a target's leader terminate close to the\n * visual focal point instead of giving every target the same, often towering,\n * world-space height. The cap scales with camera distance so it stays useful\n * at a distance while remaining restrained in surface mode.\n *\n * `scratch` is optional for tests and required by the per-frame caller to\n * avoid allocations in the render loop.\n */\nexport function deriveLeaderHeightFromCameraFocalPoint(camera, baseWorld, surfaceNormal, {\n  minHeight = TARGET_LEADER_MIN_HEIGHT_M,\n  maxHeight = TARGET_LEADER_MAX_HEIGHT_M,\n  maxDistanceRatio = TARGET_LEADER_MAX_DISTANCE_RATIO,\n  scratch = null,\n} = {}) {\n  const min = Math.max(0, Number(minHeight) || 0);\n  const absoluteMax = Math.max(min, Number(maxHeight) || min);\n  if (!camera || !baseWorld?.isVector3 || !surfaceNormal?.isVector3) return min;\n\n  const cameraPos = scratch?.cameraPos || new THREE.Vector3();\n  const cameraForward = scratch?.cameraForward || new THREE.Vector3();\n  const toBase = scratch?.toBase || new THREE.Vector3();\n  const normal = scratch?.normal || new THREE.Vector3();\n\n  if (typeof camera.getWorldPosition === 'function') camera.getWorldPosition(cameraPos);\n  else cameraPos.copy(camera.userData?.worldPosition || camera.position || new THREE.Vector3());\n  if (!Number.isFinite(cameraPos.x) || !Number.isFinite(cameraPos.y) || !Number.isFinite(cameraPos.z)) return min;\n\n  if (typeof camera.getWorldDirection === 'function') camera.getWorldDirection(cameraForward);\n  else cameraForward.set(0, 0, -1).applyQuaternion(camera.quaternion || new THREE.Quaternion());\n  if (cameraForward.lengthSq() < 1e-10) return min;\n  cameraForward.normalize();\n\n  normal.copy(surfaceNormal);\n  if (normal.lengthSq() < 1e-10) return min;\n  normal.normalize();\n  toBase.copy(baseWorld).sub(cameraPos);\n\n  // Closest points between L(h) = base + h·normal and the positive camera\n  // focal ray R(t) = camera + t·forward. Solving the two orthogonality\n  // equations gives h below; it is stable except when line and ray are\n  // effectively parallel, which falls back to the compact minimum leader.\n  const normalForward = normal.dot(cameraForward);\n  const denominator = 1 - normalForward * normalForward;\n  if (denominator <= 1e-5) return min;\n  const forwardBase = cameraForward.dot(toBase);\n  const normalBase = normal.dot(toBase);\n  const focalHeight = (forwardBase * normalForward - normalBase) / denominator;\n  const focalDepth = forwardBase + focalHeight * normalForward;\n  if (!Number.isFinite(focalHeight) || focalHeight < 0 || focalDepth <= 0) return min;\n\n  const targetDistance = cameraPos.distanceTo(baseWorld);\n  const distanceCap = Number.isFinite(targetDistance)\n    ? Math.max(min, Math.min(absoluteMax, targetDistance * Math.max(0, maxDistanceRatio)))\n    : absoluteMax;\n  return THREE.MathUtils.clamp(focalHeight, min, distanceCap);\n}\n\n/** A small physical leader, bounded by camera height rather than a fixed tower. */\nexport function deriveSelectionSpireHeight(camera, baseWorld, normal, { viewportHeight = globalThis.innerHeight || 800, cameraHeight, scratch = {} } = {}) {\n  if (!camera || !baseWorld || !normal) return 1.5;\n  const cameraPos = scratch.cameraPos || new THREE.Vector3();\n  const delta = scratch.toBase || new THREE.Vector3();\n  camera.getWorldPosition(cameraPos); delta.copy(cameraPos).sub(baseWorld);\n  const distance = delta.length(); if (!(distance > 0)) return 1.5;\n  const altitude = Math.max(0,Number.isFinite(cameraHeight)?cameraHeight:delta.dot(normal));\n  const projectedUp = Math.sqrt(Math.max(0,1 - (delta.dot(normal)/distance)**2));\n  const metersPerPixel = 2*distance*Math.tan(THREE.MathUtils.degToRad(camera.fov || 60)*.5)/Math.max(1,viewportHeight);\n  return THREE.MathUtils.clamp(14*metersPerPixel/Math.max(.25,projectedUp),1.5,Math.min(160,2+altitude*.025));\n}\n\nfunction formatRouteDistance(meters) {\n  if (!Number.isFinite(meters) || meters <= 0) return '';\n  if (meters < 1000) return `${Math.round(meters)}m`;\n  const km = meters / 1000;\n  return km < 10 ? `${km.toFixed(1)}km` : `${Math.round(km)}km`;\n}\n\nfunction formatRouteDuration(seconds) {\n  if (!Number.isFinite(seconds) || seconds <= 0) return '';\n  const mins = Math.max(1, Math.round(seconds / 60));\n  if (mins < 60) return `${mins}m`;\n  const hours = Math.floor(mins / 60);\n  const rem = mins % 60;\n  return rem ? `${hours}h ${String(rem).padStart(2, '0')}m` : `${hours}h`;\n}\n\nexport class AddressHoverOverlay {\n  constructor({\n    parentGroup,\n    surfaceController,\n    eventBus,\n    buildingResolver,\n    footprintResolver = null,\n    spireHeightM = DEFAULT_INCIDENT_SPIRE_HEIGHT_M,\n  }) {\n    this.parentGroup = parentGroup || null;\n    this.eventBus = eventBus || null;\n    this._surfaceController = surfaceController || null;\n    this._buildingResolver = typeof buildingResolver === 'function' ? buildingResolver : null;\n    this._footprintResolver = footprintResolver;\n    this._footprintHeightM = this._normalizeSpireHeight(spireHeightM);\n\n    this.group = new THREE.Group();\n    this.group.name = 'AddressHoverOverlay';\n    if (this.parentGroup) this.parentGroup.add(this.group);\n\n    this._leaderMat = new THREE.LineBasicMaterial({\n      color: TARGET_LEADER_COLOR,\n      transparent: true,\n      opacity: 0.72,\n      depthWrite: false,\n      depthTest: false,\n    });\n\n    this._leaderLine = null;\n    this._footprintMarker = null;\n    this._footprintGeojson = null;\n    this._footprintRequestSeq = 0;\n    this._footprintRequestController = null;\n    this._footprintRequestTask = null;\n    this._eventUnsubscribers = [];\n    this._labelHandle = null;\n    this._losStatusText = '';\n    this._routeStatusText = '';\n    this._labelBaseText = '';\n    this._labelBaseSubText = '';\n    this._currentLat = null;\n    this._currentLon = null;\n    this._exactSurfaceSelection = false;\n    // When the toast is pinned (user clicked), the leader stays standing\n    // and its colour swaps from white to accent-teal. `_persisted`\n    // short-circuits hover:clear and subsequent hover events so the\n    // selected target doesn't get stolen by cursor drift.\n    this._persisted = false;\n    this._tmpQuat = new THREE.Quaternion();\n    this._targetDir = new THREE.Vector3();\n    this._targetSurfaceRadius = null;\n    this._targetBasePos = new THREE.Vector3();\n    this._targetTopPos = new THREE.Vector3();\n    this._targetLabelPos = new THREE.Vector3();\n    this._tmpBaseWorld = new THREE.Vector3();\n    this._tmpWorldNormal = new THREE.Vector3();\n    this._focalScratch = {\n      cameraPos: new THREE.Vector3(),\n      cameraForward: new THREE.Vector3(),\n      toBase: new THREE.Vector3(),\n      normal: new THREE.Vector3(),\n    };\n\n    this._wireEvents();\n  }\n\n  _normalizeSpireHeight(heightM) {\n    return THREE.MathUtils.clamp(\n      Number(heightM) || DEFAULT_INCIDENT_SPIRE_HEIGHT_M,\n      5,\n      300,\n    );\n  }\n\n  setSpireHeightM(heightM) {\n    const next = this._normalizeSpireHeight(heightM);\n    if (Math.abs(next - this._footprintHeightM) < 1e-6) return false;\n    this._footprintHeightM = next;\n    this._updateTargetLeaderGeometry();\n    return true;\n  }\n\n  _wireEvents() {\n    if (!this.eventBus) return;\n    const on = (event, handler) => {\n      const unsubscribe = this.eventBus.on(event, handler);\n      this._eventUnsubscribers.push(typeof unsubscribe === 'function'\n        ? unsubscribe : () => this.eventBus.off?.(event, handler));\n    };\n\n    // Incident settings own the shared surface-marker height. A selected\n    // building/location follows the same runtime value instead of retaining a\n    // separate towering constant.\n    on('incidents:config', (config = {}) => {\n      const heightM = Number.isFinite(config.spireHeightM)\n        ? config.spireHeightM\n        : config.markerScaleM;\n      if (Number.isFinite(heightM)) this.setSpireHeightM(heightM);\n    });\n\n    // Geocoded address resolved from the canonical Mapsource lookup.\n    on('address:resolved', (data) => {\n      const samePinnedTarget = this._persisted\n        && Number.isFinite(this._currentLat)\n        && Number.isFinite(this._currentLon)\n        && Math.abs(Number(data?.lat) - this._currentLat) < 1e-7\n        && Math.abs(Number(data?.lon) - this._currentLon) < 1e-7;\n      if (!samePinnedTarget) return;\n      if (data?.lat != null && data?.lon != null) {\n        this._showTargetLeader(data.lat, data.lon, data.name || data.address?.split(',')[0] || 'Address', {\n          ...data,\n          entityType: data.category === 'commercial' ? 'business' : 'address',\n          typeLabel: data.category === 'commercial' ? 'Business' : 'Surface Target',\n        });\n        const geocodedFootprint = resolveBuildingQualifiedGeoJson(data);\n        if (geocodedFootprint) {\n          this._showFootprint(data.lat, data.lon, geocodedFootprint, 'geocoder-building');\n        } else {\n          this._requestFootprint(data.lat, data.lon);\n        }\n      }\n    });\n\n    // Building footprint polygon arrived (async upgrade from Overpass)\n    on('address:footprint', (data) => {\n      if (!this._persisted) return;\n      if (data?.geojson && data?.lat != null) {\n        this._showFootprint(data.lat, data.lon, data.geojson, 'overpass');\n        if (this._persisted) this._setTargetColor(TARGET_COLOR_PINNED);\n      }\n    });\n\n    on('building:hover:clear', () => {\n      if (this._persisted) return; // pinned target stays standing\n      this._hideTargetLeader();\n    });\n\n    // Pin → persist + swap to teal + append LOS status to the label.\n    // If no leader exists yet (e.g. toast was pinned from a minimap click\n    // rather than a scene hover), synthesise one at the pin target so the\n    // user gets the teal marker without needing to hover-first.\n    on('address:pin', (data) => {\n      const tLat = Number(data?.targetLat);\n      const tLon = Number(data?.targetLon);\n      const exactSurfaceRadius = Number(data?.surfaceRadius ?? data?.surfaceRadiusM);\n      const hasExactPhotoAnchor = data?.surfaceSource === 'photo'\n        && Number.isFinite(exactSurfaceRadius)\n        && exactSurfaceRadius > 0;\n      const sameLeaderTarget = Number.isFinite(this._currentLat)\n        && Number.isFinite(this._currentLon)\n        && Math.abs(tLat - this._currentLat) < 1e-7\n        && Math.abs(tLon - this._currentLon) < 1e-7;\n      this._persisted = true;\n      // Even if hover rounded to the same lat/lon, rebuild from an explicit\n      // click's mesh radius. Hover geometry may have been sampled radially or\n      // attached to a nearby building centroid.\n      if (hasExactPhotoAnchor) this._clearFootprint();\n      if ((!sameLeaderTarget || hasExactPhotoAnchor)\n        && Number.isFinite(tLat) && Number.isFinite(tLon)) {\n        this._showTargetLeader(tLat, tLon, data.name || data.address || 'Pinned', {\n          ...data,\n          lat: tLat,\n          lon: tLon,\n          entityType: data.category === 'commercial' ? 'business' : 'address',\n          typeLabel: data.category === 'commercial' ? 'Business' : 'Surface Target',\n        });\n      }\n      this._requestFootprint(tLat, tLon);\n      if (this._labelHandle) this._labelHandle.labelPriority = 100;\n      this._setTargetColor(TARGET_COLOR_PINNED);\n      this._setRouteStatus('');\n      this._setLosStatus(data?.playerLat != null && data?.targetLat != null ? data.distance : '');\n    });\n    on('address:route', (data) => {\n      if (!this._persisted) return;\n      if (data?.status === 'loading') {\n        this._setRouteStatus('Drive calculating');\n        return;\n      }\n      if (data?.status === 'ready') {\n        const dist = formatRouteDistance(Number(data.route?.distance ?? data.distance));\n        const eta = formatRouteDuration(Number(data.route?.duration ?? data.duration));\n        const drive = ['Drive', dist, eta ? `ETA ${eta}` : ''].filter(Boolean).join(' ');\n        this._setRouteStatus(drive);\n        return;\n      }\n      if (data?.status === 'unavailable') {\n        this._setRouteStatus('Drive unavailable');\n      }\n    });\n    // Unpin → revert colour, drop persist, hide.\n    on('address:unpin', () => {\n      this._persisted = false;\n      this._setTargetColor(TARGET_COLOR);\n      this._hideTargetLeader();\n      this._clearTargetStatus();\n    });\n  }\n\n  /**\n   * Recolour the active target leader.\n   */\n  _setTargetColor(color) {\n    if (!color) return;\n    const c = color instanceof THREE.Color ? color : new THREE.Color(color);\n    if (this._leaderLine?.material?.color) {\n      this._leaderLine.material.color.copy(c);\n    }\n    this._footprintMarker?.setColor(c);\n  }\n\n  _getTerrainRadius(localDir) {\n    // Use surfaceController with mutateCache:false to avoid contaminating\n    // the camera's terrain clamp state (which would cause camera altitude jumps).\n    if (this._surfaceController?.sampleTerrainRadiusForDir) {\n      const worldDir = localDir.clone();\n      if (this.parentGroup?.getWorldQuaternion) {\n        this.parentGroup.getWorldQuaternion(this._tmpQuat);\n        worldDir.applyQuaternion(this._tmpQuat).normalize();\n      }\n      const r = this._surfaceController.sampleTerrainRadiusForDir(worldDir, { mutateCache: false });\n      if (Number.isFinite(r) && r > 0) return r;\n    }\n    return ellipsoidRadiusForLocalDir(localDir);\n  }\n\n  _resolveLocalBuildingFootprint(lat, lon) {\n    let building = null;\n    try {\n      building = this._buildingResolver?.(lat, lon) || null;\n    } catch {\n      return null;\n    }\n    return building?.footprint?.length >= 3\n      ? { latLonPairs: building.footprint }\n      : null;\n  }\n\n  // ── Surface target leader (thin vertical line + LabelSystem label) ──\n\n  _getFocalLeaderHeight(basePos, localSurfaceNormal) {\n    const camera = this._surfaceController?.camera;\n    if (!camera || !basePos || !localSurfaceNormal) return 1.5;\n\n    // The address overlay lives in the rotating planet group while the camera\n    // is in world space. Compute the focal solution in world coordinates, then\n    // apply the resulting scalar height back along the local surface normal.\n    const baseWorld = this.group.localToWorld(this._tmpBaseWorld.copy(basePos));\n    const worldNormal = this._tmpWorldNormal.copy(localSurfaceNormal);\n    this.group.getWorldQuaternion(this._tmpQuat);\n    worldNormal.applyQuaternion(this._tmpQuat).normalize();\n    // Surface AGL belongs to the navigation owner. Height above a distant\n    // target plane includes terrain relief and Earth curvature, so it cannot\n    // determine whether the observer is standing on the ground.\n    const controller=this._surfaceController;\n    const cameraHeight=controller.cameraMode==='surface'\n      ? controller.getSurfaceAltitudeMeters?.() ?? controller.surfaceAltitudeMeters\n      : undefined;\n    return deriveSelectionSpireHeight(camera,baseWorld,worldNormal,{cameraHeight,scratch:this._focalScratch});\n  }\n\n  _updateTargetLeaderGeometry() {\n    if (!this._leaderLine || !Number.isFinite(this._targetSurfaceRadius)) return;\n\n    if (this._footprintMarker?.isTerrainMated()) {\n      this._targetBasePos.copy(this._targetDir).multiplyScalar(this._footprintMarker.centerRadius);\n      this._footprintMarker.setHeight(this._getFocalLeaderHeight(this._targetBasePos,this._targetDir));\n      this._leaderLine.visible = false;\n      this._targetSurfaceRadius = this._footprintMarker.centerRadius;\n      if (this._footprintMarker.getTopPosition(this._targetLabelPos, .15)\n        && this._labelHandle) {\n        getLabelSystem({ planetRadius: PLANET_RADIUS })\n          .updatePosition(this._labelHandle, this._targetLabelPos);\n      }\n      return;\n    }\n    // Surface picks are represented by projected footprint geometry.  Keep\n    // the legacy line object hidden while an accurate footprint is resolving;\n    // a line floating above the click point conveys no area or address.\n    this._leaderLine.visible = false;\n    const baseRadius = this._targetSurfaceRadius + TARGET_LEADER_GROUND_OFFSET_M;\n    this._targetBasePos.copy(this._targetDir).multiplyScalar(baseRadius);\n    const leaderHeight = this._getFocalLeaderHeight(this._targetBasePos, this._targetDir);\n    const labelOffset = THREE.MathUtils.clamp(\n      leaderHeight * 0.2,\n      TARGET_LABEL_MIN_OFFSET_M,\n      TARGET_LABEL_MAX_OFFSET_M,\n    );\n    this._targetTopPos.copy(this._targetDir).multiplyScalar(baseRadius + leaderHeight);\n    this._targetLabelPos.copy(this._targetDir).multiplyScalar(baseRadius + leaderHeight + labelOffset);\n\n    const posAttr = this._leaderLine.geometry.attributes.position;\n    posAttr.setXYZ(0, this._targetBasePos.x, this._targetBasePos.y, this._targetBasePos.z);\n    posAttr.setXYZ(1, this._targetTopPos.x, this._targetTopPos.y, this._targetTopPos.z);\n    posAttr.needsUpdate = true;\n    this._leaderLine.geometry.computeBoundingSphere();\n\n    if (this._labelHandle) {\n      getLabelSystem({ planetRadius: PLANET_RADIUS }).updatePosition(this._labelHandle, this._targetLabelPos);\n    }\n  }\n\n  /** Keep an active hover/pinned marker attached to the moving camera focus. */\n  update() {\n    if (!Number.isFinite(this._targetSurfaceRadius)) return;\n    this._footprintMarker?.update?.();\n    // The old leader is deliberately invisible. Keep only a terrain-mated\n    // marker's label attached here; tile replacement events perform the actual\n    // contact-plane refresh through refreshTerrainAnchors().\n    if (this._footprintMarker?.isTerrainMated()) this._updateTargetLeaderGeometry();\n  }\n\n  _showTargetLeader(lat, lon, label, metadata = {}) {\n    const locationChanged = !Number.isFinite(this._currentLat)\n      || !Number.isFinite(this._currentLon)\n      || Math.abs(lat - this._currentLat) > 1e-7\n      || Math.abs(lon - this._currentLon) > 1e-7;\n    this._currentLat = lat;\n    this._currentLon = lon;\n    const dir = latLonToLocalDir(lat, lon);\n    const retainedExactAnchor = !locationChanged && this._exactSurfaceSelection;\n    const exactSurfaceRadius = Number(metadata.surfaceRadius ?? metadata.surfaceRadiusM\n      ?? (retainedExactAnchor ? this._targetSurfaceRadius : NaN));\n    const hasExactPhotoAnchor = (metadata.surfaceSource === 'photo' || retainedExactAnchor)\n      && Number.isFinite(exactSurfaceRadius)\n      && exactSurfaceRadius > 0;\n    this._exactSurfaceSelection = hasExactPhotoAnchor;\n    const surfaceR = hasExactPhotoAnchor\n      ? exactSurfaceRadius\n      : this._getTerrainRadius(dir);\n    this._targetDir.copy(dir).normalize();\n    this._targetSurfaceRadius = surfaceR;\n\n    if (locationChanged) {\n      this._clearFootprint();\n      this._clearTargetStatus();\n    }\n\n    const localFootprint = hasExactPhotoAnchor\n      ? null\n      : this._resolveLocalBuildingFootprint(lat, lon);\n    if (localFootprint) {\n      this._showFootprint(lat, lon, localFootprint, 'building-overlay');\n    } else {\n      this._ensureFallbackFootprint(lat, lon, {\n        anchorRadius: hasExactPhotoAnchor ? exactSurfaceRadius : null,\n        anchorSource: hasExactPhotoAnchor ? 'photoreal-screen-hit' : '',\n      });\n    }\n\n    if (!this._leaderLine) {\n      const geo = new THREE.BufferGeometry();\n      geo.setAttribute('position', new THREE.Float32BufferAttribute(new Float32Array(6), 3));\n      this._leaderLine = new THREE.Line(geo, this._leaderMat.clone());\n      this._leaderLine.name = 'AddressTargetLeader';\n      this._leaderLine.renderOrder = 24;\n      this._leaderLine.frustumCulled = false;\n      this.group.add(this._leaderLine);\n    }\n\n    this._leaderLine.visible = false;\n    this._updateTargetLeaderGeometry();\n\n    const ls = getLabelSystem({ planetRadius: PLANET_RADIUS });\n    const labelMetadata = {\n      entityType: 'address',\n      typeLabel: 'Surface Target',\n      ...metadata,\n      occlusionPolicy: 'hide',\n      geojson: this._footprintGeojson || metadata.geojson || null,\n      name: metadata.name || label,\n      lat,\n      lon,\n    };\n    this._labelBaseText = label || 'Surface Target';\n    this._labelBaseSubText = metadata.address || metadata.meta || '';\n\n    if (this._labelHandle) {\n      this._labelHandle.labelPriority = this._persisted ? 100 : 20;\n      ls.updatePosition(this._labelHandle, this._targetLabelPos);\n      ls.updateMetadata?.(this._labelHandle, labelMetadata);\n    } else {\n      this._labelHandle = ls.createLabel(this._labelBaseText, {\n        position: this._targetLabelPos,\n        type: 'geojson',\n        color: TARGET_COLOR.getHex(),\n        objectRadius: 1,\n        subText: this._labelBaseSubText,\n        metadata: labelMetadata,\n        labelPriority: this._persisted ? 100 : 20,\n      });\n      if (this._labelHandle?.group) this.group.add(this._labelHandle.group);\n    }\n    this._refreshTargetLabelText();\n  }\n\n  _refreshTargetLabelText() {\n    if (!this._labelHandle) return;\n    const ls = getLabelSystem({ planetRadius: PLANET_RADIUS });\n    const subText = [this._labelBaseSubText, this._losStatusText, this._routeStatusText]\n      .map((part) => String(part || '').trim())\n      .filter(Boolean)\n      .join(' · ');\n    ls.updateText(this._labelHandle, this._labelBaseText || 'Surface Target', subText);\n  }\n\n  // ── Terrain-mated building footprint ──\n\n  _ensureFallbackFootprint(lat, lon, {\n    anchorRadius = null,\n    anchorSource = '',\n  } = {}) {\n    if (this._footprintMarker?.source === 'building-overlay'\n      || this._footprintMarker?.source === 'geocoder-building'\n      || this._footprintMarker?.source === 'overpass') return;\n    if (this._footprintMarker?.source === 'resolving') {\n      this._footprintMarker.refreshTerrain();\n      return;\n    }\n    const marker = new SurfaceFootprintMarker({\n      parentGroup: this.group,\n      presentation: 'selection',\n      surfaceController: this._surfaceController,\n      color: this._persisted ? TARGET_COLOR_PINNED : TARGET_COLOR,\n      heightM: 1.5,\n      embedM: TARGET_FOOTPRINT_EMBED_M,\n      opacity: 0.12,\n      outlineOpacity: 0.24,\n      renderOrder: 24,\n      name: 'AddressSurfaceSelection',\n      lightChannel: 'surface-selection',\n      lightPriority: 155,\n      lightRadiusM: 175,\n      lightIntensityScale: 1.55,\n      lightPulseHz: 0.82,\n    });\n    if (!marker.setResolvingSpire(lat, lon, {\n      radiusM: 1,\n      anchorRadius,\n      anchorSource,\n    })) {\n      marker.dispose();\n      return;\n    }\n    this._footprintMarker = marker;\n  }\n\n  _showFootprint(lat, lon, geojson, source = 'overpass') {\n    if (!Number.isFinite(this._currentLat) || !Number.isFinite(this._currentLon)) return;\n    if (Math.abs(lat - this._currentLat) > 1e-7 || Math.abs(lon - this._currentLon) > 1e-7) return;\n    // An exact screen pick may grow into its containing building, never a\n    // nearby reverse-geocoder result. The existing marker retains its locked\n    // click origin/radius during the morph and later metadata enrichment.\n    if (this._exactSurfaceSelection && !buildingFootprintContains(geojson, lat, lon)) return;\n    if (this._footprintMarker && this._footprintMarker.source !== 'resolving') return;\n    if (this._footprintMarker?.source === 'resolving'\n      && this._footprintMarker.transitionToFootprint(geojson, {\n        lat,\n        lon,\n        source,\n      })) {\n      this._footprintMarker.setColor(\n        this._persisted ? TARGET_COLOR_PINNED : TARGET_COLOR,\n      );\n      this._footprintMarker.setOpacity(0.12, 0.24);\n      this._footprintMarker.setVisible(true);\n      this._rememberFootprint(geojson);\n      this._updateTargetLeaderGeometry();\n      return;\n    }\n    this._clearFootprint();\n    const marker = new SurfaceFootprintMarker({\n      parentGroup: this.group,\n      presentation: 'selection',\n      surfaceController: this._surfaceController,\n      color: this._persisted ? TARGET_COLOR_PINNED : TARGET_COLOR,\n      heightM: 1.5,\n      embedM: TARGET_FOOTPRINT_EMBED_M,\n      opacity: 0.12,\n      outlineOpacity: 0.24,\n      renderOrder: 24,\n      name: 'AddressBuildingFootprint',\n      lightChannel: 'surface-selection',\n      lightPriority: 150,\n      lightRadiusM: 175,\n      lightIntensityScale: 1.5,\n      lightPulseHz: 0.72,\n    });\n    if (!marker.setFootprint(geojson, { lat, lon, source })) {\n      marker.dispose();\n      return;\n    }\n    this._footprintMarker = marker;\n    this._rememberFootprint(geojson);\n    this._updateTargetLeaderGeometry();\n  }\n\n  _rememberFootprint(geojson) {\n    this._footprintGeojson = geojson;\n    if (this._labelHandle) getLabelSystem({ planetRadius: PLANET_RADIUS }).updateMetadata(\n      this._labelHandle, { ...this._labelHandle.metadata, geojson },\n    );\n    const toast = typeof window !== 'undefined' ? window.__noclipAddressToast : null;\n    if (Math.abs(Number(toast?._current?.lat) - this._currentLat) < 1e-7\n      && Math.abs(Number(toast?._current?.lon) - this._currentLon) < 1e-7) {\n      toast._current.geojson = geojson;\n    }\n  }\n\n  _clearFootprint() {\n    this._footprintRequestSeq += 1;\n    this._footprintRequestController?.abort();\n    this._footprintRequestController = null;\n    this._footprintRequestTask = null;\n    this._footprintMarker?.dispose();\n    this._footprintMarker = null;\n    this._footprintGeojson = null;\n  }\n\n  _requestFootprint(lat, lon) {\n    if (!Number.isFinite(Number(lat)) || !Number.isFinite(Number(lon))) return;\n    if (this._footprintRequestTask) return this._footprintRequestTask;\n    if (this._footprintMarker?.source === 'building-overlay'\n      || this._footprintMarker?.source === 'geocoder-building'\n      || this._footprintMarker?.source === 'overpass') return;\n    const seq = ++this._footprintRequestSeq;\n    const controller = new AbortController();\n    this._footprintRequestController = controller;\n    const requireContaining = this._exactSurfaceSelection;\n    this._footprintRequestTask = Promise.resolve(this._footprintResolver)\n      .then(resolver => resolver || import('../../modules/geocoding-service.js').then(m => m.fetchBuildingFootprint))\n      .then(resolver => {\n        if (controller.signal.aborted || seq !== this._footprintRequestSeq) return null;\n        return resolver(Number(lat), Number(lon), { signal: controller.signal, requireContaining });\n      })\n      .then((footprint) => {\n        if (!footprint || controller.signal.aborted || seq !== this._footprintRequestSeq) return;\n        this._showFootprint(Number(lat), Number(lon), footprint, 'overpass');\n      })\n      .catch(() => {});\n    return this._footprintRequestTask;\n  }\n\n  refreshTerrainAnchors(changes) {\n    if (!this._footprintMarker?.refreshTerrain(changes)) return 0;\n    this._targetSurfaceRadius = this._footprintMarker.centerRadius;\n    this._updateTargetLeaderGeometry();\n    return 1;\n  }\n\n  _hideTargetLeader() {\n    if (this._leaderLine) {\n      this._leaderLine.geometry?.dispose();\n      this._leaderLine.material?.dispose();\n      this.group.remove(this._leaderLine);\n      this._leaderLine = null;\n    }\n    this._clearFootprint();\n    if (this._labelHandle) {\n      if (this._labelHandle.group?.parent) this._labelHandle.group.parent.remove(this._labelHandle.group);\n      this._labelHandle.dispose?.();\n      this._labelHandle = null;\n    }\n    this._labelBaseText = '';\n    this._labelBaseSubText = '';\n    this._clearTargetStatus();\n    this._currentLat = null;\n    this._currentLon = null;\n    this._exactSurfaceSelection = false;\n    this._targetSurfaceRadius = null;\n  }\n\n  // ── LOS / route label status ──\n\n  _setLosStatus(distLabel) {\n    this._losStatusText = distLabel ? `LOS ${distLabel}` : '';\n    this._refreshTargetLabelText();\n  }\n\n  _setRouteStatus(text) {\n    this._routeStatusText = text || '';\n    this._refreshTargetLabelText();\n  }\n\n  _clearTargetStatus() {\n    this._losStatusText = '';\n    this._routeStatusText = '';\n    this._refreshTargetLabelText();\n  }\n\n  dispose() {\n    for (const unsubscribe of this._eventUnsubscribers.splice(0)) unsubscribe();\n    this._hideTargetLeader();\n    this._leaderMat?.dispose();\n    if (this.group.parent) this.group.parent.remove(this.group);\n  }\n}\n\nlet _instance = null;\nexport function getAddressHoverOverlay(opts) {\n  if (!_instance && opts) _instance = new AddressHoverOverlay(opts);\n  return _instance;\n}\n","/**\n * SensorEventStore — normalizes and stores sensor events from all sources.\n * All events are normalized to a common shape for rendering.\n */\n\nimport { SENSOR_SOURCES, SENSOR_CATEGORIES } from './SensorRegistry.js';\n\nconst MAX_EVENTS_PER_SOURCE = 500;\nconst MAX_TOTAL_EVENTS = 2000;\n\nlet _instance = null;\n\nexport class SensorEventStore {\n  constructor() {\n    this._events = new Map(); // sourceId -> SensorEvent[]\n    this._listeners = new Set();\n    this._stats = new Map();\n  }\n\n  /**\n   * Ingest raw data from a source, normalize it, and store.\n   */\n  ingest(sourceId, rawData) {\n    const normalized = this._normalize(sourceId, rawData);\n    if (!normalized || normalized.length === 0) return;\n\n    const existing = this._events.get(sourceId) || [];\n    const merged = this._mergeAndDedupe(existing, normalized);\n    const trimmed = merged.slice(0, MAX_EVENTS_PER_SOURCE);\n    this._events.set(sourceId, trimmed);\n\n    this._stats.set(sourceId, {\n      count: trimmed.length,\n      lastIngestMs: Date.now(),\n      lastRawCount: normalized.length,\n    });\n\n    this._enforceGlobalLimit();\n    this._emit({ sourceId, count: trimmed.length });\n  }\n\n  ingestWebSocketMessage(sourceId, msg) {\n    const event = this._normalizeWsMessage(sourceId, msg);\n    if (!event) return;\n\n    const existing = this._events.get(sourceId) || [];\n    const idx = existing.findIndex((e) => e.id === event.id);\n    if (idx >= 0) {\n      existing[idx] = event;\n    } else {\n      existing.unshift(event);\n    }\n    const trimmed = existing.slice(0, MAX_EVENTS_PER_SOURCE);\n    this._events.set(sourceId, trimmed);\n\n    this._stats.set(sourceId, {\n      count: trimmed.length,\n      lastIngestMs: Date.now(),\n      lastRawCount: 1,\n    });\n\n    this._emit({ sourceId, count: trimmed.length, event });\n  }\n\n  getEvents(sourceId) {\n    return this._events.get(sourceId) || [];\n  }\n\n  getAllEvents() {\n    const all = [];\n    for (const events of this._events.values()) {\n      all.push(...events);\n    }\n    return all;\n  }\n\n  getEventsByCategory(category) {\n    const result = [];\n    for (const [sourceId, events] of this._events) {\n      const source = SENSOR_SOURCES[sourceId];\n      if (source && source.category === category) {\n        result.push(...events);\n      }\n    }\n    return result;\n  }\n\n  getStats(sourceId) {\n    return this._stats.get(sourceId) || null;\n  }\n\n  subscribe(handler) {\n    this._listeners.add(handler);\n    return () => this._listeners.delete(handler);\n  }\n\n  clear(sourceId) {\n    if (sourceId) {\n      this._events.delete(sourceId);\n      this._stats.delete(sourceId);\n    } else {\n      this._events.clear();\n      this._stats.clear();\n    }\n    this._emit({ cleared: sourceId || 'all' });\n  }\n\n  _emit(payload) {\n    for (const fn of this._listeners) fn(payload);\n  }\n\n  _enforceGlobalLimit() {\n    let total = 0;\n    for (const events of this._events.values()) total += events.length;\n    if (total <= MAX_TOTAL_EVENTS) return;\n\n    // Trim oldest events from largest sources first\n    const entries = [...this._events.entries()].sort((a, b) => b[1].length - a[1].length);\n    let excess = total - MAX_TOTAL_EVENTS;\n    for (const [id, events] of entries) {\n      if (excess <= 0) break;\n      const trim = Math.min(excess, Math.floor(events.length * 0.3));\n      if (trim > 0) {\n        this._events.set(id, events.slice(0, events.length - trim));\n        excess -= trim;\n      }\n    }\n  }\n\n  _mergeAndDedupe(existing, incoming) {\n    const idSet = new Set(existing.map((e) => e.id));\n    const merged = [...existing];\n    for (const evt of incoming) {\n      if (!idSet.has(evt.id)) {\n        merged.unshift(evt);\n        idSet.add(evt.id);\n      } else {\n        const idx = merged.findIndex((e) => e.id === evt.id);\n        if (idx >= 0) merged[idx] = evt;\n      }\n    }\n    return merged;\n  }\n\n  // ── Normalization dispatch ──────────────────────────────────────────────\n  _normalize(sourceId, data) {\n    switch (sourceId) {\n      case 'usgs_earthquake': return this._normalizeUsgsQuake(data);\n      case 'emsc': return this._normalizeEmsc(data);\n      case 'geonet': return this._normalizeGeonet(data);\n      case 'usgs_volcano': return this._normalizeUsgsVolcano(data);\n      case 'eonet': return this._normalizeEonet(data);\n      case 'nws': return this._normalizeNws(data);\n      case 'nhc': return this._normalizeNhc(data);\n      case 'aviation': return this._normalizeAviation(data);\n      case 'gdacs': return this._normalizeGdacs(data);\n      default: return [];\n    }\n  }\n\n  _normalizeWsMessage(sourceId, msg) {\n    if (sourceId === 'emsc') return this._normalizeEmscWs(msg);\n    return null;\n  }\n\n  _coordinates(value) {\n    if (!Array.isArray(value) || value.length < 2) return null;\n    if (value[0] === null || value[0] === undefined || String(value[0]).trim() === ''\n      || value[1] === null || value[1] === undefined || String(value[1]).trim() === '') return null;\n    const lon = Number(value[0]);\n    const lat = Number(value[1]);\n    if (!Number.isFinite(lon) || !Number.isFinite(lat) || lon < -180 || lon > 180 || lat < -90 || lat > 90) return null;\n    const result = [lon, lat];\n    const altitude = Number(value[2]);\n    if (Number.isFinite(altitude)) result.push(altitude);\n    return result;\n  }\n\n  // ── USGS Earthquake (GeoJSON FeatureCollection) ─────────────────────────\n  _normalizeUsgsQuake(data) {\n    if (!data?.features) return [];\n    return data.features.map((f) => ({\n      id: `usgs_eq_${f.id}`,\n      source: 'usgs_earthquake',\n      category: 'seismic',\n      title: f.properties?.title || f.properties?.place || 'Earthquake',\n      severity: this._magToSeverity(f.properties?.mag),\n      magnitude: f.properties?.mag,\n      time: f.properties?.time,\n      updated: f.properties?.updated,\n      coordinates: this._coordinates(f.geometry?.coordinates), // [lon, lat, depth_km]\n      properties: {\n        place: f.properties?.place,\n        alert: f.properties?.alert,\n        tsunami: f.properties?.tsunami,\n        type: f.properties?.type,\n        url: f.properties?.url,\n      },\n    })).filter((event) => event.coordinates);\n  }\n\n  // ── EMSC REST ───────────────────────────────────────────────────────────\n  _normalizeEmsc(data) {\n    const events = data?.events || data?.features || [];\n    return events.map((e) => {\n      const props = e.properties || e;\n      return {\n        id: `emsc_${props.unid || props.source_id || props.evid}`,\n        source: 'emsc',\n        category: 'seismic',\n        title: `M${props.mag} - ${props.flynn_region || props.region || 'Unknown'}`,\n        severity: this._magToSeverity(props.mag),\n        magnitude: props.mag,\n        time: props.time ? new Date(props.time).getTime() : null,\n        coordinates: this._coordinates(e.geometry?.coordinates || [props.lon, props.lat, props.depth]),\n        properties: {\n          region: props.flynn_region || props.region,\n          depth: props.depth,\n          unid: props.unid,\n        },\n      };\n    }).filter((event) => event.coordinates);\n  }\n\n  // ── EMSC WebSocket ──────────────────────────────────────────────────────\n  _normalizeEmscWs(msg) {\n    if (!msg?.data?.properties) return null;\n    const p = msg.data.properties;\n    const geo = msg.data.geometry;\n    const coordinates = this._coordinates(geo?.coordinates || [p.lon, p.lat, p.depth]);\n    if (!coordinates) return null;\n    return {\n      id: `emsc_${p.unid || p.source_id}`,\n      source: 'emsc',\n      category: 'seismic',\n      title: `M${p.mag} - ${p.flynn_region || 'Unknown'}`,\n      severity: this._magToSeverity(p.mag),\n      magnitude: p.mag,\n      time: p.time ? new Date(p.time).getTime() : Date.now(),\n      coordinates,\n      properties: {\n        region: p.flynn_region,\n        depth: p.depth,\n        unid: p.unid,\n        action: msg.action,\n      },\n    };\n  }\n\n  // ── GeoNet NZ ───────────────────────────────────────────────────────────\n  _normalizeGeonet(data) {\n    const features = data?.features || [];\n    return features.map((f) => {\n      const p = f.properties || {};\n      return {\n        id: `geonet_${p.publicID}`,\n        source: 'geonet',\n        category: 'seismic',\n        title: `M${p.magnitude} - ${p.locality || 'New Zealand'}`,\n        severity: this._magToSeverity(p.magnitude),\n        magnitude: p.magnitude,\n        time: p.time ? new Date(p.time).getTime() : null,\n        coordinates: this._coordinates(f.geometry?.coordinates),\n        properties: {\n          publicID: p.publicID,\n          locality: p.locality,\n          depth: p.depth,\n          quality: p.quality,\n          mmi: p.mmi,\n        },\n      };\n    }).filter((event) => event.coordinates);\n  }\n\n  // ── USGS Volcano HANS ──────────────────────────────────────────────────\n  _normalizeUsgsVolcano(data) {\n    // HANS elevated returns an array or object with volcanos\n    const items = Array.isArray(data) ? data : (data?.features || data?.volcanos || []);\n    return items.map((v) => {\n      const props = v.properties || v;\n      return {\n        id: `volcano_${props.vnum || props.volcanoName || Math.random().toString(36).slice(2)}`,\n        source: 'usgs_volcano',\n        category: 'volcanic',\n        title: props.volcano_name || props.volcanoName || 'Volcano',\n        severity: this._alertToSeverity(props.alert_level || props.alertLevel),\n        time: props.sent_utc ? new Date(props.sent_utc).getTime() : Date.now(),\n        coordinates: this._coordinates(v.geometry?.coordinates || [props.longitude, props.latitude]),\n        properties: {\n          vnum: props.vnum,\n          alertLevel: props.alert_level || props.alertLevel,\n          colorCode: props.color_code || props.colorCode,\n          observatory: props.observatory,\n          noticeUrl: props.notice_url,\n        },\n      };\n    }).filter((event) => event.coordinates);\n  }\n\n  // ── NASA EONET ──────────────────────────────────────────────────────────\n  _normalizeEonet(data) {\n    const events = data?.events || [];\n    return events.map((e) => {\n      const lastGeo = e.geometry?.[e.geometry.length - 1];\n      const coords = this._coordinates(lastGeo?.coordinates);\n      return {\n        id: `eonet_${e.id}`,\n        source: 'eonet',\n        category: 'natural_event',\n        title: e.title || 'Natural Event',\n        severity: 'info',\n        time: lastGeo?.date ? new Date(lastGeo.date).getTime() : null,\n        coordinates: coords,\n        properties: {\n          categories: e.categories?.map((c) => c.title),\n          sources: e.sources?.map((s) => ({ id: s.id, url: s.url })),\n          closed: e.closed,\n          geometry: lastGeo?.type && lastGeo?.coordinates ? { type: lastGeo.type, coordinates: lastGeo.coordinates } : null,\n        },\n      };\n    }).filter((event) => event.coordinates);\n  }\n\n  // ── NWS Alerts ──────────────────────────────────────────────────────────\n  _normalizeNws(data) {\n    const features = data?.features || [];\n    return features.map((f) => {\n      const p = f.properties || {};\n      // NWS geometry can be polygon — use centroid approximation\n      const coords = this._centroidFromGeometry(f.geometry);\n      return {\n        id: `nws_${p.id || f.id}`,\n        source: 'nws',\n        category: 'weather',\n        title: `${p.event || 'Alert'} - ${p.areaDesc || ''}`.trim(),\n        severity: (p.severity || 'unknown').toLowerCase(),\n        time: p.sent ? new Date(p.sent).getTime() : null,\n        coordinates: coords,\n        properties: {\n          event: p.event,\n          severity: p.severity,\n          certainty: p.certainty,\n          urgency: p.urgency,\n          headline: p.headline,\n          description: p.description?.slice(0, 500),\n          areaDesc: p.areaDesc,\n          effective: p.effective,\n          expires: p.expires,\n          geometry: f.geometry || null,\n        },\n      };\n    }).filter((event) => event.coordinates);\n  }\n\n  // ── NHC Storms ──────────────────────────────────────────────────────────\n  _normalizeNhc(data) {\n    const storms = data?.activeStorms || [];\n    return storms.map((s) => ({\n      id: `nhc_${s.binNumber || s.id}`,\n      source: 'nhc',\n      category: 'weather',\n      title: s.name || 'Tropical System',\n      severity: this._nhcClassToSeverity(s.classification),\n      time: s.lastUpdate ? new Date(s.lastUpdate).getTime() : Date.now(),\n      coordinates: this._coordinates([s.longitude, s.latitude]),\n      properties: {\n        classification: s.classification,\n        intensity: s.intensity,\n        pressure: s.pressure,\n        movementDir: s.movementDir,\n        movementSpeed: s.movementSpeed,\n        publicAdvisoryUrl: s.publicAdvisory?.url,\n        forecastGraphicUrl: s.forecastGraphic?.url,\n      },\n    })).filter((event) => event.coordinates);\n  }\n\n  // ── AviationWeather METAR ───────────────────────────────────────────────\n  _normalizeAviation(data) {\n    if (!Array.isArray(data)) return [];\n    return data.map((m) => ({\n      id: `metar_${m.icaoId || m.stationId}_${m.obsTime || m.reportTime}`,\n      source: 'aviation',\n      category: 'aviation',\n      title: `METAR ${m.icaoId || m.stationId}`,\n      severity: 'info',\n      time: m.obsTime ? new Date(m.obsTime).getTime() : Date.now(),\n      coordinates: this._coordinates([m.lon, m.lat]),\n      properties: {\n        rawOb: m.rawOb,\n        temp: m.temp,\n        dewp: m.dewp,\n        wdir: m.wdir,\n        wspd: m.wspd,\n        visib: m.visib,\n        altim: m.altim,\n        fltcat: m.fltcat,\n      },\n    })).filter((event) => event.coordinates);\n  }\n\n  // ── GDACS ───────────────────────────────────────────────────────────────\n  _normalizeGdacs(data) {\n    const features = data?.features || data?.result || [];\n    const items = Array.isArray(features) ? features : [];\n    return items.map((f) => {\n      const p = f.properties || f;\n      return {\n        id: `gdacs_${p.source_id || p.eventid || p.eventId || f.id || Math.random().toString(36).slice(2)}`,\n        source: 'gdacs',\n        category: 'disaster',\n        title: p.title || p.name || p.eventname || p.htmldescription || 'GDACS Event',\n        severity: (p.alert_level || p.alertlevel || p.severitytext || 'info').toLowerCase(),\n        time: (p.observed_at || p.fromdate) ? new Date(p.observed_at || p.fromdate).getTime() : Date.now(),\n        coordinates: this._coordinates(f.geometry?.coordinates || [p.longitude ?? p.lng, p.latitude ?? p.lat]),\n        properties: {\n          eventId: p.source_id || p.eventid || p.eventId,\n          eventType: p.kind || p.eventtype,\n          alertLevel: p.alert_level || p.alertlevel,\n          country: p.country,\n          severity: p.severitytext || null,\n          url: p.report_url || p.url,\n          semanticNotice: p.semantic_notice || null,\n          provenance: p.provenance || null,\n          geometry: f.geometry || null,\n        },\n      };\n    }).filter((event) => event.coordinates);\n  }\n\n  // ── Severity helpers ────────────────────────────────────────────────────\n  _magToSeverity(mag) {\n    if (mag == null) return 'info';\n    if (mag >= 7) return 'extreme';\n    if (mag >= 5) return 'severe';\n    if (mag >= 3) return 'moderate';\n    if (mag >= 1) return 'minor';\n    return 'info';\n  }\n\n  _alertToSeverity(level) {\n    if (!level) return 'info';\n    const upper = String(level).toUpperCase();\n    if (upper === 'WARNING') return 'extreme';\n    if (upper === 'WATCH') return 'severe';\n    if (upper === 'ADVISORY') return 'moderate';\n    return 'info';\n  }\n\n  _nhcClassToSeverity(classification) {\n    if (!classification) return 'info';\n    const upper = String(classification).toUpperCase();\n    if (upper.includes('HURRICANE') || upper === 'HU') return 'extreme';\n    if (upper.includes('STORM') || upper === 'TS') return 'severe';\n    if (upper.includes('DEPRESSION') || upper === 'TD') return 'moderate';\n    return 'minor';\n  }\n\n  _centroidFromGeometry(geom) {\n    if (!geom) return null;\n    if (geom.type === 'Point') return this._coordinates(geom.coordinates);\n    if (geom.type === 'Polygon' && geom.coordinates?.[0]) {\n      const ring = geom.coordinates[0];\n      const points = ring.map((point) => this._coordinates(point)).filter(Boolean);\n      if (!points.length) return null;\n      let sumSin = 0;\n      let sumCos = 0;\n      let sumLat = 0;\n      for (const [lon, lat] of points) {\n        const radians = lon * Math.PI / 180;\n        sumSin += Math.sin(radians);\n        sumCos += Math.cos(radians);\n        sumLat += lat;\n      }\n      const lon = Math.atan2(sumSin / points.length, sumCos / points.length) * 180 / Math.PI;\n      return this._coordinates([lon, sumLat / points.length]);\n    }\n    if (geom.type === 'MultiPolygon' && geom.coordinates?.[0]?.[0]) {\n      return this._centroidFromGeometry({ type: 'Polygon', coordinates: geom.coordinates[0] });\n    }\n    return null;\n  }\n}\n\nexport function getSensorEventStore() {\n  if (!_instance) _instance = new SensorEventStore();\n  return _instance;\n}\n","/**\n * SensorOverlay — Renders sensor events as spire markers, heatmap discs,\n * GeoJSON polygons, and labels on the globe with altitude-aware scaling.\n *\n * Visual elements scale with camera proximity:\n * - Spire height/radius grows as you approach the surface\n * - Heatmap glow rings appear and intensify at lower altitudes\n * - Labels fade in below a threshold altitude\n * - Polygon fills become more opaque at closer range\n */\n\nimport * as THREE from 'three';\nimport { latLonToLocalDir, ellipsoidRadiusForLocalDir } from '../../modules/geometry-utils.js';\nimport { terrainSurfaceChangesAffectLatLon } from '../scene/TerrainSurfaceChange.js';\nimport { getSensorEventStore } from './SensorEventStore.js';\nimport { SENSOR_SOURCES, SENSOR_CATEGORIES } from './SensorRegistry.js';\n\n// ── Altitude scaling bands ───────────────────────────────────────────────\nconst ALT_HIGH_M = 800000;    // orbital — minimal visuals\nconst ALT_MED_M = 400000;     // continental — spires + labels visible\nconst ALT_LOW_M = 200000;     // regional — labels + heatmaps fade in\nconst ALT_SURFACE_M = 5000;   // surface — full detail\n\n// ── Spire constants ──────────────────────────────────────────────────────\nconst SPIRE_BASE_HEIGHT_M = 120;\nconst SPIRE_BASE_RADIUS_M = 8;\nconst SPIRE_MIN_SCALE = 0.6;\nconst SPIRE_MAX_SCALE = 5.0;\nconst SURFACE_OFFSET_M = 0.25;\n\n// ── Heatmap ring constants ───────────────────────────────────────────────\nconst HEATMAP_RING_SEGMENTS = 48;\nconst HEATMAP_BASE_RADIUS_M = 2000;\nconst HEATMAP_MIN_OPACITY = 0.08;\nconst HEATMAP_MAX_OPACITY = 0.5;\nconst HEATMAP_ALTITUDE_FADE_START = ALT_LOW_M;\n\n// ── Label constants ──────────────────────────────────────────────────────\nconst LABEL_FONT_SIZE = 36;\nconst LABEL_MAX_CHARS = 48;\nconst LABEL_BASE_SCALE_M = 14;\nconst MAX_LABEL_COUNT = 300;\nconst LABEL_FADE_ALT_START = ALT_LOW_M;\nconst LABEL_FADE_ALT_END = ALT_HIGH_M;\n\n// ── Pulse constants ──────────────────────────────────────────────────────\nconst RECENT_WINDOW_MS = 5 * 60 * 1000;\nconst PULSE_SPEED = 3.0;\nconst PULSE_SCALE_AMP = 0.12;\nconst PULSE_BRIGHT_AMP = 0.4;\nconst PULSE_RING_AMP = 0.25;\n\n// ── Fade constants ───────────────────────────────────────────────────────\nconst FADE_START_MS = 30 * 60 * 1000;\nconst FADE_END_MS = 6 * 60 * 60 * 1000;\n\n// ── GeoJSON constants ────────────────────────────────────────────────────\nconst POLYGON_OFFSET_M = 30;\nconst LINE_OPACITY = 0.85;\nconst FILL_OPACITY_BASE = 0.12;\nconst FILL_OPACITY_MAX = 0.35;\nconst POINT_SIZE = 2500;\n\n// ── Severity color palette ───────────────────────────────────────────────\nconst SEVERITY_COLORS = {\n  extreme:  0xff2020,\n  severe:   0xff6600,\n  moderate: 0xffcc00,\n  minor:    0x44cc44,\n  info:     0x4488ff,\n};\n\nconst CATEGORY_COLORS = {\n  seismic:        0xff4444,\n  volcanic:       0xff6600,\n  weather:        0x44aaff,\n  space:          0xaa66ff,\n  natural_event:  0x44cc88,\n  aviation:       0xcccc44,\n  conflict:       0xff3366,\n  disaster:       0xff8800,\n  network:        0x00cccc,\n};\n\n// Sensor types that benefit from heatmap rings (all categories)\nconst HEATMAP_CATEGORIES = new Set([\n  'seismic', 'volcanic', 'weather', 'disaster', 'natural_event',\n  'space', 'aviation', 'conflict', 'network',\n]);\n\nconst resolveColor = (event) => {\n  if (event.severity && SEVERITY_COLORS[event.severity]) {\n    return SEVERITY_COLORS[event.severity];\n  }\n  if (event.category && CATEGORY_COLORS[event.category]) {\n    return CATEGORY_COLORS[event.category];\n  }\n  return 0x4488ff;\n};\n\nconst resolveSpireHeight = (event) => {\n  const base = SPIRE_BASE_HEIGHT_M;\n  if (event.category === 'seismic' && Number.isFinite(event.magnitude)) {\n    return base * Math.max(0.5, Math.min(4, event.magnitude / 3));\n  }\n  const severityScale = { extreme: 3, severe: 2.2, moderate: 1.5, minor: 1, info: 0.7 };\n  return base * (severityScale[event.severity] || 1);\n};\n\nconst resolveHeatmapRadius = (event) => {\n  if (event.category === 'seismic' && Number.isFinite(event.magnitude)) {\n    return HEATMAP_BASE_RADIUS_M * Math.max(0.5, Math.pow(event.magnitude / 3, 1.5));\n  }\n  const severityScale = { extreme: 3, severe: 2, moderate: 1.3, minor: 0.8, info: 0.5 };\n  return HEATMAP_BASE_RADIUS_M * (severityScale[event.severity] || 1);\n};\n\nconst hashPhase = (id) => {\n  if (!id) return 0;\n  let h = 0;\n  for (let i = 0; i < id.length; i++) {\n    h = ((h << 5) - h) + id.charCodeAt(i);\n    h |= 0;\n  }\n  return ((Math.abs(h) % 360) / 360) * Math.PI * 2;\n};\n\nconst truncate = (text, max) => {\n  if (!text) return '';\n  const s = String(text);\n  return s.length <= max ? s : `${s.slice(0, max - 3).trim()}...`;\n};\n\n// Compute altitude-dependent scale factor (0..1 for low→high)\nconst altitudeScale = (altM) => {\n  if (!Number.isFinite(altM) || altM <= ALT_SURFACE_M) return 1;\n  if (altM >= ALT_HIGH_M) return SPIRE_MIN_SCALE;\n  // Log scale for smooth transition\n  const logMin = Math.log(ALT_SURFACE_M);\n  const logMax = Math.log(ALT_HIGH_M);\n  const logAlt = Math.log(altM);\n  const t = (logAlt - logMin) / (logMax - logMin);\n  return THREE.MathUtils.lerp(SPIRE_MAX_SCALE, SPIRE_MIN_SCALE, t);\n};\n\nconst altitudeLabelOpacity = (altM) => {\n  if (!Number.isFinite(altM) || altM <= LABEL_FADE_ALT_START) return 1;\n  if (altM >= LABEL_FADE_ALT_END) return 0;\n  return 1 - (altM - LABEL_FADE_ALT_START) / (LABEL_FADE_ALT_END - LABEL_FADE_ALT_START);\n};\n\nconst altitudeHeatmapOpacity = (altM) => {\n  if (!Number.isFinite(altM) || altM <= ALT_SURFACE_M) return HEATMAP_MAX_OPACITY;\n  if (altM >= HEATMAP_ALTITUDE_FADE_START) return HEATMAP_MIN_OPACITY;\n  const t = (altM - ALT_SURFACE_M) / (HEATMAP_ALTITUDE_FADE_START - ALT_SURFACE_M);\n  return THREE.MathUtils.lerp(HEATMAP_MAX_OPACITY, HEATMAP_MIN_OPACITY, t);\n};\n\nexport class SensorOverlay {\n  constructor({\n    parentGroup,\n    camera,\n    terrainSampler,\n    sceneInitializer,\n    eventBus,\n    surfaceController,\n  } = {}) {\n    this.parentGroup = parentGroup || null;\n    this.camera = camera || null;\n    this.eventBus = eventBus || null;\n    this.sceneInitializer = sceneInitializer || null;\n    this.surfaceController = surfaceController || null;\n    this._terrainSampler = typeof terrainSampler === 'function' ? terrainSampler : null;\n\n    this.enabled = false;\n    this._store = getSensorEventStore();\n    this._entries = new Map();      // eventId -> entry (spires + heatmaps + labels)\n    this._geoGroups = new Map();    // sourceId -> THREE.Group (polygon/line layers)\n\n    // Shared geometry templates\n    this._spireGeo = this._buildSpireGeometry();\n    this._spireMat = this._buildSpireMaterial();\n    this._heatmapGeo = this._buildHeatmapGeometry();\n\n    // Main group\n    this.group = new THREE.Group();\n    this.group.name = 'SensorOverlay';\n    this.group.visible = false;\n    this.parentGroup?.add(this.group);\n\n    if (this.sceneInitializer?.addDepthPassExclude) {\n      this.sceneInitializer.addDepthPassExclude(this.group);\n    }\n\n    // Temps\n    this._worldUp = new THREE.Vector3(0, 1, 0);\n    this._tmpVec = new THREE.Vector3();\n    this._tmpQuat = new THREE.Quaternion();\n    this._tmpColor = new THREE.Color();\n    this._tmpCamPos = new THREE.Vector3();\n    this._pulseElapsed = 0;\n    this._storeUnsub = null;\n    this._lastSyncVersion = 0;\n    this._syncVersion = 0;\n    this._currentAltitudeM = ALT_HIGH_M;\n\n    this._bindStore();\n  }\n\n  // ── Lifecycle ───────────────────────────────────────────────────────────\n\n  setEnabled(enabled) {\n    this.enabled = enabled;\n    this.group.visible = enabled;\n    if (enabled) {\n      this._fullSync();\n    } else {\n      this._clearAll();\n    }\n  }\n\n  update(dt) {\n    if (!this.enabled) return;\n    const sec = Number.isFinite(dt) ? dt : 0;\n    this._pulseElapsed += sec;\n\n    // Sample current altitude\n    this._currentAltitudeM = this._sampleAltitude();\n\n    // Check if store changed\n    if (this._syncVersion !== this._lastSyncVersion) {\n      this._lastSyncVersion = this._syncVersion;\n      this._fullSync();\n    }\n\n    // Altitude-dependent updates\n    this._updateScaling();\n    this._updatePulse();\n    this._updateLabelVisibility();\n    this._updateHeatmapVisibility();\n  }\n\n  dispose() {\n    this._clearAll();\n    if (this._storeUnsub) this._storeUnsub();\n    this._spireGeo.dispose();\n    this._spireMat.dispose();\n    this._heatmapGeo.dispose();\n    if (this.group?.parent) this.group.parent.remove(this.group);\n    if (this.sceneInitializer?.removeDepthPassExclude) {\n      this.sceneInitializer.removeDepthPassExclude(this.group);\n    }\n  }\n\n  // ── Altitude sampling ──────────────────────────────────────────────────\n\n  _sampleAltitude() {\n    if (this.surfaceController?.getSurfaceAltitudeMeters) {\n      const alt = this.surfaceController.getSurfaceAltitudeMeters();\n      if (Number.isFinite(alt)) return alt;\n    }\n    if (this.surfaceController?.surfaceAltitudeMSL) {\n      const alt = this.surfaceController.surfaceAltitudeMSL;\n      if (Number.isFinite(alt)) return alt;\n    }\n    // Fallback: compute from camera distance to planet surface\n    if (this.camera && this.parentGroup) {\n      this.camera.getWorldPosition(this._tmpCamPos);\n      const camDist = this._tmpCamPos.length();\n      const surfaceR = 6371000;\n      return Math.max(0, camDist - surfaceR);\n    }\n    return ALT_HIGH_M;\n  }\n\n  // ── Store binding ─────────────────────────────────────────────────────\n\n  _bindStore() {\n    this._storeUnsub = this._store.subscribe(() => {\n      this._syncVersion++;\n    });\n  }\n\n  // ── Full sync from event store ────────────────────────────────────────\n\n  _fullSync() {\n    const allEvents = this._store.getAllEvents();\n    const nextIds = new Set();\n\n    for (const event of allEvents) {\n      if (!event?.coordinates || !Array.isArray(event.coordinates)) continue;\n      const [lon, lat] = event.coordinates;\n      if (!Number.isFinite(lat) || !Number.isFinite(lon)) continue;\n\n      const key = event.id;\n      nextIds.add(key);\n\n      let entry = this._entries.get(key);\n      if (!entry) {\n        entry = this._createEntry(event);\n        this._entries.set(key, entry);\n        this.group.add(entry.object);\n        if (entry.label) this.group.add(entry.label);\n        if (entry.heatmap) this.group.add(entry.heatmap);\n      } else {\n        this._updateEntry(entry, event);\n      }\n    }\n\n    // Remove stale\n    for (const [id, entry] of this._entries) {\n      if (!nextIds.has(id)) {\n        this._disposeEntry(entry);\n        this._entries.delete(id);\n      }\n    }\n\n    // Rebuild GeoJSON layers\n    this._rebuildGeoLayers();\n  }\n\n  // ── Entry creation ────────────────────────────────────────────────────\n\n  _createEntry(event) {\n    const color = resolveColor(event);\n    const heightM = resolveSpireHeight(event);\n    const material = this._spireMat.clone();\n    material.uniforms = THREE.UniformsUtils.clone(this._spireMat.uniforms);\n    material.uniforms.uColor.value.setHex(color);\n    material.uniforms.uOpacity.value = 0.85;\n\n    const mesh = new THREE.Mesh(this._spireGeo, material);\n    mesh.name = 'SensorSpire';\n    mesh.renderOrder = 5;\n    mesh.scale.set(SPIRE_BASE_RADIUS_M, heightM, SPIRE_BASE_RADIUS_M);\n\n    const entry = {\n      id: event.id,\n      source: event.source,\n      category: event.category,\n      lat: event.coordinates[1],\n      lon: event.coordinates[0],\n      time: event.time,\n      severity: event.severity,\n      magnitude: event.magnitude,\n      title: event.title,\n      object: mesh,\n      material,\n      baseColor: new THREE.Color(color),\n      pulsePhase: hashPhase(event.id),\n      baseHeightM: heightM,\n      baseRadiusM: SPIRE_BASE_RADIUS_M,\n      label: null,\n      labelMaterial: null,\n      labelTexture: null,\n      labelAspect: 1,\n      heatmap: null,\n      heatmapMaterial: null,\n      heatmapBaseRadius: resolveHeatmapRadius(event),\n    };\n\n    // Position on globe\n    this._positionEntry(entry);\n\n    // Create label\n    if (this._entries.size < MAX_LABEL_COUNT) {\n      this._createLabel(entry, event);\n    }\n\n    // Create heatmap ring for appropriate categories\n    if (HEATMAP_CATEGORIES.has(event.category)) {\n      this._createHeatmapRing(entry);\n    }\n\n    return entry;\n  }\n\n  _updateEntry(entry, event) {\n    const nextColor = resolveColor(event);\n    const nextHeight = resolveSpireHeight(event);\n\n    entry.severity = event.severity;\n    entry.magnitude = event.magnitude;\n    entry.time = event.time;\n    entry.title = event.title;\n    entry.baseHeightM = nextHeight;\n\n    entry.baseColor.setHex(nextColor);\n    if (entry.material.uniforms?.uColor) {\n      entry.material.uniforms.uColor.value.setHex(nextColor);\n    }\n    if (entry.heatmapMaterial) {\n      entry.heatmapMaterial.color.setHex(nextColor);\n    }\n    entry.heatmapBaseRadius = resolveHeatmapRadius(event);\n  }\n\n  _disposeEntry(entry) {\n    if (!entry) return;\n    if (entry.object?.parent) entry.object.parent.remove(entry.object);\n    if (entry.material?.dispose) entry.material.dispose();\n    if (entry.label?.parent) entry.label.parent.remove(entry.label);\n    if (entry.labelMaterial?.dispose) entry.labelMaterial.dispose();\n    if (entry.labelTexture?.dispose) entry.labelTexture.dispose();\n    if (entry.heatmap?.parent) entry.heatmap.parent.remove(entry.heatmap);\n    if (entry.heatmapMaterial?.dispose) entry.heatmapMaterial.dispose();\n  }\n\n  _clearAll() {\n    for (const entry of this._entries.values()) {\n      this._disposeEntry(entry);\n    }\n    this._entries.clear();\n    for (const [, grp] of this._geoGroups) {\n      this._clearGroup(grp);\n      if (grp.parent) grp.parent.remove(grp);\n    }\n    this._geoGroups.clear();\n  }\n\n  _clearGroup(grp) {\n    while (grp.children.length > 0) {\n      const child = grp.children[0];\n      grp.remove(child);\n      if (child.geometry?.dispose) child.geometry.dispose();\n      if (child.material?.dispose) child.material.dispose();\n      if (child.material?.map?.dispose) child.material.map.dispose();\n    }\n  }\n\n  // ── Altitude-dependent scaling ─────────────────────────────────────────\n\n  _updateScaling() {\n    const scale = altitudeScale(this._currentAltitudeM);\n    for (const entry of this._entries.values()) {\n      if (!entry?.object) continue;\n      const h = entry.baseHeightM * scale;\n      const r = entry.baseRadiusM * scale;\n      entry._currentHeightM = h;\n      entry._currentRadiusM = r;\n      // Pulse will apply final scale\n    }\n  }\n\n  // ── Positioning ───────────────────────────────────────────────────────\n\n  _positionEntry(entry) {\n    if (!Number.isFinite(entry.lat) || !Number.isFinite(entry.lon)) return;\n    const dir = latLonToLocalDir(entry.lat, entry.lon);\n    const sample = this._surfaceSample(dir);\n    if (sample.authoritative || !Number.isFinite(entry._stableRadius)) {\n      entry._stableRadius = sample.radius;\n    }\n    if (sample.authoritative) entry._terrainMated = true;\n    const radius = entry._stableRadius + SURFACE_OFFSET_M;\n    entry.object.position.copy(dir).multiplyScalar(radius);\n    entry.object.quaternion.setFromUnitVectors(this._worldUp, dir);\n    if (entry.label) {\n      const labelR = radius + (entry._currentHeightM || entry.baseHeightM) + 2;\n      entry.label.position.copy(dir).multiplyScalar(labelR);\n    }\n    if (entry.heatmap) {\n      entry.heatmap.position.copy(dir).multiplyScalar(radius + 0.5);\n      entry.heatmap.quaternion.setFromUnitVectors(this._worldUp, dir);\n    }\n  }\n\n  _surfaceSample(dir) {\n    const r = ellipsoidRadiusForLocalDir(dir);\n    if (!this._terrainSampler) return { radius: r, authoritative: false };\n    const worldDir = this._tmpVec.copy(dir).normalize();\n    if (this.parentGroup?.getWorldQuaternion) {\n      this.parentGroup.getWorldQuaternion(this._tmpQuat);\n      worldDir.applyQuaternion(this._tmpQuat);\n    }\n    const requireFreshPhotoHit = !!this.surfaceController?.photoTileGroup;\n    const sampled = this._terrainSampler(worldDir, {\n      mutateCache: false,\n      requireFreshPhotoHit,\n      allowTriTreeFallback: !requireFreshPhotoHit,\n      skipWorldMatrixUpdate: true,\n    });\n    return Number.isFinite(sampled)\n      ? { radius: sampled, authoritative: true }\n      : { radius: r, authoritative: false };\n  }\n\n  refreshTerrainAnchors(changes) {\n    if (!this._terrainSampler || !Array.isArray(changes) || changes.length === 0) return 0;\n    let updated = 0;\n    for (const entry of this._entries.values()) {\n      if (!terrainSurfaceChangesAffectLatLon(changes, entry.lat, entry.lon)) continue;\n      this._positionEntry(entry);\n      updated += 1;\n    }\n    return updated;\n  }\n\n  // ── Spire shader ──────────────────────────────────────────────────────\n\n  _buildSpireGeometry() {\n    const geo = new THREE.CylinderGeometry(1, 1, 1, 16, 1, true);\n    geo.translate(0, 0.5, 0);\n    return geo;\n  }\n\n  _buildSpireMaterial() {\n    return new THREE.ShaderMaterial({\n      uniforms: {\n        uColor: { value: new THREE.Color(1, 1, 1) },\n        uOpacity: { value: 0.85 },\n        uGradientPower: { value: 1.4 },\n      },\n      vertexShader: `\n        varying float vHeight;\n        void main() {\n          vHeight = position.y;\n          gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n        }\n      `,\n      fragmentShader: `\n        varying float vHeight;\n        uniform vec3 uColor;\n        uniform float uOpacity;\n        uniform float uGradientPower;\n        void main() {\n          float t = clamp(1.0 - vHeight, 0.0, 1.0);\n          float alpha = uOpacity * pow(t, uGradientPower);\n          if (alpha <= 0.002) discard;\n          // Boost color intensity for bright glow\n          vec3 boosted = uColor * 1.6 + vec3(0.15);\n          gl_FragColor = vec4(boosted, alpha);\n        }\n      `,\n      transparent: true,\n      depthWrite: false,\n      depthTest: false,\n      side: THREE.DoubleSide,\n      toneMapped: false,\n    });\n  }\n\n  // ── Heatmap ring geometry ─────────────────────────────────────────────\n\n  _buildHeatmapGeometry() {\n    // Unit disc — scaled per-entry\n    const geo = new THREE.RingGeometry(0.3, 1, HEATMAP_RING_SEGMENTS, 3);\n    return geo;\n  }\n\n  _createHeatmapRing(entry) {\n    const color = entry.baseColor.clone();\n    const mat = new THREE.MeshBasicMaterial({\n      color,\n      transparent: true,\n      opacity: 0,\n      side: THREE.DoubleSide,\n      depthWrite: false,\n      blending: THREE.AdditiveBlending,\n    });\n    const mesh = new THREE.Mesh(this._heatmapGeo, mat);\n    mesh.name = 'SensorHeatmap';\n    mesh.renderOrder = 3;\n    const r = entry.heatmapBaseRadius;\n    mesh.scale.set(r, r, r);\n    // Rotate disc to lie flat (RingGeometry is in XY plane, we need XZ)\n    mesh.rotation.x = -Math.PI / 2;\n    entry.heatmap = mesh;\n    entry.heatmapMaterial = mat;\n  }\n\n  // ── Pulse animation ───────────────────────────────────────────────────\n\n  _updatePulse() {\n    const now = Date.now();\n    const heatmapAlpha = altitudeHeatmapOpacity(this._currentAltitudeM);\n\n    for (const entry of this._entries.values()) {\n      if (!entry?.object || !entry.material) continue;\n\n      const ageMs = Number.isFinite(entry.time) ? now - entry.time : Infinity;\n      const h = entry._currentHeightM || entry.baseHeightM;\n      const r = entry._currentRadiusM || entry.baseRadiusM;\n      let scale = 1;\n      let opacity = 0.85;\n\n      if (ageMs <= RECENT_WINDOW_MS) {\n        const pulse = 0.5 + 0.5 * Math.sin(this._pulseElapsed * PULSE_SPEED + entry.pulsePhase);\n        scale = 1 + PULSE_SCALE_AMP * pulse;\n        const bright = 1 + PULSE_BRIGHT_AMP * pulse;\n        this._tmpColor.copy(entry.baseColor).multiplyScalar(bright);\n        this._tmpColor.r = Math.min(1, this._tmpColor.r);\n        this._tmpColor.g = Math.min(1, this._tmpColor.g);\n        this._tmpColor.b = Math.min(1, this._tmpColor.b);\n        entry.material.uniforms.uColor.value.copy(this._tmpColor);\n\n        // Pulse heatmap ring\n        if (entry.heatmapMaterial) {\n          const ringPulse = heatmapAlpha * (0.7 + PULSE_RING_AMP * pulse);\n          entry.heatmapMaterial.opacity = ringPulse;\n          const ringScale = entry.heatmapBaseRadius * (1 + 0.15 * pulse);\n          entry.heatmap.scale.set(ringScale, ringScale, ringScale);\n        }\n      } else {\n        entry.material.uniforms.uColor.value.copy(entry.baseColor);\n        // Fade old events\n        if (ageMs > FADE_START_MS) {\n          const t = Math.min(1, (ageMs - FADE_START_MS) / (FADE_END_MS - FADE_START_MS));\n          opacity = THREE.MathUtils.lerp(0.85, 0.15, t);\n        }\n\n        // Static heatmap\n        if (entry.heatmapMaterial) {\n          const ageFade = ageMs > FADE_START_MS\n            ? Math.max(0.1, 1 - Math.min(1, (ageMs - FADE_START_MS) / (FADE_END_MS - FADE_START_MS)))\n            : 1;\n          entry.heatmapMaterial.opacity = heatmapAlpha * ageFade * 0.6;\n        }\n      }\n\n      entry.object.scale.set(r * scale, h * scale, r * scale);\n      entry.material.uniforms.uOpacity.value = opacity;\n    }\n  }\n\n  // ── Label management ──────────────────────────────────────────────────\n\n  _createLabel(entry, event) {\n    const text = truncate(event.title || event.source || '', LABEL_MAX_CHARS);\n    if (!text) return;\n\n    const canvas = document.createElement('canvas');\n    const ctx = canvas.getContext('2d');\n    if (!ctx) return;\n\n    const paddingX = 10;\n    const paddingY = 8;\n    const lineHeight = Math.round(LABEL_FONT_SIZE * 1.2);\n    ctx.font = `600 ${LABEL_FONT_SIZE}px system-ui`;\n    const width = Math.ceil(ctx.measureText(text).width) + paddingX * 2;\n    const height = lineHeight + paddingY * 2;\n    canvas.width = width;\n    canvas.height = height;\n\n    ctx.font = `600 ${LABEL_FONT_SIZE}px system-ui`;\n    // Category-tinted background\n    const catColor = CATEGORY_COLORS[event.category] || 0x4488ff;\n    const r = ((catColor >> 16) & 0xff) / 255;\n    const g = ((catColor >> 8) & 0xff) / 255;\n    const b = (catColor & 0xff) / 255;\n    ctx.fillStyle = `rgba(${Math.round(r * 40)},${Math.round(g * 40)},${Math.round(b * 40)},0.75)`;\n    ctx.fillRect(0, 0, width, height);\n    // Left color bar\n    ctx.fillStyle = `rgb(${Math.round(r * 255)},${Math.round(g * 255)},${Math.round(b * 255)})`;\n    ctx.fillRect(0, 0, 3, height);\n    ctx.fillStyle = '#ffffff';\n    ctx.textBaseline = 'top';\n    ctx.fillText(text, paddingX, paddingY);\n\n    const texture = new THREE.CanvasTexture(canvas);\n    texture.needsUpdate = true;\n    const mat = new THREE.SpriteMaterial({ map: texture, transparent: true, opacity: 0 });\n    const sprite = new THREE.Sprite(mat);\n    const aspect = width / height;\n    sprite.center.set(0.5, 0);\n    sprite.scale.set(LABEL_BASE_SCALE_M * aspect, LABEL_BASE_SCALE_M, 1);\n    sprite.renderOrder = 6;\n\n    entry.label = sprite;\n    entry.labelMaterial = mat;\n    entry.labelTexture = texture;\n    entry.labelAspect = aspect;\n  }\n\n  _updateLabelVisibility() {\n    const labelAlpha = altitudeLabelOpacity(this._currentAltitudeM);\n    const scale = altitudeScale(this._currentAltitudeM);\n    for (const entry of this._entries.values()) {\n      if (!entry.label || !entry.labelMaterial) continue;\n      entry.labelMaterial.opacity = labelAlpha;\n      entry.label.visible = labelAlpha > 0.01;\n      // Scale labels with altitude\n      const s = LABEL_BASE_SCALE_M * scale;\n      entry.label.scale.set(s * entry.labelAspect, s, 1);\n    }\n  }\n\n  _updateHeatmapVisibility() {\n    const alpha = altitudeHeatmapOpacity(this._currentAltitudeM);\n    for (const entry of this._entries.values()) {\n      if (!entry.heatmap) continue;\n      entry.heatmap.visible = alpha > 0.005;\n    }\n  }\n\n  // ── GeoJSON polygon/line layers ───────────────────────────────────────\n\n  _rebuildGeoLayers() {\n    const geoSources = ['nws', 'eonet', 'gdacs'];\n\n    for (const sourceId of geoSources) {\n      const events = this._store.getEvents(sourceId);\n      let grp = this._geoGroups.get(sourceId);\n\n      if (!events.length) {\n        if (grp) this._clearGroup(grp);\n        continue;\n      }\n\n      if (!grp) {\n        grp = new THREE.Group();\n        grp.name = `SensorGeo_${sourceId}`;\n        this._geoGroups.set(sourceId, grp);\n        this.group.add(grp);\n      } else {\n        this._clearGroup(grp);\n      }\n\n      const source = SENSOR_SOURCES[sourceId];\n      const catColor = CATEGORY_COLORS[source?.category] || 0x4488ff;\n\n      for (const event of events) {\n        const geom = event.properties?.geometry || event.properties?.geojson;\n        if (!geom) continue;\n        this._renderGeometry(grp, geom, catColor);\n      }\n    }\n  }\n\n  _renderGeometry(grp, geom, baseColor) {\n    if (!geom?.type) return;\n    const coords = geom.coordinates;\n    if (!coords) return;\n\n    switch (geom.type) {\n      case 'Point':\n        this._renderPoint(grp, coords, baseColor);\n        break;\n      case 'MultiPoint':\n        if (Array.isArray(coords)) {\n          for (const c of coords) this._renderPoint(grp, c, baseColor);\n        }\n        break;\n      case 'LineString':\n        this._renderLine(grp, coords, baseColor);\n        break;\n      case 'MultiLineString':\n        if (Array.isArray(coords)) {\n          for (const line of coords) this._renderLine(grp, line, baseColor);\n        }\n        break;\n      case 'Polygon':\n        this._renderPolygon(grp, coords, baseColor);\n        break;\n      case 'MultiPolygon':\n        if (Array.isArray(coords)) {\n          for (const poly of coords) this._renderPolygon(grp, poly, baseColor);\n        }\n        break;\n      case 'GeometryCollection':\n        if (Array.isArray(geom.geometries)) {\n          for (const g of geom.geometries) {\n            this._renderGeometry(grp, g, baseColor);\n          }\n        }\n        break;\n    }\n  }\n\n  _toWorld(lon, lat, offsetM) {\n    if (!Number.isFinite(lat) || !Number.isFinite(lon)) return null;\n    const dir = latLonToLocalDir(lat, lon);\n    const r = ellipsoidRadiusForLocalDir(dir) + offsetM;\n    return dir.multiplyScalar(r);\n  }\n\n  _renderPoint(grp, coord, color) {\n    const pos = this._toWorld(coord[0], coord[1], POLYGON_OFFSET_M);\n    if (!pos) return;\n    const geo = new THREE.BufferGeometry();\n    geo.setAttribute('position', new THREE.Float32BufferAttribute([pos.x, pos.y, pos.z], 3));\n    const mat = new THREE.PointsMaterial({\n      color: new THREE.Color(color),\n      size: POINT_SIZE,\n      sizeAttenuation: true,\n      opacity: LINE_OPACITY,\n      transparent: true,\n    });\n    const points = new THREE.Points(geo, mat);\n    points.renderOrder = 7;\n    points.frustumCulled = false;\n    grp.add(points);\n  }\n\n  _renderLine(grp, coords, color) {\n    if (!Array.isArray(coords) || coords.length < 2) return;\n    const positions = [];\n    for (let i = 0; i < coords.length - 1; i++) {\n      const a = this._toWorld(coords[i][0], coords[i][1], POLYGON_OFFSET_M);\n      const b = this._toWorld(coords[i + 1][0], coords[i + 1][1], POLYGON_OFFSET_M);\n      if (!a || !b) continue;\n      positions.push(a.x, a.y, a.z, b.x, b.y, b.z);\n    }\n    if (!positions.length) return;\n    const geo = new THREE.BufferGeometry();\n    geo.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3));\n    const mat = new THREE.LineBasicMaterial({\n      color: new THREE.Color(color),\n      opacity: LINE_OPACITY,\n      transparent: true,\n    });\n    const lines = new THREE.LineSegments(geo, mat);\n    lines.renderOrder = 6;\n    lines.frustumCulled = false;\n    grp.add(lines);\n  }\n\n  _renderPolygon(grp, rings, color) {\n    if (!Array.isArray(rings)) return;\n    for (const ring of rings) {\n      if (!Array.isArray(ring) || ring.length < 2) continue;\n      this._renderLine(grp, ring, color);\n      const first = ring[0];\n      const last = ring[ring.length - 1];\n      if (first && last && (first[0] !== last[0] || first[1] !== last[1])) {\n        this._renderLine(grp, [last, first], color);\n      }\n    }\n\n    const outer = rings[0];\n    if (!Array.isArray(outer) || outer.length < 3) return;\n\n    let sumLat = 0, sumLon = 0, count = 0;\n    for (const c of outer) {\n      if (Array.isArray(c) && Number.isFinite(c[0]) && Number.isFinite(c[1])) {\n        sumLon += c[0]; sumLat += c[1]; count++;\n      }\n    }\n    if (count < 3) return;\n\n    const spanLat = Math.max(...outer.map(c => c[1])) - Math.min(...outer.map(c => c[1]));\n    const spanLon = Math.max(...outer.map(c => c[0])) - Math.min(...outer.map(c => c[0]));\n    if (spanLat > 60 || spanLon > 60) return;\n\n    // Altitude-dependent fill opacity\n    const altFill = THREE.MathUtils.lerp(FILL_OPACITY_MAX, FILL_OPACITY_BASE,\n      Math.min(1, Math.max(0, (this._currentAltitudeM - ALT_SURFACE_M) / (ALT_MED_M - ALT_SURFACE_M))));\n\n    const fillPositions = [];\n    const centerPos = this._toWorld(sumLon / count, sumLat / count, POLYGON_OFFSET_M);\n    if (!centerPos) return;\n\n    for (let i = 0; i < outer.length; i++) {\n      const a = this._toWorld(outer[i][0], outer[i][1], POLYGON_OFFSET_M);\n      const next = outer[(i + 1) % outer.length];\n      const b = this._toWorld(next[0], next[1], POLYGON_OFFSET_M);\n      if (!a || !b) continue;\n      fillPositions.push(\n        centerPos.x, centerPos.y, centerPos.z,\n        a.x, a.y, a.z,\n        b.x, b.y, b.z\n      );\n    }\n\n    if (!fillPositions.length) return;\n    const geo = new THREE.BufferGeometry();\n    geo.setAttribute('position', new THREE.Float32BufferAttribute(fillPositions, 3));\n    const mat = new THREE.MeshBasicMaterial({\n      color: new THREE.Color(color),\n      opacity: altFill,\n      transparent: true,\n      depthWrite: false,\n      side: THREE.DoubleSide,\n    });\n    const mesh = new THREE.Mesh(geo, mat);\n    mesh.renderOrder = 5;\n    mesh.frustumCulled = false;\n    grp.add(mesh);\n  }\n}\n\nlet _instance = null;\n\nexport function getSensorOverlay(opts) {\n  if (!_instance && opts) _instance = new SensorOverlay(opts);\n  return _instance;\n}\n","const DB_NAME = 'noclip-meshtastic';\nconst DB_VERSION = 2;\nconst MESSAGE_STORE = 'messages';\nconst READ_STORE = 'threadReads';\nconst META_STORE = 'meta';\nconst MAX_LOCAL_MESSAGES_PER_THREAD = 1000;\n\nexport function canonicalMeshtasticNodeId(value, fallback = 'unknown') {\n  const text = String(value ?? '').trim().toLowerCase();\n  if (!text || text === 'local') return fallback;\n  if (text === 'broadcast' || text === '^all') return 'broadcast';\n  if (/^![0-9a-f]+$/.test(text)) return `!${text.slice(1).padStart(8, '0')}`;\n  if (/^0x[0-9a-f]+$/.test(text)) return `!${text.slice(2).padStart(8, '0')}`;\n  return text;\n}\n\nfunction fnv1a(value) {\n  let hash = 0x811c9dc5;\n  for (let index = 0; index < value.length; index += 1) {\n    hash ^= value.charCodeAt(index);\n    hash = Math.imul(hash, 0x01000193);\n  }\n  return (hash >>> 0).toString(16).padStart(8, '0');\n}\n\nfunction requestResult(request) {\n  return new Promise((resolve, reject) => {\n    request.onsuccess = () => resolve(request.result);\n    request.onerror = () => reject(request.error);\n  });\n}\n\nfunction transactionDone(transaction) {\n  return new Promise((resolve, reject) => {\n    transaction.oncomplete = () => resolve();\n    transaction.onerror = () => reject(transaction.error);\n    transaction.onabort = () => reject(transaction.error || new Error('IndexedDB transaction aborted'));\n  });\n}\n\nlet dbPromise = null;\nfunction openDatabase() {\n  if (typeof indexedDB === 'undefined') return Promise.resolve(null);\n  if (dbPromise) return dbPromise;\n  dbPromise = new Promise((resolve, reject) => {\n    const request = indexedDB.open(DB_NAME, DB_VERSION);\n    request.onupgradeneeded = () => {\n      const db = request.result;\n      if (!db.objectStoreNames.contains(MESSAGE_STORE)) {\n        const messages = db.createObjectStore(MESSAGE_STORE, { keyPath: 'id' });\n        messages.createIndex('threadTimestamp', ['threadKey', 'timestamp']);\n        messages.createIndex('syncState', 'syncState');\n        messages.createIndex('updatedAt', 'updatedAt');\n      }\n      if (!db.objectStoreNames.contains(READ_STORE)) {\n        db.createObjectStore(READ_STORE, { keyPath: 'threadKey' });\n      }\n      if (!db.objectStoreNames.contains(META_STORE)) {\n        db.createObjectStore(META_STORE, { keyPath: 'key' });\n      }\n    };\n    request.onsuccess = () => resolve(request.result);\n    request.onerror = () => {\n      dbPromise = null;\n      reject(request.error);\n    };\n  });\n  return dbPromise;\n}\n\nexport function getMeshtasticPeerId(message, localNodeId = null) {\n  const local = canonicalMeshtasticNodeId(localNodeId, 'local');\n  const from = canonicalMeshtasticNodeId(message?.from, 'unknown');\n  const to = canonicalMeshtasticNodeId(message?.to, 'broadcast');\n  if (to === 'broadcast') return 'broadcast';\n  if (message?.outgoing || from === 'local' || from === local) return to;\n  return from;\n}\n\nexport function buildMeshtasticThreadKey(localNodeId, peerNodeId, channel = 0) {\n  return `${canonicalMeshtasticNodeId(localNodeId, 'local')}|${canonicalMeshtasticNodeId(peerNodeId)}|${Number(channel) || 0}`;\n}\n\nexport function createMeshtasticMessageId(message, localNodeId = null) {\n  const local = canonicalMeshtasticNodeId(localNodeId, 'local');\n  const from = canonicalMeshtasticNodeId(message?.from, message?.outgoing ? local : 'unknown');\n  const to = canonicalMeshtasticNodeId(message?.to, 'broadcast');\n  const channel = Number(message?.channel) || 0;\n  const packetId = message?.packetId == null ? null : Number(message.packetId);\n  if (Number.isFinite(packetId)) {\n    return `mesh:${local}:${from}:${to}:${channel}:${packetId >>> 0}`;\n  }\n  const fingerprint = [local, from, to, channel, Number(message?.timestamp) || 0, String(message?.text || '')].join('\\u001f');\n  return `mesh:${local}:fallback:${fnv1a(fingerprint)}`;\n}\n\nexport function normalizeStoredMeshtasticMessage(message, localNodeId = null) {\n  const local = canonicalMeshtasticNodeId(message?.localNodeId ?? localNodeId, 'local');\n  const from = canonicalMeshtasticNodeId(message?.from, message?.outgoing ? local : 'unknown');\n  const to = canonicalMeshtasticNodeId(message?.to, 'broadcast');\n  // @meshtastic/core deliberately emits a local echo for sendText() without\n  // an `outgoing` property. Direction is a fact of the packet endpoints, not\n  // an optional UI hint, once the connected radio identity is known.\n  const outgoing = Boolean(message?.outgoing) || (local !== 'local' && from === local);\n  const channel = Number(message?.channel) || 0;\n  const peerNodeId = canonicalMeshtasticNodeId(\n    getMeshtasticPeerId({ ...message, from, to, outgoing }, local),\n  );\n  const timestamp = Number(message?.timestamp) || Date.now();\n  const updatedAt = Number(message?.updatedAt) || timestamp;\n  let deliveryStatus = message?.deliveryStatus || (outgoing ? 'gateway-sent' : 'received');\n  if (outgoing && deliveryStatus === 'received') deliveryStatus = 'gateway-sent';\n  const normalized = {\n    ...message,\n    localNodeId: local,\n    peerNodeId,\n    threadKey: buildMeshtasticThreadKey(local, peerNodeId, channel),\n    from,\n    to,\n    channel,\n    outgoing,\n    timestamp,\n    updatedAt,\n    deliveryStatus,\n    readAt: Number(message?.readAt) || null,\n    packetId: message?.packetId != null && Number.isFinite(Number(message.packetId))\n      ? Number(message.packetId)\n      : null,\n    syncState: message?.syncState || 'pending',\n  };\n  const canonicalId = createMeshtasticMessageId(normalized, local);\n  // A radio packet ID is the durable identity. Client-generated optimistic IDs\n  // only exist until the transport assigns a packet ID.\n  normalized.id = normalized.packetId == null ? String(message?.id || canonicalId) : canonicalId;\n  return normalized;\n}\n\nexport function mergeMeshtasticMessages(previous, incoming) {\n  if (!previous) return incoming;\n  if (!incoming) return previous;\n  if ((Number(incoming.updatedAt) || 0) < (Number(previous.updatedAt) || 0)) {\n    return {\n      ...incoming,\n      ...previous,\n      outgoing: Boolean(previous.outgoing || incoming.outgoing),\n      syncState: incoming.syncState === 'synced' ? 'synced' : previous.syncState,\n    };\n  }\n  return {\n    ...previous,\n    ...incoming,\n    outgoing: Boolean(previous.outgoing || incoming.outgoing),\n    readAt: Math.max(Number(previous.readAt) || 0, Number(incoming.readAt) || 0) || null,\n  };\n}\n\nexport class MeshtasticConversationStore {\n  constructor() {\n    this._memoryMessages = new Map();\n    this._memoryReads = new Map();\n  }\n\n  async putMessage(message, { localNodeId = null, synced = false } = {}) {\n    const next = normalizeStoredMeshtasticMessage({\n      ...message,\n      syncState: synced ? 'synced' : (message?.syncState || 'pending'),\n    }, localNodeId);\n    const db = await openDatabase().catch(() => null);\n    if (!db) {\n      const merged = mergeMeshtasticMessages(this._memoryMessages.get(next.id), next);\n      this._memoryMessages.set(merged.id, merged);\n      this._pruneMemoryThread(merged.threadKey);\n      return { ...merged };\n    }\n    const transaction = db.transaction(MESSAGE_STORE, 'readwrite');\n    const store = transaction.objectStore(MESSAGE_STORE);\n    const previous = await requestResult(store.get(next.id));\n    const merged = mergeMeshtasticMessages(previous, next);\n    store.put(merged);\n    await transactionDone(transaction);\n    await this.pruneThread(merged.threadKey);\n    return { ...merged };\n  }\n\n  /**\n   * Atomically replace an optimistic client identity with the radio packet\n   * identity. This is also safe when the SDK echo already inserted the target.\n   */\n  async replaceMessage(previousId, message, { localNodeId = null, synced = false } = {}) {\n    const next = normalizeStoredMeshtasticMessage({\n      ...message,\n      syncState: synced ? 'synced' : (message?.syncState || 'pending'),\n    }, localNodeId);\n    const oldId = String(previousId || '');\n    const db = await openDatabase().catch(() => null);\n    if (!db) {\n      const previous = this._memoryMessages.get(oldId);\n      const target = oldId === next.id ? previous : this._memoryMessages.get(next.id);\n      const merged = mergeMeshtasticMessages(mergeMeshtasticMessages(target, previous), next);\n      if (oldId && oldId !== next.id) this._memoryMessages.delete(oldId);\n      this._memoryMessages.set(next.id, merged);\n      this._pruneMemoryThread(merged.threadKey);\n      return { ...merged };\n    }\n    const transaction = db.transaction(MESSAGE_STORE, 'readwrite');\n    const store = transaction.objectStore(MESSAGE_STORE);\n    const previous = oldId ? await requestResult(store.get(oldId)) : null;\n    const target = oldId === next.id ? previous : await requestResult(store.get(next.id));\n    const merged = mergeMeshtasticMessages(mergeMeshtasticMessages(target, previous), next);\n    if (oldId && oldId !== next.id) store.delete(oldId);\n    store.put(merged);\n    await transactionDone(transaction);\n    await this.pruneThread(merged.threadKey);\n    return { ...merged };\n  }\n\n  /**\n   * Repair history written by clients that retained an optimistic ID after a\n   * packet ID was assigned. Colliding local-echo and optimistic rows merge in\n   * one IndexedDB transaction, preserving the newest receipt state.\n   */\n  async repairCanonicalMessageIdentity() {\n    const db = await openDatabase().catch(() => null);\n    const source = db\n      ? await requestResult(db.transaction(MESSAGE_STORE, 'readonly').objectStore(MESSAGE_STORE).getAll())\n      : Array.from(this._memoryMessages.values());\n    const canonical = new Map();\n    let repaired = 0;\n    for (const message of source) {\n      const next = normalizeStoredMeshtasticMessage(message, message?.localNodeId || 'local');\n      const identityChanged = next.id !== message.id\n        || next.outgoing !== message.outgoing\n        || next.peerNodeId !== message.peerNodeId\n        || next.threadKey !== message.threadKey\n        || next.deliveryStatus !== message.deliveryStatus;\n      if (identityChanged) {\n        repaired += 1;\n        next.syncState = 'pending';\n      }\n      canonical.set(next.id, mergeMeshtasticMessages(canonical.get(next.id), next));\n    }\n    const removed = Math.max(0, source.length - canonical.size);\n    if (!repaired && !removed) return { repaired: 0, removed: 0 };\n    if (!db) {\n      this._memoryMessages = canonical;\n      return { repaired, removed };\n    }\n    const transaction = db.transaction(MESSAGE_STORE, 'readwrite');\n    const store = transaction.objectStore(MESSAGE_STORE);\n    store.clear();\n    for (const message of canonical.values()) store.put(message);\n    await transactionDone(transaction);\n    return { repaired, removed };\n  }\n\n  async putMessages(messages, options = {}) {\n    const saved = [];\n    for (const message of Array.isArray(messages) ? messages : []) {\n      saved.push(await this.putMessage(message, options));\n    }\n    return saved;\n  }\n\n  async listThread(threadKey, { limit = 500 } = {}) {\n    const db = await openDatabase().catch(() => null);\n    let messages;\n    if (!db) {\n      messages = Array.from(this._memoryMessages.values()).filter((message) => message.threadKey === threadKey);\n    } else {\n      const transaction = db.transaction(MESSAGE_STORE, 'readonly');\n      const index = transaction.objectStore(MESSAGE_STORE).index('threadTimestamp');\n      const range = IDBKeyRange.bound([threadKey, 0], [threadKey, Number.MAX_SAFE_INTEGER]);\n      messages = await requestResult(index.getAll(range));\n    }\n    return messages\n      .sort((a, b) => a.timestamp - b.timestamp || a.id.localeCompare(b.id))\n      .slice(-Math.max(1, limit))\n      .map((message) => ({ ...message }));\n  }\n\n  async listRecent({ limit = 256 } = {}) {\n    const db = await openDatabase().catch(() => null);\n    let messages;\n    if (!db) {\n      messages = Array.from(this._memoryMessages.values());\n    } else {\n      const transaction = db.transaction(MESSAGE_STORE, 'readonly');\n      messages = await requestResult(transaction.objectStore(MESSAGE_STORE).getAll());\n    }\n    return messages\n      .sort((a, b) => a.timestamp - b.timestamp || a.id.localeCompare(b.id))\n      .slice(-Math.max(1, limit))\n      .map((message) => ({ ...message }));\n  }\n\n  async listPendingSync({ limit = 200 } = {}) {\n    const db = await openDatabase().catch(() => null);\n    let messages;\n    if (!db) {\n      messages = Array.from(this._memoryMessages.values()).filter((message) => message.syncState !== 'synced');\n    } else {\n      const transaction = db.transaction(MESSAGE_STORE, 'readonly');\n      messages = await requestResult(transaction.objectStore(MESSAGE_STORE).getAll());\n      messages = messages.filter((message) => message.syncState !== 'synced');\n    }\n    return messages.sort((a, b) => a.updatedAt - b.updatedAt).slice(0, limit).map((message) => ({ ...message }));\n  }\n\n  async markMessagesSynced(ids) {\n    for (const id of Array.isArray(ids) ? ids : []) {\n      const existing = await this.getMessage(id);\n      if (existing) await this.putMessage({ ...existing, syncState: 'synced' }, { synced: true });\n    }\n  }\n\n  async getMessage(id) {\n    const db = await openDatabase().catch(() => null);\n    if (!db) return this._memoryMessages.has(id) ? { ...this._memoryMessages.get(id) } : null;\n    const transaction = db.transaction(MESSAGE_STORE, 'readonly');\n    const message = await requestResult(transaction.objectStore(MESSAGE_STORE).get(id));\n    return message ? { ...message } : null;\n  }\n\n  async markThreadRead(threadKey, readAt = Date.now()) {\n    const state = { threadKey, readAt: Number(readAt) || Date.now(), syncState: 'pending' };\n    const db = await openDatabase().catch(() => null);\n    if (!db) {\n      this._memoryReads.set(threadKey, state);\n      for (const [id, message] of this._memoryMessages) {\n        if (message.threadKey === threadKey && !message.outgoing && !message.readAt) {\n          this._memoryMessages.set(id, { ...message, readAt: state.readAt, updatedAt: state.readAt, syncState: 'pending' });\n        }\n      }\n      return { ...state };\n    }\n    const transaction = db.transaction([MESSAGE_STORE, READ_STORE], 'readwrite');\n    transaction.objectStore(READ_STORE).put(state);\n    const messages = transaction.objectStore(MESSAGE_STORE);\n    const index = messages.index('threadTimestamp');\n    const range = IDBKeyRange.bound([threadKey, 0], [threadKey, Number.MAX_SAFE_INTEGER]);\n    const threadMessages = await requestResult(index.getAll(range));\n    for (const message of threadMessages) {\n      if (!message.outgoing && !message.readAt) {\n        messages.put({ ...message, readAt: state.readAt, updatedAt: state.readAt, syncState: 'pending' });\n      }\n    }\n    await transactionDone(transaction);\n    return { ...state };\n  }\n\n  async listReadStates({ pendingOnly = false } = {}) {\n    const db = await openDatabase().catch(() => null);\n    let states;\n    if (!db) states = Array.from(this._memoryReads.values());\n    else {\n      const transaction = db.transaction(READ_STORE, 'readonly');\n      states = await requestResult(transaction.objectStore(READ_STORE).getAll());\n    }\n    return states.filter((state) => !pendingOnly || state.syncState !== 'synced').map((state) => ({ ...state }));\n  }\n\n  async putReadStates(states, { synced = false } = {}) {\n    const db = await openDatabase().catch(() => null);\n    for (const incoming of Array.isArray(states) ? states : []) {\n      if (!incoming?.threadKey) continue;\n      const current = db\n        ? await requestResult(db.transaction(READ_STORE, 'readonly').objectStore(READ_STORE).get(incoming.threadKey))\n        : this._memoryReads.get(incoming.threadKey);\n      const next = Number(incoming.readAt) >= Number(current?.readAt || 0)\n        ? { ...current, ...incoming, syncState: synced ? 'synced' : (incoming.syncState || 'pending') }\n        : current;\n      if (!next) continue;\n      if (!db) this._memoryReads.set(next.threadKey, next);\n      else {\n        const transaction = db.transaction(READ_STORE, 'readwrite');\n        transaction.objectStore(READ_STORE).put(next);\n        await transactionDone(transaction);\n      }\n    }\n  }\n\n  async getMeta(key) {\n    const db = await openDatabase().catch(() => null);\n    if (!db) return null;\n    const transaction = db.transaction(META_STORE, 'readonly');\n    const entry = await requestResult(transaction.objectStore(META_STORE).get(String(key)));\n    return entry?.value ?? null;\n  }\n\n  async setMeta(key, value) {\n    const db = await openDatabase().catch(() => null);\n    if (!db) return value;\n    const transaction = db.transaction(META_STORE, 'readwrite');\n    transaction.objectStore(META_STORE).put({ key: String(key), value });\n    await transactionDone(transaction);\n    return value;\n  }\n\n  async pruneThread(threadKey, maxMessages = MAX_LOCAL_MESSAGES_PER_THREAD) {\n    const messages = await this.listThread(threadKey, { limit: Number.MAX_SAFE_INTEGER });\n    const remove = messages.slice(0, Math.max(0, messages.length - maxMessages));\n    if (!remove.length) return;\n    const db = await openDatabase().catch(() => null);\n    if (!db) {\n      for (const message of remove) this._memoryMessages.delete(message.id);\n      return;\n    }\n    const transaction = db.transaction(MESSAGE_STORE, 'readwrite');\n    for (const message of remove) transaction.objectStore(MESSAGE_STORE).delete(message.id);\n    await transactionDone(transaction);\n  }\n\n  _pruneMemoryThread(threadKey) {\n    const messages = Array.from(this._memoryMessages.values())\n      .filter((message) => message.threadKey === threadKey)\n      .sort((a, b) => a.timestamp - b.timestamp);\n    for (const message of messages.slice(0, Math.max(0, messages.length - MAX_LOCAL_MESSAGES_PER_THREAD))) {\n      this._memoryMessages.delete(message.id);\n    }\n  }\n}\n\nlet singleton = null;\nexport function getMeshtasticConversationStore() {\n  if (!singleton) singleton = new MeshtasticConversationStore();\n  return singleton;\n}\n","import { getAuthService } from '../auth/AuthService.js';\nimport { getBackendApiBase } from '../shared/backend.js';\nimport { getMeshtasticConversationStore } from './MeshtasticConversationStore.js';\n\nconst API_BASE = getBackendApiBase();\nconst SYNC_PAGE_SIZE = 500;\n\nfunction parseTimestamp(value) {\n  if (typeof value === 'number' && Number.isFinite(value)) return value;\n  const parsed = Date.parse(String(value || ''));\n  return Number.isFinite(parsed) ? parsed : 0;\n}\n\nfunction publicMessage(message) {\n  return {\n    id: message.id,\n    localNodeId: message.localNodeId,\n    peerNodeId: message.peerNodeId,\n    threadKey: message.threadKey,\n    from: message.from,\n    to: message.to,\n    channel: message.channel,\n    text: message.text,\n    timestamp: message.timestamp,\n    outgoing: message.outgoing,\n    packetId: message.packetId,\n    deliveryStatus: message.deliveryStatus,\n    deliveryError: message.deliveryError || null,\n    readAt: message.readAt,\n    updatedAt: message.updatedAt,\n  };\n}\n\nexport class MeshtasticSyncService {\n  constructor({ store = getMeshtasticConversationStore(), authService = getAuthService() } = {}) {\n    this.store = store;\n    this.authService = authService;\n    this._syncPromise = null;\n    this._unsubscribeAuth = this.authService.subscribe?.((state) => {\n      if (state?.isAuthenticated) void this.syncNow();\n    }) ?? null;\n    this._onlineHandler = () => void this.syncNow();\n    globalThis.addEventListener?.('online', this._onlineHandler);\n  }\n\n  get isAuthenticated() {\n    return Boolean(this.authService.getState?.().isAuthenticated);\n  }\n\n  async syncNow() {\n    if (!this.isAuthenticated) return { pushed: 0, pulled: 0 };\n    if (this._syncPromise) return this._syncPromise;\n    this._syncPromise = this._performSync().finally(() => {\n      this._syncPromise = null;\n    });\n    return this._syncPromise;\n  }\n\n  async _performSync() {\n    const state = this.authService.getState();\n    const userId = String(state?.user?.id || state?.user?.userId || 'account');\n    let pendingReads = await this.store.listReadStates({ pendingOnly: true });\n    let pushed = 0;\n\n    while (true) {\n      const pendingMessages = await this.store.listPendingSync({ limit: SYNC_PAGE_SIZE });\n      if (!pendingMessages.length && !pendingReads.length) break;\n      const response = await this.authService.authenticatedFetch(`${API_BASE}/chat/meshtastic/sync`, {\n        method: 'POST',\n        headers: { 'Content-Type': 'application/json' },\n        body: JSON.stringify({\n          messages: pendingMessages.map(publicMessage),\n          readStates: pendingReads.map(({ threadKey, readAt }) => ({ threadKey, readAt })),\n        }),\n      });\n      const data = await response.json().catch(() => ({}));\n      if (!response.ok) throw new Error(data?.message || data?.error || 'Meshtastic history sync failed');\n      await this.store.markMessagesSynced(data.acceptedMessageIds || pendingMessages.map((message) => message.id));\n      await this.store.putReadStates(pendingReads, { synced: true });\n      pushed += pendingMessages.length;\n      pendingReads = [];\n      if (pendingMessages.length < SYNC_PAGE_SIZE) break;\n    }\n\n    const storageKey = `syncCursor:${userId}`;\n    const savedCursor = Number(await this.store.getMeta?.(storageKey)) || 0;\n    let offset = 0;\n    let pulled = 0;\n    let newestUpdate = savedCursor;\n    while (true) {\n      const params = new URLSearchParams({\n        updatedAfter: String(savedCursor),\n        limit: String(SYNC_PAGE_SIZE),\n        offset: String(offset),\n      });\n      const response = await this.authService.authenticatedFetch(`${API_BASE}/chat/meshtastic/sync?${params}`);\n      const data = await response.json().catch(() => ({}));\n      if (!response.ok) throw new Error(data?.message || data?.error || 'Meshtastic history pull failed');\n      const messages = Array.isArray(data.messages) ? data.messages : [];\n      const readStates = Array.isArray(data.readStates) ? data.readStates : [];\n      await this.store.putMessages(messages.map((message) => ({ ...message, syncState: 'synced' })), { synced: true });\n      await this.store.putReadStates(readStates.map((entry) => ({ ...entry, syncState: 'synced' })), { synced: true });\n      pulled += messages.length;\n      for (const message of messages) {\n        newestUpdate = Math.max(newestUpdate, parseTimestamp(message.serverUpdatedAt || message.updatedAt));\n      }\n      for (const read of readStates) newestUpdate = Math.max(newestUpdate, parseTimestamp(read.updatedAt || read.readAt));\n      if (messages.length < SYNC_PAGE_SIZE) break;\n      offset += messages.length;\n    }\n    if (newestUpdate > savedCursor) await this.store.setMeta?.(storageKey, newestUpdate);\n    return { pushed, pulled };\n  }\n\n  destroy() {\n    this._unsubscribeAuth?.();\n    this._unsubscribeAuth = null;\n    globalThis.removeEventListener?.('online', this._onlineHandler);\n  }\n}\n\nlet singleton = null;\nexport function getMeshtasticSyncService() {\n  if (!singleton) singleton = new MeshtasticSyncService();\n  return singleton;\n}\n","import {\n  buildMeshtasticThreadKey,\n  canonicalMeshtasticNodeId,\n  getMeshtasticConversationStore,\n  mergeMeshtasticMessages,\n  MeshtasticConversationStore,\n  normalizeStoredMeshtasticMessage,\n} from './MeshtasticConversationStore.js';\nimport { getMeshtasticSyncService } from './MeshtasticSyncService.js';\n\n/**\n * MeshtasticService\n *\n * Manages Meshtastic device data via two transport modes:\n *\n *   1. HTTP API mode (primary) — polls a meshtastic JSON API, either the\n *      noclip backend proxy at /api/meshtastic/nodes or a locally-running\n *      Python meshtastic_server at http://localhost:5555/api/nodes.\n *\n *   2. Web Serial mode — lazily loads the official Meshtastic core and Web\n *      Serial transport when the user requests a USB connection. An injected\n *      MeshtasticSerialCodec remains supported for isolated/offline harnesses.\n *\n * Emits on eventBus:\n *   meshtastic:nodes        — { nodes: MeshtasticNode[] }\n *   meshtastic:message      — { from, to, text, timestamp, channel }\n *   meshtastic:connected    — device connected (serial or first successful poll)\n *   meshtastic:disconnected — device disconnected\n *\n * Usage:\n *   const svc = getMeshtasticService({ eventBus, apiBase });\n *   await svc.startPolling();\n *   // or\n *   await svc.connectSerial();\n */\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_POLL_INTERVAL_MS = 30_000;\nconst SERIAL_BAUD_RATE = 115_200;\nconst SERIAL_HEARTBEAT_INTERVAL_MS = 5 * 60_000;\nconst MAX_MESSAGE_HISTORY = 256;\nconst SERIAL_AUTO_CONNECT_KEY = 'noclip.meshtastic.serial.autoConnect.v1';\nconst SERIAL_PORT_DESCRIPTOR_KEY = 'noclip.meshtastic.serial.port.v1';\nconst MAX_OWNER_LONG_NAME_BYTES = 40;\nconst MAX_OWNER_SHORT_NAME_BYTES = 4;\n\n/** Fallback local Python meshtastic_server base URL. */\nconst LOCAL_SERVER_BASE = 'http://localhost:5555';\n\nfunction normalizeBaseUrl(base) {\n  return String(base || '').trim().replace(/\\/+$/, '');\n}\n\nfunction readLocalStorage(key) {\n  try {\n    return globalThis.localStorage?.getItem?.(key) ?? null;\n  } catch {\n    return null;\n  }\n}\n\nfunction writeLocalStorage(key, value) {\n  try {\n    if (value == null) globalThis.localStorage?.removeItem?.(key);\n    else globalThis.localStorage?.setItem?.(key, String(value));\n  } catch {\n    // Storage can be unavailable in private/embedded contexts. The active\n    // session still honors the in-memory preference.\n  }\n}\n\nfunction readStoredPortDescriptor() {\n  try {\n    const value = JSON.parse(readLocalStorage(SERIAL_PORT_DESCRIPTOR_KEY) || 'null');\n    if (!value || typeof value !== 'object') return null;\n    const usbVendorId = Number(value.usbVendorId);\n    const usbProductId = Number(value.usbProductId);\n    if (!Number.isInteger(usbVendorId) || !Number.isInteger(usbProductId)) return null;\n    return { usbVendorId, usbProductId };\n  } catch {\n    return null;\n  }\n}\n\nfunction describeSerialPort(port) {\n  try {\n    const info = port?.getInfo?.() ?? {};\n    const usbVendorId = Number(info.usbVendorId);\n    const usbProductId = Number(info.usbProductId);\n    if (!Number.isInteger(usbVendorId) || !Number.isInteger(usbProductId)) return null;\n    return { usbVendorId, usbProductId };\n  } catch {\n    return null;\n  }\n}\n\nfunction sameSerialPortDescriptor(port, descriptor) {\n  if (!descriptor) return true;\n  const candidate = describeSerialPort(port);\n  return candidate?.usbVendorId === descriptor.usbVendorId\n    && candidate?.usbProductId === descriptor.usbProductId;\n}\n\nfunction utf8ByteLength(value) {\n  return new TextEncoder().encode(String(value ?? '')).byteLength;\n}\n\nfunction normalizeAdvertisedNodeId(value) {\n  const id = String(value || '').trim().toLowerCase();\n  if (!/^![0-9a-f]{8}$/.test(id)) {\n    throw new Error('Advertised node ID must be ! followed by exactly 8 hexadecimal characters.');\n  }\n  return id;\n}\n\nfunction joinApiPath(base, path) {\n  const cleanBase = normalizeBaseUrl(base);\n  if (!cleanBase) return path;\n  if (cleanBase.endsWith('/api') && path.startsWith('/api/')) {\n    return `${cleanBase}${path.slice(4)}`;\n  }\n  return `${cleanBase}${path}`;\n}\n\nfunction getGlobalSerialCodec() {\n  const codec = globalThis.MeshtasticSerialCodec;\n  if (\n    codec &&\n    typeof codec.decodeFromRadio === 'function' &&\n    typeof codec.encodeTextPacket === 'function'\n  ) {\n    return codec;\n  }\n  return null;\n}\n\nfunction nodeIdFromNum(value) {\n  if (value == null || value === '') return null;\n  const num = Number(value);\n  if (!Number.isFinite(num)) return null;\n  return `!${(num >>> 0).toString(16).padStart(8, '0')}`;\n}\n\nfunction normalizeDestination(value) {\n  const target = String(value || '').trim();\n  if (!target || target === 'broadcast' || target === '^all') return 'broadcast';\n  const hex = target.match(/^!([0-9a-f]{1,8})$/i);\n  if (hex) return Number.parseInt(hex[1], 16) >>> 0;\n  if (/^\\d+$/.test(target)) {\n    const num = Number(target);\n    if (Number.isSafeInteger(num) && num >= 0 && num <= 0xffffffff) {\n      return num >>> 0;\n    }\n  }\n  throw new Error(`Invalid Meshtastic destination: ${target}`);\n}\n\nfunction dateToUnixSeconds(value) {\n  if (value instanceof Date && Number.isFinite(value.getTime())) {\n    return Math.floor(value.getTime() / 1000);\n  }\n  const numeric = Number(value);\n  if (!Number.isFinite(numeric)) return 0;\n  return numeric > 10_000_000_000 ? Math.floor(numeric / 1000) : Math.floor(numeric);\n}\n\nfunction dateToUnixMilliseconds(value) {\n  if (value instanceof Date && Number.isFinite(value.getTime())) return value.getTime();\n  const numeric = Number(value);\n  if (!Number.isFinite(numeric)) return Date.now();\n  return numeric < 100_000_000_000 ? numeric * 1000 : numeric;\n}\n\nfunction asUint8Array(value) {\n  if (value instanceof Uint8Array) return value;\n  if (value instanceof ArrayBuffer) return new Uint8Array(value);\n  if (ArrayBuffer.isView(value)) return new Uint8Array(value.buffer, value.byteOffset, value.byteLength);\n  if (Array.isArray(value)) return Uint8Array.from(value);\n  throw new Error('Serial codec returned a non-binary payload.');\n}\n\n/**\n * @typedef {Object} MeshtasticNode\n * @property {string}      id           — hex node ID e.g. \"!849ac7f4\"\n * @property {number}      num          — numeric node ID\n * @property {string}      user         — long name\n * @property {string}      shortName    — 4-char short name\n * @property {string|null} hardware     — hardware model string\n * @property {string|null} role         — device role (\"CLIENT\", \"ROUTER\", etc.)\n * @property {number}      lastHeard    — unix seconds\n * @property {number|null} snr          — signal-to-noise ratio (dB)\n * @property {number|null} hopsAway     — hop count from us\n * @property {number|null} lat          — WGS84 latitude degrees\n * @property {number|null} lon          — WGS84 longitude degrees\n * @property {number|null} altitude     — meters above sea level\n * @property {number|null} batteryLevel — 0-100 or null\n */\n\n/**\n * @typedef {Object} MeshtasticMessage\n * @property {string} from\n * @property {string} to\n * @property {string} text\n * @property {number} timestamp — unix milliseconds\n * @property {number} channel\n */\n\n// ---------------------------------------------------------------------------\n// Normalisation helpers\n// ---------------------------------------------------------------------------\n\nconst toNumber = (v) => {\n  if (v == null || (typeof v === 'string' && v.trim() === '') || typeof v === 'boolean') return null;\n  const number = Number(v);\n  return Number.isFinite(number) ? number : null;\n};\nconst toStr = (v) => (typeof v === 'string' ? v.trim() : v != null ? String(v) : null);\n\nconst validLatitude = (value) => Number.isFinite(value) && value >= -90 && value <= 90;\nconst validLongitude = (value) => Number.isFinite(value) && value >= -180 && value <= 180;\n\n/**\n * Resolve one complete WGS84 pair from the shapes emitted by Meshtastic's\n * official JS client, protobuf JSON, and meshtastic_map_oneshot. Protobuf\n * scalar defaults expose an unset position as 0/0, so that exact pair is\n * treated as absent. A single zero remains valid when its companion\n * coordinate is non-zero (equator or prime meridian).\n *\n * Integer E7 fields are authoritative when populated. This is important for\n * official packets which may expose default decimal fields alongside a valid\n * latitudeI/longitudeI pair.\n *\n * @param {Object} raw\n * @returns {{ lat: number|null, lon: number|null }}\n */\nexport function resolveMeshtasticPosition(raw) {\n  if (!raw || typeof raw !== 'object') return { lat: null, lon: null };\n\n  const candidates = [];\n  const addCandidate = (candidate) => {\n    if (!candidate || typeof candidate !== 'object' || candidates.includes(candidate)) return;\n    candidates.push(candidate);\n  };\n  addCandidate(raw.position);\n  addCandidate(raw.data?.position);\n  addCandidate(raw.data);\n  addCandidate(raw);\n\n  for (const candidate of candidates) {\n    const latitudeI = toNumber(candidate.latitudeI ?? candidate.latitude_i);\n    const longitudeI = toNumber(candidate.longitudeI ?? candidate.longitude_i);\n    if (latitudeI == null || longitudeI == null) continue;\n    const lat = latitudeI / 1e7;\n    const lon = longitudeI / 1e7;\n    if (validLatitude(lat) && validLongitude(lon) && (lat !== 0 || lon !== 0)) {\n      return { lat, lon };\n    }\n  }\n\n  for (const candidate of candidates) {\n    const lat = toNumber(candidate.latitude ?? candidate.lat);\n    const lon = toNumber(candidate.longitude ?? candidate.lon ?? candidate.lng);\n    if (validLatitude(lat) && validLongitude(lon) && (lat !== 0 || lon !== 0)) {\n      return { lat, lon };\n    }\n  }\n\n  return { lat: null, lon: null };\n}\n\n/**\n * Coerce a raw API response object into a canonical MeshtasticNode shape.\n * Handles both the noclip backend schema and the Python meshtastic_server schema.\n *\n * @param {Object} raw\n * @returns {MeshtasticNode|null}\n */\nexport function normalizeMeshtasticNode(raw) {\n  if (!raw || typeof raw !== 'object') return null;\n\n  // Support both nested user object (official API) and flat schema (Python server)\n  const user = raw.user && typeof raw.user === 'object' ? raw.user : {};\n  const flatUserName = typeof raw.user === 'string' ? raw.user : null;\n  const pos = raw.position || raw.data?.position || raw.data || {};\n\n  // Node ID — prefer string \"!hex\" form\n  const num = toNumber(raw.num ?? raw.nodeNum ?? user.id);\n  // Routing identity is the packet/node number. User.id is owner metadata and\n  // can be edited independently, so it must not re-key the live node roster.\n  const id = toStr(raw.id) || nodeIdFromNum(num) || toStr(user.id);\n  if (!id && num == null) return null;\n\n  const { lat, lon } = resolveMeshtasticPosition(raw);\n\n  return {\n    id: id ?? nodeIdFromNum(num),\n    num: num ?? 0,\n    user: toStr(user.longName ?? user.long_name ?? raw.longName ?? raw.user_name ?? flatUserName) ?? id ?? 'Unknown',\n    shortName: toStr(user.shortName ?? user.short_name ?? raw.shortName ?? raw.short_name) ?? '????',\n    hardware: toStr(user.hwModel ?? user.hw_model ?? raw.hardware ?? raw.hwModel) ?? null,\n    role: toStr(user.role ?? raw.role) ?? null,\n    lastHeard: toNumber(raw.lastHeard ?? raw.last_heard ?? raw.lastSeen) ?? 0,\n    snr: toNumber(raw.snr ?? raw.SNR),\n    hopsAway: toNumber(raw.hopsAway ?? raw.hops_away),\n    lat: Number.isFinite(lat) ? lat : null,\n    lon: Number.isFinite(lon) ? lon : null,\n    altitude: toNumber(pos.altitude ?? pos.alt ?? raw.altitude),\n    batteryLevel: toNumber(raw.batteryLevel ?? raw.battery_level ?? raw.deviceMetrics?.batteryLevel),\n  };\n}\n\nconst normalizeNode = normalizeMeshtasticNode;\n\n/**\n * Coerce a raw message object into a canonical MeshtasticMessage shape.\n *\n * @param {Object} raw\n * @returns {MeshtasticMessage|null}\n */\nfunction normalizeMessage(raw) {\n  if (!raw || typeof raw !== 'object') return null;\n  const rawFrom = raw.from ?? raw.fromId;\n  const rawTo = raw.to ?? raw.toId;\n  const from = typeof rawFrom === 'number' ? nodeIdFromNum(rawFrom) : toStr(rawFrom);\n  const to = Number(rawTo) === 0xffffffff\n    ? 'broadcast'\n    : (typeof rawTo === 'number' ? nodeIdFromNum(rawTo) : toStr(rawTo));\n  const text = toStr(raw.text ?? raw.message ?? raw.data ?? raw.payload?.text);\n  if (!text) return null;\n  return {\n    from: from ?? 'unknown',\n    to: to ?? 'broadcast',\n    text,\n    timestamp: dateToUnixMilliseconds(raw.timestamp ?? raw.rxTime),\n    channel: toNumber(raw.channel ?? raw.chan) ?? 0,\n    packetId: toNumber(raw.id ?? raw.packetId ?? raw.packet_id),\n    outgoing: Boolean(raw.outgoing),\n  };\n}\n\n// ---------------------------------------------------------------------------\n// MeshtasticService\n// ---------------------------------------------------------------------------\n\nconst MESHTASTIC_NODE_CACHE_KEY = 'noclip:meshtastic:nodes:v1';\nconst MESHTASTIC_NODE_CACHE_LIMIT = 5000;\n\nexport class MeshtasticService {\n  /**\n   * @param {Object} [opts]\n   * @param {Object} [opts.eventBus]  — noclip event bus ({ emit, on, off })\n   * @param {string} [opts.apiBase]   — base URL for the noclip backend proxy\n   * @param {Object} [opts.serialCodec] — optional Meshtastic protobuf codec\n   * @param {Function} [opts.serialClientFactory] — optional Web Serial client factory for harnesses\n   */\n  constructor({\n    eventBus,\n    apiBase,\n    serialCodec,\n    serialClientFactory,\n    conversationStore,\n    syncService,\n  } = {}) {\n    this.eventBus = eventBus ?? null;\n    const defaultApiBase = typeof window !== 'undefined' ? window.location.origin : '';\n    this.apiBase = normalizeBaseUrl(typeof apiBase === 'string' ? apiBase : defaultApiBase);\n    this.localServerBase = LOCAL_SERVER_BASE;\n\n    /** @type {Map<string, MeshtasticNode>} */\n    this._nodes = new Map();\n    this._hydrateNodeCache();\n\n    /** @type {MeshtasticMessage[]} */\n    this._messageHistory = [];\n\n    /** @type {Array<(msg: MeshtasticMessage) => void>} */\n    this._messageHandlers = [];\n    this._messageUpdateHandlers = [];\n    this._localNodeId = null;\n    this._localOwner = null;\n    this._userRecords = new Map();\n    this._pendingOutbound = new Map();\n    this._lastOutgoingTimestamp = 0;\n    const isBrowserRuntime = typeof window !== 'undefined';\n    this._conversationStore = conversationStore\n      ?? (isBrowserRuntime ? getMeshtasticConversationStore() : new MeshtasticConversationStore());\n    this._syncService = syncService\n      ?? (isBrowserRuntime ? getMeshtasticSyncService() : { syncNow: async () => ({ pushed: 0, pulled: 0 }) });\n    this.ready = this._hydrateConversationHistory();\n\n    this._pollTimer = null;\n    this._polling = false;\n    this._connected = false;\n    this._useFallback = false;  // flip to true when primary endpoint 404s\n\n    // Serial state\n    this._serialPort = null;\n    this._serialReader = null;\n    this._serialWriter = null;\n    this._serialReadLoopActive = false;\n    this._serialCodec = serialCodec ?? getGlobalSerialCodec();\n    this._serialClientFactory = serialClientFactory ?? null;\n    this._meshDevice = null;\n    this._serialTransport = null;\n    this._serialTypes = null;\n    this._serialProtobuf = null;\n    this._serialMode = null;\n    this._officialSerialPort = null;\n    this._serialConnectPromise = null;\n    this._autoConnectEnabled = readLocalStorage(SERIAL_AUTO_CONNECT_KEY) === 'true';\n    this._autoConnectState = this._autoConnectEnabled ? 'idle' : 'disabled';\n    this._boundSerialConnect = (event) => {\n      if (!this._autoConnectEnabled || this.isSerialConnected) return;\n      const port = event?.port;\n      if (!port) return;\n      void this.tryAutoConnectSerial({ port }).catch(() => {});\n    };\n    globalThis.navigator?.serial?.addEventListener?.('connect', this._boundSerialConnect);\n    if (this._autoConnectEnabled) {\n      queueMicrotask(() => void this.tryAutoConnectSerial().catch(() => {}));\n    }\n  }\n\n  // ── Public API ─────────────────────────────────────────────────────────────\n\n  /** Current snapshot of all known nodes (defensive copy). */\n  get nodes() {\n    return Array.from(this._nodes.values());\n  }\n\n  /** Bounded chronological transcript shared by every Meshtastic UI surface. */\n  get messageHistory() {\n    return this._messageHistory.map((message) => ({ ...message }));\n  }\n\n  /** Canonical node ID reported by the directly-connected radio. */\n  get localNodeId() {\n    return this._localNodeId;\n  }\n\n  /** Best available roster record for the directly-connected radio. */\n  get localNode() {\n    if (!this._localNodeId) return null;\n    const node = this._nodes.get(this._localNodeId);\n    return node ? { ...node } : { id: this._localNodeId, user: this._localNodeId, shortName: 'SELF' };\n  }\n\n  /** Owner identity broadcast by this radio; routing node number is separate. */\n  get localIdentity() {\n    const node = this.localNode;\n    if (!node && !this._localOwner) return null;\n    return {\n      id: this._localOwner?.id || node?.id || this._localNodeId || '',\n      longName: this._localOwner?.longName || node?.user || '',\n      shortName: this._localOwner?.shortName || node?.shortName || '',\n      routingNodeId: this._localNodeId || '',\n    };\n  }\n\n  get autoConnectEnabled() {\n    return this._autoConnectEnabled;\n  }\n\n  get autoConnectState() {\n    return this._autoConnectState;\n  }\n\n  get canEditLocalIdentity() {\n    return typeof this._meshDevice?.setOwner === 'function';\n  }\n\n  /** True when a serial connection is open. */\n  get isSerialConnected() {\n    return this._meshDevice != null\n      || (this._serialPort != null && this._serialPort.readable != null);\n  }\n\n  /** True for either an active serial session or a successful HTTP connection. */\n  get isConnected() {\n    return this._connected || this.isSerialConnected;\n  }\n\n  // ── HTTP polling ───────────────────────────────────────────────────────────\n\n  /**\n   * Fetch node list from the HTTP API.\n   * Tries the noclip backend first; falls back to the local Python server.\n   *\n   * @returns {Promise<MeshtasticNode[]>}\n   */\n  async fetchNodes() {\n    const primaryUrl = joinApiPath(this.apiBase, '/api/meshtastic/nodes');\n    const fallbackUrl = joinApiPath(this.localServerBase, '/api/nodes');\n\n    let raw = null;\n\n    if (!this._useFallback) {\n      try {\n        raw = await this._getJson(primaryUrl);\n        this._useFallback = false;\n      } catch (err) {\n        console.warn('[MeshtasticService] Primary endpoint failed, trying local fallback:', err.message);\n        this._useFallback = true;\n      }\n    }\n\n    if (raw == null) {\n      try {\n        raw = await this._getJson(fallbackUrl);\n      } catch (err) {\n        console.warn('[MeshtasticService] Fallback endpoint also failed:', err.message);\n        return [];\n      }\n    }\n\n    // Both endpoints may return { nodes: [...] } or a bare array\n    const list = Array.isArray(raw) ? raw\n      : Array.isArray(raw?.nodes) ? raw.nodes\n      : Array.isArray(raw?.data) ? raw.data\n      : [];\n\n    const reportedLocalId = raw?.localNodeId ?? raw?.local_node_id ?? raw?.myNodeId ?? raw?.my_node_id;\n    if (reportedLocalId != null) this._setLocalNodeId(reportedLocalId);\n    const nodes = list.map(normalizeNode).filter(Boolean);\n    this._applyNodeUpdate(nodes);\n    return nodes;\n  }\n\n  /**\n   * Start automatic polling every 30 seconds.\n   * Fires `meshtastic:connected` on the first successful fetch.\n   */\n  async startPolling() {\n    if (this._polling) return;\n    this._polling = true;\n\n    const tick = async () => {\n      if (!this._polling) return;\n      try {\n        const nodes = await this.fetchNodes();\n        if (nodes.length > 0 && !this._connected) {\n          this._connected = true;\n          this._emit('meshtastic:connected', {});\n        }\n      } catch {\n        // fetchNodes already logs — swallow here so the timer keeps running\n      }\n      if (this._polling) {\n        this._pollTimer = setTimeout(tick, DEFAULT_POLL_INTERVAL_MS);\n      }\n    };\n\n    await tick();\n  }\n\n  /** Stop the polling loop. */\n  stopPolling() {\n    this._polling = false;\n    if (this._pollTimer != null) {\n      clearTimeout(this._pollTimer);\n      this._pollTimer = null;\n    }\n  }\n\n  /**\n   * Connect to a direct Meshtastic HTTP server and fetch its first node list.\n   *\n   * @param {string} baseUrl\n   * @returns {Promise<MeshtasticNode[]>}\n   */\n  async connectHttp(baseUrl = LOCAL_SERVER_BASE) {\n    if (typeof baseUrl === 'string' && baseUrl.trim()) {\n      this.localServerBase = normalizeBaseUrl(baseUrl);\n    }\n    this._useFallback = true;\n    const nodes = await this.fetchNodes();\n    if (!this._connected) {\n      this._connected = true;\n      this._emit('meshtastic:connected', {});\n    }\n    return nodes;\n  }\n\n  // ── Web Serial mode ────────────────────────────────────────────────────────\n\n  /**\n   * Request a serial port from the browser and start the Meshtastic client.\n   * The official transport owns framing and protobuf decoding. The legacy\n   * injected-codec path remains available for deterministic/offline harnesses.\n   *\n   * @returns {Promise<void>}\n   * @throws If the user cancels the port picker or serial is unavailable.\n   */\n  async connectSerial({ port = null, requestPort = true, automatic = false } = {}) {\n    if (!globalThis.navigator?.serial) {\n      throw new Error('Web Serial API is not available in this browser.');\n    }\n    if (this.isSerialConnected) return true;\n    if (this._serialConnectPromise) return this._serialConnectPromise;\n\n    const connect = async () => {\n      if (automatic) this._setAutoConnectState('connecting');\n      try {\n        if (this._serialCodec) {\n          await this._connectLegacySerial({ port, requestPort });\n        } else {\n          await this._connectOfficialSerial({ port, requestPort });\n        }\n        const activePort = this._officialSerialPort || this._serialPort || port;\n        this._rememberSerialPort(activePort);\n        if (automatic) this._setAutoConnectState('connected');\n        return true;\n      } catch (error) {\n        if (automatic) this._setAutoConnectState('failed', error);\n        throw error;\n      }\n    };\n\n    this._serialConnectPromise = connect().finally(() => {\n      this._serialConnectPromise = null;\n    });\n    return this._serialConnectPromise;\n  }\n\n  /**\n   * Persist the user's reconnect policy. Automatic reconnect only considers\n   * ports already authorized through a prior user-initiated picker.\n   */\n  async setAutoConnectEnabled(enabled) {\n    this._autoConnectEnabled = enabled === true;\n    writeLocalStorage(SERIAL_AUTO_CONNECT_KEY, this._autoConnectEnabled ? 'true' : 'false');\n    this._setAutoConnectState(this._autoConnectEnabled ? 'idle' : 'disabled');\n    if (!this._autoConnectEnabled || this.isSerialConnected) return this.isSerialConnected;\n    return this.tryAutoConnectSerial();\n  }\n\n  /** Reopen a previously authorized, currently attached Web Serial device. */\n  async tryAutoConnectSerial({ port = null } = {}) {\n    if (!this._autoConnectEnabled || this.isSerialConnected) return this.isSerialConnected;\n    const serial = globalThis.navigator?.serial;\n    if (!serial?.getPorts) {\n      this._setAutoConnectState('unavailable');\n      return false;\n    }\n\n    let selectedPort = port;\n    if (!selectedPort) {\n      const authorizedPorts = await serial.getPorts();\n      const descriptor = readStoredPortDescriptor();\n      const candidates = descriptor\n        ? authorizedPorts.filter((candidate) => sameSerialPortDescriptor(candidate, descriptor))\n        : authorizedPorts;\n      if (candidates.length === 1) {\n        [selectedPort] = candidates;\n      } else if (candidates.length > 1) {\n        this._setAutoConnectState('ambiguous');\n        return false;\n      }\n    }\n\n    if (!selectedPort) {\n      this._setAutoConnectState('waiting');\n      return false;\n    }\n    const descriptor = readStoredPortDescriptor();\n    if (descriptor && !sameSerialPortDescriptor(selectedPort, descriptor)) return false;\n    return this.connectSerial({ port: selectedPort, requestPort: false, automatic: true });\n  }\n\n  /**\n   * Update the owner record advertised to other Meshtastic radios. The\n   * firmware routing node number remains unchanged and is shown separately.\n   */\n  async setLocalIdentity({ longName, shortName, id } = {}) {\n    if (!this._meshDevice || typeof this._meshDevice.setOwner !== 'function') {\n      throw new Error('Connect directly to the Meshtastic radio before editing its identity.');\n    }\n    const normalizedLongName = String(longName || '').trim();\n    const normalizedShortName = String(shortName || '').trim();\n    if (!normalizedLongName) throw new Error('Device name is required.');\n    if (!normalizedShortName) throw new Error('Short name is required.');\n    if (utf8ByteLength(normalizedLongName) > MAX_OWNER_LONG_NAME_BYTES) {\n      throw new Error(`Device name must be ${MAX_OWNER_LONG_NAME_BYTES} UTF-8 bytes or fewer.`);\n    }\n    if (utf8ByteLength(normalizedShortName) > MAX_OWNER_SHORT_NAME_BYTES) {\n      throw new Error(`Short name must be ${MAX_OWNER_SHORT_NAME_BYTES} UTF-8 bytes or fewer.`);\n    }\n    const normalizedId = normalizeAdvertisedNodeId(id || this._localOwner?.id || this._localNodeId);\n    const owner = {\n      ...(this._localOwner || {}),\n      id: normalizedId,\n      longName: normalizedLongName,\n      shortName: normalizedShortName,\n    };\n    await this._meshDevice.setOwner(owner);\n    this._localOwner = owner;\n    if (this._localNodeId) {\n      const previous = this._nodes.get(this._localNodeId) || { id: this._localNodeId };\n      this._applyNodeUpdate([{\n        ...previous,\n        id: this._localNodeId,\n        user: normalizedLongName,\n        shortName: normalizedShortName,\n      }]);\n    }\n    const identity = this.localIdentity;\n    this._emit('meshtastic:local-identity', { identity, node: this.localNode });\n    return identity;\n  }\n\n  /** @private */\n  _rememberSerialPort(port) {\n    const descriptor = describeSerialPort(port);\n    if (descriptor) writeLocalStorage(SERIAL_PORT_DESCRIPTOR_KEY, JSON.stringify(descriptor));\n  }\n\n  /** @private */\n  _setAutoConnectState(state, error = null) {\n    this._autoConnectState = state;\n    this._emit('meshtastic:auto-connect', {\n      enabled: this._autoConnectEnabled,\n      state,\n      error: error ? String(error?.message || error) : null,\n    });\n  }\n\n  /** @private */\n  async _connectOfficialSerial({ port = null, requestPort = true } = {}) {\n    let client = null;\n    try {\n      if (this._serialClientFactory) {\n        const options = { baudRate: SERIAL_BAUD_RATE };\n        if (port) options.port = port;\n        if (!requestPort) options.requestPort = false;\n        client = await this._serialClientFactory(options);\n      } else {\n        client = await this._createOfficialSerialClient({ port, requestPort });\n      }\n\n      const { device, transport, Types, Protobuf } = client ?? {};\n      if (!device?.events || typeof device.configure !== 'function') {\n        throw new Error('Meshtastic Web Serial client did not initialize correctly.');\n      }\n\n      this._meshDevice = device;\n      this._serialTransport = transport ?? null;\n      this._serialTypes = Types ?? null;\n      this._serialProtobuf = Protobuf ?? null;\n      this._serialMode = 'official';\n      this._officialSerialPort = client?.port || port || transport?.connection || null;\n      this._wireOfficialSerialEvents(device, Types);\n\n      device.setHeartbeatInterval?.(SERIAL_HEARTBEAT_INTERVAL_MS);\n      this._markConnected();\n\n      // Configuration streams node/user/position records through events. The\n      // legacy SDK keeps this promise open until its queue timeout, so the UI\n      // connection flow must not wait for it.\n      void device.configure().catch((err) => {\n        if (this._meshDevice === device) {\n          console.warn('[MeshtasticService] Device configuration request failed:', err);\n        }\n      });\n    } catch (err) {\n      const device = client?.device;\n      const transport = client?.transport;\n      try {\n        if (typeof device?.disconnect === 'function') await device.disconnect();\n        else if (typeof transport?.disconnect === 'function') await transport.disconnect();\n      } catch { /* ignore failed cleanup after a failed connect */ }\n      this._meshDevice = null;\n      this._serialTransport = null;\n      this._serialTypes = null;\n      this._serialProtobuf = null;\n      this._serialMode = null;\n      this._officialSerialPort = null;\n      throw err;\n    }\n  }\n\n  /** @private */\n  async _createOfficialSerialClient({ port = null, requestPort = true } = {}) {\n    const [{ MeshDevice, Types, Protobuf }, { TransportWebSerial }] = await Promise.all([\n      import('@meshtastic/core'),\n      import('@meshtastic/transport-web-serial'),\n    ]);\n    const selectedPort = port || (requestPort ? await globalThis.navigator.serial.requestPort() : null);\n    if (!selectedPort) {\n      throw new Error('No previously authorized Meshtastic serial device is available.');\n    }\n    const transport = await TransportWebSerial.createFromPort(selectedPort, SERIAL_BAUD_RATE);\n    try {\n      return { device: new MeshDevice(transport), transport, Types, Protobuf, port: selectedPort };\n    } catch (err) {\n      await transport.disconnect().catch(() => {});\n      throw err;\n    }\n  }\n\n  /** @private */\n  async _connectLegacySerial({ port = null, requestPort = true } = {}) {\n    this._serialPort = port || (requestPort ? await globalThis.navigator.serial.requestPort() : null);\n    if (!this._serialPort) {\n      throw new Error('No previously authorized Meshtastic serial device is available.');\n    }\n    await this._serialPort.open({ baudRate: SERIAL_BAUD_RATE });\n    this._serialMode = 'codec';\n\n    this._markConnected();\n    this._serialReadLoopActive = true;\n    this._runSerialReadLoop().catch((err) => {\n      console.error('[MeshtasticService] Serial read loop error:', err);\n      void this.disconnectSerial();\n    });\n  }\n\n  /** @private */\n  _wireOfficialSerialEvents(device, Types) {\n    const events = device.events;\n    const subscribe = (event, handler) => {\n      if (typeof event?.subscribe === 'function') event.subscribe(handler);\n    };\n    const applyPartialNode = (raw) => {\n      const node = normalizeNode(raw);\n      if (node) this._applyNodeUpdate([node]);\n    };\n\n    subscribe(events.onNodeInfoPacket, (node) => {\n      this._rememberUserRecord(node?.num ?? node?.nodeNum, node?.user);\n      applyPartialNode(node);\n    });\n    subscribe(events.onPositionPacket, (packet) => applyPartialNode({\n      num: packet?.from,\n      position: packet?.data,\n      lastHeard: dateToUnixSeconds(packet?.rxTime),\n    }));\n    subscribe(events.onUserPacket, (packet) => {\n      this._rememberUserRecord(packet?.from, packet?.data);\n      applyPartialNode({\n        id: nodeIdFromNum(packet?.from),\n        num: packet?.from,\n        user: packet?.data,\n        lastHeard: dateToUnixSeconds(packet?.rxTime),\n      });\n    });\n    subscribe(events.onTelemetryPacket, (packet) => {\n      const data = packet?.data;\n      const variant = data?.variant ?? data?.payloadVariant;\n      const deviceMetrics = variant?.case === 'deviceMetrics'\n        ? variant.value\n        : data?.deviceMetrics;\n      if (!deviceMetrics) return;\n      applyPartialNode({\n        num: packet?.from,\n        deviceMetrics,\n        lastHeard: dateToUnixSeconds(packet?.rxTime),\n      });\n    });\n    subscribe(events.onMyNodeInfo, (info) => {\n      const num = info?.myNodeNum ?? info?.my_node_num;\n      this._setLocalNodeId(num);\n      applyPartialNode({ num });\n    });\n    subscribe(events.onMessagePacket, (packet) => this._handleIncomingMessage(packet));\n    subscribe(events.onDeviceStatus, (status) => {\n      if (this._meshDevice !== device) return;\n      const statuses = Types?.DeviceStatusEnum ?? {};\n      if (status === statuses.DeviceDisconnected || status === 2) {\n        this._meshDevice = null;\n        this._serialTransport = null;\n        this._serialTypes = null;\n        this._serialProtobuf = null;\n        this._serialMode = null;\n        this._officialSerialPort = null;\n        this._markDisconnected();\n      } else if (\n        status === statuses.DeviceConnected\n        || status === statuses.DeviceConfiguring\n        || status === statuses.DeviceConfigured\n        || status === 5\n        || status === 6\n        || status === 7\n      ) {\n        this._markConnected();\n      }\n    });\n  }\n\n  /**\n   * Close the serial port and release the reader/writer.\n   *\n   * @returns {Promise<void>}\n   */\n  async disconnectSerial() {\n    if (this._meshDevice) {\n      const device = this._meshDevice;\n      const transport = this._serialTransport;\n      this._meshDevice = null;\n      this._serialTransport = null;\n      this._serialTypes = null;\n      this._serialProtobuf = null;\n      this._serialMode = null;\n      this._officialSerialPort = null;\n      try {\n        if (typeof device.disconnect === 'function') await device.disconnect();\n        else if (typeof transport?.disconnect === 'function') await transport.disconnect();\n      } finally {\n        this._markDisconnected();\n      }\n      return;\n    }\n\n    this._serialReadLoopActive = false;\n\n    try { await this._serialReader?.cancel(); } catch { /* ignore */ }\n    try { this._serialReader?.releaseLock(); } catch { /* ignore */ }\n    try { this._serialWriter?.releaseLock(); } catch { /* ignore */ }\n    try { await this._serialPort?.close(); } catch { /* ignore */ }\n\n    this._serialReader = null;\n    this._serialWriter = null;\n    this._serialPort = null;\n    this._serialMode = null;\n    this._markDisconnected();\n  }\n\n  /**\n   * Internal read loop: consumes raw bytes from the serial port.\n   * Hands complete framed packets to `_parseSerialPacket`.\n   *\n   * @private\n   */\n  async _runSerialReadLoop() {\n    const FRAME_START_1 = 0x94;\n    const FRAME_START_2 = 0xc3;\n\n    let buffer = new Uint8Array(4096);\n    let bufLen = 0;\n\n    this._serialReader = this._serialPort.readable.getReader();\n\n    try {\n      while (this._serialReadLoopActive) {\n        const { value, done } = await this._serialReader.read();\n        if (done) break;\n        if (!value) continue;\n\n        // Append incoming bytes into local buffer\n        const needed = bufLen + value.length;\n        if (needed > buffer.length) {\n          const grown = new Uint8Array(needed * 2);\n          grown.set(buffer.subarray(0, bufLen));\n          buffer = grown;\n        }\n        buffer.set(value, bufLen);\n        bufLen += value.length;\n\n        // Consume complete frames\n        let offset = 0;\n        while (offset + 4 <= bufLen) {\n          // Scan for frame start magic bytes\n          if (buffer[offset] !== FRAME_START_1 || buffer[offset + 1] !== FRAME_START_2) {\n            offset++;\n            continue;\n          }\n          const frameLen = (buffer[offset + 2] << 8) | buffer[offset + 3];\n          const totalLen = 4 + frameLen;\n          if (offset + totalLen > bufLen) break;  // wait for more data\n\n          const payload = buffer.slice(offset + 4, offset + totalLen);\n          this._parseSerialPacket(payload);\n          offset += totalLen;\n        }\n\n        // Slide unconsumed bytes to front\n        if (offset > 0) {\n          buffer.copyWithin(0, offset, bufLen);\n          bufLen -= offset;\n        }\n      }\n    } finally {\n      try { this._serialReader.releaseLock(); } catch { /* ignore */ }\n    }\n  }\n\n  /**\n   * Parse a single framed serial payload.\n   *\n   * @private\n   * @param {Uint8Array} payload\n   */\n  _parseSerialPacket(payload) {\n    if (!this._serialCodec) return;\n    try {\n      const decoded = this._serialCodec.decodeFromRadio(payload);\n      if (Array.isArray(decoded?.nodes)) {\n        const nodes = decoded.nodes.map(normalizeNode).filter(Boolean);\n        if (nodes.length) this._applyNodeUpdate(nodes);\n      }\n      if (decoded?.message) {\n        this._handleIncomingMessage(decoded.message);\n      } else if (decoded?.text) {\n        this._handleIncomingMessage(decoded);\n      }\n    } catch (err) {\n      console.warn('[MeshtasticService] Serial decode failed:', err);\n    }\n  }\n\n  // ── Messaging ──────────────────────────────────────────────────────────────\n\n  /**\n   * Send a text message to a node.\n   * Uses serial if connected, otherwise POSTs to the HTTP API.\n   *\n   * @param {string} nodeId  — destination node ID (e.g. \"!849ac7f4\") or \"broadcast\"\n   * @param {string} text\n   * @returns {Promise<MeshtasticMessage|null>}\n   */\n  async sendMessage(nodeId, text) {\n    if (text === undefined) {\n      text = nodeId;\n      nodeId = 'broadcast';\n    }\n    if (!text || typeof text !== 'string') return null;\n    const target = nodeId || 'broadcast';\n    if (this.isSerialConnected) normalizeDestination(target);\n    // Preserve user send order even when two clicks land in the same\n    // millisecond; thread ordering falls back to IDs only after timestamp.\n    const timestamp = Math.max(Date.now(), this._lastOutgoingTimestamp + 1);\n    this._lastOutgoingTimestamp = timestamp;\n    const clientId = `mesh:out:${this._localNodeId || 'local'}:${timestamp}:${Math.random().toString(36).slice(2, 9)}`;\n    const pending = {\n      clientId,\n      messageId: clientId,\n      to: canonicalMeshtasticNodeId(target, 'broadcast'),\n      text,\n      channel: 0,\n      timestamp,\n      packetId: null,\n    };\n    this._pendingOutbound.set(clientId, pending);\n    const initial = this._recordMessage({\n      id: clientId,\n      from: this._localNodeId || 'local',\n      to: target,\n      text,\n      timestamp,\n      channel: 0,\n      outgoing: true,\n      deliveryStatus: 'sending',\n    }, { persist: false });\n    pending.messageId = initial.id;\n    try {\n      let packetId = null;\n      let deliveryStatus = 'gateway-sent';\n      if (this.isSerialConnected) {\n        const usesRoutingAck = Boolean(this._meshDevice) && target !== 'broadcast';\n        packetId = await this._sendMessageSerial(target, text);\n        if (usesRoutingAck) deliveryStatus = 'delivered';\n      } else {\n        packetId = await this._sendMessageHttp(target, text);\n      }\n      const updated = this._updateMessage(pending.messageId, {\n        packetId,\n        deliveryStatus,\n        deliveryError: null,\n        updatedAt: Date.now(),\n      });\n      return updated;\n    } catch (error) {\n      this._updateMessage(pending.messageId, {\n        deliveryStatus: 'failed',\n        deliveryError: String(error?.message || error),\n        updatedAt: Date.now(),\n      });\n      throw error;\n    } finally {\n      this._pendingOutbound.delete(clientId);\n    }\n  }\n\n  /**\n   * @private\n   */\n  async _sendMessageHttp(nodeId, text) {\n    const useFallback = this._useFallback;\n    const url = useFallback\n      ? joinApiPath(this.localServerBase, '/api/send')\n      : joinApiPath(this.apiBase, '/api/meshtastic/send');\n    const body = JSON.stringify(useFallback\n      ? {\n          message: text,\n          destination: nodeId && nodeId !== 'broadcast' ? nodeId : null,\n        }\n      : { to: nodeId, text });\n    const res = await fetch(url, {\n      method: 'POST',\n      headers: { 'Content-Type': 'application/json' },\n      body,\n    });\n    if (!res.ok) {\n      throw new Error(`[MeshtasticService] sendMessage HTTP ${res.status}: ${res.statusText}`);\n    }\n    const data = await res.json().catch(() => null);\n    const packetId = Number(data?.packetId ?? data?.packet_id ?? data?.id);\n    return Number.isFinite(packetId) ? packetId : null;\n  }\n\n  /**\n   * @private\n   */\n  async _sendMessageSerial(nodeId, text) {\n    if (this._meshDevice) {\n      const destination = normalizeDestination(nodeId);\n      const packetId = await this._meshDevice.sendText(text, destination, true);\n      return Number.isFinite(Number(packetId)) ? Number(packetId) : null;\n    }\n    if (!this._serialCodec) {\n      throw new Error('Meshtastic serial send requires a loaded protobuf codec.');\n    }\n    if (!this._serialPort?.writable) {\n      throw new Error('Meshtastic serial port is not writable.');\n    }\n    const payload = asUint8Array(await this._serialCodec.encodeTextPacket({ to: nodeId, text }));\n    if (payload.length > 0xffff) {\n      throw new Error('Meshtastic serial payload is too large.');\n    }\n    const frame = new Uint8Array(4 + payload.length);\n    frame[0] = 0x94;\n    frame[1] = 0xc3;\n    frame[2] = (payload.length >> 8) & 0xff;\n    frame[3] = payload.length & 0xff;\n    frame.set(payload, 4);\n    if (!this._serialWriter) {\n      this._serialWriter = this._serialPort.writable.getWriter();\n    }\n    await this._serialWriter.write(frame);\n    return null;\n  }\n\n  /**\n   * Register a handler for incoming messages.\n   * The handler is called synchronously when a message is received.\n   *\n   * @param {(msg: MeshtasticMessage) => void} callback\n   * @returns {() => void} Unsubscribe function\n   */\n  onMessage(callback) {\n    if (typeof callback !== 'function') return () => {};\n    this._messageHandlers.push(callback);\n    return () => {\n      this._messageHandlers = this._messageHandlers.filter((h) => h !== callback);\n    };\n  }\n\n  onMessageUpdate(callback) {\n    if (typeof callback !== 'function') return () => {};\n    this._messageUpdateHandlers.push(callback);\n    return () => {\n      this._messageUpdateHandlers = this._messageUpdateHandlers.filter((handler) => handler !== callback);\n    };\n  }\n\n  /** Return the chronological in-memory thread shared by every UI surface. */\n  getThreadMessages(peerNodeId, channel = 0) {\n    const threadKey = buildMeshtasticThreadKey(this._localNodeId || 'local', peerNodeId, channel);\n    return this._messageHistory\n      .filter((message) => message.threadKey === threadKey)\n      .map((message) => ({ ...message }));\n  }\n\n  async loadThreadMessages(peerNodeId, channel = 0, { limit = 500 } = {}) {\n    await this.ready;\n    const threadKey = buildMeshtasticThreadKey(this._localNodeId || 'local', peerNodeId, channel);\n    const messages = await this._conversationStore.listThread(threadKey, { limit });\n    for (const message of messages) {\n      const index = this._messageHistory.findIndex((entry) => entry.id === message.id);\n      if (index < 0) this._messageHistory.push(message);\n      else if (message.updatedAt >= this._messageHistory[index].updatedAt) this._messageHistory[index] = message;\n    }\n    this._messageHistory.sort((a, b) => a.timestamp - b.timestamp || a.id.localeCompare(b.id));\n    return messages.map((message) => ({ ...message }));\n  }\n\n  async retryMessage(messageId) {\n    const message = this._messageHistory.find((entry) => entry.id === messageId);\n    if (!message?.outgoing || message.deliveryStatus !== 'failed') return null;\n    return this.sendMessage(message.to, message.text);\n  }\n\n  getUnreadCount(peerNodeId, channel = 0) {\n    return this.getThreadMessages(peerNodeId, channel)\n      .filter((message) => !message.outgoing && !message.readAt).length;\n  }\n\n  async markThreadRead(peerNodeId, channel = 0) {\n    const threadKey = buildMeshtasticThreadKey(this._localNodeId || 'local', peerNodeId, channel);\n    const readAt = Date.now();\n    let changed = false;\n    this._messageHistory = this._messageHistory.map((message) => {\n      if (message.threadKey !== threadKey || message.outgoing || message.readAt) return message;\n      changed = true;\n      return { ...message, readAt, updatedAt: readAt, syncState: 'pending' };\n    });\n    await this._conversationStore.markThreadRead(threadKey, readAt);\n    if (changed) this._emit('meshtastic:thread-read', { threadKey, peerNodeId, channel, readAt });\n    void this._syncService?.syncNow?.().catch(() => {});\n    return readAt;\n  }\n\n  // ── Internals ──────────────────────────────────────────────────────────────\n\n  _hydrateNodeCache() {\n    const rawCache = readLocalStorage(MESHTASTIC_NODE_CACHE_KEY);\n    if (!rawCache) return;\n\n    try {\n      const parsed = JSON.parse(rawCache);\n      const nodes = Array.isArray(parsed) ? parsed : parsed?.nodes;\n      if (!Array.isArray(nodes)) return;\n\n      for (const node of nodes) {\n        if (node?.id) this._nodes.set(node.id, node);\n      }\n      this._pruneNodeCache();\n    } catch (_) {\n      // A corrupted cache must not prevent a radio connection from starting.\n    }\n  }\n\n  _pruneNodeCache() {\n    if (this._nodes.size <= MESHTASTIC_NODE_CACHE_LIMIT) return;\n\n    const retained = Array.from(this._nodes.values())\n      .sort((a, b) => (Number(b?.lastHeard) || 0) - (Number(a?.lastHeard) || 0))\n      .slice(0, MESHTASTIC_NODE_CACHE_LIMIT);\n    this._nodes.clear();\n    for (const node of retained) this._nodes.set(node.id, node);\n  }\n\n  _persistNodeCache() {\n    try {\n      globalThis.localStorage?.setItem(\n        MESHTASTIC_NODE_CACHE_KEY,\n        JSON.stringify(Array.from(this._nodes.values()))\n      );\n    } catch (_) {\n      // Storage can be unavailable or full; the live node map remains usable.\n    }\n  }\n\n  /**\n   * Merge freshly-fetched nodes into the internal map and emit an update.\n   *\n   * @private\n   * @param {MeshtasticNode[]} nodes\n   */\n  _applyNodeUpdate(nodes) {\n    for (const node of nodes) {\n      const previous = this._nodes.get(node.id);\n      if (!previous) {\n        this._nodes.set(node.id, node);\n        continue;\n      }\n\n      const merged = { ...previous, ...node };\n      for (const field of ['hardware', 'role', 'snr', 'hopsAway', 'lat', 'lon', 'altitude', 'batteryLevel']) {\n        if (node[field] == null) merged[field] = previous[field] ?? null;\n      }\n      if (!node.user || node.user === node.id || node.user === 'Unknown') {\n        merged.user = previous.user ?? node.user;\n      }\n      if (!node.shortName || node.shortName === '????') {\n        merged.shortName = previous.shortName ?? node.shortName;\n      }\n      merged.lastHeard = Math.max(previous.lastHeard || 0, node.lastHeard || 0);\n      this._nodes.set(node.id, merged);\n    }\n    this._pruneNodeCache();\n    this._persistNodeCache();\n    this._emit('meshtastic:nodes', { nodes: Array.from(this._nodes.values()) });\n  }\n\n  _rememberUserRecord(nodeNum, user) {\n    const id = typeof nodeNum === 'number' ? nodeIdFromNum(nodeNum) : canonicalMeshtasticNodeId(nodeNum, null);\n    if (!id || !user || typeof user !== 'object') return;\n    this._userRecords.set(id, { ...user });\n    if (id === this._localNodeId) {\n      this._localOwner = { ...user };\n      this._emit('meshtastic:local-identity', { identity: this.localIdentity, node: this.localNode });\n    }\n  }\n\n  _setLocalNodeId(value) {\n    let id = null;\n    if (typeof value === 'number') id = nodeIdFromNum(value);\n    else {\n      const text = String(value ?? '').trim().toLowerCase();\n      const match = text.match(/^!(?:0x)?([0-9a-f]+)$/i) || text.match(/^0x([0-9a-f]+)$/i);\n      if (match) id = `!${match[1].padStart(8, '0')}`;\n      else if (/^\\d+$/.test(text)) id = nodeIdFromNum(Number(text));\n    }\n    if (!id || this._localNodeId === id) return;\n    this._localNodeId = id;\n    const owner = this._userRecords.get(id);\n    if (owner) this._localOwner = { ...owner };\n    this._emit('meshtastic:local-node', { localNodeId: id, node: this.localNode });\n    this._emit('meshtastic:local-identity', { identity: this.localIdentity, node: this.localNode });\n  }\n\n  /** @private */\n  _markConnected() {\n    if (this._connected) return;\n    this._connected = true;\n    this._emit('meshtastic:connected', {});\n  }\n\n  /** @private */\n  _markDisconnected() {\n    if (!this._connected) return;\n    this._connected = false;\n    this._emit('meshtastic:disconnected', {});\n    if (this._autoConnectEnabled) this._setAutoConnectState('waiting');\n  }\n\n  /**\n   * Fire an incoming message event.\n   *\n   * @private\n   * @param {Object} raw\n   */\n  _handleIncomingMessage(raw) {\n    const msg = normalizeMessage(raw);\n    if (!msg) return;\n    const pending = this._findPendingOutbound(msg);\n    const local = canonicalMeshtasticNodeId(this._localNodeId, 'local');\n    const from = canonicalMeshtasticNodeId(msg.from, 'unknown');\n    const isLocalEcho = Boolean(pending) || (local !== 'local' && from === local);\n    if (isLocalEcho) {\n      msg.outgoing = true;\n      msg.deliveryStatus = pending ? 'sending' : 'gateway-sent';\n      if (pending) {\n        if (!this._localNodeId && from !== 'unknown') this._setLocalNodeId(from);\n        const updated = this._updateMessage(pending.messageId, {\n          ...msg,\n          outgoing: true,\n          deliveryStatus: 'sending',\n          deliveryError: null,\n          updatedAt: msg.timestamp,\n        }, { sync: false });\n        if (updated) {\n          pending.messageId = updated.id;\n          pending.packetId = updated.packetId;\n        }\n        return;\n      }\n    }\n    this._recordMessage(msg);\n  }\n\n  _findPendingOutbound(message) {\n    const to = canonicalMeshtasticNodeId(message?.to, 'broadcast');\n    const channel = Number(message?.channel) || 0;\n    const packetId = Number(message?.packetId);\n    const candidates = Array.from(this._pendingOutbound.values()).reverse();\n    return candidates.find((pending) => (\n      pending.to === to\n      && pending.channel === channel\n      && pending.text === message.text\n      && (!Number.isFinite(packetId) || pending.packetId == null || pending.packetId === packetId)\n      && Math.abs((Number(message?.timestamp) || Date.now()) - pending.timestamp) <= 120_000\n    )) || null;\n  }\n\n  /** @private */\n  _recordMessage(msg, { persist = true, sync = true } = {}) {\n    const normalized = normalizeStoredMeshtasticMessage(msg, this._localNodeId || 'local');\n    const existingIndex = this._messageHistory.findIndex((message) => message.id === normalized.id);\n    let stored = normalized;\n    if (existingIndex >= 0) {\n      const previous = this._messageHistory[existingIndex];\n      stored = mergeMeshtasticMessages(previous, normalized);\n      this._messageHistory[existingIndex] = stored;\n    } else {\n      this._messageHistory.push(stored);\n    }\n    this._messageHistory.sort((a, b) => a.timestamp - b.timestamp || a.id.localeCompare(b.id));\n    if (this._messageHistory.length > MAX_MESSAGE_HISTORY) {\n      this._messageHistory.splice(0, this._messageHistory.length - MAX_MESSAGE_HISTORY);\n    }\n    if (existingIndex < 0) {\n      for (const handler of this._messageHandlers) {\n        try { handler({ ...stored }); } catch (err) {\n          console.error('[MeshtasticService] Message handler error:', err);\n        }\n      }\n      this._emit('meshtastic:message', stored);\n    } else {\n      this._notifyMessageUpdate(stored);\n    }\n    if (persist) this._persistMessage(stored, { sync: sync && stored.deliveryStatus !== 'sending' });\n    return { ...stored };\n  }\n\n  _updateMessage(id, patch, { persist = true, sync = true } = {}) {\n    const index = this._messageHistory.findIndex((message) => message.id === id);\n    if (index < 0) return null;\n    const previous = this._messageHistory[index];\n    const next = normalizeStoredMeshtasticMessage({\n      ...previous,\n      ...patch,\n      syncState: 'pending',\n    }, this._localNodeId || 'local');\n    const collisionIndex = this._messageHistory.findIndex((message, candidateIndex) => (\n      candidateIndex !== index && message.id === next.id\n    ));\n    let stored = next;\n    if (collisionIndex >= 0) {\n      stored = mergeMeshtasticMessages(this._messageHistory[collisionIndex], next);\n      this._messageHistory[collisionIndex] = stored;\n      this._messageHistory.splice(index, 1);\n    } else {\n      this._messageHistory[index] = stored;\n    }\n    this._messageHistory.sort((a, b) => a.timestamp - b.timestamp || a.id.localeCompare(b.id));\n    this._notifyMessageUpdate(stored);\n    if (persist) {\n      this._persistMessage(stored, {\n        previousId: previous.id,\n        sync: sync && stored.deliveryStatus !== 'sending',\n      });\n    }\n    return { ...stored };\n  }\n\n  _notifyMessageUpdate(message) {\n    for (const handler of this._messageUpdateHandlers) {\n      try { handler({ ...message }); } catch (error) {\n        console.error('[MeshtasticService] Message update handler error:', error);\n      }\n    }\n    this._emit('meshtastic:message-status', message);\n  }\n\n  _persistMessage(message, { previousId = null, sync = true } = {}) {\n    const operation = previousId && previousId !== message.id\n      ? this._conversationStore.replaceMessage(previousId, message, { localNodeId: this._localNodeId || 'local' })\n      : this._conversationStore.putMessage(message, { localNodeId: this._localNodeId || 'local' });\n    void operation\n      .then(() => (sync ? this._syncService?.syncNow?.() : null))\n      .catch((error) => console.warn('[MeshtasticService] Message persistence failed:', error));\n  }\n\n  async _hydrateConversationHistory() {\n    try {\n      await this._conversationStore.repairCanonicalMessageIdentity?.();\n      await this._syncService?.syncNow?.().catch(() => {});\n      const messages = await this._conversationStore.listRecent({ limit: MAX_MESSAGE_HISTORY });\n      for (const message of messages) {\n        const normalized = normalizeStoredMeshtasticMessage(message, message.localNodeId || this._localNodeId || 'local');\n        const index = this._messageHistory.findIndex((entry) => entry.id === normalized.id);\n        if (index < 0) this._messageHistory.push(normalized);\n        else if (normalized.updatedAt >= this._messageHistory[index].updatedAt) this._messageHistory[index] = normalized;\n      }\n      this._messageHistory.sort((a, b) => a.timestamp - b.timestamp || a.id.localeCompare(b.id));\n      this._emit('meshtastic:history-hydrated', { messages: this.messageHistory });\n    } catch (error) {\n      console.warn('[MeshtasticService] Conversation history unavailable:', error);\n    }\n    return this.messageHistory;\n  }\n\n  /**\n   * Emit an event on the shared bus.\n   *\n   * @private\n   * @param {string} event\n   * @param {Object} detail\n   */\n  _emit(event, detail) {\n    try {\n      this.eventBus?.emit(event, detail);\n    } catch (err) {\n      console.error('[MeshtasticService] eventBus.emit error:', err);\n    }\n  }\n\n  /**\n   * Fetch JSON from a URL with a 15-second timeout.\n   *\n   * @private\n   * @param {string} url\n   * @returns {Promise<unknown>}\n   */\n  async _getJson(url) {\n    const controller = new AbortController();\n    const tid = setTimeout(() => controller.abort(), 15_000);\n    try {\n      const res = await fetch(url, { signal: controller.signal });\n      if (!res.ok) throw new Error(`HTTP ${res.status}`);\n      return await res.json();\n    } finally {\n      clearTimeout(tid);\n    }\n  }\n}\n\n// ---------------------------------------------------------------------------\n// Singleton factory\n// ---------------------------------------------------------------------------\n\nlet _instance = null;\n\n/**\n * Return the shared MeshtasticService instance, creating it on first call.\n *\n * @param {Object} [opts]\n * @param {Object} [opts.eventBus]\n * @param {string} [opts.apiBase]\n * @returns {MeshtasticService}\n */\nexport function getMeshtasticService(opts) {\n  if (!_instance) {\n    _instance = new MeshtasticService(opts ?? {});\n  } else if (opts?.eventBus && !_instance.eventBus) {\n    _instance.eventBus = opts.eventBus;\n  }\n  return _instance;\n}\n","/**\n * MeshtasticOverlay\n *\n * Positions connected Meshtastic nodes through the same terrain/building\n * footprint and lightweight LabelSystem contracts used by incidents. The\n * canonical `Sensors & mesh` label category owns all map presentation;\n * `scene.meshtastic.enabled` only opts into the HTTP source.\n */\n\nimport * as THREE from 'three';\nimport { PLANET_RADIUS } from '../../modules/constants.js';\nimport { getLabelSystem } from '../labels/LabelSystem.js';\nimport { SurfaceFootprintMarker } from '../overlays/SurfaceFootprintMarker.js';\nimport { getMeshtasticService } from './MeshtasticService.js';\nimport {\n  meshtasticNodeIdFromLabelHover,\n  meshtasticNodeIdsEqual,\n  normalizeMeshtasticNodeId,\n} from './MeshtasticNodeUtils.js';\n\nconst STALE_THRESHOLD_MS = 24 * 60 * 60 * 1000;\nconst LIVE_THRESHOLD_MS = 60 * 60 * 1000;\nconst STALE_CHECK_INTERVAL_MS = 60_000;\nconst COLOR_LIVE = 0x4ade80;\nconst COLOR_STALE = 0xfbbf24;\nconst COLOR_LIVE_CSS = '#4ade80';\nconst COLOR_STALE_CSS = '#fbbf24';\nconst LABEL_TARGET_RADIUS_M = 5;\nconst DEFAULT_SPIRE_HEIGHT_M = 42;\nconst DEFAULT_SPIRE_RADIUS_M = 3.5;\nconst LABEL_OFFSET_M = 1.5;\nconst MARKER_OPACITY = 0.82;\nconst MARKER_OUTLINE_OPACITY = 0.96;\n\nexport class MeshtasticOverlay {\n  constructor({\n    parentGroup,\n    planetRadius,\n    eventBus,\n    sceneInitializer,\n    surfaceController,\n    buildingResolver,\n    labelSystem,\n    service,\n    enabled = false,\n    showLabels = true,\n    spireHeightM = DEFAULT_SPIRE_HEIGHT_M,\n    spireRadiusM = DEFAULT_SPIRE_RADIUS_M,\n  } = {}) {\n    this.parentGroup = parentGroup ?? null;\n    this.planetRadius = planetRadius ?? PLANET_RADIUS;\n    this.eventBus = eventBus ?? null;\n    this.sceneInitializer = sceneInitializer ?? null;\n    this.surfaceController = surfaceController ?? null;\n    this._buildingResolver = typeof buildingResolver === 'function' ? buildingResolver : null;\n\n    // Source acquisition and visual presentation intentionally have separate\n    // gates. Serial nodes keep flowing without turning on HTTP polling, while\n    // the Sensors & mesh category is the only map-visibility authority.\n    this.enabled = !!enabled;\n    this.showLabels = showLabels !== false;\n    this.spireHeightM = Math.max(8, Number(spireHeightM) || DEFAULT_SPIRE_HEIGHT_M);\n    this.spireRadiusM = Math.max(1, Number(spireRadiusM) || DEFAULT_SPIRE_RADIUS_M);\n    this._labelSystem = labelSystem ?? null;\n    this._service = service ?? getMeshtasticService({ eventBus: this.eventBus });\n    this._entries = new Map();\n    this._tmpLabelPosition = new THREE.Vector3();\n    this._staleCheckElapsed = 0;\n    this._highlightedNodeId = null;\n\n    this.group = new THREE.Group();\n    this.group.name = 'MeshtasticOverlay';\n    this.group.visible = this.showLabels;\n    this.parentGroup?.add(this.group);\n\n    this._onNodes = this._handleNodesEvent.bind(this);\n    this._onRequestedNodeHover = this._handleRequestedNodeHover.bind(this);\n    this._onSceneLabelHover = this._handleSceneLabelHover.bind(this);\n    this._subscribeEvents();\n    if (this.showLabels) this._hydrateConnectedNodes({ allowFetch: this.enabled });\n  }\n\n  /** Enable or disable the optional HTTP source without bypassing the label rail. */\n  setEnabled(enabled) {\n    const next = !!enabled;\n    if (this.enabled === next) return;\n    this.enabled = next;\n    if (next) this._hydrateConnectedNodes({ allowFetch: true });\n  }\n\n  /**\n   * Canonical Sensors & mesh category gate. It owns scene spires, labels, and\n   * minimap nodes together so no hidden producer remains in a render hot path.\n   */\n  setLabelsEnabled(enabled) {\n    const next = !!enabled;\n    if (this.showLabels === next) return;\n    this.showLabels = next;\n    this.group.visible = next;\n    if (next) {\n      this._hydrateConnectedNodes({ allowFetch: this.enabled });\n    } else {\n      this._clearAll();\n      this._emitMiniMapUpdate();\n    }\n  }\n\n  applyConfig(config = {}) {\n    if (typeof config.enabled === 'boolean') this.setEnabled(config.enabled);\n  }\n\n  getEntriesSnapshot() {\n    return Array.from(this._entries.values(), ({ nodeData }) => ({ ...nodeData }));\n  }\n\n  update(_camera, dtMs = 0) {\n    if (!this.showLabels) return;\n\n    const nowMs = typeof performance !== 'undefined' && performance.now\n      ? performance.now()\n      : Date.now();\n    for (const entry of this._entries.values()) {\n      if (!entry.marker?.isAnimating?.()) continue;\n      entry.marker.update(nowMs);\n      this._syncLabelPosition(entry);\n    }\n\n    this._staleCheckElapsed += dtMs;\n    if (this._staleCheckElapsed >= STALE_CHECK_INTERVAL_MS) {\n      this._staleCheckElapsed = 0;\n      this._refreshFreshnessAndCull();\n    }\n  }\n\n  /** Refresh only nodes touched by native photoreal tile ownership changes. */\n  refreshTerrainAnchors(changes) {\n    if (!this.showLabels || !Array.isArray(changes) || changes.length === 0) return 0;\n    let updated = 0;\n    for (const entry of this._entries.values()) {\n      if (!entry.marker?.refreshTerrain?.(changes)) continue;\n      this._resolveBuildingFootprint(entry, { transition: true });\n      this._syncLabelPosition(entry);\n      updated += 1;\n    }\n    return updated;\n  }\n\n  dispose() {\n    this._unsubscribeEvents();\n    this._clearAll();\n    this.group.parent?.remove?.(this.group);\n  }\n\n  getMiniMapMarkers() {\n    if (!this.showLabels) return [];\n    const markers = [];\n    const nowS = Date.now() / 1000;\n    for (const { nodeData } of this._entries.values()) {\n      if (!Number.isFinite(nodeData.lat) || !Number.isFinite(nodeData.lon)) continue;\n      const live = _isLiveNode(nodeData, nowS);\n      markers.push({\n        id: nodeData.id,\n        lat: nodeData.lat,\n        lon: nodeData.lon,\n        label: nodeData.shortName || nodeData.user || nodeData.id,\n        color: live ? COLOR_LIVE_CSS : COLOR_STALE_CSS,\n      });\n    }\n    return markers;\n  }\n\n  _applyNodes(nodes) {\n    if (!this.showLabels) return;\n    for (const node of nodes) {\n      if (!Number.isFinite(node?.lat) || !Number.isFinite(node?.lon)) continue;\n      const existing = this._entries.get(node.id);\n      if (existing) this._updateEntry(existing, node);\n      else this._createEntry(node);\n    }\n    this._refreshFreshnessAndCull();\n    this._emitMiniMapUpdate();\n  }\n\n  _createEntry(nodeData) {\n    const live = _isLiveNode(nodeData);\n    const marker = new SurfaceFootprintMarker({\n      parentGroup: this.group,\n      surfaceController: this.surfaceController,\n      color: live ? COLOR_LIVE : COLOR_STALE,\n      heightM: this.spireHeightM,\n      embedM: Math.max(1.5, Math.min(3.5, this.spireHeightM * 0.08)),\n      opacity: 0.82,\n      outlineOpacity: 0.96,\n      renderOrder: 5,\n      name: `MeshtasticFootprint:${nodeData.id}`,\n      lightChannel: 'meshtastic',\n      lightPriority: live ? 108 : 88,\n      lightRadiusM: live ? 165 : 110,\n      lightIntensityScale: live ? 1.45 : 1.1,\n      lightPulseHz: live ? 0.9 : 0.28,\n    });\n    const entry = { nodeData, marker, labelHandle: null, live };\n    marker.group.userData.meshtasticEntry = entry;\n    marker.wallMesh.userData.meshtasticEntry = entry;\n    marker.outline.userData.meshtasticEntry = entry;\n    marker.setResolvingSpire(nodeData.lat, nodeData.lon, {\n      radiusM: this.spireRadiusM,\n      growDurationMs: 320,\n    });\n    this._resolveBuildingFootprint(entry, { transition: false });\n    marker.setVisible(true);\n    entry.labelHandle = this._createLabel(entry);\n    this._entries.set(nodeData.id, entry);\n    this._applyEntryHighlight(entry, meshtasticNodeIdsEqual(nodeData.id, this._highlightedNodeId));\n  }\n\n  _updateEntry(entry, nodeData) {\n    const moved = Math.abs(entry.nodeData.lat - nodeData.lat) > 1e-7\n      || Math.abs(entry.nodeData.lon - nodeData.lon) > 1e-7;\n    entry.nodeData = nodeData;\n    if (moved) {\n      entry.marker.setResolvingSpire(nodeData.lat, nodeData.lon, {\n        radiusM: this.spireRadiusM,\n        growDurationMs: 220,\n      });\n      this._resolveBuildingFootprint(entry, { transition: false });\n    }\n\n    const live = _isLiveNode(nodeData);\n    if (entry.live !== live) {\n      const retainHover = meshtasticNodeIdsEqual(nodeData.id, this._highlightedNodeId);\n      entry.live = live;\n      entry.marker.setColor(live ? COLOR_LIVE : COLOR_STALE);\n      this._disposeLabel(entry);\n      entry.labelHandle = this._createLabel(entry);\n      if (retainHover) {\n        this._setHighlightedNode(nodeData.id);\n        this._getLabelSystem().setExternalHoveredLabel?.(entry.labelHandle);\n      }\n      return;\n    }\n\n    if (entry.labelHandle) {\n      const labels = this._getLabelSystem();\n      labels.updateText(\n        entry.labelHandle,\n        nodeData.user || nodeData.shortName || nodeData.id,\n        _buildSubText(nodeData),\n      );\n      labels.updateMetadata?.(entry.labelHandle, _buildMetadata(nodeData, entry.marker.source));\n      this._syncLabelPosition(entry);\n    }\n  }\n\n  _resolveBuildingFootprint(entry, { transition = false } = {}) {\n    if (!entry?.marker || !this._buildingResolver) return false;\n    const { lat, lon } = entry.nodeData;\n    const building = this._buildingResolver(lat, lon);\n    if (!building?.footprint || building.footprint.length < 3) return false;\n    if (entry.marker.source === 'building-overlay') return true;\n    if (transition && entry.marker.isTerrainMated()) {\n      return entry.marker.transitionToFootprint(\n        { latLonPairs: building.footprint },\n        { lat, lon, source: 'building-overlay', durationMs: 360 },\n      );\n    }\n    return entry.marker.setFootprint(\n      { latLonPairs: building.footprint },\n      { lat, lon, source: 'building-overlay' },\n    );\n  }\n\n  _refreshFreshnessAndCull() {\n    const nowS = Date.now() / 1000;\n    for (const [id, entry] of this._entries.entries()) {\n      const ageMs = (nowS - entry.nodeData.lastHeard) * 1000;\n      if (entry.nodeData.lastHeard > 0 && ageMs > STALE_THRESHOLD_MS) {\n        this._destroyEntry(id, entry);\n        continue;\n      }\n      const live = _isLiveNode(entry.nodeData, nowS);\n      if (live === entry.live) continue;\n      const retainHover = meshtasticNodeIdsEqual(entry.nodeData.id, this._highlightedNodeId);\n      entry.live = live;\n      entry.marker?.setColor?.(live ? COLOR_LIVE : COLOR_STALE);\n      this._disposeLabel(entry);\n      entry.labelHandle = this._createLabel(entry);\n      if (retainHover) {\n        this._setHighlightedNode(entry.nodeData.id);\n        this._getLabelSystem().setExternalHoveredLabel?.(entry.labelHandle);\n      }\n    }\n  }\n\n  _destroyEntry(id, entry) {\n    this._disposeLabel(entry);\n    entry.marker?.dispose?.();\n    this._entries.delete(id);\n  }\n\n  _clearAll() {\n    for (const [id, entry] of this._entries.entries()) this._destroyEntry(id, entry);\n    this._entries.clear();\n  }\n\n  _createLabel(entry) {\n    let labels;\n    try {\n      labels = this._getLabelSystem();\n    } catch {\n      return null;\n    }\n    const { nodeData, marker } = entry;\n    const position = marker.getTopLocalPosition(new THREE.Vector3(), LABEL_OFFSET_M)\n      || new THREE.Vector3();\n    const handle = labels.createLabel(nodeData.user || nodeData.shortName || nodeData.id, {\n      position,\n      type: 'sensor',\n      color: entry.live ? COLOR_LIVE : COLOR_STALE,\n      objectRadius: LABEL_TARGET_RADIUS_M,\n      subText: _buildSubText(nodeData),\n      occurredAt: nodeData.lastHeard > 0\n        ? new Date(nodeData.lastHeard * 1000).toISOString()\n        : null,\n      recencyAnimated: nodeData.lastHeard > 0,\n      metadata: _buildMetadata(nodeData, marker.source),\n      labelPriority: 3,\n      treeShyness: true,\n    });\n    if (handle?.group) marker.group.add(handle.group);\n    return handle ?? null;\n  }\n\n  _syncLabelPosition(entry) {\n    if (!entry?.labelHandle) return;\n    if (!entry.marker.getTopLocalPosition(this._tmpLabelPosition, LABEL_OFFSET_M)) return;\n    this._getLabelSystem().updatePosition(entry.labelHandle, this._tmpLabelPosition);\n  }\n\n  _disposeLabel(entry) {\n    const handle = entry?.labelHandle;\n    if (!handle) return;\n    handle.group?.parent?.remove?.(handle.group);\n    this._getLabelSystem().removeLabel(handle);\n    entry.labelHandle = null;\n  }\n\n  _getLabelSystem() {\n    return this._labelSystem || getLabelSystem({ planetRadius: this.planetRadius });\n  }\n\n  _hydrateConnectedNodes({ allowFetch = false } = {}) {\n    const cached = Array.isArray(this._service?.nodes) ? this._service.nodes : [];\n    if (cached.length > 0) this._applyNodes(cached);\n    if (!allowFetch || this._service?.isSerialConnected) return;\n    this._service?.fetchNodes?.().catch((error) => {\n      console.warn('[MeshtasticOverlay] node source refresh failed:', error.message);\n    });\n  }\n\n  _subscribeEvents() {\n    this.eventBus?.on('meshtastic:nodes', this._onNodes);\n    this.eventBus?.on('meshtastic:node-hover', this._onRequestedNodeHover);\n    globalThis.document?.addEventListener?.('noclip:scene-label-hover', this._onSceneLabelHover);\n  }\n\n  _unsubscribeEvents() {\n    this.eventBus?.off('meshtastic:nodes', this._onNodes);\n    this.eventBus?.off('meshtastic:node-hover', this._onRequestedNodeHover);\n    globalThis.document?.removeEventListener?.('noclip:scene-label-hover', this._onSceneLabelHover);\n  }\n\n  _handleNodesEvent(detail) {\n    if (!this.showLabels) return;\n    this._applyNodes(Array.isArray(detail?.nodes) ? detail.nodes : []);\n  }\n\n  _handleRequestedNodeHover(detail) {\n    const nodeId = detail?.nodeId || null;\n    const entry = this._findEntry(nodeId);\n    this._setHighlightedNode(entry?.nodeData?.id || nodeId);\n    try {\n      this._getLabelSystem().setExternalHoveredLabel?.(entry?.labelHandle || null);\n    } catch {\n      // The overlay may be receiving a list event before LabelSystem is ready.\n    }\n  }\n\n  _handleSceneLabelHover(event) {\n    this._setHighlightedNode(meshtasticNodeIdFromLabelHover(event?.detail));\n  }\n\n  _findEntry(nodeId) {\n    if (!nodeId) return null;\n    const direct = this._entries.get(nodeId);\n    if (direct) return direct;\n    for (const entry of this._entries.values()) {\n      if (meshtasticNodeIdsEqual(entry.nodeData?.id, nodeId)) return entry;\n    }\n    return null;\n  }\n\n  _setHighlightedNode(nodeId) {\n    const normalized = normalizeMeshtasticNodeId(nodeId) || null;\n    if (normalized === this._highlightedNodeId) return;\n    const previous = this._findEntry(this._highlightedNodeId);\n    this._highlightedNodeId = normalized;\n    const next = this._findEntry(normalized);\n    if (previous && previous !== next) this._applyEntryHighlight(previous, false);\n    if (next) this._applyEntryHighlight(next, true);\n  }\n\n  _applyEntryHighlight(entry, highlighted) {\n    if (!entry?.marker) return;\n    entry.marker.setOpacity?.(\n      highlighted ? 1 : MARKER_OPACITY,\n      highlighted ? 1 : MARKER_OUTLINE_OPACITY,\n    );\n    entry.marker.group.userData.meshtasticHighlighted = !!highlighted;\n  }\n\n  _emitMiniMapUpdate() {\n    try {\n      this.eventBus?.emit('meshtastic:minimapUpdate', { markers: this.getMiniMapMarkers() });\n    } catch (error) {\n      console.error('[MeshtasticOverlay] minimapUpdate emit error:', error);\n    }\n  }\n}\n\nfunction _buildSubText(node) {\n  const parts = [];\n  if (node.hardware) parts.push(node.hardware);\n  if (Number.isFinite(node.snr)) parts.push(`SNR ${node.snr.toFixed(1)} dB`);\n  if (Number.isFinite(node.hopsAway) && node.hopsAway > 0) {\n    parts.push(`${node.hopsAway} hop${node.hopsAway !== 1 ? 's' : ''}`);\n  }\n  if (Number.isFinite(node.batteryLevel)) parts.push(`${node.batteryLevel}%`);\n  return parts.join(' · ');\n}\n\nfunction _isLiveNode(node, nowS = Date.now() / 1000) {\n  return Number.isFinite(node?.lastHeard)\n    && node.lastHeard > 0\n    && (nowS - node.lastHeard) * 1000 < LIVE_THRESHOLD_MS;\n}\n\nfunction _buildMetadata(node, footprintSource = null) {\n  return {\n    id: node.id,\n    meshtasticNodeId: node.id,\n    kind: 'meshtastic-node',\n    entityType: 'sensor',\n    typeLabel: 'Meshtastic node',\n    source: 'Meshtastic',\n    footprintSource,\n    shortName: node.shortName,\n    hardware: node.hardware,\n    role: node.role,\n    lastHeard: node.lastHeard > 0 ? new Date(node.lastHeard * 1000).toISOString() : null,\n    observedAt: node.lastHeard > 0 ? new Date(node.lastHeard * 1000).toISOString() : null,\n    snr: node.snr,\n    hopsAway: node.hopsAway,\n    batteryLevel: node.batteryLevel,\n    altitudeM: node.altitude,\n    lat: node.lat,\n    lon: node.lon,\n  };\n}\n","import {Vector3} from 'three';\nimport {weatherEcef,weatherBasis,weatherPalette,weatherLatLon} from './WeatherFieldMath.js';\nimport {WEATHER_PRODUCT_STYLES} from './WeatherVolumeContract.js';\n\nexport const WEATHER_FLOW_PLAYBACK = 20;\nexport const WEATHER_FLOW_PERIOD_SECONDS = 240;\nconst MAX_STREAMS = 1536, STEPS = 24, MAX_STEP_SECONDS = 180;\nconst D=Math.PI/180;\n\nfunction nearestLevel(rows, height) {\n  let lo=0,hi=rows.length;\n  while(lo<hi){const mid=(lo+hi)>>>1;if(rows[mid].row[2]<height)lo=mid+1;else hi=mid;}\n  if(lo<rows.length&&Math.abs(rows[lo].row[2]-height)<1e-6){const s=rows[lo];return s.valid&&Number.isFinite(s.row[4])&&Number.isFinite(s.row[5])?[s.row[4],s.row[5]]:null;}\n  if(lo===0||lo===rows.length){const s=rows[lo===0?0:rows.length-1];return s.valid&&Math.abs(s.row[2]-height)<=s.verticalReach&&Number.isFinite(s.row[4])&&Number.isFinite(s.row[5])?[s.row[4],s.row[5]]:null;}\n  const a=rows[lo-1],b=rows[lo];\n  if(!a.valid||!b.valid||![a.row[4],a.row[5],b.row[4],b.row[5]].every(Number.isFinite))return null;\n  const t=(height-a.row[2])/Math.max(1e-9,b.row[2]-a.row[2]);\n  return[a.row[4]*(1-t)+b.row[4]*t,a.row[5]*(1-t)+b.row[5]*t];\n}\n\n/** Snapshot streamlines: RK2 integration of the supplied horizontal field at a\n * constant geometric MSL height. No vertical velocity or future motion inferred. */\nexport function buildWeatherWindStreams({volume,columns,memberships,hulls,anchor,stepEast,stepNorth,undulation}) {\n  const arrays={positions:[],colors:[],travel:[],bodies:[]};\n  const empty=()=>({positions:new Float32Array(arrays.positions),colors:new Float32Array(arrays.colors),travel:new Float32Array(arrays.travel),bodies:new Float32Array(arrays.bodies),count:0,playback:WEATHER_FLOW_PLAYBACK});\n  if(volume.product!=='wind'||!memberships.length)return empty();\n  const focus=volume.focus||{lat:memberships[0][0].row[0],lon:memberships[0][0].row[1]},scale=Math.max(.01,Math.cos(focus.lat*D)),buckets=new Map();\n  for(const col of columns.values()){\n    const key=`${Math.floor(col.x/stepEast)},${Math.floor(col.y/stepNorth)}`;\n    if(!buckets.has(key))buckets.set(key,[]);buckets.get(key).push(col);\n  }\n  const extent=[Math.min(...[...columns.values()].map(c=>c.x))-stepEast/2,Math.min(...[...columns.values()].map(c=>c.y))-stepNorth/2,Math.max(...[...columns.values()].map(c=>c.x))+stepEast/2,Math.max(...[...columns.values()].map(c=>c.y))+stepNorth/2];\n  const sample=(lat,lon,height)=>{\n    const x=((lon-focus.lon+540)%360-180)*111320*scale,y=(lat-focus.lat)*111320,bx=Math.floor(x/stepEast),by=Math.floor(y/stepNorth),near=[];\n    if(x<extent[0]||y<extent[1]||x>extent[2]||y>extent[3])return null;\n    for(let dx=-1;dx<=1;dx++)for(let dy=-1;dy<=1;dy++)for(const col of buckets.get(`${bx+dx},${by+dy}`)||[]){\n      const d=((col.x-x)/stepEast)**2+((col.y-y)/stepNorth)**2;if(d<=2.2)near.push({col,d});\n    }\n    near.sort((a,b)=>a.d-b.d);if(!near.length||near[0].d>.8**2)return null;\n    // The nearest column is authoritative for an explicit missing-data barrier.\n    if(!nearestLevel(near[0].col.rows,height))return null;\n    let east=0,north=0,weight=0;\n    for(const {col,d}of near.slice(0,4)){const v=nearestLevel(col.rows,height);if(!v)continue;const w=1/Math.max(.0001,d);east+=v[0]*w;north+=v[1]*w;weight+=w;}\n    return weight?[east/weight,north/weight]:null;\n  };\n  const advance=(lat,lon,height,u,v,dt)=>{\n    const p=new Vector3().fromArray(weatherEcef(lat,lon,height+undulation(lat,lon))),[east,,north]=weatherBasis(lat,lon);\n    p.addScaledVector(east,u*dt).addScaledVector(north,v*dt);\n    return weatherLatLon(p);\n  };\n  const integrate=(seed,sign)=>{\n    let lat=seed.row[0],lon=seed.row[1],time=0;const height=seed.row[2],points=[];\n    for(let i=0;i<=STEPS;i++){\n      const wind=sample(lat,lon,height);if(!wind)break;\n      const speed=Math.hypot(...wind);if(speed<.1)break;\n      points.push({position:weatherEcef(lat,lon,height+undulation(lat,lon)).map((v,k)=>v-anchor[k]),time,speed,velocity:weatherBasis(lat,lon)[0].multiplyScalar(wind[0]).addScaledVector(weatherBasis(lat,lon)[2],wind[1]).toArray()});\n      const dt=Math.min(MAX_STEP_SECONDS,Math.min(stepEast,stepNorth)*.35/speed)*sign;\n      const mid=advance(lat,lon,height,wind[0],wind[1],dt/2),velocity=sample(mid[0],mid[1],height);if(!velocity)break;\n      const next=advance(lat,lon,height,velocity[0],velocity[1],dt);\n      if(!sample(next[0],next[1],height))break;\n      [lat,lon]=next;time+=dt;\n    }\n    return points;\n  };\n  let count=0;\n  const total=memberships.length,admitted=Math.min(total,MAX_STREAMS),perBody=Math.max(1,Math.min(3,Math.floor(MAX_STREAMS/admitted)));\n  for(let slot=0;slot<admitted;slot++){\n    const body=Math.floor(slot*total/admitted),members=memberships[body],hull=hulls[body];\n    hull.flowStart=arrays.positions.length/6;hull.flowCount=0;hull.pickBounds=hull.bounds.slice();\n    const center=members.reduce((sum,s)=>sum.add(s.position),new Vector3()).divideScalar(members.length);\n    const seeds=[members.reduce((best,s)=>s.position.distanceToSquared(center)<best.position.distanceToSquared(center)?s:best)];\n    while(seeds.length<Math.min(perBody,members.length)){\n      let best=null,score=-1;\n      for(const candidate of members){if(!candidate.valid||!Number.isFinite(candidate.row[4])||Math.hypot(candidate.row[4],candidate.row[5])<.1)continue;\n        const distance=Math.min(...seeds.map(s=>candidate.position.distanceToSquared(s.position)));if(distance>score){score=distance;best=candidate;}}\n      if(!best||score<1)break;seeds.push(best);\n    }\n    for(const seed of seeds){\n      const back=integrate(seed,-1).reverse(),forward=integrate(seed,1),points=[...back.slice(0,-1),...forward];\n      if(points.length<2)continue;count++;\n      // Cubic Hermite follows the sampled endpoint velocities; unlike a\n      // decorative arc it has no invented apex, lift or oscillation.\n      const smooth=(a,b,t)=>{const t2=t*t,t3=t2*t,dt=b.time-a.time;\n        return{position:a.position.map((v,k)=>(2*t3-3*t2+1)*v+(t3-2*t2+t)*dt*a.velocity[k]+(-2*t3+3*t2)*b.position[k]+(t3-t2)*dt*b.velocity[k]),time:a.time+dt*t,speed:a.speed*(1-t)+b.speed*t};};\n      for(let i=0;i<points.length-1;i++)for(let subdivision=0;subdivision<2;subdivision++)for(const p of[smooth(points[i],points[i+1],subdivision/2),smooth(points[i],points[i+1],(subdivision+1)/2)]){\n        arrays.positions.push(...p.position);arrays.colors.push(...weatherPalette(WEATHER_PRODUCT_STYLES.wind,p.speed));arrays.travel.push(p.time);arrays.bodies.push(body);\n        for(let k=0;k<3;k++){hull.pickBounds[k]=Math.min(hull.pickBounds[k],p.position[k]);hull.pickBounds[k+3]=Math.max(hull.pickBounds[k+3],p.position[k]);}\n      }\n    }\n    hull.flowCount=arrays.positions.length/6-hull.flowStart;\n  }\n  return{...empty(),count};\n}\n","import * as THREE from 'three';\nimport {WEATHER_FLOW_PERIOD_SECONDS,WEATHER_FLOW_PLAYBACK} from './WeatherWindStreams.js';\n\nfunction focusUniforms() { return {hoverBody:{value:-1},selectedBody:{value:-1}}; }\nexport function setWeatherVolumeFocus(mesh, hovered = -1, selected = -1) {\n  mesh.traverse(object => {const uniforms=object.material?.userData.weatherUniforms;if(uniforms){uniforms.hoverBody.value=hovered;uniforms.selectedBody.value=selected;}});\n}\n\nfunction createStreams(result,opacity) {\n  const data=result.streams,geometry=new THREE.BufferGeometry();\n  for(const [name,array,size]of[['position',data.positions,3],['color',data.colors,3],['travelTime',data.travel,1],['weatherBody',data.bodies,1]])geometry.setAttribute(name,new THREE.BufferAttribute(array,size));\n  const uniforms={...focusUniforms(),flowTime:{value:0},opacity:{value:opacity}};\n  const material=new THREE.ShaderMaterial({transparent:true,opacity,depthWrite:false,toneMapped:false,uniforms,\n    vertexShader:`attribute vec3 color;attribute float travelTime;attribute float weatherBody;\n      varying vec3 flowColor;varying float flowTravel;varying float flowBody;\n      #include <common>\n      #include <logdepthbuf_pars_vertex>\n      void main(){flowColor=color;flowTravel=travelTime;flowBody=weatherBody;\n        vec4 mvPosition=modelViewMatrix*vec4(position,1.0);gl_Position=projectionMatrix*mvPosition;\n        #include <logdepthbuf_vertex>\n      }`,\n    fragmentShader:`uniform float flowTime,opacity,hoverBody,selectedBody;\n      varying vec3 flowColor;varying float flowTravel;varying float flowBody;\n      #include <logdepthbuf_pars_fragment>\n      void main(){\n        #include <logdepthbuf_fragment>\n        float selected=1.0-step(0.5,abs(flowBody-selectedBody));\n        float hovered=1.0-step(0.5,abs(flowBody-hoverBody));\n        float phase=fract((flowTravel-flowTime)/${WEATHER_FLOW_PERIOD_SECONDS.toFixed(1)});\n        float dash=smoothstep(0.0,0.1,phase)*(1.0-smoothstep(0.38,0.55,phase));\n        vec3 color=mix(flowColor,vec3(0.96,0.98,1.0),hovered*0.6);\n        color=mix(color,vec3(1.0,0.67,0.13),selected*0.8);\n        gl_FragColor=vec4(color,opacity*mix(0.18,1.0,dash)*mix(0.85,1.0,max(selected,hovered)));\n        #include <colorspace_fragment>\n      }`});\n  material.userData.weatherUniforms=uniforms;\n  const lines=new THREE.LineSegments(geometry,material);lines.name='Horizontal wind streamlines · animated snapshot';\n  // Geometry is built in the worker. One bounded uniform write per actual draw,\n  // including XR/mobile frames; no CPU particle advection or independent RAF.\n  lines.onBeforeRender=()=>{uniforms.flowTime.value=(performance.now()/1000%(WEATHER_FLOW_PERIOD_SECONDS*1024/WEATHER_FLOW_PLAYBACK))*WEATHER_FLOW_PLAYBACK;};\n  lines.raycast=()=>{};\n  return lines;\n}\n\n/** One batched weather surface. Per-body rim emphasis supplies hover/selection\n * without wireframe triangles, extra render targets, or per-body draw calls. */\nexport function createWeatherVolumeMesh(result,opacity) {\n  const geometry=new THREE.BufferGeometry();\n  for(const[name,array,size]of[['position',result.positions,3],['normal',result.normals,3],['color',result.colors,3],['weatherWeight',result.weights,1],['weatherBody',result.bodies,1]])geometry.setAttribute(name,new THREE.BufferAttribute(array,size));\n  geometry.setIndex(new THREE.BufferAttribute(result.indices,1));\n  const box=new THREE.Box3(new THREE.Vector3().fromArray(result.bounds.minimum),new THREE.Vector3().fromArray(result.bounds.maximum));\n  geometry.boundingBox=box;geometry.boundingSphere=box.getBoundingSphere(new THREE.Sphere());\n  const material=new THREE.MeshBasicMaterial({vertexColors:true,transparent:true,opacity,depthWrite:false,depthTest:true,toneMapped:false,side:THREE.DoubleSide,forceSinglePass:true});\n  const uniforms=focusUniforms();material.userData.weatherUniforms=uniforms;\n  material.customProgramCacheKey=()=>`weather-convex-interaction-v2-${result.streams.count>0?'wind':'scalar'}`;\n  material.onBeforeCompile=shader=>{\n    Object.assign(shader.uniforms,uniforms);\n    shader.vertexShader='attribute float weatherWeight;\\nattribute float weatherBody;\\nvarying float vWeatherWeight;\\nvarying float vWeatherBody;\\nvarying vec3 vWeatherNormal;\\nvarying vec3 vWeatherView;\\n'+shader.vertexShader;\n    shader.vertexShader=shader.vertexShader.replace('#include <project_vertex>',`#include <project_vertex>\n      vWeatherBody=weatherBody;vWeatherWeight=weatherWeight;\n      vWeatherNormal=normalize(normalMatrix*normal);vWeatherView=-mvPosition.xyz;`);\n    shader.fragmentShader='uniform float hoverBody,selectedBody;\\nvarying float vWeatherWeight;\\nvarying float vWeatherBody;\\nvarying vec3 vWeatherNormal;\\nvarying vec3 vWeatherView;\\n'+shader.fragmentShader;\n    shader.fragmentShader=shader.fragmentShader.replace('#include <color_fragment>',`#include <color_fragment>\n      float weatherFacing=abs(dot(normalize(vWeatherNormal),normalize(vWeatherView)));\n      float weatherSelected=1.0-step(0.5,abs(vWeatherBody-selectedBody));\n      float weatherHovered=1.0-step(0.5,abs(vWeatherBody-hoverBody));\n      float weatherFocus=max(weatherSelected,weatherHovered),weatherRim=pow(1.0-weatherFacing,1.6);\n      diffuseColor.rgb*=0.78+0.22*weatherFacing;\n      diffuseColor.rgb=mix(diffuseColor.rgb,vec3(0.96,0.98,1.0),weatherHovered*(0.25+0.55*weatherRim));\n      diffuseColor.rgb=mix(diffuseColor.rgb,vec3(1.0,0.67,0.13),weatherSelected*(0.3+0.6*weatherRim));\n      diffuseColor.a*=max(vWeatherWeight*${result.streams.count>0?'0.22':'1.0'}*(0.22+0.78*pow(weatherFacing,0.65)),weatherFocus*(0.08+0.8*weatherRim));`);\n  };\n  const mesh=new THREE.Mesh(geometry,material);mesh.position.fromArray(result.anchor);\n  Object.assign(mesh.userData,{weatherSamples:result.count,weatherHulls:result.hulls.length,weatherStreams:result.streams.count,weatherRepresentation:result.representation});\n  // All interaction uses the worker-built convex BVH, including hover rays.\n  mesh.raycast=()=>{};\n  if(result.streams.count){const lines=createStreams(result,opacity),b=result.picking.nodes[0].bounds;\n    lines.geometry.boundingBox=new THREE.Box3(new THREE.Vector3(...b.slice(0,3)),new THREE.Vector3(...b.slice(3)));\n    lines.geometry.boundingSphere=lines.geometry.boundingBox.getBoundingSphere(new THREE.Sphere());mesh.add(lines);}\n\n  return mesh;\n}\n\nexport function setWeatherVolumeOpacity(mesh,opacity) {\n  mesh.traverse(object=>{if(object.material){object.material.opacity=opacity;if(object.material.uniforms?.opacity)object.material.uniforms.opacity.value=opacity;}});\n}\nexport function disposeWeatherVolumeMesh(mesh) {\n  mesh.removeFromParent();mesh.traverse(object=>{object.geometry?.dispose();object.material?.dispose();});\n}\n","/** Worker-built body BVH. Picking intersects closed convex half-spaces, never\n * all mesh triangles. Bounds include wind paths where present. */\nexport function buildWeatherPickTree(bodies) {\n  const order = bodies.map((_, i) => i), nodes = [];\n  const build = (start, end) => {\n    const bounds = [Infinity, Infinity, Infinity, -Infinity, -Infinity, -Infinity];\n    for (let i = start; i < end; i++) for (let k = 0; k < 3; k++) {\n      const b = bodies[order[i]].pickBounds || bodies[order[i]].bounds;\n      bounds[k] = Math.min(bounds[k], b[k]); bounds[k + 3] = Math.max(bounds[k + 3], b[k + 3]);\n    }\n    const id = nodes.length, node = {bounds, start, count:end - start}; nodes.push(node);\n    if (end - start > 8) {\n      const spans = [0, 1, 2].map(k => bounds[k + 3] - bounds[k]), axis = spans.indexOf(Math.max(...spans));\n      const slice = order.slice(start, end).sort((a, b) => {\n        const x = bodies[a].pickBounds || bodies[a].bounds, y = bodies[b].pickBounds || bodies[b].bounds;\n        return x[axis] + x[axis + 3] - y[axis] - y[axis + 3];\n      });\n      order.splice(start, slice.length, ...slice);\n      const mid = (start + end) >>> 1;\n      node.left = build(start, mid); node.right = build(mid, end); node.count = 0;\n    }\n    return id;\n  };\n  if (bodies.length) build(0, bodies.length);\n  return {nodes, order:new Uint32Array(order)};\n}\n\nexport function weatherRayBox(origin, direction, bounds, limit = Infinity, padding = 0) {\n  let near = 0, far = limit;\n  for (let k = 0; k < 3; k++) {\n    if (Math.abs(direction[k]) < 1e-12) { if (origin[k] < bounds[k] - padding || origin[k] > bounds[k + 3] + padding) return null; continue; }\n    let a = (bounds[k] - padding - origin[k]) / direction[k], b = (bounds[k + 3] + padding - origin[k]) / direction[k];\n    if (a > b) [a, b] = [b, a]; near = Math.max(near, a); far = Math.min(far, b);\n    if (near > far) return null;\n  }\n  return near;\n}\n\nexport function weatherRayConvex(origin, direction, planes, body, limit = Infinity) {\n  let near = 0, far = limit;\n  for (let i = body.planeStart * 4; i < (body.planeStart + body.planeCount) * 4; i += 4) {\n    const distance = planes[i + 3] - planes[i] * origin[0] - planes[i + 1] * origin[1] - planes[i + 2] * origin[2];\n    const denominator = planes[i] * direction[0] + planes[i + 1] * direction[1] + planes[i + 2] * direction[2];\n    if (Math.abs(denominator) < 1e-12) { if (distance < -.01) return null; continue; }\n    const t = distance / denominator;\n    if (denominator < 0) near = Math.max(near, t); else far = Math.min(far, t);\n    if (near > far + .01) return null;\n  }\n  return far >= 0 ? near > 0 ? near : far : null;\n}\n\n/** First WGS84 intersection blocks picking bodies through the far hemisphere. */\nexport function weatherEarthLimit(origin, direction) {\n  const radii = [6378137, 6356752.314245179, 6378137];\n  let a = 0, b = 0, c = -1;\n  for (let k = 0; k < 3; k++) {const p = origin[k] / radii[k], d = direction[k] / radii[k]; a += d*d; b += p*d; c += p*p;}\n  if (c <= 0) return Infinity;\n  const disc = b*b - a*c;\n  if (disc < 0) return Infinity;\n  const t = (-b - Math.sqrt(disc)) / a;\n  return t > 0 ? t : Infinity;\n}\n\nexport function weatherPickCandidates(tree, origin, direction, limit, padding = 0) {\n  if (!tree.nodes.length) return [];\n  const stack = [0], result = [];\n  while (stack.length) {\n    const node = tree.nodes[stack.pop()];\n    if (weatherRayBox(origin, direction, node.bounds, limit, padding) === null) continue;\n    if (node.count) for (let i = node.start; i < node.start + node.count; i++) result.push(tree.order[i]);\n    else stack.push(node.left, node.right);\n  }\n  return result;\n}\n","import * as THREE from 'three';\nimport {getLabelSystem} from '../labels/LabelSystem.js';\nimport {weatherRayBox,weatherRayConvex,weatherEarthLimit,weatherPickCandidates} from './WeatherVolumePicking.js';\nimport {WEATHER_PRODUCT_STYLES} from './WeatherVolumeContract.js';\nimport {WEATHER_FLOW_PLAYBACK} from './WeatherWindStreams.js';\nimport {setWeatherVolumeFocus} from './WeatherVolumeMesh.js';\n\n/** One pointer owner for all weather layers. Coalesced hover uses the existing\n * scene update; deliberate click shares the HUD gesture gate and LabelSystem. */\nexport class WeatherVolumeInteraction {\n  constructor({overlay,camera,canvas,labelSystem=getLabelSystem}) {\n    Object.assign(this,{overlay,camera,canvas,labelSystem});this.hovered=null;this.selected=null;this.label=null;\n    this.raycaster=new THREE.Raycaster();this.inverse=new THREE.Matrix4();this.localRay=new THREE.Ray();\n    this.a=new THREE.Vector3();this.b=new THREE.Vector3();this.closest=new THREE.Vector3();this.onRay=new THREE.Vector3();\n    this._move=e=>{if(e.buttons||e.pointerType==='touch'){this.pointer=null;this.clearHover();return;}this.pointer={x:e.clientX,y:e.clientY};this.dirty=true;};\n    this._leave=()=>{this.pointer=null;this.clearHover();};\n    canvas?.addEventListener('pointermove',this._move);canvas?.addEventListener('pointerleave',this._leave);\n  }\n  active() {\n    if(this.overlay.disposed||this.overlay.suspended||!this.overlay._enabled||this.overlay.options.opacity<=0)return false;\n    for(const state of this.overlay.layers.values())if(state.enabled&&state.mesh&&state.result?.picking.nodes.length)return true;\n    return false;\n  }\n  update(now=performance.now()) {\n    if(!this.active()||!this.pointer)return;\n    if(now<(this.nextPick||0))return;this.nextPick=now+80;\n    this.camera.updateMatrixWorld();this.overlay.group.updateWorldMatrix(true,false);\n    const key=[...this.camera.matrixWorld.elements,...this.camera.projectionMatrix.elements,...this.overlay.group.matrixWorld.elements].join(',');\n    if(!this.dirty&&key===this.cameraKey)return;\n    this.cameraKey=key;this.dirty=false;this._setHover(this.pickAtClient(this.pointer.x,this.pointer.y));\n  }\n  pickAtClient(x,y) {\n    if(!this.active()||!this.canvas)return null;\n    const rect=this.canvas.getBoundingClientRect();\n    if(!rect.width||!rect.height||x<rect.left||x>rect.right||y<rect.top||y>rect.bottom)return null;\n    this.camera.updateMatrixWorld();this.raycaster.setFromCamera(new THREE.Vector2((x-rect.left)/rect.width*2-1,1-(y-rect.top)/rect.height*2),this.camera);\n    const pixelAngle=this.camera.isPerspectiveCamera?2*Math.tan(this.camera.fov*Math.PI/360)/this.camera.zoom/rect.height:0;\n    let best=null;\n    for(const state of this.overlay.layers.values()) {\n      if(!state.enabled||!state.mesh||!state.result?.picking.nodes.length)continue;\n      const result=state.result;state.mesh.updateWorldMatrix(true,false);\n      this.inverse.copy(state.mesh.matrixWorld).invert();this.localRay.copy(this.raycaster.ray).applyMatrix4(this.inverse);\n      const origin=this.localRay.origin.toArray(),direction=this.localRay.direction.toArray();\n      const limit=weatherEarthLimit(origin.map((v,k)=>v+result.anchor[k]),direction);\n      const root=result.picking.nodes[0].bounds;\n      const extent=Math.hypot(...[0,1,2].map(k=>Math.max(Math.abs(root[k]-origin[k]),Math.abs(root[k+3]-origin[k]))));\n      const tolerance=state.info.product==='wind'?Math.max(1,extent*pixelAngle*6):0;\n      for(const index of weatherPickCandidates(result.picking,origin,direction,limit,tolerance)){\n        const body=result.hulls[index];\n        if(weatherRayBox(origin,direction,body.pickBounds||body.bounds,limit,tolerance)===null)continue;\n        let distance=null,point=null,screenScore=Infinity;\n        if(state.info.product==='wind'&&body.flowCount){\n          let score=Infinity;\n          for(let s=body.flowStart;s<body.flowStart+body.flowCount;s++){\n            this.a.fromArray(result.streams.positions,s*6);this.b.fromArray(result.streams.positions,s*6+3);\n            const squared=this.localRay.distanceSqToSegment(this.a,this.b,this.onRay,this.closest),depth=this.onRay.distanceTo(this.localRay.origin);\n            const threshold=Math.max(1,depth*pixelAngle*6);\n            if(depth>limit||squared>threshold*threshold||squared/(threshold*threshold)>=score)continue;\n            score=squared/(threshold*threshold);screenScore=score;distance=depth;point=this.closest.toArray();\n          }\n        }else distance=weatherRayConvex(origin,direction,result.planes,body,limit);\n        if(distance===null||distance>limit)continue;\n        const flow=Number.isFinite(screenScore);\n        if(best){\n          if(flow&&best.flow){if(screenScore>best.screenScore+.0025||Math.abs(screenScore-best.screenScore)<=.0025&&distance>=best.distance)continue;}\n          else if(!flow&&best.flow||!flow&&!best.flow&&distance>=best.distance)continue;\n        }\n        best={state,index,body,distance,flow,screenScore,point:point||origin.map((v,k)=>v+direction[k]*distance)};\n      }\n    }\n    return best;\n  }\n  _applyFocus() {\n    for(const state of this.overlay.layers.values())if(state.mesh)setWeatherVolumeFocus(state.mesh,this.hovered?.state===state?this.hovered.index:-1,this.selected?.state===state?this.selected.index:-1);\n  }\n  _setHover(hit) {\n    if(this.hovered?.state===hit?.state&&this.hovered?.index===hit?.index)return;\n    this.hovered=hit;this._applyFocus();\n  }\n  clearHover() {this._setHover(null);}\n  selectAtClient(x,y) {\n    const hit=this.pickAtClient(x,y);\n    if(!hit){this.clearSelection();return false;}\n    if(this.selected?.state===hit.state&&this.selected.index===hit.index)return true;\n    this.clearSelection();this.selected={...hit,source:hit.state.info.source,sampleKey:hit.body.sampleKey,sampleHeight:hit.body.sample[2],sampleTolerance:hit.body.sampleTolerances[hit.body.sampleKeys.indexOf(hit.body.sampleKey)]};\n    this._showLabel();this._applyFocus();return true;\n  }\n  _showLabel() {\n    const selected=this.selected;if(!selected)return;\n    const {state,body}=selected,info=state.info,style=WEATHER_PRODUCT_STYLES[info.product],ls=this.labelSystem();\n    const value=n=>n.toLocaleString('en-US',{maximumSignificantDigits:4});\n    const range=body.minimum===body.maximum?value(body.minimum):`${value(body.minimum)}–${value(body.maximum)}`;\n    const title=`${state.definition.label} · ${range} ${info.units||style.unit}`;\n    const subText=`${info.source.toUpperCase()} · ${info.classification} · ${new Date(info.validTime).toISOString().slice(11,16)} UTC`;\n    const position=new THREE.Vector3().fromArray(selected.point||body.anchorPosition).add(new THREE.Vector3().fromArray(state.result.anchor));\n    const metadata={typeLabel:state.definition.label,weatherBodyId:`${state.id}:${selected.sampleKey}`,source:info.source,classification:info.classification,\n      validTime:info.validTime,referenceTime:info.referenceTime,units:info.units,minimum:body.minimum,maximum:body.maximum,mean:body.mean,\n      samples:body.samples,minimumHeightMSL:body.minimumHeight,maximumHeightMSL:body.maximumHeight,\n      lat:body.sample[0],lon:body.sample[1],altitudeM:body.sample[2],sourceUrl:info.sourceUrl,attribution:info.attribution,\n      sourceUnits:info.sourceUnits||info.units,unitConversion:info.unitConversion||'None',verticalDatum:'Geometric MSL; EGM96 → WGS84 for rendering',\n      representation:state.result.representation,warnings:(info.warnings||[]).join(' · '),sampling:info.sampling};\n    if(info.product==='wind')Object.assign(metadata,{eastMps:body.sample[4],northMps:body.sample[5],\n      flow:'Instantaneous horizontal streamlines at fixed geometric MSL height; not forecast trajectories. No vertical wind supplied.',\n      animation:`${WEATHER_FLOW_PLAYBACK}× display playback; colors and numeric velocities retain source units.`});\n    if(!this.label){\n      this.label=ls.createLabel(title,{position,type:'weather-volume-'+info.product,color:style.colors.at(-1),objectRadius:150,\n        subText,occurredAt:info.validTime,maxDistance:20000000,labelPriority:1000,metadata,\n        onSelect:()=>this._applyFocus(),onDeselect:()=>this.clearSelection()});\n      this.overlay.group.add(this.label.group);\n    }else{ls.updateText(this.label,title,subText);ls.updatePosition(this.label,position);ls.updateMetadata(this.label,metadata);}\n    state.label=this.label;this.label.sourceVisible=true;this.label.occurredAt=info.validTime;this.label.occurredAtMs=Date.parse(info.validTime);ls.setExternalSelectedLabel(this.label);\n  }\n  clearSelection() {\n    const selected=this.selected,label=this.label;this.selected=null;this.label=null;\n    if(selected&&selected.state.label===label)selected.state.label=null;\n    if(label){const ls=this.labelSystem();if(ls._externalSelectedLabel===label)ls.setExternalSelectedLabel(null,{notify:false});label.dispose();}\n    this._applyFocus();\n  }\n  replace(state) {\n    if(this.hovered?.state===state)this.hovered=null;\n    if(this.selected?.state===state){\n      const index=state.info.source===this.selected.source?state.result.hulls.findIndex(h=>{const i=h.sampleKeys.indexOf(this.selected.sampleKey);return i>=0&&Math.abs(h.sampleHeights[i]-this.selected.sampleHeight)<=Math.min(h.sampleTolerances[i],this.selected.sampleTolerance);}):-1;\n      if(index<0)this.clearSelection();\n      else{const body=state.result.hulls[index],member=body.sampleKeys.indexOf(this.selected.sampleKey);this.selected={...this.selected,sampleHeight:body.sampleHeights[member],sampleTolerance:body.sampleTolerances[member],index,body:state.result.hulls[index],point:state.result.hulls[index].anchorPosition};this._showLabel();}\n    }\n    this.dirty=true;this.nextPick=0;this._applyFocus();\n  }\n  retire(state) {if(this.hovered?.state===state)this.clearHover();if(this.selected?.state===state)this.clearSelection();this.dirty=true;}\n  hide() {this.pointer=null;this.clearHover();if(this.label)this.label.sourceVisible=false;}\n  show() {if(this.label)this.label.sourceVisible=true;this.dirty=true;}\n  dispose() {this.hide();this.clearSelection();this.canvas?.removeEventListener('pointermove',this._move);this.canvas?.removeEventListener('pointerleave',this._leave);}\n}\n","import{getBackendApiBase}from'../shared/backend.js';\nimport{getNoclipGovernanceClient}from'../shared/NoclipGovernanceClient.js';\n/** Decoded byte bound is enforced while reading, before worker JSON parsing. */\nexport async function readWeatherVolume(query,signal){\n  const url=getBackendApiBase()+'/v1/weather/volumes?'+new URLSearchParams(query);\n  const response=await getNoclipGovernanceClient().request(url,{signal,governanceLane:'scene',headers:{Accept:'application/json'}});\n  if(!response.ok){await response.body?.cancel();throw new Error(response.status===400?'This source does not provide the selected weather product/time.':'Weather source is currently unavailable for this region/time.');}\n  const reader=response.body.getReader(),parts=[];let size=0;\n  try{while(true){signal?.throwIfAborted();const{value,done}=await reader.read();if(done)break;size+=value.byteLength;if(size>8*1024*1024)throw new Error('Weather volume response limit');parts.push(value);}\n    signal?.throwIfAborted();const bytes=new Uint8Array(size);let offset=0;for(const p of parts){bytes.set(p,offset);offset+=p.length;}return bytes.buffer;\n  }finally{await reader.cancel().catch(()=>{});reader.releaseLock();}\n}\n","import * as THREE from 'three';\nimport{dirToLatLonLocal,ellipsoidRadiusForLocalDir}from'../../modules/geometry-utils.js';\nimport{createWeatherVolumeMesh,setWeatherVolumeOpacity,disposeWeatherVolumeMesh}from'./WeatherVolumeMesh.js';\nimport{WeatherVolumeInteraction}from'./WeatherVolumeInteraction.js';\nimport{getEgm96GeoidRaster}from'../imagery/MapzenElevationTileSource.js';\nimport{WEATHER_VOLUME_LAYERS,WEATHER_VOLUME_DEFAULTS}from'./WeatherVolumeContract.js';\nimport{readWeatherVolume}from'./WeatherVolumeApi.js';\n\nexport class WeatherVolumeOverlay{\n  constructor({parentGroup,camera,eventBus,sceneInitializer}){\n    this.sceneInitializer=sceneInitializer;this.parentGroup=parentGroup;this.camera=camera;this.eventBus=eventBus;\n    this.options={...WEATHER_VOLUME_DEFAULTS};this.layers=new Map();this.active=0;this.disposed=false;this.suspended=false;this.lastCheck=0;\n    this.group=new THREE.Group();this.group.name='Scientific weather volumes';parentGroup.add(this.group);sceneInitializer?.addDepthPassExclude?.(this.group);\n    this.interaction=new WeatherVolumeInteraction({overlay:this,camera,canvas:sceneInitializer?.renderer?.domElement});\n    this.p=new THREE.Vector3();this.d=new THREE.Vector3();this.inverse=new THREE.Matrix4();this._enabled=true;\n    this._onVisibility=()=>{if(document.hidden)this.setSuspended(true);else this.setSuspended(false);};\n    globalThis.document?.addEventListener('visibilitychange',this._onVisibility);\n  }\n  setSuspended(value){this.suspended=value===true;this.interaction?.[this.suspended?'hide':'show']();if(this.suspended)for(const state of this.layers.values())this._cancel(state);this.lastCheck=0;}\n  setOptions(options={}){const changed=['source','radarSource','forecastHours','radiusKm','lod'].some(k=>options[k]!==undefined&&options[k]!==this.options[k]);Object.assign(this.options,options);\n    for(const state of this.layers.values()){if(state.mesh)setWeatherVolumeOpacity(state.mesh,this.options.opacity);if(changed){this._cancel(state);state.key=null;}}\n    this.lastCheck=0;\n  }\n  setGlobalEnabled(enabled){this._enabled=enabled!==false;this.group.visible=this._enabled;this.interaction?.[this._enabled?'show':'hide']();if(!this._enabled)for(const state of this.layers.values())this._cancel(state);this.lastCheck=0;}\n  setLayerEnabled(id,enabled){const definition=WEATHER_VOLUME_LAYERS.find(x=>x.id===id);if(!definition)return;\n    let state=this.layers.get(id);if(!state){state={id,definition,enabled:false,epoch:0,status:'off'};this.layers.set(id,state);}\n    if(state.enabled===(enabled===true))return;state.enabled=enabled===true;\n    if(!state.enabled){this._cancel(state);this._retire(state);state.status='off';state.key=null;}this.lastCheck=0;\n  }\n  _cancel(state){state.epoch++;state.controller?.abort();state.controller=null;state.worker?.terminate();state.worker=null;state.finishWorker?.(null);state.finishWorker=null;state.pending=null;}\n  _retire(state,{replacement=false}={}){if(!replacement)this.interaction.retire(state);if(state.mesh){disposeWeatherVolumeMesh(state.mesh);state.mesh=null;}if(!replacement)state.result=null;}\n  _focus(){\n    this.camera.getWorldPosition(this.p);this.parentGroup.worldToLocal(this.p);\n    const altitude=this.p.length()-ellipsoidRadiusForLocalDir(this.p.clone().normalize());\n    let target=this.p.clone();\n    if(altitude>100000){\n      this.camera.getWorldDirection(this.d);this.inverse.copy(this.parentGroup.matrixWorld).invert();this.d.transformDirection(this.inverse);\n      const a=6378137,b=6356752.314245,p=this.p,d=this.d,A=(d.x*d.x+d.z*d.z)/(a*a)+d.y*d.y/(b*b),B=2*((p.x*d.x+p.z*d.z)/(a*a)+p.y*d.y/(b*b)),C=(p.x*p.x+p.z*p.z)/(a*a)+p.y*p.y/(b*b)-1,disc=B*B-4*A*C;\n      if(disc<0)return null;const t=(-B-Math.sqrt(disc))/(2*A);if(t<0)return null;target.addScaledVector(d,t);\n    }\n    const ll=dirToLatLonLocal(target.normalize());return{lat:ll.latDeg,lon:ll.lonDeg,altitude};\n  }\n  update(){\n    if(this.disposed)return;\n    if(this.suspended)return;\n    const parked=typeof document!=='undefined'&&(document.hidden||document.body.classList.contains('nca-map-expanded')||document.documentElement.dataset.mapPresentation==='2d');\n    if(parked||!this._enabled){for(const state of this.layers.values())if(state.pending)this._cancel(state);return;}\n    const now=performance.now();this.interaction.update(now);if(now-this.lastCheck<1000)return;this.lastCheck=now;\n    if(![...this.layers.values()].some(s=>s.enabled))return;\n    const focus=this._focus();if(!focus)return;\n    for(const state of this.layers.values()){\n      if(!state.enabled)continue;\n      const radar=['reflectivity','radial-velocity'].includes(state.definition.product);\n      const source=radar?(state.definition.product==='radial-velocity'?'nexrad':this.options.radarSource):this.options.source;\n      const query={source,product:state.definition.product,lat:Math.round(focus.lat*10)/10,lon:Math.round(focus.lon*10)/10,radiusKm:Math.min(400,Math.max(this.options.radiusKm,Math.round(focus.altitude/2000/20)*20)),lod:this.options.lod,forecastHours:radar?0:this.options.forecastHours};\n      const key=JSON.stringify(query);\n      if(state.pending&&state.pending!==key)this._cancel(state);\n      if(state.pending||state.key===key&&Date.now()<state.expires||Date.now()<(state.retryAt||0))continue;\n      if(this.active>=2)continue;\n      void this._load(state,query,key);\n    }\n  }\n  async _load(state,query,key){\n    const epoch=++state.epoch,controller=new AbortController();state.controller=controller;state.pending=key;state.status='loading';this.active++;\n    this._notify();\n    try{\n      const geoid=await getEgm96GeoidRaster({url:'/data/us_nga_egm96_15.tif'});if(controller.signal.aborted)return;\n      const bytes=await readWeatherVolume(query,controller.signal);if(controller.signal.aborted)return;\n      const data=await new Promise((resolve,reject)=>{\n        const worker=new Worker(new URL('./weather-volume-geometry.worker.js',import.meta.url),{type:'module'});state.worker=worker;state.finishWorker=resolve;\n        worker.onmessage=({data})=>{worker.terminate();if(state.worker===worker){state.worker=null;state.finishWorker=null;}data.error?reject(new Error(data.error)):resolve(data);};\n        worker.onerror=()=>{worker.terminate();if(state.worker===worker){state.worker=null;state.finishWorker=null;}reject(new Error('Weather geometry unavailable'));};\n        worker.postMessage({bytes,geoid},[bytes]);\n      });\n      if(!data||controller.signal.aborted||state.epoch!==epoch)return;\n      const{result,info}=data;\n      const mesh=createWeatherVolumeMesh(result,this.options.opacity);mesh.name=state.definition.label;\n      this._retire(state,{replacement:true});this.group.add(mesh);state.mesh=mesh;state.result=result;state.info=info;state.key=key;state.pending=null;state.error=null;state.status=result.count?'ready':info.status==='unavailable'?'unavailable':'empty';\n      state.expires=Date.now()+(query.product==='reflectivity'||query.product==='radial-velocity'?120000:1800000);state.retryAt=0;\n      this.interaction.replace(state);\n    }catch(error){if(!controller.signal.aborted&&state.epoch===epoch){state.status=state.mesh?'stale':'unavailable';state.error=error.message;state.retryAt=Date.now()+60000;}}\n    finally{this.active--;if(state.epoch===epoch){state.pending=null;state.controller=null;}this._notify();}\n  }\n  selectAtClient(x,y){return this.interaction.selectAtClient(x,y);}\n  _notify(){this.eventBus?.emit?.('weather-volumes:status',this.status());}\n  status(){return Object.fromEntries([...this.layers].map(([key,s])=>[key,{enabled:s.enabled,status:s.status,samples:s.mesh?.userData.weatherSamples||0,hulls:s.mesh?.userData.weatherHulls||0,streams:s.mesh?.userData.weatherStreams||0,selected:this.interaction.selected?.state===s?this.interaction.selected.index:null,source:s.info?.source||null,validTime:s.info?.validTime||null,error:s.error||null}]));}\n  dispose(){this.disposed=true;this.interaction.dispose();this.sceneInitializer?.removeDepthPassExclude?.(this.group);globalThis.document?.removeEventListener('visibilitychange',this._onVisibility);for(const state of this.layers.values()){this._cancel(state);this._retire(state);}this.layers.clear();this.group.removeFromParent();}\n}\n","import { getBackendApiBase } from '../shared/backend.js';\nimport { getNoclipGovernanceClient } from '../shared/NoclipGovernanceClient.js';\nimport { SENSOR_SOURCES, getAllSensorIds } from './SensorRegistry.js';\n\nlet _instance = null;\n\nexport class SensorApiService {\n  constructor() {\n    this._cache = new Map();\n    this._inflight = new Map();\n    this._wsConnections = new Map();\n    this._wsListeners = new Map();\n    this._eventBuffer = new Map();\n    this._pollTimers = new Map();\n    this._enabled = new Map();\n    this._lastFetchMs = new Map();\n    this._sourceErrors = new Map(); // sourceId -> { message, code, at, count }\n    this._fetchCounts = new Map(); // sourceId -> { ok, fail }\n  }\n\n  _apiBase() {\n    return getBackendApiBase();\n  }\n\n  async fetchJson(path, opts = {}) {\n    const url = `${this._apiBase()}${path}`;\n    const cacheKey = url;\n    const now = Date.now();\n    const cached = this._cache.get(cacheKey);\n    if (cached && (now - cached.ts) < (opts.cacheTtlMs || 30000)) {\n      return cached.data;\n    }\n    if (this._inflight.has(cacheKey)) {\n      return this._inflight.get(cacheKey);\n    }\n    const promise = getNoclipGovernanceClient().request(url, {\n      signal: opts.signal,\n      governanceLane: 'scene',\n      headers: { Accept: 'application/json' },\n    }).then(async (resp) => {\n      if (!resp.ok) throw new Error(`HTTP ${resp.status}`);\n      const data = await resp.json();\n      this._cache.set(cacheKey, { data, ts: Date.now() });\n      return data;\n    }).finally(() => {\n      this._inflight.delete(cacheKey);\n    });\n    this._inflight.set(cacheKey, promise);\n    return promise;\n  }\n\n  // ── REST polling ────────────────────────────────────────────────────────\n  async fetchSource(sourceId, params = {}) {\n    const source = SENSOR_SOURCES[sourceId];\n    if (!source || !source.proxyPath) return null;\n    const qs = new URLSearchParams(params).toString();\n    const path = qs ? `${source.proxyPath}?${qs}` : source.proxyPath;\n    return this.fetchJson(path, { cacheTtlMs: source.cacheControlSec * 1000 });\n  }\n\n  _trackOk(sourceId) {\n    const c = this._fetchCounts.get(sourceId) || { ok: 0, fail: 0 };\n    c.ok++;\n    this._fetchCounts.set(sourceId, c);\n    this._sourceErrors.delete(sourceId);\n  }\n\n  _trackError(sourceId, err) {\n    const c = this._fetchCounts.get(sourceId) || { ok: 0, fail: 0 };\n    c.fail++;\n    this._fetchCounts.set(sourceId, c);\n    const prev = this._sourceErrors.get(sourceId);\n    this._sourceErrors.set(sourceId, {\n      message: err?.message || String(err),\n      code: err?.status || null,\n      at: Date.now(),\n      count: (prev?.count || 0) + 1,\n    });\n  }\n\n  startPolling(sourceId, callback, overrideIntervalMs) {\n    this.stopPolling(sourceId);\n    const source = SENSOR_SOURCES[sourceId];\n    if (!source) return;\n    const intervalMs = overrideIntervalMs || source.pollIntervalMs;\n    if (!intervalMs || intervalMs <= 0) return;\n\n    const poll = async () => {\n      try {\n        const data = await this.fetchSource(sourceId);\n        if (data && callback) callback(sourceId, data);\n        this._lastFetchMs.set(sourceId, Date.now());\n        this._trackOk(sourceId);\n      } catch (err) {\n        console.warn(`[SensorApi] Poll failed for ${sourceId}:`, err.message);\n        this._trackError(sourceId, err);\n      }\n    };\n    poll();\n    const timer = setInterval(poll, intervalMs);\n    this._pollTimers.set(sourceId, timer);\n  }\n\n  stopPolling(sourceId) {\n    const timer = this._pollTimers.get(sourceId);\n    if (timer) {\n      clearInterval(timer);\n      this._pollTimers.delete(sourceId);\n    }\n  }\n\n  // ── WebSocket connections ───────────────────────────────────────────────\n  connectWebSocket(sourceId, onMessage) {\n    this.disconnectWebSocket(sourceId);\n    const source = SENSOR_SOURCES[sourceId];\n    if (!source || !source.wsUrl) return;\n\n    const connect = () => {\n      let ws;\n      try {\n        ws = new WebSocket(source.wsUrl);\n      } catch (err) {\n        console.warn(`[SensorApi] WS connect failed for ${sourceId}:`, err.message);\n        this._trackError(sourceId, err);\n        return;\n      }\n\n      ws.onopen = () => {\n        console.log(`[SensorApi] WS connected: ${sourceId}`);\n        this._trackOk(sourceId);\n        // EMSC needs no subscribe message, RIPE RIS needs a subscribe\n        if (sourceId === 'ripe_ris') {\n          ws.send(JSON.stringify({\n            type: 'ris_subscribe',\n            data: { type: 'UPDATE' },\n          }));\n        }\n      };\n\n      ws.onmessage = (event) => {\n        try {\n          const msg = JSON.parse(event.data);\n          if (onMessage) onMessage(sourceId, msg);\n        } catch { /* ignore parse errors */ }\n      };\n\n      ws.onerror = (err) => {\n        console.warn(`[SensorApi] WS error for ${sourceId}:`, err);\n        this._trackError(sourceId, { message: 'WebSocket error' });\n      };\n\n      ws.onclose = (event) => {\n        console.log(`[SensorApi] WS closed: ${sourceId} (${event.code})`);\n        this._wsConnections.delete(sourceId);\n        // Reconnect with exponential backoff\n        const meta = this._wsListeners.get(sourceId);\n        if (meta && meta.active) {\n          meta.failures = (meta.failures || 0) + 1;\n          const delay = Math.min(30000, 2000 * Math.pow(1.5, meta.failures - 1));\n          meta.reconnectTimer = setTimeout(() => connect(), delay);\n        }\n      };\n\n      this._wsConnections.set(sourceId, ws);\n    };\n\n    this._wsListeners.set(sourceId, { active: true, failures: 0, reconnectTimer: null });\n    connect();\n  }\n\n  disconnectWebSocket(sourceId) {\n    const meta = this._wsListeners.get(sourceId);\n    if (meta) {\n      meta.active = false;\n      if (meta.reconnectTimer) clearTimeout(meta.reconnectTimer);\n      this._wsListeners.delete(sourceId);\n    }\n    const ws = this._wsConnections.get(sourceId);\n    if (ws) {\n      try { ws.close(1000, 'client disconnect'); } catch { /* ok */ }\n      this._wsConnections.delete(sourceId);\n    }\n  }\n\n  isWebSocketConnected(sourceId) {\n    const ws = this._wsConnections.get(sourceId);\n    return ws && ws.readyState === WebSocket.OPEN;\n  }\n\n  // ── Lifecycle ───────────────────────────────────────────────────────────\n  enableSource(sourceId, callback) {\n    if (this._enabled.get(sourceId)) return;\n    this._enabled.set(sourceId, true);\n    const source = SENSOR_SOURCES[sourceId];\n    if (!source) return;\n\n    if (source.transport === 'websocket' && source.wsUrl) {\n      this.connectWebSocket(sourceId, callback);\n    }\n    if (source.transport === 'rest' || (source.transport === 'websocket' && source.proxyPath)) {\n      this.startPolling(sourceId, callback, source.pollIntervalMs);\n    }\n  }\n\n  disableSource(sourceId) {\n    this._enabled.delete(sourceId);\n    this.stopPolling(sourceId);\n    this.disconnectWebSocket(sourceId);\n  }\n\n  isSourceEnabled(sourceId) {\n    return !!this._enabled.get(sourceId);\n  }\n\n  destroy() {\n    for (const id of getAllSensorIds()) {\n      this.disableSource(id);\n    }\n    this._cache.clear();\n  }\n\n  getLastFetchTime(sourceId) {\n    return this._lastFetchMs.get(sourceId) || 0;\n  }\n\n  getSourceError(sourceId) {\n    return this._sourceErrors.get(sourceId) || null;\n  }\n\n  getSourceFetchCounts(sourceId) {\n    return this._fetchCounts.get(sourceId) || { ok: 0, fail: 0 };\n  }\n\n  getWsReconnectCount(sourceId) {\n    const meta = this._wsListeners.get(sourceId);\n    return meta?.failures || 0;\n  }\n}\n\nexport function getSensorApiService() {\n  if (!_instance) _instance = new SensorApiService();\n  return _instance;\n}\n","/**\n * SensorManager — top-level coordinator that bridges SceneSettings,\n * SensorApiService, SensorEventStore, and the HUD.\n *\n * Usage:\n *   const mgr = getSensorManager();\n *   mgr.init(sceneSettings);\n */\n\nimport { SENSOR_SOURCES, getAllSensorIds } from './SensorRegistry.js';\nimport { getSensorApiService } from './SensorApiService.js';\nimport { getSensorEventStore } from './SensorEventStore.js';\n\nlet _instance = null;\n\nexport class SensorManager {\n  constructor() {\n    this._settings = null;\n    this._api = getSensorApiService();\n    this._store = getSensorEventStore();\n    this._overlay = null;\n    this._initialized = false;\n    this._settingsUnsub = null;\n    this._storeUnsub = null;\n    this._hudCallback = null;\n  }\n\n  /**\n   * @param {Object|SceneSettings} opts — either a SceneSettings instance\n   *   or { settings, apiService?, eventStore?, overlay? }\n   */\n  init(opts) {\n    if (this._initialized) return;\n\n    // Accept both forms: init(sceneSettings) and init({ settings, ... })\n    let sceneSettings;\n    if (opts && typeof opts.subscribe === 'function') {\n      // Direct SceneSettings instance\n      sceneSettings = opts;\n    } else if (opts && opts.settings) {\n      sceneSettings = opts.settings;\n      if (opts.apiService) this._api = opts.apiService;\n      if (opts.eventStore) this._store = opts.eventStore;\n      if (opts.overlay) this._overlay = opts.overlay;\n    } else {\n      console.warn('[SensorManager] init called without valid settings');\n      return;\n    }\n\n    this._settings = sceneSettings;\n    this._initialized = true;\n\n    // Listen for settings changes\n    if (typeof sceneSettings.subscribe === 'function') {\n      this._settingsUnsub = sceneSettings.subscribe(({ patch }) => {\n        if (!patch) return;\n        this._handleSettingsChange(patch);\n      });\n    }\n\n    // Apply initial state from settings\n    this._applyInitialState();\n  }\n\n  setHudCallback(fn) {\n    this._hudCallback = fn;\n    // Also subscribe to store changes\n    if (!this._storeUnsub) {\n      this._storeUnsub = this._store.subscribe((payload) => {\n        if (this._hudCallback) this._hudCallback(payload);\n      });\n    }\n  }\n\n  _applyInitialState() {\n    const sensorSettings = this._settings?.getSection('scene.sensors') || {};\n    if (!sensorSettings.enabled) {\n      this._overlay?.setEnabled(false);\n      return;\n    }\n\n    // Enable the overlay so visuals render\n    this._overlay?.setEnabled(true);\n\n    const sources = sensorSettings.sources || {};\n    for (const id of getAllSensorIds()) {\n      const cfg = sources[id];\n      if (cfg && cfg.enabled) {\n        this._api.enableSource(id, (sourceId, data) => {\n          this._store.ingest(sourceId, data);\n        });\n      }\n    }\n  }\n\n  _handleSettingsChange(patch) {\n    // Check if sensors section changed\n    const sensorPatch = patch?.scene?.sensors || patch?.sensors;\n    if (!sensorPatch) return;\n\n    // Master toggle\n    if (sensorPatch.enabled === false) {\n      this._overlay?.setEnabled(false);\n      for (const id of getAllSensorIds()) {\n        this._api.disableSource(id);\n      }\n      return;\n    }\n\n    if (sensorPatch.enabled === true) {\n      this._overlay?.setEnabled(true);\n      this._applyInitialState();\n      return;\n    }\n\n    // Per-source toggles\n    if (sensorPatch.sources) {\n      // Ensure overlay is visible when any source gets enabled\n      const anyEnabled = Object.values(sensorPatch.sources).some(cfg => cfg.enabled === true);\n      if (anyEnabled && this._overlay && !this._overlay.enabled) {\n        this._overlay.setEnabled(true);\n      }\n\n      for (const [id, cfg] of Object.entries(sensorPatch.sources)) {\n        if (cfg.enabled === true && !this._api.isSourceEnabled(id)) {\n          this._api.enableSource(id, (sourceId, data) => {\n            this._store.ingest(sourceId, data);\n          });\n        } else if (cfg.enabled === false) {\n          this._api.disableSource(id);\n        }\n      }\n    }\n  }\n\n  getStore() {\n    return this._store;\n  }\n\n  getApi() {\n    return this._api;\n  }\n\n  getSourceStatus() {\n    const result = {};\n    for (const id of getAllSensorIds()) {\n      const source = SENSOR_SOURCES[id];\n      const stats = this._store.getStats(id);\n      const error = this._api.getSourceError?.(id) || null;\n      const counts = this._api.getSourceFetchCounts?.(id) || { ok: 0, fail: 0 };\n      const wsReconnects = this._api.getWsReconnectCount?.(id) || 0;\n      result[id] = {\n        label: source.label,\n        enabled: this._api.isSourceEnabled(id),\n        transport: source.transport,\n        tier: source.tier,\n        category: source.category,\n        wsConnected: source.transport === 'websocket' ? this._api.isWebSocketConnected(id) : null,\n        eventCount: stats?.count || 0,\n        lastIngestMs: stats?.lastIngestMs || 0,\n        lastFetchMs: this._api.getLastFetchTime(id),\n        error,\n        fetchOk: counts.ok,\n        fetchFail: counts.fail,\n        wsReconnects,\n        pollIntervalMs: source.pollIntervalMs,\n        proxyPath: source.proxyPath || null,\n        wsUrl: source.wsUrl || null,\n        licenseNotes: source.licenseNotes || null,\n      };\n    }\n    return result;\n  }\n\n  getStatus() {\n    return this.getSourceStatus();\n  }\n\n  destroy() {\n    if (this._settingsUnsub) this._settingsUnsub();\n    if (this._storeUnsub) this._storeUnsub();\n    this._api.destroy();\n    this._store.clear();\n    this._initialized = false;\n  }\n\n  dispose() {\n    this.destroy();\n  }\n}\n\nexport function getSensorManager() {\n  if (!_instance) _instance = new SensorManager();\n  return _instance;\n}\n","/**\n * InfrastructureOverlay\n *\n * Purpose:\n * - Fetches OSM infrastructure elements (roads, bridges, waterways, areas, railways) from Overpass\n *   and renders them as terrain-flush geometry on the globe surface.\n * - Provides radius-based visibility and terrain snapping similar to BuildingOverlay.\n * - Uses the NOCLIP relay to the co-hosted Mapsource Overpass engine.\n *\n * API intention:\n * - constructor({ parentGroup, triTree, planetRadius, overpassUrl, ... })\n * - load({ center, radiusM })\n * - setCenter(lat, lon, opts)\n * - refresh()\n * - update(dt)\n * - clear(), dispose()\n */\nimport * as THREE from 'three';\nimport { latLonToLocalDir, dirToLatLonLocal, geodesicDistanceWGS84, ellipsoidRadiusForLocalDir } from '../../modules/geometry-utils.js';\nimport { PLANET_RADIUS } from '../../modules/constants.js';\nimport { getLabelSystem } from '../labels/LabelSystem.js';\nimport { terrainSurfaceChangesAffectLatLon } from '../scene/TerrainSurfaceChange.js';\nimport { getNoclipGovernanceClient } from '../shared/NoclipGovernanceClient.js';\nimport { resolveBackendApiUrl } from '../shared/backend.js';\n\nconst OVERPASS_URL = resolveBackendApiUrl('/overpass');\nconst DEFAULT_RADIUS_M = 500;\nconst DEFAULT_REFRESH_DISTANCE_M = 500;\nconst DEFAULT_RESNAP_INTERVAL_MS = 1000;\nconst DEFAULT_RESNAP_BUDGET = 2;\nconst DEFAULT_DRAPE_BUDGET = 800;\n// Per-frame CPU budget for sliced ribbon/area build pass. The whole build\n// (which can touch hundreds of features and easily spike >100 ms when run\n// synchronously after the Overpass fetch resolves) is now processed in\n// time-budgeted slices driven by update(dt). Desktop = 4 ms, mobile/low-\n// power = 2 ms. The build is also tail-budgeted by an idle scheduler so\n// it makes progress while the page is otherwise idle.\nconst DEFAULT_BUILD_SLICE_MS_DESKTOP = 4;\nconst DEFAULT_BUILD_SLICE_MS_MOBILE = 2;\nconst DEFAULT_SURFACE_OFFSET_M = 0.3;\nconst DEFAULT_ROAD_STEP_M = 5; // Densify roads every 5 meters\nconst DEFAULT_RIBBON_THICKNESS_M = 0.2; // Ribbon volume thickness (height above terrain)\nconst DEFAULT_ALIGN_FREEZE_FRAMES = 3;\nconst DEFAULT_ALIGN_TOLERANCE_M = 0.2;\nconst DEFAULT_ALIGN_SAMPLE_STEP_M = 60;\nconst DEFAULT_ALIGN_MAX_SAMPLES = 96;\nconst DEFAULT_PAINT_RESOLUTION = 512;\nconst DEFAULT_PAINT_LINE_WIDTH_PX = 2.0;\nconst DEFAULT_PAINT_OPACITY = 0.9;\nconst DEFAULT_PAINT_REPAINT_ON_LOD = true;\nconst DEFAULT_PAINT_BUDGET = 2;\nconst DEFAULT_PAUSE_WHEN_FAR = true;\nconst DEFAULT_PAUSE_DISTANCE_MULTIPLIER = 2.5;\nconst DEFAULT_MOTION_MIN_SPEED_MPS = 0.35;\nconst DEFAULT_MOTION_SPEED_REF_MPS = 6;\nconst DEFAULT_MOTION_AHEAD_FACTOR = 1.4;\nconst DEFAULT_MOTION_BEHIND_FACTOR = 0.7;\nconst DEFAULT_MOTION_QUERY_BIAS = 0.35;\nconst DEFAULT_MOTION_RETENTION_FACTOR = 1.1;\n// External Overpass responses can intermittently exceed 8s under load.\n// Keep this above the query timeout window to avoid aborting valid responses.\nconst DEFAULT_OVERPASS_TIMEOUT_MS = 30000;\n\nconst nowMs = () => (typeof performance !== 'undefined' && typeof performance.now === 'function'\n    ? performance.now()\n    : Date.now());\n\nconst getDeviceMemoryGb = () => {\n    const memory = typeof navigator !== 'undefined' ? Number(navigator.deviceMemory || 0) : 0;\n    return Number.isFinite(memory) && memory > 0 ? memory : null;\n};\n\nconst getHardwareConcurrency = () => {\n    const cores = typeof navigator !== 'undefined' ? Number(navigator.hardwareConcurrency || 0) : 0;\n    return Number.isFinite(cores) && cores > 0 ? cores : null;\n};\n\nconst scheduleIdle = (fn) => {\n    if (typeof requestIdleCallback === 'function') {\n        return requestIdleCallback(fn, { timeout: 50 });\n    }\n    return setTimeout(() => fn({ timeRemaining: () => 0, didTimeout: true }), 0);\n};\n\nconst cancelIdle = (handle) => {\n    if (!handle) return;\n    if (typeof cancelIdleCallback === 'function') {\n        cancelIdleCallback(handle);\n        return;\n    }\n    clearTimeout(handle);\n};\n\n// Road width by highway type (meters)\nconst ROAD_WIDTHS = {\n    motorway: 14,\n    trunk: 12,\n    primary: 10,\n    secondary: 8,\n    tertiary: 7,\n    residential: 6,\n    unclassified: 5,\n    service: 4,\n    track: 3,\n    path: 2,\n    footway: 2,\n    cycleway: 2.5,\n    bridleway: 2.5,\n    pedestrian: 4,\n    default: 5\n};\n\n// Road colors by highway type\nconst ROAD_COLORS = {\n    motorway: 0x4a6fa5,\n    trunk: 0x5a7fb5,\n    primary: 0x606060,\n    secondary: 0x707070,\n    tertiary: 0x808080,\n    residential: 0x909090,\n    unclassified: 0x888888,\n    service: 0x999999,\n    track: 0x8b7355,\n    path: 0xa89070,\n    footway: 0xc0a080,\n    cycleway: 0x7090a0,\n    default: 0x808080\n};\n\nconst DEFAULT_INFRA_COLORS = {\n    roads: ROAD_COLORS.default,\n    bridges: 0x606060,\n    waterways: 0x4a90d9,\n    areas: 0x4a8b4a,\n    railways: 0x505050,\n    // OpenInfraMap color scheme (matched from openinframap.org)\n    power: 0xc83737,        // Deep red — power lines, substations\n    telecoms: 0xe85d12,     // Orange — telecom towers, fiber\n    petroleum: 0x666666,    // Gray — pipelines, wells\n    water: 0x3388ff,        // Blue — water treatment, dams\n    internet: 0x7b68ee,     // Medium purple — data centers, exchanges\n    solar: 0xffc800,        // Amber — solar farms, panels\n};\n\n// Line widths per layer type (meters) — visible from orbit altitude\nconst INFRA_LINE_WIDTHS = {\n    roads: 6,\n    bridges: 8,\n    waterways: 8,\n    areas: 4,\n    railways: 5,\n    power: 30,       // Thick — transmission lines visible from high orbit\n    telecoms: 20,    // Medium thick\n    petroleum: 25,   // Pipeline thick\n    water: 15,       // Water mains\n    internet: 15,    // Fiber routes\n    solar: 10,       // Solar farm outlines\n};\n\nconst UTILITY_RIBBON_KINDS = ['power', 'telecoms', 'petroleum', 'water', 'internet', 'solar'];\nconst INFRA_RIBBON_KINDS = new Set(['road', 'bridge', 'railway', 'waterway', ...UTILITY_RIBBON_KINDS]);\n\nfunction metersPerDegLat(phiRad) {\n    return (\n        111132.954 -\n        559.822 * Math.cos(2 * phiRad) +\n        1.175 * Math.cos(4 * phiRad) -\n        0.0023 * Math.cos(6 * phiRad)\n    );\n}\n\nfunction metersPerDegLon(phiRad) {\n    return (\n        111412.84 * Math.cos(phiRad) -\n        93.5 * Math.cos(3 * phiRad) +\n        0.118 * Math.cos(5 * phiRad)\n    );\n}\n\nfunction haversine(lat1, lon1, lat2, lon2, radius = PLANET_RADIUS) {\n    const dist = geodesicDistanceWGS84(lat1, lon1, lat2, lon2);\n    if (Number.isFinite(dist)) return dist;\n    const dLat = THREE.MathUtils.degToRad(lat2 - lat1);\n    const dLon = THREE.MathUtils.degToRad(lon2 - lon1);\n    const a =\n        Math.sin(dLat / 2) ** 2 +\n        Math.cos(THREE.MathUtils.degToRad(lat1)) *\n        Math.cos(THREE.MathUtils.degToRad(lat2)) *\n        Math.sin(dLon / 2) ** 2;\n    const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));\n    return radius * c;\n}\n\n/**\n * Build Overpass query for infrastructure\n */\nfunction buildOverpassQuery(bbox, layers) {\n    const [minLat, minLon, maxLat, maxLon] = bbox;\n    const parts = [];\n\n    if (layers.roads) {\n        parts.push(`way[\"highway\"](${minLat},${minLon},${maxLat},${maxLon});`);\n    }\n    if (layers.bridges) {\n        parts.push(`way[\"bridge\"](${minLat},${minLon},${maxLat},${maxLon});`);\n    }\n    if (layers.waterways) {\n        parts.push(`way[\"waterway\"](${minLat},${minLon},${maxLat},${maxLon});`);\n    }\n    if (layers.areas) {\n        parts.push(`way[\"leisure\"=\"park\"](${minLat},${minLon},${maxLat},${maxLon});`);\n        parts.push(`way[\"landuse\"](${minLat},${minLon},${maxLat},${maxLon});`);\n        parts.push(`way[\"natural\"=\"water\"](${minLat},${minLon},${maxLat},${maxLon});`);\n    }\n    if (layers.railways) {\n        parts.push(`way[\"railway\"](${minLat},${minLon},${maxLat},${maxLon});`);\n    }\n    // OpenInfraMap utility infrastructure layers\n    if (layers.power) {\n        parts.push(`way[\"power\"=\"line\"](${minLat},${minLon},${maxLat},${maxLon});`);\n        parts.push(`way[\"power\"=\"minor_line\"](${minLat},${minLon},${maxLat},${maxLon});`);\n        parts.push(`node[\"power\"=\"tower\"](${minLat},${minLon},${maxLat},${maxLon});`);\n        parts.push(`node[\"power\"=\"pole\"](${minLat},${minLon},${maxLat},${maxLon});`);\n    }\n    if (layers.telecoms) {\n        parts.push(`way[\"telecom\"](${minLat},${minLon},${maxLat},${maxLon});`);\n        parts.push(`node[\"man_made\"=\"mast\"][\"tower:type\"=\"communication\"](${minLat},${minLon},${maxLat},${maxLon});`);\n        parts.push(`node[\"man_made\"=\"tower\"][\"tower:type\"=\"communication\"](${minLat},${minLon},${maxLat},${maxLon});`);\n    }\n    if (layers.petroleum) {\n        parts.push(`way[\"pipeline\"](${minLat},${minLon},${maxLat},${maxLon});`);\n        parts.push(`way[\"man_made\"=\"pipeline\"](${minLat},${minLon},${maxLat},${maxLon});`);\n        parts.push(`node[\"man_made\"=\"petroleum_well\"](${minLat},${minLon},${maxLat},${maxLon});`);\n    }\n    if (layers.water) {\n        parts.push(`way[\"man_made\"=\"water_works\"](${minLat},${minLon},${maxLat},${maxLon});`);\n        parts.push(`node[\"man_made\"=\"water_tower\"](${minLat},${minLon},${maxLat},${maxLon});`);\n        parts.push(`way[\"waterway\"=\"dam\"](${minLat},${minLon},${maxLat},${maxLon});`);\n    }\n    if (layers.internet) {\n        parts.push(`way[\"telecom\"=\"data_centre\"](${minLat},${minLon},${maxLat},${maxLon});`);\n        parts.push(`node[\"telecom\"=\"data_centre\"](${minLat},${minLon},${maxLat},${maxLon});`);\n        parts.push(`node[\"telecom\"=\"exchange\"](${minLat},${minLon},${maxLat},${maxLon});`);\n    }\n    if (layers.solar) {\n        parts.push(`way[\"power\"=\"generator\"][\"generator:source\"=\"solar\"](${minLat},${minLon},${maxLat},${maxLon});`);\n        parts.push(`node[\"power\"=\"generator\"][\"generator:source\"=\"solar\"](${minLat},${minLon},${maxLat},${maxLon});`);\n        parts.push(`way[\"power\"=\"plant\"][\"plant:source\"=\"solar\"](${minLat},${minLon},${maxLat},${maxLon});`);\n    }\n\n    if (parts.length === 0) return null;\n\n    return `\n        [out:json][timeout:25];\n        (\n            ${parts.join('\\n            ')}\n        );\n        (._;>;);\n        out body;\n    `.trim();\n}\n\nexport class InfrastructureOverlay {\n    constructor({\n        parentGroup,\n        triTree,\n        camera,\n        motionTracker,\n        surfaceController,\n        planetRadius,\n        overpassUrl,\n        overpassTimeoutMs,\n        radiusM,\n        refreshDistanceM,\n        surfaceOffsetM,\n        resnapIntervalMs,\n        resnapBudget,\n        drapeBudget,\n        tileDrivenResnap,\n        roadWidthScale,\n        roadStepM,\n        bridgeHeightM,\n        ribbonThicknessM,\n        alignFreezeFrames,\n        alignToleranceM,\n        alignSampleStepM,\n        alignMaxSamples,\n        pauseWhenFar,\n        pauseDistanceM,\n        pauseDistanceMultiplier,\n        eventBus,\n        sceneInitializer,\n        perf,\n        perfStart,\n        perfEnd,\n        perfRecord,\n        enabled,\n        terrainMode = 'tritree',\n        motionEnabled,\n        motionMinSpeedMps,\n        motionSpeedRefMps,\n        motionAheadFactor,\n        motionBehindFactor,\n        motionQueryBias,\n        motionRetentionFactor,\n        // Layer toggles\n        roadsEnabled,\n        bridgesEnabled,\n        waterwaysEnabled,\n        areasEnabled,\n        railwaysEnabled,\n        colors,\n        paint,\n        backendUrl\n    } = {}) {\n        this.parentGroup = parentGroup || null;\n        this.triTree = triTree || null;\n        this.camera = camera || null;\n        this.motionTracker = motionTracker || null;\n        // SurfaceController owns the canonical terrain sampler that\n        // already prefers photorealistic-tile raycasts over triTree\n        // elevation. When it's available, ribbons resnap onto the\n        // photoreal surface (so power lines / comms stop floating in\n        // the air over photorealistic tiles when the photoreal surface\n        // sits above the procedural elevation mesh).\n        this.surfaceController = surfaceController || null;\n        this.planetRadius = Number.isFinite(planetRadius) ? planetRadius : PLANET_RADIUS;\n        if (typeof overpassUrl === 'string' && overpassUrl.trim() && overpassUrl.trim() !== OVERPASS_URL) {\n            console.warn('[InfrastructureOverlay] Ignoring custom overpassUrl; using fixed endpoint:', OVERPASS_URL);\n        }\n        this.overpassUrl = OVERPASS_URL;\n        this.overpassTimeoutMs = Number.isFinite(overpassTimeoutMs)\n            ? Math.max(1000, overpassTimeoutMs)\n            : DEFAULT_OVERPASS_TIMEOUT_MS;\n        this.radiusM = Number.isFinite(radiusM) ? radiusM : DEFAULT_RADIUS_M;\n        this.refreshDistanceM = Number.isFinite(refreshDistanceM) ? refreshDistanceM : DEFAULT_REFRESH_DISTANCE_M;\n        this.surfaceOffsetM = Number.isFinite(surfaceOffsetM) ? surfaceOffsetM : DEFAULT_SURFACE_OFFSET_M;\n        this.resnapIntervalMs = Number.isFinite(resnapIntervalMs) ? resnapIntervalMs : DEFAULT_RESNAP_INTERVAL_MS;\n        this.resnapBudget = Number.isFinite(resnapBudget) ? resnapBudget : DEFAULT_RESNAP_BUDGET;\n        this.drapeBudget = Number.isFinite(drapeBudget) ? drapeBudget : DEFAULT_DRAPE_BUDGET;\n        this.tileDrivenResnap = tileDrivenResnap !== false;\n        this.roadWidthScale = Number.isFinite(roadWidthScale) ? roadWidthScale : 1.0;\n        this.roadStepM = Number.isFinite(roadStepM) ? roadStepM : DEFAULT_ROAD_STEP_M;\n        this.bridgeHeightM = Number.isFinite(bridgeHeightM) ? bridgeHeightM : 3.0;\n        this.ribbonThicknessM = Number.isFinite(ribbonThicknessM) ? ribbonThicknessM : DEFAULT_RIBBON_THICKNESS_M;\n        this.alignFreezeFrames = Number.isFinite(alignFreezeFrames)\n            ? Math.max(0, Math.floor(alignFreezeFrames))\n            : DEFAULT_ALIGN_FREEZE_FRAMES;\n        this.alignToleranceM = Number.isFinite(alignToleranceM)\n            ? Math.max(0, alignToleranceM)\n            : DEFAULT_ALIGN_TOLERANCE_M;\n        this.alignSampleStepM = Number.isFinite(alignSampleStepM)\n            ? Math.max(1, alignSampleStepM)\n            : DEFAULT_ALIGN_SAMPLE_STEP_M;\n        this.alignMaxSamples = Number.isFinite(alignMaxSamples)\n            ? Math.max(4, Math.floor(alignMaxSamples))\n            : DEFAULT_ALIGN_MAX_SAMPLES;\n        this.pauseWhenFar = typeof pauseWhenFar === 'boolean' ? pauseWhenFar : DEFAULT_PAUSE_WHEN_FAR;\n        this.pauseDistanceM = Number.isFinite(pauseDistanceM) ? Math.max(0, pauseDistanceM) : null;\n        this.pauseDistanceMultiplier = Number.isFinite(pauseDistanceMultiplier)\n            ? Math.max(0.1, pauseDistanceMultiplier)\n            : DEFAULT_PAUSE_DISTANCE_MULTIPLIER;\n        this.eventBus = eventBus || null;\n        this.sceneInitializer = sceneInitializer || null;\n        const start = typeof perfStart === 'function'\n            ? perfStart\n            : (perf && typeof perf.start === 'function' ? perf.start.bind(perf) : null);\n        const end = typeof perfEnd === 'function'\n            ? perfEnd\n            : (perf && typeof perf.end === 'function' ? perf.end.bind(perf) : null);\n        const record = typeof perfRecord === 'function'\n            ? perfRecord\n            : (perf && typeof perf.record === 'function' ? perf.record.bind(perf) : null);\n        this._perfStart = start || (() => {});\n        this._perfEnd = end || (() => {});\n        this._perfRecord = record || (() => {});\n        this.motionEnabled = motionEnabled !== false;\n        this.motionMinSpeedMps = Number.isFinite(motionMinSpeedMps)\n            ? motionMinSpeedMps\n            : DEFAULT_MOTION_MIN_SPEED_MPS;\n        this.motionSpeedRefMps = Number.isFinite(motionSpeedRefMps)\n            ? motionSpeedRefMps\n            : DEFAULT_MOTION_SPEED_REF_MPS;\n        this.motionAheadFactor = Number.isFinite(motionAheadFactor)\n            ? motionAheadFactor\n            : DEFAULT_MOTION_AHEAD_FACTOR;\n        this.motionBehindFactor = Number.isFinite(motionBehindFactor)\n            ? motionBehindFactor\n            : DEFAULT_MOTION_BEHIND_FACTOR;\n        this.motionQueryBias = Number.isFinite(motionQueryBias)\n            ? motionQueryBias\n            : DEFAULT_MOTION_QUERY_BIAS;\n        this.motionRetentionFactor = Number.isFinite(motionRetentionFactor)\n            ? motionRetentionFactor\n            : DEFAULT_MOTION_RETENTION_FACTOR;\n\n        // Layer enable states\n        const resolveLayer = (value, fallback) => (typeof value === 'boolean' ? value : fallback);\n        this.layers = {\n            roads: resolveLayer(roadsEnabled, true),\n            bridges: resolveLayer(bridgesEnabled, false),\n            waterways: resolveLayer(waterwaysEnabled, false),\n            areas: resolveLayer(areasEnabled, false),\n            railways: resolveLayer(railwaysEnabled, false),\n            power: false,\n            telecoms: false,\n            petroleum: false,\n            water: false,\n            internet: false,\n            solar: false,\n        };\n        const resolveColor = (value, fallback) => {\n            if (typeof value === 'number' && Number.isFinite(value)) return value;\n            if (typeof value === 'string') {\n                const clean = value.trim();\n                if (clean.startsWith('#')) {\n                    const parsed = Number.parseInt(clean.slice(1), 16);\n                    if (Number.isFinite(parsed)) return parsed;\n                }\n            }\n            return fallback;\n        };\n        this.colors = {\n            roads: resolveColor(colors?.roads, DEFAULT_INFRA_COLORS.roads),\n            bridges: resolveColor(colors?.bridges, DEFAULT_INFRA_COLORS.bridges),\n            waterways: resolveColor(colors?.waterways, DEFAULT_INFRA_COLORS.waterways),\n            areas: resolveColor(colors?.areas, DEFAULT_INFRA_COLORS.areas),\n            railways: resolveColor(colors?.railways, DEFAULT_INFRA_COLORS.railways),\n            power: resolveColor(colors?.power, DEFAULT_INFRA_COLORS.power),\n            telecoms: resolveColor(colors?.telecoms, DEFAULT_INFRA_COLORS.telecoms),\n            petroleum: resolveColor(colors?.petroleum, DEFAULT_INFRA_COLORS.petroleum),\n            water: resolveColor(colors?.water, DEFAULT_INFRA_COLORS.water),\n            internet: resolveColor(colors?.internet, DEFAULT_INFRA_COLORS.internet),\n            solar: resolveColor(colors?.solar, DEFAULT_INFRA_COLORS.solar),\n        };\n\n        // Backend infrastructure proxy URL (optional — falls back to direct Overpass)\n        this._backendUrl = typeof backendUrl === 'string' && backendUrl.trim() ? backendUrl.trim() : null;\n\n        this._terrainMode = terrainMode;\n        this._requestedEnabled = enabled !== false;\n        this.enabled = terrainMode === 'tritree' && this._requestedEnabled;\n        this._fetchSeq = 0;\n        this._fetchAbortController = null;\n        this._renderSuppressed = false;\n        const paintConfig = paint && typeof paint === 'object' ? paint : {};\n        this.paintEnabled = paintConfig.enabled === true;\n        this.paintResolution = Number.isFinite(paintConfig.resolution)\n            ? Math.max(64, Math.min(2048, Math.floor(paintConfig.resolution)))\n            : DEFAULT_PAINT_RESOLUTION;\n        this.paintLineWidthPx = Number.isFinite(paintConfig.lineWidthPx)\n            ? Math.max(0.5, Math.min(20, paintConfig.lineWidthPx))\n            : DEFAULT_PAINT_LINE_WIDTH_PX;\n        this.paintOpacity = Number.isFinite(paintConfig.opacity)\n            ? Math.max(0, Math.min(1, paintConfig.opacity))\n            : DEFAULT_PAINT_OPACITY;\n        this.paintRepaintOnLod = typeof paintConfig.repaintOnLod === 'boolean'\n            ? paintConfig.repaintOnLod\n            : DEFAULT_PAINT_REPAINT_ON_LOD;\n        this.paintBudget = Number.isFinite(paintConfig.budget)\n            ? Math.max(1, Math.min(20, Math.floor(paintConfig.budget)))\n            : DEFAULT_PAINT_BUDGET;\n\n        this.group = new THREE.Group();\n        this.group.name = 'InfrastructureOverlay';\n        this.group.visible = this.enabled && !this.paintEnabled && !this._renderSuppressed;\n        this.parentGroup?.add(this.group);\n\n        // Register group to be excluded from atmosphere depth passes\n        if (this.sceneInitializer && typeof this.sceneInitializer.addDepthPassExclude === 'function') {\n            this.sceneInitializer.addDepthPassExclude(this.group);\n        }\n\n        // Materials\n        this._roadMaterial = new THREE.MeshBasicMaterial({\n            vertexColors: true,\n            side: THREE.DoubleSide,\n            depthWrite: true,\n            polygonOffset: true,\n            polygonOffsetFactor: -1,\n            polygonOffsetUnits: -1\n        });\n\n        this._bridgeMaterial = new THREE.MeshStandardMaterial({\n            color: this.colors.bridges,\n            roughness: 0.8,\n            metalness: 0.1,\n            side: THREE.DoubleSide\n        });\n\n        this._waterwayMaterial = new THREE.MeshBasicMaterial({\n            color: this.colors.waterways,\n            transparent: true,\n            opacity: 0.7,\n            side: THREE.DoubleSide,\n            depthWrite: true,\n            polygonOffset: true,\n            polygonOffsetFactor: -1,\n            polygonOffsetUnits: -1\n        });\n\n        this._areaMaterial = new THREE.MeshBasicMaterial({\n            color: this.colors.areas,\n            transparent: true,\n            opacity: 0.5,\n            side: THREE.DoubleSide,\n            depthWrite: true,\n            polygonOffset: true,\n            polygonOffsetFactor: -2,\n            polygonOffsetUnits: -2\n        });\n\n        this._railwayMaterial = new THREE.MeshBasicMaterial({\n            color: this.colors.railways,\n            side: THREE.DoubleSide,\n            depthWrite: true,\n            polygonOffset: true,\n            polygonOffsetFactor: -1,\n            polygonOffsetUnits: -1\n        });\n\n        // Utility infrastructure materials (thick, emissive for orbit visibility)\n        this._utilityMaterials = {};\n        for (const layerId of ['power', 'telecoms', 'petroleum', 'water', 'internet', 'solar']) {\n            this._utilityMaterials[layerId] = new THREE.MeshBasicMaterial({\n                color: this.colors[layerId],\n                side: THREE.DoubleSide,\n                depthWrite: true,\n                transparent: true,\n                opacity: 0.85,\n                polygonOffset: true,\n                polygonOffsetFactor: -2,\n                polygonOffsetUnits: -2\n            });\n        }\n\n        // State\n        this._center = null; // { lat, lon }\n        this._inflight = false;\n        this._entries = []; // Array of entry objects with mesh, group, etc.\n        this._entryMap = new Map();\n        this._alignQueue = [];\n        this._alignQueueIndex = 0;\n        this._alignQueued = new Set();\n        this._drapeIndex = 0;\n        this._refreshQueued = false;\n        this._motionState = null;\n        this._motionListener = null;\n        this._tileListener = null;\n        this._tileToEntries = new Map();\n        this._tileResnapQueue = new Set();\n        this._drapeIdleHandle = null;\n        this._drapeScheduled = false;\n        this._drapeSliceMs = 4;\n        this._drapeMaxVerticesPerSlice = 0;\n        this._drapeMaxVerticesPerEntry = 0;\n\n        // Sliced build pipeline state. Replaces the old synchronous\n        // _processOverpassData loop that blocked the main thread for\n        // hundreds of ms when the Overpass response landed. _buildState\n        // is null when no build is in progress; otherwise it holds the\n        // queued ways + accumulated nextEntries + center + window for\n        // the slicer driven by update(dt).\n        this._buildState = null;\n        this._buildIdleHandle = null;\n        this._buildScheduled = false;\n        const memoryGb = getDeviceMemoryGb();\n        const cores = getHardwareConcurrency();\n        const lowPower = (Number.isFinite(memoryGb) && memoryGb <= 4)\n            || (Number.isFinite(cores) && cores <= 4);\n        this._buildSliceMs = lowPower\n            ? DEFAULT_BUILD_SLICE_MS_MOBILE\n            : DEFAULT_BUILD_SLICE_MS_DESKTOP;\n        this._retryTimer = null;\n        this._retryFailures = 0;\n        this._retryBaseDelayMs = 3000;\n        this._retryMaxDelayMs = 30000;\n        this._paintTiles = new Map();\n        this._paintQueue = new Set();\n        this._lastWireframeActive = null;\n        this._processingPaused = false;\n        this._processingPauseReason = null;\n        this._lastFocusLatLon = null;\n\n        // Temp objects for calculations\n        this._tmpDir = new THREE.Vector3();\n        this._tmpQuat = new THREE.Quaternion();\n        this._tmpVec = new THREE.Vector3();\n        this._tmpVec2 = new THREE.Vector3();\n        this._tmpVec3 = new THREE.Vector3();\n        this._tmpMotionDir = new THREE.Vector3();\n        this._tmpSurfaceVec = new THREE.Vector3();\n        this._tmpMatrix = new THREE.Matrix4();\n        this._tmpTerrainA = new THREE.Vector3();\n        this._tmpTerrainB = new THREE.Vector3();\n        this._tmpTerrainC = new THREE.Vector3();\n        this._tmpNormal = new THREE.Vector3();\n        this._tmpWorldQuat = new THREE.Quaternion();\n        this._tmpPaintUv = { u: 0, v: 0 };\n        this._tmpPaintPoint = { x: 0, y: 0 };\n        this._tmpLabelVec = new THREE.Vector3();\n\n        this._labelSystem = null;\n        this._labelsEnabled = true;\n        this._geometryVisible = true;\n\n        this._bindMotionListener();\n        this._bindTileListeners();\n        this._updateDrapeScheduler();\n    }\n\n    /**\n     * Set layer enabled state\n     */\n    setLayerEnabled(layer, enabled) {\n        if (!(layer in this.layers)) return;\n        const wasEnabled = this.layers[layer];\n        this.layers[layer] = !!enabled;\n\n        // Update visibility of existing entries\n        for (const entry of this._entries) {\n            if (entry.layerType === layer) {\n                if (entry.group) entry.group.visible = this.layers[layer];\n            }\n        }\n\n        // Refresh if enabling a previously disabled layer\n        if (enabled && !wasEnabled && this._center) {\n            this._refreshQueued = true;\n        }\n\n        if (this.paintEnabled) {\n            this._queueAllPaintTiles();\n        }\n    }\n\n    /**\n     * Get layer enabled state\n     */\n    isLayerEnabled(layer) {\n        return this.layers[layer] ?? false;\n    }\n\n    setLabelsEnabled(enabled) {\n        this._labelsEnabled = !!enabled;\n        if (!enabled) {\n            for (const entry of this._entries) {\n                if (entry.labelHandle) {\n                    if (entry.labelHandle.group) this.group.remove(entry.labelHandle.group);\n                    entry.labelHandle.dispose();\n                    entry.labelHandle = null;\n                }\n            }\n        }\n    }\n\n    /**\n     * Hide/show infrastructure geometry without disabling the overlay.\n     * Labels and data pipeline remain active.\n     */\n    setGeometryVisible(visible) {\n        this._geometryVisible = !!visible;\n        for (const entry of this._entries) {\n            if (entry.group) entry.group.visible = visible && this.layers[entry.layerType] !== false;\n        }\n    }\n\n    getEntriesSnapshot() {\n        if (!this._entries?.length) return [];\n        return this._entries\n            .filter((entry) => {\n                if (!entry?.center || this.layers[entry.layerType] === false) return false;\n                const tags = entry.tags || {};\n                return !!(tags.name || tags.ref || tags.operator || tags.network || tags.power || tags.man_made || tags.pipeline || tags.telecom);\n            })\n            .map((entry) => {\n                const color = this._resolveEntryLabelColor(entry);\n                const bounds = entry.bounds || {};\n                const sizeM = Math.max(\n                    8,\n                    Math.min(\n                        5000,\n                        Math.max(\n                            Number(bounds.width) || 0,\n                            Number(bounds.depth) || 0,\n                            INFRA_LINE_WIDTHS[entry.kind] || INFRA_LINE_WIDTHS[entry.layerType] || 20\n                        )\n                    )\n                );\n                return {\n                    id: this._resolveEntryId(entry),\n                    osmId: entry.osmId || null,\n                    lat: entry.center.lat,\n                    lon: entry.center.lon,\n                    surfaceRadius: Number.isFinite(entry.surfaceRadius) ? entry.surfaceRadius : this.planetRadius,\n                    name: this._resolveEntryName(entry),\n                    kind: entry.kind || '',\n                    layerType: entry.layerType || '',\n                    kindLabel: this._formatEntryKindLabel(entry),\n                    category: entry.layerType || entry.kind || 'infrastructure',\n                    color,\n                    colorHex: `#${(color >>> 0).toString(16).padStart(6, '0')}`,\n                    sizeM,\n                    tags: entry.tags || null,\n                };\n            });\n    }\n\n    _ensureLabelSystem() {\n        if (!this._labelSystem) {\n            try {\n                this._labelSystem = getLabelSystem({ planetRadius: this.planetRadius });\n            } catch { /* Label system not available */ }\n        }\n        return this._labelSystem;\n    }\n\n    _resolveEntryId(entry) {\n        if (!entry) return null;\n        if (entry.osmId !== undefined && entry.osmId !== null) {\n            return `${entry.layerType || entry.kind || 'infra'}:${entry.osmId}`;\n        }\n        return entry._signature || entry._nodeHash || null;\n    }\n\n    _resolveEntryName(entry) {\n        const tags = entry?.tags || {};\n        return String(\n            tags.name ||\n            tags.ref ||\n            tags.operator ||\n            tags.network ||\n            this._formatEntryKindLabel(entry) ||\n            'Infrastructure'\n        ).trim();\n    }\n\n    _formatEntryKindLabel(entry) {\n        const tags = entry?.tags || {};\n        const value = tags.highway ||\n            tags.railway ||\n            tags.waterway ||\n            tags.power ||\n            tags.man_made ||\n            tags.pipeline ||\n            tags.telecom ||\n            tags['generator:source'] ||\n            entry?.kind ||\n            entry?.layerType ||\n            'infrastructure';\n        return String(value).replace(/_/g, ' ');\n    }\n\n    _resolveEntryLabelColor(entry) {\n        if (!entry) return DEFAULT_INFRA_COLORS.roads;\n        if (entry.kind === 'bridge') return this.colors.bridges;\n        if (entry.kind === 'waterway') return this.colors.waterways;\n        if (entry.kind === 'railway') return this.colors.railways;\n        if (entry.kind === 'area') return this.colors.areas;\n        if (entry.kind && this.colors[entry.kind]) return this.colors[entry.kind];\n        if (entry.layerType && this.colors[entry.layerType]) return this.colors[entry.layerType];\n        return this.colors.roads || DEFAULT_INFRA_COLORS.roads;\n    }\n\n    /**\n     * Late-bind the SurfaceController. Used when the overlay is\n     * constructed before the surface controller exists (or before the\n     * photorealistic tile group is wired into it). After this call,\n     * subsequent resnaps will sample the photoreal-aware terrain.\n     */\n    setSurfaceController(surfaceController) {\n        const previous = this.surfaceController || null;\n        this.surfaceController = surfaceController || null;\n        if (previous === this.surfaceController || !this._entries?.length) return;\n\n        let needsDrape = false;\n        for (const entry of this._entries) {\n            if (!entry) continue;\n            entry.alignStamp = null;\n            entry.alignStableFrames = 0;\n            if (entry.alignState === 'frozen') {\n                entry.alignState = 'coarse';\n            }\n            if (entry.kind !== 'bridge' && entry.vertexLatLons?.length) {\n                entry._drapeDirty = true;\n                entry._drapeIndex = 0;\n                needsDrape = true;\n            }\n        }\n        this._queueAllAlignEntries('surface-controller');\n        if (needsDrape) {\n            this._scheduleDrapeWork();\n        }\n    }\n\n    /**\n     * Set the center location and optionally trigger a refresh\n     */\n    setCenter(lat, lon, opts = {}) {\n        if (!this.enabled) return;\n        const newCenter = { lat, lon };\n        const radiusM = opts.radiusM ?? this.radiusM;\n        const refreshDistanceM = Number.isFinite(opts.refreshDistanceM)\n            ? Math.max(0, opts.refreshDistanceM)\n            : this.refreshDistanceM;\n        const forceRefresh = opts.force === true;\n        if (Number.isFinite(opts.refreshDistanceM)) {\n            this.refreshDistanceM = refreshDistanceM;\n        }\n\n        if (!forceRefresh && this._center) {\n            const dist = haversine(this._center.lat, this._center.lon, lat, lon, this.planetRadius);\n            if (dist < refreshDistanceM && Math.abs(radiusM - this.radiusM) < 50) {\n                return; // Haven't moved enough\n            }\n        }\n\n        this._center = newCenter;\n        this.radiusM = radiusM;\n        this._refreshQueued = true;\n        if (opts.immediate === true && this.enabled && !this._inflight) {\n            this.refresh();\n        }\n    }\n\n    /**\n     * Force refresh of infrastructure data\n     */\n    async refresh() {\n        if (!this.enabled || !this._center || this._inflight || this._renderSuppressed) return;\n        this._refreshQueued = false;\n        const seq = ++this._fetchSeq;\n        const controller = new AbortController();\n        this._fetchAbortController = controller;\n        this._inflight = true;\n\n        try {\n            await this._fetchAndBuild(controller.signal, seq);\n        } catch (err) {\n            console.warn('[InfrastructureOverlay] refresh error:', err);\n        } finally {\n            if (seq === this._fetchSeq) {\n                this._inflight = false;\n                this._fetchAbortController = null;\n            }\n        }\n    }\n\n    /**\n     * Update loop - handle resnapping and queued refreshes\n     */\n    update(dt) {\n        if (!this.enabled) return;\n        this._perfStart('cpu.infrastructure.update');\n        try {\n            this._updateProcessingPause();\n\n            if (this._renderSuppressed) {\n                this._processHiddenTerrainResnap();\n                return;\n            }\n\n            if (this.enabled && !this._processingPaused && this._refreshQueued && !this._inflight) {\n                this.refresh();\n            }\n\n            // Drive the sliced build pass (replaces the old synchronous\n            // _processOverpassData loop). Budgeted to a few ms per frame\n            // so we never block the main render loop, regardless of how\n            // many features the Overpass response carries.\n            if (this._buildState && !this._processingPaused) {\n                this._processBuildSlice(this._buildSliceMs);\n            }\n\n            if (this.paintEnabled) {\n                const wireframeActive = this._isWireframeActive();\n                if (this._lastWireframeActive === null) {\n                    this._lastWireframeActive = wireframeActive;\n                } else if (this._lastWireframeActive !== wireframeActive) {\n                    this._lastWireframeActive = wireframeActive;\n                    if (!wireframeActive) {\n                        this._clearPaintTiles();\n                    } else {\n                        this._queueAllPaintTiles();\n                    }\n                }\n                if (!this._processingPaused) {\n                    this._processPaintQueue();\n                }\n            }\n\n            if (this._processingPaused) {\n                return;\n            }\n\n            this._processAlignQueue();\n\n        } finally {\n            this._perfEnd('cpu.infrastructure.update');\n        }\n    }\n\n    /**\n     * Clear all infrastructure meshes\n     */\n    clear() {\n        this._fetchSeq += 1;\n        this._fetchAbortController?.abort();\n        this._fetchAbortController = null;\n        this._inflight = false;\n        this._refreshQueued = false;\n        if (this._retryTimer != null) clearTimeout(this._retryTimer);\n        this._retryTimer = null;\n        this._cancelDrapeWork();\n        this._cancelBuildSlicing({ disposePending: true });\n        for (const entry of this._entries) {\n            this._disposeEntry(entry);\n        }\n        this._entries = [];\n        this._entryMap.clear();\n        this._tileToEntries.clear();\n        this._tileResnapQueue.clear();\n        this._alignQueue.length = 0;\n        this._alignQueueIndex = 0;\n        this._alignQueued.clear();\n        this._clearPaintTiles();\n    }\n\n    /**\n     * Dispose of the overlay\n     */\n    dispose() {\n        this.clear();\n        this._unbindMotionListener();\n        this._unbindTileListeners();\n        if (this._retryTimer) {\n            clearTimeout(this._retryTimer);\n            this._retryTimer = null;\n        }\n        this._roadMaterial?.dispose();\n        this._bridgeMaterial?.dispose();\n        this._waterwayMaterial?.dispose();\n        this._areaMaterial?.dispose();\n        this._railwayMaterial?.dispose();\n        this.parentGroup?.remove(this.group);\n    }\n\n    _scheduleRetry() {\n        if (this._retryTimer || !this.enabled || this._renderSuppressed) return;\n        const failures = Number.isFinite(this._retryFailures) ? this._retryFailures : 0;\n        const delay = Math.min(this._retryBaseDelayMs * (2 ** failures), this._retryMaxDelayMs);\n        this._retryTimer = setTimeout(() => {\n            this._retryTimer = null;\n            if (!this.enabled || !this._center || this._renderSuppressed) return;\n            this._refreshQueued = true;\n            this.refresh();\n        }, delay);\n    }\n\n    setRenderSuppressed(suppressed) {\n        const next = suppressed === true;\n        if (this._renderSuppressed === next) return;\n        this._renderSuppressed = next;\n        this.group.visible = this.enabled && !this.paintEnabled && !this._renderSuppressed;\n        if (!this.group.visible) {\n            this._cancelDrapeWork();\n            this._cancelBuildSlicing({ disposePending: true });\n            this._alignQueue.length = 0;\n            this._alignQueueIndex = 0;\n            this._alignQueued.clear();\n            this._tileResnapQueue.clear();\n        }\n    }\n\n    forceTerrainResnap() {\n        if (!this._entries?.length) return 0;\n        let queued = 0;\n        for (const entry of this._entries) {\n            if (!entry) continue;\n            entry.alignStamp = null;\n            entry.alignStableFrames = 0;\n            if (entry.alignState === 'frozen') entry.alignState = 'coarse';\n            if (entry.kind !== 'bridge' && entry.vertexLatLons?.length) {\n                entry._drapeDirty = true;\n                entry._drapeIndex = 0;\n            }\n            this._queueAlignEntry(entry, 'photoreal-quality-ready');\n            queued += 1;\n        }\n        return queued;\n    }\n\n    /**\n     * Wake only infrastructure whose geographic footprint intersects a\n     * photoreal tile ownership change. Stable entries otherwise remain asleep.\n     */\n    refreshTerrainAnchors(changes) {\n        if (!Array.isArray(changes) || changes.length === 0 || !this._entries?.length) {\n            return 0;\n        }\n\n        let queued = 0;\n        for (const entry of this._entries) {\n            if (!this._terrainChangesAffectEntry(changes, entry)) continue;\n            entry.alignStamp = null;\n            entry.alignStableFrames = 0;\n            if (entry.alignState === 'frozen') entry.alignState = 'coarse';\n            if (entry.kind !== 'bridge' && entry.vertexLatLons?.length) {\n                entry._drapeDirty = true;\n                entry._drapeIndex = 0;\n            }\n            this._queueAlignEntry(entry, 'photoreal-tile-change');\n            queued += 1;\n        }\n        return queued;\n    }\n\n    _terrainChangesAffectEntry(changes, entry) {\n        if (Number.isFinite(entry?.center?.lat)\n            && Number.isFinite(entry?.center?.lon)\n            && terrainSurfaceChangesAffectLatLon(\n                changes,\n                entry.center.lat,\n                entry.center.lon\n            )) {\n            return true;\n        }\n\n        const points = entry?.vertexLatLons;\n        if (!Array.isArray(points) || points.length === 0) return false;\n        const stride = Math.max(1, Math.floor(points.length / 32));\n        for (let i = 0; i < points.length; i += stride) {\n            const point = points[i];\n            if (terrainSurfaceChangesAffectLatLon(changes, point?.lat, point?.lon)) {\n                return true;\n            }\n        }\n        return false;\n    }\n\n    hasPendingTerrainResnap() {\n        return this._alignQueued.size > 0 ||\n            this._hasPendingDrapeWork() ||\n            this._drapeScheduled ||\n            !!this._drapeIdleHandle;\n    }\n\n    _processHiddenTerrainResnap() {\n        if (this._processingPaused) return;\n        this._processAlignQueue();\n        if (this._hasPendingDrapeWork()) {\n            this._scheduleDrapeWork({ allowHidden: true });\n        }\n    }\n\n    _bindTileListeners() {\n        if (!this.triTree || typeof this.triTree.addTileListener !== 'function') return;\n        if (this._tileListener) return;\n        this._tileListener = (payload) => this._handleTileEvent(payload);\n        this.triTree.addTileListener(this._tileListener);\n    }\n\n    _unbindTileListeners() {\n        if (!this.triTree || typeof this.triTree.removeTileListener !== 'function') return;\n        if (!this._tileListener) return;\n        this.triTree.removeTileListener(this._tileListener);\n        this._tileListener = null;\n    }\n\n    _bindMotionListener() {\n        if (!this.eventBus || typeof this.eventBus.on !== 'function') return;\n        if (this._motionListener) return;\n        this._motionListener = (state) => {\n            this._motionState = state || null;\n        };\n        this.eventBus.on('motion:update', this._motionListener);\n    }\n\n    _unbindMotionListener() {\n        if (!this.eventBus || typeof this.eventBus.off !== 'function') return;\n        if (!this._motionListener) return;\n        this.eventBus.off('motion:update', this._motionListener);\n        this._motionListener = null;\n    }\n\n    _updateDrapeScheduler() {\n        const memoryGb = getDeviceMemoryGb();\n        const cores = getHardwareConcurrency();\n        const lowPower = (Number.isFinite(memoryGb) && memoryGb <= 4) || (Number.isFinite(cores) && cores <= 4);\n        const baseBudget = Number.isFinite(this.drapeBudget)\n            ? Math.max(0, Math.floor(this.drapeBudget))\n            : DEFAULT_DRAPE_BUDGET;\n        if (baseBudget <= 0) {\n            this._drapeSliceMs = 0;\n            this._drapeMaxVerticesPerSlice = 0;\n            this._drapeMaxVerticesPerEntry = 0;\n            return;\n        }\n\n        const maxSlice = Math.min(baseBudget, lowPower ? 150 : 400);\n        this._drapeSliceMs = lowPower ? 2.5 : 6;\n        this._drapeMaxVerticesPerSlice = Math.max(10, maxSlice);\n        this._drapeMaxVerticesPerEntry = Math.max(\n            8,\n            Math.min(120, Math.floor(this._drapeMaxVerticesPerSlice / 2))\n        );\n    }\n\n    _hasPendingDrapeWork() {\n        if (!this._entries?.length) return false;\n        for (const entry of this._entries) {\n            if (entry?._drapeDirty && entry.vertexLatLons?.length) return true;\n        }\n        return false;\n    }\n\n    _scheduleDrapeWork({ allowHidden = false } = {}) {\n        if (this._drapeScheduled) return;\n        if (this._processingPaused) return;\n        if (!allowHidden && !this.group?.visible) return;\n        if (!this._entries?.length) return;\n        if (this._drapeMaxVerticesPerSlice <= 0 || this.drapeBudget <= 0) return;\n        if (!this._hasPendingDrapeWork()) return;\n\n        this._drapeScheduled = true;\n        this._drapeIdleHandle = scheduleIdle((deadline) => {\n            this._drapeScheduled = false;\n            this._drapeIdleHandle = null;\n            this._drapeBatch(deadline);\n            if (this._hasPendingDrapeWork()) {\n                this._scheduleDrapeWork({ allowHidden });\n            }\n        });\n    }\n\n    _cancelDrapeWork() {\n        if (!this._drapeIdleHandle && !this._drapeScheduled) return;\n        cancelIdle(this._drapeIdleHandle);\n        this._drapeIdleHandle = null;\n        this._drapeScheduled = false;\n    }\n\n    async _fetchOverpass(url, query, requestSignal) {\n        const timeoutMs = Number.isFinite(this.overpassTimeoutMs)\n            ? Math.max(1000, this.overpassTimeoutMs)\n            : DEFAULT_OVERPASS_TIMEOUT_MS;\n        const controller = typeof AbortController === 'function' ? new AbortController() : null;\n        const relayAbort = () => controller?.abort();\n        if (requestSignal?.aborted) relayAbort();\n        else requestSignal?.addEventListener('abort', relayAbort, { once: true });\n        let timeoutHandle = null;\n        if (controller) {\n            timeoutHandle = setTimeout(() => {\n                controller.abort();\n            }, timeoutMs);\n        }\n        try {\n            const response = await fetch(url, {\n                method: 'POST',\n                body: query,\n                headers: {\n                    'Content-Type': 'text/plain',\n                    Accept: 'application/json'\n                },\n                signal: controller?.signal\n            });\n            const text = await response.text();\n            if (!response.ok) {\n                return {\n                    ok: false,\n                    url,\n                    status: response.status,\n                    phase: 'external',\n                    message: `Overpass ${response.status}: ${text.slice(0, 200)}`\n                };\n            }\n            try {\n                return {\n                    ok: true,\n                    url,\n                    status: response.status,\n                    phase: 'external',\n                    data: JSON.parse(text)\n                };\n            } catch (err) {\n                return {\n                    ok: false,\n                    url,\n                    status: response.status,\n                    phase: 'external',\n                    message: `Overpass non-JSON response: ${text.slice(0, 200)}`\n                };\n            }\n        } catch (err) {\n            const timedOut = err?.name === 'AbortError';\n            return {\n                ok: false,\n                url,\n                status: timedOut ? 408 : null,\n                phase: 'external',\n                message: timedOut\n                    ? `Overpass timeout after ${timeoutMs}ms`\n                    : `Overpass request failed: ${err?.message || 'network error'}`\n            };\n        } finally {\n            requestSignal?.removeEventListener('abort', relayAbort);\n            if (timeoutHandle) {\n                clearTimeout(timeoutHandle);\n            }\n        }\n    }\n\n    _buildOverpassFailureError(result) {\n        const terminal = result || null;\n        const message = terminal?.message || 'Overpass request failed';\n        const error = new Error(message);\n        error.details = {\n            url: terminal?.url || null,\n            status: terminal?.status ?? null,\n            phase: terminal?.phase || 'external',\n            message,\n            failures: terminal\n                ? [{\n                    url: terminal.url || null,\n                    status: terminal.status ?? null,\n                    phase: terminal.phase || 'external',\n                    message: terminal.message || 'Overpass request failed'\n                }]\n                : []\n        };\n        return error;\n    }\n\n    // ============ Private Methods ============\n\n    /**\n     * Fetch data from Overpass and build geometries\n     */\n    async _fetchAndBuild(requestSignal, seq = this._fetchSeq) {\n        const obsolete = () => !this.enabled || this._renderSuppressed\n            || requestSignal?.aborted || seq !== this._fetchSeq;\n        if (!this._center || obsolete()) return;\n\n        const { lat, lon } = this._center;\n        const window = this._resolveMotionWindow(lat, lon);\n        const queryLat = window.queryLat;\n        const queryLon = window.queryLon;\n        const queryRadius = window.queryRadius;\n        const phiRad = THREE.MathUtils.degToRad(queryLat);\n        const mPerDegLat = metersPerDegLat(phiRad);\n        const mPerDegLon = metersPerDegLon(phiRad);\n\n        const dLat = queryRadius / mPerDegLat;\n        const dLon = queryRadius / mPerDegLon;\n        const bbox = [queryLat - dLat, queryLon - dLon, queryLat + dLat, queryLon + dLon];\n\n        const query = buildOverpassQuery(bbox, this.layers);\n        if (!query) return;\n\n        // Enabled layer IDs for backend proxy\n        const enabledLayers = Object.entries(this.layers)\n            .filter(([, v]) => v)\n            .map(([k]) => k);\n\n        try {\n            // Try backend infrastructure proxy first (cached, faster)\n            let result = null;\n            if (this._backendUrl) {\n                try {\n                    const params = new URLSearchParams({\n                        minLat: bbox[0].toFixed(6),\n                        minLon: bbox[1].toFixed(6),\n                        maxLat: bbox[2].toFixed(6),\n                        maxLon: bbox[3].toFixed(6),\n                        layers: enabledLayers.join(','),\n                    });\n                    const resp = await getNoclipGovernanceClient().request(`${this._backendUrl}/infrastructure/bbox?${params}`, {\n                        governanceLane: 'scene',\n                        signal: requestSignal\n                            ? AbortSignal.any([requestSignal, AbortSignal.timeout(20000)])\n                            : AbortSignal.timeout(20000),\n                    });\n                    if (resp.ok) {\n                        const json = await resp.json();\n                        if (json.elements?.length > 0) {\n                            result = { ok: true, data: { elements: json.elements } };\n                            console.info(`[InfrastructureOverlay] Backend proxy: ${json.elementCount} elements (${json.source})`);\n                        }\n                    }\n                } catch {\n                    // Backend unavailable — fall through to direct Overpass\n                }\n            }\n\n            // Fallback: direct Overpass\n            if (!result) {\n                if (obsolete()) return;\n                result = await this._fetchOverpass(this.overpassUrl, query, requestSignal);\n            }\n\n            if (obsolete()) return;\n            if (!result.ok) {\n                console.warn(\n                    '[InfrastructureOverlay] Overpass fetch failed:',\n                    result.message,\n                    'url:',\n                    result.url,\n                    'phase:',\n                    result.phase\n                );\n                throw this._buildOverpassFailureError(result);\n            }\n\n            this._perfStart('cpu.infrastructure.process');\n            try {\n                if (obsolete()) return;\n                this._processOverpassData(result.data, lat, lon, window);\n            } finally {\n                this._perfEnd('cpu.infrastructure.process');\n            }\n            this._retryFailures = 0;\n        } catch (err) {\n            if (obsolete()) return;\n            console.warn('[InfrastructureOverlay] Overpass fetch failed:', err);\n            const details = err?.details || {};\n            this.eventBus?.emit?.('infrastructure:error', {\n                url: details.url || null,\n                status: Object.prototype.hasOwnProperty.call(details, 'status') ? details.status : null,\n                phase: details.phase || 'external',\n                message: details.message || (err?.message || 'Overpass request failed'),\n                failures: Array.isArray(details.failures) ? details.failures : [],\n                error: err\n            });\n            this._retryFailures = (this._retryFailures || 0) + 1;\n            this._scheduleRetry();\n        }\n    }\n\n    _getMotionState() {\n        if (this._motionState) return this._motionState;\n        if (this.motionTracker && typeof this.motionTracker.getState === 'function') {\n            return this.motionTracker.getState();\n        }\n        return null;\n    }\n\n    _resolveMotionWindow(centerLat, centerLon) {\n        const baseRadius = Number.isFinite(this.radiusM) ? this.radiusM : 0;\n        const centerDir = latLonToLocalDir(centerLat, centerLon).normalize();\n        const window = {\n            centerLat,\n            centerLon,\n            centerDir,\n            queryLat: centerLat,\n            queryLon: centerLon,\n            queryRadius: baseRadius,\n            aheadRadius: baseRadius,\n            behindRadius: baseRadius,\n            motionDir: null,\n            motionAlpha: 0\n        };\n\n        if (!this.motionEnabled || baseRadius <= 0) {\n            return window;\n        }\n\n        const motion = this._getMotionState();\n        if (!motion?.tangentDir) {\n            return window;\n        }\n\n        const speed = Number.isFinite(motion.speedMps) ? motion.speedMps : 0;\n        const minSpeed = Number.isFinite(this.motionMinSpeedMps) ? this.motionMinSpeedMps : 0;\n        if (speed <= minSpeed) {\n            return window;\n        }\n\n        const speedRef = Number.isFinite(this.motionSpeedRefMps)\n            ? Math.max(this.motionSpeedRefMps, minSpeed + 0.01)\n            : DEFAULT_MOTION_SPEED_REF_MPS;\n        const motionAlpha = THREE.MathUtils.clamp((speed - minSpeed) / speedRef, 0, 1);\n        window.motionAlpha = motionAlpha;\n        window.aheadRadius = baseRadius * THREE.MathUtils.lerp(1, this.motionAheadFactor, motionAlpha);\n        window.behindRadius = baseRadius * THREE.MathUtils.lerp(1, this.motionBehindFactor, motionAlpha);\n\n        const rawMotionDir = this._tmpMotionDir.copy(motion.tangentDir).normalize();\n        const radialComponent = rawMotionDir.dot(centerDir);\n        rawMotionDir.addScaledVector(centerDir, -radialComponent);\n        if (rawMotionDir.lengthSq() < 1e-6) {\n            return window;\n        }\n        rawMotionDir.normalize();\n        window.motionDir = rawMotionDir.clone();\n\n        const bias = Number.isFinite(this.motionQueryBias) ? this.motionQueryBias : DEFAULT_MOTION_QUERY_BIAS;\n        const biasDistance = baseRadius * THREE.MathUtils.clamp(bias, 0, 1) * motionAlpha;\n        if (biasDistance > 0) {\n            const shifted = this._tmpVec.copy(centerDir).multiplyScalar(this.planetRadius)\n                .add(this._tmpSurfaceVec.copy(rawMotionDir).multiplyScalar(biasDistance))\n                .normalize();\n            const shiftedLatLon = dirToLatLonLocal(shifted);\n            if (shiftedLatLon && Number.isFinite(shiftedLatLon.lat) && Number.isFinite(shiftedLatLon.lon)) {\n                window.queryLat = shiftedLatLon.lat;\n                window.queryLon = shiftedLatLon.lon;\n            }\n        }\n\n        window.queryRadius = Math.max(window.aheadRadius, window.behindRadius, baseRadius + biasDistance);\n        return window;\n    }\n\n    _computeDirectionalDot(centerDir, entryDir, motionDir) {\n        if (!motionDir || !centerDir || !entryDir) return 0;\n        const radial = entryDir.dot(centerDir);\n        this._tmpSurfaceVec.copy(entryDir).addScaledVector(centerDir, -radial);\n        if (this._tmpSurfaceVec.lengthSq() < 1e-8) return 0;\n        this._tmpSurfaceVec.normalize();\n        return THREE.MathUtils.clamp(this._tmpSurfaceVec.dot(motionDir), -1, 1);\n    }\n\n    _computeEntryMetrics(entry, centerLat, centerLon, window) {\n        const center = entry?.featureCenter;\n        if (!center) return { distance: Infinity, dirRadius: window?.behindRadius || this.radiusM };\n        const distance = haversine(center.lat, center.lon, centerLat, centerLon);\n        let dirRadius = this.radiusM;\n        if (window?.motionDir) {\n            const entryDir = entry.dir || latLonToLocalDir(center.lat, center.lon).normalize();\n            const dot = this._computeDirectionalDot(window.centerDir, entryDir, window.motionDir);\n            const bias = (dot + 1) * 0.5;\n            dirRadius = THREE.MathUtils.lerp(window.behindRadius, window.aheadRadius, bias);\n        }\n        return { distance, dirRadius };\n    }\n\n    _makeEntryKey(kind, osmId) {\n        return `${kind}:${osmId}`;\n    }\n\n    _hashNodes(nodes) {\n        if (!Array.isArray(nodes) || nodes.length === 0) return 0;\n        let hash = 0;\n        for (const nodeId of nodes) {\n            const id = Number.isFinite(nodeId) ? nodeId : 0;\n            hash = ((hash << 5) - hash) + id;\n            hash |= 0;\n        }\n        return hash;\n    }\n\n    _hashCoordinates(points) {\n        if (!Array.isArray(points) || points.length === 0) return 0;\n        let hash = 0;\n        for (const point of points) {\n            const lat = Math.round(Number(point?.lat) * 1e7) || 0;\n            const lon = Math.round(Number(point?.lon) * 1e7) || 0;\n            hash = ((hash << 5) - hash) + lat;\n            hash = ((hash << 5) - hash) + lon;\n            hash |= 0;\n        }\n        return hash;\n    }\n\n    _resolveStyleKey(kind, tags = {}) {\n        if (kind === 'road' || kind === 'bridge') {\n            return tags.highway || 'default';\n        }\n        if (kind === 'waterway') {\n            return tags.waterway || 'stream';\n        }\n        if (kind === 'railway') {\n            return tags.railway || 'railway';\n        }\n        if (kind === 'area') {\n            return tags.natural || tags.landuse || tags.leisure || 'area';\n        }\n        return kind;\n    }\n\n    _buildEntrySignature(kind, styleKey, isClosed) {\n        const renderMode = this.paintEnabled ? 'paint' : 'mesh';\n        return [\n            kind,\n            styleKey,\n            isClosed ? 1 : 0,\n            renderMode,\n            this.roadWidthScale,\n            this.roadStepM,\n            this.ribbonThicknessM,\n            this.bridgeHeightM\n        ].join('|');\n    }\n\n    _disposeEntry(entry) {\n        if (!entry) return;\n        if (entry.labelHandle) {\n            if (entry.labelHandle.group) this.group.remove(entry.labelHandle.group);\n            entry.labelHandle.dispose();\n            entry.labelHandle = null;\n        }\n        if (!entry.group) {\n            this._detachEntryFromTiles(entry);\n            return;\n        }\n        this._detachEntryFromTiles(entry);\n        entry.group.traverse(child => {\n            if (child.geometry) child.geometry.dispose();\n            if (child.material) {\n                if (Array.isArray(child.material)) {\n                    child.material.forEach(m => m.dispose());\n                } else {\n                    child.material.dispose();\n                }\n            }\n        });\n        this.group.remove(entry.group);\n    }\n\n    /**\n     * Process Overpass response and create geometries.\n     *\n     * The build pass used to run as a single synchronous loop here,\n     * which spiked the main thread for hundreds of ms when the response\n     * carried hundreds of features (each `_buildEntry` allocates ribbon\n     * geometry, materials, and a group). That sat directly between the\n     * awaited fetch and the next render frame.\n     *\n     * Now we just stage the work into _buildState and let update(dt)\n     * drain it under a per-frame time budget. Net effect: the build is\n     * spread across N frames instead of stalling one frame for ~hundreds\n     * of ms. The final retention sweep + align/paint/drape kick is run\n     * in _finalizeBuild() once the queue is drained.\n     */\n    _processOverpassData(data, centerLat, centerLon, motionWindow = null) {\n        if (!this.enabled) return;\n        const elements = data?.elements || [];\n        const nodeMap = new Map();\n        const wayMap = new Map();\n        const window = motionWindow || this._resolveMotionWindow(centerLat, centerLon);\n\n        for (const el of elements) {\n            if (el.type === 'node') {\n                nodeMap.set(el.id, el);\n            } else if (el.type === 'way') {\n                wayMap.set(el.id, el);\n            }\n        }\n\n        const phiRad = THREE.MathUtils.degToRad(centerLat);\n        const mPerDegLat = metersPerDegLat(phiRad);\n        const mPerDegLon = metersPerDegLon(phiRad);\n\n        // If a build was already in progress (e.g. user moved before the\n        // previous slice drain finished), drop its in-flight nextEntries\n        // so we don't double-add. Existing entries in this._entryMap are\n        // preserved and will be reconsidered by the new pass.\n        this._cancelBuildSlicing({ disposePending: false });\n\n        this._buildState = {\n            ways: Array.from(wayMap.values()),\n            cursor: 0,\n            nodeMap,\n            window,\n            centerLat,\n            centerLon,\n            mPerDegLat,\n            mPerDegLon,\n            nextEntries: new Map(),\n            startedMs: nowMs(),\n        };\n\n        // Kick the scheduler immediately; update(dt) will keep draining\n        // it on subsequent frames. The idle scheduler exists so progress\n        // is also made when the page is otherwise idle (e.g. the user\n        // hasn't moved and update() hasn't fired in a while).\n        this._scheduleBuildWork();\n    }\n\n    /**\n     * Process one way from the Overpass result. Extracted from the\n     * old monolithic _processOverpassData so the slicer can call it\n     * inside a time budget. Mutates _buildState.nextEntries.\n     */\n    _processBuildWay(state, way) {\n        const { nodeMap, window, centerLat, centerLon, mPerDegLat, mPerDegLon, nextEntries } = state;\n        const tags = way.tags || {};\n        const nodes = (way.nodes || []).map(id => nodeMap.get(id)).filter(Boolean);\n        const embeddedGeometry = Array.isArray(way.geometry)\n            ? way.geometry\n                .filter((point) => Number.isFinite(point?.lat) && Number.isFinite(point?.lon))\n                .map((point) => ({ lat: point.lat, lon: point.lon }))\n            : [];\n        // The canonical relay uses Overpass `out geom`, so every bounded way\n        // remains self-contained even when the response cap is reached.\n        const latLonPairs = nodes.length >= 2\n            ? nodes.map(n => ({ lat: n.lat, lon: n.lon }))\n            : embeddedGeometry;\n        if (latLonPairs.length < 2) return;\n\n        let sumLat = 0;\n        let sumLon = 0;\n        for (const p of latLonPairs) {\n            sumLat += p.lat;\n            sumLon += p.lon;\n        }\n        const featureCenterLat = sumLat / latLonPairs.length;\n        const featureCenterLon = sumLon / latLonPairs.length;\n\n        let layerType = null;\n        let kind = null;\n        if (tags.bridge && this.layers.bridges) {\n            layerType = 'bridges';\n            kind = 'bridge';\n        } else if (tags.highway && this.layers.roads) {\n            layerType = 'roads';\n            kind = 'road';\n        } else if (tags.railway && this.layers.railways) {\n            layerType = 'railways';\n            kind = 'railway';\n        } else if (tags.waterway && this.layers.waterways) {\n            layerType = 'waterways';\n            kind = 'waterway';\n        } else if ((tags.leisure || tags.landuse || tags.natural) && this.layers.areas) {\n            layerType = 'areas';\n            kind = 'area';\n        } else if (tags.power === 'generator' && tags['generator:source'] === 'solar' && this.layers.solar) {\n            layerType = 'solar';\n            kind = 'solar';\n        } else if (tags.power === 'plant' && tags['plant:source'] === 'solar' && this.layers.solar) {\n            layerType = 'solar';\n            kind = 'solar';\n        } else if ((tags.telecom === 'data_centre' || tags.telecom === 'data_center' || tags.telecom === 'exchange') && this.layers.internet) {\n            layerType = 'internet';\n            kind = 'internet';\n        } else if ((tags.pipeline || tags['man_made'] === 'pipeline') && this.layers.petroleum) {\n            layerType = 'petroleum';\n            kind = 'petroleum';\n        } else if ((tags['man_made'] === 'water_works' || tags['man_made'] === 'water_tower' || tags.waterway === 'dam') && this.layers.water) {\n            layerType = 'water';\n            kind = 'water';\n        } else if (tags.power && this.layers.power) {\n            layerType = 'power';\n            kind = 'power';\n        } else if (tags.telecom && this.layers.telecoms) {\n            layerType = 'telecoms';\n            kind = 'telecoms';\n        }\n\n        if (!kind || !layerType) return;\n\n        const wayNodes = Array.isArray(way.nodes) ? way.nodes : [];\n        const firstPoint = latLonPairs[0];\n        const lastPoint = latLonPairs[latLonPairs.length - 1];\n        const isClosed = wayNodes.length > 1\n            ? wayNodes[0] === wayNodes[wayNodes.length - 1]\n            : Math.abs(firstPoint.lat - lastPoint.lat) < 1e-9\n                && Math.abs(firstPoint.lon - lastPoint.lon) < 1e-9;\n        const nodeHash = wayNodes.length\n            ? this._hashNodes(wayNodes)\n            : this._hashCoordinates(latLonPairs);\n        const styleKey = this._resolveStyleKey(kind, tags);\n        const signature = this._buildEntrySignature(kind, styleKey, isClosed);\n        const entryKey = this._makeEntryKey(kind, way.id);\n        const existing = this._entryMap.get(entryKey);\n        const expectsGeometryGroup = !this.paintEnabled;\n        const renderModeMatches = existing\n            ? (expectsGeometryGroup ? !!existing.group : !existing.group)\n            : false;\n\n        const distance = haversine(featureCenterLat, featureCenterLon, centerLat, centerLon);\n        let dirRadius = this.radiusM;\n        if (window?.motionDir) {\n            const entryDir = latLonToLocalDir(featureCenterLat, featureCenterLon).normalize();\n            const dot = this._computeDirectionalDot(window.centerDir, entryDir, window.motionDir);\n            const bias = (dot + 1) * 0.5;\n            dirRadius = THREE.MathUtils.lerp(window.behindRadius, window.aheadRadius, bias);\n        }\n        if (distance > dirRadius) return;\n\n        if (existing &&\n            existing._nodeHash === nodeHash &&\n            existing._signature === signature &&\n            renderModeMatches) {\n            existing.tags = tags;\n            existing.layerType = layerType;\n            existing.featureCenter = { lat: featureCenterLat, lon: featureCenterLon };\n            if (existing.group) {\n                existing.group.visible = this.layers[layerType] !== false;\n                if (existing.group.parent !== this.group) {\n                    this.group.add(existing.group);\n                }\n            }\n            this._setEntryTiles(existing);\n            nextEntries.set(entryKey, existing);\n            return;\n        }\n\n        if (existing) {\n            this._disposeEntry(existing);\n        }\n\n        const entry = this._buildEntry({\n            kind,\n            layerType,\n            latLonPairs,\n            tags,\n            osmId: way.id,\n            isClosed,\n            nodeHash,\n            signature,\n            centerLat,\n            centerLon,\n            mPerDegLat,\n            mPerDegLon\n        });\n\n        if (entry) {\n            nextEntries.set(entryKey, entry);\n            if (entry.group) {\n                this.group.add(entry.group);\n            }\n            this._setEntryTiles(entry);\n        }\n    }\n\n    /**\n     * Drain the build queue under a time budget. Called from update(dt)\n     * each frame, and also from a requestIdleCallback so progress is\n     * made even on quiet frames. budgetMs is the wall-clock budget for\n     * THIS slice — once exceeded, we yield to the next frame.\n     */\n    _processBuildSlice(budgetMs) {\n        const state = this._buildState;\n        if (!state) return;\n        if (!this.enabled) {\n            // Drop the build entirely if the overlay was disabled mid-flight.\n            this._cancelBuildSlicing({ disposePending: true });\n            return;\n        }\n\n        this._perfStart('cpu.infrastructure.process');\n        try {\n            const sliceStart = nowMs();\n            const budget = Number.isFinite(budgetMs) && budgetMs > 0 ? budgetMs : 4;\n            // Always make at least a tiny bit of progress per slice, even\n            // on a frame that's already past budget.\n            let processed = 0;\n            const minPerSlice = 1;\n            while (state.cursor < state.ways.length) {\n                this._processBuildWay(state, state.ways[state.cursor]);\n                state.cursor += 1;\n                processed += 1;\n                if (processed >= minPerSlice && (nowMs() - sliceStart) >= budget) {\n                    break;\n                }\n            }\n        } finally {\n            this._perfEnd('cpu.infrastructure.process');\n        }\n\n        if (state.cursor >= state.ways.length) {\n            this._finalizeBuild(state);\n        } else {\n            // More to do — schedule an idle continuation in case update()\n            // pauses (e.g. tab background). update() will also keep\n            // draining whenever it runs.\n            this._scheduleBuildWork();\n        }\n    }\n\n    _scheduleBuildWork() {\n        if (!this.enabled) return;\n        if (this._buildScheduled || !this._buildState) return;\n        this._buildScheduled = true;\n        this._buildIdleHandle = scheduleIdle((deadline) => {\n            this._buildScheduled = false;\n            this._buildIdleHandle = null;\n            if (!this._buildState) return;\n            // Use whatever the idle callback is willing to give us, but\n            // never more than our normal slice cap (we don't want to\n            // hog the next frame either).\n            const idleMs = (deadline && typeof deadline.timeRemaining === 'function')\n                ? deadline.timeRemaining()\n                : 0;\n            const budget = Math.max(this._buildSliceMs, Math.min(idleMs, 8));\n            this._processBuildSlice(budget);\n        });\n    }\n\n    _cancelBuildSlicing({ disposePending = false } = {}) {\n        if (this._buildIdleHandle != null) {\n            cancelIdle(this._buildIdleHandle);\n            this._buildIdleHandle = null;\n        }\n        this._buildScheduled = false;\n        if (!this._buildState) return;\n        if (disposePending) {\n            // Dispose any already-built brand-new entries that never\n            // graduated to this._entryMap so we don't leak GPU resources.\n            for (const [key, entry] of this._buildState.nextEntries) {\n                if (this._entryMap.get(key) !== entry) {\n                    this._disposeEntry(entry);\n                }\n            }\n        }\n        this._buildState = null;\n    }\n\n    /**\n     * Run the post-build retention sweep + queue alignment/painting/drape.\n     * Splits cleanly from _processBuildWay so the slicer can call it\n     * exactly once after the last way is processed.\n     */\n    _finalizeBuild(state) {\n        const { nextEntries, centerLat, centerLon, window } = state;\n        const retention = Number.isFinite(this.motionRetentionFactor)\n            ? Math.max(this.motionRetentionFactor, 1)\n            : DEFAULT_MOTION_RETENTION_FACTOR;\n        for (const [key, entry] of this._entryMap.entries()) {\n            if (nextEntries.has(key)) continue;\n            if (!this.layers[entry.layerType]) {\n                this._disposeEntry(entry);\n                continue;\n            }\n            const metrics = this._computeEntryMetrics(entry, centerLat, centerLon, window);\n            const limit = metrics.dirRadius * retention;\n            if (!Number.isFinite(metrics.distance) || metrics.distance > limit) {\n                this._disposeEntry(entry);\n                continue;\n            }\n            nextEntries.set(key, entry);\n        }\n\n        this._entryMap = nextEntries;\n        this._entries = Array.from(nextEntries.values());\n        const elapsed = Math.round(nowMs() - state.startedMs);\n        console.log(`[InfrastructureOverlay] Built ${this._entries.length} features (sliced over ${elapsed}ms)`);\n        this._buildState = null;\n        this._buildScheduled = false;\n        this._buildIdleHandle = null;\n        this._queueAllAlignEntries('refresh');\n        if (this.paintEnabled) {\n            this._queueAllPaintTiles();\n        }\n        this._scheduleDrapeWork();\n    }\n\n    /**\n     * Build a single infrastructure entry with proper globe positioning\n     */\n    _buildEntry({\n        kind,\n        layerType,\n        latLonPairs,\n        tags,\n        osmId,\n        isClosed,\n        nodeHash,\n        signature,\n        centerLat,\n        centerLon,\n        mPerDegLat,\n        mPerDegLon\n    }) {\n        if (latLonPairs.length < 2) return null;\n        if (kind === 'area' && (latLonPairs.length < 3 || !isClosed)) return null;\n\n        // Calculate the centroid of the feature\n        let sumLat = 0, sumLon = 0;\n        for (const p of latLonPairs) {\n            sumLat += p.lat;\n            sumLon += p.lon;\n        }\n        const featureCenterLat = sumLat / latLonPairs.length;\n        const featureCenterLon = sumLon / latLonPairs.length;\n\n        // Get the up direction at the feature center (direction from planet center)\n        const upVec = latLonToLocalDir(featureCenterLat, featureCenterLon);\n\n        // Build local coordinate frame: east, north, up\n        // North is roughly toward +Y in world space at equator, adjusted for local tangent\n        const north = new THREE.Vector3(0, 1, 0);\n        // East = north x up (right-hand rule)\n        const east = new THREE.Vector3().crossVectors(north, upVec).normalize();\n        // If east is degenerate (at poles), use a fallback\n        if (east.lengthSq() < 0.01) {\n            east.set(1, 0, 0);\n        }\n        // Recalculate north to be orthogonal\n        north.crossVectors(upVec, east).normalize();\n\n        // Convert lat/lon points to local meter offsets from feature center\n        const localPoints = [];\n        for (const p of latLonPairs) {\n            const dx = (p.lon - featureCenterLon) * mPerDegLon; // East offset in meters\n            const dy = (p.lat - featureCenterLat) * mPerDegLat; // North offset in meters\n            localPoints.push({ x: dx, y: dy, lat: p.lat, lon: p.lon });\n        }\n\n        let minX = Infinity;\n        let maxX = -Infinity;\n        let minY = Infinity;\n        let maxY = -Infinity;\n        for (const pt of localPoints) {\n            if (Number.isFinite(pt.x)) {\n                if (pt.x < minX) minX = pt.x;\n                if (pt.x > maxX) maxX = pt.x;\n            }\n            if (Number.isFinite(pt.y)) {\n                if (pt.y < minY) minY = pt.y;\n                if (pt.y > maxY) maxY = pt.y;\n            }\n        }\n        const boundsWidth = Number.isFinite(minX) && Number.isFinite(maxX) ? Math.max(0, maxX - minX) : 0;\n        const boundsDepth = Number.isFinite(minY) && Number.isFinite(maxY) ? Math.max(0, maxY - minY) : 0;\n\n        const paintOnly = this.paintEnabled === true;\n        if (paintOnly) {\n            return {\n                group: null,\n                mesh: null,\n                kind,\n                layerType,\n                osmId,\n                tags,\n                dir: upVec.clone(),\n                localPoints,\n                latLonPairs,\n                densifiedPoints: Array.isArray(latLonPairs) ? latLonPairs.slice() : null,\n                vertexLatLons: null,\n                vertexDirs: null,\n                featureCenter: { lat: featureCenterLat, lon: featureCenterLon },\n                center: { lat: featureCenterLat, lon: featureCenterLon },\n                surfaceRadius: this.planetRadius,\n                terrainNormal: upVec.clone(),\n                mPerDegLat,\n                mPerDegLon,\n                bounds: { minX, maxX, minY, maxY, width: boundsWidth, depth: boundsDepth },\n                up: upVec.clone(),\n                _nodeHash: nodeHash,\n                _signature: signature,\n                _drapeIndex: 0,\n                _drapeDirty: false,\n                alignState: 'provisional',\n                alignStamp: null,\n                alignStableFrames: 0,\n                alignAttempts: 0,\n                alignLastAlignedMs: 0,\n                alignLastRadius: this.planetRadius,\n                alignLastNormal: upVec.clone()\n            };\n        }\n\n        // Build geometry based on kind\n        let mesh = null;\n        let geometry = null;\n        let vertexLatLons = null;\n        let densifiedPoints = null;\n\n        // All line-based infrastructure uses ribbon geometry (thick visible cables)\n        const isLineFeature = INFRA_RIBBON_KINDS.has(kind);\n        if (isLineFeature) {\n            const result = this._buildRibbonGeometry(localPoints, tags, kind);\n            if (!result) return null;\n            geometry = result.geometry;\n            vertexLatLons = result.vertexLatLons;\n            densifiedPoints = result.densified || null;\n\n            // Choose material — utility layers use thick emissive materials\n            let material;\n            if (this._utilityMaterials[kind]) {\n                material = this._utilityMaterials[kind].clone();\n            } else if (kind === 'bridge') {\n                material = this._bridgeMaterial.clone();\n            } else if (kind === 'waterway') {\n                material = this._waterwayMaterial.clone();\n            } else if (kind === 'railway') {\n                material = this._railwayMaterial.clone();\n            } else {\n                material = this._roadMaterial.clone();\n            }\n\n            mesh = new THREE.Mesh(geometry, material);\n        } else if (kind === 'area') {\n            const result = this._buildAreaGeometry(localPoints, tags);\n            if (!result) return null;\n            geometry = result.geometry;\n            vertexLatLons = result.vertexLatLons;\n            densifiedPoints = result.densifiedPoints || null;\n            const material = this._areaMaterial.clone();\n            material.color.setHex(this.colors.areas);\n            mesh = new THREE.Mesh(geometry, material);\n        }\n\n        if (!mesh) return null;\n\n        // Create group and set orientation\n        // The geometry is built in local XY plane (X=east, Y=north)\n        // We need to rotate it so local Z points along the up vector\n        const group = new THREE.Group();\n\n        // Build rotation matrix: local X->east, local Y->north, local Z->up\n        const basis = new THREE.Matrix4().makeBasis(east, north, upVec);\n        const quat = new THREE.Quaternion().setFromRotationMatrix(basis);\n        group.quaternion.copy(quat);\n\n        // Sample terrain to get base surface radius at center (fast sampling)\n        const centerSample = this._sampleTerrainRadiusForDir(upVec, true);\n        const surfaceRadius = Number.isFinite(centerSample?.radius) ? centerSample.radius : this.planetRadius;\n\n        // Position the group at the terrain surface\n        // Bridges are elevated, others are at terrain level (vertices handle lift via Z offset)\n        if (kind === 'bridge') {\n            const bridgeLift = this.surfaceOffsetM + this.bridgeHeightM;\n            group.position.copy(upVec).multiplyScalar(surfaceRadius + bridgeLift);\n        } else {\n            group.position.copy(upVec).multiplyScalar(surfaceRadius);\n        }\n\n        group.add(mesh);\n        group.visible = this.layers[layerType] !== false;\n\n        const entry = {\n            group,\n            mesh,\n            kind,\n            layerType,\n            osmId,\n            tags,\n            dir: upVec.clone(),\n            localPoints,\n            latLonPairs,\n            densifiedPoints,\n            vertexLatLons, // Per-vertex lat/lon for terrain sampling\n            vertexDirs: vertexLatLons ? this._buildVertexDirs(vertexLatLons) : null,\n            featureCenter: { lat: featureCenterLat, lon: featureCenterLon },\n            center: { lat: featureCenterLat, lon: featureCenterLon },\n            surfaceRadius,\n            terrainNormal: upVec.clone(),\n            mPerDegLat,\n            mPerDegLon,\n            east: east.clone(),\n            north: north.clone(),\n            baseEast: east.clone(),\n            baseNorth: north.clone(),\n            bounds: { minX, maxX, minY, maxY, width: boundsWidth, depth: boundsDepth },\n            up: upVec.clone(),\n            _nodeHash: nodeHash,\n            _signature: signature,\n            _drapeIndex: 0,\n            _drapeDirty: kind !== 'bridge',\n            alignState: 'provisional',\n            alignStamp: null,\n            alignStableFrames: 0,\n            alignAttempts: 0,\n            alignLastAlignedMs: 0,\n            alignLastRadius: surfaceRadius,\n            alignLastNormal: upVec.clone(),\n            labelHandle: null\n        };\n\n        group.userData.entry = entry;\n        group.userData.surfaceDir = upVec.clone();\n\n        // Align to terrain normal when elevation data is available\n        this._applyTerrainFrame(entry, centerSample, true);\n\n        // Create label for named features\n        if (this._labelsEnabled && tags.name) {\n            const ls = this._ensureLabelSystem();\n            if (ls) {\n                this._tmpLabelVec.copy(entry.dir).multiplyScalar(\n                    (Number.isFinite(entry.surfaceRadius) ? entry.surfaceRadius : surfaceRadius) + 2\n                );\n                entry.labelHandle = ls.createLabel(tags.name, {\n                    position: this._tmpLabelVec,\n                    type: 'infrastructure',\n                    objectRadius: 10,\n                    subText: this._formatEntryKindLabel(entry),\n                    color: this._resolveEntryLabelColor(entry),\n                });\n                if (entry.labelHandle?.group) {\n                    this.group.add(entry.labelHandle.group);\n                }\n            }\n        }\n\n        return entry;\n    }\n\n    _handleTileEvent(payload) {\n        if (!this.enabled) return;\n        if (!payload || !payload.tile) return;\n        const tile = payload.tile;\n        switch (payload.type) {\n            case 'elevation':\n            case 'split':\n            case 'merge':\n                this._queueEntriesForTile(tile, { refreshTiles: true });\n                if (Array.isArray(payload.children)) {\n                    for (const child of payload.children) {\n                        this._queueEntriesForTile(child, { refreshTiles: true });\n                    }\n                }\n                if (this.paintEnabled && this.paintRepaintOnLod) {\n                    this._queuePaintForTile(tile);\n                    if (Array.isArray(payload.children)) {\n                        for (const child of payload.children) {\n                            this._queuePaintForTile(child);\n                        }\n                    }\n                }\n                break;\n            case 'imagery':\n                if (this.paintEnabled) {\n                    this._queuePaintForTile(tile);\n                }\n                break;\n            case 'visible-added':\n                if (this.paintEnabled) {\n                    this._queuePaintForTile(tile);\n                }\n                break;\n            case 'visible-removed':\n                if (this.paintEnabled) {\n                    this._clearPaintTile(tile);\n                }\n                break;\n            default:\n                break;\n        }\n    }\n\n    _queueEntriesForTile(tile, { refreshTiles = false } = {}) {\n        if (!tile) return;\n        const entries = this._tileToEntries.get(tile);\n        if (!entries?.size) return;\n        let needsDrape = false;\n        for (const entry of entries) {\n            if (!entry) continue;\n            if (refreshTiles) {\n                this._setEntryTiles(entry);\n            }\n            if (refreshTiles && entry.kind !== 'bridge') {\n                entry._drapeDirty = true;\n                entry._drapeIndex = 0;\n                if (entry.vertexLatLons?.length) {\n                    needsDrape = true;\n                }\n            }\n            if (this.tileDrivenResnap) {\n                this._queueAlignEntry(entry, 'tile-event');\n            }\n        }\n        if (needsDrape) {\n            this._scheduleDrapeWork();\n        }\n    }\n\n    _isWireframeActive() {\n        return !!this.triTree?.renderRules?.wireframe;\n    }\n\n    _queuePaintForTile(tile) {\n        if (!this.enabled) return;\n        if (!tile) return;\n        this._paintQueue.add(tile);\n    }\n\n    _queueAllPaintTiles() {\n        if (!this.enabled) return;\n        for (const tile of this._paintTiles.keys()) {\n            this._paintQueue.add(tile);\n        }\n        if (this.triTree?.visibleLeafTiles?.length) {\n            for (const tile of this.triTree.visibleLeafTiles) {\n                this._paintQueue.add(tile);\n            }\n        }\n    }\n\n    _processPaintQueue() {\n        const wireframeActive = this._isWireframeActive();\n        if (!this.paintEnabled || !this.enabled || !wireframeActive) {\n            if (this._paintTiles.size) {\n                this._clearPaintTiles();\n            }\n            this._paintQueue.clear();\n            return;\n        }\n        if (!this._paintQueue.size) return;\n        const budget = Math.min(this.paintBudget, this._paintQueue.size);\n        let processed = 0;\n        for (const tile of this._paintQueue) {\n            this._paintQueue.delete(tile);\n            this._repaintTile(tile);\n            processed += 1;\n            if (processed >= budget) break;\n        }\n    }\n\n    _getTileUvBounds(tile) {\n        const uvAttr = tile?.geometry?.getAttribute('uv2') || tile?.geometry?.getAttribute('uv');\n        if (!uvAttr || uvAttr.count <= 0) return null;\n        let minU = 1;\n        let maxU = 0;\n        let minV = 1;\n        let maxV = 0;\n        for (let i = 0; i < uvAttr.count; i++) {\n            const u = uvAttr.getX(i);\n            const v = uvAttr.getY(i);\n            if (u < minU) minU = u;\n            if (u > maxU) maxU = u;\n            if (v < minV) minV = v;\n            if (v > maxV) maxV = v;\n        }\n        minU = THREE.MathUtils.clamp(minU, 0, 1);\n        maxU = THREE.MathUtils.clamp(maxU, 0, 1);\n        minV = THREE.MathUtils.clamp(minV, 0, 1);\n        maxV = THREE.MathUtils.clamp(maxV, 0, 1);\n        const spanU = maxU - minU;\n        const spanV = maxV - minV;\n        if (spanU <= 1e-5 || spanV <= 1e-5) return null;\n        return { minU, maxU, minV, maxV, spanU, spanV };\n    }\n\n    _ensurePaintTile(tile) {\n        if (!tile?.geometry) return null;\n        const bounds = this._getTileUvBounds(tile);\n        if (!bounds) return null;\n\n        const key = `${bounds.minU.toFixed(6)}|${bounds.maxU.toFixed(6)}|${bounds.minV.toFixed(6)}|${bounds.maxV.toFixed(6)}`;\n        const existing = this._paintTiles.get(tile);\n        if (existing && existing.resolution === this.paintResolution && existing.uvKey === key) {\n            return existing;\n        }\n\n        if (existing) {\n            this._clearPaintTile(tile);\n        }\n\n        const canvas = document.createElement('canvas');\n        canvas.width = this.paintResolution;\n        canvas.height = this.paintResolution;\n        const ctx = canvas.getContext('2d');\n        const texture = new THREE.CanvasTexture(canvas);\n        texture.wrapS = THREE.ClampToEdgeWrapping;\n        texture.wrapT = THREE.ClampToEdgeWrapping;\n        texture.minFilter = THREE.LinearFilter;\n        texture.magFilter = THREE.LinearFilter;\n        texture.generateMipmaps = false;\n\n        const info = {\n            canvas,\n            ctx,\n            texture,\n            bounds,\n            uvKey: key,\n            resolution: this.paintResolution,\n            overlayMesh: null,\n            overlayMaterial: null\n        };\n        this._paintTiles.set(tile, info);\n        this._applyPaintUniforms(tile, info);\n        this._ensurePaintOverlay(tile, info);\n        return info;\n    }\n\n    _applyPaintUniforms(tile, paintInfo) {\n        const wireframeActive = this._isWireframeActive();\n        const materials = [];\n        if (tile?.materialDefault) materials.push(tile.materialDefault);\n        if (tile?.mesh?.material && tile.mesh.material !== tile.materialDefault) {\n            materials.push(tile.mesh.material);\n        }\n        for (const material of materials) {\n            const uniforms = material?.userData?.uniforms;\n            if (!uniforms) continue;\n            if (uniforms.infraPaintEnabled) {\n                uniforms.infraPaintEnabled.value = (this.enabled && this.paintEnabled && paintInfo && !wireframeActive)\n                    ? 1.0\n                    : 0.0;\n            }\n            if (uniforms.infraPaintTexture) {\n                uniforms.infraPaintTexture.value = paintInfo ? paintInfo.texture : null;\n            }\n            if (uniforms.infraPaintOpacity) {\n                uniforms.infraPaintOpacity.value = this.paintOpacity;\n            }\n            if (paintInfo?.bounds && uniforms.infraPaintUvOffset && uniforms.infraPaintUvScale) {\n                uniforms.infraPaintUvOffset.value.set(paintInfo.bounds.minU, paintInfo.bounds.minV);\n                uniforms.infraPaintUvScale.value.set(1 / paintInfo.bounds.spanU, 1 / paintInfo.bounds.spanV);\n            }\n            material.needsUpdate = true;\n        }\n    }\n\n    _ensurePaintOverlay(tile, paintInfo) {\n        if (!this._isWireframeActive()) return;\n        if (!paintInfo || !tile?.mesh) return;\n        if (paintInfo.overlayMesh && paintInfo.overlayMaterial) {\n            this._applyPaintOverlayUniforms(paintInfo);\n            return;\n        }\n        const material = new THREE.ShaderMaterial({\n            uniforms: {\n                uPaintTexture: { value: paintInfo.texture },\n                uOpacity: { value: this.paintOpacity },\n                uUvOffset: { value: new THREE.Vector2(paintInfo.bounds.minU, paintInfo.bounds.minV) },\n                uUvScale: { value: new THREE.Vector2(1 / paintInfo.bounds.spanU, 1 / paintInfo.bounds.spanV) }\n            },\n            vertexShader: `\n                #include <common>\n                #include <logdepthbuf_pars_vertex>\n                attribute vec2 uv;\n                #ifdef USE_UV2\n                attribute vec2 uv2;\n                #endif\n                varying vec2 vUvPaint;\n                void main() {\n                    #ifdef USE_UV2\n                        vUvPaint = uv2;\n                    #else\n                        vUvPaint = uv;\n                    #endif\n                    gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n                    #include <logdepthbuf_vertex>\n                }\n            `,\n            fragmentShader: `\n                #include <common>\n                #include <logdepthbuf_pars_fragment>\n                uniform sampler2D uPaintTexture;\n                uniform float uOpacity;\n                uniform vec2 uUvOffset;\n                uniform vec2 uUvScale;\n                varying vec2 vUvPaint;\n                void main() {\n                    #include <logdepthbuf_fragment>\n                    vec2 paintUv = (vUvPaint - uUvOffset) * uUvScale;\n                    if (paintUv.x < 0.0 || paintUv.x > 1.0 || paintUv.y < 0.0 || paintUv.y > 1.0) {\n                        discard;\n                    }\n                    vec4 sample = texture2D(uPaintTexture, paintUv);\n                    float alpha = sample.a * uOpacity;\n                    if (alpha <= 0.001) discard;\n                    gl_FragColor = vec4(sample.rgb, alpha);\n                }\n            `,\n            transparent: true,\n            depthWrite: false,\n            depthTest: true,\n            side: THREE.DoubleSide,\n            polygonOffset: true,\n            polygonOffsetFactor: -1,\n            polygonOffsetUnits: -1,\n            defines: { USE_UV2: '' }\n        });\n        const mesh = new THREE.Mesh(tile.geometry, material);\n        mesh.renderOrder = 3;\n        tile.mesh.add(mesh);\n        paintInfo.overlayMesh = mesh;\n        paintInfo.overlayMaterial = material;\n    }\n\n    _applyPaintOverlayUniforms(paintInfo) {\n        if (!paintInfo?.overlayMaterial) return;\n        const uniforms = paintInfo.overlayMaterial.uniforms;\n        if (uniforms.uPaintTexture) uniforms.uPaintTexture.value = paintInfo.texture;\n        if (uniforms.uOpacity) uniforms.uOpacity.value = this.paintOpacity;\n        if (uniforms.uUvOffset && paintInfo.bounds) {\n            uniforms.uUvOffset.value.set(paintInfo.bounds.minU, paintInfo.bounds.minV);\n        }\n        if (uniforms.uUvScale && paintInfo.bounds) {\n            uniforms.uUvScale.value.set(1 / paintInfo.bounds.spanU, 1 / paintInfo.bounds.spanV);\n        }\n        paintInfo.overlayMaterial.needsUpdate = true;\n    }\n\n    _clearPaintTile(tile) {\n        const info = this._paintTiles.get(tile);\n        if (!info) return;\n        if (info.texture) info.texture.dispose();\n        if (info.overlayMesh && info.overlayMesh.parent) {\n            info.overlayMesh.parent.remove(info.overlayMesh);\n        }\n        if (info.overlayMaterial) {\n            info.overlayMaterial.dispose();\n        }\n        this._paintTiles.delete(tile);\n        this._paintQueue.delete(tile);\n        this._applyPaintUniforms(tile, null);\n    }\n\n    _clearPaintTiles() {\n        for (const tile of this._paintTiles.keys()) {\n            this._clearPaintTile(tile);\n        }\n        this._paintQueue.clear();\n    }\n\n    _latLonToPaintPoint(tile, bounds, lat, lon, out) {\n        let u = null;\n        let v = null;\n        if (tile?.getAtlasUvForLatLon && tile?.imageryTexture) {\n            const uv = tile.getAtlasUvForLatLon(lat, lon, this._tmpPaintUv);\n            if (uv) {\n                u = uv.u;\n                v = uv.v;\n            }\n        }\n        if (u === null || v === null) {\n            u = (lon + 180) / 360;\n            v = 1 - (lat + 90) / 180;\n        }\n        const uLocal = (u - bounds.minU) / bounds.spanU;\n        const vLocal = (v - bounds.minV) / bounds.spanV;\n        if (uLocal < 0 || uLocal > 1 || vLocal < 0 || vLocal > 1) return null;\n        out.x = uLocal * this.paintResolution;\n        out.y = (1 - vLocal) * this.paintResolution;\n        return out;\n    }\n\n    _colorToRgba(colorHex, alpha) {\n        const color = new THREE.Color(colorHex);\n        const r = Math.round(color.r * 255);\n        const g = Math.round(color.g * 255);\n        const b = Math.round(color.b * 255);\n        const a = Math.max(0, Math.min(1, alpha));\n        return `rgba(${r}, ${g}, ${b}, ${a})`;\n    }\n\n    _repaintTile(tile) {\n        if (!this.paintEnabled || !this.enabled || !this._isWireframeActive()) {\n            this._clearPaintTile(tile);\n            return;\n        }\n        if (!tile?.geometry) {\n            this._clearPaintTile(tile);\n            return;\n        }\n        const entries = this._tileToEntries.get(tile);\n        if (!entries || entries.size === 0) {\n            this._clearPaintTile(tile);\n            return;\n        }\n\n        const paintInfo = this._ensurePaintTile(tile);\n        if (!paintInfo?.ctx) return;\n\n        const ctx = paintInfo.ctx;\n        const res = this.paintResolution;\n        ctx.clearRect(0, 0, res, res);\n        ctx.lineJoin = 'round';\n        ctx.lineCap = 'round';\n\n        const point = this._tmpPaintPoint;\n\n        for (const entry of entries) {\n            if (!entry || !this.layers[entry.layerType]) continue;\n            const points = entry.latLonPairs;\n            if (!Array.isArray(points) || points.length < 2) continue;\n\n            if (entry.kind === 'area') {\n                let started = false;\n                ctx.beginPath();\n                for (const pt of points) {\n                    const mapped = this._latLonToPaintPoint(tile, paintInfo.bounds, pt.lat, pt.lon, point);\n                    if (!mapped) continue;\n                    if (!started) {\n                        ctx.moveTo(mapped.x, mapped.y);\n                        started = true;\n                    } else {\n                        ctx.lineTo(mapped.x, mapped.y);\n                    }\n                }\n                if (!started) continue;\n                ctx.closePath();\n                ctx.fillStyle = this._colorToRgba(this.colors.areas, this.paintOpacity * 0.55);\n                ctx.fill();\n                continue;\n            }\n\n            let width = this.paintLineWidthPx;\n            if (entry.kind === 'waterway') width *= 1.2;\n            if (entry.kind === 'railway') width *= 0.75;\n            ctx.lineWidth = width;\n            if (entry.kind === 'bridge') {\n                ctx.strokeStyle = this._colorToRgba(this.colors.bridges, this.paintOpacity);\n            } else if (entry.kind === 'waterway') {\n                ctx.strokeStyle = this._colorToRgba(this.colors.waterways, this.paintOpacity * 0.9);\n            } else if (entry.kind === 'railway') {\n                ctx.strokeStyle = this._colorToRgba(this.colors.railways, this.paintOpacity);\n            } else {\n                ctx.strokeStyle = this._colorToRgba(this.colors.roads, this.paintOpacity);\n            }\n\n            let started = false;\n            ctx.beginPath();\n            for (const pt of points) {\n                const mapped = this._latLonToPaintPoint(tile, paintInfo.bounds, pt.lat, pt.lon, point);\n                if (!mapped) continue;\n                if (!started) {\n                    ctx.moveTo(mapped.x, mapped.y);\n                    started = true;\n                } else {\n                    ctx.lineTo(mapped.x, mapped.y);\n                }\n            }\n            if (started) {\n                ctx.stroke();\n            }\n        }\n\n        paintInfo.texture.needsUpdate = true;\n        this._applyPaintUniforms(tile, paintInfo);\n        this._applyPaintOverlayUniforms(paintInfo);\n    }\n\n    _resolveTilesForEntry(entry) {\n        if (!entry || !this.triTree || typeof this.triTree.findLeafTileForWorldDir !== 'function') {\n            return null;\n        }\n        const center = entry.center;\n        if (!center) return null;\n\n        const samples = [];\n        samples.push({ lat: center.lat, lon: center.lon });\n\n        const maxSamples = Number.isFinite(this.alignMaxSamples)\n            ? Math.max(4, Math.floor(this.alignMaxSamples))\n            : DEFAULT_ALIGN_MAX_SAMPLES;\n\n        const densified = entry.densifiedPoints;\n        if (Array.isArray(densified) && densified.length) {\n            let stride = 1;\n            if (Number.isFinite(this.alignSampleStepM) &&\n                Number.isFinite(this.roadStepM) &&\n                this.roadStepM > 0) {\n                stride = Math.max(1, Math.round(this.alignSampleStepM / this.roadStepM));\n            }\n            if (densified.length / stride > maxSamples) {\n                stride = Math.ceil(densified.length / maxSamples);\n            }\n            for (let i = 0; i < densified.length; i += stride) {\n                const pt = densified[i];\n                if (pt && Number.isFinite(pt.lat) && Number.isFinite(pt.lon)) {\n                    samples.push({ lat: pt.lat, lon: pt.lon });\n                }\n            }\n        } else if (Array.isArray(entry.vertexLatLons) && entry.vertexLatLons.length) {\n            const stride = Math.max(1, Math.ceil(entry.vertexLatLons.length / maxSamples));\n            for (let i = 0; i < entry.vertexLatLons.length; i += stride) {\n                const pt = entry.vertexLatLons[i];\n                if (pt && Number.isFinite(pt.lat) && Number.isFinite(pt.lon)) {\n                    samples.push({ lat: pt.lat, lon: pt.lon });\n                }\n            }\n        }\n\n        if (samples.length < 3) {\n            const bounds = entry.bounds || {};\n            const minX = Number.isFinite(bounds.minX) ? bounds.minX : 0;\n            const maxX = Number.isFinite(bounds.maxX) ? bounds.maxX : 0;\n            const minY = Number.isFinite(bounds.minY) ? bounds.minY : 0;\n            const maxY = Number.isFinite(bounds.maxY) ? bounds.maxY : 0;\n\n            const mPerDegLat = Number.isFinite(entry.mPerDegLat)\n                ? entry.mPerDegLat\n                : metersPerDegLat(THREE.MathUtils.degToRad(center.lat));\n            const mPerDegLon = Number.isFinite(entry.mPerDegLon)\n                ? entry.mPerDegLon\n                : metersPerDegLon(THREE.MathUtils.degToRad(center.lat));\n\n            const corners = [\n                { x: minX, y: minY },\n                { x: minX, y: maxY },\n                { x: maxX, y: minY },\n                { x: maxX, y: maxY }\n            ];\n            for (const corner of corners) {\n                const lat = center.lat + corner.y / mPerDegLat;\n                const lon = center.lon + corner.x / mPerDegLon;\n                if (Number.isFinite(lat) && Number.isFinite(lon)) {\n                    samples.push({ lat, lon });\n                }\n            }\n        }\n\n        const tiles = new Set();\n        for (const sample of samples) {\n            const dir = latLonToLocalDir(sample.lat, sample.lon).normalize();\n            const tile = this.triTree.findLeafTileForWorldDir(dir);\n            if (tile) tiles.add(tile);\n        }\n        return tiles.size ? tiles : null;\n    }\n\n    _setEntryTiles(entry) {\n        if (!entry) return;\n        const prevKeys = Array.isArray(entry.tileKeys) ? entry.tileKeys.join('|') : null;\n        if (entry.tiles && entry.tiles.size) {\n            for (const tile of entry.tiles) {\n                const bucket = this._tileToEntries.get(tile);\n                if (bucket) {\n                    bucket.delete(entry);\n                    if (!bucket.size) this._tileToEntries.delete(tile);\n                }\n            }\n        }\n        const tiles = this._resolveTilesForEntry(entry);\n        entry.tiles = tiles;\n        this._buildEntryTileCache(entry);\n        const nextKeys = Array.isArray(entry.tileKeys) ? entry.tileKeys.join('|') : null;\n        if (prevKeys !== nextKeys) {\n            entry.alignStamp = null;\n            entry.alignStableFrames = 0;\n            if (entry.alignState !== 'provisional') {\n                entry.alignState = 'coarse';\n            }\n            this._queueAlignEntry(entry, 'tiles-updated');\n        }\n        if (!tiles?.size) return;\n        for (const tile of tiles) {\n            let bucket = this._tileToEntries.get(tile);\n            if (!bucket) {\n                bucket = new Set();\n                this._tileToEntries.set(tile, bucket);\n            }\n            bucket.add(entry);\n        }\n    }\n\n    _detachEntryFromTiles(entry) {\n        if (!entry?.tiles) return;\n        for (const tile of entry.tiles) {\n            const bucket = this._tileToEntries.get(tile);\n            if (!bucket) continue;\n            bucket.delete(entry);\n            if (!bucket.size) this._tileToEntries.delete(tile);\n        }\n        entry.tiles = null;\n        entry.tileList = null;\n        entry.tileKeys = null;\n    }\n\n    _getTileKey(tile) {\n        if (!tile) return 'unknown';\n        if (tile._infraTileKey) return tile._infraTileKey;\n        let key = null;\n        if (typeof tile.getTileId === 'function') {\n            key = tile.getTileId();\n        } else if (typeof tile.id === 'string') {\n            key = tile.id;\n        } else if (Number.isFinite(tile.index)) {\n            key = `L${tile.level ?? 'x'}-${tile.index}`;\n        } else {\n            key = `tile-${Math.random().toString(36).slice(2, 8)}`;\n        }\n        tile._infraTileKey = key;\n        return key;\n    }\n\n    _buildEntryTileCache(entry) {\n        if (!entry?.tiles || !entry.tiles.size) {\n            entry.tileList = null;\n            entry.tileKeys = null;\n            return;\n        }\n        const tiles = Array.from(entry.tiles);\n        tiles.sort((a, b) => this._getTileKey(a).localeCompare(this._getTileKey(b)));\n        entry.tileList = tiles;\n        entry.tileKeys = tiles.map((tile) => this._getTileKey(tile));\n    }\n\n    _getEntryElevationStamp(entry) {\n        if (!entry?.tileList?.length || !entry.tileKeys?.length) return null;\n        const parts = [];\n        for (let i = 0; i < entry.tileList.length; i++) {\n            const tile = entry.tileList[i];\n            const key = entry.tileKeys[i] || this._getTileKey(tile);\n            const version = Number.isFinite(tile?.elevationVersion) ? tile.elevationVersion : 0;\n            parts.push(`${key}:${version}`);\n        }\n        return parts.join('|');\n    }\n\n    _entryHasElevation(entry) {\n        if (!entry?.tileList?.length) return false;\n        for (const tile of entry.tileList) {\n            if (tile?.elevationHasData) return true;\n            if (Number.isFinite(tile?.elevationDone) && tile.elevationDone > 0) return true;\n            if (Number.isFinite(tile?.elevationSeededCount) && tile.elevationSeededCount > 0) return true;\n        }\n        return false;\n    }\n\n    _hasPhotorealSurface() {\n        return !!(this.surfaceController?.photoTileGroup\n            && typeof this.surfaceController.sampleTerrainRadiusForDir === 'function');\n    }\n\n    _queueAlignEntry(entry, reason = '') {\n        if (!entry) return;\n        if (this._alignQueued.has(entry)) return;\n        this._alignQueued.add(entry);\n        this._alignQueue.push(entry);\n        entry._alignQueuedReason = reason || entry._alignQueuedReason;\n    }\n\n    _queueAllAlignEntries(reason = '') {\n        if (!this._entries?.length) return;\n        for (const entry of this._entries) {\n            this._queueAlignEntry(entry, reason);\n        }\n    }\n\n    _processAlignQueue() {\n        if (!this._alignQueue.length) return;\n        const budget = Math.min(\n            Math.max(1, this.resnapBudget || 1),\n            this._alignQueue.length\n        );\n        let processed = 0;\n        while (processed < budget && this._alignQueueIndex < this._alignQueue.length) {\n            const entry = this._alignQueue[this._alignQueueIndex++];\n            if (!this._alignQueued.has(entry)) continue;\n            this._alignQueued.delete(entry);\n            this._alignEntry(entry, { reason: entry?._alignQueuedReason });\n            processed += 1;\n        }\n        if (this._alignQueueIndex >= this._alignQueue.length) {\n            this._alignQueue.length = 0;\n            this._alignQueueIndex = 0;\n        } else if (this._alignQueueIndex > 256) {\n            this._alignQueue = this._alignQueue.slice(this._alignQueueIndex);\n            this._alignQueueIndex = 0;\n        }\n    }\n\n    _updateProcessingPause() {\n        if (!this.pauseWhenFar || !this._center || !this.triTree?.viewFocusDir) {\n            if (this._processingPaused) {\n                this._setProcessingPaused(false, null);\n            }\n            return;\n        }\n        const focus = dirToLatLonLocal(this.triTree.viewFocusDir);\n        if (!Number.isFinite(focus?.latDeg) || !Number.isFinite(focus?.lonDeg)) {\n            if (this._processingPaused) {\n                this._setProcessingPaused(false, null);\n            }\n            return;\n        }\n        this._lastFocusLatLon = { lat: focus.latDeg, lon: focus.lonDeg };\n        const distance = geodesicDistanceWGS84(\n            this._center.lat,\n            this._center.lon,\n            focus.latDeg,\n            focus.lonDeg\n        );\n        const limit = Number.isFinite(this.pauseDistanceM)\n            ? this.pauseDistanceM\n            : (Number.isFinite(this.radiusM) ? this.radiusM * this.pauseDistanceMultiplier : null);\n        if (!Number.isFinite(limit)) {\n            if (this._processingPaused) {\n                this._setProcessingPaused(false, null);\n            }\n            return;\n        }\n        const shouldPause = distance > limit;\n        if (shouldPause !== this._processingPaused) {\n            this._setProcessingPaused(shouldPause, shouldPause ? 'focus-distance' : null);\n        }\n    }\n\n    _setProcessingPaused(paused, reason = null) {\n        this._processingPaused = paused;\n        this._processingPauseReason = paused ? reason : null;\n        if (paused) {\n            this._cancelDrapeWork();\n        } else {\n            this._queueAllAlignEntries('resume');\n            if (this.paintEnabled) {\n                this._queueAllPaintTiles();\n            }\n            this._scheduleDrapeWork();\n        }\n    }\n\n    /**\n     * Build ribbon geometry for roads, waterways, railways\n     * Geometry is built in local XY plane (X=east, Y=north, Z=up)\n     * Creates volumetric ribbons with top surface and sides for visibility\n     */\n    _buildRibbonGeometry(localPoints, tags, kind) {\n        if (localPoints.length < 2) return null;\n\n        // Determine width — utility layers use INFRA_LINE_WIDTHS for orbit visibility\n        let width;\n        if (INFRA_LINE_WIDTHS[kind]) {\n            width = INFRA_LINE_WIDTHS[kind];\n        } else if (kind === 'waterway') {\n            const waterwayType = tags.waterway || 'stream';\n            if (waterwayType === 'river') width = 15;\n            else if (waterwayType === 'stream') width = 4;\n            else if (waterwayType === 'canal') width = 8;\n            else if (waterwayType === 'drain') width = 2;\n            else width = 3;\n        } else if (kind === 'railway') {\n            width = 5;\n        } else {\n            const highwayType = tags.highway || 'default';\n            width = (ROAD_WIDTHS[highwayType] || ROAD_WIDTHS.default) * this.roadWidthScale;\n        }\n\n        const halfW = width * 0.5;\n        const thickness = this.ribbonThicknessM;\n\n        // Densify the line\n        const densified = this._densifyLine(localPoints, this.roadStepM);\n\n        // Get color for roads\n        let color = null;\n        if (kind === 'road') {\n            color = new THREE.Color(this.colors.roads);\n        }\n\n        // Build volumetric ribbon with top and side faces\n        // For each segment point, we create 4 vertices: left-top, right-top, left-bottom, right-bottom\n        const positions = [];\n        const colors = [];\n        const indices = [];\n        const vertexLatLons = []; // Store lat/lon for each vertex for terrain sampling\n\n        const segments = densified.length;\n\n        for (let i = 0; i < segments; i++) {\n            const pt = densified[i];\n            const x = pt.x;\n            const y = pt.y;\n\n            // Calculate direction to next/prev point for perpendicular\n            let dx, dy;\n            if (i < segments - 1) {\n                dx = densified[i + 1].x - x;\n                dy = densified[i + 1].y - y;\n            } else {\n                dx = x - densified[i - 1].x;\n                dy = y - densified[i - 1].y;\n            }\n\n            const len = Math.sqrt(dx * dx + dy * dy) || 1;\n            // Perpendicular direction (90 degrees rotated)\n            const perpX = -dy / len;\n            const perpY = dx / len;\n\n            // Left and right positions\n            const leftX = x + perpX * halfW;\n            const leftY = y + perpY * halfW;\n            const rightX = x - perpX * halfW;\n            const rightY = y - perpY * halfW;\n\n            // 4 vertices per segment point:\n            // 0: left-top, 1: right-top, 2: left-bottom, 3: right-bottom\n            // Z=thickness for top, Z=0 for bottom (draping will adjust the bottom Z)\n            positions.push(leftX, leftY, thickness);   // left-top\n            positions.push(rightX, rightY, thickness); // right-top\n            positions.push(leftX, leftY, 0);           // left-bottom\n            positions.push(rightX, rightY, 0);         // right-bottom\n\n            // Calculate lat/lon for left and right vertices\n            const mPerDegLat = metersPerDegLat(THREE.MathUtils.degToRad(pt.lat));\n            const mPerDegLon = metersPerDegLon(THREE.MathUtils.degToRad(pt.lat));\n\n            const leftLat = pt.lat + (perpY * halfW) / mPerDegLat;\n            const leftLon = pt.lon + (perpX * halfW) / mPerDegLon;\n            const rightLat = pt.lat - (perpY * halfW) / mPerDegLat;\n            const rightLon = pt.lon - (perpX * halfW) / mPerDegLon;\n\n            // Store lat/lon for each of the 4 vertices (same left/right position, different Z)\n            vertexLatLons.push({ lat: leftLat, lon: leftLon });   // left-top\n            vertexLatLons.push({ lat: rightLat, lon: rightLon }); // right-top\n            vertexLatLons.push({ lat: leftLat, lon: leftLon });   // left-bottom\n            vertexLatLons.push({ lat: rightLat, lon: rightLon }); // right-bottom\n\n            // Vertex colors (same for all 4 vertices at this segment)\n            if (color) {\n                colors.push(color.r, color.g, color.b); // left-top\n                colors.push(color.r, color.g, color.b); // right-top\n                colors.push(color.r, color.g, color.b); // left-bottom\n                colors.push(color.r, color.g, color.b); // right-bottom\n            }\n\n            // Triangle indices - connect to next segment\n            if (i < segments - 1) {\n                const base = i * 4;\n                const next = (i + 1) * 4;\n\n                // Top face (left-top, right-top of current and next)\n                indices.push(base + 0, next + 0, base + 1); // left-top -> next-left-top -> right-top\n                indices.push(next + 0, next + 1, base + 1); // next-left-top -> next-right-top -> right-top\n\n                // Left side face (left-top, left-bottom of current and next)\n                indices.push(base + 0, base + 2, next + 0); // left-top -> left-bottom -> next-left-top\n                indices.push(base + 2, next + 2, next + 0); // left-bottom -> next-left-bottom -> next-left-top\n\n                // Right side face (right-top, right-bottom of current and next)\n                indices.push(base + 1, next + 1, base + 3); // right-top -> next-right-top -> right-bottom\n                indices.push(next + 1, next + 3, base + 3); // next-right-top -> next-right-bottom -> right-bottom\n            }\n        }\n\n        // Add end caps\n        if (segments >= 2) {\n            // Start cap\n            indices.push(0, 1, 2); // left-top, right-top, left-bottom\n            indices.push(1, 3, 2); // right-top, right-bottom, left-bottom\n\n            // End cap\n            const last = (segments - 1) * 4;\n            indices.push(last + 0, last + 2, last + 1); // left-top, left-bottom, right-top\n            indices.push(last + 1, last + 2, last + 3); // right-top, left-bottom, right-bottom\n        }\n\n        const geometry = new THREE.BufferGeometry();\n        geometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3));\n        if (colors.length > 0) {\n            geometry.setAttribute('color', new THREE.Float32BufferAttribute(colors, 3));\n        }\n        geometry.setIndex(indices);\n        geometry.computeVertexNormals();\n\n        // Mark position attribute as dynamic for resnapping\n        geometry.getAttribute('position').setUsage(THREE.DynamicDrawUsage);\n\n        return { geometry, densified, halfW, vertexLatLons };\n    }\n\n    /**\n     * Build area geometry (filled polygon) with vertex lat/lon for terrain draping\n     * Geometry is built in local XY plane\n     */\n    _buildAreaGeometry(localPoints, tags) {\n        if (localPoints.length < 3) return null;\n\n        // First, densify the polygon edges to get more vertices for terrain conformance\n        const densifiedPoints = this._densifyPolygon(localPoints, this.roadStepM);\n\n        // Create shape from densified points\n        const shape = new THREE.Shape();\n        for (let i = 0; i < densifiedPoints.length; i++) {\n            const pt = densifiedPoints[i];\n            if (i === 0) shape.moveTo(pt.x, pt.y);\n            else shape.lineTo(pt.x, pt.y);\n        }\n        shape.autoClose = true;\n\n        // Create geometry in XY plane (Z is up in our local frame)\n        const geometry = new THREE.ShapeGeometry(shape);\n\n        // Extract vertex positions and build lat/lon mapping\n        // ShapeGeometry vertices are in the same XY plane\n        const posAttr = geometry.getAttribute('position');\n        const vertexLatLons = [];\n\n        // Build a lookup from local XY to lat/lon from densified points\n        const xyToLatLon = new Map();\n        for (const pt of densifiedPoints) {\n            // Use rounded key for floating point matching\n            const key = `${pt.x.toFixed(4)},${pt.y.toFixed(4)}`;\n            xyToLatLon.set(key, { lat: pt.lat, lon: pt.lon });\n        }\n\n        // For each vertex in the geometry, find its lat/lon\n        for (let i = 0; i < posAttr.count; i++) {\n            const x = posAttr.getX(i);\n            const y = posAttr.getY(i);\n            const key = `${x.toFixed(4)},${y.toFixed(4)}`;\n            const latLon = xyToLatLon.get(key);\n            if (latLon) {\n                vertexLatLons.push({ lat: latLon.lat, lon: latLon.lon });\n            } else {\n                // Interpolate lat/lon for internal vertices created by triangulation\n                // Find the original polygon's centroid lat/lon as fallback\n                // This happens for vertices inside the polygon from triangulation\n                const centerLat = localPoints.reduce((s, p) => s + p.lat, 0) / localPoints.length;\n                const centerLon = localPoints.reduce((s, p) => s + p.lon, 0) / localPoints.length;\n                const mPerDegLat = metersPerDegLat(THREE.MathUtils.degToRad(centerLat));\n                const mPerDegLon = metersPerDegLon(THREE.MathUtils.degToRad(centerLat));\n                // Convert local x,y back to lat/lon offset from center\n                const lat = centerLat + y / mPerDegLat;\n                const lon = centerLon + x / mPerDegLon;\n                vertexLatLons.push({ lat, lon });\n            }\n        }\n\n        // Mark position attribute as dynamic for resnapping\n        posAttr.setUsage(THREE.DynamicDrawUsage);\n\n        return { geometry, vertexLatLons, densifiedPoints };\n    }\n\n    _buildVertexDirs(vertexLatLons) {\n        if (!vertexLatLons?.length) return null;\n        const dirs = new Float32Array(vertexLatLons.length * 3);\n        for (let i = 0; i < vertexLatLons.length; i++) {\n            const latLon = vertexLatLons[i];\n            const dir = latLonToLocalDir(latLon.lat, latLon.lon);\n            const offset = i * 3;\n            dirs[offset] = dir.x;\n            dirs[offset + 1] = dir.y;\n            dirs[offset + 2] = dir.z;\n        }\n        return dirs;\n    }\n\n    /**\n     * Densify a polygon by adding intermediate points along edges\n     */\n    _densifyPolygon(points, stepM) {\n        if (points.length < 3) return points;\n\n        const result = [];\n        for (let i = 0; i < points.length; i++) {\n            const p0 = points[i];\n            const p1 = points[(i + 1) % points.length];\n\n            result.push({ ...p0 });\n\n            const dx = p1.x - p0.x;\n            const dy = p1.y - p0.y;\n            const dist = Math.sqrt(dx * dx + dy * dy);\n\n            if (dist > stepM) {\n                const steps = Math.ceil(dist / stepM);\n                for (let s = 1; s < steps; s++) {\n                    const t = s / steps;\n                    result.push({\n                        x: p0.x + dx * t,\n                        y: p0.y + dy * t,\n                        lat: p0.lat + (p1.lat - p0.lat) * t,\n                        lon: p0.lon + (p1.lon - p0.lon) * t\n                    });\n                }\n            }\n        }\n\n        return result;\n    }\n\n    /**\n     * Densify a line by adding intermediate points\n     */\n    _densifyLine(points, stepM) {\n        if (points.length < 2) return points;\n\n        const result = [];\n        for (let i = 0; i < points.length - 1; i++) {\n            const p0 = points[i];\n            const p1 = points[i + 1];\n\n            result.push({ ...p0 });\n\n            const dx = p1.x - p0.x;\n            const dy = p1.y - p0.y;\n            const dist = Math.sqrt(dx * dx + dy * dy);\n\n            if (dist > stepM) {\n                const steps = Math.ceil(dist / stepM);\n                for (let s = 1; s < steps; s++) {\n                    const t = s / steps;\n                    result.push({\n                        x: p0.x + dx * t,\n                        y: p0.y + dy * t,\n                        lat: p0.lat + (p1.lat - p0.lat) * t,\n                        lon: p0.lon + (p1.lon - p0.lon) * t\n                    });\n                }\n            }\n        }\n        result.push({ ...points[points.length - 1] });\n\n        return result;\n    }\n\n    /**\n     * Drape geometry vertices to terrain by sampling elevation at each vertex lat/lon.\n     * This makes roads/areas conform to the underlying terrain topology.\n     * Uses raycast for accuracy, limited to maxVertices per call to avoid freezing.\n     *\n     * For volumetric ribbons (roads/railways/waterways), vertices come in groups of 4:\n     * [left-top, right-top, left-bottom, right-bottom]\n     * Top vertices get terrain Z + thickness, bottom vertices get terrain Z.\n     */\n    _drapeToTerrain(entry, maxVertices = 10, worldQuat = null) {\n        if (!entry?.mesh?.geometry) return 0;\n        if (entry.kind === 'bridge') return 0; // Bridges stay flat above terrain\n\n        const geometry = entry.mesh.geometry;\n        const posAttr = geometry.getAttribute('position');\n        if (!posAttr) return 0;\n\n        const vertexLatLons = entry.vertexLatLons || [];\n        const vertexDirs = entry.vertexDirs;\n        const vertexCount = posAttr.count;\n\n        if (!vertexCount || (!vertexLatLons.length && !vertexDirs)) {\n            return 0;\n        }\n\n        if (vertexDirs && vertexDirs.length !== vertexCount * 3 && vertexLatLons.length !== vertexCount) {\n            return 0;\n        }\n\n        const groupPos = entry.group?.position;\n        if (!groupPos) return 0;\n        const normal = entry.terrainNormal?.isVector3\n            ? this._tmpNormal.copy(entry.terrainNormal)\n            : this._tmpNormal.copy(entry.dir || new THREE.Vector3(0, 1, 0));\n        if (normal.lengthSq() < 1e-8) return 0;\n        normal.normalize();\n\n        // Surface offset and ribbon thickness\n        // For volumetric ribbons: bottom is at terrain, top is at terrain + thickness + offset\n        // For flat areas: at terrain + offset\n        const surfaceOffset = Math.max(this.surfaceOffsetM, 0);\n        const thickness = this.ribbonThicknessM;\n\n        // Check if this is a volumetric ribbon (4 vertices per segment point).\n        // Utility layers are built through _buildRibbonGeometry too, so they\n        // must keep top/bottom vertices instead of being flattened as areas.\n        const isVolumetricRibbon = INFRA_RIBBON_KINDS.has(entry.kind) && entry.kind !== 'bridge';\n\n        // Track where we left off\n        const startIdx = entry._drapeIndex || 0;\n        const endIdx = Math.min(startIdx + maxVertices, vertexCount);\n\n        // Sample terrain at each vertex using raycast\n        let changed = false;\n        for (let i = startIdx; i < endIdx; i++) {\n            let vertexDir = null;\n            if (vertexDirs && vertexDirs.length === vertexCount * 3) {\n                const offset = i * 3;\n                this._tmpVec.set(vertexDirs[offset], vertexDirs[offset + 1], vertexDirs[offset + 2]);\n                vertexDir = this._tmpVec;\n            } else {\n                const latLon = vertexLatLons[i];\n                if (!latLon) continue;\n                vertexDir = latLonToLocalDir(latLon.lat, latLon.lon);\n            }\n\n            // Sample terrain at this vertex using fast sampling\n            const vertexRadius = this._sampleSurfaceRadiusLocalDir(vertexDir, worldQuat);\n            if (!Number.isFinite(vertexRadius)) continue;\n\n            const worldPos = this._tmpVec2.copy(vertexDir).multiplyScalar(vertexRadius);\n            const terrainZ = this._tmpSurfaceVec.copy(worldPos).sub(groupPos).dot(normal);\n\n            let newZ;\n            if (isVolumetricRibbon) {\n                // Vertex index within segment: 0=left-top, 1=right-top, 2=left-bottom, 3=right-bottom\n                const vertexInSegment = i % 4;\n                const isTopVertex = vertexInSegment < 2;\n                // Bottom vertices flush at terrain + offset, top vertices raised by thickness\n                const baseZ = terrainZ + surfaceOffset;\n                newZ = isTopVertex ? baseZ + thickness : baseZ;\n            } else {\n                // Flat geometry (areas) - at terrain + offset\n                newZ = terrainZ + surfaceOffset;\n            }\n\n            const oldZ = posAttr.getZ(i);\n\n            if (Math.abs(newZ - oldZ) > 0.01) {\n                posAttr.setZ(i, newZ);\n                changed = true;\n            }\n        }\n\n        // Update drape index for next call (wrap around)\n        entry._drapeIndex = endIdx >= vertexCount ? 0 : endIdx;\n        if (entry._drapeIndex === 0) {\n            entry._drapeDirty = false;\n            if (entry.alignState === 'coarse') {\n                entry.alignState = 'draped';\n            }\n            if (entry.alignStamp &&\n                (this.alignFreezeFrames <= 0 || entry.alignStableFrames >= this.alignFreezeFrames)) {\n                entry.alignState = 'frozen';\n            }\n        }\n\n        // Update geometry if changed\n        if (changed) {\n            posAttr.needsUpdate = true;\n            if (entry._drapeIndex === 0) {\n                geometry.computeBoundingSphere();\n            }\n        }\n\n        return endIdx - startIdx;\n    }\n\n    /**\n     * Sample surface radius using raycast (accurate but expensive - use sparingly)\n     */\n    _sampleSurfaceRadiusRaycast(localDir) {\n        if (!this.triTree) return ellipsoidRadiusForLocalDir(localDir);\n\n        const dir = this._tmpVec.copy(localDir).normalize();\n\n        // Transform to world space if needed\n        const worldQuat = this.triTree.group?.getWorldQuaternion(this._tmpQuat);\n        if (worldQuat) {\n            dir.applyQuaternion(worldQuat);\n        }\n        dir.normalize();\n\n        // Prefer surfaceController — raycasts photoreal tiles first.\n        if (this.surfaceController\n            && typeof this.surfaceController.sampleTerrainRadiusForDir === 'function') {\n            const r = this.surfaceController.sampleTerrainRadiusForDir(dir, {\n                mutateCache: false,\n                requireFreshPhotoHit: true\n            });\n            if (Number.isFinite(r) && r > 0) {\n                return r;\n            }\n            if (this._hasPhotorealSurface()) return null;\n        }\n\n        // Use raycast for accurate surface position\n        if (typeof this.triTree.sampleTerrainRadiusForDir === 'function') {\n            const r = this.triTree.sampleTerrainRadiusForDir(dir);\n            if (Number.isFinite(r) && r > 0) {\n                return r;\n            }\n        }\n\n        // Fallback to vertex sampling\n        if (typeof this.triTree.getSurfaceRadiusAtDir === 'function') {\n            const r = this.triTree.getSurfaceRadiusAtDir(dir);\n            if (Number.isFinite(r) && r > 0) {\n                return r;\n            }\n        }\n\n        return ellipsoidRadiusForLocalDir(localDir);\n    }\n\n    _sampleTerrainRadiusForDir(localDir, allowRaycast = true, worldQuat = null) {\n        if (!localDir) {\n            return { radius: this.planetRadius, hasData: false };\n        }\n        const ellipsoidR = ellipsoidRadiusForLocalDir(localDir);\n        if (!this.triTree) {\n            return { radius: ellipsoidR, hasData: false };\n        }\n\n        const dir = this._tmpVec.copy(localDir).normalize();\n        const quat = worldQuat || this.triTree.group?.getWorldQuaternion?.(this._tmpWorldQuat);\n        if (quat) {\n            dir.applyQuaternion(quat);\n        }\n        dir.normalize();\n\n        // Prefer the SurfaceController's sampler when wired up — it\n        // raycasts photorealistic tiles first (the actual rendered\n        // surface) and falls back to triTree elevation. Without this,\n        // ribbons over photoreal areas snap to the procedural triTree\n        // height instead of the photoreal tile height, so power /\n        // comms lines float in mid-air over cities.\n        // Passive consumers must require a fresh hit at their own coordinate.\n        // The controller's underfoot cache belongs to the camera and would\n        // otherwise make unrelated infrastructure rise/fall together.\n        if (allowRaycast\n            && this.surfaceController\n            && typeof this.surfaceController.sampleTerrainRadiusForDir === 'function') {\n            const r = this.surfaceController.sampleTerrainRadiusForDir(dir, {\n                mutateCache: false,\n                requireFreshPhotoHit: true\n            });\n            if (Number.isFinite(r) && r > 0) {\n                return { radius: r, hasData: true };\n            }\n            if (this._hasPhotorealSurface()) {\n                return { radius: ellipsoidR, hasData: false };\n            }\n        }\n\n        const leaf = this.triTree?.findLeafTileForWorldDir?.(dir);\n        if (!leaf?.elevationHasData) {\n            return { radius: ellipsoidR, hasData: false };\n        }\n\n        let radius = null;\n        if (allowRaycast && typeof this.triTree.sampleTerrainRadiusForDir === 'function') {\n            radius = this.triTree.sampleTerrainRadiusForDir(dir);\n        }\n        if (!Number.isFinite(radius) || radius <= 0) {\n            radius = this.triTree.getSurfaceRadiusAtDir?.(dir);\n        }\n        if (!Number.isFinite(radius) || radius <= 0) {\n            return { radius: ellipsoidR, hasData: false };\n        }\n\n        return { radius, hasData: true };\n    }\n\n    _sampleSurfaceRadiusLocalDir(localDir, worldQuat = null) {\n        if (!this.triTree) return ellipsoidRadiusForLocalDir(localDir);\n\n        const dir = this._tmpVec2.copy(localDir).normalize();\n\n        const quat = worldQuat || this.triTree.group?.getWorldQuaternion(this._tmpQuat);\n        if (quat) {\n            dir.applyQuaternion(quat);\n        }\n        dir.normalize();\n\n        if (this.surfaceController\n            && typeof this.surfaceController.sampleTerrainRadiusForDir === 'function') {\n            const r = this.surfaceController.sampleTerrainRadiusForDir(dir, {\n                mutateCache: false,\n                requireFreshPhotoHit: true\n            });\n            if (Number.isFinite(r) && r > 0) {\n                return r;\n            }\n            if (this._hasPhotorealSurface()) return null;\n        }\n\n        const leaf = this.triTree?.findLeafTileForWorldDir?.(dir);\n        const hasElevation = leaf?.elevationHasData === true;\n\n        if (hasElevation && typeof this.triTree.sampleTerrainRadiusForDir === 'function') {\n            const r = this.triTree.sampleTerrainRadiusForDir(dir);\n            if (Number.isFinite(r) && r > 0) {\n                return r;\n            }\n        }\n\n        if (hasElevation && typeof this.triTree.getSurfaceRadiusAtDir === 'function') {\n            const r = this.triTree.getSurfaceRadiusAtDir(dir);\n            if (Number.isFinite(r) && r > 0) {\n                return r;\n            }\n        }\n\n        return ellipsoidRadiusForLocalDir(localDir);\n    }\n\n    /**\n     * Sample surface radius at a direction using triTree (vertex-based only for performance)\n     */\n    _sampleSurfaceRadius(localDir) {\n        if (!this.triTree) return ellipsoidRadiusForLocalDir(localDir);\n\n        const dir = this._tmpVec.copy(localDir).normalize();\n\n        // Transform to world space if needed\n        const worldQuat = this.triTree.group?.getWorldQuaternion(this._tmpQuat);\n        if (worldQuat) {\n            dir.applyQuaternion(worldQuat);\n        }\n        dir.normalize();\n\n        // Use vertex sampling only (fast) - no raycast\n        if (typeof this.triTree.getSurfaceRadiusAtDir === 'function') {\n            const r = this.triTree.getSurfaceRadiusAtDir(dir);\n            if (Number.isFinite(r) && r > 0) {\n                return r;\n            }\n        }\n\n        return ellipsoidRadiusForLocalDir(localDir);\n    }\n\n    _applyTerrainFrame(entry, centerSample = null, allowRaycast = true) {\n        if (!entry?.center || !entry?.dir || !entry?.baseEast || !entry?.baseNorth) return false;\n        const centerInfo = centerSample || this._sampleTerrainRadiusForDir(entry.dir, allowRaycast);\n        if (!centerInfo?.hasData || !Number.isFinite(centerInfo.radius)) return false;\n\n        const latRad = THREE.MathUtils.degToRad(entry.center.lat);\n        const metersLat = Math.max(0.0001, metersPerDegLat(latRad));\n        const metersLon = Math.max(0.0001, metersPerDegLon(latRad));\n        const bounds = entry.bounds || {};\n        const span = Math.max(\n            8,\n            Math.min(40, Math.max(bounds.width || 0, bounds.depth || 0) * 0.25 || 12)\n        );\n        const dLat = span / metersLat;\n        const dLon = span / metersLon;\n\n        const worldQuat = this.triTree?.group?.getWorldQuaternion?.(this._tmpWorldQuat) || null;\n        const eastDir = latLonToLocalDir(entry.center.lat, entry.center.lon + dLon).normalize();\n        const northDir = latLonToLocalDir(entry.center.lat + dLat, entry.center.lon).normalize();\n\n        const eastSample = this._sampleTerrainRadiusForDir(eastDir, allowRaycast, worldQuat);\n        const northSample = this._sampleTerrainRadiusForDir(northDir, allowRaycast, worldQuat);\n\n        if (!eastSample.hasData || !northSample.hasData) return false;\n\n        const centerPos = this._tmpTerrainA.copy(entry.dir).multiplyScalar(centerInfo.radius);\n        const eastPos = this._tmpTerrainB.copy(eastDir).multiplyScalar(eastSample.radius);\n        const northPos = this._tmpTerrainC.copy(northDir).multiplyScalar(northSample.radius);\n\n        const vEast = eastPos.sub(centerPos);\n        const vNorth = northPos.sub(centerPos);\n        if (vEast.lengthSq() < 1e-6 || vNorth.lengthSq() < 1e-6) return false;\n\n        const normal = vEast.cross(vNorth).normalize();\n        if (normal.dot(entry.dir) < 0) {\n            normal.negate();\n        }\n\n        let east = this._tmpVec3.copy(entry.baseEast);\n        east.addScaledVector(normal, -east.dot(normal));\n        if (east.lengthSq() < 1e-6) {\n            east.copy(vEast).normalize();\n        } else {\n            east.normalize();\n        }\n        const north = this._tmpSurfaceVec.copy(normal).cross(east).normalize();\n\n        this._tmpMatrix.makeBasis(east, north, normal);\n        const quat = this._tmpQuat.setFromRotationMatrix(this._tmpMatrix);\n        entry.group.quaternion.copy(quat);\n        entry.terrainNormal = entry.terrainNormal || new THREE.Vector3();\n        entry.terrainNormal.copy(normal);\n\n        let lift = 0;\n        if (entry.kind === 'bridge') {\n            lift = this.surfaceOffsetM + this.bridgeHeightM;\n        }\n        entry.group.position.copy(centerPos).addScaledVector(normal, lift);\n        entry.surfaceRadius = centerInfo.radius;\n\n        if (entry.group?.userData) {\n            if (entry.group.userData.surfaceDir?.isVector3) {\n                entry.group.userData.surfaceDir.copy(normal);\n            } else {\n                entry.group.userData.surfaceDir = normal.clone();\n            }\n        }\n\n        return true;\n    }\n\n    _drapeBatch(deadline = null) {\n        if (this._entries.length === 0 || this.drapeBudget <= 0) return;\n        if (this._drapeMaxVerticesPerSlice <= 0 || this._drapeSliceMs <= 0) return;\n        if (this._processingPaused) return;\n        this._perfStart('cpu.infrastructure.drape');\n        try {\n            const sliceStart = nowMs();\n            let budget = Math.min(this.drapeBudget, this._drapeMaxVerticesPerSlice);\n            let iterations = 0;\n            const total = this._entries.length;\n            const worldQuat = this.triTree?.group?.getWorldQuaternion(this._tmpQuat);\n\n            while (budget > 0 && iterations < total) {\n                const entry = this._entries[this._drapeIndex % total];\n                this._drapeIndex = (this._drapeIndex + 1) % total;\n                iterations += 1;\n                if (!entry?._drapeDirty || !entry.vertexLatLons?.length) continue;\n                const entryBudget = Math.min(budget, this._drapeMaxVerticesPerEntry || budget);\n                const used = this._drapeToTerrain(entry, entryBudget, worldQuat);\n                if (Number.isFinite(used)) {\n                    budget -= used;\n                } else {\n                    budget -= 1;\n                }\n                if (deadline && typeof deadline.timeRemaining === 'function' &&\n                    deadline.timeRemaining() <= 0) {\n                    break;\n                }\n                if ((nowMs() - sliceStart) >= this._drapeSliceMs) {\n                    break;\n                }\n            }\n        } finally {\n            this._perfEnd('cpu.infrastructure.drape');\n        }\n    }\n\n    /**\n     * Resnap a single entry to terrain - updates group position and drapes vertices\n     */\n    _alignEntry(entry, { force = false, reason = '' } = {}) {\n        if (!entry?.group || !entry?.dir) return false;\n        if (entry.layerType && this.layers?.[entry.layerType] === false) return false;\n\n        const stamp = this._getEntryElevationStamp(entry);\n        if (!force && entry.alignState === 'frozen' && !entry._drapeDirty && stamp && stamp === entry.alignStamp) {\n            return false;\n        }\n\n        const prevStamp = entry.alignStamp;\n        const prevRadius = entry.surfaceRadius;\n        const prevNormal = entry.terrainNormal ? this._tmpNormal.copy(entry.terrainNormal) : null;\n        const hasElevation = this._entryHasElevation(entry);\n        const hasPhotorealSurface = this._hasPhotorealSurface();\n\n        if (!hasElevation && !hasPhotorealSurface) {\n            if (!force && entry.alignState === 'provisional' && stamp && stamp === entry.alignStamp) {\n                return false;\n            }\n            const fallbackRadius = this._sampleSurfaceRadiusLocalDir(entry.dir);\n            if (!Number.isFinite(fallbackRadius)) return false;\n            const lift = entry.kind === 'bridge' ? (this.surfaceOffsetM + this.bridgeHeightM) : 0;\n            entry.group.position.copy(entry.dir).multiplyScalar(fallbackRadius + lift);\n            entry.surfaceRadius = fallbackRadius;\n            entry.terrainNormal = entry.terrainNormal || new THREE.Vector3();\n            entry.terrainNormal.copy(entry.dir);\n            if (entry.group?.userData) {\n                if (entry.group.userData.surfaceDir?.isVector3) {\n                    entry.group.userData.surfaceDir.copy(entry.dir);\n                } else {\n                    entry.group.userData.surfaceDir = entry.dir.clone();\n                }\n            }\n            entry.alignState = 'provisional';\n            entry.alignStamp = stamp;\n            entry.alignStableFrames = 0;\n            entry.alignAttempts = (entry.alignAttempts || 0) + 1;\n            entry.alignLastAlignedMs = nowMs();\n            return true;\n        }\n\n        const centerSample = this._sampleTerrainRadiusForDir(entry.dir, true);\n        const hasCenter = centerSample?.hasData && Number.isFinite(centerSample.radius);\n        // A parent/child replacement can briefly leave no rendered hit at the\n        // feature coordinate. Keep the last mated frame through that gap.\n        if (hasPhotorealSurface && !hasCenter) return false;\n        const applied = hasCenter ? this._applyTerrainFrame(entry, centerSample, true) : false;\n\n        if (!applied) {\n            const fallbackRadius = hasCenter ? centerSample.radius : this._sampleSurfaceRadiusLocalDir(entry.dir);\n            if (!Number.isFinite(fallbackRadius)) return false;\n            const lift = entry.kind === 'bridge' ? (this.surfaceOffsetM + this.bridgeHeightM) : 0;\n            entry.group.position.copy(entry.dir).multiplyScalar(fallbackRadius + lift);\n            entry.surfaceRadius = fallbackRadius;\n            entry.terrainNormal = entry.terrainNormal || new THREE.Vector3();\n            entry.terrainNormal.copy(entry.dir);\n            if (entry.group?.userData) {\n                if (entry.group.userData.surfaceDir?.isVector3) {\n                    entry.group.userData.surfaceDir.copy(entry.dir);\n                } else {\n                    entry.group.userData.surfaceDir = entry.dir.clone();\n                }\n            }\n        }\n\n        const delta = Number.isFinite(prevRadius) ? Math.abs(prevRadius - entry.surfaceRadius) : Infinity;\n        const normalChanged = prevNormal && entry.terrainNormal\n            ? prevNormal.dot(entry.terrainNormal) < 0.999\n            : false;\n\n        const stampChanged = stamp !== prevStamp;\n        if (stampChanged) {\n            entry.alignStableFrames = 0;\n        }\n        const stable = delta <= this.alignToleranceM && !normalChanged;\n        entry.alignStableFrames = stable ? (entry.alignStableFrames + 1) : 0;\n\n        if ((delta > this.alignToleranceM || normalChanged) &&\n            entry.vertexLatLons?.length &&\n            entry.kind !== 'bridge') {\n            entry._drapeDirty = true;\n            entry._drapeIndex = 0;\n            this._scheduleDrapeWork();\n        }\n\n        entry.alignState = entry._drapeDirty ? 'coarse' : 'draped';\n        entry.alignStamp = stamp;\n        entry.alignAttempts = (entry.alignAttempts || 0) + 1;\n        entry.alignLastAlignedMs = nowMs();\n\n        if (!entry._drapeDirty &&\n            (this.alignFreezeFrames <= 0 || entry.alignStableFrames >= this.alignFreezeFrames) &&\n            entry.alignStamp) {\n            entry.alignState = 'frozen';\n        }\n\n        return true;\n    }\n\n    _resnapEntry(entry) {\n        return this._alignEntry(entry, { force: true, reason: 'legacy' });\n    }\n\n    _applyColorsToEntries() {\n        const roadColor = new THREE.Color(this.colors.roads);\n        for (const entry of this._entries) {\n            if (!entry?.mesh) continue;\n            if (entry.kind === 'road') {\n                const colorAttr = entry.mesh.geometry?.getAttribute('color');\n                if (!colorAttr) continue;\n                for (let i = 0; i < colorAttr.count; i++) {\n                    colorAttr.setXYZ(i, roadColor.r, roadColor.g, roadColor.b);\n                }\n                colorAttr.needsUpdate = true;\n                continue;\n            }\n\n            let nextHex = null;\n            if (entry.kind === 'bridge') nextHex = this.colors.bridges;\n            else if (entry.kind === 'waterway') nextHex = this.colors.waterways;\n            else if (entry.kind === 'railway') nextHex = this.colors.railways;\n            else if (entry.kind === 'area') nextHex = this.colors.areas;\n            if (nextHex !== null && entry.mesh.material?.color) {\n                entry.mesh.material.color.setHex(nextHex);\n                entry.mesh.material.needsUpdate = true;\n            }\n        }\n    }\n\n    /**\n     * Get configuration object for serialization\n     */\n    getConfig() {\n        return {\n            enabled: this.enabled,\n            radiusM: this.radiusM,\n            refreshDistanceM: this.refreshDistanceM,\n            surfaceOffsetM: this.surfaceOffsetM,\n            roadWidthScale: this.roadWidthScale,\n            roadStepM: this.roadStepM,\n            bridgeHeightM: this.bridgeHeightM,\n            ribbonThicknessM: this.ribbonThicknessM,\n            resnapIntervalMs: this.resnapIntervalMs,\n            resnapBudget: this.resnapBudget,\n            drapeBudget: this.drapeBudget,\n            tileDrivenResnap: this.tileDrivenResnap,\n            alignFreezeFrames: this.alignFreezeFrames,\n            alignToleranceM: this.alignToleranceM,\n            alignSampleStepM: this.alignSampleStepM,\n            alignMaxSamples: this.alignMaxSamples,\n            pauseWhenFar: this.pauseWhenFar,\n            pauseDistanceM: this.pauseDistanceM,\n            pauseDistanceMultiplier: this.pauseDistanceMultiplier,\n            motionEnabled: this.motionEnabled,\n            motionMinSpeedMps: this.motionMinSpeedMps,\n            motionSpeedRefMps: this.motionSpeedRefMps,\n            motionAheadFactor: this.motionAheadFactor,\n            motionBehindFactor: this.motionBehindFactor,\n            motionQueryBias: this.motionQueryBias,\n            motionRetentionFactor: this.motionRetentionFactor,\n            layers: { ...this.layers },\n            colors: { ...this.colors },\n            paint: {\n                enabled: this.paintEnabled,\n                resolution: this.paintResolution,\n                lineWidthPx: this.paintLineWidthPx,\n                opacity: this.paintOpacity,\n                repaintOnLod: this.paintRepaintOnLod,\n                budget: this.paintBudget\n            }\n        };\n    }\n\n    /**\n     * Apply configuration\n     */\n    setTerrainMode(mode) {\n        if (this._terrainMode === mode) return;\n        this._terrainMode = mode;\n        this.applyConfig({ enabled: this._requestedEnabled });\n    }\n\n    applyConfig(config = {}) {\n        const prevEnabled = this.enabled;\n        const prevRadius = this.radiusM;\n        const prevSurfaceOffset = this.surfaceOffsetM;\n        const prevRoadWidthScale = this.roadWidthScale;\n        const prevRoadStepM = this.roadStepM;\n        const prevBridgeHeightM = this.bridgeHeightM;\n        const prevRibbonThicknessM = this.ribbonThicknessM;\n        const prevAlignFreezeFrames = this.alignFreezeFrames;\n        const prevAlignToleranceM = this.alignToleranceM;\n        const prevAlignSampleStepM = this.alignSampleStepM;\n        const prevAlignMaxSamples = this.alignMaxSamples;\n        const prevDrapeBudget = this.drapeBudget;\n        const prevMotionEnabled = this.motionEnabled;\n        const prevMotionAhead = this.motionAheadFactor;\n        const prevMotionBehind = this.motionBehindFactor;\n        const prevMotionBias = this.motionQueryBias;\n        const prevPauseWhenFar = this.pauseWhenFar;\n        const prevPauseDistanceM = this.pauseDistanceM;\n        const prevPauseDistanceMultiplier = this.pauseDistanceMultiplier;\n        const prevPaintEnabled = this.paintEnabled;\n        const prevPaintResolution = this.paintResolution;\n        const prevPaintOpacity = this.paintOpacity;\n        const prevPaintLineWidthPx = this.paintLineWidthPx;\n        const prevPaintRepaintOnLod = this.paintRepaintOnLod;\n        const prevPaintBudget = this.paintBudget;\n        const prevColors = { ...this.colors };\n        if (typeof config.enabled === 'boolean') {\n            this._requestedEnabled = config.enabled;\n            this.enabled = this._terrainMode === 'tritree' && this._requestedEnabled;\n            if (!this.enabled) {\n                this.group.visible = false;\n                this.clear();\n                this._refreshQueued = false;\n                if (this._retryTimer) {\n                    clearTimeout(this._retryTimer);\n                    this._retryTimer = null;\n                }\n            }\n        }\n        if (Number.isFinite(config.radiusM)) {\n            this.radiusM = config.radiusM;\n        }\n        if (Number.isFinite(config.refreshDistanceM)) {\n            this.refreshDistanceM = config.refreshDistanceM;\n        }\n        if (Number.isFinite(config.surfaceOffsetM)) {\n            this.surfaceOffsetM = config.surfaceOffsetM;\n        }\n        if (Number.isFinite(config.roadWidthScale)) {\n            this.roadWidthScale = config.roadWidthScale;\n        }\n        if (Number.isFinite(config.roadStepM)) {\n            this.roadStepM = config.roadStepM;\n        }\n        if (Number.isFinite(config.bridgeHeightM)) {\n            this.bridgeHeightM = config.bridgeHeightM;\n        }\n        if (Number.isFinite(config.ribbonThicknessM)) {\n            this.ribbonThicknessM = config.ribbonThicknessM;\n        }\n        if (Number.isFinite(config.alignFreezeFrames)) {\n            this.alignFreezeFrames = Math.max(0, Math.floor(config.alignFreezeFrames));\n        }\n        if (Number.isFinite(config.alignToleranceM)) {\n            this.alignToleranceM = Math.max(0, config.alignToleranceM);\n        }\n        if (Number.isFinite(config.alignSampleStepM)) {\n            this.alignSampleStepM = Math.max(1, config.alignSampleStepM);\n        }\n        if (Number.isFinite(config.alignMaxSamples)) {\n            this.alignMaxSamples = Math.max(4, Math.floor(config.alignMaxSamples));\n        }\n        if (typeof config.pauseWhenFar === 'boolean') {\n            this.pauseWhenFar = config.pauseWhenFar;\n        }\n        if (config.pauseDistanceM === null) {\n            this.pauseDistanceM = null;\n        } else if (Number.isFinite(config.pauseDistanceM)) {\n            this.pauseDistanceM = config.pauseDistanceM > 0 ? config.pauseDistanceM : null;\n        }\n        if (Number.isFinite(config.pauseDistanceMultiplier)) {\n            this.pauseDistanceMultiplier = Math.max(0.1, config.pauseDistanceMultiplier);\n        }\n        if (Number.isFinite(config.resnapIntervalMs)) {\n            this.resnapIntervalMs = config.resnapIntervalMs;\n        }\n        if (Number.isFinite(config.resnapBudget)) {\n            this.resnapBudget = config.resnapBudget;\n        }\n        if (Number.isFinite(config.drapeBudget)) {\n            this.drapeBudget = config.drapeBudget;\n        }\n        if (prevDrapeBudget !== this.drapeBudget) {\n            this._updateDrapeScheduler();\n            if (this.drapeBudget > 0) {\n                this._scheduleDrapeWork();\n            }\n        }\n        if (typeof config.tileDrivenResnap === 'boolean') {\n            this.tileDrivenResnap = config.tileDrivenResnap;\n        }\n        if (typeof config.motionEnabled === 'boolean') {\n            this.motionEnabled = config.motionEnabled;\n        }\n        if (Number.isFinite(config.motionMinSpeedMps)) {\n            this.motionMinSpeedMps = config.motionMinSpeedMps;\n        }\n        if (Number.isFinite(config.motionSpeedRefMps)) {\n            this.motionSpeedRefMps = config.motionSpeedRefMps;\n        }\n        if (Number.isFinite(config.motionAheadFactor)) {\n            this.motionAheadFactor = config.motionAheadFactor;\n        }\n        if (Number.isFinite(config.motionBehindFactor)) {\n            this.motionBehindFactor = config.motionBehindFactor;\n        }\n        if (Number.isFinite(config.motionQueryBias)) {\n            this.motionQueryBias = config.motionQueryBias;\n        }\n        if (Number.isFinite(config.motionRetentionFactor)) {\n            this.motionRetentionFactor = config.motionRetentionFactor;\n        }\n        if (config.paint && typeof config.paint === 'object') {\n            if (typeof config.paint.enabled === 'boolean') {\n                this.paintEnabled = config.paint.enabled;\n            }\n            if (Number.isFinite(config.paint.resolution)) {\n                this.paintResolution = Math.max(64, Math.min(2048, Math.floor(config.paint.resolution)));\n            }\n            if (Number.isFinite(config.paint.lineWidthPx)) {\n                this.paintLineWidthPx = Math.max(0.5, Math.min(20, config.paint.lineWidthPx));\n            }\n            if (Number.isFinite(config.paint.opacity)) {\n                this.paintOpacity = Math.max(0, Math.min(1, config.paint.opacity));\n            }\n            if (typeof config.paint.repaintOnLod === 'boolean') {\n                this.paintRepaintOnLod = config.paint.repaintOnLod;\n            }\n            if (Number.isFinite(config.paint.budget)) {\n                this.paintBudget = Math.max(1, Math.min(20, Math.floor(config.paint.budget)));\n            }\n        }\n        if (config.colors && typeof config.colors === 'object') {\n            const resolveColor = (value, fallback) => {\n                if (typeof value === 'number' && Number.isFinite(value)) return value;\n                if (typeof value === 'string') {\n                    const clean = value.trim();\n                    if (clean.startsWith('#')) {\n                        const parsed = Number.parseInt(clean.slice(1), 16);\n                        if (Number.isFinite(parsed)) return parsed;\n                    }\n                }\n                return fallback;\n            };\n            this.colors = {\n                ...this.colors,\n                roads: resolveColor(config.colors.roads, this.colors.roads),\n                bridges: resolveColor(config.colors.bridges, this.colors.bridges),\n                waterways: resolveColor(config.colors.waterways, this.colors.waterways),\n                areas: resolveColor(config.colors.areas, this.colors.areas),\n                railways: resolveColor(config.colors.railways, this.colors.railways),\n                power: resolveColor(config.colors.power, this.colors.power),\n                telecoms: resolveColor(config.colors.telecoms, this.colors.telecoms),\n                petroleum: resolveColor(config.colors.petroleum, this.colors.petroleum),\n                water: resolveColor(config.colors.water, this.colors.water),\n                internet: resolveColor(config.colors.internet, this.colors.internet),\n                solar: resolveColor(config.colors.solar, this.colors.solar)\n            };\n            this._bridgeMaterial.color.setHex(this.colors.bridges);\n            this._waterwayMaterial.color.setHex(this.colors.waterways);\n            this._areaMaterial.color.setHex(this.colors.areas);\n            this._railwayMaterial.color.setHex(this.colors.railways);\n            for (const [layerId, material] of Object.entries(this._utilityMaterials || {})) {\n                if (material?.color && this.colors[layerId]) material.color.setHex(this.colors[layerId]);\n            }\n        }\n\n        const alignConfigChanged = (\n            prevAlignFreezeFrames !== this.alignFreezeFrames ||\n            prevAlignToleranceM !== this.alignToleranceM ||\n            prevAlignSampleStepM !== this.alignSampleStepM ||\n            prevAlignMaxSamples !== this.alignMaxSamples\n        );\n        if (alignConfigChanged) {\n            if (prevAlignSampleStepM !== this.alignSampleStepM ||\n                prevAlignMaxSamples !== this.alignMaxSamples) {\n                for (const entry of this._entries) {\n                    this._setEntryTiles(entry);\n                }\n            }\n            this._queueAllAlignEntries('config');\n            this._scheduleDrapeWork();\n        }\n        if (prevPauseWhenFar !== this.pauseWhenFar ||\n            prevPauseDistanceM !== this.pauseDistanceM ||\n            prevPauseDistanceMultiplier !== this.pauseDistanceMultiplier) {\n            this._updateProcessingPause();\n        }\n\n        this.group.visible = this.enabled && !this.paintEnabled && !this._renderSuppressed;\n        if (!this.group.visible) {\n            this._cancelDrapeWork();\n        }\n\n        const paintModeChanged = prevPaintEnabled !== this.paintEnabled;\n        if (paintModeChanged) {\n            this._lastWireframeActive = null;\n        }\n        const paintTuningChanged = (\n            prevPaintResolution !== this.paintResolution ||\n            prevPaintOpacity !== this.paintOpacity ||\n            prevPaintLineWidthPx !== this.paintLineWidthPx ||\n            prevPaintRepaintOnLod !== this.paintRepaintOnLod ||\n            prevPaintBudget !== this.paintBudget\n        );\n\n        if (paintModeChanged) {\n            if (this.paintEnabled) {\n                this.clear();\n            } else {\n                this._clearPaintTiles();\n            }\n            if (this._center) {\n                this._refreshQueued = true;\n            }\n        } else if (this.paintEnabled && paintTuningChanged) {\n            if (prevPaintResolution !== this.paintResolution) {\n                this._clearPaintTiles();\n            }\n            this._queueAllPaintTiles();\n        }\n\n        let layersChanged = false;\n        if (config.layers && typeof config.layers === 'object') {\n            for (const [layer, enabled] of Object.entries(config.layers)) {\n                const prevLayerState = this.layers[layer];\n                this.setLayerEnabled(layer, enabled);\n                if (prevLayerState !== this.layers[layer]) {\n                    layersChanged = true;\n                }\n            }\n        }\n\n        const colorChanged = (\n            prevColors.roads !== this.colors.roads ||\n            prevColors.bridges !== this.colors.bridges ||\n            prevColors.waterways !== this.colors.waterways ||\n            prevColors.areas !== this.colors.areas ||\n            prevColors.railways !== this.colors.railways\n        );\n        if (colorChanged) {\n            if (this.paintEnabled) {\n                this._queueAllPaintTiles();\n            } else {\n                this._applyColorsToEntries();\n            }\n        }\n        if (this._center) {\n            if (this.enabled && !prevEnabled) {\n                this._refreshQueued = true;\n                this._scheduleDrapeWork();\n            } else if (this.radiusM !== prevRadius) {\n                this._refreshQueued = true;\n            } else if (layersChanged) {\n                this._refreshQueued = true;\n            } else {\n                const geometryChanged = (\n                    prevRoadWidthScale !== this.roadWidthScale ||\n                    prevRoadStepM !== this.roadStepM ||\n                    prevBridgeHeightM !== this.bridgeHeightM ||\n                    prevRibbonThicknessM !== this.ribbonThicknessM\n                );\n                const motionChanged = (\n                    prevMotionEnabled !== this.motionEnabled ||\n                    prevMotionAhead !== this.motionAheadFactor ||\n                    prevMotionBehind !== this.motionBehindFactor ||\n                    prevMotionBias !== this.motionQueryBias\n                );\n                if (geometryChanged) {\n                    this._refreshQueued = true;\n                } else if (motionChanged) {\n                    this._refreshQueued = true;\n                }\n            }\n        }\n\n        if (!this.paintEnabled && prevSurfaceOffset !== this.surfaceOffsetM && this._entries.length > 0) {\n            for (const entry of this._entries) {\n                if (entry.kind !== 'bridge') {\n                    entry._drapeDirty = true;\n                    entry._drapeIndex = 0;\n                }\n            }\n            this._queueAllAlignEntries('surface-offset');\n            this._scheduleDrapeWork();\n        }\n    }\n}\n","/**\n * Canonical policy for every terminal value in the Earth settings document.\n *\n * The registry is deliberately generated from trusted application defaults,\n * then classified by ordered rules. Runtime/user data can never create a new\n * descriptor. Unknown roots and paths therefore fail closed at every boundary.\n */\n\nimport { LABEL_TEMPORAL_FILTER_MODE_IDS } from '../labels/LabelTemporalFilter.js';\nimport { LENS_LIMITS } from '../render/LensContract.js';\n\nconst LENS_SETTING_BOUNDS = Object.freeze(Object.fromEntries(\n  Object.entries(LENS_LIMITS).map(([key, range]) => [`scene.lens.${key}`, range]),\n));\n\nexport const SETTINGS_POLICY_VERSION = 2;\n\nexport const EXPOSURE_CLASSES = Object.freeze([\n  'user',\n  'advanced',\n  'operator',\n  'engineering',\n  'internal',\n]);\n\nconst KNOWN_ROOTS = new Set(['meta', 'scene', 'hud', 'nkn', 'pathfinding', 'mobileOverride']);\nconst PRODUCTION_EXPOSURES = new Set(['user', 'advanced']);\nconst SYSTEM_META_DEFAULTS = Object.freeze({\n  'meta.settingsPolicyVersion': SETTINGS_POLICY_VERSION,\n  'meta.labelPresentationContract': 1,\n  'meta.photoSurfaceLightingContract': 2,\n  'meta.orbitalSimpleCloudsContract': 2,\n  'meta.atmosphereBaseOffsetContract': 1,\n  'meta.nightVisibilityContract': 2,\n  'meta.buildingRepairContract': 2,\n  'meta.nightLightsEmissionContract': 3,\n  'meta.mobileOrbitNightContract': 1,\n  'meta.satelliteCatalogContract': 1,\n  'meta.aircraftCatalogContract': 1,\n  'meta.utc': '',\n});\n\nconst isPlainObject = (value) => (\n  value !== null\n  && typeof value === 'object'\n  && !Array.isArray(value)\n  && Object.prototype.toString.call(value) === '[object Object]'\n);\n\nconst clone = (value) => {\n  if (typeof structuredClone === 'function') return structuredClone(value);\n  return JSON.parse(JSON.stringify(value));\n};\n\nconst setPath = (target, parts, value) => {\n  let cursor = target;\n  for (let index = 0; index < parts.length - 1; index += 1) {\n    const part = parts[index];\n    if (!isPlainObject(cursor[part])) cursor[part] = {};\n    cursor = cursor[part];\n  }\n  cursor[parts.at(-1)] = clone(value);\n};\n\nexport const flattenSettingLeaves = (value, prefix = '', output = []) => {\n  if (isPlainObject(value) && Object.keys(value).length) {\n    for (const [key, child] of Object.entries(value)) {\n      flattenSettingLeaves(child, prefix ? `${prefix}.${key}` : key, output);\n    }\n    return output;\n  }\n  if (prefix) output.push({ path: prefix, value });\n  return output;\n};\n\nconst pathMatches = (path, prefix) => path === prefix || path.startsWith(`${prefix}.`);\n\nconst classifyExposure = (path) => {\n  if (pathMatches(path, 'meta') || pathMatches(path, 'mobileOverride')) return 'internal';\n  if (pathMatches(path, 'pathfinding')) return 'engineering';\n  if (path === 'nkn.enabled') return 'advanced';\n  if (pathMatches(path, 'nkn')) return path === 'nkn.seed' ? 'internal' : 'engineering';\n  if (pathMatches(path, 'hud')) return 'advanced';\n\n  const userPrefixes = [\n    'scene.audio.enabled',\n    'scene.audio.wind.enabled',\n    'scene.audio.wind.volume',\n    'scene.weather.enabled',\n    'scene.weather.autoTarget',\n    'scene.labels.enabled',\n    'scene.labels.categories',\n    'scene.labels.temporalFilter',\n    'scene.labels.feedRules',\n    'scene.labels.weatherVolumes',\n    'scene.labels.skyKinds',\n    'scene.avatar.appearance',\n    'scene.avatar.sharing',\n    'scene.lens.chromaticAberration.enabled',\n    'scene.lens.depthOfField.enabled',\n    'scene.lens.filmGrain.enabled',\n  ];\n  if (userPrefixes.some((prefix) => pathMatches(path, prefix))) return 'user';\n\n  const sourceVisibility = /^scene\\.(flights|satellites|maritime|incidents|sensors|trafficCameras|roadTraffic|buildings|infrastructure|radioData|geocaches)\\.(enabled|showLabels)$/;\n  if (sourceVisibility.test(path)) return 'user';\n  if (/^scene\\.radioData\\.feeds\\.(receivers|propagation|satellite-rf|balloons|broadcast)$/.test(path)) return 'user';\n  if (/^scene\\.infrastructure\\.layers\\.[^.]+$/.test(path)) return 'user';\n  if (path === 'scene.incidents.autoZipEnabled') return 'user';\n  if (path === 'scene.camera.mode') return 'user';\n  // Product shortcuts may change visibility, while cloud quality and budgets\n  // retain their engineering policy.\n  if (/^scene\\.atmosphere\\.(clouds|orbitClouds|simpleClouds)\\.enabled$/.test(path)) return 'user';\n\n  const advancedPrefixes = [\n    'scene.audio.speak',\n    'scene.lighting.date',\n    'scene.lighting.timeSpeed',\n    'scene.labels.viewConeDeg',\n    'scene.labels.scaleMultiplier',\n    'scene.labels.maxVisible',\n    'scene.labels.presentation',\n    'scene.labels.dynamics',\n    'scene.avatar.identity',\n    // Lens modifier tuneables (strength, focal length, aperture, ...).\n    'scene.lens',\n  ];\n  if (advancedPrefixes.some((prefix) => pathMatches(path, prefix))) return 'advanced';\n\n  // The remaining scene tree contains renderer budgets, transforms, provider\n  // internals, cache controls, shaders, diagnostics, and raw geometry tuning.\n  return 'engineering';\n};\n\nconst ownerFor = (path) => {\n  if (path.startsWith('hud.')) return 'earth.ui';\n  if (path.startsWith('nkn.')) return 'earth.networking';\n  if (path.startsWith('pathfinding.')) return 'earth.navigation';\n  if (path.startsWith('mobileOverride.')) return 'earth.capability-profile';\n  if (path.startsWith('meta.')) return 'earth.settings';\n  const domain = path.split('.')[1] || 'scene';\n  return `earth.scene.${domain}`;\n};\n\nconst boundsFor = (path, value) => {\n  if (path === 'scene.labels.weatherVolumes.opacity') return {minimum:0.05,maximum:0.8};\n  if (path === 'scene.audio.wind.volume') return { minimum: 0, maximum: 1 };\n  if (path === 'scene.audio.speak.radiusM') return { minimum: 1, maximum: 500 };\n  if (path === 'scene.lighting.timeSpeed') return { minimum: -1000, maximum: 1000 };\n  if (path === 'scene.labels.viewConeDeg') return { minimum: 1, maximum: 180 };\n  if (path === 'scene.labels.scaleMultiplier') return { minimum: 0.25, maximum: 4 };\n  if (path === 'scene.labels.maxVisible') return { minimum: 1, maximum: 500 };\n  if (path === 'scene.labels.presentation.maxWidthPx') return { minimum: 48, maximum: 480 };\n  if (path === 'scene.labels.presentation.maxLines') return { minimum: 1, maximum: 8 };\n  if (path === 'scene.labels.presentation.verbosity') return { minimum: 0, maximum: 3 };\n  if (path.startsWith('scene.labels.dynamics.')) {\n    if (path.endsWith('Px')) return { minimum: 0, maximum: 1000 };\n    return { minimum: 0, maximum: 4 };\n  }\n  const lensBounds = LENS_SETTING_BOUNDS[path];\n  if (lensBounds) return { minimum: lensBounds[0], maximum: lensBounds[1] };\n  if (path === 'scene.avatar.appearance.roughness' || path === 'scene.avatar.appearance.metalness') {\n    return { minimum: 0, maximum: 1 };\n  }\n  return Number.isFinite(value) ? {} : {};\n};\n\nconst enumFor = (path) => {\n  if (path === 'scene.labels.weatherVolumes.source') return ['auto','gfs','ifs','hrrr','icon','icon-eu','icon-d2','gdps','geos','gefs','rrfs'];\n  if (path === 'scene.labels.weatherVolumes.radarSource') return ['auto','mrms','nexrad'];\n  if (path === 'scene.labels.weatherVolumes.forecastHours') return [0,3,6,12,24,48];\n  if (path === 'scene.labels.weatherVolumes.radiusKm') return [20,60,120,240];\n  if (path === 'scene.labels.weatherVolumes.lod') return [0,1,2];\n  if (path === 'scene.camera.mode') return ['orbit', 'surface'];\n  if (path === 'scene.audio.speak.mode') return ['push_to_talk', 'always_on', 'voice_activity', 'disabled'];\n  if (path === 'scene.labels.temporalFilter.mode') return LABEL_TEMPORAL_FILTER_MODE_IDS;\n  if (path.startsWith('hud.pins.') || path.startsWith('hud.widgetPins.')) {\n    return [null, 'top-left', 'top-right', 'bottom-left', 'bottom-right'];\n  }\n  return null;\n};\n\nconst schemaFor = (path, value) => {\n  const enumValues = enumFor(path);\n  if (enumValues) return { type: [...new Set(enumValues.map((entry) => entry === null ? 'null' : typeof entry))], enum: enumValues };\n  if (value === null) {\n    if (path === 'scene.lighting.date') return { type: ['string', 'null'], format: 'date-time' };\n    if (path.startsWith('hud.')) return { type: ['string', 'null'] };\n    return { type: ['number', 'null'] };\n  }\n  if (Array.isArray(value)) {\n    const first = value.find((entry) => entry !== null && entry !== undefined);\n    return { type: 'array', items: first === undefined ? {} : { type: typeof first } };\n  }\n  if (typeof value === 'number') return { type: 'number', ...boundsFor(path, value) };\n  if (typeof value === 'boolean') return { type: 'boolean' };\n  if (typeof value === 'string') return { type: 'string', maxLength: 4096 };\n  return { type: typeof value };\n};\n\nconst replacementPresetFor = (path, exposureClass) => {\n  if (exposureClass !== 'engineering') return null;\n  if (/^scene\\.(renderer|terrain|atmosphere|camera|buildings|infrastructure)\\./.test(path)) {\n    return 'renderQuality';\n  }\n  return null;\n};\n\nconst policiesFor = (path, exposureClass) => {\n  const productPreference = PRODUCTION_EXPOSURES.has(exposureClass);\n  const systemMetadata = exposureClass === 'internal' && path.startsWith('meta.');\n  return {\n    persistencePolicy: productPreference ? 'user-preference' : (systemMetadata ? 'system-metadata' : 'never'),\n    importPolicy: productPreference ? 'allow' : 'deny',\n    exportPolicy: productPreference ? 'allow' : 'deny',\n    agentPolicy: {\n      visible: productPreference,\n      writable: false,\n    },\n  };\n};\n\nconst descriptorFor = (path, value) => {\n  const exposureClass = classifyExposure(path);\n  return Object.freeze({\n    path,\n    owner: ownerFor(path),\n    schema: Object.freeze(schemaFor(path, value)),\n    default: clone(value),\n    exposureClass,\n    supportedPlatforms: Object.freeze(['desktop', 'mobile', 'xr']),\n    ...policiesFor(path, exposureClass),\n    restartRequirement: path.startsWith('nkn.') && path !== 'nkn.enabled' ? 'network-reconnect' : 'none',\n    riskClassification: exposureClass === 'engineering' || exposureClass === 'internal'\n      ? 'high'\n      : (exposureClass === 'advanced' ? 'moderate' : 'low'),\n    replacementPreset: replacementPresetFor(path, exposureClass),\n  });\n};\n\nconst schemaTypes = (schema) => Array.isArray(schema.type) ? schema.type : [schema.type];\n\nconst validateValue = (descriptor, value) => {\n  const type = value === null ? 'null' : (Array.isArray(value) ? 'array' : typeof value);\n  if (!schemaTypes(descriptor.schema).includes(type)) return `expected ${schemaTypes(descriptor.schema).join('|')}, received ${type}`;\n  if (descriptor.schema.enum && !descriptor.schema.enum.includes(value)) return 'value is outside the allowed enum';\n  if (type === 'number') {\n    if (!Number.isFinite(value)) return 'number must be finite';\n    if (Number.isFinite(descriptor.schema.minimum) && value < descriptor.schema.minimum) return `value is below ${descriptor.schema.minimum}`;\n    if (Number.isFinite(descriptor.schema.maximum) && value > descriptor.schema.maximum) return `value is above ${descriptor.schema.maximum}`;\n  }\n  if (type === 'string' && Number.isFinite(descriptor.schema.maxLength) && value.length > descriptor.schema.maxLength) {\n    return `string exceeds ${descriptor.schema.maxLength} characters`;\n  }\n  if (type === 'array' && descriptor.schema.items?.type) {\n    const invalid = value.some((entry) => entry !== null && typeof entry !== descriptor.schema.items.type);\n    if (invalid) return `array items must be ${descriptor.schema.items.type}`;\n  }\n  return null;\n};\n\nconst canReadExposure = (descriptor, context) => {\n  if (PRODUCTION_EXPOSURES.has(descriptor.exposureClass)) return true;\n  if (descriptor.exposureClass === 'operator') return context.operatorCapability === true;\n  if (descriptor.exposureClass === 'engineering') {\n    return context.engineeringBuild === true && context.engineeringCapability === true;\n  }\n  return context.internal === true;\n};\n\nconst canMutateExposure = (descriptor, context) => {\n  if (PRODUCTION_EXPOSURES.has(descriptor.exposureClass)) return true;\n  if (descriptor.exposureClass === 'engineering') {\n    return context.engineeringBuild === true && context.engineeringCapability === true;\n  }\n  return context.internal === true;\n};\n\nexport class SettingDescriptorRegistry {\n  constructor(defaults) {\n    if (!isPlainObject(defaults)) throw new TypeError('Settings defaults must be a plain object');\n    const roots = Object.keys(defaults);\n    const unknownRoots = roots.filter((root) => !KNOWN_ROOTS.has(root));\n    if (unknownRoots.length) throw new Error(`Unclassified settings roots: ${unknownRoots.join(', ')}`);\n\n    this.policyVersion = SETTINGS_POLICY_VERSION;\n    this._descriptors = new Map();\n    // Paths identify policy entries, but trusted object keys define storage.\n    // HUD metric IDs such as \"nav.lat\" are literal keys, not nested objects.\n    this._segments = new Map();\n    const collect = (value, segments = []) => {\n      if (isPlainObject(value) && Object.keys(value).length) {\n        for (const [key, child] of Object.entries(value)) collect(child, [...segments, key]);\n      } else if (segments.length) this._segments.set(segments.join('.'), segments);\n    };\n    collect(defaults);\n    for (const { path, value } of flattenSettingLeaves(defaults)) {\n      const root = path.split('.')[0];\n      if (!KNOWN_ROOTS.has(root)) throw new Error(`Unclassified settings path: ${path}`);\n      this._descriptors.set(path, descriptorFor(path, value));\n    }\n    for (const [path, value] of Object.entries(SYSTEM_META_DEFAULTS)) {\n      if (!this._descriptors.has(path)) {\n        this._descriptors.set(path, descriptorFor(path, value));\n        this._segments.set(path, path.split('.'));\n      }\n    }\n    if (!this._descriptors.size) throw new Error('Settings defaults contain no terminal values');\n  }\n\n  get size() {\n    return this._descriptors.size;\n  }\n\n  get(path) {\n    return this._descriptors.get(String(path)) || null;\n  }\n\n  list({ exposureClass } = {}) {\n    const values = [...this._descriptors.values()];\n    return exposureClass ? values.filter((entry) => entry.exposureClass === exposureClass) : values;\n  }\n\n  inventory() {\n    return this.list().map((descriptor) => clone(descriptor));\n  }\n\n  sanitize(input, { operation = 'mutation', context = {}, includeSystemMetadata = false } = {}) {\n    const value = {};\n    const rejected = [];\n    if (!isPlainObject(input)) return { value, rejected: [{ path: '', reason: 'settings payload must be an object' }] };\n\n    for (const leaf of flattenSettingLeaves(input)) {\n      const descriptor = this.get(leaf.path);\n      if (!descriptor) {\n        rejected.push({ path: leaf.path, reason: 'unclassified path' });\n        continue;\n      }\n\n      let allowed = false;\n      if (operation === 'mutation') allowed = canMutateExposure(descriptor, context);\n      else if (operation === 'read') allowed = canReadExposure(descriptor, context);\n      else if (operation === 'agent') allowed = descriptor.agentPolicy.visible === true;\n      else if (operation === 'import') allowed = descriptor.importPolicy === 'allow';\n      else if (operation === 'export') allowed = descriptor.exportPolicy === 'allow';\n      else if (operation === 'persistence') {\n        allowed = descriptor.persistencePolicy === 'user-preference'\n          || (includeSystemMetadata && descriptor.persistencePolicy === 'system-metadata');\n      }\n\n      if (!allowed) {\n        rejected.push({ path: leaf.path, reason: `${operation} denied for ${descriptor.exposureClass} setting` });\n        continue;\n      }\n      const validationError = validateValue(descriptor, leaf.value);\n      if (validationError) {\n        rejected.push({ path: leaf.path, reason: validationError });\n        continue;\n      }\n      setPath(value, this._segments.get(leaf.path), leaf.value);\n    }\n    return { value, rejected };\n  }\n\n  project(settings, options = {}) {\n    return this.sanitize(settings, options).value;\n  }\n}\n\nexport const buildSettingDescriptorRegistry = (defaults) => new SettingDescriptorRegistry(defaults);\n","/**\n * Resolves device capability facts into an ephemeral runtime profile.\n * Profile-derived values are never user preferences and are not persisted.\n */\n\nconst isPlainObject = (value) => (\n  value !== null && typeof value === 'object' && !Array.isArray(value)\n);\n\nconst clone = (value) => {\n  if (typeof structuredClone === 'function') return structuredClone(value);\n  return JSON.parse(JSON.stringify(value));\n};\n\nconst merge = (target, source) => {\n  if (!isPlainObject(source)) return target;\n  const output = isPlainObject(target) ? { ...target } : {};\n  for (const [key, value] of Object.entries(source)) {\n    if (isPlainObject(value)) output[key] = merge(output[key], value);\n    else output[key] = Array.isArray(value) ? value.slice() : value;\n  }\n  return output;\n};\n\nexport const CAPABILITY_PROFILES = Object.freeze({\n  battery: Object.freeze({\n    scene: Object.freeze({\n      labels: Object.freeze({ maxVisible: 24 }),\n      weather: Object.freeze({ updateIntervalMs: 900_000 }),\n    }),\n  }),\n  balanced: Object.freeze({}),\n  quality: Object.freeze({\n    scene: Object.freeze({ labels: Object.freeze({ maxVisible: 80 }) }),\n  }),\n});\n\nexport class CapabilityProfileService {\n  constructor({ facts = null, preference = 'auto' } = {}) {\n    this.facts = facts || this.detectFacts();\n    this.preference = ['auto', 'battery', 'balanced', 'quality'].includes(preference) ? preference : 'auto';\n  }\n\n  detectFacts() {\n    const nav = typeof navigator === 'object' ? navigator : {};\n    const win = typeof window === 'object' ? window : {};\n    const coarsePointer = typeof win.matchMedia === 'function'\n      ? win.matchMedia('(pointer:coarse)').matches\n      : false;\n    const mobileUserAgent = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i\n      .test(String(nav.userAgent || ''));\n    return Object.freeze({\n      mobile: mobileUserAgent || (Number(nav.maxTouchPoints) > 0 && (coarsePointer || Number(win.innerWidth) <= 768)),\n      logicalCores: Number.isFinite(nav.hardwareConcurrency) ? nav.hardwareConcurrency : null,\n      deviceMemoryGiB: Number.isFinite(nav.deviceMemory) ? nav.deviceMemory : null,\n      coarsePointer,\n      viewportWidth: Number.isFinite(win.innerWidth) ? win.innerWidth : null,\n      viewportHeight: Number.isFinite(win.innerHeight) ? win.innerHeight : null,\n    });\n  }\n\n  selectProfile() {\n    if (this.preference !== 'auto') return this.preference;\n    if (this.facts.mobile && (\n      (Number.isFinite(this.facts.deviceMemoryGiB) && this.facts.deviceMemoryGiB <= 4)\n      || (Number.isFinite(this.facts.logicalCores) && this.facts.logicalCores <= 4)\n    )) return 'battery';\n    return this.facts.mobile ? 'balanced' : 'quality';\n  }\n\n  resolve(defaults) {\n    const source = clone(defaults || {});\n    const legacyMobileOverride = isPlainObject(source.mobileOverride) ? source.mobileOverride : null;\n    delete source.mobileOverride;\n\n    const profile = this.selectProfile();\n    let settings = source;\n    // Preserve the existing tuned mobile contract while it is progressively\n    // replaced by named profiles. It is trusted application data, never a\n    // persisted/importable user surface.\n    if (this.facts.mobile && legacyMobileOverride) settings = merge(settings, legacyMobileOverride);\n    settings = merge(settings, CAPABILITY_PROFILES[profile]);\n\n    return {\n      settings,\n      profile,\n      facts: this.facts,\n      legacyMobileOverrideApplied: Boolean(this.facts.mobile && legacyMobileOverride),\n    };\n  }\n}\n","import {\n    migrateLegacyLabelSettings,\n    synchronizeLabelCategorySourcePatch,\n} from '../labels/LabelCategoryRegistry.js';\nimport {\n    PHOTOREAL_ALBEDO_SCALE_DEFAULT,\n    PHOTOREAL_OCEAN_DEFAULTS,\n} from '../tiles/PhotorealAppearanceContract.js';\nimport {\n    LEGACY_NIGHT_LIGHTS_EMISSION_DEFAULTS,\n    PREVIOUS_NIGHT_LIGHTS_EMISSION_DEFAULTS,\n    V2_NIGHT_LIGHTS_EMISSION_DEFAULTS,\n} from '../render/NightLightsEmissionContract.js';\nimport {\n    SettingDescriptorRegistry,\n    SETTINGS_POLICY_VERSION,\n    flattenSettingLeaves,\n} from './SettingDescriptorRegistry.js';\nimport { CapabilityProfileService } from './CapabilityProfileService.js';\n\nconst DEFAULT_STORAGE_KEY = 'nkn.globe.settings';\nconst PHOTO_SURFACE_LIGHTING_CONTRACT_VERSION = 2;\nconst ORBITAL_SIMPLE_CLOUDS_CONTRACT_VERSION = 2;\nconst ATMOSPHERE_BASE_OFFSET_CONTRACT_VERSION = 1;\nconst NIGHT_VISIBILITY_CONTRACT_VERSION = 2;\nconst BUILDING_REPAIR_CONTRACT_VERSION = 2;\nconst LABEL_PRESENTATION_CONTRACT_VERSION = 1;\nconst NIGHT_LIGHTS_EMISSION_CONTRACT_VERSION = 3;\nconst MOBILE_ORBIT_NIGHT_CONTRACT_VERSION = 1;\n\nconst isPlainObject = (value) => {\n    if (!value || typeof value !== 'object') return false;\n    return Object.prototype.toString.call(value) === '[object Object]';\n};\n\nconst deepClone = (value) => {\n    if (typeof structuredClone === 'function') {\n        return structuredClone(value);\n    }\n    return JSON.parse(JSON.stringify(value));\n};\n\nconst deepMerge = (target, source) => {\n    if (!isPlainObject(source)) return target;\n    const out = isPlainObject(target) ? { ...target } : {};\n    Object.entries(source).forEach(([key, value]) => {\n        if (isPlainObject(value)) {\n            out[key] = deepMerge(out[key], value);\n        } else if (Array.isArray(value)) {\n            out[key] = value.slice();\n        } else {\n            out[key] = value;\n        }\n    });\n    return out;\n};\n\nconst isMobileDevice = () => {\n    if (typeof window === 'undefined') return false;\n    const uaMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);\n    const hasTouch = ('ontouchstart' in window) || navigator.maxTouchPoints > 0;\n    const coarsePointer = typeof window.matchMedia === 'function' &&\n        window.matchMedia('(pointer:coarse)').matches;\n    const narrowViewport = window.innerWidth <= 768;\n    return uaMobile || (hasTouch && (coarsePointer || narrowViewport));\n};\n\nconst setPath = (obj, path, value) => {\n    if (!obj || !path) return;\n    const parts = Array.isArray(path) ? path : String(path).split('.');\n    let current = obj;\n    for (let i = 0; i < parts.length - 1; i++) {\n        const key = parts[i];\n        if (!isPlainObject(current[key])) current[key] = {};\n        current = current[key];\n    }\n    current[parts[parts.length - 1]] = value;\n};\n\nexport class SceneSettings {\n    constructor({\n        url,\n        storageKey = DEFAULT_STORAGE_KEY,\n        applyScene,\n        normalizeScene,\n        capabilityProfileService = null,\n        policyContext = null,\n    } = {}) {\n        this.url = url || null;\n        this.storageKey = storageKey;\n        this._applyScene = typeof applyScene === 'function' ? applyScene : null;\n        this._normalizeScene = typeof normalizeScene === 'function' ? normalizeScene : null;\n        this._defaults = {};\n        this._settings = {};\n        this._loaded = false;\n        this._listeners = new Set();\n        this._registry = null;\n        this._policyEnforced = false;\n        this._capabilityProfileService = capabilityProfileService || new CapabilityProfileService();\n        this._capabilityProfile = null;\n        this._policyContext = isPlainObject(policyContext) ? { ...policyContext } : {};\n        this._lastPolicyRejections = [];\n    }\n\n    _migrateCloudUltra(stored) {\n        if (!isPlainObject(stored) || stored.meta?.cloudUltraContract === 1) return;\n        stored.meta ||= {};\n        stored.scene ||= {}; stored.scene.atmosphere ||= {};\n        stored.scene.atmosphere.clouds ||= {}; stored.scene.atmosphere.orbitClouds ||= {};\n        stored.scene.atmosphere.clouds.qualityPreset = 'ultra';\n        stored.scene.atmosphere.orbitClouds.qualityPreset = 'ultra';\n        stored.scene.atmosphere.orbitClouds.resolutionScale = 1;\n        stored.meta.cloudUltraContract = 1;\n    }\n\n    // Aurora brightness became a saturating emission column (30 km reference);\n    // an untouched 140 km reference would keep it invisible from above.\n    _migrateAuroraPathRef(stored) {\n        if (!isPlainObject(stored) || stored.meta?.auroraPathContract === 1) return;\n        for (const value of [stored.scene?.atmosphere?.aurora, stored.mobileOverride?.scene?.atmosphere?.aurora]) {\n            if (isPlainObject(value) && value.pathRefMeters === 140000) value.pathRefMeters = 30000;\n        }\n        stored.meta ||= {};\n        stored.meta.auroraPathContract = 1;\n    }\n\n    /** Film grain became on by default (it shipped off on 2026-11-11). */\n    _migrateFilmGrainDefault(stored) {\n        if (!isPlainObject(stored) || stored.meta?.filmGrainDefaultContract === 1) return;\n        for (const lens of [stored.scene?.lens, stored.mobileOverride?.scene?.lens]) {\n            if (isPlainObject(lens?.filmGrain) && lens.filmGrain.enabled === false) lens.filmGrain.enabled = true;\n        }\n        stored.meta ||= {};\n        stored.meta.filmGrainDefaultContract = 1;\n    }\n\n    _migrateAirglowLayers(stored) {\n        if (!isPlainObject(stored) || stored.meta?.airglowLayerContract === 2) return;\n        const old={baseAltitudeMeters:85000,coreAltitudeMeters:122000,fringeAltitudeMeters:255000,riseScaleMeters:26000,tailScaleMeters:56000};\n        const next={baseAltitudeMeters:80000,coreAltitudeMeters:97000,fringeAltitudeMeters:330000,riseScaleMeters:4500,tailScaleMeters:35000};\n        for(const value of [stored.scene?.atmosphere?.airglow,stored.mobileOverride?.scene?.atmosphere?.airglow]) {\n            if(!isPlainObject(value))continue;\n            if([old,next].some(profile=>Object.entries(profile).every(([key,v])=>value[key]==null||value[key]===v))) {\n                Object.assign(value,next);\n                if(value.strength==null||value.strength===.13)value.strength=.005;\n            }\n        }\n        stored.meta ||= {};stored.meta.airglowLayerContract=2;\n    }\n\n    async load() {\n        const defaults = await this._loadDefaults();\n        this._registry = new SettingDescriptorRegistry(defaults);\n        this._policyEnforced = Number(defaults?.meta?.settingsPolicyVersion) >= SETTINGS_POLICY_VERSION;\n        const capabilityResolution = this._capabilityProfileService.resolve(defaults);\n        const resolvedDefaults = capabilityResolution.settings;\n        this._capabilityProfile = capabilityResolution;\n        const stored = this._loadStored();\n        this._defaults = resolvedDefaults;\n        // Migration: the former palette/topographic controls have been reduced\n        // to a physically shaded surface plus one crease-outline color.\n        this._migrateLegacyWireframeColors(stored);\n        this._migrateLegacyLabelSettings(stored);\n        this._migrateLabelPresentationDefaults(stored);\n        this._migratePhotorealSurfaceLighting(stored);\n        this._migrateOrbitalSimpleClouds(stored);\n        this._migrateAtmosphereBaseOffsets(stored);\n        this._migrateNightVisibilityTransition(stored);\n        this._migrateNightLightsEmission(stored);\n        this._migrateMobileOrbitNight(stored);\n        this._migrateBuildingRepairDefaults(stored);\n        this._migrateSatelliteCatalogDefaults(stored);\n        this._migrateAircraftCatalogDefaults(stored);\n        this._migrateCloudUltra(stored);\n        this._migrateAirglowLayers(stored);\n        this._migrateAuroraPathRef(stored);\n        this._migrateFilmGrainDefault(stored);\n        const sanitizedStored = this._policyEnforced\n            ? this._registry.sanitize(stored || {}, {\n                operation: 'persistence',\n                includeSystemMetadata: true,\n            })\n            : { value: stored || {}, rejected: [] };\n        this._recordPolicyRejections('load', sanitizedStored.rejected);\n        this._settings = deepMerge(deepClone(resolvedDefaults), sanitizedStored.value);\n        if (!isPlainObject(this._settings.meta)) this._settings.meta = {};\n        this._settings.meta.settingsPolicyVersion = SETTINGS_POLICY_VERSION;\n        if (this._normalizeScene && isPlainObject(this._settings?.scene)) {\n            const normalizedScene = this._normalizeScene(this._settings.scene, this._settings.scene);\n            if (normalizedScene && normalizedScene !== this._settings.scene) {\n                this._settings = deepMerge(this._settings, { scene: normalizedScene });\n            }\n        }\n        this._loaded = true;\n        // Rewrite policy-versioned storage immediately so engineering/debug\n        // overrides and unknown paths cannot survive a successful migration.\n        if (this._policyEnforced) this._persist();\n        return this._settings;\n    }\n\n    get() {\n        return this._settings;\n    }\n\n    getSection(path) {\n        if (!path) return this._settings;\n        const parts = Array.isArray(path) ? path : String(path).split('.');\n        let current = this._settings;\n        for (const part of parts) {\n            if (!current || typeof current !== 'object') return null;\n            current = current[part];\n        }\n        return current ?? null;\n    }\n\n    getRegistry() {\n        return this._registry;\n    }\n\n    getCapabilityProfile() {\n        if (!this._capabilityProfile) return null;\n        return {\n            profile: this._capabilityProfile.profile,\n            facts: this._capabilityProfile.facts,\n            legacyMobileOverrideApplied: this._capabilityProfile.legacyMobileOverrideApplied,\n        };\n    }\n\n    getProjection(operation = 'read', context = {}) {\n        if (!this._registry || !this._policyEnforced) return deepClone(this._settings);\n        return this._registry.project(this._settings, {\n            operation,\n            context: { ...this._policyContext, ...context },\n        });\n    }\n\n    getLastPolicyRejections() {\n        return this._lastPolicyRejections.map((entry) => ({ ...entry }));\n    }\n\n    update(patch, { persist = true, apply = true, policyContext = null } = {}) {\n        if (!isPlainObject(patch)) return { applied: false, rejected: [{ path: '', reason: 'patch must be an object' }] };\n        const normalized = this._normalizePatch(patch);\n        const policyResult = this._registry && this._policyEnforced\n            ? this._registry.sanitize(normalized, {\n                operation: 'mutation',\n                context: { ...this._policyContext, ...(policyContext || {}) },\n            })\n            : { value: normalized, rejected: [] };\n        this._recordPolicyRejections('update', policyResult.rejected);\n        if (!flattenSettingLeaves(policyResult.value).length) {\n            return { applied: false, rejected: policyResult.rejected };\n        }\n        this._settings = deepMerge(this._settings, policyResult.value);\n        if (apply) this._applySceneSettings(policyResult.value);\n        if (persist) this._persist();\n        this._emitChange({ patch: policyResult.value, settings: this._settings, rejected: policyResult.rejected });\n        return { applied: true, patch: policyResult.value, rejected: policyResult.rejected };\n    }\n\n    updatePath(path, value, options = {}) {\n        if (!path) return;\n        const patch = {};\n        setPath(patch, path, value);\n        return this.update(patch, options);\n    }\n\n    updateScene(patch, opts) {\n        return this.update({ scene: patch }, opts);\n    }\n\n    reset({ apply = true } = {}) {\n        this._settings = deepClone(this._defaults);\n        if (this._normalizeScene && isPlainObject(this._settings?.scene)) {\n            const normalizedScene = this._normalizeScene(this._settings.scene, this._settings.scene);\n            if (normalizedScene && normalizedScene !== this._settings.scene) {\n                this._settings = deepMerge(this._settings, { scene: normalizedScene });\n            }\n        }\n        if (apply) this._applySceneSettings();\n        this._persist();\n        this._emitChange({ patch: null, settings: this._settings, reset: true });\n    }\n\n    import(json, { apply = true } = {}) {\n        if (!json) return;\n        const data = isPlainObject(json) ? json : JSON.parse(json);\n        this._migrateLegacyLabelSettings(data);\n        this._markLabelPresentationContract(data);\n        this._markPhotorealSurfaceLightingContract(data);\n        this._markOrbitalSimpleCloudsContract(data);\n        this._migrateAtmosphereBaseOffsets(data);\n        this._markNightVisibilityContract(data);\n        this._markMobileOrbitNightContract(data);\n        this._markBuildingRepairContract(data);\n        this._migrateSatelliteCatalogDefaults(data);\n        this._migrateAircraftCatalogDefaults(data);\n        const policyResult = this._registry && this._policyEnforced\n            ? this._registry.sanitize(data, { operation: 'import' })\n            : { value: data, rejected: [] };\n        this._recordPolicyRejections('import', policyResult.rejected);\n        this._settings = deepMerge(deepClone(this._defaults), policyResult.value);\n        if (!isPlainObject(this._settings.meta)) this._settings.meta = {};\n        this._settings.meta.settingsPolicyVersion = SETTINGS_POLICY_VERSION;\n        if (this._normalizeScene && isPlainObject(this._settings?.scene)) {\n            const normalizedScene = this._normalizeScene(this._settings.scene, this._settings.scene);\n            if (normalizedScene && normalizedScene !== this._settings.scene) {\n                this._settings = deepMerge(this._settings, { scene: normalizedScene });\n            }\n        }\n        if (apply) this._applySceneSettings();\n        this._persist();\n        this._emitChange({ patch: null, settings: this._settings, import: true, rejected: policyResult.rejected });\n        return { imported: true, rejected: policyResult.rejected };\n    }\n\n    export() {\n        const data = this._registry && this._policyEnforced\n            ? this._registry.project(this._settings, { operation: 'export' })\n            : deepClone(this._settings);\n        const nowIso = new Date().toISOString();\n        if (!isPlainObject(data.meta)) data.meta = {};\n        data.meta.schema = this._settings?.meta?.schema || 'noclip.scene.settings';\n        data.meta.version = this._settings?.meta?.version || 1;\n        data.meta.settingsPolicyVersion = SETTINGS_POLICY_VERSION;\n        data.meta.generated = nowIso;\n        data.meta.utc = nowIso;\n        return JSON.stringify(data, null, 2);\n    }\n\n    apply() {\n        this._applySceneSettings();\n    }\n\n    subscribe(handler) {\n        if (typeof handler !== 'function') return () => {};\n        this._listeners.add(handler);\n        return () => this._listeners.delete(handler);\n    }\n\n    _emitChange(payload) {\n        if (!this._listeners.size) return;\n        for (const handler of this._listeners) {\n            handler(payload);\n        }\n    }\n\n    _normalizePatch(patch) {\n        if (!isPlainObject(patch)) return patch;\n        let normalized = patch;\n        if (isPlainObject(patch.scene)) {\n            const synchronized = synchronizeLabelCategorySourcePatch(patch.scene);\n            const normalizedScene = this._normalizeScene\n                ? this._normalizeScene(synchronized, this._settings?.scene || {})\n                : synchronized;\n            const scene = normalizedScene || synchronized;\n            normalized = { ...patch, scene };\n        } else {\n            const sceneKeys = [\n                'renderer', 'lens', 'audio', 'lighting', 'atmosphere', 'terrain', 'weather',\n                'camera', 'debug', 'labels', 'flights', 'satellites', 'maritime',\n                'incidents', 'sensors', 'trafficCameras', 'roadTraffic', 'buildings',\n                'infrastructure', 'radioData', 'geocaches',\n            ];\n            const looksLikeScenePatch = sceneKeys.some((key) => Object.prototype.hasOwnProperty.call(patch, key));\n            if (looksLikeScenePatch) {\n                const synchronized = synchronizeLabelCategorySourcePatch(patch);\n                normalized = this._normalizeScene\n                    ? (this._normalizeScene(synchronized, this._settings?.scene || {}) || synchronized)\n                    : synchronized;\n            }\n        }\n        return normalized;\n    }\n\n    _applySceneSettings(patch = null) {\n        if (!this._applyScene) return;\n        let sceneSettings = null;\n        if (isPlainObject(patch)) {\n            if (isPlainObject(patch.scene)) {\n                sceneSettings = patch.scene;\n            } else {\n                const sceneKeys = [\n                    'renderer', 'lens', 'audio', 'lighting', 'atmosphere', 'terrain', 'weather',\n                    'camera', 'debug', 'labels', 'flights', 'satellites', 'maritime',\n                    'incidents', 'sensors', 'trafficCameras', 'roadTraffic', 'buildings',\n                    'infrastructure', 'radioData', 'geocaches',\n                ];\n                const looksLikeScenePatch = sceneKeys.some((key) => Object.prototype.hasOwnProperty.call(patch, key));\n                if (looksLikeScenePatch) {\n                    sceneSettings = patch;\n                } else {\n                    return;\n                }\n            }\n        } else {\n            sceneSettings = this._settings?.scene || {};\n        }\n        this._applyScene(sceneSettings);\n    }\n\n    _persist() {\n        try {\n            const persisted = this._registry && this._policyEnforced\n                ? this._registry.project(this._settings, {\n                    operation: 'persistence',\n                    includeSystemMetadata: true,\n                })\n                : this._settings;\n            localStorage.setItem(this.storageKey, JSON.stringify(persisted));\n        } catch (error) {\n            console.warn('[SceneSettings] Persist failed', error);\n        }\n    }\n\n    _recordPolicyRejections(boundary, rejected) {\n        this._lastPolicyRejections = (rejected || []).map((entry) => ({ boundary, ...entry }));\n        if (this._lastPolicyRejections.length && typeof console !== 'undefined') {\n            console.warn(`[SceneSettings] ${boundary} rejected ${this._lastPolicyRejections.length} settings path(s)`);\n        }\n    }\n\n    /** Remove retired multi-palette wireframe fields from persisted settings. */\n    _migrateLegacyWireframeColors(stored) {\n        const ws = stored?.scene?.debug?.wireframeStyle;\n        if (!ws || typeof ws !== 'object') return;\n        let changed = false;\n        if (!ws.lineColor && ws.terrainLine) {\n            ws.lineColor = ws.terrainLine;\n            changed = true;\n        }\n        const retiredKeys = [\n            'mode',\n            'terrainLine',\n            'terrainFillMin',\n            'terrainFillMax',\n            'terrainMaterial',\n            'terrainLineOverlay',\n            'buildingFill',\n            'buildingLine',\n            'topoEnabled',\n            'topoInterval',\n            'topoMinorDivisions',\n            'halftoneScale',\n            'halftoneStrength',\n            'halftoneSoftness',\n            'halftoneAngle',\n        ];\n        for (const key of retiredKeys) {\n            if (!Object.prototype.hasOwnProperty.call(ws, key)) continue;\n            delete ws[key];\n            changed = true;\n        }\n        if (changed) {\n            console.info('[SceneSettings] Migrated legacy wireframe palette → surface + outline colors.');\n            try {\n                localStorage.setItem(this.storageKey, JSON.stringify(stored));\n            } catch { /* best effort */ }\n        }\n    }\n\n    _migrateLegacyLabelSettings(stored) {\n        if (!stored?.scene || typeof stored.scene !== 'object') return;\n        migrateLegacyLabelSettings(stored.scene);\n    }\n\n    /**\n     * The former two-line default was commonly persisted even when untouched.\n     * Drop only that exact inherited value once so full-detail labels can use\n     * the new three-line central band; later explicit line-limit choices remain\n     * stable behind the contract marker.\n     */\n    _migrateLabelPresentationDefaults(stored) {\n        if (!isPlainObject(stored)) return;\n        const meta = isPlainObject(stored.meta) ? stored.meta : (stored.meta = {});\n        if (meta.labelPresentationContract === LABEL_PRESENTATION_CONTRACT_VERSION) return;\n        const presentation = stored.scene?.labels?.presentation;\n        if (isPlainObject(presentation) && Number(presentation.maxLines) === 2) {\n            delete presentation.maxLines;\n        }\n        this._markLabelPresentationContract(stored);\n        try {\n            localStorage.setItem(this.storageKey, JSON.stringify(stored));\n        } catch { /* best effort */ }\n    }\n\n    _markLabelPresentationContract(settings) {\n        if (!isPlainObject(settings)) return;\n        if (!isPlainObject(settings.meta)) settings.meta = {};\n        settings.meta.labelPresentationContract = LABEL_PRESENTATION_CONTRACT_VERSION;\n    }\n\n    /**\n     * Takram 0.19 renamed the r182 post-process lighting controls. The former\n     * false/false defaults were inert at the time, but persisted copies would\n     * now explicitly disable the corrected sun and sky irradiance path. Migrate\n     * that exact legacy-default pair once; after the marker is present, a user\n     * can deliberately disable either control and the choice remains stable.\n     */\n    _migratePhotorealSurfaceLighting(stored) {\n        if (!isPlainObject(stored)) return;\n        const meta = isPlainObject(stored.meta) ? stored.meta : (stored.meta = {});\n        if (meta.photoSurfaceLightingContract === PHOTO_SURFACE_LIGHTING_CONTRACT_VERSION) return;\n\n        const atmosphere = stored.scene?.atmosphere;\n        const inheritedLegacyDefaults = atmosphere?.sunIrradiance === false\n            && atmosphere?.skyIrradiance === false;\n        if (inheritedLegacyDefaults) {\n            delete atmosphere.sunIrradiance;\n            delete atmosphere.skyIrradiance;\n            console.info(\n                '[SceneSettings] Migrated legacy inert atmosphere lighting defaults → physical surface lighting.'\n            );\n        }\n        // Version 2 calibrates display-referred provider photography before\n        // Takram treats it as Lambertian albedo, and restores the deep-water\n        // body colour that the dormant legacy tile injection never applied.\n        // Only exact former defaults migrate; explicit custom values remain.\n        if (Number(atmosphere?.irradianceScale) === 1\n            && PHOTOREAL_ALBEDO_SCALE_DEFAULT !== 1) {\n            delete atmosphere.irradianceScale;\n        }\n        const water = atmosphere?.water;\n        if (isPlainObject(water)) {\n            if (String(water.color || '').toLowerCase() === '#0b3754'\n                && PHOTOREAL_OCEAN_DEFAULTS.color.toLowerCase() !== '#0b3754') {\n                delete water.color;\n            }\n            if (Number(water.opacity) === 0.85\n                && PHOTOREAL_OCEAN_DEFAULTS.opacity !== 0.85) {\n                delete water.opacity;\n            }\n        }\n        this._markPhotorealSurfaceLightingContract(stored);\n        try {\n            localStorage.setItem(this.storageKey, JSON.stringify(stored));\n        } catch { /* best effort */ }\n    }\n\n    _markPhotorealSurfaceLightingContract(settings) {\n        if (!isPlainObject(settings)) return;\n        if (!isPlainObject(settings.meta)) settings.meta = {};\n        settings.meta.photoSurfaceLightingContract = PHOTO_SURFACE_LIGHTING_CONTRACT_VERSION;\n    }\n\n    /**\n     * The live non-GIBS orbit cloud map was disabled when surface volumetric\n     * clouds became the default. OverviewGlobeFallback cannot use that local\n     * volume, so persisted copies of the former false default would continue\n     * hiding the restored orbital cloud/shadow path. Drop that exact inherited\n     * value once. The resolved mobile override remains authoritative, and any\n     * later explicit user choice is preserved by the contract marker.\n     */\n    _migrateOrbitalSimpleClouds(stored) {\n        if (!isPlainObject(stored)) return;\n        const meta = isPlainObject(stored.meta) ? stored.meta : (stored.meta = {});\n        if (meta.orbitalSimpleCloudsContract === ORBITAL_SIMPLE_CLOUDS_CONTRACT_VERSION) return;\n\n        const simpleClouds = stored.scene?.atmosphere?.simpleClouds;\n        if (simpleClouds?.enabled === false) {\n            delete simpleClouds.enabled;\n            console.info(\n                '[SceneSettings] Restored live simple orbital clouds over the overview globe.'\n            );\n        }\n        if (isPlainObject(simpleClouds)) {\n            simpleClouds.alphaThreshold = 0;\n        }\n        this._markOrbitalSimpleCloudsContract(stored);\n        try {\n            localStorage.setItem(this.storageKey, JSON.stringify(stored));\n        } catch { /* best effort */ }\n    }\n\n    _markOrbitalSimpleCloudsContract(settings) {\n        if (!isPlainObject(settings)) return;\n        if (!isPlainObject(settings.meta)) settings.meta = {};\n        settings.meta.orbitalSimpleCloudsContract = ORBITAL_SIMPLE_CLOUDS_CONTRACT_VERSION;\n    }\n\n    /**\n     * The first styled-Black-Marble gate used max(R,G,B), so blue mountain\n     * relief was mistaken for emitted light. Migrate only the complete former\n     * default response tuple; any custom night-light curve remains untouched.\n     */\n    _migrateNightLightsEmission(stored) {\n        if (!isPlainObject(stored)) return;\n        const meta = isPlainObject(stored.meta) ? stored.meta : (stored.meta = {});\n        if (meta.nightLightsEmissionContract === NIGHT_LIGHTS_EMISSION_CONTRACT_VERSION) return;\n\n        const lightPollution = stored.scene?.atmosphere?.lightPollution;\n        const inheritedLegacyDefaults = isPlainObject(lightPollution)\n            && Number(lightPollution.intensity)\n                === LEGACY_NIGHT_LIGHTS_EMISSION_DEFAULTS.intensity\n            && Number(lightPollution.emissionThreshold)\n                === LEGACY_NIGHT_LIGHTS_EMISSION_DEFAULTS.emissionThreshold\n            && Number(lightPollution.emissionSoftness)\n                === LEGACY_NIGHT_LIGHTS_EMISSION_DEFAULTS.emissionSoftness\n            && Number(lightPollution.emissionPower)\n                === LEGACY_NIGHT_LIGHTS_EMISSION_DEFAULTS.emissionPower;\n        const inheritedPreviousDefaults = isPlainObject(lightPollution)\n            && Number(lightPollution.intensity)\n                === PREVIOUS_NIGHT_LIGHTS_EMISSION_DEFAULTS.intensity\n            && Number(lightPollution.mapGain)\n                === PREVIOUS_NIGHT_LIGHTS_EMISSION_DEFAULTS.mapGain\n            && Number(lightPollution.emissionThreshold)\n                === PREVIOUS_NIGHT_LIGHTS_EMISSION_DEFAULTS.emissionThreshold\n            && Number(lightPollution.emissionSoftness)\n                === PREVIOUS_NIGHT_LIGHTS_EMISSION_DEFAULTS.emissionSoftness\n            && Number(lightPollution.emissionPower)\n                === PREVIOUS_NIGHT_LIGHTS_EMISSION_DEFAULTS.emissionPower\n            && Number(lightPollution.emissionBlueSuppression)\n                === PREVIOUS_NIGHT_LIGHTS_EMISSION_DEFAULTS.emissionBlueSuppression;\n        const inheritedV2Defaults = isPlainObject(lightPollution)\n            && Number(lightPollution.intensity)\n                === V2_NIGHT_LIGHTS_EMISSION_DEFAULTS.intensity\n            && Number(lightPollution.mapGain)\n                === V2_NIGHT_LIGHTS_EMISSION_DEFAULTS.mapGain\n            && Number(lightPollution.emissionThreshold)\n                === V2_NIGHT_LIGHTS_EMISSION_DEFAULTS.emissionThreshold\n            && Number(lightPollution.emissionSoftness)\n                === V2_NIGHT_LIGHTS_EMISSION_DEFAULTS.emissionSoftness\n            && Number(lightPollution.emissionPower)\n                === V2_NIGHT_LIGHTS_EMISSION_DEFAULTS.emissionPower\n            && Number(lightPollution.emissionBlueSuppression)\n                === V2_NIGHT_LIGHTS_EMISSION_DEFAULTS.emissionBlueSuppression;\n        if (inheritedLegacyDefaults || inheritedPreviousDefaults || inheritedV2Defaults) {\n            delete lightPollution.intensity;\n            delete lightPollution.mapGain;\n            delete lightPollution.emissionThreshold;\n            delete lightPollution.emissionSoftness;\n            delete lightPollution.emissionPower;\n            delete lightPollution.emissionBlueSuppression;\n            if (Number(lightPollution.surfaceIntensityScale)\n                === V2_NIGHT_LIGHTS_EMISSION_DEFAULTS.surfaceIntensityScale) {\n                delete lightPollution.surfaceIntensityScale;\n            }\n            console.info(\n                '[SceneSettings] Migrated NASA night lights to calibrated terrain-rejected emission.'\n            );\n        }\n        meta.nightLightsEmissionContract = NIGHT_LIGHTS_EMISSION_CONTRACT_VERSION;\n        try {\n            localStorage.setItem(this.storageKey, JSON.stringify(stored));\n        } catch { /* best effort */ }\n    }\n\n    /**\n     * Older mobile defaults persisted the entire resolved settings tree with\n     * NASA night lights disabled. Changing the default alone cannot repair\n     * those returning browsers because stored settings merge last. Remove only\n     * that former inherited mobile value once; after the marker is present an\n     * explicit user choice remains stable.\n     */\n    _migrateMobileOrbitNight(stored) {\n        if (!isPlainObject(stored) || !isMobileDevice()) return;\n        const meta = isPlainObject(stored.meta) ? stored.meta : (stored.meta = {});\n        if (meta.mobileOrbitNightContract === MOBILE_ORBIT_NIGHT_CONTRACT_VERSION) return;\n\n        const lightPollution = stored.scene?.atmosphere?.lightPollution;\n        if (isPlainObject(lightPollution) && lightPollution.enabled === false) {\n            delete lightPollution.enabled;\n            console.info(\n                '[SceneSettings] Restored mobile orbital NASA night-light emission.'\n            );\n        }\n        this._markMobileOrbitNightContract(stored);\n        try {\n            localStorage.setItem(this.storageKey, JSON.stringify(stored));\n        } catch { /* best effort */ }\n    }\n\n    _markMobileOrbitNightContract(settings) {\n        if (!isPlainObject(settings)) return;\n        if (!isPlainObject(settings.meta)) settings.meta = {};\n        settings.meta.mobileOrbitNightContract = MOBILE_ORBIT_NIGHT_CONTRACT_VERSION;\n    }\n\n    /**\n     * Night-Side Visibility is an authored geography/emission control, not the\n     * physical solar terminator. Migrate only the exact former defaults to the\n     * requested 0 → 0.5 range; custom saved transitions remain authoritative.\n     */\n    _migrateNightVisibilityTransition(stored) {\n        if (!isPlainObject(stored)) return;\n        const meta = isPlainObject(stored.meta) ? stored.meta : (stored.meta = {});\n        if (meta.nightVisibilityContract === NIGHT_VISIBILITY_CONTRACT_VERSION) return;\n\n        const night = stored.scene?.atmosphere?.nightSettings;\n        if (isPlainObject(night)\n            && Number(night.nightTransitionStart) === -0.02\n            && Number(night.nightTransitionEnd) === 0.06) {\n            delete night.nightTransitionStart;\n            delete night.nightTransitionEnd;\n            console.info(\n                '[SceneSettings] Migrated Night-Side Visibility transition to 0 → 0.5.'\n            );\n        }\n        // The old fully-resolved 1% floor otherwise wins over the mobile\n        // capability profile forever. Remove only that exact former default;\n        // user-authored night floors remain stable.\n        if (isPlainObject(night) && Number(night.nightMinBrightness) === 0.01) {\n            delete night.nightMinBrightness;\n        }\n        this._markNightVisibilityContract(stored);\n        try {\n            localStorage.setItem(this.storageKey, JSON.stringify(stored));\n        } catch { /* best effort */ }\n    }\n\n    _markNightVisibilityContract(settings) {\n        if (!isPlainObject(settings)) return;\n        if (!isPlainObject(settings.meta)) settings.meta = {};\n        settings.meta.nightVisibilityContract = NIGHT_VISIBILITY_CONTRACT_VERSION;\n    }\n\n    /**\n     * Building ownership now follows the terrain provider: TriTree owns the\n     * generated OSM layer and photoreal mode owns its native building mesh.\n     * Remove the retired persisted toggles once so scene normalization can\n     * derive the correct state from tileSource without an old preference\n     * re-enabling the expensive photoreal coverage probes.\n     */\n    // Upgrade the prior feed default once; later explicit choices are durable.\n    _migrateAircraftCatalogDefaults(stored) {\n        if (!isPlainObject(stored)) return;\n        const meta=isPlainObject(stored.meta)?stored.meta:(stored.meta={});\n        if(meta.aircraftCatalogContract===1)return;\n        const flights=stored.scene?.flights;\n        if(isPlainObject(flights)&&flights.provider==='adsb_lol'\n            &&(!flights.queryMode||flights.queryMode==='point')&&!flights.queryValue){\n            flights.provider='unified';flights.queryMode='catalog';\n            if(!flights.pollIntervalMs||flights.pollIntervalMs===15000)flights.pollIntervalMs=2000;\n        }\n        meta.aircraftCatalogContract=1;\n    }\n\n    _migrateSatelliteCatalogDefaults(stored) {\n        if (!isPlainObject(stored)) return;\n        const meta = isPlainObject(stored.meta) ? stored.meta : (stored.meta = {});\n        if (meta.satelliteCatalogContract === 1) return;\n        const satellites = stored.scene?.satellites;\n        // Upgrade only the old out-of-box 200-object subset. Explicit custom\n        // sources/queries remain selectable, and the marker preserves later\n        // deliberate selection of that legacy provider across reloads.\n        if (isPlainObject(satellites) && satellites.provider === 'satnogs'\n            && (!satellites.queryMode || satellites.queryMode === 'tle')\n            && !satellites.queryValue && (!satellites.maxSatellites || satellites.maxSatellites === 200)) {\n            satellites.provider = 'unified'; satellites.queryMode = 'catalog';\n        }\n        meta.satelliteCatalogContract = 1;\n    }\n\n    _migrateBuildingRepairDefaults(stored) {\n        if (!isPlainObject(stored)) return;\n        const meta = isPlainObject(stored.meta) ? stored.meta : (stored.meta = {});\n        if (meta.buildingRepairContract === BUILDING_REPAIR_CONTRACT_VERSION) return;\n\n        const buildings = stored.scene?.buildings;\n        if (isPlainObject(buildings)) {\n            delete buildings.enabled;\n            delete buildings.photorealFallbackEnabled;\n            console.info(\n                '[SceneSettings] Migrated buildings to terrain-provider ownership.'\n            );\n        }\n        this._markBuildingRepairContract(stored);\n        try {\n            localStorage.setItem(this.storageKey, JSON.stringify(stored));\n        } catch { /* best effort */ }\n    }\n\n    _markBuildingRepairContract(settings) {\n        if (!isPlainObject(settings)) return;\n        if (!isPlainObject(settings.meta)) settings.meta = {};\n        settings.meta.buildingRepairContract = BUILDING_REPAIR_CONTRACT_VERSION;\n    }\n\n    /**\n     * The former single offset served surface cloud/terrain clearance and was\n     * also applied in orbit, where depressing the scattering sphere creates a\n     * black jagged Earth limb. Move that legacy value to the surface-only\n     * field and make the orbital floor exact once.\n     */\n    _migrateAtmosphereBaseOffsets(stored) {\n        if (!isPlainObject(stored)) return;\n        const meta = isPlainObject(stored.meta) ? stored.meta : (stored.meta = {});\n        if (meta.atmosphereBaseOffsetContract === ATMOSPHERE_BASE_OFFSET_CONTRACT_VERSION) return;\n\n        const atmosphere = stored.scene?.atmosphere;\n        if (isPlainObject(atmosphere)) {\n            const hasSurfaceOffset = Number.isFinite(Number(atmosphere.surfaceBaseOffsetMeters));\n            const legacyOffset = Number(atmosphere.baseOffsetMeters);\n            if (!hasSurfaceOffset && Number.isFinite(legacyOffset) && legacyOffset > 0) {\n                atmosphere.surfaceBaseOffsetMeters = legacyOffset;\n            }\n            atmosphere.baseOffsetMeters = 0;\n        }\n        meta.atmosphereBaseOffsetContract = ATMOSPHERE_BASE_OFFSET_CONTRACT_VERSION;\n        try {\n            localStorage.setItem(this.storageKey, JSON.stringify(stored));\n        } catch { /* best effort */ }\n    }\n\n    _loadStored() {\n        try {\n            const raw = localStorage.getItem(this.storageKey);\n            if (!raw) return null;\n            return JSON.parse(raw);\n        } catch (error) {\n            console.warn('[SceneSettings] Stored settings invalid', error);\n            return null;\n        }\n    }\n\n    async _loadDefaults() {\n        if (!this.url) return {};\n        try {\n            const response = await fetch(this.url, { cache: 'no-store' });\n            if (!response.ok) {\n                throw new Error(`HTTP ${response.status}`);\n            }\n            return await response.json();\n        } catch (error) {\n            console.warn('[SceneSettings] Default settings load failed', error);\n            return {};\n        }\n    }\n\n}\n","const isPlainObject = (value) => {\n    if (!value || typeof value !== 'object') return false;\n    return Object.prototype.toString.call(value) === '[object Object]';\n};\n\nconst clonePlainObject = (value) => (isPlainObject(value) ? { ...value } : undefined);\n\nexport const IMAGERY_MANAGER_CONFIG_NUMERIC_KEYS = Object.freeze([\n    'maxAtlasTiles',\n    'padTiles',\n    'maxTileCacheMB',\n    'maxAtlasCacheMB',\n    'textureAnisotropy',\n    'tileSize',\n    'maxConcurrentAtlasBuilds',\n    'maxConcurrentTileLoads',\n    'contextBurstTileLoads',\n    'contextBurstAtlasBuilds',\n    'atlasDrawBudgetMs',\n    'atlasDrawMinTiles',\n    'tileRetryDelayMs',\n    'atlasRetryDelayMs',\n    'retryBypassPriority',\n    'maxAtlasTileFetches',\n    'atlasTileFetchConcurrency',\n    'atlasParentFallbackMaxParents',\n    'maxQueuedTileRequests',\n    'maxQueuedAtlasRequests'\n]);\n\nexport const IMAGERY_MANAGER_CONFIG_BOOLEAN_KEYS = Object.freeze([\n    'useMobileTiles',\n    'atlasParentFallbackEnabled'\n]);\n\nexport const IMAGERY_MANAGER_CONFIG_KEYS = Object.freeze([\n    ...IMAGERY_MANAGER_CONFIG_NUMERIC_KEYS,\n    ...IMAGERY_MANAGER_CONFIG_BOOLEAN_KEYS\n]);\n\nexport const ELEVATION_CLIENT_CONFIG_NUMERIC_KEYS = Object.freeze([\n    'batchSize',\n    'maxConcurrent',\n    'minIntervalMs',\n    'maxKBPerMinute',\n    'maxChunkBytes',\n    'maxRequestBytes',\n    'backendTimeoutMs',\n    'angleLimitDeg',\n    'surfaceMinLevel',\n    'maxVertexRecords',\n    'pendingTimeoutMs',\n    'pendingRecoveryIntervalMs',\n    'pendingRecoveryMaxPerTick',\n    'fullFetchMinLevel',\n    'initialSampleStrideMultiplier',\n    'sampleStrideMultiplier',\n    'viewshedMinDeg',\n    'viewshedMarginDeg',\n    'ringNearMeters',\n    'ringMidMeters',\n    'ringBudgetNear',\n    'ringBudgetMid'\n]);\n\nexport const ELEVATION_CLIENT_CONFIG_BOOLEAN_KEYS = Object.freeze([\n    'cacheEnabled'\n]);\n\nexport const ELEVATION_CLIENT_CONFIG_OBJECT_KEYS = Object.freeze([\n    'ringLodCaps'\n]);\n\nexport function extractImageryManagerConfig(source = {}) {\n    const config = {};\n    IMAGERY_MANAGER_CONFIG_KEYS.forEach((key) => {\n        config[key] = source?.[key];\n    });\n    return config;\n}\n\nexport function buildTerrainImagerySettings({ imageryManager = null, triTree = null } = {}) {\n    const imageryConfig = imageryManager?.getConfig?.() || {};\n    const config = {\n        ...extractImageryManagerConfig(imageryConfig)\n    };\n    if (Number.isFinite(triTree?.mergeMosaicMaxAtlasTiles)) {\n        config.mergeMosaicMaxAtlasTiles = triTree.mergeMosaicMaxAtlasTiles;\n    }\n    if (Number.isFinite(triTree?.mergeMosaicPadTiles)) {\n        config.mergeMosaicPadTiles = triTree.mergeMosaicPadTiles;\n    }\n    if (Number.isFinite(triTree?.mergeMosaicMinZoom)) {\n        config.mergeMosaicMinZoom = triTree.mergeMosaicMinZoom;\n    }\n    if (Number.isFinite(triTree?.mergeMosaicPriority)) {\n        config.mergeMosaicPriority = triTree.mergeMosaicPriority;\n    }\n    if (Number.isFinite(triTree?.mergeChildAdoptMinCoverage)) {\n        config.mergeChildAdoptMinCoverage = triTree.mergeChildAdoptMinCoverage;\n    }\n    if (Number.isFinite(triTree?.surfaceUnderfootMaxAtlasTiles)) {\n        config.surfaceUnderfootMaxAtlasTiles = triTree.surfaceUnderfootMaxAtlasTiles;\n    }\n    if (Number.isFinite(triTree?.surfaceNearMaxAtlasTiles)) {\n        config.surfaceNearMaxAtlasTiles = triTree.surfaceNearMaxAtlasTiles;\n    }\n    if (Number.isFinite(triTree?.surfaceNearAtlasRadiusMeters)) {\n        config.surfaceNearAtlasRadiusMeters = triTree.surfaceNearAtlasRadiusMeters;\n    }\n    if (typeof triTree?.imageryInheritanceEnabled === 'boolean') {\n        config.imageryInheritanceEnabled = triTree.imageryInheritanceEnabled;\n    }\n    if (typeof triTree?.imageryBackpressureDropZoomEnabled === 'boolean') {\n        config.imageryBackpressureDropZoomEnabled = triTree.imageryBackpressureDropZoomEnabled;\n    }\n    if (Number.isFinite(triTree?.imageryBackpressureSplitBudgetMinScale)) {\n        config.imageryBackpressureSplitBudgetMinScale = triTree.imageryBackpressureSplitBudgetMinScale;\n    }\n    if (Number.isFinite(triTree?.imageryBackpressureImageryBudgetMinScale)) {\n        config.imageryBackpressureImageryBudgetMinScale = triTree.imageryBackpressureImageryBudgetMinScale;\n    }\n    if (Number.isFinite(triTree?.imageryBackpressureElevationScanMinScale)) {\n        config.imageryBackpressureElevationScanMinScale = triTree.imageryBackpressureElevationScanMinScale;\n    }\n    if (typeof triTree?.imageryCoverFirstEnabled === 'boolean') {\n        config.imageryCoverFirstEnabled = triTree.imageryCoverFirstEnabled;\n    }\n    if (Number.isFinite(triTree?.imageryCoverBootstrapWindowMs)) {\n        config.imageryCoverBootstrapWindowMs = triTree.imageryCoverBootstrapWindowMs;\n    }\n    if (Number.isFinite(triTree?.imageryCoverZoomGap)) {\n        config.imageryCoverZoomGap = triTree.imageryCoverZoomGap;\n    }\n    if (Number.isFinite(triTree?.imageryCoverUnderfootZoomGap)) {\n        config.imageryCoverUnderfootZoomGap = triTree.imageryCoverUnderfootZoomGap;\n    }\n    if (Number.isFinite(triTree?.imageryCoverMinZoom)) {\n        config.imageryCoverMinZoom = triTree.imageryCoverMinZoom;\n    }\n    if (Number.isFinite(triTree?.imageryCoverUnderfootMinZoom)) {\n        config.imageryCoverUnderfootMinZoom = triTree.imageryCoverUnderfootMinZoom;\n    }\n    if (typeof triTree?.imageryBootstrapEnabled === 'boolean') {\n        config.imageryBootstrapEnabled = triTree.imageryBootstrapEnabled;\n    }\n    if (Number.isFinite(triTree?.imageryBootstrapDeltaZoom)) {\n        config.imageryBootstrapDeltaZoom = triTree.imageryBootstrapDeltaZoom;\n    }\n    if (Number.isFinite(triTree?.imageryBootstrapMaxRing)) {\n        config.imageryBootstrapMaxRing = triTree.imageryBootstrapMaxRing;\n    }\n    if (Number.isFinite(triTree?.imageryBootstrapBudgetMax)) {\n        config.imageryBootstrapBudgetMax = triTree.imageryBootstrapBudgetMax;\n    }\n    if (Number.isFinite(triTree?.imageryBootstrapMinPriority)) {\n        config.imageryBootstrapMinPriority = triTree.imageryBootstrapMinPriority;\n    }\n    return {\n        enabled: imageryConfig.enabled,\n        versionId: imageryConfig.versionId,\n        zoom: imageryConfig.zoom,\n        minZoom: triTree?.imageryMinZoom,\n        maxZoom: triTree?.imageryMaxZoom,\n        resolutionBoost: triTree?.imageryResolutionBoost,\n        config\n    };\n}\n\nexport function buildTriTreeImageryConfigPatch(imagery = {}, currentImageryConfig = {}) {\n    const patch = {\n        enabled: typeof imagery.enabled === 'boolean' ? imagery.enabled : currentImageryConfig.enabled,\n        versionId: imagery.versionId || currentImageryConfig.versionId,\n        zoom: Number.isFinite(imagery.zoom) ? imagery.zoom : currentImageryConfig.zoom\n    };\n    const imageryConfig = isPlainObject(imagery?.config) ? imagery.config : null;\n    if (!imageryConfig) return patch;\n\n    if (Object.prototype.hasOwnProperty.call(imageryConfig, 'mergeMosaicMaxAtlasTiles')) {\n        patch.mergeMosaicMaxAtlasTiles = Number.isFinite(imageryConfig.mergeMosaicMaxAtlasTiles)\n            ? imageryConfig.mergeMosaicMaxAtlasTiles\n            : null;\n    }\n    if (Object.prototype.hasOwnProperty.call(imageryConfig, 'mergeMosaicPadTiles')) {\n        patch.mergeMosaicPadTiles = Number.isFinite(imageryConfig.mergeMosaicPadTiles)\n            ? imageryConfig.mergeMosaicPadTiles\n            : null;\n    }\n    if (Object.prototype.hasOwnProperty.call(imageryConfig, 'mergeMosaicMinZoom')) {\n        patch.mergeMosaicMinZoom = Number.isFinite(imageryConfig.mergeMosaicMinZoom)\n            ? imageryConfig.mergeMosaicMinZoom\n            : null;\n    }\n    if (Object.prototype.hasOwnProperty.call(imageryConfig, 'mergeMosaicPriority')) {\n        patch.mergeMosaicPriority = Number.isFinite(imageryConfig.mergeMosaicPriority)\n            ? imageryConfig.mergeMosaicPriority\n            : null;\n    }\n    if (Object.prototype.hasOwnProperty.call(imageryConfig, 'mergeChildAdoptMinCoverage')) {\n        patch.mergeChildAdoptMinCoverage = Number.isFinite(imageryConfig.mergeChildAdoptMinCoverage)\n            ? imageryConfig.mergeChildAdoptMinCoverage\n            : null;\n    }\n    if (Object.prototype.hasOwnProperty.call(imageryConfig, 'surfaceUnderfootMaxAtlasTiles')) {\n        patch.surfaceUnderfootMaxAtlasTiles = Number.isFinite(imageryConfig.surfaceUnderfootMaxAtlasTiles)\n            ? imageryConfig.surfaceUnderfootMaxAtlasTiles\n            : null;\n    }\n    if (Object.prototype.hasOwnProperty.call(imageryConfig, 'surfaceNearMaxAtlasTiles')) {\n        patch.surfaceNearMaxAtlasTiles = Number.isFinite(imageryConfig.surfaceNearMaxAtlasTiles)\n            ? imageryConfig.surfaceNearMaxAtlasTiles\n            : null;\n    }\n    if (Object.prototype.hasOwnProperty.call(imageryConfig, 'surfaceNearAtlasRadiusMeters')) {\n        patch.surfaceNearAtlasRadiusMeters = Number.isFinite(imageryConfig.surfaceNearAtlasRadiusMeters)\n            ? imageryConfig.surfaceNearAtlasRadiusMeters\n            : null;\n    }\n    if (Object.prototype.hasOwnProperty.call(imageryConfig, 'imageryInheritanceEnabled')) {\n        patch.imageryInheritanceEnabled = imageryConfig.imageryInheritanceEnabled === true;\n    }\n    if (Object.prototype.hasOwnProperty.call(imageryConfig, 'imageryBackpressureDropZoomEnabled')) {\n        patch.imageryBackpressureDropZoomEnabled = imageryConfig.imageryBackpressureDropZoomEnabled === true;\n    }\n    if (Object.prototype.hasOwnProperty.call(imageryConfig, 'imageryBackpressureSplitBudgetMinScale')) {\n        patch.imageryBackpressureSplitBudgetMinScale = Number.isFinite(imageryConfig.imageryBackpressureSplitBudgetMinScale)\n            ? imageryConfig.imageryBackpressureSplitBudgetMinScale\n            : null;\n    }\n    if (Object.prototype.hasOwnProperty.call(imageryConfig, 'imageryBackpressureImageryBudgetMinScale')) {\n        patch.imageryBackpressureImageryBudgetMinScale = Number.isFinite(imageryConfig.imageryBackpressureImageryBudgetMinScale)\n            ? imageryConfig.imageryBackpressureImageryBudgetMinScale\n            : null;\n    }\n    if (Object.prototype.hasOwnProperty.call(imageryConfig, 'imageryBackpressureElevationScanMinScale')) {\n        patch.imageryBackpressureElevationScanMinScale = Number.isFinite(imageryConfig.imageryBackpressureElevationScanMinScale)\n            ? imageryConfig.imageryBackpressureElevationScanMinScale\n            : null;\n    }\n    if (Object.prototype.hasOwnProperty.call(imageryConfig, 'imageryCoverFirstEnabled')) {\n        patch.imageryCoverFirstEnabled = imageryConfig.imageryCoverFirstEnabled === true;\n    }\n    if (Object.prototype.hasOwnProperty.call(imageryConfig, 'imageryCoverBootstrapWindowMs')) {\n        patch.imageryCoverBootstrapWindowMs = Number.isFinite(imageryConfig.imageryCoverBootstrapWindowMs)\n            ? imageryConfig.imageryCoverBootstrapWindowMs\n            : null;\n    }\n    if (Object.prototype.hasOwnProperty.call(imageryConfig, 'imageryCoverZoomGap')) {\n        patch.imageryCoverZoomGap = Number.isFinite(imageryConfig.imageryCoverZoomGap)\n            ? imageryConfig.imageryCoverZoomGap\n            : null;\n    }\n    if (Object.prototype.hasOwnProperty.call(imageryConfig, 'imageryCoverUnderfootZoomGap')) {\n        patch.imageryCoverUnderfootZoomGap = Number.isFinite(imageryConfig.imageryCoverUnderfootZoomGap)\n            ? imageryConfig.imageryCoverUnderfootZoomGap\n            : null;\n    }\n    if (Object.prototype.hasOwnProperty.call(imageryConfig, 'imageryCoverMinZoom')) {\n        patch.imageryCoverMinZoom = Number.isFinite(imageryConfig.imageryCoverMinZoom)\n            ? imageryConfig.imageryCoverMinZoom\n            : null;\n    }\n    if (Object.prototype.hasOwnProperty.call(imageryConfig, 'imageryCoverUnderfootMinZoom')) {\n        patch.imageryCoverUnderfootMinZoom = Number.isFinite(imageryConfig.imageryCoverUnderfootMinZoom)\n            ? imageryConfig.imageryCoverUnderfootMinZoom\n            : null;\n    }\n    if (Object.prototype.hasOwnProperty.call(imageryConfig, 'imageryBootstrapEnabled')) {\n        patch.imageryBootstrapEnabled = imageryConfig.imageryBootstrapEnabled === true;\n    }\n    if (Object.prototype.hasOwnProperty.call(imageryConfig, 'imageryBootstrapDeltaZoom')) {\n        patch.imageryBootstrapDeltaZoom = Number.isFinite(imageryConfig.imageryBootstrapDeltaZoom)\n            ? imageryConfig.imageryBootstrapDeltaZoom\n            : null;\n    }\n    if (Object.prototype.hasOwnProperty.call(imageryConfig, 'imageryBootstrapMaxRing')) {\n        patch.imageryBootstrapMaxRing = Number.isFinite(imageryConfig.imageryBootstrapMaxRing)\n            ? imageryConfig.imageryBootstrapMaxRing\n            : null;\n    }\n    if (Object.prototype.hasOwnProperty.call(imageryConfig, 'imageryBootstrapBudgetMax')) {\n        patch.imageryBootstrapBudgetMax = Number.isFinite(imageryConfig.imageryBootstrapBudgetMax)\n            ? imageryConfig.imageryBootstrapBudgetMax\n            : null;\n    }\n    if (Object.prototype.hasOwnProperty.call(imageryConfig, 'imageryBootstrapMinPriority')) {\n        patch.imageryBootstrapMinPriority = Number.isFinite(imageryConfig.imageryBootstrapMinPriority)\n            ? imageryConfig.imageryBootstrapMinPriority\n            : null;\n    }\n    return patch;\n}\n\nexport function buildImageryManagerConfigPatch(source = {}) {\n    if (!isPlainObject(source)) return {};\n    const patch = {};\n    IMAGERY_MANAGER_CONFIG_NUMERIC_KEYS.forEach((key) => {\n        if (Number.isFinite(source[key])) {\n            patch[key] = source[key];\n        }\n    });\n    IMAGERY_MANAGER_CONFIG_BOOLEAN_KEYS.forEach((key) => {\n        if (typeof source[key] === 'boolean') {\n            patch[key] = source[key];\n        }\n    });\n    return patch;\n}\n\nexport function hasImageryManagerConfigChanges(nextConfig = {}, currentConfig = {}) {\n    if (!isPlainObject(nextConfig)) return false;\n    const keys = Object.keys(nextConfig);\n    if (!keys.length) return false;\n    return keys.some((key) => nextConfig[key] !== currentConfig[key]);\n}\n\nexport function buildTerrainElevationSettings({ elevationClient = null, triTree = null } = {}) {\n    const ringBudget = elevationClient?.ringBudgetWeights || {};\n    return {\n        batchSize: elevationClient?.batchSize,\n        maxConcurrent: elevationClient?.maxConcurrentBatches,\n        minIntervalMs: elevationClient?.minIntervalMs,\n        maxKBPerMinute: elevationClient?.maxKBPerMinute,\n        maxChunkBytes: elevationClient?.maxChunkBytes,\n        maxRequestBytes: elevationClient?.maxRequestBytes,\n        backendTimeoutMs: elevationClient?._backendTimeoutMs,\n        angleLimitDeg: elevationClient?.angleLimitDeg,\n        surfaceMinLevel: elevationClient?.surfaceMinLevel,\n        maxVertexRecords: elevationClient?.maxVertexRecords,\n        pendingTimeoutMs: elevationClient?.pendingTimeoutMs,\n        pendingRecoveryIntervalMs: elevationClient?.pendingRecoveryIntervalMs,\n        pendingRecoveryMaxPerTick: elevationClient?.pendingRecoveryMaxPerTick,\n        fullFetchMinLevel: elevationClient?.fullFetchMinLevel,\n        initialSampleStrideMultiplier: elevationClient?.sampleStrideMultiplier,\n        sampleStrideMultiplier: elevationClient?.sampleStrideMultiplier,\n        cacheEnabled: elevationClient?.isCacheEnabled?.(),\n        persistentCacheEnabled: elevationClient?.isPersistentCacheEnabled?.(),\n        viewshedMinDeg: elevationClient?.viewshedMinDeg,\n        viewshedMarginDeg: elevationClient?.viewshedMarginDeg,\n        ringNearMeters: elevationClient?.ringNearMeters,\n        ringMidMeters: elevationClient?.ringMidMeters,\n        ringBudgetNear: Number.isFinite(ringBudget.near) ? ringBudget.near * 100 : undefined,\n        ringBudgetMid: Number.isFinite(ringBudget.mid) ? ringBudget.mid * 100 : undefined,\n        ringLodCaps: clonePlainObject(elevationClient?.ringLodCaps),\n        fetchMode: triTree?.elevationFetchMode,\n        queueResetDistanceM: triTree?.elevationQueueResetDistance,\n        queueResetAngleDeg: triTree?.elevationQueueResetAngleDeg,\n        cascadeEnabled: triTree?.elevationCascadeEnabled,\n        cascadeCoarseReadyRatio: triTree?.elevationCascadeCoarseReadyRatio,\n        cascadeTileReadyRatio: triTree?.elevationCascadeTileReadyRatio,\n        cascadeMinVisibleTiles: triTree?.elevationCascadeMinVisibleTiles,\n        cascadeCoarseMaxLevel: triTree?.elevationCascadeCoarseMaxLevel,\n        forceCompleteStallMs: triTree?.elevationForceCompleteStallMs,\n        forceCompleteMaxPerFrame: triTree?.elevationForceCompleteMaxPerFrame,\n        forceCompleteMaxPerTile: triTree?.elevationForceCompleteMaxPerTile\n    };\n}\n\nexport function buildElevationClientConfigPatch(source = {}) {\n    if (!isPlainObject(source)) return {};\n    const patch = {};\n    ELEVATION_CLIENT_CONFIG_NUMERIC_KEYS.forEach((key) => {\n        if (Number.isFinite(source[key])) {\n            patch[key] = source[key];\n        }\n    });\n    ELEVATION_CLIENT_CONFIG_BOOLEAN_KEYS.forEach((key) => {\n        if (typeof source[key] === 'boolean') {\n            patch[key] = source[key];\n        }\n    });\n    ELEVATION_CLIENT_CONFIG_OBJECT_KEYS.forEach((key) => {\n        if (isPlainObject(source[key])) {\n            patch[key] = { ...source[key] };\n        }\n    });\n    return patch;\n}\n","/** One lazy, release-bundled Rapier runtime; failure permits an explicit retry. */\n// Native Node/dev URL; bundle-rapier-runtime replaces this expression with an\n// emitted, release-qualified Rollup chunk URL for production. Never a CDN URL.\nconst RAPIER_MODULE_URL = new URL('../node_modules/@dimforge/rapier3d-compat/rapier.es.js', import.meta.url).href;\n\nexport function createRapierModuleLoader(importModule = url => import(/* @vite-ignore */ url), moduleUrl = RAPIER_MODULE_URL) {\n    let initialization = null;\n    let runtime = null;\n    let importAttempts = 0;\n    return function loadRapierModule() {\n        if (!initialization) {\n            initialization = Promise.resolve().then(async () => {\n                if (!runtime) {\n                    const url = new URL(moduleUrl);\n                    // Browser module maps cache failed fetches. Only an explicit\n                    // retry changes this one owned URL, retaining its release id.\n                    if (importAttempts > 0) url.searchParams.set('nclp_retry', String(importAttempts));\n                    importAttempts++;\n                    runtime = await importModule(url.href);\n                }\n                // The pinned compatibility package embeds its WASM. Vite owns the\n                // complete async asset graph; no CDN or runtime URL fallback.\n                await runtime.init();\n                return runtime;\n            }).catch(error => {\n                initialization = null;\n                throw error;\n            });\n        }\n        return initialization;\n    };\n}\n\nexport const loadRapierModule = createRapierModuleLoader();\n","/**\n * PhysicsSystem\n *\n * Spherical gravity-based physics system for globe environments.\n * Wraps Rapier physics with:\n * - Radial gravity pulling toward globe center\n * - Character controller for first-person movement\n * - Dynamic rigid bodies with collision detection\n * - Impact sound integration\n *\n * API:\n * - addPhysicsObject(mesh, options) - Add dynamic physics object\n * - removePhysicsObject(mesh) - Remove physics object\n * - addStaticCollider(mesh) - Add static terrain collider\n * - removeStaticCollider(mesh) - Remove static collider\n * - update(dt, gravityCenter) - Step simulation with radial gravity\n */\n\nimport * as THREE from 'three';\n// Note: RapierHelper removed - doesn't exist in three.js addons\nimport { PLANET_RADIUS } from './constants.js';\nimport { loadRapierModule } from './rapier-runtime.js';\n\nconst TMP_TRANSLATION = new THREE.Vector3();\nconst TMP_ROTATION = new THREE.Quaternion();\nconst TMP_LINEAR_VELOCITY = new THREE.Vector3();\nconst TMP_VELOCITY_DELTA = new THREE.Vector3();\nconst TMP_GRAVITY = new THREE.Vector3();\nconst TMP_WORLD_POSITION = new THREE.Vector3();\nconst TMP_WORLD_QUATERNION = new THREE.Quaternion();\nconst TMP_WORLD_SCALE = new THREE.Vector3(1, 1, 1);\n\nfunction _safeFinite(value, fallback) {\n    return Number.isFinite(value) ? value : fallback;\n}\n\nfunction _scaledRadius(baseRadius, scaleVec) {\n    const sx = Math.abs(_safeFinite(scaleVec?.x, 1));\n    const sy = Math.abs(_safeFinite(scaleVec?.y, 1));\n    const sz = Math.abs(_safeFinite(scaleVec?.z, 1));\n    const maxScale = Math.max(sx, sy, sz, 1e-6);\n    return Math.max(1e-4, _safeFinite(baseRadius, 0.5) * maxScale);\n}\n\nfunction _geometryBoundingSphereRadius(geometry) {\n    if (!geometry) return 0.5;\n    try {\n        geometry.computeBoundingSphere?.();\n        const radius = geometry.boundingSphere?.radius;\n        return Number.isFinite(radius) && radius > 0 ? radius : 0.5;\n    } catch {\n        return 0.5;\n    }\n}\n\nfunction createDynamicColliderDesc(RAPIER, mesh, radiusOverride = null) {\n    if (!RAPIER || !mesh?.geometry) return null;\n\n    mesh.getWorldScale?.(TMP_WORLD_SCALE);\n    const sx = Math.abs(_safeFinite(TMP_WORLD_SCALE.x, 1));\n    const sy = Math.abs(_safeFinite(TMP_WORLD_SCALE.y, 1));\n    const sz = Math.abs(_safeFinite(TMP_WORLD_SCALE.z, 1));\n\n    if (Number.isFinite(radiusOverride) && radiusOverride > 0) {\n        return RAPIER.ColliderDesc.ball(_scaledRadius(radiusOverride, TMP_WORLD_SCALE));\n    }\n\n    const geometry = mesh.geometry;\n    const parameters = geometry.parameters || {};\n\n    if (geometry.type === 'BoxGeometry' || geometry.type === 'RoundedBoxGeometry') {\n        const halfX = Math.max(1e-4, _safeFinite(parameters.width, 1) * 0.5 * sx);\n        const halfY = Math.max(1e-4, _safeFinite(parameters.height, 1) * 0.5 * sy);\n        const halfZ = Math.max(1e-4, _safeFinite(parameters.depth, 1) * 0.5 * sz);\n        return RAPIER.ColliderDesc.cuboid(halfX, halfY, halfZ);\n    }\n\n    if (geometry.type === 'SphereGeometry' || geometry.type === 'IcosahedronGeometry') {\n        const baseRadius = _safeFinite(parameters.radius, _geometryBoundingSphereRadius(geometry));\n        return RAPIER.ColliderDesc.ball(_scaledRadius(baseRadius, TMP_WORLD_SCALE));\n    }\n\n    if (geometry.type === 'CapsuleGeometry') {\n        const baseRadius = _safeFinite(parameters.radius, 0.5);\n        const baseHeight = _safeFinite(parameters.height, 1);\n        const radius = Math.max(1e-4, baseRadius * Math.max(sx, sz));\n        const halfHeight = Math.max(1e-4, (baseHeight * 0.5) * sy);\n        return RAPIER.ColliderDesc.capsule(halfHeight, radius);\n    }\n\n    if (geometry.type === 'CylinderGeometry') {\n        const baseRadius = _safeFinite(parameters.radiusBottom, _safeFinite(parameters.radiusTop, 0.5));\n        const baseHeight = _safeFinite(parameters.height, 1);\n        const radius = Math.max(1e-4, baseRadius * Math.max(sx, sz));\n        const halfHeight = Math.max(1e-4, (baseHeight * 0.5) * sy);\n        return RAPIER.ColliderDesc.cylinder(halfHeight, radius);\n    }\n\n    // Fallback to sphere for unsupported procedural/loaded geometries.\n    return RAPIER.ColliderDesc.ball(_scaledRadius(_geometryBoundingSphereRadius(geometry), TMP_WORLD_SCALE));\n}\n\nexport class PhysicsSystem {\n    constructor({\n        scene,\n        audioSystem = null,\n        planetRadius = PLANET_RADIUS,\n        runtimeLoader = loadRapierModule,\n        initializeOnConstruct = true\n    } = {}) {\n        if (!scene) throw new Error('PhysicsSystem requires a scene');\n\n        this.scene = scene;\n        this.audioSystem = audioSystem;\n        this.planetRadius = planetRadius;\n\n        // Rapier physics engine\n        this.core = null;\n\n        // Dynamic objects tracking\n        this.dynamicObjects = new Set();\n        this.staticColliders = new Map();\n\n        // Character controller\n        this.character = null;\n        this.characterReady = false;\n        this._characterImpactCooldown = 0;\n\n        // Gravity settings\n        this.gravityStrength = 9.8; // m/s²\n\n        // Deferred operations queue (to avoid recursive Rapier errors)\n        this._deferredOps = [];\n        this._isUpdating = false;\n        this._fixedMinStep = 1 / 240;\n        this._fixedMaxStep = 1 / 20;\n        this._surfaceCollisionResolver = null;\n\n        this._runtimeLoader = runtimeLoader;\n        this._disposed = false;\n        this._initializing = false;\n        this._initializationRequested = false;\n        this.initializationError = null;\n        this.ready = null;\n        if (initializeOnConstruct) this.initialize();\n    }\n\n    /** Coalesce callers on this world; retry only when explicitly requested. */\n    initialize() {\n        if (this._disposed) return Promise.reject(new Error('PhysicsSystem is disposed'));\n        if (this._initializing || this.core) return this.ready;\n        this._initializationRequested = true;\n        this._initializing = true;\n        this.initializationError = null;\n        this.ready = this._init().catch(error => {\n            this.initializationError = error;\n            throw error;\n        }).finally(() => { this._initializing = false; });\n        return this.ready;\n    }\n\n    async _init() {\n        const RAPIER = await this._runtimeLoader();\n        // A scene removed during import/compile must not acquire a late world.\n        if (this._disposed) return this;\n        const world = new RAPIER.World({ x: 0, y: 0, z: 0 });\n        this.core = { RAPIER, world };\n\n        // Disable global gravity (we use radial gravity)\n        if (world?.gravity) {\n            world.gravity.x = 0;\n            world.gravity.y = 0;\n            world.gravity.z = 0;\n        }\n\n        return this;\n    }\n\n    /**\n     * Add a dynamic physics object\n     * @param {THREE.Mesh} mesh - Object to add physics to\n     * @param {Object} options - { mass, restitution, friction, radius }\n     * @returns {Object} - Physics body and collider references\n     */\n    addPhysicsObject(mesh, options = {}) {\n        if (!this.core) {\n            if (mesh && !this._disposed) {\n                if (!this._deferredOps.some((op) => op.type === 'add' && op.mesh === mesh)) {\n                    this._deferredOps.push({ type: 'add', mesh, options });\n                }\n                void this.initialize()\n                    .then(() => this._processDeferredOps())\n                    .catch(() => { /* explicit status/retry owns the observable error */ });\n            }\n            return null;\n        }\n\n        // Defer if currently updating to avoid Rapier recursive errors\n        if (this._isUpdating) {\n            this._deferredOps.push({ type: 'add', mesh, options });\n            return null;\n        }\n\n        const {\n            mass = 1.0,\n            restitution = 0.2,\n            friction = 0.7,\n            radius = null\n        } = options;\n\n        if (!mesh?.geometry || !this.core?.RAPIER || !this.core?.world) return null;\n\n        const { RAPIER, world } = this.core;\n        mesh.updateMatrixWorld?.(true);\n        mesh.getWorldPosition?.(TMP_WORLD_POSITION);\n        mesh.getWorldQuaternion?.(TMP_WORLD_QUATERNION);\n\n        const bodyDesc = RAPIER.RigidBodyDesc.dynamic()\n            .setTranslation(TMP_WORLD_POSITION.x, TMP_WORLD_POSITION.y, TMP_WORLD_POSITION.z)\n            .setRotation({\n                x: TMP_WORLD_QUATERNION.x,\n                y: TMP_WORLD_QUATERNION.y,\n                z: TMP_WORLD_QUATERNION.z,\n                w: TMP_WORLD_QUATERNION.w\n            });\n        const body = world.createRigidBody(bodyDesc);\n\n        const colliderDesc = createDynamicColliderDesc(RAPIER, mesh, radius);\n        if (!colliderDesc) {\n            world.removeRigidBody(body);\n            return null;\n        }\n        colliderDesc.setMass?.(Math.max(1e-4, mass));\n        colliderDesc.setFriction?.(friction);\n        colliderDesc.setRestitution?.(restitution);\n        const collider = world.createCollider(colliderDesc, body);\n\n        if (!mesh.userData.physics) mesh.userData.physics = {};\n        mesh.userData.physics.body = body;\n        mesh.userData.physics.collider = collider;\n        mesh.userData.physics.surfaceCollisionRadius = Number.isFinite(radius) && radius > 0\n            ? _scaledRadius(radius, TMP_WORLD_SCALE)\n            : _scaledRadius(_geometryBoundingSphereRadius(mesh.geometry), TMP_WORLD_SCALE);\n        mesh.userData.physics.previousWorldPosition = TMP_WORLD_POSITION.clone();\n        mesh.userData.physics.resolvedWorldPosition = TMP_WORLD_POSITION.clone();\n        mesh.userData.hasPhysics = true;\n        mesh.userData.physicsData = { body, collider };\n\n        if (body) {\n            body.setCcdEnabled?.(true);\n            body.setCanSleep?.(false);\n            body.wakeUp?.();\n        }\n\n        if (collider) {\n            collider.setFriction?.(friction);\n            collider.setRestitution?.(restitution);\n        }\n\n        // Track for impact detection\n        mesh.userData._impactState = {\n            prevVel: new THREE.Vector3(),\n            speed: 0,\n            cooldown: 0,\n            ready: false\n        };\n\n        this.dynamicObjects.add(mesh);\n\n        return { body, collider };\n    }\n\n    /**\n     * Install a bounded streamed-surface resolver. TriTree terrain continues\n     * to use native Rapier trimeshes; photoreal 3D Tiles are too transient and\n     * numerous to rebuild as global Rapier colliders on every LOD swap, so\n     * their local swept contact is resolved after each fixed step instead.\n     */\n    setSurfaceCollisionResolver(resolver) {\n        this._surfaceCollisionResolver = typeof resolver === 'function' ? resolver : null;\n    }\n\n    /**\n     * Remove physics from object\n     */\n    removePhysicsObject(mesh) {\n        if (!mesh || !this.core) return;\n\n        // Defer if currently updating to avoid Rapier recursive errors\n        if (this._isUpdating) {\n            this._deferredOps.push({ type: 'remove', mesh });\n            return;\n        }\n\n        const physicsData = mesh.userData.physics;\n        if (physicsData?.body && this.core.world) {\n            this.core.world.removeRigidBody(physicsData.body);\n        }\n\n        this.dynamicObjects.delete(mesh);\n        delete mesh.userData.physics;\n        delete mesh.userData._impactState;\n    }\n\n    /**\n     * Add static collider (terrain, buildings, etc.)\n     */\n    addStaticCollider(mesh) {\n        if (!mesh || !this.core || !this.core.RAPIER) {\n            if (mesh) console.warn('[PhysicsSystem] Cannot add collider - physics not ready');\n            return null;\n        }\n\n        if (this._isUpdating) {\n            this._deferredOps.push({ type: 'static-add', mesh });\n            return null;\n        }\n\n        const geometry = mesh.geometry;\n        if (!geometry || !geometry.attributes?.position) {\n            console.warn('[PhysicsSystem] Cannot add collider - invalid geometry');\n            return null;\n        }\n\n        mesh.updateMatrixWorld(true);\n\n        // Check if already exists\n        const existing = this.staticColliders.get(mesh.uuid);\n        if (existing) {\n            this.removeStaticCollider(mesh);\n        }\n\n        mesh.matrixWorld.decompose(TMP_TRANSLATION, TMP_ROTATION, TMP_WORLD_SCALE);\n\n        // Build trimesh\n        const positionAttr = geometry.attributes.position;\n        const vertexCount = positionAttr.count;\n        const vertices = new Float32Array(vertexCount * 3);\n\n        for (let i = 0; i < vertexCount; i++) {\n            vertices[3 * i + 0] = positionAttr.getX(i) * TMP_WORLD_SCALE.x;\n            vertices[3 * i + 1] = positionAttr.getY(i) * TMP_WORLD_SCALE.y;\n            vertices[3 * i + 2] = positionAttr.getZ(i) * TMP_WORLD_SCALE.z;\n        }\n\n        const indexAttr = geometry.getIndex();\n        let indices;\n        if (indexAttr) {\n            const src = indexAttr.array;\n            indices = new Uint32Array(src.length);\n            for (let i = 0; i < src.length; i++) {\n                indices[i] = src[i];\n            }\n        } else {\n            indices = new Uint32Array(vertexCount);\n            for (let i = 0; i < vertexCount; i++) {\n                indices[i] = i;\n            }\n        }\n\n        try {\n            const { RAPIER } = this.core;\n            const bodyDesc = RAPIER.RigidBodyDesc.fixed()\n                .setTranslation(TMP_TRANSLATION.x, TMP_TRANSLATION.y, TMP_TRANSLATION.z)\n                .setRotation({ x: TMP_ROTATION.x, y: TMP_ROTATION.y, z: TMP_ROTATION.z, w: TMP_ROTATION.w });\n\n            const body = this.core.world.createRigidBody(bodyDesc);\n\n            const colliderDesc = RAPIER.ColliderDesc.trimesh(vertices, indices)\n                .setRestitution(0)\n                .setFriction(0.9);\n\n            const collider = this.core.world.createCollider(colliderDesc, body);\n\n            const colliderData = { body, collider, mesh };\n            this.staticColliders.set(mesh.uuid, colliderData);\n\n            return colliderData;\n        } catch (error) {\n            console.error('[PhysicsSystem] Failed to create trimesh collider:', error);\n            return null;\n        }\n    }\n\n    /**\n     * Remove static collider\n     */\n    removeStaticCollider(mesh) {\n        if (!mesh || !this.core) return;\n\n        if (this._isUpdating) {\n            this._deferredOps.push({ type: 'static-remove', mesh });\n            return;\n        }\n\n        const entry = this.staticColliders.get(mesh.uuid);\n        if (!entry) return;\n\n        if (entry.collider && this.core.world) {\n            this.core.world.removeCollider(entry.collider, true);\n        }\n\n        this.staticColliders.delete(mesh.uuid);\n    }\n\n    /**\n     * Configure character controller\n     */\n    async configureCharacter(options = {}) {\n        await this.initialize();\n        if (!this.core?.RAPIER) return;\n\n        const {\n            position = new THREE.Vector3(0, this.planetRadius + 2, 0),\n            eyeHeight = 1.6,\n            radius = 0.35,\n            halfHeight = 0.45\n        } = options;\n\n        const { RAPIER } = this.core;\n        const controller = this.core.world.createCharacterController(0.01);\n        controller.setApplyImpulsesToDynamicBodies(false);\n        controller.enableAutostep?.(0.4, 0.4, true);\n        controller.enableSnapToGround?.(0.3, 0.6);\n\n        const offset = eyeHeight - (radius + halfHeight);\n        const center = position.clone();\n        center.y -= offset;\n\n        const colliderDesc = RAPIER.ColliderDesc.capsule(halfHeight, radius)\n            .setFriction(0.0)\n            .setRestitution(0.0)\n            .setTranslation(center.x, center.y, center.z);\n\n        const collider = this.core.world.createCollider(colliderDesc);\n\n        this.character = {\n            controller,\n            collider,\n            radius,\n            halfHeight,\n            offset\n        };\n\n        this.characterReady = true;\n    }\n\n    /**\n     * Update physics simulation\n     * @param {number} dt - Delta time in seconds\n     * @param {THREE.Vector3} gravityCenter - Point to pull objects toward (globe center)\n     */\n    update(dt, gravityCenter = new THREE.Vector3(0, 0, 0)) {\n        if (!this.core?.world) return;\n        const hasActiveDynamics = this.dynamicObjects.size > 0;\n        const hasCharacterController = !!this.characterReady;\n        if (!hasActiveDynamics && !hasCharacterController) {\n            if (this._deferredOps.length > 0) {\n                this._processDeferredOps();\n            }\n            return;\n        }\n\n        // Set flag to defer operations during update\n        this._isUpdating = true;\n\n        try {\n            const stepDt = THREE.MathUtils.clamp(\n                Number.isFinite(dt) ? dt : (1 / 60),\n                this._fixedMinStep,\n                this._fixedMaxStep\n            );\n\n            // Apply radial gravity to all dynamic objects\n            for (const mesh of this.dynamicObjects) {\n                const body = mesh.userData.physics?.body;\n                if (!body || typeof body.translation !== 'function') continue;\n\n                const translation = body.translation();\n                const previous = mesh.userData.physics?.previousWorldPosition;\n                if (previous) previous.set(translation.x, translation.y, translation.z);\n                TMP_TRANSLATION.set(translation.x, translation.y, translation.z);\n\n                // Calculate gravity direction (toward center)\n                TMP_GRAVITY.copy(gravityCenter).sub(TMP_TRANSLATION).normalize();\n                TMP_GRAVITY.multiplyScalar(this.gravityStrength);\n\n                // Apply gravity force\n                body.applyImpulse?.(\n                    { x: TMP_GRAVITY.x * stepDt, y: TMP_GRAVITY.y * stepDt, z: TMP_GRAVITY.z * stepDt },\n                    true\n                );\n            }\n\n            // Step simulation in the same update loop that mutates the world.\n            this.core.world.timestep = stepDt;\n            this.core.world.step();\n            this._resolveStreamedSurfaceContacts();\n            this._syncDynamicMeshesFromBodies();\n\n            // Update impact detection\n            if (this._characterImpactCooldown > 0) {\n                this._characterImpactCooldown = Math.max(0, this._characterImpactCooldown - stepDt);\n            }\n\n            this._updateDynamicImpacts(stepDt);\n        } finally {\n            // Clear flag\n            this._isUpdating = false;\n\n            // Process any deferred operations\n            this._processDeferredOps();\n        }\n    }\n\n    /**\n     * Process deferred add/remove operations that were queued during update\n     */\n    _processDeferredOps() {\n        if (this._deferredOps.length === 0) return;\n\n        const ops = this._deferredOps.slice();\n        this._deferredOps = [];\n\n        for (const op of ops) {\n            if (op.type === 'add') {\n                this.addPhysicsObject(op.mesh, op.options);\n            } else if (op.type === 'remove') {\n                this.removePhysicsObject(op.mesh);\n            } else if (op.type === 'static-add') {\n                this.addStaticCollider(op.mesh);\n            } else if (op.type === 'static-remove') {\n                this.removeStaticCollider(op.mesh);\n            }\n        }\n    }\n\n    _syncDynamicMeshesFromBodies() {\n        for (const mesh of this.dynamicObjects) {\n            const body = mesh?.userData?.physics?.body;\n            if (!body) continue;\n            const position = body.translation?.();\n            const rotation = body.rotation?.();\n            if (!position || !rotation) continue;\n            mesh.position.set(position.x, position.y, position.z);\n            mesh.quaternion.set(rotation.x, rotation.y, rotation.z, rotation.w);\n        }\n    }\n\n    _resolveStreamedSurfaceContacts() {\n        if (!this._surfaceCollisionResolver || this.dynamicObjects.size === 0) return;\n\n        for (const mesh of this.dynamicObjects) {\n            const physics = mesh?.userData?.physics;\n            const body = physics?.body;\n            const previous = physics?.previousWorldPosition;\n            if (!body || !previous || typeof body.translation !== 'function') continue;\n\n            const translation = body.translation();\n            const proposed = physics.resolvedWorldPosition\n                || (physics.resolvedWorldPosition = new THREE.Vector3());\n            proposed.set(translation.x, translation.y, translation.z);\n            const radius = Number.isFinite(physics.surfaceCollisionRadius)\n                ? physics.surfaceCollisionRadius\n                : 0.25;\n\n            let contact = null;\n            try {\n                contact = this._surfaceCollisionResolver(previous, proposed, radius, mesh);\n            } catch (error) {\n                console.warn('[PhysicsSystem] Streamed surface contact failed:', error);\n                continue;\n            }\n            const position = contact?.position;\n            if (!position || !Number.isFinite(position.x)\n                || !Number.isFinite(position.y) || !Number.isFinite(position.z)) continue;\n\n            body.setTranslation?.({ x: position.x, y: position.y, z: position.z }, true);\n            const normal = contact.normal;\n            const velocity = body.linvel?.();\n            if (normal && velocity) {\n                TMP_LINEAR_VELOCITY.set(velocity.x, velocity.y, velocity.z);\n                const inwardSpeed = TMP_LINEAR_VELOCITY.dot(normal);\n                if (inwardSpeed < 0) {\n                    TMP_LINEAR_VELOCITY.addScaledVector(normal, -inwardSpeed);\n                    body.setLinvel?.({\n                        x: TMP_LINEAR_VELOCITY.x,\n                        y: TMP_LINEAR_VELOCITY.y,\n                        z: TMP_LINEAR_VELOCITY.z\n                    }, true);\n                }\n            }\n        }\n    }\n\n    /**\n     * Detect and emit impact sounds for dynamic objects\n     */\n    _updateDynamicImpacts(dt) {\n        if (!this.dynamicObjects.size) return;\n\n        const toRemove = [];\n\n        for (const mesh of this.dynamicObjects) {\n            if (!mesh || !mesh.userData) {\n                toRemove.push(mesh);\n                continue;\n            }\n\n            const physicsData = mesh.userData.physics;\n            const body = physicsData?.body;\n            if (!body || typeof body.linvel !== 'function') {\n                toRemove.push(mesh);\n                continue;\n            }\n\n            const state = mesh.userData._impactState;\n            if (!state) continue;\n\n            state.cooldown = Math.max(0, (state.cooldown || 0) - dt);\n\n            const lv = body.linvel();\n            TMP_LINEAR_VELOCITY.set(lv.x, lv.y, lv.z);\n            const speed = TMP_LINEAR_VELOCITY.length();\n\n            if (!state.ready) {\n                state.prevVel.copy(TMP_LINEAR_VELOCITY);\n                state.speed = speed;\n                state.ready = true;\n                continue;\n            }\n\n            TMP_VELOCITY_DELTA.copy(state.prevVel).sub(TMP_LINEAR_VELOCITY);\n\n            const deltaMag = TMP_VELOCITY_DELTA.length();\n            const speedDrop = Math.max(0, state.speed - speed);\n            const verticalDelta = Math.abs(state.prevVel.y - TMP_LINEAR_VELOCITY.y);\n            const magnitude = Math.max(deltaMag * 0.55, speedDrop, verticalDelta * 0.8);\n\n            if (this.audioSystem && state.cooldown <= 0 && magnitude > 0.75) {\n                const pos = body.translation?.();\n                if (pos) {\n                    const impactPos = new THREE.Vector3(pos.x, pos.y, pos.z);\n                    this._emitImpactSound(impactPos, magnitude);\n                    state.cooldown = 0.085 + Math.min(0.25, magnitude * 0.025);\n                }\n            }\n\n            state.prevVel.copy(TMP_LINEAR_VELOCITY);\n            state.speed = speed;\n        }\n\n        for (const mesh of toRemove) {\n            this.dynamicObjects.delete(mesh);\n        }\n    }\n\n    /**\n     * Emit impact sound through audio system\n     */\n    _emitImpactSound(position, magnitude = 1) {\n        if (!this.audioSystem || !position) return;\n\n        const mag = Math.max(0, magnitude);\n        const baseFreq = 240 + Math.min(680, mag * 140);\n        const frequency = Math.max(60, baseFreq + (Math.random() - 0.5) * 40);\n        const roughness = THREE.MathUtils.clamp(0.28 + mag * 0.08, 0.15, 0.85);\n        const decay = 0.14 + Math.min(0.3, mag * 0.05);\n        const intensity = 0.25 + mag * 0.32;\n\n        this.audioSystem.triggerImpact(position, {\n            intensity,\n            frequency,\n            roughness,\n            decay\n        });\n    }\n\n    /**\n     * Spawn a test ball (useful for testing)\n     */\n    spawnTestBall(options = {}) {\n        if (!this.core) return null;\n\n        const {\n            radius = 0.2,\n            mass = 0.5,\n            restitution = 0.2,\n            color = 0xffffff,\n            origin = new THREE.Vector3(0, this.planetRadius + 3, 0)\n        } = options;\n\n        const geometry = new THREE.SphereGeometry(radius, 24, 24);\n        const material = new THREE.MeshStandardMaterial({ color });\n        const ball = new THREE.Mesh(geometry, material);\n        ball.castShadow = true;\n        ball.receiveShadow = true;\n        ball.name = 'physics-test-ball';\n\n        ball.position.copy(origin);\n\n        this.scene.add(ball);\n        this.addPhysicsObject(ball, { mass, restitution, radius });\n\n        return ball;\n    }\n\n    /**\n     * Clean up physics system\n     */\n    dispose() {\n        if (this._disposed) return;\n        this._disposed = true;\n        this._deferredOps = [];\n\n        for (const mesh of this.dynamicObjects) {\n            this.removePhysicsObject(mesh);\n        }\n        this.dynamicObjects.clear();\n\n        for (const entry of this.staticColliders.values()) {\n            if (entry.collider && this.core?.world) {\n                this.core.world.removeCollider(entry.collider, true);\n            }\n        }\n        this.staticColliders.clear();\n\n        if (this.character?.collider && this.core?.world) {\n            this.core.world.removeCollider(this.character.collider, true);\n        }\n        this.character = null;\n        this.characterReady = false;\n        // Rapier worlds own native allocations, including bodies and controllers.\n        this.core?.world.free();\n        this.core = null;\n        this._surfaceCollisionResolver = null;\n    }\n\n    get initializationState() {\n        if (this.core?.RAPIER) return 'ready';\n        if (this.initializationError) return 'failed';\n        if (this._initializing) return 'loading';\n        return this._initializationRequested ? 'idle' : 'deferred';\n    }\n}\n","/**\n * ProximityTrigger\n *\n * Generic proximity-based trigger system for overlay assets.\n * Supports multiple trigger types:\n * - audio: Play sound when within N meters\n * - motion: Animate object when approached\n * - scale: Change scale based on distance\n * - visibility: Show/hide based on proximity\n * - custom: Execute custom callback\n *\n * Usage:\n *   const trigger = new ProximityTrigger({\n *     object3d: mesh,\n *     triggerDistance: 10,\n *     actions: [\n *       { type: 'audio', sound: '/path/to/sound.wav', volume: 0.8, loop: false },\n *       { type: 'scale', from: 1.0, to: 1.5, duration: 0.5 }\n *     ]\n *   });\n *   trigger.update(cameraPosition, dt);\n */\n\nimport * as THREE from 'three';\n\nexport class ProximityTrigger {\n    constructor(options = {}) {\n        const {\n            object3d = null,\n            triggerDistance = 10,\n            exitDistance = null,\n            actions = [],\n            audioSystem = null,\n            once = false,\n            cooldown = 0,\n            debugName = 'ProximityTrigger'\n        } = options;\n\n        this.object3d = object3d;\n        this.triggerDistance = triggerDistance;\n        this.exitDistance = exitDistance ?? triggerDistance * 1.2;\n        this.actions = actions;\n        this.audioSystem = audioSystem;\n        this.once = once;\n        this.cooldown = cooldown;\n        this.debugName = debugName;\n\n        // State\n        this.isActive = false;\n        this.hasTriggered = false;\n        this._cooldownTimer = 0;\n        this._activeAudio = null;\n        this._animations = new Map();\n    }\n\n    /**\n     * Update trigger based on observer position\n     * @param {THREE.Vector3} observerPos - Camera or player position\n     * @param {number} dt - Delta time in seconds\n     */\n    update(observerPos, dt) {\n        if (!this.object3d || !observerPos) return;\n\n        // Update cooldown\n        if (this._cooldownTimer > 0) {\n            this._cooldownTimer -= dt;\n        }\n\n        // Get trigger position (use audioAnchor if available, otherwise object position)\n        const triggerPos = this.object3d.userData?.audioAnchor?.getWorldPosition(new THREE.Vector3())\n            || this.object3d.getWorldPosition(new THREE.Vector3());\n\n        const distance = observerPos.distanceTo(triggerPos);\n\n        // Check trigger state\n        const wasActive = this.isActive;\n        const shouldActivate = distance <= this.triggerDistance;\n        const shouldDeactivate = distance > this.exitDistance;\n\n        if (shouldActivate && !this.isActive) {\n            // Enter trigger zone\n            if (this.once && this.hasTriggered) return;\n            if (this._cooldownTimer > 0) return;\n\n            this._onEnter(triggerPos, distance);\n        } else if (shouldDeactivate && this.isActive) {\n            // Exit trigger zone\n            this._onExit(triggerPos);\n        }\n\n        // Update active animations\n        this._updateAnimations(dt);\n    }\n\n    /**\n     * Trigger enter handler\n     */\n    _onEnter(position, distance) {\n        this.isActive = true;\n        this.hasTriggered = true;\n\n        for (const action of this.actions) {\n            this._executeAction(action, position, distance, true);\n        }\n    }\n\n    /**\n     * Trigger exit handler\n     */\n    _onExit(position) {\n        this.isActive = false;\n        this._cooldownTimer = this.cooldown;\n\n        for (const action of this.actions) {\n            this._executeAction(action, position, 0, false);\n        }\n    }\n\n    /**\n     * Execute a trigger action\n     */\n    _executeAction(action, position, distance, isEntering) {\n        const type = action.type || 'audio';\n\n        switch (type) {\n            case 'audio':\n                this._handleAudioAction(action, position, isEntering);\n                break;\n\n            case 'motion':\n                this._handleMotionAction(action, isEntering);\n                break;\n\n            case 'scale':\n                this._handleScaleAction(action, isEntering);\n                break;\n\n            case 'visibility':\n                this._handleVisibilityAction(action, isEntering);\n                break;\n\n            case 'rotation':\n                this._handleRotationAction(action, isEntering);\n                break;\n\n            case 'custom':\n                this._handleCustomAction(action, position, distance, isEntering);\n                break;\n\n            default:\n                console.warn(`[ProximityTrigger] Unknown action type: ${type}`);\n        }\n    }\n\n    /**\n     * Audio action: Play sound at trigger position\n     */\n    _handleAudioAction(action, position, isEntering) {\n        if (isEntering) {\n            if (this._activeAudio) {\n                this._activeAudio.stop?.();\n                this._activeAudio = null;\n            }\n\n            if (this.audioSystem && action.sound) {\n                const volume = action.volume ?? 1.0;\n                const loop = action.loop ?? false;\n                const refDistance = action.refDistance ?? 10;\n                const rolloff = action.rolloff ?? 1.0;\n\n                this.audioSystem.playSound(action.sound, position, {\n                    volume,\n                    loop,\n                    refDistance,\n                    rolloff,\n                    onEnd: () => {\n                        if (this._activeAudio) {\n                            this._activeAudio = null;\n                        }\n                    }\n                }).then((audioControl) => {\n                    this._activeAudio = audioControl;\n                });\n            }\n        } else {\n            // Exiting - stop looping audio\n            if (this._activeAudio && action.stopOnExit !== false) {\n                this._activeAudio.stop?.();\n                this._activeAudio = null;\n            }\n        }\n    }\n\n    /**\n     * Motion action: Animate position offset\n     */\n    _handleMotionAction(action, isEntering) {\n        const offset = action.offset || new THREE.Vector3(0, 1, 0);\n        const duration = action.duration ?? 1.0;\n        const easing = action.easing || 'easeInOutQuad';\n\n        const startPos = this.object3d.position.clone();\n        const targetPos = isEntering\n            ? startPos.clone().add(offset)\n            : startPos.clone().sub(offset);\n\n        this._startAnimation('motion', {\n            duration,\n            easing,\n            onUpdate: (t) => {\n                this.object3d.position.lerpVectors(startPos, targetPos, t);\n            }\n        });\n    }\n\n    /**\n     * Scale action: Animate scale\n     */\n    _handleScaleAction(action, isEntering) {\n        const from = action.from ?? 1.0;\n        const to = action.to ?? 1.5;\n        const duration = action.duration ?? 0.5;\n        const easing = action.easing || 'easeInOutQuad';\n\n        const startScale = isEntering ? from : to;\n        const targetScale = isEntering ? to : from;\n\n        this._startAnimation('scale', {\n            duration,\n            easing,\n            onUpdate: (t) => {\n                const scale = THREE.MathUtils.lerp(startScale, targetScale, t);\n                this.object3d.scale.setScalar(scale);\n            }\n        });\n    }\n\n    /**\n     * Visibility action: Show/hide object\n     */\n    _handleVisibilityAction(action, isEntering) {\n        const fadeIn = action.fadeIn ?? false;\n        const duration = action.duration ?? 0.3;\n\n        if (fadeIn) {\n            const startOpacity = isEntering ? 0 : 1;\n            const targetOpacity = isEntering ? 1 : 0;\n\n            this.object3d.visible = true;\n\n            this._startAnimation('visibility', {\n                duration,\n                easing: 'linear',\n                onUpdate: (t) => {\n                    const opacity = THREE.MathUtils.lerp(startOpacity, targetOpacity, t);\n                    this.object3d.traverse((child) => {\n                        if (child.material) {\n                            child.material.opacity = opacity;\n                            child.material.transparent = true;\n                            child.material.needsUpdate = true;\n                        }\n                    });\n                },\n                onComplete: () => {\n                    if (!isEntering) {\n                        this.object3d.visible = false;\n                    }\n                }\n            });\n        } else {\n            this.object3d.visible = isEntering;\n        }\n    }\n\n    /**\n     * Rotation action: Animate rotation\n     */\n    _handleRotationAction(action, isEntering) {\n        const axis = action.axis || new THREE.Vector3(0, 1, 0);\n        const angle = action.angle ?? Math.PI * 2;\n        const duration = action.duration ?? 2.0;\n        const continuous = action.continuous ?? false;\n\n        if (continuous && isEntering) {\n            this._startAnimation('rotation', {\n                duration: Infinity,\n                easing: 'linear',\n                onUpdate: (t, elapsed) => {\n                    const rotation = (elapsed / duration) * angle;\n                    this.object3d.rotateOnAxis(axis, rotation - (this.object3d.userData._lastRotation || 0));\n                    this.object3d.userData._lastRotation = rotation;\n                }\n            });\n        } else if (!continuous) {\n            const startRotation = 0;\n            const targetRotation = isEntering ? angle : 0;\n\n            this._startAnimation('rotation', {\n                duration,\n                easing: 'easeInOutQuad',\n                onUpdate: (t) => {\n                    const rotation = THREE.MathUtils.lerp(startRotation, targetRotation, t);\n                    const deltaRotation = rotation - (this.object3d.userData._lastRotation || 0);\n                    this.object3d.rotateOnAxis(axis, deltaRotation);\n                    this.object3d.userData._lastRotation = rotation;\n                }\n            });\n        } else {\n            // Stop continuous rotation\n            this._stopAnimation('rotation');\n        }\n    }\n\n    /**\n     * Custom action: Execute user callback\n     */\n    _handleCustomAction(action, position, distance, isEntering) {\n        if (typeof action.callback === 'function') {\n            action.callback({\n                object3d: this.object3d,\n                position,\n                distance,\n                isEntering,\n                trigger: this\n            });\n        }\n    }\n\n    /**\n     * Start an animation\n     */\n    _startAnimation(name, config) {\n        this._stopAnimation(name);\n\n        this._animations.set(name, {\n            elapsed: 0,\n            duration: config.duration,\n            easing: config.easing,\n            onUpdate: config.onUpdate,\n            onComplete: config.onComplete\n        });\n    }\n\n    /**\n     * Stop an animation\n     */\n    _stopAnimation(name) {\n        this._animations.delete(name);\n    }\n\n    /**\n     * Update all active animations\n     */\n    _updateAnimations(dt) {\n        for (const [name, anim] of this._animations.entries()) {\n            anim.elapsed += dt;\n\n            const t = anim.duration === Infinity\n                ? 1\n                : Math.min(1, anim.elapsed / anim.duration);\n\n            const easedT = this._ease(t, anim.easing);\n\n            if (anim.onUpdate) {\n                anim.onUpdate(easedT, anim.elapsed);\n            }\n\n            if (t >= 1 && anim.duration !== Infinity) {\n                if (anim.onComplete) {\n                    anim.onComplete();\n                }\n                this._animations.delete(name);\n            }\n        }\n    }\n\n    /**\n     * Easing functions\n     */\n    _ease(t, easing) {\n        switch (easing) {\n            case 'linear':\n                return t;\n            case 'easeInQuad':\n                return t * t;\n            case 'easeOutQuad':\n                return t * (2 - t);\n            case 'easeInOutQuad':\n                return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;\n            case 'easeInCubic':\n                return t * t * t;\n            case 'easeOutCubic':\n                return (--t) * t * t + 1;\n            case 'easeInOutCubic':\n                return t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1;\n            default:\n                return t;\n        }\n    }\n\n    /**\n     * Reset trigger state\n     */\n    reset() {\n        this.isActive = false;\n        this.hasTriggered = false;\n        this._cooldownTimer = 0;\n\n        if (this._activeAudio) {\n            this._activeAudio.stop?.();\n            this._activeAudio = null;\n        }\n\n        this._animations.clear();\n    }\n\n    /**\n     * Clean up\n     */\n    dispose() {\n        this.reset();\n        this.object3d = null;\n        this.audioSystem = null;\n        this.actions = [];\n    }\n}\n\n/**\n * ProximityTriggerManager\n *\n * Manages multiple proximity triggers\n */\nexport class ProximityTriggerManager {\n    constructor({ audioSystem = null } = {}) {\n        this.audioSystem = audioSystem;\n        this.triggers = new Map();\n    }\n\n    /**\n     * Add a proximity trigger\n     */\n    addTrigger(id, options) {\n        if (this.triggers.has(id)) {\n            this.removeTrigger(id);\n        }\n\n        const trigger = new ProximityTrigger({\n            ...options,\n            audioSystem: this.audioSystem\n        });\n\n        this.triggers.set(id, trigger);\n        return trigger;\n    }\n\n    /**\n     * Remove a trigger\n     */\n    removeTrigger(id) {\n        const trigger = this.triggers.get(id);\n        if (trigger) {\n            trigger.dispose();\n            this.triggers.delete(id);\n        }\n    }\n\n    /**\n     * Update all triggers\n     */\n    update(observerPos, dt) {\n        for (const trigger of this.triggers.values()) {\n            trigger.update(observerPos, dt);\n        }\n    }\n\n    /**\n     * Clean up all triggers\n     */\n    dispose() {\n        for (const trigger of this.triggers.values()) {\n            trigger.dispose();\n        }\n        this.triggers.clear();\n    }\n}\n","/**\n * ClickTrigger & ClickTriggerManager\n *\n * Raycast-based click detection system for overlay assets with:\n * - Click/touch interaction detection\n * - Conditional triggers (proximity, state, custom)\n * - Nested action execution\n * - Visual feedback (hover, click)\n *\n * Usage:\n *   const manager = new ClickTriggerManager({\n *     camera,\n *     domElement: renderer.domElement,\n *     audioSystem,\n *     physicsSystem\n *   });\n *\n *   manager.addTrigger('my-object', {\n *     object3d: mesh,\n *     conditions: [\n *       { type: 'proximity', distance: 100 }\n *     ],\n *     actions: [\n *       { type: 'physics', spawn: true }\n *     ]\n *   });\n */\n\nimport * as THREE from 'three';\n\nexport class ClickTrigger {\n    constructor(options = {}) {\n        const {\n            object3d = null,\n            conditions = [],\n            actions = [],\n            hoverEnabled = true,\n            clickEnabled = true,\n            audioSystem = null,\n            physicsSystem = null,\n            debugName = 'ClickTrigger'\n        } = options;\n\n        this.object3d = object3d;\n        this.conditions = conditions;\n        this.actions = actions;\n        this.hoverEnabled = hoverEnabled;\n        this.clickEnabled = clickEnabled;\n        this.audioSystem = audioSystem;\n        this.physicsSystem = physicsSystem;\n        this.debugName = debugName;\n\n        // State\n        this.isHovered = false;\n        this.isClicked = false;\n        this.clickCount = 0;\n        this._originalMaterial = null;\n        this._hoverMaterial = null;\n    }\n\n    /**\n     * Check if all conditions are met\n     */\n    checkConditions(context = {}) {\n        if (this.conditions.length === 0) return true;\n\n        for (const condition of this.conditions) {\n            if (!this._evaluateCondition(condition, context)) {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    /**\n     * Evaluate a single condition\n     */\n    _evaluateCondition(condition, context) {\n        const type = condition.type || 'proximity';\n\n        switch (type) {\n            case 'proximity':\n                return this._checkProximity(condition, context);\n\n            case 'state':\n                return this._checkState(condition);\n\n            case 'click_count':\n                return this._checkClickCount(condition);\n\n            case 'custom':\n                return this._checkCustom(condition, context);\n\n            default:\n                console.warn(`[ClickTrigger] Unknown condition type: ${type}`);\n                return true;\n        }\n    }\n\n    /**\n     * Check proximity condition\n     */\n    _checkProximity(condition, context) {\n        if (!context.observerPos || !this.object3d) return false;\n\n        const targetPos = this.object3d.userData?.audioAnchor?.getWorldPosition(new THREE.Vector3())\n            || this.object3d.getWorldPosition(new THREE.Vector3());\n\n        const distance = context.observerPos.distanceTo(targetPos);\n        const maxDistance = condition.distance ?? 100;\n        const minDistance = condition.min_distance ?? 0;\n\n        return distance >= minDistance && distance <= maxDistance;\n    }\n\n    /**\n     * Check state condition\n     */\n    _checkState(condition) {\n        if (!this.object3d?.userData) return false;\n\n        const key = condition.key || 'state';\n        const value = condition.value;\n        const actual = this.object3d.userData[key];\n\n        if (condition.operator === 'not_equals') {\n            return actual !== value;\n        }\n\n        return actual === value;\n    }\n\n    /**\n     * Check click count condition\n     */\n    _checkClickCount(condition) {\n        const min = condition.min ?? 0;\n        const max = condition.max ?? Infinity;\n        return this.clickCount >= min && this.clickCount <= max;\n    }\n\n    /**\n     * Check custom condition\n     */\n    _checkCustom(condition, context) {\n        if (typeof condition.check === 'function') {\n            return condition.check({\n                object3d: this.object3d,\n                context,\n                trigger: this\n            });\n        }\n        return true;\n    }\n\n    /**\n     * Execute click actions\n     */\n    executeActions(context = {}) {\n        this.clickCount++;\n        this.isClicked = true;\n\n        console.log(`[ClickTrigger] ${this.debugName} clicked (count: ${this.clickCount})`);\n\n        for (const action of this.actions) {\n            this._executeAction(action, context);\n        }\n\n        // Reset clicked state after brief delay\n        setTimeout(() => {\n            this.isClicked = false;\n        }, 100);\n    }\n\n    /**\n     * Execute a single action\n     */\n    _executeAction(action, context) {\n        const type = action.type || 'custom';\n\n        switch (type) {\n            case 'physics':\n                this._handlePhysicsAction(action);\n                break;\n\n            case 'audio':\n                this._handleAudioAction(action, context);\n                break;\n\n            case 'state':\n                this._handleStateAction(action);\n                break;\n\n            case 'visibility':\n                this._handleVisibilityAction(action);\n                break;\n\n            case 'material':\n                this._handleMaterialAction(action);\n                break;\n\n            case 'custom':\n                this._handleCustomAction(action, context);\n                break;\n\n            default:\n                console.warn(`[ClickTrigger] Unknown action type: ${type}`);\n        }\n    }\n\n    /**\n     * Physics action: Enable/spawn physics\n     */\n    _handlePhysicsAction(action) {\n        if (!this.physicsSystem || !this.object3d) return;\n\n        if (action.spawn === true && !this.object3d.userData.hasPhysics) {\n            const mass = action.mass ?? 1.0;\n            const restitution = action.restitution ?? 0.3;\n            const friction = action.friction ?? 0.7;\n            const radius = action.radius ?? null;\n\n            const physicsData = this.physicsSystem.addPhysicsObject(this.object3d, {\n                mass,\n                restitution,\n                friction,\n                radius\n            });\n\n            if (physicsData) {\n                this.object3d.userData.hasPhysics = true;\n                this.object3d.userData.physicsData = physicsData;\n                console.log(`[ClickTrigger] ⚾ Physics spawned on ${this.debugName}`);\n            }\n        }\n    }\n\n    /**\n     * Audio action: Play sound\n     */\n    _handleAudioAction(action, context) {\n        if (!this.audioSystem || !this.object3d) return;\n\n        const position = this.object3d.getWorldPosition(new THREE.Vector3());\n        const sound = action.sound || action.url;\n\n        if (sound) {\n            this.audioSystem.playSound(sound, position, {\n                volume: action.volume ?? 0.8,\n                loop: action.loop ?? false,\n                refDistance: action.refDistance ?? 10,\n                rolloff: action.rolloff ?? 1.0\n            });\n        } else if (action.blip) {\n            this.audioSystem.triggerBlip(position, action.intensity ?? 0.5);\n        }\n    }\n\n    /**\n     * State action: Set userData state\n     */\n    _handleStateAction(action) {\n        if (!this.object3d?.userData) return;\n\n        const key = action.key || 'state';\n        const value = action.value;\n\n        this.object3d.userData[key] = value;\n        console.log(`[ClickTrigger] State set: ${key} = ${value}`);\n    }\n\n    /**\n     * Visibility action: Show/hide\n     */\n    _handleVisibilityAction(action) {\n        if (!this.object3d) return;\n\n        this.object3d.visible = action.visible ?? !this.object3d.visible;\n    }\n\n    /**\n     * Material action: Change material properties\n     */\n    _handleMaterialAction(action) {\n        if (!this.object3d) return;\n\n        this.object3d.traverse((child) => {\n            if (child.isMesh && child.material) {\n                if (action.color) {\n                    child.material.color.set(action.color);\n                }\n                if (action.emissive !== undefined) {\n                    child.material.emissive?.set(action.emissive);\n                }\n                if (action.opacity !== undefined) {\n                    child.material.opacity = action.opacity;\n                    child.material.transparent = action.opacity < 1;\n                }\n                child.material.needsUpdate = true;\n            }\n        });\n    }\n\n    /**\n     * Custom action: Execute callback\n     */\n    _handleCustomAction(action, context) {\n        if (typeof action.callback === 'function') {\n            action.callback({\n                object3d: this.object3d,\n                context,\n                trigger: this,\n                clickCount: this.clickCount\n            });\n        }\n    }\n\n    /**\n     * Handle hover enter\n     */\n    onHoverEnter() {\n        if (!this.hoverEnabled) return;\n\n        this.isHovered = true;\n\n        // Apply hover effect\n        if (this.object3d) {\n            this._applyHoverEffect(true);\n        }\n    }\n\n    /**\n     * Handle hover exit\n     */\n    onHoverExit() {\n        if (!this.hoverEnabled) return;\n\n        this.isHovered = false;\n\n        // Remove hover effect\n        if (this.object3d) {\n            this._applyHoverEffect(false);\n        }\n    }\n\n    /**\n     * Apply hover visual effect\n     */\n    _applyHoverEffect(enable) {\n        if (!this.object3d) return;\n        // Objects with their own affordance (e.g. theater screens) handle it.\n        const hook = this.object3d.userData?.onHoverChange;\n        if (typeof hook === 'function') {\n            hook(enable);\n            return;\n        }\n\n        this.object3d.traverse((child) => {\n            if (child.isMesh && child.material) {\n                if (enable) {\n                    // Store original and apply hover\n                    if (!child.userData._originalEmissive) {\n                        child.userData._originalEmissive = child.material.emissive?.clone() || new THREE.Color(0x000000);\n                    }\n                    if (child.material.emissive) {\n                        child.material.emissive.setHex(0x444444);\n                    }\n                } else {\n                    // Restore original\n                    if (child.userData._originalEmissive && child.material.emissive) {\n                        child.material.emissive.copy(child.userData._originalEmissive);\n                    }\n                }\n                child.material.needsUpdate = true;\n            }\n        });\n    }\n\n    /**\n     * Clean up\n     */\n    dispose() {\n        if (this.object3d && this.isHovered) {\n            this._applyHoverEffect(false);\n        }\n        this.object3d = null;\n        this.audioSystem = null;\n        this.physicsSystem = null;\n    }\n}\n\n/**\n * ClickTriggerManager\n *\n * Manages click triggers with raycasting\n */\nexport class ClickTriggerManager {\n    constructor(options = {}) {\n        const {\n            camera = null,\n            domElement = null,\n            audioSystem = null,\n            physicsSystem = null\n        } = options;\n\n        this.camera = camera;\n        this.domElement = domElement;\n        this.audioSystem = audioSystem;\n        this.physicsSystem = physicsSystem;\n\n        this.triggers = new Map();\n        this.raycaster = new THREE.Raycaster();\n        this.mouse = new THREE.Vector2();\n        this.hoveredTrigger = null;\n        this.observerPos = new THREE.Vector3();\n\n        this._setupEventListeners();\n    }\n\n    /**\n     * Setup DOM event listeners\n     */\n    _setupEventListeners() {\n        if (!this.domElement) return;\n\n        this._onPointerMove = this._handlePointerMove.bind(this);\n        this._onPointerDown = this._handlePointerDown.bind(this);\n\n        this.domElement.addEventListener('pointermove', this._onPointerMove);\n        this.domElement.addEventListener('pointerdown', this._onPointerDown);\n    }\n\n    /**\n     * Add a click trigger\n     */\n    addTrigger(id, options) {\n        if (this.triggers.has(id)) {\n            this.removeTrigger(id);\n        }\n\n        const trigger = new ClickTrigger({\n            ...options,\n            audioSystem: this.audioSystem,\n            physicsSystem: this.physicsSystem\n        });\n\n        this.triggers.set(id, trigger);\n        return trigger;\n    }\n\n    /**\n     * Remove a trigger\n     */\n    removeTrigger(id) {\n        const trigger = this.triggers.get(id);\n        if (trigger) {\n            trigger.dispose();\n            this.triggers.delete(id);\n        }\n    }\n\n    /**\n     * Update observer position (camera)\n     */\n    update(observerPos) {\n        if (observerPos) {\n            this.observerPos.copy(observerPos);\n        }\n    }\n\n    /**\n     * Handle pointer move for hover detection\n     */\n    _handlePointerMove(event) {\n        if (!this.camera || !this.domElement) return;\n\n        // Calculate mouse position\n        const rect = this.domElement.getBoundingClientRect();\n        this.mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;\n        this.mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;\n\n        // Raycast\n        this.raycaster.setFromCamera(this.mouse, this.camera);\n\n        // Get all clickable objects\n        const objects = [];\n        for (const trigger of this.triggers.values()) {\n            if (trigger.object3d && trigger.hoverEnabled) {\n                // Check conditions\n                const context = { observerPos: this.observerPos };\n                if (trigger.checkConditions(context)) {\n                    objects.push({ object: trigger.object3d, trigger });\n                }\n            }\n        }\n\n        // Find intersections\n        const intersects = this.raycaster.intersectObjects(\n            objects.map(o => o.object),\n            true\n        );\n\n        // Update hover state\n        if (intersects.length > 0) {\n            // Find the trigger for the intersected object\n            const intersectedObj = intersects[0].object;\n            let foundTrigger = null;\n\n            for (const { object, trigger } of objects) {\n                if (object === intersectedObj || object.getObjectById(intersectedObj.id)) {\n                    foundTrigger = trigger;\n                    break;\n                }\n            }\n\n            if (foundTrigger && foundTrigger !== this.hoveredTrigger) {\n                // Exit previous hover\n                if (this.hoveredTrigger) {\n                    this.hoveredTrigger.onHoverExit();\n                }\n\n                // Enter new hover\n                this.hoveredTrigger = foundTrigger;\n                this.hoveredTrigger.onHoverEnter();\n\n                // Change cursor\n                this.domElement.style.cursor = 'pointer';\n            }\n        } else {\n            // Exit hover\n            if (this.hoveredTrigger) {\n                this.hoveredTrigger.onHoverExit();\n                this.hoveredTrigger = null;\n                this.domElement.style.cursor = 'default';\n            }\n        }\n    }\n\n    /**\n     * Handle pointer down for click detection\n     */\n    _handlePointerDown(event) {\n        if (!this.camera || !this.domElement) return;\n\n        // Calculate mouse position\n        const rect = this.domElement.getBoundingClientRect();\n        this.mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;\n        this.mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;\n\n        // Raycast\n        this.raycaster.setFromCamera(this.mouse, this.camera);\n\n        // Get all clickable objects\n        const objects = [];\n        for (const trigger of this.triggers.values()) {\n            if (trigger.object3d && trigger.clickEnabled) {\n                // Check conditions\n                const context = { observerPos: this.observerPos };\n                if (trigger.checkConditions(context)) {\n                    objects.push({ object: trigger.object3d, trigger });\n                }\n            }\n        }\n\n        // Find intersections\n        const intersects = this.raycaster.intersectObjects(\n            objects.map(o => o.object),\n            true\n        );\n\n        // Execute click actions\n        if (intersects.length > 0) {\n            const intersectedObj = intersects[0].object;\n\n            for (const { object, trigger } of objects) {\n                if (object === intersectedObj || object.getObjectById(intersectedObj.id)) {\n                    const context = {\n                        observerPos: this.observerPos,\n                        intersection: intersects[0]\n                    };\n                    trigger.executeActions(context);\n                    break;\n                }\n            }\n        }\n    }\n\n    /**\n     * Clean up\n     */\n    dispose() {\n        if (this.domElement) {\n            this.domElement.removeEventListener('pointermove', this._onPointerMove);\n            this.domElement.removeEventListener('pointerdown', this._onPointerDown);\n            this.domElement.style.cursor = 'default';\n        }\n\n        for (const trigger of this.triggers.values()) {\n            trigger.dispose();\n        }\n\n        this.triggers.clear();\n        this.hoveredTrigger = null;\n    }\n}\n","// WebXR xr-standard: thumbstick axes 2/3, not the reserved touchpad 0/1.\nconst deadzone = 0.18;\nconst verticalDeadzone = 0.25;\nexport const XR_TAKEOFF_HOLD_SECONDS = 0.42;\nexport const XR_TURN_RATE = Math.PI / 2; // Full deflection: 90 degrees/second.\nexport const XR_TURN_RESPONSE_SECONDS = 0.12;\n\nexport class XRControllerInput {\n  constructor() {\n    this.state = { forward: 0, right: 0, vertical: 0, crouch: false, jump: false, turn: 0, haltMove: true, haltVertical: true };\n    this._left = null; this._right = null;\n    this._leftReady = false; this._rightReady = false;\n    this._turnVelocity = 0;\n    this._leftUpHoldSeconds = 0;\n    this._leftUpGesture = false;\n    this._leftTakeoff = false;\n  }\n\n  clear() {\n    const s = this.state;\n    s.forward = s.right = s.vertical = s.turn = 0; s.crouch = s.jump = false; s.haltMove = s.haltVertical = true;\n    this._left = this._right = null;\n    this._leftReady = this._rightReady = false;\n    this._leftUpHoldSeconds = 0;\n    this._leftUpGesture = this._leftTakeoff = false;\n    this._turnVelocity = 0;\n    return this.state;\n  }\n\n  sample(session, frame, referenceSpace, deltaTime = 1 / 72, { airborne = false } = {}) {\n    const s = this.state;\n    s.forward = s.right = s.vertical = s.turn = 0; s.crouch = s.jump = false;\n    if (!session || session.visibilityState !== 'visible' || !frame || !referenceSpace) return this.clear();\n    let left = null, right = null;\n    for (const source of session.inputSources) {\n      if (source.targetRayMode !== 'tracked-pointer' || source.gamepad?.mapping !== 'xr-standard'\n        || source.gamepad.connected === false || !source.gripSpace) continue;\n      // Lost tracking must stop locomotion even if the last gamepad values persist.\n      if (!frame.getPose(source.gripSpace, referenceSpace)) continue;\n      if (source.handedness === 'left' && !left) left = source;\n      if (source.handedness === 'right' && !right) right = source;\n    }\n    if (left !== this._left) {\n      this._left = left; this._leftReady = false; this._turnVelocity = 0;\n      this._leftUpHoldSeconds = 0; this._leftUpGesture = this._leftTakeoff = false;\n    }\n    if (right !== this._right) { this._right = right; this._rightReady = false; }\n    if (left) {\n      const pad = left.gamepad, x = axis(pad.axes[2]), y = axis(pad.axes[3]);\n      if (Math.abs(x) < deadzone && Math.abs(y) < deadzone) this._leftReady = true;\n      if (this._leftReady) {\n        // Dominant-axis arbitration avoids diagonal jump+turn surprises.\n        if (Math.abs(x) > deadzone && Math.abs(x) >= Math.abs(y)) {\n          const target = Math.sign(x) * XR_TURN_RATE * Math.pow((Math.abs(x) - deadzone) / (1 - deadzone), 1.6);\n          const dt = Number.isFinite(deltaTime) ? Math.max(0, Math.min(deltaTime, 0.05)) : 0;\n          // Exact integral of an exponential velocity ramp: independent of\n          // headset refresh rate, with fine aim near centre. Never catch up a\n          // suspended frame with a large rotation. Neutral stops immediately.\n          const decay = Math.exp(-dt / XR_TURN_RESPONSE_SECONDS);\n          s.turn = target * dt + (this._turnVelocity - target) * XR_TURN_RESPONSE_SECONDS * (1 - decay);\n          this._turnVelocity = target + (this._turnVelocity - target) * decay;\n        } else {\n          this._turnVelocity = 0;\n        }\n        const dominantY = Math.abs(y) > Math.abs(x);\n        const upStrength = dominantY && y < -verticalDeadzone\n          ? Math.min(1, (-y - verticalDeadzone) / (1 - verticalDeadzone))\n          : 0;\n        const downStrength = dominantY && y > verticalDeadzone\n          ? Math.min(1, (y - verticalDeadzone) / (1 - verticalDeadzone))\n          : 0;\n        const dt = Number.isFinite(deltaTime) ? Math.max(0, Math.min(deltaTime, 0.05)) : 0;\n        if (airborne) {\n          s.vertical = upStrength - downStrength;\n          this._leftUpHoldSeconds = 0; this._leftUpGesture = this._leftTakeoff = false;\n        } else if (upStrength > 0) {\n          this._leftUpGesture = true;\n          this._leftUpHoldSeconds += dt;\n          if (this._leftUpHoldSeconds >= XR_TAKEOFF_HOLD_SECONDS) {\n            this._leftTakeoff = true;\n            s.vertical = upStrength;\n          }\n        } else {\n          if (this._leftUpGesture && !this._leftTakeoff && this._leftUpHoldSeconds > 0) s.jump = true;\n          this._leftUpHoldSeconds = 0; this._leftUpGesture = this._leftTakeoff = false;\n          s.crouch = downStrength >= 0.4;\n        }\n      }\n    }\n    if (right) {\n      const x = axis(right.gamepad.axes[2]), y = axis(right.gamepad.axes[3]), magnitude = Math.hypot(x, y);\n      if (magnitude < deadzone) this._rightReady = true;\n      if (this._rightReady && magnitude > deadzone) {\n        const strength = Math.min(1, (magnitude - deadzone) / (1 - deadzone));\n        s.right = x / magnitude * strength; s.forward = -y / magnitude * strength;\n      }\n    }\n    s.haltMove = !right || !this._rightReady;\n    s.haltVertical = !left || !this._leftReady;\n    return s;\n  }\n}\n\nfunction axis(value) { return Number.isFinite(value) ? Math.max(-1, Math.min(1, value)) : 0; }\n","import * as THREE from 'three';\nimport { XR_LABEL_LAYER } from './NativeXRAtmosphereRenderer.js';\n\nexport const XR_LABEL_CAPACITY = 32;\nconst ROW_HEIGHT = 112, ATLAS_WIDTH = 512, PANEL_SIZE = 1024, PAGE_LINES = 14;\nconst ICON_DIAMETER = 78, ICON_CENTRE_X = 45, ICON_ONLY_WIDTH = 90;\nconst FOCUS_INNER_COS = Math.cos(14 * Math.PI / 180);\nconst FOCUS_OUTER_COS = Math.cos(24 * Math.PI / 180);\n\n/** Session-scoped, batched native labels; no DOM overlay or per-label texture. */\nexport class XRLabelLayer {\n  constructor({ scene, camera, labels, createCanvas = () => document.createElement('canvas') }) {\n    this.camera = camera; this.labels = labels; this.active = true;\n    this.group = new THREE.Group(); this.group.name = 'NativeXRLabels'; scene.add(this.group);\n    this.handles = []; this._keys = []; this._cardWidths = []; this._nextRefresh = 0; this.textureUpdates = 0;\n    this._world = new THREE.Vector3(); this._cameraPos = new THREE.Vector3();\n    this._forward = new THREE.Vector3(); this._right = new THREE.Vector3();\n    this._previousLabelLayer = camera.layers.isEnabled(XR_LABEL_LAYER); camera.layers.enable(XR_LABEL_LAYER);\n    this._scale = new THREE.Vector3(); this._matrix = new THREE.Matrix4(); this._quaternion = new THREE.Quaternion();\n    this._panelWorld = new THREE.Vector3(); this._panelQuaternion = new THREE.Quaternion();\n    this._panelAnchor = null; this._anchorQuaternion = new THREE.Quaternion();\n    this._hits = []; this._selected = null; this._selectedMeta = null; this._page = 0; this._lines = [];\n    this.atlas = createCanvas(); this.atlas.width = ATLAS_WIDTH; this.atlas.height = ROW_HEIGHT * XR_LABEL_CAPACITY;\n    this.atlasContext = this.atlas.getContext('2d');\n    this.atlasTexture = new THREE.CanvasTexture(this.atlas); this.atlasTexture.colorSpace = THREE.SRGBColorSpace;\n    this.atlasTexture.generateMipmaps = false; this.atlasTexture.minFilter = THREE.LinearFilter;\n    const geometry = new THREE.PlaneGeometry(1, 1);\n    geometry.translate(0.5, 0.5, 0); // Bottom-left corner is the geographic anchor.\n    this._fade = new THREE.InstancedBufferAttribute(new Float32Array(XR_LABEL_CAPACITY), 1);\n    this._fade.setUsage(THREE.DynamicDrawUsage); geometry.setAttribute('labelFade', this._fade);\n    this._uvWidth = new THREE.InstancedBufferAttribute(new Float32Array(XR_LABEL_CAPACITY), 1);\n    this._uvWidth.setUsage(THREE.DynamicDrawUsage); geometry.setAttribute('labelUvWidth', this._uvWidth);\n    geometry.setAttribute('atlasRow', new THREE.InstancedBufferAttribute(Float32Array.from({ length: XR_LABEL_CAPACITY }, (_, i) => XR_LABEL_CAPACITY - i - 1), 1));\n    const material = new THREE.MeshBasicMaterial({ map: this.atlasTexture, transparent: true, alphaTest: 0.05,\n      depthWrite: false, toneMapped: false, side: THREE.DoubleSide });\n    material.forceSinglePass = true;\n    material.onBeforeCompile = shader => {\n      shader.vertexShader = 'attribute float atlasRow; attribute float labelFade; attribute float labelUvWidth; varying float vLabelFade;\\n' + shader.vertexShader;\n      shader.vertexShader = shader.vertexShader.replace('#include <uv_vertex>',\n        '#include <uv_vertex>\\n vLabelFade=labelFade; vMapUv.x *= labelUvWidth; vMapUv.y = (vMapUv.y + atlasRow) / ' + XR_LABEL_CAPACITY + '.0;');\n      shader.fragmentShader = 'varying float vLabelFade;\\n' + shader.fragmentShader;\n      shader.fragmentShader = shader.fragmentShader.replace('#include <alphatest_fragment>',\n        'diffuseColor.a *= vLabelFade;\\n#include <alphatest_fragment>');\n    };\n    material.customProgramCacheKey = () => 'noclip-xr-label-atlas-v3-focus-icons';\n    this.cards = new THREE.InstancedMesh(geometry, material, XR_LABEL_CAPACITY);\n    this.cards.instanceMatrix.setUsage(THREE.DynamicDrawUsage); this.cards.frustumCulled = false; this.cards.count = 0;\n    this.cards.renderOrder = 900; this.group.add(this.cards);\n    this.cards.layers.set(XR_LABEL_LAYER);\n    this.panelCanvas = createCanvas(); this.panelCanvas.width = this.panelCanvas.height = PANEL_SIZE;\n    this.panelContext = this.panelCanvas.getContext('2d');\n    this.panelTexture = new THREE.CanvasTexture(this.panelCanvas); this.panelTexture.colorSpace = THREE.SRGBColorSpace;\n    this.panelTexture.generateMipmaps = false; this.panelTexture.minFilter = THREE.LinearFilter;\n    this.panel = new THREE.Mesh(new THREE.PlaneGeometry(1, 1), new THREE.MeshBasicMaterial({ map: this.panelTexture,\n      transparent: true, depthTest: false, depthWrite: false, toneMapped: false, side: THREE.DoubleSide }));\n    this.panel.scale.setScalar(1.15); this.panel.visible = false; this.panel.renderOrder = 1000; this.group.add(this.panel);\n    this.panel.material.forceSinglePass = true;\n    this.panel.layers.set(XR_LABEL_LAYER);\n    labels.setXRPresenter(this);\n  }\n\n  update(now = performance.now()) {\n    if (!this.active) return;\n    this.camera.getWorldPosition(this._cameraPos); this.camera.getWorldQuaternion(this._quaternion);\n    this._forward.set(0, 0, -1).applyQuaternion(this._quaternion);\n    this._right.set(1, 0, 0).applyQuaternion(this._quaternion);\n    // Instance translations stay camera-relative floats, even at Earth scale.\n    this.group.position.copy(this._cameraPos);\n    if (now >= this._nextRefresh) {\n      this._nextRefresh = now + 250;\n      this.labels.getXRVisibleHandles(this.handles, XR_LABEL_CAPACITY);\n      let dirty = false;\n      for (let i = 0; i < this.handles.length; i++) {\n        const handle = this.handles[i], presentation = this.labels.getLabelPresentation(handle);\n        if (!presentation) continue;\n        const title = text(presentation.title, 160), sub = text(presentation.subText || presentation.distanceText, 180);\n        const icon = presentation.markerIcon || null;\n        const key = `${handle.id}|${title}|${sub}|${presentation.colorHex}|${icon?.id || ''}`;\n        if (key !== this._keys[i]) {\n          this._keys[i] = key;\n          this._cardWidths[i] = this._drawCard(i, title, sub, presentation.colorHex, icon);\n          dirty = true;\n        }\n      }\n      if (dirty) { this.atlasTexture.needsUpdate = true; this.textureUpdates++; }\n      if (this._selected) {\n        if (!this.labels.getLabelHandle(this._selected)) this.close();\n        else if (this._selectedMeta !== this._selected.metadata || this._selectedTitle !== this._selected.displayText\n          || this._selectedSub !== this._selected.subText) this._refreshDetails();\n      }\n    }\n    this.cards.count = this.handles.length;\n    for (let i = 0; i < this.handles.length; i++) {\n      const handle = this.handles[i];\n      this._fade.setX(i, 0); this._uvWidth.setX(i, ICON_ONLY_WIDTH / ATLAS_WIDTH);\n      if (!this.labels.getLabelHandle(handle) || !handle.group?.visible || handle.sourceVisible === false) {\n        this._scale.setScalar(0); this._world.set(0, 0, 0);\n      } else {\n        handle.group.getWorldPosition(this._world);\n        const distance = this._world.distanceTo(this._cameraPos);\n        this._world.sub(this._cameraPos);\n        const alignment = this._world.dot(this._forward) / Math.max(distance, 1e-6);\n        const fade = THREE.MathUtils.smoothstep(alignment, Math.cos(42 * Math.PI / 180), Math.cos(25 * Math.PI / 180));\n        this._fade.setX(i, fade);\n        const focus = THREE.MathUtils.smoothstep(alignment, FOCUS_OUTER_COS, FOCUS_INNER_COS);\n        const cardWidth = this._cardWidths[i] || ATLAS_WIDTH;\n        const displayWidth = THREE.MathUtils.lerp(ICON_ONLY_WIDTH, cardWidth, focus);\n        const uvWidth = displayWidth / ATLAS_WIDTH;\n        this._uvWidth.setX(i, uvWidth);\n        const angularWidth = THREE.MathUtils.lerp(0.23, 0.11, THREE.MathUtils.smoothstep(distance, 15, 1000));\n        const maxWidth = Math.max(0.04, distance * angularWidth);\n        this._world.addScaledVector(this._right, -maxWidth * ICON_CENTRE_X / ATLAS_WIDTH);\n        this._scale.set(maxWidth * uvWidth, maxWidth * ROW_HEIGHT / ATLAS_WIDTH, 1);\n      }\n      this._matrix.compose(this._world, this._quaternion, this._scale); this.cards.setMatrixAt(i, this._matrix);\n    }\n    this.cards.instanceMatrix.needsUpdate = true;\n    this._fade.needsUpdate = true;\n    this._uvWidth.needsUpdate = true;\n    // InstancedMesh caches its raycast sphere, including the initial empty\n    // batch. Moving/admitting labels must invalidate it before the next pick.\n    this.cards.boundingSphere = null;\n    if (this.panel.visible) {\n      this.panel.position.copy(this._panelWorld);\n      if (this._panelAnchor) {\n        this.panel.position.applyMatrix4(this._panelAnchor.matrixWorld);\n        this._panelAnchor.getWorldQuaternion(this._anchorQuaternion);\n        this.panel.quaternion.copy(this._anchorQuaternion).multiply(this._panelQuaternion);\n      } else this.panel.quaternion.copy(this._panelQuaternion);\n      this.panel.position.sub(this._cameraPos);\n    }\n    this.group.updateMatrixWorld(true);\n  }\n\n  _drawCard(index, title, sub, color, markerIcon) {\n    const ctx = this.atlasContext, y = index * ROW_HEIGHT;\n    ctx.clearRect(0, y, ATLAS_WIDTH, ROW_HEIGHT);\n    const textX = 98, textLimit = ATLAS_WIDTH - textX - 18;\n    ctx.font = 'bold 34px sans-serif';\n    const titleWidth = Math.min(textLimit, ctx.measureText(title).width);\n    ctx.font = '25px sans-serif';\n    const subText = sub || 'Trigger for details';\n    const subWidth = Math.min(textLimit, ctx.measureText(subText).width);\n    const cardWidth = Math.ceil(THREE.MathUtils.clamp(textX + Math.max(titleWidth, subWidth) + 18, 230, ATLAS_WIDTH));\n    ctx.fillStyle = '#080808ee';\n    if (ctx.roundRect) { ctx.beginPath(); ctx.roundRect(ICON_CENTRE_X, y + 3, cardWidth - ICON_CENTRE_X - 3, ROW_HEIGHT - 6, 10); ctx.fill(); }\n    else ctx.fillRect(ICON_CENTRE_X, y + 3, cardWidth - ICON_CENTRE_X - 3, ROW_HEIGHT - 6);\n    const iconColor = colorCss(color);\n    ctx.beginPath(); ctx.arc(ICON_CENTRE_X, y + ROW_HEIGHT / 2, ICON_DIAMETER / 2, 0, Math.PI * 2);\n    ctx.fillStyle = '#080808f5'; ctx.fill(); ctx.strokeStyle = iconColor; ctx.lineWidth = 5; ctx.stroke();\n    ctx.fillStyle = iconColor; ctx.font = 'bold 31px sans-serif'; ctx.textAlign = 'center'; ctx.textBaseline = 'middle';\n    ctx.fillText(iconGlyph(markerIcon), ICON_CENTRE_X, y + ROW_HEIGHT / 2 + 1, ICON_DIAMETER - 18);\n    ctx.textAlign = 'left'; ctx.textBaseline = 'alphabetic';\n    ctx.fillStyle = '#ffffff'; ctx.font = 'bold 34px sans-serif'; ctx.fillText(fit(ctx, title, textLimit), textX, y + 45);\n    ctx.fillStyle = '#d6d6d6'; ctx.font = '25px sans-serif'; ctx.fillText(fit(ctx, subText, textLimit), textX, y + 86);\n    return cardWidth;\n  }\n\n  open(handle) {\n    if (!this.active || !this.labels.getLabelHandle(handle)) return false;\n    this._selected = handle; this._page = 0; this._refreshDetails();\n    this.camera.getWorldPosition(this._cameraPos); this.camera.getWorldQuaternion(this._panelQuaternion);\n    this._panelWorld.set(0, 0, -1.7).applyQuaternion(this._panelQuaternion).add(this._cameraPos);\n    // Fix the panel in the navigation room frame, not the celestial world:\n    // Earth rotation must not carry the user away from an open detail panel.\n    // Native head motion remains free; this is not a head-locked display.\n    this._panelAnchor = this.camera.parent;\n    if (this._panelAnchor) {\n      this._panelAnchor.worldToLocal(this._panelWorld);\n      this._panelAnchor.getWorldQuaternion(this._anchorQuaternion).invert();\n      this._panelQuaternion.premultiply(this._anchorQuaternion);\n    }\n    this.panel.visible = true; this.update(); return true;\n  }\n\n  close() { this.panel.visible = false; this._panelAnchor = null; this._selected = null; this._selectedMeta = null; this._lines.length = 0; }\n\n  _refreshDetails() {\n    const details = this.labels.getLabelDetailsPresentation(this._selected);\n    if (!details) { this.close(); return; }\n    this._selectedMeta = this._selected.metadata; this._selectedTitle = this._selected.displayText; this._selectedSub = this._selected.subText;\n    this._title = text(details.title, 512); this._lines.length = 0;\n    // Same normalized key/value fields as the desktop modal, paged in-headset.\n    for (const row of details.rows.slice(0, 128)) {\n      const content = `${text(row.label, 100)}: ${text(row.value, 4096)}`;\n      for (let i = 0; i < content.length; i += 54) this._lines.push(content.slice(i, i + 54));\n    }\n    if (details.rows.length > 128) this._lines.push('Additional fields exceed the VR detail limit.');\n    if (!this._lines.length) this._lines.push('No additional details for this label.');\n    this._page = Math.min(this._page, this._pageCount() - 1); this._drawPanel();\n  }\n\n  _pageCount() { return Math.max(1, Math.ceil(this._lines.length / PAGE_LINES)); }\n\n  _drawPanel() {\n    const ctx = this.panelContext;\n    ctx.clearRect(0, 0, PANEL_SIZE, PANEL_SIZE); ctx.fillStyle = '#080808f5'; ctx.fillRect(0, 0, PANEL_SIZE, PANEL_SIZE);\n    ctx.fillStyle = colorCss(this.labels.getLabelPresentation(this._selected)?.colorHex); ctx.fillRect(0, 0, 8, PANEL_SIZE);\n    ctx.font = 'bold 46px sans-serif'; ctx.fillStyle = '#f4f9ff'; ctx.fillText(fit(ctx, this._title, 930), 40, 76);\n    ctx.font = '26px sans-serif'; ctx.fillStyle = '#bdd5e6'; ctx.fillText(`Details · ${this._page + 1}/${this._pageCount()} · aim and trigger`, 40, 124);\n    ctx.font = '29px sans-serif'; ctx.fillStyle = '#f4f9ff';\n    const start = this._page * PAGE_LINES;\n    for (let i = 0; i < PAGE_LINES && start + i < this._lines.length; i++) ctx.fillText(this._lines[start + i], 40, 188 + i * 47);\n    ctx.fillStyle = '#193448'; ctx.fillRect(18, 901, 988, 103);\n    ctx.fillStyle = '#f4f9ff'; ctx.font = 'bold 32px sans-serif';\n    ctx.fillText('PREVIOUS', 52, 964); ctx.fillText('CLOSE', 446, 964); ctx.fillText('NEXT', 832, 964);\n    this.panelTexture.needsUpdate = true;\n  }\n\n  pick(raycaster) {\n    if (!this.active) return null;\n    const mask = raycaster.layers.mask; raycaster.layers.enable(XR_LABEL_LAYER);\n    try { return this._pick(raycaster); } finally { raycaster.layers.mask = mask; }\n  }\n\n  _pick(raycaster) {\n    this._hits.length = 0;\n    if (this.panel.visible) {\n      raycaster.intersectObject(this.panel, false, this._hits);\n      if (this._hits.length) return { ...this._hits[0], panel: true };\n    }\n    this._hits.length = 0; raycaster.intersectObject(this.cards, false, this._hits);\n    for (const hit of this._hits) {\n      const handle = this.handles[hit.instanceId];\n      if (this._fade.getX(hit.instanceId) > 0.05 && handle?.group?.visible && handle.sourceVisible !== false && this.labels.getLabelHandle(handle)) return { ...hit, handle };\n    }\n    return null;\n  }\n\n  select(hit) {\n    if (hit?.panel) {\n      if (hit.uv?.y < 0.12) {\n        if (hit.uv.x < 1 / 3) this._page = Math.max(0, this._page - 1);\n        else if (hit.uv.x > 2 / 3) this._page = Math.min(this._pageCount() - 1, this._page + 1);\n        else { this.close(); return true; }\n        this._drawPanel();\n      }\n      return true;\n    }\n    return hit?.handle ? this.labels.openLabelDetails(hit.handle) : false;\n  }\n\n  dispose() {\n    this.active = false; this.close(); this.labels.setXRPresenter(null, this);\n    if (!this._previousLabelLayer) this.camera.layers.disable(XR_LABEL_LAYER);\n    this.group.removeFromParent(); this.cards.geometry.dispose(); this.cards.material.dispose();\n    this.panel.geometry.dispose(); this.panel.material.dispose(); this.atlasTexture.dispose(); this.panelTexture.dispose();\n    this.handles.length = this._keys.length = this._cardWidths.length = 0;\n  }\n}\n\nfunction text(value, limit) { return typeof value === 'string' || typeof value === 'number' ? String(value).replace(/[\\u0000-\\u001f]/g, ' ').slice(0, limit) : ''; }\nfunction colorCss(color = 0xffffff) { return '#' + (Number(color) >>> 0).toString(16).padStart(6, '0').slice(-6); }\nfunction fit(ctx, value, width) { let result = value; while (result.length > 1 && ctx.measureText(result).width > width) result = result.slice(0, -1); return result === value ? result : result.slice(0, -1) + '…'; }\nfunction iconGlyph(icon) {\n  const id = String(icon?.id || icon?.category || '').toLowerCase();\n  if (id.includes('aircraft')) return '✈';\n  if (id.includes('maritime')) return '⚓';\n  if (id.includes('satellite')) return '◈';\n  if (id.includes('user')) return '●';\n  if (id.includes('incident') || id.includes('hazard') || id.includes('fire')) return '!';\n  if (id.includes('traffic') || id.includes('road')) return '↔';\n  if (id.includes('radio') || id.includes('sensor')) return '∿';\n  if (id.includes('building') || id.includes('business')) return '■';\n  if (id.includes('natural')) return '▲';\n  return '•';\n}\n","import * as THREE from 'three';\n\nconst MAX_PALETTE_ELEMENT = 1e5;\n\n/**\n * The established Avatar precision contract, shared by native articulated hands.\n * Cancel the mesh/Earth world transform in CPU doubles before publishing the\n * float32 palette: M^-1 * boneWorld * boneInverse * originalBind. GPU skinning\n * then uses detached identity binds and the ordinary camera-relative model view.\n * This owns no geometry, animation, textures, renderer, or frame clock.\n */\nexport function enableMeshSpaceSkinning(root, updateRoot = root) {\n  if (!root) return 0;\n  const skeletons = new Map();\n  root.traverse(node => {\n    if (!node?.isSkinnedMesh || !node.skeleton) return;\n    const meshes = skeletons.get(node.skeleton) || [];\n    meshes.push(node); skeletons.set(node.skeleton, meshes);\n  });\n  if (!skeletons.size) return 0;\n  updateRoot.updateMatrixWorld(true);\n  const identity = new THREE.Matrix4();\n  let installed = 0;\n  for (const [skeleton, meshes] of skeletons) {\n    skeleton.userData ||= {};\n    // A palette is relative to one mesh. Keep the existing multi-mesh exclusion;\n    // the shipped Character and each articulated hand have one mesh per skin.\n    if (skeleton.userData.meshSpaceSkinning || meshes.length !== 1) continue;\n    const mesh = meshes[0]; mesh.updateMatrixWorld(true);\n    const size = skeleton.bones.length * 16;\n    const state = skeleton.userData.meshSpaceSkinning = {\n      mesh, bindMatrix: mesh.bindMatrix.clone(), bindMatrixInverse: mesh.bindMatrixInverse.clone(), bindMode: mesh.bindMode,\n      meshWorldInv: new THREE.Matrix4(), tmpMatrix: new THREE.Matrix4(), identity,\n      candidate: new Float32Array(size), palette: new Float32Array(size),\n      hasValidPalette: false, lastUpdateValid: null, rejectedUpdates: 0,\n    };\n    // If the first pose is not yet complete, a local rest-shaped palette is\n    // safe. Never publish world/ECEF bones or a partially computed candidate.\n    for (let offset = 0; offset < size; offset += 16) identity.toArray(state.palette, offset);\n    skeleton.boneMatrices.set(state.palette);\n    mesh.frustumCulled = false;\n    mesh.bindMode = THREE.DetachedBindMode; mesh.bindMatrix.identity(); mesh.bindMatrixInverse.identity();\n    skeleton.update = function () {\n      // Keep this contract even after an invalid frame or caller-owned matrix\n      // refresh. AttachedBindMode would overwrite the inverse with ECEF data.\n      mesh.bindMode = THREE.DetachedBindMode; mesh.bindMatrix.identity(); mesh.bindMatrixInverse.identity();\n      mesh.updateMatrixWorld(true);\n      const determinant = mesh.matrixWorld.determinant();\n      let invalid = !Number.isFinite(determinant) || determinant === 0;\n      if (!invalid) state.meshWorldInv.copy(mesh.matrixWorld).invert();\n      for (let i = 0; !invalid && i < this.bones.length; i++) {\n        const boneMatrix = this.bones[i] ? this.bones[i].matrixWorld : identity;\n        const boneInverse = this.boneInverses[i] || identity;\n        // Preserve the Avatar formula and multiply order in double precision.\n        const matrix = state.tmpMatrix.multiplyMatrices(state.meshWorldInv, boneMatrix);\n        matrix.multiply(boneInverse); matrix.multiply(state.bindMatrix);\n        for (const value of matrix.elements) {\n          if (!Number.isFinite(value) || Math.abs(value) > MAX_PALETTE_ELEMENT) { invalid = true; break; }\n        }\n        if (!invalid) matrix.toArray(state.candidate, i * 16);\n      }\n      state.lastUpdateValid = !invalid;\n      if (invalid) state.rejectedUpdates = Math.min(Number.MAX_SAFE_INTEGER, state.rejectedUpdates + 1);\n      else { state.palette.set(state.candidate); state.hasValidPalette = true; }\n      // Commit a whole valid palette atomically. During a stale/invalid pose,\n      // reuse the last valid local palette and retry on the ordinary next update.\n      this.boneMatrices.set(state.palette);\n      if (this.boneTexture) this.boneTexture.needsUpdate = true;\n    };\n    installed++;\n  }\n  return installed;\n}\n","import * as THREE from 'three';\nimport { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';\nimport { clone } from 'three/addons/utils/SkeletonUtils.js';\nimport { MotionController } from 'three/addons/libs/motion-controllers.module.js';\nimport { XR_LABEL_LAYER } from './NativeXRAtmosphereRenderer.js';\nimport { enableMeshSpaceSkinning } from '../avatar/MeshSpaceSkinning.js';\n\nconst ROOT = '/assets/xr/profiles/';\n\n/** Session-independent bounded cache. Reconnection rebinds, never clones or\n * refetches the same model. Only active models update, once per native frame. */\nexport class XRInputModels {\n  constructor({ loader = new GLTFLoader(), fetchProfile = url => fetch(url).then(r => {\n    if (!r.ok) throw new Error('XR input profile unavailable'); return r.json();\n  }) } = {}) {\n    this.loader = loader; this.fetchProfile = fetchProfile;\n    this.entries = new Map(); this.profiles = new Map(); this.resources = new Set(); this.disposed = false;\n  }\n\n  async connect(slot, source) {\n    this.disconnect(slot);\n    slot.modelSource = source;\n    const hand = source?.handedness;\n    if (hand !== 'left' && hand !== 'right') return;\n    const profile = source.hand ? 'generic-hand' : source.profiles?.includes('oculus-touch-v3') ? 'oculus-touch-v3' : 'generic-trigger';\n    const key = `${profile}/${hand}`;\n    if (!this.entries.has(key)) this.entries.set(key, this._load(profile, hand, source));\n    try {\n      const entry = await this.entries.get(key);\n      if (this.disposed || slot.modelSource !== source) return;\n      // Only one of hand/controller sources of this handedness presents this\n      // asset; a new native source replaces its previous slot cleanly.\n      if (entry.slot) entry.slot.model = null;\n      entry.slot = slot; slot.model = entry;\n      if (entry.motion) entry.motion.xrInputSource = source;\n      (source.hand ? slot.hand : slot.grip).add(entry.object);\n    } catch (error) {\n      // Keep the pointing ray usable; no pill placeholder, retry storm or\n      // unhandled rejected GLTF callback on flaky mobile connectivity.\n      if (!this.disposed) console.warn('[XRInputModels] Model unavailable', error?.message);\n    }\n  }\n\n  async _load(profile, hand, source) {\n    const url = `${ROOT}${profile}/${hand}.glb`;\n    const asset = await this.loader.loadAsync(url);\n    this._own(asset.scene);\n    if (this.disposed) { this._disposeResources(); throw new Error('XR model owner disposed'); }\n    const object = profile === 'generic-hand' ? clone(asset.scene.children[0]) : asset.scene;\n    // Articulated hands live under the same Earth-radius rig as avatars.\n    // Reuse their precision contract before any float32 bone upload.\n    if (profile === 'generic-hand') enableMeshSpaceSkinning(object);\n    const entry = { object, motion: null, responses: [], bones: [], slot: null };\n    object.name = `NativeXR:${profile}:${hand}`;\n    object.traverse(node => {\n      node.layers.set(XR_LABEL_LAYER);\n      if (node.isBone) entry.bones.push(node);\n      if (node.isMesh) {\n        node.castShadow = node.receiveShadow = false;\n        if (node.isSkinnedMesh) { node.frustumCulled = false; this.resources.add(node.skeleton); }\n        for (const mat of Array.isArray(node.material) ? node.material : [node.material]) {\n          mat.toneMapped = false; mat.envMap = null;\n        }\n      }\n    });\n    if (profile !== 'generic-hand') {\n      if (!this.profiles.has(profile)) this.profiles.set(profile, this.fetchProfile(`${ROOT}${profile}/profile.json`));\n      const description = await this.profiles.get(profile);\n      entry.motion = new MotionController(source, description, url);\n      for (const component of Object.values(entry.motion.components)) {\n        for (const response of Object.values(component.visualResponses)) {\n          const valueNode = object.getObjectByName(response.valueNodeName);\n          const minNode = object.getObjectByName(response.minNodeName);\n          const maxNode = object.getObjectByName(response.maxNodeName);\n          if (valueNode && (response.valueNodeProperty === 'visibility' || (minNode && maxNode))) {\n            entry.responses.push({ response, valueNode, minNode, maxNode });\n          }\n        }\n      }\n    }\n    return entry;\n  }\n\n  update(slot) {\n    const entry = slot.model;\n    if (!entry || (!slot.grip.visible && !slot.hand?.visible)) return;\n    if (entry.motion) {\n      entry.motion.updateFromGamepad();\n      for (const {response, valueNode, minNode, maxNode} of entry.responses) {\n        if (response.valueNodeProperty === 'visibility') valueNode.visible = response.value;\n        else {\n          valueNode.position.lerpVectors(minNode.position, maxNode.position, response.value);\n          valueNode.quaternion.slerpQuaternions(minNode.quaternion, maxNode.quaternion, response.value);\n        }\n      }\n    } else {\n      for (const bone of entry.bones) {\n        const joint = slot.hand.joints[bone.name];\n        if (joint?.visible) { bone.position.copy(joint.position); bone.quaternion.copy(joint.quaternion); }\n      }\n    }\n  }\n\n  disconnect(slot) {\n    slot.modelSource = null;\n    if (slot.model?.slot === slot) {\n      slot.model.object.removeFromParent(); slot.model.slot = null;\n    }\n    slot.model = null;\n  }\n\n  _own(object) {\n    object.traverse(node => {\n      if (node.geometry) this.resources.add(node.geometry);\n      if (node.skeleton) this.resources.add(node.skeleton);\n      for (const material of Array.isArray(node.material) ? node.material : [node.material]) {\n        if (!material) continue;\n        this.resources.add(material);\n        for (const value of Object.values(material)) if (value?.isTexture) this.resources.add(value);\n      }\n    });\n  }\n  _disposeResources() { for (const resource of this.resources) resource.dispose(); this.resources.clear(); }\n  dispose() {\n    this.disposed = true;\n    for (const pending of this.entries.values()) pending.then(entry => {\n      entry.object.removeFromParent(); if (entry.slot) entry.slot.model = null;\n    }).catch(() => {});\n    this.entries.clear(); this.profiles.clear(); this._disposeResources();\n  }\n}\n","import * as THREE from 'three';\nimport { radialSector } from '../ui/RadialActionMenu.js';\nimport { XR_LABEL_LAYER } from './NativeXRAtmosphereRenderer.js';\n\nconst SIZE = 1024, CENTRE = SIZE / 2, INNER = 85, WIDTH = 175, GAP = 8;\n\nexport function pickRadialSector(uv, levels) {\n  const x = uv.x * SIZE - CENTRE, y = (1 - uv.y) * SIZE - CENTRE, radius = Math.hypot(x, y);\n  // Keep the root origin transparent and non-interactive so the entity that\n  // opened the menu remains visible. Deeper levels retain Back navigation.\n  if (radius <= INNER - 8) return levels.length > 1 ? { centre: true } : null;\n  const ring = Math.floor((radius - INNER) / (WIDTH + GAP));\n  const first = Math.max(0, levels.length - 2), level = first + ring;\n  if (ring < 0 || ring > 1 || !levels[level] || radius > INNER + ring * (WIDTH + GAP) + WIDTH) return null;\n  const count = levels[level].items.length;\n  if (!count) return null;\n  const angle = 2 * Math.PI / count;\n  const a = (Math.atan2(y, x) + Math.PI / 2 + angle / 2 + 2 * Math.PI) % (2 * Math.PI);\n  const offset = a % angle, gap = Math.min(0.025, angle * 0.06);\n  if (offset < gap || offset > angle - gap) return null;\n  return { level, index: Math.floor(a / angle) };\n}\n\n/** One fixed native UI texture. No DOM, polling, per-frame painting or\n * geometry allocation. Uses the desktop action tree, including submenus. */\nexport class XRRadialMenu {\n  constructor({ scene, camera, exitToBrowser, createCanvas = () => document.createElement('canvas') }) {\n    this.camera = camera; this.exitToBrowser = exitToBrowser; this.levels = [];\n    this.canvas = createCanvas(); this.canvas.width = this.canvas.height = SIZE;\n    this.ctx = this.canvas.getContext('2d'); this.texture = new THREE.CanvasTexture(this.canvas);\n    this.texture.colorSpace = THREE.SRGBColorSpace; this.texture.generateMipmaps = false; this.texture.minFilter = THREE.LinearFilter;\n    this.mesh = new THREE.Mesh(new THREE.PlaneGeometry(1, 1), new THREE.MeshBasicMaterial({map:this.texture,\n      transparent:true, depthTest:false, depthWrite:false, toneMapped:false, side:THREE.DoubleSide}));\n    this.mesh.material.forceSinglePass = true; this.mesh.layers.set(XR_LABEL_LAYER);\n    this.mesh.scale.setScalar(1.2); this.mesh.renderOrder = 1100; this.mesh.visible = false; scene.add(this.mesh);\n    this.position = new THREE.Vector3(); this.quaternion = new THREE.Quaternion(); this._q = new THREE.Quaternion();\n    this.hits = []; this.controller = null; this.hoverKey = ''; this.message = ''; this.busy = false;\n  }\n\n  open(items) {\n    if (!items?.length) return false;\n    this.close(); this.controller = new AbortController();\n    this.levels = [{items, selected:null}]; this.message = ''; this.busy = false;\n    this.camera.getWorldPosition(this.position); this.camera.getWorldQuaternion(this.quaternion);\n    this.position.add(new THREE.Vector3(0, 0, -1.5).applyQuaternion(this.quaternion));\n    this.anchor = this.camera.parent;\n    if (this.anchor) {\n      this.anchor.worldToLocal(this.position);\n      this.anchor.getWorldQuaternion(this._q).invert(); this.quaternion.premultiply(this._q);\n    }\n    this.mesh.visible = true; this.update(); this.draw(); return true;\n  }\n\n  update() {\n    if (!this.mesh.visible) return;\n    this.mesh.position.copy(this.position); this.mesh.quaternion.copy(this.quaternion);\n    if (this.anchor) {\n      this.mesh.position.applyMatrix4(this.anchor.matrixWorld);\n      this.anchor.getWorldQuaternion(this._q); this.mesh.quaternion.premultiply(this._q);\n    }\n    this.mesh.updateMatrixWorld();\n  }\n\n  pick(raycaster) {\n    if (!this.mesh.visible) return null;\n    this.hits.length = 0;\n    const mask = raycaster.layers.mask; raycaster.layers.enable(XR_LABEL_LAYER);\n    try { raycaster.intersectObject(this.mesh, false, this.hits); } finally { raycaster.layers.mask = mask; }\n    const hit = this.hits[0], sector = hit?.uv && pickRadialSector(hit.uv, this.levels);\n    return sector ? { ...hit, ...sector, radial:true } : null;\n  }\n\n  hover(hit) {\n    const key = hit ? hit.centre ? 'centre' : `${hit.level}:${hit.index}` : '';\n    if (key !== this.hoverKey) { this.hoverKey = key; this.draw(); }\n  }\n\n  async select(hit) {\n    if (!this.mesh.visible || !hit) return false;\n    if (hit.centre) {\n      if (this.levels.length === 1) return false;\n      this.levels.pop(); this.message = ''; this.draw();\n      return true;\n    }\n    if (this.busy) return true;\n    const level = this.levels[hit.level], item = level?.items[hit.index];\n    if (!item) return false;\n    if (item.children?.length) {\n      this.levels.length = hit.level + 1; level.selected = hit.index;\n      this.levels.push({items:item.children, selected:null}); this.hoverKey = ''; this.message = ''; this.draw(); return true;\n    }\n    // Text editors, route confirmation and browser share sheets cannot be\n    // operated through invisible CSS. Ask explicitly before leaving immersive\n    // mode; execute the canonical action only after a successful exit.\n    if (!item.nativeXR) {\n      this.levels.push({items:[{id:'browser-confirm', label:'Open in browser', nativeXR:true, run:async context => {\n        if (!await this.exitToBrowser()) throw new Error('Could not exit VR. Try again.');\n        return item.run(context);\n      }}]});\n      this.message = `${item.label}: browser interface required`; this.draw(); return true;\n    }\n    const owner = this.controller;\n    this.busy = true; this.message = 'Working…'; this.draw();\n    try {\n      const result = await item.run({signal:owner.signal});\n      if (this.controller === owner && !owner.signal.aborted) {\n        this.message = typeof result === 'string' ? result.slice(0, 100) : 'Done';\n      }\n    } catch (error) {\n      if (this.controller === owner && !owner.signal.aborted) this.message = String(error?.message || 'Action unavailable').slice(0,100);\n    } finally {\n      if (this.controller === owner && !owner.signal.aborted) { this.busy = false; this.draw(); }\n    }\n    return true;\n  }\n\n  draw() {\n    if (!this.mesh.visible) return;\n    const ctx = this.ctx; ctx.clearRect(0,0,SIZE,SIZE); ctx.textAlign = 'center'; ctx.textBaseline = 'middle';\n    const first = Math.max(0, this.levels.length - 2);\n    for (let l = first; l < this.levels.length; l++) {\n      const level = this.levels[l], inner = INNER + (l - first) * (WIDTH + GAP);\n      for (let i = 0; i < level.items.length; i++) {\n        const sector = radialSector(level.items.length, i, inner, inner + WIDTH, CENTRE);\n        const gap = Math.min(0.025, sector.angle * 0.06), start = sector.mid - sector.angle / 2 + gap, end = sector.mid + sector.angle / 2 - gap;\n        ctx.beginPath(); ctx.arc(CENTRE,CENTRE,inner+WIDTH,start,end); ctx.arc(CENTRE,CENTRE,inner,end,start,true); ctx.closePath();\n        const active = this.hoverKey === `${l}:${i}` || level.selected === i;\n        ctx.fillStyle = active ? '#343322fa' : '#111111f5'; ctx.strokeStyle = active ? '#facc15' : '#777777'; ctx.lineWidth = 2;\n        ctx.fill(); ctx.stroke(); ctx.fillStyle = '#ffffff'; ctx.font = '26px sans-serif';\n        const words = level.items[i].label.split(' ');\n        if (words.length > 1) { const middle = Math.ceil(words.length / 2);\n          ctx.fillText(words.slice(0,middle).join(' '),sector.label[0],sector.label[1]-16,145);\n          ctx.fillText(words.slice(middle).join(' '),sector.label[0],sector.label[1]+16,145);\n        } else ctx.fillText(words[0],...sector.label,145);\n        if (level.items[i].children) { ctx.fillStyle = '#facc15'; ctx.fillText('›',sector.label[0],sector.label[1]+47); }\n      }\n    }\n    if (this.levels.length > 1) {\n      ctx.beginPath(); ctx.arc(CENTRE,CENTRE,INNER-8,0,2*Math.PI); ctx.fillStyle = '#090909'; ctx.fill();\n      ctx.strokeStyle = this.hoverKey === 'centre' ? '#facc15' : '#aaaaaa'; ctx.stroke();\n      ctx.fillStyle = '#ffffff'; ctx.font = '27px sans-serif'; ctx.fillText('BACK',CENTRE,CENTRE);\n    }\n    ctx.font = '23px sans-serif'; ctx.fillText(this.message,CENTRE,985,980); this.texture.needsUpdate = true;\n  }\n  close() { this.controller?.abort(); this.controller = null; this.mesh.visible = false; this.levels.length = 0; this.hoverKey = ''; }\n  dispose() { this.close(); this.mesh.removeFromParent(); this.mesh.geometry.dispose(); this.mesh.material.dispose(); this.texture.dispose(); }\n}\n","import * as THREE from 'three';\n\nexport class XRVisionTools {\n  constructor({ scene, camera, eventBus } = {}) {\n    this.scene = scene;\n    this.camera = camera;\n    this.eventBus = eventBus;\n    this.controller = null;\n    this.mode = 'off';\n    this._cameraPosition = new THREE.Vector3();\n\n    this.spot = new THREE.SpotLight(0xfff1c7, 0, 140, Math.PI / 7, 0.48, 1.25);\n    this.spot.name = 'XRProjectedVisionLight';\n    this.target = new THREE.Object3D(); this.target.position.set(0, 0, -20);\n    this.spot.target = this.target;\n    this.ambient = new THREE.HemisphereLight(0x82ff8a, 0x001306, 0);\n    this.ambient.name = 'XRNightVisionFill';\n    this.scene?.add(this.ambient);\n\n    this.tint = new THREE.Mesh(\n      new THREE.SphereGeometry(0.35, 24, 16),\n      new THREE.MeshBasicMaterial({\n        color: 0x5bff68, transparent: true, opacity: 0.22,\n        depthTest: false, depthWrite: false, side: THREE.BackSide,\n        blending: THREE.MultiplyBlending, toneMapped: false,\n      }),\n    );\n    this.tint.name = 'XRNightVisionMonochrome';\n    this.tint.renderOrder = 5000; this.tint.visible = false;\n    this.scene?.add(this.tint);\n  }\n\n  connect(controller) {\n    if (this.controller === controller) return;\n    this.spot.removeFromParent(); this.target.removeFromParent();\n    this.controller = controller || null;\n    if (this.controller) {\n      this.controller.add(this.spot, this.target);\n      this.spot.position.set(0, 0, -0.035);\n    }\n  }\n\n  toggleFlashlight() { return this.setMode(this.mode === 'flashlight' ? 'off' : 'flashlight'); }\n  toggleNightVision() { return this.setMode(this.mode === 'night-vision' ? 'off' : 'night-vision'); }\n\n  setMode(mode) {\n    this.mode = ['flashlight', 'night-vision'].includes(mode) ? mode : 'off';\n    const night = this.mode === 'night-vision';\n    this.spot.color.setHex(night ? 0x78ff72 : 0xfff1c7);\n    this.spot.intensity = this.mode === 'off' ? 0 : (night ? 6000 : 1800);\n    this.spot.distance = night ? 230 : 140;\n    this.spot.angle = night ? Math.PI / 5.2 : Math.PI / 7;\n    this.ambient.intensity = night ? 0.38 : 0;\n    this.tint.visible = night;\n    this.eventBus?.emit?.('vr:vision-mode', { mode: this.mode });\n    return this.mode;\n  }\n\n  update() {\n    if (!this.tint.visible || !this.camera) return;\n    this.camera.getWorldPosition(this._cameraPosition);\n    this.tint.position.copy(this._cameraPosition);\n  }\n\n  dispose() {\n    this.connect(null);\n    this.spot.dispose?.();\n    this.ambient.removeFromParent();\n    this.tint.removeFromParent(); this.tint.geometry.dispose(); this.tint.material.dispose();\n  }\n}\n","import * as THREE from 'three';\nimport { XR_LABEL_LAYER } from './NativeXRAtmosphereRenderer.js';\nimport { getMapTileApiBase } from '../shared/backend.js';\n\nconst PANEL_WIDTH = 640;\nconst PANEL_HEIGHT = 320;\n\nfunction coord(value, positive, negative) {\n  if (!Number.isFinite(value)) return '--';\n  return `${Math.abs(value).toFixed(5)}°${value >= 0 ? positive : negative}`;\n}\n\nfunction weatherLines(weatherSystem) {\n  const data = weatherSystem?.getWeatherData?.();\n  const current = data?.current || {};\n  const code = Number(current.weather_code);\n  const description = Number.isFinite(code)\n    ? weatherSystem?.getWeatherDescription?.(code) || 'Current conditions'\n    : 'Weather loading';\n  const temperature = Number.isFinite(current.temperature_2m) ? `${Math.round(current.temperature_2m)}°C` : '--°C';\n  const humidity = Number.isFinite(current.relative_humidity_2m) ? `${Math.round(current.relative_humidity_2m)}% RH` : '-- RH';\n  const wind = Number.isFinite(current.wind_speed_10m)\n    ? `${Math.round(current.wind_speed_10m)} km/h${Number.isFinite(current.wind_direction_10m) ? ` · ${Math.round(current.wind_direction_10m)}°` : ''}`\n    : 'Wind --';\n  return { data, lines: [description, `${temperature} · ${humidity}`, wind] };\n}\n\nexport class XRWristPanels {\n  constructor({ camera, weatherSystem, getLocation, getSceneTime } = {}) {\n    this.camera = camera;\n    this.weatherSystem = weatherSystem;\n    this.getLocation = getLocation;\n    this.getSceneTime = getSceneTime;\n    this.panels = new Map();\n    this.miniMapVisible = false;\n    this._miniMapTiles = new Map();\n    this._nextPaint = 0;\n    this._cameraPosition = new THREE.Vector3();\n    this._panelPosition = new THREE.Vector3();\n    this._panelNormal = new THREE.Vector3();\n    this._panelQuaternion = new THREE.Quaternion();\n  }\n\n  connect(slot, source) {\n    const handedness = source?.handedness;\n    if (typeof document === 'undefined' || !slot?.grip || (handedness !== 'left' && handedness !== 'right')) return;\n    this.disconnect(slot);\n    const canvas = document.createElement('canvas');\n    canvas.width = PANEL_WIDTH; canvas.height = PANEL_HEIGHT;\n    const texture = new THREE.CanvasTexture(canvas);\n    texture.colorSpace = THREE.SRGBColorSpace;\n    texture.minFilter = THREE.LinearFilter;\n    texture.generateMipmaps = false;\n    const material = new THREE.MeshBasicMaterial({\n      map: texture, transparent: true, depthTest: false, depthWrite: false,\n      side: THREE.DoubleSide, toneMapped: false,\n    });\n    const mesh = new THREE.Mesh(new THREE.PlaneGeometry(0.24, 0.12), material);\n    mesh.name = `XR${handedness === 'left' ? 'Location' : 'Weather'}WristPanel`;\n    mesh.layers.set(XR_LABEL_LAYER);\n    mesh.position.set(handedness === 'left' ? -0.035 : 0.035, 0.085, 0.055);\n    mesh.rotation.set(-Math.PI / 2, 0, handedness === 'left' ? -0.08 : 0.08);\n    mesh.renderOrder = 1120;\n    mesh.visible = false;\n    slot.grip.add(mesh);\n    const panel = { slot, handedness, mesh, canvas, ctx: canvas.getContext('2d'), texture };\n    slot.wristPanel = panel;\n    this.panels.set(slot, panel);\n    this._draw(panel);\n  }\n\n  disconnect(slot) {\n    const panel = slot?.wristPanel || this.panels.get(slot);\n    if (!panel) return;\n    panel.mesh.removeFromParent();\n    panel.mesh.geometry.dispose(); panel.mesh.material.dispose(); panel.texture.dispose();\n    this.panels.delete(slot); delete slot.wristPanel;\n  }\n\n  toggleMiniMap() {\n    this.miniMapVisible = !this.miniMapVisible;\n    this._nextPaint = 0;\n    return this.miniMapVisible;\n  }\n\n  update(now = performance.now()) {\n    if (!this.camera) return;\n    this.camera.getWorldPosition(this._cameraPosition);\n    for (const panel of this.panels.values()) {\n      panel.mesh.getWorldPosition(this._panelPosition);\n      panel.mesh.getWorldQuaternion(this._panelQuaternion);\n      this._panelNormal.set(0, 0, 1).applyQuaternion(this._panelQuaternion);\n      const facing = this._cameraPosition.clone().sub(this._panelPosition).normalize().dot(this._panelNormal);\n      panel.mesh.visible = facing > 0.18 || (panel.handedness === 'left' && this.miniMapVisible);\n    }\n    if (now < this._nextPaint) return;\n    this._nextPaint = now + 350;\n    for (const panel of this.panels.values()) this._draw(panel);\n  }\n\n  _draw(panel) {\n    const { ctx } = panel;\n    const gradient = ctx.createLinearGradient(0, 0, PANEL_WIDTH, PANEL_HEIGHT);\n    gradient.addColorStop(0, 'rgba(8,8,8,.96)'); gradient.addColorStop(1, 'rgba(25,24,15,.95)');\n    ctx.clearRect(0, 0, PANEL_WIDTH, PANEL_HEIGHT);\n    ctx.fillStyle = gradient; ctx.beginPath(); ctx.roundRect(5, 5, PANEL_WIDTH - 10, PANEL_HEIGHT - 10, 32); ctx.fill();\n    ctx.strokeStyle = '#facc15'; ctx.lineWidth = 5; ctx.stroke();\n    ctx.fillStyle = '#facc15'; ctx.font = '700 28px sans-serif'; ctx.textAlign = 'left';\n    ctx.fillText(panel.handedness === 'left' ? (this.miniMapVisible ? 'MINI MAP' : 'LOCATION') : 'TIME + WEATHER', 34, 48);\n    if (panel.handedness === 'left') this._drawLocation(ctx);\n    else this._drawWeather(ctx);\n    panel.texture.needsUpdate = true;\n  }\n\n  _drawLocation(ctx) {\n    const location = this.getLocation?.() || {};\n    if (this.miniMapVisible) {\n      const cx = 320, cy = 169;\n      this._drawMiniMapTiles(ctx, location, cx, cy);\n      ctx.fillStyle = '#facc15'; ctx.beginPath(); ctx.moveTo(cx, cy - 20); ctx.lineTo(cx - 13, cy + 15); ctx.lineTo(cx + 13, cy + 15); ctx.closePath(); ctx.fill();\n      ctx.fillStyle = '#fff'; ctx.font = '24px sans-serif'; ctx.fillText('N', cx - 9, 75);\n      ctx.font = '22px monospace'; ctx.fillText(`${coord(location.lat, 'N', 'S')}  ${coord(location.lon, 'E', 'W')}`, 34, 302);\n      return;\n    }\n    ctx.fillStyle = '#fff'; ctx.font = '34px monospace';\n    ctx.fillText(coord(location.lat, 'N', 'S'), 34, 112);\n    ctx.fillText(coord(location.lon, 'E', 'W'), 34, 163);\n    ctx.font = '27px sans-serif';\n    const altitude = Number.isFinite(location.altitudeM) ? `${Math.round(location.altitudeM)} m MSL` : 'Altitude --';\n    const agl = Number.isFinite(location.aglM) ? `${Math.round(location.aglM)} m AGL` : 'AGL --';\n    ctx.fillText(`${altitude} · ${agl}`, 34, 220);\n    ctx.fillStyle = '#aaa'; ctx.font = '23px sans-serif'; ctx.fillText('Flip wrist outward to glance', 34, 276);\n  }\n\n  _drawMiniMapTiles(ctx, location, cx, cy) {\n    const lat = Number(location.lat), lon = Number(location.lon);\n    const size = 236;\n    ctx.save(); ctx.beginPath(); ctx.roundRect(cx - size, 58, size * 2, 220, 18); ctx.clip();\n    ctx.fillStyle = '#111'; ctx.fillRect(cx - size, 58, size * 2, 220);\n    if (Number.isFinite(lat) && Number.isFinite(lon) && typeof Image !== 'undefined') {\n      const zoom = 14, count = 2 ** zoom;\n      const safeLat = THREE.MathUtils.clamp(lat, -85.05112878, 85.05112878);\n      const xFloat = ((lon + 180) / 360) * count;\n      const yFloat = (1 - Math.asinh(Math.tan(THREE.MathUtils.degToRad(safeLat))) / Math.PI) * count / 2;\n      const centerX = Math.floor(xFloat), centerY = Math.floor(yFloat), tilePixels = 190;\n      for (let offsetY = -1; offsetY <= 1; offsetY++) {\n        for (let offsetX = -1; offsetX <= 1; offsetX++) {\n          const x = ((centerX + offsetX) % count + count) % count;\n          const y = THREE.MathUtils.clamp(centerY + offsetY, 0, count - 1);\n          const key = `${zoom}/${x}/${y}`;\n          let image = this._miniMapTiles.get(key);\n          if (!image) {\n            image = new Image(); image.crossOrigin = 'anonymous';\n            image.onload = () => { this._nextPaint = 0; };\n            image.onerror = () => { image.failed = true; };\n            image.src = `${String(getMapTileApiBase()).replace(/\\/$/, '')}/tiles/dark/${key}.png?v=20260828.2`;\n            this._miniMapTiles.set(key, image);\n          }\n          if (image.complete && !image.failed && image.naturalWidth) {\n            const drawX = cx + (centerX + offsetX - xFloat) * tilePixels;\n            const drawY = cy + (centerY + offsetY - yFloat) * tilePixels;\n            ctx.drawImage(image, drawX, drawY, tilePixels, tilePixels);\n          }\n        }\n      }\n    }\n    ctx.restore();\n    ctx.strokeStyle = 'rgba(250,204,21,.36)'; ctx.lineWidth = 2;\n    ctx.strokeRect(cx - size, 58, size * 2, 220);\n  }\n\n  _drawWeather(ctx) {\n    const { data, lines } = weatherLines(this.weatherSystem);\n    const sceneTime = Number(this.getSceneTime?.()) || Date.now();\n    const offset = Number(data?.utcOffsetSeconds) || 0;\n    const local = new Date(sceneTime + offset * 1000);\n    const time = local.toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit', timeZone: 'UTC' });\n    const date = local.toLocaleDateString('en-US', { month: 'short', day: 'numeric', timeZone: 'UTC' });\n    ctx.fillStyle = '#fff'; ctx.font = '700 52px sans-serif'; ctx.fillText(time, 34, 116);\n    ctx.fillStyle = '#aaa'; ctx.font = '25px sans-serif'; ctx.fillText(date, 390, 112);\n    ctx.fillStyle = '#fff'; ctx.font = '27px sans-serif';\n    lines.forEach((line, index) => ctx.fillText(line, 34, 174 + index * 43));\n  }\n\n  dispose() {\n    for (const slot of [...this.panels.keys()]) this.disconnect(slot);\n    this._miniMapTiles.clear();\n  }\n}\n","import { getAuthService } from '../auth/AuthService.js';\nimport { getBackendApiBase } from '../shared/backend.js';\n\nexport const VR_ACCESS_REASONS = Object.freeze({\n  ALLOWED: 'allowed',\n  CHECKING: 'checking',\n  SIGN_IN_REQUIRED: 'sign-in-required',\n  WALLET_REQUIRED: 'wallet-required',\n  NOCLIP_REQUIRED: 'noclip-required',\n  UNAVAILABLE: 'unavailable',\n});\n\nexport function hasPositiveNoclipBalance(tier) {\n  const baseUnits = tier?.balanceBaseUnits;\n  if (baseUnits !== undefined && baseUnits !== null) {\n    if (typeof baseUnits !== 'string' || !/^(0|[1-9]\\d*)$/.test(baseUnits)) return false;\n    try { return BigInt(baseUnits) > 0n; } catch { return false; }\n  }\n  const display = Number(tier?.balanceDisplay);\n  return Number.isFinite(display) && display > 0;\n}\n\nexport function evaluateVrAccess(authState, tier) {\n  if (!authState?.resolved) {\n    return { allowed: false, reason: VR_ACCESS_REASONS.CHECKING };\n  }\n  if (!authState?.isAuthenticated) {\n    return { allowed: false, reason: VR_ACCESS_REASONS.SIGN_IN_REQUIRED };\n  }\n  if (!tier) {\n    return { allowed: false, reason: VR_ACCESS_REASONS.CHECKING };\n  }\n  if (Number(tier.walletCount || 0) <= 0) {\n    return { allowed: false, reason: VR_ACCESS_REASONS.WALLET_REQUIRED, tier };\n  }\n  if (!hasPositiveNoclipBalance(tier)) {\n    return { allowed: false, reason: VR_ACCESS_REASONS.NOCLIP_REQUIRED, tier };\n  }\n  return { allowed: true, reason: VR_ACCESS_REASONS.ALLOWED, tier };\n}\n\n/**\n * Fail-closed eligibility cache shared by WebXR and mobile stereo entry.\n * WebXR must inspect the synchronous cache from the input event because\n * awaiting a network request can consume the browser's transient activation.\n */\nexport class VrAccessGate {\n  constructor({ authService = null, eventBus = null, apiBase = null } = {}) {\n    this.authService = authService || getAuthService();\n    this.eventBus = eventBus || null;\n    this.apiBase = apiBase;\n    this._tier = null;\n    this._refreshPromise = null;\n    this._disposed = false;\n\n    this._unsubscribeAuth = this.authService?.subscribe?.((state) => {\n      if (!state?.isAuthenticated) {\n        this._tier = null;\n        this._emitUpdate();\n        return;\n      }\n      void this.refresh();\n    }) || null;\n    this._onTierUpdate = ({ tier } = {}) => this.setTierSnapshot(tier);\n    this.eventBus?.on?.('noclip:tier:update', this._onTierUpdate);\n\n    const initial = this.authService?.getState?.();\n    if (initial?.isAuthenticated) void this.refresh();\n    else if (!initial?.resolved) {\n      const resolved = this.authService?.whenResolved?.();\n      if (resolved?.then) {\n        void resolved.then((state) => {\n          if (state?.isAuthenticated && !this._disposed) return this.refresh();\n          return null;\n        });\n      }\n    }\n  }\n\n  peek() {\n    return evaluateVrAccess(this.authService?.getState?.(), this._tier);\n  }\n\n  async check() {\n    let decision = this.peek();\n    if (decision.reason === VR_ACCESS_REASONS.CHECKING) {\n      await this.refresh();\n      decision = this.peek();\n    }\n    return decision;\n  }\n\n  setTierSnapshot(tier) {\n    this._tier = tier && typeof tier === 'object' ? tier : null;\n    this._emitUpdate();\n    return this.peek();\n  }\n\n  async refresh() {\n    if (this._disposed) return null;\n    const state = this.authService?.getState?.();\n    if (!state?.isAuthenticated) {\n      this._tier = null;\n      this._emitUpdate();\n      return null;\n    }\n    if (this._refreshPromise) return this._refreshPromise;\n\n    const pending = (async () => {\n      try {\n        const base = String(this.apiBase || getBackendApiBase() || '').replace(/\\/+$/, '');\n        const response = await this.authService.authenticatedFetch(`${base}/auth/me/tier`);\n        if (!response?.ok) {\n          this._tier = null;\n          return null;\n        }\n        const tier = await response.json();\n        this._tier = tier && typeof tier === 'object' ? tier : null;\n        return this._tier;\n      } catch (error) {\n        console.warn('[VrAccessGate] NOCLIP eligibility refresh failed', error);\n        this._tier = null;\n        return null;\n      } finally {\n        this._emitUpdate();\n      }\n    })();\n    this._refreshPromise = pending;\n    try {\n      return await pending;\n    } finally {\n      if (this._refreshPromise === pending) this._refreshPromise = null;\n    }\n  }\n\n  deny(decision = this.peek(), source = 'vr') {\n    const payload = { ...decision, source };\n    this.eventBus?.emit?.('vr:access-denied', payload);\n    return false;\n  }\n\n  _emitUpdate() {\n    this.eventBus?.emit?.('vr:access-update', this.peek());\n  }\n\n  dispose() {\n    this._disposed = true;\n    this._unsubscribeAuth?.();\n    this.eventBus?.off?.('noclip:tier:update', this._onTierUpdate);\n    this._tier = null;\n  }\n}\n","/**\n * VRManager.js\n *\n * Manages native WebXR sessions, Earth-local locomotion and ray selection.\n * Provides a custom VR entry button for the HUD dock.\n */\n\nimport * as THREE from 'three';\nimport { XRControllerInput } from './XRControllerInput.js';\nimport { XRLabelLayer } from './XRLabelLayer.js';\nimport { XRInputModels } from './XRInputModels.js';\nimport { XRRadialMenu } from './XRRadialMenu.js';\nimport { XRVisionTools } from './XRVisionTools.js';\nimport { XRWristPanels } from './XRWristPanels.js';\nimport { XR_LABEL_LAYER } from './NativeXRAtmosphereRenderer.js';\nimport { createMapActions } from '../ui/MapActionMenu.js';\nimport { searchPlaces } from '../../modules/geocoding-service.js';\nimport { VrAccessGate } from './VrAccessGate.js';\nimport {\n  LABEL_CATEGORIES,\n  LABEL_CATEGORY_GROUPS,\n  buildLabelCategoryControlPatch,\n  buildLabelCategoryPresetPatch,\n  getLabelCategoriesByGroup,\n  getLabelCategoryControlValue,\n  getLabelCategoryForType,\n  getLabelCategorySourceBinding,\n} from '../labels/LabelCategoryRegistry.js';\n\nconst XR_MENU_SECTOR_LIMIT = 8;\n\n/** Keep controller targets comfortably wide even for high-cardinality feeds. */\nexport function paginateXRMenuItems(items, id, label, pageSize = XR_MENU_SECTOR_LIMIT) {\n  if (items.length <= pageSize) return items;\n  const pages = [];\n  for (let i = 0; i < items.length; i += pageSize) {\n    pages.push({\n      id: `${id}-page-${pages.length + 1}`,\n      label: `${label} ${pages.length + 1}`,\n      children: items.slice(i, i + pageSize),\n    });\n  }\n  return pages;\n}\n\nexport class VRManager {\n  constructor(options = {}) {\n    this.renderer = options.renderer || null;\n    this.scene = options.scene || null;\n    this.camera = options.camera || null;\n    this.eventBus = options.eventBus || null;\n    this._ownsAccessGate = !options.accessGate;\n    this.accessGate = options.accessGate || new VrAccessGate({ eventBus: this.eventBus });\n    this.planetRadius = options.planetRadius || 6371000;\n    // External camera rig (vrDolly from scene-initializer) - preferred over creating our own\n    this._externalCameraRig = options.cameraRig || options.vrDolly || null;\n    // Surface controller reference for VR mode coordination\n    this._surfaceController = options.surfaceController || null;\n    this._labels = options.labels || null;\n    this._settings = options.settings || null;\n    this._presence = options.presenceSystem || null;\n    this._audioSystem = options.audioSystem || null;\n    this._onSurfaceSelect = options.onSurfaceSelect || null;\n    this._onSurfaceContext = options.onSurfaceContext || null;\n    this._onNavigate = options.onNavigate || null;\n    this._weatherSystem = options.weatherSystem || null;\n    this._getLocation = options.getLocation || null;\n    this._getSceneTime = options.getSceneTime || null;\n    this._input = new XRControllerInput();\n    this._labelLayer = null;\n    this._radialMenu = null;\n    this._inputModels = null;\n    this._controllerSlots = [];\n    this._controllerListeners = [];\n    this._ownedResources = new Set();\n    this._selectionRaycaster = new THREE.Raycaster();\n    this._rayToRig = new THREE.Matrix4();\n    this._surfacePoint = new THREE.Vector3();\n    this._visionTools = null;\n    this._wristPanels = null;\n    this._menuHandles = [];\n    this._visibilityListener = () => {\n      this._input.clear(); this._surfaceController?.setXRLocomotionInput?.(null);\n      for (const slot of this._controllerSlots) slot.pending = false;\n      if (this._labelLayer) this._labelLayer.group.visible = this._session?.visibilityState === 'visible';\n      this._radialMenu?.close();\n      if (this._session?.visibilityState === 'visible') void this._resumeSceneAudio('visibility');\n    };\n\n    this._isAvailable = false;\n    this._availabilityPending = true;\n    this._entering = null;\n    this._disposed = false;\n    this._isInSession = false;\n    this._session = null;\n\n    // Controller references\n    this._controller1 = null;\n    this._controller2 = null;\n    this._controllerGrip1 = null;\n    this._controllerGrip2 = null;\n    this._controllerModelFactory = null;\n\n    // Teleport state\n    this._teleportEnabled = false; // Triggers select; no global-plane teleport.\n    this._teleportRay = null;\n    this._teleportTarget = null;\n    this._teleportMarker = null;\n    this._isTeleporting = false;\n    this._teleportController = null;\n\n    // VR camera rig for movement (will use external rig if provided)\n    this._cameraRig = null;\n    this._tmpCamPos = new THREE.Vector3();\n    this._tmpCamQuat = new THREE.Quaternion();\n\n    // State callbacks\n    this._onSessionStartCallbacks = [];\n    this._onSessionEndCallbacks = [];\n    this._onAccessUpdate = (decision = {}) => {\n      if (this._isInSession && !decision.allowed) void this.exit();\n    };\n    this.eventBus?.on?.('vr:access-update', this._onAccessUpdate);\n\n    this.ready = this._init();\n  }\n\n  async _init() {\n    if (!this.renderer) {\n      console.warn('[VRManager] No renderer provided');\n      this._availabilityPending = false;\n      return;\n    }\n\n    // Check WebXR availability\n    if (typeof navigator !== 'undefined' && navigator.xr) {\n      try {\n        this._isAvailable = await navigator.xr.isSessionSupported('immersive-vr');\n      } catch (err) {\n        console.warn('[VRManager] WebXR check failed:', err);\n        this._isAvailable = false;\n      }\n    }\n\n    this._availabilityPending = false;\n    if (this._disposed) return;\n    if (this._isAvailable) {\n      this._setupRenderer();\n      this._setupControllers();\n      this._setupTeleport();\n      this._emit('vr:available', { available: true });\n    } else {\n      this._emit('vr:available', { available: false });\n    }\n  }\n\n  _setupRenderer() {\n    this.renderer.xr.enabled = true;\n    this.renderer.xr.setReferenceSpaceType('local-floor');\n\n    // Use external camera rig if provided (from scene-initializer.vrDolly)\n    // This ensures we use the same rig that's already set up for the camera\n    if (this._externalCameraRig) {\n      this._cameraRig = this._externalCameraRig;\n      console.log('[VRManager] Using external camera rig (vrDolly)');\n      // Camera should already be a child of the external rig\n      this._originalCameraParent = null;\n    } else {\n      // Fallback: create our own camera rig\n      console.log('[VRManager] Creating internal camera rig');\n      this._cameraRig = new THREE.Group();\n      this._cameraRig.name = 'VRCameraRig';\n      this._cameraRig.userData.isVRCameraRig = true;\n      if (this.scene && this.camera) {\n        // Store original camera parent\n        this._originalCameraParent = this.camera.parent;\n        this._cameraRig.add(this.camera);\n        this.scene.add(this._cameraRig);\n      }\n    }\n  }\n\n  _setupControllers() {\n    if (!this.renderer || !this.scene) return;\n    this._inputModels ??= new XRInputModels();\n    // A standalone headset can briefly expose hands AND controllers. Reserve\n    // four native slots, but only connected sources draw/update their models.\n    for (let index = 0; index < 4; index++) {\n      const controller = this.renderer.xr.getController(index);\n      const grip = this.renderer.xr.getControllerGrip(index);\n      if (!controller || !grip) continue;\n      const hand = this.renderer.xr.getHand?.(index);\n      const geometry = new THREE.BufferGeometry().setFromPoints([new THREE.Vector3(), new THREE.Vector3(0, 0, -1)]);\n      const material = new THREE.LineBasicMaterial({ color: 0xfacc15, transparent: true, opacity: 0.72, toneMapped: false });\n      const line = new THREE.Line(geometry, material); line.scale.z = 40; controller.add(line);\n      line.layers.set(XR_LABEL_LAYER);\n      for (const resource of [geometry, material]) this._ownedResources.add(resource);\n      this._cameraRig.add(controller, grip);\n      if (hand) this._cameraRig.add(hand);\n      const slot = {\n        controller, grip, hand, line, pending: false, ray: new THREE.Ray(), nextHover: 0,\n        surfacePoint: new THREE.Vector3(), triggerDown: false, triggerDownAt: 0,\n        triggerHoldFired: false, faceReady: false,\n        faceButtons: { a: { down: false, downAt: 0, held: false }, b: { down: false, downAt: 0, held: false } },\n      };\n      this._controllerSlots.push(slot);\n      const listen = (type, handler) => {\n        controller.addEventListener(type, handler); this._controllerListeners.push([controller, type, handler]);\n      };\n      listen('connected', event => {\n        controller.userData.inputSource = event.data;\n        controller.userData.handedness = event.data?.handedness || 'none';\n        void this._inputModels.connect(slot, event.data);\n        this._wristPanels?.connect(slot, event.data);\n        if (event.data?.handedness === 'right') this._visionTools?.connect(controller);\n        this._emit('vr:controller-connected', { handedness: controller.userData.handedness, controller });\n      });\n      listen('disconnected', () => {\n        controller.userData.inputSource = null; slot.pending = false;\n        slot.triggerDown = false; slot.faceReady = false;\n        this._wristPanels?.disconnect(slot);\n        if (this._visionTools?.controller === controller) {\n          this._visionTools.setMode('off'); this._visionTools.connect(null);\n        }\n        this._inputModels.disconnect(slot);\n        this._input.clear(); this._surfaceController?.setXRLocomotionInput?.(null);\n        this._emit('vr:controller-disconnected', { controller });\n      });\n      listen('selectstart', () => {\n        material.opacity = 1; slot.triggerDown = true;\n        slot.triggerDownAt = typeof performance !== 'undefined' ? performance.now() : Date.now();\n        slot.triggerHoldFired = false;\n      });\n      listen('selectend', () => { material.opacity = 0.72; slot.triggerDown = false; });\n      // Native 'select' fires once for a completed trigger/pinch. selectend can\n      // also mean cancellation and must not perform an action.\n      listen('select', () => {\n        // XR input events do not bubble through the DOM autoplay-unlock hooks.\n        // Retry from the trusted controller gesture in case the browser\n        // suspended Web Audio while installing or hiding the XR session.\n        void this._resumeSceneAudio('controller-select');\n        if (!this._isInSession || this._session?.visibilityState !== 'visible' || !controller.visible) return;\n        if (slot.triggerHoldFired) { slot.triggerHoldFired = false; return; }\n        this._readControllerRay(controller, slot.ray);\n        // Input events occur between render frames. Keep the sampled aim in\n        // room/rig space so Earth rotation and navigation before the next\n        // frame do not leave a stale world-space ray metres behind the user.\n        this._rayToRig.copy(this._cameraRig.matrixWorld).invert();\n        slot.ray.applyMatrix4(this._rayToRig); slot.pending = true;\n      });\n    }\n    [this._controller1, this._controller2] = this._controllerSlots.map(slot => slot.controller);\n    [this._controllerGrip1, this._controllerGrip2] = this._controllerSlots.map(slot => slot.grip);\n    this._visionTools = new XRVisionTools({ scene: this.scene, camera: this.camera, eventBus: this.eventBus });\n    this._wristPanels = new XRWristPanels({\n      camera: this.camera,\n      weatherSystem: this._weatherSystem,\n      getLocation: this._getLocation,\n      getSceneTime: this._getSceneTime,\n    });\n    // UI-only lighting does not participate in the physical terrain pass.\n    this._inputLight = new THREE.HemisphereLight(0xddeeff, 0x686058, 2);\n    this._inputLight.layers.set(XR_LABEL_LAYER); this._cameraRig.add(this._inputLight);\n  }\n\n  _setupTeleport() {} // Legacy initialization hook; triggers now select.\n\n  _readControllerRay(controller, ray) {\n    controller.updateWorldMatrix(true, false);\n    ray.origin.setFromMatrixPosition(controller.matrixWorld);\n    ray.direction.set(0, 0, -1).transformDirection(controller.matrixWorld);\n  }\n\n  updateInput(deltaTime) {\n    if (!this._isInSession || !this._surfaceController?._xrSurfaceRig) return;\n    const xr = this.renderer.xr;\n    const input = this._input.sample(this._session, xr.getFrame(), xr.getReferenceSpace(), deltaTime, {\n      airborne: this._surfaceController.isSurfaceAirborne?.() || false,\n    });\n    this._surfaceController.setXRLocomotionInput(input);\n  }\n\n  updateInteraction(now = performance.now()) {\n    if (!this._isInSession || !this._labelLayer || this._session?.visibilityState !== 'visible') return;\n    this._labelLayer.update(now);\n    this._radialMenu?.update();\n    this._wristPanels?.update(now);\n    this._visionTools?.update();\n    for (const slot of this._controllerSlots) {\n      const source = slot.controller.userData.inputSource;\n      let connected = false;\n      for (const active of this._session.inputSources) if (active === source) connected = true;\n      if (!slot.controller.visible || !source || !connected) {\n        slot.pending = false; continue;\n      }\n      this._inputModels?.update(slot);\n      this._updateFaceButtons(slot, source, now);\n      if (slot.triggerDown && !slot.triggerHoldFired && now - slot.triggerDownAt >= 520) {\n        slot.triggerHoldFired = true; slot.pending = false;\n        if (source.handedness === 'left') this._openNavigationRadial();\n        else this._openContextFromRay(slot);\n        source.gamepad?.hapticActuators?.[0]?.pulse?.(0.35, 35).catch?.(() => {});\n      }\n      if (slot.pending) {\n        slot.pending = false;\n        this._cameraRig.updateWorldMatrix(true, false);\n        const ray = this._selectionRaycaster.ray.copy(slot.ray).applyMatrix4(this._cameraRig.matrixWorld);\n        this._selectionRaycaster.near = 0.02; this._selectionRaycaster.far = 1e16;\n        const radial = this._radialMenu?.pick(this._selectionRaycaster);\n        if (radial) { void this._radialMenu.select(radial); continue; }\n        // An open modal owns triggers. A miss must not select terrain through\n        // its transparent gaps or accidentally launch a second action.\n        if (this._radialMenu?.mesh.visible) continue;\n        const label = this._labelLayer.pick(this._selectionRaycaster);\n        const surface = label?.panel ? null : this._surfaceController.getSurfacePointFromRay?.(ray, this._surfacePoint);\n        const surfaceDistance = surface ? ray.origin.distanceTo(surface) : Infinity;\n        if (label && (label.panel || label.distance <= surfaceDistance + 0.15)) {\n          this._labelLayer.select(label);\n        }\n        else if (surface && this._onSurfaceSelect) {\n          const handle = this._onSurfaceSelect(surface, this._surfaceController._lastGeoHitSource);\n          if (handle) this._labelLayer.open(handle);\n        }\n      }\n      // A throttled terrain ray makes the physical beam terminate at the real\n      // photoreal/surface hit instead of a cosmetic fixed length.\n      if (now >= slot.nextHover) {\n        slot.nextHover = now + 80;\n        this._readControllerRay(slot.controller, this._selectionRaycaster.ray);\n        const uiHit = this._radialMenu?.mesh.visible\n          ? this._radialMenu.pick(this._selectionRaycaster) : this._labelLayer.pick(this._selectionRaycaster);\n        if (this._radialMenu?.mesh.visible) this._radialMenu.hover(uiHit);\n        const surface = this._radialMenu?.mesh.visible ? null\n          : this._surfaceController.getSurfacePointFromRay?.(this._selectionRaycaster.ray, slot.surfacePoint);\n        const surfaceDistance = surface ? this._selectionRaycaster.ray.origin.distanceTo(surface) : Infinity;\n        const hitDistance = Math.min(uiHit?.distance ?? Infinity, surfaceDistance);\n        slot.line.scale.z = Number.isFinite(hitDistance) ? Math.max(0.03, hitDistance) : 250;\n        slot.line.material.opacity = Number.isFinite(hitDistance) ? 1 : 0.72;\n      }\n    }\n  }\n\n  updateTeleport() { this.updateInteraction(); }\n\n  _openRadial(handle, contextCoords = null) {\n    const context = this._labels?.getLabelActions?.(handle);\n    const canonicalItems = context?.items || (contextCoords ? createMapActions({\n      ...contextCoords, onNavigate: destination => this._navigate(destination),\n    }) : (handle ? [{id:'details', label:'Details', run:() => this._labelLayer.open(handle)}] : []));\n    const items = [\n      ...canonicalItems,\n      this._buildLabelMenu(),\n      { id:'exit-vr', label:'Exit VR', nativeXR:true, run:() => this.exit() },\n    ];\n    const adapt = entries => entries.map(item => {\n      if (item.children) return {...item, children:adapt(item.children)};\n      if (item.id === 'details') return {...item, nativeXR:true, run:() => {\n        this._radialMenu.close(); return this._labelLayer.open(handle);\n      }};\n      return {...item, nativeXR:item.nativeXR === true || ['go','follow','track','tag'].includes(item.id)};\n    });\n    this._labelLayer.close(); return this._radialMenu?.open(adapt(items));\n  }\n\n  _updateFaceButtons(slot, source, now) {\n    if (source.handedness !== 'right' || source.gamepad?.mapping !== 'xr-standard') return;\n    const buttons = source.gamepad.buttons || [];\n    const down = key => buttons[key === 'a' ? 4 : 5]?.pressed === true\n      || Number(buttons[key === 'a' ? 4 : 5]?.value) >= 0.75;\n    if (!slot.faceReady) {\n      if (!down('a') && !down('b')) slot.faceReady = true;\n      return;\n    }\n    for (const key of ['a', 'b']) {\n      const state = slot.faceButtons[key], pressed = down(key);\n      if (pressed && !state.down) { state.down = true; state.downAt = now; state.held = false; }\n      if (pressed && !state.held && now - state.downAt >= 475) {\n        state.held = true;\n        if (key === 'a') {\n          const labels = this._buildLabelMenu();\n          this._radialMenu?.open(labels.children || [labels]);\n        } else this._openLayerToolsMenu();\n        source.gamepad?.hapticActuators?.[0]?.pulse?.(0.28, 30).catch?.(() => {});\n      }\n      if (!pressed && state.down) {\n        if (!state.held) {\n          const mode = key === 'a' ? this._visionTools?.toggleFlashlight() : this._visionTools?.toggleNightVision();\n          if (mode) this._emit('vr:toast', { message: mode === 'off' ? 'Vision light off' : mode === 'flashlight' ? 'Flashlight on' : 'IR night vision on' });\n        }\n        state.down = false; state.held = false;\n      }\n    }\n  }\n\n  _openContextFromRay(slot) {\n    this._readControllerRay(slot.controller, this._selectionRaycaster.ray);\n    this._selectionRaycaster.near = 0.02; this._selectionRaycaster.far = 1e16;\n    const label = this._labelLayer?.pick(this._selectionRaycaster);\n    const surface = label?.panel ? null\n      : this._surfaceController?.getSurfacePointFromRay?.(this._selectionRaycaster.ray, slot.surfacePoint);\n    const surfaceDistance = surface ? this._selectionRaycaster.ray.origin.distanceTo(surface) : Infinity;\n    if (label && (label.panel || label.distance <= surfaceDistance + 0.15)) {\n      return this._openRadial(label.handle || this._labelLayer?._selected);\n    }\n    if (surface) {\n      const source = this._surfaceController?._lastGeoHitSource;\n      const handle = this._onSurfaceSelect?.(surface, source);\n      const context = this._onSurfaceContext?.(surface, source);\n      return this._openRadial(handle, context);\n    }\n    return this._openRadial(null);\n  }\n\n  _openNavigationRadial() {\n    const location = this._getLocation?.() || {};\n    const minimap = this._wristPanels?.miniMapVisible === true;\n    const quickSearches = ['Restaurants', 'Hospitals', 'Airports', 'Hotels', 'Fuel', 'Landmarks'].map(query => ({\n      id: `xr-search-${query.toLowerCase()}`, label: query, nativeXR: true,\n      run: ({ signal }) => this._searchPlaces(query, signal),\n    }));\n    this._radialMenu?.open([{\n      id: 'xr-place-search', label: 'Search places',\n      children: [{\n        id: 'xr-voice-search', label: 'Voice search', nativeXR: true,\n        run: ({ signal }) => this._voiceSearchPlaces(signal),\n      }, ...quickSearches],\n    }, {\n      id: 'xr-mini-map', label: minimap ? 'Hide mini map' : 'Show mini map', nativeXR: true,\n      run: () => `${this._wristPanels?.toggleMiniMap() ? 'Mini map shown' : 'Mini map hidden'} on left wrist`,\n    }, {\n      id: 'xr-current-location', label: 'Current location', nativeXR: true,\n      run: () => Number.isFinite(location.lat) && Number.isFinite(location.lon)\n        ? `${location.lat.toFixed(5)}, ${location.lon.toFixed(5)}` : 'Location is still resolving',\n    }, {\n      id: 'xr-exit-vr', label: 'Exit VR', nativeXR: true, run: () => this.exit(),\n    }]);\n  }\n\n  _openLayerToolsMenu() {\n    const labelSettings = this._settings?.getSection?.('scene.labels') || {};\n    const apply = patch => {\n      if (this._settings?.updateScene) this._settings.updateScene(patch);\n      else this._emit('vr:scene-patch', patch);\n    };\n    const layerItems = LABEL_CATEGORIES.filter(category => getLabelCategorySourceBinding(category.id)).map(category => {\n      const enabled = getLabelCategoryControlValue(this._settings, labelSettings, category.id);\n      return {\n        id: `xr-layer-${category.id}`, label: `${category.label} ${enabled ? 'ON' : 'OFF'}`, nativeXR: true,\n        run: () => { apply(buildLabelCategoryControlPatch(category.id, !enabled)); return `${category.label} ${enabled ? 'off' : 'on'}`; },\n      };\n    });\n    this._radialMenu?.open([{\n      id: 'xr-live-layers', label: 'Live layers',\n      children: paginateXRMenuItems(layerItems, 'xr-live-layers', 'Layers'),\n    }, {\n      id: 'xr-flashlight', label: this._visionTools?.mode === 'flashlight' ? 'Light OFF' : 'Flashlight', nativeXR: true,\n      run: () => `Vision mode: ${this._visionTools?.toggleFlashlight() || 'unavailable'}`,\n    }, {\n      id: 'xr-night-vision', label: this._visionTools?.mode === 'night-vision' ? 'IR OFF' : 'IR vision', nativeXR: true,\n      run: () => `Vision mode: ${this._visionTools?.toggleNightVision() || 'unavailable'}`,\n    }, {\n      id: 'xr-mini-map-tool', label: 'Mini map', nativeXR: true,\n      run: () => `${this._wristPanels?.toggleMiniMap() ? 'Mini map shown' : 'Mini map hidden'} on left wrist`,\n    }]);\n  }\n\n  async _voiceSearchPlaces(signal) {\n    const Recognition = globalThis.SpeechRecognition || globalThis.webkitSpeechRecognition;\n    if (!Recognition) throw new Error('Voice place search is unavailable in this headset browser');\n    const query = await new Promise((resolve, reject) => {\n      const recognition = new Recognition();\n      const timer = setTimeout(() => { recognition.abort(); reject(new Error('Place search timed out')); }, 9000);\n      const finish = value => { clearTimeout(timer); signal?.removeEventListener?.('abort', abort); resolve(value); };\n      const abort = () => { recognition.abort(); reject(signal.reason || new Error('Search cancelled')); };\n      recognition.lang = navigator.language || 'en-US'; recognition.interimResults = false; recognition.maxAlternatives = 1;\n      recognition.onresult = event => finish(event.results?.[0]?.[0]?.transcript || '');\n      recognition.onerror = event => { clearTimeout(timer); reject(new Error(event.error || 'Voice recognition failed')); };\n      signal?.addEventListener?.('abort', abort, { once: true });\n      recognition.start();\n    });\n    return this._searchPlaces(query, signal);\n  }\n\n  async _searchPlaces(query, signal) {\n    const location = this._getLocation?.() || {};\n    const results = await searchPlaces(query, { limit: 7, lat: location.lat, lon: location.lon, signal });\n    if (!results.length) return `No places found for ${query}`;\n    const items = results.map((result, index) => ({\n      id: `xr-search-${result.placeId || index}`,\n      label: menuText(result.name || result.displayName || 'Place'), nativeXR: true,\n      run: () => {\n        this._radialMenu?.close();\n        this._navigate({ lat: result.lat, lon: result.lon, label: result.displayName });\n        return `Going to ${result.name || result.displayName}`;\n      },\n    }));\n    this._radialMenu?.open(items);\n    return `Results for ${query}`;\n  }\n\n  _navigate(destination) {\n    if (this._onNavigate) return this._onNavigate(destination);\n    this._emit('vr:navigate', destination);\n  }\n\n  _buildLabelMenu() {\n    const labelSettings = this._settings?.getSection?.('scene.labels') || {};\n    const globalEnabled = labelSettings.enabled !== false;\n    this._menuHandles.length = 0;\n    this._labels?.getXRVisibleHandles?.(this._menuHandles, 64);\n    const handlesByCategory = new Map();\n    for (const handle of this._menuHandles) {\n      const category = getLabelCategoryForType(handle?.type);\n      if (!category) continue;\n      const list = handlesByCategory.get(category.id) || [];\n      list.push(handle); handlesByCategory.set(category.id, list);\n    }\n\n    const apply = patch => {\n      if (this._settings?.updateScene) this._settings.updateScene(patch);\n      else this._emit('vr:scene-patch', patch);\n    };\n    const categoryItem = category => {\n      const enabled = getLabelCategoryControlValue(this._settings, labelSettings, category.id);\n      const handles = handlesByCategory.get(category.id) || [];\n      const labelItems = handles.map((labelHandle, index) => {\n        const presentation = this._labels?.getLabelPresentation?.(labelHandle);\n        return {\n          id: `xr-label-${category.id}-${labelHandle.id || index}`,\n          label: menuText(presentation?.title || labelHandle.displayText || category.label),\n          nativeXR: true,\n          run: () => {\n            this._radialMenu?.close();\n            return this._labelLayer?.open(labelHandle) || 'Label is no longer visible';\n          },\n        };\n      });\n      const visibleItems = labelItems.length\n        ? paginateXRMenuItems(labelItems, `xr-labels-${category.id}`, 'Labels')\n        : [{\n          id: `xr-labels-${category.id}-empty`,\n          label: 'No nearby labels',\n          nativeXR: true,\n          run: () => `No nearby ${category.label.toLowerCase()} labels`,\n        }];\n      return {\n        id: `xr-category-${category.id}`,\n        label: `${category.label} ${enabled ? 'ON' : 'OFF'}${handles.length ? ` · ${handles.length}` : ''}`,\n        children: [{\n          id: `xr-toggle-${category.id}`,\n          label: `${enabled ? 'Disable' : 'Enable'} ${category.label}`,\n          nativeXR: true,\n          run: () => {\n            apply(buildLabelCategoryControlPatch(category.id, !enabled));\n            return `${category.label} labels ${enabled ? 'disabled' : 'enabled'}`;\n          },\n        }, ...visibleItems],\n      };\n    };\n\n    const groups = LABEL_CATEGORY_GROUPS.map(group => {\n      const categories = getLabelCategoriesByGroup(group.id).map(categoryItem);\n      return {\n        id: `xr-label-group-${group.id}`,\n        label: group.label,\n        children: paginateXRMenuItems(categories, `xr-label-group-${group.id}`, 'Categories'),\n      };\n    });\n    const essentialStates = Object.fromEntries(LABEL_CATEGORIES.map(category => [category.id, category.essential === true]));\n    return {\n      id: 'xr-label-controls',\n      label: `Labels ${globalEnabled ? 'ON' : 'OFF'}`,\n      children: [{\n        id: 'xr-label-global-toggle',\n        label: globalEnabled ? 'Hide all labels' : 'Show labels',\n        nativeXR: true,\n        run: () => { apply({ labels: { enabled: !globalEnabled } }); return `Labels ${globalEnabled ? 'hidden' : 'shown'}`; },\n      }, {\n        id: 'xr-label-essentials',\n        label: 'Essential labels',\n        nativeXR: true,\n        run: () => {\n          const patch = buildLabelCategoryPresetPatch(essentialStates);\n          patch.labels = { ...patch.labels, enabled: true };\n          apply(patch); return 'Essential labels enabled';\n        },\n      }, ...groups],\n    };\n  }\n\n  /**\n   * Check if WebXR VR is available\n   */\n  isAvailable() {\n    return this._isAvailable;\n  }\n\n  isAvailabilityPending() {\n    return this._availabilityPending;\n  }\n\n  /**\n   * Check if currently in VR session\n   */\n  isInSession() {\n    return this._isInSession;\n  }\n\n  /**\n   * Enter VR session\n   */\n  enter() {\n    if (this._entering) return this._entering;\n    if (this._disposed || !this._isAvailable || this._isInSession) return Promise.resolve(false);\n    // Do not await here: immersive-vr session requests require transient user\n    // activation. Eligibility is refreshed proactively and entry fails closed\n    // if the signed-in wallet snapshot is not ready yet.\n    const access = this.accessGate?.peek?.();\n    if (access && !access.allowed) {\n      if (access.reason === 'checking') void this.accessGate.refresh?.();\n      return Promise.resolve(this.accessGate.deny?.(access, 'webxr') ?? false);\n    }\n    // Invoke resume synchronously inside the entry click's transient user\n    // activation. Do not await it before requestSession or either browser API\n    // can lose the gesture token.\n    void this._resumeSceneAudio('entry');\n    // Call before awaiting anything: browser user activation belongs to this click.\n    this._entering = this._startSession().finally(() => { this._entering = null; });\n    return this._entering;\n  }\n\n  async _startSession() {\n    let session = null;\n    try {\n      if (this.renderer.xr.isPresenting) throw new DOMException('Exit the current XR session first', 'InvalidStateError');\n      window.__noclipXRDiagnostics?.record('vr-request');\n      const sessionInit = {\n        optionalFeatures: ['local-floor', 'bounded-floor', 'hand-tracking', 'layers']\n      };\n\n      session = await navigator.xr.requestSession('immersive-vr', sessionInit);\n      if (this._disposed) { await session.end(); return false; }\n      this._session = session;\n      // Subscribe before installation; an end during asynchronous setSession\n      // must not publish a phantom active session or leave controllers attached.\n      session.addEventListener('end', () => this._onSessionEnd(session), { once: true });\n      this.renderer.xr.enabled = true; // AR exit may have switched it off.\n      try {\n        await session.requestReferenceSpace('local-floor');\n        this.renderer.xr.setReferenceSpaceType('local-floor');\n      } catch { this.renderer.xr.setReferenceSpaceType('local'); }\n      if (this._disposed || this._session !== session) { await session.end().catch(() => {}); return false; }\n      window.__noclipXRDiagnostics?.bindSession(session, 'immersive-vr');\n      await this.renderer.xr.setSession(session);\n      if (this._disposed || this._session !== session) { await session.end().catch(() => {}); return false; }\n      // The shared SceneInitializer already positions/restores the external\n      // rig for BOTH AR and VR. A second surface-controller entry moves it twice.\n      if (!this._externalCameraRig) this._alignRigToCamera();\n      this._isInSession = true;\n      void this._resumeSceneAudio('session-start');\n      this._presence?.setXRPresenting?.(true);\n      this._input.clear();\n      session.addEventListener('visibilitychange', this._visibilityListener);\n      if (this._labels) this._labelLayer = new XRLabelLayer({ scene: this.scene, camera: this.camera, labels: this._labels });\n      if (this.scene && this.camera) this._radialMenu = new XRRadialMenu({scene:this.scene, camera:this.camera, exitToBrowser:() => this.exit()});\n      window.__noclipXRDiagnostics?.record('vr-start');\n\n      this._emit('vr:session-start', { session });\n      this._onSessionStartCallbacks.forEach(cb => cb(session));\n\n      return true;\n    } catch (err) {\n      window.__noclipXRDiagnostics?.error(err);\n      if (session) {\n        await session.end().catch(() => {});\n        this._onSessionEnd(session);\n      }\n      console.error('[VRManager] Failed to enter VR:', err);\n      this._emit('vr:error', { error: err, scope: 'enter' });\n      return false;\n    }\n  }\n\n  async _resumeSceneAudio(scope) {\n    try {\n      return await this._audioSystem?.resumeForXR?.() || false;\n    } catch (error) {\n      this._emit('audio:error', { error, scope: `webxr-${scope}` });\n      return false;\n    }\n  }\n\n  /**\n   * Exit VR session\n   */\n  async exit() {\n    if (!this._isInSession || !this._session) {\n      return false;\n    }\n\n    try {\n      await this._session.end();\n      return true;\n    } catch (err) {\n      console.error('[VRManager] Failed to exit VR:', err);\n      return false;\n    }\n  }\n\n  _onSessionEnd(endedSession = this._session) {\n    if (!endedSession || this._session !== endedSession) return;\n    this._isInSession = false;\n    this._presence?.setXRPresenting?.(false);\n    const session = this._session;\n    this._session = null;\n    session.removeEventListener('visibilitychange', this._visibilityListener);\n    this._input.clear(); this._surfaceController?.setXRLocomotionInput?.(null);\n    for (const slot of this._controllerSlots) slot.pending = false;\n    for (const slot of this._controllerSlots) {\n      slot.triggerDown = false; slot.faceReady = false;\n      this._wristPanels?.disconnect(slot);\n    }\n    this._visionTools?.setMode('off');\n    this._labelLayer?.dispose(); this._labelLayer = null;\n    this._radialMenu?.dispose(); this._radialMenu = null;\n    for (const slot of this._controllerSlots) this._inputModels?.disconnect(slot);\n\n    if (!this._externalCameraRig) this._restoreCameraFromRig();\n    window.__noclipXRDiagnostics?.record('vr-end');\n\n    // Hide teleport marker\n    if (this._teleportMarker) {\n      this._teleportMarker.visible = false;\n    }\n    this._isTeleporting = false;\n    this._teleportTarget = null;\n\n    this._emit('vr:session-end', { session });\n    this._onSessionEndCallbacks.forEach(cb => cb(session));\n  }\n\n  _alignRigToCamera() {\n    if (!this._cameraRig || !this.camera) return;\n\n    // If we have a surface controller, let it handle VR mode entry\n    // This ensures proper coordination with the existing dolly system\n    if (this._surfaceController && typeof this._surfaceController.enterVRMode === 'function') {\n      this._surfaceController.enterVRMode();\n      console.log('[VRManager] Delegated rig alignment to surfaceController.enterVRMode()');\n      return;\n    }\n\n    // Fallback: handle alignment ourselves\n    this.camera.updateMatrixWorld(true);\n    this.camera.getWorldPosition(this._tmpCamPos);\n    this.camera.getWorldQuaternion(this._tmpCamQuat);\n\n    this._cameraRig.position.copy(this._tmpCamPos);\n\n    // Extract yaw from camera orientation for dolly rotation\n    const forward = new THREE.Vector3(0, 0, -1).applyQuaternion(this._tmpCamQuat);\n    forward.y = 0;\n    if (forward.lengthSq() > 0.001) {\n      forward.normalize();\n      const yaw = Math.atan2(forward.x, forward.z);\n      this._cameraRig.rotation.set(0, yaw + Math.PI, 0);\n    }\n    this._cameraRig.updateMatrixWorld(true);\n\n    // Reset camera to local origin - headset controls position within rig\n    this.camera.position.set(0, 0, 0);\n    this.camera.rotation.set(0, 0, 0);\n    this.camera.updateMatrixWorld(true);\n  }\n\n  _restoreCameraFromRig() {\n    if (!this._cameraRig || !this.camera) return;\n\n    // If we have a surface controller, let it handle VR mode exit\n    if (this._surfaceController && typeof this._surfaceController.exitVRMode === 'function') {\n      this._surfaceController.exitVRMode();\n      console.log('[VRManager] Delegated rig restoration to surfaceController.exitVRMode()');\n      return;\n    }\n\n    // Fallback: handle restoration ourselves\n    this._cameraRig.updateMatrixWorld(true);\n\n    // Get the XR camera's world position (where user ended up in VR)\n    const xrCamera = this.renderer?.xr?.getCamera?.(this.camera);\n    if (xrCamera) {\n      this._tmpCamPos.setFromMatrixPosition(xrCamera.matrixWorld);\n    } else {\n      this._cameraRig.getWorldPosition(this._tmpCamPos);\n    }\n\n    // Reset rig to origin and move camera to world position\n    this._cameraRig.position.set(0, 0, 0);\n    this._cameraRig.rotation.set(0, 0, 0);\n    this._cameraRig.updateMatrixWorld(true);\n\n    this.camera.position.copy(this._tmpCamPos);\n    this.camera.updateMatrixWorld(true);\n  }\n\n  /**\n   * Register callback for session start\n   */\n  onSessionStart(callback) {\n    if (typeof callback === 'function') {\n      this._onSessionStartCallbacks.push(callback);\n    }\n  }\n\n  /**\n   * Register callback for session end\n   */\n  onSessionEnd(callback) {\n    if (typeof callback === 'function') {\n      this._onSessionEndCallbacks.push(callback);\n    }\n  }\n\n  /**\n   * Enable/disable teleport locomotion\n   */\n  setTeleportEnabled(enabled) {\n    this._teleportEnabled = false; // Global-plane teleport is retired; triggers select.\n    if (!enabled && this._teleportMarker) {\n      this._teleportMarker.visible = false;\n    }\n  }\n\n  /**\n   * Set the surface controller reference (for VR mode coordination)\n   */\n  setSurfaceController(controller) {\n    this._surfaceController = controller;\n    // Also pass the camera rig to the surface controller\n    if (controller && typeof controller.setVRDolly === 'function' && this._cameraRig) {\n      controller.setVRDolly(this._cameraRig);\n    }\n  }\n\n  /**\n   * Set the camera rig to use (can be called after init)\n   */\n  setCameraRig(rig) {\n    if (!rig) return;\n    this._cameraRig = rig;\n    this._externalCameraRig = rig;\n    // Update controllers to be children of the new rig\n    if (this._controller1 && this._controller1.parent !== rig) {\n      rig.add(this._controller1);\n    }\n    if (this._controller2 && this._controller2.parent !== rig) {\n      rig.add(this._controller2);\n    }\n    if (this._controllerGrip1 && this._controllerGrip1.parent !== rig) {\n      rig.add(this._controllerGrip1);\n    }\n    if (this._controllerGrip2 && this._controllerGrip2.parent !== rig) {\n      rig.add(this._controllerGrip2);\n    }\n  }\n\n  /**\n   * Get camera rig for external manipulation\n   */\n  getCameraRig() {\n    return this._cameraRig;\n  }\n\n  /**\n   * Get controllers\n   */\n  getControllers() {\n    return [this._controller1, this._controller2].filter(Boolean);\n  }\n\n  _emit(eventName, data) {\n    if (this.eventBus) {\n      this.eventBus.emit(eventName, data);\n    }\n  }\n\n  /**\n   * Cleanup\n   */\n  dispose() {\n    this._disposed = true;\n    this._visibilityListener();\n    this._labelLayer?.dispose(); this._labelLayer = null;\n    this._radialMenu?.dispose(); this._radialMenu = null;\n    this._inputModels?.dispose(); this._inputModels = null;\n    this._wristPanels?.dispose(); this._wristPanels = null;\n    this._visionTools?.dispose(); this._visionTools = null;\n    this._inputLight?.removeFromParent();\n    if (this._session) this._session.end().catch(() => {});\n    for (const [target, type, handler] of this._controllerListeners) target.removeEventListener(type, handler);\n    this._controllerListeners.length = 0;\n    for (const slot of this._controllerSlots) {\n      slot.line.removeFromParent(); slot.controller.removeFromParent(); slot.grip.removeFromParent(); slot.hand?.removeFromParent();\n    }\n    for (const resource of this._ownedResources) resource.dispose();\n    this._ownedResources.clear();\n    if (this._ownsAccessGate) this.accessGate?.dispose?.();\n    this.eventBus?.off?.('vr:access-update', this._onAccessUpdate);\n\n    // Remove teleport marker\n    if (this._teleportMarker && this._teleportMarker.parent) {\n      this._teleportMarker.parent.remove(this._teleportMarker);\n      this._teleportMarker.geometry?.dispose();\n      this._teleportMarker.material?.dispose();\n    }\n\n    // Remove controllers from rig\n    [this._controller1, this._controller2, this._controllerGrip1, this._controllerGrip2]\n      .filter(Boolean)\n      .forEach(controller => {\n        if (controller.parent) {\n          controller.parent.remove(controller);\n        }\n      });\n\n    // Restore camera to original parent\n    if (this.camera && this._originalCameraParent) {\n      this._originalCameraParent.add(this.camera);\n    }\n\n    // Remove camera rig\n    if (!this._externalCameraRig && this._cameraRig && this._cameraRig.parent) {\n      this._cameraRig.parent.remove(this._cameraRig);\n    }\n\n    this._onSessionStartCallbacks = [];\n    this._onSessionEndCallbacks = [];\n  }\n}\n\n// Singleton instance\nlet vrManagerInstance = null;\n\nexport function getVRManager(options = {}) {\n  if (!vrManagerInstance) {\n    vrManagerInstance = new VRManager(options);\n  }\n  return vrManagerInstance;\n}\n\nfunction menuText(value) {\n  const clean = String(value ?? '').replace(/[\\u0000-\\u001f]/g, ' ').trim();\n  return clean.length > 34 ? clean.slice(0, 33) + '…' : (clean || 'Label');\n}\n","/**\n * Avatar - Animated character with state machine\n *\n * Handles:\n * - Animation state machine (Idle, Walk, Run, Crouch, Jump, Fall, Meditate)\n * - Phase-synced animation transitions\n * - Head look IK for VR/XR\n * - Jump arc physics\n * - Speed-based animation tempo scaling\n */\n\nimport * as THREE from 'three';\nimport { enableMeshSpaceSkinning } from './MeshSpaceSkinning.js';\nimport {\n  DEFAULT_AVATAR_APPEARANCE,\n  normalizeAvatarAppearance,\n} from './AvatarAppearance.js';\n\n// Exponential smoothing helper\nfunction smoothAlpha(ratePerSec, dt) {\n  return 1 - Math.exp(-Math.max(0, ratePerSec) * Math.max(0, dt));\n}\n\n// Primary animation states\nconst PRIMARY_STATE_KEYS = [\n  'Idle',\n  'WalkForward',\n  'WalkBackward',\n  'WalkLeft',\n  'WalkRight',\n  'Sprint',\n  'CrouchIdle',\n  'CrouchForward',\n  'CrouchBackward',\n  'CrouchLeft',\n  'CrouchRight',\n  'Fall',\n  'Jump',\n  'Meditate',\n  'Death',\n  'Surrender'\n];\n\n// State aliases for backwards compatibility\nconst STATE_ALIASES = {\n  Walk: 'WalkForward',\n  Run: 'Sprint'\n};\n\n// Reference speeds for animation tempo scaling\nconst STATE_SPEED_REF = {\n  WalkForward: 1.8,\n  WalkBackward: 1.6,\n  WalkLeft: 1.4,\n  WalkRight: 1.4,\n  Sprint: 5.0,\n  CrouchForward: 1.1,\n  CrouchBackward: 1.1,\n  CrouchLeft: 1.0,\n  CrouchRight: 1.0\n};\n\n// Thresholds for state selection\nconst IDLE_SPEED_THRESHOLD = 0.12;      // m/s - below this is idle\nconst RUN_SPEED_THRESHOLD = 3.4;        // m/s - above this is sprint/run\nconst DIRECTION_THRESHOLD = 0.25;       // for strafe vs forward detection\n\n/**\n * Avatars are solid scene geometry. Imported GLBs and preview/debug code can\n * leave blending or depth flags behind on a cloned material; that makes the\n * photoreal surface visible through a character even when its color alpha is\n * one. Reassert the render contract on every owned material.\n */\nexport function enforceOpaqueAvatarMaterial(material) {\n  if (!material) return material;\n  material.transparent = false;\n  material.opacity = 1;\n  material.alphaTest = 0;\n  if ('alphaHash' in material) material.alphaHash = false;\n  if ('alphaToCoverage' in material) material.alphaToCoverage = false;\n  material.depthTest = true;\n  material.depthWrite = true;\n  material.colorWrite = true;\n  material.blending = THREE.NormalBlending;\n  material.premultipliedAlpha = false;\n  return material;\n}\n\n/**\n * Avatar class - represents a single animated character\n */\nexport class Avatar {\n  constructor(root, clips, footYOffset, height, groundContact = null) {\n    this.group = new THREE.Group();\n    this.group.name = 'Avatar';\n    this.group.add(root);\n\n    this.root = root;\n    this.height = height || 1.7;\n    this.mixer = new THREE.AnimationMixer(root);\n    this._ownedMaterials = new Set();\n    this.appearance = null;\n\n    this._rootRestY = Number.isFinite(this.root.position.y) ? this.root.position.y : 0;\n    this._staticFootYOffset = Number.isFinite(footYOffset) ? footYOffset : 0;\n    this._groundContact = groundContact?.profiles ? groundContact : null;\n    this._baseGroundOffset = Number.isFinite(this._groundContact?.baseOffset)\n      ? this._groundContact.baseOffset\n      : this._staticFootYOffset;\n\n    // Preserve the established first-person camera rig measurement. Visual\n    // shoe calibration is applied after eye height is measured and is kept\n    // independent from the explicit camera-to-terrain AGL contract.\n    this.root.position.y = this._rootRestY - this._staticFootYOffset;\n\n    // Head look IK state\n    this._neckBone = null;\n    this._headBone = null;\n    this._headLookTargetYaw = 0;\n    this._headLookTargetPitch = 0;\n    this._headLookTargetRoll = 0;\n    this._headLookCurYaw = 0;\n    this._headLookCurPitch = 0;\n    this._headLookCurRoll = 0;\n    this._headLookTargetActive = false;\n    this._headLookRate = 12;\n    this._headYawMax = THREE.MathUtils.degToRad(75);\n    this._headPitchUpMax = THREE.MathUtils.degToRad(55);\n    this._headPitchDownMax = THREE.MathUtils.degToRad(65);\n    this._headRollMax = THREE.MathUtils.degToRad(30);\n    this._tmpQuatNeck = new THREE.Quaternion();\n    this._tmpQuatHead = new THREE.Quaternion();\n    this._appliedHeadLookNeck = new THREE.Quaternion();\n    this._appliedHeadLookHead = new THREE.Quaternion();\n    this._hasAppliedHeadLookNeck = false;\n    this._hasAppliedHeadLookHead = false;\n\n    this._initHeadBones();\n    this.eyeHeight = this._computeEyeHeight();\n\n    // Static bounds previously used the opposite sign here, putting the\n    // character below its contact point. The calibrated positive offset moves\n    // the deformed sole onto local y=0.\n    this.root.position.y = this._rootRestY + this._baseGroundOffset;\n\n    // SkeletonUtils clones share geometry and materials with the factory\n    // template. Geometry is intentionally immutable/shared, while materials\n    // are cloned per avatar so appearance edits and peer disposal cannot\n    // change or invalidate another visible user.\n    const materialClones = new Map();\n    this.root.traverse((obj) => {\n      if (obj.isMesh) {\n        obj.castShadow = true;\n        obj.receiveShadow = true;\n        const cloneMaterial = (material) => {\n          if (!material?.clone) return material;\n          if (!materialClones.has(material)) {\n            const clone = enforceOpaqueAvatarMaterial(material.clone());\n            materialClones.set(material, clone);\n            this._ownedMaterials.add(clone);\n          }\n          return materialClones.get(material);\n        };\n        obj.material = Array.isArray(obj.material)\n          ? obj.material.map(cloneMaterial)\n          : cloneMaterial(obj.material);\n      }\n    });\n    this.applyAppearance(DEFAULT_AVATAR_APPEARANCE);\n\n    // Keep skinning math in mesh space to avoid precision loss at planetary scale.\n    this._enableMeshSpaceSkinning();\n\n    // Build animation actions\n    this.actions = {};\n    this._stateOrder = [];\n\n    const registerAction = (state, clip) => {\n      if (!clip || this.actions[state]) return;\n      const action = this.mixer.clipAction(clip);\n      action.enabled = true;\n      action.setEffectiveTimeScale(1);\n      action.setEffectiveWeight(0);\n\n      // Special handling for one-shot animations\n      if (state === 'Fall' || state === 'Jump' || state === 'Death' || state === 'Surrender') {\n        action.loop = THREE.LoopOnce;\n        action.clampWhenFinished = true;\n      } else {\n        action.loop = THREE.LoopRepeat;\n      }\n\n      this.actions[state] = action;\n      this._stateOrder.push(state);\n    };\n\n    const getClipForState = (state) => {\n      if (clips[state]) return clips[state];\n      for (const [alias, target] of Object.entries(STATE_ALIASES)) {\n        if (target === state && clips[alias]) return clips[alias];\n      }\n      return null;\n    };\n\n    // Register all primary states\n    for (const state of PRIMARY_STATE_KEYS) {\n      const clip = getClipForState(state);\n      if (clip) registerAction(state, clip);\n    }\n\n    // Start with Idle or first available state\n    const startState = this._chooseAvailable(['Idle', 'CrouchIdle', 'WalkForward', 'Sprint']);\n    if (startState && this.actions[startState]) {\n      this.actions[startState].setEffectiveWeight(1).play();\n    }\n    this.current = startState || null;\n\n    // State tracking\n    this._isCrouch = false;\n    this._manualState = null;\n    this._airborneManual = false;\n    this._airborneAuto = false;\n    this._lastPos = new THREE.Vector3();\n    this._velWorld = new THREE.Vector3();\n    this._velLocal = new THREE.Vector3();\n    this._invQuat = new THREE.Quaternion();\n    this._hasPrevPos = false;\n    this._hasExternalVelocity = false;\n\n    // Transition settings\n    this.fadeDuration = 0.35;\n\n    // Speed smoothing (EMA)\n    this._vTarget = 0;\n    this._vSmooth = 0;\n    this._vRate = 12;\n    this._idleSpeedThreshold = IDLE_SPEED_THRESHOLD;\n    this._runSpeedThreshold = RUN_SPEED_THRESHOLD;\n    this._directionThreshold = DIRECTION_THRESHOLD;\n    this._speedRef = { ...STATE_SPEED_REF };\n\n    // Jump physics\n    this.GRAV = 20;\n    this.JUMP_H = 0.8;\n    this.jumpState = 'idle';\n    this.vertVel = 0;\n    this.jumpYOffset = 0;\n    this.baseY = 0;\n\n    // Debug proxy rendering\n    this._debugProxyEnabled = false;\n    this._debugBall = null;\n    this._debugBallRadius = 0.35;\n    this._debugBallColor = '#38bdf8';\n  }\n\n  /**\n   * Initialize head bones for IK\n   */\n  _initHeadBones() {\n    const seen = new Set();\n    const considerBone = (bone) => {\n      if (!bone || seen.has(bone)) return;\n      seen.add(bone);\n      const name = String(bone.name || '').toLowerCase();\n      if (!this._neckBone && name.includes('neck')) {\n        this._neckBone = bone;\n        return;\n      }\n      if (!this._headBone && name.includes('head')) {\n        this._headBone = bone;\n      }\n    };\n\n    this.root.traverse((obj) => {\n      if (this._neckBone && this._headBone) return;\n      if (!obj?.isSkinnedMesh || !obj.skeleton) return;\n      for (const bone of obj.skeleton.bones) {\n        considerBone(bone);\n        if (this._neckBone && this._headBone) return;\n      }\n    });\n\n    // If we found neck but not head, look for head as child of neck\n    if (!this._headBone && this._neckBone) {\n      const directChild = this._neckBone.children?.find?.(\n        (child) => child?.isBone && String(child.name || '').toLowerCase().includes('head')\n      );\n      if (directChild) {\n        this._headBone = directChild;\n      } else if (this._neckBone.children?.length) {\n        const firstBoneChild = this._neckBone.children.find((child) => child?.isBone);\n        if (firstBoneChild) this._headBone = firstBoneChild;\n      }\n    }\n  }\n\n  _computeEyeHeight() {\n    const bone = this._headBone || this._neckBone;\n    const offset = this._getEyeHeightOffset();\n    if (!bone) {\n      const fallback = Math.max(0.1, this.height * 0.9);\n      return this._clampEyeHeight(fallback + offset);\n    }\n    this.group.updateMatrixWorld(true);\n    const worldPos = new THREE.Vector3();\n    bone.getWorldPosition(worldPos);\n    this.group.worldToLocal(worldPos);\n    if (!Number.isFinite(worldPos.y)) {\n      const fallback = Math.max(0.1, this.height * 0.9);\n      return this._clampEyeHeight(fallback + offset);\n    }\n    return this._clampEyeHeight(worldPos.y + offset);\n  }\n\n  _getEyeHeightOffset() {\n    if (Number.isFinite(this._eyeHeightOffset)) return this._eyeHeightOffset;\n    const base = Number.isFinite(this.height) ? this.height : 1.7;\n    // Lift camera slightly into the head volume for first-person alignment.\n    this._eyeHeightOffset = Math.max(0, base * 0.06);\n    return this._eyeHeightOffset;\n  }\n\n  _clampEyeHeight(value) {\n    const max = Number.isFinite(this.height) ? Math.max(0.1, this.height * 0.98) : value;\n    return Math.min(Math.max(0.1, value), max);\n  }\n\n  _enableMeshSpaceSkinning() {\n    return enableMeshSpaceSkinning(this.root, this.group);\n  }\n\n  /**\n   * Choose first available state from candidates\n   */\n  _chooseAvailable(candidates = []) {\n    for (const name of candidates) {\n      const mapped = STATE_ALIASES[name] || name;\n      if (this.actions[mapped]) return mapped;\n    }\n    for (const state of this._stateOrder) {\n      if (this.actions[state]) return state;\n    }\n    return this.current && this.actions[this.current] ? this.current : null;\n  }\n\n  /**\n   * Select animation state based on movement\n   */\n  _selectState({ speed, forward, strafe, airborne }) {\n    // Airborne takes priority\n    if (airborne) {\n      if (this.actions.Fall) return 'Fall';\n      if (this.actions.Jump) return 'Jump';\n    }\n\n    const absForward = Math.abs(forward);\n    const absStrafe = Math.abs(strafe);\n    const primaryForward = absForward >= absStrafe;\n\n    // Idle check\n    if (speed < this._idleSpeedThreshold) {\n      return this._isCrouch\n        ? this._chooseAvailable(['CrouchIdle', 'Idle'])\n        : this._chooseAvailable(['Idle', 'CrouchIdle', 'WalkForward']);\n    }\n\n    // Crouching movement\n    if (this._isCrouch) {\n      if (primaryForward) {\n        if (forward > this._directionThreshold) return this._chooseAvailable(['CrouchForward', 'CrouchIdle']);\n        if (forward < -this._directionThreshold) return this._chooseAvailable(['CrouchBackward', 'CrouchIdle']);\n      } else {\n        if (strafe > this._directionThreshold) return this._chooseAvailable(['CrouchRight', 'CrouchForward', 'CrouchIdle']);\n        if (strafe < -this._directionThreshold) return this._chooseAvailable(['CrouchLeft', 'CrouchForward', 'CrouchIdle']);\n      }\n      return this._chooseAvailable(['CrouchIdle', 'Idle']);\n    }\n\n    // Standing movement\n    if (primaryForward) {\n      if (forward > this._directionThreshold) {\n        if (speed >= this._runSpeedThreshold) {\n          return this._chooseAvailable(['Sprint', 'Run', 'WalkForward', 'Walk']);\n        }\n        return this._chooseAvailable(['WalkForward', 'Walk', 'Sprint']);\n      }\n      if (forward < -this._directionThreshold) {\n        return this._chooseAvailable(['WalkBackward', 'WalkForward', 'Walk']);\n      }\n    } else {\n      if (strafe > this._directionThreshold) {\n        return this._chooseAvailable(['WalkRight', 'WalkForward', 'Walk']);\n      }\n      if (strafe < -this._directionThreshold) {\n        return this._chooseAvailable(['WalkLeft', 'WalkForward', 'Walk']);\n      }\n    }\n\n    // Default based on speed\n    if (speed >= this._runSpeedThreshold) {\n      return this._chooseAvailable(['Sprint', 'Run', 'WalkForward', 'Walk']);\n    }\n    return this._chooseAvailable(['WalkForward', 'Walk', 'Idle']);\n  }\n\n  /**\n   * Phase-synced animation transition\n   */\n  _transition(nextName) {\n    const next = this.actions[nextName];\n    const prev = this.actions[this.current];\n\n    if (nextName === this.current) return;\n    this.current = nextName;\n\n    if (!next) {\n      if (prev) prev.fadeOut(this.fadeDuration);\n      return;\n    }\n\n    if (!prev || prev === next) {\n      next.reset().fadeIn(this.fadeDuration).play();\n      return;\n    }\n\n    // Phase sync for smooth foot transitions\n    const prevClip = prev.getClip();\n    const nextClip = next.getClip();\n    const prevDur = Math.max(1e-6, prevClip?.duration || 1);\n    const nextDur = Math.max(1e-6, nextClip?.duration || 1);\n    const norm = (prev.time % prevDur) / prevDur;\n\n    next.enabled = true;\n    next.reset();\n    next.time = norm * nextDur;\n    next.setEffectiveWeight(1);\n\n    // Cross-fade with warp to preserve cadence\n    next.crossFadeFrom(prev, this.fadeDuration, true);\n    next.play();\n  }\n\n  /**\n   * Set avatar quaternion (facing direction)\n   */\n  setQuaternion(q) {\n    this.group.quaternion.copy(q);\n  }\n\n  /**\n   * Set avatar position\n   */\n  setPosition(x, y, z) {\n    this.baseY = y;\n    const newY = y + this.jumpYOffset;\n    this.group.position.set(x, newY, z);\n\n    if (!this._hasPrevPos) {\n      this._lastPos.set(x, newY, z);\n      this._hasPrevPos = true;\n    } else {\n      // Detect teleportation (large position change)\n      const dx = x - this._lastPos.x;\n      const dy = newY - this._lastPos.y;\n      const dz = z - this._lastPos.z;\n      const distSq = dx * dx + dy * dy + dz * dz;\n      if (distSq > 25) {\n        this._lastPos.set(x, newY, z);\n      }\n    }\n  }\n\n  /**\n   * Set instantaneous speed for animation selection\n   */\n  setSpeed(speed) {\n    this._vTarget = speed;\n  }\n\n  /**\n   * Set external velocity for animation state selection (used by PeerManager)\n   * This bypasses internal position-based velocity tracking\n   * @param {THREE.Vector3} velocity - World-space velocity vector\n   */\n  setExternalVelocity(velocity) {\n    if (!velocity) return;\n\n    // Store world velocity\n    this._velWorld.copy(velocity);\n\n    // Compute horizontal speed\n    const horizontalSpeed = Math.hypot(velocity.x, velocity.z);\n    this._vTarget = horizontalSpeed;\n\n    // Convert to local space for direction detection\n    this._velLocal.set(velocity.x, 0, velocity.z);\n    if (this._velLocal.lengthSq() > 1e-6) {\n      this._invQuat.copy(this.group.quaternion).invert();\n      this._velLocal.applyQuaternion(this._invQuat);\n    } else {\n      this._velLocal.set(0, 0, 0);\n    }\n\n    // Mark that we have external velocity (skip internal tracking this frame)\n    this._hasExternalVelocity = true;\n  }\n\n  /**\n   * Set crouch state\n   */\n  setCrouch(active) {\n    this._isCrouch = !!active;\n  }\n\n  /**\n   * Set airborne state (external, e.g., from physics)\n   */\n  setAirborne(active) {\n    this._airborneManual = !!active;\n  }\n\n  /**\n   * Set head look angles for IK\n   */\n  setHeadLook(state = {}) {\n    const hasAngles = Number.isFinite(state.yaw) || Number.isFinite(state.pitch) || Number.isFinite(state.roll);\n    const active = state.active != null ? !!state.active : hasAngles;\n\n    const yawRaw = Number.isFinite(state.yaw) ? state.yaw : 0;\n    const pitchRaw = Number.isFinite(state.pitch) ? state.pitch : 0;\n    const rollRaw = Number.isFinite(state.roll) ? state.roll : 0;\n\n    const yaw = THREE.MathUtils.clamp(yawRaw, -this._headYawMax, this._headYawMax);\n    const pitch = THREE.MathUtils.clamp(pitchRaw, -this._headPitchDownMax, this._headPitchUpMax);\n    const roll = THREE.MathUtils.clamp(rollRaw, -this._headRollMax, this._headRollMax);\n\n    this._headLookTargetActive = active;\n    this._headLookTargetYaw = active ? yaw : 0;\n    this._headLookTargetPitch = active ? pitch : 0;\n    this._headLookTargetRoll = active ? roll : 0;\n  }\n\n  /**\n   * Trigger a jump\n   */\n  jump() {\n    if (this.jumpState !== 'idle') return;\n    this.vertVel = Math.sqrt(2 * this.GRAV * this.JUMP_H);\n    this.jumpState = 'jumping';\n    this._airborneAuto = true;\n  }\n\n  /**\n   * Force a specific animation state (e.g., Meditate)\n   */\n  setManualState(stateName) {\n    if (!stateName) {\n      this._manualState = null;\n      return true;\n    }\n    if (!this.actions[stateName]) return false;\n    if (this._manualState === stateName) return true;\n    this._manualState = stateName;\n    this._transition(stateName);\n    return true;\n  }\n\n  /**\n   * Clear manual state override\n   */\n  clearManualState(stateName = null) {\n    if (!this._manualState) return;\n    if (stateName && stateName !== this._manualState) return;\n    this._manualState = null;\n  }\n\n  /**\n   * Apply head look IK\n   */\n  _applyHeadLook(dt) {\n    if (!this._neckBone && !this._headBone) return;\n\n    const alpha = smoothAlpha(this._headLookRate, dt);\n    this._headLookCurYaw += (this._headLookTargetYaw - this._headLookCurYaw) * alpha;\n    this._headLookCurPitch += (this._headLookTargetPitch - this._headLookCurPitch) * alpha;\n    this._headLookCurRoll += (this._headLookTargetRoll - this._headLookCurRoll) * alpha;\n\n    const yaw = this._headLookCurYaw;\n    const pitch = this._headLookCurPitch;\n    const roll = this._headLookCurRoll;\n    const magnitude = Math.abs(yaw) + Math.abs(pitch) + Math.abs(roll);\n\n    if (magnitude < 1e-4 && !this._headLookTargetActive) return;\n\n    if (this._neckBone) {\n      // Negate pitch for correct look direction (positive pitch = look up)\n      this._tmpQuatNeck.setFromEuler(new THREE.Euler(-pitch * 0.5, yaw * 0.6, roll * 0.3, 'XYZ'));\n      this._neckBone.quaternion.multiply(this._tmpQuatNeck);\n      this._appliedHeadLookNeck.copy(this._tmpQuatNeck);\n      this._hasAppliedHeadLookNeck = true;\n      this._neckBone.updateMatrixWorld(true);\n    }\n\n    if (this._headBone) {\n      // Negate pitch for correct look direction (positive pitch = look up)\n      this._tmpQuatHead.setFromEuler(new THREE.Euler(-pitch * 0.75, yaw * 0.4, roll * 0.7, 'XYZ'));\n      this._headBone.quaternion.multiply(this._tmpQuatHead);\n      this._appliedHeadLookHead.copy(this._tmpQuatHead);\n      this._hasAppliedHeadLookHead = true;\n      this._headBone.updateMatrixWorld(true);\n    }\n  }\n\n  /**\n   * Remove only the IK delta applied after the previous mixer evaluation.\n   * Some character clips do not key the neck/head bones, so multiplying a new\n   * delta without this step accumulates rotation forever. Clearing first keeps\n   * every frame relative to the current animation pose.\n   */\n  _clearAppliedHeadLook() {\n    if (this._neckBone && this._hasAppliedHeadLookNeck) {\n      this._tmpQuatNeck.copy(this._appliedHeadLookNeck).invert();\n      this._neckBone.quaternion.multiply(this._tmpQuatNeck).normalize();\n      this._appliedHeadLookNeck.identity();\n      this._hasAppliedHeadLookNeck = false;\n    }\n    if (this._headBone && this._hasAppliedHeadLookHead) {\n      this._tmpQuatHead.copy(this._appliedHeadLookHead).invert();\n      this._headBone.quaternion.multiply(this._tmpQuatHead).normalize();\n      this._appliedHeadLookHead.identity();\n      this._hasAppliedHeadLookHead = false;\n    }\n  }\n\n  _sampleGroundContactOffset(profile, action) {\n    const offsets = profile?.offsets;\n    const count = offsets?.length || 0;\n    if (!count) return this._baseGroundOffset;\n    if (count === 1) return offsets[0];\n\n    const duration = Math.max(1e-6, action?.getClip?.()?.duration || profile.duration || 1);\n    const rawPhase = (Number(action?.time) || 0) / duration;\n    const phase = ((rawPhase % 1) + 1) % 1;\n    const scaled = phase * count;\n    const index = Math.floor(scaled) % count;\n    const nextIndex = (index + 1) % count;\n    const previousIndex = (index - 1 + count) % count;\n    const followingIndex = (nextIndex + 1) % count;\n    const t = scaled - Math.floor(scaled);\n    const t2 = t * t;\n    const t3 = t2 * t;\n    // Periodic Catmull-Rom follows the smooth sole-height curve much more\n    // closely between samples than a straight segment, without any geometry\n    // work in the frame loop.\n    let offset = 0.5 * (\n      (2 * offsets[index])\n      + (-offsets[previousIndex] + offsets[nextIndex]) * t\n      + (2 * offsets[previousIndex] - 5 * offsets[index] + 4 * offsets[nextIndex] - offsets[followingIndex]) * t2\n      + (-offsets[previousIndex] + 3 * offsets[index] - 3 * offsets[nextIndex] + offsets[followingIndex]) * t3\n    );\n\n    if (profile.preserveFlight && Number.isFinite(profile.maxOffset)) {\n      // A sprint has intervals where both shoes leave the surface. Keep that\n      // authored clearance while still locking stance phases to the terrain.\n      const clearance = Math.max(0, profile.maxOffset - offset);\n      const flightBlend = THREE.MathUtils.smoothstep(clearance, 0.02, 0.06);\n      offset = THREE.MathUtils.lerp(offset, profile.maxOffset, flightBlend);\n    }\n    return offset;\n  }\n\n  _updateGroundContactOffset(airborne) {\n    if (!this.root) return;\n    let offset = this._baseGroundOffset;\n\n    if (!airborne && this._groundContact?.profiles) {\n      let weightedOffset = 0;\n      let totalWeight = 0;\n      for (const [state, action] of Object.entries(this.actions || {})) {\n        const profile = this._groundContact.profiles[state];\n        if (!profile || !action) continue;\n        // Stopped actions retain their last effective-weight scalar in Three.js\n        // even though the mixer no longer evaluates them.\n        if (typeof action.isScheduled === 'function' && !action.isScheduled()) continue;\n        const weight = Math.max(0, Number(action.getEffectiveWeight?.()) || 0);\n        if (weight <= 1e-4) continue;\n        weightedOffset += this._sampleGroundContactOffset(profile, action) * weight;\n        totalWeight += weight;\n      }\n      if (totalWeight > 1e-4) offset = weightedOffset / totalWeight;\n    }\n\n    if (Number.isFinite(offset)) {\n      this.root.position.y = this._rootRestY + offset;\n    }\n  }\n\n  /**\n   * Update animation and physics each frame\n   */\n  update(dt) {\n    // Remove last frame's additive look pose before animation evaluation. This\n    // is essential for unkeyed flight poses where the mixer otherwise leaves\n    // the already-rotated bone untouched.\n    this._clearAppliedHeadLook();\n\n    // Smooth speed towards target\n    const a = smoothAlpha(this._vRate, dt);\n    this._vSmooth += (this._vTarget - this._vSmooth) * a;\n\n    let horizontalSpeed;\n\n    // Check if external velocity was provided (e.g., by PeerManager)\n    if (this._hasExternalVelocity) {\n      // Use externally-set velocity (already stored in _velWorld and _velLocal)\n      horizontalSpeed = Math.hypot(this._velWorld.x, this._velWorld.z);\n      this._hasExternalVelocity = false; // Clear flag for next frame\n    } else {\n      // Measure velocity from position changes (for local player)\n      const invDt = 1 / Math.max(dt, 1e-5);\n      if (!this._hasPrevPos) {\n        this._lastPos.copy(this.group.position);\n        this._hasPrevPos = true;\n      }\n\n      this._velWorld.set(\n        (this.group.position.x - this._lastPos.x) * invDt,\n        (this.group.position.y - this._lastPos.y) * invDt,\n        (this.group.position.z - this._lastPos.z) * invDt\n      );\n      this._lastPos.copy(this.group.position);\n\n      horizontalSpeed = Math.hypot(this._velWorld.x, this._velWorld.z);\n\n      // Convert velocity to local space for direction detection\n      this._velLocal.set(this._velWorld.x, 0, this._velWorld.z);\n      if (this._velLocal.lengthSq() > 1e-6) {\n        this._invQuat.copy(this.group.quaternion).invert();\n        this._velLocal.applyQuaternion(this._invQuat);\n      } else {\n        this._velLocal.set(0, 0, 0);\n      }\n    }\n\n    const forward = -this._velLocal.z;\n    const strafe = this._velLocal.x;\n\n    // Determine airborne state\n    const airborneFlag = this._airborneManual || this._airborneAuto || this.jumpState !== 'idle' || this.jumpYOffset > 0;\n\n    // Select animation state\n    const manualState = this._manualState;\n    const desired = manualState || this._selectState({\n      speed: Math.max(this._vSmooth, horizontalSpeed),\n      forward,\n      strafe,\n      airborne: airborneFlag\n    });\n\n    if (desired && desired !== this.current) {\n      this._transition(desired);\n    }\n\n    // Animation tempo adaptation\n    if (this.current && this.actions[this.current]) {\n      const ref = this._speedRef[this.current];\n      if (ref) {\n        const scaleSource = Math.max(horizontalSpeed, this._vSmooth);\n        this.actions[this.current].setEffectiveTimeScale(\n          THREE.MathUtils.clamp(scaleSource / ref, 0.6, 1.6)\n        );\n      } else {\n        this.actions[this.current].setEffectiveTimeScale(1);\n      }\n    }\n\n    // Jump arc physics\n    if (this.jumpState === 'jumping') {\n      this.vertVel -= this.GRAV * dt;\n      this.jumpYOffset += this.vertVel * dt;\n      if (this.jumpYOffset <= 0) {\n        this.jumpYOffset = 0;\n        this.vertVel = 0;\n        this.jumpState = 'idle';\n      }\n    }\n\n    // Maintain y = base + jump\n    this.group.position.y = this.baseY + this.jumpYOffset;\n\n    // Update airborne auto flag\n    if (this.jumpState !== 'idle' || this.jumpYOffset > 1e-3) {\n      this._airborneAuto = true;\n    } else if (!this._airborneManual) {\n      this._airborneAuto = false;\n    }\n\n    // Update mixer\n    if (this.mixer) {\n      this.mixer.update(dt);\n    }\n\n    // This is a constant-time profile lookup. The expensive skinned-vertex\n    // measurement happened once in AvatarFactory, never in the render loop.\n    this._updateGroundContactOffset(airborneFlag);\n\n    // Apply head look IK\n    this._applyHeadLook(dt);\n  }\n\n  getActionNames() {\n    return Object.keys(this.actions || {});\n  }\n\n  applyConfig(config = {}) {\n    if (!config || typeof config !== 'object') return;\n\n    if (config.appearance) this.applyAppearance(config.appearance);\n\n    const animation = config.animation || {};\n    if (Number.isFinite(animation.fadeDuration)) this.fadeDuration = animation.fadeDuration;\n    if (Number.isFinite(animation.speedSmoothingRate)) this._vRate = animation.speedSmoothingRate;\n    if (Number.isFinite(animation.idleSpeedThreshold)) this._idleSpeedThreshold = animation.idleSpeedThreshold;\n    if (Number.isFinite(animation.runSpeedThreshold)) this._runSpeedThreshold = animation.runSpeedThreshold;\n    if (Number.isFinite(animation.directionThreshold)) this._directionThreshold = animation.directionThreshold;\n    if (animation.speedRef && typeof animation.speedRef === 'object') {\n      this._speedRef = { ...this._speedRef, ...animation.speedRef };\n    }\n\n    const headLook = config.headLook || {};\n    if (Number.isFinite(headLook.rate)) this._headLookRate = headLook.rate;\n    if (Number.isFinite(headLook.yawMaxDeg)) this._headYawMax = THREE.MathUtils.degToRad(headLook.yawMaxDeg);\n    if (Number.isFinite(headLook.pitchUpMaxDeg)) this._headPitchUpMax = THREE.MathUtils.degToRad(headLook.pitchUpMaxDeg);\n    if (Number.isFinite(headLook.pitchDownMaxDeg)) this._headPitchDownMax = THREE.MathUtils.degToRad(headLook.pitchDownMaxDeg);\n    if (Number.isFinite(headLook.rollMaxDeg)) this._headRollMax = THREE.MathUtils.degToRad(headLook.rollMaxDeg);\n\n    const jump = config.jump || {};\n    if (Number.isFinite(jump.height)) this.JUMP_H = jump.height;\n    if (Number.isFinite(jump.gravity)) this.GRAV = jump.gravity;\n\n    const debug = config.debug || {};\n    const hasProxyFlag = typeof debug.useProxyBall === 'boolean';\n    const hasProxyRadius = Number.isFinite(debug.proxyRadius);\n    const hasProxyColor = typeof debug.proxyColor === 'string' && debug.proxyColor.length > 0;\n    if (hasProxyFlag || hasProxyRadius || hasProxyColor) {\n      const enabled = hasProxyFlag ? debug.useProxyBall : this._debugProxyEnabled;\n      const radius = hasProxyRadius ? debug.proxyRadius : this._debugBallRadius;\n      const color = hasProxyColor ? debug.proxyColor : this._debugBallColor;\n      this.setDebugProxyBall(enabled, { radius, color });\n    }\n  }\n\n  applyAppearance(value = {}) {\n    const next = normalizeAvatarAppearance(value, this.appearance);\n    this.appearance = next;\n    for (const material of this._ownedMaterials) {\n      enforceOpaqueAvatarMaterial(material);\n      if (material?.color?.set) material.color.set(next.color);\n      if ('roughness' in material) material.roughness = next.roughness;\n      if ('metalness' in material) material.metalness = next.metalness;\n      material.needsUpdate = true;\n    }\n    return this.appearance;\n  }\n\n  setDebugProxyBall(enabled, opts = {}) {\n    const useBall = !!enabled;\n    const radius = Number.isFinite(opts.radius) ? opts.radius : this._debugBallRadius;\n    const color = opts.color || this._debugBallColor;\n\n    this._debugProxyEnabled = useBall;\n    this._debugBallRadius = radius;\n    this._debugBallColor = color;\n\n    if (useBall) {\n      this._ensureDebugBall();\n      this._debugBall.visible = true;\n      this._debugBall.scale.setScalar(radius);\n      this._debugBall.position.set(0, radius, 0);\n      if (this._debugBall.material?.color) {\n        this._debugBall.material.color.set(color);\n      }\n      if (this.root) {\n        this.root.visible = false;\n      }\n    } else {\n      if (this._debugBall) this._debugBall.visible = false;\n      if (this.root) this.root.visible = true;\n    }\n  }\n\n  _ensureDebugBall() {\n    if (this._debugBall) return;\n    const geom = new THREE.SphereGeometry(1, 24, 16);\n    const mat = enforceOpaqueAvatarMaterial(\n      new THREE.MeshStandardMaterial({ color: this._debugBallColor })\n    );\n    const mesh = new THREE.Mesh(geom, mat);\n    mesh.name = 'AvatarDebugBall';\n    mesh.castShadow = true;\n    mesh.receiveShadow = true;\n    mesh.visible = false;\n    this.group.add(mesh);\n    this._debugBall = mesh;\n  }\n\n  /**\n   * Set visibility\n   */\n  setVisible(visible) {\n    this.group.visible = !!visible;\n  }\n\n  /**\n   * Dispose of resources\n   */\n  dispose() {\n    if (this.mixer) {\n      this.mixer.stopAllAction();\n      this.mixer.uncacheRoot(this.root);\n    }\n\n    if (this._debugBall) {\n      this._debugBall.geometry?.dispose?.();\n      if (Array.isArray(this._debugBall.material)) {\n        this._debugBall.material.forEach((mat) => mat.dispose());\n      } else {\n        this._debugBall.material?.dispose?.();\n      }\n      this._debugBall = null;\n    }\n\n    // AvatarFactory clones share geometry, so disposing it here can make\n    // every remaining guest/registered avatar disappear. Only per-instance\n    // materials created by this Avatar are owned by it.\n    for (const material of this._ownedMaterials) material?.dispose?.();\n    this._ownedMaterials.clear();\n  }\n}\n\nexport default Avatar;\n","/**\n * AvatarFactory - Loads and clones character models with animations\n *\n * Handles:\n * - Loading the Character.glb model\n * - Retargeting animations from external sources\n * - Cloning models for multiple avatars (local + peers)\n */\n\nimport * as THREE from 'three';\nimport { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';\nimport * as SkeletonUtils from 'three/addons/utils/SkeletonUtils.js';\n\nconst MODEL_URL = '/refactor/models/Character.glb';\nconst TARGET_HEIGHT_M = 1.65;\nconst GROUND_CONTACT_SAMPLE_COUNT = 129;\nconst FOOT_SKIN_WEIGHT_MIN = 0.02;\nconst GROUND_CONTACT_EPSILON_M = 0.001;\nconst FOOT_BONE_PATTERN = /(?:foot|toe)/i;\n\n// These clips are expected to keep at least one shoe on the surface. Airborne,\n// seated/floating, and terminal poses intentionally do not participate.\nconst GROUND_CONTACT_STATES = Object.freeze([\n  'Idle',\n  'WalkForward',\n  'WalkBackward',\n  'WalkLeft',\n  'WalkRight',\n  'Sprint',\n  'CrouchIdle',\n  'CrouchForward',\n  'CrouchBackward',\n  'CrouchLeft',\n  'CrouchRight',\n]);\n\nconst normalizeTemplateHeight = (template, targetHeightM) => {\n  if (!template || !Number.isFinite(targetHeightM) || targetHeightM <= 0) {\n    return { height: targetHeightM || 1.65, footYOffset: 0, rawHeight: targetHeightM || 1.65, scale: 1 };\n  }\n\n  template.updateMatrixWorld(true);\n  const bounds = new THREE.Box3().setFromObject(template);\n  const size = new THREE.Vector3();\n  bounds.getSize(size);\n  const rawHeight = Number.isFinite(size.y) && size.y > 0 ? size.y : targetHeightM;\n  const scale = rawHeight > 0 ? targetHeightM / rawHeight : 1;\n\n  if (Number.isFinite(scale) && Math.abs(scale - 1) > 1e-4) {\n    template.scale.setScalar(scale);\n    template.updateMatrixWorld(true);\n  }\n\n  const scaledBounds = new THREE.Box3().setFromObject(template);\n  const scaledSize = new THREE.Vector3();\n  scaledBounds.getSize(scaledSize);\n  const height = Number.isFinite(scaledSize.y) && scaledSize.y > 0 ? scaledSize.y : rawHeight * (Number.isFinite(scale) ? scale : 1);\n  const footYOffset = -scaledBounds.min.y;\n\n  return { height, footYOffset, rawHeight, scale: Number.isFinite(scale) ? scale : 1 };\n};\n\n// Animation URLs for retargeting (if model doesn't have native animations)\nconst ANIMATION_URLS = {\n  Idle: '/models/anims/Idle.glb',\n  Walk: '/models/anims/Walk_Forward.glb',\n  Run: '/models/anims/Sprint.glb',\n};\n\n// Root bone names for stripping root motion\nconst ROOT_BONE_HINTS = ['characters3dcom___hips', 'mixamorighips', 'hips'];\n\n// Animation clip specifications for matching by name\nconst CHARACTER_CLIP_SPECS = {\n  Idle: {\n    names: ['Idle'],\n    match: [/\\bidle\\b/i],\n    fallback: [0]\n  },\n  WalkForward: {\n    names: ['Walk Forward', 'Walk'],\n    match: [/walk\\s*forward/i, /\\bwalk\\b/i],\n    fallback: [2, 3]\n  },\n  WalkBackward: {\n    names: ['Walk Backward'],\n    match: [/walk\\s*back/i],\n    fallback: [1]\n  },\n  WalkLeft: {\n    names: ['Walk Left'],\n    match: [/walk\\s*left/i],\n    fallback: [3]\n  },\n  WalkRight: {\n    names: ['Walk Right'],\n    match: [/walk\\s*right/i],\n    fallback: [4]\n  },\n  Sprint: {\n    names: ['Sprint', 'Run'],\n    match: [/\\bsprint\\b/i, /\\brun\\b/i],\n    fallback: [13, 1]\n  },\n  CrouchIdle: {\n    names: ['Crouch Idle'],\n    match: [/crouch\\s*idle/i],\n    fallback: [5]\n  },\n  CrouchForward: {\n    names: ['Crouch Move Forward Stealth', 'Crouch Walk'],\n    match: [/crouch.*forward/i, /crouch.*walk/i],\n    fallback: [7, 8]\n  },\n  CrouchBackward: {\n    names: ['Crouch Move Backward Stealth'],\n    match: [/crouch.*back/i],\n    fallback: [6]\n  },\n  CrouchLeft: {\n    names: ['Crouch Move Left Stealth'],\n    match: [/crouch.*left/i],\n    fallback: [9]\n  },\n  CrouchRight: {\n    names: ['Crouch Move Right Stealth'],\n    match: [/crouch.*right/i],\n    fallback: [10]\n  },\n  Fall: {\n    names: ['Fall', 'Falling'],\n    match: [/fall/i],\n    fallback: [11]\n  },\n  Jump: {\n    names: ['Jump', 'Jumping'],\n    match: [/jump/i],\n    fallback: [12]\n  },\n  Meditate: {\n    names: ['Meditate', 'Meditation', 'Float', 'Levitate'],\n    match: [/meditat/i, /float/i, /levitat/i],\n    fallback: [15]\n  },\n  Death: {\n    names: ['Death', 'Die', 'Dead'],\n    match: [/death/i, /\\bdie\\b/i, /\\bdead\\b/i],\n    fallback: [14]\n  },\n  Surrender: {\n    names: ['Surrender', 'Hands Up', 'Give Up'],\n    match: [/surrender/i, /hands?\\s*up/i],\n    fallback: [16]\n  }\n};\n\nexport const CHARACTER_CLIP_KEYS = Object.freeze(Object.keys(CHARACTER_CLIP_SPECS));\n\n/**\n * Strip root motion from animation clip to prevent sliding\n */\nexport function stripRootMotionFromClip(clip, opts = {}) {\n  if (!clip) return clip;\n  const { rootNames = ROOT_BONE_HINTS, freeze = { x: true, z: true }, preserveY = true } = opts;\n  const roots = (rootNames || []).map((name) => String(name || '').toLowerCase());\n\n  const shouldFreezeAxis = (axis) => {\n    if (!freeze || typeof freeze !== 'object') return true;\n    if (typeof freeze[axis] === 'boolean') return freeze[axis];\n    return true;\n  };\n\n  for (const track of clip.tracks || []) {\n    const trackName = (track?.name || '').toLowerCase();\n    if (!trackName.endsWith('.position')) continue;\n    if (roots.length && !roots.some((root) => trackName.includes(root))) continue;\n\n    const valueSize = typeof track.getValueSize === 'function' ? track.getValueSize() : 3;\n    if (valueSize !== 3) continue;\n\n    const values = track.values;\n    if (!values || values.length === 0) continue;\n\n    for (let i = 0; i < values.length; i += 3) {\n      if (shouldFreezeAxis('x')) values[i] = 0;\n      if (!preserveY) values[i + 1] = 0;\n      if (shouldFreezeAxis('z')) values[i + 2] = 0;\n    }\n    track.needsUpdate = true;\n  }\n\n  clip.optimize?.();\n  return clip;\n}\n\n/**\n * Find a clip in a list matching a specification\n */\nfunction findClipInList(clips, spec) {\n  if (!Array.isArray(clips) || !spec) return null;\n  const haystack = clips.filter(Boolean);\n  if (!haystack.length) return null;\n\n  // Try exact name match first\n  if (spec.names) {\n    for (const name of spec.names) {\n      const found = haystack.find((clip) =>\n        String(clip?.name || '').toLowerCase() === String(name).toLowerCase()\n      );\n      if (found) return found.clone();\n    }\n  }\n\n  // Try regex match\n  if (spec.match) {\n    const regexes = Array.isArray(spec.match) ? spec.match : [spec.match];\n    for (const rx of regexes) {\n      const found = haystack.find((clip) => rx.test(clip?.name || ''));\n      if (found) return found.clone();\n    }\n  }\n\n  // Try fallback indices\n  if (spec.fallback) {\n    for (const idx of spec.fallback) {\n      if (idx != null && idx >= 0 && idx < haystack.length) {\n        const clip = haystack[idx];\n        if (clip) return clip.clone();\n      }\n    }\n  }\n\n  return null;\n}\n\n/**\n * Build a clip map from a list of animations\n */\nfunction buildClipMapFromList(clips, opts = {}) {\n  const out = {};\n  if (!Array.isArray(clips)) return out;\n\n  for (const [key, spec] of Object.entries(CHARACTER_CLIP_SPECS)) {\n    const found = findClipInList(clips, spec);\n    out[key] = found ? stripRootMotionFromClip(found, opts.stripOptions) : null;\n  }\n  return out;\n}\n\n/**\n * Derive clips from animations array\n */\nexport function deriveClipsFromAnimations(animations, opts = {}) {\n  return buildClipMapFromList(animations, opts);\n}\n\n/**\n * Find vertices actually influenced by foot/toe bones. Box3.setFromObject()\n * only sees the bind/static shape and cannot answer where a skinned shoe is\n * after an animation has been evaluated.\n */\nfunction collectFootVertexSets(root, minWeight = FOOT_SKIN_WEIGHT_MIN) {\n  const sets = [];\n  const skeletonUseCount = new Map();\n  root?.traverse?.((mesh) => {\n    if (!mesh?.isSkinnedMesh || !mesh.skeleton) return;\n    skeletonUseCount.set(mesh.skeleton, (skeletonUseCount.get(mesh.skeleton) || 0) + 1);\n  });\n  root?.traverse?.((mesh) => {\n    if (!mesh?.isSkinnedMesh || !mesh.skeleton || !mesh.geometry) return;\n    const position = mesh.geometry.attributes?.position;\n    const skinIndex = mesh.geometry.attributes?.skinIndex;\n    const skinWeight = mesh.geometry.attributes?.skinWeight;\n    if (!position || !skinIndex || !skinWeight) return;\n\n    const footBones = new Set();\n    mesh.skeleton.bones.forEach((bone, index) => {\n      if (FOOT_BONE_PATTERN.test(String(bone?.name || ''))) footBones.add(index);\n    });\n    if (!footBones.size) return;\n\n    const indices = [];\n    for (let i = 0; i < position.count; i += 1) {\n      const boneIndices = [\n        skinIndex.getX(i),\n        skinIndex.getY(i),\n        skinIndex.getZ(i),\n        skinIndex.getW(i),\n      ];\n      const weights = [\n        skinWeight.getX(i),\n        skinWeight.getY(i),\n        skinWeight.getZ(i),\n        skinWeight.getW(i),\n      ];\n      let isFootVertex = false;\n      for (let component = 0; component < 4; component += 1) {\n        if (weights[component] > minWeight && footBones.has(boneIndices[component])) {\n          isFootVertex = true;\n          break;\n        }\n      }\n      if (isFootVertex) indices.push(i);\n    }\n    if (indices.length) {\n      sets.push({\n        mesh,\n        indices: Uint32Array.from(indices),\n        meshSpaceSkinning: skeletonUseCount.get(mesh.skeleton) === 1,\n      });\n    }\n  });\n  return sets;\n}\n\nfunction captureLocalPose(root) {\n  const pose = [];\n  root?.traverse?.((obj) => {\n    pose.push({\n      obj,\n      position: obj.position.clone(),\n      quaternion: obj.quaternion.clone(),\n      scale: obj.scale.clone(),\n    });\n  });\n  return pose;\n}\n\nfunction restoreLocalPose(root, pose) {\n  for (const entry of pose) {\n    entry.obj.position.copy(entry.position);\n    entry.obj.quaternion.copy(entry.quaternion);\n    entry.obj.scale.copy(entry.scale);\n  }\n  root?.updateMatrixWorld?.(true);\n}\n\nfunction measureFootMinimumY(root, vertexSets) {\n  root.updateMatrixWorld(true);\n  const parentWorldInverse = root.parent\n    ? new THREE.Matrix4().copy(root.parent.matrixWorld).invert()\n    : new THREE.Matrix4();\n  const meshToContact = new THREE.Matrix4();\n  const vertex = new THREE.Vector3();\n  const baseVertex = new THREE.Vector3();\n  const weightedVertex = new THREE.Vector3();\n  const boneMatrix = new THREE.Matrix4();\n  let minY = Infinity;\n\n  for (const { mesh, indices, meshSpaceSkinning } of vertexSets) {\n    mesh.updateMatrixWorld(true);\n    // Measure in the root parent's coordinates: that parent is Avatar.group\n    // at runtime and its y=0 plane is the actual terrain contact plane. Do\n    // not invert `root` itself or its scale/position correction disappears.\n    meshToContact.multiplyMatrices(parentWorldInverse, mesh.matrixWorld);\n    const position = mesh.geometry.attributes.position;\n    const skinIndex = mesh.geometry.attributes.skinIndex;\n    const skinWeight = mesh.geometry.attributes.skinWeight;\n    for (let i = 0; i < indices.length; i += 1) {\n      const vertexIndex = indices[i];\n      vertex.fromBufferAttribute(position, vertexIndex);\n      if (meshSpaceSkinning) {\n        // Avatar._enableMeshSpaceSkinning() uploads\n        // M^-1 * boneWorld * boneInverse * originalBind. After the mesh model\n        // matrix is applied by the shader, the rendered contact-space vertex\n        // is boneWorld * boneInverse * originalBind * position. Reproduce that\n        // exact path here instead of relying on applyBoneTransform(), whose\n        // bind matrices are intentionally replaced at runtime.\n        baseVertex.copy(vertex).applyMatrix4(mesh.bindMatrix);\n        vertex.set(0, 0, 0);\n        const bones = [skinIndex.getX(vertexIndex), skinIndex.getY(vertexIndex), skinIndex.getZ(vertexIndex), skinIndex.getW(vertexIndex)];\n        const weights = [skinWeight.getX(vertexIndex), skinWeight.getY(vertexIndex), skinWeight.getZ(vertexIndex), skinWeight.getW(vertexIndex)];\n        for (let component = 0; component < 4; component += 1) {\n          const weight = weights[component];\n          if (weight <= 0) continue;\n          const boneIndex = bones[component];\n          boneMatrix.multiplyMatrices(\n            mesh.skeleton.bones[boneIndex].matrixWorld,\n            mesh.skeleton.boneInverses[boneIndex]\n          );\n          vertex.addScaledVector(weightedVertex.copy(baseVertex).applyMatrix4(boneMatrix), weight);\n        }\n        vertex.applyMatrix4(parentWorldInverse);\n      } else {\n        mesh.applyBoneTransform(vertexIndex, vertex);\n        vertex.applyMatrix4(meshToContact);\n      }\n      if (Number.isFinite(vertex.y) && vertex.y < minY) minY = vertex.y;\n    }\n  }\n\n  return minY;\n}\n\n/**\n * Sample the real deformed shoe geometry once at factory load. Avatars only\n * interpolate these tiny profiles at runtime; no vertex scanning enters the\n * scene render loop.\n */\nexport function deriveGroundContactProfiles(template, clips, opts = {}) {\n  if (!template || !clips) return null;\n  const sampleCount = Math.max(9, Math.floor(opts.sampleCount || GROUND_CONTACT_SAMPLE_COUNT));\n  const epsilon = Number.isFinite(opts.epsilon) ? Math.max(0, opts.epsilon) : GROUND_CONTACT_EPSILON_M;\n  const calibrationRoot = SkeletonUtils.clone(template);\n  calibrationRoot.visible = true;\n  calibrationRoot.traverse((obj) => { obj.visible = true; });\n  calibrationRoot.updateMatrixWorld(true);\n\n  const vertexSets = collectFootVertexSets(calibrationRoot, opts.minSkinWeight);\n  if (!vertexSets.length) return null;\n\n  const mixer = new THREE.AnimationMixer(calibrationRoot);\n  // Skeleton.pose() reconstructs local transforms from inverse bind matrices\n  // and is not equivalent to this GLB's authored local rest hierarchy. Preserve\n  // that hierarchy explicitly so every clip starts from the same valid pose.\n  const localPose = captureLocalPose(calibrationRoot);\n  const profiles = {};\n\n  for (const state of GROUND_CONTACT_STATES) {\n    const clip = clips[state];\n    if (!clip || !Number.isFinite(clip.duration) || clip.duration <= 0) continue;\n\n    mixer.stopAllAction();\n    restoreLocalPose(calibrationRoot, localPose);\n    const action = mixer.clipAction(clip);\n    action.reset();\n    action.enabled = true;\n    action.setEffectiveTimeScale(1);\n    action.setEffectiveWeight(1);\n    action.setLoop(THREE.LoopRepeat, Infinity);\n    action.play();\n\n    const offsets = [];\n    for (let sample = 0; sample < sampleCount; sample += 1) {\n      action.time = (sample / sampleCount) * clip.duration;\n      mixer.update(0);\n      const minY = measureFootMinimumY(calibrationRoot, vertexSets);\n      if (!Number.isFinite(minY)) {\n        offsets.length = 0;\n        break;\n      }\n      offsets.push(-minY + epsilon);\n    }\n    action.stop();\n    if (!offsets.length) continue;\n\n    profiles[state] = Object.freeze({\n      duration: clip.duration,\n      offsets: Object.freeze(offsets),\n      minOffset: Math.min(...offsets),\n      maxOffset: Math.max(...offsets),\n      // Sprint contains genuine both-feet-airborne intervals. Those intervals\n      // must retain their authored clearance instead of being pulled down.\n      preserveFlight: state === 'Sprint',\n    });\n  }\n\n  mixer.stopAllAction();\n  mixer.uncacheRoot(calibrationRoot);\n  if (!Object.keys(profiles).length) return null;\n\n  const baseOffset = Number.isFinite(profiles.Idle?.maxOffset)\n    ? profiles.Idle.maxOffset\n    : Object.values(profiles)[0].maxOffset;\n  return Object.freeze({\n    sampleCount,\n    epsilon,\n    footVertexCount: vertexSets.reduce((sum, entry) => sum + entry.indices.length, 0),\n    baseOffset,\n    profiles: Object.freeze(profiles),\n  });\n}\n\n/**\n * Get skeleton bundle from a model\n */\nfunction getSkinBundle(root) {\n  if (!root) return null;\n  let mesh = null;\n  root.traverse((obj) => {\n    if (mesh || !obj.isSkinnedMesh) return;\n    mesh = obj;\n  });\n  if (mesh && mesh.skeleton) return { mesh, skeleton: mesh.skeleton };\n  if (mesh) {\n    const helper = new THREE.SkeletonHelper(mesh);\n    const skeleton = new THREE.Skeleton(helper.bones);\n    helper.visible = false;\n    helper.dispose?.();\n    return { mesh, skeleton };\n  }\n  const helper = new THREE.SkeletonHelper(root);\n  const skeleton = new THREE.Skeleton(helper.bones);\n  helper.visible = false;\n  helper.dispose?.();\n  return { mesh: root, skeleton };\n}\n\n/**\n * Load and retarget animation clips from external sources\n */\nasync function loadExternalAnimations(loader, targetModel) {\n  const targetBundle = getSkinBundle(targetModel);\n  if (!targetBundle) {\n    console.warn('[AvatarFactory] No skinned mesh found on target model');\n    return {};\n  }\n\n  const results = {};\n\n  for (const [key, url] of Object.entries(ANIMATION_URLS)) {\n    try {\n      const gltf = await loader.loadAsync(url);\n      const clip = gltf.animations?.[0];\n      if (!clip) {\n        console.warn(`[AvatarFactory] No animation found in ${url}`);\n        continue;\n      }\n\n      // Try to retarget the clip\n      const sourceScene = SkeletonUtils.clone(gltf.scene);\n      const sourceBundle = getSkinBundle(sourceScene);\n\n      if (sourceBundle) {\n        try {\n          const retargeted = SkeletonUtils.retargetClip(\n            targetBundle.mesh,\n            sourceBundle.skeleton,\n            clip.clone(),\n            { useTargetRestPose: true }\n          );\n          results[key] = stripRootMotionFromClip(retargeted);\n        } catch (err) {\n          console.warn(`[AvatarFactory] Retarget failed for ${key}:`, err);\n          results[key] = stripRootMotionFromClip(clip.clone());\n        }\n      } else {\n        results[key] = stripRootMotionFromClip(clip.clone());\n      }\n    } catch (err) {\n      console.warn(`[AvatarFactory] Failed to load ${url}:`, err);\n    }\n  }\n\n  return results;\n}\n\n/**\n * Build a fallback primitive avatar when model loading fails\n */\nfunction buildFallbackTemplate() {\n  const root = new THREE.Group();\n\n  const bodyMat = new THREE.MeshStandardMaterial({ color: 0x3a82f7, metalness: 0.15, roughness: 0.65 });\n  const headMat = new THREE.MeshStandardMaterial({ color: 0xffd8b5, metalness: 0.05, roughness: 0.4 });\n\n  const body = new THREE.Mesh(new THREE.CapsuleGeometry(0.32, 1.05, 12, 18), bodyMat);\n  body.castShadow = true;\n  body.receiveShadow = true;\n  root.add(body);\n\n  const head = new THREE.Mesh(new THREE.SphereGeometry(0.24, 18, 14), headMat);\n  head.castShadow = true;\n  head.receiveShadow = true;\n  head.position.y = 0.95 + 0.24 + 0.05;\n  root.add(head);\n\n  const visor = new THREE.Mesh(\n    new THREE.CylinderGeometry(0.14, 0.18, 0.08, 12, 1, true),\n    new THREE.MeshStandardMaterial({ color: 0x222831, metalness: 0.6, roughness: 0.2, side: THREE.DoubleSide })\n  );\n  visor.rotation.z = Math.PI / 2;\n  visor.position.set(0, head.position.y + 0.02, 0.18);\n  root.add(visor);\n\n  // Arms\n  const armGeo = new THREE.CapsuleGeometry(0.09, 0.65, 8, 12);\n  const armL = new THREE.Mesh(armGeo, bodyMat);\n  armL.rotation.z = Math.PI / 2;\n  armL.position.set(0.46, 0.45, 0);\n  armL.castShadow = armL.receiveShadow = true;\n  root.add(armL);\n  const armR = armL.clone();\n  armR.position.x = -0.46;\n  root.add(armR);\n\n  // Legs\n  const legGeo = new THREE.CapsuleGeometry(0.11, 0.8, 10, 16);\n  const legMat = new THREE.MeshStandardMaterial({ color: 0x2d2f3a, metalness: 0.1, roughness: 0.7 });\n  const legL = new THREE.Mesh(legGeo, legMat);\n  legL.position.set(0.18, -0.7, 0);\n  legL.castShadow = legL.receiveShadow = true;\n  root.add(legL);\n  const legR = legL.clone();\n  legR.position.x = -0.18;\n  root.add(legR);\n\n  // Ensure feet rest on y=0 plane\n  const bounds = new THREE.Box3().setFromObject(root);\n  root.position.y -= bounds.min.y;\n\n  const bbox = new THREE.Box3().setFromObject(root);\n  const size = new THREE.Vector3();\n  bbox.getSize(size);\n  const height = size.y || 1.7;\n  const footYOffset = -bbox.min.y;\n\n  return { template: root, footYOffset, height };\n}\n\n/**\n * AvatarFactory - Singleton factory for creating avatar instances\n */\nexport class AvatarFactory {\n  static _promise = null;\n  static _instance = null;\n\n  /**\n   * Load the avatar factory (singleton)\n   */\n  static load() {\n    if (this._promise) return this._promise;\n\n    this._promise = (async () => {\n      const loader = new GLTFLoader();\n\n      try {\n        console.log('[AvatarFactory] Loading model from', MODEL_URL);\n        const gltf = await loader.loadAsync(MODEL_URL);\n        const template = gltf.scene;\n\n        // Don't add template to any scene\n        if (template.parent) {\n          template.parent.remove(template);\n        }\n        template.visible = false;\n\n        // Face -Z direction (standard Three.js convention)\n        template.rotation.y = Math.PI;\n        template.updateMatrixWorld(true);\n\n        // Get native animations from model\n        const animations = gltf.animations || [];\n        const animationNames = animations.map((clip, idx) => clip?.name || `Animation ${idx + 1}`);\n        console.log('[AvatarFactory] Found', animations.length, 'native animations');\n\n        const nativeClips = deriveClipsFromAnimations(animations);\n\n        // Try to load external animations for missing clips\n        let externalClips = {};\n        const missingClips = CHARACTER_CLIP_KEYS.filter(key => !nativeClips[key]);\n        if (missingClips.length > 0) {\n          console.log('[AvatarFactory] Loading external animations for:', missingClips);\n          try {\n            externalClips = await loadExternalAnimations(loader, template);\n          } catch (err) {\n            console.warn('[AvatarFactory] External animation loading failed:', err);\n          }\n        }\n\n        // Merge clips (native takes priority)\n        const merged = {};\n        for (const key of CHARACTER_CLIP_KEYS) {\n          merged[key] = nativeClips[key] || externalClips[key] || null;\n        }\n\n        // Add aliases\n        merged.Walk = merged.WalkForward || merged.Walk || null;\n        merged.Run = merged.Sprint || merged.Run || null;\n\n        // Normalize model height to target\n        const normalized = normalizeTemplateHeight(template, TARGET_HEIGHT_M);\n        console.log(\n          '[AvatarFactory] Model height:',\n          normalized.rawHeight.toFixed(2),\n          'm ->',\n          normalized.height.toFixed(2),\n          'm (scale',\n          normalized.scale.toFixed(3),\n          ')'\n        );\n\n        const groundContact = deriveGroundContactProfiles(template, merged);\n        if (groundContact) {\n          console.log(\n            '[AvatarFactory] Calibrated animated shoe contact:',\n            groundContact.footVertexCount,\n            'vertices across',\n            Object.keys(groundContact.profiles).length,\n            'grounded clips'\n          );\n        } else {\n          console.warn('[AvatarFactory] Animated shoe calibration unavailable; using static bounds');\n        }\n\n        this._instance = new AvatarFactory(\n          template,\n          merged,\n          normalized.footYOffset,\n          normalized.height,\n          animationNames,\n          normalized.rawHeight,\n          groundContact\n        );\n        return this._instance;\n\n      } catch (err) {\n        console.warn('[AvatarFactory] Model load failed, using fallback:', err);\n        const fallback = buildFallbackTemplate();\n        const emptyClips = {};\n        for (const key of CHARACTER_CLIP_KEYS) {\n          emptyClips[key] = null;\n        }\n        const normalized = normalizeTemplateHeight(fallback.template, TARGET_HEIGHT_M);\n        console.log(\n          '[AvatarFactory] Fallback height:',\n          normalized.rawHeight.toFixed(2),\n          'm ->',\n          normalized.height.toFixed(2),\n          'm (scale',\n          normalized.scale.toFixed(3),\n          ')'\n        );\n        this._instance = new AvatarFactory(\n          fallback.template,\n          emptyClips,\n          normalized.footYOffset,\n          normalized.height,\n          [],\n          normalized.rawHeight\n        );\n        return this._instance;\n      }\n    })();\n\n    return this._promise;\n  }\n\n  /**\n   * Get the loaded factory instance (or null if not loaded)\n   */\n  static getInstance() {\n    return this._instance;\n  }\n\n  constructor(template, clips, footYOffset, height, animationNames = [], rawHeight = null, groundContact = null) {\n    this.template = template;\n    this.clips = clips;\n    this.footYOffset = footYOffset;\n    this.height = height;\n    this.rawHeight = Number.isFinite(rawHeight) ? rawHeight : height;\n    this.groundContact = groundContact;\n    this.animationNames = Array.isArray(animationNames)\n      ? animationNames.filter((name) => !!name)\n      : [];\n  }\n\n  /**\n   * Create a new Avatar instance by cloning the template\n   */\n  create() {\n    // Deep clone preserves skinning and bone hierarchy\n    const root = SkeletonUtils.clone(this.template);\n\n    // Template is invisible, make clone visible\n    root.visible = true;\n    root.traverse((obj) => {\n      obj.visible = true;\n      if (obj.isMesh) {\n        obj.castShadow = true;\n        obj.receiveShadow = true;\n      }\n    });\n\n    // Clone clips for this instance\n    const clips = {};\n    for (const [key, clip] of Object.entries(this.clips || {})) {\n      clips[key] = clip ? clip.clone() : null;\n    }\n\n    // Import Avatar class dynamically to avoid circular dependency\n    // Return the components needed to construct an Avatar\n    return {\n      root,\n      clips,\n      footYOffset: this.footYOffset,\n      groundContact: this.groundContact,\n      height: this.height,\n      rawHeight: this.rawHeight\n    };\n  }\n\n  getAnimationNames() {\n    return this.animationNames.slice();\n  }\n}\n\nexport default AvatarFactory;\n","/**\n * LocalPlayer - Local player avatar with input handling\n *\n * Handles:\n * - Avatar positioning based on surface controller\n * - Animation state based on movement\n * - Jump and crouch input\n * - Meditate state when floating above ground\n * - Broadcasting state to presence system\n */\n\nimport * as THREE from 'three';\nimport { Avatar } from './Avatar.js';\nimport { AvatarFactory } from './AvatarFactory.js';\nimport { PLANET_RADIUS } from '../../modules/constants.js';\n\n// Altitude threshold for meditate animation (meters above eye height)\n// Triggers when player uses Q/E or scroll to rise above normal standing height\nconst MEDITATE_ALTITUDE_THRESHOLD = 0.5;\n\n// Smoothing helper\nfunction smoothAlpha(ratePerSec, dt) {\n  return 1 - Math.exp(-Math.max(0, ratePerSec) * Math.max(0, dt));\n}\n\n/**\n * LocalPlayer - Manages the local player's avatar\n */\nexport class LocalPlayer {\n  constructor(options = {}) {\n    this.surfaceController = options.surfaceController || null;\n    this.scene = options.scene || null;\n    this.triTree = options.triTree || null;\n    this.camera = options.camera || null;\n    this.eventBus = options.eventBus || null;\n\n    // Avatar instance\n    this.avatar = null;\n    this._avatarGroup = null;\n    this._avatarLayer = null;\n\n    // State\n    this._ready = false;\n    this._visible = true;\n    this._firstPerson = true; // Hide avatar in first-person mode\n    this._xrPresenting = false; // A headset must never render its own body back through the head camera.\n\n    // Movement state\n    this._velocity = new THREE.Vector3();\n    this._speed = 0;\n    this._isGrounded = true;\n    this._isCrouching = false;\n    this._isJumping = false;\n    this._jumpRequested = false;\n    this._isMeditating = false;\n    this._meditateThreshold = MEDITATE_ALTITUDE_THRESHOLD;\n    this._config = null;\n    // Scene-only path previews own a tokenized visual pose. They never write\n    // the SurfaceController, GPS state, or presence-authoritative camera.\n    this._motionVisualOverride = null;\n\n    // Position tracking\n    this._lastPosition = new THREE.Vector3();\n    this._currentPosition = new THREE.Vector3();\n    this._hasLastPosition = false;\n\n    // For world-to-local transforms\n    this._tmpQuat = new THREE.Quaternion();\n    this._tmpEuler = new THREE.Euler();\n    this._tmpVec = new THREE.Vector3();\n    this._tmpWorldPoint = new THREE.Vector3();\n    this._tmpLocalUp = new THREE.Vector3();\n    this._tmpParentQuat = new THREE.Quaternion();\n\n    // Keyboard listener for jump/crouch\n    this._boundKeyDown = this._onKeyDown.bind(this);\n    this._boundKeyUp = this._onKeyUp.bind(this);\n    this._boundOriginShift = this._onOriginShift.bind(this);\n    this._boundXRStart = () => this.setXRPresenting(true);\n    this._boundXREnd = () => this.setXRPresenting(false);\n\n    if (typeof window !== 'undefined') {\n      window.addEventListener('keydown', this._boundKeyDown);\n      window.addEventListener('keyup', this._boundKeyUp);\n    }\n\n    // Listen for floating origin shifts\n    this.eventBus?.on?.('origin:shift', this._boundOriginShift);\n    this.eventBus?.on?.('vr:session-start', this._boundXRStart);\n    this.eventBus?.on?.('vr:session-end', this._boundXREnd);\n  }\n\n  /**\n   * Handle origin shift event from floating origin system\n   */\n  _onOriginShift(event) {\n    if (event?.shift) {\n      this.handleOriginShift(event.shift);\n    }\n  }\n\n  /**\n   * Initialize the local player avatar\n   */\n  async init() {\n    try {\n      console.log('[LocalPlayer] Initializing...');\n      const factory = await AvatarFactory.load();\n\n      if (!factory) {\n        console.error('[LocalPlayer] Failed to load avatar factory');\n        return false;\n      }\n\n      // Create avatar from factory\n      const avatarData = factory.create();\n      this.avatar = new Avatar(\n        avatarData.root,\n        avatarData.clips,\n        avatarData.footYOffset,\n        avatarData.height,\n        avatarData.groundContact\n      );\n      const rawHeight = Number.isFinite(avatarData.rawHeight) ? avatarData.rawHeight : avatarData.height;\n      if (Number.isFinite(this.avatar?.height)) {\n        const eyeHeight = this.avatar.eyeHeight;\n        console.log(\n          '[LocalPlayer] Avatar height:',\n          this.avatar.height.toFixed(2),\n          'm (raw',\n          Number.isFinite(rawHeight) ? rawHeight.toFixed(2) : 'n/a',\n          'm), eye',\n          Number.isFinite(eyeHeight) ? eyeHeight.toFixed(2) : 'n/a',\n          'm'\n        );\n      }\n      this._applyAvatarEyeHeight();\n\n      this._avatarGroup = this.avatar.group;\n      this._avatarLayer = new THREE.Group();\n      this._avatarLayer.name = 'LocalPlayerLayer';\n      this._avatarLayer.add(this._avatarGroup);\n      this._avatarGroup.name = 'LocalPlayer';\n\n      // Initially hidden in first-person mode\n      this._syncVisibility();\n\n      // Add to triTree.group for planet-local positioning\n      const parentGroup = this.triTree?.group || this.scene;\n      if (parentGroup) {\n        parentGroup.add(this._avatarLayer);\n      }\n\n      if (this._config) {\n        this.applyConfig(this._config);\n      }\n\n      this._ready = true;\n      console.log('[LocalPlayer] Initialized successfully');\n\n      return true;\n\n    } catch (err) {\n      console.error('[LocalPlayer] Initialization failed:', err);\n      return false;\n    }\n  }\n\n  _applyAvatarEyeHeight() {\n    if (!this.surfaceController || !this.avatar) return;\n    const eyeHeight = this.avatar.eyeHeight;\n    if (!Number.isFinite(eyeHeight) || eyeHeight <= 0) return;\n\n    const prevStand = Number.isFinite(this.surfaceController.STAND_EYE_HEIGHT)\n      ? this.surfaceController.STAND_EYE_HEIGHT\n      : (Number.isFinite(this.surfaceController.SURFACE_EYE_HEIGHT) ? this.surfaceController.SURFACE_EYE_HEIGHT : 1.6);\n    const prevCrouch = Number.isFinite(this.surfaceController.CROUCH_EYE_HEIGHT)\n      ? this.surfaceController.CROUCH_EYE_HEIGHT\n      : 0.9;\n    const crouchRatio = prevStand > 0 ? prevCrouch / prevStand : 0.56;\n\n    this.surfaceController.SURFACE_EYE_HEIGHT = eyeHeight;\n    this.surfaceController.STAND_EYE_HEIGHT = eyeHeight;\n    this.surfaceController.SURFACE_ALTITUDE_MIN = eyeHeight;\n    this.surfaceController.CROUCH_EYE_HEIGHT = eyeHeight * crouchRatio;\n\n    const oceanState = this.surfaceController.getOceanNavigationState?.();\n    if (Number.isFinite(this.surfaceController.surfaceAltitudeMeters) && !oceanState?.swimming) {\n      this.surfaceController.surfaceAltitudeMeters = Math.max(this.surfaceController.surfaceAltitudeMeters, eyeHeight);\n    }\n\n    // Avatar eye height only constrains an Earth surface orbit.  Do not\n    // overwrite the active Moon/Sun orbit limits after URL body anchoring.\n    if (this.surfaceController.controls && this.surfaceController.getBodyAnchor?.() === 'terra') {\n      this.surfaceController.controls.minDistance = PLANET_RADIUS + eyeHeight;\n    }\n  }\n\n  /**\n   * Handle keydown events\n   * Note: Jump and crouch are now handled by SurfaceController\n   * LocalPlayer just reads state from surfaceController for animation\n   */\n  _onKeyDown(e) {\n    // Jump and crouch handled by SurfaceController\n    // We only track state here for animation purposes\n  }\n\n  /**\n   * Handle keyup events\n   */\n  _onKeyUp(e) {\n    // Jump and crouch handled by SurfaceController\n  }\n\n  /**\n   * Compute velocity from position change\n   */\n  _computeVelocity(dt) {\n    if (!this.surfaceController) return;\n\n    // The surface controller owns the geodetic movement state in every input\n    // mode, including XR. Prefer its metre-scale speed instead of subtracting\n    // headset-local poses or two 6.4 Mm ECEF positions.\n    const surfaceSpeed = this.surfaceController.getSurfaceSpeed?.();\n    if (Number.isFinite(surfaceSpeed)) {\n      this._speed = Math.max(0, surfaceSpeed);\n      return;\n    }\n\n    // Fallback for reduced controller fixtures: resolve the full nested world\n    // transform rather than mistaking room-space camera.position for Earth.\n    const camera = this.camera || this.surfaceController.camera;\n    const published = camera?.userData?.worldPosition;\n    const camPos = published?.isVector3\n      ? published\n      : camera?.getWorldPosition?.(this._tmpWorldPoint) || camera?.position;\n    if (!camPos) return;\n\n    this._currentPosition.copy(camPos);\n\n    if (this._hasLastPosition) {\n      const invDt = 1 / Math.max(dt, 1e-5);\n      this._velocity.subVectors(this._currentPosition, this._lastPosition).multiplyScalar(invDt);\n\n      // Horizontal speed for animation\n      this._speed = Math.hypot(this._velocity.x, this._velocity.z);\n    }\n\n    this._lastPosition.copy(this._currentPosition);\n    this._hasLastPosition = true;\n  }\n\n  /**\n   * Determine if player is grounded based on surface controller state\n   */\n  _updateGroundedState() {\n    if (!this.surfaceController) {\n      this._isGrounded = true;\n      this._isCrouching = false;\n      this._isJumping = false;\n      this._isMeditating = false;\n      return;\n    }\n\n    // Get states from surface controller (single source of truth)\n    this._isCrouching = this.surfaceController.isCrouching?.() || false;\n    this._isJumping = this.surfaceController.isJumping?.() || false;\n    this._isGrounded = this.surfaceController.isGrounded?.() || false;\n    this._isSwimming = this.surfaceController.getOceanNavigationState?.().swimming === true;\n\n    // Determine meditate state based on altitude\n    const alt = this.surfaceController.surfaceAltitudeMeters || 0;\n    const standHeight = this.surfaceController.STAND_EYE_HEIGHT || 1.6;\n    const heightAboveStand = alt - standHeight;\n\n    // Meditate when floating well above normal standing height\n    if (this._isSwimming) {\n      this._isMeditating = false;\n      this._isGrounded = false;\n    } else if (!this._isJumping && heightAboveStand > this._meditateThreshold) {\n      this._isMeditating = true;\n      this._isGrounded = false;\n    } else {\n      this._isMeditating = false;\n    }\n  }\n\n  /**\n   * Update animation state based on movement\n   */\n  _updateAnimationState() {\n    if (!this.avatar) return;\n\n    // Handle meditate state (manual override)\n    if (this._isMeditating) {\n      this.avatar.setManualState('Meditate');\n    } else {\n      this.avatar.clearManualState('Meditate');\n    }\n\n    // Update avatar state from surface controller\n    this.avatar.setSpeed(this._speed);\n    this.avatar.setCrouch(this._isCrouching);\n\n    // Set airborne for jump/fall animation\n    // Jump triggers Fall animation when airborne\n    this.avatar.setAirborne(this._isJumping || !this._isGrounded);\n\n    // Update head look based on camera pitch\n    this._updateHeadLook();\n  }\n\n  /**\n   * Update avatar head look based on camera pitch\n   */\n  _updateHeadLook() {\n    if (!this.avatar || !this.surfaceController) return;\n\n    // Get pitch from surface controller (in radians)\n    const pitchRad = this.surfaceController.surfaceState?.pitch || 0;\n\n    // Pass to avatar for head/neck IK\n    // Yaw is 0 since avatar body faces camera direction\n    this.avatar.setHeadLook({\n      active: true,\n      yaw: 0,\n      pitch: pitchRad,\n      roll: 0\n    });\n  }\n\n  /**\n   * Sync avatar position and orientation to surface controller\n   *\n   * HIGH-PRECISION POSITIONING (same technique as BuildingOverlay):\n   * Instead of computing world coordinates directly (which lose precision at 6.4M meters),\n   * we use direction-vector positioning:\n   *   position = direction_vector * radius\n   *\n   * The direction vector is unit-length (~1.0), so all intermediate math stays in\n   * high-precision range. Only the final multiplication by radius produces large values,\n   * but this happens in a single operation preserving precision.\n   *\n   * This is why buildings don't jitter - they use this same technique.\n   */\n  _syncToSurface() {\n    if (!this.avatar || !this.surfaceController) return;\n\n    const surfaceState = this.surfaceController.surfaceState;\n    if (!surfaceState) return;\n\n    // Get the surface up direction (unit vector pointing from planet center through player)\n    // This is already normalized and in the correct coordinate space\n    const surfaceUp = surfaceState.up;\n    if (!surfaceUp) return;\n\n    // Camera collision and avatar feet share one settled contact point. The\n    // controller returns world space; convert both point and up direction into\n    // the avatar parent's planet-local frame before applying them.\n    const contactWorld = this.surfaceController.getSurfaceContactPoint?.(this._tmpWorldPoint, surfaceUp)\n      || this._tmpWorldPoint.copy(surfaceUp).multiplyScalar(this.surfaceController._terrainRadius || PLANET_RADIUS);\n    const parent = this._avatarLayer?.parent || this.triTree?.group || null;\n    parent?.updateWorldMatrix?.(true, false);\n    const localPos = this._tmpVec.copy(contactWorld);\n    if (parent?.worldToLocal) parent.worldToLocal(localPos);\n\n    const localUp = this._tmpLocalUp.copy(surfaceUp).normalize();\n    if (parent?.getWorldQuaternion) {\n      parent.getWorldQuaternion(this._tmpParentQuat).invert();\n      localUp.applyQuaternion(this._tmpParentQuat).normalize();\n    }\n\n    // Set avatar position directly using direction * radius\n    this.avatar.setPosition(localPos.x, localPos.y, localPos.z);\n\n    // Build orientation quaternion aligned to local surface\n    this._buildSurfaceOrientation(localUp, surfaceState.yaw || 0);\n  }\n\n  /**\n   * Build quaternion for surface-aligned orientation at given local up direction\n   *\n   * Avatar is parented to triTree.group. The surfaceUp is in the same coordinate\n   * space as the avatar position (triTree.group local space).\n   */\n  _buildSurfaceOrientation(surfaceUp, yawRad) {\n    // Create local coordinate system on the surface\n    // surfaceUp is already in triTree.group local space\n    const up = this._tmpVec.copy(surfaceUp).normalize();\n\n    // Create tangent basis vectors\n    // Use a reference \"world up\" to derive east/north tangent vectors\n    const refUp = new THREE.Vector3(0, 1, 0);\n    const east = new THREE.Vector3().crossVectors(refUp, up);\n    if (east.lengthSq() < 1e-6) {\n      // Near poles, use a different reference\n      east.set(1, 0, 0);\n    }\n    east.normalize();\n\n    const north = new THREE.Vector3().crossVectors(up, east).normalize();\n\n    // Rotate by yaw to get forward direction\n    const forward = new THREE.Vector3();\n    forward.addScaledVector(north, Math.cos(yawRad));\n    forward.addScaledVector(east, Math.sin(yawRad));\n\n    // Build rotation matrix\n    const right = new THREE.Vector3().crossVectors(forward, up).normalize();\n\n    const m = new THREE.Matrix4();\n    m.makeBasis(right, up, forward.negate());\n\n    // Set quaternion directly - no coordinate conversion needed since\n    // surfaceUp is already in the avatar's parent coordinate space\n    this._tmpQuat.setFromRotationMatrix(m);\n    this.avatar.setQuaternion(this._tmpQuat);\n  }\n\n  beginMotionVisualOverride({ executionId, generation } = {}) {\n    if (!this._ready || !this.avatar || !this._avatarGroup || this._motionVisualOverride) return null;\n    const token = Object.freeze({ executionId: String(executionId || ''), generation: Number(generation) });\n    this._motionVisualOverride = {\n      token,\n      original: {\n        position: this._avatarGroup.position.clone(),\n        quaternion: this._avatarGroup.quaternion.clone(),\n        scale: this._avatarGroup.scale.clone(),\n        visible: this._avatarGroup.visible,\n      },\n      position: this._avatarGroup.position.clone(),\n      quaternion: this._avatarGroup.quaternion.clone(),\n      scale: this._avatarGroup.scale.clone(),\n      visible: this._avatarGroup.visible,\n      hasPose: false,\n    };\n    return token;\n  }\n\n  applyMotionVisualOverride(token, pose = {}) {\n    const override = this._motionVisualOverride;\n    if (!override || override.token !== token || !this._ready || !this.avatar) return false;\n    if (pose.position?.isVector3) override.position.copy(pose.position);\n    if (pose.quaternion?.isQuaternion) override.quaternion.copy(pose.quaternion);\n    if (pose.scale?.isVector3) override.scale.copy(pose.scale);\n    if (typeof pose.visible === 'boolean') override.visible = pose.visible;\n    override.hasPose = true;\n    return true;\n  }\n\n  endMotionVisualOverride(token, { restore = true } = {}) {\n    const override = this._motionVisualOverride;\n    if (!override || override.token !== token) return false;\n    if (restore && this._avatarGroup) {\n      this._avatarGroup.position.copy(override.original.position);\n      this._avatarGroup.quaternion.copy(override.original.quaternion);\n      this._avatarGroup.scale.copy(override.original.scale);\n      this._avatarGroup.visible = override.original.visible;\n      this._avatarGroup.updateMatrixWorld?.();\n    }\n    this._motionVisualOverride = null;\n    return true;\n  }\n\n  /**\n   * Update each frame\n   */\n  update(dt) {\n    if (!this._ready || !this.avatar) return;\n\n    const motionPose = this._motionVisualOverride;\n    if (motionPose?.hasPose) {\n      this.avatar.setPosition(motionPose.position.x, motionPose.position.y, motionPose.position.z);\n      this.avatar.setQuaternion(motionPose.quaternion);\n      this._avatarGroup.scale.copy(motionPose.scale);\n      this._avatarGroup.visible = motionPose.visible\n        && !this._xrPresenting\n        && this.surfaceController?.isVRMode?.() !== true;\n      this.avatar.update(dt);\n      this._avatarGroup.updateMatrixWorld?.();\n      return;\n    }\n\n    // Skip if not in surface mode\n    if (this.surfaceController?.cameraMode !== 'surface') {\n      this._avatarGroup.visible = false;\n      return;\n    }\n\n    // Compute velocity from movement\n    this._computeVelocity(dt);\n\n    // Update grounded/floating state\n    this._updateGroundedState();\n\n    // Update animation state\n    this._updateAnimationState();\n\n    // Sync position to surface controller\n    this._syncToSurface();\n\n    // Update avatar animation\n    this.avatar.update(dt);\n\n    // Visibility based on first-person mode\n    this._syncVisibility();\n  }\n\n  /**\n   * Set first-person mode (hides avatar)\n   */\n  setFirstPerson(enabled) {\n    this._firstPerson = !!enabled;\n    this._syncVisibility();\n  }\n\n  /**\n   * Set visibility\n   */\n  setVisible(visible) {\n    this._visible = !!visible;\n    this._syncVisibility();\n  }\n\n  /** Preserve the user's desktop camera preference while hard-excluding the\n   * local avatar from immersive headset rendering. */\n  setXRPresenting(presenting) {\n    this._xrPresenting = !!presenting;\n    this._syncVisibility();\n  }\n\n  _syncVisibility() {\n    if (this._avatarGroup) {\n      const nativeXR = this._xrPresenting || this.surfaceController?.isVRMode?.() === true;\n      this._avatarGroup.visible = !nativeXR && !this._firstPerson && this._visible;\n    }\n  }\n\n  applyConfig(config = {}) {\n    this._config = config;\n    const local = config?.local || {};\n    if (Number.isFinite(local.meditateAltitudeThreshold)) {\n      this._meditateThreshold = local.meditateAltitudeThreshold;\n    }\n    if (this.avatar?.applyConfig) {\n      this.avatar.applyConfig(config);\n    }\n  }\n\n  /**\n   * Get current animation state for presence broadcasting\n   */\n  getAnimationState() {\n    if (!this.avatar) {\n      const swimming = this.surfaceController?.getOceanNavigationState?.().swimming === true;\n      return {\n        animState: 'Idle',\n        speed: 0,\n        isGrounded: true,\n        isCrouching: false,\n        isJumping: false,\n        isMeditating: false,\n        isSwimming: swimming\n      };\n    }\n\n    return {\n      animState: this.avatar.current || 'Idle',\n      speed: this._speed,\n      isGrounded: this._isGrounded,\n      isCrouching: this._isCrouching,\n      isJumping: this._isJumping,\n      isMeditating: this._isMeditating,\n      isSwimming: this._isSwimming === true\n    };\n  }\n\n  /**\n   * Check if ready\n   */\n  isReady() {\n    return this._ready;\n  }\n\n  /**\n   * Handle origin shift from floating origin system\n   * Adjusts cached world positions to maintain correct velocity tracking\n   */\n  handleOriginShift(shift) {\n    if (this._hasLastPosition && this._lastPosition) {\n      this._lastPosition.sub(shift);\n    }\n    if (this._currentPosition) {\n      this._currentPosition.sub(shift);\n    }\n  }\n\n  /**\n   * Dispose of resources\n   */\n  dispose() {\n    this._motionVisualOverride = null;\n    if (typeof window !== 'undefined') {\n      window.removeEventListener('keydown', this._boundKeyDown);\n      window.removeEventListener('keyup', this._boundKeyUp);\n    }\n\n    // Unsubscribe from origin shift events\n    this.eventBus?.off?.('origin:shift', this._boundOriginShift);\n    this.eventBus?.off?.('vr:session-start', this._boundXRStart);\n    this.eventBus?.off?.('vr:session-end', this._boundXREnd);\n\n    // Remove from parent (triTree.group or scene)\n    if (this._avatarLayer?.parent) {\n      this._avatarLayer.parent.remove(this._avatarLayer);\n    }\n\n    if (this.avatar) {\n      this.avatar.dispose();\n      this.avatar = null;\n    }\n\n    this._avatarGroup = null;\n    this._avatarLayer = null;\n    this._ready = false;\n  }\n\n}\n\nexport default LocalPlayer;\n","/**\n * PeerManager - Manages remote peer avatars\n *\n * Handles:\n * - Creating avatars for remote peers\n * - Updating avatar positions from presence data\n * - Smooth interpolation of remote positions\n * - Cleanup when peers leave\n */\n\nimport * as THREE from 'three';\nimport { Avatar } from './Avatar.js';\nimport { AvatarFactory } from './AvatarFactory.js';\nimport { getLabelSystem } from '../labels/LabelSystem.js';\nimport { latLonToLocalDir, ellipsoidRadiusForLocalDir } from '../../modules/geometry-utils.js';\nimport { PLANET_RADIUS } from '../../modules/constants.js';\nimport { presenceLabelMetadata, presenceInstanceText } from '../presence/PresenceLabel.js';\nimport {\n  avatarAppearanceSignature,\n  normalizeAvatarAppearance,\n} from './AvatarAppearance.js';\n\nconst PEER_LABEL_MAX_DISTANCE_M = 100_000;\n// Surface-contact samples can move by centimetres while a photoreal child LOD\n// replaces its parent. Do not turn that terrain sampling noise into a remote\n// character hop or, worse, extrapolated radial velocity.\nconst PEER_STATIONARY_CONTACT_RADIUS_M = 1.5;\nconst PEER_STATIONARY_CONTACT_DEADBAND_M = 0.08;\nconst PEER_STATIONARY_SPEED_MPS = 0.12;\nconst PEER_CONTACT_CONFIRM_MS = 350;\nconst PEER_CONTACT_CANDIDATE_TOLERANCE_M = 0.12;\n\nconst MOTION_STATE_KEYS = [\n  'isGrounded',\n  'isJumping',\n  'isMeditating',\n  'isSwimming',\n];\n\nfunction hasExplicitMotionState(state) {\n  return MOTION_STATE_KEYS.some((key) => typeof state?.[key] === 'boolean');\n}\n\nfunction remoteAvatarConfig(config = {}) {\n  const { appearance: _localAppearance, identity: _localIdentity, ...shared } = config || {};\n  return shared;\n}\n\n// Smoothing helper\nfunction smoothAlpha(ratePerSec, dt) {\n  return 1 - Math.exp(-Math.max(0, ratePerSec) * Math.max(0, dt));\n}\n\n/**\n * PeerManager - Manages all remote peer avatars\n */\nexport class PeerManager {\n  constructor(options = {}) {\n    this.scene = options.scene || null;\n    this.triTree = options.triTree || null;\n    this.presenceSystem = options.presenceSystem || null;\n    this.eventBus = options.eventBus || null;\n    this.planetRadius = options.planetRadius || PLANET_RADIUS;\n    this.camera = options.camera || null;\n    this.surfaceController = options.surfaceController || null;\n    this._labelSystem = options.labelSystem || null;\n\n    // Peer data\n    this._peers = new Map();      // peerId -> PeerEntry\n    this._factory = null;\n    this._ready = false;\n    this._config = null;\n\n    // Container for all peer avatars\n    // Add to triTree.group for planet-local positioning\n    // Peer positions are stored in the same coordinate space as terrain tiles.\n    this._peerLayer = new THREE.Group();\n    this._peerLayer.name = 'PeerAvatars';\n\n    const parentGroup = this.triTree?.group || this.scene;\n    if (parentGroup) {\n      parentGroup.add(this._peerLayer);\n    }\n\n    // Interpolation settings\n    this._positionRate = 24;  // Render-frame interpolation over 24 Hz snapshots\n    this._rotationRate = 28;  // Keep look direction perceptually immediate\n\n    // Temporary vectors\n    this._tmpVec = new THREE.Vector3();\n    this._tmpQuat = new THREE.Quaternion();\n    this._inverseMatrix = new THREE.Matrix4();\n  }\n\n  /**\n   * Initialize the peer manager\n   */\n  async init() {\n    try {\n      console.log('[PeerManager] Initializing...');\n      this._factory = await AvatarFactory.load();\n\n      if (!this._factory) {\n        console.error('[PeerManager] Failed to load avatar factory');\n        return false;\n      }\n\n      this._ready = true;\n      console.log('[PeerManager] Initialized successfully');\n      return true;\n\n    } catch (err) {\n      console.error('[PeerManager] Initialization failed:', err);\n      return false;\n    }\n  }\n\n  /**\n   * Create a peer entry with avatar\n   */\n  _createPeer(peerId, state) {\n    if (!this._factory) return null;\n\n    // Create avatar\n    const avatarData = this._factory.create();\n    const avatar = new Avatar(\n      avatarData.root,\n      avatarData.clips,\n      avatarData.footYOffset,\n      avatarData.height,\n      avatarData.groundContact\n    );\n    if (this._config) {\n      avatar.applyConfig?.(remoteAvatarConfig(this._config));\n    }\n    const initialAppearance = normalizeAvatarAppearance(state?.appearance);\n    avatar.applyAppearance?.(initialAppearance);\n\n    // Create container group\n    const group = new THREE.Group();\n    group.name = `peer-${peerId.slice(0, 8)}`;\n    group.add(avatar.group);\n\n    // Create the canonical user label as a child of the oriented avatar. This\n    // keeps its world anchor mated to the live character while LabelSystem owns\n    // viewshed distance, view-cone fading, collision, DOM, and type visibility.\n    const labelText = this._composeLabelText(peerId, state);\n    const labelHandle = this._ensureLabelSystem()?.createLabel(labelText, {\n      position: new THREE.Vector3(0, avatar.height + 0.35, 0),\n      type: 'user',\n      objectRadius: Math.max(0.35, avatar.height * 0.22),\n      maxDistance: PEER_LABEL_MAX_DISTANCE_M,\n      labelPriority: 20,\n      treeShyness: true,\n      metadata: this._buildLabelMetadata(peerId, state, labelText),\n    }) || null;\n    if (labelHandle) avatar.group.add(labelHandle.group);\n\n    // Add to scene\n    this._peerLayer.add(group);\n\n    // Create peer entry\n    const entry = {\n      peerId,\n      group,\n      avatar,\n      labelHandle,\n      labelText,\n      appearance: initialAppearance,\n      appearanceSignature: avatarAppearanceSignature(initialAppearance),\n      targetPosition: new THREE.Vector3(),\n      previousTargetPosition: new THREE.Vector3(),\n      predictedTargetPosition: new THREE.Vector3(),\n      networkVelocity: new THREE.Vector3(),\n      reportedContactDir: new THREE.Vector3(),\n      reportedContactMsl: null,\n      hasReportedContact: false,\n      reportedContactCandidateMsl: null,\n      reportedContactCandidateSinceMs: 0,\n      targetQuaternion: new THREE.Quaternion(),\n      hasSnapshot: false,\n      lastSnapshotSentAtMs: 0,\n      lastUpdateTime: performance.now(),\n      state: state || {}\n    };\n\n    // Set initial position\n    if (state) {\n      this._updateTargetFromState(entry, state);\n      group.position.copy(entry.targetPosition);\n      avatar.setQuaternion(entry.targetQuaternion);\n    }\n\n    this._peers.set(peerId, entry);\n    console.log('[PeerManager] Created peer avatar:', peerId.slice(0, 8));\n\n    return entry;\n  }\n\n  /**\n   * Compose label text from peer state\n   */\n  _composeLabelText(peerId, state) {\n    const shortId = peerId ? peerId.slice(0, 8) : 'Unknown';\n    // The backend-authorized `label` field is the sole identity surface. Do\n    // not bypass a registered user's hide-username preference with incidental\n    // username/handle fields from a provider payload.\n    const label = [state?.label]\n      .find((value) => typeof value === 'string' && value.trim())?.trim() || '';\n    const identity = label || `Guest ${shortId.slice(0, 4)}`;\n    return state?.deviceClass ? `${identity} · ${presenceInstanceText(state, peerId)}` : identity;\n  }\n\n  _buildLabelMetadata(peerId, state, username) {\n    return {\n      ...presenceLabelMetadata(state, peerId),\n      id: `presence:${peerId}`,\n      peerId,\n      userId: state?.userId || null,\n      deviceId: state?.deviceId || null,\n      username,\n      source: 'NOCLIP presence',\n      type: 'user',\n      lat: Number.isFinite(Number(state?.lat)) ? Number(state.lat) : undefined,\n      lon: Number.isFinite(Number(state?.lon)) ? Number(state.lon) : undefined,\n      elevationM: Number.isFinite(Number(state?.elevation_m)) ? Number(state.elevation_m) : undefined,\n      headingDeg: Number.isFinite(Number(state?.heading_deg)) ? Number(state.heading_deg) : undefined,\n      pitchDeg: Number.isFinite(Number(state?.pitch_deg)) ? Number(state.pitch_deg) : undefined,\n      sequence: Number.isFinite(Number(state?.seq)) ? Number(state.seq) : undefined,\n      sentAtMs: Number.isFinite(Number(state?.sentAtMs)) ? Number(state.sentAtMs) : undefined,\n    };\n  }\n\n  _ensureLabelSystem() {\n    if (!this._labelSystem) {\n      this._labelSystem = getLabelSystem({ planetRadius: this.planetRadius });\n    }\n    return this._labelSystem;\n  }\n\n  /**\n   * Update target position/orientation from presence state\n   *\n   * Stores positions in planet-local coordinates (same coordinate system as terrain).\n   */\n  _updateTargetFromState(entry, state) {\n    if (!state) return;\n\n    const lat = state.lat;\n    const lon = state.lon;\n    const elevation = state.elevation_m || 0;\n    const heading = state.heading_deg;\n\n    if (!Number.isFinite(lat) || !Number.isFinite(lon)) return;\n\n    const hadSnapshot = entry.hasSnapshot === true;\n    if (hadSnapshot) entry.previousTargetPosition.copy(entry.targetPosition);\n\n    // Convert lat/lon to planet-local direction\n    // This is the same coordinate system as terrain vertices\n    const dir = latLonToLocalDir(lat, lon);\n\n    // Calculate planet-local position (same as terrain vertex positions)\n    // elevation_m from presence is camera altitude (includes eye height)\n    // When grounded, subtract eye height to place avatar feet on ground\n    // When floating/meditating, keep the avatar elevated at camera position\n    const eyeHeight = Number.isFinite(entry.avatar?.eyeHeight) ? entry.avatar.eyeHeight : 1.6;\n    const isSwimming = state.isSwimming === true;\n    const motionStateKnown = hasExplicitMotionState(state);\n    const isFloating = state.isMeditating === true\n      || isSwimming\n      || (motionStateKnown && state.isGrounded === false && state.isJumping !== true);\n    const reportedContactMsl = Number(state.surface_contact_msl);\n    // `surface_contact_msl` belongs to the altitude permission, while\n    // `isGrounded` belongs to the independently configurable motion\n    // permission. A motion-hidden packet therefore has no `isGrounded`\n    // field. Treating that omission as false ignored the exact foot datum and\n    // raised the peer by roughly half an eye height. It also let differently\n    // enriched public/friend packets alternate between two vertical frames.\n    // Presence of a finite contact is sufficient unless the sender explicitly\n    // reports an airborne pose.\n    const canUseReportedContact = Number.isFinite(reportedContactMsl)\n      && (state.isGrounded === true || !motionStateKnown);\n    let stableContactMsl = reportedContactMsl;\n    const receivedAtMs = performance.now();\n    if (canUseReportedContact) {\n      if (entry.hasReportedContact !== true) {\n        entry.reportedContactMsl = reportedContactMsl;\n        entry.hasReportedContact = true;\n      } else {\n        const horizontalTravelM = Math.sqrt(entry.reportedContactDir.distanceToSquared(dir))\n          * this.planetRadius;\n        const reportedSpeed = Math.max(0, Number(state.speed) || 0);\n        const stationary = reportedSpeed <= PEER_STATIONARY_SPEED_MPS\n          && horizontalTravelM <= PEER_STATIONARY_CONTACT_RADIUS_M;\n        const contactDeltaM = reportedContactMsl - entry.reportedContactMsl;\n\n        if (Math.abs(contactDeltaM) <= PEER_STATIONARY_CONTACT_DEADBAND_M) {\n          stableContactMsl = entry.reportedContactMsl;\n          entry.reportedContactCandidateMsl = null;\n          entry.reportedContactCandidateSinceMs = 0;\n        } else if (stationary) {\n          const candidateMatches = Number.isFinite(entry.reportedContactCandidateMsl)\n            && Math.abs(reportedContactMsl - entry.reportedContactCandidateMsl)\n              <= PEER_CONTACT_CANDIDATE_TOLERANCE_M;\n          if (!candidateMatches) {\n            entry.reportedContactCandidateMsl = reportedContactMsl;\n            entry.reportedContactCandidateSinceMs = receivedAtMs;\n          } else if (receivedAtMs - entry.reportedContactCandidateSinceMs >= PEER_CONTACT_CONFIRM_MS) {\n            // A persistent change is a real terrain/LOD correction. Adopt it\n            // once, then let render interpolation move the avatar smoothly.\n            entry.reportedContactMsl = reportedContactMsl;\n            entry.reportedContactCandidateMsl = null;\n            entry.reportedContactCandidateSinceMs = 0;\n          }\n          stableContactMsl = entry.reportedContactMsl;\n        } else {\n          // While the peer is actually walking, follow the terrain datum. The\n          // outer render interpolation provides smoothing without delaying a\n          // legitimate climb or descent.\n          entry.reportedContactMsl = reportedContactMsl;\n          entry.reportedContactCandidateMsl = null;\n          entry.reportedContactCandidateSinceMs = 0;\n        }\n      }\n      // Track every horizontal sample even while the vertical datum is held;\n      // otherwise accumulated travel would masquerade as one discontinuity.\n      entry.reportedContactDir.copy(dir);\n      stableContactMsl = entry.reportedContactMsl;\n    } else {\n      entry.hasReportedContact = false;\n      entry.reportedContactCandidateMsl = null;\n      entry.reportedContactCandidateSinceMs = 0;\n    }\n    const avatarElevation = canUseReportedContact\n      ? stableContactMsl\n      : (isFloating\n        ? elevation - eyeHeight * (isSwimming ? 0.55 : 0.5)\n        : elevation - eyeHeight);\n    const baseRadius = ellipsoidRadiusForLocalDir(dir);\n    const radius = baseRadius + avatarElevation;\n    entry.targetPosition.copy(dir).multiplyScalar(radius);\n\n    // Estimate short-horizon velocity from authoritative snapshots. It is\n    // used only for a bounded prediction between packets; discontinuous Go,\n    // Nav, teleport, and body changes intentionally clear prediction.\n    const sentAtMs = Number(state.sentAtMs);\n    if (hadSnapshot) {\n      const remoteDt = Number.isFinite(sentAtMs) && sentAtMs > entry.lastSnapshotSentAtMs\n        ? (sentAtMs - entry.lastSnapshotSentAtMs) / 1000\n        : (receivedAtMs - entry.lastUpdateTime) / 1000;\n      const delta = entry.predictedTargetPosition.subVectors(\n        entry.targetPosition,\n        entry.previousTargetPosition,\n      );\n      const reportedSpeed = Math.max(0, Number(state.speed) || 0);\n      const continuityLimitM = Math.max(20, reportedSpeed * Math.max(remoteDt, 0) * 4 + 8);\n      if (remoteDt >= 0.005 && remoteDt <= 0.5 && delta.length() <= continuityLimitM) {\n        entry.networkVelocity.copy(delta).multiplyScalar(1 / remoteDt);\n        if (canUseReportedContact) {\n          // Grounded prediction may advance horizontally, but never forecast a\n          // tile-contact correction upward/downward between network packets.\n          entry.networkVelocity.addScaledVector(\n            dir,\n            -entry.networkVelocity.dot(dir),\n          );\n        }\n      } else {\n        entry.networkVelocity.set(0, 0, 0);\n      }\n    } else {\n      entry.networkVelocity.set(0, 0, 0);\n    }\n    entry.hasSnapshot = true;\n    entry.lastSnapshotSentAtMs = Number.isFinite(sentAtMs) ? sentAtMs : 0;\n\n    // Calculate orientation from heading\n    if (Number.isFinite(heading)) {\n      const headingRad = heading * (Math.PI / 180);\n      // Build quaternion that faces heading direction while aligned to surface\n      this._buildSurfaceQuaternion(entry.targetQuaternion, dir, headingRad);\n    }\n\n    // Update avatar state from presence data\n    // We pass hints but let the Avatar's automatic state machine do the heavy lifting\n    // by interpreting velocity from position changes in update()\n    if (entry.avatar) {\n      // An omitted appearance field is a partial-packet omission, not a\n      // command to repaint the peer with the default material. This is\n      // especially important while a live connection transitions between\n      // backend and P2P delivery paths.\n      const hasAppearance = !!state.appearance && typeof state.appearance === 'object';\n      const nextAppearanceSignature = hasAppearance\n        ? avatarAppearanceSignature(state.appearance)\n        : entry.appearanceSignature;\n      if (hasAppearance && nextAppearanceSignature !== entry.appearanceSignature) {\n        entry.appearance = normalizeAvatarAppearance(state.appearance);\n        entry.avatar.applyAppearance?.(entry.appearance);\n        entry.appearanceSignature = nextAppearanceSignature;\n      }\n      // Crouch state must be explicit - can't be inferred from motion\n      if (state.isCrouching !== undefined) {\n        entry.avatar.setCrouch(state.isCrouching);\n      }\n\n      // Airborne/grounded affects Fall animation selection\n      // Also set airborne when jumping\n      if (state.isJumping) {\n        entry.avatar.setAirborne(true);\n      } else if (state.isGrounded !== undefined) {\n        entry.avatar.setAirborne(!state.isGrounded);\n      }\n\n      // Special states that override automatic selection\n      // These are \"poses\" that can't be inferred from movement\n      if (state.isMeditating) {\n        entry.avatar.setManualState('Meditate');\n      } else if (state.animState === 'Death' || state.animState === 'Surrender') {\n        // Death and Surrender are explicit manual states\n        entry.avatar.setManualState(state.animState);\n      } else {\n        // Clear any manual state so automatic selection takes over\n        // Walk/Run/Idle/Crouch states are inferred from velocity\n        entry.avatar.clearManualState();\n      }\n\n      // Optionally provide speed hint for tempo scaling\n      // But Avatar.update() will also compute speed from position delta\n      if (Number.isFinite(state.speed)) {\n        entry.avatar.setSpeed(state.speed);\n      }\n\n      // Update head look from pitch (peer is looking up/down)\n      if (Number.isFinite(state.pitch_deg)) {\n        const pitchRad = state.pitch_deg * (Math.PI / 180);\n        entry.avatar.setHeadLook({\n          active: true,\n          yaw: 0,\n          pitch: pitchRad,\n          roll: 0\n        });\n      }\n    }\n\n    entry.state = state;\n    entry.lastUpdateTime = receivedAtMs;\n  }\n\n  /**\n   * Build a quaternion for surface-aligned orientation\n   */\n  _buildSurfaceQuaternion(target, upDir, yawRad) {\n    // Create a local coordinate system on the surface\n    const up = this._tmpVec.copy(upDir).normalize();\n\n    // Create forward direction (tangent to surface, pointing in yaw direction)\n    const worldUp = new THREE.Vector3(0, 1, 0);\n    const east = new THREE.Vector3().crossVectors(worldUp, up);\n    if (east.lengthSq() < 1e-6) {\n      east.set(1, 0, 0);\n    }\n    east.normalize();\n\n    const north = new THREE.Vector3().crossVectors(up, east).normalize();\n\n    // Rotate by yaw\n    const forward = new THREE.Vector3();\n    forward.addScaledVector(north, Math.cos(yawRad));\n    forward.addScaledVector(east, Math.sin(yawRad));\n\n    // Build rotation matrix\n    const right = new THREE.Vector3().crossVectors(forward, up).normalize();\n\n    const m = new THREE.Matrix4();\n    m.makeBasis(right, up, forward.negate());\n\n    target.setFromRotationMatrix(m);\n  }\n\n  /**\n   * Handle presence peer update\n   */\n  handlePeerUpdate(peerId, state) {\n    if (!this._ready) return;\n    if (!peerId) return;\n\n    let entry = this._peers.get(peerId);\n\n    if (!entry) {\n      entry = this._createPeer(peerId, state);\n      if (!entry) return;\n    }\n\n    this._updateTargetFromState(entry, state);\n\n    // Update label text only when needed, but always refresh live coordinates\n    // and pose metadata so label actions/details resolve the peer's actual\n    // geodetic location instead of its avatar-local head offset.\n    const newLabelText = this._composeLabelText(peerId, state);\n    this._updateLabel(entry, newLabelText);\n  }\n\n  /**\n   * Handle peer leaving\n   */\n  handlePeerLeave(peerId) {\n    const entry = this._peers.get(peerId);\n    if (!entry) return;\n\n    console.log('[PeerManager] Peer left:', peerId.slice(0, 8));\n\n    // Remove from scene\n    if (entry.group) {\n      this._peerLayer.remove(entry.group);\n    }\n\n    // Release the shared label before its avatar parent is disposed.\n    if (entry.labelHandle) this._ensureLabelSystem()?.removeLabel?.(entry.labelHandle);\n\n    if (entry.avatar) entry.avatar.dispose();\n\n    this._peers.delete(peerId);\n  }\n\n  /**\n   * Update label text\n   */\n  _updateLabel(entry, text) {\n    if (!entry) return;\n    if (entry.labelHandle) {\n      const labels = this._ensureLabelSystem();\n      if (text !== entry.labelText) labels?.updateText?.(entry.labelHandle, text);\n      labels?.updateMetadata?.(\n        entry.labelHandle,\n        this._buildLabelMetadata(entry.peerId, entry.state, text),\n      );\n    }\n    entry.labelText = text;\n  }\n\n  /**\n   * Update hover state based on raycaster\n   */\n  updateHover(raycaster) {\n    if (!raycaster) return null;\n\n    let hoveredPeer = null;\n    let minDist = Infinity;\n\n    for (const entry of this._peers.values()) {\n      const hits = raycaster.intersectObject(entry.avatar.group, true);\n      if (hits.length > 0 && hits[0].distance < minDist) {\n        hoveredPeer = entry;\n        minDist = hits[0].distance;\n      }\n    }\n\n    // Preserve avatar picking while letting the unified label system own\n    // visibility. Hover only raises the semantic opacity for the selected user.\n    for (const entry of this._peers.values()) {\n      const isHovered = entry === hoveredPeer;\n      if (entry.labelHandle) entry.labelHandle.opacity = isHovered ? 1 : 0.9;\n    }\n\n    return hoveredPeer ? hoveredPeer.peerId : null;\n  }\n\n  /**\n   * Clear hover state\n   */\n  clearHover() {\n    for (const entry of this._peers.values()) {\n      if (entry.labelHandle) entry.labelHandle.opacity = 0.9;\n    }\n  }\n\n  /**\n   * Update all peer avatars each frame\n   *\n   * Peer avatars are children of triTree.group, so positions are in planet-local space.\n   * We compute velocity from position changes to drive animation state selection.\n   */\n  update(dt) {\n    if (!this._ready) return;\n\n    const invDt = 1 / Math.max(dt, 1e-5);\n\n    for (const entry of this._peers.values()) {\n      // Store previous position for velocity calculation\n      if (!entry.prevPosition) {\n        entry.prevPosition = new THREE.Vector3();\n        entry.prevPosition.copy(entry.group.position);\n      }\n\n      // Predict no more than 80 ms ahead, then interpolate on every render\n      // frame. Network cadence and visual cadence remain decoupled, so a\n      // 60/90/120 Hz display stays smooth without emitting at display rate.\n      const snapshotAgeSec = Math.min(0.08, Math.max(0, (performance.now() - entry.lastUpdateTime) / 1000));\n      entry.predictedTargetPosition\n        .copy(entry.targetPosition)\n        .addScaledVector(entry.networkVelocity, snapshotAgeSec);\n\n      // Interpolate position in planet-local coordinates. Large discontinuous\n      // changes are navigation/teleport events and must land immediately.\n      const posAlpha = smoothAlpha(this._positionRate, dt);\n      if (entry.group.position.distanceToSquared(entry.predictedTargetPosition) > 250 * 250) {\n        entry.group.position.copy(entry.predictedTargetPosition);\n      } else {\n        entry.group.position.lerp(entry.predictedTargetPosition, posAlpha);\n      }\n\n      // Compute velocity from position change (for animation state selection)\n      // This gives us direction as well as speed for proper walk direction\n      this._tmpVec.subVectors(entry.group.position, entry.prevPosition).multiplyScalar(invDt);\n      entry.prevPosition.copy(entry.group.position);\n\n      // Pass computed velocity to avatar for automatic animation selection\n      // Avatar will use this for both speed AND direction (forward/backward/strafe)\n      entry.avatar.setExternalVelocity(this._tmpVec);\n\n      // Interpolate rotation - apply to avatar.group so direction detection works\n      const rotAlpha = smoothAlpha(this._rotationRate, dt);\n      entry.avatar.group.quaternion.slerp(entry.targetQuaternion, rotAlpha);\n\n      // Update avatar animation\n      entry.avatar.update(dt);\n    }\n  }\n\n  /**\n   * Get peer by ID\n   */\n  getPeer(peerId) {\n    return this._peers.get(peerId);\n  }\n\n  /**\n   * Get all peer IDs\n   */\n  getPeerIds() {\n    return Array.from(this._peers.keys());\n  }\n\n  /**\n   * Get peer count\n   */\n  getPeerCount() {\n    return this._peers.size;\n  }\n\n  /**\n   * Check if ready\n   */\n  isReady() {\n    return this._ready;\n  }\n\n  applyConfig(config = {}) {\n    this._config = config;\n    for (const entry of this._peers.values()) {\n      entry.avatar?.applyConfig?.(remoteAvatarConfig(config));\n      // A later config refresh is local presentation state. Reapply the last\n      // authoritative remote appearance rather than consulting the most recent\n      // partial presence packet, which may intentionally omit appearance.\n      entry.avatar?.applyAppearance?.(entry.appearance);\n    }\n  }\n\n  /**\n   * Dispose of all resources\n   */\n  dispose() {\n    // Dispose all peers\n    for (const peerId of this._peers.keys()) {\n      this.handlePeerLeave(peerId);\n    }\n\n    // Remove peer layer from parent (triTree.group or scene)\n    if (this._peerLayer?.parent) {\n      this._peerLayer.parent.remove(this._peerLayer);\n    }\n\n    this._peers.clear();\n    this._factory = null;\n    this._ready = false;\n  }\n}\n\nexport default PeerManager;\n","import * as THREE from 'three';\n\nconst DEFAULT_IPD = 0.11;\nconst IPD_STORAGE_KEY = 'stereo-ipd';\nconst MAX_IPD = 0.15;\n\nexport class MobileStereoRenderer {\n  constructor({ renderer, scene, camera, sceneInitializer } = {}) {\n    this.renderer = renderer || null;\n    this.scene = scene || null;\n    this.camera = camera || null;\n    this.sceneInitializer = sceneInitializer || null;\n    this.enabled = false;\n    this.ipd = this._loadIpd();\n    this._tmpSize = new THREE.Vector2();\n  }\n\n  _loadIpd() {\n    if (typeof localStorage === 'undefined') return DEFAULT_IPD;\n    const stored = parseFloat(localStorage.getItem(IPD_STORAGE_KEY));\n    if (!Number.isFinite(stored)) return DEFAULT_IPD;\n    return THREE.MathUtils.clamp(stored, 0, MAX_IPD);\n  }\n\n  _storeIpd(value) {\n    if (typeof localStorage === 'undefined') return;\n    try {\n      localStorage.setItem(IPD_STORAGE_KEY, String(value));\n    } catch {}\n  }\n\n  setEnabled(enabled) {\n    const next = !!enabled;\n    if (next === this.enabled) return;\n    this.enabled = next;\n\n    // Every VR enter/exit MUST force a clean renderer + camera recompute.\n    // Without this, iPhone users saw two distinct regressions:\n    //   - On entry, the two stereo viewports rendered with a stale aspect\n    //     (the full-viewport aspect from the previous frame leaked into\n    //     the per-eye projection, so objects appeared horizontally\n    //     squashed in each half).\n    //   - On exit back to portrait, the camera kept the half-width aspect\n    //     from the final stereo frame, producing the \"portrait squeeze\"\n    //     where the whole scene looked laterally compressed.\n    //\n    // The recompute is run repeatedly across several animation frames\n    // because iOS Safari does not finalize the post-orientationchange\n    // layout synchronously — the very first call after rotation often\n    // sees the OLD viewport dimensions, caches them, and the genuine\n    // resize that arrives 1–2 frames later then short-circuits via\n    // sizeUnchanged guards in event-manager / scene-initializer.\n    this._scheduleRecomputeBurst();\n  }\n\n  /**\n   * Run _forceViewportRecompute now, then again across the next several\n   * animation frames + a setTimeout fallback. This catches iOS Safari's\n   * late-settling layout after orientationchange / VR exit.\n   */\n  _scheduleRecomputeBurst() {\n    this._forceViewportRecompute();\n\n    if (typeof window === 'undefined') return;\n    const dispatchResize = () => {\n      try { window.dispatchEvent(new Event('resize')); } catch (_err) { /* ignore */ }\n    };\n\n    if (typeof requestAnimationFrame !== 'function') {\n      // No rAF (very old browser): synthesize one resize and exit.\n      dispatchResize();\n      return;\n    }\n\n    // Frame +1 — first chance for layout to settle after orientationchange.\n    requestAnimationFrame(() => {\n      this._forceViewportRecompute();\n      dispatchResize();\n      // Frame +2 — iOS Safari sometimes only finalizes innerWidth/innerHeight\n      // on the second frame post-rotation. Re-run + redispatch.\n      requestAnimationFrame(() => {\n        this._forceViewportRecompute();\n        dispatchResize();\n      });\n    });\n\n    // Long tail — a few hundred ms after rotation iOS has definitely\n    // finalized the layout, so a final pass guarantees the renderer\n    // matches whatever the user is actually looking at.\n    setTimeout(() => {\n      this._forceViewportRecompute();\n      dispatchResize();\n    }, 350);\n  }\n\n  /**\n   * Force renderer + camera + post-processing targets to recompute from\n   * the current viewport. Bypasses the sizeUnchanged caches in\n   * event-manager and scene-initializer by clearing them first, so the\n   * next handleResize() / _onResize() definitely runs.\n   */\n  _forceViewportRecompute() {\n    if (!this.renderer || !this.camera) return;\n    const canvas = this.renderer.domElement;\n    if (!canvas) return;\n\n    // Strip any per-eye frustum asymmetry left over from the last stereo\n    // frame. Without this, the projection matrix keeps rendering an\n    // off-center slab of the scene.\n    if (typeof this.camera.clearViewOffset === 'function') {\n      this.camera.clearViewOffset();\n    }\n\n    // Ground truth for the new viewport: prefer window.innerWidth /\n    // innerHeight (the platform's authoritative orientation-aware\n    // values), then fall back to the canvas CSS box, then to the\n    // drawing buffer. window.* is preferred because the canvas\n    // bounding-rect can lag a frame behind the actual orientation\n    // change on iOS Safari.\n    let cssW = window.innerWidth;\n    let cssH = window.innerHeight;\n    if (!Number.isFinite(cssW) || cssW <= 0) {\n      const rect = canvas.getBoundingClientRect?.();\n      cssW = rect?.width || canvas.clientWidth || 1;\n    }\n    if (!Number.isFinite(cssH) || cssH <= 0) {\n      const rect = canvas.getBoundingClientRect?.();\n      cssH = rect?.height || canvas.clientHeight || 1;\n    }\n    cssW = Math.max(1, Math.floor(cssW));\n    cssH = Math.max(1, Math.floor(cssH));\n\n    // Apply to camera aspect so the NEXT render() capture of\n    // originalAspect starts from a correct full-viewport value.\n    if (Number.isFinite(cssW / cssH) && cssW > 0 && cssH > 0) {\n      this.camera.aspect = cssW / cssH;\n      if (typeof this.camera.updateProjectionMatrix === 'function') {\n        this.camera.updateProjectionMatrix();\n      }\n    }\n\n    // CRITICAL: invalidate the sizeUnchanged caches before asking the\n    // scene-initializer to resize. Otherwise — if its cache happened\n    // to be populated by an interleaved resize event during the\n    // orientation transition that recorded the stale (landscape) dims\n    // as the latest — the sizeUnchanged early-return swallows our\n    // recompute and the renderer keeps the wrong drawing-buffer size,\n    // producing the portrait stretch the user reported.\n    this._invalidateResizeCaches();\n\n    if (this.sceneInitializer && typeof this.sceneInitializer.handleResize === 'function') {\n      try {\n        this.sceneInitializer.handleResize();\n      } catch (err) {\n        console.warn('[MobileStereoRenderer] sceneInitializer.handleResize threw', err);\n      }\n    }\n\n    // Belt-and-suspenders: also call renderer.setSize directly with the\n    // ground-truth dimensions, in case sceneInitializer.handleResize is\n    // not wired (e.g. partial init) or its container measurement\n    // disagrees with window.innerWidth/innerHeight on this frame.\n    this._applyRendererSize(cssW, cssH);\n  }\n\n  /**\n   * Reset the size-cache fields on every component that participates in\n   * resize, so the next handleResize / _onResize call cannot be\n   * short-circuited by a stale equality check.\n   */\n  _invalidateResizeCaches() {\n    const targets = [];\n    if (this.sceneInitializer) targets.push(this.sceneInitializer);\n    // event-manager keeps an identical cache; reach it through the\n    // sceneInitializer if it's exposed, otherwise leave it to the\n    // dispatched resize burst (event-manager will see new dims on\n    // the dispatched event).\n    const eventManager = this.sceneInitializer?.eventManager\n      || this.sceneInitializer?._eventManager\n      || null;\n    if (eventManager) targets.push(eventManager);\n    for (const t of targets) {\n      // Setting to -1 (a value that no real measurement can match) is\n      // safer than 0, which equals the constructor default and could\n      // theoretically still match a 0-sized container during teardown.\n      t._lastClientWidth = -1;\n      t._lastClientHeight = -1;\n      t._lastRenderWidth = -1;\n      t._lastRenderHeight = -1;\n    }\n  }\n\n  /**\n   * Apply renderer.setSize with renderScale honored, with no CSS-style\n   * mutation (we keep the canvas at 100% / 100%, matching the rest of\n   * the app's resize convention).\n   */\n  _applyRendererSize(cssW, cssH) {\n    if (!this.renderer) return;\n    const renderScale = this.sceneInitializer?.renderScale || 1.0;\n    const renderW = Math.max(1, Math.floor(cssW * renderScale));\n    const renderH = Math.max(1, Math.floor(cssH * renderScale));\n    try {\n      // Ensure CSS sizing rules stay at full container width/height\n      // even if a previous setSize(updateStyle=true) call wrote pixel\n      // values to the canvas inline style.\n      if (this.renderer.domElement) {\n        this.renderer.domElement.style.width = '100%';\n        this.renderer.domElement.style.height = '100%';\n      }\n      this.renderer.setSize(renderW, renderH, false);\n    } catch (err) {\n      console.warn('[MobileStereoRenderer] renderer.setSize threw', err);\n    }\n  }\n\n  isEnabled() {\n    return !!this.enabled;\n  }\n\n  setIPD(value) {\n    if (!Number.isFinite(value)) return;\n    const next = THREE.MathUtils.clamp(value, 0, MAX_IPD);\n    this.ipd = next;\n    this._storeIpd(next);\n  }\n\n  getIPD() {\n    return this.ipd;\n  }\n\n  render(deltaTime = 0) {\n    if (!this.enabled) return false;\n    if (!this.renderer || !this.scene || !this.camera) return false;\n    if (this.renderer.xr?.isPresenting) return false;\n\n    this.renderer.getDrawingBufferSize(this._tmpSize);\n    const fullW = Math.max(1, Math.floor(this._tmpSize.x));\n    const fullH = Math.max(1, Math.floor(this._tmpSize.y));\n    if (fullW < 2 || fullH < 2) return false;\n\n    const halfW = Math.floor(fullW / 2);\n    const shift = (this.ipd / MAX_IPD) * (halfW / 2);\n    // Derive the \"full\" aspect from the ACTUAL drawing buffer rather\n    // than relying on this.camera.aspect. If the drawing buffer just\n    // changed (orientationchange landed during a frame) the camera\n    // aspect may still hold the previous full-frame value, which would\n    // produce squashed eyes this frame and a squeezed portrait next\n    // frame when we restore it.\n    const restoreAspect = fullW / fullH;\n\n    this.renderer.setScissorTest(true);\n\n    this._renderEye({\n      x: 0,\n      width: halfW,\n      fullW,\n      fullH,\n      offsetX: shift,\n      deltaTime\n    });\n\n    this._renderEye({\n      x: halfW,\n      width: halfW,\n      fullW,\n      fullH,\n      offsetX: fullW / 2 - shift,\n      deltaTime\n    });\n\n    this.camera.clearViewOffset();\n    this.camera.aspect = restoreAspect;\n    this.camera.updateProjectionMatrix();\n\n    this.renderer.setViewport(0, 0, fullW, fullH);\n    this.renderer.setScissor(0, 0, fullW, fullH);\n    this.renderer.setScissorTest(false);\n\n    return true;\n  }\n\n  _renderEye({ x, width, fullW, fullH, offsetX, deltaTime }) {\n    this.renderer.setViewport(x, 0, width, fullH);\n    this.renderer.setScissor(x, 0, width, fullH);\n\n    this.camera.aspect = width / fullH;\n    this.camera.setViewOffset(fullW, fullH, offsetX, 0, width, fullH);\n    this.camera.updateProjectionMatrix();\n    this.camera.updateMatrixWorld(true);\n\n    if (this.sceneInitializer?.renderSceneWithAtmosphere) {\n      this.sceneInitializer.renderSceneWithAtmosphere(this.renderer, this.scene, this.camera, deltaTime);\n    } else {\n      this.renderer.render(this.scene, this.camera);\n    }\n  }\n}\n","/**\n * Scene Budget Governor — monitors renderer.info and enforces GPU budgets.\n *\n * Watches triangle count, draw calls, texture count, and geometry count\n * each frame and applies progressive quality reduction when thresholds\n * are exceeded.  On mobile the budgets are lowered automatically.\n *\n * Integration:\n *   governor = new SceneBudgetGovernor(renderer, { isMobile })\n *   governor.setTriTree(triTree)\n *   // call once per frame AFTER renderer.render()\n *   governor.tick(dt)\n */\nexport class SceneBudgetGovernor {\n    constructor(renderer, opts = {}) {\n        this.renderer = renderer;\n\n        const mobile = !!opts.isMobile;\n        this.isMobile = mobile;\n\n        // Hard triangle budget — emergency merge if scene exceeds this\n        this.triangleBudget = mobile ? 350_000 : 3_000_000;\n        // Soft triangle budget — start throttling splits above this\n        this.triangleSoftBudget = mobile ? 220_000 : 2_000_000;\n        // Draw call budget\n        this.drawCallBudget = mobile ? 200 : 800;\n        // Geometry object count budget\n        this.geometryBudget = mobile ? 350 : 3000;\n        // Texture slot budget (GPU-resident textures)\n        this.textureBudget = mobile ? 96 : 600;\n\n        // How much to reduce tile budget when hard limit hit (multiplied each tick over)\n        this._emergencyTileBudgetScale = 0.88;\n        // How aggressively to boost merge budget during emergency\n        this._emergencyMergeBudgetScale = 1.6;\n        // Min tile budget floor even during emergency\n        this._emergencyTileBudgetFloor = mobile ? 300 : 600;\n\n        // --- Memory-pressure tier ---\n        // JS heap is the axis that actually kills mobile tabs (per-label textures/\n        // DOM + geojson borders). We watch usedJSHeapSize (when the browser exposes\n        // it) and drive optional subsystems to shed memory — WITHOUT ever changing\n        // render resolution (that is deliberately pinned elsewhere).\n        const devMem = (typeof navigator !== 'undefined' && Number.isFinite(navigator.deviceMemory))\n            ? navigator.deviceMemory : (mobile ? 4 : 8);\n        // Soft = start shedding; hard = maximum shed. Scale with reported RAM but\n        // stay conservative on mobile where the tab budget is a fraction of RAM.\n        this.memSoftMB = mobile ? 250 : Math.max(900, Math.min(2400, devMem * 200));\n        this.memHardMB = mobile ? 360 : Math.max(1400, Math.min(3600, devMem * 320));\n        this._memPressureEma = 0;\n        this._memEmaAlpha = 0.25;\n        this._lastMemPressureApplied = -1;\n\n        // Optional subsystems the governor modulates under memory pressure.\n        this._labelSystem = null;\n        this._geoJsonLayer = null;\n        this._photogrammetry = null;\n        this._elevationClient = null;\n\n        // State\n        this._triTree = null;\n        this._overlaySubsystem = null;\n        this._buildingOverlays = [];\n        this._throttled = false;\n        this._emergencyActive = false;\n        this._savedBudgets = null;\n        this._tickIntervalMs = 500;\n        this._lastTickMs = 0;\n        // Consecutive ticks under soft budget before restoring budgets\n        this._recoverTicks = 0;\n        this._recoverThreshold = 6; // ~3 s of healthy ticks\n\n        // Snapshot for diagnostics\n        this.lastSnapshot = null;\n    }\n\n    setTriTree(triTree) { this._triTree = triTree; }\n    setOverlaySubsystem(sys) { this._overlaySubsystem = sys; }\n    addBuildingOverlay(bo) { if (bo) this._buildingOverlays.push(bo); }\n    setLabelSystem(sys) { this._labelSystem = sys || null; }\n    setGeoJsonLayer(layer) { this._geoJsonLayer = layer || null; }\n    setPhotogrammetryManager(mgr) { this._photogrammetry = mgr || null; }\n    setElevationClient(client) { this._elevationClient = client || null; }\n\n    /**\n     * Read JS heap and drive optional subsystems to shed memory. Called from\n     * tick(). Produces a smoothed pressure level in [0,1] (0 = healthy,\n     * 1 = at/over the hard budget) and forwards it to labels / geojson /\n     * elevation, and terrain. Photoreal pressure is combined with GPU counts in\n     * tick(), while the application's global render scale remains untouched.\n     */\n    _updateMemoryPressure() {\n        const mem = (typeof performance !== 'undefined') ? performance.memory : null;\n        const heapMB = mem && Number.isFinite(mem.usedJSHeapSize)\n            ? mem.usedJSHeapSize / 1048576\n            : null;\n        const span = Math.max(1, this.memHardMB - this.memSoftMB);\n        const heapPressure = Number.isFinite(heapMB)\n            ? Math.min(1, Math.max(0, (heapMB - this.memSoftMB) / span))\n            : 0;\n        // Safari does not expose performance.memory. Elevation records are a\n        // substantial object cache with a known ceiling, so use occupancy as\n        // a portable signal rather than silently disabling all memory shedding\n        // on the very phones it is meant to protect.\n        const elevationStats = this._elevationClient?.getStats?.() || null;\n        const elevationCap = elevationStats?.memoryBudgetBaseline\n            || elevationStats?.maxVertexRecords\n            || this._elevationClient?.maxVertexRecords\n            || 0;\n        const elevationRatio = elevationCap > 0\n            ? (Number(elevationStats?.totalVertices) || 0) / elevationCap\n            : 0;\n        const elevationPressure = Math.min(1, Math.max(0, (elevationRatio - 0.65) / 0.35));\n        const raw = Math.max(heapPressure, elevationPressure);\n        // EMA so a single spike does not thrash caps.\n        this._memPressureEma += (raw - this._memPressureEma) * this._memEmaAlpha;\n        const level = this._memPressureEma;\n\n        // Only push when it moves meaningfully (avoid per-tick churn).\n        if (Math.abs(level - this._lastMemPressureApplied) < 0.03\n            && !(level === 0 && this._lastMemPressureApplied > 0)) {\n            return;\n        }\n        this._lastMemPressureApplied = level;\n\n        this._labelSystem?.applyMemoryPressure?.(level);\n        this._geoJsonLayer?.applyMemoryPressure?.(level);\n        this._elevationClient?.applyMemoryPressure?.(level);\n        this._triTree?.applyMemoryPressure?.(level);\n        this._memorySnapshot = {\n            heapMB,\n            heapPressure,\n            elevationRecords: elevationStats?.totalVertices ?? null,\n            elevationCap: elevationCap || null,\n            elevationPressure,\n            level,\n        };\n    }\n\n    /**\n     * Call once per frame after renderer.render().\n     * Uses renderer.info which Three.js populates during render.\n     */\n    tick(dt) {\n        const now = performance.now();\n        if (now - this._lastTickMs < this._tickIntervalMs) return;\n        this._lastTickMs = now;\n\n        // Memory-pressure tier (independent of the GPU-count budgets below).\n        this._updateMemoryPressure();\n\n        const info = this.renderer?.info;\n        if (!info) {\n            this._photogrammetry?.applyMemoryPressure?.(this._memPressureEma);\n            return;\n        }\n\n        const triangles = info.render?.triangles ?? 0;\n        const calls = info.render?.calls ?? 0;\n        const geometries = info.memory?.geometries ?? 0;\n        const textures = info.memory?.textures ?? 0;\n\n        this.lastSnapshot = { triangles, calls, geometries, textures, ts: now };\n\n        const overTriHard = triangles > this.triangleBudget;\n        const overTriSoft = triangles > this.triangleSoftBudget;\n        const overDrawCalls = calls > this.drawCallBudget;\n        const overGeometry = geometries > this.geometryBudget;\n        const overTextures = textures > this.textureBudget;\n        const trianglePressure = Math.min(1, Math.max(0,\n            (triangles - this.triangleSoftBudget)\n                / Math.max(1, this.triangleBudget - this.triangleSoftBudget)\n        ));\n        const drawPressure = Math.min(1, Math.max(0,\n            (calls - this.drawCallBudget * 0.7) / Math.max(1, this.drawCallBudget * 0.3)\n        ));\n        const texturePressure = Math.min(1, Math.max(0,\n            (textures - this.textureBudget * 0.75) / Math.max(1, this.textureBudget * 0.25)\n        ));\n        const scenePressure = Math.max(trianglePressure, drawPressure, texturePressure);\n        const effectivePhotorealPressure = Math.max(this._memPressureEma, scenePressure);\n        this._photogrammetry?.applyMemoryPressure?.(effectivePhotorealPressure);\n        this.lastSnapshot.scenePressure = scenePressure;\n        this.lastSnapshot.photorealPressure = effectivePhotorealPressure;\n\n        const needsEmergency = overTriHard || overDrawCalls;\n        const needsThrottle = overTriSoft || overGeometry || overTextures;\n\n        if (needsEmergency) {\n            this._recoverTicks = 0;\n            this._applyEmergency();\n        } else if (needsThrottle) {\n            this._recoverTicks = 0;\n            this._applyThrottle();\n        } else {\n            this._recoverTicks++;\n            if (this._recoverTicks >= this._recoverThreshold) {\n                this._releaseBudgets();\n            }\n        }\n    }\n\n    _saveBudgets() {\n        if (this._savedBudgets || !this._triTree) return;\n        this._savedBudgets = {\n            tileBudget: this._triTree.tileBudget,\n            splitBudget: this._triTree.splitBudget,\n            mergeBudget: this._triTree.mergeBudget,\n            imageryBudgetPerFrame: this._triTree.imageryBudgetPerFrame,\n        };\n    }\n\n    _applyEmergency() {\n        if (!this._triTree) return;\n        this._saveBudgets();\n        this._emergencyActive = true;\n        this._throttled = true;\n\n        const tt = this._triTree;\n        // Reduce tile budget to force merges\n        tt.tileBudget = Math.max(\n            this._emergencyTileBudgetFloor,\n            Math.floor(tt.tileBudget * this._emergencyTileBudgetScale)\n        );\n        // Halt splitting\n        tt.splitBudget = 0;\n        // Boost merges\n        tt.mergeBudget = Math.max(tt.mergeBudget, Math.ceil(\n            (this._savedBudgets?.mergeBudget ?? tt.mergeBudget) * this._emergencyMergeBudgetScale\n        ));\n        // Reduce imagery budget\n        tt.imageryBudgetPerFrame = Math.max(\n            tt.imageryMinBudget ?? 4,\n            Math.floor(tt.imageryBudgetPerFrame * 0.5)\n        );\n\n        // Reduce building overlay features if available\n        for (const bo of this._buildingOverlays) {\n            if (bo && typeof bo.maxFeatures === 'number') {\n                bo.maxFeatures = Math.max(40, Math.floor(bo.maxFeatures * 0.75));\n            }\n        }\n    }\n\n    _applyThrottle() {\n        if (!this._triTree) return;\n        this._saveBudgets();\n        this._throttled = true;\n\n        const tt = this._triTree;\n        // Reduce split rate but don't halt\n        tt.splitBudget = Math.max(4, Math.floor(\n            (this._savedBudgets?.splitBudget ?? tt.splitBudget) * 0.5\n        ));\n    }\n\n    _releaseBudgets() {\n        if (!this._throttled || !this._savedBudgets || !this._triTree) return;\n        const tt = this._triTree;\n        const saved = this._savedBudgets;\n        // Gradually restore — lerp back toward saved values\n        tt.tileBudget = Math.min(saved.tileBudget,\n            tt.tileBudget + Math.max(1, Math.ceil((saved.tileBudget - tt.tileBudget) * 0.15)));\n        tt.splitBudget = Math.min(saved.splitBudget,\n            tt.splitBudget + Math.max(1, Math.ceil((saved.splitBudget - tt.splitBudget) * 0.25)));\n        tt.mergeBudget = saved.mergeBudget;\n        tt.imageryBudgetPerFrame = Math.min(saved.imageryBudgetPerFrame,\n            tt.imageryBudgetPerFrame + Math.max(1, Math.ceil(\n                (saved.imageryBudgetPerFrame - tt.imageryBudgetPerFrame) * 0.2)));\n\n        // Fully restored?\n        if (tt.tileBudget >= saved.tileBudget &&\n            tt.splitBudget >= saved.splitBudget &&\n            tt.imageryBudgetPerFrame >= saved.imageryBudgetPerFrame) {\n            this._throttled = false;\n            this._emergencyActive = false;\n            this._savedBudgets = null;\n        }\n    }\n\n    getStats() {\n        return {\n            throttled: this._throttled,\n            emergencyActive: this._emergencyActive,\n            ...(this.lastSnapshot || {}),\n            memory: this._memorySnapshot || null,\n            triangleBudget: this.triangleBudget,\n            triangleSoftBudget: this.triangleSoftBudget,\n            drawCallBudget: this.drawCallBudget,\n        };\n    }\n}\n","/**\n * PhotoAtmosphereEffect\n *\n * Compatibility owner for legacy per-material atmosphere effects and the\n * active lean-r185 photoreal surface uniform contract.\n *\n * Shares uniform objects by reference from the TriTree earth material,\n * so all tuneable changes (ConfigSidebar sliders) automatically apply\n * to both tile systems without extra wiring.\n *\n * Effects:\n *   1. Night-side darkening (sun-dot driven, always active at all altitudes)\n *   2. Simple orbit clouds (equirect overlay + shadows, orbit-blended)\n *   3. Light pollution (Web Mercator emissive, orbit-blended)\n *   4. Animated ocean normals, Fresnel and sun glint (global water mask)\n *\n * Production tiles consume only getPhotorealSurfaceUniforms(): deep-water\n * diffuse albedo is resolved before Takram's deferred physical sun/sky pass.\n * This avoids duplicating atmosphere, cloud, and tone-mapping work in every\n * provider material. applyToScene() remains a rollback/diagnostic path.\n *\n * Chaining: TilesFadePlugin modifies shaders via onBeforeCompile using\n * regexes that break up `void main() {` across lines. We use regex\n * lookahead `(?=void\\\\s+main\\\\s*\\\\()` to inject GLSL pars before\n * `void main` regardless of how previous plugins reformatted it.\n */\n\nimport * as THREE from 'three';\nimport { wrapCloudMapSampling } from '../../modules/cloud-map-sampling.js';\nimport { waterCoverageUniforms } from '../../modules/water-coverage.js';\nimport {\n  NIGHT_LIGHTS_EMISSION_DEFAULTS,\n  NIGHT_LIGHTS_SOURCE_SIGNAL_GLSL,\n  NIGHT_LIGHTS_SURFACE_CARRIER_GLSL,\n} from '../render/NightLightsEmissionContract.js';\nimport { NIGHT_LIGHTS_GEOGRAPHY_GLSL } from '../imagery/NightLightsGeoreference.js';\n\n// ───────────────────────────── Vertex Shader Injection ─────────────────────────────\n\nconst ATM_VERTEX_PARS = /* glsl */ `\n// PhotoAtmosphereEffect varyings & uniforms\nvarying vec3 vAtmSurfaceDir;\nvarying vec3 vAtmLocalDir;\nvarying vec3 vAtmWorldPos;\nuniform mat4 uAtmPlanetInvMatrix;\n`;\n\nconst ATM_VERTEX_MAIN = /* glsl */ `\n// PhotoAtmosphereEffect: compute planet-local direction for fragment UVs.\n// TriTree tiles have mesh UVs (vUv) in geographic equirectangular coordinates\n// fixed to the planet surface. Photorealistic tile vertices are in world space\n// (via modelMatrix), which includes planet rotation (axial tilt + daily spin).\n// We undo the planet rotation here, then derive wrapped equirect UVs per\n// fragment so the longitude seam cannot interpolate across a tile triangle.\n{\n  vec4 _atmWp = modelMatrix * vec4(transformed, 1.0);\n  vAtmWorldPos = _atmWp.xyz;\n  vAtmSurfaceDir = normalize(_atmWp.xyz);\n  vec4 _atmLp = uAtmPlanetInvMatrix * _atmWp;\n  // Retain metres for geodetic latitude/elevation; cloud directions normalize\n  // in the fragment shader independently.\n  vAtmLocalDir = _atmLp.xyz;\n}\n`;\n\n// ───────────────────────────── Fragment Shader Injection ─────────────────────────────\n\nconst ATM_FRAGMENT_PARS = /* glsl */ `\n// PhotoAtmosphereEffect uniforms\nuniform vec3 uAtmSunDirection;\nuniform float uAtmPlanetRadius;\nuniform float uAtmNightMinBrightness;\nuniform vec3 uAtmNightAmbientColor;\nuniform float uAtmNightAmbientStrength;\nuniform float uAtmNightTransitionStart;\nuniform float uAtmNightTransitionEnd;\nuniform float uAtmNightPower;\nuniform sampler2D uAtmSpecularTexture;\nuniform float uAtmSpecularEnabled;\nuniform float uAtmSpecularStrength;\nuniform vec3 uAtmWaterColor;\nuniform float uAtmWaterOpacity;\nuniform sampler2D uAtmWaterNormalsTexture;\nuniform float uAtmWaterEnabled;\nuniform float uAtmSeaSurfaceActive;\nuniform float uAtmSeaLevelRadius;\nuniform vec3 uAtmSeaConfirmedCenter;\nuniform float uAtmSeaConfirmedRadius;\nuniform float uAtmWaterNormalScale;\nuniform float uAtmWaterDistortion;\nuniform float uAtmWaterSpecularStrength;\nuniform float uAtmWaterSpecularPower;\nuniform float uAtmWaterFresnelStrength;\nuniform float uAtmWaterFresnelPower;\nuniform float uAtmWaterUvScale;\nuniform float uAtmWaterTime;\nuniform sampler2D uAtmSimpleCloudsTexture;\nuniform float uAtmSimpleCloudsEnabled;\nuniform float uAtmSimpleCloudsOpacity;\nuniform float uAtmSimpleCloudsShadowStrength;\nuniform float uAtmSimpleCloudsShadowHeight;\nuniform float uAtmSimpleCloudsBlendMode;\nuniform float uAtmSimpleCloudsAlphaThreshold;\nuniform float uAtmSimpleCloudsAlphaSoftness;\nuniform vec3 uAtmSimpleCloudsNightAirglowColor;\nuniform float uAtmSimpleCloudsNightAirglowStrength;\nuniform sampler2D uAtmLightPollutionTexture;\nuniform sampler2D uAtmLightPollutionDetailTexture;\nuniform float uAtmLightPollutionDetailEnabled;\nuniform vec4 uAtmLightPollutionDetailBounds;\nuniform float uAtmLightPollutionEnabled;\nuniform float uAtmLightPollutionIntensity;\nuniform float uAtmLightPollutionMapGain;\nuniform float uAtmLightPollutionSurfaceIntensityScale;\nuniform float uAtmLightPollutionEmissionThreshold;\nuniform float uAtmLightPollutionEmissionSoftness;\nuniform float uAtmLightPollutionEmissionPower;\nuniform float uAtmLightPollutionEmissionBlueSuppression;\nuniform vec3 uAtmLightPollutionColor;\nuniform float uAtmLightPollutionMercator;\nuniform vec2 uAtmLightPollutionUvOffset;\nuniform vec2 uAtmLightPollutionUvScale;\nuniform mat4 uAtmPlanetInvMatrix;\n\n// PhotoAtmosphereEffect varyings\nvarying vec3 vAtmSurfaceDir;\nvarying vec3 vAtmLocalDir;\nvarying vec3 vAtmWorldPos;\n\nfloat atmResolveCloudMask(vec4 cs) {\n  float coverage = clamp(cs.a, 0.0, 1.0);\n  float black = clamp(uAtmSimpleCloudsAlphaThreshold, 0.0, 0.95);\n  float contrast = 1.0 + clamp(uAtmSimpleCloudsAlphaSoftness, 0.0, 1.0) * 6.0;\n  float t = clamp((coverage - black) / (1.0 - black + 1e-4), 0.0, 1.0);\n  return pow(t, contrast);\n}\n\nvec2 atmDirToEquirectUv(vec3 d) {\n  vec3 n = normalize(d);\n  float lon = atan(n.x, n.z);\n  float lat = asin(clamp(n.y, -1.0, 1.0));\n  return vec2(\n    fract(lon / (2.0 * 3.14159265) + 0.5 + 1.0),\n    clamp(0.5 - lat / 3.14159265, 0.0, 1.0)\n  );\n}\n\n${NIGHT_LIGHTS_GEOGRAPHY_GLSL}\n\nvec4 atmSampleLightPollution(vec3 planetPosition) {\n  vec2 equirectUv = ncaNightLightsGeographicUv(planetPosition);\n  vec2 sourceUv = equirectUv;\n  if (uAtmLightPollutionMercator > 0.5) {\n    float latitude = (0.5 - equirectUv.y) * 3.14159265;\n    latitude = clamp(latitude, -1.4844222297, 1.4844222297);\n    float sinLatitude = sin(latitude);\n    sourceUv.y = clamp(\n      0.5 - 0.25 * log((1.0 + sinLatitude) / (1.0 - sinLatitude)) / 3.14159265,\n      0.0,\n      1.0\n    );\n  }\n  sourceUv = (sourceUv - 0.5) * uAtmLightPollutionUvScale\n    + 0.5\n    + uAtmLightPollutionUvOffset;\n  sourceUv.x = fract(sourceUv.x + 1.0);\n  sourceUv.y = clamp(sourceUv.y, 0.0, 1.0);\n\n  vec4 lightSample = texture2D(uAtmLightPollutionTexture, sourceUv);\n  if (uAtmLightPollutionDetailEnabled < 0.5) return lightSample;\n  float wrappedDeltaU = fract(\n    sourceUv.x - uAtmLightPollutionDetailBounds.x + 0.5\n  ) - 0.5;\n  vec2 detailUv = vec2(\n    wrappedDeltaU / max(uAtmLightPollutionDetailBounds.z, 1e-6) + 0.5,\n    (sourceUv.y - uAtmLightPollutionDetailBounds.y)\n      / max(uAtmLightPollutionDetailBounds.w, 1e-6)\n  );\n  float detailInside = step(0.0, detailUv.x)\n    * step(detailUv.x, 1.0)\n    * step(0.0, detailUv.y)\n    * step(detailUv.y, 1.0);\n  vec4 detailSample = texture2D(\n    uAtmLightPollutionDetailTexture,\n    clamp(detailUv, vec2(0.0), vec2(1.0))\n  );\n  return mix(lightSample, detailSample, detailInside);\n}\n\n${NIGHT_LIGHTS_SOURCE_SIGNAL_GLSL}\n${NIGHT_LIGHTS_SURFACE_CARRIER_GLSL}\n\nfloat atmResolveLightEmission(float sourceSignal) {\n  float threshold = clamp(uAtmLightPollutionEmissionThreshold, 0.0, 0.95);\n  float softness = max(uAtmLightPollutionEmissionSoftness, 1e-4);\n  float normalizedSignal = clamp(\n    (sourceSignal - threshold) / max(1.0 - threshold, 1e-4),\n    0.0,\n    1.0\n  );\n  float emissionGate = smoothstep(\n    threshold,\n    min(1.0, threshold + softness),\n    sourceSignal\n  );\n  return pow(\n    normalizedSignal,\n    max(uAtmLightPollutionEmissionPower, 0.1)\n  ) * emissionGate;\n}\n\nfloat atmRaySphereHit(vec3 ro, vec3 rd, float r) {\n  float b = dot(ro, rd);\n  float c = dot(ro, ro) - r * r;\n  float h = b * b - c;\n  if (h < 0.0) return -1.0;\n  float s = sqrt(h);\n  float tN = -b - s;\n  float tF = -b + s;\n  if (tN > 0.0) return tN;\n  if (tF > 0.0) return tF;\n  return -1.0;\n}\n`;\n\nconst ATM_FRAGMENT_MAIN = /* glsl */ `\n// PhotoAtmosphereEffect: apply atmosphere effects to photorealistic tiles\n{\n  // Preserve the provider imagery before night attenuation. NASA source\n  // pixels emit from the same depth-tested fragment; they never replace it.\n  vec3 _providerAlbedo = max(gl_FragColor.rgb, vec3(0.0));\n  vec3 _surfDir = normalize(vAtmSurfaceDir);\n  vec3 _localDir = normalize(vAtmLocalDir);\n  vec2 _eqUv = atmDirToEquirectUv(_localDir);\n  // uAtmSunDirection is in world space (from TriTree earth material via\n  // getSunDirectionEcliptic → setSunDirection → shared uniform reference).\n  // vAtmSurfaceDir is also in world space (modelMatrix includes planet rotation).\n  // Both vectors are already in the same frame — no transform needed.\n  vec3 _sunDir = normalize(uAtmSunDirection);\n  float _sunDot = dot(_surfDir, _sunDir);\n  float _dayToNight = smoothstep(uAtmNightTransitionStart, uAtmNightTransitionEnd, _sunDot);\n  float _nightMask = pow(1.0 - _dayToNight, uAtmNightPower);\n  float _camDist = length(cameraPosition);\n  float _orbitBlend = smoothstep(uAtmPlanetRadius + 20000.0, uAtmPlanetRadius + 120000.0, _camDist);\n\n  // ── Night-side darkening + source-pixel emission at ground level ──\n  if (_orbitBlend <= 0.0) {\n    float _nightDarken = mix(1.0, uAtmNightMinBrightness, _nightMask);\n    gl_FragColor.rgb *= _nightDarken;\n    gl_FragColor.rgb = mix(\n      gl_FragColor.rgb,\n      uAtmNightAmbientColor,\n      _nightMask * uAtmNightAmbientStrength\n    );\n    if (uAtmLightPollutionEnabled > 0.5) {\n      vec4 _lightSample = atmSampleLightPollution(vAtmLocalDir);\n      vec3 _lightRgb = max(_lightSample.rgb, vec3(0.0));\n      float _sourceLuminance = max(max(_lightRgb.r, _lightRgb.g), _lightRgb.b);\n      float _sourceSignal = resolveNightLightsSourceSignal(\n        _lightRgb,\n        uAtmLightPollutionEmissionBlueSuppression\n      );\n      float _sourceRadiance = atmResolveLightEmission(_sourceSignal)\n        * uAtmLightPollutionMapGain;\n      vec3 _sourceChroma = _lightRgb / max(_sourceLuminance, 1e-4);\n      float _fadeStart = uAtmNightTransitionStart - 0.05;\n      float _fadeEnd = uAtmNightTransitionEnd + 0.02;\n      float _nightFactor = 1.0 - smoothstep(_fadeStart, _fadeEnd, _sunDot);\n      _nightFactor = pow(_nightFactor, 1.5);\n      vec3 _normal = normalize(cross(dFdx(vAtmWorldPos), dFdy(vAtmWorldPos)));\n      float _outwardEmission = 0.65\n        + 0.35 * clamp(abs(dot(_normal, _surfDir)), 0.0, 1.0);\n      vec3 _surfaceEmissionCarrier = resolveNightLightsSurfaceCarrier(\n        _providerAlbedo,\n        _sourceChroma,\n        uAtmLightPollutionColor,\n        ${NIGHT_LIGHTS_EMISSION_DEFAULTS.surfaceProviderColorMix}\n      );\n      vec3 _emittedRadiance = _surfaceEmissionCarrier\n        * uAtmLightPollutionIntensity\n        * _sourceRadiance;\n      gl_FragColor.rgb += _emittedRadiance\n        * _lightSample.a\n        * _nightFactor\n        * _outwardEmission\n        * uAtmLightPollutionSurfaceIntensityScale;\n    }\n  }\n\n  // ── Confirmed sea around the observer ──\n  // Where the vector ocean resolver confirms sea, tile surface at or below\n  // water level is the seabed proxy beneath the simulated surface, even when\n  // the coarse mask calls it land; islands above +0.3 m are untouched.\n  float _atmSeaConfirmed = (uAtmSeaSurfaceActive > 0.5 && uAtmSeaConfirmedRadius > 0.0\n      && distance(vAtmWorldPos, uAtmSeaConfirmedCenter) < uAtmSeaConfirmedRadius\n      && length(vAtmWorldPos) - uAtmSeaLevelRadius < 0.3) ? 1.0 : 0.0;\n#if defined( USE_LOGARITHMIC_DEPTH_BUFFER )\n  if (_atmSeaConfirmed > 0.5 && vIsPerspective != 0.0) gl_FragDepth = log2(vFragDepth + 4.0) * logDepthBufFC * 0.5;\n#endif\n\n  // ── Tile-integrated ocean surface ──\n  // Google photorealistic tiles keep their own GLTF materials, so the base\n  // earth water shader cannot shade them. Reuse its mask and two scrolling\n  // WaterMesh-style normal samples directly in each tile material. This keeps\n  // one surface and one draw call: there is no duplicate planet-sized water\n  // mesh competing with the photogrammetry depth buffer.\n  if (uAtmSpecularEnabled > 0.5) {\n    float _oceanMask = texture2D(uAtmSpecularTexture, _eqUv).r;\n    float _coastSafe = smoothstep(0.06, 0.45, _oceanMask);\n    if (_coastSafe > 0.001) {\n      vec3 _viewDirWater = normalize(cameraPosition - vAtmWorldPos);\n      float _openOcean = smoothstep(0.35, 0.85, _oceanMask);\n\n      vec3 _waterNormal = _surfDir;\n      if (uAtmWaterEnabled > 0.5) {\n        vec2 _waterUv = _eqUv * uAtmWaterUvScale;\n        vec2 _flowA = vec2(uAtmWaterTime * 0.018, uAtmWaterTime * 0.011);\n        vec2 _flowB = vec2(-uAtmWaterTime * 0.013, uAtmWaterTime * 0.021);\n        vec3 _wn1 = texture2D(uAtmWaterNormalsTexture, _waterUv + _flowA).xyz * 2.0 - 1.0;\n        vec3 _wn2 = texture2D(uAtmWaterNormalsTexture, _waterUv * 1.91 + _flowB).xyz * 2.0 - 1.0;\n        vec3 _wave = normalize(_wn1 + _wn2);\n        _wave.xy *= uAtmWaterNormalScale * uAtmWaterDistortion;\n\n        vec3 _axis = abs(_surfDir.y) > 0.98 ? vec3(1.0, 0.0, 0.0) : vec3(0.0, 1.0, 0.0);\n        vec3 _east = normalize(cross(_axis, _surfDir));\n        vec3 _north = normalize(cross(_surfDir, _east));\n        _waterNormal = normalize(\n          _surfDir + _east * _wave.x + _north * _wave.y + _surfDir * max(_wave.z, 0.0) * 0.12\n        );\n      }\n\n      float _ndv = clamp(dot(_viewDirWater, _waterNormal), 0.0, 1.0);\n      float _fresnelWater = pow(1.0 - _ndv, uAtmWaterFresnelPower) * uAtmWaterFresnelStrength;\n      vec3 _reflectedSun = reflect(-_sunDir, _waterNormal);\n      float _sunGlint = pow(max(dot(_reflectedSun, _viewDirWater), 0.0), uAtmWaterSpecularPower);\n      _sunGlint *= uAtmWaterSpecularStrength * _dayToNight;\n\n      float _oceanView = pow(1.0 - clamp(dot(_viewDirWater, _surfDir), 0.0, 1.0), 2.0);\n      vec3 _deepWater = uAtmWaterColor;\n      vec3 _shallowWater = clamp(uAtmWaterColor * 1.65 + vec3(0.0, 0.025, 0.04), 0.0, 1.0);\n      vec3 _oceanBody = mix(_deepWater, _shallowWater, clamp(_oceanView * 0.28 + _fresnelWater * 0.5, 0.0, 1.0));\n      // While the simulated sea surface is drawn here, the tile's flat sea\n      // keeps its satellite colour as a seabed proxy beneath it: no painted\n      // body or glint, and pushed 4 m down so wave troughs never expose it.\n      // Same mask threshold at which the sea mesh itself draws (0.45).\n      float _seaProxy = uAtmSeaSurfaceActive * smoothstep(0.4, 0.5, _oceanMask)\n        * (1.0 - smoothstep(2.0, 6.0, abs(length(vAtmWorldPos) - uAtmSeaLevelRadius)));\n      _seaProxy = max(_seaProxy, _atmSeaConfirmed);\n      float _oceanOpacity = _coastSafe * mix(uAtmWaterOpacity, 0.95, _openOcean) * (1.0 - _seaProxy);\n      gl_FragColor.rgb = mix(gl_FragColor.rgb, _oceanBody, clamp(_oceanOpacity, 0.0, 0.96));\n      gl_FragColor.rgb += vec3(1.0, 0.94, 0.78) * _sunGlint * _coastSafe * (1.0 - _seaProxy);\n#if defined( USE_LOGARITHMIC_DEPTH_BUFFER )\n      if (_seaProxy > 0.5 && vIsPerspective != 0.0) gl_FragDepth = log2(vFragDepth + 4.0) * logDepthBufFC * 0.5;\n#endif\n\n      // Underwater transmission, depth dimming and shafts are applied once,\n      // physically, by refactor/render/UnderwaterEffect.js.\n    }\n  }\n\n  // ── Orbit-altitude effects ──\n  if (_orbitBlend > 0.0) {\n    // ── 1. Simple orbit clouds (BEFORE night darkening) ──\n    if (uAtmSimpleCloudsEnabled > 0.5) {\n      vec4 _cloudSample = texture2D(uAtmSimpleCloudsTexture, _eqUv);\n      float _cloudMask = atmResolveCloudMask(_cloudSample);\n\n      // Cloud shadow projection\n      float _shadowMask = _cloudMask;\n      if (uAtmSimpleCloudsShadowStrength > 0.0 && _dayToNight > 0.0) {\n        float _cloudShellR = max(uAtmPlanetRadius + 1.0, uAtmPlanetRadius + max(uAtmSimpleCloudsShadowHeight, 0.0));\n        float _hitT = atmRaySphereHit(vAtmWorldPos, _sunDir, _cloudShellR);\n        if (_hitT > 0.0) {\n          vec3 _hitPos = vAtmWorldPos + _sunDir * _hitT;\n          vec4 _hitLocal = uAtmPlanetInvMatrix * vec4(_hitPos, 1.0);\n          vec2 _shadowUv = atmDirToEquirectUv(normalize(_hitLocal.xyz));\n          _shadowMask = atmResolveCloudMask(texture2D(uAtmSimpleCloudsTexture, _shadowUv));\n        }\n      }\n\n      float _cloudShadow = _shadowMask * uAtmSimpleCloudsShadowStrength * _orbitBlend * _dayToNight;\n      _cloudShadow = clamp(_cloudShadow, 0.0, 0.85);\n      gl_FragColor.rgb *= (1.0 - _cloudShadow);\n\n      float _cloudAlpha = _cloudMask * uAtmSimpleCloudsOpacity * _orbitBlend;\n      vec3 _nightCloudAirglow = uAtmSimpleCloudsNightAirglowColor\n        * uAtmSimpleCloudsNightAirglowStrength;\n      vec3 _cloudColor = mix(\n        _nightCloudAirglow,\n        vec3(1.0),\n        _dayToNight\n      );\n\n      if (uAtmSimpleCloudsBlendMode < 0.5) {\n        gl_FragColor.rgb = mix(gl_FragColor.rgb, _cloudColor, _cloudAlpha);\n      } else if (uAtmSimpleCloudsBlendMode < 1.5) {\n        gl_FragColor.rgb = clamp(gl_FragColor.rgb + _cloudColor * _cloudAlpha, 0.0, 1.0);\n      } else if (uAtmSimpleCloudsBlendMode < 2.5) {\n        vec3 _screenC = _cloudColor * _cloudAlpha;\n        gl_FragColor.rgb = 1.0 - (1.0 - gl_FragColor.rgb) * (1.0 - _screenC);\n      } else {\n        gl_FragColor.rgb *= (1.0 - _cloudAlpha);\n      }\n    }\n\n    // ── 2. Night darkening (AFTER clouds, so clouds get darkened too) ──\n    float _nightDarken = mix(1.0, uAtmNightMinBrightness, _nightMask);\n    gl_FragColor.rgb *= _nightDarken;\n    gl_FragColor.rgb = mix(gl_FragColor.rgb, uAtmNightAmbientColor, _nightMask * uAtmNightAmbientStrength);\n\n    // ── 3. NASA source-pixel radiance emitted by the real tile surface. ──\n    if (uAtmLightPollutionEnabled > 0.5) {\n      vec4 _lightSample = atmSampleLightPollution(vAtmLocalDir);\n      vec3 _lightRgb = max(_lightSample.rgb, vec3(0.0));\n      float _sourceLuminance = max(max(_lightRgb.r, _lightRgb.g), _lightRgb.b);\n      float _sourceSignal = resolveNightLightsSourceSignal(\n        _lightRgb,\n        uAtmLightPollutionEmissionBlueSuppression\n      );\n      float _sourceRadiance = atmResolveLightEmission(_sourceSignal)\n        * uAtmLightPollutionMapGain;\n      vec3 _sourceChroma = _lightRgb / max(_sourceLuminance, 1e-4);\n      float _fadeStart = uAtmNightTransitionStart - 0.05;\n      float _fadeEnd = uAtmNightTransitionEnd + 0.02;\n      float _nightFactor = 1.0 - smoothstep(_fadeStart, _fadeEnd, _sunDot);\n      _nightFactor = pow(_nightFactor, 1.5);\n\n      float _cloudOcclusion = 1.0;\n      if (uAtmSimpleCloudsEnabled > 0.5) {\n        float _cm = atmResolveCloudMask(texture2D(uAtmSimpleCloudsTexture, _eqUv));\n        _cloudOcclusion = 1.0 - clamp(_cm * uAtmSimpleCloudsOpacity, 0.0, 0.95);\n      }\n\n      vec3 _emittedRadiance = _sourceChroma\n        * uAtmLightPollutionColor\n        * uAtmLightPollutionIntensity\n        * _sourceRadiance;\n      gl_FragColor.rgb += _emittedRadiance\n        * _lightSample.a\n        * _orbitBlend\n        * _nightFactor\n        * _cloudOcclusion;\n    }\n\n    // ── 3. Specular ocean shine ──\n    if (uAtmSpecularEnabled > 0.5) {\n      float _specMask = texture2D(uAtmSpecularTexture, _eqUv).r;\n      vec3 _viewDir = normalize(cameraPosition - vAtmWorldPos);\n      vec3 _refl = reflect(-_sunDir, _surfDir);\n      float _specAngle = max(dot(_refl, _viewDir), 0.0);\n      float _spec = pow(_specAngle, 96.0);\n      float _fresnel = pow(1.0 - max(dot(_viewDir, _surfDir), 0.0), 5.0);\n      float _specular = _spec * _specMask * uAtmSpecularStrength * _dayToNight * _orbitBlend;\n      _specular *= mix(0.35, 1.0, _fresnel);\n      gl_FragColor.rgb += vec3(_specular);\n    }\n  }\n}\n`;\n\n// Regex that matches `void main(` with flexible whitespace — works even after\n// TilesFadePlugin breaks `void main() {` across lines.\nconst VOID_MAIN_RE = /(?=void\\s+main\\s*\\()/;\n\n// ───────────────────────────── Effect Class ─────────────────────────────\n\nexport class PhotoAtmosphereEffect {\n    /**\n     * @param {Object} earthMaterialUniforms  Uniform objects from the TriTree\n     *   earth material (createEarthMaterial). Shared by reference so that\n     *   ConfigSidebar tuneable updates automatically propagate.\n     */\n    constructor(earthMaterialUniforms) {\n        // Share uniform objects by reference — no copy, same { value } objects\n        this._uniforms = {\n            uAtmSunDirection:                earthMaterialUniforms.sunDirection,\n            uAtmPlanetRadius:                earthMaterialUniforms.planetRadius,\n            uAtmNightMinBrightness:          earthMaterialUniforms.nightMinBrightness,\n            uAtmNightAmbientColor:           earthMaterialUniforms.nightAmbientColor,\n            uAtmNightAmbientStrength:        earthMaterialUniforms.nightAmbientStrength,\n            uAtmNightTransitionStart:        earthMaterialUniforms.nightTransitionStart,\n            uAtmNightTransitionEnd:          earthMaterialUniforms.nightTransitionEnd,\n            uAtmNightPower:                  earthMaterialUniforms.nightPower,\n            uAtmSpecularTexture:             earthMaterialUniforms.specularTexture,\n            uAtmSpecularEnabled:             earthMaterialUniforms.specularEnabled,\n            uAtmSpecularStrength:            earthMaterialUniforms.specularStrength,\n            uAtmWaterColor:                  earthMaterialUniforms.waterColor,\n            uAtmWaterOpacity:                earthMaterialUniforms.waterOpacity,\n            uAtmWaterNormalsTexture:         earthMaterialUniforms.waterNormalsTexture,\n            uAtmWaterEnabled:                earthMaterialUniforms.waterEnabled,\n            uAtmSeaSurfaceActive:            earthMaterialUniforms.seaSurfaceActive,\n            uAtmSeaLevelRadius:              earthMaterialUniforms.seaLevelRadius,\n            uAtmSeaConfirmedCenter:          earthMaterialUniforms.seaConfirmedCenter,\n            uAtmSeaConfirmedRadius:          earthMaterialUniforms.seaConfirmedRadius,\n            uAtmWaterNormalScale:            earthMaterialUniforms.waterNormalScale,\n            uAtmWaterDistortion:             earthMaterialUniforms.waterDistortion,\n            uAtmWaterSpecularStrength:       earthMaterialUniforms.waterSpecularStrength,\n            uAtmWaterSpecularPower:          earthMaterialUniforms.waterSpecularPower,\n            uAtmWaterFresnelStrength:        earthMaterialUniforms.waterFresnelStrength,\n            uAtmWaterFresnelPower:           earthMaterialUniforms.waterFresnelPower,\n            uAtmWaterUvScale:                earthMaterialUniforms.waterUvScale,\n            uAtmWaterTime:                   earthMaterialUniforms.waterTime,\n            uAtmSimpleCloudsTexture:         earthMaterialUniforms.simpleCloudsTexture,\n            uAtmSimpleCloudsEnabled:         earthMaterialUniforms.simpleCloudsEnabled,\n            uAtmSimpleCloudsOpacity:         earthMaterialUniforms.simpleCloudsOpacity,\n            uAtmSimpleCloudsShadowStrength:  earthMaterialUniforms.simpleCloudsShadowStrength,\n            uAtmSimpleCloudsShadowHeight:    earthMaterialUniforms.simpleCloudsShadowHeight,\n            uAtmSimpleCloudsBlendMode:       earthMaterialUniforms.simpleCloudsBlendMode,\n            uAtmSimpleCloudsAlphaThreshold:  earthMaterialUniforms.simpleCloudsAlphaThreshold,\n            uAtmSimpleCloudsAlphaSoftness:   earthMaterialUniforms.simpleCloudsAlphaSoftness,\n            uAtmSimpleCloudsNightAirglowColor: earthMaterialUniforms.simpleCloudsNightAirglowColor,\n            uAtmSimpleCloudsNightAirglowStrength: earthMaterialUniforms.simpleCloudsNightAirglowStrength,\n            uAtmLightPollutionTexture:       earthMaterialUniforms.lightPollutionTexture,\n            uAtmLightPollutionDetailTexture: earthMaterialUniforms.lightPollutionDetailTexture,\n            uAtmLightPollutionDetailEnabled: earthMaterialUniforms.lightPollutionDetailEnabled,\n            uAtmLightPollutionDetailBounds:  earthMaterialUniforms.lightPollutionDetailBounds,\n            uAtmLightPollutionEnabled:       earthMaterialUniforms.lightPollutionEnabled,\n            uAtmLightPollutionIntensity:     earthMaterialUniforms.lightPollutionIntensity,\n            uAtmLightPollutionMapGain:       earthMaterialUniforms.lightPollutionMapGain,\n            uAtmLightPollutionSurfaceIntensityScale:\n                earthMaterialUniforms.lightPollutionSurfaceIntensityScale,\n            uAtmLightPollutionEmissionThreshold: earthMaterialUniforms.lightPollutionEmissionThreshold,\n            uAtmLightPollutionEmissionSoftness: earthMaterialUniforms.lightPollutionEmissionSoftness,\n            uAtmLightPollutionEmissionPower: earthMaterialUniforms.lightPollutionEmissionPower,\n            uAtmLightPollutionEmissionBlueSuppression: earthMaterialUniforms.lightPollutionEmissionBlueSuppression,\n            uAtmLightPollutionColor:         earthMaterialUniforms.lightPollutionColor,\n            uAtmLightPollutionMercator:      earthMaterialUniforms.lightPollutionMercator,\n            uAtmLightPollutionUvOffset:      earthMaterialUniforms.lightPollutionUvOffset,\n            uAtmLightPollutionUvScale:       earthMaterialUniforms.lightPollutionUvScale,\n            // Owned uniform — updated per frame via update()\n            uAtmPlanetInvMatrix:             { value: new THREE.Matrix4() },\n        };\n        // Lean r185 photoreal materials consume only these albedo-class\n        // uniforms. Sun/sky irradiance, atmosphere, clouds, and tone mapping\n        // remain exclusively owned by the deferred Takram compositor.\n        this._photorealSurfaceUniforms = {\n            ...waterCoverageUniforms(earthMaterialUniforms),\n            uPhotoSunDirection: earthMaterialUniforms.sunDirection,\n            uPhotoPlanetInvMatrix: this._uniforms.uAtmPlanetInvMatrix,\n            uPhotoOceanMaskTexture: this._uniforms.uAtmSpecularTexture,\n            uPhotoOceanMaskEnabled: this._uniforms.uAtmSpecularEnabled,\n            uPhotoWaterEnabled: this._uniforms.uAtmWaterEnabled,\n            uPhotoWaterColor: this._uniforms.uAtmWaterColor,\n            uPhotoWaterOpacity: this._uniforms.uAtmWaterOpacity,\n        };\n        this._modifiedMaterials = new WeakSet();\n        this._modifiedCount = 0;\n    }\n\n    /**\n     * Shared uniform objects for the lean photoreal albedo shader.\n     * Returning the stable map preserves later texture/color updates without\n     * traversing or recompiling resident tile materials.\n     */\n    getPhotorealSurfaceUniforms() {\n        return this._photorealSurfaceUniforms;\n    }\n\n    /**\n     * Traverse a scene graph and inject atmosphere GLSL into all mesh materials.\n     * Safe to call multiple times — already-modified materials are skipped.\n     *\n     * @param {THREE.Object3D} scene  Root of the loaded tile model\n     */\n    applyToScene(scene) {\n        scene.traverse((child) => {\n            if (child.isMesh && child.material) {\n                const mats = Array.isArray(child.material)\n                    ? child.material\n                    : [child.material];\n                for (const mat of mats) {\n                    if (!this._modifiedMaterials.has(mat)) {\n                        try {\n                            this._modifyMaterial(mat);\n                            this._modifiedMaterials.add(mat);\n                            this._modifiedCount++;\n                        } catch (err) {\n                            console.warn('[PhotoAtmosphereEffect] Failed to modify material:', err);\n                        }\n                    }\n                }\n            }\n        });\n    }\n\n    /**\n     * Inject atmosphere shader code into a single material via onBeforeCompile.\n     * Chains with any existing onBeforeCompile (e.g. TilesFadePlugin).\n     *\n     * Uses regex lookahead to find `void main(` — this is necessary because\n     * TilesFadePlugin's regex replacement breaks `void main() {` across\n     * multiple lines, so a literal string match fails.\n     */\n    _modifyMaterial(material) {\n        const uniforms = this._uniforms;\n        const prevOBC = material.onBeforeCompile;\n        const prevCacheKey = material.customProgramCacheKey;\n\n        material.onBeforeCompile = function (shader, renderer) {\n            // Chain with previous (e.g. TilesFadePlugin)\n            if (prevOBC) prevOBC.call(this, shader, renderer);\n\n            // Merge atmosphere uniforms\n            Object.assign(shader.uniforms, uniforms);\n\n            // ── Vertex shader: inject pars before void main, code after project_vertex ──\n            const vsBefore = shader.vertexShader;\n            shader.vertexShader = shader.vertexShader.replace(\n                VOID_MAIN_RE,\n                ATM_VERTEX_PARS + '\\n'\n            );\n            shader.vertexShader = shader.vertexShader.replace(\n                '#include <project_vertex>',\n                '#include <project_vertex>\\n' + ATM_VERTEX_MAIN\n            );\n\n            // ── Fragment shader: inject pars before void main, effects before tonemapping ──\n            const fsBefore = shader.fragmentShader;\n            shader.fragmentShader = shader.fragmentShader.replace(\n                VOID_MAIN_RE,\n                ATM_FRAGMENT_PARS + '\\n'\n            );\n            shader.fragmentShader = shader.fragmentShader.replace(\n                '#include <tonemapping_fragment>',\n                ATM_FRAGMENT_MAIN + '\\n#include <tonemapping_fragment>'\n            );\n\n            // Verify replacements succeeded\n            if (shader.vertexShader === vsBefore) {\n                console.warn('[PhotoAtmosphereEffect] Vertex shader injection failed — void main not found');\n            }\n            if (shader.fragmentShader === fsBefore) {\n                console.warn('[PhotoAtmosphereEffect] Fragment shader injection failed — void main not found');\n            }\n            shader.fragmentShader = wrapCloudMapSampling(shader.fragmentShader, ['uAtmSimpleCloudsTexture']);\n        };\n\n        material.customProgramCacheKey = function () {\n            const base = prevCacheKey ? prevCacheKey.call(this) : '';\n            return base + '|photo-atm-v10-periodic-clouds';\n        };\n\n        material.needsUpdate = true;\n    }\n\n    /**\n     * Call each frame to update the planet inverse matrix uniform.\n     * This matrix undoes the planet's world rotation (axial tilt + daily spin)\n     * so UV computation produces geographic coordinates matching TriTree's vUv.\n     *\n     * @param {THREE.Object3D} planetGroup  The planet group (triTree.group)\n     */\n    update(planetGroup) {\n        if (planetGroup) {\n            planetGroup.updateWorldMatrix(true, false);\n            this._uniforms.uAtmPlanetInvMatrix.value\n                .copy(planetGroup.matrixWorld)\n                .invert();\n        }\n    }\n\n    dispose() {\n        this._modifiedMaterials = new WeakSet();\n        this._modifiedCount = 0;\n    }\n}\n","const WARM_SESSION_PREFIX = 'noclip.photo-warm-session.v1';\nconst WARM_SESSION_MAX_AGE_MS = 15 * 60 * 1000;\nconst WARM_SESSION_EXPIRY_MARGIN_MS = 30 * 1000;\nconst SNAPSHOT_MESSAGE_TYPE = 'NOCLIP_PHOTO_TILE_SNAPSHOT';\nconst PROFILE_MESSAGE_TYPE = 'NOCLIP_PHOTO_TILE_PROFILE';\nconst MAX_SNAPSHOT_URLS_DESKTOP = 240;\nconst MAX_SNAPSHOT_URLS_MOBILE = 96;\n\nconst usedWarmSessionScopes = new Set();\n\nconst getStorage = (storage) => {\n    if (storage) return storage;\n    try {\n        return typeof sessionStorage !== 'undefined' ? sessionStorage : null;\n    } catch {\n        return null;\n    }\n};\n\nconst normalizeProvider = (provider) => (\n    provider === 'google' || provider === 'cesiumIon' ? provider : null\n);\n\nconst sessionScopeKey = (provider, credentialId = null) => {\n    const normalizedProvider = normalizeProvider(provider);\n    if (!normalizedProvider) return null;\n    const owner = credentialId ? `credential:${credentialId}` : 'community';\n    return `${WARM_SESSION_PREFIX}:${normalizedProvider}:${owner}`;\n};\n\nconst parseExpiry = (session) => {\n    const value = session?.expires_at ?? session?.expiresAt;\n    const expiry = typeof value === 'number' ? value : Date.parse(value || '');\n    return Number.isFinite(expiry) ? expiry : null;\n};\n\nconst isExpectedProxyRoot = (rootUrl, provider) => {\n    if (typeof rootUrl !== 'string' || !rootUrl) return false;\n    try {\n        const url = new URL(rootUrl, 'https://noclip.invalid');\n        const pathProvider = provider === 'cesiumIon' ? 'cesium' : provider;\n        return new RegExp(`^/api/earth/photorealistic/${pathProvider}/sessions/[^/]+/root\\\\.json$`)\n            .test(url.pathname);\n    } catch {\n        return false;\n    }\n};\n\n/**\n * Reuse one still-live photoreal session across a same-tab reload. This keeps\n * proxy URLs stable so CacheStorage can satisfy the exact tile requests, and\n * preserves a direct Cesium endpoint for the same reason. SessionStorage is\n * deliberately tab-scoped and each scope owns one replacing record.\n */\nexport function takeWarmPhotorealSession({\n    provider,\n    credentialId = null,\n    storage = null,\n    now = Date.now(),\n} = {}) {\n    const key = sessionScopeKey(provider, credentialId);\n    const target = getStorage(storage);\n    if (!key || !target || usedWarmSessionScopes.has(key)) return null;\n    usedWarmSessionScopes.add(key);\n\n    let record;\n    try {\n        record = JSON.parse(target.getItem(key) || 'null');\n    } catch {\n        record = null;\n    }\n    const normalizedProvider = normalizeProvider(provider);\n    const storedAt = Number(record?.storedAt);\n    const expiresAt = Number(record?.expiresAt);\n    const session = record?.session;\n    const valid = record?.provider === normalizedProvider\n        && session && typeof session === 'object'\n        && Number.isFinite(storedAt)\n        && now - storedAt >= 0\n        && now - storedAt <= WARM_SESSION_MAX_AGE_MS\n        && (!Number.isFinite(expiresAt) || expiresAt - now > WARM_SESSION_EXPIRY_MARGIN_MS)\n        && isExpectedProxyRoot(session.rootUrl, normalizedProvider);\n    if (valid) return session;\n\n    try { target.removeItem(key); } catch { /* storage may be disabled */ }\n    return null;\n}\n\nexport function rememberWarmPhotorealSession(session, {\n    provider,\n    credentialId = null,\n    storage = null,\n    now = Date.now(),\n} = {}) {\n    const key = sessionScopeKey(provider, credentialId);\n    const target = getStorage(storage);\n    const normalizedProvider = normalizeProvider(provider);\n    if (!key || !target || !session || typeof session !== 'object'\n        || !isExpectedProxyRoot(session.rootUrl, normalizedProvider)) return false;\n\n    const expiresAt = parseExpiry(session);\n    if (Number.isFinite(expiresAt) && expiresAt - now <= WARM_SESSION_EXPIRY_MARGIN_MS) {\n        return false;\n    }\n\n    // Retain only fields consumed by the existing loader. This avoids copying\n    // account/session response metadata into an accumulating client store.\n    const compactSession = {\n        rootUrl: session.rootUrl,\n        endpoint: session.endpoint && typeof session.endpoint === 'object'\n            ? session.endpoint\n            : undefined,\n        expires_at: session.expires_at ?? session.expiresAt ?? undefined,\n    };\n    try {\n        target.setItem(key, JSON.stringify({\n            provider: normalizedProvider,\n            storedAt: now,\n            expiresAt,\n            session: compactSession,\n        }));\n        return true;\n    } catch {\n        return false;\n    }\n}\n\nexport function reportPhotorealCacheProfile({ mobile = false } = {}) {\n    try {\n        navigator.serviceWorker?.controller?.postMessage?.({\n            type: PROFILE_MESSAGE_TYPE,\n            mobile: mobile === true,\n            deviceMemory: Number(navigator.deviceMemory) || null,\n        });\n        return true;\n    } catch {\n        return false;\n    }\n}\n\nexport function reportVisiblePhotorealTiles(urls, { mobile = false } = {}) {\n    const controller = typeof navigator !== 'undefined'\n        ? navigator.serviceWorker?.controller\n        : null;\n    if (!controller?.postMessage || !urls) return false;\n    const limit = mobile ? MAX_SNAPSHOT_URLS_MOBILE : MAX_SNAPSHOT_URLS_DESKTOP;\n    const compact = [];\n    const seen = new Set();\n    for (const value of urls) {\n        if (typeof value !== 'string' || !value || seen.has(value)) continue;\n        seen.add(value);\n        compact.push(value);\n        if (compact.length >= limit) break;\n    }\n    try {\n        controller.postMessage({\n            type: SNAPSHOT_MESSAGE_TYPE,\n            mobile: mobile === true,\n            urls: compact,\n        });\n        return true;\n    } catch {\n        return false;\n    }\n}\n\nexport const PHOTOREAL_WARM_CACHE_CONTRACT = Object.freeze({\n    sessionMaxAgeMs: WARM_SESSION_MAX_AGE_MS,\n    maxSnapshotUrlsDesktop: MAX_SNAPSHOT_URLS_DESKTOP,\n    maxSnapshotUrlsMobile: MAX_SNAPSHOT_URLS_MOBILE,\n    snapshotMessageType: SNAPSHOT_MESSAGE_TYPE,\n    profileMessageType: PROFILE_MESSAGE_TYPE,\n});\n","import * as THREE from 'three';\nimport { MOON_RADIUS_M } from '../../modules/constants.js';\nimport { resolveSceneRuntimeResource } from '../scene/SceneRuntimeResources.js';\nimport { lunarSurfacePoint } from './LunarFrame.js';\n\nexport const LUNAR_LABEL_LIMIT = 96;\nconst TYPE = 'lunar-feature';\nconst yieldTask = () => new Promise(resolve => setTimeout(resolve, 0));\n\nexport function validateLunarCatalog(data) {\n  if (data?.schema !== 'noclip.lunar-features/1' || data.body !== 'luna'\n      || data.radiusM !== MOON_RADIUS_M || !Array.isArray(data.types)\n      || !Array.isArray(data.features) || data.features.length > 12000) throw new Error('Invalid lunar catalogue');\n  const ids = new Set();\n  for (const row of data.features) {\n    if (!Array.isArray(row) || row.length !== 8 || !/^\\d+$/.test(row[0]) || ids.has(row[0])\n        || typeof row[1] !== 'string' || !row[1] || row[1].length > 160\n        || !row.slice(2).every(Number.isFinite) || Math.abs(row[2]) > 90 || Math.abs(row[3]) > 180\n        || row[4] < 0 || !Number.isInteger(row[5]) || typeof data.types[row[5]] !== 'string'\n        || Math.abs(row[6]) > 30000 || Math.abs(row[7]) > 30000) throw new Error('Invalid lunar feature');\n    ids.add(row[0]);\n  }\n  return data;\n}\n\n/** Pure bounded top-N selector. All catalogue entries remain eligible at closer LOD. */\nexport function scoreLunarFeature(row, localCamera, localToClip, pixelsPerRadian, heightColumn, scratch) {\n  const point = lunarSurfacePoint(row[2], row[3], MOON_RADIUS_M + row[heightColumn] + 20, scratch.point);\n  // Radial tangent horizon in Moon-local doubles, never origin-centred Earth.\n  if (point.dot(localCamera) < point.lengthSq()) return null;\n  const distance = point.distanceTo(localCamera);\n  const pixels = Math.max(row[4] * 1000, 300) / Math.max(1, distance) * pixelsPerRadian;\n  if (pixels < 10) return null;\n  scratch.ndc.copy(point).applyMatrix4(localToClip);\n  const p = scratch.ndc;\n  if (p.z < -1 || p.z > 1 || Math.abs(p.x) > 1.08 || Math.abs(p.y) > 1.08) return null;\n  return Math.min(1500, pixels) / (1 + .25 * (p.x * p.x + p.y * p.y));\n}\n\n/** One canonical label producer; the existing accepted scene frame supplies cadence. */\nexport class LunarFeatureLabels {\n  constructor({ moonSystem, labels, fetchImpl = globalThis.fetch }) {\n    this.moon = moonSystem; this.labels = labels; this.fetch = (...args) => fetchImpl(...args);\n    this.group = new THREE.Group(); this.group.name = 'LunarFeatures'; this.group.visible = false;\n    moonSystem.moonMesh.add(this.group);\n    this.handles = new Map(); this.catalog = null; this.epoch = 0; this.active = false;\n    this._camera = new THREE.Vector3(); this._clip = new THREE.Matrix4(); this._inverse = new THREE.Matrix4();\n    this._scratch = { point: new THREE.Vector3(), ndc: new THREE.Vector3() };\n    this._lastPose = new THREE.Matrix4(); this._lastProjection = new THREE.Matrix4();\n  }\n  async _load(epoch) {\n    if (this.catalog) return this.catalog;\n    this.abort = new AbortController();\n    const response = await this.fetch(resolveSceneRuntimeResource('/data/lunar-features.json'), { signal: this.abort.signal });\n    if (!response.ok) throw new Error('Lunar catalogue unavailable');\n    const bytes = new Uint8Array(await response.arrayBuffer());\n    if (bytes.byteLength > 1024 * 1024) throw new Error('Lunar catalogue exceeds admission limit');\n    if (this.disposed || this.epoch !== epoch) return null;\n    const data = JSON.parse(new TextDecoder().decode(bytes));\n    // Validate slices too: no nine-thousand-row construction in one frame.\n    if (!Array.isArray(data.features)) throw new Error('Invalid lunar catalogue');\n    const seen = new Set();\n    for (let start = 0; start < data.features.length; start += 256) {\n      if (this.disposed || this.epoch !== epoch) return null;\n      const part = validateLunarCatalog({ ...data, features: data.features.slice(start, start + 256) });\n      for (const row of part.features) { if (seen.has(row[0])) throw new Error('Duplicate lunar identity'); seen.add(row[0]); }\n      await yieldTask();\n    }\n    if (data.features.length > 12000) throw new Error('Lunar catalogue exceeds feature limit');\n    if (this.disposed || this.epoch !== epoch) return null;\n    this.catalog = data; return data;\n  }\n  update(camera, { focused = false, now = 0, height = 800 } = {}) {\n    const active = focused && this.labels.isTypeEnabled(TYPE);\n    this.group.visible = active;\n    if (!active) {\n      const wasActive = this.active; this.active = false;\n      if (wasActive) {\n        this.epoch++; this.abort?.abort(); this._lastHeight = null;\n        this.nextScan = 0; this.failed = false; void this._retire();\n      }\n      return;\n    }\n    this.active = true;\n    if (this.running || now < (this.nextScan || 0) || this.failed) return;\n    this.nextScan = now + 200;\n    camera.updateWorldMatrix(true, false); this.moon.moonMesh.updateWorldMatrix(true, false);\n    this._inverse.copy(this.moon.moonMesh.matrixWorld).invert();\n    const pose = new THREE.Matrix4().multiplyMatrices(this._inverse, camera.matrixWorld);\n    const heightColumn = this.moon._moonMaterial?.displacementMap\n      ? (this.moon._heightSize >= 4096 ? 7 : 6) : null;\n    if (this.catalog && pose.equals(this._lastPose) && camera.projectionMatrix.equals(this._lastProjection)\n        && heightColumn === this._lastHeightColumn && height === this._lastHeight) return;\n    this._lastPose.copy(pose); this._lastProjection.copy(camera.projectionMatrix);\n    this._lastHeightColumn = heightColumn; this._lastHeight = height;\n    this._camera.setFromMatrixPosition(pose);\n    this._clip.copy(camera.projectionMatrix).multiply(pose.invert());\n    const epoch = this.epoch;\n    this.running = this._scan(epoch, height, heightColumn).catch(error => {\n      if (!this.disposed && epoch === this.epoch && error.name !== 'AbortError') {\n        this.failed = true; console.warn('[LunarFeatures] Catalogue unavailable', error);\n      }\n    }).finally(() => { this.running = null; });\n  }\n  async _scan(epoch, height, heightColumn) {\n    const data = await this._load(epoch); if (!data) return;\n    const best = [], pixelsPerRadian = height * Math.abs(this._lastProjection.elements[5]) / 2;\n    for (let start = 0; start < data.features.length; start += 256) {\n      if (this.disposed || epoch !== this.epoch) return;\n      for (const row of data.features.slice(start, start + 256)) {\n        // No displacement map: use the actual undisplaced sphere.\n        const scored = heightColumn === null ? [...row.slice(0, 6), 0, 0] : row;\n        const score = scoreLunarFeature(scored, this._camera, this._clip, pixelsPerRadian, heightColumn ?? 6, this._scratch);\n        if (score === null) continue;\n        let i = best.findIndex(item => score > item.score);\n        if (i < 0) i = best.length;\n        if (i < LUNAR_LABEL_LIMIT) { best.splice(i, 0, { row, score }); if (best.length > LUNAR_LABEL_LIMIT) best.pop(); }\n      }\n      await yieldTask();\n    }\n    const wanted = new Set(best.map(item => item.row[0]));\n    let operations = 0;\n    for (const [id, handle] of this.handles) {\n      if (this.disposed || epoch !== this.epoch) return;\n      // Selection can change while a catalogue slice is yielded. Consult the\n      // shared modal now, never a selection captured before the async ranking.\n      if (!wanted.has(id) && !this.labels.isLabelDetailsOpen(handle)) {\n        this.labels.removeLabel(handle); this.handles.delete(id);\n        if (++operations % 16 === 0) await yieldTask();\n      }\n    }\n    for (const { row } of best) {\n      if (this.disposed || epoch !== this.epoch) return;\n      const radius = MOON_RADIUS_M + (heightColumn === null ? 0 : row[heightColumn]) + 20;\n      const position = lunarSurfacePoint(row[2], row[3], radius, this._scratch.point);\n      let handle = this.handles.get(row[0]);\n      if (handle) { handle.position.copy(position); handle.group.position.copy(position); continue; }\n      if (this.handles.size >= LUNAR_LABEL_LIMIT + 1) continue;\n      handle = this.labels.createLabel(row[1], { position, type: TYPE,\n        subText: data.types[row[5]], objectRadius: 80, maxDistance: 1e12, labelPriority: 12,\n        metadata: { celestial: true, body: 'luna', catalogId: row[0], typeLabel: data.types[row[5]],\n          lunarLatitude: row[2], lunarLongitude: row[3], diameterKm: row[4],\n          coordinateFrame: data.coordinates, source: data.source.name,\n          sourceUrl: `https://planetarynames.wr.usgs.gov/Feature/${row[0]}`, semanticNotice: data.source.notice },\n      });\n      this.handles.set(row[0], handle); this.group.add(handle.group);\n      if (++operations % 16 === 0) await yieldTask();\n    }\n  }\n  async _retire() {\n    const epoch = this.epoch;\n    for (const [id, handle] of this.handles) {\n      if (epoch !== this.epoch || this.active && !this.disposed) return;\n      this.labels.removeLabel(handle); this.handles.delete(id);\n      if (this.handles.size % 16 === 0) await yieldTask();\n    }\n  }\n  dispose() {\n    this.disposed = true; this.active = false; this.epoch++; this.abort?.abort();\n    this.group.visible = false; this.group.removeFromParent();\n    return this._retire();\n  }\n}\n","/**\n * PhotoBuildingLabels\n *\n * Lightweight building label system for photorealistic (Cesium/Google 3D) tile mode.\n * Instead of running the full BuildingOverlay pipeline, this module:\n *\n * 1. Fetches building centers, bounds, tags, and hover footprints from Overpass\n * 2. Raycasts downward onto the Cesium tile mesh to find actual roof height\n * 3. Places LabelSystem labels at the raycasted roof positions\n *\n * This avoids the alignment problem of OSM footprints vs photorealistic buildings —\n * the raycast hits the real geometry, so labels sit on actual rooftops.\n */\nimport * as THREE from 'three';\nimport { latLonToLocalDir, ellipsoidRadiusForLocalDir } from '../../modules/geometry-utils.js';\nimport { PLANET_RADIUS } from '../../modules/constants.js';\nimport {\n  extractOsmContactFields,\n  fetchBuildingsForLabels,\n  formatOsmBusinessCategory,\n} from '../../modules/geocoding-service.js';\nimport { terrainSurfaceChangesAffectLatLon } from '../scene/TerrainSurfaceChange.js';\nimport { getLabelSystem } from './LabelSystem.js';\n\nconst DEFAULT_RADIUS_M = 1200;\nconst DEFAULT_REFRESH_DISTANCE_M = 500;\nconst DEFAULT_MAX_BUILDINGS = 120;\nconst DEFAULT_RAYCAST_BUDGET = 6; // max raycasts per frame\nconst MIN_FETCH_INTERVAL_MS = 30000;\nconst OVERPASS_FETCH_TIMEOUT_MS = 9000;\n\n// Scratch objects — never allocate in hot path\nconst _rayOrigin = new THREE.Vector3();\nconst _rayDir = new THREE.Vector3();\nconst _tmpDir = new THREE.Vector3();\nconst _tmpMatrix = new THREE.Matrix4();\nconst _tmpQuat = new THREE.Quaternion();\nconst _raycaster = new THREE.Raycaster();\n\n/**\n * Meters per degree at a given latitude (radians).\n */\nconst metersPerDegLat = (latRad) => 111132.954 - 559.822 * Math.cos(2 * latRad) + 1.175 * Math.cos(4 * latRad);\nconst metersPerDegLon = (latRad) => 111132.954 * Math.cos(latRad);\n\nexport class PhotoBuildingLabels {\n  constructor({ planetRadius, eventBus, surfaceController } = {}) {\n    this.planetRadius = Number.isFinite(planetRadius) ? planetRadius : PLANET_RADIUS;\n    this.eventBus = eventBus || null;\n    this.surfaceController = surfaceController || null;\n    this.enabled = false;\n    this.radiusM = DEFAULT_RADIUS_M;\n    this.refreshDistanceM = DEFAULT_REFRESH_DISTANCE_M;\n    this.maxBuildings = DEFAULT_MAX_BUILDINGS;\n    this.raycastBudget = DEFAULT_RAYCAST_BUDGET;\n\n    /** @type {THREE.Object3D|null} The Cesium tile group to raycast against */\n    this.tileGroup = null;\n\n    /** @type {THREE.Group|null} Parent group for label objects */\n    this.parentGroup = null;\n\n    this._labelSystem = null;\n    this._center = null; // { lat, lon }\n    this._inflight = false;\n    this._lastFetchMs = 0;\n    this._fetchController = null;\n\n    // Building entries: Map<string, { lat, lon, name, address, height, dir, labelHandle, raycasted }>\n    this._entries = new Map();\n    // Queue of entry keys needing raycast\n    this._raycastQueue = [];\n    // Hover label state\n    this._hoverHandle = null;\n    this._hoverKey = null;\n  }\n\n  // ── Lifecycle ──\n\n  /**\n   * Activate for photorealistic tile mode.\n   * @param {THREE.Object3D} tileGroup - The Cesium tile group to raycast\n   * @param {THREE.Group} parentGroup - Where to add label objects\n   */\n  activate(tileGroup, parentGroup) {\n    this.tileGroup = tileGroup;\n    this.parentGroup = parentGroup;\n    this.enabled = true;\n  }\n\n  /**\n   * Deactivate and clean up all labels.\n   */\n  deactivate() {\n    this.enabled = false;\n    this.tileGroup = null;\n    if (this._fetchController) {\n      this._fetchController.abort();\n      this._fetchController = null;\n    }\n    this._clearHoverLabel();\n    this._clearLabels();\n  }\n\n  /**\n   * Call each frame with observer position (world space).\n   * Handles refresh triggering and raycast budget.\n   */\n  update(observerPos) {\n    if (!this.enabled || !this.tileGroup) return;\n\n    // Check if we need a new fetch.\n    // observerPos is in WORLD space — must transform to planet-local first\n    // (triTree group has rotation transforms applied).\n    if (observerPos && observerPos.lengthSq && observerPos.lengthSq() > 0) {\n      const localObs = _tmpDir.copy(observerPos);\n      // Transform world → planet-local via tileGroup's parent inverse\n      if (this.tileGroup?.parent) {\n        this.tileGroup.parent.updateWorldMatrix(true, false);\n        const inv = _tmpMatrix.copy(this.tileGroup.parent.matrixWorld).invert();\n        localObs.applyMatrix4(inv);\n      }\n      const dir = localObs.normalize();\n      const WGS84_ONE_MINUS_E2 = 0.99330562;\n      const latDeg = THREE.MathUtils.radToDeg(\n        Math.atan2(dir.y / WGS84_ONE_MINUS_E2, Math.sqrt(dir.x * dir.x + dir.z * dir.z))\n      );\n      const lonDeg = THREE.MathUtils.radToDeg(Math.atan2(dir.x, dir.z));\n\n      if (this._shouldRefresh(latDeg, lonDeg)) {\n        this._fetchNames(latDeg, lonDeg);\n      }\n    }\n\n    // Process raycast queue (budget-limited)\n    this._processRaycastQueue();\n  }\n\n  dispose() {\n    this.deactivate();\n  }\n\n  // ── Overpass fetch (lightweight — names + centers only) ──\n\n  _shouldRefresh(lat, lon) {\n    if (!this._center) return true;\n    if (this._inflight) return false;\n    const now = performance.now();\n    if (now - this._lastFetchMs < MIN_FETCH_INTERVAL_MS) return false;\n\n    const latRad = THREE.MathUtils.degToRad(lat);\n    const dLat = (lat - this._center.lat) * metersPerDegLat(latRad) / 111132.954 * 111132.954;\n    const dLon = (lon - this._center.lon) * metersPerDegLon(latRad);\n    const dist = Math.sqrt(dLat * dLat + dLon * dLon);\n    return dist > this.refreshDistanceM;\n  }\n\n  async _fetchNames(lat, lon) {\n    if (this._inflight) return;\n    this._inflight = true;\n    this._lastFetchMs = performance.now();\n\n    try {\n      const controller = typeof AbortController === 'function' ? new AbortController() : null;\n      this._fetchController = controller;\n      const elements = await fetchBuildingsForLabels(lat, lon, {\n        radiusM: this.radiusM,\n        limit: this.maxBuildings,\n        timeoutMs: OVERPASS_FETCH_TIMEOUT_MS,\n        signal: controller?.signal,\n      });\n      if (controller?.signal.aborted || !this.enabled) return;\n      if (!elements.length) {\n        this._center = { lat, lon };\n        return;\n      }\n\n      this._applyResults(elements, lat, lon);\n      this._center = { lat, lon };\n    } catch (err) {\n      if (err?.name !== 'AbortError') {\n        console.warn('[PhotoBuildingLabels] fetch failed:', err);\n      }\n    } finally {\n      this._fetchController = null;\n      this._inflight = false;\n    }\n  }\n\n  _applyResults(elements, centerLat, centerLon) {\n    const nextKeys = new Set();\n\n    for (const el of elements) {\n      if (!el.center) continue;\n      const tags = el.tags || {};\n      const lat = el.center.lat;\n      const lon = el.center.lon;\n      if (!Number.isFinite(lat) || !Number.isFinite(lon)) continue;\n\n      const key = `${el.id}`;\n      nextKeys.add(key);\n\n      if (this._entries.has(key)) continue; // already tracked\n\n      const dir = latLonToLocalDir(lat, lon).normalize();\n      const contact = extractOsmContactFields(tags);\n      const footprint = Array.isArray(el.geometry) && el.geometry.length >= 3\n        ? el.geometry\n            .map((node) => [Number(node?.lat), Number(node?.lon)])\n            .filter(([nodeLat, nodeLon]) => Number.isFinite(nodeLat) && Number.isFinite(nodeLon))\n        : null;\n      const entry = {\n        key,\n        osmType: el.type || 'way',\n        osmId: el.id,\n        lat,\n        lon,\n        name: tags.name || '',\n        address: this._formatAddress(tags),\n        category: formatOsmBusinessCategory(tags),\n        phone: contact.phone,\n        website: contact.website,\n        email: contact.email,\n        fax: contact.fax,\n        tags: { ...tags },\n        height: this._parseHeight(tags),\n        footprint: footprint?.length >= 3 ? footprint : null,\n        dir,\n        // Bounding box from Overpass `out bb` (footprint extent)\n        bounds: el.bounds ? {\n          minLat: el.bounds.minlat, maxLat: el.bounds.maxlat,\n          minLon: el.bounds.minlon, maxLon: el.bounds.maxlon,\n        } : null,\n        labelHandle: null,\n        raycasted: false,\n        hasLabel: !!(tags.name || tags['addr:housenumber']),\n      };\n      this._entries.set(key, entry);\n      // Only queue for persistent label raycast if it has meaningful text\n      if (entry.hasLabel) {\n        this._raycastQueue.push(key);\n      }\n    }\n\n    // Remove entries no longer in range\n    for (const [key, entry] of this._entries) {\n      if (!nextKeys.has(key)) {\n        this._disposeEntry(entry);\n        this._entries.delete(key);\n      }\n    }\n  }\n\n  // ── Raycast queue processing ──\n\n  _processRaycastQueue() {\n    if (!this._raycastQueue.length || !this.tileGroup) return;\n\n    const budget = Math.min(this.raycastBudget, this._raycastQueue.length);\n    const processed = [];\n\n    for (let i = 0; i < budget; i++) {\n      const key = this._raycastQueue[i];\n      const entry = this._entries.get(key);\n      if (!entry || entry.raycasted) {\n        processed.push(i);\n        continue;\n      }\n\n      // Every new entry gets one bounded initial attempt. A miss is removed\n      // from this frame queue and retried only when native traversal reports a\n      // tile visibility change for the entry's geographic region.\n      processed.push(i);\n      this._snapEntryToSurface(entry);\n    }\n\n    // Remove processed items from queue (reverse order to preserve indices)\n    for (let i = processed.length - 1; i >= 0; i--) {\n      this._raycastQueue.splice(processed[i], 1);\n    }\n  }\n\n  _snapEntryToSurface(entry) {\n    if (!entry?.dir) return false;\n    const roofRadius = this._raycastRoof(entry.dir);\n    if (!Number.isFinite(roofRadius)) {\n      entry.raycasted = false;\n      return false;\n    }\n    entry.raycasted = true;\n    this._createLabel(entry, roofRadius);\n    return true;\n  }\n\n  /**\n   * Re-raycast already-mated roof labels only for the tile footprints whose\n   * rendered ownership changed. This is synchronous with native traversal, so\n   * a replacement LOD cannot leave labels climbing over subsequent frames.\n   */\n  refreshTerrainAnchors(changes) {\n    if (!this.enabled || !this.tileGroup\n      || !Array.isArray(changes) || changes.length === 0) return 0;\n    let updated = 0;\n    for (const entry of this._entries.values()) {\n      if (!entry.hasLabel) continue;\n      if (!terrainSurfaceChangesAffectLatLon(changes, entry.lat, entry.lon)) continue;\n      this._snapEntryToSurface(entry);\n      updated += 1;\n    }\n    return updated;\n  }\n\n  /**\n   * Raycast downward from far above onto Cesium tile mesh at a given direction.\n   * Returns the radius (distance from planet center) of the highest hit, or null.\n   */\n  _raycastRoof(dir) {\n    const sampler = this.surfaceController?.sampleTerrainRadiusForDir;\n    if (typeof sampler === 'function' && this.surfaceController?.photoTileGroup) {\n      const worldDir = _tmpDir.copy(dir);\n      if (this.tileGroup?.parent?.getWorldQuaternion) {\n        this.tileGroup.parent.getWorldQuaternion(_tmpQuat);\n        worldDir.applyQuaternion(_tmpQuat).normalize();\n      }\n      const sampled = sampler.call(this.surfaceController, worldDir, {\n        mutateCache: false,\n        requireFreshPhotoHit: true,\n        allowTriTreeFallback: false,\n        skipWorldMatrixUpdate: true,\n      });\n      return Number.isFinite(sampled) ? sampled : null;\n    }\n\n    const startR = this.planetRadius * 3 + 1_000_000;\n    _rayOrigin.copy(dir).multiplyScalar(startR);\n    _rayDir.copy(dir).negate();\n\n    _raycaster.set(_rayOrigin, _rayDir);\n    _raycaster.near = 0;\n    _raycaster.far = startR + 10;\n\n    const hits = _raycaster.intersectObject(this.tileGroup, true);\n    if (!hits.length) return null;\n\n    // Find the outermost (highest) hit — that's the roof\n    const ellipsoidR = ellipsoidRadiusForLocalDir(dir);\n    const maxOffset = 2000; // ignore hits more than 2km from ellipsoid\n    let bestR = null;\n    for (const hit of hits) {\n      const r = hit.point.length();\n      if (Math.abs(r - ellipsoidR) > maxOffset) continue;\n      if (bestR === null || r > bestR) bestR = r;\n    }\n    return bestR;\n  }\n\n  // ── Label management ──\n\n  _createLabel(entry, roofRadius) {\n    const ls = this._ensureLabelSystem();\n    if (!ls) return;\n\n    // Position label slightly above the roof\n    const labelPos = _tmpDir.copy(entry.dir).multiplyScalar(roofRadius + 2);\n    if (entry.labelHandle) {\n      ls.updatePosition(entry.labelHandle, labelPos);\n      if (this._hoverKey === entry.key && this._hoverHandle) {\n        ls.updatePosition(this._hoverHandle, labelPos);\n      }\n      return;\n    }\n\n    const subText = entry.address\n      || (Number.isFinite(entry.height) ? `${Math.round(entry.height)}m` : '');\n\n    entry.labelHandle = ls.createLabel(entry.name, {\n      position: labelPos.clone(), // clone — scratch vector reused\n      type: 'building',\n      objectRadius: 15,\n      subText,\n      metadata: {\n        entityType: 'building',\n        typeLabel: entry.category || 'Building',\n        name: entry.name || '',\n        address: entry.address || '',\n        lat: entry.lat,\n        lon: entry.lon,\n        category: entry.category || '',\n        phone: entry.phone || '',\n        website: entry.website || '',\n        email: entry.email || '',\n        fax: entry.fax || '',\n        contact: {\n          phone: entry.phone || '',\n          website: entry.website || '',\n          email: entry.email || '',\n          fax: entry.fax || '',\n        },\n        osm: { type: entry.osmType, id: entry.osmId },\n        source: 'OpenStreetMap',\n        tags: entry.tags || null,\n      },\n    });\n\n    if (entry.labelHandle?.group && this.parentGroup) {\n      this.parentGroup.add(entry.labelHandle.group);\n    }\n  }\n\n  _disposeEntry(entry) {\n    if (!entry) return;\n    if (entry.labelHandle) {\n      if (entry.labelHandle.group?.parent) {\n        entry.labelHandle.group.parent.remove(entry.labelHandle.group);\n      }\n      entry.labelHandle.dispose();\n      entry.labelHandle = null;\n    }\n  }\n\n  _clearLabels() {\n    for (const entry of this._entries.values()) {\n      this._disposeEntry(entry);\n    }\n    this._entries.clear();\n    this._raycastQueue.length = 0;\n  }\n\n  _ensureLabelSystem() {\n    if (!this._labelSystem) {\n      try {\n        this._labelSystem = getLabelSystem({ planetRadius: this.planetRadius });\n      } catch { /* not available */ }\n    }\n    return this._labelSystem;\n  }\n\n  // ── Hover interaction (Cesium tile raycast → building lookup) ──\n\n  /**\n   * Raycast the Cesium tile mesh at the given screen coords.\n   * If the hit falls near a known OSM building centroid, return it.\n   *\n   * @param {THREE.Raycaster} raycaster - Pre-configured raycaster from mouse coords\n   * @param {THREE.Camera} camera\n   * @returns {{ entry, hitPoint: THREE.Vector3 } | null}\n   */\n  findBuildingAtRaycast(raycaster, camera) {\n    if (!this.enabled || !this.tileGroup || this._entries.size === 0) {\n      return null;\n    }\n    if (!raycaster) return null;\n    if (camera?.matrixWorld) {\n      raycaster.camera = camera;\n    }\n    if (!raycaster.camera?.matrixWorld) {\n      return null;\n    }\n\n    let hits = [];\n    try {\n      hits = raycaster.intersectObject(this.tileGroup, true);\n    } catch (error) {\n      if (globalThis.__noclipDebugPhotoLabels === true) {\n        console.warn('[PBL] raycast failed:', error);\n      }\n      return null;\n    }\n    if (!hits.length) {\n      // Log once per second when raycast misses\n      if (globalThis.__noclipDebugPhotoLabels === true) {\n        this._missCount = (this._missCount || 0) + 1;\n      }\n      if (globalThis.__noclipDebugPhotoLabels === true && this._missCount % 60 === 1) {\n        console.warn(`[PBL] raycast MISS — no tile hit (entries=${this._entries.size})`);\n      }\n      return null;\n    }\n\n    // Use closest hit\n    const hit = hits[0];\n    const hitPoint = hit.point;\n\n    // Convert hit point from WORLD space to planet-local space\n    // (the triTree/planet group has rotation transforms applied)\n    const localHit = _tmpDir.copy(hitPoint);\n    if (this.tileGroup.parent) {\n      // Get the inverse of the parent's world matrix to go from world → local\n      const parentInverse = new THREE.Matrix4();\n      this.tileGroup.parent.updateWorldMatrix(true, false);\n      parentInverse.copy(this.tileGroup.parent.matrixWorld).invert();\n      localHit.applyMatrix4(parentInverse);\n    }\n\n    // Convert local-space direction to lat/lon (WGS84)\n    const dir = localHit.normalize();\n    const WGS84_ONE_MINUS_E2 = 0.99330562;\n    const latDeg = THREE.MathUtils.radToDeg(\n      Math.atan2(dir.y / WGS84_ONE_MINUS_E2, Math.sqrt(dir.x * dir.x + dir.z * dir.z))\n    );\n    const lonDeg = THREE.MathUtils.radToDeg(Math.atan2(dir.x, dir.z));\n\n    // Match hit point against building footprint bounding boxes.\n    // If bb data available, check containment. Otherwise fall back to centroid distance.\n    let bestEntry = null;\n    let bestDistSq = Infinity;\n\n    for (const entry of this._entries.values()) {\n      const bb = entry.bounds;\n      if (bb) {\n        // Bounding box containment test (footprint projection)\n        if (latDeg >= bb.minLat && latDeg <= bb.maxLat &&\n            lonDeg >= bb.minLon && lonDeg <= bb.maxLon) {\n          // Inside footprint bbox — pick the smallest (most specific) building\n          const area = (bb.maxLat - bb.minLat) * (bb.maxLon - bb.minLon);\n          if (area < bestDistSq) {\n            bestDistSq = area;\n            bestEntry = entry;\n          }\n        }\n      } else {\n        // Fallback: centroid distance (~111m threshold)\n        const dLat = entry.lat - latDeg;\n        const dLon = entry.lon - lonDeg;\n        const distSq = dLat * dLat + dLon * dLon;\n        const threshold = 0.001 * 0.001;\n        if (distSq < threshold && distSq < bestDistSq) {\n          bestDistSq = distSq;\n          bestEntry = entry;\n        }\n      }\n    }\n\n    if (bestEntry) {\n      if (globalThis.__noclipDebugPhotoLabels === true) {\n        console.warn(`[PBL] MATCH: \"${bestEntry.name || bestEntry.address}\" at ${latDeg.toFixed(5)},${lonDeg.toFixed(5)}`);\n      }\n    } else {\n      // Log misses periodically\n      if (globalThis.__noclipDebugPhotoLabels === true) {\n        this._noMatchCount = (this._noMatchCount || 0) + 1;\n      }\n      if (globalThis.__noclipDebugPhotoLabels === true && this._noMatchCount % 30 === 1) {\n        // Show the hit lat/lon and a sample entry for comparison\n        const sample = this._entries.values().next().value;\n        const sampleBB = sample?.bounds;\n        console.warn(`[PBL] hit at ${latDeg.toFixed(5)},${lonDeg.toFixed(5)} — no bbox match (${this._entries.size} entries). Sample: lat=${sample?.lat?.toFixed(5)} lon=${sample?.lon?.toFixed(5)} bb=${sampleBB ? `${sampleBB.minLat.toFixed(5)}-${sampleBB.maxLat.toFixed(5)}, ${sampleBB.minLon.toFixed(5)}-${sampleBB.maxLon.toFixed(5)}` : 'none'}`);\n      }\n    }\n    return bestEntry ? { entry: bestEntry, hitPoint: hitPoint.clone() } : null;\n  }\n\n  /**\n   * Show a temporary hover label at a Cesium tile raycast hit point.\n   * Call from PlanetScene's mouse move handler.\n   *\n   * @param {Object} buildingResult - From findBuildingAtRaycast()\n   */\n  showHoverLabel(buildingResult) {\n    if (!buildingResult) {\n      this._clearHoverLabel();\n      return;\n    }\n\n    const { entry, hitPoint } = buildingResult;\n    if (this._hoverKey === entry.key) return; // same building\n\n    this._clearHoverLabel();\n    this._hoverKey = entry.key;\n\n    const ls = this._ensureLabelSystem();\n    if (!ls) return;\n\n    const primary = entry.name || entry.address || 'Building';\n    const subText = entry.name && entry.address ? entry.address : '';\n\n    this._hoverHandle = ls.createLabel(primary, {\n      position: hitPoint,\n      type: 'building',\n      objectRadius: 8,\n      subText,\n    });\n\n    if (this._hoverHandle?.group && this.parentGroup) {\n      this.parentGroup.add(this._hoverHandle.group);\n    }\n  }\n\n  _clearHoverLabel() {\n    if (this._hoverHandle) {\n      if (this._hoverHandle.group?.parent) {\n        this._hoverHandle.group.parent.remove(this._hoverHandle.group);\n      }\n      this._hoverHandle.dispose();\n      this._hoverHandle = null;\n    }\n    this._hoverKey = null;\n  }\n\n  // ── Tag parsing helpers ──\n\n  _parseHeight(tags) {\n    if (!tags) return null;\n    const raw = tags.height || tags['building:height'];\n    if (!raw) return null;\n    const parsed = parseFloat(raw);\n    return Number.isFinite(parsed) ? parsed : null;\n  }\n\n  _formatAddress(tags) {\n    if (!tags) return '';\n    const parts = [];\n    if (tags['addr:housenumber']) parts.push(tags['addr:housenumber']);\n    if (tags['addr:street']) parts.push(tags['addr:street']);\n    if (parts.length) return parts.join(' ');\n    if (tags['addr:full']) return tags['addr:full'];\n    return '';\n  }\n}\n\n// ── Singleton ──\n\nlet _instance = null;\n\nexport function getPhotoBuildingLabels(opts) {\n  if (!_instance) _instance = new PhotoBuildingLabels(opts);\n  if (opts?.surfaceController) _instance.surfaceController = opts.surfaceController;\n  return _instance;\n}\n","/**\n * BusinessLabels\n *\n * Lightweight OSM business label layer. Fetches bounded Overpass POIs near\n * the camera, creates LabelSystem labels, and exposes hover hit tests so the\n * shared address toast can show phone/website details.\n */\nimport * as THREE from 'three';\nimport {\n  latLonToLocalDir,\n  ellipsoidRadiusForLocalDir,\n  worldPosToLatLonLocal,\n  geodesicDistanceWGS84,\n} from '../../modules/geometry-utils.js';\nimport { PLANET_RADIUS } from '../../modules/constants.js';\nimport {\n  fetchBusinessesAround,\n  formatOsmAddress,\n  classifyOsmPlace,\n  PLACE_CATEGORIES,\n} from '../../modules/geocoding-service.js';\nimport { terrainSurfaceChangesAffectLatLon } from '../scene/TerrainSurfaceChange.js';\nimport { getLabelSystem } from './LabelSystem.js';\n\nconst DEFAULT_RADIUS_M = 2500;\nconst DEFAULT_REFRESH_DISTANCE_M = 240;\nconst DEFAULT_MIN_FETCH_INTERVAL_MS = 8000;\nconst DEFAULT_MAX_BUSINESSES = 180;\nconst DEFAULT_RETENTION_MS = 300000;\nconst DEFAULT_MAX_RETAINED = 300;\nconst DEFAULT_LABEL_MAX_DISTANCE_M = 14000;\nconst DEFAULT_SURFACE_HOVER_DISTANCE_M = 36;\nconst MOBILE_RADIUS_M = 1200;\nconst MOBILE_REFRESH_DISTANCE_M = 160;\nconst MOBILE_MIN_FETCH_INTERVAL_MS = 12000;\nconst MOBILE_MAX_BUSINESSES = 48;\nconst MOBILE_RETENTION_MS = 120000;\nconst MOBILE_MAX_RETAINED = 72;\nconst MOBILE_SURFACE_HOVER_DISTANCE_M = 28;\n\nconst _tmpDir = new THREE.Vector3();\nconst _tmpPos = new THREE.Vector3();\nconst _tmpQuat = new THREE.Quaternion();\n\nfunction distanceM(lat1, lon1, lat2, lon2) {\n  const geodesic = geodesicDistanceWGS84(lat1, lon1, lat2, lon2);\n  if (Number.isFinite(geodesic)) return geodesic;\n  const R = 6371000;\n  const dLat = (lat2 - lat1) * Math.PI / 180;\n  const dLon = (lon2 - lon1) * Math.PI / 180;\n  const a = Math.sin(dLat / 2) ** 2\n    + Math.cos(lat1 * Math.PI / 180)\n    * Math.cos(lat2 * Math.PI / 180)\n    * Math.sin(dLon / 2) ** 2;\n  return R * 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));\n}\n\nfunction compactText(value, max = 42) {\n  const text = String(value || '').replace(/\\s+/g, ' ').trim();\n  return text.length > max ? `${text.slice(0, max - 1)}...` : text;\n}\n\nfunction isAbortError(error) {\n  return error?.name === 'AbortError';\n}\n\nexport class BusinessLabels {\n  constructor({ planetRadius, eventBus, parentGroup, surfaceController } = {}) {\n    this.planetRadius = Number.isFinite(planetRadius) ? planetRadius : PLANET_RADIUS;\n    this.eventBus = eventBus || null;\n    this.parentGroup = parentGroup || null;\n    this.planetGroup = parentGroup || null;\n    this.surfaceController = surfaceController || null;\n    this.enabled = false;\n    this.radiusM = DEFAULT_RADIUS_M;\n    this.refreshDistanceM = DEFAULT_REFRESH_DISTANCE_M;\n    this.minFetchIntervalMs = DEFAULT_MIN_FETCH_INTERVAL_MS;\n    this.maxBusinesses = DEFAULT_MAX_BUSINESSES;\n    this.retentionMs = DEFAULT_RETENTION_MS;\n    this.maxRetained = DEFAULT_MAX_RETAINED;\n    this.surfaceHoverDistanceM = DEFAULT_SURFACE_HOVER_DISTANCE_M;\n\n    this._labelSystem = null;\n    this._center = null;\n    this._lastFetchMs = 0;\n    this._inflight = false;\n    this._fetchController = null;\n    this._fetchGeneration = 0;\n    this._entries = new Map();\n    this._hoverKey = null;\n    this._hoverHandle = null;\n    this._pulseTimer = null;\n    this._pulseKey = null;\n    this._complexityProfile = 'desktop';\n\n    this._onExternalSelect = (ev) => this._handleExternalSelection(ev);\n    if (typeof document !== 'undefined' && document.addEventListener) {\n      document.addEventListener('noclip:business-selected', this._onExternalSelect);\n    }\n  }\n\n  setComplexityProfile({ mobile = false } = {}) {\n    const nextProfile = mobile ? 'mobile' : 'desktop';\n    if (this._complexityProfile === nextProfile) return;\n    this._complexityProfile = nextProfile;\n    if (mobile) {\n      this.radiusM = MOBILE_RADIUS_M;\n      this.refreshDistanceM = MOBILE_REFRESH_DISTANCE_M;\n      this.minFetchIntervalMs = MOBILE_MIN_FETCH_INTERVAL_MS;\n      this.maxBusinesses = MOBILE_MAX_BUSINESSES;\n      this.retentionMs = MOBILE_RETENTION_MS;\n      this.maxRetained = MOBILE_MAX_RETAINED;\n      this.surfaceHoverDistanceM = MOBILE_SURFACE_HOVER_DISTANCE_M;\n    } else {\n      this.radiusM = DEFAULT_RADIUS_M;\n      this.refreshDistanceM = DEFAULT_REFRESH_DISTANCE_M;\n      this.minFetchIntervalMs = DEFAULT_MIN_FETCH_INTERVAL_MS;\n      this.maxBusinesses = DEFAULT_MAX_BUSINESSES;\n      this.retentionMs = DEFAULT_RETENTION_MS;\n      this.maxRetained = DEFAULT_MAX_RETAINED;\n      this.surfaceHoverDistanceM = DEFAULT_SURFACE_HOVER_DISTANCE_M;\n    }\n    this._enforceRetentionLimit();\n  }\n\n  activate(parentGroup, { planetGroup } = {}) {\n    this.parentGroup = parentGroup || this.parentGroup;\n    this.planetGroup = planetGroup || parentGroup || this.planetGroup;\n    this.enabled = true;\n  }\n\n  /**\n   * Find a label entry that matches an OSM identity ({ osmType, osmId } or an\n   * \"osmType/osmId\" id string). Used to cross-highlight between 2D and 3D.\n   */\n  findEntryByOsm(osm) {\n    if (!osm) return null;\n    const id = typeof osm === 'string' ? osm : (osm.type && osm.id ? `${osm.type}/${osm.id}` : null);\n    if (!id) return null;\n    return this._entries.get(id) || null;\n  }\n\n  getEntriesSnapshot() {\n    return [...this._entries.values()].map((entry) => ({\n      id: entry.id || entry.key,\n      key: entry.key,\n      osmType: entry.osmType || null,\n      osmId: entry.osmId || null,\n      lat: entry.lat,\n      lon: entry.lon,\n      altitudeM: 28,\n      name: entry.name || '',\n      address: entry.address || '',\n      category: entry.category || '',\n      kind: entry.kind || 'poi',\n      kindLabel: entry.kindLabel || '',\n      kindSubtype: entry.kindSubtype || '',\n      type: entry.kind === 'natural' ? 'natural' : 'business',\n      color: entry.color,\n      colorHex: entry.hex || '',\n      hex: entry.hex || '',\n      glyph: entry.glyph || '',\n      phone: entry.phone || '',\n      website: entry.website || '',\n      websiteHost: entry.websiteHost || '',\n      email: entry.email || '',\n      fax: entry.fax || '',\n      contact: {\n        phone: entry.phone || '',\n        website: entry.website || '',\n        email: entry.email || '',\n        fax: entry.fax || '',\n      },\n      tags: entry.tags || null,\n      bounds: entry.bounds || null,\n      lastSeenMs: entry.lastSeenMs || 0,\n      distanceFromCenterM: Number.isFinite(entry.distanceFromCenterM) ? entry.distanceFromCenterM : null,\n    }));\n  }\n\n  /**\n   * Emphasise a label for ~1.5s when its 2D pin is clicked. Uses label scale\n   * instead of a timer-managed animation so the label system can dispose\n   * cleanly when the camera moves away.\n   */\n  pulseEntry(entry) {\n    if (!entry?.labelHandle?.group) return;\n    if (this._pulseTimer) {\n      clearTimeout(this._pulseTimer);\n      const prev = this._pulseKey ? this._entries.get(this._pulseKey) : null;\n      if (prev?.labelHandle?.group) prev.labelHandle.group.scale.setScalar(1);\n      this._pulseTimer = null;\n    }\n    entry.labelHandle.group.scale.setScalar(1.35);\n    this._pulseKey = entry.key;\n    this._pulseTimer = setTimeout(() => {\n      const current = this._pulseKey ? this._entries.get(this._pulseKey) : null;\n      if (current?.labelHandle?.group && this._pulseKey !== this._hoverKey) {\n        current.labelHandle.group.scale.setScalar(1);\n      }\n      this._pulseTimer = null;\n      this._pulseKey = null;\n    }, 1500);\n  }\n\n  _handleExternalSelection(ev) {\n    // Ignore events we originated ourselves (`source === '3d'` from this layer).\n    const detail = ev?.detail || {};\n    if (detail.source === '3d' || detail.source === 'businesslabels') return;\n    const data = detail.data || detail;\n    const entry = this.findEntryByOsm(data?.osm || detail.id);\n    if (entry) this.pulseEntry(entry);\n  }\n\n  setEnabled(enabled, { clearEntries = true } = {}) {\n    const wasEnabled = this.enabled;\n    this.enabled = !!enabled;\n    if (!this.enabled) {\n      this._cancelFetch();\n      this.clearHover();\n      if (clearEntries) {\n        this.clear();\n      } else {\n        for (const entry of this._entries.values()) this._disposeEntry(entry);\n      }\n    }\n    if (this.enabled && !wasEnabled) {\n      for (const entry of this._entries.values()) this._createOrUpdateLabel(entry);\n    }\n  }\n\n  update(observerPos) {\n    if (!this.enabled || !this.parentGroup || !observerPos) return;\n    const ll = worldPosToLatLonLocal(observerPos, this.planetGroup || this.parentGroup);\n    if (!ll || !Number.isFinite(ll.latDeg) || !Number.isFinite(ll.lonDeg)) return;\n    const lat = ll.latDeg;\n    const lon = ll.lonDeg;\n    this._updateDistanceFalloff(lat, lon);\n    if (!this._shouldRefresh(lat, lon)) return;\n    this._fetch(lat, lon);\n  }\n\n  ingestBusinesses(businesses, { centerLat = null, centerLon = null, prune = false } = {}) {\n    if (!Array.isArray(businesses) || !businesses.length) return;\n    this._applyBusinesses(businesses, { centerLat, centerLon, prune });\n  }\n\n  clear() {\n    this.clearHover();\n    for (const entry of this._entries.values()) this._disposeEntry(entry);\n    this._entries.clear();\n  }\n\n  dispose() {\n    this.enabled = false;\n    this._cancelFetch();\n    this.clear();\n    this.parentGroup = null;\n    this.planetGroup = null;\n    if (this._pulseTimer) { clearTimeout(this._pulseTimer); this._pulseTimer = null; }\n    if (this._onExternalSelect && typeof document !== 'undefined' && document.removeEventListener) {\n      document.removeEventListener('noclip:business-selected', this._onExternalSelect);\n    }\n    this._onExternalSelect = null;\n  }\n\n  findLabelAtRaycast(raycaster, camera = null) {\n    if (!this.enabled || !raycaster || !this._entries.size) return null;\n    const activeCamera = camera || raycaster.camera || null;\n    if (!activeCamera?.matrixWorld) return null;\n    raycaster.camera = activeCamera;\n    const objects = [];\n    for (const entry of this._entries.values()) {\n      const group = entry.labelHandle?.group;\n      if (!group || group.visible === false) continue;\n      objects.push(...group.children);\n    }\n    if (!objects.length) return null;\n    let hits = null;\n    try {\n      hits = raycaster.intersectObjects(objects, true);\n    } catch (error) {\n      if (globalThis.__noclipDebugBusinessLabels === true) {\n        console.warn('[BusinessLabels] raycast failed:', error);\n      }\n      return null;\n    }\n    if (!hits.length) return null;\n    for (const hit of hits) {\n      const key = hit.object?.userData?.businessLabelKey\n        || hit.object?.parent?.userData?.businessLabelKey;\n      const entry = key ? this._entries.get(key) : null;\n      if (entry) return { entry, hitPoint: hit.point?.clone?.() || entry.position.clone(), source: 'label' };\n    }\n    return null;\n  }\n\n  findBusinessNearLatLon(lat, lon, { maxDistanceM = this.surfaceHoverDistanceM } = {}) {\n    if (!this.enabled || !Number.isFinite(lat) || !Number.isFinite(lon)) return null;\n    let best = null;\n    let bestDist = Infinity;\n    for (const entry of this._entries.values()) {\n      const d = distanceM(lat, lon, entry.lat, entry.lon);\n      if (d <= maxDistanceM && d < bestDist) {\n        bestDist = d;\n        best = entry;\n      }\n    }\n    return best ? { entry: best, hitPoint: best.position.clone(), source: 'location', distanceM: bestDist } : null;\n  }\n\n  showHover(result) {\n    if (!result?.entry) {\n      this.clearHover();\n      return;\n    }\n    const entry = result.entry;\n    if (this._hoverKey === entry.key) return;\n    this.clearHover();\n    this._hoverKey = entry.key;\n\n    if (entry.labelHandle?.group) {\n      entry.labelHandle.group.scale.setScalar(1.16);\n    }\n\n    const ls = this._ensureLabelSystem();\n    if (!ls) return;\n    const subText = entry.kindLabel || entry.phone || entry.websiteHost || entry.category || entry.address || '';\n    this._hoverHandle = ls.createLabel(entry.name || 'Place', {\n      position: result.hitPoint?.clone?.() || entry.position.clone(),\n      type: entry.kind === 'natural' ? 'natural' : 'business',\n      color: Number.isFinite(entry.color) ? entry.color : 0xffffff,\n      objectRadius: 16,\n      subText: compactText(subText, 36),\n    });\n    if (this._hoverHandle?.group && this.parentGroup) {\n      this.parentGroup.add(this._hoverHandle.group);\n    }\n  }\n\n  clearHover() {\n    if (this._hoverKey) {\n      const entry = this._entries.get(this._hoverKey);\n      if (entry?.labelHandle?.group) entry.labelHandle.group.scale.setScalar(1);\n    }\n    if (this._hoverHandle) {\n      if (this._hoverHandle.group?.parent) this._hoverHandle.group.parent.remove(this._hoverHandle.group);\n      this._hoverHandle.dispose();\n      this._hoverHandle = null;\n    }\n    this._hoverKey = null;\n  }\n\n  toToastData(entry) {\n    if (!entry) return null;\n    return {\n      name: entry.name || entry.kindLabel || 'Place',\n      address: entry.address || `${entry.lat.toFixed(5)}, ${entry.lon.toFixed(5)}`,\n      lat: entry.lat,\n      lon: entry.lon,\n      meta: [entry.kindLabel, entry.category && entry.category !== entry.kindLabel ? entry.category : '']\n        .filter(Boolean)\n        .join(' · '),\n      category: entry.category || entry.kind || 'poi',\n      kind: entry.kind || 'poi',\n      phone: entry.phone || '',\n      website: entry.website || '',\n      email: entry.email || '',\n      fax: entry.fax || '',\n      contact: {\n        phone: entry.phone || '',\n        website: entry.website || '',\n        email: entry.email || '',\n        fax: entry.fax || '',\n      },\n      osm: { type: entry.osmType, id: entry.osmId },\n      tags: entry.tags || null,\n      bbox: entry.bounds || null,\n    };\n  }\n\n  _shouldRefresh(lat, lon) {\n    if (this._inflight) return false;\n    const now = performance.now?.() || Date.now();\n    if (now - this._lastFetchMs < this.minFetchIntervalMs) return false;\n    if (!this._center) return true;\n    return distanceM(lat, lon, this._center.lat, this._center.lon) > this.refreshDistanceM;\n  }\n\n  async _fetch(lat, lon) {\n    if (this._inflight) return;\n    const generation = ++this._fetchGeneration;\n    const controller = typeof AbortController === 'function' ? new AbortController() : null;\n    this._fetchController = controller;\n    this._inflight = true;\n    this._lastFetchMs = performance.now?.() || Date.now();\n    try {\n      const businesses = await fetchBusinessesAround(lat, lon, {\n        radiusM: this.radiusM,\n        limit: this.maxBusinesses,\n        signal: controller?.signal,\n      });\n      if (generation !== this._fetchGeneration || controller?.signal.aborted || !this.enabled) return;\n      this._applyBusinesses(businesses, { centerLat: lat, centerLon: lon, prune: true });\n      this._center = { lat, lon };\n    } catch (error) {\n      if (!isAbortError(error)) {\n        console.warn('[BusinessLabels] fetch failed:', error);\n      }\n    } finally {\n      if (generation === this._fetchGeneration) {\n        this._fetchController = null;\n        this._inflight = false;\n      }\n    }\n  }\n\n  _cancelFetch() {\n    this._fetchGeneration++;\n    this._fetchController?.abort?.();\n    this._fetchController = null;\n    this._inflight = false;\n  }\n\n  _applyBusinesses(businesses, { centerLat = null, centerLon = null, prune = true } = {}) {\n    const now = performance.now?.() || Date.now();\n    const hasCenter = Number.isFinite(centerLat) && Number.isFinite(centerLon);\n    const nextKeys = new Set();\n    for (const business of businesses || []) {\n      if (!Number.isFinite(business.lat) || !Number.isFinite(business.lon)) continue;\n      const key = business.id || `${business.osmType || 'node'}/${business.osmId || `${business.lat},${business.lon}`}`;\n      nextKeys.add(key);\n      const entry = this._entries.get(key) || { key, labelHandle: null, position: new THREE.Vector3() };\n      // Classify once up-front so both the label tint and toast metadata agree.\n      const classification = business.kind\n        ? {\n            kind: business.kind,\n            label: business.kindLabel || business.kind,\n            color: business.color ?? PLACE_CATEGORIES[business.kind]?.color ?? 0xcbd5e1,\n            hex: business.hex || PLACE_CATEGORIES[business.kind]?.hex || '#cbd5e1',\n            glyph: business.glyph || PLACE_CATEGORIES[business.kind]?.glyph || '.',\n            subtype: business.kindSubtype || '',\n          }\n        : classifyOsmPlace(business.tags || {});\n      Object.assign(entry, {\n        key,\n        id: key,\n        osmType: business.osmType || null,\n        osmId: business.osmId || null,\n        lat: business.lat,\n        lon: business.lon,\n        name: business.name || classification.label || 'Place',\n        address: business.address || formatOsmAddress(business.tags || {}),\n        category: business.category || '',\n        kind: classification.kind,\n        kindLabel: classification.label,\n        kindSubtype: classification.subtype || '',\n        color: classification.color,\n        hex: classification.hex,\n        glyph: classification.glyph,\n        phone: business.phone || '',\n        website: business.website || '',\n        websiteHost: business.website ? business.website.replace(/^https?:\\/\\//i, '').replace(/^www\\./i, '').split('/')[0] : '',\n        email: business.email || '',\n        fax: business.fax || '',\n        tags: business.tags || {},\n        bounds: business.bounds || null,\n        lastSeenMs: now,\n        distanceFromCenterM: hasCenter ? distanceM(centerLat, centerLon, business.lat, business.lon) : business.distanceM,\n      });\n      entry.dir = latLonToLocalDir(entry.lat, entry.lon).normalize();\n      this._positionEntry(entry);\n      this._entries.set(key, entry);\n      if (this.enabled) this._createOrUpdateLabel(entry);\n    }\n\n    const pruneDistanceM = this.radiusM * 1.45;\n    for (const [key, entry] of this._entries.entries()) {\n      if (nextKeys.has(key)) continue;\n      const ageMs = now - (entry.lastSeenMs || 0);\n      const distFromCenter = hasCenter ? distanceM(centerLat, centerLon, entry.lat, entry.lon) : 0;\n      if (prune && (ageMs > this.retentionMs || distFromCenter > pruneDistanceM)) {\n        this._disposeEntry(entry);\n        this._entries.delete(key);\n      }\n    }\n\n    this._enforceRetentionLimit();\n    if (hasCenter) this._updateDistanceFalloff(centerLat, centerLon);\n  }\n\n  _positionEntry(entry) {\n    if (!entry?.dir || !entry?.position) return false;\n    const ellipsoid = ellipsoidRadiusForLocalDir(entry.dir);\n    let sampled = null;\n    const sampler = this.surfaceController?.sampleTerrainRadiusForDir;\n    if (typeof sampler === 'function') {\n      const worldDir = _tmpPos.copy(entry.dir);\n      if (this.planetGroup?.getWorldQuaternion) {\n        this.planetGroup.getWorldQuaternion(_tmpQuat);\n        worldDir.applyQuaternion(_tmpQuat).normalize();\n      }\n      const requireFreshPhotoHit = !!this.surfaceController?.photoTileGroup;\n      sampled = sampler.call(this.surfaceController, worldDir, {\n        mutateCache: false,\n        requireFreshPhotoHit,\n        allowTriTreeFallback: !requireFreshPhotoHit,\n        skipWorldMatrixUpdate: true,\n      });\n    }\n    if (Number.isFinite(sampled)) {\n      entry._stableRadius = sampled;\n      entry._terrainMated = true;\n    } else if (!Number.isFinite(entry._stableRadius)) {\n      entry._stableRadius = ellipsoid;\n    }\n    entry.position.copy(entry.dir).multiplyScalar(entry._stableRadius + 28);\n    if (entry.labelHandle) {\n      this._ensureLabelSystem()?.updatePosition?.(entry.labelHandle, entry.position);\n    }\n    if (this._hoverKey === entry.key && this._hoverHandle) {\n      this._ensureLabelSystem()?.updatePosition?.(this._hoverHandle, entry.position);\n    }\n    return Number.isFinite(sampled);\n  }\n\n  refreshTerrainAnchors(changes) {\n    if (!Array.isArray(changes) || changes.length === 0) return 0;\n    let updated = 0;\n    for (const entry of this._entries.values()) {\n      if (!terrainSurfaceChangesAffectLatLon(changes, entry.lat, entry.lon)) continue;\n      this._positionEntry(entry);\n      updated += 1;\n    }\n    return updated;\n  }\n\n  _createOrUpdateLabel(entry) {\n    const ls = this._ensureLabelSystem();\n    if (!ls || !this.parentGroup) return;\n    const text = compactText(entry.name || entry.kindLabel || 'Place', 34);\n    const subText = compactText(\n      entry.kindLabel || entry.category || entry.address || entry.phone || entry.websiteHost || '',\n      38\n    );\n    if (entry.labelHandle) {\n      ls.updateText(entry.labelHandle, text, subText);\n      ls.updatePosition(entry.labelHandle, entry.position);\n      entry.labelHandle.maxDistance = this._labelMaxDistanceM();\n      entry.labelHandle.opacity = Number.isFinite(entry.falloff)\n        ? Math.max(0.08, Math.min(1, entry.falloff))\n        : 1;\n      // Colour may have changed if the entry's classification was updated\n      if (Number.isFinite(entry.color) && entry.labelHandle.color !== entry.color) {\n        entry.labelHandle.color = entry.color;\n      }\n      ls.updateMetadata?.(entry.labelHandle, this._labelMetadata(entry));\n      return;\n    }\n    entry.labelHandle = ls.createLabel(text, {\n      position: entry.position,\n      type: entry.kind === 'natural' ? 'natural' : 'business',\n      objectRadius: 12,\n      subText,\n      color: Number.isFinite(entry.color) ? entry.color : undefined,\n      maxDistance: this._labelMaxDistanceM(),\n      opacity: Number.isFinite(entry.falloff) ? Math.max(0.08, Math.min(1, entry.falloff)) : 1,\n      metadata: this._labelMetadata(entry),\n    });\n    if (entry.labelHandle?.group) {\n      entry.labelHandle.group.userData.businessLabelKey = entry.key;\n      entry.labelHandle.group.traverse?.((node) => {\n        node.userData.businessLabelKey = entry.key;\n      });\n      this.parentGroup.add(entry.labelHandle.group);\n    }\n  }\n\n  _labelMetadata(entry) {\n    const type = entry.kind === 'natural' ? 'natural' : 'business';\n    return {\n      entityType: type,\n      typeLabel: type === 'natural' ? 'Landmark' : 'Business',\n      name: entry.name || entry.kindLabel || 'Place',\n      address: entry.address || '',\n      lat: entry.lat,\n      lon: entry.lon,\n      category: entry.category || entry.kind || 'poi',\n      kind: entry.kind || 'poi',\n      kindLabel: entry.kindLabel || '',\n      phone: entry.phone || '',\n      website: entry.website || '',\n      email: entry.email || '',\n      fax: entry.fax || '',\n      contact: {\n        phone: entry.phone || '',\n        website: entry.website || '',\n        email: entry.email || '',\n        fax: entry.fax || '',\n      },\n      osm: { type: entry.osmType, id: entry.osmId },\n      source: 'OpenStreetMap',\n      tags: entry.tags || null,\n    };\n  }\n\n  _disposeEntry(entry) {\n    if (!entry) return;\n    if (entry.labelHandle) {\n      if (entry.labelHandle.group?.parent) entry.labelHandle.group.parent.remove(entry.labelHandle.group);\n      entry.labelHandle.dispose();\n      entry.labelHandle = null;\n    }\n  }\n\n  _updateDistanceFalloff(lat, lon) {\n    if (!Number.isFinite(lat) || !Number.isFinite(lon)) return;\n    const fadeStart = this.radiusM * 0.62;\n    const fadeEnd = this.radiusM * 1.18;\n    const fadeSpan = Math.max(1, fadeEnd - fadeStart);\n    for (const entry of this._entries.values()) {\n      const d = distanceM(lat, lon, entry.lat, entry.lon);\n      entry.distanceFromCenterM = d;\n      const fade = Math.max(0, Math.min(1, 1 - ((d - fadeStart) / fadeSpan)));\n      entry.falloff = fade;\n      if (entry.labelHandle?.group) {\n        entry.labelHandle.group.userData.businessFalloff = fade;\n        entry.labelHandle.opacity = fade;\n        entry.labelHandle.maxDistance = this._labelMaxDistanceM();\n        // Only LabelSystem owns group.visible (category, master, camera and\n        // admission gates). A producer update after that pass must not revive\n        // the business brackets while their category is disabled.\n        entry.labelHandle.sourceVisible = fade > 0.04;\n      }\n    }\n  }\n\n  _labelMaxDistanceM() {\n    const radiusBased = Number.isFinite(this.radiusM) ? this.radiusM * 4 : 0;\n    return Math.max(DEFAULT_LABEL_MAX_DISTANCE_M, radiusBased);\n  }\n\n  _enforceRetentionLimit() {\n    const maxRetained = Number.isFinite(this.maxRetained)\n      ? Math.max(1, Math.floor(this.maxRetained))\n      : DEFAULT_MAX_RETAINED;\n    if (this._entries.size <= maxRetained) return;\n    const entries = [...this._entries.entries()].sort((a, b) => {\n      const ageA = a[1].lastSeenMs || 0;\n      const ageB = b[1].lastSeenMs || 0;\n      if (ageA !== ageB) return ageA - ageB;\n      const distA = Number.isFinite(a[1].distanceFromCenterM) ? a[1].distanceFromCenterM : Infinity;\n      const distB = Number.isFinite(b[1].distanceFromCenterM) ? b[1].distanceFromCenterM : Infinity;\n      return distB - distA;\n    });\n    const removeCount = this._entries.size - maxRetained;\n    for (let i = 0; i < removeCount; i++) {\n      const [key, entry] = entries[i];\n      this._disposeEntry(entry);\n      this._entries.delete(key);\n    }\n  }\n\n  _ensureLabelSystem() {\n    if (!this._labelSystem) {\n      try {\n        this._labelSystem = getLabelSystem({ planetRadius: this.planetRadius });\n      } catch {\n        this._labelSystem = null;\n      }\n    }\n    return this._labelSystem;\n  }\n}\n\nlet _instance = null;\n\nexport function getBusinessLabels(opts) {\n  if (!_instance) _instance = new BusinessLabels(opts);\n  if (typeof opts?.mobile === 'boolean') _instance.setComplexityProfile({ mobile: opts.mobile });\n  if (opts?.parentGroup) _instance.activate(opts.parentGroup, { planetGroup: opts.planetGroup });\n  if (opts?.eventBus) _instance.eventBus = opts.eventBus;\n  if (opts?.surfaceController) _instance.surfaceController = opts.surfaceController;\n  if (Number.isFinite(opts?.planetRadius)) _instance.planetRadius = opts.planetRadius;\n  return _instance;\n}\n","/**\n * MotionTracker.js\n *\n * Captures user motion through the globe as two parallel tracks:\n *   1. GPS Track — Real device GPS positions (encrypted, user-only)\n *   2. Manual Track — Camera position from manual navigation\n *\n * Each sample contains full position + orientation profile:\n *   lat, lon, elevation_m, heading, pitch, quaternion, velocity, timestamp\n *\n * Samples are buffered in memory and flushed to the backend in batches.\n * Tracks are organized into sessions (start → stop = one session).\n *\n * Usage:\n *   const tracker = getMotionTracker({ scene, authService, eventBus });\n *   tracker.startSession('manual');\n *   // ... user navigates ...\n *   tracker.stopSession();\n *   tracker.getTrail('manual'); // → array of samples for rendering\n */\n\nimport { getAuthService } from '../auth/AuthService.js';\n\nconst DEFAULT_MANUAL_INTERVAL_MS = 1000;  // 1 Hz manual sampling\nconst DEFAULT_GPS_INTERVAL_MS = 2000;     // 0.5 Hz GPS sampling\nconst DEFAULT_FLUSH_INTERVAL_MS = 30000;  // Flush every 30s\nconst DEFAULT_FLUSH_BATCH_SIZE = 100;     // Or when 100 samples accumulated\nconst MIN_DISTANCE_M = 2;                 // Skip samples closer than 2m\n\n// ── Haversine distance (meters) ───────────────────────────────────────\n\nfunction haversineM(lat1, lon1, lat2, lon2) {\n  const R = 6371000;\n  const dLat = (lat2 - lat1) * Math.PI / 180;\n  const dLon = (lon2 - lon1) * Math.PI / 180;\n  const a = Math.sin(dLat / 2) ** 2 +\n    Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180) *\n    Math.sin(dLon / 2) ** 2;\n  return R * 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));\n}\n\n// ── MotionTracker class ───────────────────────────────────────────────\n\nexport class MotionTracker {\n  constructor({ scene, authService, eventBus } = {}) {\n    this.scene = scene || null;\n    this.authService = authService || getAuthService();\n    this.eventBus = eventBus || null;\n\n    // Active sessions: { manual: { id, startedAt, samples }, gps: { ... } }\n    this._sessions = { manual: null, gps: null };\n\n    // Completed sessions (not yet synced)\n    this._completedSessions = [];\n\n    // Intervals\n    this._manualTimer = null;\n    this._gpsTimer = null;\n    this._flushTimer = null;\n\n    // Configuration\n    this.manualIntervalMs = DEFAULT_MANUAL_INTERVAL_MS;\n    this.gpsIntervalMs = DEFAULT_GPS_INTERVAL_MS;\n    this.flushIntervalMs = DEFAULT_FLUSH_INTERVAL_MS;\n    this.flushBatchSize = DEFAULT_FLUSH_BATCH_SIZE;\n    this.minDistanceM = MIN_DISTANCE_M;\n\n    // GPS state (updated externally via setGpsPosition)\n    this._gpsLat = null;\n    this._gpsLon = null;\n    this._gpsAlt = null;\n    this._gpsAccuracy = null;\n    this._gpsTimestamp = 0;\n  }\n\n  // ── Session lifecycle ───────────────────────────────────────────────\n\n  /**\n   * Start a tracking session.\n   * @param {'manual'|'gps'|'both'} type\n   */\n  startSession(type = 'both') {\n    const sessionId = crypto.randomUUID();\n    const now = Date.now();\n\n    if (type === 'manual' || type === 'both') {\n      if (!this._sessions.manual) {\n        this._sessions.manual = { id: sessionId, startedAt: now, samples: [], lastSample: null };\n        this._startManualCapture();\n        console.info('[MotionTracker] Manual session started:', sessionId);\n      }\n    }\n\n    if (type === 'gps' || type === 'both') {\n      if (!this._sessions.gps) {\n        this._sessions.gps = { id: sessionId + '-gps', startedAt: now, samples: [], lastSample: null };\n        this._startGpsCapture();\n        console.info('[MotionTracker] GPS session started:', sessionId + '-gps');\n      }\n    }\n\n    // Start flush timer\n    if (!this._flushTimer) {\n      this._flushTimer = setInterval(() => this._flushToBackend(), this.flushIntervalMs);\n    }\n\n    this.eventBus?.emit?.('tracking:sessionStart', { type, sessionId });\n  }\n\n  /**\n   * Stop a tracking session.\n   * @param {'manual'|'gps'|'both'} type\n   */\n  stopSession(type = 'both') {\n    if (type === 'manual' || type === 'both') {\n      if (this._sessions.manual) {\n        this._stopManualCapture();\n        this._completedSessions.push({ ...this._sessions.manual, endedAt: Date.now() });\n        console.info('[MotionTracker] Manual session stopped:', this._sessions.manual.id, 'samples:', this._sessions.manual.samples.length);\n        this._sessions.manual = null;\n      }\n    }\n\n    if (type === 'gps' || type === 'both') {\n      if (this._sessions.gps) {\n        this._stopGpsCapture();\n        this._completedSessions.push({ ...this._sessions.gps, endedAt: Date.now() });\n        console.info('[MotionTracker] GPS session stopped:', this._sessions.gps.id, 'samples:', this._sessions.gps.samples.length);\n        this._sessions.gps = null;\n      }\n    }\n\n    // Stop flush timer if no active sessions\n    if (!this._sessions.manual && !this._sessions.gps && this._flushTimer) {\n      clearInterval(this._flushTimer);\n      this._flushTimer = null;\n      // Final flush\n      this._flushToBackend();\n    }\n\n    this.eventBus?.emit?.('tracking:sessionStop', { type });\n  }\n\n  isTracking(type = 'manual') {\n    return !!this._sessions[type];\n  }\n\n  // ── Get trail data (for rendering) ────────────────────────────────\n\n  /**\n   * Get all samples for the current or most recent session of a given type.\n   * @param {'manual'|'gps'} type\n   * @returns {Array} Array of MotionSample objects\n   */\n  getTrail(type = 'manual') {\n    const active = this._sessions[type];\n    if (active) return active.samples;\n\n    // Find most recent completed session of this type\n    for (let i = this._completedSessions.length - 1; i >= 0; i--) {\n      const sess = this._completedSessions[i];\n      if (sess.id.endsWith('-gps') ? type === 'gps' : type === 'manual') {\n        return sess.samples;\n      }\n    }\n    return [];\n  }\n\n  /**\n   * Get all completed sessions metadata.\n   */\n  getSessions() {\n    const sessions = [];\n    for (const sess of this._completedSessions) {\n      sessions.push({\n        id: sess.id,\n        type: sess.id.endsWith('-gps') ? 'gps' : 'manual',\n        startedAt: sess.startedAt,\n        endedAt: sess.endedAt,\n        sampleCount: sess.samples.length,\n      });\n    }\n    // Add active sessions\n    for (const [type, sess] of Object.entries(this._sessions)) {\n      if (sess) {\n        sessions.push({\n          id: sess.id,\n          type,\n          startedAt: sess.startedAt,\n          endedAt: null,\n          sampleCount: sess.samples.length,\n          active: true,\n        });\n      }\n    }\n    return sessions;\n  }\n\n  // ── GPS input (called externally by DeviceSensorPanel) ────────────\n\n  setGpsPosition(lat, lon, altitude, accuracy) {\n    this._gpsLat = lat;\n    this._gpsLon = lon;\n    this._gpsAlt = altitude;\n    this._gpsAccuracy = accuracy;\n    this._gpsTimestamp = Date.now();\n  }\n\n  // ── Manual capture (camera position) ──────────────────────────────\n\n  _startManualCapture() {\n    this._manualTimer = setInterval(() => {\n      this._captureManualSample();\n    }, this.manualIntervalMs);\n  }\n\n  _stopManualCapture() {\n    if (this._manualTimer) {\n      clearInterval(this._manualTimer);\n      this._manualTimer = null;\n    }\n  }\n\n  _captureManualSample() {\n    const session = this._sessions.manual;\n    if (!session || !this.scene) return;\n\n    // Get camera position from scene\n    const camera = this.scene._camera;\n    if (!camera) return;\n\n    const camPos = camera.userData?.worldPosition || camera.position;\n    if (!camPos || camPos.lengthSq() === 0) return;\n\n    // Use scene's own lat/lon if available (most accurate)\n    const sceneApi = this.scene?.api;\n    let latDeg, lonDeg, elevationM;\n\n    if (sceneApi?.camera?.latitude != null) {\n      latDeg = sceneApi.camera.latitude;\n      lonDeg = sceneApi.camera.longitude;\n      elevationM = sceneApi.camera.altitude || 0;\n    } else {\n      // Fallback: compute from camera world position\n      const dir = camPos.clone().normalize();\n      const WGS84_ONE_MINUS_E2 = 0.99330562;\n      latDeg = Math.atan2(dir.y / WGS84_ONE_MINUS_E2,\n        Math.sqrt(dir.x * dir.x + dir.z * dir.z)) * 180 / Math.PI;\n      lonDeg = Math.atan2(dir.x, dir.z) * 180 / Math.PI;\n      const radius = camPos.length();\n      elevationM = radius - 6378137.0;\n    }\n\n    // Get camera quaternion\n    const quat = camera.quaternion;\n\n    // Heading from camera forward vector\n    const fwd = { x: 0, y: 0, z: -1 };\n    // Apply quaternion to forward\n    const headingDeg = Math.atan2(\n      2 * (quat.w * quat.y + quat.x * quat.z),\n      1 - 2 * (quat.y * quat.y + quat.z * quat.z)\n    ) * 180 / Math.PI;\n\n    const sample = {\n      timestamp: Date.now(),\n      lat: latDeg,\n      lon: lonDeg,\n      elevation_m: elevationM,\n      heading_deg: ((headingDeg % 360) + 360) % 360,\n      pitch_deg: Math.asin(2 * (quat.w * quat.x - quat.z * quat.y)) * 180 / Math.PI,\n      quaternion: [quat.x, quat.y, quat.z, quat.w],\n      velocity_mps: 0, // Computed from delta\n      source: 'manual',\n    };\n\n    // Compute velocity from previous sample\n    if (session.lastSample) {\n      const dt = (sample.timestamp - session.lastSample.timestamp) / 1000;\n      if (dt > 0) {\n        const dist = haversineM(session.lastSample.lat, session.lastSample.lon, sample.lat, sample.lon);\n        sample.velocity_mps = dist / dt;\n\n        // Skip if too close (deduplicate stationary samples)\n        if (dist < this.minDistanceM) return;\n      }\n    }\n\n    session.samples.push(sample);\n    session.lastSample = sample;\n\n    this.eventBus?.emit?.('tracking:sample', { type: 'manual', sample });\n  }\n\n  // ── GPS capture ───────────────────────────────────────────────────\n\n  _startGpsCapture() {\n    this._gpsTimer = setInterval(() => {\n      this._captureGpsSample();\n    }, this.gpsIntervalMs);\n  }\n\n  _stopGpsCapture() {\n    if (this._gpsTimer) {\n      clearInterval(this._gpsTimer);\n      this._gpsTimer = null;\n    }\n  }\n\n  _captureGpsSample() {\n    const session = this._sessions.gps;\n    if (!session) return;\n    if (!Number.isFinite(this._gpsLat) || !Number.isFinite(this._gpsLon)) return;\n\n    const sample = {\n      timestamp: this._gpsTimestamp || Date.now(),\n      lat: this._gpsLat,\n      lon: this._gpsLon,\n      elevation_m: this._gpsAlt || 0,\n      heading_deg: 0,\n      pitch_deg: 0,\n      quaternion: [0, 0, 0, 1],\n      velocity_mps: 0,\n      source: 'gps',\n      accuracy_m: this._gpsAccuracy,\n    };\n\n    // Compute velocity + heading from GPS delta\n    if (session.lastSample) {\n      const dt = (sample.timestamp - session.lastSample.timestamp) / 1000;\n      if (dt > 0) {\n        const dist = haversineM(session.lastSample.lat, session.lastSample.lon, sample.lat, sample.lon);\n        sample.velocity_mps = dist / dt;\n\n        if (dist > 1) {\n          sample.heading_deg = Math.atan2(\n            sample.lon - session.lastSample.lon,\n            sample.lat - session.lastSample.lat\n          ) * 180 / Math.PI;\n          sample.heading_deg = ((sample.heading_deg % 360) + 360) % 360;\n        }\n\n        if (dist < this.minDistanceM) return;\n      }\n    }\n\n    session.samples.push(sample);\n    session.lastSample = sample;\n\n    this.eventBus?.emit?.('tracking:sample', { type: 'gps', sample });\n  }\n\n  // ── Backend flush ─────────────────────────────────────────────────\n\n  async _flushToBackend() {\n    if (!this.authService?.accessToken) return;\n\n    for (const type of ['manual', 'gps']) {\n      const session = this._sessions[type];\n      if (!session || session.samples.length === 0) continue;\n\n      // Take samples that haven't been flushed yet\n      const unflushed = session.samples.slice(session._flushedCount || 0);\n      if (unflushed.length === 0) continue;\n\n      try {\n        const resp = await this.authService.authenticatedFetch?.('/api/motion/batch', {\n          method: 'POST',\n          headers: { 'Content-Type': 'application/json' },\n          body: JSON.stringify({\n            session_id: session.id,\n            track_type: type,\n            samples: unflushed,\n          }),\n        });\n\n        if (resp?.ok) {\n          session._flushedCount = session.samples.length;\n          console.info(`[MotionTracker] Flushed ${unflushed.length} ${type} samples`);\n        }\n      } catch (err) {\n        console.warn(`[MotionTracker] Flush failed for ${type}:`, err.message);\n      }\n    }\n  }\n\n  // ── Cleanup ───────────────────────────────────────────────────────\n\n  dispose() {\n    this.stopSession('both');\n    this._completedSessions = [];\n  }\n}\n\n// ── Singleton ───────────────────────────────────────────────────────\n\nlet _instance = null;\n\nexport function getMotionTracker(opts) {\n  if (!_instance) _instance = new MotionTracker(opts);\n  return _instance;\n}\n","/**\n * RouteProgressTracker — snap the live player position to the active route\n * polyline, compute distance along, distance remaining, which step is\n * \"current\", and the bearing to the next maneuver.\n *\n * Consumed by NavBanner, RouteRibbonRenderer, and the minimap layer via\n * RouteStore events.\n *\n * Math is plain haversine on the sphere — fine for the scales we care\n * about (street networks of any city).\n */\n\nconst EARTH_R = 6371000;\nconst OFF_ROUTE_THRESHOLD_M = 50;       // >50m from polyline = off-route\nconst RECOMPUTE_COOLDOWN_MS = 30_000;   // rate-limit auto-reroute requests\n\nfunction toRad(d) { return d * Math.PI / 180; }\nfunction toDeg(r) { return r * 180 / Math.PI; }\n\nexport function haversineM(lat1, lon1, lat2, lon2) {\n  const dLat = toRad(lat2 - lat1);\n  const dLon = toRad(lon2 - lon1);\n  const a = Math.sin(dLat / 2) ** 2\n    + Math.cos(toRad(lat1)) * Math.cos(toRad(lat2)) * Math.sin(dLon / 2) ** 2;\n  return EARTH_R * 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));\n}\n\nexport function bearingDeg(lat1, lon1, lat2, lon2) {\n  const y = Math.sin(toRad(lon2 - lon1)) * Math.cos(toRad(lat2));\n  const x = Math.cos(toRad(lat1)) * Math.sin(toRad(lat2))\n    - Math.sin(toRad(lat1)) * Math.cos(toRad(lat2)) * Math.cos(toRad(lon2 - lon1));\n  return (toDeg(Math.atan2(y, x)) + 360) % 360;\n}\n\n/**\n * Snap a point onto the closest segment of a polyline (array of [lon,lat]).\n * Uses a small-angle planar approximation within each segment — safe for\n * segments < a few km (typical road links).\n *\n * Returns: { segmentIndex, t, lat, lon, distanceM }\n *   segmentIndex — index of segment start\n *   t — interpolation parameter ∈ [0,1] along that segment\n *   lat/lon — the snapped point\n *   distanceM — perpendicular distance from input to polyline\n */\nexport function snapToPolyline(coords, lat, lon) {\n  if (!coords || coords.length < 2) return null;\n  let best = null;\n  for (let i = 0; i < coords.length - 1; i++) {\n    const [lon1, lat1] = coords[i];\n    const [lon2, lat2] = coords[i + 1];\n    // Project point (lat,lon) onto segment (1→2) using local equirectangular\n    // approximation with the segment midpoint as the tangent origin.\n    const midLat = (lat1 + lat2) / 2;\n    const kx = Math.cos(toRad(midLat)) * 111319.9; // metres per degree lon\n    const ky = 110574.0;                           // metres per degree lat\n    const ax = (lon1) * kx;\n    const ay = (lat1) * ky;\n    const bx = (lon2) * kx;\n    const by = (lat2) * ky;\n    const px = (lon) * kx;\n    const py = (lat) * ky;\n    const dx = bx - ax;\n    const dy = by - ay;\n    const segLenSq = dx * dx + dy * dy;\n    let t = 0;\n    if (segLenSq > 1e-9) t = ((px - ax) * dx + (py - ay) * dy) / segLenSq;\n    t = Math.max(0, Math.min(1, t));\n    const qx = ax + t * dx;\n    const qy = ay + t * dy;\n    const snappedLon = qx / kx;\n    const snappedLat = qy / ky;\n    const distM = haversineM(lat, lon, snappedLat, snappedLon);\n    if (!best || distM < best.distanceM) {\n      best = { segmentIndex: i, t, lat: snappedLat, lon: snappedLon, distanceM: distM };\n    }\n  }\n  return best;\n}\n\n/**\n * Pre-computed cumulative distances along a coord list.\n */\nexport function buildCumulativeDistances(coords) {\n  if (!coords || coords.length < 2) return new Float64Array(coords?.length || 0);\n  const out = new Float64Array(coords.length);\n  let total = 0;\n  for (let i = 1; i < coords.length; i++) {\n    const [lon1, lat1] = coords[i - 1];\n    const [lon2, lat2] = coords[i];\n    total += haversineM(lat1, lon1, lat2, lon2);\n    out[i] = total;\n  }\n  return out;\n}\n\n/**\n * Main tracker class. Instantiate with a route, feed it GPS updates, it\n * pushes progress snapshots into the supplied RouteStore.\n */\nexport class RouteProgressTracker {\n  constructor({ store }) {\n    this._store = store;\n    this._route = null;\n    this._coords = null;\n    this._cumulative = null;\n    this._stepIndex = new Int32Array(0); // coord index → step index (advancing)\n    this._lastOffRouteRequestMs = 0;\n    this._onRouteSet = () => this._bindRoute();\n    this._onRouteCleared = () => this._clear();\n    this._subscribe();\n  }\n\n  dispose() {\n    this._unsubscribe();\n    this._clear();\n  }\n\n  _subscribe() {\n    if (typeof document !== 'undefined' && document.addEventListener) {\n      document.addEventListener('noclip:route:set', this._onRouteSet);\n      document.addEventListener('noclip:route:cleared', this._onRouteCleared);\n    }\n  }\n  _unsubscribe() {\n    if (typeof document !== 'undefined' && document.removeEventListener) {\n      document.removeEventListener('noclip:route:set', this._onRouteSet);\n      document.removeEventListener('noclip:route:cleared', this._onRouteCleared);\n    }\n  }\n\n  _clear() {\n    this._route = null;\n    this._coords = null;\n    this._cumulative = null;\n    this._stepIndex = new Int32Array(0);\n  }\n\n  _bindRoute() {\n    const route = this._store?.getRoute?.();\n    if (!route?.geometry?.coordinates?.length) return this._clear();\n    this._route = route;\n    this._coords = route.geometry.coordinates;\n    this._cumulative = buildCumulativeDistances(this._coords);\n    // Map each coord index to the step index whose \"point\" it is closest to —\n    // lets us look up \"what step am I inside\" in O(1) from the snapped point.\n    const steps = route.steps || [];\n    this._stepIndex = new Int32Array(this._coords.length);\n    let s = 0;\n    for (let i = 0; i < this._coords.length; i++) {\n      // advance s while the next step's point is behind or equal to this coord\n      while (s + 1 < steps.length) {\n        const nextStep = steps[s + 1];\n        if (!nextStep?.point) break;\n        const [slon, slat] = nextStep.point;\n        const [clon, clat] = this._coords[i];\n        // If nextStep's point is very close to the current coord (≤5m), advance.\n        const distToNext = haversineM(clat, clon, slat, slon);\n        if (distToNext < 5) { s++; continue; }\n        break;\n      }\n      this._stepIndex[i] = s;\n    }\n  }\n\n  /**\n   * Feed a live player position. Returns the snapshot that was written to\n   * the store (or null if no active route).\n   */\n  update(lat, lon) {\n    if (!this._route || !this._coords?.length) return null;\n    const snap = snapToPolyline(this._coords, lat, lon);\n    if (!snap) return null;\n\n    // Compute distance along = cumulative[segmentIndex] + t * segmentLength\n    const [lon1, lat1] = this._coords[snap.segmentIndex];\n    const [lon2, lat2] = this._coords[snap.segmentIndex + 1];\n    const segLen = haversineM(lat1, lon1, lat2, lon2);\n    const distanceAlong = this._cumulative[snap.segmentIndex] + snap.t * segLen;\n    const totalDist = this._route.distance || this._cumulative[this._cumulative.length - 1];\n    const distanceRemaining = Math.max(0, totalDist - distanceAlong);\n\n    // Per-unit-length time estimate\n    const remainingFraction = totalDist > 0 ? distanceRemaining / totalDist : 0;\n    const durationRemaining = (this._route.duration || 0) * remainingFraction;\n\n    // Which step is \"next\" — the first step whose point lies ahead on the polyline\n    const currentStepIdx = this._stepIndex[snap.segmentIndex] ?? 0;\n    let nextStepIndex = Math.min(currentStepIdx + 1, (this._route.steps?.length || 1) - 1);\n    // If currentStepIdx is the last step, keep it.\n    if (nextStepIndex <= currentStepIdx) nextStepIndex = currentStepIdx;\n\n    // Distance to the next step's point (if it exists ahead)\n    let distanceToNextStep = 0;\n    const nextStep = this._route.steps?.[nextStepIndex];\n    if (nextStep?.point) {\n      const [nlon, nlat] = nextStep.point;\n      distanceToNextStep = haversineM(snap.lat, snap.lon, nlat, nlon);\n    }\n\n    // Bearing from snapped position to the next coord on the polyline\n    const lookahead = this._coords[Math.min(snap.segmentIndex + 1, this._coords.length - 1)];\n    const bearing = bearingDeg(snap.lat, snap.lon, lookahead[1], lookahead[0]);\n\n    const offRoute = snap.distanceM > OFF_ROUTE_THRESHOLD_M;\n    const shouldReroute = offRoute && (Date.now() - this._lastOffRouteRequestMs) > RECOMPUTE_COOLDOWN_MS;\n    if (shouldReroute) this._lastOffRouteRequestMs = Date.now();\n\n    const snapshot = {\n      distanceAlong,\n      distanceRemaining,\n      durationRemaining,\n      currentStepIndex: currentStepIdx,\n      nextStepIndex,\n      distanceToNextStep,\n      bearingDeg: bearing,\n      snapped: { lat: snap.lat, lon: snap.lon },\n      snapDistanceM: snap.distanceM,\n      offRoute,\n      shouldReroute,\n    };\n    this._store?.updateProgress?.(snapshot);\n    return snapshot;\n  }\n}\n\nexport const __internal = { snapToPolyline, buildCumulativeDistances, bearingDeg, haversineM };\n","import { getMapTileApiBase } from '../shared/backend.js';\n\nconst TILE_ZOOM = 14;\nconst TILE_VERSION = '20260828.1';\nconst MAX_CACHE_ENTRIES = 48;\nconst MAX_MATCH_DISTANCE_M = 85;\nconst MAX_ROAD_AUDIO_DISTANCE_M = 450;\nconst UPDATE_INTERVAL_MS = 700;\nconst EARTH_METERS_PER_DEGREE = 111_319.9;\n\nlet decoderPromise = null;\n\nfunction decoder() {\n  decoderPromise ||= Promise.all([\n    import('@mapbox/vector-tile'),\n    import('pbf'),\n  ]).then(([vectorModule, pbfModule]) => ({\n    VectorTile: vectorModule.VectorTile,\n    Pbf: pbfModule.default,\n  }));\n  return decoderPromise;\n}\n\nexport function lonLatToTile(lon, lat, zoom = TILE_ZOOM) {\n  const count = 2 ** zoom;\n  const safeLat = Math.max(-85.05112878, Math.min(85.05112878, Number(lat)));\n  const wrappedLon = ((((Number(lon) + 180) % 360) + 360) % 360) - 180;\n  const xFloat = ((wrappedLon + 180) / 360) * count;\n  const latitudeRad = safeLat * Math.PI / 180;\n  const yFloat = (1 - Math.asinh(Math.tan(latitudeRad)) / Math.PI) * count / 2;\n  return {\n    z: zoom,\n    x: Math.max(0, Math.min(count - 1, Math.floor(xFloat))),\n    y: Math.max(0, Math.min(count - 1, Math.floor(yFloat))),\n    xFraction: xFloat - Math.floor(xFloat),\n    yFraction: yFloat - Math.floor(yFloat),\n  };\n}\n\nfunction wrappedLonDelta(value) {\n  return ((((value + 180) % 360) + 360) % 360) - 180;\n}\n\nfunction segmentDistance(point, start, end) {\n  const cosLat = Math.max(0.01, Math.cos(point.lat * Math.PI / 180));\n  const ax = wrappedLonDelta(start[0] - point.lon) * EARTH_METERS_PER_DEGREE * cosLat;\n  const ay = (start[1] - point.lat) * EARTH_METERS_PER_DEGREE;\n  const bx = wrappedLonDelta(end[0] - point.lon) * EARTH_METERS_PER_DEGREE * cosLat;\n  const by = (end[1] - point.lat) * EARTH_METERS_PER_DEGREE;\n  const dx = bx - ax;\n  const dy = by - ay;\n  const lengthSq = dx * dx + dy * dy;\n  const t = lengthSq > 1e-9 ? Math.max(0, Math.min(1, -(ax * dx + ay * dy) / lengthSq)) : 0;\n  const qx = ax + t * dx;\n  const qy = ay + t * dy;\n  return {\n    distanceM: Math.hypot(qx, qy),\n    bearingDeg: (Math.atan2(dx, dy) * 180 / Math.PI + 360) % 360,\n    snapped: {\n      lon: point.lon + (qx / (EARTH_METERS_PER_DEGREE * cosLat)),\n      lat: point.lat + (qy / EARTH_METERS_PER_DEGREE),\n    },\n  };\n}\n\nfunction headingDifference(a, b) {\n  let difference = Math.abs((((a - b) % 360) + 540) % 360 - 180);\n  if (difference > 90) difference = 180 - difference;\n  return Math.abs(difference);\n}\n\nfunction profileAllows(properties, profile) {\n  const roadClass = String(properties?.class || '').toLowerCase();\n  const subclass = String(properties?.subclass || '').toLowerCase();\n  if (profile === 'driving') {\n    if (roadClass === 'path' || ['footway', 'pedestrian', 'steps', 'cycleway'].includes(subclass)) return false;\n    return properties?.access !== 'no';\n  }\n  if (profile === 'cycling') {\n    return roadClass !== 'motorway' && properties?.bicycle !== 'no' && properties?.access !== 'no';\n  }\n  if (profile === 'foot') {\n    return roadClass !== 'motorway' && properties?.foot !== 'no' && properties?.access !== 'no';\n  }\n  return true;\n}\n\nfunction featureLines(feature) {\n  if (!feature?.geometry) return [];\n  if (feature.geometry.type === 'LineString') return [feature.geometry.coordinates];\n  if (feature.geometry.type === 'MultiLineString') return feature.geometry.coordinates;\n  return [];\n}\n\nfunction displayName(properties) {\n  return String(\n    properties?.name\n    || properties?.name_en\n    || properties?.name_int\n    || properties?.ref\n    || '',\n  ).trim();\n}\n\nexport function findNearestRoadContext(features, point, options = {}) {\n  const heading = Number(options.headingDeg);\n  const useHeading = Number.isFinite(heading) && Number(options.speedMps || 0) >= 0.8;\n  const profile = options.profile || 'driving';\n  const previous = options.previous || null;\n  const candidates = [];\n\n  for (const feature of features || []) {\n    const properties = feature?.properties || {};\n    if (!profileAllows(properties, profile)) continue;\n    for (const line of featureLines(feature)) {\n      for (let index = 0; index < line.length - 1; index += 1) {\n        const segment = segmentDistance(point, line[index], line[index + 1]);\n        if (segment.distanceM > MAX_MATCH_DISTANCE_M) continue;\n        const headingPenalty = useHeading ? headingDifference(heading, segment.bearingDeg) * 0.16 : 0;\n        const name = displayName(properties);\n        // Prefer a nearby named carriageway/path over an unnamed parallel\n        // geometry unless the unnamed segment is materially closer.\n        const unnamedPenalty = name ? 0 : 12;\n        candidates.push({\n          feature,\n          properties,\n          ...segment,\n          score: segment.distanceM + headingPenalty + unnamedPenalty,\n          name,\n        });\n      }\n    }\n  }\n  if (!candidates.length) return null;\n  candidates.sort((a, b) => a.score - b.score || a.distanceM - b.distanceM);\n  let best = candidates[0];\n  if (previous?.name) {\n    const stable = candidates.find((candidate) => candidate.name === previous.name);\n    if (stable && stable.score <= best.score + 5) best = stable;\n  }\n  const props = best.properties;\n  return {\n    name: best.name || null,\n    ref: props.ref || null,\n    class: props.class || null,\n    subclass: props.subclass || null,\n    network: props.network || null,\n    surface: props.surface || null,\n    oneway: props.oneway === 1 || props.oneway === '1' || props.oneway === true,\n    access: props.access || null,\n    foot: props.foot || null,\n    bicycle: props.bicycle || null,\n    distanceM: best.distanceM,\n    bearingDeg: best.bearingDeg,\n    snapped: best.snapped,\n    source: 'openmaptiles-local',\n    confidence: Math.max(0, Math.min(1, 1 - best.score / MAX_MATCH_DISTANCE_M)),\n  };\n}\n\nexport function findNearbyRoadSoundSources(features, point, options = {}) {\n  const maxDistanceM = Number.isFinite(options.maxDistanceM)\n    ? Math.max(25, options.maxDistanceM)\n    : MAX_ROAD_AUDIO_DISTANCE_M;\n  const maxSources = Number.isFinite(options.maxSources) ? Math.max(1, options.maxSources) : 8;\n  const candidates = [];\n\n  for (const feature of features || []) {\n    const properties = feature?.properties || {};\n    if (!profileAllows(properties, 'driving')) continue;\n    let best = null;\n    for (const line of featureLines(feature)) {\n      for (let index = 0; index < line.length - 1; index += 1) {\n        const segment = segmentDistance(point, line[index], line[index + 1]);\n        if (segment.distanceM <= maxDistanceM && (!best || segment.distanceM < best.distanceM)) {\n          best = { ...segment, line };\n        }\n      }\n    }\n    if (!best) continue;\n    const name = displayName(properties);\n    candidates.push({\n      id: `${properties.ref || name || properties.class || 'road'}:${best.snapped.lat.toFixed(4)}:${best.snapped.lon.toFixed(4)}`,\n      name: name || null,\n      ref: properties.ref || null,\n      class: properties.class || null,\n      subclass: properties.subclass || null,\n      surface: properties.surface || null,\n      oneway: properties.oneway === 1 || properties.oneway === '1' || properties.oneway === true,\n      distanceM: best.distanceM,\n      bearingDeg: best.bearingDeg,\n      lat: best.snapped.lat,\n      lon: best.snapped.lon,\n      path: simplifyCoordinatePath(best.line, 64),\n      source: 'openmaptiles-local',\n    });\n  }\n\n  candidates.sort((a, b) => a.distanceM - b.distanceM);\n  const unique = [];\n  const seen = new Set();\n  for (const candidate of candidates) {\n    const key = `${candidate.ref || candidate.name || candidate.class || 'road'}:${candidate.lat.toFixed(4)}:${candidate.lon.toFixed(4)}`;\n    if (seen.has(key)) continue;\n    seen.add(key);\n    unique.push(candidate);\n    if (unique.length >= maxSources) break;\n  }\n  return unique;\n}\n\nfunction simplifyCoordinatePath(line, limit) {\n  if (!Array.isArray(line) || line.length < 2) return [];\n  if (line.length <= limit) return line.map(([lon, lat]) => [Number(lon), Number(lat)]);\n  const out = [];\n  for (let index = 0; index < limit; index += 1) {\n    const sourceIndex = Math.round((index / (limit - 1)) * (line.length - 1));\n    const [lon, lat] = line[sourceIndex] || [];\n    if (Number.isFinite(lon) && Number.isFinite(lat)) out.push([lon, lat]);\n  }\n  return out;\n}\n\nfunction pointInRing(point, ring) {\n  let inside = false;\n  for (let index = 0, previous = ring.length - 1; index < ring.length; previous = index++) {\n    const [x, y] = ring[index] || [];\n    const [px, py] = ring[previous] || [];\n    if (((y > point.lat) !== (py > point.lat))\n      && point.lon < ((px - x) * (point.lat - y)) / ((py - y) || 1e-12) + x) inside = !inside;\n  }\n  return inside;\n}\n\nfunction geometryLines(geometry) {\n  if (!geometry) return [];\n  if (geometry.type === 'LineString') return [geometry.coordinates];\n  if (geometry.type === 'MultiLineString' || geometry.type === 'Polygon') return geometry.coordinates;\n  if (geometry.type === 'MultiPolygon') return geometry.coordinates.flat();\n  if (geometry.type === 'Point') return [[geometry.coordinates, geometry.coordinates]];\n  return [];\n}\n\nfunction nearestPointOnFeature(feature, point) {\n  const lines = geometryLines(feature?.geometry);\n  const inside = (feature?.geometry?.type === 'Polygon' || feature?.geometry?.type === 'MultiPolygon')\n    && lines.some((ring) => pointInRing(point, ring));\n  let closest = { distanceM: Infinity, lat: null, lon: null };\n  for (const line of lines) {\n    for (let index = 0; index < line.length - 1; index += 1) {\n      const segment = segmentDistance(point, line[index], line[index + 1]);\n      if (segment.distanceM < closest.distanceM) closest = { distanceM: segment.distanceM, ...segment.snapped };\n    }\n  }\n  if (inside && Number.isFinite(closest.distanceM)) {\n    // Keep the acoustic anchor tied to the mapped polygon rather than to the\n    // listener. For large polygons, select a point a bounded distance toward\n    // the nearest boundary so an in-park listener still hears a spatial source.\n    const t = Math.min(1, 24 / Math.max(0.001, closest.distanceM));\n    return {\n      distanceM: 0,\n      lat: point.lat + (closest.lat - point.lat) * t,\n      lon: point.lon + (closest.lon - point.lon) * t,\n    };\n  }\n  return closest;\n}\n\nfunction distanceToFeature(feature, point) { return nearestPointOnFeature(feature, point).distanceM; }\n\nexport function findNearbyHabitatContext(features, point, options = {}) {\n  const limit = Number.isFinite(options.maxDistanceM) ? Math.max(100, options.maxDistanceM) : 1800;\n  let greenSpace = { distanceM: Infinity, lat: null, lon: null };\n  let nearestWater = { distanceM: Infinity, lat: null, lon: null };\n  const greenClasses = /park|wood|forest|grass|meadow|garden|recreation|nature_reserve|scrub|wetland/;\n  const waterClasses = /water|river|stream|canal|lake|pond|wetland|reservoir/;\n  for (const feature of features || []) {\n    const properties = feature?.properties || {};\n    const layer = String(properties._layer || '').toLowerCase();\n    const classification = [properties.class, properties.subclass, properties.type, properties.natural,\n      properties.landuse, properties.leisure, properties.waterway].filter(Boolean).join(' ').toLowerCase();\n    const green = /landcover|landuse|park/.test(layer) && greenClasses.test(classification);\n    const water = /water|waterway/.test(layer) || waterClasses.test(classification);\n    if (!green && !water) continue;\n    const nearest = nearestPointOnFeature(feature, point);\n    if (green && nearest.distanceM < greenSpace.distanceM) greenSpace = nearest;\n    if (water && nearest.distanceM < nearestWater.distanceM) nearestWater = nearest;\n  }\n  return {\n    greenSpaceDistanceM: greenSpace.distanceM <= limit ? greenSpace.distanceM : null,\n    greenSpacePosition: greenSpace.distanceM <= limit ? { lat: greenSpace.lat, lon: greenSpace.lon } : null,\n    waterDistanceM: nearestWater.distanceM <= limit ? nearestWater.distanceM : null,\n    waterPosition: nearestWater.distanceM <= limit ? { lat: nearestWater.lat, lon: nearestWater.lon } : null,\n    source: 'openmaptiles-local',\n  };\n}\n\nfunction neighborTiles(position, lat) {\n  const count = 2 ** position.z;\n  const tileWidthM = Math.cos(lat * Math.PI / 180) * 2 * Math.PI * 6_378_137 / count;\n  const threshold = Math.min(0.2, 100 / Math.max(1, tileWidthM));\n  const offsetsX = [0];\n  const offsetsY = [0];\n  if (position.xFraction < threshold) offsetsX.push(-1);\n  if (position.xFraction > 1 - threshold) offsetsX.push(1);\n  if (position.yFraction < threshold) offsetsY.push(-1);\n  if (position.yFraction > 1 - threshold) offsetsY.push(1);\n  const tiles = [];\n  for (const offsetX of offsetsX) {\n    for (const offsetY of offsetsY) {\n      const x = ((position.x + offsetX) % count + count) % count;\n      const y = position.y + offsetY;\n      if (y >= 0 && y < count) tiles.push({ z: position.z, x, y });\n    }\n  }\n  return tiles;\n}\n\nexport class RoadContextService {\n  constructor({ onUpdate = null, onSoundscapeUpdate = null, fetchImpl = null } = {}) {\n    this._onUpdate = onUpdate;\n    this._onSoundscapeUpdate = onSoundscapeUpdate;\n    // Browser fetch requires its Window receiver in Chromium/WebKit. Keep the\n    // default as a wrapper instead of storing an unbound function reference.\n    this._fetch = fetchImpl || ((...args) => globalThis.fetch(...args));\n    this._cache = new Map();\n    this._inFlight = new Map();\n    this._current = null;\n    this._nearbyRoads = [];\n    this._habitatContext = null;\n    this._queued = null;\n    this._draining = false;\n    this._lastStartedAt = 0;\n    this._disposed = false;\n  }\n\n  getCurrent() {\n    return this._current;\n  }\n\n  getNearbyRoads() {\n    return this._nearbyRoads.slice();\n  }\n\n  getHabitatContext() { return this._habitatContext ? { ...this._habitatContext } : null; }\n\n  update(lat, lon, options = {}) {\n    if (this._disposed || !Number.isFinite(lat) || !Number.isFinite(lon)) return;\n    this._queued = { lat, lon, options };\n    if (!this._draining) void this._drain();\n  }\n\n  clear() {\n    this._queued = null;\n    this._current = null;\n    this._nearbyRoads = [];\n    this._habitatContext = null;\n    this._publish(null);\n    this._publishSoundscape([]);\n  }\n\n  dispose() {\n    this._disposed = true;\n    this._queued = null;\n    this._cache.clear();\n    this._inFlight.clear();\n  }\n\n  async _drain() {\n    this._draining = true;\n    try {\n      while (!this._disposed && this._queued) {\n        const request = this._queued;\n        this._queued = null;\n        const waitMs = UPDATE_INTERVAL_MS - (Date.now() - this._lastStartedAt);\n        if (waitMs > 0) await new Promise((resolve) => setTimeout(resolve, waitMs));\n        if (this._disposed) break;\n        this._lastStartedAt = Date.now();\n        try {\n          const { context, nearbyRoads, habitatContext } = await this._resolve(request.lat, request.lon, request.options);\n          if (!this._queued) {\n            this._current = context;\n            this._nearbyRoads = nearbyRoads;\n            this._habitatContext = habitatContext;\n            this._publish(context);\n            this._publishSoundscape(nearbyRoads, habitatContext);\n          }\n        } catch {\n          // Keep the last known road through a transient tile/network failure.\n        }\n      }\n    } finally {\n      this._draining = false;\n      if (!this._disposed && this._queued) void this._drain();\n    }\n  }\n\n  async _resolve(lat, lon, options) {\n    const position = lonLatToTile(lon, lat);\n    const tiles = neighborTiles(position, lat);\n    const decoded = await Promise.all(tiles.map((tile) => this._loadTile(tile)));\n    const features = decoded.flatMap((entry) => entry.features);\n    return {\n      context: findNearestRoadContext(features, { lat, lon }, {\n        ...options,\n        previous: this._current,\n      }),\n      nearbyRoads: findNearbyRoadSoundSources(features, { lat, lon }),\n      habitatContext: findNearbyHabitatContext(features, { lat, lon }),\n    };\n  }\n\n  async _loadTile(tile) {\n    const key = `${tile.z}/${tile.x}/${tile.y}`;\n    const cached = this._cache.get(key);\n    if (cached) {\n      this._cache.delete(key);\n      this._cache.set(key, cached);\n      return cached;\n    }\n    if (this._inFlight.has(key)) return this._inFlight.get(key);\n    const pending = this._fetchAndDecode(tile).finally(() => this._inFlight.delete(key));\n    this._inFlight.set(key, pending);\n    return pending;\n  }\n\n  async _fetchAndDecode(tile) {\n    const base = String(getMapTileApiBase()).replace(/\\/+$/, '');\n    const response = await this._fetch(\n      `${base}/tiles/vector/${tile.z}/${tile.x}/${tile.y}.pbf?v=${TILE_VERSION}`,\n      { headers: { Accept: 'application/vnd.mapbox-vector-tile' } },\n    );\n    if (!response.ok) throw new Error(`Road vector tile failed (${response.status})`);\n    const { VectorTile, Pbf } = await decoder();\n    const vectorTile = new VectorTile(new Pbf(new Uint8Array(await response.arrayBuffer())));\n    const features = [];\n    for (const layerId of ['transportation_name', 'transportation', 'water', 'waterway', 'landcover', 'landuse', 'park']) {\n      const layer = vectorTile.layers[layerId];\n      if (!layer) continue;\n      for (let index = 0; index < layer.length; index += 1) {\n        const feature = layer.feature(index).toGeoJSON(tile.x, tile.y, tile.z);\n        if (feature?.geometry) {\n          feature.properties = { ...(feature.properties || {}), _layer: layerId };\n          features.push(feature);\n        }\n      }\n    }\n    const entry = { features };\n    this._cache.set(`${tile.z}/${tile.x}/${tile.y}`, entry);\n    while (this._cache.size > MAX_CACHE_ENTRIES) {\n      this._cache.delete(this._cache.keys().next().value);\n    }\n    return entry;\n  }\n\n  _publish(context) {\n    try { this._onUpdate?.(context); } catch {}\n    try {\n      document.dispatchEvent(new CustomEvent('noclip:road-context', { detail: context }));\n    } catch {}\n  }\n\n\n  _publishSoundscape(roads, habitat = null) {\n    try { this._onSoundscapeUpdate?.(roads, habitat); } catch {}\n  }\n}\n\nexport const __internal = {\n  segmentDistance,\n  headingDifference,\n  neighborTiles,\n  profileAllows,\n  distanceToFeature,\n  nearestPointOnFeature,\n};\n","/**\n * ScenePuppetController\n *\n * A small, bounded facade for browser/debug agents that need to exercise the\n * scene as a traveller rather than mutate camera internals. It deliberately\n * owns no DOM and delegates all rendering to PlanetScene's surface adapter.\n *\n * Real-time defaults model a 30 mph city car. `simulate()` is virtual time for\n * deterministic route coverage; it is not a hidden background movement loop.\n */\n\nimport { buildCumulativeDistances, bearingDeg } from '../routing/RouteProgressTracker.js';\n\nexport const DEFAULT_CAR_SPEED_MPS = 13.4112; // 30 mph\nconst MIN_SPEED_MPS = 0.5;\nconst MAX_SPEED_MPS = 44.704; // 100 mph safety ceiling\nconst MIN_TICK_MS = 100;\nconst MAX_TICK_MS = 1000;\n\nconst clamp = (value, min, max) => Math.max(min, Math.min(max, value));\n\nfunction finiteLatLon(value) {\n  return value && Number.isFinite(value.lat) && Number.isFinite(value.lon);\n}\n\nexport function sampleRouteAtDistance(coords, cumulative, distanceM) {\n  if (!Array.isArray(coords) || coords.length < 2 || !cumulative?.length) return null;\n  const total = cumulative[cumulative.length - 1] || 0;\n  const target = clamp(Number(distanceM) || 0, 0, total);\n  let index = 0;\n  while (index < cumulative.length - 2 && cumulative[index + 1] < target) index++;\n  const startDistance = cumulative[index] || 0;\n  const endDistance = cumulative[index + 1] || startDistance;\n  const ratio = endDistance > startDistance ? (target - startDistance) / (endDistance - startDistance) : 0;\n  const [lonA, latA] = coords[index];\n  const [lonB, latB] = coords[index + 1];\n  const lat = latA + ((latB - latA) * ratio);\n  const lon = lonA + ((lonB - lonA) * ratio);\n  return {\n    lat,\n    lon,\n    segmentIndex: index,\n    distanceAlong: target,\n    bearingDeg: bearingDeg(latA, lonA, latB, lonB),\n  };\n}\n\nexport class ScenePuppetController {\n  constructor({ applyPose, routeStore = null, routeProgressTracker = null, getRoute = null, now = null } = {}) {\n    this._applyPose = typeof applyPose === 'function' ? applyPose : null;\n    this._routeStore = routeStore;\n    this._routeProgressTracker = routeProgressTracker;\n    this._getRoute = typeof getRoute === 'function' ? getRoute : null;\n    this._now = typeof now === 'function' ? now : () => (typeof performance !== 'undefined' ? performance.now() : Date.now());\n    this._timer = null;\n    this._driveAbort = null; this._driveRequest = null; this._disposed = false;\n    this._route = null;\n    this._coords = null;\n    this._cumulative = null;\n    this._distanceAlong = 0;\n    this._speedMps = DEFAULT_CAR_SPEED_MPS;\n    this._elapsedSec = 0;\n    this._lastTickAt = 0;\n    this._altitudeM = 1.8;\n    this._status = { active: false, reason: 'idle', distanceAlong: 0, distanceRemaining: 0, speedMps: DEFAULT_CAR_SPEED_MPS, elapsedSec: 0 };\n  }\n\n  getStatus() { return { ...this._status }; }\n\n  async driveTo({ origin, destination, speedMps = DEFAULT_CAR_SPEED_MPS, altitudeM = 1.8, tickMs = 250, start = true } = {}) {\n    if (this._disposed) return { ok: false, error: 'drive controller disposed' };\n    if (!finiteLatLon(origin) || !finiteLatLon(destination)) {\n      return { ok: false, error: 'origin and destination require finite lat/lon' };\n    }\n    this.stop('superseded');\n    const controller = new AbortController(); this._driveAbort = controller;\n    const request = this._routeStore?.beginRequest?.({ origin, destination, profile: 'driving' });\n    this._driveRequest = request;\n    const signal = request?.signal || controller.signal;\n    try {\n      const route = await this._resolveRoute([{ ...origin }, { ...destination }], { profile: 'driving', signal });\n      if (signal.aborted || this._driveAbort !== controller || this._disposed || (request && !request.isCurrent())) {\n        return { ok: false, error: 'drive request cancelled' };\n      }\n      if (!route?.geometry?.coordinates?.length) return { ok: false, error: 'no driving route available' };\n      if (request) {\n        if (!this._routeStore.commitRequest(request, route)) return { ok: false, error: 'drive request superseded' };\n      } else this._routeStore?.setRoute?.(route, { origin, destination, profile: 'driving' });\n      this._driveAbort = null; this._driveRequest = null;\n      return this.start(route, { speedMps, altitudeM, tickMs, start });\n    } catch (error) {\n      return { ok: false, error: signal.aborted ? 'drive request cancelled' : error.message };\n    } finally {\n      request?.finish();\n      if (this._driveAbort === controller) { this._driveAbort = null; this._driveRequest = null; }\n    }\n  }\n\n  start(route, { speedMps = DEFAULT_CAR_SPEED_MPS, altitudeM = 1.8, tickMs = 250, start = true } = {}) {\n    if (this._disposed) return { ok: false, error: 'drive controller disposed' };\n    const coords = route?.geometry?.coordinates;\n    if (!Array.isArray(coords) || coords.length < 2) return { ok: false, error: 'route needs at least two coordinates' };\n    if (!this._applyPose) return { ok: false, error: 'scene pose adapter unavailable' };\n\n    this.stop('superseded');\n    const cumulative = buildCumulativeDistances(coords);\n    const distance = cumulative[cumulative.length - 1] || 0;\n    if (!(distance > 0)) return { ok: false, error: 'route has no measurable distance' };\n\n    this._route = route;\n    this._coords = coords;\n    this._cumulative = cumulative;\n    this._distanceAlong = 0;\n    this._elapsedSec = 0;\n    this._speedMps = clamp(Number(speedMps) || DEFAULT_CAR_SPEED_MPS, MIN_SPEED_MPS, MAX_SPEED_MPS);\n    this._altitudeM = Math.max(0.5, Number(altitudeM) || 1.8);\n    this._status = {\n      active: true,\n      reason: 'driving',\n      distanceAlong: 0,\n      distanceRemaining: distance,\n      speedMps: this._speedMps,\n      elapsedSec: 0,\n      routeDistanceM: distance,\n    };\n    this._applyCurrentPose();\n\n    if (start) {\n      const interval = clamp(Math.round(Number(tickMs) || 250), MIN_TICK_MS, MAX_TICK_MS);\n      this._lastTickAt = this._now();\n      this._timer = setInterval(() => {\n        const now = this._now();\n        const dtSec = Math.max(0, Math.min(2, (now - this._lastTickAt) / 1000));\n        this._lastTickAt = now;\n        this.advance(dtSec);\n      }, interval);\n    }\n    return { ok: true, ...this.getStatus() };\n  }\n\n  advance(deltaSec) {\n    if (!this._status.active || !this._cumulative) return this.getStatus();\n    const dtSec = Math.max(0, Number(deltaSec) || 0);\n    const total = this._cumulative[this._cumulative.length - 1] || 0;\n    this._elapsedSec += dtSec;\n    this._distanceAlong = Math.min(total, this._distanceAlong + (this._speedMps * dtSec));\n    this._applyCurrentPose();\n    this._status.distanceAlong = this._distanceAlong;\n    this._status.distanceRemaining = Math.max(0, total - this._distanceAlong);\n    this._status.elapsedSec = this._elapsedSec;\n    if (this._distanceAlong >= total) this.stop('arrived');\n    return this.getStatus();\n  }\n\n  simulate(route, { speedMps = DEFAULT_CAR_SPEED_MPS, altitudeM = 1.8, stepSeconds = 1 } = {}) {\n    const started = this.start(route, { speedMps, altitudeM, start: false });\n    if (!started.ok) return started;\n    const step = Math.max(0.05, Number(stepSeconds) || 1);\n    const maxSteps = Math.ceil((started.routeDistanceM / started.speedMps) / step) + 2;\n    for (let i = 0; i < maxSteps && this._status.active; i++) this.advance(step);\n    return { ok: this._status.reason === 'arrived', ...this.getStatus() };\n  }\n\n  stop(reason = 'cancelled') {\n    this._driveAbort?.abort(); this._driveAbort = null;\n    this._driveRequest?.cancel(); this._driveRequest = null;\n    if (this._timer) clearInterval(this._timer);\n    this._timer = null;\n    if (this._status.active) {\n      this._status.active = false;\n      this._status.reason = reason;\n    }\n    return this.getStatus();\n  }\n\n  dispose() { this.stop('disposed'); this._disposed = true; this._route = this._coords = this._cumulative = null; }\n\n  _applyCurrentPose() {\n    const point = sampleRouteAtDistance(this._coords, this._cumulative, this._distanceAlong);\n    if (!point) return;\n    this._applyPose({ ...point, altitudeM: this._altitudeM });\n    this._routeProgressTracker?.update?.(point.lat, point.lon);\n  }\n\n  async _resolveRoute(waypoints, options) {\n    if (this._getRoute) return this._getRoute(waypoints, options);\n    const { getRoute } = await import('../../modules/routing-service.js');\n    return getRoute(waypoints, options);\n  }\n}\n\nexport default ScenePuppetController;\n","/**\n * RouteRibbonRenderer — surface-following ribbon for the active route.\n *\n * Design:\n *   • Floating-origin group. All ribbon vertices are stored in LOCAL\n *     coordinates relative to the group's world position (the route\n *     centroid). This prevents the float32 precision loss that occurs\n *     when you store ~6.37M-metre ECEF coordinates in a Float32Array\n *     BufferGeometry — which is what produces the \"jitter\" the user\n *     sees as the camera moves.\n *   • Surface-snap (drape). Each vertex is re-projected against the\n *     active surface sampler — photoreal tiles first, then the tritree\n *     elevation mesh, then ellipsoid as a last resort. This mirrors the\n *     InfrastructureOverlay._alignEntry pattern so the ribbon sits mated\n *     to the ground (e.g. on top of roofs in photoreal areas) instead\n *     of floating 35m above sea level.\n *   • Periodic resnap. A tiny slice of vertices is re-sampled per tick\n *     so photoreal LOD swaps don't leave the ribbon buried or airborne.\n *\n * Left-half (ahead-of-progress) is accent-coloured; right-half\n * (traversed) is dimmed.  Colour updates happen on every\n * `route:progress` event and are O(n) vertex writes — no geometry\n * rebuild.\n */\nimport * as THREE from 'three';\nimport {\n  latLonToLocalDir,\n  ellipsoidRadiusForLocalDir,\n} from '../../modules/geometry-utils.js';\nimport { SurfaceFootprintMarker } from '../overlays/SurfaceFootprintMarker.js';\n\nconst RIBBON_WIDTH_M = 18;\n// Lift above the draped surface. Small (0.3 m) so the ribbon looks\n// mated to the ground under photoreal tiles. The legacy 35m lift put\n// the ribbon floating well above rooftops.\nconst SURFACE_LIFT_M = 0.3;\n// Fallback lift above the bare ellipsoid when no surface data is\n// available yet. Large so the ribbon is at least visible over the\n// raw tritree elevation mesh before draping has run.\nconst ELLIPSOID_LIFT_M = 35;\nconst COLOR_AHEAD = new THREE.Color(0x00d4ff);\nconst COLOR_BEHIND = new THREE.Color(0x004466);\nconst COLOR_DEST = new THREE.Color(0x6ee7b7);\n// How many vertices to re-sample per tick when draping. Keeps the\n// worst-case raycast load bounded on long routes.\nconst DRAPE_BUDGET_PER_TICK = 32;\n// Milliseconds between drape passes when a route is active.\nconst DRAPE_INTERVAL_MS = 500;\n\nconst _tmpTangent = new THREE.Vector3();\nconst _tmpSide = new THREE.Vector3();\nconst _tmpDir = new THREE.Vector3();\nconst _tmpWorldDir = new THREE.Vector3();\nconst _tmpWorldQuat = new THREE.Quaternion();\nconst _tmpCenterLocal = new THREE.Vector3();\nconst _tmpLeftLocal = new THREE.Vector3();\nconst _tmpRightLocal = new THREE.Vector3();\nconst _tmpPosA = new THREE.Vector3();\nconst _tmpPosB = new THREE.Vector3();\n\n/**\n * For a [lon, lat] coord, compute the planet-local unit direction and\n * world-ECEF position at the target radius. Centralised so the draping\n * code and geometry builder agree.\n */\nfunction _dirForLatLon(lon, lat, out) {\n  const dir = latLonToLocalDir(lat, lon);\n  (out || _tmpDir).copy(dir);\n  return out || _tmpDir;\n}\n\nexport class RouteRibbonRenderer {\n  constructor({ parentGroup, eventBus, triTree = null, surfaceController = null } = {}) {\n    this.parentGroup = parentGroup || null;\n    this.eventBus = eventBus || null;\n    // triTree lets us reuse its sampleTerrainRadiusForDir() which\n    // prefers photoreal tile raycasts over the tritree elevation mesh.\n    // Optional — ribbon still renders (on the ellipsoid) without it.\n    this.triTree = triTree || null;\n    // surfaceController samples photoreal tiles via raycast (preferred).\n    // Falls back to triTree elevation mesh, then ellipsoid.\n    this.surfaceController = surfaceController || null;\n\n    this._group = null;         // floating-origin THREE.Group\n    this._ribbon = null;        // the ribbon mesh (child of _group)\n    this._destinationMarker = null; // planet-local footprint, independent of ribbon origin\n    this._destinationLookupSeq = 0;\n    this._cumulative = null;    // cumulative distance per coord (m)\n    this._progressDist = 0;\n\n    // Route source-of-truth. We hold the plan-local direction + lon/lat\n    // for every coord so we can re-sample surfaces without re-deriving\n    // from world-space positions (which are lossy in float32).\n    this._coordCount = 0;\n    this._coordDirs = null;      // Vector3[] local planet-frame directions\n    this._coordLonLat = null;    // [lon, lat, ...] flat array\n    this._coordRadii = null;     // Float64Array of surface-radius samples per coord (draped)\n    this._localOrigin = new THREE.Vector3();\n\n    // Drape loop state.\n    this._drapeCursor = 0;\n    this._drapeTimer = 0;\n    this._lastTickMs = 0;\n\n    this._onSet = (ev) => this.setRoute(ev?.detail || ev);\n    this._onCleared = () => this.clear();\n    this._onProgress = (ev) => this._updateProgress(ev?.detail || ev);\n\n    if (typeof document !== 'undefined' && document.addEventListener) {\n      document.addEventListener('noclip:route:set', this._onSet);\n      document.addEventListener('noclip:route:cleared', this._onCleared);\n      document.addEventListener('noclip:route:progress', this._onProgress);\n    }\n  }\n\n  dispose() {\n    this.clear();\n    if (typeof document !== 'undefined' && document.removeEventListener) {\n      document.removeEventListener('noclip:route:set', this._onSet);\n      document.removeEventListener('noclip:route:cleared', this._onCleared);\n      document.removeEventListener('noclip:route:progress', this._onProgress);\n    }\n  }\n\n  setParentGroup(group) {\n    if (this.parentGroup === group) return;\n    if (this._group?.parent) this._group.parent.remove(this._group);\n    if (this._destinationMarker?.group?.parent) {\n      this._destinationMarker.group.parent.remove(this._destinationMarker.group);\n    }\n    this.parentGroup = group;\n    if (this._group && group) group.add(this._group);\n    if (this._destinationMarker) {\n      this._destinationMarker.parentGroup = group;\n      group?.add?.(this._destinationMarker.group);\n      this._destinationMarker.refreshTerrain();\n    }\n  }\n\n  setTriTree(tt) {\n    this.triTree = tt || null;\n  }\n\n  setSurfaceController(sc) {\n    this.surfaceController = sc || null;\n    if (this._destinationMarker) {\n      this._destinationMarker.surfaceController = this.surfaceController;\n      this._destinationMarker.refreshTerrain();\n    }\n  }\n\n  clear() {\n    this._destinationLookupSeq += 1;\n    if (this._ribbon) {\n      this._ribbon.geometry?.dispose?.();\n      this._ribbon.material?.dispose?.();\n      this._ribbon = null;\n    }\n    this._destinationMarker?.dispose();\n    this._destinationMarker = null;\n    if (this._group) {\n      this._group.parent?.remove(this._group);\n      this._group.clear();\n      this._group = null;\n    }\n    this._coordCount = 0;\n    this._coordDirs = null;\n    this._coordLonLat = null;\n    this._coordRadii = null;\n    this._cumulative = null;\n    this._progressDist = 0;\n    this._drapeCursor = 0;\n    this._drapeTimer = 0;\n  }\n\n  setRoute(route) {\n    this.clear();\n    if (!route?.geometry?.coordinates?.length || !this.parentGroup) {\n      if (typeof console !== 'undefined') {\n        console.warn('[RouteRibbonRenderer] setRoute skipped',\n          { hasRoute: !!route, coordCount: route?.geometry?.coordinates?.length || 0,\n            hasParent: !!this.parentGroup });\n      }\n      return;\n    }\n    const coords = route.geometry.coordinates;\n    if (coords.length < 2) return;\n\n    const count = coords.length;\n    this._coordCount = count;\n    this._coordDirs = new Array(count);\n    this._coordLonLat = new Float64Array(count * 2);\n    this._coordRadii = new Float64Array(count);\n\n    // Seed each coord with ellipsoid radius. Drape passes will refine.\n    for (let i = 0; i < count; i++) {\n      const [lon, lat] = coords[i];\n      const dir = latLonToLocalDir(lat, lon);\n      this._coordDirs[i] = dir;\n      this._coordLonLat[i * 2]     = lon;\n      this._coordLonLat[i * 2 + 1] = lat;\n      this._coordRadii[i] = ellipsoidRadiusForLocalDir(dir) + ELLIPSOID_LIFT_M;\n    }\n\n    // Local origin = first vertex's ECEF position. Every ribbon\n    // vertex is stored as `worldPos - _localOrigin`, so values fed\n    // into the Float32Array stay small (≤ route_length, typically\n    // < 100 km) — no float32 jitter.\n    const dir0 = this._coordDirs[0];\n    this._localOrigin\n      .copy(dir0)\n      .multiplyScalar(this._coordRadii[0]);\n\n    // Build initial geometry (pre-drape). The drape loop will refine\n    // per-vertex radii over subsequent ticks.\n    this._buildRibbonGeometry();\n    this._group = new THREE.Group();\n    this._group.name = 'RouteRibbon';\n    this._group.position.copy(this._localOrigin);\n    this._group.frustumCulled = false;\n    if (this._ribbon) this._group.add(this._ribbon);\n    this.parentGroup.add(this._group);\n    this._buildDestinationFootprint(coords[count - 1]);\n\n    // Kick off an initial aggressive drape pass — run DRAPE_BUDGET_PER_TICK\n    // vertices right now so the ribbon starts on the surface.\n    this._drapeStep();\n  }\n\n  /**\n   * Advance the surface-drape loop. Callers (PlanetScene update hook)\n   * should invoke this once per frame. It's a no-op when no route is\n   * active.\n   */\n  update(dtSec = 0.016) {\n    this._destinationMarker?.update?.();\n    if (!this._group || !this._coordCount) return;\n    this._drapeTimer += Math.max(0, dtSec) * 1000;\n    if (this._drapeTimer < DRAPE_INTERVAL_MS) return;\n    this._drapeTimer = 0;\n    this._drapeStep();\n  }\n\n  /** Sample one slice of vertices and refresh their per-coord radius. */\n  _drapeStep() {\n    if (!this._coordCount) return;\n    const budget = Math.min(DRAPE_BUDGET_PER_TICK, this._coordCount);\n    let changed = false;\n\n    const worldQuat = (this.parentGroup?.getWorldQuaternion)\n      ? this.parentGroup.getWorldQuaternion(_tmpWorldQuat)\n      : null;\n\n    for (let k = 0; k < budget; k++) {\n      const i = (this._drapeCursor + k) % this._coordCount;\n      const dir = this._coordDirs[i];\n      const sampled = this._sampleSurfaceRadius(dir, worldQuat);\n      if (Number.isFinite(sampled)) {\n        const liftR = sampled + SURFACE_LIFT_M;\n        if (Math.abs(liftR - this._coordRadii[i]) > 0.05) {\n          this._coordRadii[i] = liftR;\n          changed = true;\n        }\n      }\n    }\n    this._drapeCursor = (this._drapeCursor + budget) % this._coordCount;\n\n    if (changed) {\n      this._rewriteRibbonPositions();\n    }\n  }\n\n  _sampleSurfaceRadius(localDir, worldQuat) {\n    _tmpWorldDir.copy(localDir);\n    if (worldQuat) _tmpWorldDir.applyQuaternion(worldQuat);\n    _tmpWorldDir.normalize();\n\n    // Prefer surfaceController — raycasts against photoreal tile geometry\n    // (same pattern as AddressHoverOverlay._getTerrainRadius and\n    // InfrastructureOverlay._sampleTerrainRadiusForDir).\n    if (this.surfaceController && typeof this.surfaceController.sampleTerrainRadiusForDir === 'function') {\n      const r = this.surfaceController.sampleTerrainRadiusForDir(_tmpWorldDir, { mutateCache: false });\n      if (Number.isFinite(r) && r > 0) return r;\n    }\n\n    // Fallback: triTree elevation mesh raycast\n    if (this.triTree && typeof this.triTree.sampleTerrainRadiusForDir === 'function') {\n      const r = this.triTree.sampleTerrainRadiusForDir(_tmpWorldDir);\n      if (Number.isFinite(r) && r > 0) return r;\n    }\n\n    return ellipsoidRadiusForLocalDir(localDir);\n  }\n\n  _buildRibbonGeometry() {\n    const count = this._coordCount;\n    const segCount = count - 1;\n    const vertexCount = count * 2;\n\n    const positions = new Float32Array(vertexCount * 3);\n    const colors = new Float32Array(vertexCount * 3);\n    const indices = new Uint32Array(segCount * 6);\n    const cumulative = new Float64Array(count);\n    let total = 0;\n\n    for (let i = 0; i < count; i++) {\n      this._writeVertexPair(i, positions);\n\n      colors[i * 6]     = COLOR_AHEAD.r;\n      colors[i * 6 + 1] = COLOR_AHEAD.g;\n      colors[i * 6 + 2] = COLOR_AHEAD.b;\n      colors[i * 6 + 3] = COLOR_AHEAD.r;\n      colors[i * 6 + 4] = COLOR_AHEAD.g;\n      colors[i * 6 + 5] = COLOR_AHEAD.b;\n\n      if (i > 0) {\n        const lon1 = this._coordLonLat[(i - 1) * 2];\n        const lat1 = this._coordLonLat[(i - 1) * 2 + 1];\n        const lon2 = this._coordLonLat[i * 2];\n        const lat2 = this._coordLonLat[i * 2 + 1];\n        total += haversineM(lat1, lon1, lat2, lon2);\n      }\n      cumulative[i] = total;\n    }\n\n    for (let s = 0; s < segCount; s++) {\n      const l0 = s * 2;\n      const r0 = s * 2 + 1;\n      const l1 = s * 2 + 2;\n      const r1 = s * 2 + 3;\n      const io = s * 6;\n      indices[io]     = l0;\n      indices[io + 1] = r0;\n      indices[io + 2] = r1;\n      indices[io + 3] = l0;\n      indices[io + 4] = r1;\n      indices[io + 5] = l1;\n    }\n\n    const geom = new THREE.BufferGeometry();\n    geom.setAttribute('position', new THREE.BufferAttribute(positions, 3));\n    geom.setAttribute('color', new THREE.BufferAttribute(colors, 3));\n    geom.setIndex(new THREE.BufferAttribute(indices, 1));\n    geom.computeBoundingSphere();\n    geom.attributes.position.usage = THREE.DynamicDrawUsage;\n\n    const mat = new THREE.MeshBasicMaterial({\n      vertexColors: true,\n      transparent: true,\n      opacity: 0.88,\n      depthTest: false,\n      depthWrite: false,\n      side: THREE.DoubleSide,\n    });\n    this._ribbon = new THREE.Mesh(geom, mat);\n    this._ribbon.renderOrder = 1500;\n    this._ribbon.frustumCulled = false;\n    this._cumulative = cumulative;\n  }\n\n  /**\n   * Compute left/right LOCAL-space vertices for coord index `i` and\n   * write them into `positions`. LOCAL = world - _localOrigin. This is\n   * the whole point of the renderer — float32 precision holds when\n   * magnitudes are small, which they are once we subtract the origin.\n   */\n  _writeVertexPair(i, positions) {\n    const count = this._coordCount;\n    const dirCur = this._coordDirs[i];\n    const rCur = this._coordRadii[i];\n    _tmpCenterLocal\n      .copy(dirCur)\n      .multiplyScalar(rCur)\n      .sub(this._localOrigin);\n\n    // Tangent in world space, then we project against center local up.\n    let nextIdx, sign;\n    if (i < count - 1) { nextIdx = i + 1; sign = 1; }\n    else { nextIdx = i - 1; sign = -1; }\n    const dirNext = this._coordDirs[nextIdx];\n    const rNext = this._coordRadii[nextIdx];\n    _tmpPosA.copy(dirNext).multiplyScalar(rNext).sub(this._localOrigin);\n    _tmpTangent.copy(_tmpPosA).sub(_tmpCenterLocal).multiplyScalar(sign).normalize();\n\n    // Up = outward radial direction at this point\n    _tmpPosB.copy(dirCur);\n    _tmpSide.crossVectors(_tmpPosB, _tmpTangent).normalize().multiplyScalar(RIBBON_WIDTH_M);\n\n    _tmpLeftLocal.copy(_tmpCenterLocal).sub(_tmpSide);\n    _tmpRightLocal.copy(_tmpCenterLocal).add(_tmpSide);\n\n    const l = i * 2;\n    positions[l * 3]     = _tmpLeftLocal.x;\n    positions[l * 3 + 1] = _tmpLeftLocal.y;\n    positions[l * 3 + 2] = _tmpLeftLocal.z;\n    const r = i * 2 + 1;\n    positions[r * 3]     = _tmpRightLocal.x;\n    positions[r * 3 + 1] = _tmpRightLocal.y;\n    positions[r * 3 + 2] = _tmpRightLocal.z;\n  }\n\n  _rewriteRibbonPositions() {\n    if (!this._ribbon) return;\n    const attr = this._ribbon.geometry.getAttribute('position');\n    const positions = attr.array;\n    for (let i = 0; i < this._coordCount; i++) {\n      this._writeVertexPair(i, positions);\n    }\n    attr.needsUpdate = true;\n    this._ribbon.geometry.computeBoundingSphere();\n  }\n\n  _buildDestinationFootprint(coord) {\n    const [lon, lat] = coord;\n    const marker = new SurfaceFootprintMarker({\n      parentGroup: this.parentGroup,\n      surfaceController: this.surfaceController,\n      color: COLOR_DEST,\n      heightM: 150,\n      embedM: 1.75,\n      opacity: 0.75,\n      outlineOpacity: 0.96,\n      renderOrder: 1500,\n      name: 'RouteDestinationFootprint',\n      lightChannel: 'route-destination',\n      lightPriority: 112,\n      lightRadiusM: 240,\n      lightIntensityScale: 1.45,\n      lightPulseHz: 0.58,\n    });\n    marker.group.frustumCulled = false;\n    marker.group.userData.coordIndex = this._coordCount - 1;\n    marker.setResolvingSpire(lat, lon, { radiusM: 6 });\n    this._destinationMarker = marker;\n\n    const lookupSeq = ++this._destinationLookupSeq;\n    import('../../modules/geocoding-service.js')\n      .then(({ fetchBuildingFootprint }) => fetchBuildingFootprint?.(lat, lon))\n      .then((footprint) => {\n        if (!footprint\n          || lookupSeq !== this._destinationLookupSeq\n          || this._destinationMarker !== marker) return;\n        marker.transitionToFootprint(footprint, { lat, lon, source: 'overpass' });\n        marker.setVisible(true);\n      })\n      .catch(() => {});\n  }\n\n  refreshTerrainAnchors(changes) {\n    return this._destinationMarker?.refreshTerrain(changes) ? 1 : 0;\n  }\n\n  _updateProgress(snapshot) {\n    if (!this._ribbon || !this._cumulative) return;\n    const along = Number(snapshot?.distanceAlong);\n    if (!Number.isFinite(along)) return;\n    this._progressDist = Math.max(0, along);\n\n    const colors = this._ribbon.geometry.getAttribute('color');\n    const count = this._cumulative.length;\n    for (let i = 0; i < count; i++) {\n      const target = this._cumulative[i] <= this._progressDist ? COLOR_BEHIND : COLOR_AHEAD;\n      const l = i * 2;\n      const r = i * 2 + 1;\n      colors.array[l * 3]     = target.r;\n      colors.array[l * 3 + 1] = target.g;\n      colors.array[l * 3 + 2] = target.b;\n      colors.array[r * 3]     = target.r;\n      colors.array[r * 3 + 1] = target.g;\n      colors.array[r * 3 + 2] = target.b;\n    }\n    colors.needsUpdate = true;\n  }\n}\n\nfunction haversineM(lat1, lon1, lat2, lon2) {\n  const R = 6371000;\n  const dLat = (lat2 - lat1) * Math.PI / 180;\n  const dLon = (lon2 - lon1) * Math.PI / 180;\n  const a = Math.sin(dLat / 2) ** 2\n    + Math.cos(lat1 * Math.PI / 180)\n    * Math.cos(lat2 * Math.PI / 180)\n    * Math.sin(dLon / 2) ** 2;\n  return R * 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));\n}\n\nlet _instance = null;\n\nexport function getRouteRibbonRenderer(options = {}) {\n  if (!_instance) _instance = new RouteRibbonRenderer(options);\n  if (options.parentGroup && _instance.parentGroup !== options.parentGroup) {\n    _instance.setParentGroup(options.parentGroup);\n  }\n  if (options.triTree && _instance.triTree !== options.triTree) {\n    _instance.setTriTree(options.triTree);\n  }\n  if (options.surfaceController && _instance.surfaceController !== options.surfaceController) {\n    _instance.setSurfaceController(options.surfaceController);\n  }\n  if (options.eventBus) _instance.eventBus = options.eventBus;\n  return _instance;\n}\n\nexport default RouteRibbonRenderer;\n","import * as THREE from 'three';\nimport { SurfaceFootprintMarker } from './SurfaceFootprintMarker.js';\nimport { getPlaceSearchStore } from '../geo/PlaceSearchStore.js';\nimport { getRouteStore } from '../routing/RouteStore.js';\nimport { routeStopBadge } from '../geo/PlaceSearchResults.js';\n\n/** Bounded surface projection of transient search and staged route stops.\n * Uses existing terrain anchoring and label admission; no per-frame requests. */\nexport class PlaceSearchSurfaceLayer {\n  constructor({ parentGroup, surfaceController, labels, store = getPlaceSearchStore(), routes = getRouteStore() }) {\n    Object.assign(this, { parentGroup, surfaceController, labels, store, routes });\n    this.entries = new Map(); this.position = new THREE.Vector3();\n    this.off = store.subscribe(state => this.sync(state));\n    this.onStops = () => this.sync(this.store.getState());\n    this.onHover = event => {\n      const id = event.detail?.metadata?.searchId;\n      if (id) store.hover(id);\n      else if (!event.detail) store.hover(null);\n    };\n    document.addEventListener('noclip:route:waypoints', this.onStops);\n    document.addEventListener('noclip:scene-label-hover', this.onHover);\n  }\n  sync(state) {\n    if (this.syncing) return;\n    this.syncing = true;\n    try {\n    const points = [...state.results.map(p => ({ ...p, key: `search:${p.searchId}`, title: p.name, color: '#facc15' })),\n      ...this.routes.getWaypoints().map((p, i, all) => ({ ...p, key: `stop:${p.id}`,\n        title: `${routeStopBadge(i, all.length, p.role)} · ${p.name}`, color: '#6ee7b7' }))];\n    const wanted = new Set(points.map(p => p.key));\n    for (const [key, entry] of this.entries) if (!wanted.has(key)) {\n      entry.label.dispose(); entry.marker.dispose(); this.entries.delete(key);\n    }\n    for (const point of points) {\n      let entry = this.entries.get(point.key);\n      if (entry && (entry.lat !== point.lat || entry.lon !== point.lon)) {\n        entry.label.dispose(); entry.marker.dispose(); this.entries.delete(point.key); entry = null;\n      }\n      if (!entry) {\n        const marker = new SurfaceFootprintMarker({ parentGroup: this.parentGroup, surfaceController: this.surfaceController,\n          color: point.color, heightM: 24, opacity: 0.65, name: 'PlaceSearchSurfaceMarker' });\n        marker.setResolvingSpire(point.lat, point.lon, { radiusM: 3 });\n        const label = this.labels.createLabel(point.title, { type: 'poi', color: point.color,\n          position: marker.getTopPosition(this.position) || this.position, objectRadius: 8,\n          maxDistance: 250000, labelPriority: 100, sourceVisible: marker.isTerrainMated(), subText: point.displayName || point.address || '',\n          metadata: { searchId: point.searchId, routeStopId: point.id, lat: point.lat, lon: point.lon,\n            name: point.name, address: point.displayName || point.address || '', provider: 'mapsource-local' } });\n        label.lat = point.lat; label.lon = point.lon; this.parentGroup.add(label.group);\n        entry = { marker, label, lat: point.lat, lon: point.lon }; this.entries.set(point.key, entry);\n      }\n      this.labels.updateText(entry.label, point.title, point.displayName || point.address || null);\n      entry.label.opacity = state.hovered && point.searchId && state.hovered !== point.searchId ? 0.25 : 1;\n      entry.marker.setOpacity(entry.label.opacity * 0.65);\n      if (point.searchId === state.hovered) this.labels.setExternalHoveredLabel(entry.label);\n    }\n    if (!state.hovered && this.externalHover) this.labels.setExternalHoveredLabel(null);\n    this.externalHover = !!state.hovered;\n    } finally { this.syncing = false; }\n  }\n  update() {\n    const now = performance.now();\n    for (const { marker, label } of this.entries.values()) {\n      marker.update(now);\n      const position = marker.getTopPosition(this.position);\n      if (position) this.labels.updatePosition(label, position);\n      label.sourceVisible = marker.isTerrainMated();\n    }\n  }\n  setSurfaceController(controller) {\n    this.surfaceController = controller;\n    for (const { marker } of this.entries.values()) {\n      marker.surfaceController = controller;\n      marker.refreshTerrain();\n    }\n  }\n  refreshTerrainAnchors(changes) { for (const { marker } of this.entries.values()) marker.refreshTerrain(changes); }\n  dispose() {\n    this.off(); document.removeEventListener('noclip:route:waypoints', this.onStops);\n    document.removeEventListener('noclip:scene-label-hover', this.onHover);\n    for (const { marker, label } of this.entries.values()) { label.dispose(); marker.dispose(); }\n    this.entries.clear();\n  }\n}\n","import { resolveBackendApiUrl } from '../../shared/backend.js';\nimport { getNoclipGovernanceClient } from '../../shared/NoclipGovernanceClient.js';\nimport { readBoundedBytes } from '../../shared/readBoundedBytes.js';\nimport { getWorkerPool } from '../workers/WorkerPool.js';\n\nexport const LOCAL_ROUTING_CLIENT_LIMITS = Object.freeze({\n  active: 2, waiting: 8, timeoutMs: 15000, responseBytes: 8 * 1024 * 1024,\n  errorBytes: 32768, requestBytes: 1024 * 1024, parseThreshold: 32768,\n  cacheEntries: 16, cacheBytes: 4 * 1024 * 1024, cacheEntryBytes: 512 * 1024, cacheTtlMs: 300000,\n});\nconst PATHS = new Set(['/routing/directions', '/routing/isochrone', '/routing/match', '/overpass']);\nconst MESSAGES = Object.freeze({\n  routing_invalid_request: 'The routing request contains invalid locations or options.',\n  routing_coverage_unavailable: 'No suitable roads were found near these locations in the local routing graph.',\n  routing_no_route: 'No connecting route or matching road was found for these points.',\n  routing_unsupported: 'The local routing service does not support this request.',\n  routing_overloaded: 'The local routing service is busy. Please retry shortly.',\n  routing_unavailable: 'The local routing service is unavailable. Please retry.',\n  routing_timeout: 'The local routing request timed out. Please retry.',\n  routing_invalid_response: 'The local routing service returned an invalid response.',\n  routing_result_too_large: 'The local routing result exceeds the supported resource limit.',\n  routing_worker_unavailable: 'The routing parser is unavailable. Please retry.',\n  routing_access_denied: 'Routing access was denied. Check the access notice before retrying.',\n});\n\nexport class RoutingError extends Error {\n  constructor(code, { status = 0, retryable = false, retryAfterMs = 0 } = {}) {\n    super(MESSAGES[code] || MESSAGES.routing_unavailable);\n    this.name = 'RoutingError'; this.code = code; this.status = status;\n    this.retryable = retryable; this.retryAfterMs = retryAfterMs;\n  }\n}\nexport const invalidRoutingRequest = () => { throw new RoutingError('routing_invalid_request'); };\nexport const invalidRoutingResponse = () => { throw new RoutingError('routing_invalid_response'); };\nexport const checkRoutingAbort = signal => signal?.throwIfAborted();\n\n/** Large results always parse in the packaged worker. Keep the permit until\n * the actual RPC settles: an abort message cannot interrupt synchronous JSON.parse. */\nexport async function parseRoutingBytes(bytes) {\n  if (bytes.byteLength < LOCAL_ROUTING_CLIENT_LIMITS.parseThreshold || typeof window === 'undefined') {\n    return JSON.parse(new TextDecoder().decode(bytes));\n  }\n  if (typeof Worker === 'undefined') throw new RoutingError('routing_worker_unavailable', { retryable: true });\n  try {\n    const parsed = await getWorkerPool().run('parser-worker', 'parseJSONBuffer',\n      { buffer: bytes.buffer }, { transfer: [bytes.buffer], timeoutMs: 15000 });\n    if (!parsed?.ok) invalidRoutingResponse();\n    return parsed.data;\n  } catch (error) {\n    if (error instanceof RoutingError) throw error;\n    throw new RoutingError('routing_worker_unavailable', { retryable: true });\n  }\n}\n\n/** One bounded browser owner for canonical routing only. No automatic retry,\n * response-clone deduplication, public bypass, or browser graph fallback. */\nexport class LocalRoutingClient {\n  constructor({ request = (url, init) => getNoclipGovernanceClient().request(url, init),\n    parse = parseRoutingBytes, resolveUrl = resolveBackendApiUrl, now = Date.now,\n    timeoutMs = LOCAL_ROUTING_CLIENT_LIMITS.timeoutMs } = {}) {\n    if (!Number.isFinite(timeoutMs) || timeoutMs < 1 || timeoutMs > 15000) throw new RangeError('Invalid routing deadline');\n    this._request = request; this._parse = parse; this._resolveUrl = resolveUrl;\n    this._now = now; this._timeoutMs = timeoutMs;\n    this._active = 0; this._waiting = []; this._cache = new Map(); this._cacheBytes = 0;\n    this._cacheGeneration = 0; this._sequence = 0; this._success = new Map(); this._cooldown = new Map();\n  }\n\n  request(path, { query, body, signal, cache = false, validate = data => data } = {}) {\n    try { checkRoutingAbort(signal); } catch (error) { return Promise.reject(error); }\n    if (!PATHS.has(path)) return Promise.reject(new RoutingError('routing_invalid_request'));\n    if (this._active >= LOCAL_ROUTING_CLIENT_LIMITS.active && this._waiting.length >= LOCAL_ROUTING_CLIENT_LIMITS.waiting) {\n      return Promise.reject(new RoutingError('routing_overloaded', { retryable: true, retryAfterMs: 1000 }));\n    }\n    const controller = new AbortController();\n    const forwardAbort = () => controller.abort(signal.reason);\n    signal?.addEventListener('abort', forwardAbort, { once: true });\n    const timer = setTimeout(() => controller.abort(new RoutingError('routing_timeout', { retryable: true })), this._timeoutMs);\n    return new Promise((resolve, reject) => {\n      let settled = false;\n      const finish = (fn, result) => {\n        if (settled) return;\n        settled = true; clearTimeout(timer);\n        signal?.removeEventListener('abort', forwardAbort);\n        controller.signal.removeEventListener('abort', abort);\n        fn(result);\n      };\n      const job = { controller, run: async () => {\n        try { finish(resolve, await this._run(path, { query, body, cache, validate, signal: controller.signal })); }\n        catch (error) { finish(reject, error); }\n        finally { this._active--; this._drain(); }\n      } };\n      const abort = () => {\n        const index = this._waiting.indexOf(job);\n        if (index >= 0) this._waiting.splice(index, 1);\n        finish(reject, controller.signal.reason);\n        // Active jobs retain their permit through actual reader/parser cleanup.\n      };\n      controller.signal.addEventListener('abort', abort, { once: true });\n      this._waiting.push(job); this._drain();\n    });\n  }\n\n  _drain() {\n    while (this._active < LOCAL_ROUTING_CLIENT_LIMITS.active && this._waiting.length) {\n      const job = this._waiting.shift();\n      if (job.controller.signal.aborted) continue;\n      this._active++; void job.run();\n    }\n  }\n\n  async _run(path, { query, body, signal, cache, validate }) {\n    const url = this._resolveUrl(`${path}${query ? `?${new URLSearchParams(query)}` : ''}`);\n    const sequence = ++this._sequence, generation = this._cacheGeneration;\n    let cached = cache && path === '/routing/isochrone' && body === undefined && this._cache.get(url);\n    if (cached && this._now() - cached.time >= LOCAL_ROUTING_CLIENT_LIMITS.cacheTtlMs) {\n      this._removeCache(url); cached = null;\n    }\n    let bytes, savedBytes, status = 0, headers, response, attempted = false;\n    try {\n      checkRoutingAbort(signal);\n      if (cached) {\n        this._cache.delete(url); this._cache.set(url, cached);\n        bytes = cached.bytes.slice(); // Every caller owns its parsed result, including cache hits.\n      } else {\n        const cooldown = this._cooldown.get(path);\n        if (cooldown && cooldown.until > this._now()) throw new RoutingError(cooldown.code,\n          { retryable: true, retryAfterMs: cooldown.until - this._now() });\n        if (typeof body === 'string' && path !== '/overpass') invalidRoutingRequest();\n        const serialized = body === undefined ? undefined : typeof body === 'string' ? body : JSON.stringify(body);\n        if (serialized && new TextEncoder().encode(serialized).byteLength > LOCAL_ROUTING_CLIENT_LIMITS.requestBytes) invalidRoutingRequest();\n        attempted = true;\n        response = await this._request(url, {\n          method: serialized === undefined ? 'GET' : 'POST', body: serialized, signal,\n          headers: { Accept: 'application/json', ...(serialized === undefined ? {} : { 'Content-Type': typeof body === 'string' ? 'text/plain' : 'application/json' }) },\n          redirect: 'error', cache: 'no-store', governanceLane: 'scene', governanceRetry: false,\n          governanceProblemBodyLimit: LOCAL_ROUTING_CLIENT_LIMITS.errorBytes,\n        });\n        status = response.status; headers = response.headers;\n        bytes = await readBoundedBytes(response, {\n          maxBytes: response.ok ? LOCAL_ROUTING_CLIENT_LIMITS.responseBytes : LOCAL_ROUTING_CLIENT_LIMITS.errorBytes, signal,\n        });\n        if (cache && path === '/routing/isochrone' && response.ok && bytes.byteLength <= LOCAL_ROUTING_CLIENT_LIMITS.cacheEntryBytes) savedBytes = bytes.slice();\n      }\n      checkRoutingAbort(signal);\n      let data;\n      try { data = await this._parse(bytes); }\n      catch (error) {\n        if (error instanceof RoutingError) throw error;\n        invalidRoutingResponse();\n      }\n      checkRoutingAbort(signal);\n      if (response && !response.ok) {\n        const seconds = Number(headers?.get('retry-after'));\n        const retryAfterMs = seconds > 0 && Number.isFinite(seconds) ? seconds * 1000\n          : Math.max(0, Date.parse(headers?.get('retry-after') || '') - this._now()) || 0;\n        const code = Object.hasOwn(MESSAGES, data?.code) ? data.code\n          : status === 401 || status === 403 ? 'routing_access_denied'\n          : status === 429 || status === 503 ? 'routing_overloaded' : 'routing_unavailable';\n        throw new RoutingError(code, { status, retryable: data?.retryable === true || [429, 502, 503, 504].includes(status), retryAfterMs });\n      }\n      const result = await validate(data, signal);\n      checkRoutingAbort(signal);\n      if (attempted) { this._success.set(path, sequence); this._cooldown.delete(path); }\n      if (savedBytes && generation === this._cacheGeneration) this._storeCache(url, savedBytes);\n      return result;\n    } catch (error) {\n      if (signal.aborted) throw signal.reason;\n      if (cached) this._removeCache(url);\n      const failure = error instanceof RoutingError ? error : new RoutingError(error instanceof RangeError\n        ? 'routing_result_too_large' : 'routing_unavailable', { status, retryable: !(error instanceof RangeError) });\n      if (attempted && failure.retryable && sequence > (this._success.get(path) || 0)) {\n        const until = this._now() + (failure.retryAfterMs || 5000);\n        const previous = this._cooldown.get(path);\n        this._cooldown.set(path, { code: failure.code, until: Math.max(until, previous?.until || 0) });\n      }\n      throw failure;\n    }\n  }\n\n  _removeCache(key) {\n    const value = this._cache.get(key);\n    if (value) this._cacheBytes -= value.bytes.byteLength;\n    this._cache.delete(key);\n  }\n  _storeCache(key, bytes) {\n    this._removeCache(key); this._cache.set(key, { bytes, time: this._now() }); this._cacheBytes += bytes.byteLength;\n    while (this._cache.size > LOCAL_ROUTING_CLIENT_LIMITS.cacheEntries || this._cacheBytes > LOCAL_ROUTING_CLIENT_LIMITS.cacheBytes) {\n      this._removeCache(this._cache.keys().next().value);\n    }\n  }\n  clearIsochroneCache() { this._cacheGeneration++; this._cache.clear(); this._cacheBytes = 0; }\n  getStats() { return { active: this._active, waiting: this._waiting.length, cacheEntries: this._cache.size, cacheBytes: this._cacheBytes }; }\n}\n\nlet instance;\nexport function getLocalRoutingClient() { return instance ||= new LocalRoutingClient(); }\n","import { checkRoutingAbort, invalidRoutingRequest, invalidRoutingResponse } from '../async/fetch/LocalRoutingClient.js';\n\nconst PROFILES = new Set(['driving', 'cycling', 'foot']);\nexport function routingProfile(profile = 'driving') {\n  if (!PROFILES.has(profile)) invalidRoutingRequest();\n  return profile;\n}\nexport function routingPoint(point) {\n  return Array.isArray(point) && point.length === 2 && Number.isFinite(point[0]) && Number.isFinite(point[1])\n    && Math.abs(point[0]) <= 180 && Math.abs(point[1]) <= 90;\n}\nexport function routingCoordinates(points, maximum = 20) {\n  if (!Array.isArray(points) || points.length < 2 || points.length > maximum) invalidRoutingRequest();\n  return points.map(point => {\n    const pair = Array.isArray(point) ? point : [point?.lon ?? point?.lng, point?.lat];\n    if (!routingPoint(pair)) invalidRoutingRequest();\n    return [pair[0], pair[1]];\n  });\n}\nconst nonnegative = value => Number.isFinite(value) && value >= 0;\nexport const routingYield = () => globalThis.scheduler?.yield ? globalThis.scheduler.yield() : new Promise(resolve => setTimeout(resolve, 0));\n\n// Yield actual tasks, not microtasks, while checking large canonical geometry.\nasync function validateLine(points, signal, count) {\n  if (!Array.isArray(points) || points.length < 2 || count.points + points.length > 200000) invalidRoutingResponse();\n  for (const point of points) {\n    if (!routingPoint(point)) invalidRoutingResponse();\n    if (++count.points % 1024 === 0) { await routingYield(); checkRoutingAbort(signal); }\n  }\n}\n\nexport async function validateRoute(data, profile, signal) {\n  if (data?.profile !== profile || data?.provider !== 'valhalla-local' || data.geometry?.type !== 'LineString'\n    || !nonnegative(data.distance) || !nonnegative(data.duration) || !Array.isArray(data.steps)\n    || !data.steps.length || data.steps.length > 20000) invalidRoutingResponse();\n  await validateLine(data.geometry.coordinates, signal, { points: 0 });\n  for (let i = 0; i < data.steps.length; i++) {\n    const step = data.steps[i];\n    if (!routingPoint(step?.point) || !nonnegative(step.distance) || !nonnegative(step.duration)\n      || typeof step.instruction !== 'string' || typeof step.maneuver !== 'string'\n      || (step.modifier !== null && typeof step.modifier !== 'string')) invalidRoutingResponse();\n    if (i && i % 512 === 0) { await routingYield(); checkRoutingAbort(signal); }\n  }\n  return data;\n}\n\nexport async function validateIsochrones(data, { profile, lat, lon, contours }, signal) {\n  if (data?.type !== 'FeatureCollection' || data.provider !== 'valhalla-local' || data.profile !== profile\n    || data.origin?.lat !== lat || data.origin?.lon !== lon || !Array.isArray(data.features) || !data.features.length\n    || data.features.length > 256 || !Array.isArray(data.contours)\n    || data.contours.length !== contours.length || data.contours.some((value, i) => value !== contours[i])) invalidRoutingResponse();\n  const seen = new Set(), count = { points: 0 };\n  for (const feature of data.features) {\n    const geometry = feature?.geometry, props = feature?.properties;\n    if (feature?.type !== 'Feature' || !contours.includes(props?.contour)\n      || !/^#[a-fA-F0-9]{6}$/.test(props.color) || !Number.isFinite(props['fill-opacity'])\n      || props['fill-opacity'] < 0 || props['fill-opacity'] > 1 || !['Polygon', 'MultiPolygon'].includes(geometry?.type)) invalidRoutingResponse();\n    seen.add(props.contour);\n    const polygons = geometry.type === 'Polygon' ? [geometry.coordinates] : geometry.coordinates;\n    if (!Array.isArray(polygons) || !polygons.length) invalidRoutingResponse();\n    for (const polygon of polygons) {\n      if (!Array.isArray(polygon) || !polygon.length) invalidRoutingResponse();\n      for (const ring of polygon) {\n        if (!Array.isArray(ring) || ring.length < 4) invalidRoutingResponse();\n        await validateLine(ring, signal, count);\n        if (ring[0][0] !== ring.at(-1)[0] || ring[0][1] !== ring.at(-1)[1]) invalidRoutingResponse();\n      }\n    }\n  }\n  if (contours.some(value => !seen.has(value))) invalidRoutingResponse();\n  return data;\n}\n\nexport async function validateMatching(data, inputCount, signal) {\n  if (data?.provider !== 'valhalla-local' || !Array.isArray(data?.matchings) || !data.matchings.length || data.matchings.length * inputCount > 200000) invalidRoutingResponse();\n  const count = { points: 0 }; let edgeCount = 0;\n  for (const match of data.matchings) {\n    if (match.geometry?.type !== 'LineString' || !Number.isFinite(match.confidence)\n      || match.confidence < 0 || match.confidence > 1 || !Array.isArray(match.snapped) || match.snapped.length !== inputCount\n      || !Array.isArray(match.edges) || !match.edges.length) invalidRoutingResponse();\n    await validateLine(match.geometry.coordinates, signal, count);\n    edgeCount += match.edges.length;\n    if (edgeCount > 64000) invalidRoutingResponse();\n    for (let i = 0; i < match.edges.length; i++) {\n      const edge = match.edges[i];\n      if (!Number.isSafeInteger(edge.beginShapeIndex) || !Number.isSafeInteger(edge.endShapeIndex)\n        || edge.beginShapeIndex < 0 || edge.endShapeIndex < edge.beginShapeIndex\n        || edge.endShapeIndex >= match.geometry.coordinates.length) invalidRoutingResponse();\n      if (i && i % 1024 === 0) { await routingYield(); checkRoutingAbort(signal); }\n    }\n    for (let i = 0; i < match.snapped.length; i++) {\n      const point = match.snapped[i];\n      if (point !== null && (!routingPoint([point.lon, point.lat]) || !Number.isSafeInteger(point.edge_index)\n        || point.edge_index < 0 || point.edge_index >= match.edges.length)) invalidRoutingResponse();\n      if (i && i % 1024 === 0) { await routingYield(); checkRoutingAbort(signal); }\n    }\n  }\n  return data;\n}\n","/** Turn-by-turn routing through NOCLIP's co-hosted Valhalla only.\n * Local unavailability is an explicit RoutingError, never a public-provider\n * or browser-compute fallback. Explicit offline tools remain in osm-router.js.\n */\nimport { getLocalRoutingClient, checkRoutingAbort, invalidRoutingRequest, RoutingError } from '../refactor/async/fetch/LocalRoutingClient.js';\nimport { routingCoordinates, routingProfile, routingYield, validateRoute } from '../refactor/routing/RoutingContracts.js';\n\nfunction haversineMeters(lat1, lon1, lat2, lon2) {\n  const R = 6371000;\n  const dLat = (lat2 - lat1) * Math.PI / 180;\n  const dLon = (lon2 - lon1) * Math.PI / 180;\n  const a = Math.sin(dLat / 2) ** 2\n    + Math.cos(lat1 * Math.PI / 180)\n    * Math.cos(lat2 * Math.PI / 180)\n    * Math.sin(dLon / 2) ** 2;\n  return R * 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));\n}\n\n/**\n * Turn an OSRM step into a normalised maneuver. OSRM step.maneuver.instruction\n * is absent; we synthesise a short human-readable instruction from (type, modifier, street).\n */\nexport function buildOsrmInstruction(step) {\n  const m = step?.maneuver || {};\n  const type = m.type || '';\n  const modifier = m.modifier || '';\n  const name = String(step?.name || '').trim();\n  const streetPart = name ? ` onto ${name}` : '';\n  switch (type) {\n    case 'depart': return name ? `Head ${modifier || ''} on ${name}`.trim() : 'Start';\n    case 'arrive': return 'You have arrived';\n    case 'turn': return `Turn ${modifier || 'ahead'}${streetPart}`.trim();\n    case 'continue': return `Continue${streetPart || ' straight'}`;\n    case 'merge': return `Merge${modifier ? ` ${modifier}` : ''}${streetPart}`.trim();\n    case 'fork': return `Keep ${modifier || 'straight'}${streetPart}`.trim();\n    case 'end of road': return `Turn ${modifier || ''}${streetPart}`.trim();\n    case 'roundabout':\n    case 'rotary': {\n      const exit = m.exit ? ` take exit ${m.exit}` : '';\n      return `Enter roundabout${exit}${streetPart}`.trim();\n    }\n    case 'new name': return `Continue${streetPart || ' straight'}`;\n    case 'on ramp': return `Take on-ramp${streetPart}`.trim();\n    case 'off ramp': return `Take exit${streetPart}`.trim();\n    default: return name || (type ? type.replace(/\\b\\w/g, (c) => c.toUpperCase()) : 'Continue');\n  }\n}\n\n/**\n * Pick a short glyph / icon identifier from a maneuver. Consumers (NavBanner,\n * DirectionsPanel) use this to choose an arrow sprite. Values keep the\n * vocabulary small so we don't need a full icon atlas.\n */\nexport function maneuverGlyph(step) {\n  const type = (step?.maneuver || step?.maneuverType || '').toLowerCase();\n  const mod = (step?.modifier || step?.maneuverModifier || '').toLowerCase();\n  if (type === 'arrive' || type === 'destination') return 'flag';\n  if (type === 'depart' || type === 'start') return 'up';\n  if (type === 'roundabout' || type === 'rotary') return 'rotary';\n  if (type === 'fork') return mod.includes('left') ? 'fork-left' : 'fork-right';\n  if (type === 'merge') return mod.includes('left') ? 'merge-left' : 'merge-right';\n  if (type === 'on ramp' || type === 'off ramp') return 'ramp';\n  if (mod.includes('sharp left')) return 'sharp-left';\n  if (mod.includes('sharp right')) return 'sharp-right';\n  if (mod.includes('slight left')) return 'slight-left';\n  if (mod.includes('slight right')) return 'slight-right';\n  if (mod.includes('left') || mod === 'left') return 'left';\n  if (mod.includes('right') || mod === 'right') return 'right';\n  if (mod.includes('u-turn') || mod.includes('uturn')) return 'u-turn';\n  return 'up';\n}\n\n/**\n * Waypoint arrays are [longitude, latitude]; objects are {lat, lon}.\n * Reject invalid waypoints rather than silently routing around a missing stop.\n */\nexport async function getRoute(waypoints, options = {}) {\n  checkRoutingAbort(options.signal);\n  const profile = routingProfile(options.profile);\n  const coords = routingCoordinates(waypoints);\n  if (options.alternatives !== undefined && typeof options.alternatives !== 'boolean') invalidRoutingRequest();\n  return getLocalRoutingClient().request('/routing/directions', {\n    query: { profile, coords: coords.map(point => point.join(',')).join(';'), alternatives: options.alternatives ? 'true' : 'false' },\n    signal: options.signal,\n    validate: async (data, signal) => hydrateRouteSteps(await validateRoute(data, profile, signal), signal),\n  });\n}\n\n/** Hydrate private canonical steps without duplicating the geometry or all steps. */\nasync function hydrateRouteSteps(route, signal) {\n  for (let i = 0; i < route.steps.length; i++) {\n    const step = route.steps[i];\n    if (!step.instruction.trim()) step.instruction = buildOsrmInstruction({\n      maneuver: { type: step.maneuver, modifier: step.modifier, location: step.point }, name: step.streetName,\n    });\n    step.glyph = maneuverGlyph(step);\n    if (i && i % 512 === 0) { await routingYield(); checkRoutingAbort(signal); }\n  }\n  route.trafficDelay = Number(route.trafficDelay) || 0;\n  return route;\n}\n\n/**\n * Return the total distance along the route as [0, total] for each coordinate\n * in the geometry — useful for snap-to-route calculations downstream.\n */\nexport function cumulativeDistancesMeters(route) {\n  const coords = route?.geometry?.coordinates || [];\n  if (coords.length < 2) return new Float64Array(coords.length);\n  const out = new Float64Array(coords.length);\n  let total = 0;\n  for (let i = 1; i < coords.length; i++) {\n    const [lon1, lat1] = coords[i - 1];\n    const [lon2, lat2] = coords[i];\n    total += haversineMeters(lat1, lon1, lat2, lon2);\n    out[i] = total;\n  }\n  return out;\n}\n\n// ── Transit stops (Overpass, no key) ─────────────────────────────────────\n\n/**\n * Return OSM transit stops within `radiusM` of (lat, lon) — bus stops,\n * rail stations, tram stops, ferry terminals.\n *\n * @returns {Promise<Array<{id, name, lat, lon, kind, refs:string[], network:string}>>}\n */\nexport async function fetchNearbyTransitStops(lat, lon, { radiusM = 600, limit = 40, signal } = {}) {\n  checkRoutingAbort(signal);\n  if (!Number.isFinite(lat) || !Number.isFinite(lon)) return [];\n  if (!Number.isInteger(limit) || limit < 1 || limit > 40) invalidRoutingRequest();\n  const r = Math.min(Math.max(Number(radiusM) || 600, 50), 3000);\n  const query = `\n[out:json][timeout:10];\n(\n  node[\"public_transport\"=\"stop_position\"](around:${r},${lat},${lon});\n  node[\"public_transport\"=\"platform\"](around:${r},${lat},${lon});\n  node[\"highway\"=\"bus_stop\"](around:${r},${lat},${lon});\n  node[\"railway\"=\"station\"](around:${r},${lat},${lon});\n  node[\"railway\"=\"tram_stop\"](around:${r},${lat},${lon});\n  node[\"amenity\"=\"bus_station\"](around:${r},${lat},${lon});\n  node[\"amenity\"=\"ferry_terminal\"](around:${r},${lat},${lon});\n);\nout body ${limit};`.trim();\n\n  return getLocalRoutingClient().request('/overpass', {\n    body: query, signal,\n    validate: (data) => {\n      if (!Array.isArray(data?.elements) || data.elements.length > limit) throw new RoutingError('routing_invalid_response');\n      const stops = [];\n      for (const el of data?.elements || []) {\n        if (el.type !== 'node' || !Number.isFinite(el.lat) || !Number.isFinite(el.lon)) continue;\n        const t = el.tags || {};\n        let kind = 'bus';\n        if (t.railway === 'station') kind = 'rail';\n        else if (t.railway === 'tram_stop' || t.railway === 'light_rail') kind = 'tram';\n        else if (t.amenity === 'ferry_terminal') kind = 'ferry';\n        else if (t.amenity === 'bus_station') kind = 'bus-station';\n        const name = String(t.name || t['name:en'] || '').trim();\n        const network = String(t.network || t.operator || '').trim();\n        const refs = String(t.route_ref || t.ref || '').split(/[;,]/).map((s) => s.trim()).filter(Boolean);\n        stops.push({\n          id: `node/${el.id}`,\n          lat: el.lat,\n          lon: el.lon,\n          name,\n          kind,\n          refs,\n          network,\n          tags: t,\n        });\n      }\n      return stops;\n    },\n  });\n}\n\nexport const __internal = {\n  haversineMeters,\n};\n","/**\n * OsmTrafficModel — synthetic traffic based on OSM road class + time of day.\n *\n * This is *not* live floating-car traffic (no free global keyless source\n * exists for that). Instead it's the same approach mapping apps used\n * pre-Waze/Google-Traffic: weight road-segment durations by how congested\n * that road class is expected to be at that hour, on that day of week.\n *\n * Shape is fully pluggable: if a real-time traffic source appears, callers\n * can swap in a different multiplier function via `createTrafficModel()`.\n *\n * ── Research basis ─────────────────────────────────────────────────────\n * Road-class sensitivity and rush-hour peak windows follow TRB-HCM style\n * tables: motorways are most volatile (free-flow 1.0x → peak 2.0–2.5x),\n * residentials barely move (0.95x → 1.2x). Weekends peak later and lower.\n */\n\nconst HOUR_BASELINE = 1.0;\n\n/**\n * Per-road-class peak multiplier (weekday). Values are what the multiplier\n * hits at the worst minute of rush hour. Overnight minimum is 0.7–0.9x.\n */\nconst CLASS_PEAK = {\n  motorway:      2.3,\n  motorway_link: 2.0,\n  trunk:         2.1,\n  trunk_link:    1.9,\n  primary:       1.9,\n  primary_link:  1.7,\n  secondary:     1.7,\n  secondary_link:1.55,\n  tertiary:      1.5,\n  tertiary_link: 1.4,\n  unclassified:  1.3,\n  residential:   1.2,\n  living_street: 1.05,\n  service:       1.1,\n  // Non-car classes don't suffer traffic in the same way\n  cycleway:      1.0,\n  path:          1.0,\n  footway:       1.0,\n  pedestrian:    1.0,\n  sidewalk:      1.0,\n  steps:         1.0,\n  track:         1.0,\n  default:       1.25,\n};\n\n/**\n * 24-hour congestion profile (normalised 0..1 of peak excess). 0 = free-flow,\n * 1 = at peak multiplier. Two typical rush peaks: 7-9am and 16-19pm.\n */\nconst WEEKDAY_HOURS = [\n  0.05, 0.03, 0.02, 0.02, 0.04, 0.15,  // 00..05\n  0.40, 0.85, 0.95, 0.65, 0.35, 0.30,  // 06..11\n  0.35, 0.32, 0.38, 0.55, 0.85, 1.00,  // 12..17\n  0.80, 0.50, 0.30, 0.20, 0.14, 0.08,  // 18..23\n];\n\nconst WEEKEND_HOURS = [\n  0.05, 0.04, 0.03, 0.02, 0.02, 0.04,\n  0.08, 0.15, 0.25, 0.40, 0.55, 0.60,\n  0.65, 0.68, 0.70, 0.72, 0.65, 0.55,\n  0.50, 0.45, 0.40, 0.30, 0.20, 0.10,\n];\n\nfunction hourWeight(hour, dow) {\n  const h = ((hour % 24) + 24) % 24;\n  const table = (dow === 0 || dow === 6) ? WEEKEND_HOURS : WEEKDAY_HOURS;\n  // Interpolate between hourly samples so duration transitions are smooth.\n  const h0 = Math.floor(h);\n  const h1 = (h0 + 1) % 24;\n  const f = h - h0;\n  return table[h0] * (1 - f) + table[h1] * f;\n}\n\n/**\n * Returns a multiplier to apply to a segment's free-flow duration.\n *\n * @param {object} args\n * @param {string} [args.highway]   — OSM highway class\n * @param {number} [args.hourLocal] — hour in local time 0..23.999 (fractional OK)\n * @param {number} [args.dow]       — day of week 0=Sun..6=Sat\n * @param {number} [args.lanes]     — OSM `lanes` count (reduces peak on wide roads)\n * @returns {number} multiplier ∈ [0.7, 2.5]\n */\nexport function getMultiplier({\n  highway = 'default',\n  hourLocal = 12,\n  dow = 2,\n  lanes = null,\n} = {}) {\n  const peak = CLASS_PEAK[highway] ?? CLASS_PEAK.default;\n  const w = hourWeight(hourLocal, dow);\n  // Base is interpolation between 0.85 (deep-night) and peak (fully-congested)\n  let m = 0.85 + (peak - 0.85) * w;\n  if (Number.isFinite(lanes) && lanes > 2) {\n    // Each lane above 2 shaves ~8% off peak excess (more capacity).\n    const shave = Math.min(0.3, (lanes - 2) * 0.08);\n    m = Math.max(1.0, m * (1 - shave * w));\n  }\n  // Wider clamp than per-class peak to absorb unclassified + edge cases.\n  return Math.max(0.7, Math.min(2.5, m));\n}\n\n/**\n * Re-weight a UnifiedRoute's step & total durations using the multiplier\n * at the caller-supplied \"now\" timestamp (or `Date.now()`). Returns an\n * augmented copy — *does not* mutate the input — with a `trafficDelay` field.\n */\nexport function applyTrafficToRoute(route, options = {}) {\n  if (!route || !Array.isArray(route.steps)) return route;\n  const now = options.now || new Date();\n  const dow = typeof options.dow === 'number' ? options.dow : now.getDay();\n  const hourLocal = typeof options.hourLocal === 'number'\n    ? options.hourLocal\n    : now.getHours() + now.getMinutes() / 60;\n  let freeFlow = 0;\n  let withTraffic = 0;\n  const steps = route.steps.map((step) => {\n    const highway = step.highway\n      || step.highwayClass\n      || (step.streetName ? 'unclassified' : 'default');\n    const m = getMultiplier({ highway, hourLocal, dow });\n    const newDur = Number(step.duration) * m;\n    freeFlow += Number(step.duration) || 0;\n    withTraffic += newDur || 0;\n    return { ...step, duration: newDur, trafficMultiplier: m };\n  });\n  const trafficDelay = Math.max(0, withTraffic - freeFlow);\n  return {\n    ...route,\n    steps,\n    duration: withTraffic || route.duration,\n    trafficDelay,\n    trafficModel: 'osm-time-of-day',\n  };\n}\n\n/**\n * Factory for pluggable traffic models. Future real-time sources can\n * implement this interface and register via a routing-service option.\n *\n * @typedef {object} TrafficModel\n * @property {(step:object, ctx:object) => number} getMultiplier\n * @property {(route:object, opts:object) => object} applyToRoute\n * @property {string} name\n */\nexport function createOsmTrafficModel(defaults = {}) {\n  return {\n    name: 'osm-time-of-day',\n    getMultiplier: (step, ctx = {}) => getMultiplier({\n      highway: step?.highway || step?.highwayClass || 'default',\n      hourLocal: ctx.hourLocal ?? defaults.hourLocal,\n      dow: ctx.dow ?? defaults.dow,\n      lanes: step?.lanes,\n    }),\n    applyToRoute: (route, opts) => applyTrafficToRoute(route, { ...defaults, ...opts }),\n  };\n}\n\nexport const __internal = { hourWeight, CLASS_PEAK, WEEKDAY_HOURS, WEEKEND_HOURS };\n","/** Variable-height navigation rows: all instructions remain scrollable while\n * only the visible range plus overscan owns DOM. No per-progress full scan. */\nexport class RouteStepHeights {\n  constructor(count, estimate = 40) {\n    this.count = count; this.estimate = estimate;\n    this.measured = new Float64Array(count);\n    this.deltas = new Float64Array(count + 1);\n  }\n  offset(index) {\n    let total = index * this.estimate;\n    for (let i = index; i > 0; i -= i & -i) total += this.deltas[i];\n    return total;\n  }\n  measure(index, height) {\n    if (index < 0 || index >= this.count || !Number.isFinite(height) || height <= 0) return false;\n    const before = this.measured[index] || this.estimate;\n    if (Math.abs(height - before) < 0.1) return false;\n    this.measured[index] = height;\n    for (let i = index + 1; i <= this.count; i += i & -i) this.deltas[i] += height - before;\n    return true;\n  }\n  indexAt(offset) {\n    if (!this.count) return 0;\n    let low = 0, high = this.count;\n    while (low < high) {\n      const mid = Math.floor((low + high) / 2);\n      if (this.offset(mid + 1) <= offset) low = mid + 1;\n      else high = mid;\n    }\n    return Math.min(this.count - 1, low);\n  }\n}\n\nexport class RouteStepsWindow {\n  constructor(element, renderRow) {\n    this.element = element; this.renderRow = renderRow;\n    this.rows = new Map(); this.steps = []; this.heights = new RouteStepHeights(0);\n    this.active = -1; this.frame = null; this.disposed = false;\n    this.start = -1; this.end = -1;\n    this.top = this._spacer(); this.bottom = this._spacer();\n    element.tabIndex = 0; element.setAttribute('aria-label', 'Route instructions');\n    // We preserve the measured anchor ourselves; do not double-adjust with\n    // the browser's independent DOM-insertion scroll anchoring.\n    element.style.overflowAnchor = 'none';\n    this.onScroll = () => this._schedule();\n    element.addEventListener('scroll', this.onScroll, { passive: true });\n    this.resize = typeof ResizeObserver === 'function' ? new ResizeObserver(() => this._schedule()) : null;\n    this.resize?.observe(element);\n  }\n  _spacer() {\n    const node = document.createElement('li'); node.setAttribute('aria-hidden', 'true'); node.setAttribute('role', 'presentation');\n    node.style.cssText = 'height:0;padding:0;margin:0;border:0;list-style:none;pointer-events:none';\n    return node;\n  }\n  setSteps(steps) {\n    if (this.disposed) return;\n    this._cancel(); this._clearRows();\n    this.steps = steps; this.heights = new RouteStepHeights(steps.length);\n    this.start = -1; this.end = -1; this.active = -1;\n    this.element.scrollTop = 0; this._render();\n  }\n  setActive(index) {\n    if (index === this.active || this.disposed) return;\n    this.rows.get(this.active)?.classList.remove('active');\n    this.active = index; this.rows.get(index)?.classList.add('active');\n  }\n  _cancel() {\n    if (this.frame !== null) cancelAnimationFrame(this.frame);\n    this.frame = null;\n  }\n  _schedule() {\n    if (this.disposed || this.frame !== null) return;\n    this.frame = requestAnimationFrame(() => { this.frame = null; this._render(); });\n  }\n  _clearRows() {\n    for (const row of this.rows.values()) this.resize?.unobserve(row);\n    this.rows.clear(); this.element.replaceChildren();\n  }\n  _render() {\n    if (this.disposed || !this.steps.length) return;\n    const heights = this.heights, el = this.element;\n    const anchor = heights.indexAt(el.scrollTop), within = el.scrollTop - heights.offset(anchor);\n    const start = Math.max(0, anchor - 8);\n    const end = Math.min(this.steps.length, start + 64, heights.indexAt(el.scrollTop + (el.clientHeight || 150)) + 9);\n    if (start !== this.start || end !== this.end) {\n      for (const [index, row] of this.rows) if (index < start || index >= end) {\n        this.resize?.unobserve(row); this.rows.delete(index);\n      }\n      const nodes = [this.top];\n      for (let i = start; i < end; i++) {\n        let row = this.rows.get(i);\n        if (!row) {\n          row = this.renderRow(this.steps[i], i);\n          row.setAttribute('aria-posinset', String(i + 1)); row.setAttribute('aria-setsize', String(this.steps.length));\n          this.rows.set(i, row); this.resize?.observe(row);\n        }\n        row.classList.toggle('active', i === this.active); nodes.push(row);\n      }\n      nodes.push(this.bottom); el.replaceChildren(...nodes);\n      this.start = start; this.end = end;\n    }\n    this.top.style.height = `${heights.offset(start)}px`;\n    this.bottom.style.height = `${Math.max(0, heights.offset(this.steps.length) - heights.offset(end))}px`;\n    // Read one bounded batch, then write. Prefix updates are logarithmic and\n    // preserve the reader's scroll anchor when wrapped rows are measured.\n    const measured = [...this.rows].map(([i, row]) => [i, row.getBoundingClientRect().height]);\n    let changed = false;\n    for (const [i, height] of measured) changed = heights.measure(i, height) || changed;\n    if (changed) {\n      this.top.style.height = `${heights.offset(start)}px`;\n      this.bottom.style.height = `${Math.max(0, heights.offset(this.steps.length) - heights.offset(end))}px`;\n      el.scrollTop = Math.max(0, heights.offset(anchor) + within);\n      this._schedule();\n    }\n  }\n  dispose() {\n    if (this.disposed) return;\n    this.disposed = true; this._cancel(); this.resize?.disconnect();\n    this.element.removeEventListener('scroll', this.onScroll); this._clearRows();\n    this.steps = []; this.heights = new RouteStepHeights(0);\n  }\n}\n","import { routeStopBadge } from '../geo/PlaceSearchResults.js';\n\n/** Touch and keyboard equivalents accompany desktop row drag and map drag. */\nexport class RouteWaypointsEditor {\n  constructor({ container, routes, onSearch, getLocation }) {\n    Object.assign(this, { routes, onSearch, getLocation });\n    this.el = document.createElement('section'); this.el.className = 'nc-route-stops';\n    this.el.setAttribute('aria-label', 'Route stops'); container.prepend(this.el);\n    this.onChange = () => this.render();\n    document.addEventListener('noclip:route:waypoints', this.onChange); this.render();\n  }\n  render() {\n    this.el.replaceChildren();\n    const points = this.routes.getWaypoints();\n    const button = (text, title, run) => {\n      const el = document.createElement('button'); el.type = 'button'; el.textContent = text;\n      el.title = title; el.setAttribute('aria-label', title); el.addEventListener('click', run); return el;\n    };\n    const heading = document.createElement('div'); heading.className = 'nc-route-stops__heading';\n    heading.append('Route stops');\n    heading.append(button('My location', 'Use current location as origin', () => {\n      const location = this.getLocation?.(); if (!location) return;\n      if (points.length > 1) points[0] = { ...points[0], ...location, name: 'My location', liveLocation: true };\n      else points.unshift({ ...location, name: 'My location', role: 'origin', liveLocation: true });\n      this.routes.setWaypoints(points);\n    }));\n    this.el.append(heading);\n    points.forEach((point, index) => {\n      const row = document.createElement('div'); row.className = 'nc-route-stop'; row.draggable = true;\n      row.dataset.waypointId = point.id;\n      const badge = document.createElement('b'); badge.textContent = routeStopBadge(index, points.length, point.role);\n      const name = document.createElement('input'); name.value = point.name; name.maxLength = 160;\n      name.setAttribute('aria-label', `Name for stop ${badge.textContent}`);\n      name.addEventListener('change', () => this.routes.renameWaypoint(point.id, name.value));\n      row.append(badge, name,\n        button('Search', `Search for stop ${badge.textContent}`, () => this.onSearch(point.id)),\n        button('Move', `Move stop ${badge.textContent} on the map`, () => this.routes.setMovingWaypoint(point.id)),\n        button('↑', `Move stop ${badge.textContent} earlier`, () => { if (index) this.routes.reorderWaypoint(point.id, points[index - 1].id); }),\n        button('↓', `Move stop ${badge.textContent} later`, () => { if (index < points.length - 1) this.routes.reorderWaypoint(point.id, points[index + 1].id); }),\n        button('×', `Remove stop ${badge.textContent}`, () => this.routes.removeWaypoint(point.id)));\n      row.addEventListener('dragstart', event => { event.dataTransfer.setData('text/noclip-route-stop', point.id); });\n      row.addEventListener('dragover', event => event.preventDefault());\n      row.addEventListener('drop', event => { event.preventDefault(); this.routes.reorderWaypoint(event.dataTransfer.getData('text/noclip-route-stop'), point.id); });\n      this.el.append(row);\n    });\n    if (points.length < 10) this.el.append(button('+ Add stop', 'Search for an additional route stop', () => this.onSearch('new')));\n    if (this.routes.getMovingWaypoint()) {\n      const note = document.createElement('p'); note.textContent = 'Tap the map to move this stop, or choose Move route stop here in the surface menu.';\n      note.setAttribute('role', 'status');\n      note.append(button('Cancel', 'Cancel moving stop', () => this.routes.setMovingWaypoint(null))); this.el.append(note);\n    }\n  }\n  dispose() { document.removeEventListener('noclip:route:waypoints', this.onChange); this.el.remove(); }\n}\n","/**\n * DirectionsPanel — destination entry + mode selection + step list.\n *\n * Flow:\n *   1. User types into the destination input → local Mapsource autocomplete\n *   2. Picks a result → RouteStore.setDestination\n *   3. Mode tab (Walk/Bike/Drive/Transit) → RouteStore.setProfile\n *   4. \"Go\" → fetches route via getRoute() → RouteStore.setRoute\n *   5. Step list + ETA populate from RouteStore events\n *   6. \"Cancel\" clears RouteStore + panel inputs\n *\n * All styling lives in admin-theme.css under the .nc-directions prefix.\n */\nimport { searchPlaces, getPlaceSearchBias, lookupNotice, formatResultForDisplay } from '../../modules/geocoding-service.js';\nimport { getRoute, fetchNearbyTransitStops } from '../../modules/routing-service.js';\nimport { applyTrafficToRoute } from '../../modules/osm-traffic-model.js';\nimport { RoutingError } from '../async/fetch/LocalRoutingClient.js';\nimport { getRouteStore } from '../routing/RouteStore.js';\nimport { RouteStepsWindow } from './RouteStepsWindow.js';\nimport { RouteWaypointsEditor } from './RouteWaypointsEditor.js';\nimport { getPlaceSearchStore } from '../geo/PlaceSearchStore.js';\nimport { bindPlaceSearchList } from './PlaceSearchList.js';\n\nconst MODES = [\n  { id: 'driving', label: 'Drive', glyph: '⌂' },  // house (car placeholder)\n  { id: 'cycling', label: 'Bike',  glyph: '☯' },\n  { id: 'foot',    label: 'Walk',  glyph: '⛷' },\n  { id: 'transit', label: 'Transit', glyph: '✈' },\n];\n\n/**\n * Map a normalised maneuver-glyph token to a printable arrow character.\n * Mirrors the table NavBanner uses so step icons in the side list match\n * the live arrow in the banner.\n */\nconst STEP_ARROWS = {\n  up:             '↑',\n  left:           '↰',\n  right:          '↱',\n  'slight-left':  '↖',\n  'slight-right': '↗',\n  'sharp-left':   '↺',\n  'sharp-right':  '↻',\n  'fork-left':    '⇤',\n  'fork-right':   '⇥',\n  'merge-left':   '⇇',\n  'merge-right':  '⇉',\n  'u-turn':       '⟲',\n  ramp:           '↯',\n  rotary:         '⟳',\n  flag:           '⚑',\n};\nfunction arrowFor(glyph) {\n  return STEP_ARROWS[glyph] || STEP_ARROWS.up;\n}\n\nfunction escapeHtml(v) {\n  return String(v || '').replace(/[&<>\"']/g, (c) => ({\n    '&': '&amp;', '<': '&lt;', '>': '&gt;', '\"': '&quot;', \"'\": '&#39;',\n  }[c]));\n}\n\nfunction formatDistance(m) {\n  if (!Number.isFinite(m) || m <= 0) return '0 m';\n  if (m < 1000) return `${Math.round(m)} m`;\n  return `${(m / 1000).toFixed(m < 10000 ? 1 : 0)} km`;\n}\n\nfunction formatDuration(s) {\n  if (!Number.isFinite(s) || s <= 0) return '—';\n  const mins = Math.round(s / 60);\n  if (mins < 60) return `${mins} min`;\n  const h = Math.floor(mins / 60);\n  const m = mins % 60;\n  return `${h}h ${m.toString().padStart(2, '0')}m`;\n}\n\nexport class DirectionsPanel {\n  constructor({ container, getPlayerLatLon, routeStore, routeLoader = getRoute, transitLoader = fetchNearbyTransitStops, placeSearch = searchPlaces } = {}) {\n    this.container = container || document.body;\n    this.getPlayerLatLon = typeof getPlayerLatLon === 'function' ? getPlayerLatLon : null;\n    this._el = null;\n    this._destInput = null;\n    this._suggestions = null;\n    this._modeTabs = null;\n    this._etaEl = null;\n    this._distEl = null;\n    this._stepsEl = null;\n    this._stepsView = null;\n    this._statusEl = null;\n    this._profile = 'driving';\n    this._destination = null;\n    this._routeStore = routeStore || getRouteStore();\n    this._routeLoader = routeLoader; this._transitLoader = transitLoader; this._placeSearch = placeSearch;\n    this._listeners = []; this._disposed = false; this._searchGeneration = 0; this._retryAt = 0;\n    this._retryHandler = () => this._go();\n    this._searchTimer = null;\n    this._routeRequest = null;\n    this._visible = false;\n    this._build();\n    this._bindEvents();\n    this._bindRouteStore();\n  }\n\n  open() {\n    if (this._disposed) return;\n    this._ensureBody();\n    this._visible = true;\n    if (this._el) this._el.classList.add('visible');\n    if (this._routeStore.getRoute()) this._onRouteSet(this._routeStore.getRoute());\n    this._destInput?.focus?.();\n  }\n\n  close({ removeBody = false } = {}) {\n    this._searchAbort?.abort(); this._searchAbort = null;\n    this._stepsView?.dispose(); this._stepsView = null;\n    this._routeRequest?.cancel(); this._routeRequest = null;\n    clearTimeout(this._searchTimer); this._searchTimer = null; this._searchGeneration++;\n    this._visible = false;\n    if (this._el) this._el.classList.remove('visible');\n    this._setSuggestions([]);\n    // Ending navigation must not leave the directions body visible beneath\n    // the shared search row (notably on the mobile HUD override).\n    if (removeBody && this._bodyEl) {\n      this._waypointsEditor?.dispose(); this._waypointsEditor = null;\n      this._offSearchList?.(); this._offSearchList = null;\n      this._bodyEl.remove();\n      this._bodyEl = null;\n      this._suggestions = null;\n      this._etaEl = null;\n      this._distEl = null;\n      this._summaryEl = null;\n      this._statusEl = null;\n      this._retryBtn = null;\n      this._stepsEl = null;\n    }\n  }\n\n  toggle() { this._visible ? this.close() : this.open(); }\n\n  isVisible() { return this._visible; }\n\n  /** True when a destination has been picked from suggestions. */\n  hasDestination() { return !!this._destination; }\n  /** True when a route has been computed and is currently being followed. */\n  isRouting() { return !!this._routeStore?.getRoute?.(); }\n  /** Public alias for the internal _go action. */\n  go() { return this._go(); }\n  /** End routing and remove its panel body from the shared HUD. */\n  cancelRoute() { return this._cancel({ close: true }); }\n\n  toggleCollapse() {\n    this._collapsed = !this._collapsed;\n    if (this._el) this._el.classList.toggle('collapsed', this._collapsed);\n    if (this._collapseBtn) {\n      this._collapseBtn.textContent = this._collapsed ? '+' : '−';\n      this._collapseBtn.title = this._collapsed ? 'Expand' : 'Collapse';\n      this._collapseBtn.setAttribute('aria-label', this._collapsed ? 'Expand directions' : 'Collapse directions');\n    }\n  }\n\n  _build() {\n    // Header + own input row removed: the panel now reuses the\n    // existing top-center .hud-search-input as the destination\n    // search box when nav mode is active. Suggestions render below\n    // the search bar (mounted into the panel's .nc-directions-body).\n    const el = document.createElement('div');\n    el.className = 'nc-directions';\n    el.innerHTML = `\n      <div class=\"nc-directions-body\">\n        <div class=\"nc-directions-suggestions\" role=\"listbox\" aria-label=\"Destination suggestions\"></div>\n        <div class=\"nc-directions-status\"></div>\n        <div class=\"nc-directions-summary\" hidden>\n          <div class=\"nc-directions-eta\"></div>\n          <div class=\"nc-directions-distance\"></div>\n        </div>\n        <ol class=\"nc-directions-steps\" hidden></ol>\n      </div>\n    `;\n    this.container.appendChild(el);\n    this._el = el;\n    this._collapseBtn = null;\n    this._bodyEl = el.querySelector('.nc-directions-body');\n    this._collapsed = false;\n    // Adopt the global hud-search-input as the destination input.\n    // Falls back to a hidden synthetic input if hud-search isn't\n    // mounted yet — prevents null-deref on early init.\n    this._destInput = document.getElementById('hud-search-input')\n      || (() => { const i = document.createElement('input'); i.style.display = 'none'; el.appendChild(i); return i; })();\n    this._suggestions = el.querySelector('.nc-directions-suggestions');\n    // Mode tabs are now external (see HUD .hud-search-modes dropdown\n    // wired up by HudManager). Keep a stub so _setActiveMode doesn't\n    // throw when the external tabs aren't mounted yet.\n    this._modeTabs = document.querySelector('.hud-search-modes') || document.createElement('div');\n    this._etaEl = el.querySelector('.nc-directions-eta');\n    this._distEl = el.querySelector('.nc-directions-distance');\n    this._summaryEl = el.querySelector('.nc-directions-summary');\n    this._statusEl = el.querySelector('.nc-directions-status');\n    this._stepsEl = el.querySelector('.nc-directions-steps');\n    // The Go / Cancel buttons are removed — the hud-directions-button\n    // (top-center search row) now drives that action: clicking it\n    // when a destination is selected starts navigation, clicking it\n    // again while routing cancels it. Keep the field references as\n    // disposable stubs so the rest of the file can write\n    // `this._goBtn.disabled = …` without null-derefs.\n    this._goBtn = { disabled: false };\n    this._cancelBtn = { hidden: true };\n    this._bindPlaceSearchTools();\n    this._ensureRetryButton();\n    this._setActiveMode(this._profile);\n  }\n\n  _ensureBody() {\n    if (this._bodyEl || !this._el) return;\n    const body = document.createElement('div');\n    body.className = 'nc-directions-body';\n    body.innerHTML = `\n      <div class=\"nc-directions-suggestions\" role=\"listbox\" aria-label=\"Destination suggestions\"></div>\n      <div class=\"nc-directions-status\"></div>\n      <div class=\"nc-directions-summary\" hidden>\n        <div class=\"nc-directions-eta\"></div>\n        <div class=\"nc-directions-distance\"></div>\n      </div>\n      <ol class=\"nc-directions-steps\" hidden></ol>\n    `;\n    this._el.appendChild(body);\n    this._bodyEl = body;\n    this._suggestions = body.querySelector('.nc-directions-suggestions');\n    this._etaEl = body.querySelector('.nc-directions-eta');\n    this._distEl = body.querySelector('.nc-directions-distance');\n    this._summaryEl = body.querySelector('.nc-directions-summary');\n    this._statusEl = body.querySelector('.nc-directions-status');\n    this._stepsEl = body.querySelector('.nc-directions-steps');\n    this._bindPlaceSearchTools();\n    this._suggestions.addEventListener('click', this._suggestionClickHandler);\n    this._ensureRetryButton();\n  }\n\n  _bindPlaceSearchTools() {\n    this._waypointsEditor = new RouteWaypointsEditor({ container: this._bodyEl, routes: this._routeStore,\n      getLocation: this.getPlayerLatLon, onSearch: id => {\n        this._editingWaypointId = id; this._destInput.value = ''; this._destInput.focus();\n        this._status('Search for a place to use for this stop.', 'info');\n      } });\n    this._offSearchList = bindPlaceSearchList(this._suggestions, { owner: this,\n      selector: '.nc-directions-suggestion', indexAttribute: 'data-index' });\n  }\n\n  _ensureRetryButton() {\n    if (!this._bodyEl || this._retryBtn) return;\n    this._retryBtn = document.createElement('button');\n    this._retryBtn.type = 'button'; this._retryBtn.className = 'nc-directions-retry';\n    this._retryBtn.textContent = 'Retry route'; this._retryBtn.hidden = true;\n    this._retryBtn.addEventListener('click', this._retryHandler);\n    this._statusEl?.after(this._retryBtn);\n  }\n\n  _listen(target, type, handler) {\n    target.addEventListener(type, handler); this._listeners.push(() => target.removeEventListener(type, handler));\n  }\n\n  dispose() {\n    if (this._disposed) return;\n    this.close({ removeBody: true }); this._disposed = true;\n    for (const off of this._listeners.splice(0)) off();\n    this._destInput?.removeEventListener('input', this._destInputHandler);\n    this._destInput?.removeEventListener('keydown', this._destInputKeyHandler);\n    this._modeTabs?.removeEventListener('click', this._modeClickHandler);\n    this._el?.remove(); this._el = null; this._lastResults = [];\n  }\n\n  _bindEvents() {\n    // Bind to the shared hud-search-input. We attach a wrapper handler\n    // that delegates to _scheduleSearch only while nav mode is active\n    // (this._visible) — when the panel is closed, the search bar\n    // resumes its normal place-search behaviour managed by index.html.\n    this._destInputHandler = () => {\n      if (this._visible) this._scheduleSearch();\n    };\n    this._destInputKeyHandler = (e) => {\n      if (!this._visible) return;\n      if (e.key === 'Escape') { this.close(); }\n      if (e.key === 'Enter') {\n        e.preventDefault();\n        if (this._destination) this._go();\n      }\n    };\n    this._destInput.addEventListener('input', this._destInputHandler);\n    this._destInput.addEventListener('keydown', this._destInputKeyHandler);\n\n    // Mode tab clicks (external .hud-search-modes dropdown — owned\n    // by HudManager). Delegated handler tolerates the dropdown not\n    // being mounted yet.\n    this._modeClickHandler = (e) => {\n      const btn = e.target.closest('.nc-directions-mode, [data-nav-mode]');\n      if (!btn) return;\n      const mode = btn.dataset.mode || btn.dataset.navMode;\n      if (mode) this._setActiveMode(mode);\n    };\n    this._modeTabs.addEventListener('click', this._modeClickHandler);\n\n    // Go / Cancel buttons are gone — handled via the directions\n    // toggle button outside the panel. Nothing to bind here.\n    this._suggestionClickHandler = (e) => {\n      const li = e.target.closest('.nc-directions-suggestion');\n      if (!li) return;\n      const idx = Number(li.dataset.index);\n      const results = this._lastResults || [];\n      this._selectSuggestion(results[idx]);\n    };\n    this._suggestions.addEventListener('click', this._suggestionClickHandler);\n    this._listen(document, 'click', (e) => {\n      if (!this._el || !this._visible) return;\n      // Click is \"outside\" if it lands on neither the suggestions list\n      // nor the shared hud-search-input we're piggy-backing on.\n      if (!this._el.contains(e.target) && e.target !== this._destInput) {\n        this._setSuggestions([]);\n      }\n    });\n  }\n\n  _bindRouteStore() {\n    this._listen(document, 'noclip:route:destination-set', ev => {\n      this._destination = ev.detail;\n      if (this._destInput && ev.detail) this._destInput.value = ev.detail.name || '';\n    });\n    this._listen(document, 'noclip:route:profile-set', ev => this._setActiveMode(ev.detail));\n    this._listen(document, 'noclip:route:set', (ev) => this._onRouteSet(ev.detail));\n    this._listen(document, 'noclip:route:cleared', () => this._onRouteCleared());\n    this._listen(document, 'noclip:route:progress', (ev) => this._onRouteProgress(ev.detail));\n    this._listen(document, 'noclip:route:arrived', () => this._status('You have arrived.', 'success'));\n  }\n\n  // ── Destination search ─────────────────────────────────────────────────\n\n  _scheduleSearch() {\n    this._searchAbort?.abort(); this._searchAbort = null;\n    clearTimeout(this._searchTimer);\n    const generation = ++this._searchGeneration;\n    this._routeRequest?.cancel(); this._retryAt = 0;\n    if (!this._editingWaypointId) {\n      this._destination = null;\n      this._routeStore.clear({ clearDestination: true });\n    }\n    getPlaceSearchStore().clear(this);\n    const q = this._destInput.value.trim();\n    if (q.length < 2) {\n      this._setSuggestions([]);\n      return;\n    }\n    this._searchTimer = setTimeout(() => this._runSearch(q, generation), 260);\n  }\n\n  async _runSearch(q, generation = this._searchGeneration) {\n    this._searchAbort?.abort();\n    const controller = this._searchAbort = new AbortController();\n    const bias = getPlaceSearchBias();\n    const location = Number.isFinite(bias.lat) ? bias : this.getPlayerLatLon?.();\n    try {\n      const results = await this._placeSearch(q, {\n        limit: 8,\n        ...(Number.isFinite(location?.lat) && Number.isFinite(location?.lon) ? { lat: location.lat, lon: location.lon } : {}),\n        signal: controller.signal,\n      });\n      if (this._disposed || !this._visible || generation !== this._searchGeneration || this._destInput.value.trim() !== q) return;\n      this._lastResults = results || [];\n      this._setSuggestions(this._lastResults);\n    } catch (error) {\n      if (this._visible && generation === this._searchGeneration && !controller.signal.aborted) {\n        this._setSuggestions([]);\n        this._status('Local Mapsource search is temporarily unavailable.', 'warn');\n      }\n    }\n  }\n\n  _buildViewbox() {\n    const player = this.getPlayerLatLon?.();\n    if (!player) return undefined;\n    // A ~200km window around the player — biases results to \"places near me\".\n    const d = 1.8;\n    return [player.lon - d, player.lat - d, player.lon + d, player.lat + d];\n  }\n\n  _setSuggestions(results) {\n    if (!this._suggestions) return;\n    const notice = lookupNotice(results);\n    if (!results?.length) {\n      getPlaceSearchStore().clear(this);\n      this._suggestions.textContent = notice;\n      this._suggestions.classList.toggle('visible', !!notice);\n      return;\n    }\n    this._suggestions.innerHTML = (notice ? `<div class=\"search-coverage-notice\">${escapeHtml(notice)}</div>` : '') + results.map((r, i) => {\n      const { primary, secondary } = formatResultForDisplay(r);\n      return `\n        <button class=\"nc-directions-suggestion\" type=\"button\" role=\"option\" data-index=\"${i}\">\n          <span class=\"nc-directions-suggestion-primary\">${escapeHtml(primary)}</span>\n          <span class=\"nc-directions-suggestion-secondary\">${escapeHtml(secondary)}</span>\n        </button>\n      `;\n    }).join('');\n    this._suggestions.classList.add('visible');\n    getPlaceSearchStore().setResults(this, results, { onSelect: result => this._selectSuggestion(result) });\n  }\n\n  _selectSuggestion(result) {\n    if (!result) return;\n    if (this._editingWaypointId) {\n      const id = this._editingWaypointId; this._editingWaypointId = null;\n      const point = { lat: result.lat, lon: result.lon, name: result.name || result.displayName, address: result.displayName };\n      if (id === 'new') {\n        if (this._routeStore.getWaypoints().length === 1) {\n          const location = this.getPlayerLatLon?.();\n          if (location) this._routeStore.insertWaypoint({ ...location, name: 'My location' }, 0);\n        }\n        this._routeStore.insertWaypoint(point);\n      } else {\n        this._routeStore.setWaypoints(this._routeStore.getWaypoints().map(p => p.id === id ? { ...p, ...point } : p));\n      }\n      this._setSuggestions([]); this._lastResults = [];\n      this._destInput.value = this._destination?.name || '';\n      return;\n    }\n    this.setDestinationDirect({ lat: result.lat, lon: result.lon,\n      name: result.name || result.displayName?.split(',')[0] || 'Destination', address: result.displayName || '' });\n  }\n\n  _setActiveMode(mode) {\n    if (mode === 'walking') mode = 'foot';\n    if (!MODES.some(item => item.id === mode)) return;\n    if (this._profile !== mode) { this._routeRequest?.cancel(); this._retryAt = 0; }\n    this._profile = mode;\n    this._routeStore.setProfile(mode);\n    // Update internal mode tabs (legacy markup, may be empty in\n    // two-tier mode where the dropdown lives next to hud-home-icon).\n    if (this._modeTabs?.querySelectorAll) {\n      for (const btn of this._modeTabs.querySelectorAll('.nc-directions-mode, [data-nav-mode], [data-mode]')) {\n        const m = btn.dataset.mode || btn.dataset.navMode;\n        const active = m === mode;\n        btn.classList.toggle('active', active);\n        btn.setAttribute('aria-selected', active ? 'true' : 'false');\n      }\n    }\n    // Notify the external mode dropdown (HUD .hud-search-modes).\n    if (typeof document !== 'undefined') {\n      document.dispatchEvent(new CustomEvent('noclip:nav-mode:change', { detail: { mode } }));\n    }\n  }\n\n  /** Public setter — accepts driving | cycling | walking | transit. */\n  setMode(mode) { this._setActiveMode(mode); }\n  /** Current active mode. */\n  getMode() { return this._profile; }\n\n  /**\n   * Programmatic destination set — bypasses the typed-search /\n   * suggestion flow. Used by the agent's `navigate_to` intent so the\n   * LLM can hand us a {lat, lon, name} directly without simulating\n   * keystrokes. Returns true on success.\n   */\n  setDestinationDirect({ lat, lon, name, address } = {}) {\n    if (this._disposed || !Number.isFinite(lat) || !Number.isFinite(lon) || Math.abs(lat) > 90 || Math.abs(lon) > 180) return false;\n    this._searchAbort?.abort(); this._searchAbort = null;\n    this._editingWaypointId = null;\n    this._routeRequest?.cancel(); this._retryAt = 0;\n    clearTimeout(this._searchTimer); this._searchGeneration++;\n    this._destination = {\n      lat,\n      lon,\n      name: name || 'Destination',\n      address: address || '',\n    };\n    if (this._destInput) this._destInput.value = this._destination.name;\n    this._setSuggestions([]);\n    this._routeStore.setDestination(this._destination);\n    if (this._goBtn) this._goBtn.disabled = false;\n    this._status('Destination set. Press Go (or wait for the agent).', 'info');\n    return true;\n  }\n\n  // ── Route action ───────────────────────────────────────────────────────\n\n  async _go() {\n    if (this._disposed || !this._destination) return;\n    if (this._retryAt > Date.now()) {\n      this._status(`Please retry in ${Math.ceil((this._retryAt - Date.now()) / 1000)} seconds.`, 'warn', true);\n      return;\n    }\n    let points = this._routeStore.getWaypoints();\n    const location = points.length > 1 && !points[0].liveLocation ? points[0] : this.getPlayerLatLon?.();\n    if (!location || !Number.isFinite(location.lat) || !Number.isFinite(location.lon)) {\n      this._status('Waiting for your location…', 'warn');\n      return;\n    }\n    this._routeRequest?.cancel();\n    if (points.length < 2) {\n      this._routeStore.insertWaypoint({ ...location, name: 'My location', liveLocation: true }, 0);\n      points = this._routeStore.getWaypoints();\n    } else if (points[0].liveLocation && (points[0].lat !== location.lat || points[0].lon !== location.lon)) {\n      points[0] = { ...points[0], ...location };\n      this._routeStore.setWaypoints(points);\n    }\n    const request = this._routeStore.beginRequest({ origin: location, destination: this._destination, profile: this._profile, waypoints: points });\n    this._routeRequest = request;\n    const { origin, destination, profile, signal } = request;\n    let transitNote = '';\n    const current = () => !this._disposed && this._routeRequest === request && request.isCurrent();\n    this._status('Calculating route…', 'info');\n    this._goBtn.disabled = true;\n    if (this._retryBtn) this._retryBtn.disabled = true;\n    try {\n      if (profile === 'transit') {\n        // Nearby stop data is not a timetable or a transit routing graph.\n        this._status('Finding nearby transit stops…', 'info');\n        const lookup = new AbortController(), stopLookup = () => lookup.abort(signal.reason);\n        signal.addEventListener('abort', stopLookup, { once: true });\n        try {\n          const [originStops, destStops] = await Promise.all([\n            this._transitLoader(origin.lat, origin.lon, { radiusM: 500, limit: 12, signal: lookup.signal }),\n            this._transitLoader(destination.lat, destination.lon, { radiusM: 500, limit: 12, signal: lookup.signal }),\n          ]);\n          if (!current()) return;\n          this._publishTransitStops(originStops, destStops);\n          transitNote = `${originStops.length} stops near you · ${destStops.length} near destination. `;\n        } catch (error) {\n          lookup.abort(error);\n          if (!current() || signal.aborted) return;\n          transitNote = 'Transit stops unavailable. ';\n        } finally { signal.removeEventListener('abort', stopLookup); }\n        this._status('Calculating a walking baseline; transit schedules are not included.', 'info');\n      }\n      let route = await this._routeLoader(request.waypoints || [origin, destination], { profile: profile === 'transit' ? 'foot' : profile, signal });\n      if (!current()) return;\n      if (!route) throw new RoutingError('routing_no_route');\n      if (profile === 'driving' || profile === 'cycling') route = applyTrafficToRoute(route);\n      if (!current()) return;\n      if (this._routeStore.commitRequest(request, route)) {\n        this._retryAt = 0;\n        this._status(`${profile === 'transit' ? `${transitNote}Walking baseline (no transit schedules) · ` : ''}${route.provider} • ${formatDistance(route.distance)} • ${formatDuration(route.duration)}`, 'success');\n        return route;\n      }\n    } catch (error) {\n      if (!current() || signal.aborted) return;\n      this._retryAt = Date.now() + (error?.retryAfterMs || 0);\n      const message = error instanceof RoutingError ? error.message : 'The local routing service is unavailable. Please retry.';\n      this._status(message, 'error', true);\n    } finally {\n      request.finish();\n      if (this._routeRequest === request) {\n        this._routeRequest = null;\n        this._goBtn.disabled = !this._destination || this.isRouting();\n        if (this._retryBtn) this._retryBtn.disabled = false;\n      }\n    }\n  }\n\n  _cancel({ close = false } = {}) {\n    this._routeRequest?.cancel(); this._routeRequest = null; this._retryAt = 0;\n    this._routeStore.clear({ clearDestination: close });\n    if (close) {\n      this._destination = null;\n      if (this._destInput) this._destInput.value = '';\n    }\n    this._goBtn.disabled = !this._destination;\n    this._cancelBtn.hidden = true;\n    if (close) this.close({ removeBody: true });\n  }\n\n  // ── RouteStore reactions ───────────────────────────────────────────────\n\n  _onRouteSet(route) {\n    if (!this._summaryEl) return;\n    this._summaryEl.hidden = false;\n    this._etaEl.textContent = `ETA ${formatDuration(route?.duration)}`;\n    const delayStr = route?.trafficDelay > 30\n      ? ` • traffic +${formatDuration(route.trafficDelay)}`\n      : '';\n    this._distEl.textContent = `${formatDistance(route?.distance)} • ${route?.provider || ''}${delayStr}`;\n    this._renderSteps(route?.steps || []);\n    this._cancelBtn.hidden = false;\n    this._goBtn.disabled = true;\n  }\n\n  _onRouteCleared() {\n    this._stepsView?.dispose(); this._stepsView = null;\n    if (!this._summaryEl) return;\n    this._summaryEl.hidden = true;\n    this._etaEl.textContent = '';\n    this._distEl.textContent = '';\n    this._stepsEl.hidden = true;\n    this._stepsEl.innerHTML = '';\n    this._cancelBtn.hidden = true;\n    this._goBtn.disabled = !this._destination;\n    this._status('', '');\n  }\n\n  _onRouteProgress(snapshot) {\n    if (!snapshot || !this._stepsEl) return;\n    const activeIdx = snapshot.currentStepIndex ?? snapshot.nextStepIndex ?? 0;\n    this._stepsView?.setActive(activeIdx);\n    if (Number.isFinite(snapshot.durationRemaining) && this._etaEl) {\n      this._etaEl.textContent = `ETA ${formatDuration(snapshot.durationRemaining)}`;\n    }\n    if (Number.isFinite(snapshot.distanceRemaining) && this._distEl) {\n      const prev = this._distEl.textContent;\n      const prefix = prev.split('•')[1]?.trim() || '';\n      this._distEl.textContent = `${formatDistance(snapshot.distanceRemaining)}${prefix ? ' • ' + prefix : ''}`;\n    }\n    if (snapshot.offRoute) {\n      this._status('Off route. Retry to calculate from your current location.', 'warn', true);\n    }\n  }\n\n  _renderSteps(steps) {\n    this._stepsView?.dispose(); this._stepsView = null;\n    if (!steps?.length || !this._visible) {\n      this._stepsEl.hidden = true;\n      return;\n    }\n    this._stepsEl.hidden = false;\n    this._stepsView = new RouteStepsWindow(this._stepsEl, (step, i) => {\n      const glyphToken = step.glyph || 'up';\n      const arrow = arrowFor(glyphToken);\n      const row = document.createElement('li'); row.className = 'nc-directions-step';\n      row.dataset.index = String(i); row.dataset.glyph = glyphToken;\n      row.innerHTML = `\n          <span class=\"nc-directions-step-glyph\" aria-hidden=\"true\">${arrow}</span>\n          <span class=\"nc-directions-step-body\">\n            <span class=\"nc-directions-step-instruction\">${escapeHtml(step.instruction || 'Continue')}</span>\n            ${step.distance > 0 ? `<span class=\"nc-directions-step-distance\">${escapeHtml(formatDistance(step.distance))}</span>` : ''}\n          </span>\n      `;\n      return row;\n    });\n    this._stepsView.setSteps(steps);\n    const progress = this._routeStore.getProgress();\n    if (progress) this._stepsView.setActive(progress.currentStepIndex ?? progress.nextStepIndex ?? 0);\n  }\n\n  _status(text, tone = 'info', retry = false) {\n    if (this._retryBtn) this._retryBtn.hidden = !retry;\n    if (!this._statusEl) return;\n    this._statusEl.textContent = text || '';\n    this._statusEl.dataset.tone = tone;\n    this._statusEl.hidden = !text;\n  }\n\n  _publishTransitStops(originStops, destStops) {\n    try {\n      if (typeof document === 'undefined' || typeof CustomEvent === 'undefined') return;\n      document.dispatchEvent(new CustomEvent('noclip:transit-stops', {\n        detail: { origin: originStops || [], destination: destStops || [] },\n      }));\n    } catch {}\n  }\n}\n\nlet _instance = null;\nexport function getDirectionsPanel(options = {}) {\n  if (!_instance || _instance._disposed) _instance = new DirectionsPanel(options);\n  return _instance;\n}\n\nexport default DirectionsPanel;\n","/**\n * SpeechBubble — billboard text bubble that follows a 3D anchor.\n *\n * Renders text into a canvas, mounts the canvas as a Sprite material\n * positioned above an anchor object. Re-renders on every show() with\n * fresh text. Word-wraps long messages, sizes the canvas to fit, and\n * fades in/out so cut-off feels intentional.\n *\n * The sprite is added directly to the scene root (not parented to the\n * anchor) so it always faces the camera regardless of the anchor's\n * orientation. We track the anchor's world position each frame.\n */\n\nimport * as THREE from 'three';\n\nconst PADDING_PX = 24;\nconst FONT_SIZE_PX = 36;\nconst FONT_FAMILY = '\"Chakra Petch\", \"Helvetica Neue\", system-ui, sans-serif';\nconst LINE_HEIGHT_PX = 44;\nconst MAX_WIDTH_PX = 720;\nconst BG_FILL = 'rgba(8, 8, 10, 0.92)';\nconst BG_BORDER = 'rgba(255, 255, 255, 0.42)';\nconst TEXT_FILL = 'rgba(245, 241, 233, 1.0)';\nconst ANCHOR_OFFSET_M = 2.4;          // metres above the anchor's foot\nconst SPRITE_WORLD_HEIGHT_M = 1.1;    // world-space height for the bubble\nconst FADE_IN_MS = 200;\nconst FADE_OUT_MS = 350;\n\nexport class SpeechBubble {\n    constructor({ scene, anchor }) {\n        this.scene = scene || null;\n        this.anchor = anchor || null;\n        this._canvas = document.createElement('canvas');\n        this._ctx = this._canvas.getContext('2d');\n        this._texture = new THREE.CanvasTexture(this._canvas);\n        this._texture.colorSpace = THREE.SRGBColorSpace;\n        this._material = new THREE.SpriteMaterial({\n            map: this._texture,\n            transparent: true,\n            depthTest: false,    // always-on-top\n            depthWrite: false,\n            opacity: 0,\n        });\n        this._sprite = new THREE.Sprite(this._material);\n        this._sprite.renderOrder = 9999;\n        this._sprite.visible = false;\n        this._sprite.userData.kind = 'daemon-speech-bubble';\n        if (this.scene) this.scene.add(this._sprite);\n        // Reusable temp vector — avoid GC pressure during follow.\n        this._tmpAnchorPos = new THREE.Vector3();\n        // Schedule state\n        this._showTimer = null;\n        this._hideTimer = null;\n        this._fadeRaf = 0;\n        this._fadeStart = 0;\n        this._fadeFromOpacity = 0;\n        this._fadeToOpacity = 0;\n        this._fadeDuration = 0;\n    }\n\n    /**\n     * Show `text` for `durationMs` (default scaled by length, min 3s).\n     * Replaces any in-flight bubble immediately.\n     */\n    show(text, durationMs = null) {\n        if (typeof text !== 'string' || !text.trim()) return;\n        const t = text.trim();\n        const ms = Number.isFinite(durationMs) && durationMs > 0\n            ? durationMs\n            : Math.max(3000, Math.min(12000, t.length * 60));\n        this._renderText(t);\n        this._sprite.visible = true;\n        // Headless Chromium throttles requestAnimationFrame heavily —\n        // the fade animation may not advance in time for tests. Set\n        // opacity to the target immediately, then run the fade for\n        // visible smoothness in real browsers. The end state is the\n        // same; tests that read computed opacity see the final value\n        // without depending on rAF cadence.\n        this._material.opacity = 1;\n        this._fadeTo(1, FADE_IN_MS);\n        if (this._hideTimer) clearTimeout(this._hideTimer);\n        this._hideTimer = setTimeout(() => this.hide(), ms);\n        // Diagnostic — preserved as userData so tests can inspect\n        // without reading internal state.\n        this._sprite.userData.lastShownText = t;\n        this._sprite.userData.lastShownAt = performance.now();\n    }\n\n    /** Fade out and stop following. */\n    hide() {\n        if (this._hideTimer) {\n            clearTimeout(this._hideTimer);\n            this._hideTimer = null;\n        }\n        this._fadeTo(0, FADE_OUT_MS, () => {\n            this._sprite.visible = false;\n        });\n    }\n\n    /** Per-frame: track the anchor's world position. */\n    update() {\n        if (!this._sprite.visible || !this.anchor) return;\n        this.anchor.getWorldPosition(this._tmpAnchorPos);\n        this._sprite.position.copy(this._tmpAnchorPos);\n        this._sprite.position.y += ANCHOR_OFFSET_M;\n    }\n\n    setAnchor(anchor) { this.anchor = anchor || null; }\n\n    dispose() {\n        if (this._sprite.parent) this._sprite.parent.remove(this._sprite);\n        if (this._hideTimer) { clearTimeout(this._hideTimer); this._hideTimer = null; }\n        if (this._showTimer) { clearTimeout(this._showTimer); this._showTimer = null; }\n        if (this._fadeRaf) { cancelAnimationFrame(this._fadeRaf); this._fadeRaf = 0; }\n        this._material.dispose();\n        this._texture.dispose();\n    }\n\n    // ── internals ──\n\n    _renderText(text) {\n        const ctx = this._ctx;\n        const lines = this._wrap(text);\n        const lineCount = lines.length;\n        const blockWidth = lines.reduce((max, line) => {\n            ctx.font = `500 ${FONT_SIZE_PX}px ${FONT_FAMILY}`;\n            return Math.max(max, ctx.measureText(line).width);\n        }, 0);\n        const w = Math.min(MAX_WIDTH_PX, Math.ceil(blockWidth)) + PADDING_PX * 2;\n        const h = lineCount * LINE_HEIGHT_PX + PADDING_PX * 2;\n        this._canvas.width = w;\n        this._canvas.height = h;\n        ctx.clearRect(0, 0, w, h);\n        // Background — rounded rect with thin accent border.\n        const r = 14;\n        ctx.beginPath();\n        ctx.moveTo(r, 0);\n        ctx.lineTo(w - r, 0);\n        ctx.quadraticCurveTo(w, 0, w, r);\n        ctx.lineTo(w, h - r);\n        ctx.quadraticCurveTo(w, h, w - r, h);\n        ctx.lineTo(r, h);\n        ctx.quadraticCurveTo(0, h, 0, h - r);\n        ctx.lineTo(0, r);\n        ctx.quadraticCurveTo(0, 0, r, 0);\n        ctx.closePath();\n        ctx.fillStyle = BG_FILL;\n        ctx.fill();\n        ctx.lineWidth = 2;\n        ctx.strokeStyle = BG_BORDER;\n        ctx.stroke();\n        // Text\n        ctx.fillStyle = TEXT_FILL;\n        ctx.font = `500 ${FONT_SIZE_PX}px ${FONT_FAMILY}`;\n        ctx.textAlign = 'left';\n        ctx.textBaseline = 'top';\n        for (let i = 0; i < lines.length; i++) {\n            ctx.fillText(lines[i], PADDING_PX, PADDING_PX + i * LINE_HEIGHT_PX);\n        }\n        this._texture.needsUpdate = true;\n        // Scale the sprite so the bubble's world height stays constant\n        // even as canvas resolution changes between calls.\n        const aspect = w / h;\n        this._sprite.scale.set(SPRITE_WORLD_HEIGHT_M * aspect, SPRITE_WORLD_HEIGHT_M, 1);\n    }\n\n    _wrap(text) {\n        // Word wrap to keep canvas under MAX_WIDTH_PX.\n        const ctx = this._ctx;\n        ctx.font = `500 ${FONT_SIZE_PX}px ${FONT_FAMILY}`;\n        const words = text.split(/\\s+/);\n        const lines = [];\n        let line = '';\n        for (const w of words) {\n            const probe = line ? `${line} ${w}` : w;\n            if (ctx.measureText(probe).width <= MAX_WIDTH_PX - PADDING_PX * 2) {\n                line = probe;\n            } else {\n                if (line) lines.push(line);\n                line = w;\n            }\n        }\n        if (line) lines.push(line);\n        return lines;\n    }\n\n    _fadeTo(target, duration, onComplete) {\n        if (this._fadeRaf) cancelAnimationFrame(this._fadeRaf);\n        this._fadeStart = performance.now();\n        this._fadeFromOpacity = this._material.opacity;\n        this._fadeToOpacity = target;\n        this._fadeDuration = duration;\n        const tick = () => {\n            const t = Math.min(1, (performance.now() - this._fadeStart) / this._fadeDuration);\n            this._material.opacity = this._fadeFromOpacity + (this._fadeToOpacity - this._fadeFromOpacity) * t;\n            if (t < 1) {\n                this._fadeRaf = requestAnimationFrame(tick);\n            } else {\n                this._fadeRaf = 0;\n                if (typeof onComplete === 'function') onComplete();\n            }\n        };\n        this._fadeRaf = requestAnimationFrame(tick);\n    }\n}\n","/**\n * EarthDaemon — autonomous companion that teleports to the user, follows\n * them across the photoreal globe, and briefs them on local events.\n *\n * Reuses the same character model + animation rig the player avatar\n * loads (AvatarFactory). The visual identity is enforced by overriding\n * every cloned mesh's material with a black-satin MeshStandardMaterial\n * — same character silhouette, but inky monolithic finish so it reads\n * as a daemon (per Snow Crash usage of the term: a low-level autonomous\n * service that takes a humanoid form when interacting with users).\n *\n * Lifecycle:\n *   manifest({lat, lon}) → place daemon at lat/lon, fade in\n *   follow(getter)        → per-frame, walk toward the user's position\n *   speak(text)           → server-side TTS + speech bubble + Idle anim\n *   dismiss()             → fade out + dispose\n *\n * The daemon is always rendered above the photoreal terrain via the\n * same surface-radius sampler the BuildingOverlay / IncidentOverlay\n * use, so it stands cleanly on the surface regardless of LOD.\n */\n\nimport * as THREE from 'three';\nimport { AvatarFactory } from '../avatar/AvatarFactory.js';\nimport { Avatar } from '../avatar/Avatar.js';\nimport { SpeechBubble } from './SpeechBubble.js';\nimport { latLonToLocalDir, dirToLatLonLocal, ellipsoidRadiusForLocalDir } from '../../modules/geometry-utils.js';\nimport { getBackendApiBase } from '../shared/backend.js';\nimport { getAuthService } from '../auth/AuthService.js';\n\n// Black-satin material params (read like polished obsidian under any light).\nconst SATIN_BLACK_PARAMS = Object.freeze({\n    color: 0x070707,\n    metalness: 0.55,\n    roughness: 0.28,\n    envMapIntensity: 0.6,\n});\n\n// How far ahead of the user the daemon stands when manifesting.\nconst MANIFEST_FORWARD_OFFSET_M = 3.0;\n// Daemon walks toward the user when farther than this.\nconst FOLLOW_TRIGGER_DIST_M = 6.0;\n// Max horizontal speed while following (m/s — easy walking pace).\nconst FOLLOW_SPEED_MPS = 2.5;\n// When closer than this, daemon stops walking and idles.\nconst FOLLOW_STOP_DIST_M = 3.0;\n// Explicit daemon navigation stops tighter than follow mode.\nconst NAV_STOP_DIST_M = 1.25;\n\nconst DEG2RAD = Math.PI / 180;\nconst RAD2DEG = 180 / Math.PI;\n\nfunction normalizeLon(lon) {\n    let next = ((lon + 180) % 360 + 360) % 360 - 180;\n    if (next === -180) next = 180;\n    return next;\n}\n\nfunction offsetLatLonMeters(lat, lon, headingDeg, distanceM, radiusM = 6378137) {\n    if (!Number.isFinite(lat) || !Number.isFinite(lon)) return null;\n    const distance = Number.isFinite(distanceM) ? distanceM : 0;\n    if (Math.abs(distance) < 1e-6) return { lat, lon };\n    const heading = Number.isFinite(headingDeg) ? headingDeg : 90;\n    const phi1 = lat * DEG2RAD;\n    const lambda1 = lon * DEG2RAD;\n    const theta = heading * DEG2RAD;\n    const delta = distance / Math.max(1, radiusM);\n    const sinPhi1 = Math.sin(phi1);\n    const cosPhi1 = Math.cos(phi1);\n    const sinDelta = Math.sin(delta);\n    const cosDelta = Math.cos(delta);\n    const phi2 = Math.asin(\n        sinPhi1 * cosDelta + cosPhi1 * sinDelta * Math.cos(theta)\n    );\n    const lambda2 = lambda1 + Math.atan2(\n        Math.sin(theta) * sinDelta * cosPhi1,\n        cosDelta - sinPhi1 * Math.sin(phi2)\n    );\n    return {\n        lat: THREE.MathUtils.clamp(phi2 * RAD2DEG, -89.999999, 89.999999),\n        lon: normalizeLon(lambda2 * RAD2DEG),\n    };\n}\n\nfunction bearingDeg(from, to) {\n    if (!from || !to) return null;\n    const lat1 = Number(from.lat) * DEG2RAD;\n    const lat2 = Number(to.lat) * DEG2RAD;\n    const dLon = (Number(to.lon) - Number(from.lon)) * DEG2RAD;\n    if (!Number.isFinite(lat1) || !Number.isFinite(lat2) || !Number.isFinite(dLon)) return null;\n    const y = Math.sin(dLon) * Math.cos(lat2);\n    const x = Math.cos(lat1) * Math.sin(lat2) -\n        Math.sin(lat1) * Math.cos(lat2) * Math.cos(dLon);\n    return (Math.atan2(y, x) * RAD2DEG + 360) % 360;\n}\n\nexport class EarthDaemon {\n    constructor({ scene, parentGroup, planetRadius, surfaceController, renderer = null, name = 'Daemon' }) {\n        this.scene = scene || null;\n        this.parentGroup = parentGroup || scene || null;\n        this.planetRadius = planetRadius || 6378137;\n        this.surfaceController = surfaceController || null;\n        this.renderer = renderer || null;\n        this.name = name;\n\n        this.group = new THREE.Group();\n        this.group.name = 'EarthDaemon';\n        this.group.userData.kind = 'earth-daemon';\n        this.group.userData.agentic = true;\n        this.group.visible = false;\n\n        this.avatar = null;\n        this.bubble = null;\n        this.povCamera = new THREE.PerspectiveCamera(65, 16 / 9, 0.05, 250000);\n        this.povCamera.name = 'EarthDaemonPOVCamera';\n        this.povCamera.userData.kind = 'earth-daemon-pov-camera';\n        this.group.add(this.povCamera);\n        this._loaded = false;\n        this._followTargetGetter = null;\n        this._navTarget = null;\n        this._motionMode = 'idle';\n        this._currentLatLon = null;\n        this._headingDeg = 0;\n        this._tmpVec = new THREE.Vector3();\n        this._tmpDir = new THREE.Vector3();\n        this._tmpUp = new THREE.Vector3();\n        this._tmpEast = new THREE.Vector3();\n        this._tmpNorth = new THREE.Vector3();\n        this._tmpForward = new THREE.Vector3();\n        this._tmpRight = new THREE.Vector3();\n        this._tmpMatrix = new THREE.Matrix4();\n        this._tmpQuat = new THREE.Quaternion();\n        this._lastPos = new THREE.Vector3();\n        this._fadeRaf = 0;\n        this._currentAudio = null;\n        this._opacity = 0;\n\n        if (this.parentGroup) this.parentGroup.add(this.group);\n    }\n\n    /**\n     * Async setup: clone an avatar from the factory, override every\n     * material with black satin, attach to the daemon group.\n     */\n    async load() {\n        if (this._loaded) return;\n        const factory = await AvatarFactory.load();\n        const components = factory.create();\n        this.avatar = new Avatar(\n            components.root,\n            components.clips,\n            components.footYOffset,\n            components.height,\n            components.groundContact,\n        );\n        this._applySatinBlack(components.root);\n        this.group.add(this.avatar.group);\n        this._loaded = true;\n        this._syncPovCamera();\n        if (this.scene) {\n            this.bubble = new SpeechBubble({\n                scene: this.scene,\n                anchor: this.avatar.group,\n            });\n        }\n    }\n\n    /**\n     * Manifest the daemon at the given lat/lon (or just in front of\n     * the user if not specified). Fades in over ~400 ms. Plays Idle.\n     */\n    async manifest({ lat, lon, headingDeg = null } = {}) {\n        if (!this._loaded) await this.load();\n        if (!Number.isFinite(lat) || !Number.isFinite(lon)) {\n            // Caller should have passed user coords; bail silently.\n            return false;\n        }\n        this._currentLatLon = { lat, lon };\n        this._placeAtLatLon(lat, lon, headingDeg);\n        this.group.visible = true;\n        this._fadeOpacity(0, 1, 400);\n        this.avatar?.setManualState?.('Idle');\n        return true;\n    }\n\n    /**\n     * Begin following — every frame, the daemon walks toward whatever\n     * `latLonGetter()` returns. Pass null to stop following.\n     */\n    follow(latLonGetter) {\n        this._followTargetGetter = (typeof latLonGetter === 'function')\n            ? latLonGetter\n            : null;\n        if (this._followTargetGetter) {\n            this._navTarget = null;\n            this._motionMode = 'follow';\n        } else if (!this._navTarget) {\n            this._motionMode = 'idle';\n        }\n    }\n\n    /**\n     * Navigate the daemon itself to a waypoint. This is intentionally\n     * separate from moving the user camera: the daemon is an embodied\n     * participant with its own pose and movement state.\n     */\n    navigateTo({ lat, lon } = {}) {\n        if (!Number.isFinite(lat) || !Number.isFinite(lon)) return false;\n        this._followTargetGetter = null;\n        this._navTarget = { lat, lon };\n        this._motionMode = 'navigate';\n        return true;\n    }\n\n    getPovSnapshot({ includeImage = false, width = 320, height = 180 } = {}) {\n        this._syncPovCamera();\n        const camera = this.povCamera;\n        camera.updateMatrixWorld(true);\n        const worldPos = new THREE.Vector3();\n        const worldQuat = new THREE.Quaternion();\n        const viewDir = new THREE.Vector3();\n        camera.getWorldPosition(worldPos);\n        camera.getWorldQuaternion(worldQuat);\n        camera.getWorldDirection(viewDir);\n        const snapshot = {\n            ok: true,\n            daemonId: this.group.uuid,\n            mode: this._motionMode,\n            lat: this._currentLatLon?.lat ?? null,\n            lon: this._currentLatLon?.lon ?? null,\n            headingDeg: this._headingDeg,\n            camera: {\n                fov: camera.fov,\n                aspect: camera.aspect,\n                near: camera.near,\n                far: camera.far,\n                position: worldPos.toArray(),\n                quaternion: [worldQuat.x, worldQuat.y, worldQuat.z, worldQuat.w],\n                direction: viewDir.toArray(),\n            },\n            navigation: this._navTarget ? { ...this._navTarget } : null,\n        };\n        if (includeImage) {\n            snapshot.image = this._capturePovImage({ width, height });\n        }\n        return snapshot;\n    }\n\n    /**\n     * Speak `text` via server TTS and show a speech bubble. If the\n     * TTS endpoint isn't reachable, the bubble still shows; audio is\n     * silently skipped. Returns once playback ends (or text duration\n     * elapses if no audio).\n     */\n    async speak(text) {\n        if (typeof text !== 'string' || !text.trim()) return;\n        const trimmed = text.trim();\n        // Show the bubble immediately — audio is best-effort.\n        this.bubble?.show(trimmed);\n        // Stop any prior audio.\n        try {\n            if (this._currentAudio) {\n                this._currentAudio.pause();\n                URL.revokeObjectURL(this._currentAudio.src);\n                this._currentAudio = null;\n            }\n        } catch { /* ignore */ }\n        const base = getBackendApiBase() || '';\n        try {\n            const rsp = await getAuthService().authenticatedFetch(`${base}/agent/tts`, {\n                method: 'POST',\n                headers: { 'content-type': 'application/json' },\n                body: JSON.stringify({ text: trimmed, format: 'wav' }),\n            });\n            if (!rsp.ok) {\n                // TTS unavailable — bubble alone carries the message.\n                return;\n            }\n            const blob = await rsp.blob();\n            const url = URL.createObjectURL(blob);\n            const audio = new Audio(url);\n            audio.crossOrigin = 'anonymous';\n            this._currentAudio = audio;\n            // Try to autoplay. Some browsers block until a user\n            // gesture — bubble still works.\n            try { await audio.play(); } catch { /* policy block — silent */ }\n            await new Promise((res) => {\n                audio.addEventListener('ended', res, { once: true });\n                audio.addEventListener('error', res, { once: true });\n            });\n        } catch {\n            /* TTS unreachable — bubble already showed */\n        }\n    }\n\n    /** Fade out + remove from scene. */\n    async dismiss() {\n        try {\n            if (this._currentAudio) {\n                this._currentAudio.pause();\n                this._currentAudio = null;\n            }\n        } catch { /* ignore */ }\n        this.bubble?.hide();\n        this._followTargetGetter = null;\n        await new Promise((resolve) => {\n            this._fadeOpacity(this._opacity, 0, 350, () => {\n                this.group.visible = false;\n                resolve();\n            });\n        });\n    }\n\n    /** Per-frame update — driven by PlanetScene.update(dt). */\n    update(dt) {\n        if (!this._loaded) return;\n        // Animation mixer.\n        this.avatar?.update?.(dt);\n        // Bubble follow.\n        this.bubble?.update?.();\n        // Track user.\n        if (this._followTargetGetter) {\n            const target = this._followTargetGetter();\n            if (target && Number.isFinite(target.lat) && Number.isFinite(target.lon)) {\n                this._stepToward(target, dt);\n            }\n        } else if (this._navTarget) {\n            this._stepToward(this._navTarget, dt, {\n                stopDistanceM: NAV_STOP_DIST_M,\n                clearOnArrive: true,\n            });\n        } else if (this._currentLatLon) {\n            // Re-snap to surface as terrain LODs in.\n            this._snapToSurface(this._currentLatLon.lat, this._currentLatLon.lon);\n        }\n        this._syncPovCamera();\n    }\n\n    /** Used by tests — returns world-space bounding-box height + visibility. */\n    getDiagnostic() {\n        const bbox = new THREE.Box3().setFromObject(this.group);\n        const size = new THREE.Vector3();\n        bbox.getSize(size);\n        return {\n            visible: this.group.visible,\n            opacity: this._opacity,\n            position: this.group.position.toArray(),\n            heightM: size.y,\n            isLoaded: this._loaded,\n            bubbleVisible: !!this.bubble?._sprite?.visible,\n            agentic: true,\n            mode: this._motionMode,\n            lat: this._currentLatLon?.lat ?? null,\n            lon: this._currentLatLon?.lon ?? null,\n            headingDeg: this._headingDeg,\n            hasPovCamera: !!this.povCamera,\n            navigation: this._navTarget ? { ...this._navTarget } : null,\n        };\n    }\n\n    dispose() {\n        if (this._fadeRaf) cancelAnimationFrame(this._fadeRaf);\n        if (this._currentAudio) {\n            try { this._currentAudio.pause(); } catch { /* ignore */ }\n            this._currentAudio = null;\n        }\n        this.bubble?.dispose?.();\n        if (this.group.parent) this.group.parent.remove(this.group);\n        this._loaded = false;\n    }\n\n    // ── internals ──────────────────────────────────────────────────\n\n    _applySatinBlack(root) {\n        root.traverse((obj) => {\n            if (!obj.isMesh && !obj.isSkinnedMesh) return;\n            const old = obj.material;\n            const next = new THREE.MeshStandardMaterial({\n                ...SATIN_BLACK_PARAMS,\n                skinning: !!obj.isSkinnedMesh,\n                transparent: true,   // for fade-in\n                opacity: 1,\n            });\n            // Preserve any texture that defines the silhouette so the\n            // mesh still reads as humanoid (the underlying body texture\n            // shape — e.g. the model's UVs — drives proper lighting).\n            // We DON'T copy the diffuse map, so the colour reads as\n            // pure black, but normal maps if present go through.\n            if (old?.normalMap) next.normalMap = old.normalMap;\n            obj.material = next;\n        });\n    }\n\n    /** Place the daemon's group at the given lat/lon on the surface. */\n    _placeAtLatLon(lat, lon, headingDeg = null) {\n        const dir = latLonToLocalDir(lat, lon).normalize();\n        const r = this._sampleSurfaceRadius(dir);\n        this.group.position.copy(dir.multiplyScalar(r));\n        const heading = Number.isFinite(headingDeg) ? headingDeg : this._headingDeg;\n        this._headingDeg = Number.isFinite(heading) ? ((heading % 360) + 360) % 360 : 0;\n        this._buildSurfaceQuaternion(lat, lon, this._headingDeg, this.group.quaternion);\n        this.group.updateMatrixWorld(true);\n        this._syncPovCamera();\n    }\n\n    _buildSurfaceQuaternion(lat, lon, headingDeg, target) {\n        const up = this._tmpUp.copy(latLonToLocalDir(lat, lon)).normalize();\n        const refUp = this._tmpVec.set(0, 1, 0);\n        const east = this._tmpEast.crossVectors(refUp, up);\n        if (east.lengthSq() < 1e-8) east.set(1, 0, 0);\n        east.normalize();\n        const north = this._tmpNorth.crossVectors(up, east).normalize();\n        const headingRad = (Number.isFinite(headingDeg) ? headingDeg : 0) * DEG2RAD;\n        const forward = this._tmpForward.set(0, 0, 0)\n            .addScaledVector(north, Math.cos(headingRad))\n            .addScaledVector(east, Math.sin(headingRad))\n            .normalize();\n        const right = this._tmpRight.crossVectors(forward, up).normalize();\n        this._tmpMatrix.makeBasis(right, up, forward.multiplyScalar(-1));\n        target.setFromRotationMatrix(this._tmpMatrix);\n    }\n\n    _sampleSurfaceRadius(dir) {\n        if (this.surfaceController?.sampleTerrainRadiusForDir) {\n            const r = this.surfaceController.sampleTerrainRadiusForDir(dir, { mutateCache: false });\n            if (Number.isFinite(r) && r > 0) return r;\n        }\n        return ellipsoidRadiusForLocalDir(dir);\n    }\n\n    _snapToSurface(lat, lon) {\n        const dir = latLonToLocalDir(lat, lon).normalize();\n        const r = this._sampleSurfaceRadius(dir);\n        this.group.position.copy(dir.multiplyScalar(r));\n        this._syncPovCamera();\n    }\n\n    /** Walk toward target lat/lon at FOLLOW_SPEED_MPS. */\n    _stepToward(target, dt, { stopDistanceM = FOLLOW_STOP_DIST_M, clearOnArrive = false } = {}) {\n        const here = this._currentLatLon;\n        if (!here) return;\n        // Convert both to local 3D, step in world space, then re-derive\n        // lat/lon. Good enough for short distances.\n        const fromDir = latLonToLocalDir(here.lat, here.lon).normalize();\n        const toDir = latLonToLocalDir(target.lat, target.lon).normalize();\n        const angle = fromDir.angleTo(toDir); // radians along the great circle\n        const arcM = angle * this.planetRadius;\n        if (!Number.isFinite(arcM)) return;\n        if (arcM <= stopDistanceM) {\n            this._currentLatLon = { lat: target.lat, lon: target.lon };\n            this._snapToSurface(target.lat, target.lon);\n            this.avatar?.setManualState?.('Idle');\n            if (clearOnArrive) {\n                this._navTarget = null;\n                this._motionMode = 'idle';\n            }\n            return;\n        }\n        // Fraction of the great-circle arc we cover this frame.\n        const stepM = Math.min(arcM, FOLLOW_SPEED_MPS * Math.max(0.001, dt));\n        const t = arcM > 0 ? stepM / arcM : 0;\n        // Slerp the unit direction.\n        const newDir = fromDir.clone().lerp(toDir, t).normalize();\n        const nextLatLon = dirToLatLonLocal(newDir);\n        const newLat = nextLatLon.latDeg;\n        const newLon = nextLatLon.lonDeg;\n        this._currentLatLon = { lat: newLat, lon: newLon };\n        // Face the target.\n        const heading = bearingDeg(here, target);\n        this._placeAtLatLon(newLat, newLon, heading);\n        // Walking animation while we're on the move.\n        if (arcM > FOLLOW_TRIGGER_DIST_M) {\n            this.avatar?.setManualState?.('Sprint');\n        } else {\n            this.avatar?.setManualState?.('WalkForward');\n        }\n    }\n\n    _syncPovCamera() {\n        if (!this.povCamera) return;\n        const eyeHeight = Number.isFinite(this.avatar?.eyeHeight)\n            ? this.avatar.eyeHeight\n            : (Number.isFinite(this.avatar?.height) ? this.avatar.height * 0.9 : 1.55);\n        this.povCamera.position.set(0, Math.max(0.1, eyeHeight), -0.04);\n        this.povCamera.quaternion.identity();\n        this.povCamera.updateMatrixWorld(true);\n    }\n\n    _capturePovImage({ width = 320, height = 180 } = {}) {\n        if (!this.renderer || !this.scene || !this.povCamera) {\n            return { ok: false, error: 'renderer unavailable' };\n        }\n        const w = Math.max(64, Math.min(1024, Math.floor(width)));\n        const h = Math.max(64, Math.min(768, Math.floor(height)));\n        const target = new THREE.WebGLRenderTarget(w, h, {\n            format: THREE.RGBAFormat,\n            type: THREE.UnsignedByteType,\n            depthBuffer: true,\n            stencilBuffer: false,\n        });\n        const pixels = new Uint8Array(w * h * 4);\n        const prevTarget = this.renderer.getRenderTarget?.() || null;\n        const prevXr = this.renderer.xr ? this.renderer.xr.enabled : null;\n        const prevAutoClear = this.renderer.autoClear;\n        try {\n            if (this.renderer.xr) this.renderer.xr.enabled = false;\n            this.renderer.autoClear = true;\n            this.povCamera.aspect = w / h;\n            this.povCamera.updateProjectionMatrix();\n            this.renderer.setRenderTarget(target);\n            this.renderer.clear(true, true, true);\n            this.renderer.render(this.scene, this.povCamera);\n            this.renderer.readRenderTargetPixels(target, 0, 0, w, h, pixels);\n            const canvas = document.createElement('canvas');\n            canvas.width = w;\n            canvas.height = h;\n            const ctx = canvas.getContext('2d');\n            const imageData = ctx.createImageData(w, h);\n            const row = w * 4;\n            for (let y = 0; y < h; y += 1) {\n                const src = (h - 1 - y) * row;\n                const dst = y * row;\n                imageData.data.set(pixels.subarray(src, src + row), dst);\n            }\n            ctx.putImageData(imageData, 0, 0);\n            return {\n                ok: true,\n                width: w,\n                height: h,\n                mime: 'image/png',\n                dataUrl: canvas.toDataURL('image/png'),\n            };\n        } catch (error) {\n            return { ok: false, error: String(error?.message || error) };\n        } finally {\n            this.renderer.setRenderTarget(prevTarget);\n            if (this.renderer.xr && prevXr !== null) this.renderer.xr.enabled = prevXr;\n            this.renderer.autoClear = prevAutoClear;\n            target.dispose();\n        }\n    }\n\n    /**\n     * Cross-fade material opacity. We pulse all skinned-mesh materials\n     * together so the daemon dematerialises uniformly.\n     */\n    _fadeOpacity(from, to, durationMs, onComplete) {\n        if (this._fadeRaf) cancelAnimationFrame(this._fadeRaf);\n        const start = performance.now();\n        const tick = () => {\n            const t = Math.min(1, (performance.now() - start) / durationMs);\n            const v = from + (to - from) * t;\n            this._opacity = v;\n            this.group.traverse((obj) => {\n                if ((obj.isMesh || obj.isSkinnedMesh) && obj.material) {\n                    obj.material.opacity = v;\n                }\n            });\n            if (t < 1) {\n                this._fadeRaf = requestAnimationFrame(tick);\n            } else {\n                this._fadeRaf = 0;\n                if (typeof onComplete === 'function') onComplete();\n            }\n        };\n        this._fadeRaf = requestAnimationFrame(tick);\n    }\n}\n","/**\n * DaemonVisionActionDriver\n *\n * Low-rate observation/action bridge for external game agents. The browser owns\n * scene state, POV capture, validation, and actuation; Omnius, Dreamer, NitroGen,\n * STEVE-class, or custom policies run outside the render loop and return one\n * bounded daemon action per tick.\n */\n\nconst ACTION_SPACE = Object.freeze([\n    'idle',\n    'follow_user',\n    'navigate_to',\n    'navigate_offset',\n    'brief',\n    'dismiss',\n    // Read-only web tools. These do not move or mutate the scene — they\n    // fetch fresh information the policy can reason with. Results are\n    // stored in a small ring buffer and surfaced in the next\n    // observation (observation.tools.recentResults) so a stateless HTTP\n    // policy (Omnius, …) can search, observe, then act.\n    'web_search',\n    'web_fetch',\n]);\n\n// Read-only tool actions — exempt from the movement rate-limiter and the\n// dryRun gate (they never touch the scene), governed instead by their own\n// lighter cadence so the policy can gather information while dry-running.\nconst WEB_TOOL_ACTIONS = new Set(['web_search', 'web_fetch']);\n\nconst DEFAULT_MAX_TOOL_CALLS_PER_MINUTE = 12;\nconst DEFAULT_TOOL_RESULT_LIMIT = 4;\nconst DEFAULT_TOOL_TIMEOUT_MS = 8000;\n\nconst KNOWN_DRIVERS = new Set([\n    'omnius',\n    'dreamerv3',\n    'dreamer4',\n    'nitrogen',\n    'steve1',\n    'mrsteve',\n    'game_tars',\n    'custom',\n]);\n\nconst DEFAULT_TICK_MS = 500;\nconst DEFAULT_MAX_ACTIONS_PER_MINUTE = 30;\nconst DEFAULT_MAX_OFFSET_METERS = 25;\nconst DEFAULT_REQUEST_TIMEOUT_MS = 2500;\n\nfunction clampNumber(value, min, max, fallback) {\n    const n = Number(value);\n    if (!Number.isFinite(n)) return fallback;\n    return Math.max(min, Math.min(max, n));\n}\n\nfunction clampInt(value, min, max, fallback) {\n    return Math.floor(clampNumber(value, min, max, fallback));\n}\n\nfunction normalizeLon(lon) {\n    let next = ((lon + 180) % 360 + 360) % 360 - 180;\n    if (next === -180) next = 180;\n    return next;\n}\n\nfunction normalizeDriverName(driver) {\n    const raw = String(driver || 'custom').trim().toLowerCase().replace(/[\\s-]+/g, '_');\n    return KNOWN_DRIVERS.has(raw) ? raw : 'custom';\n}\n\nfunction normalizeAction(rawAction) {\n    const raw = rawAction?.action && typeof rawAction.action === 'object'\n        ? rawAction.action\n        : rawAction;\n    if (!raw) return { type: 'idle' };\n    if (typeof raw === 'string') return { type: raw.trim().toLowerCase().replace(/[\\s-]+/g, '_') || 'idle' };\n    if (typeof raw !== 'object') return { type: 'idle' };\n    const type = String(raw.type || raw.name || raw.action || 'idle')\n        .trim()\n        .toLowerCase()\n        .replace(/[\\s-]+/g, '_');\n    return { ...raw, type: type || 'idle' };\n}\n\nfunction compactError(error) {\n    return String(error?.message || error || 'unknown error').slice(0, 240);\n}\n\nexport function getDaemonVisionActionSpace() {\n    return [...ACTION_SPACE];\n}\n\nexport class DaemonVisionActionDriver {\n    constructor(manager, options = {}) {\n        this.manager = manager;\n        this.driver = normalizeDriverName(options.driver || options.provider);\n        this.agentId = String(options.agentId || 'omnius').trim().slice(0, 80) || 'omnius';\n        this.endpoint = typeof options.endpoint === 'string' ? options.endpoint.trim() : '';\n        this.autonomy = String(options.autonomy || 'daemon_only').trim().slice(0, 80) || 'daemon_only';\n        this.tickMs = clampInt(options.tickMs, 100, 10_000, DEFAULT_TICK_MS);\n        this.includeImage = options.includeImage === true;\n        this.imageWidth = clampInt(options.imageWidth ?? options.width, 64, 512, 224);\n        this.imageHeight = clampInt(options.imageHeight ?? options.height, 64, 512, 126);\n        this.maxActionsPerMinute = clampInt(\n            options.maxActionsPerMinute,\n            1,\n            120,\n            DEFAULT_MAX_ACTIONS_PER_MINUTE\n        );\n        this.maxOffsetMeters = clampNumber(\n            options.maxOffsetMeters,\n            0.25,\n            500,\n            DEFAULT_MAX_OFFSET_METERS\n        );\n        this.requestTimeoutMs = clampInt(\n            options.requestTimeoutMs,\n            250,\n            10_000,\n            DEFAULT_REQUEST_TIMEOUT_MS\n        );\n        this.dryRun = options.dryRun === true;\n        this.autoSummon = options.summon !== false && options.autoSummon !== false;\n        this.fetchImpl = options.fetchImpl || globalThis.fetch?.bind(globalThis) || null;\n\n        // Web-tool bridge. `executeTool(name, args) => result` runs a\n        // server-handled tool. A caller can inject one directly (tests),\n        // or supply `toolBaseUrl` (the backend `/agent/tools` prefix) and\n        // let the driver POST to `${toolBaseUrl}/${name}` itself.\n        this.toolBaseUrl = typeof options.toolBaseUrl === 'string'\n            ? options.toolBaseUrl.replace(/\\/+$/, '')\n            : '';\n        this.executeTool = typeof options.executeTool === 'function'\n            ? options.executeTool\n            : (this.toolBaseUrl ? this._defaultExecuteTool.bind(this) : null);\n        this.maxToolCallsPerMinute = clampInt(\n            options.maxToolCallsPerMinute,\n            1,\n            60,\n            DEFAULT_MAX_TOOL_CALLS_PER_MINUTE\n        );\n        this.toolTimeoutMs = clampInt(\n            options.toolTimeoutMs,\n            500,\n            30_000,\n            DEFAULT_TOOL_TIMEOUT_MS\n        );\n        this._toolResultLimit = clampInt(options.toolResultLimit, 1, 12, DEFAULT_TOOL_RESULT_LIMIT);\n        this._toolResults = [];\n        this._lastToolCallAt = 0;\n        this._lastToolResult = null;\n        this._toolCallsApplied = 0;\n\n        this.active = false;\n        this._elapsedMs = 0;\n        this._inFlight = false;\n        this._lastObservationAt = 0;\n        this._lastStepAt = 0;\n        this._lastActionAt = 0;\n        this._lastSpeechAt = 0;\n        this._lastAction = null;\n        this._lastResult = null;\n        this._lastError = null;\n        this._decisionCount = 0;\n        this._actionsApplied = 0;\n        this._actionsDropped = 0;\n        this._abortController = null;\n    }\n\n    start() {\n        this.active = true;\n        this._elapsedMs = this.tickMs;\n        this._lastError = null;\n        return this.getStatus();\n    }\n\n    stop(reason = 'stopped') {\n        this.active = false;\n        this._abortController?.abort?.();\n        this._abortController = null;\n        this._inFlight = false;\n        this._lastResult = { ok: true, stopped: true, reason };\n        return this.getStatus();\n    }\n\n    update(dt = 0) {\n        if (!this.active || this._inFlight) return;\n        this._elapsedMs += clampNumber(dt, 0, 1, 0) * 1000;\n        if (this._elapsedMs < this.tickMs) return;\n        this._elapsedMs = 0;\n        this.stepOnce().catch((error) => {\n            this._lastError = compactError(error);\n            this._lastResult = { ok: false, error: this._lastError };\n        });\n    }\n\n    async stepOnce() {\n        if (!this.active) return { ok: false, error: 'driver inactive' };\n        if (this._inFlight) return { ok: false, skipped: 'in_flight' };\n        this._inFlight = true;\n        this._lastStepAt = Date.now();\n        try {\n            if (this.autoSummon && !this.manager?.getStatus?.()?.active && this.manager?.summon) {\n                await this.manager.summon({ follow: false });\n            }\n            const observation = this.buildObservation();\n            const decision = await this.decide(observation);\n            this._decisionCount += 1;\n            const result = await this.applyAction(decision);\n            this._lastResult = { ok: true, observationAt: observation.timestamp, decision, result };\n            return this._lastResult;\n        } catch (error) {\n            this._lastError = compactError(error);\n            this._lastResult = { ok: false, error: this._lastError };\n            return this._lastResult;\n        } finally {\n            this._inFlight = false;\n        }\n    }\n\n    buildObservation() {\n        const timestamp = Date.now();\n        this._lastObservationAt = timestamp;\n        const daemon = this.manager?.getStatus?.() || { active: false };\n        const player = this.manager?._getPlayerPose?.() || this.manager?.getPlayerPose?.() || null;\n        let pov = null;\n        if (daemon.active && this.manager?.look) {\n            pov = this.manager.look({\n                includeImage: this.includeImage,\n                width: this.imageWidth,\n                height: this.imageHeight,\n            });\n        }\n        return {\n            version: 1,\n            kind: 'noclip.daemon.vision_action.observation',\n            timestamp,\n            agentId: this.agentId,\n            driver: this.driver,\n            autonomy: this.autonomy,\n            scene: {\n                planetRadius: this.manager?.planetRadius ?? null,\n                actionSpace: getDaemonVisionActionSpace(),\n                constraints: {\n                    daemonOnly: true,\n                    cameraControl: false,\n                    tickMs: this.tickMs,\n                    includeImage: this.includeImage,\n                    maxActionsPerMinute: this.maxActionsPerMinute,\n                    maxOffsetMeters: this.maxOffsetMeters,\n                    maxToolCallsPerMinute: this.maxToolCallsPerMinute,\n                },\n            },\n            player,\n            daemon,\n            pov,\n            // Web-tool surface + rolling memory of recent results so the\n            // policy can decide to search, then act on the returns it sees\n            // here on the following tick.\n            tools: {\n                available: this._webToolsAvailable(),\n                recentResults: this._toolResults.slice(-this._toolResultLimit),\n            },\n        };\n    }\n\n    async decide(observation) {\n        if (!this.endpoint) {\n            return { type: 'idle', reason: 'no_endpoint_configured' };\n        }\n        if (!this.fetchImpl) {\n            throw new Error('fetch unavailable for daemon driver endpoint');\n        }\n        const controller = typeof AbortController !== 'undefined' ? new AbortController() : null;\n        this._abortController = controller;\n        const timeout = controller\n            ? setTimeout(() => controller.abort(), this.requestTimeoutMs)\n            : null;\n        try {\n            const res = await this.fetchImpl(this.endpoint, {\n                method: 'POST',\n                headers: { 'content-type': 'application/json' },\n                body: JSON.stringify({\n                    version: 1,\n                    kind: 'noclip.daemon.vision_action.request',\n                    agentId: this.agentId,\n                    driver: this.driver,\n                    autonomy: this.autonomy,\n                    actionSpace: getDaemonVisionActionSpace(),\n                    observation,\n                }),\n                signal: controller?.signal,\n            });\n            if (!res?.ok) throw new Error(`driver endpoint returned ${res?.status || 'non-ok'}`);\n            const json = await res.json();\n            return normalizeAction(json?.action || json?.actions?.[0] || json);\n        } finally {\n            if (timeout) clearTimeout(timeout);\n            if (this._abortController === controller) this._abortController = null;\n        }\n    }\n\n    async applyAction(rawAction) {\n        const action = normalizeAction(rawAction);\n        this._lastAction = action;\n        if (action.type === 'noop') action.type = 'idle';\n        if (!ACTION_SPACE.includes(action.type)) {\n            this._actionsDropped += 1;\n            return { ok: false, applied: false, error: `unsupported action: ${action.type}`, action };\n        }\n        if (action.type === 'idle') {\n            return { ok: true, applied: false, action };\n        }\n        // Read-only web tools take their own path: no movement cooldown,\n        // no dryRun gate (they never mutate the scene), lighter cadence.\n        if (WEB_TOOL_ACTIONS.has(action.type)) {\n            return this._applyWebToolAction(action);\n        }\n        const now = Date.now();\n        const cooldownMs = 60_000 / Math.max(1, this.maxActionsPerMinute);\n        if (now - this._lastActionAt < cooldownMs) {\n            this._actionsDropped += 1;\n            return { ok: false, applied: false, skipped: 'action_cooldown', action };\n        }\n        if (this.dryRun) {\n            this._lastActionAt = now;\n            return { ok: true, applied: false, dryRun: true, action };\n        }\n\n        let result;\n        if (action.type === 'follow_user') {\n            const daemon = this.manager?.daemon;\n            if (!daemon?.follow || !this.manager?.getPlayerLatLon) {\n                return { ok: false, applied: false, error: 'follow unavailable', action };\n            }\n            daemon.follow(this.manager.getPlayerLatLon);\n            result = { mode: 'follow' };\n        } else if (action.type === 'navigate_to') {\n            const lat = clampNumber(action.lat, -89.999999, 89.999999, NaN);\n            const lon = normalizeLon(Number(action.lon));\n            if (!Number.isFinite(lat) || !Number.isFinite(lon)) {\n                return { ok: false, applied: false, error: 'navigate_to requires finite lat/lon', action };\n            }\n            const ok = this.manager?.navigateTo?.({ lat, lon });\n            result = { navigating: !!ok, lat, lon };\n        } else if (action.type === 'navigate_offset') {\n            const status = this.manager?.getStatus?.() || {};\n            const base = Number.isFinite(status.lat) && Number.isFinite(status.lon)\n                ? status\n                : this.manager?._getPlayerPose?.();\n            if (!base || !Number.isFinite(base.lat) || !Number.isFinite(base.lon)) {\n                return { ok: false, applied: false, error: 'navigate_offset requires daemon or player pose', action };\n            }\n            const headingDeg = Number.isFinite(Number(action.headingDeg))\n                ? Number(action.headingDeg)\n                : (Number.isFinite(base.headingDeg) ? base.headingDeg : 90);\n            const distanceM = clampNumber(action.distanceM, -this.maxOffsetMeters, this.maxOffsetMeters, 0);\n            const target = this.manager?._offsetLatLonMeters?.(base.lat, base.lon, headingDeg, distanceM);\n            if (!target) return { ok: false, applied: false, error: 'offset target unavailable', action };\n            const ok = this.manager?.navigateTo?.(target);\n            result = { navigating: !!ok, ...target, headingDeg, distanceM };\n        } else if (action.type === 'brief') {\n            const text = String(action.text || '').trim().slice(0, 320);\n            if (!text) return { ok: false, applied: false, error: 'brief requires text', action };\n            if (now - this._lastSpeechAt < 3000) {\n                this._actionsDropped += 1;\n                return { ok: false, applied: false, skipped: 'speech_cooldown', action };\n            }\n            const ok = await this.manager?.brief?.(text);\n            this._lastSpeechAt = now;\n            result = { spoken: !!ok, text };\n        } else if (action.type === 'dismiss') {\n            await this.manager?.dismiss?.();\n            this.stop('dismiss_action');\n            result = { dismissed: true };\n        }\n\n        this._lastActionAt = now;\n        this._actionsApplied += 1;\n        return { ok: true, applied: true, action, result };\n    }\n\n    _webToolsAvailable() {\n        return this.executeTool ? ['web_search', 'web_fetch'] : [];\n    }\n\n    /**\n     * Run a read-only web tool (web_search / web_fetch) on the policy's\n     * behalf. Executes via the injected/derived tool executor, caps the\n     * payload, and records it in the ring buffer surfaced by the next\n     * observation. Rate-limited independently of movement actions.\n     */\n    async _applyWebToolAction(action) {\n        if (!this.executeTool) {\n            this._actionsDropped += 1;\n            return { ok: false, applied: false, error: 'web tools not configured', action };\n        }\n        const args = this._toolArgsFor(action);\n        if (action.type === 'web_search' && !args.query) {\n            return { ok: false, applied: false, error: 'web_search requires a query', action };\n        }\n        if (action.type === 'web_fetch' && !args.url) {\n            return { ok: false, applied: false, error: 'web_fetch requires a url', action };\n        }\n        const now = Date.now();\n        const cooldownMs = 60_000 / Math.max(1, this.maxToolCallsPerMinute);\n        if (now - this._lastToolCallAt < cooldownMs) {\n            this._actionsDropped += 1;\n            return { ok: false, applied: false, skipped: 'tool_cooldown', action };\n        }\n        this._lastToolCallAt = now;\n        try {\n            const raw = await this.executeTool(action.type, args);\n            const compact = this._compactToolResult(action.type, raw);\n            this._recordToolResult({ tool: action.type, args, at: now, ok: true, result: compact });\n            this._toolCallsApplied += 1;\n            this._actionsApplied += 1;\n            return { ok: true, applied: true, action, result: compact };\n        } catch (error) {\n            const message = compactError(error);\n            this._recordToolResult({ tool: action.type, args, at: now, ok: false, error: message });\n            this._lastError = message;\n            return { ok: false, applied: false, error: message, action };\n        }\n    }\n\n    _toolArgsFor(action) {\n        if (action.type === 'web_search') {\n            const query = String(action.query ?? action.q ?? action.text ?? '').trim().slice(0, 240);\n            const args = { query };\n            const n = Number(action.num_results ?? action.numResults ?? action.limit);\n            if (Number.isFinite(n)) args.num_results = clampInt(n, 1, 10, 5);\n            return args;\n        }\n        if (action.type === 'web_fetch') {\n            return { url: String(action.url ?? action.href ?? action.link ?? '').trim() };\n        }\n        return {};\n    }\n\n    _compactToolResult(type, result) {\n        if (result == null) return null;\n        if (type === 'web_search') {\n            const list = Array.isArray(result?.results)\n                ? result.results\n                : (Array.isArray(result) ? result : []);\n            const results = list.slice(0, 6).map((r) => ({\n                title: String(r?.title ?? '').slice(0, 180),\n                url: String(r?.url ?? r?.href ?? '').slice(0, 400),\n                snippet: String(r?.snippet ?? r?.description ?? '').slice(0, 280),\n            })).filter((r) => r.url || r.title);\n            return { query: result?.query ?? undefined, results };\n        }\n        if (type === 'web_fetch') {\n            const text = typeof result === 'string'\n                ? result\n                : String(result?.text ?? result?.bodyText ?? result?.content ?? '');\n            return {\n                url: result?.url ?? undefined,\n                title: result?.title ? String(result.title).slice(0, 180) : undefined,\n                text: text.slice(0, 2000),\n            };\n        }\n        return result;\n    }\n\n    _recordToolResult(entry) {\n        this._toolResults.push(entry);\n        if (this._toolResults.length > this._toolResultLimit) {\n            this._toolResults.splice(0, this._toolResults.length - this._toolResultLimit);\n        }\n        this._lastToolResult = entry;\n    }\n\n    async _defaultExecuteTool(name, args) {\n        if (!this.fetchImpl) throw new Error('fetch unavailable for daemon tool endpoint');\n        const url = `${this.toolBaseUrl}/${encodeURIComponent(name)}`;\n        const controller = typeof AbortController !== 'undefined' ? new AbortController() : null;\n        const timeout = controller\n            ? setTimeout(() => controller.abort(), this.toolTimeoutMs)\n            : null;\n        try {\n            const res = await this.fetchImpl(url, {\n                method: 'POST',\n                headers: { 'content-type': 'application/json' },\n                body: JSON.stringify({ args: args || {} }),\n                signal: controller?.signal,\n            });\n            if (!res?.ok) throw new Error(`tool endpoint returned ${res?.status || 'non-ok'}`);\n            const json = await res.json();\n            // Backend wraps the tool return under `result`; pass it through.\n            return json?.result ?? json;\n        } finally {\n            if (timeout) clearTimeout(timeout);\n        }\n    }\n\n    getStatus() {\n        return {\n            active: this.active,\n            driver: this.driver,\n            agentId: this.agentId,\n            autonomy: this.autonomy,\n            endpointConfigured: !!this.endpoint,\n            tickMs: this.tickMs,\n            includeImage: this.includeImage,\n            imageWidth: this.imageWidth,\n            imageHeight: this.imageHeight,\n            maxActionsPerMinute: this.maxActionsPerMinute,\n            maxOffsetMeters: this.maxOffsetMeters,\n            dryRun: this.dryRun,\n            autoSummon: this.autoSummon,\n            inFlight: this._inFlight,\n            lastObservationAt: this._lastObservationAt || null,\n            lastStepAt: this._lastStepAt || null,\n            lastActionAt: this._lastActionAt || null,\n            lastAction: this._lastAction,\n            lastResult: this._lastResult,\n            lastError: this._lastError,\n            decisions: this._decisionCount,\n            actionsApplied: this._actionsApplied,\n            actionsDropped: this._actionsDropped,\n            actionSpace: getDaemonVisionActionSpace(),\n            webToolsAvailable: this._webToolsAvailable(),\n            maxToolCallsPerMinute: this.maxToolCallsPerMinute,\n            toolCallsApplied: this._toolCallsApplied,\n            lastToolResult: this._lastToolResult,\n        };\n    }\n}\n","/**\n * EarthDaemonManager — singleton lifecycle owner for the Earth-world\n * daemon. The current contract is \"one daemon at a time\" — summoning\n * a fresh daemon dismisses any prior one. Drives per-frame update,\n * exposes a public API for agent intents (summon / brief / dismiss /\n * follow), and integrates with the running scene's surfaceController\n * so the daemon stands on the photoreal terrain.\n *\n * The manager mounts under the photoreal tile group (so it inherits\n * planet rotation / world transform) and reads the user's lat/lon\n * via the same getter the DirectionsPanel uses.\n */\n\nimport { EarthDaemon } from './EarthDaemon.js';\nimport { DaemonVisionActionDriver } from './DaemonVisionActionDriver.js';\nimport { resolveBackendApiUrl } from '../shared/backend.js';\n\nlet _instance = null;\n\nconst DEG2RAD = Math.PI / 180;\nconst RAD2DEG = 180 / Math.PI;\n\nfunction normalizeLon(lon) {\n    let next = ((lon + 180) % 360 + 360) % 360 - 180;\n    if (next === -180) next = 180;\n    return next;\n}\n\nfunction offsetLatLonMeters(lat, lon, headingDeg, distanceM, radiusM = 6378137) {\n    if (!Number.isFinite(lat) || !Number.isFinite(lon)) return null;\n    const heading = Number.isFinite(headingDeg) ? headingDeg : 90;\n    const phi1 = lat * DEG2RAD;\n    const lambda1 = lon * DEG2RAD;\n    const theta = heading * DEG2RAD;\n    const delta = (Number.isFinite(distanceM) ? distanceM : 0) / Math.max(1, radiusM);\n    const phi2 = Math.asin(\n        Math.sin(phi1) * Math.cos(delta) +\n        Math.cos(phi1) * Math.sin(delta) * Math.cos(theta)\n    );\n    const lambda2 = lambda1 + Math.atan2(\n        Math.sin(theta) * Math.sin(delta) * Math.cos(phi1),\n        Math.cos(delta) - Math.sin(phi1) * Math.sin(phi2)\n    );\n    return {\n        lat: Math.max(-89.999999, Math.min(89.999999, phi2 * RAD2DEG)),\n        lon: normalizeLon(lambda2 * RAD2DEG),\n    };\n}\n\nclass EarthDaemonManager {\n    constructor() {\n        this.scene = null;\n        this.renderer = null;\n        this.parentGroup = null;\n        this.planetRadius = 6378137;\n        this.surfaceController = null;\n        this.getPlayerLatLon = null;\n        this.getPlayerPose = null;\n        this.daemon = null;\n        this._followBound = false;\n        this._visionActionDriver = null;\n    }\n\n    /**\n     * One-time wiring. Called from PlanetScene init after triTree +\n     * surfaceController are ready.\n     */\n    setup({ scene, renderer, parentGroup, planetRadius, surfaceController, getPlayerLatLon, getPlayerPose }) {\n        this.scene = scene || this.scene;\n        this.renderer = renderer || this.renderer;\n        this.parentGroup = parentGroup || this.parentGroup;\n        if (Number.isFinite(planetRadius)) this.planetRadius = planetRadius;\n        this.surfaceController = surfaceController || this.surfaceController;\n        if (typeof getPlayerLatLon === 'function') this.getPlayerLatLon = getPlayerLatLon;\n        if (typeof getPlayerPose === 'function') this.getPlayerPose = getPlayerPose;\n    }\n\n    /** True when setup() has been called with the bare-minimum deps. */\n    isReady() {\n        return !!(this.scene && this.parentGroup && this.getPlayerLatLon);\n    }\n\n    /**\n     * Summon a daemon. Defaults to the user's current location with\n     * a small forward offset. The previous daemon is dismissed first.\n     * Returns the EarthDaemon instance once it has been placed.\n     */\n    async summon({ lat, lon, headingDeg = null, follow = true } = {}) {\n        if (!this.isReady()) return null;\n        await this.dismiss();\n        const pose = this._getPlayerPose();\n        const target = (Number.isFinite(lat) && Number.isFinite(lon))\n            ? { lat, lon, headingDeg: Number.isFinite(headingDeg) ? headingDeg : pose?.headingDeg }\n            : pose;\n        if (!target || !Number.isFinite(target.lat) || !Number.isFinite(target.lon)) {\n            return null;\n        }\n        // Place the daemon in front of the user's current heading so\n        // summoning produces an immediately visible embodied participant.\n        const forwardHeading = Number.isFinite(headingDeg)\n            ? headingDeg\n            : (Number.isFinite(target.headingDeg) ? target.headingDeg : 90);\n        const spawn = offsetLatLonMeters(\n            target.lat,\n            target.lon,\n            forwardHeading,\n            3,\n            this.planetRadius\n        ) || { lat: target.lat, lon: target.lon };\n        const faceUser = (forwardHeading + 180) % 360;\n        const daemon = new EarthDaemon({\n            scene: this.scene,\n            parentGroup: this.parentGroup,\n            planetRadius: this.planetRadius,\n            surfaceController: this.surfaceController,\n            renderer: this.renderer,\n        });\n        this.daemon = daemon;\n        await daemon.manifest({ lat: spawn.lat, lon: spawn.lon, headingDeg: faceUser });\n        if (follow) daemon.follow(this.getPlayerLatLon);\n        return daemon;\n    }\n\n    /** Speak `text` through the active daemon (summons one if needed). */\n    async brief(text) {\n        if (!this.daemon) await this.summon();\n        if (!this.daemon) return false;\n        await this.daemon.speak(String(text || ''));\n        return true;\n    }\n\n    async dismiss() {\n        if (this._visionActionDriver) {\n            this.stopDriver('daemon dismissed');\n        }\n        if (!this.daemon) return;\n        const d = this.daemon;\n        this.daemon = null;\n        await d.dismiss();\n        d.dispose();\n    }\n\n    navigateTo({ lat, lon } = {}) {\n        if (!this.daemon) return false;\n        return this.daemon.navigateTo({ lat, lon });\n    }\n\n    look({ includeImage = false, width = 320, height = 180 } = {}) {\n        if (!this.daemon) return { ok: false, active: false, error: 'no active daemon' };\n        return this.daemon.getPovSnapshot({ includeImage, width, height });\n    }\n\n    async startDriver(options = {}) {\n        if (!this.isReady()) return { ok: false, active: false, error: 'daemon manager not ready' };\n        if (this._visionActionDriver) {\n            this.stopDriver('replaced');\n        }\n        if (!this.daemon && options?.summon !== false) {\n            await this.summon({ follow: false });\n        }\n        // Default the web-tool bridge to the backend `/agent/tools`\n        // endpoint so an Omnius/Dreamer/etc. policy driving the daemon can\n        // emit `web_search`/`web_fetch` actions and have the browser run\n        // them, feeding results back through observations. Callers may\n        // override `toolBaseUrl`/`executeTool` explicitly.\n        const driver = new DaemonVisionActionDriver(this, {\n            toolBaseUrl: resolveBackendApiUrl('/agent/tools'),\n            ...options,\n        });\n        this._visionActionDriver = driver;\n        return { ok: true, ...driver.start() };\n    }\n\n    stopDriver(reason = 'stopped') {\n        if (!this._visionActionDriver) return { ok: true, active: false, reason: 'no active driver' };\n        const status = this._visionActionDriver.stop(reason);\n        this._visionActionDriver = null;\n        return { ok: true, ...status };\n    }\n\n    getDriverStatus() {\n        return this._visionActionDriver?.getStatus?.() || { active: false };\n    }\n\n    /** Per-frame — called from the main scene update. */\n    update(dt) {\n        this.daemon?.update?.(dt);\n        this._visionActionDriver?.update?.(dt);\n    }\n\n    /**\n     * Diagnostic snapshot — used by tests and the chat panel's status\n     * indicator. Returns null when no daemon is active.\n     */\n    getStatus() {\n        if (!this.daemon) return { active: false };\n        return { active: true, ...this.daemon.getDiagnostic() };\n    }\n\n    _getPlayerPose() {\n        const pose = this.getPlayerPose?.();\n        if (pose && Number.isFinite(pose.lat) && Number.isFinite(pose.lon)) return pose;\n        const latLon = this.getPlayerLatLon?.();\n        if (!latLon || !Number.isFinite(latLon.lat) || !Number.isFinite(latLon.lon)) return null;\n        const headingDeg = this.surfaceController?.getSurfaceHeadingDeg?.();\n        return {\n            ...latLon,\n            headingDeg: Number.isFinite(headingDeg) ? headingDeg : null,\n        };\n    }\n\n    _offsetLatLonMeters(lat, lon, headingDeg, distanceM) {\n        return offsetLatLonMeters(lat, lon, headingDeg, distanceM, this.planetRadius);\n    }\n}\n\nexport function getEarthDaemonManager() {\n    if (!_instance) _instance = new EarthDaemonManager();\n    return _instance;\n}\n","/**\n * NavBanner — full-width banner below the HUD showing the upcoming maneuver\n * while a route is active.\n *\n * Shape: [rotating arrow glyph] [distance to next turn]  |  [instruction]  [street name]\n *\n * The arrow glyph rotates on each rAF tick so it points to the next maneuver\n * point *relative to the camera's current yaw*. Looking the right way →\n * arrow points up; looking 180° away → arrow flips around. Bearing comes\n * from RouteProgressTracker; camera yaw from\n * window.planetScene._surfaceController.getSurfaceHeadingDeg().\n *\n * Reacts to RouteStore events only; no direct dependency on routing-service.\n */\n\nfunction escapeHtml(v) {\n  return String(v || '').replace(/[&<>\"']/g, (c) => ({\n    '&': '&amp;', '<': '&lt;', '>': '&gt;', '\"': '&quot;', \"'\": '&#39;',\n  }[c]));\n}\n\nfunction formatDistance(m) {\n  if (!Number.isFinite(m) || m <= 0) return '';\n  if (m < 30) return 'Now';\n  if (m < 1000) return `${Math.round(m / 10) * 10} m`;\n  return `${(m / 1000).toFixed(1)} km`;\n}\n\nexport class NavBanner {\n  constructor({ container } = {}) {\n    this.container = container || document.body;\n    this._el = null;\n    this._glyphEl = null;\n    this._distEl = null;\n    this._instrEl = null;\n    this._streetEl = null;\n    // Most-recent bearing FROM the snapped player position to the next\n    // polyline coord (degrees, 0 = north). Comes from RouteProgressTracker\n    // in the route:progress event payload.\n    this._bearingToNextDeg = NaN;\n    // Last interpolated rotation we wrote to the glyph element. Tracked so\n    // we can ease toward the target rather than snapping on each frame.\n    this._displayedRotationDeg = 0;\n    this._rafId = null;\n    this._arrived = false;\n\n    this._build();\n\n    this._onRouteSet = () => { this._arrived = false; this.show(); this._startTicking(); };\n    this._onRouteCleared = () => { this._stopTicking(); this.hide(); };\n    this._onRouteProgress = (ev) => this._update(ev?.detail || null);\n    this._onRouteArrived = () => this._showArrived();\n\n    document.addEventListener('noclip:route:set', this._onRouteSet);\n    document.addEventListener('noclip:route:cleared', this._onRouteCleared);\n    document.addEventListener('noclip:route:progress', this._onRouteProgress);\n    document.addEventListener('noclip:route:arrived', this._onRouteArrived);\n  }\n\n  dispose() {\n    this._stopTicking();\n    document.removeEventListener('noclip:route:set', this._onRouteSet);\n    document.removeEventListener('noclip:route:cleared', this._onRouteCleared);\n    document.removeEventListener('noclip:route:progress', this._onRouteProgress);\n    document.removeEventListener('noclip:route:arrived', this._onRouteArrived);\n    if (this._el?.parentNode) this._el.parentNode.removeChild(this._el);\n  }\n\n  _build() {\n    const el = document.createElement('div');\n    el.className = 'nc-nav-banner';\n    el.hidden = true;\n    el.innerHTML = `\n      <div class=\"nc-nav-glyph\" aria-hidden=\"true\">\n        <span class=\"nc-nav-glyph-arrow\">&#8593;</span>\n      </div>\n      <div class=\"nc-nav-distance\"></div>\n      <div class=\"nc-nav-body\">\n        <div class=\"nc-nav-instruction\"></div>\n        <div class=\"nc-nav-street\"></div>\n      </div>\n    `;\n    this.container.appendChild(el);\n    this._el = el;\n    this._glyphEl = el.querySelector('.nc-nav-glyph');\n    this._glyphArrowEl = el.querySelector('.nc-nav-glyph-arrow');\n    this._distEl = el.querySelector('.nc-nav-distance');\n    this._instrEl = el.querySelector('.nc-nav-instruction');\n    this._streetEl = el.querySelector('.nc-nav-street');\n  }\n\n  show()  { if (this._el) this._el.hidden = false; }\n  hide()  { if (this._el) this._el.hidden = true; }\n\n  _update(snapshot) {\n    if (!snapshot) return;\n    const idx = snapshot.nextStepIndex;\n    const route = this._getRoute();\n    if (!route || !Number.isFinite(idx)) return;\n    const step = route.steps?.[idx];\n    if (!step) return;\n\n    // Capture bearing-to-next-coord so the rAF tick can rotate the glyph\n    // relative to the live camera yaw.\n    if (Number.isFinite(snapshot.bearingDeg)) {\n      this._bearingToNextDeg = snapshot.bearingDeg;\n    }\n    if (this._glyphEl) {\n      this._glyphEl.dataset.glyph = step.glyph || 'up';\n    }\n    const dist = snapshot.distanceToNextStep;\n    if (this._distEl) {\n      this._distEl.textContent = formatDistance(dist);\n      this._distEl.classList.toggle('imminent', dist >= 0 && dist < 80);\n    }\n    if (this._instrEl) {\n      this._instrEl.textContent = step.instruction || 'Continue';\n    }\n    if (this._streetEl) {\n      this._streetEl.textContent = step.streetName || '';\n    }\n    this.show();\n  }\n\n  _showArrived() {\n    this._arrived = true;\n    if (this._glyphEl) this._glyphEl.dataset.glyph = 'flag';\n    if (this._glyphArrowEl) this._glyphArrowEl.textContent = '⚑'; // 'flag of victory' glyph\n    if (this._distEl) this._distEl.textContent = 'Arrived';\n    if (this._instrEl) this._instrEl.textContent = 'You have arrived at your destination.';\n    if (this._streetEl) this._streetEl.textContent = '';\n    // Stop rotating the arrow once arrived; lock it upright.\n    this._displayedRotationDeg = 0;\n    if (this._glyphArrowEl) this._glyphArrowEl.style.transform = 'rotate(0deg)';\n    this.show();\n  }\n\n  _getRoute() {\n    // Late-binding import avoids a cycle when RouteStore hasn't booted yet.\n    try {\n      const store = globalThis.__noclipRouteStore;\n      if (store?.getRoute) return store.getRoute();\n    } catch {}\n    return null;\n  }\n\n  _getCameraYawDeg() {\n    try {\n      const sc = globalThis.window?.planetScene?._surfaceController;\n      const yaw = sc?.getSurfaceHeadingDeg?.();\n      if (Number.isFinite(yaw)) return yaw;\n    } catch {}\n    return 0;\n  }\n\n  _startTicking() {\n    if (this._rafId != null) return;\n    const tick = () => {\n      this._rafId = null;\n      if (!this._el || this._el.hidden) return; // banner hidden; don't burn frames\n      if (!this._arrived) this._tickRotation();\n      // Schedule again only while the banner is visible AND we still have\n      // an active route (RouteStore reachable + isActive).\n      const store = globalThis.__noclipRouteStore;\n      if (store?.isActive?.()) {\n        this._rafId = requestAnimationFrame(tick);\n      }\n    };\n    this._rafId = requestAnimationFrame(tick);\n  }\n\n  _stopTicking() {\n    if (this._rafId != null) {\n      cancelAnimationFrame(this._rafId);\n      this._rafId = null;\n    }\n  }\n\n  _tickRotation() {\n    if (!this._glyphArrowEl || !Number.isFinite(this._bearingToNextDeg)) return;\n    const cameraYaw = this._getCameraYawDeg();\n    // Relative bearing — how much the camera needs to rotate clockwise to\n    // face the next maneuver point.\n    let rel = (this._bearingToNextDeg - cameraYaw) % 360;\n    if (rel > 180) rel -= 360;\n    if (rel < -180) rel += 360;\n    // Ease toward target — keeps the arrow stable when GPS jitters or\n    // camera ticks at high frequency. Wrap-around safe via the shortest-arc\n    // delta we just computed.\n    let delta = rel - this._displayedRotationDeg;\n    if (delta > 180) delta -= 360;\n    if (delta < -180) delta += 360;\n    this._displayedRotationDeg += delta * 0.18;\n    // Normalise back into [-180, 180] for transform string sanity.\n    if (this._displayedRotationDeg > 180) this._displayedRotationDeg -= 360;\n    if (this._displayedRotationDeg < -180) this._displayedRotationDeg += 360;\n    this._glyphArrowEl.style.transform = `rotate(${this._displayedRotationDeg.toFixed(1)}deg)`;\n  }\n}\n\nlet _instance = null;\nexport function getNavBanner(options = {}) {\n  if (!_instance) _instance = new NavBanner(options);\n  return _instance;\n}\n\nexport default NavBanner;\n","/**\n * MotionTrailRenderer.js\n *\n * Renders motion tracking history as 3D spline trails in the scene.\n * Two trail types:\n *   - Manual trail (camera navigation) — accent color\n *   - GPS trail — green color\n *\n * Each trail is a CatmullRom spline through the sample positions,\n * with point markers at each sample showing orientation.\n */\n\nimport * as THREE from 'three';\nimport { latLonToLocalDir, ellipsoidRadiusForLocalDir } from '../../modules/geometry-utils.js';\n\nconst MANUAL_COLOR = 0xffffff;  // Accent orange\nconst GPS_COLOR = 0x00ff88;     // Green\nconst TRAIL_OPACITY = 0.7;\nconst POINT_SIZE = 3;\nconst TRAIL_SEGMENTS = 4;       // Subdivisions between sample points\nconst CAMERA_HELPER_SIZE = 15;  // Size of mini camera frustum (meters)\nconst CAMERA_HELPER_EVERY = 1;  // Place a camera helper at every Nth sample\n\n// ── Shared camera helper geometry (frustum wireframe) ─────────────────\n// A small frustum/pyramid shape: apex at origin, base spread in -Z direction.\n// Represents the camera's view direction and field of view.\nlet _helperGeo = null;\nfunction getCameraHelperGeometry() {\n  if (_helperGeo) return _helperGeo;\n  const s = CAMERA_HELPER_SIZE;\n  const d = s * 1.5; // depth (forward)\n  const hw = s * 0.6; // half-width at far plane\n  const hh = s * 0.4; // half-height at far plane\n  // Frustum vertices: apex + 4 corners of far plane\n  const verts = new Float32Array([\n    // Apex (camera position)\n    0, 0, 0,\n    // Far-plane corners (in camera-local space: -Z is forward)\n    -hw,  hh, -d,\n     hw,  hh, -d,\n     hw, -hh, -d,\n    -hw, -hh, -d,\n    // Up indicator (small spike above apex)\n    0, s * 0.3, 0,\n  ]);\n  // Line indices: apex → each corner, far plane edges, up spike\n  const indices = new Uint16Array([\n    0, 1,  0, 2,  0, 3,  0, 4, // Apex → corners\n    1, 2,  2, 3,  3, 4,  4, 1, // Far plane rectangle\n    0, 5,                       // Up indicator\n  ]);\n  _helperGeo = new THREE.BufferGeometry();\n  _helperGeo.setAttribute('position', new THREE.BufferAttribute(verts, 3));\n  _helperGeo.setIndex(new THREE.BufferAttribute(indices, 1));\n  return _helperGeo;\n}\n\nexport class MotionTrailRenderer {\n  constructor({ parentGroup, planetRadius } = {}) {\n    this.parentGroup = parentGroup || null;\n    this.planetRadius = planetRadius || 6378137;\n\n    this.group = new THREE.Group();\n    this.group.name = 'MotionTrails';\n    if (this.parentGroup) this.parentGroup.add(this.group);\n\n    this._trails = new Map(); // sessionId → { line, points, type }\n  }\n\n  /**\n   * Render or update a trail from sample data.\n   * @param {string} sessionId\n   * @param {Array} samples — array of MotionSample objects\n   * @param {'manual'|'gps'} type\n   */\n  updateTrail(sessionId, samples, type = 'manual') {\n    if (!samples || samples.length < 2) return;\n\n    // Remove existing trail for this session\n    this.removeTrail(sessionId);\n\n    const color = type === 'gps' ? GPS_COLOR : MANUAL_COLOR;\n    const positions = [];\n\n    // Convert lat/lon/elevation to 3D positions\n    for (const sample of samples) {\n      const dir = latLonToLocalDir(sample.lat, sample.lon);\n      const radius = ellipsoidRadiusForLocalDir(dir) + (sample.elevation_m || 0);\n      const pos = dir.multiplyScalar(radius);\n      positions.push(pos);\n    }\n\n    // Create spline through positions\n    const curve = new THREE.CatmullRomCurve3(positions, false, 'catmullrom', 0.5);\n    const curvePoints = curve.getPoints(positions.length * TRAIL_SEGMENTS);\n\n    // Line geometry\n    const lineGeo = new THREE.BufferGeometry().setFromPoints(curvePoints);\n    const lineMat = new THREE.LineBasicMaterial({\n      color,\n      transparent: true,\n      opacity: TRAIL_OPACITY,\n      depthWrite: false,\n    });\n    const line = new THREE.Line(lineGeo, lineMat);\n    line.name = `Trail:${sessionId}:line`;\n    line.renderOrder = 5;\n    line.frustumCulled = false;\n\n    // Point markers at each sample position\n    const pointGeo = new THREE.BufferGeometry();\n    const pointPositions = new Float32Array(positions.length * 3);\n    const pointColors = new Float32Array(positions.length * 3);\n    const baseColor = new THREE.Color(color);\n\n    for (let i = 0; i < positions.length; i++) {\n      const p = positions[i];\n      pointPositions[i * 3] = p.x;\n      pointPositions[i * 3 + 1] = p.y;\n      pointPositions[i * 3 + 2] = p.z;\n\n      // Color gradient: older = dimmer, newer = brighter\n      const t = positions.length > 1 ? i / (positions.length - 1) : 1;\n      pointColors[i * 3] = baseColor.r * (0.3 + 0.7 * t);\n      pointColors[i * 3 + 1] = baseColor.g * (0.3 + 0.7 * t);\n      pointColors[i * 3 + 2] = baseColor.b * (0.3 + 0.7 * t);\n    }\n\n    pointGeo.setAttribute('position', new THREE.BufferAttribute(pointPositions, 3));\n    pointGeo.setAttribute('color', new THREE.BufferAttribute(pointColors, 3));\n\n    const pointMat = new THREE.PointsMaterial({\n      size: POINT_SIZE,\n      vertexColors: true,\n      transparent: true,\n      opacity: 0.9,\n      depthWrite: false,\n      sizeAttenuation: false,\n    });\n    const points = new THREE.Points(pointGeo, pointMat);\n    points.name = `Trail:${sessionId}:points`;\n    points.renderOrder = 6;\n    points.frustumCulled = false;\n\n    this.group.add(line);\n    this.group.add(points);\n\n    // Camera helper frustums at each sample point showing orientation\n    const helpers = new THREE.Group();\n    helpers.name = `Trail:${sessionId}:helpers`;\n    const helperGeo = getCameraHelperGeometry();\n    const helperMat = new THREE.LineBasicMaterial({\n      color,\n      transparent: true,\n      opacity: 0.6,\n      depthWrite: false,\n    });\n\n    for (let i = 0; i < samples.length; i += CAMERA_HELPER_EVERY) {\n      const sample = samples[i];\n      const pos = positions[i];\n      if (!pos || !sample.quaternion) continue;\n\n      const helper = new THREE.LineSegments(helperGeo, helperMat);\n      helper.position.copy(pos);\n\n      // Apply the stored camera quaternion.\n      // The quaternion from MotionTracker is in camera-local space.\n      // We need to compose it with the surface orientation at this lat/lon\n      // so the frustum points in the correct world direction.\n      const surfaceUp = latLonToLocalDir(sample.lat, sample.lon).normalize();\n      const surfaceQuat = new THREE.Quaternion();\n\n      // Build surface frame: up = surfaceUp, forward = tangent north\n      const north = new THREE.Vector3(0, 1, 0);\n      const east = new THREE.Vector3().crossVectors(north, surfaceUp).normalize();\n      if (east.lengthSq() < 0.001) {\n        east.set(1, 0, 0); // Pole fallback\n      }\n      const surfaceNorth = new THREE.Vector3().crossVectors(surfaceUp, east).normalize();\n      const surfaceMat = new THREE.Matrix4().makeBasis(east, surfaceUp, surfaceNorth);\n      surfaceQuat.setFromRotationMatrix(surfaceMat);\n\n      // Compose: surface frame × stored camera quaternion\n      const [qx, qy, qz, qw] = sample.quaternion;\n      const camQuat = new THREE.Quaternion(qx, qy, qz, qw);\n      helper.quaternion.copy(surfaceQuat).multiply(camQuat);\n\n      // Fade older helpers\n      const t = samples.length > 1 ? i / (samples.length - 1) : 1;\n      helper.material = helperMat.clone();\n      helper.material.opacity = 0.2 + 0.6 * t;\n\n      helper.frustumCulled = false;\n      helper.renderOrder = 7;\n      helpers.add(helper);\n    }\n\n    this.group.add(helpers);\n\n    this._trails.set(sessionId, { line, points, helpers, type, sampleCount: samples.length });\n  }\n\n  /**\n   * Remove a trail.\n   */\n  removeTrail(sessionId) {\n    const trail = this._trails.get(sessionId);\n    if (!trail) return;\n\n    this.group.remove(trail.line);\n    this.group.remove(trail.points);\n    trail.line.geometry.dispose();\n    trail.line.material.dispose();\n    trail.points.geometry.dispose();\n    trail.points.material.dispose();\n\n    // Clean up camera helper frustums\n    if (trail.helpers) {\n      trail.helpers.traverse(child => {\n        if (child.material && child.material !== trail.line.material) {\n          child.material.dispose();\n        }\n      });\n      this.group.remove(trail.helpers);\n    }\n\n    this._trails.delete(sessionId);\n  }\n\n  /**\n   * Remove all trails.\n   */\n  clear() {\n    for (const [id] of this._trails) {\n      this.removeTrail(id);\n    }\n  }\n\n  /**\n   * Set visibility of trails by type.\n   */\n  setTypeVisible(type, visible) {\n    for (const trail of this._trails.values()) {\n      if (trail.type === type) {\n        trail.line.visible = visible;\n        trail.points.visible = visible;\n        if (trail.helpers) trail.helpers.visible = visible;\n      }\n    }\n  }\n\n  dispose() {\n    this.clear();\n    if (this.group.parent) this.group.parent.remove(this.group);\n  }\n}\n","const clamp01 = value => Math.max(0, Math.min(1, value));\nconst lerp = (a, b, t) => a + (b - a) * t;\n\nfunction easing(id, t) {\n  const x = clamp01(t);\n  if (id === 'step') return x < 1 ? 0 : 1;\n  if (id === 'ease-in') return x * x;\n  if (id === 'ease-out') return 1 - (1 - x) * (1 - x);\n  if (id === 'ease-in-out') return x < 0.5 ? 2 * x * x : 1 - ((-2 * x + 2) ** 2) / 2;\n  return x;\n}\n\nfunction unitFromLatLon(latitude, longitude) {\n  const lat = latitude * Math.PI / 180;\n  const lon = longitude * Math.PI / 180;\n  const cosLat = Math.cos(lat);\n  return [cosLat * Math.cos(lon), Math.sin(lat), cosLat * Math.sin(lon)];\n}\n\nfunction latLonFromUnit(value) {\n  const length = Math.hypot(value[0], value[1], value[2]) || 1;\n  return {\n    latitude: Math.asin(value[1] / length) * 180 / Math.PI,\n    longitude: Math.atan2(value[2], value[0]) * 180 / Math.PI,\n  };\n}\n\nfunction slerpLatLon(from, to, t) {\n  const a = unitFromLatLon(from.latitude, from.longitude);\n  const b = unitFromLatLon(to.latitude, to.longitude);\n  const dot = Math.max(-1, Math.min(1, a[0] * b[0] + a[1] * b[1] + a[2] * b[2]));\n  const angle = Math.acos(dot);\n  if (angle < 1e-8) return { latitude: lerp(from.latitude, to.latitude, t), longitude: from.longitude };\n  const sin = Math.sin(angle);\n  const aa = Math.sin((1 - t) * angle) / sin;\n  const bb = Math.sin(t * angle) / sin;\n  return latLonFromUnit([a[0] * aa + b[0] * bb, a[1] * aa + b[1] * bb, a[2] * aa + b[2] * bb]);\n}\n\nfunction cardinalPoint(p0, p1, p2, p3, t, tension) {\n  const scale = (1 - tension) * 0.5;\n  const t2 = t * t; const t3 = t2 * t;\n  const h00 = 2 * t3 - 3 * t2 + 1;\n  const h10 = t3 - 2 * t2 + t;\n  const h01 = -2 * t3 + 3 * t2;\n  const h11 = t3 - t2;\n  return p1.map((value, index) => h00 * value + h10 * scale * (p2[index] - p0[index]) + h01 * p2[index] + h11 * scale * (p3[index] - p1[index]));\n}\n\nfunction catmullPosition(compiled, index, t, ecef = false) {\n  const points = compiled.waypoints;\n  const point = offset => points[Math.max(0, Math.min(points.length - 1, index + offset))];\n  const vector = waypoint => ecef\n    ? [waypoint.ecef.x, waypoint.ecef.y, waypoint.ecef.z]\n    : unitFromLatLon(waypoint.latitude, waypoint.longitude);\n  const result = cardinalPoint(vector(point(-1)), vector(point(0)), vector(point(1)), vector(point(2)), t, compiled.definition.interpolation.tension ?? 0.5);\n  if (ecef) return { ecef: { x: result[0], y: result[1], z: result[2] } };\n  return latLonFromUnit(result);\n}\n\nfunction binarySearchTime(entries, timeMs) {\n  let low = 0; let high = entries.length - 1;\n  while (low <= high) {\n    const mid = (low + high) >>> 1;\n    if (entries[mid].timeMs <= timeMs) low = mid + 1;\n    else high = mid - 1;\n  }\n  return Math.max(0, Math.min(entries.length - 1, high));\n}\n\nfunction sampleTrack(track, timeMs) {\n  const keys = track.keyframes;\n  if (!keys.length) return undefined;\n  const index = binarySearchTime(keys, timeMs);\n  const from = keys[index];\n  const to = keys[Math.min(index + 1, keys.length - 1)];\n  if (from === to || track.interpolation === 'step' || typeof from.value !== 'number' || typeof to.value !== 'number') return from.value;\n  const span = Math.max(1, to.timeMs - from.timeMs);\n  return lerp(from.value, to.value, easing(to.easing, (timeMs - from.timeMs) / span));\n}\n\nfunction normalizeQuaternion(value) {\n  const length = Math.hypot(...value) || 1;\n  return value.map(part => part / length);\n}\n\nfunction slerpQuaternion(aValue, bValue, t) {\n  let a = aValue; let b = bValue;\n  let dot = a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3];\n  if (dot < 0) { dot = -dot; b = b.map(value => -value); }\n  if (dot > 0.9995) return normalizeQuaternion(a.map((value, index) => lerp(value, b[index], t)));\n  const theta = Math.acos(Math.max(-1, Math.min(1, dot)));\n  const sinTheta = Math.sin(theta);\n  const aa = Math.sin((1 - t) * theta) / sinTheta;\n  const bb = Math.sin(t * theta) / sinTheta;\n  return a.map((value, index) => value * aa + b[index] * bb);\n}\n\nfunction lerpAngleDeg(a, b, t) {\n  const delta = ((b - a + 540) % 360) - 180;\n  return a + delta * t;\n}\n\nfunction sampleOrientation(from, to, t) {\n  if (from.orientation.mode === 'quaternion' && to.orientation.mode === 'quaternion') {\n    return { mode: 'quaternion', value: slerpQuaternion(from.orientation.value, to.orientation.value, t) };\n  }\n  if (from.orientation.mode === 'enu-hpr' && to.orientation.mode === 'enu-hpr') {\n    return {\n      mode: 'enu-hpr',\n      headingDeg: lerpAngleDeg(from.orientation.headingDeg, to.orientation.headingDeg, t),\n      pitchDeg: lerp(from.orientation.pitchDeg, to.orientation.pitchDeg, t),\n      rollDeg: lerpAngleDeg(from.orientation.rollDeg, to.orientation.rollDeg, t),\n    };\n  }\n  return t < 1 ? from.orientation : to.orientation;\n}\n\nexport function sampleMotionPath(compiled, requestedTimeMs) {\n  if (!compiled?.waypoints?.length) throw new TypeError('A compiled motion path is required.');\n  const timeMs = Math.max(0, Math.min(compiled.durationMs, Number(requestedTimeMs) || 0));\n  const waypointIndex = binarySearchTime(compiled.waypoints, timeMs);\n  const from = compiled.waypoints[waypointIndex];\n  const to = compiled.waypoints[Math.min(waypointIndex + 1, compiled.waypoints.length - 1)];\n  const heldUntil = from.timeMs + (from.holdMs || 0);\n  const rawT = from === to || timeMs <= heldUntil ? 0 : (timeMs - heldUntil) / Math.max(1, to.timeMs - heldUntil);\n  const t = easing(to.easing, rawT);\n  const altitudeReference = from.altitude.reference === to.altitude.reference ? from.altitude.reference : 'mixed';\n  let position;\n  if (compiled.definition.interpolation.position === 'step') {\n    position = t < 1 ? { latitude: from.latitude, longitude: from.longitude } : { latitude: to.latitude, longitude: to.longitude };\n  } else if (compiled.definition.interpolation.position === 'straight-ecef') {\n    position = compiled.definition.interpolation.curve === 'catmull-rom'\n      ? catmullPosition(compiled, waypointIndex, t, true)\n      : { ecef: { x: lerp(from.ecef.x, to.ecef.x, t), y: lerp(from.ecef.y, to.ecef.y, t), z: lerp(from.ecef.z, to.ecef.z, t) } };\n    position = {\n      ...position,\n      latitude: lerp(from.latitude, to.latitude, t),\n      longitude: lerp(from.longitude, to.longitude, t),\n    };\n  } else position = compiled.definition.interpolation.curve === 'catmull-rom'\n    ? catmullPosition(compiled, waypointIndex, t)\n    : slerpLatLon(from, to, t);\n  const tracks = {};\n  for (const track of compiled.tracks) tracks[track.property] = sampleTrack(track, timeMs);\n  return Object.freeze({\n    timeMs,\n    segmentIndex: Math.min(waypointIndex, Math.max(0, compiled.segments.length - 1)),\n    waypointIndex,\n    position: Object.freeze({\n      ...position,\n      altitudeM: lerp(from.resolvedAltitude.heightM, to.resolvedAltitude.heightM, t),\n      altitudeResolved: from.resolvedAltitude.resolved && to.resolvedAltitude.resolved,\n      altitudeReference,\n      altitudeAuthority: from.resolvedAltitude.authority === to.resolvedAltitude.authority ? from.resolvedAltitude.authority : 'mixed',\n    }),\n    orientation: Object.freeze(sampleOrientation(from, to, t)),\n    tracks: Object.freeze(tracks),\n    completed: timeMs >= compiled.durationMs,\n  });\n}\n","export const MOTION_EXECUTION_STATE = Object.freeze({\n  CREATED: 'created',\n  RUNNING: 'running',\n  PAUSED: 'paused',\n  COMPLETED: 'completed',\n  CANCELLED: 'cancelled',\n  FAILED: 'failed',\n});\n\nexport const MOTION_TERMINAL_STATES = Object.freeze(new Set([\n  MOTION_EXECUTION_STATE.COMPLETED,\n  MOTION_EXECUTION_STATE.CANCELLED,\n  MOTION_EXECUTION_STATE.FAILED,\n]));\n\nconst TRANSITIONS = Object.freeze({\n  created: new Set(['running', 'paused', 'cancelled', 'failed']),\n  running: new Set(['paused', 'completed', 'cancelled', 'failed']),\n  paused: new Set(['running', 'completed', 'cancelled', 'failed']),\n  completed: new Set(),\n  cancelled: new Set(),\n  failed: new Set(),\n});\n\nexport class MotionRuntimeError extends Error {\n  constructor(code, message = code, details = null) {\n    super(message);\n    this.name = 'MotionRuntimeError';\n    this.code = code;\n    this.details = details;\n  }\n}\n\nexport function transitionMotionState(current, next) {\n  if (current === next) return next;\n  if (!TRANSITIONS[current]?.has(next)) {\n    throw new MotionRuntimeError('INVALID_STATE_TRANSITION', `Cannot transition motion execution from ${current} to ${next}.`, { current, next });\n  }\n  return next;\n}\n\nexport const isMotionTerminal = state => MOTION_TERMINAL_STATES.has(state);\n","import { MotionRuntimeError } from './MotionExecutionState.js';\n\nconst clamp = (value, min, max) => Math.max(min, Math.min(max, value));\n\n/** A deterministic timeline. It never reads a clock; callers provide the one\n * scene-owned monotonic frame timestamp. */\nexport class MotionTimelineClock {\n  constructor({ durationMs, rate = 1, timeMs = 0 } = {}) {\n    if (!Number.isFinite(durationMs) || durationMs <= 0) throw new MotionRuntimeError('DURATION_INVALID');\n    this.durationMs = durationMs;\n    this.rate = 1;\n    this.timeMs = clamp(Number(timeMs) || 0, 0, durationMs);\n    this.state = 'paused';\n    this.anchorNowMs = null;\n    this.lastFrameNowMs = null;\n    this.setRate(rate);\n  }\n\n  play() {\n    if (this.timeMs >= this.durationMs) this.timeMs = 0;\n    this.state = 'running'; this.anchorNowMs = null; return this.snapshot();\n  }\n\n  pause() { this.state = 'paused'; this.anchorNowMs = null; return this.snapshot(); }\n  resume() { if (this.timeMs < this.durationMs) { this.state = 'running'; this.anchorNowMs = null; } return this.snapshot(); }\n\n  seek(timeMs) {\n    if (!Number.isFinite(timeMs)) throw new MotionRuntimeError('TIME_INVALID');\n    this.timeMs = clamp(timeMs, 0, this.durationMs);\n    this.anchorNowMs = null;\n    return this.snapshot();\n  }\n\n  setRate(rate) {\n    if (!Number.isFinite(rate) || rate <= 0 || rate > 16) throw new MotionRuntimeError('RATE_INVALID', 'Motion rate must be within (0, 16].');\n    this.rate = rate; this.anchorNowMs = null; return this.snapshot();\n  }\n\n  sample(monotonicNowMs) {\n    if (!Number.isFinite(monotonicNowMs)) throw new MotionRuntimeError('FRAME_TIME_INVALID');\n    const now = this.lastFrameNowMs === null ? monotonicNowMs : Math.max(this.lastFrameNowMs, monotonicNowMs);\n    this.lastFrameNowMs = now;\n    if (this.state !== 'running') return this.timeMs;\n    if (this.anchorNowMs === null) { this.anchorNowMs = now; return this.timeMs; }\n    const elapsed = Math.max(0, now - this.anchorNowMs);\n    this.anchorNowMs = now;\n    this.timeMs = clamp(this.timeMs + elapsed * this.rate, 0, this.durationMs);\n    return this.timeMs;\n  }\n\n  snapshot() {\n    return Object.freeze({ state: this.state, durationMs: this.durationMs, timeMs: this.timeMs, rate: this.rate });\n  }\n}\n","import { MotionRuntimeError } from './MotionExecutionState.js';\n\nexport class MotionTargetRegistry {\n  constructor() { this.records = new Map(); this.generation = 0; }\n\n  register(adapter) {\n    const kind = String(adapter?.kind || '');\n    if (!kind || typeof adapter.acquire !== 'function') throw new MotionRuntimeError('TARGET_ADAPTER_INVALID');\n    const record = Object.freeze({ kind, adapter, generation: ++this.generation });\n    this.records.set(kind, record);\n    return () => this.unregister(kind, record);\n  }\n\n  unregister(kind, expected = null) {\n    const current = this.records.get(kind);\n    if (!current || (expected && current !== expected)) return false;\n    this.records.delete(kind); this.generation += 1; return true;\n  }\n\n  resolve(kind) {\n    const record = this.records.get(kind);\n    if (!record) throw new MotionRuntimeError('TARGET_ADAPTER_UNAVAILABLE', `No motion adapter is registered for ${kind}.`, { kind });\n    return record;\n  }\n\n  isCurrent(record) { return !!record && this.records.get(record.kind) === record; }\n  dispose() { this.records.clear(); this.generation += 1; }\n}\n","import { sampleMotionPath } from './MotionPathEvaluator.js';\nimport { MotionTimelineClock } from './MotionTimelineClock.js';\nimport { MotionTargetRegistry } from './MotionTargetRegistry.js';\nimport { MOTION_EXECUTION_STATE, MotionRuntimeError, isMotionTerminal, transitionMotionState } from './MotionExecutionState.js';\n\nconst MAX_EXECUTIONS = 512;\nconst MAX_EVENTS = 256;\nconst clone = value => value == null ? value : structuredClone(value);\n\nfunction publicSnapshot(execution) {\n  return Object.freeze({\n    id: execution.id,\n    generation: execution.generation,\n    state: execution.state,\n    reason: execution.reason,\n    mode: execution.mode,\n    target: Object.freeze({ ...execution.compiled.target }),\n    clock: execution.clock.snapshot(),\n    lastSample: clone(execution.lastSample),\n    error: execution.error ? Object.freeze({ code: execution.error.code || 'MOTION_RUNTIME_FAILED', message: execution.error.message }) : null,\n  });\n}\n\nexport class MotionRuntime {\n  constructor({ targetRegistry = new MotionTargetRegistry(), onEvent = null } = {}) {\n    this.targetRegistry = targetRegistry;\n    this.onEvent = typeof onEvent === 'function' ? onEvent : null;\n    this.executions = new Map();\n    this.events = [];\n    this.generation = 0;\n    this.lastFrameNowMs = null;\n    this.updateCount = 0;\n    this.disposed = false;\n  }\n\n  registerTarget(adapter) { return this.targetRegistry.register(adapter); }\n  unregisterTarget(kind) { return this.targetRegistry.unregister(kind); }\n\n  loadCompiledExecution(descriptor = {}) {\n    if (this.disposed) throw new MotionRuntimeError('RUNTIME_DISPOSED');\n    const id = String(descriptor.id || '').trim();\n    const compiled = descriptor.compiled;\n    if (!id || id.length > 200) throw new MotionRuntimeError('EXECUTION_ID_INVALID');\n    if (!compiled?.definition || !compiled?.target || !Number.isFinite(compiled.durationMs)) throw new MotionRuntimeError('COMPILED_PATH_INVALID');\n    if (!['preview', 'simulated'].includes(descriptor.mode || 'preview')) throw new MotionRuntimeError('EXECUTION_MODE_DISABLED');\n    if (compiled.target.kind === 'physical-device') throw new MotionRuntimeError('PHYSICAL_EXECUTION_DISABLED');\n    if (!this.executions.has(id)) this._ensureCapacity();\n    if (this.executions.has(id)) this.cancel(id, 'EXECUTION_REPLACED');\n    const adapterRecord = this.targetRegistry.resolve(compiled.target.kind);\n    const generation = ++this.generation;\n    const execution = {\n      id, generation, compiled,\n      mode: descriptor.mode || 'preview',\n      restoreOnComplete: descriptor.restoreOnComplete ?? (descriptor.mode || 'preview') === 'preview',\n      state: MOTION_EXECUTION_STATE.CREATED,\n      reason: null, error: null, sequence: generation,\n      clock: new MotionTimelineClock({ durationMs: compiled.durationMs, rate: descriptor.rate || 1, timeMs: descriptor.timeMs || 0 }),\n      adapterRecord, handle: null, lastSample: null, lastEventTimeMs: null, pendingSample: false, settled: false,\n    };\n    try {\n      execution.handle = adapterRecord.adapter.acquire({\n        executionId: id,\n        generation,\n        compiled,\n        mode: execution.mode,\n        targetContext: descriptor.targetContext || {},\n        cancel: reason => this.cancel(id, reason || 'TARGET_CANCELLED', generation),\n      });\n      if (!execution.handle || typeof execution.handle.apply !== 'function') {\n        execution.handle?.restore?.('TARGET_HANDLE_INVALID');\n        throw new MotionRuntimeError('TARGET_HANDLE_INVALID');\n      }\n    } catch (error) {\n      if (error instanceof MotionRuntimeError) throw error;\n      throw new MotionRuntimeError('TARGET_ACQUIRE_FAILED', error?.message || 'Target acquisition failed.');\n    }\n    this.executions.delete(id); this.executions.set(id, execution);\n    this._event(execution, 'loaded');\n    return publicSnapshot(execution);\n  }\n\n  play(id, expectedGeneration) {\n    const execution = this._active(id, expectedGeneration);\n    execution.clock.play(); execution.state = transitionMotionState(execution.state, MOTION_EXECUTION_STATE.RUNNING);\n    execution.pendingSample = true; execution.lastEventTimeMs = null; this._event(execution, 'playing'); return publicSnapshot(execution);\n  }\n\n  pause(id, expectedGeneration) {\n    const execution = this._active(id, expectedGeneration);\n    execution.clock.pause(); execution.state = transitionMotionState(execution.state, MOTION_EXECUTION_STATE.PAUSED);\n    this._event(execution, 'paused'); return publicSnapshot(execution);\n  }\n\n  resume(id, expectedGeneration) {\n    const execution = this._active(id, expectedGeneration);\n    execution.clock.resume(); execution.state = transitionMotionState(execution.state, MOTION_EXECUTION_STATE.RUNNING);\n    this._event(execution, 'resumed'); return publicSnapshot(execution);\n  }\n\n  seek(id, timeMs, { emitEvents = false, expectedGeneration } = {}) {\n    const execution = this._active(id, expectedGeneration);\n    execution.clock.seek(timeMs); execution.pendingSample = true;\n    execution.lastEventTimeMs = emitEvents ? execution.lastEventTimeMs : execution.clock.timeMs;\n    this._event(execution, 'seeked', { timeMs: execution.clock.timeMs }); return publicSnapshot(execution);\n  }\n\n  cancel(id, reason = 'CANCELLED', expectedGeneration) {\n    const execution = this.executions.get(id);\n    if (!execution || isMotionTerminal(execution.state)) return false;\n    if (expectedGeneration !== undefined && execution.generation !== expectedGeneration) return false;\n    execution.clock.pause(); execution.reason = reason;\n    try {\n      this._settle(execution, true, reason);\n      execution.state = transitionMotionState(execution.state, MOTION_EXECUTION_STATE.CANCELLED);\n      this._event(execution, 'cancelled', { reason });\n    } catch (error) {\n      this._fail(execution, error);\n    }\n    return true;\n  }\n\n  release(id, reason = 'RELEASED', expectedGeneration) {\n    const execution = this.executions.get(id);\n    if (!execution) return false;\n    if (expectedGeneration !== undefined && execution.generation !== expectedGeneration) return false;\n    if (!isMotionTerminal(execution.state)) this.cancel(id, reason, execution.generation);\n    return this.executions.delete(id);\n  }\n\n  update(monotonicNowMs, frameContext = {}) {\n    if (this.disposed) return Object.freeze({ updated: 0, active: 0 });\n    if (!Number.isFinite(monotonicNowMs)) throw new MotionRuntimeError('FRAME_TIME_INVALID');\n    const frameNow = this.lastFrameNowMs === null ? monotonicNowMs : Math.max(this.lastFrameNowMs, monotonicNowMs);\n    this.lastFrameNowMs = frameNow; this.updateCount += 1;\n    let updated = 0; let active = 0;\n    for (const execution of this.executions.values()) {\n      if (isMotionTerminal(execution.state)) continue;\n      active += 1;\n      if (!this.targetRegistry.isCurrent(execution.adapterRecord)) { this._fail(execution, new MotionRuntimeError('TARGET_REPLACED')); continue; }\n      const running = execution.state === MOTION_EXECUTION_STATE.RUNNING;\n      if (!running && !execution.pendingSample) continue;\n      try {\n        const previousTime = execution.lastEventTimeMs;\n        const timeMs = execution.clock.sample(frameNow);\n        const sample = sampleMotionPath(execution.compiled, timeMs);\n        if (!sample.position.altitudeResolved && sample.position.altitudeReference !== 'agl') throw new MotionRuntimeError('ALTITUDE_UNRESOLVED');\n        const result = execution.handle.apply(sample, { frameNowMs: frameNow, frameContext, generation: execution.generation });\n        if (result?.ok === false) throw new MotionRuntimeError(result.code || 'TARGET_APPLY_FAILED', result.message || result.code);\n        execution.lastSample = sample; execution.pendingSample = false; updated += 1;\n        if (running) this._emitCrossedEvents(execution, previousTime, timeMs);\n        execution.lastEventTimeMs = timeMs;\n        if (sample.completed && running) {\n          execution.clock.pause(); execution.reason = 'COMPLETED';\n          this._settle(execution, execution.restoreOnComplete, 'COMPLETED');\n          execution.state = transitionMotionState(execution.state, MOTION_EXECUTION_STATE.COMPLETED); this._event(execution, 'completed');\n        }\n      } catch (error) { this._fail(execution, error); }\n    }\n    return Object.freeze({ updated, active, frameNowMs: frameNow });\n  }\n\n  getExecutionSnapshot(id) { const execution = this.executions.get(id); return execution ? publicSnapshot(execution) : null; }\n  getRuntimeSnapshot() {\n    return Object.freeze({ updateCount: this.updateCount, lastFrameNowMs: this.lastFrameNowMs, executions: Object.freeze([...this.executions.values()].map(publicSnapshot)), events: Object.freeze(this.events.map(clone)) });\n  }\n\n  dispose() {\n    if (this.disposed) return;\n    for (const execution of this.executions.values()) if (!isMotionTerminal(execution.state)) this.cancel(execution.id, 'RUNTIME_DISPOSED', execution.generation);\n    this.executions.clear(); this.targetRegistry.dispose(); this.disposed = true;\n  }\n\n  _active(id, expectedGeneration) {\n    const execution = this.executions.get(id);\n    if (!execution) throw new MotionRuntimeError('EXECUTION_NOT_FOUND');\n    if (expectedGeneration !== undefined && execution.generation !== expectedGeneration) throw new MotionRuntimeError('STALE_GENERATION');\n    if (isMotionTerminal(execution.state)) throw new MotionRuntimeError('EXECUTION_TERMINAL');\n    return execution;\n  }\n\n  _ensureCapacity() {\n    if (this.executions.size < MAX_EXECUTIONS) return;\n    for (const [id, execution] of this.executions) {\n      if (!isMotionTerminal(execution.state)) continue;\n      this.executions.delete(id);\n      if (this.executions.size < MAX_EXECUTIONS) return;\n    }\n    throw new MotionRuntimeError('EXECUTION_LIMIT_EXCEEDED');\n  }\n\n  _settle(execution, restore, reason) {\n    if (execution.settled) return;\n    execution.settled = true;\n    try {\n      if (restore) execution.handle.restore?.(reason);\n      else execution.handle.commit?.(reason);\n    } catch (error) {\n      throw new MotionRuntimeError('TARGET_SETTLE_FAILED', error?.message || 'Target settlement failed.');\n    }\n  }\n\n  _fail(execution, error) {\n    if (isMotionTerminal(execution.state)) return;\n    execution.clock.pause(); execution.state = transitionMotionState(execution.state, MOTION_EXECUTION_STATE.FAILED);\n    execution.error = error instanceof Error ? error : new MotionRuntimeError('TARGET_APPLY_FAILED', String(error)); execution.reason = execution.error.code || 'MOTION_RUNTIME_FAILED';\n    this._settle(execution, true, execution.reason); this._event(execution, 'failed', { code: execution.reason });\n  }\n\n  _emitCrossedEvents(execution, fromTime, toTime) {\n    if (toTime < (fromTime ?? -1)) return;\n    for (const event of execution.compiled.events || []) {\n      if (event.timeMs > toTime || event.timeMs <= (fromTime ?? -1)) continue;\n      this._event(execution, 'path-event', { pathEvent: event });\n    }\n  }\n\n  _event(execution, type, detail = {}) {\n    const event = Object.freeze({ executionId: execution.id, generation: execution.generation, type, timeMs: execution.clock.timeMs, ...clone(detail) });\n    this.events.push(event); if (this.events.length > MAX_EVENTS) this.events.shift(); this.onEvent?.(event);\n  }\n}\n","import * as THREE from 'three';\nimport { ellipsoidRadiusForLocalDir, latLonToLocalDir } from '../../../modules/geometry-utils.js';\n\nexport function sampleWorldPosition(sample, planetGroup, target = new THREE.Vector3()) {\n  if (sample?.position?.ecef) {\n    const ecef = sample.position.ecef;\n    // Runtime Earth-local axes are X=east at 90E, Y=north, Z=0E.\n    target.set(ecef.z, ecef.y, ecef.x);\n  } else {\n    latLonToLocalDir(sample.position.latitude, sample.position.longitude, target);\n    target.multiplyScalar(ellipsoidRadiusForLocalDir(target) + sample.position.altitudeM);\n  }\n  if (planetGroup?.localToWorld) {\n    planetGroup.updateWorldMatrix?.(true, false);\n    planetGroup.localToWorld(target);\n  }\n  return target;\n}\n\nexport function copyQuaternion(target, orientation) {\n  if (orientation?.mode !== 'quaternion' || !Array.isArray(orientation.value)) return false;\n  target.set(orientation.value[0], orientation.value[1], orientation.value[2], orientation.value[3]).normalize();\n  return true;\n}\n","import * as THREE from 'three';\nimport { MotionRuntimeError } from '../MotionExecutionState.js';\nimport { copyQuaternion, sampleWorldPosition } from './MotionTargetGeo.js';\n\nconst INPUT_EVENTS = ['pointerdown', 'wheel', 'touchstart', 'keydown'];\n\nexport class CameraMotionTarget {\n  constructor({ camera, surfaceController, planetGroup = null, inputTarget = null, isBlocked = null } = {}) {\n    this.kind = 'camera'; this.camera = camera; this.surfaceController = surfaceController; this.planetGroup = planetGroup;\n    this.inputTarget = inputTarget || globalThis.window || null; this.isBlocked = typeof isBlocked === 'function' ? isBlocked : () => false;\n    this.owner = null; this.world = new THREE.Vector3(); this.look = new THREE.Vector3(); this.quaternion = new THREE.Quaternion();\n  }\n\n  acquire(context) {\n    if (!this.camera || !this.surfaceController) throw new MotionRuntimeError('TARGET_NOT_READY');\n    if (this.owner || this.surfaceController._externalCameraOverride === true || this.isBlocked()) throw new MotionRuntimeError('CAMERA_OWNERSHIP_UNAVAILABLE');\n    const controls = this.surfaceController.controls;\n    const surface = this.surfaceController.surfaceState;\n    const original = {\n      position: this.camera.position.clone(), quaternion: this.camera.quaternion.clone(), up: this.camera.up.clone(),\n      near: this.camera.near, far: this.camera.far, mode: this.surfaceController.cameraMode, lodMode: this.surfaceController.lodMode,\n      controlsEnabled: controls?.enabled,\n      controlsTarget: controls?.target?.clone?.() || null,\n      surface: surface ? { up: surface.up?.clone?.(), yaw: surface.yaw, pitch: surface.pitch, roll: surface.roll } : null,\n      altitude: this.surfaceController.surfaceAltitudeMeters, terrainRadius: this.surfaceController._terrainRadius,\n    };\n    const overrideToken = this.surfaceController.acquireExternalCameraOverride?.({\n      owner: `motion:${context.executionId}:${context.generation}`,\n      onConflict: reason => context.cancel(reason),\n    });\n    if (!overrideToken) throw new MotionRuntimeError('CAMERA_OWNERSHIP_UNAVAILABLE');\n    const owner = { executionId: context.executionId, generation: context.generation, original, overrideToken, cancel: context.cancel, settled: false };\n    this.owner = owner; if (controls) controls.enabled = false;\n    owner.onInput = () => owner.cancel('USER_INPUT');\n    owner.inputTargets = [...new Set([this.inputTarget, globalThis.window].filter(Boolean))];\n    for (const target of owner.inputTargets) for (const type of INPUT_EVENTS) target.addEventListener?.(type, owner.onInput, { passive: true });\n    const settle = (restore) => {\n      if (owner.settled) return; owner.settled = true;\n      for (const target of owner.inputTargets) for (const type of INPUT_EVENTS) target.removeEventListener?.(type, owner.onInput);\n      if (restore) {\n        this.camera.position.copy(original.position); this.camera.quaternion.copy(original.quaternion); this.camera.up.copy(original.up);\n        this.camera.near = original.near; this.camera.far = original.far; this.camera.updateProjectionMatrix?.();\n        this.surfaceController.cameraMode = original.mode; this.surfaceController.lodMode = original.lodMode;\n        if (original.surface && surface) {\n          if (original.surface.up && surface.up?.copy) surface.up.copy(original.surface.up);\n          surface.yaw = original.surface.yaw; surface.pitch = original.surface.pitch; surface.roll = original.surface.roll;\n        }\n        this.surfaceController.surfaceAltitudeMeters = original.altitude; this.surfaceController._terrainRadius = original.terrainRadius;\n        if (original.controlsTarget && controls?.target?.copy) controls.target.copy(original.controlsTarget);\n      }\n      this.surfaceController.releaseExternalCameraOverride?.(owner.overrideToken);\n      if (controls) controls.enabled = restore ? original.controlsEnabled : this.surfaceController.cameraMode === 'orbit';\n      if (this.owner === owner) this.owner = null;\n    };\n    return {\n      apply: sample => this._apply(owner, context.compiled, sample),\n      restore: () => settle(true),\n      commit: () => settle(false),\n    };\n  }\n\n  _apply(owner, compiled, sample) {\n    if (this.owner !== owner || this.surfaceController._externalCameraOverrideOwner !== owner.overrideToken || this.isBlocked()) return { ok: false, code: 'CAMERA_OWNERSHIP_LOST' };\n    const reference = sample.position.altitudeReference;\n    if (reference === 'agl') {\n      const hpr = sample.orientation.mode === 'enu-hpr' ? sample.orientation : {};\n      const applied = this.surfaceController.applyExternalSurfacePose?.(owner.overrideToken, {\n        latitude: sample.position.latitude,\n        longitude: sample.position.longitude,\n        altitudeM: sample.position.altitudeM,\n        headingDeg: hpr.headingDeg,\n        pitchDeg: hpr.pitchDeg,\n        rollDeg: hpr.rollDeg,\n      });\n      if (!applied) return { ok: false, code: 'CAMERA_OWNERSHIP_LOST' };\n      if (sample.orientation.mode === 'quaternion') copyQuaternion(this.camera.quaternion, sample.orientation);\n      return { ok: true };\n    }\n    if (!sample.position.altitudeResolved) return { ok: false, code: 'ALTITUDE_UNRESOLVED' };\n    sampleWorldPosition(sample, this.planetGroup, this.world);\n    this.camera.parent?.updateWorldMatrix?.(true, false);\n    if (this.camera.parent?.worldToLocal) this.camera.parent.worldToLocal(this.world);\n    this.camera.position.copy(this.world);\n    if (!copyQuaternion(this.camera.quaternion, sample.orientation)) {\n      const segment = compiled.segments[sample.segmentIndex]; const next = compiled.waypoints[segment?.toIndex ?? sample.waypointIndex];\n      if (next) {\n        const nextSample = { position: { latitude: next.latitude, longitude: next.longitude, altitudeM: next.resolvedAltitude.heightM, ecef: compiled.definition.interpolation.position === 'straight-ecef' ? next.ecef : undefined } };\n        sampleWorldPosition(nextSample, this.planetGroup, this.look); this.camera.lookAt?.(this.look);\n      }\n    }\n    this.camera.updateMatrixWorld?.(); return { ok: true };\n  }\n}\n","import * as THREE from 'three';\nimport { MotionRuntimeError } from '../MotionExecutionState.js';\nimport { copyQuaternion, sampleWorldPosition } from './MotionTargetGeo.js';\n\nexport class LocalUserMotionTarget {\n  constructor({ localPlayer, planetGroup = null } = {}) { this.kind = 'local-user'; this.localPlayer = localPlayer; this.planetGroup = planetGroup; this.owner = null; this.world = new THREE.Vector3(); this.local = new THREE.Vector3(); this.quaternion = new THREE.Quaternion(); this.scale = new THREE.Vector3(1, 1, 1); }\n\n  acquire(context) {\n    const group = this.localPlayer?.avatar?.group || this.localPlayer?._avatarGroup;\n    if (!group) throw new MotionRuntimeError('TARGET_NOT_READY');\n    if (this.owner) throw new MotionRuntimeError('TARGET_BUSY');\n    const token = this.localPlayer.beginMotionVisualOverride?.({ executionId: context.executionId, generation: context.generation });\n    if (!token) throw new MotionRuntimeError('TARGET_BUSY');\n    const owner = { executionId: context.executionId, generation: context.generation, group, token, settled: false }; this.owner = owner;\n    const settle = restore => {\n      if (owner.settled) return; owner.settled = true;\n      this.localPlayer.endMotionVisualOverride?.(owner.token, { restore });\n      if (this.owner === owner) this.owner = null;\n    };\n    return { apply: sample => this._apply(owner, sample), restore: () => settle(true), commit: () => settle(false) };\n  }\n\n  _apply(owner, sample) {\n    if (this.owner !== owner || owner.group !== (this.localPlayer?.avatar?.group || this.localPlayer?._avatarGroup)) return { ok: false, code: 'TARGET_REPLACED' };\n    if (!sample.position.altitudeResolved) return { ok: false, code: 'ALTITUDE_UNRESOLVED' };\n    sampleWorldPosition(sample, this.planetGroup, this.world); this.local.copy(this.world);\n    owner.group.parent?.updateWorldMatrix?.(true, false); owner.group.parent?.worldToLocal?.(this.local);\n    this.quaternion.copy(owner.group.quaternion); copyQuaternion(this.quaternion, sample.orientation);\n    this.scale.copy(owner.group.scale);\n    if (Number.isFinite(sample.tracks['transform.scale'])) this.scale.setScalar(sample.tracks['transform.scale']);\n    const visible = typeof sample.tracks['appearance.visibility'] === 'boolean' ? sample.tracks['appearance.visibility'] : owner.group.visible;\n    return this.localPlayer.applyMotionVisualOverride?.(owner.token, { position: this.local, quaternion: this.quaternion, scale: this.scale, visible })\n      ? { ok: true }\n      : { ok: false, code: 'TARGET_GENERATION_STALE' };\n  }\n}\n","import { MotionRuntimeError } from '../MotionExecutionState.js';\n\nfunction previewPatch(original, sample) {\n  const current = structuredClone(original.current || {}); const properties = { ...(current.properties || {}) };\n  current.geom = { type: 'Point', coordinates: [sample.position.longitude, sample.position.latitude] };\n  if (sample.position.altitudeReference === 'agl') {\n    properties.height_reference = 'surface_agl'; properties.anchor_agl_m = sample.position.altitudeM;\n    properties.surface_anchor_policy ||= 'follow-surface';\n  } else if (sample.position.altitudeResolved) {\n    current.elevation_m = sample.position.altitudeM; properties.height_reference = 'ellipsoid'; properties.anchor_ellipsoid_m = sample.position.altitudeM;\n  } else throw new MotionRuntimeError('ALTITUDE_UNRESOLVED');\n  if (sample.orientation?.mode === 'quaternion') current.orientation_quat = [...sample.orientation.value];\n  const mapping = { 'transform.scale': 'model_scale', 'appearance.visibility': 'visible', 'appearance.opacity': 'opacity', 'material.color': 'color', 'material.emissiveIntensity': 'emissive_intensity', 'payload.status': 'status' };\n  for (const [track, property] of Object.entries(mapping)) if (sample.tracks[track] !== undefined) properties[property] = cloneValue(sample.tracks[track]);\n  current.properties = properties; return { ...structuredClone(original), current };\n}\n\nconst cloneValue = value => value == null ? value : structuredClone(value);\n\nexport class OverlayItemMotionTarget {\n  constructor({ overlaySubsystem } = {}) { this.kind = 'overlay-item'; this.overlaySubsystem = overlaySubsystem; }\n  acquire(context) {\n    const overlayId = String(context.targetContext?.overlayId || ''); const itemId = String(context.compiled.target.id || '');\n    if (!overlayId || !itemId) throw new MotionRuntimeError('TARGET_CONTEXT_REQUIRED');\n    const lease = this.overlaySubsystem?.beginMotionPreview?.({ overlayId, itemId, executionId: context.executionId, generation: context.generation });\n    if (!lease) throw new MotionRuntimeError('TARGET_NOT_LOADED');\n    return {\n      apply: sample => this.overlaySubsystem.updateMotionPreview(lease, previewPatch(lease.itemEntry.data, sample)) ? { ok: true } : { ok: false, code: 'TARGET_GENERATION_STALE' },\n      restore: () => this.overlaySubsystem.endMotionPreview(lease),\n      commit: () => this.overlaySubsystem.endMotionPreview(lease, { restore: false }),\n    };\n  }\n}\n","import { MotionRuntimeError } from '../MotionExecutionState.js';\n\nexport class PhysicalDeviceMotionTarget {\n  constructor() { this.kind = 'physical-device'; this.capability = Object.freeze({ enabled: false, reason: 'PHYSICAL_EXECUTION_DISABLED', requires: ['path-execution-grant', 'fenced-lease'] }); }\n  acquire() { throw new MotionRuntimeError('PHYSICAL_EXECUTION_DISABLED', 'Physical motion requires WO-068 authorization and a fenced lease.'); }\n}\n","import { MotionRuntimeError } from '../MotionExecutionState.js';\n\nexport class SimulatedDeviceMotionTarget {\n  constructor({ eventBus = null } = {}) { this.kind = 'simulated-device'; this.eventBus = eventBus; this.devices = new Map(); this.owners = new Map(); }\n  acquire(context) {\n    const id = String(context.compiled.target.id || ''); if (!id) throw new MotionRuntimeError('TARGET_ID_REQUIRED');\n    if (this.owners.has(id)) throw new MotionRuntimeError('TARGET_BUSY');\n    const previous = this.devices.has(id) ? structuredClone(this.devices.get(id)) : null;\n    const owner = { id, executionId: context.executionId, generation: context.generation, previous, settled: false }; this.owners.set(id, owner);\n    const settle = restore => {\n      if (owner.settled) return; owner.settled = true;\n      if (restore) { if (previous) this.devices.set(id, previous); else this.devices.delete(id); }\n      this.owners.delete(id);\n    };\n    return {\n      apply: (sample, frame) => {\n        if (this.owners.get(id) !== owner) return { ok: false, code: 'TARGET_GENERATION_STALE' };\n        const telemetry = Object.freeze({ id, executionId: owner.executionId, generation: owner.generation, frameNowMs: frame.frameNowMs, sample: structuredClone(sample), acknowledged: true });\n        this.devices.set(id, telemetry); this.eventBus?.emit?.('motion:simulated-device', telemetry); return { ok: true };\n      },\n      restore: () => settle(true), commit: () => settle(false),\n    };\n  }\n  getSnapshot(id) { const value = this.devices.get(String(id)); return value ? structuredClone(value) : null; }\n}\n","import { MotionRuntime } from './MotionRuntime.js';\nimport { CameraMotionTarget } from './targets/CameraMotionTarget.js';\nimport { LocalUserMotionTarget } from './targets/LocalUserMotionTarget.js';\nimport { OverlayItemMotionTarget } from './targets/OverlayItemMotionTarget.js';\nimport { PhysicalDeviceMotionTarget } from './targets/PhysicalDeviceMotionTarget.js';\nimport { SimulatedDeviceMotionTarget } from './targets/SimulatedDeviceMotionTarget.js';\n\nexport function createSceneMotionRuntime({ camera, surfaceController, planetGroup, localPlayer, overlaySubsystem, eventBus, inputTarget, isCameraBlocked } = {}) {\n  const runtime = new MotionRuntime({ onEvent: event => eventBus?.emit?.('motion:path-event', event) });\n  const simulated = new SimulatedDeviceMotionTarget({ eventBus });\n  runtime.registerTarget(new CameraMotionTarget({ camera, surfaceController, planetGroup, inputTarget, isBlocked: isCameraBlocked }));\n  runtime.registerTarget(new LocalUserMotionTarget({ localPlayer, planetGroup }));\n  runtime.registerTarget(new OverlayItemMotionTarget({ overlaySubsystem }));\n  runtime.registerTarget(simulated);\n  runtime.registerTarget(new PhysicalDeviceMotionTarget());\n  runtime.simulatedDevices = simulated;\n  return runtime;\n}\n","/**\n * HudSlots — single source of truth for batch-4 HUD panel visual\n * language and slot positioning.\n *\n * Visual language: every panel that opts into the system gets the\n * `.nca-hud-panel` class, which inherits the same surface, border,\n * radius, font, and z-index conventions used by `.nca-address-toast`.\n * That keeps the HUD coherent — basemap toggle, timeline scrubber,\n * marketplace panel, photogrammetry uploader, creator studio, etc. all\n * read as one family with the address toast.\n *\n * Slot positioning: the document root publishes a small set of CSS\n * variables that anchored panels read instead of hard-coding pixel\n * offsets. Panels that need to live \"courteous of the address toast\"\n * subtract from `--nc-hud-bottom-offset`; panels that respect the left\n * sidebar's width subtract from `--nc-hud-left-offset`. When the\n * sidebar opens or the address toast becomes visible, this module\n * updates the vars and every dependent panel reflows automatically.\n *\n * Default-on registry: an explicit list of panels mounted by\n * PlanetScene on init (basemap picker, timeline, AR HUD). Everything\n * else is on-demand and surfaced through agent intents or the HUD\n * Builder widget catalog.\n */\n\nconst STYLE_ID = 'nca-hud-panel-styles';\nconst ROOT = (typeof document !== 'undefined') ? document : null;\n\n/**\n * Inject the shared `.nca-hud-panel` stylesheet. Idempotent — safe to\n * call from any panel constructor; only the first invocation actually\n * touches the DOM.\n */\nexport function ensureHudPanelStyles() {\n  if (!ROOT) return;\n  if (ROOT.getElementById(STYLE_ID)) return;\n  const style = ROOT.createElement('style');\n  style.id = STYLE_ID;\n  style.textContent = `\n    :root {\n      /* Bottom-anchored panels stack above the address-toast (which\n         sits at bottom: 20px and is ~80px tall when expanded). HUD\n         consumers add their own offset on top of this. */\n      --nc-hud-bottom-offset: 12px;\n      --nc-hud-bottom-clearance: 110px;     /* address-toast envelope */\n      /* Side-anchored panels respect the primary left sidebar's width\n         so they never disappear under it. Falls through to 0 if the\n         sidebar isn't mounted. */\n      --nc-hud-left-offset: var(--nca-sidebar-width, 0px);\n      --nc-hud-right-offset: 0px;\n      --nc-hud-top-offset: 12px;\n      --nc-hud-edge-gap: 12px;\n      --nc-hud-pill-size: 32px;\n      --nc-hud-pill-stack-gap: 8px;\n      --nc-hud-pill-radius: 3px;\n      --nc-hud-glass-bg: rgba(5, 9, 14, 0.7);\n      --nc-hud-glass-border: rgba(255, 255, 255, 0.18);\n      --nc-hud-glass-filter: blur(18px) brightness(0.82);\n      --nc-hud-glass-shadow: 0 10px 32px rgba(0, 0, 0, 0.3);\n      --nc-hud-z: 1500;          /* above scene, below address-toast (z:2000) */\n      --nc-hud-z-stack: 1600;    /* for stacked dropdowns / pickers */\n    }\n\n    /* Compact HUD pill — used for small trigger buttons (sidebar\n       arrow, ARHud, minimap-expand, future chat toggle, etc.) so the\n       row of corner-anchored controls reads as one family. Square or\n       icon+label, fixed height, accent-on-hover. */\n    .nca-hud-pill {\n      position: fixed;\n      z-index: var(--nc-hud-z);\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      gap: 6px;\n      height: var(--nc-hud-pill-size);\n      min-width: var(--nc-hud-pill-size);\n      padding: 0 10px;\n      background: transparent;\n      border: 1px solid rgba(255, 255, 255, 0.10);\n      border-radius: var(--nc-hud-pill-radius) !important;\n      color: #fff;\n      font: 11px var(--nca-font-mono, 'IBM Plex Mono', monospace);\n      letter-spacing: 0.04em;\n      cursor: pointer;\n      backdrop-filter: blur(12px) brightness(0.7);\n      -webkit-backdrop-filter: blur(12px) brightness(0.7);\n      transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;\n      box-sizing: border-box;\n    }\n    .nca-hud-pill:hover {\n      background: rgba(255, 255, 255, 0.10);\n      border-color: rgba(255, 255, 255, 0.40);\n      color: var(--nca-accent, #ffffff);\n    }\n    .nca-hud-pill.is-active {\n      background: rgba(255, 255, 255, 0.18);\n      border-color: rgba(255, 255, 255, 0.55);\n      color: var(--nca-accent, #ffffff);\n    }\n    .nca-hud-pill svg { width: 14px; height: 14px; flex-shrink: 0; }\n    .nca-hud-pill.nca-hud-pill--square { width: var(--nc-hud-pill-size); padding: 0; }\n\n    /* The exit button is only visible during a target noclip session. It\n       lives at the left end of the shared corner action row, independent of the\n       bottom-right agent panel, so an open chat can never cover the way home. */\n    .nca-noclip-exit.is-noclip-active {\n      color: #ffb36b;\n      border-color: rgba(255, 179, 107, 0.72);\n      background: rgba(255, 125, 40, 0.14);\n      animation: nca-noclip-exit-pulse 1.15s steps(2, end) infinite;\n    }\n    @keyframes nca-noclip-exit-pulse {\n      50% {\n        color: #fff2df;\n        border-color: rgba(255, 225, 190, 0.98);\n        background: rgba(255, 155, 75, 0.30);\n      }\n    }\n    @media (prefers-reduced-motion: reduce) {\n      .nca-noclip-exit.is-noclip-active { animation: none; }\n    }\n\n    /* Desktop top HUD row. The row ends before the top-right pill\n       column, so the global search and promoted sidebar header share\n       one line without covering the minimap/AR stack. */\n    .nca-hud-top-row {\n      position: fixed;\n      top: 12px;\n      --nca-hud-safe-left: max(var(--nc-hud-left-offset, 0px), var(--nca-sidebar-rail-width, 56px));\n      left: calc(var(--nca-hud-safe-left) + 12px);\n      right: calc(var(--nc-hud-right-offset, 0px) + 52px);\n      z-index: var(--nc-hud-z);\n      display: flex;\n      align-items: flex-start;\n      gap: 8px;\n      min-width: 0;\n      pointer-events: none;\n      box-sizing: border-box;\n      --nca-hud-top-row-height: 32px;\n      --nca-hud-top-row-radius: 3px;\n      --nca-hud-top-row-border: 1px solid rgba(255, 255, 255, 0.10);\n      --nca-hud-top-row-bg: transparent;\n      --nca-search-surface-radius: var(--nca-hud-top-row-radius);\n      --nca-search-surface-bg: var(--nclp-bg-main, rgba(0, 0, 0, 0.88));\n      --nca-search-surface-border: var(--nclp-line, rgba(255, 255, 255, 0.10));\n      --nca-search-surface-shadow: none;\n      --nca-search-surface-filter: blur(12px) brightness(0.7);\n      --nca-search-drawer-gap: 8px;\n    }\n    .nca-hud-top-row > .nca-hud-panel,\n    .nca-hud-top-row > .nca-hud-pill,\n    .nca-hud-top-row > .hud-search {\n      pointer-events: auto;\n    }\n    .nca-hud-top-row > .nca-sidebar-header.nca-hud-panel {\n      position: relative;\n      top: auto !important;\n      left: auto !important;\n      right: auto !important;\n      flex: 0 1 var(--nca-location-header-width, max-content);\n      min-width: 0;\n      width: var(--nca-location-header-width, max-content);\n      max-width: min(660px, 62vw);\n      height: var(--nca-hud-top-row-height);\n      min-height: var(--nca-hud-top-row-height);\n      padding: 0 12px;\n      /* nclp-dashboard.css applies border/border-radius with !important via a\n         broad :is(.nc-panel, ..., .nca-hud-panel, [class$=\"-panel\"]) rule, which\n         beats any specificity. Matching !important here is the only way this\n         panel keeps the HUD top-row geometry. */\n      border: 0 !important;\n      border-radius: var(--nca-hud-top-row-radius) !important;\n      overflow: clip;\n      background: var(--nca-hud-top-row-bg);\n      align-items: center;\n      gap: 9px;\n      line-height: 1;\n      box-sizing: border-box;\n    }\n    .nca-hud-top-row > .nca-sidebar-header.nca-hud-panel .nca-sidebar-region {\n      min-width: 0;\n      overflow: hidden;\n      text-overflow: ellipsis;\n      white-space: nowrap;\n    }\n    .nca-hud-top-row .nca-sidebar-brand {\n      flex: 0 0 auto;\n      color: rgba(255, 255, 255, 0.96);\n      font: 700 10px var(--nca-font-mono, 'IBM Plex Mono', monospace);\n      letter-spacing: 0.18em;\n    }\n    .nca-hud-top-row .nca-sidebar-region {\n      flex: 1 1 220px;\n      max-width: 300px;\n      color: rgba(255, 255, 255, 0.92);\n      font: 600 10px var(--nca-font-mono, 'IBM Plex Mono', monospace);\n      letter-spacing: 0.035em;\n    }\n    .nca-hud-top-row .nca-sidebar-metrics {\n      flex: 0 0 auto;\n      width: auto;\n      margin: 0;\n      justify-content: flex-start;\n      gap: 9px;\n      overflow: visible;\n    }\n    .nca-hud-top-row .nca-metric-local-time,\n    .nca-hud-top-row .nca-metric-heading,\n    .nca-hud-top-row .nca-metric-latlon {\n      flex: 0 0 auto;\n      color: rgba(255, 255, 255, 0.64);\n      font-size: 9px;\n      letter-spacing: 0.04em;\n    }\n    .nca-hud-top-row .nca-metric-local-time::before,\n    .nca-hud-top-row .nca-metric-heading::before,\n    .nca-hud-top-row .nca-metric-latlon::before {\n      content: '';\n      display: inline-block;\n      width: 1px;\n      height: 11px;\n      margin-right: 9px;\n      vertical-align: -2px;\n      background: rgba(255, 255, 255, 0.18);\n    }\n    .nca-hud-top-row .nca-metric-heading {\n      display: inline-flex;\n      align-items: center;\n      gap: 4px;\n      white-space: nowrap;\n      color: rgba(255, 255, 255, 0.72);\n    }\n    .nca-hud-top-row .nca-metric-heading.is-unavailable {\n      color: rgba(255, 255, 255, 0.38);\n    }\n    .nca-metric-heading-value {\n      display: inline-block;\n      width: 3.5ch;\n      text-align: right;\n      font-variant-numeric: tabular-nums;\n    }\n    .nca-heading-north-indicator {\n      position: relative;\n      display: inline-block;\n      width: 13px;\n      height: 13px;\n      flex: 0 0 13px;\n      border: 1px solid rgba(255, 255, 255, 0.38);\n      border-radius: 50%;\n      box-sizing: border-box;\n    }\n    .nca-heading-north-arm {\n      position: absolute;\n      inset: 0;\n      transform: rotate(var(--nca-north-rotation, 0deg));\n      transform-origin: 50% 50%;\n      transition: transform 80ms linear;\n    }\n    .nca-heading-north-line {\n      position: absolute;\n      top: 1px;\n      left: 5px;\n      width: 1px;\n      height: 5px;\n      border-radius: 1px;\n      background: currentColor;\n      box-shadow: 0 0 3px rgba(255, 255, 255, 0.45);\n    }\n    .nca-heading-north-hub {\n      position: absolute;\n      top: 5px;\n      left: 5px;\n      width: 1px;\n      height: 1px;\n      border-radius: 50%;\n      background: currentColor;\n    }\n    @media (prefers-reduced-motion: reduce) {\n      .nca-heading-north-arm { transition: none; }\n    }\n    .nca-hud-top-row > .hud-search {\n      position: relative !important;\n      top: auto !important;\n      left: auto !important;\n      right: auto !important;\n      width: auto !important;\n      max-width: 100%;\n      transform: none !important;\n      flex: 1 2 340px;\n      min-width: 210px;\n      z-index: auto !important;\n      box-sizing: border-box;\n    }\n    body.hud-nav-active .nca-hud-top-row > .nca-sidebar-header.nca-hud-panel {\n      flex-basis: var(--nca-location-header-width, max-content);\n      max-width: min(560px, 54vw);\n    }\n    body.hud-nav-active .nca-hud-top-row > .hud-search {\n      flex: 1 1 min(420px, 100%);\n      min-width: 0;\n      max-width: 100%;\n    }\n    @media (max-width: 1180px) {\n      body:not(.is-mobile) .nca-hud-top-row .nca-sidebar-brand {\n        display: none;\n      }\n      body:not(.is-mobile) .nca-hud-top-row > .nca-sidebar-header.nca-hud-panel {\n        max-width: min(560px, 58vw);\n      }\n    }\n    .nca-hud-top-row .hud-search-row {\n      width: 100%;\n      max-width: 100%;\n      height: var(--nca-hud-top-row-height);\n      align-items: center;\n      min-width: 0;\n      flex-wrap: nowrap;\n    }\n    .nca-hud-top-row .hud-search-inner,\n    .nca-hud-top-row .hud-search-home {\n      height: var(--nca-hud-top-row-height);\n      min-height: var(--nca-hud-top-row-height);\n      border: var(--nca-hud-top-row-border);\n      border-radius: var(--nca-hud-top-row-radius);\n      background: var(--nca-hud-top-row-bg);\n      box-sizing: border-box;\n      backdrop-filter: blur(12px) brightness(0.7);\n      -webkit-backdrop-filter: blur(12px) brightness(0.7);\n    }\n    .nca-hud-top-row .hud-search-inner {\n      flex: 1 1 0;\n      min-width: 0;\n      padding: 0 12px;\n    }\n    .nca-hud-top-row .hud-search-home {\n      flex: 0 0 var(--nca-hud-top-row-height);\n      width: var(--nca-hud-top-row-height);\n      padding: 0;\n    }\n    .nca-hud-top-row .hud-search-input {\n      min-width: 0;\n    }\n    body.hud-nav-active .nca-hud-top-row .hud-search-modes[data-active=\"true\"] {\n      flex: 0 1 calc((var(--nca-hud-top-row-height) * 4) + 12px);\n      width: min(100%, calc((var(--nca-hud-top-row-height) * 4) + 12px));\n      max-width: min(100%, calc((var(--nca-hud-top-row-height) * 4) + 12px));\n      min-width: 0;\n      margin-left: 0;\n      box-sizing: border-box;\n    }\n\n    /* Same visual base as .nca-address-toast — transparent w/ glass\n       blur, subtle border, monospace, accent-friendly text. */\n    .nca-hud-panel {\n      position: fixed;\n      background: transparent;\n      border: 1px solid rgba(255, 255, 255, 0.1);\n      border-radius: 10px;\n      padding: 10px 14px;\n      color: #fff;\n      font-family: var(--nca-font-mono, 'IBM Plex Mono', monospace);\n      font-size: 12px;\n      line-height: 1.45;\n      backdrop-filter: blur(12px) brightness(0.7);\n      -webkit-backdrop-filter: blur(12px) brightness(0.7);\n      z-index: var(--nc-hud-z);\n      pointer-events: auto;\n      max-width: 360px;\n      box-sizing: border-box;\n    }\n    .nca-hud-panel.is-collapsed > :not(.nca-hud-header) { display: none; }\n    .nca-hud-panel .nca-hud-header {\n      display: flex;\n      align-items: center;\n      justify-content: space-between;\n      gap: 8px;\n      cursor: pointer;\n      user-select: none;\n      color: var(--nca-accent, #ffffff);\n      font-weight: 600;\n      letter-spacing: 0.02em;\n      text-transform: uppercase;\n      font-size: 11px;\n    }\n    .nca-hud-panel .nca-hud-body {\n      display: flex;\n      flex-direction: column;\n      gap: 6px;\n      margin-top: 8px;\n    }\n    .nca-hud-panel button,\n    .nca-hud-panel .nca-hud-btn {\n      background: rgba(255,255,255,0.06);\n      color: var(--nca-accent, #ffffff);\n      border: 1px solid rgba(255, 255, 255,0.28);\n      border-radius: 4px;\n      padding: 4px 8px;\n      font: inherit;\n      font-size: 11px;\n      cursor: pointer;\n      transition: background 0.12s ease, border-color 0.12s ease;\n    }\n    .nca-hud-panel button:hover,\n    .nca-hud-panel .nca-hud-btn:hover {\n      background: rgba(255, 255, 255,0.14);\n      border-color: rgba(255, 255, 255,0.55);\n    }\n    .nca-hud-panel input,\n    .nca-hud-panel textarea {\n      width:100%;\n      background: rgba(0,0,0,0.4);\n      color: #fff;\n      border: 1px solid rgba(255,255,255,0.12);\n      border-radius: 4px;\n      padding: 4px 6px;\n      font: inherit;\n      font-family: var(--nca-font-mono, monospace);\n      font-size: 11px;\n    }\n\n    /* Slot positioning. Each slot is a positional contract — panels\n       composed with these classes share a screen region and stack\n       cleanly. */\n    .nca-hud-panel--bottom-center {\n      bottom: calc(var(--nc-hud-bottom-offset) + var(--nc-hud-bottom-clearance));\n      left: 50%;\n      transform: translateX(-50%);\n    }\n    .nca-hud-panel--bottom-left {\n      bottom: calc(var(--nc-hud-bottom-offset) + var(--nc-hud-bottom-clearance));\n      left: calc(var(--nc-hud-left-offset) + 12px);\n    }\n    .nca-hud-panel--bottom-right {\n      bottom: calc(var(--nc-hud-bottom-offset) + var(--nc-hud-bottom-clearance));\n      right: calc(var(--nc-hud-right-offset) + 12px);\n    }\n    .nca-hud-panel--top-left {\n      top: var(--nc-hud-top-offset);\n      left: calc(var(--nc-hud-left-offset) + 12px);\n    }\n    .nca-hud-panel--top-right {\n      top: var(--nc-hud-top-offset);\n      right: calc(var(--nc-hud-right-offset) + var(--nc-hud-edge-gap));\n    }\n    .nca-hud-panel--mid-left {\n      top: 50%;\n      left: calc(var(--nc-hud-left-offset) + 12px);\n      transform: translateY(-50%);\n    }\n    .nca-hud-panel--mid-right {\n      top: 50%;\n      right: calc(var(--nc-hud-right-offset) + 12px);\n      transform: translateY(-50%);\n    }\n\n    /* Embedded variant — used when a panel that normally floats (top-\n       left basemap picker, bottom-center timeline, etc.) is rendered\n       inside a host container (HUD dock panel, LeftSidebar detail\n       content, HUD builder widget). Drops fixed positioning, drops\n       the backdrop blur, lets the host control width and chrome. */\n    .nca-hud-panel--embedded {\n      position: static;\n      max-width: none;\n      width: 100%;\n      background: transparent;\n      border: 0;\n      border-radius: 0;\n      backdrop-filter: none;\n      -webkit-backdrop-filter: none;\n      padding: 8px 10px;\n      box-shadow: none;\n    }\n    .nca-hud-panel--embedded .nca-hud-header {\n      cursor: default;\n    }\n    .nca-hud-panel--embedded.is-collapsed > :not(.nca-hud-header) {\n      display: revert;\n    }\n  `;\n  ROOT.head.appendChild(style);\n}\n\n/**\n * Static manifest of which batch-4 panels are mounted by default on\n * scene init (vs on-demand via agent intents). Read by PlanetScene to\n * decide whether to invoke the panel's getter eagerly.\n */\nexport const HUD_PANELS_DEFAULT_ON = Object.freeze([\n  'BasemapPicker',     // map style toggle — top-left\n  'TimelinePanel',     // sun-clock scrubber — bottom-center\n  'ARHud',             // AR entry button — top-right (mobile)\n]);\n\nexport const HUD_PANELS_ON_DEMAND = Object.freeze([\n  'DrawToolbar',\n  'MeasurementReadout',\n  'FloorSwitcher',\n  'StyleEditorLauncher',\n  'MarketplacePanel',\n  'SunStudyPanel',\n  'StacBrowserPanel',\n  'PhotogrammetryPanel',\n  'CreatorStudio',\n  'StorefrontPanel',\n]);\n\n/**\n * Notify HudSlots that the address toast just changed visibility.\n * Updates `--nc-hud-bottom-clearance` so bottom-anchored panels lift\n * out of the way (or settle back in when the toast hides).\n */\nexport function setAddressToastVisible(visible) {\n  if (!ROOT?.documentElement) return;\n  ROOT.documentElement.style.setProperty(\n    '--nc-hud-bottom-clearance',\n    visible ? '110px' : '20px'\n  );\n}\n\n/**\n * Update the left-sidebar width var. Called when the primary sidebar\n * opens, closes, or resizes so left-anchored panels stay courteous.\n */\nexport function setLeftSidebarWidth(px) {\n  if (!ROOT?.documentElement) return;\n  const v = (Number.isFinite(px) && px > 0) ? `${Math.round(px)}px` : '0px';\n  ROOT.documentElement.style.setProperty('--nc-hud-left-offset', v);\n}\n","/**\n * TimelinePanel — collapsible scene-clock control bound to SceneClock.\n *\n * The panel no longer pins itself to the bottom-center of the screen\n * by default. It builds the same `.nca-hud-panel` body element it\n * always has, but leaves mounting to the host (HUD dock on phones,\n * LeftSidebar on desktop). The body stays open while the host shows\n * the panel, so the slider/buttons are always reachable.\n *\n * Backwards-compatible options:\n *   - mode: 'embedded' (default) — no slot class, no auto-mount, no\n *     collapse chrome; the body is always visible.\n *   - mode: 'floating' — legacy behavior (`nca-hud-panel--bottom-center`,\n *     auto-append to container, collapse toggle visible).\n */\nimport { getSceneClock } from '../scene/SceneClock.js';\nimport { ensureHudPanelStyles } from './HudSlots.js';\n\nconst SPEEDS = [1, 4, 30, 60, 600];\nconst HOUR_MS = 60 * 60 * 1000;\nconst RANGE_MIN_MS = -30 * 24 * HOUR_MS;\nconst RANGE_MAX_MS = 30 * 24 * HOUR_MS;\n\nfunction injectTimelineStyles() {\n  if (document.getElementById('nca-structured-timeline-styles')) return;\n  const style = document.createElement('style');\n  style.id = 'nca-structured-timeline-styles';\n  style.textContent = `\n    .nc-timeline.nc-timeline--structured .nc-timeline-body {\n      display: grid;\n      gap: 11px;\n      min-width: min(360px, 100%);\n      width: 100%;\n      box-sizing: border-box;\n    }\n    .nc-timeline.nc-timeline--structured .nc-timeline-row {\n      width: 100%;\n      box-sizing: border-box;\n    }\n    .nc-timeline-summary {\n      display: grid !important;\n      grid-template-columns: 40px minmax(0, 1fr) 52px;\n      align-items: center;\n      gap: 8px;\n    }\n    .nc-timeline-current {\n      min-width: 0;\n      display: grid;\n      gap: 3px;\n    }\n    .nc-timeline-readout {\n      min-width: 0;\n      overflow: hidden;\n      text-overflow: ellipsis;\n      white-space: nowrap;\n      font: 600 11px/1.2 var(--nca-font-mono, monospace);\n    }\n    .nc-timeline-mode {\n      width: max-content;\n      max-width: 100%;\n      padding: 0 !important;\n      background: transparent !important;\n      font: 650 9px/1.2 var(--nca-font-mono, monospace);\n      letter-spacing: .06em;\n      text-transform: uppercase;\n    }\n    .nc-timeline-btn,\n    .nc-timeline-speed {\n      min-height: 36px;\n      border-radius: 0 !important;\n    }\n    .nc-timeline-play {\n      width: 40px;\n      padding: 0 !important;\n      font-size: 14px;\n    }\n    .nc-timeline-now {\n      width: 52px;\n      padding: 0 7px !important;\n      font-size: 9px;\n      font-weight: 650;\n      letter-spacing: .05em;\n      text-transform: uppercase;\n    }\n    .nc-timeline-now[aria-pressed=\"true\"],\n    .nc-timeline-speed[aria-pressed=\"true\"] {\n      border-color: var(--nca-accent, #ffae00) !important;\n      box-shadow: inset 2px 0 0 var(--nca-accent, #ffae00);\n      color: #fff !important;\n      background: rgba(255,255,255,.08) !important;\n    }\n    .nc-timeline-controls {\n      display: grid !important;\n      grid-template-columns: 48px minmax(0,1fr) 48px;\n      gap: 7px !important;\n    }\n    .nc-timeline-step {\n      width: 48px;\n      padding: 0 !important;\n      font-size: 9px;\n      font-weight: 650;\n    }\n    .nc-timeline-scrub {\n      width: 100%;\n      min-width: 0;\n      min-height: 36px;\n      margin: 0;\n      accent-color: var(--nca-accent, #ffae00);\n      cursor: pointer;\n    }\n    .nc-timeline-range-labels {\n      display: grid;\n      grid-template-columns: 1fr 1fr 1fr;\n      margin-top: -8px;\n      color: rgba(255,255,255,.4);\n      font: 600 8px/1 var(--nca-font-mono, monospace);\n      letter-spacing: .04em;\n    }\n    .nc-timeline-range-labels span:nth-child(2) { text-align: center; }\n    .nc-timeline-range-labels span:last-child { text-align: right; }\n    .nc-timeline-speed-field {\n      min-width: 0;\n      margin: 0;\n      padding: 0;\n      border: 0;\n    }\n    .nc-timeline-speed-field legend {\n      margin: 0 0 6px;\n      padding: 0;\n      color: rgba(255,255,255,.44);\n      font: 650 8px/1 var(--nca-font-mono, monospace);\n      letter-spacing: .09em;\n      text-transform: uppercase;\n    }\n    .nc-timeline-speeds {\n      display: grid !important;\n      grid-template-columns: repeat(5, minmax(0, 1fr));\n      gap: 5px !important;\n    }\n    .nc-timeline-speed {\n      min-width: 0;\n      padding: 0 3px !important;\n    }\n    .nc-timeline button:focus-visible,\n    .nc-timeline input:focus-visible {\n      outline: 2px solid var(--nca-accent, #ffae00);\n      outline-offset: 2px;\n    }\n    body.is-mobile .nca-mobile-sheet .nc-timeline-btn,\n    body.is-mobile .nca-mobile-sheet .nc-timeline-speed,\n    body.is-mobile .nca-mobile-sheet .nc-timeline-scrub {\n      min-height: 44px;\n    }\n    body.is-mobile .nca-mobile-sheet .nc-timeline-summary {\n      grid-template-columns: 44px minmax(0,1fr) 56px;\n    }\n    body.is-mobile .nca-mobile-sheet .nc-timeline-play { width: 44px; }\n    body.is-mobile .nca-mobile-sheet .nc-timeline-now { width: 56px; }\n    body.is-mobile .nca-mobile-sheet .nc-timeline-controls {\n      grid-template-columns: 48px minmax(0,1fr) 48px;\n    }\n    @media (max-width: 350px) {\n      .nc-timeline-speeds { grid-template-columns: repeat(3, minmax(0,1fr)) !important; }\n    }\n  `;\n  document.head.appendChild(style);\n}\n\nlet _instance = null;\nexport function getTimelinePanel(opts) {\n  if (!_instance) _instance = new TimelinePanel(opts);\n  return _instance;\n}\n\nexport class TimelinePanel {\n  constructor({ container, mode = 'embedded' } = {}) {\n    this.mode = mode === 'floating' ? 'floating' : 'embedded';\n    this.container = container || (this.mode === 'floating' ? document.body : null);\n    this.clock = getSceneClock();\n    this._el = null;\n    this._lastTickRenderAt = 0;\n    this._unsubscribeClock = null;\n    this._build();\n    this._bind();\n    this._subscribeClock();\n    this._render();\n  }\n\n  /**\n   * Returns the panel root element so a host (dock panel, sidebar\n   * detail content, HUD builder widget) can mount it. Idempotent.\n   */\n  get element() {\n    return this._el;\n  }\n\n  /**\n   * Mount (or re-parent) the panel into a host container. Use this\n   * from dock/sidebar render callbacks instead of cloning DOM.\n   */\n  mount(container) {\n    if (!container || !this._el) return;\n    if (this._el.parentNode === container) return;\n    container.appendChild(this._el);\n    this._render();\n  }\n\n  _build() {\n    ensureHudPanelStyles();\n    injectTimelineStyles();\n    const el = document.createElement('div');\n    if (this.mode === 'floating') {\n      el.className = 'nc-timeline nc-timeline--structured nca-hud-panel nca-hud-panel--bottom-center is-collapsed';\n    } else {\n      el.className = 'nc-timeline nc-timeline--structured nca-hud-panel nca-hud-panel--embedded';\n    }\n    el.innerHTML = `\n      <div class=\"nca-hud-header\" role=\"button\" tabindex=\"0\">\n        <span>Timeline</span>\n        <button class=\"nc-timeline-toggle\" type=\"button\" title=\"Timeline\" aria-label=\"Toggle timeline\">⏱</button>\n      </div>\n      <div class=\"nca-hud-body nc-timeline-body\">\n        <div class=\"nc-timeline-row nc-timeline-summary\">\n          <button class=\"nc-timeline-btn nc-timeline-play\" type=\"button\" title=\"Play or pause\" aria-label=\"Play scene timeline\">▶</button>\n          <div class=\"nc-timeline-current\" aria-live=\"polite\">\n            <time class=\"nc-timeline-readout\"></time>\n            <span class=\"nc-timeline-mode\"></span>\n          </div>\n          <button class=\"nc-timeline-btn nc-timeline-now\" type=\"button\" title=\"Return to live time\" aria-label=\"Return to live time\">Now</button>\n        </div>\n        <div class=\"nc-timeline-row nc-timeline-controls\">\n          <button class=\"nc-timeline-btn nc-timeline-step nc-timeline-step-back\" type=\"button\" aria-label=\"Move scene time back one hour\">−1h</button>\n          <input class=\"nc-timeline-scrub\" type=\"range\" min=\"${RANGE_MIN_MS}\" max=\"${RANGE_MAX_MS}\" step=\"60000\" value=\"0\" aria-label=\"Scene time, from 30 days ago to 30 days ahead\" />\n          <button class=\"nc-timeline-btn nc-timeline-step nc-timeline-step-forward\" type=\"button\" aria-label=\"Move scene time forward one hour\">+1h</button>\n        </div>\n        <div class=\"nc-timeline-range-labels\" aria-hidden=\"true\">\n          <span>−30 days</span><span>Now</span><span>+30 days</span>\n        </div>\n        <fieldset class=\"nc-timeline-speed-field\">\n          <legend>Playback speed</legend>\n          <div class=\"nc-timeline-row nc-timeline-speeds\">\n            ${SPEEDS.map((s) => `<button class=\"nc-timeline-speed\" data-speed=\"${s}\" type=\"button\" aria-label=\"Play at ${s} times speed\">${s}×</button>`).join('')}\n          </div>\n        </fieldset>\n      </div>\n    `;\n    if (this.mode === 'floating' && this.container) {\n      this.container.appendChild(el);\n    }\n    this._el = el;\n    this._toggle = el.querySelector('.nc-timeline-toggle');\n    this._playBtn = el.querySelector('.nc-timeline-play');\n    this._nowBtn = el.querySelector('.nc-timeline-now');\n    this._readout = el.querySelector('.nc-timeline-readout');\n    this._modeBadge = el.querySelector('.nc-timeline-mode');\n    this._scrub = el.querySelector('.nc-timeline-scrub');\n    this._stepBackBtn = el.querySelector('.nc-timeline-step-back');\n    this._stepForwardBtn = el.querySelector('.nc-timeline-step-forward');\n    this._speedBtns = el.querySelectorAll('.nc-timeline-speed');\n  }\n\n  _bind() {\n    if (this.mode === 'floating') {\n      const toggle = () => this._el.classList.toggle('is-collapsed');\n      this._toggle.addEventListener('click', (e) => { e.stopPropagation(); toggle(); });\n      this._el.querySelector('.nca-hud-header')?.addEventListener('click', toggle);\n    } else {\n      // Host (dock back button / sidebar close) handles open/close.\n      if (this._toggle) this._toggle.style.display = 'none';\n    }\n    this._playBtn.addEventListener('click', () => {\n      if (this.clock.getMode() === 'play') this.clock.pause();\n      else this.clock.play();\n      this._render();\n    });\n    this._nowBtn.addEventListener('click', () => {\n      this.clock.setMode('live');\n      this._render();\n    });\n    this._stepBackBtn.addEventListener('click', () => {\n      this.clock.setTime(this.clock.getTime() - HOUR_MS);\n      this._render();\n    });\n    this._stepForwardBtn.addEventListener('click', () => {\n      this.clock.setTime(this.clock.getTime() + HOUR_MS);\n      this._render();\n    });\n    this._scrub.addEventListener('input', () => {\n      const offsetMs = Number(this._scrub.value);\n      this.clock.setTime(Date.now() + offsetMs);\n      this._render();\n    });\n    this._speedBtns.forEach((btn) => {\n      btn.addEventListener('click', () => {\n        const s = Number(btn.dataset.speed);\n        if (!Number.isFinite(s)) return;\n        this.clock.setSpeed(s);\n        this._render();\n      });\n    });\n  }\n\n  _subscribeClock() {\n    this._unsubscribeClock = this.clock.subscribe((event) => {\n      if (event.type === 'clock:tick') {\n        if (!this._el?.isConnected) return;\n        const now = performance.now();\n        if (now - this._lastTickRenderAt < 250) return;\n        this._lastTickRenderAt = now;\n      }\n      this._render();\n    });\n  }\n\n  _render() {\n    if (!this._readout) return;\n    const t = this.clock.getTime();\n    const mode = this.clock.getMode();\n    const date = new Date(t);\n    const iso = date.toISOString();\n    this._readout.textContent = iso.slice(0, 19).replace('T', ' ') + ' UTC';\n    this._readout.dateTime = iso;\n    this._modeBadge.textContent = mode === 'live'\n      ? '● Live scene'\n      : mode === 'play'\n        ? `▶ Playing · ${this.clock.getSpeed()}×`\n        : '■ Fixed scene time';\n    this._modeBadge.dataset.mode = mode;\n    this._playBtn.textContent = mode === 'play' ? '⏸' : '▶';\n    this._playBtn.setAttribute('aria-label', mode === 'play' ? 'Pause scene timeline' : 'Play scene timeline');\n    this._playBtn.setAttribute('aria-pressed', mode === 'play' ? 'true' : 'false');\n    this._nowBtn.setAttribute('aria-pressed', mode === 'live' ? 'true' : 'false');\n    const offsetMs = Math.max(RANGE_MIN_MS, Math.min(RANGE_MAX_MS, t - Date.now()));\n    if (document.activeElement !== this._scrub) {\n      this._scrub.value = String(Math.round(offsetMs / 60000) * 60000);\n    }\n    this._scrub.setAttribute('aria-valuetext', `${this._readout.textContent}, ${this._modeBadge.textContent}`);\n    const speed = this.clock.getSpeed();\n    this._speedBtns.forEach((button) => {\n      button.setAttribute('aria-pressed', Number(button.dataset.speed) === speed ? 'true' : 'false');\n    });\n  }\n\n  dispose() {\n    this._unsubscribeClock?.();\n    this._unsubscribeClock = null;\n    if (this._el?.parentNode) this._el.parentNode.removeChild(this._el);\n    if (_instance === this) _instance = null;\n  }\n}\n","/**\n * IntentRegistry — typed, pluggable agent intents.\n *\n * Replaces the giant switch in AgentCommandProcessor.js as the\n * extension point for new intents. The 13 legacy intents continue to\n * dispatch through the switch; new intents registered here are tried\n * FIRST and short-circuit the switch on a hit.\n *\n * Why this exists: every later WO (WO-001..WO-026) adds 1-4 new agent\n * intents. Without a registry, each WO would need to mutate the switch\n * — a fan-in of 25+ touch points on one file. With the registry, each\n * WO calls `registerIntent(...)` from its own module at boot.\n *\n * Schema: each intent is `{ name, description, params, handler, permissions, examples }`.\n *   name        — string, dot-prefixed for plugins (`plugin:foo:bar`)\n *   description — human-readable; embedded in LLM tool-spec\n *   params      — JSON-Schema-ish object describing slot shape\n *   handler     — async (slots, ctx) => { applied: bool, async?: bool, actionTags?: string[], toolResult?: any, errors?: string[] }\n *   permissions — array of capability strings; see PERMISSIONS below\n *   examples    — array of { utterance, slots }\n */\n\nexport const PERMISSIONS = Object.freeze({\n  READ_LAYERS: 'read:layers',\n  WRITE_OVERLAY: 'write:overlay',\n  READ_PLAYER_POSITION: 'read:player-position',\n  WRITE_PLAYER_POSITION: 'write:player-position',\n  WRITE_SCENE_CLOCK: 'write:scene-clock',\n  WRITE_BASEMAP: 'write:basemap',\n  WRITE_DRAWING: 'write:drawing',\n  WALLET_SIGN: 'wallet:sign-message',\n  NETWORK_FETCH: 'network:fetch',\n  STORAGE_WRITE: 'storage:write',\n});\n\nconst _registry = new Map();\n\n/**\n * Register an intent. Idempotent: re-registering the same name overwrites\n * (warn once). Returns an unregister function.\n */\nexport function registerIntent(spec) {\n  if (!spec || typeof spec.name !== 'string' || typeof spec.handler !== 'function') {\n    throw new Error('IntentRegistry: spec must have { name, handler }');\n  }\n  if (_registry.has(spec.name)) {\n    console.warn(`[IntentRegistry] re-registering intent \"${spec.name}\"`);\n  }\n  const normalised = {\n    name: spec.name,\n    description: spec.description || '',\n    params: spec.params || { type: 'object', properties: {} },\n    handler: spec.handler,\n    permissions: Array.isArray(spec.permissions) ? spec.permissions : [],\n    examples: Array.isArray(spec.examples) ? spec.examples : [],\n  };\n  _registry.set(spec.name, normalised);\n  return () => _registry.delete(spec.name);\n}\n\n/**\n * Unregister by name. Returns true if removed.\n */\nexport function unregisterIntent(name) {\n  return _registry.delete(name);\n}\n\n/**\n * Look up an intent spec by name.\n */\nexport function getIntent(name) {\n  return _registry.get(name) || null;\n}\n\n/**\n * List all registered intent names.\n */\nexport function listIntents() {\n  return Array.from(_registry.keys()).sort();\n}\n\n/**\n * Dispatch a command through the registry. Returns:\n *   - { handled: true, result }   — registry handled the intent\n *   - { handled: false }          — intent not registered; caller should fall through\n *\n * `result` matches the AgentCommandProcessor result shape so the caller\n * can splice it directly into its own result object.\n */\nexport async function dispatchIntent(command, ctx = {}) {\n  const intent = command?.intent;\n  if (typeof intent !== 'string') return { handled: false };\n  const spec = _registry.get(intent.trim());\n  if (!spec) return { handled: false };\n\n  // Lightweight permission check — caller can override via ctx.permissions\n  if (spec.permissions.length && Array.isArray(ctx.permissions)) {\n    const granted = new Set(ctx.permissions);\n    for (const p of spec.permissions) {\n      if (!granted.has(p)) {\n        return {\n          handled: true,\n          result: {\n            applied: false,\n            errors: [`PERMISSION_DENIED: ${spec.name} requires ${p}`],\n            actionTags: [],\n            tuneableTags: [],\n            toolResult: null,\n            async: false,\n          },\n        };\n      }\n    }\n  }\n\n  try {\n    const slots = command.slots || {};\n    const handlerResult = await spec.handler(slots, ctx) || {};\n    return {\n      handled: true,\n      result: {\n        applied: !!handlerResult.applied,\n        async: !!handlerResult.async,\n        actionTags: handlerResult.actionTags || [],\n        tuneableTags: handlerResult.tuneableTags || [],\n        errors: handlerResult.errors || [],\n        toolResult: handlerResult.toolResult || null,\n      },\n    };\n  } catch (err) {\n    return {\n      handled: true,\n      result: {\n        applied: false,\n        errors: [`Intent \"${intent}\" handler threw: ${err.message || err}`],\n        actionTags: [],\n        tuneableTags: [],\n        toolResult: null,\n        async: false,\n      },\n    };\n  }\n}\n\n/**\n * Generate an LLM tool-spec list from the registered intents in\n * OpenAI-style function-calling format. Anthropic and Ollama have\n * compatible enough shapes that the same spec works.\n */\nexport function generateToolSpec({ format = 'openai' } = {}) {\n  const intents = Array.from(_registry.values());\n  if (format === 'openai') {\n    return intents.map((i) => ({\n      type: 'function',\n      function: {\n        name: i.name,\n        description: i.description,\n        parameters: i.params,\n      },\n    }));\n  }\n  if (format === 'anthropic') {\n    return intents.map((i) => ({\n      name: i.name,\n      description: i.description,\n      input_schema: i.params,\n    }));\n  }\n  // Default: raw spec list\n  return intents.map((i) => ({\n    name: i.name,\n    description: i.description,\n    parameters: i.params,\n  }));\n}\n\n/**\n * Generate a markdown reference for all registered intents — used by\n * the docs generator at build time.\n */\nexport function generateMarkdownDocs() {\n  const intents = Array.from(_registry.values()).sort((a, b) => a.name.localeCompare(b.name));\n  let md = '# Agent Intents\\n\\nAuto-generated. Do not edit by hand.\\n\\n';\n  for (const i of intents) {\n    md += `## \\`${i.name}\\`\\n\\n${i.description || '_No description._'}\\n\\n`;\n    if (i.permissions.length) md += `**Permissions**: ${i.permissions.join(', ')}\\n\\n`;\n    md += '**Parameters**:\\n```json\\n' + JSON.stringify(i.params, null, 2) + '\\n```\\n\\n';\n    if (i.examples.length) {\n      md += '**Examples**:\\n';\n      for (const ex of i.examples) {\n        md += `- \"${ex.utterance}\" → \\`${JSON.stringify(ex.slots)}\\`\\n`;\n      }\n      md += '\\n';\n    }\n  }\n  return md;\n}\n\n/**\n * Test-only helper to clear the registry between unit tests.\n */\nexport function _clearRegistry() {\n  _registry.clear();\n}\n","/**\n * Agent intents for scene-clock control. Auto-registered on import.\n */\nimport { registerIntent, PERMISSIONS } from '../IntentRegistry.js';\nimport { getSceneClock } from '../../scene/SceneClock.js';\n\nlet _registered = false;\nexport function registerSceneClockIntents() {\n  if (_registered) return;\n  _registered = true;\n  const clock = getSceneClock();\n\n  registerIntent({\n    name: 'set_scene_time',\n    description: 'Set the scene clock to a specific date/time. Switches to fixed mode.',\n    permissions: [PERMISSIONS.WRITE_SCENE_CLOCK],\n    params: {\n      type: 'object',\n      required: ['iso'],\n      properties: {\n        iso: { type: 'string', description: 'ISO-8601 timestamp, e.g. 2024-07-15T12:00:00Z' },\n      },\n    },\n    examples: [\n      { utterance: 'go back to last Wednesday at noon', slots: { iso: '2024-09-18T12:00:00Z' } },\n    ],\n    handler: (slots) => {\n      const t = Date.parse(slots.iso);\n      if (!Number.isFinite(t)) return { applied: false, errors: ['Invalid iso'] };\n      clock.setTime(t);\n      return { applied: true, actionTags: ['clock.set_time'] };\n    },\n  });\n\n  registerIntent({\n    name: 'set_scene_speed',\n    description: 'Set scene-clock playback speed multiplier (e.g. 60x).',\n    permissions: [PERMISSIONS.WRITE_SCENE_CLOCK],\n    params: {\n      type: 'object', required: ['speed'],\n      properties: { speed: { type: 'number' } },\n    },\n    handler: (slots) => {\n      const s = Number(slots.speed);\n      if (!Number.isFinite(s) || s === 0) return { applied: false, errors: ['Invalid speed'] };\n      clock.setSpeed(s);\n      return { applied: true, actionTags: [`clock.speed:${s}`] };\n    },\n  });\n\n  registerIntent({\n    name: 'play_scene',\n    description: 'Resume scene-clock playback at the current speed.',\n    permissions: [PERMISSIONS.WRITE_SCENE_CLOCK],\n    params: { type: 'object', properties: {} },\n    handler: () => { clock.play(); return { applied: true, actionTags: ['clock.play'] }; },\n  });\n\n  registerIntent({\n    name: 'pause_scene',\n    description: 'Pause the scene clock at the current time.',\n    permissions: [PERMISSIONS.WRITE_SCENE_CLOCK],\n    params: { type: 'object', properties: {} },\n    handler: () => { clock.pause(); return { applied: true, actionTags: ['clock.pause'] }; },\n  });\n}\n","/**\n * Built-in basemap specs seeded into the BasemapRegistry on boot.\n * All providers are free + keyless or fair-use rate-limited; attribution\n * required where indicated.\n */\nimport { register } from './BasemapRegistry.js';\nimport { NASA_NIGHT_LIGHTS_TILE_SOURCE } from './NasaNightLightsTileField.js';\nimport { MAPSOURCE_STYLES } from './MapSourceStyle.js';\n\nexport function seedBuiltinBasemaps() {\n  register({\n    id: 'carto-dark',\n    label: 'Dark',\n    kind: 'raster-2d',\n    url: '/api/tiles/dark/{z}/{x}/{y}.png?v=20260828.2',\n    backendTilePath: '/tiles/dark/{z}/{x}/{y}.png?v=20260828.2',\n    backendOnly: true,\n    attribution: '© CARTO © OpenMapTiles © OpenStreetMap contributors',\n    maxZoom: 19, tileSize: 256,\n    thumbnailUrl: '',\n  });\n  register({\n    id: 'carto-positron',\n    label: 'Light',\n    kind: 'raster-2d',\n    url: '/api/tiles/light/{z}/{x}/{y}.png?v=20260828.2',\n    backendTilePath: '/tiles/light/{z}/{x}/{y}.png?v=20260828.2',\n    backendOnly: true,\n    attribution: '© CARTO © OpenMapTiles © OpenStreetMap contributors',\n    maxZoom: 19, tileSize: 256,\n    fallbackId: 'carto-dark',\n  });\n  register({\n    id: 'osm-standard',\n    label: 'OpenStreetMap',\n    kind: 'raster-2d',\n    url: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',\n    attribution: '© OpenStreetMap contributors',\n    maxZoom: 19, tileSize: 256,\n    fallbackId: 'carto-positron',\n  });\n  register({\n    id: 'esri-world-imagery',\n    label: 'Satellite',\n    kind: 'raster-2d',\n    url: 'https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}',\n    attribution: 'Tiles © Esri — Source: Esri, Maxar, Earthstar Geographics',\n    maxZoom: 19, tileSize: 256,\n    fallbackId: 'carto-dark',\n  });\n  register({\n    id: 'opentopomap',\n    label: 'Terrain',\n    kind: 'raster-2d',\n    url: 'https://a.tile.opentopomap.org/{z}/{x}/{y}.png',\n    attribution: '© OpenTopoMap (CC-BY-SA) © OpenStreetMap contributors',\n    maxZoom: 17, tileSize: 256,\n    fallbackId: 'carto-dark',\n  });\n  register({\n    id: 'cyclosm',\n    label: 'Hiking / Cycling',\n    kind: 'raster-2d',\n    url: 'https://a.tile-cyclosm.openstreetmap.fr/cyclosm/{z}/{x}/{y}.png',\n    attribution: 'CyclOSM © OpenStreetMap contributors',\n    maxZoom: 19, tileSize: 256,\n    fallbackId: 'carto-dark',\n  });\n  register({\n    id: 'mapzen-raw-elevation',\n    label: 'RAW ELEVATION',\n    kind: 'raster-2d',\n    url: 'https://s3.amazonaws.com/elevation-tiles-prod/geotiff/{z}/{x}/{y}.tif',\n    attribution: 'Mapzen Terrain Tiles · AWS Open Data',\n    minZoom: 0,\n    maxZoom: 19,\n    maxNativeZoom: 15,\n    tileSize: 256,\n    rasterEncoding: 'geotiff-float32',\n    rasterDisplay: 'elevation-grayscale',\n    elevationScale: 'viewport-linear',\n    fallbackId: 'carto-dark',\n  });\n  register({\n    id: 'sentinel1-global-2020',\n    label: 'Sentinel-1 SAR',\n    kind: 'raster-2d',\n    url: '/api/v1/maps/tiles/sentinel1-global-2020/{z}/{x}/{y}',\n    backendTilePath: '/v1/maps/tiles/sentinel1-global-2020/{z}/{x}/{y}',\n    backendOnly: true,\n    attribution: 'Contains modified Copernicus Sentinel data (2019–2020) · Earth Big Data / GAMMA / ASF',\n    minZoom: 0, maxZoom: 19, maxNativeZoom: 7, tileSize: 256,\n    allowSparseTiles: true,\n  });\n  register({\n    id: 'nasa-blue-marble',\n    label: 'NASA Blue Marble',\n    kind: 'raster-2d',\n    protocol: 'wmts',\n    url: 'https://gibs.earthdata.nasa.gov/wmts/epsg3857/best/BlueMarble_NextGeneration/default/GoogleMapsCompatible_Level8/{z}/{y}/{x}.jpg',\n    attribution: 'NASA EOSDIS GIBS',\n    maxZoom: 19, maxNativeZoom: 8,\n    fallbackId: 'carto-dark',\n  });\n  register({\n    id: 'nasa-shaded-relief-bathymetry',\n    label: 'NASA Relief + Bathymetry',\n    kind: 'raster-2d',\n    protocol: 'wmts',\n    url: 'https://gibs.earthdata.nasa.gov/wmts/epsg3857/best/BlueMarble_ShadedRelief_Bathymetry/default/GoogleMapsCompatible_Level8/{z}/{y}/{x}.jpg',\n    attribution: 'NASA EOSDIS GIBS',\n    maxZoom: 19, maxNativeZoom: 8,\n    fallbackId: 'carto-dark',\n  });\n  register({\n    id: NASA_NIGHT_LIGHTS_TILE_SOURCE.id,\n    label: NASA_NIGHT_LIGHTS_TILE_SOURCE.label,\n    kind: 'raster-2d',\n    protocol: NASA_NIGHT_LIGHTS_TILE_SOURCE.protocol,\n    url: NASA_NIGHT_LIGHTS_TILE_SOURCE.url,\n    attribution: NASA_NIGHT_LIGHTS_TILE_SOURCE.attribution,\n    tileSize: NASA_NIGHT_LIGHTS_TILE_SOURCE.tileSize,\n    maxZoom: 19,\n    maxNativeZoom: NASA_NIGHT_LIGHTS_TILE_SOURCE.maxNativeZoom,\n    fallbackId: 'carto-dark',\n  });\n  register({\n    id: 'nasa-modis-true-color',\n    label: 'NASA Daily True Color',\n    kind: 'raster-2d',\n    protocol: 'wmts',\n    url: 'https://gibs.earthdata.nasa.gov/wmts/epsg3857/best/MODIS_Terra_CorrectedReflectance_TrueColor/default/{date}/GoogleMapsCompatible_Level9/{z}/{y}/{x}.jpg',\n    attribution: 'NASA EOSDIS GIBS · MODIS Terra',\n    maxZoom: 19, maxNativeZoom: 9,\n    baseId: 'nasa-blue-marble', opacity: 1, allowSparseTiles: true,\n    fallbackId: 'nasa-blue-marble',\n  });\n  register({\n    id: 'nasa-modis-aerosol',\n    label: 'NASA Aerosol',\n    kind: 'raster-2d',\n    protocol: 'wmts',\n    url: 'https://gibs.earthdata.nasa.gov/wmts/epsg3857/best/MODIS_Terra_Aerosol/default/{date}/GoogleMapsCompatible_Level6/{z}/{y}/{x}.png',\n    attribution: 'NASA EOSDIS GIBS · MODIS Terra Aerosol',\n    maxZoom: 19, maxNativeZoom: 6,\n    baseId: 'carto-dark', opacity: 0.82, allowSparseTiles: true,\n    fallbackId: 'carto-dark',\n  });\n  register({\n    id: 'nasa-modis-snow',\n    label: 'NASA Snow Cover',\n    kind: 'raster-2d',\n    protocol: 'wmts',\n    url: 'https://gibs.earthdata.nasa.gov/wmts/epsg3857/best/MODIS_Terra_NDSI_Snow_Cover/default/{date}/GoogleMapsCompatible_Level8/{z}/{y}/{x}.png',\n    attribution: 'NASA EOSDIS GIBS · MODIS Terra NDSI',\n    maxZoom: 19, maxNativeZoom: 8,\n    baseId: 'carto-dark', opacity: 0.86, allowSparseTiles: true,\n    fallbackId: 'carto-dark',\n  });\n  register({\n    id: 'nasa-modis-chlorophyll',\n    label: 'NASA Ocean Chlorophyll',\n    kind: 'raster-2d',\n    protocol: 'wmts',\n    url: 'https://gibs.earthdata.nasa.gov/wmts/epsg3857/best/MODIS_Aqua_L2_Chlorophyll_A/default/{date}/GoogleMapsCompatible_Level7/{z}/{y}/{x}.png',\n    attribution: 'NASA EOSDIS GIBS · MODIS Aqua',\n    maxZoom: 19, maxNativeZoom: 7,\n    baseId: 'carto-dark', opacity: 0.88, allowSparseTiles: true,\n    fallbackId: 'carto-dark',\n  });\n  register({\n    id: 'nasa-goes-east-ir',\n    label: 'GOES-East Infrared',\n    kind: 'raster-2d',\n    protocol: 'wmts',\n    url: 'https://gibs.earthdata.nasa.gov/wmts/epsg3857/best/GOES-East_ABI_Band13_Clean_Infrared/default/default/GoogleMapsCompatible_Level6/{z}/{y}/{x}.png',\n    attribution: 'NASA EOSDIS GIBS · NOAA GOES-East ABI',\n    maxZoom: 19, maxNativeZoom: 6,\n    baseId: 'carto-dark', opacity: 0.9, allowSparseTiles: true,\n    fallbackId: 'carto-dark',\n  });\n  register({\n    id: 'nasa-goes-west-ir',\n    label: 'GOES-West Infrared',\n    kind: 'raster-2d',\n    protocol: 'wmts',\n    url: 'https://gibs.earthdata.nasa.gov/wmts/epsg3857/best/GOES-West_ABI_Band13_Clean_Infrared/default/default/GoogleMapsCompatible_Level6/{z}/{y}/{x}.png',\n    attribution: 'NASA EOSDIS GIBS · NOAA GOES-West ABI',\n    maxZoom: 19, maxNativeZoom: 6,\n    baseId: 'carto-dark', opacity: 0.9, allowSparseTiles: true,\n    fallbackId: 'carto-dark',\n  });\n  register({\n    id: 'nasa-himawari-ir',\n    label: 'Himawari Infrared',\n    kind: 'raster-2d',\n    protocol: 'wmts',\n    url: 'https://gibs.earthdata.nasa.gov/wmts/epsg3857/best/Himawari_AHI_Band13_Clean_Infrared/default/default/GoogleMapsCompatible_Level6/{z}/{y}/{x}.png',\n    attribution: 'NASA EOSDIS GIBS · JMA Himawari AHI',\n    maxZoom: 19, maxNativeZoom: 6,\n    baseId: 'carto-dark', opacity: 0.9, allowSparseTiles: true,\n    fallbackId: 'carto-dark',\n  });\n  register({\n    id: 'eox-sentinel-cloudless-2025',\n    label: 'Sentinel-2 Cloudless 2025',\n    kind: 'raster-2d',\n    protocol: 'wmts',\n    url: 'https://tiles.maps.eox.at/wmts/1.0.0/s2cloudless-2025_3857/default/GoogleMapsCompatible/{z}/{y}/{x}.jpg',\n    attribution: 'Sentinel-2 cloudless by EOX · Copernicus Sentinel data',\n    maxZoom: 19, maxNativeZoom: 14,\n    fallbackId: 'esri-world-imagery',\n  });\n  register({\n    id: 'eox-terrain',\n    label: 'EOX Terrain',\n    kind: 'raster-2d',\n    protocol: 'wmts',\n    url: 'https://tiles.maps.eox.at/wmts/1.0.0/terrain_3857/default/g/{z}/{y}/{x}.jpg',\n    attribution: 'EOX Maps · OpenStreetMap contributors',\n    maxZoom: 19, maxNativeZoom: 14,\n    fallbackId: 'opentopomap',\n  });\n  register({\n    id: 'gebco-relief',\n    label: 'GEBCO Global Relief',\n    kind: 'raster-2d',\n    protocol: 'wms',\n    url: 'https://wms.gebco.net/mapserv',\n    wmsLayers: 'GEBCO_LATEST',\n    wmsFormat: 'image/png',\n    attribution: 'GEBCO Compilation Group',\n    maxZoom: 19,\n    fallbackId: 'nasa-shaded-relief-bathymetry',\n  });\n  register({\n    id: 'gebco-measured-cells',\n    label: 'GEBCO Measured Bathymetry',\n    kind: 'raster-2d',\n    protocol: 'wms',\n    url: 'https://wms.gebco.net/mapserv',\n    wmsLayers: 'GEBCO_LATEST_3',\n    wmsFormat: 'image/png',\n    wmsTransparent: true,\n    baseId: 'carto-dark', opacity: 0.9, allowSparseTiles: true,\n    attribution: 'GEBCO Compilation Group · measured source cells',\n    maxZoom: 19,\n    fallbackId: 'carto-dark',\n  });\n  register({\n    id: 'emodnet-bathymetry',\n    label: 'EMODnet Bathymetry',\n    kind: 'raster-2d',\n    protocol: 'wmts',\n    url: 'https://tiles.emodnet-bathymetry.eu/latest/mean_atlas_land/web_mercator/{z}/{x}/{y}.png',\n    attribution: 'EMODnet Bathymetry Consortium',\n    maxZoom: 19, maxNativeZoom: 14,\n    fallbackId: 'gebco-relief',\n  });\n  register({\n    id: 'noaa-mrms-radar',\n    label: 'NOAA MRMS Radar',\n    kind: 'raster-2d',\n    protocol: 'wms',\n    url: 'https://mapservices.weather.noaa.gov/eventdriven/services/radar/radar_base_reflectivity/MapServer/WMSServer',\n    wmsLayers: '1',\n    wmsFormat: 'image/png',\n    wmsTransparent: true,\n    baseId: 'carto-dark', opacity: 0.9, allowSparseTiles: true,\n    attribution: 'NOAA National Weather Service · MRMS',\n    maxZoom: 19,\n    fallbackId: 'carto-dark',\n  });\n  register({\n    id: 'noaa-cmorph-precipitation',\n    label: 'NOAA Global Precipitation',\n    kind: 'raster-2d',\n    protocol: 'wms',\n    url: 'https://mapservices.weather.noaa.gov/raster/services/climate/cpc_cmorph_dly_025deg/MapServer/WMSServer',\n    wmsLayers: '1',\n    wmsFormat: 'image/png',\n    wmsTransparent: true,\n    baseId: 'carto-dark', opacity: 0.88, allowSparseTiles: true,\n    attribution: 'NOAA Climate Prediction Center · CMORPH',\n    maxZoom: 19,\n    fallbackId: 'carto-dark',\n  });\n  register({\n    id: 'rainviewer-radar',\n    label: 'Global Weather Radar',\n    kind: 'raster-2d',\n    protocol: 'dynamic',\n    dynamicSource: 'rainviewer-latest',\n    url: 'https://api.rainviewer.com/public/weather-maps.json',\n    baseId: 'carto-dark', opacity: 0.9, allowSparseTiles: true,\n    attribution: 'RainViewer',\n    maxZoom: 19, maxNativeZoom: 7,\n    fallbackId: 'noaa-mrms-radar',\n  });\n  register({\n    id: 'eumetsat-mtg-ir',\n    label: 'EUMETSAT MTG Infrared',\n    kind: 'raster-2d',\n    protocol: 'wms',\n    url: 'https://view.eumetsat.int/geoserver/wms',\n    wmsLayers: 'mtg_fd:ir105_hrfi',\n    wmsFormat: 'image/png',\n    wmsTransparent: true,\n    baseId: 'carto-dark', opacity: 0.9, allowSparseTiles: true,\n    attribution: 'EUMETSAT EUMETView · MTG FCI',\n    maxZoom: 19,\n    fallbackId: 'nasa-goes-east-ir',\n  });\n  register({\n    id: 'noaa-bluetopo',\n    label: 'NOAA BlueTopo',\n    kind: 'raster-2d',\n    protocol: 'wmts',\n    url: 'https://nowcoast.noaa.gov/geoserver/gwc/service/wmts/rest/bluetopo:bathymetry/nbs_elevation/EPSG:3857/EPSG:3857:{z}/{y}/{x}?format=image/png8',\n    baseId: 'carto-dark', opacity: 0.9, allowSparseTiles: true,\n    attribution: 'NOAA Office of Coast Survey · BlueTopo',\n    maxZoom: 19, maxNativeZoom: 16,\n    fallbackId: 'gebco-relief',\n  });\n  register({\n    id: 'usgs-topo',\n    label: 'USGS Topographic',\n    kind: 'raster-2d',\n    protocol: 'xyz',\n    url: 'https://basemap.nationalmap.gov/arcgis/rest/services/USGSTopo/MapServer/tile/{z}/{y}/{x}',\n    attribution: 'USGS The National Map',\n    maxZoom: 16,\n    fallbackId: 'opentopomap',\n  });\n  register({\n    id: 'openseamap',\n    label: 'Nautical Seamarks',\n    kind: 'raster-2d',\n    protocol: 'xyz',\n    url: 'https://t1.openseamap.org/seamark/{z}/{x}/{y}.png',\n    baseId: 'carto-dark', opacity: 1, allowSparseTiles: true,\n    attribution: 'OpenSeaMap · OpenStreetMap contributors',\n    maxZoom: 19,\n    fallbackId: 'carto-dark',\n  });\n  register({\n    id: 'google-photoreal',\n    label: 'Photorealistic 3D',\n    kind: 'photoreal-3d',\n    url: 'google-photoreal',\n    attribution: '© Google',\n    maxZoom: 22, tileSize: 256,\n  });\n  for (const preset of MAPSOURCE_STYLES) register({\n    id: `mapsource-${preset.id}`, label: preset.label, kind: 'vector-2d', mapsourcePreset: preset.id,\n    url: `/api/v1/maps/styles/${preset.id}/style.json`, backendOnly: true,\n    fallbackId: preset.dark ? 'carto-dark' : 'carto-positron',\n    attribution: '© OpenMapTiles © OpenStreetMap contributors · Mapsource', maxZoom: 23,\n  });\n}\n","/**\n * BasemapPicker — basemap toggle.\n *\n * The picker no longer plants itself as a floating top-left panel by\n * default. It builds the same `.nca-hud-panel` body element it always\n * has, but leaves mounting to the host (HUD dock on phones,\n * LeftSidebar on desktop). Callers drop the produced element wherever\n * they want; the picker stays a singleton bound to the basemap\n * registry.\n *\n * Backwards-compatible options:\n *   - mode: 'embedded' (default) — no slot class, no auto-mount, no\n *     collapse chrome; the body is always visible.\n *   - mode: 'floating' — legacy behavior (`nca-hud-panel--top-left`,\n *     auto-append to container, collapse toggle visible).\n */\nimport * as Registry from '../imagery/BasemapRegistry.js';\nimport { groupMapSources } from '../imagery/MapSourceCatalog.js';\nimport { ensureHudPanelStyles } from './HudSlots.js';\n\nlet _instance = null;\nexport function getBasemapPicker(opts) {\n  if (!_instance) _instance = new BasemapPicker(opts);\n  return _instance;\n}\n\nexport class BasemapPicker {\n  constructor({ container, mode = 'embedded' } = {}) {\n    ensureHudPanelStyles();\n    this.mode = mode === 'floating' ? 'floating' : 'embedded';\n    this.container = container || (this.mode === 'floating' ? document.body : null);\n    this._el = null;\n    this._build();\n    this._bind();\n    this._render();\n  }\n\n  /**\n   * Returns the panel root element so a host (dock panel, sidebar\n   * detail content, HUD builder widget) can mount it. Idempotent.\n   */\n  get element() {\n    return this._el;\n  }\n\n  /**\n   * Mount (or re-parent) the picker into a host container. Use this\n   * from dock/sidebar render callbacks instead of cloning DOM.\n   */\n  mount(container) {\n    if (!container || !this._el) return;\n    if (this._el.parentNode === container) return;\n    container.appendChild(this._el);\n  }\n\n  _build() {\n    const el = document.createElement('div');\n    if (this.mode === 'floating') {\n      // Legacy floating mode — kept for fallback/escape hatch.\n      el.className = 'nc-basemap-picker nca-hud-panel nca-hud-panel--top-left is-collapsed';\n    } else {\n      // Embedded mode — drops the slot class so the host (dock panel\n      // or sidebar detail) controls positioning. Drops `is-collapsed`\n      // so the body is always visible inside its host.\n      el.className = 'nc-basemap-picker nca-hud-panel nca-hud-panel--embedded';\n    }\n    el.innerHTML = `\n      <div class=\"nca-hud-header\" role=\"button\" tabindex=\"0\">\n        <span>Map layers</span>\n        <button class=\"nc-basemap-toggle\" type=\"button\" title=\"Map layers\" aria-label=\"Map layers\">🗺</button>\n      </div>\n      <div class=\"nca-hud-body nc-basemap-list\"></div>\n    `;\n    if (this.mode === 'floating' && this.container) {\n      this.container.appendChild(el);\n    }\n    this._el = el;\n    this._toggle = el.querySelector('.nc-basemap-toggle');\n    this._listEl = el.querySelector('.nc-basemap-list');\n  }\n\n  _bind() {\n    if (this.mode === 'floating') {\n      const toggle = () => this._el.classList.toggle('is-collapsed');\n      this._toggle.addEventListener('click', (e) => { e.stopPropagation(); toggle(); });\n      this._el.querySelector('.nca-hud-header')?.addEventListener('click', toggle);\n    } else {\n      // In embedded mode the trigger button is decorative — the host\n      // already provides open/close affordances (dock back button,\n      // sidebar close X). Hide the toggle to avoid redundant chrome.\n      if (this._toggle) this._toggle.style.display = 'none';\n    }\n    Registry.subscribe(({ type }) => {\n      if (type === 'basemap:registered' || type === 'basemap:unregistered' || type === 'basemap:active-change') {\n        this._render();\n      }\n    });\n  }\n\n  _render() {\n    if (!this._listEl) return;\n    const active = Registry.getActive()?.id;\n    const fragment = document.createDocumentFragment();\n    for (const group of groupMapSources(Registry.list())) {\n      const section = document.createElement('section'); section.className = 'nc-basemap-group';\n      const heading = document.createElement('h4'); heading.className = 'nc-basemap-group__title'; heading.textContent = group.label;\n      section.append(heading);\n      for (const item of group.items) {\n        const button = document.createElement('button'); button.type = 'button';\n        button.className = `nc-basemap-item${item.id === active ? ' active' : ''}`;\n        button.dataset.id = item.id;\n        button.setAttribute('aria-pressed', String(item.id === active));\n        const label = document.createElement('span'); label.className = 'nc-basemap-label'; label.textContent = item.label;\n        const kind = document.createElement('span'); kind.className = 'nc-basemap-kind'; kind.textContent = item.provider;\n        button.append(label, kind);\n        button.addEventListener('click', () => Registry.setActive(item.id));\n        section.append(button);\n      }\n      fragment.append(section);\n    }\n    this._listEl.replaceChildren(fragment);\n  }\n}\n","import { registerIntent, PERMISSIONS } from '../IntentRegistry.js';\nimport * as Registry from '../../imagery/BasemapRegistry.js';\n\nlet _registered = false;\nexport function registerBasemapIntents() {\n  if (_registered) return;\n  _registered = true;\n\n  registerIntent({\n    name: 'set_basemap',\n    description: 'Activate a basemap by id (carto-dark, esri-world-imagery, opentopomap, cyclosm, google-photoreal, ...).',\n    permissions: [PERMISSIONS.WRITE_BASEMAP],\n    params: {\n      type: 'object', required: ['id'],\n      properties: { id: { type: 'string' } },\n    },\n    handler: (slots) => {\n      if (Registry.setActive(slots.id)) {\n        return { applied: true, actionTags: [`basemap:${slots.id}`] };\n      }\n      return { applied: false, errors: [`Unknown basemap id: ${slots.id}`] };\n    },\n    examples: [\n      { utterance: 'switch to satellite', slots: { id: 'esri-world-imagery' } },\n      { utterance: 'show me the terrain map', slots: { id: 'opentopomap' } },\n    ],\n  });\n}\n","/**\n * DrawSurfaceLayer — Three.js Group that renders DrawSystem shapes as\n * surface-following geometry on the WGS84 ellipsoid. Subscribes to\n * `noclip:draw:*` events and rebuilds incrementally; the in-progress\n * shape is rendered as a separate \"preview\" object so committed shapes\n * don't churn while the user is still clicking.\n *\n * Rendering pattern matches RouteRibbonRenderer: depthTest:false, high\n * renderOrder, lifted ~35 m above the ellipsoid so the lines don't get\n * buried under terrain meshes.\n *\n * Geometry per kind:\n *   point       — small CircleGeometry, normal aligned to local up\n *   line        — Line (great-circle interpolated polyline)\n *   polygon     — Line ring + filled ShapeGeometry projected onto\n *                 the local tangent plane at the polygon centroid\n *   freehand    — Line (densely sampled raw vertices)\n *   circle      — Line ring sampled around the centre at the given radius\n *   rectangle   — Line ring along the four lat/lon edges\n */\nimport * as THREE from 'three';\nimport {\n  latLonToLocalDir,\n  ellipsoidRadiusForLocalDir,\n  interpolateGreatCircle,\n  geodesicDestinationWGS84,\n} from '../../modules/geometry-utils.js';\nimport { getLabelSystem } from '../labels/LabelSystem.js';\nimport { geometryAnchor } from './DrawingGeometry.js';\n\nconst LIFT_M = 2.5;\nconst RENDER_ORDER = 1550;\n\nconst COLOR_COMMIT  = new THREE.Color(0xffffff); // HUD accent\nconst COLOR_PREVIEW = new THREE.Color(0x6ee7b7); // mint, while drawing\nconst COLOR_FILL    = new THREE.Color(0xffffff);\nconst COLOR_SELECTED = new THREE.Color(0xfacc15);\n\nconst STEPS_PER_SEGMENT = 18;     // great-circle samples per polyline segment\nconst CIRCLE_SAMPLES = 96;\nconst POINT_RADIUS_M = 12;\n\nconst _tmpDir = new THREE.Vector3();\n\nfunction _coordToWorld(lat, lon, lift = LIFT_M, out = new THREE.Vector3(), surfaceRadius = null) {\n  const dir = latLonToLocalDir(lat, lon);\n  const r = Number.isFinite(surfaceRadius) ? surfaceRadius : ellipsoidRadiusForLocalDir(dir);\n  out.copy(dir).multiplyScalar(r + lift);\n  return out;\n}\n\nfunction _disposeObject(obj) {\n  if (!obj) return;\n  obj.parent?.remove(obj);\n  obj.traverse?.((child) => {\n    child.geometry?.dispose?.();\n    if (Array.isArray(child.material)) {\n      child.material.forEach((m) => m.dispose?.());\n    } else {\n      child.material?.dispose?.();\n    }\n  });\n}\n\nfunction _basicLineMaterial(color, opacity = 0.95) {\n  return new THREE.LineBasicMaterial({\n    color,\n    transparent: true,\n    opacity,\n    depthTest: false,\n    depthWrite: false,\n  });\n}\n\nfunction _basicMeshMaterial(color, opacity = 0.18) {\n  return new THREE.MeshBasicMaterial({\n    color,\n    transparent: true,\n    opacity,\n    depthTest: false,\n    depthWrite: false,\n    side: THREE.DoubleSide,\n  });\n}\n\n/**\n * Densify a polyline of {lat,lon} vertices using great-circle\n * interpolation between successive vertices. The first vertex of each\n * sub-arc is dropped (except the very first), avoiding duplicates at\n * segment joins.\n */\nfunction _densifyGreatCircle(vertices, stepsPerSeg = STEPS_PER_SEGMENT) {\n  if (!Array.isArray(vertices) || vertices.length < 2) {\n    return Array.isArray(vertices) ? vertices.slice() : [];\n  }\n  const out = [];\n  for (let i = 0; i < vertices.length - 1; i++) {\n    const arc = interpolateGreatCircle(vertices[i], vertices[i + 1], stepsPerSeg);\n    if (i === 0) out.push(...arc);\n    else out.push(...arc.slice(1));\n  }\n  return out;\n}\n\nfunction _buildLineFromLatLon(vertices, color, radiusFor = null) {\n  const pts = vertices.map((v) => _coordToWorld(v.lat, v.lon, LIFT_M, new THREE.Vector3(), radiusFor?.(v)));\n  const geom = new THREE.BufferGeometry().setFromPoints(pts);\n  const mat = _basicLineMaterial(color);\n  const line = new THREE.Line(geom, mat);\n  line.renderOrder = RENDER_ORDER;\n  line.frustumCulled = false;\n  return line;\n}\n\nfunction _buildPointMarker(lat, lon, color, surfaceRadius = null, radiusM = POINT_RADIUS_M) {\n  const dir = latLonToLocalDir(lat, lon);\n  const r = Number.isFinite(surfaceRadius) ? surfaceRadius : ellipsoidRadiusForLocalDir(dir);\n  const center = dir.clone().multiplyScalar(r + LIFT_M);\n\n  // Disc oriented to the local tangent plane.\n  const geom = new THREE.CircleGeometry(radiusM, 24);\n  const mat = _basicMeshMaterial(color, 0.85);\n  const mesh = new THREE.Mesh(geom, mat);\n  const yUp = new THREE.Vector3(0, 0, 1);  // CircleGeometry's normal\n  const quat = new THREE.Quaternion().setFromUnitVectors(yUp, dir.clone());\n  mesh.quaternion.copy(quat);\n  mesh.position.copy(center);\n  mesh.renderOrder = RENDER_ORDER;\n  mesh.frustumCulled = false;\n  return mesh;\n}\n\nfunction _buildCircleRing(center, radiusM, color, radiusFor = null) {\n  const ring = [];\n  for (let i = 0; i <= CIRCLE_SAMPLES; i++) {\n    const bearing = (i / CIRCLE_SAMPLES) * 360;\n    const p = geodesicDestinationWGS84(center.lat, center.lon, bearing, radiusM);\n    if (p) ring.push({ lat: p.latDeg, lon: p.lonDeg });\n  }\n  return _buildLineFromLatLon(ring, color, radiusFor);\n}\n\nfunction _buildRectangleRing(bounds, color, radiusFor = null) {\n  const ring = [\n    { lat: bounds.south, lon: bounds.west },\n    { lat: bounds.south, lon: bounds.east },\n    { lat: bounds.north, lon: bounds.east },\n    { lat: bounds.north, lon: bounds.west },\n    { lat: bounds.south, lon: bounds.west },\n  ];\n  return _buildLineFromLatLon(_densifyGreatCircle(ring, 8), color, radiusFor);\n}\n\n/**\n * Build a translucent fill mesh for a closed polygon of {lat,lon}\n * vertices, projected onto the local tangent plane at the centroid.\n * Good enough for shapes up to ~200 km across — beyond that the\n * projection error becomes visible and we'd want a proper ECEF\n * triangulation.\n */\nfunction _buildPolygonFill(verticesOrRings, color, radiusFor = null) {\n  const rings = Array.isArray(verticesOrRings?.[0]) ? verticesOrRings : [verticesOrRings];\n  const normalized = rings.map((ring) => {\n    const clean = Array.isArray(ring) ? ring.slice() : [];\n    if (clean.length > 1 && clean[0].lat === clean.at(-1).lat && clean[0].lon === clean.at(-1).lon) clean.pop();\n    return clean;\n  }).filter((ring) => ring.length >= 3);\n  const vertices = normalized[0];\n  if (!vertices) return null;\n\n  // Centroid in lat/lon space — adequate for the planar projection.\n  let sLat = 0, sLon = 0;\n  for (const v of vertices) { sLat += v.lat; sLon += v.lon; }\n  const cLat = sLat / vertices.length;\n  const cLon = sLon / vertices.length;\n\n  // Build local east/north basis at the centroid.\n  const centerDir = latLonToLocalDir(cLat, cLon).clone();\n  const centerRad = Number(radiusFor?.({ lat: cLat, lon: cLon })) || ellipsoidRadiusForLocalDir(centerDir);\n  const centerWorld = centerDir.clone().multiplyScalar(centerRad + LIFT_M);\n  const yWorld = new THREE.Vector3(0, 1, 0);\n  let east = new THREE.Vector3().crossVectors(yWorld, centerDir);\n  if (east.lengthSq() < 1e-6) east.set(1, 0, 0);\n  east.normalize();\n  const north = new THREE.Vector3().crossVectors(centerDir, east).normalize();\n\n  // Triangulate using THREE.ShapeUtils on planar (east,north) coords.\n  const projectRing = (ring) => ring.map((v) => {\n    const dir = latLonToLocalDir(v.lat, v.lon);\n    const rad = Number(radiusFor?.(v)) || ellipsoidRadiusForLocalDir(dir);\n    const world = dir.clone().multiplyScalar(rad + LIFT_M);\n    const offset = world.sub(centerWorld);\n    return new THREE.Vector2(offset.dot(east), offset.dot(north));\n  });\n  const planarRings = normalized.map(projectRing);\n  const planar = planarRings.flat();\n  const tris = THREE.ShapeUtils.triangulateShape(planarRings[0], planarRings.slice(1));\n  if (!tris.length) return null;\n\n  const positions = new Float32Array(planar.length * 3);\n  for (let i = 0; i < planar.length; i++) {\n    const v = planar[i];\n    const world = centerWorld.clone()\n      .addScaledVector(east, v.x)\n      .addScaledVector(north, v.y);\n    positions[i * 3] = world.x;\n    positions[i * 3 + 1] = world.y;\n    positions[i * 3 + 2] = world.z;\n  }\n  const indices = new Uint32Array(tris.length * 3);\n  for (let i = 0; i < tris.length; i++) {\n    indices[i * 3]     = tris[i][0];\n    indices[i * 3 + 1] = tris[i][1];\n    indices[i * 3 + 2] = tris[i][2];\n  }\n\n  const geom = new THREE.BufferGeometry();\n  geom.setAttribute('position', new THREE.BufferAttribute(positions, 3));\n  geom.setIndex(new THREE.BufferAttribute(indices, 1));\n  geom.computeBoundingSphere();\n  const mat = _basicMeshMaterial(color, 0.18);\n  const mesh = new THREE.Mesh(geom, mat);\n  mesh.renderOrder = RENDER_ORDER - 1;\n  mesh.frustumCulled = false;\n  return mesh;\n}\n\nexport class DrawSurfaceLayer extends THREE.Group {\n  constructor({ getDrawSystem, surfaceController = null } = {}) {\n    super();\n    this.name = 'DrawSurfaceLayer';\n    this._getDrawSystem = typeof getDrawSystem === 'function' ? getDrawSystem : null;\n    this._surfaceController = surfaceController;\n    this._stableRadii = new Map();\n    this._committedById = new Map(); // id → THREE.Object3D\n    this._labelsById = new Map();\n    this._previewGroup = new THREE.Group();\n    this._previewGroup.name = 'DrawPreview';\n    this.add(this._previewGroup);\n\n    this._onStart = (ev) => this._renderPreview(ev?.detail);\n    this._onVertex = (ev) => this._renderPreview(ev?.detail);\n    this._onCommit = (ev) => this._onCommitted(ev?.detail);\n    this._onCancel = () => this._clearPreview();\n    this._onCleared = (ev) => this._onShapesCleared(ev?.detail);\n    this._onUpdate = (ev) => this._onCommitted(ev?.detail);\n    this._onReplace = () => this._rebuildAll();\n    this._onSelection = () => this._rebuildAll();\n    this._onProject = () => this._rebuildAll();\n\n    if (typeof document !== 'undefined' && document.addEventListener) {\n      document.addEventListener('noclip:draw:start', this._onStart);\n      document.addEventListener('noclip:draw:vertex', this._onVertex);\n      document.addEventListener('noclip:draw:commit', this._onCommit);\n      document.addEventListener('noclip:draw:cancel', this._onCancel);\n      document.addEventListener('noclip:draw:cleared', this._onCleared);\n      document.addEventListener('noclip:draw:update', this._onUpdate);\n      document.addEventListener('noclip:draw:replace', this._onReplace);\n      document.addEventListener('noclip:draw:selection', this._onSelection);\n      document.addEventListener('noclip:draw:project', this._onProject);\n    }\n\n    // Backfill any already-committed shapes (defensive — handles the\n    // case where the layer is mounted after some shapes already exist).\n    const sys = this._getDrawSystem?.();\n    if (sys?.shapes) {\n      for (const shape of sys.shapes) this._onCommitted({ id: shape.id, shape });\n    }\n  }\n\n  dispose() {\n    if (typeof document !== 'undefined' && document.removeEventListener) {\n      document.removeEventListener('noclip:draw:start', this._onStart);\n      document.removeEventListener('noclip:draw:vertex', this._onVertex);\n      document.removeEventListener('noclip:draw:commit', this._onCommit);\n      document.removeEventListener('noclip:draw:cancel', this._onCancel);\n      document.removeEventListener('noclip:draw:cleared', this._onCleared);\n      document.removeEventListener('noclip:draw:update', this._onUpdate);\n      document.removeEventListener('noclip:draw:replace', this._onReplace);\n      document.removeEventListener('noclip:draw:selection', this._onSelection);\n      document.removeEventListener('noclip:draw:project', this._onProject);\n    }\n    this._clearPreview();\n    for (const obj of this._committedById.values()) _disposeObject(obj);\n    this._committedById.clear();\n    for (const handle of this._labelsById.values()) {\n      handle.group?.parent?.remove?.(handle.group);\n      handle.dispose?.();\n    }\n    this._labelsById.clear();\n    this._stableRadii.clear();\n  }\n\n  setSurfaceController(controller) {\n    this._surfaceController = controller || null;\n    this._rebuildAll();\n  }\n\n  refreshTerrain() {\n    this._rebuildAll();\n  }\n\n  _radiusFor(vertex) {\n    if (Number.isFinite(Number(vertex?.surfaceRadius))) return Number(vertex.surfaceRadius);\n    const lat = Number(vertex?.lat);\n    const lon = Number(vertex?.lon);\n    if (!Number.isFinite(lat) || !Number.isFinite(lon)) return null;\n    const key = `${lat.toFixed(7)},${lon.toFixed(7)}`;\n    const direction = latLonToLocalDir(lat, lon);\n    let sampled = null;\n    const sampler = this._surfaceController?.sampleTerrainRadiusForDir;\n    if (typeof sampler === 'function') {\n      const worldDirection = direction.clone();\n      const quaternion = this.parent?.getWorldQuaternion?.(new THREE.Quaternion());\n      if (quaternion) worldDirection.applyQuaternion(quaternion).normalize();\n      sampled = sampler.call(this._surfaceController, worldDirection, {\n        mutateCache: false,\n        requireFreshPhotoHit: !!this._surfaceController?.photoTileGroup,\n        allowTriTreeFallback: !this._surfaceController?.photoTileGroup,\n        skipWorldMatrixUpdate: true,\n      });\n    }\n    if (Number.isFinite(sampled)) this._stableRadii.set(key, sampled);\n    return this._stableRadii.get(key) || ellipsoidRadiusForLocalDir(direction);\n  }\n\n  _rebuildAll() {\n    for (const obj of this._committedById.values()) _disposeObject(obj);\n    this._committedById.clear();\n    for (const handle of this._labelsById.values()) {\n      handle.group?.parent?.remove?.(handle.group);\n      handle.dispose?.();\n    }\n    this._labelsById.clear();\n    const system = this._getDrawSystem?.();\n    for (const shape of system?.shapes || []) this._onCommitted({ id: shape.id, shape });\n  }\n\n  // ── Preview (in-progress) ──────────────────────────────────────────────\n\n  _clearPreview() {\n    while (this._previewGroup.children.length) {\n      _disposeObject(this._previewGroup.children[0]);\n    }\n  }\n\n  _renderPreview(detail) {\n    this._clearPreview();\n    if (!detail) return;\n    const kind = detail.kind || detail.tool;\n    const verts = Array.isArray(detail.vertices) ? detail.vertices : [];\n    const preview = { kind, vertices: verts };\n    if (kind === 'circle' && verts.length >= 2) {\n      preview.center = verts[0];\n      const a = verts[0], b = verts[1];\n      const dLat = (b.lat - a.lat) * Math.PI / 180;\n      const dLon = (b.lon - a.lon) * Math.PI / 180;\n      const h = Math.sin(dLat / 2) ** 2 + Math.cos(a.lat * Math.PI / 180) * Math.cos(b.lat * Math.PI / 180) * Math.sin(dLon / 2) ** 2;\n      preview.radius = 6371008.8 * 2 * Math.atan2(Math.sqrt(h), Math.sqrt(1 - h));\n    }\n    if (kind === 'rectangle' && verts.length >= 2) preview.bounds = {\n      south: Math.min(verts[0].lat, verts[1].lat), north: Math.max(verts[0].lat, verts[1].lat),\n      west: Math.min(verts[0].lon, verts[1].lon), east: Math.max(verts[0].lon, verts[1].lon),\n    };\n    const obj = this._buildShapeObject(preview, COLOR_PREVIEW);\n    if (obj) this._previewGroup.add(obj);\n  }\n\n  // ── Committed shapes ───────────────────────────────────────────────────\n\n  _onCommitted(detail) {\n    const shape = detail?.shape;\n    if (!shape || !shape.id) return;\n    // If we already had a stale entry under this id, remove it.\n    if (this._committedById.has(shape.id)) {\n      _disposeObject(this._committedById.get(shape.id));\n      this._committedById.delete(shape.id);\n    }\n    const oldLabel = this._labelsById.get(shape.id);\n    if (oldLabel) {\n      oldLabel.group?.parent?.remove?.(oldLabel.group);\n      oldLabel.dispose?.();\n      this._labelsById.delete(shape.id);\n    }\n    const system = this._getDrawSystem?.();\n    const group = system?.groups?.find?.((entry) => entry.groupId === shape.groupId);\n    if (group?.visible === false) return;\n    const selected = system?.selectedShapeId === shape.id;\n    const styledColor = shape.properties?.style?.color;\n    const color = selected\n      ? COLOR_SELECTED\n      : (styledColor ? new THREE.Color(styledColor) : COLOR_COMMIT);\n    const obj = this._buildShapeObject(shape, color);\n    if (obj) {\n      obj.userData = { ...obj.userData, shapeId: shape.id, kind: shape.kind };\n      this._committedById.set(shape.id, obj);\n      this.add(obj);\n      if (selected) {\n        for (const vertex of (shape.kind === 'circle' && shape.center ? [shape.center] : shape.vertices || [])) {\n          obj.add(_buildPointMarker(vertex.lat, vertex.lon, COLOR_SELECTED, this._radiusFor(vertex), 8));\n        }\n      }\n    }\n    this._createLabel(shape, color);\n    this._clearPreview();\n  }\n\n  _onShapesCleared(detail) {\n    const ids = Array.isArray(detail?.ids) ? detail.ids : null;\n    if (!ids) {\n      // Clear all committed\n      for (const obj of this._committedById.values()) _disposeObject(obj);\n      this._committedById.clear();\n      for (const handle of this._labelsById.values()) {\n        handle.group?.parent?.remove?.(handle.group);\n        handle.dispose?.();\n      }\n      this._labelsById.clear();\n      return;\n    }\n    for (const id of ids) {\n      const obj = this._committedById.get(id);\n      if (obj) _disposeObject(obj);\n      this._committedById.delete(id);\n      const handle = this._labelsById.get(id);\n      handle?.group?.parent?.remove?.(handle.group);\n      handle?.dispose?.();\n      this._labelsById.delete(id);\n    }\n  }\n\n  _createLabel(shape, color) {\n    const label = String(shape.properties?.label || '').trim();\n    // A blank annotation is geometry only until the author supplies text.\n    // Never synthesize a giant/generic \"Annotation\" label for it.\n    if (!label) return;\n    const anchor = geometryAnchor(shape);\n    if (!anchor) return;\n    const direction = latLonToLocalDir(anchor.lat, anchor.lon);\n    const position = direction.clone().multiplyScalar(this._radiusFor(anchor) + 12);\n    const measurement = shape.properties?.measurements || {};\n    const subText = shape.properties?.description\n      || (measurement.areaM2 ? `${Number(measurement.areaM2).toLocaleString()} m²` : null);\n    const handle = getLabelSystem().createLabel(label, {\n      position,\n      type: 'overlay',\n      color: color.getHex(),\n      objectRadius: 14,\n      subText,\n      labelPriority: 20,\n      maxDistance: 300_000,\n      metadata: {\n        id: shape.id,\n        entityType: 'drawing-feature',\n        typeLabel: shape.kind === 'annotation' ? 'Project annotation' : 'Drawing project feature',\n        name: label,\n        description: shape.properties?.description || '',\n        groupId: shape.groupId,\n        spatialRole: shape.properties?.spatialRole || 'none',\n        measurements: measurement,\n        assetAnchors: shape.properties?.attributes?.assetAnchors || [],\n        lat: anchor.lat,\n        lon: anchor.lon,\n      },\n    });\n    if (handle?.group) {\n      this.add(handle.group);\n      this._labelsById.set(shape.id, handle);\n    }\n  }\n\n  // ── Geometry builders ──────────────────────────────────────────────────\n\n  _buildShapeObject(shape, color) {\n    if (!shape) return null;\n    if (shape.sourceGeometry && !shape.geometryDirty) {\n      const preserved = this._buildGeoJsonObject(shape.sourceGeometry, color);\n      if (preserved) return preserved;\n    }\n    const group = new THREE.Group();\n    group.name = `Draw:${shape.kind}`;\n\n    switch (shape.kind) {\n      case 'point':\n      case 'annotation': {\n        if (!shape.vertices?.length) return null;\n        const v = shape.vertices[0];\n        group.add(_buildPointMarker(v.lat, v.lon, color, this._radiusFor(v)));\n        return group;\n      }\n      case 'line':\n      case 'freehand': {\n        if (!shape.vertices || shape.vertices.length < 2) return null;\n        const dense = _densifyGreatCircle(shape.vertices,\n          shape.kind === 'freehand' ? 4 : STEPS_PER_SEGMENT);\n        group.add(_buildLineFromLatLon(dense, color, (v) => this._radiusFor(v)));\n        return group;\n      }\n      case 'polygon': {\n        if (!shape.vertices || shape.vertices.length < 3) return null;\n        const ring = shape.vertices.concat([shape.vertices[0]]);\n        const dense = _densifyGreatCircle(ring, STEPS_PER_SEGMENT);\n        group.add(_buildLineFromLatLon(dense, color, (v) => this._radiusFor(v)));\n        const fill = _buildPolygonFill(shape.vertices, color, (v) => this._radiusFor(v));\n        if (fill) group.add(fill);\n        return group;\n      }\n      case 'circle': {\n        if (!shape.center || !Number.isFinite(shape.radius)) return null;\n        group.add(_buildCircleRing(shape.center, shape.radius, color, (v) => this._radiusFor(v)));\n        // Centre dot\n        group.add(_buildPointMarker(shape.center.lat, shape.center.lon, color, this._radiusFor(shape.center)));\n        return group;\n      }\n      case 'rectangle': {\n        if (!shape.bounds) return null;\n        group.add(_buildRectangleRing(shape.bounds, color, (v) => this._radiusFor(v)));\n        return group;\n      }\n      default:\n        return null;\n    }\n  }\n\n  _buildGeoJsonObject(geometry, color) {\n    const group = new THREE.Group();\n    group.name = `Draw:${geometry.type}`;\n    const pointMarker = (coordinates) => {\n      const vertex = { lon: Number(coordinates?.[0]), lat: Number(coordinates?.[1]) };\n      if (Number.isFinite(vertex.lat) && Number.isFinite(vertex.lon)) {\n        group.add(_buildPointMarker(vertex.lat, vertex.lon, color, this._radiusFor(vertex)));\n      }\n    };\n    const addLine = (coordinates, close = false) => {\n      const vertices = (coordinates || []).map(([lon, lat]) => ({ lon: Number(lon), lat: Number(lat) }))\n        .filter((vertex) => Number.isFinite(vertex.lat) && Number.isFinite(vertex.lon));\n      if (vertices.length < 2) return;\n      if (close && (vertices[0].lat !== vertices.at(-1).lat || vertices[0].lon !== vertices.at(-1).lon)) vertices.push({ ...vertices[0] });\n      group.add(_buildLineFromLatLon(_densifyGreatCircle(vertices), color, (vertex) => this._radiusFor(vertex)));\n    };\n    const addPolygon = (coordinates) => {\n      const rings = (coordinates || []).map((ring) => (ring || []).map(([lon, lat]) => ({ lon: Number(lon), lat: Number(lat) })));\n      for (const ring of rings) addLine(ring, true);\n      const fill = _buildPolygonFill(rings, color, (vertex) => this._radiusFor(vertex));\n      if (fill) group.add(fill);\n    };\n    if (geometry.type === 'MultiPoint') for (const coordinates of geometry.coordinates || []) pointMarker(coordinates);\n    else if (geometry.type === 'MultiLineString') for (const coordinates of geometry.coordinates || []) addLine(coordinates);\n    else if (geometry.type === 'MultiPolygon') for (const coordinates of geometry.coordinates || []) addPolygon(coordinates);\n    else if (geometry.type === 'Polygon') addPolygon(geometry.coordinates);\n    else return null;\n    return group.children.length ? group : null;\n  }\n}\n\nexport default DrawSurfaceLayer;\n\nlet _layerInstance = null;\n/**\n * Singleton getter so PlanetScene can mount a single layer regardless of\n * how many sites would otherwise instantiate one. The first call captures\n * the {getDrawSystem} dependency; subsequent calls return the same layer.\n * Exposes `.group` for parity with other overlay layers (DrawSurfaceLayer\n * IS a THREE.Group, so .group points to itself).\n */\nexport function getDrawSurfaceLayer(opts = {}) {\n  if (!_layerInstance) {\n    _layerInstance = new DrawSurfaceLayer(opts);\n    _layerInstance.group = _layerInstance;\n  }\n  return _layerInstance;\n}\n","/** Local scene PNG export, admitted only by the existing completed-frame owner. */\nexport class SceneCanvasCapture {\n  constructor(scene, { download = downloadScenePng, timeoutMs = 10_000 } = {}) {\n    this.scene = scene;\n    this.download = download;\n    this.timeoutMs = timeoutMs;\n    this.pending = null;\n    this.disposed = false;\n  }\n\n  _available() {\n    return !this.disposed && !!this.scene?._renderer?.domElement\n      && !this.scene._renderer.xr?.isPresenting\n      && !globalThis.document?.hidden\n      && !globalThis.document?.body?.classList.contains('nca-minimap-fullscreen');\n  }\n\n  save({ signal } = {}) {\n    if (signal?.aborted) return Promise.reject(aborted());\n    if (!this._available()) return Promise.reject(new Error('Scene capture is unavailable in this view.'));\n    if (this.pending) return Promise.reject(new Error('A screen capture is already being saved.'));\n    return new Promise((resolve, reject) => {\n      const request = { resolve, reject, signal, encoding: false, finished: false };\n      this.pending = request;\n      request.cancel = () => this._finish(request, aborted());\n      request.viewChanged = () => {\n        if (!this._available()) this._finish(request, new Error('Scene capture was canceled when the view changed.'));\n      };\n      signal?.addEventListener('abort', request.cancel, { once: true });\n      globalThis.document?.addEventListener('visibilitychange', request.viewChanged);\n      globalThis.window?.addEventListener('noclip:map-mode-change', request.viewChanged);\n      request.timer = setTimeout(() => this._finish(request, new Error('No scene frame is available. Please retry.')), this.timeoutMs);\n    });\n  }\n\n  frameCompleted(frame) {\n    const request = this.pending;\n    if (!request || request.finished || request.encoding) return;\n    if (!this._available()) {\n      this._finish(request, new Error('Scene capture is unavailable in this view.'));\n      return;\n    }\n    if (!frame?.submitted || frame.failed) return;\n    // HD publishes its displayed frame before this callback. Preparation still\n    // shows the native scene; capture exactly the canvas the user currently sees.\n    const hd = this.scene._hdControl;\n    const source = (typeof hd?.getDisplayedCaptureSource === 'function'\n      ? hd.getDisplayedCaptureSource() : hd?.enabled && hd.canvas?.hidden === false ? hd.canvas : null)\n      || this.scene._renderer.domElement;\n    const width = source.videoWidth || source.width, height = source.videoHeight || source.height;\n    if (!width || !height) {\n      this._finish(request, new Error('The scene canvas has no image to save.'));\n      return;\n    }\n    request.encoding = true;\n    let snapshot = null;\n    const release = () => { if (snapshot) snapshot.width = snapshot.height = 0; };\n    try {\n      let canvas = source;\n      if (typeof canvas.toBlob !== 'function') {\n        // Native HD video is already decoded. One requested local snapshot\n        // copies its displayed RGB without a continuing decode/presentation loop.\n        snapshot = document.createElement('canvas');\n        snapshot.width = width; snapshot.height = height;\n        const context = snapshot.getContext('2d', { alpha: false });\n        if (!context) throw new Error('Scene capture is unavailable in this browser.');\n        context.drawImage(source, 0, 0, width, height);\n        canvas = snapshot;\n      }\n      // toBlob snapshots the native canvas now, before\n      // preserveDrawingBuffer:false can discard its completed drawing buffer.\n      canvas.toBlob(blob => {\n        release();\n        request.encoding = false;\n        if (request.finished) {\n          if (this.pending === request) this.pending = null;\n          return;\n        }\n        if (!blob) { this._finish(request, new Error('The scene image could not be saved.')); return; }\n        try {\n          this.download(blob, `noclip-scene-${new Date().toISOString().replace(/[:.]/g, '-')}.png`);\n          this._finish(request);\n        } catch (error) { this._finish(request, error); }\n      }, 'image/png');\n    } catch (error) {\n      release();\n      request.encoding = false;\n      this._finish(request, error);\n    }\n  }\n\n  _finish(request, error) {\n    if (request.finished) return;\n    request.finished = true;\n    clearTimeout(request.timer);\n    request.signal?.removeEventListener('abort', request.cancel);\n    globalThis.document?.removeEventListener('visibilitychange', request.viewChanged);\n    globalThis.window?.removeEventListener('noclip:map-mode-change', request.viewChanged);\n    // A canceled browser encoder remains the sole admitted encoder until its\n    // actual callback settles; repeated menu actions cannot accumulate copies.\n    if (!request.encoding && this.pending === request) this.pending = null;\n    if (error) request.reject(error); else request.resolve();\n  }\n\n  dispose() {\n    this.disposed = true;\n    if (this.pending) this._finish(this.pending, aborted());\n    if (this.scene?._sceneCanvasCapture === this) this.scene._sceneCanvasCapture = null;\n  }\n}\n\nconst aborted = () => new DOMException('Scene capture canceled.', 'AbortError');\n\nexport function saveSceneCanvas(scene, options) {\n  const capture = scene._sceneCanvasCapture || (scene._sceneCanvasCapture = new SceneCanvasCapture(scene));\n  return capture.save(options);\n}\n\nfunction downloadScenePng(blob, filename) {\n  const url = URL.createObjectURL(blob);\n  const anchor = document.createElement('a');\n  anchor.href = url;\n  anchor.download = filename;\n  try {\n    document.body.appendChild(anchor);\n    anchor.click();\n  } finally {\n    // Match the drawing export's deferred object-URL retirement.\n    setTimeout(() => { anchor.remove(); URL.revokeObjectURL(url); }, 0);\n  }\n}\n","import { latLonToLocalDir, ellipsoidRadiusForLocalDir } from '../../modules/geometry-utils.js';\nimport { getDrawSystem } from './DrawSystem.js';\nimport { showMapActionMenu } from '../ui/MapActionMenu.js';\nimport { saveSceneCanvas } from '../capture/SceneCanvasCapture.js';\n\nconst SNAP_RADIUS_PX = 14;\nconst SELECT_RADIUS_PX = 20;\nconst FREEHAND_SAMPLE_PX = 4;\nconst CONTEXT_DRAG_THRESHOLD_PX = 6;\nconst CONTEXT_EVENT_SUPPRESSION_MS = 750;\n\nconst interactionNow = () => (\n  typeof performance !== 'undefined' && typeof performance.now === 'function'\n    ? performance.now()\n    : Date.now()\n);\n\nexport class DrawInteractionController {\n  constructor({ scene, system = getDrawSystem(), showActionMenu = showMapActionMenu } = {}) {\n    this.scene = scene;\n    this.system = system;\n    this._showActionMenu = showActionMenu;\n    this.canvas = scene?._renderer?.domElement || null;\n    this._drag = null;\n    this._freehandPointerId = null;\n    this._lastFreehand = null;\n    this._contextPointer = null;\n    this._contextEventSuppressedUntil = 0;\n    this._bound = false;\n    this._onPointerDown = (event) => this._pointerDown(event);\n    this._onPointerMove = (event) => this._pointerMove(event);\n    this._onPointerUp = (event) => this._pointerUp(event);\n    this._onDoubleClick = (event) => this._doubleClick(event);\n    this._onContextMenu = (event) => this._contextMenu(event);\n    this.bind();\n  }\n\n  bind() {\n    if (this._bound || !this.canvas) return;\n    this._bound = true;\n    this.canvas.addEventListener('pointerdown', this._onPointerDown, true);\n    window.addEventListener('pointermove', this._onPointerMove, true);\n    window.addEventListener('pointerup', this._onPointerUp, true);\n    window.addEventListener('pointercancel', this._onPointerUp, true);\n    this.canvas.addEventListener('dblclick', this._onDoubleClick, true);\n    this.canvas.addEventListener('contextmenu', this._onContextMenu, true);\n  }\n\n  dispose() {\n    if (!this._bound) return;\n    this._bound = false;\n    this.canvas?.removeEventListener('pointerdown', this._onPointerDown, true);\n    window.removeEventListener('pointermove', this._onPointerMove, true);\n    window.removeEventListener('pointerup', this._onPointerUp, true);\n    window.removeEventListener('pointercancel', this._onPointerUp, true);\n    this.canvas?.removeEventListener('dblclick', this._onDoubleClick, true);\n    this.canvas?.removeEventListener('contextmenu', this._onContextMenu, true);\n    this._contextPointer = null;\n    this._contextEventSuppressedUntil = 0;\n  }\n\n  _consume(event) {\n    event.preventDefault();\n    event.stopPropagation();\n    event.stopImmediatePropagation?.();\n  }\n\n  _pointerDown(event) {\n    if (Number(event.button) === 2) {\n      const x = Number(event.clientX);\n      const y = Number(event.clientY);\n      if (Number.isFinite(x) && Number.isFinite(y)) {\n        this._contextPointer = {\n          pointerId: Number(event.pointerId ?? 1),\n          startX: x,\n          startY: y,\n          lastX: x,\n          lastY: y,\n          dragged: false,\n        };\n      }\n      // Leave the event available to SurfaceController. Right-drag owns map\n      // movement there; this owner decides only whether the completed gesture\n      // may open the action wheel.\n      return;\n    }\n    if (!this.system.consumesSceneInput || Number(event.button) !== 0) return;\n    this._consume(event);\n    if (this.system.tool === 'select') {\n      const hit = this._nearestGeometry(event.clientX, event.clientY, SELECT_RADIUS_PX);\n      if (!hit) {\n        this.system.selectShape(null);\n        return;\n      }\n      this.system.selectShape(hit.shape.id);\n      if (!Number.isInteger(hit.vertexIndex)) return;\n      this._drag = {\n        pointerId: event.pointerId,\n        shapeId: hit.shape.id,\n        vertexIndex: hit.vertexIndex,\n        before: hit.shape,\n        moved: false,\n      };\n      this.canvas.setPointerCapture?.(event.pointerId);\n      return;\n    }\n    const picked = this._pick(event.clientX, event.clientY);\n    if (!picked) return;\n    const snapped = this._snap(picked, event.clientX, event.clientY);\n    this.system.addVertex(snapped);\n    if (this.system.tool === 'freehand') {\n      this._freehandPointerId = event.pointerId;\n      this._lastFreehand = { x: event.clientX, y: event.clientY };\n      this.canvas.setPointerCapture?.(event.pointerId);\n    }\n  }\n\n  _pointerMove(event) {\n    this._trackContextPointer(event);\n    if (!this.system.consumesSceneInput) return;\n    if (this._drag && this._drag.pointerId === event.pointerId) {\n      this._consume(event);\n      const picked = this._pick(event.clientX, event.clientY);\n      if (!picked) return;\n      this._drag.moved = true;\n      this.system.updateVertex(\n        this._drag.shapeId,\n        this._drag.vertexIndex,\n        this._snap(picked, event.clientX, event.clientY, this._drag),\n        { recordHistory: false, emitMutation: false },\n      );\n      return;\n    }\n    if (this._freehandPointerId === event.pointerId) {\n      const distance = Math.hypot(event.clientX - this._lastFreehand.x, event.clientY - this._lastFreehand.y);\n      if (distance < FREEHAND_SAMPLE_PX) return;\n      this._consume(event);\n      const picked = this._pick(event.clientX, event.clientY);\n      if (picked) this.system.addVertex(picked);\n      this._lastFreehand = { x: event.clientX, y: event.clientY };\n      return;\n    }\n    if (this.system.isDrawing && this.system.tool !== 'freehand') {\n      const picked = this._pick(event.clientX, event.clientY);\n      if (picked) this.system.setHoverVertex(this._snap(picked, event.clientX, event.clientY));\n    }\n  }\n\n  _pointerUp(event) {\n    if (this._contextPointer\n      && Number(event?.pointerId ?? 1) === this._contextPointer.pointerId) {\n      const cancelled = event?.type === 'pointercancel';\n      this._trackContextPointer(event, { cancelled });\n      const shouldOpen = !cancelled && !this._contextPointer.dragged;\n      this._contextPointer = null;\n      // Browsers dispatch `contextmenu` either before or after pointerup.\n      // Suppress that native event in both cases; stationary activation is\n      // owned exactly once by this completed pointer gesture.\n      this._contextEventSuppressedUntil = interactionNow()\n        + CONTEXT_EVENT_SUPPRESSION_MS;\n      if (shouldOpen) this._activateContextAction(event);\n    }\n    if (this._drag?.pointerId === event.pointerId) {\n      this._consume(event);\n      const drag = this._drag;\n      this._drag = null;\n      this.canvas.releasePointerCapture?.(event.pointerId);\n      if (drag.moved) {\n        const after = this.system.shapes.find((shape) => shape.id === drag.shapeId);\n        this.system.updateShape(drag.shapeId, drag.before, { recordHistory: false, emitMutation: false });\n        this.system.updateShape(drag.shapeId, after, { recordHistory: true, emitMutation: true });\n      }\n      return;\n    }\n    if (this._freehandPointerId === event.pointerId) {\n      this._consume(event);\n      this.canvas.releasePointerCapture?.(event.pointerId);\n      this._freehandPointerId = null;\n      this._lastFreehand = null;\n      if (this.system.vertices.length >= 2) this.system.commit();\n    }\n  }\n\n  _doubleClick(event) {\n    if (!this.system.consumesSceneInput) return;\n    if (!['line', 'polygon'].includes(this.system.tool)) return;\n    this._consume(event);\n    this.system.commit();\n  }\n\n  _contextMenu(event) {\n    this._consume(event);\n    // A mouse contextmenu is not an activation authority: on some browsers it\n    // fires at right-button press, before movement can classify a drag. The\n    // pointerup path above opens only a stationary gesture. Retain keyboard\n    // context-menu access when no mouse gesture recently owned the event.\n    if (this._contextPointer || interactionNow() <= this._contextEventSuppressedUntil) {\n      return;\n    }\n    this._activateContextAction(event);\n  }\n\n  _isCameraContextDragActive(event) {\n    const controller = this.scene?._surfaceController;\n    const pointerId = Number(event?.pointerId ?? 1);\n    return !!controller\n      && ((!!controller.geoNav?.active\n          && Number(controller.geoNav.pointerId) === pointerId)\n        || (!!controller.orbitViewPivot?.dragging\n          && Number(controller.orbitViewPivot.pointerId) === pointerId));\n  }\n\n  _trackContextPointer(event, { cancelled = false } = {}) {\n    const active = this._contextPointer;\n    if (!active || Number(event?.pointerId ?? 1) !== active.pointerId) return false;\n    const x = Number(event.clientX);\n    const y = Number(event.clientY);\n    if (!Number.isFinite(x) || !Number.isFinite(y)) {\n      if (cancelled) active.dragged = true;\n      return active.dragged;\n    }\n    const moved = x !== active.lastX || y !== active.lastY;\n    active.lastX = x;\n    active.lastY = y;\n    const dx = x - active.startX;\n    const dy = y - active.startY;\n    if (cancelled\n      || (moved && this._isCameraContextDragActive(event))\n      || dx * dx + dy * dy >= CONTEXT_DRAG_THRESHOLD_PX ** 2) {\n      active.dragged = true;\n    }\n    return active.dragged;\n  }\n\n  _activateContextAction(event) {\n    if (this.system.consumesSceneInput) {\n      if (this.system.isDrawing && this.system.vertices.length >= 2) this.system.commit();\n      else this.system.cancel();\n      return;\n    }\n    const target = this._pick(event.clientX, event.clientY);\n    if (!target) return;\n    this._showActionMenu({\n      clientX: event.clientX,\n      clientY: event.clientY,\n      lat: target.lat,\n      lon: target.lon,\n      onSaveCapture: (options) => saveSceneCanvas(this.scene, options),\n      onNavigate: ({ lat, lon }) => {\n        const controller = this.scene?._surfaceController;\n        if (!controller?.initializeSurfaceModeFromLatLon) return;\n        controller.initializeSurfaceModeFromLatLon(\n          lat,\n          lon,\n          null,\n          controller.surfaceState?.yaw ?? 0,\n          controller.surfaceState?.pitch ?? 0,\n        );\n      },\n    });\n  }\n\n  _pick(clientX, clientY) {\n    return this.scene?.getSurfaceTargetAtClient?.(clientX, clientY) || null;\n  }\n\n  _snap(picked, clientX, clientY, exclusion = null) {\n    if (!this.system.snapEnabled) return picked;\n    const hit = this._nearestVertex(clientX, clientY, SNAP_RADIUS_PX, exclusion);\n    return hit?.vertex ? { ...hit.vertex } : picked;\n  }\n\n  _nearestVertex(clientX, clientY, radiusPx, exclusion = null) {\n    const rect = this.canvas?.getBoundingClientRect?.();\n    const camera = this.scene?._camera;\n    const parent = this.scene?._triTree?.group;\n    if (!rect || !camera || !parent) return null;\n    let best = null;\n    let bestDistance = radiusPx;\n    for (const shape of this.system.shapes) {\n      const vertices = shape.kind === 'circle' && shape.center ? [shape.center] : (shape.vertices || []);\n      for (let vertexIndex = 0; vertexIndex < vertices.length; vertexIndex += 1) {\n        if (exclusion?.shapeId === shape.id && exclusion?.vertexIndex === vertexIndex) continue;\n        const vertex = vertices[vertexIndex];\n        const projected = this._projectVertex(vertex, rect, camera, parent);\n        if (!projected) continue;\n        const { x, y } = projected;\n        const distance = Math.hypot(clientX - x, clientY - y);\n        if (distance <= bestDistance) {\n          bestDistance = distance;\n          best = { shape, vertex, vertexIndex, distance };\n        }\n      }\n    }\n    return best;\n  }\n\n  _nearestGeometry(clientX, clientY, radiusPx) {\n    const vertex = this._nearestVertex(clientX, clientY, radiusPx);\n    if (vertex) return vertex;\n    const rect = this.canvas?.getBoundingClientRect?.();\n    const camera = this.scene?._camera;\n    const parent = this.scene?._triTree?.group;\n    if (!rect || !camera || !parent) return null;\n    let best = null;\n    let bestDistance = radiusPx;\n    for (const shape of this.system.shapes) {\n      const vertices = shape.kind === 'circle' && shape.center ? [shape.center] : (shape.vertices || []);\n      const screen = vertices.map((entry) => this._projectVertex(entry, rect, camera, parent)).filter(Boolean);\n      if (!screen.length) continue;\n      if (['polygon', 'rectangle'].includes(shape.kind) && pointInPolygon(clientX, clientY, screen)) {\n        return { shape, vertex: null, vertexIndex: null, distance: 0 };\n      }\n      for (let index = 1; index < screen.length; index += 1) {\n        const distance = pointSegmentDistance(clientX, clientY, screen[index - 1], screen[index]);\n        if (distance < bestDistance) { bestDistance = distance; best = { shape, vertex: null, vertexIndex: null, distance }; }\n      }\n      if (['polygon', 'rectangle'].includes(shape.kind) && screen.length > 2) {\n        const distance = pointSegmentDistance(clientX, clientY, screen.at(-1), screen[0]);\n        if (distance < bestDistance) { bestDistance = distance; best = { shape, vertex: null, vertexIndex: null, distance }; }\n      }\n    }\n    return best;\n  }\n\n  _projectVertex(vertex, rect, camera, parent) {\n    const direction = latLonToLocalDir(vertex.lat, vertex.lon);\n    const radius = Number(vertex.surfaceRadius) || ellipsoidRadiusForLocalDir(direction);\n    const world = direction.clone().multiplyScalar(radius + 3);\n    parent.localToWorld(world);\n    const projected = world.project(camera);\n    if (projected.z < -1 || projected.z > 1) return null;\n    return {\n      x: rect.left + (projected.x + 1) * 0.5 * rect.width,\n      y: rect.top + (1 - projected.y) * 0.5 * rect.height,\n    };\n  }\n}\n\nfunction pointSegmentDistance(x, y, a, b) {\n  const dx = b.x - a.x;\n  const dy = b.y - a.y;\n  if (dx === 0 && dy === 0) return Math.hypot(x - a.x, y - a.y);\n  const t = Math.max(0, Math.min(1, ((x - a.x) * dx + (y - a.y) * dy) / (dx * dx + dy * dy)));\n  return Math.hypot(x - (a.x + t * dx), y - (a.y + t * dy));\n}\n\nfunction pointInPolygon(x, y, polygon) {\n  let inside = false;\n  for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {\n    const a = polygon[i], b = polygon[j];\n    const crossed = ((a.y > y) !== (b.y > y))\n      && (x < ((b.x - a.x) * (y - a.y)) / ((b.y - a.y) || Number.EPSILON) + a.x);\n    if (crossed) inside = !inside;\n  }\n  return inside;\n}\n\nexport default DrawInteractionController;\n","import { getAuthService } from '../auth/AuthService.js';\nimport { getBackendApiBase } from '../shared/backend.js';\n\nconst json = async (response) => {\n  const payload = await response.json().catch(() => ({}));\n  if (!response.ok) {\n    const error = new Error(payload.message || payload.error || `Drawing API failed (${response.status})`);\n    error.code = payload.error || 'DRAWING_API_ERROR';\n    error.status = response.status;\n    error.details = payload.details || {};\n    throw error;\n  }\n  return payload;\n};\n\nexport class DrawingProjectApiService {\n  constructor({ authService = getAuthService(), apiBase = getBackendApiBase() } = {}) {\n    this.auth = authService;\n    this.base = `${String(apiBase).replace(/\\/$/, '')}/v1/drawing-projects`;\n  }\n\n  get authenticated() { return this.auth?.getState?.()?.isAuthenticated === true; }\n\n  request(path = '', options = {}) {\n    return this.auth.authenticatedFetch(`${this.base}${path}`, options);\n  }\n\n  async createProject(input) {\n    return (await json(await this.request('', { method: 'POST', body: JSON.stringify(input) }))).snapshot;\n  }\n\n  async listProjects({ status, limit = 100, offset = 0 } = {}) {\n    const query = new URLSearchParams({ limit: String(limit), offset: String(offset) });\n    if (status) query.set('status', status);\n    return json(await this.request(`?${query}`));\n  }\n\n  async getProject(projectId, { revision, bbox } = {}) {\n    const query = new URLSearchParams();\n    if (Number.isInteger(revision)) query.set('revision', String(revision));\n    if (Array.isArray(bbox)) query.set('bbox', bbox.join(','));\n    const suffix = query.size ? `?${query}` : '';\n    return (await json(await this.request(`/${encodeURIComponent(projectId)}${suffix}`))).snapshot;\n  }\n\n  async updateProject(projectId, patch) {\n    return (await json(await this.request(`/${encodeURIComponent(projectId)}`, {\n      method: 'PATCH', body: JSON.stringify(patch),\n    }))).project;\n  }\n\n  async deleteProject(projectId) {\n    const response = await this.request(`/${encodeURIComponent(projectId)}`, { method: 'DELETE' });\n    if (!response.ok) await json(response);\n  }\n\n  async applyEdits(projectId, batch) {\n    return (await json(await this.request(`/${encodeURIComponent(projectId)}/edits`, {\n      method: 'POST', body: JSON.stringify(batch),\n    }))).snapshot;\n  }\n\n  async checkpoint(projectId, input) {\n    return (await json(await this.request(`/${encodeURIComponent(projectId)}/checkpoints`, {\n      method: 'POST', body: JSON.stringify(input),\n    }))).snapshot;\n  }\n\n  async listRevisions(projectId) {\n    return (await json(await this.request(`/${encodeURIComponent(projectId)}/revisions`))).revisions || [];\n  }\n\n  async restoreRevision(projectId, revision, clientMutationId) {\n    return (await json(await this.request(\n      `/${encodeURIComponent(projectId)}/revisions/${Number(revision)}/restore`,\n      { method: 'POST', body: JSON.stringify({ clientMutationId }) },\n    ))).snapshot;\n  }\n\n  async previewFile(file, { format = '', latColumn = '', lonColumn = '', wktColumn = '' } = {}) {\n    const query = new URLSearchParams({ format, latColumn, lonColumn, wktColumn });\n    const form = new FormData();\n    form.append('file', file, file.name);\n    return (await json(await this.request(`/imports/preview?${query}`, {\n      method: 'POST', body: form, includeContentType: false,\n    }))).preview;\n  }\n\n  async previewArcGis(input) {\n    return (await json(await this.request('/imports/arcgis/preview', {\n      method: 'POST', body: JSON.stringify(input),\n    }))).preview;\n  }\n\n  async confirmImport(projectId, input) {\n    return (await json(await this.request(`/${encodeURIComponent(projectId)}/imports`, {\n      method: 'POST', body: JSON.stringify(input),\n    }))).snapshot;\n  }\n\n  async evaluateMasks(projectId, geometry) {\n    return json(await this.request(`/${encodeURIComponent(projectId)}/masks/evaluate`, {\n      method: 'POST', body: JSON.stringify({ geometry }),\n    }));\n  }\n\n  async exportProject(projectId, { format = 'geojson', revision, polygonAsTrack = false } = {}) {\n    const query = new URLSearchParams({ format, polygonAsTrack: String(polygonAsTrack) });\n    if (Number.isInteger(revision)) query.set('revision', String(revision));\n    const response = await this.request(`/${encodeURIComponent(projectId)}/export?${query}`);\n    if (!response.ok) await json(response);\n    return {\n      blob: await response.blob(),\n      filename: response.headers.get('content-disposition')?.match(/filename=\"([^\"]+)\"/)?.[1]\n        || `drawing-project.${format}`,\n    };\n  }\n\n  async exportToOverlay(projectId, input = {}) {\n    return (await json(await this.request(`/${encodeURIComponent(projectId)}/export-overlay`, {\n      method: 'POST', body: JSON.stringify(input),\n    }))).export;\n  }\n}\n\nlet instance = null;\nexport function getDrawingProjectApiService() {\n  if (!instance) instance = new DrawingProjectApiService();\n  return instance;\n}\n","const DB_NAME = 'noclip-drawing-projects';\nconst DB_VERSION = 1;\nconst SNAPSHOTS = 'snapshots';\nconst OUTBOX = 'outbox';\n\nconst memory = { snapshots: new Map(), outbox: new Map() };\n\nconst requestValue = (request) => new Promise((resolve, reject) => {\n  request.onsuccess = () => resolve(request.result);\n  request.onerror = () => reject(request.error);\n});\n\nexport class DrawingProjectStore {\n  constructor({ indexedDBImpl = globalThis.indexedDB } = {}) {\n    this.indexedDB = indexedDBImpl;\n    this._db = null;\n  }\n\n  async open() {\n    if (!this.indexedDB || this._db) return this._db;\n    const request = this.indexedDB.open(DB_NAME, DB_VERSION);\n    request.onupgradeneeded = () => {\n      const db = request.result;\n      if (!db.objectStoreNames.contains(SNAPSHOTS)) db.createObjectStore(SNAPSHOTS, { keyPath: 'projectId' });\n      if (!db.objectStoreNames.contains(OUTBOX)) {\n        const store = db.createObjectStore(OUTBOX, { keyPath: 'clientMutationId' });\n        store.createIndex('projectId', 'projectId');\n        store.createIndex('createdAt', 'createdAt');\n      }\n    };\n    this._db = await requestValue(request);\n    return this._db;\n  }\n\n  async putSnapshot(snapshot) {\n    if (!snapshot?.project?.projectId) return;\n    const value = { projectId: snapshot.project.projectId, snapshot, cachedAt: Date.now() };\n    const db = await this.open();\n    if (!db) { memory.snapshots.set(value.projectId, value); return; }\n    await requestValue(db.transaction(SNAPSHOTS, 'readwrite').objectStore(SNAPSHOTS).put(value));\n  }\n\n  async getSnapshot(projectId) {\n    const db = await this.open();\n    const value = db\n      ? await requestValue(db.transaction(SNAPSHOTS).objectStore(SNAPSHOTS).get(projectId))\n      : memory.snapshots.get(projectId);\n    return value?.snapshot || null;\n  }\n\n  async listSnapshots() {\n    const db = await this.open();\n    const values = db\n      ? await requestValue(db.transaction(SNAPSHOTS).objectStore(SNAPSHOTS).getAll())\n      : [...memory.snapshots.values()];\n    return values.sort((a, b) => b.cachedAt - a.cachedAt).map((value) => value.snapshot);\n  }\n\n  async enqueue(entry) {\n    const value = { ...entry, createdAt: entry.createdAt || Date.now(), attempts: entry.attempts || 0 };\n    const db = await this.open();\n    if (!db) { memory.outbox.set(value.clientMutationId, value); return value; }\n    await requestValue(db.transaction(OUTBOX, 'readwrite').objectStore(OUTBOX).put(value));\n    return value;\n  }\n\n  async listOutbox(projectId = null) {\n    const db = await this.open();\n    const values = db\n      ? await requestValue(db.transaction(OUTBOX).objectStore(OUTBOX).getAll())\n      : [...memory.outbox.values()];\n    return values\n      .filter((value) => !projectId || value.projectId === projectId)\n      .sort((a, b) => a.createdAt - b.createdAt);\n  }\n\n  async removeOutbox(clientMutationId) {\n    const db = await this.open();\n    if (!db) { memory.outbox.delete(clientMutationId); return; }\n    await requestValue(db.transaction(OUTBOX, 'readwrite').objectStore(OUTBOX).delete(clientMutationId));\n  }\n\n  async updateOutbox(entry) { return this.enqueue(entry); }\n}\n\nlet instance = null;\nexport function getDrawingProjectStore() {\n  if (!instance) instance = new DrawingProjectStore();\n  return instance;\n}\n","import { getAuthService } from '../auth/AuthService.js';\nimport { getDrawSystem } from './DrawSystem.js';\nimport { bufferShape, combineShapes, geoJSONFeatureToShape, shapeToDrawingMutation } from './DrawingGeometry.js';\nimport { getDrawingProjectApiService } from './DrawingProjectApiService.js';\nimport { getDrawingProjectStore } from './DrawingProjectStore.js';\n\nconst uuid = () => globalThis.crypto?.randomUUID?.()\n  || `drawing-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;\n\nfunction dispatch(name, detail) {\n  if (typeof document === 'undefined' || typeof CustomEvent === 'undefined') return;\n  document.dispatchEvent(new CustomEvent(`noclip:drawing-project:${name}`, { detail }));\n}\n\nexport class DrawingProjectManager {\n  constructor({\n    system = getDrawSystem(),\n    api = getDrawingProjectApiService(),\n    store = getDrawingProjectStore(),\n    auth = getAuthService(),\n  } = {}) {\n    this.system = system;\n    this.api = api;\n    this.store = store;\n    this.auth = auth;\n    this.projects = [];\n    this.snapshot = null;\n    this.syncState = 'idle';\n    this.lastError = null;\n    this._featureMutations = new Map();\n    this._groupMutations = new Map();\n    this._flushTimer = null;\n    this._flushPromise = null;\n    this._started = false;\n    this._onMutation = (event) => this._queueShapeMutation(event.detail);\n    this._onOnline = () => this.drainOutbox().catch(() => {});\n  }\n\n  get currentProjectId() { return this.snapshot?.project?.projectId || null; }\n  get hasPendingChanges() { return this._featureMutations.size + this._groupMutations.size > 0; }\n\n  async start() {\n    if (this._started) return this;\n    this._started = true;\n    document.addEventListener('noclip:draw:mutation', this._onMutation);\n    globalThis.addEventListener?.('online', this._onOnline);\n    this.projects = (await this.store.listSnapshots()).map((entry) => entry.project);\n    this._emitState();\n    this.auth?.subscribe?.((state) => {\n      if (state.isAuthenticated) this.refreshProjects().then(() => this.drainOutbox()).catch(() => {});\n    });\n    if (this.api.authenticated) {\n      await this.refreshProjects().catch((error) => this._setError(error));\n      await this.drainOutbox().catch((error) => this._setError(error));\n    }\n    return this;\n  }\n\n  dispose() {\n    document.removeEventListener('noclip:draw:mutation', this._onMutation);\n    globalThis.removeEventListener?.('online', this._onOnline);\n  }\n\n  async refreshProjects() {\n    if (!this.api.authenticated) return this.projects;\n    const result = await this.api.listProjects();\n    this.projects = result.projects || result.items || [];\n    this._emitState();\n    return this.projects;\n  }\n\n  async createProject({ name = 'Untitled drawing project', description = '' } = {}) {\n    this._requireAuth();\n    await this.flush();\n    const snapshot = await this.api.createProject({ name, description, metadata: { schema: 'noclip-drawing-project/v1' } });\n    await this._acceptSnapshot(snapshot, { open: true });\n    await this.refreshProjects();\n    return snapshot;\n  }\n\n  async openProject(projectId) {\n    if (!projectId) throw new Error('Choose a drawing project.');\n    await this.flush();\n    let snapshot = null;\n    if (this.api.authenticated) snapshot = await this.api.getProject(projectId).catch(() => null);\n    snapshot ||= await this.store.getSnapshot(projectId);\n    if (!snapshot) throw new Error('Drawing project is unavailable offline.');\n    await this._acceptSnapshot(snapshot, { open: true });\n    await this.drainOutbox(projectId).catch((error) => this._setError(error));\n    return snapshot;\n  }\n\n  async closeProject() {\n    await this.flush({ immediate: true });\n    this.snapshot = null;\n    this.system.closeDraft();\n    this.syncState = 'idle';\n    this._emitState();\n  }\n\n  async renameProject(patch) {\n    this._requireProject();\n    this._requireAuth();\n    const project = await this.api.updateProject(this.currentProjectId, patch);\n    this.snapshot.project = project;\n    this.system.updateProjectRecord(project);\n    await this.store.putSnapshot(this.snapshot);\n    await this.refreshProjects();\n    return project;\n  }\n\n  async deleteProject(projectId = this.currentProjectId) {\n    this._requireAuth();\n    await this.api.deleteProject(projectId);\n    if (projectId === this.currentProjectId) {\n      this.snapshot = null;\n      this.system.closeDraft();\n    }\n    await this.refreshProjects();\n  }\n\n  addGroup({ name = 'New group', parentGroupId = null } = {}) {\n    this._requireProject();\n    const group = {\n      groupId: uuid(), projectId: this.currentProjectId, parentGroupId,\n      name, sortOrder: this.system.groups.length, visible: true, locked: false,\n      style: {}, revision: this.snapshot.revision,\n    };\n    this.system.setGroups([...this.system.groups, group]);\n    this.system.setActiveGroup(group.groupId);\n    this._queueGroupMutation({ op: 'create', ...group });\n    return group;\n  }\n\n  updateGroup(groupId, patch) {\n    const groups = this.system.groups;\n    const index = groups.findIndex((entry) => entry.groupId === groupId);\n    if (index < 0) return null;\n    groups[index] = { ...groups[index], ...patch, groupId };\n    this.system.setGroups(groups);\n    this._queueGroupMutation({ op: 'update', groupId, ...patch });\n    return groups[index];\n  }\n\n  deleteGroup(groupId) {\n    const current = this.system.groups;\n    const removed = new Set([groupId]);\n    let changed = true;\n    while (changed) {\n      changed = false;\n      for (const group of current) {\n        if (group.parentGroupId && removed.has(group.parentGroupId) && !removed.has(group.groupId)) {\n          removed.add(group.groupId);\n          changed = true;\n        }\n      }\n    }\n    const groups = current.filter((entry) => !removed.has(entry.groupId));\n    for (const shape of this.system.shapes.filter((entry) => removed.has(entry.groupId))) {\n      this.system.updateShape(shape.id, { groupId: null });\n    }\n    this.system.setGroups(groups);\n    for (const removedId of [...removed].reverse()) this._queueGroupMutation({ op: 'delete', groupId: removedId });\n  }\n\n  async save(message = 'Saved drawing project') {\n    this._requireProject();\n    this._requireAuth();\n    await this.flush({ immediate: true });\n    const snapshot = await this.api.checkpoint(this.currentProjectId, {\n      baseRevision: this.snapshot.revision,\n      clientMutationId: uuid(),\n      message,\n    });\n    await this._acceptSnapshot(snapshot);\n    await this.refreshProjects();\n    return snapshot;\n  }\n\n  async listRevisions() {\n    this._requireProject();\n    return this.api.listRevisions(this.currentProjectId);\n  }\n\n  async restoreRevision(revision) {\n    this._requireProject();\n    await this.flush({ immediate: true });\n    return this._acceptSnapshot(\n      await this.api.restoreRevision(this.currentProjectId, revision, uuid()),\n      { open: true },\n    );\n  }\n\n  async previewFile(file, options) { return this.api.previewFile(file, options); }\n  async previewArcGis(input) { return this.api.previewArcGis(input); }\n\n  async confirmImport(preview, groupName = 'Imported features') {\n    this._requireProject();\n    await this.flush({ immediate: true });\n    const snapshot = await this.api.confirmImport(this.currentProjectId, {\n      baseRevision: this.snapshot.revision,\n      clientMutationId: uuid(),\n      groupName,\n      source: { format: preview.format, warnings: preview.warnings || [] },\n      featureCollection: preview.featureCollection,\n    });\n    return this._acceptSnapshot(snapshot, { open: true });\n  }\n\n  async exportProject(options) {\n    this._requireProject();\n    await this.flush({ immediate: true });\n    return this.api.exportProject(this.currentProjectId, options);\n  }\n\n  async exportToOverlay(input = {}) {\n    this._requireProject();\n    if (this.snapshot.project.savedRevision !== this.snapshot.revision) await this.save('Checkpoint before overlay export');\n    const result = await this.api.exportToOverlay(this.currentProjectId, input);\n    dispatch('overlay-exported', result);\n    return result;\n  }\n\n  async evaluateMasks(geometry) {\n    this._requireProject();\n    await this.flush({ immediate: true });\n    return this.api.evaluateMasks(this.currentProjectId, geometry);\n  }\n\n  applySpatialOperation(operation, shapeIds, options = {}) {\n    const shapes = shapeIds.map((shapeId) => this.system.shapes.find((entry) => entry.id === shapeId)).filter(Boolean);\n    let result;\n    if (operation === 'buffer') {\n      if (shapes.length !== 1) throw new Error('Buffer requires exactly one feature.');\n      result = bufferShape(shapes[0], Number(options.distanceM));\n    } else result = combineShapes(shapes, operation);\n    if (!result) throw new Error(`${operation} produced an empty geometry.`);\n    const shape = geoJSONFeatureToShape(result, {\n      groupId: options.groupId || this.system.activeGroupId,\n      label: options.label || `${operation} result`,\n    });\n    this.system._insertShape(shape, { recordHistory: true, emitMutation: true });\n    return shape;\n  }\n\n  _queueShapeMutation(detail) {\n    if (!detail?.shape || !this.currentProjectId) return;\n    const shape = detail.shape;\n    const existing = this._featureMutations.get(shape.id);\n    if (detail.action === 'delete' && existing?.op === 'create') {\n      this._featureMutations.delete(shape.id);\n    } else {\n      const op = existing?.op === 'create' ? 'create' : detail.action;\n      this._featureMutations.set(shape.id, detail.action === 'delete'\n        ? { op: 'delete', featureId: shape.id }\n        : shapeToDrawingMutation(shape, op));\n    }\n    this._scheduleFlush();\n    this._cacheLocal();\n  }\n\n  _queueGroupMutation(mutation) {\n    const existing = this._groupMutations.get(mutation.groupId);\n    if (mutation.op === 'delete' && existing?.op === 'create') this._groupMutations.delete(mutation.groupId);\n    else this._groupMutations.set(mutation.groupId, { ...existing, ...mutation, op: existing?.op === 'create' ? 'create' : mutation.op });\n    this._scheduleFlush();\n    this._cacheLocal();\n  }\n\n  _scheduleFlush() {\n    clearTimeout(this._flushTimer);\n    this._flushTimer = setTimeout(() => this.flush().catch((error) => this._setError(error)), 450);\n    this.syncState = 'pending';\n    this._emitState();\n  }\n\n  async flush({ immediate = false } = {}) {\n    clearTimeout(this._flushTimer);\n    if (this._flushPromise) await this._flushPromise;\n    if (!this.hasPendingChanges) return this.snapshot;\n    const features = [...this._featureMutations.values()];\n    const groups = [...this._groupMutations.values()];\n    this._featureMutations.clear();\n    this._groupMutations.clear();\n    const entry = {\n      projectId: this.currentProjectId,\n      clientMutationId: uuid(),\n      batch: { baseRevision: this.snapshot.revision, clientMutationId: '', message: 'Edited drawing project', groups, features },\n    };\n    entry.batch.clientMutationId = entry.clientMutationId;\n    await this.store.enqueue(entry);\n    if (!this.api.authenticated) {\n      this.syncState = 'offline';\n      this._emitState();\n      return this.snapshot;\n    }\n    this.syncState = 'syncing';\n    this._emitState();\n    this._flushPromise = this._sendOutboxEntry(entry)\n      .catch((error) => {\n        this.syncState = globalThis.navigator?.onLine === false ? 'offline' : 'error';\n        this._setError(error);\n        return this.snapshot;\n      })\n      .finally(() => { this._flushPromise = null; });\n    const result = await this._flushPromise;\n    if (immediate && this.hasPendingChanges) return this.flush({ immediate: true });\n    return result;\n  }\n\n  async drainOutbox(projectId = null) {\n    if (!this.api.authenticated) return;\n    for (const entry of await this.store.listOutbox(projectId)) await this._sendOutboxEntry(entry);\n    if (!this.hasPendingChanges) {\n      this.syncState = 'synced';\n      this._emitState();\n    }\n  }\n\n  async _sendOutboxEntry(entry) {\n    const active = this.currentProjectId === entry.projectId;\n    const baseSnapshot = active && this.snapshot\n      ? this.snapshot\n      : await this.api.getProject(entry.projectId);\n    const batch = { ...entry.batch, baseRevision: baseSnapshot.revision, clientMutationId: entry.clientMutationId };\n    try {\n      const snapshot = await this.api.applyEdits(entry.projectId, batch);\n      await this.store.removeOutbox(entry.clientMutationId);\n      if (active) await this._acceptSnapshot(snapshot);\n      else await this._storeBackgroundSnapshot(snapshot);\n      this.syncState = 'synced';\n      this.lastError = null;\n      this._emitState();\n      return snapshot;\n    } catch (error) {\n      if (error.code === 'REVISION_CONFLICT') {\n        const remote = await this.api.getProject(entry.projectId);\n        entry.batch.baseRevision = remote.revision;\n        await this.store.updateOutbox({ ...entry, attempts: (entry.attempts || 0) + 1 });\n        const snapshot = await this.api.applyEdits(entry.projectId, { ...entry.batch, clientMutationId: entry.clientMutationId });\n        await this.store.removeOutbox(entry.clientMutationId);\n        if (active) await this._acceptSnapshot(snapshot);\n        else await this._storeBackgroundSnapshot(snapshot);\n        return snapshot;\n      }\n      await this.store.updateOutbox({ ...entry, attempts: (entry.attempts || 0) + 1, lastError: error.message });\n      throw error;\n    }\n  }\n\n  async _storeBackgroundSnapshot(snapshot) {\n    await this.store.putSnapshot(snapshot);\n    const project = snapshot.project;\n    if (!this.projects.some((entry) => entry.projectId === project.projectId)) this.projects.unshift(project);\n    else this.projects = this.projects.map((entry) => entry.projectId === project.projectId ? project : entry);\n    this._emitState();\n    return snapshot;\n  }\n\n  async _acceptSnapshot(snapshot, { open = false } = {}) {\n    if (!snapshot?.project?.projectId) return null;\n    this.snapshot = snapshot;\n    if (open) this.system.beginDraft(snapshot);\n    else if (!this.system.isDrawing && !this.hasPendingChanges) this.system.loadSnapshot(snapshot, { emitChange: false });\n    else {\n      this.system.updateProjectRecord(snapshot.project);\n      this.system.setGroups(snapshot.groups);\n    }\n    await this.store.putSnapshot(snapshot);\n    if (!this.projects.some((project) => project.projectId === snapshot.project.projectId)) this.projects.unshift(snapshot.project);\n    else this.projects = this.projects.map((project) => project.projectId === snapshot.project.projectId ? snapshot.project : project);\n    this._emitState();\n    return snapshot;\n  }\n\n  async _cacheLocal() {\n    if (!this.snapshot) return;\n    const features = this.system.shapes.map((shape) => {\n      const mutation = shapeToDrawingMutation(shape, 'create');\n      return {\n        featureId: shape.id, projectId: this.currentProjectId, groupId: shape.groupId,\n        kind: mutation.kind, geometry: mutation.geometry, label: mutation.label,\n        description: mutation.description, spatialRole: mutation.spatialRole,\n        attributes: mutation.attributes, style: mutation.style, measurements: shape.properties?.measurements || {},\n        altitudeMode: mutation.altitudeMode, elevationM: mutation.elevationM, revision: this.snapshot.revision,\n      };\n    });\n    await this.store.putSnapshot({ ...this.snapshot, groups: this.system.groups, features });\n  }\n\n  _requireAuth() {\n    if (!this.api.authenticated) throw new Error('Sign in to create and synchronize drawing projects.');\n  }\n  _requireProject() {\n    if (!this.currentProjectId) throw new Error('Create or open a drawing project first.');\n  }\n  _setError(error) {\n    this.lastError = error;\n    this.syncState = 'error';\n    this._emitState();\n  }\n  _emitState() {\n    dispatch('state', {\n      projects: this.projects,\n      snapshot: this.snapshot,\n      syncState: this.syncState,\n      pending: this.hasPendingChanges,\n      error: this.lastError?.message || null,\n    });\n  }\n}\n\nlet instance = null;\nexport function getDrawingProjectManager() {\n  if (!instance) instance = new DrawingProjectManager();\n  return instance;\n}\n","/** Full drawing-project workspace mounted by the desktop sidebar or HUD dock. */\nimport { getDrawSystem } from '../draw/DrawSystem.js';\nimport { getDrawingProjectManager } from '../draw/DrawingProjectManager.js';\nimport { shapeMeasurements } from '../draw/DrawingGeometry.js';\nimport { ensureHudPanelStyles } from './HudSlots.js';\n\nconst TOOLS = [\n  ['select', 'Select / edit', '⌖'], ['point', 'Point', '•'], ['annotation', 'Annotation', 'T'],\n  ['line', 'Path', '╱'], ['polygon', 'Area / mask', '▱'], ['circle', 'Circle', '○'],\n  ['rectangle', 'Rectangle', '▭'], ['freehand', 'Freehand', '✎'],\n];\n\nconst FORMATS = ['geojson', 'ndjson', 'kml', 'kmz', 'gpkg', 'shapefile', 'gpx', 'csv'];\n\nlet stylesReady = false;\nfunction ensureStyles() {\n  if (stylesReady || typeof document === 'undefined') return;\n  stylesReady = true;\n  const style = document.createElement('style');\n  style.textContent = `\n    .nc-draw-toolbar{width:100%;max-width:100%;color:#fff;background:#090909!important;border:1px solid rgba(255,255,255,.15);overflow:auto}\n    .nc-draw-workspace{display:grid;gap:10px;padding:8px}.nc-draw-block{display:grid;gap:6px;padding:8px;border:1px solid rgba(255,255,255,.12);background:#101010}\n    .nc-draw-block>summary{cursor:pointer;font:600 11px/1.3 ui-monospace,monospace;text-transform:uppercase;letter-spacing:.08em;color:#facc15}\n    .nc-draw-row{display:flex;gap:6px;align-items:center;flex-wrap:wrap}.nc-draw-row--grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr))}\n    .nc-draw-toolbar input,.nc-draw-toolbar select,.nc-draw-toolbar textarea{min-width:0;width:100%;box-sizing:border-box;background:#050505;color:#fff;border:1px solid rgba(255,255,255,.22);border-radius:3px;padding:7px;font:11px/1.35 ui-monospace,monospace}\n    .nc-draw-toolbar textarea{resize:vertical;min-height:52px}.nc-draw-toolbar button{background:#151515;color:#fff;border:1px solid rgba(255,255,255,.2);border-radius:3px;padding:6px 8px;font:600 10px/1.2 ui-monospace,monospace;cursor:pointer}\n    .nc-draw-toolbar button:hover,.nc-draw-toolbar button.active{border-color:#facc15;color:#facc15}.nc-draw-toolbar button:disabled{opacity:.35;cursor:not-allowed}\n    .nc-draw-tool{min-height:34px}.nc-draw-tool span{display:block;font-size:8px;color:#aaa;margin-top:2px}.nc-draw-status{font:10px/1.3 ui-monospace,monospace;color:#aaa}.nc-draw-status[data-state=error]{color:#ff6b6b}.nc-draw-status[data-state=synced]{color:#8dd9a5}\n    .nc-draw-list{display:grid;gap:4px;max-height:170px;overflow:auto}.nc-draw-list-item{display:grid;grid-template-columns:minmax(0,1fr) auto auto;gap:4px;align-items:center;background:#0b0b0b;padding:4px;border:1px solid rgba(255,255,255,.1)}\n    .nc-draw-list-item.is-active{border-left:3px solid #facc15}.nc-draw-list-item__name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font:10px/1.3 ui-monospace,monospace}\n    .nc-draw-measurements{font:10px/1.45 ui-monospace,monospace;color:#ccc;white-space:pre-wrap}.nc-draw-preview{font:10px/1.4 ui-monospace,monospace;color:#bbb;max-height:90px;overflow:auto}\n  `;\n  document.head.appendChild(style);\n}\n\nconst text = (value) => String(value ?? '').trim();\nconst formatDistance = (value) => Number(value) >= 1000 ? `${(value / 1000).toFixed(2)} km` : `${Number(value || 0).toFixed(1)} m`;\nconst formatArea = (value) => Number(value) >= 1e6 ? `${(value / 1e6).toFixed(3)} km²` : `${Number(value || 0).toFixed(1)} m²`;\n\nlet instance = null;\nexport function getDrawToolbar(opts) {\n  if (!instance) instance = new DrawToolbar(opts);\n  return instance;\n}\n\nexport class DrawToolbar {\n  constructor({\n    container,\n    mode = 'embedded',\n    system = getDrawSystem(),\n    manager = getDrawingProjectManager(),\n  } = {}) {\n    this.mode = mode === 'floating' ? 'floating' : 'embedded';\n    this.container = container || (this.mode === 'floating' ? document.body : null);\n    this.system = system;\n    this.manager = manager;\n    this._preview = null;\n    this._build();\n    this._bind();\n    void this.manager.start().then(() => this._renderState()).catch((error) => this._message(error.message, true));\n  }\n\n  get element() { return this._el; }\n  mount(container) { if (container && this._el.parentNode !== container) container.appendChild(this._el); }\n\n  _build() {\n    ensureHudPanelStyles();\n    ensureStyles();\n    const el = document.createElement('div');\n    el.className = `nc-draw-toolbar nca-hud-panel ${this.mode === 'floating' ? 'nca-hud-panel--mid-left' : 'nca-hud-panel--embedded'}`;\n    el.innerHTML = `\n      <div class=\"nc-draw-workspace\">\n        <div class=\"nc-draw-row\"><strong style=\"font:700 12px ui-monospace,monospace\">DRAW PROJECTS</strong><span class=\"nc-draw-status\" data-role=\"status\">Idle</span></div>\n        <section class=\"nc-draw-block\">\n          <select data-role=\"project\" aria-label=\"Drawing project\"><option value=\"\">Select a project</option></select>\n          <div class=\"nc-draw-row\"><input data-role=\"new-name\" placeholder=\"New project name\" value=\"Untitled project\"><button data-action=\"create\">Create draft</button><button data-action=\"save\">Save checkpoint</button></div>\n          <div class=\"nc-draw-row\"><input data-role=\"project-name\" placeholder=\"Project name\"><button data-action=\"rename\">Update details</button><button data-action=\"close\">Close</button><button data-action=\"delete-project\">Delete</button></div>\n          <textarea data-role=\"project-description\" placeholder=\"Purpose, scope, provenance…\"></textarea>\n        </section>\n        <section class=\"nc-draw-block\">\n          <div class=\"nc-draw-row nc-draw-row--grid\">${TOOLS.map(([id, label, glyph]) => `<button class=\"nc-draw-tool\" data-tool=\"${id}\" title=\"${label}\">${glyph}<span>${label}</span></button>`).join('')}</div>\n          <div class=\"nc-draw-row\"><button data-action=\"undo\">Undo</button><button data-action=\"redo\">Redo</button><button data-action=\"finish\">Finish</button><button data-action=\"cancel\">Exit tool</button><label style=\"font:10px ui-monospace,monospace\"><input type=\"checkbox\" data-role=\"snap\" checked style=\"width:auto\"> Snap vertices</label></div>\n          <div class=\"nc-draw-status\">Click the visible surface to add vertices. Double-click/Enter finishes paths and areas; drag selected vertices to edit.</div>\n        </section>\n        <details class=\"nc-draw-block\" open><summary>Project groups</summary>\n          <div class=\"nc-draw-row\"><input data-role=\"group-name\" placeholder=\"Group name\"><button data-action=\"add-group\">Add group</button></div><div class=\"nc-draw-list\" data-role=\"groups\"></div>\n        </details>\n        <details class=\"nc-draw-block\" open><summary>Selected feature</summary>\n          <div class=\"nc-draw-status\" data-role=\"selected-empty\">Select a feature to edit its geometry and metadata.</div>\n          <div data-role=\"inspector\" hidden>\n            <input data-role=\"feature-label\" placeholder=\"Label\"><textarea data-role=\"feature-description\" placeholder=\"Annotation / notes\"></textarea>\n            <div class=\"nc-draw-row\"><select data-role=\"feature-group\"></select><select data-role=\"spatial-role\"><option value=\"none\">Geometry</option><option value=\"include\">Include mask</option><option value=\"exclude\">Exclude mask</option><option value=\"clip\">Clip mask</option></select></div>\n            <div class=\"nc-draw-row\"><input data-role=\"asset-anchor-ids\" placeholder=\"3D asset IDs, comma separated\"><select data-role=\"asset-anchor-mount\" aria-label=\"3D asset attachment\"><option value=\"centroid\">Assets at centroid</option><option value=\"vertices\">Assets at vertices</option><option value=\"path\">Assets along path</option><option value=\"endpoint\">Assets at endpoint</option></select></div>\n            <div class=\"nc-draw-row\"><label>Color <input type=\"color\" data-role=\"feature-color\" value=\"#ffffff\" style=\"width:44px;padding:1px\"></label><label>Line px <input type=\"number\" data-role=\"line-width\" value=\"2\" min=\"1\" max=\"20\" style=\"width:64px\"></label><label>Fill <input type=\"number\" data-role=\"fill-opacity\" value=\"0.18\" min=\"0\" max=\"1\" step=\"0.05\" style=\"width:68px\"></label></div>\n            <div class=\"nc-draw-measurements\" data-role=\"measurements\"></div><div class=\"nc-draw-row\"><button data-action=\"update-feature\">Apply</button><button data-action=\"delete-feature\">Delete feature</button></div>\n          </div>\n        </details>\n        <details class=\"nc-draw-block\"><summary>Spatial construction</summary>\n          <div class=\"nc-draw-status\">Check project features below, then combine polygon geometry. The first feature is the difference subject.</div><div class=\"nc-draw-list\" data-role=\"spatial-features\"></div>\n          <div class=\"nc-draw-row\"><select data-role=\"spatial-op\"><option value=\"union\">Union</option><option value=\"intersection\">Intersection</option><option value=\"difference\">Difference</option><option value=\"buffer\">Buffer selected</option></select><input type=\"number\" data-role=\"buffer-distance\" value=\"100\" min=\"0.1\" step=\"10\" title=\"Buffer metres\" style=\"width:90px\"><button data-action=\"spatial-run\">Construct</button></div>\n        </details>\n        <details class=\"nc-draw-block\"><summary>Import GIS data</summary>\n          <input type=\"file\" data-role=\"import-file\" accept=\".geojson,.json,.ndjson,.kml,.kmz,.gpkg,.zip,.shp,.gpx,.csv\"><div class=\"nc-draw-row\"><select data-role=\"import-format\"><option value=\"\">Detect format</option>${FORMATS.map((value) => `<option>${value}</option>`).join('')}</select><button data-action=\"preview-import\">Preview file</button><button data-action=\"confirm-import\" disabled>Import preview</button></div>\n          <div class=\"nc-draw-row\"><input data-role=\"arcgis-url\" placeholder=\"https://…/FeatureServer/0\"><button data-action=\"preview-arcgis\">Preview ArcGIS</button></div><div class=\"nc-draw-preview\" data-role=\"import-preview\"></div>\n        </details>\n        <details class=\"nc-draw-block\"><summary>Versions and export</summary>\n          <div class=\"nc-draw-row\"><select data-role=\"export-format\">${FORMATS.map((value) => `<option>${value}</option>`).join('')}</select><button data-action=\"export\">Download</button><button data-action=\"export-overlay\">Export to overlay</button><button data-action=\"revisions\">Refresh revisions</button></div><div class=\"nc-draw-list\" data-role=\"revisions\"></div>\n        </details>\n      </div>`;\n    if (this.mode === 'floating' && this.container) this.container.appendChild(el);\n    this._el = el;\n  }\n\n  _bind() {\n    const q = (selector) => this._el.querySelector(selector);\n    this._el.addEventListener('click', async (event) => {\n      const button = event.target.closest('button');\n      if (!button) return;\n      try { await this._action(button.dataset.action, button); } catch (error) { this._message(error.message, true); }\n    });\n    this._el.querySelectorAll('[data-tool]').forEach((button) => button.addEventListener('click', () => {\n      if (!this.manager.currentProjectId) {\n        this._message('Create or open a project before drawing.', true);\n        return;\n      }\n      this.system.setTool(button.dataset.tool);\n      this._renderTools();\n    }));\n    q('[data-role=project]').addEventListener('change', (event) => {\n      if (event.target.value) this.manager.openProject(event.target.value).catch((error) => this._message(error.message, true));\n    });\n    q('[data-role=snap]').addEventListener('change', (event) => this.system.setSnap(event.target.checked));\n    document.addEventListener('noclip:drawing-project:state', () => this._renderState());\n    document.addEventListener('noclip:draw:selection', () => this._renderInspector());\n    document.addEventListener('noclip:draw:commit', () => this._renderState());\n    document.addEventListener('noclip:draw:update', () => this._renderState());\n    document.addEventListener('noclip:draw:cleared', () => this._renderState());\n    document.addEventListener('noclip:draw:tool', () => this._renderTools());\n    document.addEventListener('keydown', (event) => {\n      const formFocused = ['INPUT', 'TEXTAREA', 'SELECT'].includes(document.activeElement?.tagName);\n      if (event.key === 'Escape') this.system.cancel();\n      if (!formFocused && event.key === 'Enter' && this.system.isDrawing) this.system.commit();\n      if (!formFocused && event.key === 'Backspace' && this.system.isDrawing) this.system.undoVertex();\n      if (!formFocused && (event.ctrlKey || event.metaKey) && event.key.toLowerCase() === 'z') {\n        event.preventDefault(); event.shiftKey ? this.system.redo() : this.system.undo();\n      }\n    });\n  }\n\n  async _action(action, button) {\n    const q = (selector) => this._el.querySelector(selector);\n    let completionMessage = '';\n    if (!action) return;\n    if (action === 'create') await this.manager.createProject({ name: text(q('[data-role=new-name]').value) || 'Untitled project' });\n    if (action === 'save') await this.manager.save();\n    if (action === 'rename') await this.manager.renameProject({ name: text(q('[data-role=project-name]').value), description: q('[data-role=project-description]').value });\n    if (action === 'close') await this.manager.closeProject();\n    if (action === 'delete-project' && this.manager.currentProjectId\n      && globalThis.confirm?.('Archive this drawing project? This removes it from your active project list.')) {\n      await this.manager.deleteProject();\n    }\n    if (action === 'undo') this.system.undo();\n    if (action === 'redo') this.system.redo();\n    if (action === 'finish') this.system.commit();\n    if (action === 'cancel') this.system.cancel();\n    if (action === 'add-group') {\n      this.manager.addGroup({ name: text(q('[data-role=group-name]').value) || 'New group' });\n      q('[data-role=group-name]').value = '';\n    }\n    if (action === 'select-group') this.system.setActiveGroup(button.dataset.groupId);\n    if (action === 'toggle-group') {\n      const group = this.system.groups.find((entry) => entry.groupId === button.dataset.groupId);\n      if (group) this.manager.updateGroup(group.groupId, { visible: !group.visible });\n    }\n    if (action === 'delete-group') this.manager.deleteGroup(button.dataset.groupId);\n    if (action === 'update-feature') this._applyInspector();\n    if (action === 'delete-feature' && this.system.selectedShapeId) this.system.removeShape(this.system.selectedShapeId);\n    if (action === 'spatial-run') {\n      const ids = [...this._el.querySelectorAll('[data-role=spatial-features] input:checked')].map((input) => input.value);\n      this.manager.applySpatialOperation(q('[data-role=spatial-op]').value, ids, { distanceM: Number(q('[data-role=buffer-distance]').value) });\n    }\n    if (action === 'preview-import') await this._previewFile();\n    if (action === 'preview-arcgis') await this._previewArcGis();\n    if (action === 'confirm-import' && this._preview) { await this.manager.confirmImport(this._preview); this._preview = null; }\n    if (action === 'export') {\n      const output = await this.manager.exportProject({ format: q('[data-role=export-format]').value });\n      const href = URL.createObjectURL(output.blob); const anchor = document.createElement('a');\n      anchor.href = href; anchor.download = output.filename; anchor.click(); setTimeout(() => URL.revokeObjectURL(href), 1000);\n    }\n    if (action === 'export-overlay') {\n      const output = await this.manager.exportToOverlay();\n      completionMessage = `Overlay ${output.overlayId} created from revision ${output.projectRevision}.`;\n    }\n    if (action === 'revisions') await this._renderRevisions();\n    if (action === 'restore') await this.manager.restoreRevision(Number(button.dataset.revision));\n    this._renderState();\n    if (completionMessage) this._message(completionMessage);\n  }\n\n  _applyInspector() {\n    const shape = this.system.selectedShape;\n    if (!shape) return;\n    const q = (selector) => this._el.querySelector(selector);\n    const spatialRole = q('[data-role=spatial-role]').value;\n    const assetIds = q('[data-role=asset-anchor-ids]').value.split(',').map((value) => value.trim()).filter(Boolean);\n    const assetMount = q('[data-role=asset-anchor-mount]').value;\n    if (spatialRole !== 'none' && !['polygon', 'circle', 'rectangle'].includes(shape.kind)) throw new Error('Only areas can be used as masks.');\n    this.system.updateShape(shape.id, {\n      groupId: q('[data-role=feature-group]').value || null,\n      properties: {\n        ...shape.properties,\n        label: q('[data-role=feature-label]').value,\n        description: q('[data-role=feature-description]').value,\n        spatialRole,\n        attributes: {\n          ...(shape.properties.attributes || {}),\n          assetAnchors: assetIds.map((assetId) => ({ assetId, assetType: 'scene-asset', mount: assetMount })),\n        },\n        style: {\n          ...(shape.properties.style || {}),\n          color: q('[data-role=feature-color]').value,\n          lineWidth: Number(q('[data-role=line-width]').value),\n          fillOpacity: Number(q('[data-role=fill-opacity]').value),\n        },\n      },\n    });\n  }\n\n  async _previewFile() {\n    const q = (selector) => this._el.querySelector(selector);\n    const file = q('[data-role=import-file]').files?.[0];\n    if (!file) throw new Error('Choose a GIS file first.');\n    this._preview = await this.manager.previewFile(file, { format: q('[data-role=import-format]').value });\n    this._renderPreview();\n  }\n\n  async _previewArcGis() {\n    const url = text(this._el.querySelector('[data-role=arcgis-url]').value);\n    if (!url) throw new Error('Enter an ArcGIS FeatureServer layer URL.');\n    this._preview = await this.manager.previewArcGis({ url, where: '1=1' });\n    this._renderPreview();\n  }\n\n  _renderPreview() {\n    const target = this._el.querySelector('[data-role=import-preview]');\n    const button = this._el.querySelector('[data-action=confirm-import]');\n    if (!this._preview) { target.textContent = ''; button.disabled = true; return; }\n    target.textContent = `${this._preview.format}: ${this._preview.featureCount} features\\n${JSON.stringify(this._preview.geometryTypes)}\\n${(this._preview.warnings || []).join('\\n')}`;\n    button.disabled = !this.manager.currentProjectId || this._preview.featureCount < 1;\n  }\n\n  _renderState() {\n    const snapshot = this.manager.snapshot;\n    const q = (selector) => this._el.querySelector(selector);\n    const select = q('[data-role=project]');\n    const selectedValue = this.manager.currentProjectId || '';\n    select.replaceChildren(new Option('Select a project', ''));\n    for (const project of this.manager.projects) select.add(new Option(`${project.name} · r${project.currentRevision}`, project.projectId));\n    select.value = selectedValue;\n    q('[data-role=project-name]').value = snapshot?.project?.name || '';\n    q('[data-role=project-description]').value = snapshot?.project?.description || '';\n    const hasProject = !!snapshot?.project?.projectId;\n    this._el.querySelectorAll('[data-tool]').forEach((button) => { button.disabled = !hasProject; });\n    for (const action of ['save', 'rename', 'close', 'delete-project', 'add-group', 'export', 'export-overlay', 'revisions']) {\n      const control = this._el.querySelector(`[data-action=\"${action}\"]`);\n      if (control) control.disabled = !hasProject;\n    }\n    this._message(this.manager.syncState === 'error' ? (this.manager.lastError?.message || 'Sync error') : `${this.manager.syncState} · ${this.system.shapes.length} features`, this.manager.syncState === 'error');\n    this._renderGroups(); this._renderInspector(); this._renderSpatialFeatures(); this._renderPreview(); this._renderTools();\n  }\n\n  _renderGroups() {\n    const target = this._el.querySelector('[data-role=groups]'); target.replaceChildren();\n    for (const group of this.system.groups) {\n      const row = document.createElement('div');\n      row.className = `nc-draw-list-item ${group.groupId === this.system.activeGroupId ? 'is-active' : ''}`;\n      const name = document.createElement('button'); name.className = 'nc-draw-list-item__name'; name.dataset.action = 'select-group'; name.dataset.groupId = group.groupId; name.textContent = group.name;\n      const visible = document.createElement('button'); visible.dataset.action = 'toggle-group'; visible.dataset.groupId = group.groupId; visible.textContent = group.visible ? 'eye' : 'off';\n      const remove = document.createElement('button'); remove.dataset.action = 'delete-group'; remove.dataset.groupId = group.groupId; remove.textContent = '×';\n      row.append(name, visible, remove); target.appendChild(row);\n    }\n  }\n\n  _renderInspector() {\n    const shape = this.system.selectedShape;\n    const inspector = this._el.querySelector('[data-role=inspector]');\n    this._el.querySelector('[data-role=selected-empty]').hidden = !!shape; inspector.hidden = !shape;\n    if (!shape) return;\n    const q = (selector) => this._el.querySelector(selector);\n    q('[data-role=feature-label]').value = shape.properties?.label || '';\n    q('[data-role=feature-description]').value = shape.properties?.description || '';\n    q('[data-role=spatial-role]').value = shape.properties?.spatialRole || 'none';\n    const assetAnchors = Array.isArray(shape.properties?.attributes?.assetAnchors) ? shape.properties.attributes.assetAnchors : [];\n    q('[data-role=asset-anchor-ids]').value = assetAnchors.map((anchor) => anchor.assetId || anchor.id || '').filter(Boolean).join(', ');\n    q('[data-role=asset-anchor-mount]').value = assetAnchors[0]?.mount || 'centroid';\n    q('[data-role=feature-color]').value = shape.properties?.style?.color || '#ffffff';\n    q('[data-role=line-width]').value = Number(shape.properties?.style?.lineWidth || 2);\n    q('[data-role=fill-opacity]').value = Number(shape.properties?.style?.fillOpacity ?? 0.18);\n    const groupSelect = q('[data-role=feature-group]'); groupSelect.replaceChildren(new Option('Ungrouped', ''));\n    for (const group of this.system.groups) groupSelect.add(new Option(group.name, group.groupId));\n    groupSelect.value = shape.groupId || '';\n    const measurements = shape.properties?.measurements || shapeMeasurements(shape);\n    q('[data-role=measurements]').textContent = [\n      measurements.lengthM ? `Length ${formatDistance(measurements.lengthM)}` : '',\n      measurements.perimeterM ? `Perimeter ${formatDistance(measurements.perimeterM)}` : '',\n      measurements.areaM2 ? `Area ${formatArea(measurements.areaM2)}` : '',\n      measurements.radiusM ? `Radius ${formatDistance(measurements.radiusM)}` : '',\n    ].filter(Boolean).join('\\n') || 'Point geometry';\n  }\n\n  _renderSpatialFeatures() {\n    const target = this._el.querySelector('[data-role=spatial-features]'); target.replaceChildren();\n    for (const shape of this.system.shapes) {\n      const label = document.createElement('label'); label.className = 'nc-draw-list-item';\n      const input = document.createElement('input'); input.type = 'checkbox'; input.value = shape.id; input.style.width = 'auto';\n      const copy = document.createElement('span'); copy.className = 'nc-draw-list-item__name'; copy.textContent = shape.properties?.label || `${shape.kind} ${shape.id.slice(0, 8)}`;\n      label.append(input, copy); target.appendChild(label);\n    }\n  }\n\n  async _renderRevisions() {\n    const target = this._el.querySelector('[data-role=revisions]'); target.replaceChildren();\n    for (const revision of await this.manager.listRevisions()) {\n      const row = document.createElement('div'); row.className = 'nc-draw-list-item';\n      const copy = document.createElement('span'); copy.className = 'nc-draw-list-item__name'; copy.textContent = `r${revision.revisionNumber} · ${revision.revisionKind} · ${revision.message || ''}`;\n      const restore = document.createElement('button'); restore.dataset.action = 'restore'; restore.dataset.revision = revision.revisionNumber; restore.textContent = 'Restore';\n      row.append(copy, restore); target.appendChild(row);\n    }\n  }\n\n  _renderTools() {\n    this._el.querySelectorAll('[data-tool]').forEach((button) => button.classList.toggle('active', button.dataset.tool === this.system.tool));\n  }\n\n  _message(message, error = false) {\n    const status = this._el.querySelector('[data-role=status]');\n    status.textContent = message || 'Idle'; status.dataset.state = error ? 'error' : this.manager.syncState;\n  }\n}\n","/**\n * MeasurementReadout — floating distance/area/perimeter/slope/LOS readout\n * shown beside the cursor while DrawSystem is in an active state.\n */\nimport { geodesicDistanceWGS84 } from '../../modules/geometry-utils.js';\n\nlet _instance = null;\nexport function getMeasurementReadout(opts) {\n  if (!_instance) _instance = new MeasurementReadout(opts);\n  return _instance;\n}\n\nfunction formatM(m) {\n  if (!Number.isFinite(m) || m <= 0) return '0 m';\n  if (m < 1000) return `${Math.round(m)} m / ${Math.round(m * 3.281)} ft`;\n  return `${(m / 1000).toFixed(2)} km / ${(m / 1609.344).toFixed(2)} mi`;\n}\nfunction formatArea(m2) {\n  if (!Number.isFinite(m2) || m2 <= 0) return '0 m²';\n  if (m2 < 10000) return `${Math.round(m2)} m² / ${Math.round(m2 * 10.764)} ft²`;\n  if (m2 < 1_000_000) return `${(m2 / 4046.86).toFixed(2)} ac / ${(m2 / 10000).toFixed(2)} ha`;\n  return `${(m2 / 1_000_000).toFixed(2)} km² / ${(m2 / 2.59e6).toFixed(2)} mi²`;\n}\n\nexport class MeasurementReadout {\n  constructor({ container } = {}) {\n    this.container = container || document.body;\n    this._build();\n    this._bind();\n  }\n\n  _build() {\n    const el = document.createElement('div');\n    el.className = 'nc-measure-readout';\n    el.hidden = true;\n    el.innerHTML = `\n      <div class=\"nc-measure-row\"><span class=\"nc-measure-label\">Segment</span><span class=\"nc-measure-segment\"></span></div>\n      <div class=\"nc-measure-row\"><span class=\"nc-measure-label\">Length</span><span class=\"nc-measure-len\"></span></div>\n      <div class=\"nc-measure-row\"><span class=\"nc-measure-label\">Area</span><span class=\"nc-measure-area\"></span></div>\n      <div class=\"nc-measure-row\"><span class=\"nc-measure-label\">Slope</span><span class=\"nc-measure-slope\"></span></div>\n      <div class=\"nc-measure-row\"><span class=\"nc-measure-label\">LOS</span><span class=\"nc-measure-los\"></span></div>\n    `;\n    this.container.appendChild(el);\n    this._el = el;\n    this._lenEl = el.querySelector('.nc-measure-len');\n    this._segmentEl = el.querySelector('.nc-measure-segment');\n    this._areaEl = el.querySelector('.nc-measure-area');\n    this._slopeEl = el.querySelector('.nc-measure-slope');\n    this._losEl = el.querySelector('.nc-measure-los');\n  }\n\n  _bind() {\n    document.addEventListener('noclip:draw:vertex', (ev) => this._render(ev.detail));\n    document.addEventListener('noclip:draw:start', () => { this._el.hidden = false; this._render({ vertices: [] }); });\n    document.addEventListener('noclip:draw:cancel', () => { this._el.hidden = true; });\n    document.addEventListener('noclip:draw:commit', () => { this._el.hidden = true; });\n    document.addEventListener('pointermove', (event) => {\n      if (this._el.hidden) return;\n      this._el.style.left = `${Math.min(window.innerWidth - 220, event.clientX + 16)}px`;\n      this._el.style.top = `${Math.min(window.innerHeight - 120, event.clientY + 16)}px`;\n    }, { passive: true });\n  }\n\n  _render(detail) {\n    const verts = detail?.vertices || [];\n    let len = 0;\n    let segment = 0;\n    for (let i = 1; i < verts.length; i++) {\n      segment = geodesicDistanceWGS84(verts[i - 1].lat, verts[i - 1].lon, verts[i].lat, verts[i].lon);\n      len += segment;\n    }\n    let area = 0;\n    if (verts.length >= 3) {\n      area = sphericalPolygonArea(verts);\n    }\n    if (this._lenEl) this._lenEl.textContent = formatM(len);\n    if (this._segmentEl) this._segmentEl.textContent = formatM(segment);\n    if (this._areaEl) this._areaEl.textContent = formatArea(area);\n    if (this._slopeEl) this._slopeEl.textContent = '—';\n    if (this._losEl) this._losEl.textContent = '—';\n  }\n}\n\n// Spherical polygon area (m²) via L'Huilier's theorem variant.\nfunction sphericalPolygonArea(verts) {\n  const R = 6371008.8;\n  if (verts.length < 3) return 0;\n  let total = 0;\n  for (let i = 0; i < verts.length; i++) {\n    const j = (i + 1) % verts.length;\n    const lon1 = verts[i].lon * Math.PI / 180;\n    const lat1 = verts[i].lat * Math.PI / 180;\n    const lon2 = verts[j].lon * Math.PI / 180;\n    const lat2 = verts[j].lat * Math.PI / 180;\n    total += (lon2 - lon1) * (2 + Math.sin(lat1) + Math.sin(lat2));\n  }\n  return Math.abs(total * R * R / 2);\n}\n","import { registerIntent, PERMISSIONS } from '../IntentRegistry.js';\nimport { getDrawSystem } from '../../draw/DrawSystem.js';\nimport { getDrawingProjectManager } from '../../draw/DrawingProjectManager.js';\n\nlet _registered = false;\nexport function registerDrawingIntents() {\n  if (_registered) return;\n  _registered = true;\n  const sys = getDrawSystem();\n  const projects = getDrawingProjectManager();\n\n  registerIntent({\n    name: 'start_drawing',\n    description: 'Start a project drawing tool: select, point, annotation, line, polygon, circle, rectangle, or freehand.',\n    permissions: [PERMISSIONS.WRITE_DRAWING],\n    params: {\n      type: 'object', required: ['tool'],\n      properties: { tool: { type: 'string', enum: ['select', 'point', 'annotation', 'line', 'polygon', 'circle', 'rectangle', 'freehand'] } },\n    },\n    handler: (slots) => {\n      const ok = sys.setTool(slots.tool);\n      return ok ? { applied: true, actionTags: [`draw.start:${slots.tool}`] } : { applied: false, errors: ['Bad tool'] };\n    },\n  });\n\n  registerIntent({\n    name: 'add_vertex',\n    description: 'Add a vertex to the active drawing.',\n    permissions: [PERMISSIONS.WRITE_DRAWING],\n    params: {\n      type: 'object', required: ['lat', 'lon'],\n      properties: { lat: { type: 'number' }, lon: { type: 'number' } },\n    },\n    handler: (slots) => {\n      const ok = sys.addVertex({ lat: Number(slots.lat), lon: Number(slots.lon) });\n      return ok ? { applied: true, actionTags: ['draw.vertex'] } : { applied: false, errors: ['Drawing not active'] };\n    },\n  });\n\n  registerIntent({\n    name: 'commit_drawing',\n    description: 'Finish and persist the active drawing.',\n    permissions: [PERMISSIONS.WRITE_DRAWING],\n    params: { type: 'object', properties: {} },\n    handler: () => {\n      const r = sys.commit();\n      return r ? { applied: true, actionTags: ['draw.commit'] } : { applied: false };\n    },\n  });\n\n  registerIntent({\n    name: 'clear_drawings',\n    description: 'Cancel any active drawing and clear all in-progress shapes.',\n    permissions: [PERMISSIONS.WRITE_DRAWING],\n    params: { type: 'object', properties: {} },\n    handler: () => { sys.cancel(); return { applied: true, actionTags: ['draw.cancel'] }; },\n  });\n\n  registerIntent({\n    name: 'create_drawing_project',\n    description: 'Create and open a persisted geospatial drawing project draft.',\n    permissions: [PERMISSIONS.WRITE_DRAWING],\n    params: { type: 'object', required: ['name'], properties: { name: { type: 'string' }, description: { type: 'string' } } },\n    handler: async (slots) => {\n      const snapshot = await projects.createProject({ name: slots.name, description: slots.description || '' });\n      return { applied: true, projectId: snapshot.project.projectId, actionTags: ['draw.project.create'] };\n    },\n  });\n\n  registerIntent({\n    name: 'open_drawing_project',\n    description: 'Open a drawing project by its project UUID.',\n    permissions: [PERMISSIONS.WRITE_DRAWING],\n    params: { type: 'object', required: ['projectId'], properties: { projectId: { type: 'string' } } },\n    handler: async ({ projectId }) => {\n      const snapshot = await projects.openProject(projectId);\n      return { applied: true, revision: snapshot.revision, featureCount: snapshot.features.length, actionTags: ['draw.project.open'] };\n    },\n  });\n\n  registerIntent({\n    name: 'add_drawing_group',\n    description: 'Add a project group for organizing geometries, annotations, masks, and future asset anchors.',\n    permissions: [PERMISSIONS.WRITE_DRAWING],\n    params: { type: 'object', required: ['name'], properties: { name: { type: 'string' }, parentGroupId: { type: 'string' } } },\n    handler: ({ name, parentGroupId }) => ({ applied: true, group: projects.addGroup({ name, parentGroupId: parentGroupId || null }), actionTags: ['draw.group.create'] }),\n  });\n\n  registerIntent({\n    name: 'save_drawing_project',\n    description: 'Flush pending edits and create a durable named checkpoint revision.',\n    permissions: [PERMISSIONS.WRITE_DRAWING],\n    params: { type: 'object', properties: { message: { type: 'string' } } },\n    handler: async ({ message }) => {\n      const snapshot = await projects.save(message || 'Agent checkpoint');\n      return { applied: true, revision: snapshot.revision, actionTags: ['draw.project.checkpoint'] };\n    },\n  });\n\n  registerIntent({\n    name: 'set_drawing_feature_metadata',\n    description: 'Set a feature label, description, mask role, group, and asset-anchor metadata.',\n    permissions: [PERMISSIONS.WRITE_DRAWING],\n    params: {\n      type: 'object', required: ['featureId'], properties: {\n        featureId: { type: 'string' }, label: { type: 'string' }, description: { type: 'string' },\n        spatialRole: { type: 'string', enum: ['none', 'include', 'exclude', 'clip'] },\n        groupId: { type: 'string' }, assetAnchors: { type: 'array' },\n      },\n    },\n    handler: (slots) => {\n      const shape = sys.shapes.find((entry) => entry.id === slots.featureId);\n      if (!shape) return { applied: false, errors: ['Feature not found'] };\n      const updated = sys.updateShape(shape.id, {\n        groupId: slots.groupId ?? shape.groupId,\n        properties: {\n          ...shape.properties,\n          label: slots.label ?? shape.properties.label,\n          description: slots.description ?? shape.properties.description,\n          spatialRole: slots.spatialRole ?? shape.properties.spatialRole,\n          attributes: { ...shape.properties.attributes, ...(slots.assetAnchors ? { assetAnchors: slots.assetAnchors } : {}) },\n        },\n      });\n      return { applied: !!updated, actionTags: ['draw.feature.update'] };\n    },\n  });\n\n  registerIntent({\n    name: 'export_drawing_to_overlay',\n    description: 'Checkpoint the current drawing project and publish an immutable private overlay snapshot for downstream overlay and 3D-asset systems.',\n    permissions: [PERMISSIONS.WRITE_DRAWING],\n    params: { type: 'object', properties: { title: { type: 'string' }, description: { type: 'string' } } },\n    handler: async (slots) => ({ applied: true, export: await projects.exportToOverlay(slots), actionTags: ['draw.overlay.export'] }),\n  });\n}\n","/**\n * IsochroneOverlay — surface-following 3D rendering of reachability polygons.\n *\n * Listens for two cross-cutting document events so the overlay is decoupled\n * from any specific HUD or AgentCommandProcessor caller:\n *   - `noclip:isochrone:set`     detail = FeatureCollection<Polygon>\n *   - `noclip:isochrone:cleared` detail = (none)\n *\n * The overlay paints UNDER the route ribbon (renderOrder 1400 vs ribbon's\n * 1500) so a navigation route is always visible on top of an isochrone fill.\n * `depthTest: false` matches AddressHoverOverlay and RouteRibbonRenderer —\n * needed because terrain/photoreal tiles can sit several hundred metres\n * above the WGS-84 ellipsoid, depth-rejecting an overlay drawn at lift=35m.\n *\n * Polygon shape:\n *   We do NOT triangulate true polygon interiors. Each contour ring is\n *   converted to a closed surface-following triangle strip (a \"ribbon\")\n *   following the polygon boundary, plus a thin fan from the polygon\n *   centroid to each boundary vertex (a fan filling the interior). This\n *   reads as a translucent stepped fill on the globe without paying the\n *   cost of a true earcut tessellation. Holes (inner rings) are skipped —\n *   acceptable for Valhalla isochrones whose rings rarely contain holes\n *   inside our public-instance contour cap.\n *\n * Colour ramp:\n *   Per-feature `properties.color` (set by isochrone-service.js) drives\n *   the fill colour. Defaults to the green→yellow→red→violet ramp from\n *   the proxy. Opacity is capped at 0.4 so multiple overlapping contours\n *   compose visually without becoming opaque.\n */\nimport * as THREE from 'three';\nimport {\n  latLonToLocalDir,\n  ellipsoidRadiusForLocalDir,\n} from '../../modules/geometry-utils.js';\n\n// Lift above the WGS-84 ellipsoid (metres). Same logic as RouteRibbonRenderer\n// — needs to clear typical terrain heights so depthTest:false doesn't get\n// us into z-fighting on the borrowed nearest-vertex-wins path.\nconst POLYGON_LIFT_M = 25;\n// Contour boundary ribbon half-width, metres. Thicker than the route\n// ribbon so the contour ring reads at altitude.\nconst BOUNDARY_HALF_WIDTH_M = 24;\n// Default fill opacity if the feature doesn't carry `fill-opacity`.\nconst DEFAULT_FILL_OPACITY = 0.33;\nconst MAX_FILL_OPACITY = 0.4;\n// Render order: under the route ribbon (1500) but over basemap and\n// buildings. RouteRibbonRenderer documents the 1500 number so we sit\n// strictly below it.\nconst RENDER_ORDER = 1400;\n\nconst _scratchVec = new THREE.Vector3();\nconst _scratchUp = new THREE.Vector3();\n\nfunction coordToWorld(lon, lat, out, upOut) {\n  const dir = latLonToLocalDir(lat, lon);\n  const radius = ellipsoidRadiusForLocalDir(dir);\n  out.copy(dir).multiplyScalar(radius + POLYGON_LIFT_M);\n  if (upOut) upOut.copy(dir);\n  return out;\n}\n\nfunction parseColour(input, fallback = '#34d399') {\n  const c = new THREE.Color();\n  try { c.set(input || fallback); } catch { c.set(fallback); }\n  return c;\n}\n\n/**\n * Compute the coordinate centroid of a ring (simple average — sufficient\n * for the fan-fill heuristic; not the true polygon centroid).\n */\nfunction ringCentroid(ring) {\n  let sx = 0, sy = 0, n = 0;\n  for (const [lon, lat] of ring) {\n    if (!Number.isFinite(lon) || !Number.isFinite(lat)) continue;\n    sx += lon; sy += lat; n++;\n  }\n  if (!n) return null;\n  return [sx / n, sy / n];\n}\n\n/**\n * Build a single THREE.Mesh for one Polygon ring (outer boundary).\n *\n * Strategy:\n *   - Compute centroid C in lat/lon, lift to world.\n *   - For each consecutive pair of ring vertices V_i, V_{i+1}, emit two\n *     triangles forming a fan slice: (C, V_i, V_{i+1}).\n *   - Result is a triangle fan that visually fills the polygon interior,\n *     surface-following (each vertex independently lifted to its own\n *     ellipsoid radius + LIFT).\n *\n * For polygons that are not star-convex from their centroid, this fan\n * still produces a valid mesh but may slightly overshoot bays. This is\n * acceptable for time-isochrones which are typically star-convex from\n * the origin point. For tighter shapes a future revision can switch to\n * earcut.\n */\nfunction buildRingFanGeometry(ring) {\n  if (!Array.isArray(ring) || ring.length < 3) return null;\n  // Make sure ring is closed (last == first); if not, append.\n  const closed = ring.slice();\n  const [lon0, lat0] = closed[0];\n  const [lonE, latE] = closed[closed.length - 1];\n  if (lon0 !== lonE || lat0 !== latE) closed.push([lon0, lat0]);\n\n  const c = ringCentroid(closed);\n  if (!c) return null;\n\n  const vertCount = closed.length + 1; // ring vertices + 1 centroid\n  const positions = new Float32Array(vertCount * 3);\n  const triCount = closed.length - 1;\n  const indices = new Uint32Array(triCount * 3);\n\n  // Centroid at index 0\n  coordToWorld(c[0], c[1], _scratchVec);\n  positions[0] = _scratchVec.x;\n  positions[1] = _scratchVec.y;\n  positions[2] = _scratchVec.z;\n\n  for (let i = 0; i < closed.length; i++) {\n    const [lon, lat] = closed[i];\n    coordToWorld(lon, lat, _scratchVec);\n    const o = (i + 1) * 3;\n    positions[o] = _scratchVec.x;\n    positions[o + 1] = _scratchVec.y;\n    positions[o + 2] = _scratchVec.z;\n  }\n\n  for (let s = 0; s < triCount; s++) {\n    const o = s * 3;\n    indices[o] = 0;            // centroid\n    indices[o + 1] = s + 1;    // V_s\n    indices[o + 2] = s + 2;    // V_{s+1}\n  }\n\n  const geom = new THREE.BufferGeometry();\n  geom.setAttribute('position', new THREE.BufferAttribute(positions, 3));\n  geom.setIndex(new THREE.BufferAttribute(indices, 1));\n  geom.computeBoundingSphere();\n  return geom;\n}\n\n/**\n * Build a thin surface-following ribbon along the ring boundary so the\n * contour line itself reads against the fill. Mirrors RouteRibbonRenderer\n * geometry but closed on itself.\n */\nfunction buildRingBoundaryGeometry(ring) {\n  if (!Array.isArray(ring) || ring.length < 3) return null;\n  const coords = ring.slice();\n  const [lon0, lat0] = coords[0];\n  const [lonE, latE] = coords[coords.length - 1];\n  if (lon0 !== lonE || lat0 !== latE) coords.push([lon0, lat0]);\n\n  const segCount = coords.length - 1;\n  const vertexCount = coords.length * 2;\n  const positions = new Float32Array(vertexCount * 3);\n  const indices = new Uint32Array(segCount * 6);\n\n  const center = new THREE.Vector3();\n  const up = new THREE.Vector3();\n  const next = new THREE.Vector3();\n  const tangent = new THREE.Vector3();\n  const side = new THREE.Vector3();\n\n  for (let i = 0; i < coords.length; i++) {\n    const [lon, lat] = coords[i];\n    coordToWorld(lon, lat, center, up);\n    const ni = i < coords.length - 1 ? i + 1 : i - 1;\n    const [lonN, latN] = coords[ni];\n    coordToWorld(lonN, latN, next);\n    if (i < coords.length - 1) {\n      tangent.subVectors(next, center).normalize();\n    } else {\n      tangent.subVectors(center, next).normalize();\n    }\n    side.crossVectors(up, tangent).normalize().multiplyScalar(BOUNDARY_HALF_WIDTH_M);\n\n    const l = i * 2;\n    positions[l * 3] = center.x - side.x;\n    positions[l * 3 + 1] = center.y - side.y;\n    positions[l * 3 + 2] = center.z - side.z;\n    const r = i * 2 + 1;\n    positions[r * 3] = center.x + side.x;\n    positions[r * 3 + 1] = center.y + side.y;\n    positions[r * 3 + 2] = center.z + side.z;\n  }\n\n  for (let s = 0; s < segCount; s++) {\n    const l0 = s * 2;\n    const r0 = s * 2 + 1;\n    const l1 = s * 2 + 2;\n    const r1 = s * 2 + 3;\n    const io = s * 6;\n    indices[io] = l0;\n    indices[io + 1] = r0;\n    indices[io + 2] = r1;\n    indices[io + 3] = l0;\n    indices[io + 4] = r1;\n    indices[io + 5] = l1;\n  }\n\n  const geom = new THREE.BufferGeometry();\n  geom.setAttribute('position', new THREE.BufferAttribute(positions, 3));\n  geom.setIndex(new THREE.BufferAttribute(indices, 1));\n  geom.computeBoundingSphere();\n  return geom;\n}\n\nexport class IsochroneOverlay {\n  constructor({ parentGroup = null, eventBus = null } = {}) {\n    this.parentGroup = parentGroup;\n    this.eventBus = eventBus;\n    this._meshes = [];\n    this._featureCollection = null;\n\n    this._onSet = (ev) => this.setFeatureCollection(ev?.detail || ev);\n    this._onCleared = () => this.clear();\n\n    if (typeof document !== 'undefined' && document.addEventListener) {\n      document.addEventListener('noclip:isochrone:set', this._onSet);\n      document.addEventListener('noclip:isochrone:cleared', this._onCleared);\n    }\n  }\n\n  dispose() {\n    this.clear();\n    if (typeof document !== 'undefined' && document.removeEventListener) {\n      document.removeEventListener('noclip:isochrone:set', this._onSet);\n      document.removeEventListener('noclip:isochrone:cleared', this._onCleared);\n    }\n  }\n\n  setParentGroup(group) {\n    if (this.parentGroup === group) return;\n    // Move all current meshes\n    for (const m of this._meshes) {\n      if (m?.parent) m.parent.remove(m);\n    }\n    this.parentGroup = group;\n    if (group) {\n      for (const m of this._meshes) group.add(m);\n    }\n  }\n\n  clear() {\n    for (const mesh of this._meshes) {\n      if (mesh?.parent) mesh.parent.remove(mesh);\n      mesh.geometry?.dispose?.();\n      mesh.material?.dispose?.();\n    }\n    this._meshes = [];\n    this._featureCollection = null;\n  }\n\n  /**\n   * Replace the current display with the given FeatureCollection.\n   * Accepts either the unified envelope from isochrone-service.js or any\n   * FeatureCollection containing Polygon/MultiPolygon features.\n   */\n  setFeatureCollection(fc) {\n    this.clear();\n    if (!fc || fc.type !== 'FeatureCollection' || !Array.isArray(fc.features)) {\n      return;\n    }\n    if (!this.parentGroup) {\n      // Stash for later attach via setParentGroup\n      this._featureCollection = fc;\n      console.warn('[IsochroneOverlay] setFeatureCollection called with no parentGroup; deferred');\n      return;\n    }\n    this._featureCollection = fc;\n    // Larger-contour features come last so smaller contours visually sit\n    // on top. The proxy already sorts ascending; we render in REVERSE so\n    // the OUTER (largest) ring is drawn first, then the inner contours.\n    const ordered = fc.features.slice().sort((a, b) => {\n      const ca = Number(a?.properties?.contour) || 0;\n      const cb = Number(b?.properties?.contour) || 0;\n      return cb - ca;\n    });\n\n    for (const feat of ordered) {\n      const geom = feat?.geometry;\n      if (!geom) continue;\n      const props = feat.properties || {};\n      const colour = parseColour(props.color || props.fill);\n      const opacity = Math.min(\n        MAX_FILL_OPACITY,\n        Number.isFinite(props['fill-opacity'])\n          ? Number(props['fill-opacity'])\n          : DEFAULT_FILL_OPACITY\n      );\n\n      const polygons = [];\n      if (geom.type === 'Polygon') {\n        polygons.push(geom.coordinates);\n      } else if (geom.type === 'MultiPolygon') {\n        for (const poly of geom.coordinates || []) polygons.push(poly);\n      } else {\n        continue;\n      }\n\n      for (const poly of polygons) {\n        const outer = poly?.[0];\n        if (!Array.isArray(outer) || outer.length < 3) continue;\n        const fanGeom = buildRingFanGeometry(outer);\n        if (fanGeom) {\n          const mat = new THREE.MeshBasicMaterial({\n            color: colour,\n            transparent: true,\n            opacity,\n            depthTest: false,\n            depthWrite: false,\n            side: THREE.DoubleSide,\n          });\n          const mesh = new THREE.Mesh(fanGeom, mat);\n          mesh.renderOrder = RENDER_ORDER;\n          mesh.frustumCulled = false;\n          mesh.userData.isochrone = {\n            contour: props.contour ?? null,\n            kind: 'fill',\n          };\n          this.parentGroup.add(mesh);\n          this._meshes.push(mesh);\n        }\n        const ringGeom = buildRingBoundaryGeometry(outer);\n        if (ringGeom) {\n          const ringMat = new THREE.MeshBasicMaterial({\n            color: colour,\n            transparent: true,\n            opacity: Math.min(0.95, opacity * 2.5),\n            depthTest: false,\n            depthWrite: false,\n            side: THREE.DoubleSide,\n          });\n          const ringMesh = new THREE.Mesh(ringGeom, ringMat);\n          // Slightly above the fill so the contour line reads.\n          ringMesh.renderOrder = RENDER_ORDER + 1;\n          ringMesh.frustumCulled = false;\n          ringMesh.userData.isochrone = {\n            contour: props.contour ?? null,\n            kind: 'boundary',\n          };\n          this.parentGroup.add(ringMesh);\n          this._meshes.push(ringMesh);\n        }\n      }\n    }\n  }\n}\n\nlet _instance = null;\n\nexport function getIsochroneOverlay(options = {}) {\n  if (!_instance) _instance = new IsochroneOverlay(options);\n  if (options.parentGroup && _instance.parentGroup !== options.parentGroup) {\n    _instance.setParentGroup(options.parentGroup);\n    // If a FeatureCollection was set before parent attached, re-render now.\n    if (_instance._featureCollection) {\n      const fc = _instance._featureCollection;\n      _instance._featureCollection = null;\n      _instance.setFeatureCollection(fc);\n    }\n  }\n  if (options.eventBus) _instance.eventBus = options.eventBus;\n  return _instance;\n}\n\nexport default IsochroneOverlay;\n","/** Reachability through NOCLIP's co-hosted routing service only.\n * Arrays use [latitude, longitude]; objects use {lat, lon}. No order guessing.\n * Exact origin, profile, contours, denoise AND generalize form the cache key.\n * The shared client retains bounded encoded bytes, never shared mutable polygons.\n */\nimport { getLocalRoutingClient, checkRoutingAbort, invalidRoutingRequest } from '../refactor/async/fetch/LocalRoutingClient.js';\nimport { routingProfile, routingPoint, validateIsochrones } from '../refactor/routing/RoutingContracts.js';\n\nexport async function getIsochrones(latLon, options = {}) {\n  checkRoutingAbort(options.signal);\n  const profile = routingProfile(options.profile);\n  const lat = Array.isArray(latLon) ? latLon[0] : latLon?.lat;\n  const lon = Array.isArray(latLon) ? latLon[1] : latLon?.lon ?? latLon?.lng ?? latLon?.longitude;\n  if (!routingPoint([lon, lat]) || (Array.isArray(latLon) && latLon.length !== 2)) invalidRoutingRequest();\n  const input = options.contours === undefined ? [5, 10, 15] : options.contours;\n  if (!Array.isArray(input) || !input.length || input.length > 4\n    || input.some(value => !Number.isFinite(value) || value < 1 || value > 120)) invalidRoutingRequest();\n  const contours = [...new Set(input)].sort((a, b) => a - b);\n  const denoise = options.denoise === undefined ? 1 : options.denoise;\n  const generalize = options.generalize === undefined ? 50 : options.generalize;\n  if (!Number.isFinite(denoise) || denoise < 0 || denoise > 1\n    || !Number.isFinite(generalize) || generalize < 0 || generalize > 500) invalidRoutingRequest();\n  return getLocalRoutingClient().request('/routing/isochrone', {\n    query: { profile, lat, lon, contours: contours.join(','), denoise, generalize },\n    signal: options.signal, cache: true,\n    validate: (data, signal) => validateIsochrones(data, { profile, lat, lon, contours }, signal),\n  });\n}\n\n/** Clears retained bytes and fences insertion by older requests. */\nexport function clearIsochroneCache() { getLocalRoutingClient().clearIsochroneCache(); }\n","/**\n * SpatialOps — thin wrapper around per-package turf.js helpers.\n *\n * Per-package imports (rather than `@turf/turf`) keep the bundle\n * tree-shakeable: only the helpers actually called are pulled in. See\n * WO-001 failure-modes table — full `@turf/turf` adds ~200 KB gzipped.\n *\n * Every helper accepts and returns ordinary GeoJSON objects so the result\n * can be handed straight to `GeoJsonLayer`, the IsochroneOverlay, or the\n * minimap's `L.geoJSON`. Inputs that are not valid GeoJSON return `null`\n * rather than throwing — callers downstream from agent intents must not\n * crash on bad LLM output.\n *\n * Distance helpers (`buffer`, `length`) default to metric units (`meters`,\n * `kilometers`) because every other module in this repo uses metres.\n */\n\n// Lazy-import the per-package turf helpers so the bundle still builds\n// when `@turf/*` deps haven't been npm-installed yet (declared in\n// package.json; install on next `npm install`). Each public function is\n// async and resolves its own helper on first call. Cache resolved\n// modules so subsequent calls are sync-fast.\nconst _modCache = new Map();\nasync function _load(pkg) {\n  if (_modCache.has(pkg)) return _modCache.get(pkg);\n  try {\n    const m = await import(/* @vite-ignore */ pkg);\n    const fn = m.default || m;\n    _modCache.set(pkg, fn);\n    return fn;\n  } catch (err) {\n    console.warn(`[spatial-ops] turf helper ${pkg} unavailable; install @turf packages.`, err.message);\n    _modCache.set(pkg, null);\n    return null;\n  }\n}\nconst _buffer = () => _load('@turf/buffer');\nconst _union = () => _load('@turf/union');\nconst _intersect = () => _load('@turf/intersect');\nconst _difference = () => _load('@turf/difference');\nconst _booleanWithin = () => _load('@turf/boolean-within');\nconst _booleanContains = () => _load('@turf/boolean-contains');\nconst _area = () => _load('@turf/area');\nconst _length = () => _load('@turf/length');\nconst _centroid = () => _load('@turf/centroid');\nconst _simplify = () => _load('@turf/simplify');\nconst _bbox = () => _load('@turf/bbox');\nconst _bboxPolygon = () => _load('@turf/bbox-polygon');\nconst _pointsWithinPolygon = () => _load('@turf/points-within-polygon');\n\nfunction _isFeatureLike(g) {\n  return g && typeof g === 'object'\n    && (g.type === 'Feature' || g.type === 'FeatureCollection'\n        || (typeof g.type === 'string' && Array.isArray(g.coordinates)));\n}\n\nfunction _safe(fn, ...args) {\n  if (!fn) return null;\n  try { return fn(...args); } catch { return null; }\n}\n\n/**\n * Buffer a Feature/Geometry by `radius` (metres by default). `radius=0`\n * is the identity — turf returns a near-copy of the input.\n *\n * @param {object} geom — GeoJSON Feature or geometry\n * @param {number} radius — buffer distance\n * @param {{units?:'meters'|'kilometers'|'miles'|'feet', steps?:number}} [opts]\n * @returns {object|null}\n */\nexport async function bufferGeom(geom, radius, opts = {}) {\n  if (!_isFeatureLike(geom) || !Number.isFinite(radius)) return null;\n  const units = opts.units || 'meters';\n  const steps = Number.isFinite(opts.steps) ? opts.steps : 8;\n  const fn = await _buffer();\n  return _safe(fn, geom, radius, { units, steps });\n}\n\n/**\n * Polygon union of A ∪ B. Both inputs must be Feature<Polygon|MultiPolygon>.\n */\nexport async function unionGeom(a, b) {\n  if (!_isFeatureLike(a) || !_isFeatureLike(b)) return null;\n  return _safe(await _union(), a, b);\n}\n\n/**\n * Polygon intersection A ∩ B. Returns `null` when the inputs are disjoint.\n */\nexport async function intersectGeom(a, b) {\n  if (!_isFeatureLike(a) || !_isFeatureLike(b)) return null;\n  return _safe(await _intersect(), a, b);\n}\n\n/**\n * Polygon difference A \\ B. Returns `null` when B fully contains A.\n */\nexport async function differenceGeom(a, b) {\n  if (!_isFeatureLike(a) || !_isFeatureLike(b)) return null;\n  return _safe(await _difference(), a, b);\n}\n\n/**\n * `true` if every coordinate of A lies strictly inside B.\n */\nexport async function withinGeom(a, b) {\n  if (!_isFeatureLike(a) || !_isFeatureLike(b)) return false;\n  return _safe(await _booleanWithin(), a, b) === true;\n}\n\nexport async function containsGeom(a, b) {\n  if (!_isFeatureLike(a) || !_isFeatureLike(b)) return false;\n  return _safe(await _booleanContains(), a, b) === true;\n}\n\nexport async function areaGeom(geom) {\n  if (!_isFeatureLike(geom)) return 0;\n  const v = _safe(await _area(), geom);\n  return Number.isFinite(v) ? v : 0;\n}\n\nexport async function lengthGeom(geom, opts = {}) {\n  if (!_isFeatureLike(geom)) return 0;\n  const units = opts.units || 'meters';\n  const fn = await _length();\n  if (units === 'meters') {\n    const km = _safe(fn, geom, { units: 'kilometers' });\n    return Number.isFinite(km) ? km * 1000 : 0;\n  }\n  const v = _safe(fn, geom, { units });\n  return Number.isFinite(v) ? v : 0;\n}\n\nexport async function centroidGeom(geom) {\n  if (!_isFeatureLike(geom)) return null;\n  return _safe(await _centroid(), geom);\n}\n\nexport async function simplifyGeom(geom, opts = {}) {\n  if (!_isFeatureLike(geom)) return null;\n  const tolerance = Number.isFinite(opts.tolerance) ? opts.tolerance : 0.0001;\n  const highQuality = opts.highQuality !== false;\n  return _safe(await _simplify(), geom, { tolerance, highQuality });\n}\n\nexport async function bboxGeom(geom) {\n  if (!_isFeatureLike(geom)) return null;\n  return _safe(await _bbox(), geom);\n}\n\nexport async function bboxPolygonGeom(bboxArray) {\n  if (!Array.isArray(bboxArray) || bboxArray.length !== 4) return null;\n  for (const v of bboxArray) if (!Number.isFinite(v)) return null;\n  return _safe(await _bboxPolygon(), bboxArray);\n}\n\nexport async function pointsWithin(points, polygon) {\n  if (!_isFeatureLike(points) || !_isFeatureLike(polygon)) {\n    return { type: 'FeatureCollection', features: [] };\n  }\n  const result = _safe(await _pointsWithinPolygon(), points, polygon);\n  if (result && result.type === 'FeatureCollection') return result;\n  return { type: 'FeatureCollection', features: [] };\n}\n\nexport async function applyOp(op, args = {}) {\n  switch (String(op || '').toLowerCase()) {\n    case 'buffer': return bufferGeom(args.geomA, args.radius, args);\n    case 'union': return unionGeom(args.geomA, args.geomB);\n    case 'intersect': return intersectGeom(args.geomA, args.geomB);\n    case 'difference': return differenceGeom(args.geomA, args.geomB);\n    case 'within': return withinGeom(args.geomA, args.geomB);\n    case 'contains': return containsGeom(args.geomA, args.geomB);\n    case 'area': return areaGeom(args.geomA);\n    case 'length': return lengthGeom(args.geomA, args);\n    case 'centroid': return centroidGeom(args.geomA);\n    case 'simplify': return simplifyGeom(args.geomA, args);\n    case 'bbox': return bboxGeom(args.geomA);\n    case 'bboxpolygon':\n    case 'bbox_polygon':\n      return bboxPolygonGeom(args.bbox || args.geomA);\n    case 'pointswithin':\n    case 'points_within':\n    case 'pointswithinpolygon':\n      return pointsWithin(args.points || args.geomA, args.polygon || args.geomB);\n    default: return null;\n  }\n}\n\nexport const SPATIAL_OPS = Object.freeze([\n  'buffer', 'union', 'intersect', 'difference',\n  'within', 'contains', 'area', 'length',\n  'centroid', 'simplify', 'bbox', 'bboxPolygon',\n  'pointsWithin',\n]);\n","/**\n * Agent intents for reachability analysis (isochrones) and the standard\n * vector spatial-ops library. Auto-registered on import.\n *\n * Two intents:\n *   - `compute_isochrone` — fetch polygons via isochrone-service and emit\n *     `noclip:isochrone:set` so IsochroneOverlay (3D) and the minimap\n *     listener (2D) both pick it up.\n *   - `apply_spatial_op`  — dispatch a named turf op via spatial-ops.applyOp;\n *     returns the resulting GeoJSON / scalar in `toolResult` so the LLM\n *     can chain it into a follow-up tool call.\n *\n * Cross-cutting integration: we DO NOT directly touch PlanetScene or\n * MiniMapWidget here — those modules subscribe to the document events\n * we emit so they can be evolved independently. See\n * IsochroneOverlay-INTEGRATION.md for the exact wiring snippets.\n */\nimport { registerIntent, PERMISSIONS } from '../IntentRegistry.js';\nimport { getIsochrones } from '../../../modules/isochrone-service.js';\nimport { applyOp, SPATIAL_OPS } from '../../../modules/spatial-ops.js';\n\nfunction emitDocumentEvent(name, detail) {\n  if (typeof document === 'undefined' || typeof CustomEvent !== 'function') return;\n  try {\n    document.dispatchEvent(new CustomEvent(name, { detail }));\n  } catch {\n    // Older browsers / non-DOM environments — fail silently. The intent\n    // result still carries the FeatureCollection in toolResult.\n  }\n}\n\nlet _registered = false;\nlet activeIsochrone = null;\n\n/**\n * Register the two isochrone-related intents. Idempotent — safe to call\n * multiple times during HMR / test suites.\n */\nexport function registerIsochroneIntents() {\n  if (_registered) return;\n  _registered = true;\n\n  registerIntent({\n    name: 'compute_isochrone',\n    description: 'Compute drive/walk/bike reachability polygons (isochrones) from a [lat, lon] origin for a list of contour minutes. Renders on the 3D globe and the minimap.',\n    permissions: [PERMISSIONS.WRITE_OVERLAY, PERMISSIONS.NETWORK_FETCH],\n    params: {\n      type: 'object',\n      required: ['lat', 'lon'],\n      properties: {\n        lat: { type: 'number', description: 'Origin latitude in decimal degrees.' },\n        lon: { type: 'number', description: 'Origin longitude in decimal degrees.' },\n        profile: {\n          type: 'string',\n          enum: ['driving', 'cycling', 'foot'],\n          description: 'Routing profile. Defaults to \"driving\".',\n        },\n        contours: {\n          type: 'array',\n          items: { type: 'number' },\n          description: 'Contour minutes; up to 4 values (e.g. [5,10,15]).',\n        },\n        denoise: {\n          type: 'number',\n          description: 'Valhalla denoise factor 0..1; higher removes more spurious holes. Default 1.',\n        },\n        generalize: { type: 'number', description: 'Contour generalization in metres, 0..500. Default 50.' },\n      },\n    },\n    examples: [\n      {\n        utterance: 'show me everywhere within 5, 10, and 15 minutes by walking from here',\n        slots: { lat: 40.7580, lon: -73.9855, profile: 'foot', contours: [5, 10, 15] },\n      },\n      {\n        utterance: 'what is the 20-minute drive radius from this address?',\n        slots: { lat: 37.7749, lon: -122.4194, profile: 'driving', contours: [20] },\n      },\n    ],\n    handler: async (slots, context = {}) => {\n      const lat = slots.lat;\n      const lon = slots.lon;\n      if (!Number.isFinite(lat) || !Number.isFinite(lon)) {\n        return { applied: false, errors: ['compute_isochrone: lat and lon required'] };\n      }\n      const profile = slots.profile === undefined ? 'driving' : slots.profile;\n      const contours = slots.contours === undefined ? [5, 10, 15] : slots.contours;\n      const denoise = slots.denoise === undefined ? 1 : slots.denoise;\n\n      context.signal?.throwIfAborted();\n      activeIsochrone?.abort(new DOMException('Reachability superseded', 'AbortError'));\n      const controller = new AbortController(); activeIsochrone = controller;\n      const abort = () => controller.abort(context.signal.reason);\n      const cleared = () => controller.abort(new DOMException('Reachability cleared', 'AbortError'));\n      context.signal?.addEventListener('abort', abort, { once: true });\n      globalThis.document?.addEventListener('noclip:isochrone:cleared', cleared);\n      try {\n        const fc = await getIsochrones({ lat, lon }, { profile, contours, denoise,\n          generalize: slots.generalize, signal: controller.signal });\n        controller.signal.throwIfAborted();\n        if (activeIsochrone !== controller) return { applied: false, errors: ['Reachability superseded'] };\n        if (!fc || !Array.isArray(fc.features) || !fc.features.length) {\n          return {\n            applied: false,\n            errors: ['compute_isochrone: upstream returned no polygons (rate-limit or out-of-coverage)'],\n          };\n        }\n        // Notify both the 3D overlay and the minimap. They listen on the\n        // document so we don't need a direct reference here.\n        emitDocumentEvent('noclip:isochrone:set', fc);\n        return {\n          applied: true,\n          actionTags: [\n            `isochrone:${profile}`,\n            `isochrone:contours:${fc.contours.join(',')}`,\n          ],\n          toolResult: fc,\n        };\n      } finally {\n        context.signal?.removeEventListener('abort', abort);\n        globalThis.document?.removeEventListener('noclip:isochrone:cleared', cleared);\n        if (activeIsochrone === controller) activeIsochrone = null;\n      }\n    },\n  });\n\n  registerIntent({\n    name: 'apply_spatial_op',\n    description: `Apply a named turf.js spatial operation. Available ops: ${SPATIAL_OPS.join(', ')}. Returns the resulting GeoJSON or scalar.`,\n    permissions: [PERMISSIONS.READ_LAYERS],\n    params: {\n      type: 'object',\n      required: ['op', 'geomA'],\n      properties: {\n        op: {\n          type: 'string',\n          enum: [...SPATIAL_OPS],\n          description: 'The spatial operation to perform.',\n        },\n        geomA: {\n          type: 'object',\n          description: 'Primary GeoJSON Feature/Geometry/FeatureCollection.',\n        },\n        geomB: {\n          type: 'object',\n          description: 'Secondary GeoJSON for binary ops (union/intersect/difference/within/contains/pointsWithin).',\n        },\n        radius: {\n          type: 'number',\n          description: 'Buffer radius (default unit: metres). Required for op=\"buffer\".',\n        },\n        units: {\n          type: 'string',\n          description: 'Unit override for buffer/length: meters | kilometers | miles | feet.',\n        },\n        tolerance: {\n          type: 'number',\n          description: 'Simplify tolerance in degrees (default 0.0001).',\n        },\n      },\n    },\n    examples: [\n      {\n        utterance: 'buffer this point by 500 metres',\n        slots: {\n          op: 'buffer',\n          geomA: { type: 'Feature', geometry: { type: 'Point', coordinates: [-73.98, 40.76] }, properties: {} },\n          radius: 500,\n        },\n      },\n      {\n        utterance: 'is this address inside the 10-min isochrone?',\n        slots: {\n          op: 'within',\n          geomA: { type: 'Feature', geometry: { type: 'Point', coordinates: [-73.97, 40.78] }, properties: {} },\n          geomB: { type: 'Feature', geometry: { type: 'Polygon', coordinates: [[[-74, 40.7], [-73.9, 40.7], [-73.9, 40.8], [-74, 40.8], [-74, 40.7]]] }, properties: {} },\n        },\n      },\n    ],\n    handler: (slots) => {\n      const op = String(slots.op || '').trim();\n      if (!op) return { applied: false, errors: ['apply_spatial_op: op required'] };\n      if (!slots.geomA) {\n        return { applied: false, errors: ['apply_spatial_op: geomA required'] };\n      }\n      const result = applyOp(op, slots);\n      if (result === null || result === undefined) {\n        return { applied: false, errors: [`apply_spatial_op: ${op} returned no result (bad input or disjoint geoms)`] };\n      }\n      return {\n        applied: true,\n        actionTags: [`spatial-op:${op}`],\n        toolResult: result,\n      };\n    },\n  });\n}\n\n// Auto-register on import — same convention as scene-clock-intents.js.\nregisterIsochroneIntents();\n","/**\n * Agent intents for alternative-addressing lookup.\n *\n * Registers a single `lookup_address` intent that resolves any of the\n * supported address forms (`plus`, `w3w`, `mapcode`, `free`) to a lat/lon\n * via the unified addressing service. The agent layer uses this to fly the\n * camera or drop a tag from a chat message like:\n *   \"go to ///filled.count.soap\"\n *   \"where is 84QV98GV+CH\"\n */\nimport { registerIntent, PERMISSIONS } from '../IntentRegistry.js';\nimport { forward, sniff } from '../../../modules/addressing/index.js';\n\nlet _registered = false;\n\nexport function registerAddressingIntents() {\n  if (_registered) return;\n  _registered = true;\n\n  registerIntent({\n    name: 'lookup_address',\n    description: 'Resolve an alternative-addressing string (Plus Code, what3words, or Mapcode) to a lat/lon. If `form` is `free` or omitted, the syntax is auto-sniffed.',\n    permissions: [PERMISSIONS.NETWORK_FETCH],\n    params: {\n      type: 'object',\n      required: ['value'],\n      properties: {\n        form: {\n          type: 'string',\n          enum: ['plus', 'w3w', 'mapcode', 'free'],\n          description: 'Which address family the value belongs to. `free` (default) auto-sniffs.',\n        },\n        value: {\n          type: 'string',\n          description: 'The alt-addr text, e.g. \"///filled.count.soap\" or \"84QV98GV+CH\".',\n        },\n      },\n    },\n    examples: [\n      { utterance: 'go to ///filled.count.soap', slots: { form: 'w3w', value: '///filled.count.soap' } },\n      { utterance: 'navigate to 84QV98GV+CH',     slots: { form: 'plus', value: '84QV98GV+CH' } },\n      { utterance: 'lookup USA XXX.YY',           slots: { form: 'mapcode', value: 'USA XXX.YY' } },\n    ],\n    handler: async (slots) => {\n      const value = String(slots?.value || '').trim();\n      if (!value) return { applied: false, errors: ['lookup_address: missing value'] };\n      const form = (slots?.form || 'free').toLowerCase();\n      // When the caller declares a form, validate the syntax matches before\n      // making a network call — saves a round trip for clearly wrong inputs.\n      if (form !== 'free') {\n        const detected = sniff(value);\n        if (detected !== form && detected !== 'free') {\n          return {\n            applied: false,\n            errors: [`lookup_address: value looks like \"${detected}\" but form=\"${form}\"`],\n          };\n        }\n      }\n      const result = await forward(value);\n      if (!result) {\n        return {\n          applied: false,\n          errors: [`lookup_address: could not resolve \"${value}\"`],\n          actionTags: ['address.lookup_failed'],\n        };\n      }\n      return {\n        applied: true,\n        actionTags: [`address.lookup:${result.system}`],\n        toolResult: result,\n      };\n    },\n  });\n}\n","/**\n * CollabDoc (WO-006) — Yjs document for collaborative drawing/annotation.\n *\n * Lazy-imports `yjs` so the bundle stays buildable when the package\n * isn't installed yet (declared in package.json). Once installed and\n * the user opens a session, this wires Y.Map<shapeId, ...> + awareness\n * for cursors/selection over the existing NKN P2P transport.\n */\nlet _instance = null;\nexport function getCollabDoc(opts) {\n  if (!_instance) _instance = new CollabDoc(opts);\n  return _instance;\n}\n\nexport class CollabDoc {\n  constructor() {\n    this._sessionId = null;\n    this._doc = null;\n    this._provider = null;\n    this._YModule = null;\n  }\n\n  async _ensureYjs() {\n    if (this._YModule) return this._YModule;\n    try {\n      const Y = await import(/* @vite-ignore */ 'yjs');\n      this._YModule = Y;\n      return Y;\n    } catch (err) {\n      console.warn('[CollabDoc] yjs unavailable; collab features disabled until installed.', err);\n      return null;\n    }\n  }\n\n  async openSession(sessionId, { transport = 'nkn' } = {}) {\n    const Y = await this._ensureYjs();\n    if (!Y) return false;\n    this._sessionId = sessionId;\n    this._doc = new Y.Doc();\n    if (transport === 'nkn') {\n      const { YjsNknProvider } = await import('./YjsNknProvider.js');\n      this._provider = new YjsNknProvider(this._doc, sessionId);\n    } else {\n      const { YjsWsProvider } = await import('./YjsWsProvider.js');\n      this._provider = new YjsWsProvider(this._doc, sessionId);\n    }\n    return true;\n  }\n\n  getShapesMap() {\n    return this._doc?.getMap('shapes') || null;\n  }\n  getAwareness() { return this._provider?.awareness || null; }\n\n  async closeSession() {\n    if (this._provider?.destroy) await this._provider.destroy();\n    if (this._doc?.destroy) this._doc.destroy();\n    this._provider = null; this._doc = null; this._sessionId = null;\n  }\n}\n","import { registerIntent, PERMISSIONS } from '../IntentRegistry.js';\nimport { getCollabDoc } from '../../collab/CollabDoc.js';\n\nlet _registered = false;\nexport function registerCollabIntents() {\n  if (_registered) return;\n  _registered = true;\n  registerIntent({\n    name: 'create_session',\n    description: 'Create or join a collaborative editing session.',\n    permissions: [PERMISSIONS.WRITE_DRAWING, PERMISSIONS.NETWORK_FETCH],\n    params: { type: 'object', properties: { sessionId: { type: 'string' }, transport: { type: 'string', enum: ['nkn', 'ws'] } } },\n    handler: async (slots) => {\n      const sid = slots.sessionId || `s-${Date.now().toString(36)}`;\n      const ok = await getCollabDoc().openSession(sid, { transport: slots.transport });\n      return ok ? { applied: true, async: true, actionTags: [`collab.session:${sid}`], toolResult: { sessionId: sid } } : { applied: false };\n    },\n  });\n  registerIntent({\n    name: 'add_comment',\n    description: 'Attach a comment to a drawn shape inside the active collab session.',\n    permissions: [PERMISSIONS.WRITE_DRAWING],\n    params: { type: 'object', required: ['shapeId', 'text'], properties: { shapeId: { type: 'string' }, text: { type: 'string' } } },\n    handler: (slots) => {\n      const map = getCollabDoc().getShapesMap();\n      if (!map) return { applied: false, errors: ['No active session'] };\n      const shape = map.get(slots.shapeId);\n      if (!shape) return { applied: false, errors: ['Shape not found'] };\n      const comments = shape.comments || [];\n      shape.comments = [...comments, { text: slots.text, ts: Date.now() }];\n      map.set(slots.shapeId, shape);\n      return { applied: true, actionTags: ['collab.comment'] };\n    },\n  });\n}\n","/**\n * TileCache (WO-011) — frontend manager that talks to the service\n * worker via postMessage to pre-fetch a region's tiles. Uses\n * navigator.storage.estimate() to gate downloads against quota.\n */\nexport async function prefetchRegion(urls) {\n  if (!navigator.serviceWorker?.controller) return false;\n  navigator.serviceWorker.controller.postMessage({ type: 'PREFETCH_REGION', urls });\n  return true;\n}\n\nexport async function listenProgress(handler) {\n  if (typeof navigator === 'undefined' || !navigator.serviceWorker) return () => {};\n  const cb = (ev) => {\n    if (ev.data?.type?.startsWith('PREFETCH_')) handler(ev.data);\n  };\n  navigator.serviceWorker.addEventListener('message', cb);\n  return () => navigator.serviceWorker.removeEventListener('message', cb);\n}\n\nexport async function quotaStatus() {\n  if (!navigator.storage?.estimate) return { used: 0, quota: 0, ratio: 0 };\n  const { usage = 0, quota = 0 } = await navigator.storage.estimate();\n  return { used: usage, quota, ratio: quota > 0 ? usage / quota : 0 };\n}\n","/**\n * Generate the list of tile URLs needed for a bbox at a zoom range.\n * Slippy-tile (XYZ) scheme. Replaces {z}/{x}/{y} placeholders in the\n * provided urlTemplate.\n */\nfunction _lonLatToTileXY(lon, lat, z) {\n  const n = Math.pow(2, z);\n  const x = Math.floor((lon + 180) / 360 * n);\n  const latRad = lat * Math.PI / 180;\n  const y = Math.floor((1 - Math.log(Math.tan(latRad) + 1 / Math.cos(latRad)) / Math.PI) / 2 * n);\n  return { x, y };\n}\n\nexport function generateTileList({ bbox, zooms, urlTemplate }) {\n  if (!bbox || !urlTemplate) return [];\n  const [west, south, east, north] = bbox;\n  const out = [];\n  for (const z of zooms) {\n    const tl = _lonLatToTileXY(west, north, z);\n    const br = _lonLatToTileXY(east, south, z);\n    for (let x = tl.x; x <= br.x; x++) {\n      for (let y = tl.y; y <= br.y; y++) {\n        out.push(urlTemplate.replace('{z}', z).replace('{x}', x).replace('{y}', y));\n      }\n    }\n  }\n  return out;\n}\n\nexport function estimateBytes(urlCount, avgBytesPerTile = 30_000) {\n  return urlCount * avgBytesPerTile;\n}\n","import { registerIntent, PERMISSIONS } from '../IntentRegistry.js';\nimport { prefetchRegion, quotaStatus } from '../../../modules/offline/TileCache.js';\nimport { generateTileList } from '../../../modules/offline/tile-list.js';\nimport { getActive as getActiveBasemap } from '../../imagery/BasemapRegistry.js';\n\nlet _registered = false;\nexport function registerOfflineIntents() {\n  if (_registered) return;\n  _registered = true;\n  registerIntent({\n    name: 'download_region',\n    description: 'Pre-fetch tiles for a bbox at given zoom levels for offline use.',\n    permissions: [PERMISSIONS.STORAGE_WRITE, PERMISSIONS.NETWORK_FETCH],\n    params: {\n      type: 'object', required: ['bbox'],\n      properties: {\n        bbox: { type: 'array', items: { type: 'number' } },\n        zooms: { type: 'array', items: { type: 'integer' } },\n      },\n    },\n    handler: async (slots) => {\n      const active = getActiveBasemap();\n      if (!active?.url) return { applied: false, errors: ['No active basemap'] };\n      const zooms = slots.zooms?.length ? slots.zooms : [14, 15, 16, 17, 18];\n      const urls = generateTileList({ bbox: slots.bbox, zooms, urlTemplate: active.url });\n      const ok = await prefetchRegion(urls);\n      const quota = await quotaStatus();\n      return ok\n        ? { applied: true, async: true, actionTags: ['offline.download'], toolResult: { count: urls.length, quota } }\n        : { applied: false, errors: ['Service worker not active'] };\n    },\n  });\n  registerIntent({\n    name: 'list_offline_regions',\n    description: 'Return offline storage usage stats.',\n    permissions: [PERMISSIONS.READ_LAYERS],\n    params: { type: 'object', properties: {} },\n    handler: async () => {\n      const q = await quotaStatus();\n      return { applied: true, async: true, toolResult: q, actionTags: ['offline.list'] };\n    },\n  });\n}\n","/**\n * IndoorOverlay (WO-012) — render OSM `indoor=*` features for the\n * current active level. Fetches venue data via Overpass, partitions\n * by level, exposes a `setActiveLevel(n)` API consumed by FloorSwitcher.\n */\nimport { getFetchQueue } from '../async/fetch/FetchQueue.js';\nimport { resolveBackendApiUrl } from '../shared/backend.js';\n\nlet _instance = null;\nexport function getIndoorOverlay(opts) {\n  if (!_instance) _instance = new IndoorOverlay(opts);\n  return _instance;\n}\n\nexport class IndoorOverlay {\n  constructor({ parentGroup } = {}) {\n    this.parentGroup = parentGroup || null;\n    this._levels = new Map(); // levelN -> features\n    this._activeLevel = 0;\n    this._venueBbox = null;\n  }\n\n  async loadVenue(bbox) {\n    this._venueBbox = bbox;\n    const query = `\n      [out:json][timeout:15];\n      (\n        node[\"indoor\"](${bbox.join(',')});\n        way[\"indoor\"](${bbox.join(',')});\n        relation[\"indoor\"](${bbox.join(',')});\n      );\n      out geom;`;\n    try {\n      const result = await getFetchQueue().fetchJSON(resolveBackendApiUrl('/overpass'), {\n        method: 'POST',\n        headers: { 'Content-Type': 'text/plain' },\n        body: query,\n      });\n      if (!result.ok) return false;\n      const data = result.data || {};\n      this._partitionByLevel(data.elements || []);\n      return true;\n    } catch (err) {\n      console.warn('[IndoorOverlay] venue fetch failed', err);\n      return false;\n    }\n  }\n\n  _partitionByLevel(elements) {\n    this._levels.clear();\n    for (const el of elements) {\n      const lvl = Number(el.tags?.level || 0);\n      if (!this._levels.has(lvl)) this._levels.set(lvl, []);\n      this._levels.get(lvl).push(el);\n    }\n  }\n\n  setActiveLevel(level) {\n    this._activeLevel = Number(level) || 0;\n    try {\n      document.dispatchEvent(new CustomEvent('noclip:indoor:level-change', {\n        detail: { level: this._activeLevel },\n      }));\n    } catch {}\n  }\n  activeLevel() { return this._activeLevel; }\n  availableLevels() { return Array.from(this._levels.keys()).sort((a, b) => a - b); }\n}\n","import { registerIntent, PERMISSIONS } from '../IntentRegistry.js';\nimport { getIndoorOverlay } from '../../overlays/IndoorOverlay.js';\n\nlet _registered = false;\nexport function registerIndoorIntents() {\n  if (_registered) return;\n  _registered = true;\n  registerIntent({\n    name: 'set_active_level',\n    description: 'Switch the active floor in an indoor venue.',\n    permissions: [PERMISSIONS.WRITE_OVERLAY],\n    params: { type: 'object', required: ['level'], properties: { level: { type: 'integer' } } },\n    handler: (slots) => {\n      getIndoorOverlay().setActiveLevel(slots.level);\n      return { applied: true, actionTags: [`indoor.level:${slots.level}`] };\n    },\n  });\n}\n","/**\n * MarketplaceClient (WO-014) — REST client for the Hydra marketplace\n * order/listing/reputation flow.\n */\nimport { resolveBackendApiUrl } from '../shared/backend.js';\nimport { getAuthService } from '../auth/AuthService.js';\n\nasync function _req(method, path, body) {\n  try {\n    const resp = await getAuthService().authenticatedFetch(resolveBackendApiUrl(path), {\n      method,\n      headers: body ? { 'Content-Type': 'application/json' } : {},\n      body: body ? JSON.stringify(body) : undefined,\n    });\n    if (!resp.ok) return null;\n    return await resp.json();\n  } catch { return null; }\n}\n\nexport const Marketplace = {\n  search(q) { return _req('GET', `/marketplace/services?${new URLSearchParams(q || {})}`); },\n  getService(id) { return _req('GET', `/marketplace/services/${encodeURIComponent(id)}`); },\n  placeOrder(serviceId, input) { return _req('POST', '/marketplace/orders', { serviceId, input }); },\n  listOrders() { return _req('GET', '/marketplace/orders'); },\n  settleOrder(orderId) { return _req('POST', `/marketplace/orders/${orderId}/settle`); },\n  registerListing(spec) { return _req('POST', '/marketplace/listings', spec); },\n  heartbeat(listingId) { return _req('POST', `/marketplace/listings/${listingId}/heartbeat`); },\n  postReputation(receipt) { return _req('POST', '/marketplace/reputation', receipt); },\n};\n","import { registerIntent, PERMISSIONS } from '../IntentRegistry.js';\nimport { Marketplace } from '../../marketplace/MarketplaceClient.js';\n\nlet _registered = false;\nexport function registerMarketplaceIntents() {\n  if (_registered) return;\n  _registered = true;\n  registerIntent({\n    name: 'marketplace_search',\n    description: 'Search the Hydra marketplace for peer-offered spatial services.',\n    permissions: [PERMISSIONS.NETWORK_FETCH],\n    params: { type: 'object', properties: { capability: { type: 'string' } } },\n    handler: async (slots) => {\n      const r = await Marketplace.search({ capability: slots.capability });\n      return r ? { applied: true, async: true, toolResult: r, actionTags: ['marketplace.search'] } : { applied: false };\n    },\n  });\n  registerIntent({\n    name: 'marketplace_order',\n    description: 'Place an order against a marketplace service.',\n    permissions: [PERMISSIONS.NETWORK_FETCH, PERMISSIONS.WALLET_SIGN],\n    params: { type: 'object', required: ['serviceId'], properties: { serviceId: { type: 'string' }, input: { type: 'object' } } },\n    handler: async (slots) => {\n      const r = await Marketplace.placeOrder(slots.serviceId, slots.input || {});\n      return r ? { applied: true, async: true, toolResult: r, actionTags: ['marketplace.order'] } : { applied: false };\n    },\n  });\n  registerIntent({\n    name: 'marketplace_status',\n    description: 'Check the status of an existing marketplace order.',\n    permissions: [PERMISSIONS.NETWORK_FETCH],\n    params: { type: 'object', required: ['orderId'], properties: { orderId: { type: 'string' } } },\n    handler: async () => {\n      const r = await Marketplace.listOrders();\n      return r ? { applied: true, async: true, toolResult: r, actionTags: ['marketplace.status'] } : { applied: false };\n    },\n  });\n}\n","/**\n * IndexedDB-backed capture store (WO-015).\n * Survives app close; syncs queue when network returns.\n */\nconst DB_NAME = 'noclip-captures';\nconst STORE = 'captures';\nconst DB_VERSION = 2;\n\nfunction _openDb() {\n  return new Promise((resolve, reject) => {\n    const req = indexedDB.open(DB_NAME, DB_VERSION);\n    req.onupgradeneeded = () => {\n      const db = req.result;\n      const transaction = req.transaction;\n      let os;\n      if (!db.objectStoreNames.contains(STORE)) {\n        os = db.createObjectStore(STORE, { keyPath: 'id', autoIncrement: true });\n        os.createIndex('ts', 'ts');\n        os.createIndex('syncStatus', 'syncStatus');\n      } else {\n        os = transaction.objectStore(STORE);\n      }\n      if (!os.indexNames.contains('assetId')) os.createIndex('assetId', 'assetId');\n    };\n    req.onsuccess = () => resolve(req.result);\n    req.onerror = () => reject(req.error);\n  });\n}\n\nlet _instance = null;\nexport function getCaptureStore() {\n  if (!_instance) _instance = new CaptureStore();\n  return _instance;\n}\n\nexport class CaptureStore {\n  async put(record) {\n    const db = await _openDb();\n    return new Promise((resolve, reject) => {\n      const tx = db.transaction(STORE, 'readwrite');\n      const req = tx.objectStore(STORE).add({ ...record, syncStatus: 'pending' });\n      req.onsuccess = () => resolve(req.result);\n      req.onerror = () => reject(req.error);\n    });\n  }\n  async listPending() {\n    const db = await _openDb();\n    return new Promise((resolve, reject) => {\n      const tx = db.transaction(STORE, 'readonly');\n      const req = tx.objectStore(STORE).index('syncStatus').getAll('pending');\n      req.onsuccess = () => resolve(req.result || []);\n      req.onerror = () => reject(req.error);\n    });\n  }\n  async get(id) {\n    const db = await _openDb();\n    return new Promise((resolve, reject) => {\n      const tx = db.transaction(STORE, 'readonly');\n      const req = tx.objectStore(STORE).get(id);\n      req.onsuccess = () => resolve(req.result || null);\n      req.onerror = () => reject(req.error);\n    });\n  }\n  async update(id, updates = {}) {\n    const db = await _openDb();\n    return new Promise((resolve, reject) => {\n      const tx = db.transaction(STORE, 'readwrite');\n      const os = tx.objectStore(STORE);\n      const req = os.get(id);\n      req.onsuccess = () => {\n        const record = req.result;\n        if (!record) {\n          resolve(null);\n          return;\n        }\n        const next = { ...record, ...updates, id: record.id };\n        const put = os.put(next);\n        put.onsuccess = () => resolve(next);\n        put.onerror = () => reject(put.error);\n      };\n      req.onerror = () => reject(req.error);\n    });\n  }\n  async listByAsset(assetId) {\n    const db = await _openDb();\n    return new Promise((resolve, reject) => {\n      const tx = db.transaction(STORE, 'readonly');\n      const req = tx.objectStore(STORE).index('assetId').getAll(assetId);\n      req.onsuccess = () => resolve(req.result || []);\n      req.onerror = () => reject(req.error);\n    });\n  }\n  async markSynced(id) {\n    const result = await this.update(id, {\n      syncStatus: 'synced',\n      syncedAt: Date.now(),\n    });\n    return !!result;\n  }\n}\n","/**\n * CaptureSystem (WO-015) — coordinator for field-capture: photo, video,\n * audio note, GPS track, POI survey. Persists to IndexedDB; syncs to\n * backend when online. Reuses MotionTracker for tracks.\n */\nimport { getCaptureStore } from '../../modules/storage/capture-store.js';\n\nlet _instance = null;\nexport function getCaptureSystem(opts) {\n  if (!_instance) _instance = new CaptureSystem(opts);\n  return _instance;\n}\n\nexport class CaptureSystem {\n  constructor() {\n    this.store = getCaptureStore();\n    this._wakeLock = null;\n  }\n\n  async startTrack() {\n    try {\n      if ('wakeLock' in navigator) {\n        this._wakeLock = await navigator.wakeLock.request('screen');\n      }\n    } catch {}\n    return true;\n  }\n\n  async stopTrack() {\n    try { if (this._wakeLock) await this._wakeLock.release(); } catch {}\n    this._wakeLock = null;\n    return true;\n  }\n\n  async capturePhoto({ blob, lat, lon, heading, altitude, ts = Date.now() } = {}) {\n    return this.store.put({ kind: 'photo', blob, lat, lon, heading, altitude, ts });\n  }\n  async captureAudioNote({ blob, lat, lon, ts = Date.now() } = {}) {\n    return this.store.put({ kind: 'audio', blob, lat, lon, ts });\n  }\n  async captureVideo({ blob, lat, lon, heading, ts = Date.now() } = {}) {\n    return this.store.put({ kind: 'video', blob, lat, lon, heading, ts });\n  }\n  async addPoi({ kind, lat, lon, attributes = {}, ts = Date.now() } = {}) {\n    return this.store.put({ kind: 'poi', poiKind: kind, lat, lon, attributes, ts });\n  }\n}\n","import { registerIntent, PERMISSIONS } from '../IntentRegistry.js';\nimport { getCaptureSystem } from '../../capture/CaptureSystem.js';\n\nlet _registered = false;\nexport function registerCaptureIntents() {\n  if (_registered) return;\n  _registered = true;\n  const cs = getCaptureSystem();\n  registerIntent({\n    name: 'start_track',\n    description: 'Start recording a GPS track with screen wake-lock.',\n    permissions: [PERMISSIONS.STORAGE_WRITE],\n    params: { type: 'object', properties: {} },\n    handler: async () => { await cs.startTrack(); return { applied: true, async: true, actionTags: ['capture.track.start'] }; },\n  });\n  registerIntent({\n    name: 'stop_track',\n    description: 'Stop the active GPS track.',\n    permissions: [PERMISSIONS.STORAGE_WRITE],\n    params: { type: 'object', properties: {} },\n    handler: async () => { await cs.stopTrack(); return { applied: true, async: true, actionTags: ['capture.track.stop'] }; },\n  });\n  registerIntent({\n    name: 'add_poi',\n    description: 'Record an OSM-style POI at the player position.',\n    permissions: [PERMISSIONS.STORAGE_WRITE],\n    params: {\n      type: 'object', required: ['kind', 'lat', 'lon'],\n      properties: {\n        kind: { type: 'string' },\n        lat: { type: 'number' }, lon: { type: 'number' },\n        attributes: { type: 'object' },\n      },\n    },\n    handler: async (slots) => { await cs.addPoi(slots); return { applied: true, async: true, actionTags: [`capture.poi:${slots.kind}`] }; },\n  });\n}\n","/**\n * Raster client (WO-009) — runs band-math / diff / classify operations\n * against the backend `/raster/*` proxy that fronts the Python sidecar.\n */\nimport { resolveBackendApiUrl } from '../refactor/shared/backend.js';\nimport { getFetchQueue } from '../refactor/async/fetch/FetchQueue.js';\n\nasync function _post(path, body) {\n  try {\n    const result = await getFetchQueue().fetchJSON(resolveBackendApiUrl(path), {\n      method: 'POST', headers: { 'Content-Type': 'application/json' },\n      body: JSON.stringify(body),\n    });\n    if (!result.ok) return null;\n    return result.data;\n  } catch { return null; }\n}\n\nexport async function runBandMath({ inputs, expression }) {\n  return _post('/raster/band-math', { inputs, expression });\n}\n\nexport async function runDiff({ cogUrlA, cogUrlB, mode = 'simple' }) {\n  return _post('/raster/diff', { cogUrlA, cogUrlB, mode });\n}\n\nexport async function runClassify({ cogUrl, training_pixels, algorithm = 'rf' }) {\n  return _post('/raster/classify', { cogUrl, training_pixels, algorithm });\n}\n\nexport async function pollJob(jobId) {\n  try {\n    const result = await getFetchQueue().fetchJSON(resolveBackendApiUrl(`/raster/job/${encodeURIComponent(jobId)}`));\n    if (!result.ok) return null;\n    return result.data;\n  } catch { return null; }\n}\n","import { registerIntent, PERMISSIONS } from '../IntentRegistry.js';\nimport { runBandMath, runDiff, runClassify } from '../../../modules/raster-client.js';\n\nlet _registered = false;\nexport function registerRasterIntents() {\n  if (_registered) return;\n  _registered = true;\n\n  registerIntent({\n    name: 'compute_index',\n    description: 'Compute a per-pixel band-math index (NDVI/NDWI/NDBI/NBR/EVI) on a Sentinel/Landsat scene.',\n    permissions: [PERMISSIONS.NETWORK_FETCH],\n    params: {\n      type: 'object', required: ['inputs', 'expression'],\n      properties: {\n        inputs: { type: 'array', items: { type: 'object', properties: { cogUrl: { type: 'string' }, band: { type: 'string' } } } },\n        expression: { type: 'string' },\n      },\n    },\n    handler: async (slots) => {\n      const r = await runBandMath(slots);\n      return r ? { applied: true, async: true, toolResult: r, actionTags: ['raster.band-math'] } : { applied: false };\n    },\n  });\n\n  registerIntent({\n    name: 'compute_diff',\n    description: 'Compute pixel-wise difference between two scenes (change detection).',\n    permissions: [PERMISSIONS.NETWORK_FETCH],\n    params: {\n      type: 'object', required: ['cogUrlA', 'cogUrlB'],\n      properties: {\n        cogUrlA: { type: 'string' }, cogUrlB: { type: 'string' },\n        mode: { type: 'string', enum: ['simple', 'change-vector'] },\n      },\n    },\n    handler: async (slots) => {\n      const r = await runDiff(slots);\n      return r ? { applied: true, async: true, toolResult: r, actionTags: ['raster.diff'] } : { applied: false };\n    },\n  });\n\n  registerIntent({\n    name: 'classify_raster',\n    description: 'Run supervised classification on a scene using user-supplied training pixels.',\n    permissions: [PERMISSIONS.NETWORK_FETCH],\n    params: {\n      type: 'object', required: ['cogUrl', 'training_pixels'],\n      properties: {\n        cogUrl: { type: 'string' },\n        training_pixels: { type: 'array' },\n        algorithm: { type: 'string', enum: ['rf', 'kmeans'] },\n      },\n    },\n    handler: async (slots) => {\n      const r = await runClassify(slots);\n      return r ? { applied: true, async: true, toolResult: r, actionTags: ['raster.classify'] } : { applied: false };\n    },\n  });\n}\n","import { registerIntent, PERMISSIONS } from '../IntentRegistry.js';\n\nlet _registered = false;\nexport function registerBigDataIntents() {\n  if (_registered) return;\n  _registered = true;\n  registerIntent({\n    name: 'add_big_data_layer',\n    description: 'Add a deck.gl-backed big-data overlay layer. Kinds: hexagon, heatmap, scatter, trips, column, grid, icon.',\n    permissions: [PERMISSIONS.WRITE_OVERLAY],\n    params: {\n      type: 'object', required: ['id', 'kind'],\n      properties: {\n        id: { type: 'string' }, kind: { type: 'string' }, sourceId: { type: 'string' },\n        data: { type: 'array' },\n      },\n    },\n    handler: async (slots) => {\n      try {\n        const { getBigDataOverlay } = await import('../../overlays/BigDataOverlay.js');\n        const overlay = getBigDataOverlay({});\n        if (slots.sourceId && Array.isArray(slots.data)) overlay.setSource(slots.sourceId, slots.data);\n        const ok = await overlay.addLayer({ id: slots.id, kind: slots.kind, sourceId: slots.sourceId });\n        return ok\n          ? { applied: true, actionTags: [`bigdata.layer:${slots.id}`] }\n          : { applied: false, errors: ['deck.gl not available'] };\n      } catch (err) { return { applied: false, errors: [String(err)] }; }\n    },\n  });\n  registerIntent({\n    name: 'remove_big_data_layer',\n    description: 'Remove a big-data overlay layer by id.',\n    permissions: [PERMISSIONS.WRITE_OVERLAY],\n    params: { type: 'object', required: ['id'], properties: { id: { type: 'string' } } },\n    handler: async (slots) => {\n      try {\n        const { getBigDataOverlay } = await import('../../overlays/BigDataOverlay.js');\n        const ok = getBigDataOverlay({}).removeLayer(slots.id);\n        return { applied: !!ok, actionTags: [`bigdata.remove:${slots.id}`] };\n      } catch (err) { return { applied: false, errors: [String(err)] }; }\n    },\n  });\n}\n","/**\n * WeatherRadarOverlay (WO-025).\n *\n * Animated precipitation radar overlay with three keyless free sources:\n *   - RainViewer (global, https://api.rainviewer.com/public/weather-maps.json)\n *   - NOAA NEXRAD via Iowa Mesonet (US)\n *   - MetOffice DataPoint (UK; requires key — disabled by default)\n *\n * Auto-picks the best source for the current visible bbox; falls back\n * to RainViewer globally. Subscribes to SceneClock for replay/scrub.\n */\nimport * as THREE from 'three';\nimport { latLonToLocalDir, ellipsoidRadiusForLocalDir } from '../../modules/geometry-utils.js';\nimport { getFetchQueue } from '../async/fetch/FetchQueue.js';\n\nconst RAINVIEWER_INDEX = 'https://api.rainviewer.com/public/weather-maps.json';\nconst FRAME_REFRESH_MS = 60_000;\n\nlet _instance = null;\nexport function getWeatherRadarOverlay(opts) {\n  if (!_instance) _instance = new WeatherRadarOverlay(opts);\n  return _instance;\n}\n\nexport class WeatherRadarOverlay {\n  constructor({ parentGroup, getSceneClock } = {}) {\n    this.parentGroup = parentGroup || null;\n    this._getClock = getSceneClock || (() => globalThis.window?.__noclipSceneClock);\n    this._enabled = false;\n    this._frames = [];        // [{ ts, path }]\n    this._lastFetchAt = 0;\n    this._activeFrameIdx = 0;\n    this._mesh = null;\n    this._tex = null;\n    this._onClockTick = (ev) => this._onClock(ev?.detail || ev);\n    if (typeof document !== 'undefined') {\n      document.addEventListener('noclip:clock:tick', this._onClockTick);\n    }\n  }\n\n  setEnabled(on) {\n    this._enabled = !!on;\n    if (this._enabled) this._refreshFrames();\n    if (this._mesh) this._mesh.visible = this._enabled;\n  }\n\n  async _refreshFrames() {\n    const now = Date.now();\n    if (now - this._lastFetchAt < FRAME_REFRESH_MS) return;\n    this._lastFetchAt = now;\n    try {\n      const result = await getFetchQueue().fetchJSON(RAINVIEWER_INDEX);\n      if (!result.ok) return;\n      const json = result.data || {};\n      const past = json.radar?.past || [];\n      const nowcast = json.radar?.nowcast || [];\n      this._frames = [...past, ...nowcast].map((f) => ({\n        ts: f.time * 1000, path: `${json.host}${f.path}/256/{z}/{x}/{y}/2/1_1.png`,\n      }));\n    } catch (err) {\n      console.warn('[WeatherRadar] frame index fetch failed', err);\n    }\n  }\n\n  _onClock(detail) {\n    if (!this._enabled || !this._frames.length) return;\n    const t = detail?.time || Date.now();\n    // Find nearest frame ≤ t\n    let best = 0;\n    for (let i = 0; i < this._frames.length; i++) {\n      if (this._frames[i].ts <= t) best = i;\n    }\n    if (best !== this._activeFrameIdx) {\n      this._activeFrameIdx = best;\n      // Frame swap is a no-op for the surface mesh; tile-layer consumer\n      // (MiniMap) reads activeFrame() to refresh its tile URL template.\n      if (typeof document !== 'undefined' && typeof CustomEvent !== 'undefined') {\n        document.dispatchEvent(new CustomEvent('noclip:weather:frame-change', {\n          detail: { idx: best, ts: this._frames[best].ts },\n        }));\n      }\n    }\n  }\n\n  activeFrame() { return this._frames[this._activeFrameIdx] || null; }\n  frames() { return this._frames; }\n\n  dispose() {\n    if (typeof document !== 'undefined' && this._onClockTick) {\n      document.removeEventListener('noclip:clock:tick', this._onClockTick);\n    }\n    this._mesh?.geometry?.dispose?.();\n    this._mesh?.material?.dispose?.();\n    this._mesh = null;\n  }\n}\n","import { registerIntent, PERMISSIONS } from '../IntentRegistry.js';\nimport { getWeatherRadarOverlay } from '../../overlays/WeatherRadarOverlay.js';\n\nlet _registered = false;\nexport function registerWeatherIntents() {\n  if (_registered) return;\n  _registered = true;\n  registerIntent({\n    name: 'show_weather_radar',\n    description: 'Enable the animated weather radar overlay.',\n    permissions: [PERMISSIONS.WRITE_OVERLAY],\n    params: { type: 'object', properties: {} },\n    handler: () => { getWeatherRadarOverlay().setEnabled(true); return { applied: true, actionTags: ['weather.show'] }; },\n  });\n  registerIntent({\n    name: 'hide_weather_radar',\n    description: 'Disable the weather radar overlay.',\n    permissions: [PERMISSIONS.WRITE_OVERLAY],\n    params: { type: 'object', properties: {} },\n    handler: () => { getWeatherRadarOverlay().setEnabled(false); return { applied: true, actionTags: ['weather.hide'] }; },\n  });\n}\n","/**\n * SatelliteImageryOverlay (WO-026) — time-series satellite imagery\n * stream from Sentinel-1/2/3, Landsat 8/9, MODIS, GOES-East/West.\n *\n * Subscribes to SceneClock; given a date range + bbox + sensor, picks\n * the most-recent-prior STAC item per visible-bbox-pixel, fetches COG\n * tiles, renders. Per-band visualisation presets (true-color,\n * false-color, NDVI via WO-009 raster pipeline).\n *\n * Currently a scaffold — full COG-to-tile rendering depends on\n * geotiff.js being installed (in package.json deps as of this WO).\n */\nlet _instance = null;\nexport function getSatelliteImageryOverlay(opts) {\n  if (!_instance) _instance = new SatelliteImageryOverlay(opts);\n  return _instance;\n}\n\nconst PRESETS = {\n  'sentinel2-truecolor': { bands: ['B04', 'B03', 'B02'], stretch: 'percentile-2-98' },\n  'sentinel2-falsecolor': { bands: ['B08', 'B04', 'B03'] },\n  'sentinel2-ndvi': { expression: '(B08 - B04) / (B08 + B04)', ramp: 'RdYlGn' },\n  'sentinel1-vv': { bands: ['vv'], stretch: 'log' },\n  'landsat-truecolor': { bands: ['red', 'green', 'blue'] },\n};\n\nexport class SatelliteImageryOverlay {\n  constructor({ parentGroup } = {}) {\n    this.parentGroup = parentGroup || null;\n    this._enabled = false;\n    this._sensor = 'sentinel2-truecolor';\n    this._items = [];   // current STAC item set\n    this._activeTs = Date.now();\n    this._onClock = (ev) => this._handleClock(ev?.detail || ev);\n    if (typeof document !== 'undefined') {\n      document.addEventListener('noclip:clock:tick', this._onClock);\n      document.addEventListener('noclip:stac:add-item', (ev) => {\n        const it = ev?.detail?.item;\n        if (it) this._items.push(it);\n      });\n    }\n  }\n\n  setEnabled(on) { this._enabled = !!on; }\n  setSensor(name) { if (PRESETS[name]) this._sensor = name; }\n  preset() { return PRESETS[this._sensor]; }\n\n  _handleClock(detail) {\n    if (!this._enabled) return;\n    const t = detail?.time || Date.now();\n    this._activeTs = t;\n    // Find the most-recent item ≤ t. For now, just emit an event other\n    // overlays can hook into; full COG rendering needs WO-009 sidecar.\n    let best = null;\n    for (const it of this._items) {\n      const ts = Date.parse(it.properties?.datetime || '');\n      if (Number.isFinite(ts) && ts <= t && (!best || ts > Date.parse(best.properties?.datetime || ''))) best = it;\n    }\n    if (best) {\n      try {\n        document.dispatchEvent(new CustomEvent('noclip:satellite:active-item', { detail: { item: best, ts: t } }));\n      } catch {}\n    }\n  }\n\n  dispose() {\n    if (this._onClock) document.removeEventListener('noclip:clock:tick', this._onClock);\n  }\n}\n","import { registerIntent, PERMISSIONS } from '../IntentRegistry.js';\nimport { getSatelliteImageryOverlay } from '../../overlays/SatelliteImageryOverlay.js';\n\nlet _registered = false;\nexport function registerSatelliteIntents() {\n  if (_registered) return;\n  _registered = true;\n  registerIntent({\n    name: 'add_satellite_layer',\n    description: 'Enable a time-series satellite imagery layer for a given sensor preset.',\n    permissions: [PERMISSIONS.WRITE_OVERLAY],\n    params: {\n      type: 'object',\n      properties: {\n        sensor: { type: 'string', enum: ['sentinel2-truecolor', 'sentinel2-falsecolor', 'sentinel2-ndvi', 'sentinel1-vv', 'landsat-truecolor'] },\n      },\n    },\n    handler: (slots) => {\n      const o = getSatelliteImageryOverlay();\n      if (slots.sensor) o.setSensor(slots.sensor);\n      o.setEnabled(true);\n      return { applied: true, actionTags: [`satellite.add:${slots.sensor || 'default'}`] };\n    },\n  });\n}\n","/**\n * STAC client (WO-007) — read+write STAC catalog operations against\n * either our backend at `/stac/*` or any external conformant STAC API\n * (Microsoft Planetary Computer, Earth Search, etc.) via the proxy.\n *\n * All methods return promise<json|null>. On any HTTP error we resolve\n * `null` rather than throw; callers handle `null` as \"no data\".\n */\nimport { resolveBackendApiUrl } from '../refactor/shared/backend.js';\nimport { getFetchQueue } from '../refactor/async/fetch/FetchQueue.js';\n\nasync function _get(url) {\n  try {\n    const result = await getFetchQueue().fetchJSON(url, { headers: { Accept: 'application/json' } });\n    if (!result.ok) return null;\n    return result.data;\n  } catch { return null; }\n}\n\nasync function _post(url, body) {\n  try {\n    const result = await getFetchQueue().fetchJSON(url, {\n      method: 'POST',\n      headers: { 'Content-Type': 'application/json', Accept: 'application/json' },\n      body: JSON.stringify(body || {}),\n    });\n    if (!result.ok) return null;\n    return result.data;\n  } catch { return null; }\n}\n\n/** GET /stac/collections */\nexport async function listCollections({ external } = {}) {\n  const base = external ? `/stac/proxy/${external}` : '/stac';\n  return _get(resolveBackendApiUrl(`${base}/collections`));\n}\n\n/** GET /stac/collections/:id */\nexport async function getCollection(id, { external } = {}) {\n  const base = external ? `/stac/proxy/${external}` : '/stac';\n  return _get(resolveBackendApiUrl(`${base}/collections/${encodeURIComponent(id)}`));\n}\n\n/** GET /stac/collections/:id/items?bbox=&datetime=&limit= */\nexport async function listItems(cid, { bbox, datetime, limit = 50, external } = {}) {\n  const base = external ? `/stac/proxy/${external}` : '/stac';\n  const p = new URLSearchParams();\n  if (bbox) p.set('bbox', Array.isArray(bbox) ? bbox.join(',') : bbox);\n  if (datetime) p.set('datetime', datetime);\n  p.set('limit', String(limit));\n  return _get(resolveBackendApiUrl(`${base}/collections/${encodeURIComponent(cid)}/items?${p}`));\n}\n\n/** POST /stac/search */\nexport async function search(criteria, { external } = {}) {\n  const base = external ? `/stac/proxy/${external}` : '/stac';\n  return _post(resolveBackendApiUrl(`${base}/search`), criteria);\n}\n\n/** GET /stac/collections/:id/items/:iid */\nexport async function getItem(cid, iid, { external } = {}) {\n  const base = external ? `/stac/proxy/${external}` : '/stac';\n  return _get(resolveBackendApiUrl(`${base}/collections/${encodeURIComponent(cid)}/items/${encodeURIComponent(iid)}`));\n}\n","import { registerIntent, PERMISSIONS } from '../IntentRegistry.js';\nimport { search, getItem } from '../../../modules/stac-client.js';\n\nlet _registered = false;\nexport function registerStacIntents() {\n  if (_registered) return;\n  _registered = true;\n  registerIntent({\n    name: 'search_stac',\n    description: 'Search the STAC catalog for satellite imagery items in a bbox + datetime window.',\n    permissions: [PERMISSIONS.READ_LAYERS, PERMISSIONS.NETWORK_FETCH],\n    params: {\n      type: 'object',\n      properties: {\n        bbox: { type: 'array', items: { type: 'number' } },\n        datetime: { type: 'string' },\n        collections: { type: 'array', items: { type: 'string' } },\n        external: { type: 'string', enum: ['planetary-computer', 'earth-search'] },\n      },\n    },\n    handler: async (slots) => {\n      const r = await search(slots, { external: slots.external });\n      return r ? { applied: true, async: true, toolResult: r, actionTags: ['stac.search'] } : { applied: false };\n    },\n  });\n  registerIntent({\n    name: 'add_stac_item',\n    description: 'Add a STAC item to the scene as an overlay.',\n    permissions: [PERMISSIONS.WRITE_OVERLAY],\n    params: {\n      type: 'object', required: ['cid', 'iid'],\n      properties: { cid: { type: 'string' }, iid: { type: 'string' }, external: { type: 'string' } },\n    },\n    handler: async (slots) => {\n      const item = await getItem(slots.cid, slots.iid, { external: slots.external });\n      if (!item) return { applied: false, errors: ['STAC item not found'] };\n      try {\n        document.dispatchEvent(new CustomEvent('noclip:stac:add-item', { detail: { item } }));\n      } catch {}\n      return { applied: true, async: true, actionTags: ['stac.add-item'] };\n    },\n  });\n}\n","import { registerIntent, PERMISSIONS } from '../IntentRegistry.js';\n\nlet _registered = false;\nexport function registerSunStudyIntents() {\n  if (_registered) return;\n  _registered = true;\n  registerIntent({\n    name: 'set_sun_time',\n    description: 'Set the sun position to a specific date/time via the SceneClock.',\n    permissions: [PERMISSIONS.WRITE_SCENE_CLOCK],\n    params: { type: 'object', required: ['iso'], properties: { iso: { type: 'string' } } },\n    handler: (slots) => {\n      const t = Date.parse(slots.iso);\n      if (!Number.isFinite(t)) return { applied: false, errors: ['bad iso'] };\n      try { globalThis.window?.__noclipSceneClock?.setTime(t); return { applied: true, actionTags: ['sun.time'] }; }\n      catch (err) { return { applied: false, errors: [String(err)] }; }\n    },\n  });\n  registerIntent({\n    name: 'start_sun_study',\n    description: 'Open the sun-study panel and enable shadows.',\n    permissions: [PERMISSIONS.WRITE_OVERLAY],\n    params: { type: 'object', properties: {} },\n    handler: async () => {\n      try {\n        const { getSunStudyPanel } = await import('../../ui/SunStudyPanel.js');\n        getSunStudyPanel({});\n        const { getShadowPass } = await import('../../lighting/ShadowPass.js');\n        getShadowPass({}).setEnabled(true);\n        return { applied: true, actionTags: ['sun.study'] };\n      } catch (err) { return { applied: false, errors: [String(err)] }; }\n    },\n  });\n}\n","/**\n * Scene-info intents — read-only lookups the agent can use to know\n * where the user is and what they are looking at. These return real\n * data via `toolResult`, which the chat layer feeds back into the\n * model on the next turn so it has actual values to reason about\n * instead of fabricating.\n */\nimport { registerIntent, PERMISSIONS } from '../IntentRegistry.js';\n\nlet _registered = false;\n\nfunction _scene() {\n  return globalThis.window?.__noclipScene || null;\n}\n\nfunction _readCameraLatLon() {\n  const scene = _scene();\n  if (!scene) return null;\n  // Prefer the surface controller's resolved player lat/lon when in\n  // surface mode — that's the \"I am here\" answer. Fall back to the\n  // generic camera position otherwise.\n  try {\n    if (typeof scene._currentPlayerLatLon === 'function') {\n      const p = scene._currentPlayerLatLon();\n      if (p && Number.isFinite(p.lat) && Number.isFinite(p.lon)) return p;\n    }\n    const sc = scene._surfaceController;\n    if (sc?.isInSurfaceMode?.() && typeof sc.getSurfacePosition === 'function') {\n      const sp = sc.getSurfacePosition();\n      if (sp && Number.isFinite(sp.lat) && Number.isFinite(sp.lon)) return { lat: sp.lat, lon: sp.lon };\n    }\n  } catch { /* ignore */ }\n  return null;\n}\n\nfunction _readAltitude() {\n  const scene = _scene();\n  const sc = scene?._surfaceController;\n  if (Number.isFinite(sc?.surfaceAltitudeMSL)) return sc.surfaceAltitudeMSL;\n  if (Number.isFinite(sc?.surfaceAltitudeMeters)) return sc.surfaceAltitudeMeters;\n  if (scene?._camera?.position?.length) {\n    const r = scene._camera.position.length();\n    return r - 6378137; // rough MSL\n  }\n  return null;\n}\n\nfunction _readHeadingDeg() {\n  const sc = _scene()?._surfaceController;\n  if (typeof sc?.getSurfaceHeadingDeg === 'function') {\n    const h = sc.getSurfaceHeadingDeg();\n    if (Number.isFinite(h)) return h;\n  }\n  return null;\n}\n\nfunction _readMode() {\n  const sc = _scene()?._surfaceController;\n  return sc?.cameraMode || (sc?.isInSurfaceMode?.() ? 'surface' : 'orbit') || 'unknown';\n}\n\nfunction _readActiveBasemap() {\n  const scene = _scene();\n  const picker = scene?._basemapPicker;\n  if (picker?.activeId) return picker.activeId;\n  // Fallback: read from registry singleton via global handle if exposed.\n  return globalThis.window?.__noclipBasemap?.activeId || null;\n}\n\nexport function registerSceneInfoIntents() {\n  if (_registered) return;\n  _registered = true;\n\n  registerIntent({\n    name: 'get_location',\n    description: 'Return the current camera location: lat, lon, altitude (m MSL), heading (deg), mode (surface|orbit).',\n    permissions: [PERMISSIONS.READ_LAYERS || 'scene:read'],\n    params: { type: 'object', properties: {} },\n    handler: () => {\n      const ll = _readCameraLatLon();\n      const result = {\n        lat: ll?.lat ?? null,\n        lon: ll?.lon ?? null,\n        altitude_m: _readAltitude(),\n        heading_deg: _readHeadingDeg(),\n        mode: _readMode(),\n      };\n      return {\n        applied: true,\n        actionTags: ['scene.get_location'],\n        toolResult: result,\n      };\n    },\n  });\n\n  registerIntent({\n    name: 'get_scene_context',\n    description: 'Return a snapshot of scene state: location, mode, active basemap, time-of-day, wireframe flag.',\n    permissions: [PERMISSIONS.READ_LAYERS || 'scene:read'],\n    params: { type: 'object', properties: {} },\n    handler: () => {\n      const ll = _readCameraLatLon();\n      const scene = _scene();\n      const settings = scene?._sceneSettings;\n      const wireframe = settings?.getSection?.('scene.debug.wireframe') === true;\n      const sceneClock = globalThis.window?.__noclipSceneClock;\n      const sceneTimeMs = (typeof sceneClock?.getTime === 'function') ? sceneClock.getTime() : null;\n      const result = {\n        lat: ll?.lat ?? null,\n        lon: ll?.lon ?? null,\n        altitude_m: _readAltitude(),\n        heading_deg: _readHeadingDeg(),\n        mode: _readMode(),\n        active_basemap: _readActiveBasemap(),\n        wireframe,\n        scene_time_iso: Number.isFinite(sceneTimeMs) ? new Date(sceneTimeMs).toISOString() : null,\n      };\n      return {\n        applied: true,\n        actionTags: ['scene.get_context'],\n        toolResult: result,\n      };\n    },\n  });\n}\n","/** Match [longitude, latitude] GPS samples through NOCLIP's local Valhalla.\n * Native road geometry, disconnected runs and input-indexed snapped points\n * are preserved. No public router or automatic in-browser HMM fallback.\n * Deliberate offline callers can use offline/hmm-matcher.js separately.\n */\nimport { getLocalRoutingClient, checkRoutingAbort, invalidRoutingRequest } from '../refactor/async/fetch/LocalRoutingClient.js';\nimport { routingCoordinates, routingProfile, validateMatching } from '../refactor/routing/RoutingContracts.js';\n\nexport async function matchTrack(coords, options = {}) {\n  checkRoutingAbort(options.signal);\n  const profile = routingProfile(options.profile);\n  const points = routingCoordinates(coords, 16000);\n  const body = { profile, coords: points };\n  for (const name of ['timestamps', 'radii']) {\n    const values = options[name];\n    if (values === undefined) continue;\n    if (!Array.isArray(values) || values.length !== points.length\n      || values.some((value, i) => !Number.isFinite(value) || value < 0\n        || (name === 'radii' ? value > 100 : i > 0 && value <= values[i - 1]))) invalidRoutingRequest();\n    body[name] = values.slice();\n  }\n  return getLocalRoutingClient().request('/routing/match', {\n    body, signal: options.signal, validate: (data, signal) => validateMatching(data, points.length, signal),\n  });\n}\n","import { registerIntent, PERMISSIONS } from '../IntentRegistry.js';\nimport { matchTrack } from '../../../modules/map-matching-service.js';\n\nlet _registered = false;\nexport function registerMapMatchingIntents() {\n  if (_registered) return;\n  _registered = true;\n  registerIntent({\n    name: 'match_track',\n    description: 'Snap a noisy GPS track to the OSM road network.',\n    permissions: [PERMISSIONS.NETWORK_FETCH],\n    params: {\n      type: 'object', required: ['coords'],\n      properties: {\n        coords: { type: 'array', items: { type: 'array', items: { type: 'number' } } },\n        profile: { type: 'string', enum: ['driving', 'cycling', 'foot'] },\n        timestamps: { type: 'array', items: { type: 'number' }, description: 'Increasing timestamp seconds, one per GPS sample.' },\n        radii: { type: 'array', items: { type: 'number' }, description: 'GPS accuracy in metres, 0..100, one per sample.' },\n      },\n    },\n    handler: async (slots, context = {}) => {\n      const result = await matchTrack(slots.coords, { profile: slots.profile, timestamps: slots.timestamps,\n        radii: slots.radii, signal: context.signal });\n      context.signal?.throwIfAborted();\n      if (!result?.matchings?.length) return { applied: false, errors: ['No match'] };\n      return { applied: true, async: true, actionTags: ['match.track'], toolResult: result };\n    },\n  });\n}\n","import { registerIntent, PERMISSIONS } from '../IntentRegistry.js';\nimport { resolveBackendApiUrl } from '../../shared/backend.js';\nimport { getAuthService } from '../../auth/AuthService.js';\n\nlet _registered = false;\nexport function registerTrafficIntents() {\n  if (_registered) return;\n  _registered = true;\n\n  registerIntent({\n    name: 'report_traffic',\n    description: 'Submit a community traffic report (jam/crash/closure/hazard) at a location.',\n    permissions: [PERMISSIONS.NETWORK_FETCH, PERMISSIONS.WRITE_OVERLAY],\n    params: {\n      type: 'object', required: ['kind', 'lat', 'lon'],\n      properties: {\n        kind: { type: 'string', enum: ['jam', 'crash', 'closure', 'hazard', 'construction'] },\n        lat: { type: 'number' }, lon: { type: 'number' },\n        severity: { type: 'string', enum: ['low', 'medium', 'high'] },\n      },\n    },\n    handler: async (slots) => {\n      try {\n        const resp = await getAuthService().authenticatedFetch(resolveBackendApiUrl('/traffic/community-reports'), {\n          method: 'POST',\n          headers: { 'Content-Type': 'application/json' },\n          body: JSON.stringify(slots),\n        });\n        if (!resp.ok) return { applied: false, errors: [`Server ${resp.status}`] };\n        return { applied: true, async: true, actionTags: ['traffic.report'] };\n      } catch (err) {\n        return { applied: false, errors: [String(err)] };\n      }\n    },\n  });\n\n  registerIntent({\n    name: 'toggle_traffic_layer',\n    description: 'Show or hide the traffic-coloured route ribbon overlay.',\n    permissions: [PERMISSIONS.WRITE_OVERLAY],\n    params: { type: 'object', properties: { enabled: { type: 'boolean' } } },\n    handler: (slots) => {\n      try {\n        document.dispatchEvent(new CustomEvent('noclip:traffic:toggle', { detail: { enabled: !!slots.enabled } }));\n        return { applied: true, actionTags: [`traffic.toggle:${!!slots.enabled}`] };\n      } catch (err) {\n        return { applied: false, errors: [String(err)] };\n      }\n    },\n  });\n}\n","import { registerIntent, PERMISSIONS } from '../IntentRegistry.js';\n\nlet _registered = false;\nexport function registerPhotogrammetryIntents() {\n  if (_registered) return;\n  _registered = true;\n  registerIntent({\n    name: 'start_photogrammetry',\n    description: 'Queue a photogrammetry job for a photo bundle.',\n    permissions: [PERMISSIONS.NETWORK_FETCH, PERMISSIONS.WRITE_OVERLAY],\n    params: { type: 'object', properties: { bundleUrl: { type: 'string' } } },\n    handler: async (slots) => {\n      try {\n        const { getPhotogrammetryPanel } = await import('../../ui/PhotogrammetryPanel.js');\n        const panel = getPhotogrammetryPanel({});\n        panel.open();\n        const r = await panel.submit({ bundleUrl: slots?.bundleUrl });\n        return r.ok\n          ? { applied: true, actionTags: ['photogram.queue'], toolResult: { jobId: r.jobId } }\n          : { applied: false, errors: [r.error || 'queue failed'] };\n      } catch (err) { return { applied: false, errors: [String(err)] }; }\n    },\n  });\n  registerIntent({\n    name: 'view_photogrammetry',\n    description: 'Open the photogrammetry panel.',\n    permissions: [PERMISSIONS.WRITE_OVERLAY],\n    params: { type: 'object', properties: {} },\n    handler: async () => {\n      try {\n        const { getPhotogrammetryPanel } = await import('../../ui/PhotogrammetryPanel.js');\n        getPhotogrammetryPanel({}).open();\n        return { applied: true, actionTags: ['photogram.view'] };\n      } catch (err) { return { applied: false, errors: [String(err)] }; }\n    },\n  });\n}\n","import { registerIntent, PERMISSIONS } from '../IntentRegistry.js';\n\nlet _registered = false;\nexport function registerARIntents() {\n  if (_registered) return;\n  _registered = true;\n  registerIntent({\n    name: 'enter_ar',\n    description: 'Start the AR session (WebXR or magic-window fallback).',\n    permissions: [PERMISSIONS.WRITE_OVERLAY, PERMISSIONS.NETWORK_FETCH],\n    params: { type: 'object', properties: {} },\n    handler: async () => {\n      try {\n        const { getARSession } = await import('../../ar/ARSession.js');\n        const session = getARSession({});\n        const r = await session.start();\n        return r.ok\n          ? { applied: true, actionTags: ['ar.enter'], toolResult: { mode: r.mode } }\n          : { applied: false, errors: [r.error || 'ar start failed'] };\n      } catch (err) { return { applied: false, errors: [String(err)] }; }\n    },\n  });\n  registerIntent({\n    name: 'exit_ar',\n    description: 'Stop the active AR session.',\n    permissions: [PERMISSIONS.WRITE_OVERLAY],\n    params: { type: 'object', properties: {} },\n    handler: async () => {\n      try {\n        const { getARSession } = await import('../../ar/ARSession.js');\n        await getARSession({}).stop();\n        return { applied: true, actionTags: ['ar.exit'] };\n      } catch (err) { return { applied: false, errors: [String(err)] }; }\n    },\n  });\n}\n","import { registerIntent, PERMISSIONS } from '../IntentRegistry.js';\n\nlet _registered = false;\nexport function registerStorefrontIntents() {\n  if (_registered) return;\n  _registered = true;\n  registerIntent({\n    name: 'open_creator_studio',\n    description: 'Open the Creator Studio panel for publishing listings.',\n    permissions: [PERMISSIONS.WRITE_OVERLAY],\n    params: { type: 'object', properties: {} },\n    handler: async () => {\n      try {\n        const { getCreatorStudio } = await import('../../ui/CreatorStudio.js');\n        getCreatorStudio({}).open();\n        return { applied: true, actionTags: ['creator.open'] };\n      } catch (err) { return { applied: false, errors: [String(err)] }; }\n    },\n  });\n  registerIntent({\n    name: 'open_storefront',\n    description: 'Open the Marketplace storefront panel to browse listings.',\n    permissions: [PERMISSIONS.WRITE_OVERLAY, PERMISSIONS.NETWORK_FETCH],\n    params: { type: 'object', properties: {} },\n    handler: async () => {\n      try {\n        const { getStorefrontPanel } = await import('../../ui/StorefrontPanel.js');\n        getStorefrontPanel({}).open();\n        return { applied: true, actionTags: ['storefront.open'] };\n      } catch (err) { return { applied: false, errors: [String(err)] }; }\n    },\n  });\n  registerIntent({\n    name: 'unlock_listing',\n    description: 'Attempt to unlock a storefront listing by id.',\n    permissions: [PERMISSIONS.NETWORK_FETCH],\n    params: { type: 'object', required: ['id'], properties: { id: { type: 'string' } } },\n    handler: async (slots) => {\n      try {\n        const { unlockListing } = await import('../../../modules/storefront-client.js');\n        const r = await unlockListing({ id: slots.id });\n        return r.ok\n          ? { applied: true, actionTags: ['storefront.unlock'], toolResult: { assetUrl: r.assetUrl } }\n          : { applied: false, errors: [r.error || 'denied'] };\n      } catch (err) { return { applied: false, errors: [String(err)] }; }\n    },\n  });\n}\n","/**\n * transit-service — client-side helper for the /transit/* backend\n * proxy. Returns GeoJSON-flavored leg geometry so the existing route\n * ribbon + DirectionsPanel can render transit itineraries without\n * bespoke code.\n *\n * OTP itineraries carry a `legGeometry.points` encoded polyline; we\n * decode it into [[lon,lat], ...] pairs here so the caller can feed\n * the geometry directly into the ribbon renderer.\n */\nimport { getFetchQueue } from '../refactor/async/fetch/FetchQueue.js';\n\nexport async function planTransit({ apiBase = globalThis.location?.origin || '', fromPlace, toPlace, date, time, mode } = {}) {\n  if (!fromPlace || !toPlace) return { ok: false, error: 'fromPlace and toPlace required' };\n  const qs = new URLSearchParams({ fromPlace, toPlace });\n  if (date) qs.set('date', date);\n  if (time) qs.set('time', time);\n  if (mode) qs.set('mode', mode);\n  try {\n    const result = await getFetchQueue().fetchJSON(`${apiBase}/transit/plan?${qs.toString()}`);\n    const j = result.data || {};\n    if (!result.ok) return { ok: false, error: j?.error || 'plan failed' };\n    const its = j?.plan?.itineraries || [];\n    if (!its.length) return { ok: false, error: 'no itineraries' };\n    const best = its[0];\n    return { ok: true, itinerary: normalizeItinerary(best) };\n  } catch (err) {\n    return { ok: false, error: String(err?.message || err) };\n  }\n}\n\nfunction normalizeItinerary(it) {\n  const legs = (it.legs || []).map((leg) => ({\n    mode: leg.mode,\n    duration: leg.duration,\n    from: { name: leg.from?.name, lat: leg.from?.lat, lon: leg.from?.lon },\n    to: { name: leg.to?.name, lat: leg.to?.lat, lon: leg.to?.lon },\n    geometry: decodePolyline(leg.legGeometry?.points || ''),\n    route: leg.routeShortName || leg.route || null,\n    agency: leg.agencyName || null,\n    headsign: leg.headsign || null,\n  }));\n  return { duration: it.duration, walkDistance: it.walkDistance, transfers: it.transfers, legs };\n}\n\n// Google-encoded polyline decoder (precision 5)\nfunction decodePolyline(str) {\n  if (!str) return [];\n  const coords = [];\n  let index = 0, lat = 0, lon = 0;\n  while (index < str.length) {\n    let b, shift = 0, result = 0;\n    do { b = str.charCodeAt(index++) - 63; result |= (b & 0x1f) << shift; shift += 5; } while (b >= 0x20);\n    const dlat = (result & 1) ? ~(result >> 1) : (result >> 1);\n    lat += dlat;\n    shift = 0; result = 0;\n    do { b = str.charCodeAt(index++) - 63; result |= (b & 0x1f) << shift; shift += 5; } while (b >= 0x20);\n    const dlon = (result & 1) ? ~(result >> 1) : (result >> 1);\n    lon += dlon;\n    coords.push([lon / 1e5, lat / 1e5]);\n  }\n  return coords;\n}\n","import { registerIntent, PERMISSIONS } from '../IntentRegistry.js';\nimport { planTransit } from '../../../modules/transit-service.js';\n\nlet _registered = false;\nexport function registerTransitIntents() {\n  if (_registered) return;\n  _registered = true;\n  registerIntent({\n    name: 'plan_transit',\n    description: 'Plan a multimodal transit + walk itinerary between two WGS84 points.',\n    permissions: [PERMISSIONS.NETWORK_FETCH],\n    params: {\n      type: 'object', required: ['fromLat', 'fromLon', 'toLat', 'toLon'],\n      properties: {\n        fromLat: { type: 'number' }, fromLon: { type: 'number' },\n        toLat: { type: 'number' }, toLon: { type: 'number' },\n        date: { type: 'string' }, time: { type: 'string' }, mode: { type: 'string' },\n      },\n    },\n    handler: async (slots) => {\n      const fromPlace = `${slots.fromLat},${slots.fromLon}`;\n      const toPlace = `${slots.toLat},${slots.toLon}`;\n      const r = await planTransit({ fromPlace, toPlace, date: slots.date, time: slots.time, mode: slots.mode });\n      return r.ok\n        ? { applied: true, actionTags: ['transit.plan'], toolResult: r.itinerary }\n        : { applied: false, errors: [r.error || 'plan failed'] };\n    },\n  });\n}\n","/**\n * Black Sun / metaverse agent intents.\n *\n * Lets the in-app assistant transport the user into the Snow-Crash\n * sub-universe and (with proper credentials) admit them through the\n * AccessGate — all without the user leaving the chat. The intents\n * dispatch through `sceneApi.metaverse` (added in PlanetScene._buildApi)\n * so the same surface is reachable from the URL handshake, the agent,\n * Playwright, or future UI buttons.\n *\n * Four intents:\n *   - enter_metaverse  : flip scene mode to 'metaverse', spawn at port\n *   - enter_blacksun   : convenience — enter port 0 + attempt admission\n *   - exit_blacksun    : leave the building (still in metaverse on Street)\n *   - exit_metaverse   : flip scene mode back to 'earth'\n *\n * Wallet/tier/invite are optional slots on enter_blacksun. If the\n * caller provides nothing, AccessGate denies politely (the user stays\n * standing on the Street outside the door, which is the correct UX).\n */\n\nimport { registerIntent, PERMISSIONS } from '../IntentRegistry.js';\n\nlet _registered = false;\n\nexport function registerBlackSunIntents() {\n  if (_registered) return;\n  _registered = true;\n\n  registerIntent({\n    name: 'enter_metaverse',\n    description: 'Switch the scene from Earth into the Snow-Crash metaverse and spawn the avatar at the given Local Port (0 = Black Sun anchor).',\n    permissions: [PERMISSIONS.WRITE_PLAYER_POSITION],\n    params: {\n      type: 'object',\n      properties: {\n        port: {\n          type: 'integer',\n          description: 'Local Port index 0..65535. Port 0 anchors the Black Sun. Defaults to 0.',\n          minimum: 0,\n          maximum: 65535,\n        },\n      },\n    },\n    handler: (slots, ctx) => {\n      const api = ctx?.sceneApi?.metaverse;\n      if (!api?.enter) {\n        return { applied: false, errors: ['metaverse api unavailable'] };\n      }\n      const port = Number.isFinite(slots?.port) ? slots.port : 0;\n      const r = api.enter(port);\n      return {\n        applied: true,\n        actionTags: [`metaverse.enter:port=${port}`],\n        toolResult: { mode: r?.mode || 'metaverse', port: r?.port ?? port },\n      };\n    },\n    examples: [\n      { utterance: 'take me to the metaverse', slots: {} },\n      { utterance: 'jack into port 256', slots: { port: 256 } },\n      { utterance: 'put me on the street outside the black sun', slots: { port: 0 } },\n    ],\n  });\n\n  registerIntent({\n    name: 'enter_blacksun',\n    description: 'Take the user to the Black Sun: switch into the metaverse at port 0, then attempt to admit them through the AccessGate. If wallet/tier/invite are not provided the agent should ask the user before calling this. On admission the interior, Pyre, and daemon ecology spawn; on denial the user is left standing on the Street outside the door.',\n    permissions: [PERMISSIONS.WRITE_PLAYER_POSITION],\n    params: {\n      type: 'object',\n      properties: {\n        wallet: {\n          type: 'string',\n          description: 'The user\\'s wallet address (any chain). Optional — if absent, admission falls back to tier/invite checks only.',\n        },\n        currentTier: {\n          type: 'string',\n          enum: ['MEMBER', 'FOUNDER', 'OWNER', 'GUEST'],\n          description: 'Tier already resolved by the auth/tier service. FOUNDER and OWNER auto-admit even if not on the roster.',\n        },\n        invite: {\n          type: 'string',\n          description: 'Hypercard invite token (Phase 4). When present, admits as GUEST regardless of roster.',\n        },\n      },\n    },\n    handler: async (slots, ctx) => {\n      const api = ctx?.sceneApi?.metaverse;\n      if (!api?.enter || !api?.attemptThresholdCross) {\n        return { applied: false, errors: ['metaverse api unavailable'] };\n      }\n      // Step 1: drop the user on the Street outside the door.\n      api.enter(0);\n      // Step 2: ask the AccessGate. attemptThresholdCross resolves with\n      //   { admitted, tier, source, reason } — we surface that to the\n      //   chat as toolResult so the agent can phrase the response.\n      const result = await api.attemptThresholdCross({\n        wallet: typeof slots?.wallet === 'string' ? slots.wallet : null,\n        invite: typeof slots?.invite === 'string' ? slots.invite : null,\n        currentTier: typeof slots?.currentTier === 'string' ? slots.currentTier : null,\n      });\n      const tag = result?.admitted\n        ? `blacksun.admit:${result.source || 'unknown'}`\n        : `blacksun.deny:${result?.reason || 'not-authorized'}`;\n      return {\n        applied: true,\n        actionTags: [tag],\n        toolResult: result,\n      };\n    },\n    examples: [\n      { utterance: 'take me to the black sun', slots: {} },\n      { utterance: 'get me inside the black sun, my wallet is 0xabc…', slots: { wallet: '0xabc' } },\n      { utterance: 'i have a hypercard, let me in', slots: { invite: 'HC-1234' } },\n    ],\n  });\n\n  registerIntent({\n    name: 'exit_blacksun',\n    description: 'Leave the Black Sun interior. The user remains in the metaverse, standing on the Street just outside the door.',\n    permissions: [PERMISSIONS.WRITE_PLAYER_POSITION],\n    params: { type: 'object', properties: {} },\n    handler: (_slots, ctx) => {\n      const api = ctx?.sceneApi?.metaverse;\n      if (!api?.exitBlackSun) {\n        return { applied: false, errors: ['metaverse api unavailable'] };\n      }\n      const r = api.exitBlackSun();\n      return { applied: true, actionTags: ['blacksun.exit'], toolResult: r };\n    },\n    examples: [\n      { utterance: 'get me out of the black sun', slots: {} },\n      { utterance: 'leave the building', slots: {} },\n    ],\n  });\n\n  registerIntent({\n    name: 'exit_metaverse',\n    description: 'Leave the metaverse and return the user to the Earth scene.',\n    permissions: [PERMISSIONS.WRITE_PLAYER_POSITION],\n    params: { type: 'object', properties: {} },\n    handler: (_slots, ctx) => {\n      const api = ctx?.sceneApi?.metaverse;\n      if (!api?.exit) {\n        return { applied: false, errors: ['metaverse api unavailable'] };\n      }\n      const r = api.exit();\n      return { applied: true, actionTags: ['metaverse.exit'], toolResult: r };\n    },\n    examples: [\n      { utterance: 'take me back to earth', slots: {} },\n      { utterance: 'get me out of the metaverse', slots: {} },\n    ],\n  });\n}\n","/**\n * Earth-world daemon intents.\n *\n * The daemon is a black-satin humanoid that teleports to the user,\n * follows them, and briefs them via server-side TTS + 3D speech\n * bubble. Three intents:\n *\n *   summon_daemon  → manifest at the user (or a specific lat/lon)\n *   brief_daemon   → speak `text` through the active daemon\n *   navigate_daemon → move the daemon itself to a waypoint\n *   daemon_look    → return the daemon's first-person POV pose/snapshot\n *   dismiss_daemon → fade out + remove\n *   start_daemon_driver → bind an external vision-action policy to the daemon\n *   stop_daemon_driver → stop the active policy driver\n *   get_daemon_driver_status → inspect policy driver state\n *\n * The intents are wired into the IntentRegistry so the chat panel's\n * applyAgentCommand can dispatch them directly. Backend has matching\n * tool definitions in /agent/chat's SCENE_TOOLS so the LLM can pick\n * them via function calling.\n */\n\nimport { registerIntent, PERMISSIONS } from '../IntentRegistry.js';\n\nlet _registered = false;\n\nexport function registerEarthDaemonIntents() {\n  if (_registered) return;\n  _registered = true;\n\n  registerIntent({\n    name: 'summon_daemon',\n    description: 'Manifest a black-satin daemon companion in front of the user on the Earth surface. The daemon follows the user automatically. Use this when the user asks for a guide, briefing, info-on-the-go, or just \"send a daemon\".',\n    permissions: [PERMISSIONS.WRITE_PLAYER_POSITION],\n    params: {\n      type: 'object',\n      properties: {\n        lat: { type: 'number', description: 'Optional latitude for the manifestation point. Defaults to the user\\'s current location.' },\n        lon: { type: 'number', description: 'Optional longitude. Defaults to the user\\'s current location.' },\n        follow: { type: 'boolean', description: 'Whether the daemon should follow the user. Default true.' },\n      },\n    },\n    handler: async (slots, ctx) => {\n      const api = ctx?.sceneApi?.daemon;\n      if (!api?.summon) {\n        return { applied: false, errors: ['daemon api unavailable'] };\n      }\n      const result = await api.summon({\n        lat: Number.isFinite(slots?.lat) ? slots.lat : null,\n        lon: Number.isFinite(slots?.lon) ? slots.lon : null,\n        follow: slots?.follow !== false,\n      });\n      const status = api.getStatus?.() || {};\n      return {\n        applied: !!result,\n        actionTags: ['daemon.summon'],\n        toolResult: {\n          active: !!result,\n          embodied: !!status.agentic,\n          hasPovCamera: !!status.hasPovCamera,\n          mode: status.mode || 'idle',\n          lat: status.lat ?? null,\n          lon: status.lon ?? null,\n        },\n      };\n    },\n    examples: [\n      { utterance: 'send me a daemon', slots: {} },\n      { utterance: 'summon a guide', slots: {} },\n      { utterance: 'I want a briefing companion', slots: {} },\n    ],\n  });\n\n  registerIntent({\n    name: 'brief_daemon',\n    description: 'Have the active daemon speak the given text aloud (server-side TTS + speech bubble). If no daemon is active, summons one first. Use when the user asks for a verbal summary, news rundown, or any \"tell me about…\" request that benefits from speech rather than text.',\n    permissions: [PERMISSIONS.WRITE_PLAYER_POSITION, PERMISSIONS.NETWORK_FETCH],\n    params: {\n      type: 'object',\n      required: ['text'],\n      properties: {\n        text: { type: 'string', description: 'The message the daemon should speak. Keep it short — 1–3 sentences.' },\n      },\n    },\n    handler: async (slots, ctx) => {\n      const api = ctx?.sceneApi?.daemon;\n      if (!api?.brief) {\n        return { applied: false, errors: ['daemon api unavailable'] };\n      }\n      const text = String(slots?.text || '').trim();\n      if (!text) return { applied: false, errors: ['empty text'] };\n      const ok = await api.brief(text);\n      return {\n        applied: !!ok,\n        actionTags: ['daemon.brief'],\n        toolResult: { spoken: text },\n      };\n    },\n    examples: [\n      { utterance: 'have a daemon brief me on local earthquakes', slots: { text: 'Two M3+ quakes in the last hour, 40km offshore.' } },\n    ],\n  });\n\n  registerIntent({\n    name: 'navigate_daemon',\n    description: 'Move the active embodied daemon avatar to a latitude/longitude waypoint. This moves the daemon, not the user camera. Use when the user asks the daemon to go scout, walk over, move to a point, or navigate independently.',\n    permissions: [PERMISSIONS.WRITE_PLAYER_POSITION],\n    params: {\n      type: 'object',\n      required: ['lat', 'lon'],\n      properties: {\n        lat: { type: 'number', description: 'Destination latitude for the daemon.' },\n        lon: { type: 'number', description: 'Destination longitude for the daemon.' },\n      },\n    },\n    handler: async (slots, ctx) => {\n      const api = ctx?.sceneApi?.daemon;\n      if (!api?.navigateTo) {\n        return { applied: false, errors: ['daemon navigation api unavailable'] };\n      }\n      const lat = Number(slots?.lat);\n      const lon = Number(slots?.lon);\n      if (!Number.isFinite(lat) || !Number.isFinite(lon)) {\n        return { applied: false, errors: ['lat/lon required'] };\n      }\n      if (!api.getStatus?.()?.active && api.summon) {\n        await api.summon({ lat, lon, follow: false });\n      }\n      const ok = api.navigateTo({ lat, lon });\n      return {\n        applied: !!ok,\n        actionTags: ['daemon.navigate'],\n        toolResult: { navigating: !!ok, lat, lon },\n      };\n    },\n    examples: [\n      { utterance: 'send the daemon over there', slots: { lat: 47.3769, lon: 8.5417 } },\n    ],\n  });\n\n  registerIntent({\n    name: 'daemon_look',\n    description: 'Read from the active daemon avatar\\'s first-person point of view. Returns the daemon POV camera pose and, when includeImage=true, an on-demand image capture from that camera.',\n    permissions: [PERMISSIONS.NETWORK_FETCH],\n    params: {\n      type: 'object',\n      properties: {\n        includeImage: { type: 'boolean', description: 'Whether to include a PNG data URL from the daemon camera. Default false.' },\n        width: { type: 'integer', description: 'Optional capture width in pixels. Default 320.' },\n        height: { type: 'integer', description: 'Optional capture height in pixels. Default 180.' },\n      },\n    },\n    handler: async (slots, ctx) => {\n      const api = ctx?.sceneApi?.daemon;\n      if (!api?.look) {\n        return { applied: false, errors: ['daemon pov api unavailable'] };\n      }\n      if (!api.getStatus?.()?.active && api.summon) {\n        await api.summon({ follow: false });\n      }\n      const result = api.look({\n        includeImage: slots?.includeImage === true,\n        width: Number.isFinite(slots?.width) ? slots.width : undefined,\n        height: Number.isFinite(slots?.height) ? slots.height : undefined,\n      });\n      return {\n        applied: !!result?.ok,\n        actionTags: ['daemon.look'],\n        toolResult: result,\n        errors: result?.ok ? [] : [result?.error || 'daemon look failed'],\n      };\n    },\n    examples: [\n      { utterance: 'what does the daemon see?', slots: { includeImage: true } },\n    ],\n  });\n\n  registerIntent({\n    name: 'dismiss_daemon',\n    description: 'Fade out and remove the active daemon. Use when the user wants the daemon gone.',\n    permissions: [PERMISSIONS.WRITE_PLAYER_POSITION],\n    params: { type: 'object', properties: {} },\n    handler: async (_slots, ctx) => {\n      const api = ctx?.sceneApi?.daemon;\n      if (!api?.dismiss) {\n        return { applied: false, errors: ['daemon api unavailable'] };\n      }\n      await api.dismiss();\n      return { applied: true, actionTags: ['daemon.dismiss'] };\n    },\n    examples: [\n      { utterance: 'dismiss the daemon', slots: {} },\n      { utterance: 'send the daemon away', slots: {} },\n    ],\n  });\n\n  registerIntent({\n    name: 'start_daemon_driver',\n    description: 'Start a bounded vision-action driver for the active daemon. Use this when Omnius, DreamerV3, NitroGen, STEVE-class, or another external policy should observe daemon POV/state and emit daemon-only actions. The browser remains the scene actuator and rate limiter.',\n    permissions: [PERMISSIONS.WRITE_PLAYER_POSITION, PERMISSIONS.NETWORK_FETCH],\n    params: {\n      type: 'object',\n      properties: {\n        driver: { type: 'string', enum: ['omnius', 'dreamerv3', 'dreamer4', 'nitrogen', 'steve1', 'mrsteve', 'game_tars', 'custom'], description: 'External policy family. Default custom.' },\n        agentId: { type: 'string', description: 'Logical agent name, e.g. omnius.' },\n        endpoint: { type: 'string', description: 'HTTP endpoint that accepts an observation and returns one daemon action. Omit for idle/no-op harness mode.' },\n        tickMs: { type: 'integer', description: 'Driver decision cadence in ms. Default 500; clamped by the scene.' },\n        includeImage: { type: 'boolean', description: 'Whether each observation should include a daemon POV PNG. Default false to avoid render churn.' },\n        imageWidth: { type: 'integer', description: 'Optional POV capture width. Default 224.' },\n        imageHeight: { type: 'integer', description: 'Optional POV capture height. Default 126.' },\n        maxActionsPerMinute: { type: 'integer', description: 'Rate limit for side-effectful daemon actions. Default 30.' },\n        maxOffsetMeters: { type: 'number', description: 'Maximum relative movement per navigate_offset action. Default 25m.' },\n        dryRun: { type: 'boolean', description: 'Validate decisions without applying daemon movement/speech.' },\n      },\n    },\n    handler: async (slots, ctx) => {\n      const api = ctx?.sceneApi?.daemon;\n      if (!api?.startDriver) {\n        return { applied: false, errors: ['daemon driver api unavailable'] };\n      }\n      const result = await api.startDriver({\n        driver: typeof slots?.driver === 'string' ? slots.driver : undefined,\n        agentId: typeof slots?.agentId === 'string' ? slots.agentId : undefined,\n        endpoint: typeof slots?.endpoint === 'string' ? slots.endpoint : undefined,\n        tickMs: Number.isFinite(Number(slots?.tickMs)) ? Number(slots.tickMs) : undefined,\n        includeImage: slots?.includeImage === true || slots?.includeImage === 'true',\n        imageWidth: Number.isFinite(Number(slots?.imageWidth)) ? Number(slots.imageWidth) : undefined,\n        imageHeight: Number.isFinite(Number(slots?.imageHeight)) ? Number(slots.imageHeight) : undefined,\n        maxActionsPerMinute: Number.isFinite(Number(slots?.maxActionsPerMinute)) ? Number(slots.maxActionsPerMinute) : undefined,\n        maxOffsetMeters: Number.isFinite(Number(slots?.maxOffsetMeters)) ? Number(slots.maxOffsetMeters) : undefined,\n        dryRun: slots?.dryRun === true,\n      });\n      return {\n        applied: !!result?.ok && result?.active !== false,\n        actionTags: ['daemon.driver.start'],\n        toolResult: result,\n        errors: result?.ok ? [] : [result?.error || 'daemon driver start failed'],\n      };\n    },\n    examples: [\n      { utterance: 'let Omnius drive the daemon', slots: { driver: 'omnius', agentId: 'omnius' } },\n      { utterance: 'start DreamerV3 control for the daemon', slots: { driver: 'dreamerv3' } },\n    ],\n  });\n\n  registerIntent({\n    name: 'stop_daemon_driver',\n    description: 'Stop the active daemon vision-action driver without necessarily dismissing the daemon avatar.',\n    permissions: [PERMISSIONS.WRITE_PLAYER_POSITION],\n    params: {\n      type: 'object',\n      properties: {\n        reason: { type: 'string', description: 'Optional stop reason for diagnostics.' },\n      },\n    },\n    handler: async (slots, ctx) => {\n      const api = ctx?.sceneApi?.daemon;\n      if (!api?.stopDriver) {\n        return { applied: false, errors: ['daemon driver api unavailable'] };\n      }\n      const result = await api.stopDriver(typeof slots?.reason === 'string' ? slots.reason : 'stopped');\n      return {\n        applied: true,\n        actionTags: ['daemon.driver.stop'],\n        toolResult: result,\n      };\n    },\n    examples: [\n      { utterance: 'stop the daemon driver', slots: {} },\n    ],\n  });\n\n  registerIntent({\n    name: 'get_daemon_driver_status',\n    description: 'Inspect the active daemon vision-action driver: configured policy family, endpoint state, cadence, last action, rate-limit counters, and errors.',\n    permissions: [PERMISSIONS.READ_PLAYER_POSITION],\n    params: { type: 'object', properties: {} },\n    handler: async (_slots, ctx) => {\n      const api = ctx?.sceneApi?.daemon;\n      if (!api?.getDriverStatus) {\n        return { applied: false, errors: ['daemon driver api unavailable'] };\n      }\n      return {\n        applied: true,\n        actionTags: ['daemon.driver.status'],\n        toolResult: api.getDriverStatus(),\n      };\n    },\n    examples: [\n      { utterance: 'is the daemon driver running?', slots: {} },\n    ],\n  });\n\n}\n","/**\n * Shared constants for the Black Sun framework. Extracted into a\n * leaf module so MetaverseScene and BlackSunBuilding do not have to\n * import from each other (which produced a circular-dependency\n * temporal-dead-zone error during module initialization).\n *\n * Canonical sphere dimensions per\n * `.aiwg/blacksun/02-street-geometry.md` §2.1: equatorial circumference\n * is exactly 65,536 km (= 2^16, hacker-aesthetic from the canon).\n */\n\nexport const METAVERSE_SPHERE_RADIUS_KM = 65536 / (2 * Math.PI);\nexport const METAVERSE_SPHERE_RADIUS_M = METAVERSE_SPHERE_RADIUS_KM * 1000;\n\nexport const STREET_WIDTH_M = 100;\nexport const STREET_HALF_WIDTH_M = STREET_WIDTH_M / 2;\n\nexport const TOTAL_LOCAL_PORTS = 65536;\nexport const EXPRESS_PORT_COUNT = 256;\n\nexport function portToTheta(portIndex) {\n    const idx = Math.max(0, Math.min(TOTAL_LOCAL_PORTS - 1, Math.floor(portIndex || 0)));\n    return (idx / TOTAL_LOCAL_PORTS) * Math.PI * 2;\n}\n","/**\n * BlackSunBuilding — Phase 2 of the Black Sun framework.\n *\n * Constructs the canonical exterior of the Black Sun per\n * `.aiwg/blacksun/03-black-sun-architecture.md`:\n *   - Squat truncated black pyramid: 80 m base, 40 m top, 24 m tall.\n *   - Single Street-facing door (2.4 m × 3 m archway).\n *   - Matte black hemisphere (~1 m diameter) above the door, at ~5 m.\n *   - Carved \"THE BLACK SUN\" text below the hemisphere.\n *\n * The building is anchored at Local Port 0, on the north side of the\n * Street, 12 m beyond the Street's far edge (= 62 m lateral offset\n * from the monorail centerline).\n *\n * Phase 2 ships exterior + property-line collider (rejects all entry\n * attempts). Phase 3 will replace the stub collider with the encrypted\n * threshold gate.\n */\n\nimport * as THREE from 'three';\nimport {\n    METAVERSE_SPHERE_RADIUS_M,\n    portToTheta,\n    STREET_HALF_WIDTH_M,\n} from './constants.js';\n\n// Building dimensions per `.aiwg/blacksun/03-black-sun-architecture.md` §3.1.\nexport const BUILDING_BASE_SIDE_M = 80;\nexport const BUILDING_TOP_SIDE_M = 40;\nexport const BUILDING_HEIGHT_M = 24;\nexport const BUILDING_SETBACK_M = 12; // beyond Street edge\n\n// Door per §3.3.\nconst DOOR_WIDTH_M = 2.4;\nconst DOOR_HEIGHT_M = 3;\n\n// Hemisphere per §3.4.\nconst HEMISPHERE_RADIUS_M = 0.5; // ~1 m diameter\nconst HEMISPHERE_CENTROID_HEIGHT_M = 5;\n\n// Property-line offset from the building front face (where the\n// \"milling crowd\" stops and the gate begins).\nexport const PROPERTY_LINE_OFFSET_M = 1.5;\n\n// The lateral offset from Street centerline to the building's NEAR\n// face (the door wall). North side of the Street, beyond the far edge,\n// plus the setback.\nexport const BUILDING_NEAR_FACE_OFFSET_M = STREET_HALF_WIDTH_M + BUILDING_SETBACK_M;\n\n/**\n * Render \"THE BLACK SUN\" (or any caption) into a canvas texture so\n * the actual letterforms paint above the door. The book describes the\n * name as carved into the front wall in tall thin letters; we use a\n * condensed sans for that read. Texture is transparent so only the\n * letters are visible — the wall behind shows through where the\n * canvas is empty.\n */\nfunction createSignTexture(caption) {\n    if (typeof document === 'undefined' || !document.createElement) return null;\n    const canvas = document.createElement('canvas');\n    // Wide enough to give the letterforms breathing room without\n    // wrapping; height kept small so the texture stays cheap.\n    canvas.width = 1024;\n    canvas.height = 128;\n    const ctx = canvas.getContext('2d');\n    if (!ctx) return null;\n    // Clear to transparent — the wall behind shows where there's no ink.\n    ctx.clearRect(0, 0, canvas.width, canvas.height);\n    // Tall thin sans, matching the \"carved into matte black wall\"\n    // aesthetic. Color is a desaturated near-white with a hint of\n    // warmth so it reads as etched stone catching the Street's\n    // neon edge-light, not as glow text.\n    ctx.fillStyle = 'rgba(220, 215, 205, 0.92)';\n    ctx.font = '600 80px \"Helvetica Neue Condensed\", \"Arial Narrow\", sans-serif';\n    ctx.textAlign = 'center';\n    ctx.textBaseline = 'middle';\n    ctx.fillText(caption, canvas.width / 2, canvas.height / 2);\n    const texture = new THREE.CanvasTexture(canvas);\n    texture.anisotropy = 4;\n    texture.needsUpdate = true;\n    return texture;\n}\n\n/**\n * Build the Black Sun building anchored at the given port index.\n * Returns a `THREE.Group` with `userData.kind = 'blacksun'` and\n * `userData.portIndex` set; ready to be added to MetaverseScene's root.\n */\nexport function buildBlackSun(portIndex = 0) {\n    const theta = portToTheta(portIndex);\n    const cos = Math.cos(theta);\n    const sin = Math.sin(theta);\n    const r = METAVERSE_SPHERE_RADIUS_M;\n\n    // Local frame at this port — same convention as MetaverseScene\n    // _buildLocalSegment: origin on the Street centerline, +tangent\n    // along the Street, +radial points outward (away from sphere\n    // center, which here is also \"up\" since we're on the equator).\n    const origin = new THREE.Vector3(r * cos, 0, r * sin);\n    const tangent = new THREE.Vector3(-sin, 0, cos);\n    // The \"across-Street\" direction: +Z component of (-up × tangent)\n    // since we want the north side. With Y as sphere axis and tangent\n    // along the equator, the \"north of Street\" direction is just the\n    // sign-flipped Z component perpendicular to the tangent in world\n    // XZ. For a Street running tangent-aligned, \"north\" is whichever\n    // side of the centerline the building sits on. We choose the side\n    // corresponding to the +radial-perpendicular direction in world\n    // XZ — for port 0 (theta=0), tangent=(0,0,1), so \"north\" is +X\n    // direction; but we want the building \"across the Street\" which\n    // we'll define as -X for port 0 (closer to the sphere axis is\n    // arbitrary; we just pick a side and stick with it).\n    //\n    // Simplest: rotate the tangent by -90° around Y to get the\n    // street-cross direction. This gives us a consistent \"north\"\n    // regardless of theta.\n    const acrossStreet = new THREE.Vector3(cos, 0, sin)\n        .multiplyScalar(0)\n        .add(tangent.clone().applyAxisAngle(new THREE.Vector3(0, 1, 0), -Math.PI / 2));\n    // Note: rotating tangent by -90° around Y gives the perpendicular\n    // direction in world XZ. For theta=0 (tangent = +Z), this gives\n    // (-sin(-π/2)·0 + cos(-π/2)·1, 0, ... ) — let me just hardcode by\n    // using the radial direction: at any port, the \"outward radial\"\n    // points away from the sphere axis. The Street is on the surface;\n    // we need a direction perpendicular to BOTH the tangent and the\n    // radial-up. For a sphere, that's a Y-axis-aligned binormal that\n    // shifts as we go around the equator. For an equatorial Street,\n    // the \"north\" we want is consistent — let's use cross(tangent, Y)\n    // which gives a unit vector in the equatorial plane perpendicular\n    // to the tangent.\n    const buildingDir = new THREE.Vector3()\n        .crossVectors(new THREE.Vector3(0, 1, 0), tangent)\n        .normalize();\n\n    // Building near-face center on the Street pavement.\n    const nearFaceCenter = origin\n        .clone()\n        .addScaledVector(buildingDir, BUILDING_NEAR_FACE_OFFSET_M);\n\n    // Building geometric center (half-height up, half-depth back).\n    const halfDepth = BUILDING_BASE_SIDE_M / 2;\n    const buildingCenter = nearFaceCenter\n        .clone()\n        .addScaledVector(buildingDir, halfDepth)\n        .add(new THREE.Vector3(0, BUILDING_HEIGHT_M / 2, 0));\n\n    const group = new THREE.Group();\n    group.name = 'blacksunBuilding';\n    group.userData.kind = 'blacksun';\n    group.userData.portIndex = portIndex;\n    group.userData.theta = theta;\n    group.userData.nearFaceCenter = nearFaceCenter.clone();\n    group.userData.buildingDir = buildingDir.clone();\n    group.userData.tangent = tangent.clone();\n    group.userData.propertyLineDist = PROPERTY_LINE_OFFSET_M;\n\n    // ── Truncated pyramid hull (the Black Sun proper) ──────────────\n    // CylinderGeometry with 4 radial segments + 45° rotation gives a\n    // square truncated pyramid. Top/bottom radii are the half-diagonal\n    // of the square (= side / sqrt(2)).\n    const hullGeom = new THREE.CylinderGeometry(\n        BUILDING_TOP_SIDE_M / Math.SQRT2,\n        BUILDING_BASE_SIDE_M / Math.SQRT2,\n        BUILDING_HEIGHT_M,\n        4,\n        1,\n    );\n    hullGeom.rotateY(Math.PI / 4);\n    const hullMat = new THREE.MeshBasicMaterial({\n        color: 0x000000,\n        transparent: false,\n    });\n    const hull = new THREE.Mesh(hullGeom, hullMat);\n    hull.position.copy(buildingCenter);\n    // Orient the hull so its X axis aligns with the Street tangent.\n    // CylinderGeometry's axis is Y (already correct for \"up\"). The\n    // square cross-section is in the XZ plane; we need to align its\n    // edges with our tangent/buildingDir. For port 0 (theta=0,\n    // tangent=+Z, buildingDir=+X — wait, let me check), the cross()\n    // calculation: cross(Y, +Z) = +X. So buildingDir = +X. Good.\n    // The square cylinder's local +X is one edge direction, +Z is\n    // another. We want +X to align with buildingDir (the\n    // perpendicular-to-Street direction, so the FRONT face faces the\n    // Street). Currently for theta=0 the cylinder is unrotated so its\n    // +X is world +X = buildingDir. Match. For other theta, we need\n    // to rotate around Y by theta.\n    hull.rotation.y = theta;\n    hull.userData.kind = 'blacksunHull';\n    group.add(hull);\n\n    // ── Door (cut into the front face as a recessed archway) ────────\n    // The door is on the near face (Street-facing side). It's an open\n    // passage — no door panel — visually a darker recessed rectangle.\n    const doorGeom = new THREE.PlaneGeometry(DOOR_WIDTH_M, DOOR_HEIGHT_M);\n    const doorMat = new THREE.MeshBasicMaterial({\n        color: 0x050505, // even darker than the wall, suggests interior void\n        side: THREE.DoubleSide,\n    });\n    const door = new THREE.Mesh(doorGeom, doorMat);\n    door.position.copy(nearFaceCenter);\n    door.position.y = DOOR_HEIGHT_M / 2;\n    // Push the door face slightly forward so it sits proud of the wall.\n    door.position.addScaledVector(buildingDir, -0.05);\n    // Orient the door to face the Street (face -buildingDir).\n    door.lookAt(door.position.clone().addScaledVector(buildingDir, -1));\n    door.userData.kind = 'blacksunDoor';\n    group.add(door);\n\n    // ── Hemisphere (matte-black decoration above the door) ─────────\n    const hemiGeom = new THREE.SphereGeometry(\n        HEMISPHERE_RADIUS_M,\n        16,\n        8,\n        0,\n        Math.PI * 2,\n        0,\n        Math.PI / 2,\n    );\n    const hemiMat = new THREE.MeshBasicMaterial({ color: 0x080808 });\n    const hemisphere = new THREE.Mesh(hemiGeom, hemiMat);\n    hemisphere.position.copy(nearFaceCenter);\n    hemisphere.position.y = HEMISPHERE_CENTROID_HEIGHT_M;\n    // Sit it just proud of the wall.\n    hemisphere.position.addScaledVector(buildingDir, -0.02);\n    // Default sphere flat-side faces +Y — we want it embedded in the\n    // wall, flat side toward +buildingDir (into the wall), bulging\n    // toward -buildingDir (out toward the Street). Rotate accordingly.\n    hemisphere.rotation.x = Math.PI / 2;\n    // Now align the bulge with -buildingDir.\n    hemisphere.rotation.y = theta;\n    hemisphere.userData.kind = 'blacksunHemisphere';\n    group.add(hemisphere);\n\n    // ── Carved name \"THE BLACK SUN\" — book describes the name as\n    //    physically carved into the wall above the door, just below\n    //    the velvet hemisphere. We render it via a canvas texture so\n    //    the actual letterforms appear (no font asset bundle needed),\n    //    set on a thin emissive-looking plane biased proud of the wall.\n    const signGeom = new THREE.PlaneGeometry(10, 1.2);\n    const signMat = new THREE.MeshBasicMaterial({\n        map: createSignTexture('THE BLACK SUN'),\n        side: THREE.DoubleSide,\n        transparent: true,\n        opacity: 0.96,\n    });\n    const sign = new THREE.Mesh(signGeom, signMat);\n    sign.position.copy(nearFaceCenter);\n    // Place between the door and the hemisphere.\n    sign.position.y = DOOR_HEIGHT_M + 0.6;\n    sign.position.addScaledVector(buildingDir, -0.04);\n    sign.lookAt(sign.position.clone().addScaledVector(buildingDir, -1));\n    sign.userData.kind = 'blacksunSign';\n    sign.userData.text = 'THE BLACK SUN';\n    group.add(sign);\n\n    return group;\n}\n\n/**\n * Distance from a world position to the Black Sun's property line.\n * Returns positive when the point is OUTSIDE the property line\n * (street-side of the door) and negative when it has crossed it.\n *\n * Used by the property-line collider in MetaverseScene to gate entry\n * attempts.\n */\nexport function distanceToPropertyLine(blackSunGroup, worldPos) {\n    if (!blackSunGroup?.userData?.nearFaceCenter || !blackSunGroup?.userData?.buildingDir) {\n        return Infinity;\n    }\n    const nearFace = blackSunGroup.userData.nearFaceCenter;\n    const dir = blackSunGroup.userData.buildingDir;\n    // Vector from the door to the world point, projected onto the\n    // door-normal direction (= -buildingDir; outward from the front\n    // face). Positive when the user is street-side of the door.\n    const fromDoor = new THREE.Vector3().subVectors(worldPos, nearFace);\n    const projection = -fromDoor.dot(dir);\n    return projection - PROPERTY_LINE_OFFSET_M;\n}\n","/**\n * CrowdRenderer — Phase 2 of the Black Sun framework.\n *\n * Renders the canonical \"thousands of avatars milling around the\n * entrance\" of the Black Sun (Snow Crash canon §F, see\n * `.aiwg/blacksun/02-street-geometry.md` §2.7 and\n * `01-canon-extraction.md` §F).\n *\n * Phase 2 implementation:\n *   - Instanced rendering of ~500 humanoid silhouettes for the\n *     headless test environment; production should crank to ~5000 via\n *     the CROWD_SIZE constant. The instance count is a simple linear\n *     cost; lowered here to keep the headless smoke test snappy.\n *   - All instances are rendered translucent (alpha ≈ 0.4) per canon\n *     \"drawing all of the avatars ghostly and translucent so you can\n *     see where you're going\" — rendered in a way that does not\n *     participate in collision or selection.\n *   - Distributed in a fan-shape in front of the Black Sun's door,\n *     respecting the property line (no instance crosses it).\n *\n * Phase 4 will optionally upgrade some fraction of crowd instances to\n * agent-driven behavior; Phase 2 is purely visual.\n */\n\nimport * as THREE from 'three';\nimport {\n    PROPERTY_LINE_OFFSET_M,\n    BUILDING_BASE_SIDE_M,\n    BUILDING_NEAR_FACE_OFFSET_M,\n} from './BlackSunBuilding.js';\n\nconst CROWD_SIZE = 500;\nconst CROWD_MIN_RADIUS = PROPERTY_LINE_OFFSET_M + 0.5; // just outside the property line\nconst CROWD_MAX_RADIUS = 18; // ~18 m fan in front of the door\nconst CROWD_FAN_HALF_ANGLE_RAD = Math.PI / 3; // 60° to either side of the door axis\n\n/**\n * Build an instanced crowd of translucent ambient avatars in front of\n * the given Black Sun group. Returns a THREE.InstancedMesh ready to be\n * added to the scene root.\n */\nexport function buildCrowd(blackSunGroup, { count = CROWD_SIZE } = {}) {\n    if (!blackSunGroup?.userData?.nearFaceCenter || !blackSunGroup?.userData?.buildingDir) {\n        // The black-sun group isn't fully initialized; return an empty\n        // group rather than throwing — the test for crowd presence\n        // will fail visibly and the user can investigate.\n        const empty = new THREE.Group();\n        empty.name = 'blacksunCrowd';\n        empty.userData.kind = 'blacksunCrowd';\n        empty.userData.empty = true;\n        return empty;\n    }\n\n    const nearFace = blackSunGroup.userData.nearFaceCenter;\n    const buildingDir = blackSunGroup.userData.buildingDir;\n    const tangent = blackSunGroup.userData.tangent;\n\n    // Each instance is a low-poly humanoid silhouette: a cylinder for\n    // the body + a small sphere for the head. We merge into a single\n    // BufferGeometry so the whole avatar is one instance.\n    const bodyGeom = new THREE.CylinderGeometry(0.18, 0.22, 1.4, 5);\n    bodyGeom.translate(0, 0.7, 0);\n    const headGeom = new THREE.SphereGeometry(0.12, 6, 5);\n    headGeom.translate(0, 1.55, 0);\n\n    // BufferGeometryUtils-free merge: combine attributes manually.\n    const merged = mergeGeometries([bodyGeom, headGeom]);\n    bodyGeom.dispose();\n    headGeom.dispose();\n\n    const mat = new THREE.MeshBasicMaterial({\n        color: 0x6f7080,\n        transparent: true,\n        opacity: 0.38, // canonical \"ghostly and translucent\"\n        depthWrite: false,\n    });\n\n    const instanced = new THREE.InstancedMesh(merged, mat, count);\n    instanced.name = 'blacksunCrowd';\n    instanced.userData.kind = 'blacksunCrowd';\n    instanced.userData.count = count;\n\n    // Distribute instances in a fan in front of the door. The fan's\n    // axis is -buildingDir (the door-outward normal); avatars are\n    // placed at random radii and angles within the fan, on the Street\n    // pavement (y = 0).\n    const dummy = new THREE.Object3D();\n    const doorAxis = buildingDir.clone().multiplyScalar(-1).normalize();\n    // The \"left\" direction across the fan; we'll use the tangent.\n    const leftAxis = tangent.clone().normalize();\n\n    for (let i = 0; i < count; i++) {\n        // Sample radius with sqrt for area-uniform distribution.\n        const u = Math.random();\n        const radius = CROWD_MIN_RADIUS + Math.sqrt(u) * (CROWD_MAX_RADIUS - CROWD_MIN_RADIUS);\n        const angle = (Math.random() * 2 - 1) * CROWD_FAN_HALF_ANGLE_RAD;\n        const pos = nearFace.clone()\n            .addScaledVector(doorAxis, radius * Math.cos(angle))\n            .addScaledVector(leftAxis, radius * Math.sin(angle));\n        // Slight per-avatar height jitter so the row doesn't look like a barcode.\n        pos.y = 0.001 + Math.random() * 0.02;\n\n        // Each avatar faces (vaguely) toward the door, with random yaw jitter.\n        const yawToDoor = Math.atan2(\n            buildingDir.x,\n            buildingDir.z,\n        );\n        const yaw = yawToDoor + (Math.random() - 0.5) * 0.6;\n\n        dummy.position.copy(pos);\n        dummy.rotation.set(0, yaw, 0);\n        // Per-avatar scale jitter.\n        const scale = 0.85 + Math.random() * 0.3;\n        dummy.scale.setScalar(scale);\n        dummy.updateMatrix();\n        instanced.setMatrixAt(i, dummy.matrix);\n    }\n    instanced.instanceMatrix.needsUpdate = true;\n\n    return instanced;\n}\n\n/**\n * Manual geometry merge for environments without BufferGeometryUtils.\n * Combines positions, normals, uvs, indices.\n */\nfunction mergeGeometries(geoms) {\n    const merged = new THREE.BufferGeometry();\n    let posCount = 0;\n    let idxCount = 0;\n    for (const g of geoms) {\n        posCount += g.attributes.position.count;\n        if (g.index) idxCount += g.index.count;\n    }\n    const positions = new Float32Array(posCount * 3);\n    const normals = new Float32Array(posCount * 3);\n    const indices = idxCount > 0 ? new Uint32Array(idxCount) : null;\n    let pOff = 0;\n    let iOff = 0;\n    let vertOff = 0;\n    for (const g of geoms) {\n        const p = g.attributes.position.array;\n        const n = g.attributes.normal?.array;\n        positions.set(p, pOff * 3);\n        if (n) normals.set(n, pOff * 3);\n        if (g.index && indices) {\n            const ix = g.index.array;\n            for (let k = 0; k < ix.length; k++) {\n                indices[iOff + k] = ix[k] + vertOff;\n            }\n            iOff += ix.length;\n        }\n        vertOff += g.attributes.position.count;\n        pOff += g.attributes.position.count;\n    }\n    merged.setAttribute('position', new THREE.BufferAttribute(positions, 3));\n    merged.setAttribute('normal', new THREE.BufferAttribute(normals, 3));\n    if (indices) merged.setIndex(new THREE.BufferAttribute(indices, 1));\n    merged.computeBoundingSphere();\n    return merged;\n}\n","/**\n * RosterClient — Phase 3 of the Black Sun framework.\n *\n * Fetches and verifies the authorized-member roster per\n * `.aiwg/blacksun/04-access-protocol.md` §4.4.\n *\n * Production: roster is served by `noclip-backend` at `/blacksun/roster`,\n * signed by the proprietor's `ROSTER_SIGNING_KEY` (Ed25519). The client\n * verifies the signature against the proprietor's well-known public key\n * before trusting any contents.\n *\n * Development: this module ships with a client-side dev fallback —\n * the dev roster is loaded from `public/blacksun/dev-roster.json`\n * (unsigned, dev-only) when the backend endpoint is unreachable. The\n * dev roster is for local iteration; production gates require a signed\n * backend roster.\n */\n\nconst ROSTER_URL_PROD = '/blacksun/roster';\nconst ROSTER_URL_DEV = '/blacksun/dev-roster.json';\nconst ROSTER_CACHE_TTL_MS = 5 * 60 * 1000; // 5 min, matches existing tier cache\n\n/**\n * The proprietor's well-known wallet identity. In production this is\n * the wallet that signs the roster; the client refuses any roster\n * not signed by this wallet. The constant is hard-coded as the trust\n * anchor per `.aiwg/blacksun/10-encryption-strategy.md` §10.9.\n *\n * Dev value placeholder. Replace with the real wallet for production.\n */\nexport const PROPRIETOR_WALLET = '0xrobitDEV0000000000000000000000000000000000';\nexport const PROPRIETOR_SIGNING_PUBLIC_KEY_B64 =\n    globalThis?.NOCLIP_BLACKSUN_SIGNING_PUBLIC_KEY_B64 || '';\n\nclass RosterClient {\n    constructor() {\n        this._roster = null;\n        this._fetchedAt = 0;\n        this._inflight = null;\n    }\n\n    /**\n     * Fetch the roster (with cache). Returns the parsed roster object\n     * with verified members; throws on signature failure (production)\n     * or returns the dev roster on backend unreachable (development).\n     */\n    async fetch({ force = false } = {}) {\n        const now = Date.now();\n        if (!force && this._roster && now - this._fetchedAt < ROSTER_CACHE_TTL_MS) {\n            return this._roster;\n        }\n        if (this._inflight) return this._inflight;\n        this._inflight = (async () => {\n            let roster = null;\n            // Try production endpoint.\n            try {\n                const resp = await fetch(ROSTER_URL_PROD, { credentials: 'omit' });\n                if (resp.ok) {\n                    roster = await resp.json();\n                    if (!(await this._verifyRosterSignature(roster))) {\n                        throw new Error('roster signature failed');\n                    }\n                }\n            } catch (err) {\n                console.warn('[RosterClient] production endpoint unreachable:', err?.message || err);\n            }\n            // Fall back to dev roster if production unavailable.\n            if (!roster) {\n                try {\n                    const resp = await fetch(ROSTER_URL_DEV, { credentials: 'omit' });\n                    if (resp.ok) {\n                        roster = await resp.json();\n                        roster.__devOnly = true;\n                    }\n                } catch (err) {\n                    console.warn('[RosterClient] dev fallback unreachable:', err?.message || err);\n                }\n            }\n            // Last-resort built-in dev roster — proprietor only.\n            if (!roster) {\n                roster = {\n                    version: '0.0.0-builtin',\n                    issuedAt: new Date().toISOString(),\n                    issuer: PROPRIETOR_WALLET,\n                    members: [\n                        {\n                            wallet: PROPRIETOR_WALLET,\n                            addedAt: new Date().toISOString(),\n                            tier: 'OWNER',\n                            expiresAt: null,\n                            notes: 'Built-in proprietor entry (no roster fetched)',\n                        },\n                    ],\n                    __devOnly: true,\n                    __builtin: true,\n                };\n            }\n            this._roster = roster;\n            this._fetchedAt = Date.now();\n            return roster;\n        })();\n        try {\n            const result = await this._inflight;\n            return result;\n        } finally {\n            this._inflight = null;\n        }\n    }\n\n    /**\n     * Check whether the given wallet has access at any tier. Returns\n     * `{ allowed, tier, source }` where source ∈ 'roster' / 'invite'\n     * / 'tier' / 'maintenance' / null.\n     */\n    async checkAccess(wallet, { invite = null, currentTier = null } = {}) {\n        if (!wallet) return { allowed: false, tier: null, source: null };\n        const roster = await this.fetch();\n        const lcWallet = String(wallet).toLowerCase();\n        const member = (roster.members || []).find(\n            (m) => String(m.wallet).toLowerCase() === lcWallet,\n        );\n        if (member) {\n            // Check expiry.\n            if (member.expiresAt && Date.parse(member.expiresAt) < Date.now()) {\n                // Member but expired.\n            } else {\n                return { allowed: true, tier: member.tier, source: 'roster' };\n            }\n        }\n        // Tier-based admission (FOUNDER and above can enter without\n        // roster entry per .aiwg/blacksun/04-access-protocol.md §4.3).\n        if (currentTier === 'FOUNDER' || currentTier === 'OWNER') {\n            return { allowed: true, tier: currentTier, source: 'tier' };\n        }\n        // Invitation-bearer admission.\n        if (invite && await this._verifyInvite(invite, wallet)) {\n            return { allowed: true, tier: 'GUEST', source: 'invite' };\n        }\n        return { allowed: false, tier: null, source: null };\n    }\n\n    /**\n     * Verify the proprietor's signature over the roster body. In\n     * production this is a real Ed25519 verification (via WebCrypto).\n     * Dev rosters are unsigned and pass through with a warning.\n     */\n    async _verifyRosterSignature(roster) {\n        if (!roster) return false;\n        if (roster.__devOnly === true) return true; // dev rosters skip signature\n        if (!roster.signature) {\n            console.warn('[RosterClient] production roster has no signature; rejecting');\n            return false;\n        }\n        if (!PROPRIETOR_SIGNING_PUBLIC_KEY_B64) {\n            console.warn('[RosterClient] roster signing public key missing; rejecting production roster');\n            return false;\n        }\n        const body = { ...roster };\n        delete body.signature;\n        return verifyEd25519Json(body, roster.signature, PROPRIETOR_SIGNING_PUBLIC_KEY_B64);\n    }\n\n    async _verifyInvite(invite, wallet) {\n        if (!invite || typeof invite !== 'object') return false;\n        if (invite.guest && String(invite.guest).toLowerCase() !== String(wallet).toLowerCase()) return false;\n        if (invite.expiresAt && Date.parse(invite.expiresAt) < Date.now()) return false;\n        if (!invite.signature || !PROPRIETOR_SIGNING_PUBLIC_KEY_B64) return false;\n        if (invite.issuer && String(invite.issuer).toLowerCase() !== PROPRIETOR_WALLET.toLowerCase()) return false;\n        const body = { ...invite };\n        delete body.signature;\n        return verifyEd25519Json(body, invite.signature, PROPRIETOR_SIGNING_PUBLIC_KEY_B64);\n    }\n\n    invalidate() {\n        this._roster = null;\n        this._fetchedAt = 0;\n    }\n}\n\nlet _instance = null;\nexport function getRosterClient() {\n    if (!_instance) _instance = new RosterClient();\n    return _instance;\n}\n\nfunction stableStringify(value) {\n    if (Array.isArray(value)) return `[${value.map(stableStringify).join(',')}]`;\n    if (value && typeof value === 'object') {\n        return `{${Object.keys(value).sort().map((key) => `${JSON.stringify(key)}:${stableStringify(value[key])}`).join(',')}}`;\n    }\n    return JSON.stringify(value);\n}\n\nfunction decodeBase64Bytes(value) {\n    const normalized = String(value || '').trim().replace(/-/g, '+').replace(/_/g, '/');\n    const padded = normalized.padEnd(normalized.length + ((4 - (normalized.length % 4)) % 4), '=');\n    const binary = atob(padded);\n    const out = new Uint8Array(binary.length);\n    for (let i = 0; i < binary.length; i += 1) out[i] = binary.charCodeAt(i);\n    return out;\n}\n\nasync function verifyEd25519Json(body, signatureB64, publicKeyB64) {\n    try {\n        if (!globalThis.crypto?.subtle) return false;\n        const key = await globalThis.crypto.subtle.importKey(\n            'raw',\n            decodeBase64Bytes(publicKeyB64),\n            { name: 'Ed25519' },\n            false,\n            ['verify'],\n        );\n        const data = new TextEncoder().encode(stableStringify(body));\n        return await globalThis.crypto.subtle.verify(\n            { name: 'Ed25519' },\n            key,\n            decodeBase64Bytes(signatureB64),\n            data,\n        );\n    } catch (err) {\n        console.warn('[RosterClient] signature verification failed:', err?.message || err);\n        return false;\n    }\n}\n","/**\n * AccessGate — Phase 3 of the Black Sun framework.\n *\n * Per `.aiwg/blacksun/04-access-protocol.md` §4.2, the threshold gate\n * is enforced by a combination of:\n *\n *   1. Authorized roster (consult RosterClient).\n *   2. Tier-based auto-admission (FOUNDER/OWNER).\n *   3. Hypercard invitation (Phase 4 wires this in).\n *\n * On success this module:\n *   - Triggers the Interior module to build/attach interior assets.\n *   - Begins the avatar opacity-ramp animation (translucent → solid).\n *   - Writes an audit-log entry.\n *\n * On failure (or pending) this module records the denial reason and\n * blocks further attempts within a back-off window.\n */\n\nimport { getRosterClient } from './RosterClient.js';\n\nconst AUDIT_LOG_KEY = 'noclip:blacksun:audit';\nconst RECENT_DENIAL_BACKOFF_MS = 2000;\n\nclass AccessGate {\n    constructor() {\n        this._lastDenialAt = 0;\n        this._lastDenialReason = null;\n        this._currentSession = null;\n    }\n\n    /**\n     * Try to admit the given wallet. Returns\n     *   { admitted, tier, source, reason }.\n     * Audit-logged regardless of outcome.\n     */\n    async attemptAdmit({ wallet, currentTier = null, invite = null } = {}) {\n        const now = Date.now();\n        // Soft back-off: if a recent denial has the same wallet, skip\n        // re-checking for a few seconds to keep the test/UX from\n        // hammering the roster endpoint.\n        if (this._lastDenialAt\n            && now - this._lastDenialAt < RECENT_DENIAL_BACKOFF_MS\n            && this._lastDenialReason?.wallet === wallet) {\n            return {\n                admitted: false,\n                reason: 'backoff',\n                detail: this._lastDenialReason,\n            };\n        }\n        const roster = getRosterClient();\n        const result = await roster.checkAccess(wallet, { invite, currentTier });\n        if (result.allowed) {\n            this._currentSession = {\n                wallet,\n                tier: result.tier,\n                source: result.source,\n                admittedAt: now,\n            };\n            this._writeAudit({\n                kind: 'admit',\n                wallet,\n                tier: result.tier,\n                source: result.source,\n                timestamp: now,\n            });\n            return {\n                admitted: true,\n                tier: result.tier,\n                source: result.source,\n            };\n        }\n        this._lastDenialAt = now;\n        this._lastDenialReason = { wallet, source: result.source, timestamp: now };\n        this._writeAudit({\n            kind: 'deny',\n            wallet,\n            timestamp: now,\n            reason: 'not-on-roster',\n        });\n        return {\n            admitted: false,\n            reason: 'not-authorized',\n            detail: { wallet },\n        };\n    }\n\n    /**\n     * End the current admission session. Audit-logs an exit event.\n     */\n    release(reason = 'exit') {\n        if (!this._currentSession) return;\n        this._writeAudit({\n            kind: reason,\n            wallet: this._currentSession.wallet,\n            tier: this._currentSession.tier,\n            source: this._currentSession.source,\n            timestamp: Date.now(),\n        });\n        this._currentSession = null;\n    }\n\n    /** Read access to the current admission record. */\n    getCurrentSession() {\n        return this._currentSession;\n    }\n\n    /**\n     * Read recent audit-log entries. Stored in localStorage in the\n     * dev environment; production should ship them to noclip-backend.\n     */\n    getAuditLog({ limit = 50 } = {}) {\n        try {\n            const raw = localStorage.getItem(AUDIT_LOG_KEY);\n            if (!raw) return [];\n            const list = JSON.parse(raw);\n            if (!Array.isArray(list)) return [];\n            return list.slice(-limit);\n        } catch {\n            return [];\n        }\n    }\n\n    _writeAudit(entry) {\n        try {\n            const raw = localStorage.getItem(AUDIT_LOG_KEY);\n            const list = raw ? JSON.parse(raw) : [];\n            list.push(entry);\n            // Cap log to last 200 entries to avoid runaway storage.\n            const trimmed = list.slice(-200);\n            localStorage.setItem(AUDIT_LOG_KEY, JSON.stringify(trimmed));\n        } catch (err) {\n            console.warn('[AccessGate] audit log write failed:', err?.message || err);\n        }\n        // Also dispatch a DOM event so the HUD and any active\n        // Playwright tests can observe.\n        try {\n            window.dispatchEvent(new CustomEvent('noclip:blacksun:audit', { detail: entry }));\n        } catch { /* ignore */ }\n    }\n}\n\nlet _instance = null;\nexport function getAccessGate() {\n    if (!_instance) _instance = new AccessGate();\n    return _instance;\n}\n","/**\n * Interior — Phase 3 of the Black Sun framework.\n *\n * Constructs the canonical interior of the Black Sun per\n * `.aiwg/blacksun/03-black-sun-architecture.md` §3.5 (the four\n * Quadrants), §3.6 (the bar), §3.7 (the stage), §3.8 (the floor).\n *\n * Layout (looking down +Y from above the building):\n *\n *      back of building (away from Street)\n *\n *      Movie Star    │    Hacker\n *      Quadrant      │    Quadrant\n *      (NW)          │    (NE)\n *      ───────── BAR ┼ STAGE ─────────\n *      Nipponese     │    Rock Star\n *      Quadrant      │    Quadrant\n *      (SW)          │    (SE)\n *\n *      front of building (Street-facing, door is here)\n *\n * Each Quadrant has its own ambient-color tint (per .aiwg spec §3.5).\n * The interior is ONLY built on threshold-cross success — it lives\n * inside an encrypted asset bundle in production. Phase 3 ships the\n * geometry stub plus the build/attach/detach lifecycle.\n */\n\nimport * as THREE from 'three';\nimport {\n    BUILDING_BASE_SIDE_M,\n    BUILDING_HEIGHT_M,\n    BUILDING_NEAR_FACE_OFFSET_M,\n} from './BlackSunBuilding.js';\n\nconst QUADRANT_TINTS = {\n    hacker:    0x00ffff,\n    movieStar: 0xffd700,\n    rockStar:  0xff00ff,\n    nipponese: 0xff4040,\n};\n\nconst FLOOR_INSET_M = 1.0;       // wall thickness inside the hull\nconst FLOOR_THICKNESS_M = 0.05;\nconst QUADRANT_DIM = (BUILDING_BASE_SIDE_M / 2) - FLOOR_INSET_M; // each is half-base less wall\n\n/**\n * Build the interior group at the building's anchor pose. Returns a\n * THREE.Group ready to be added to the scene root, OR null if the\n * blackSunGroup is not initialized.\n */\nexport function buildInterior(blackSunGroup) {\n    if (!blackSunGroup?.userData?.nearFaceCenter) return null;\n    const nearFace = blackSunGroup.userData.nearFaceCenter;\n    const buildingDir = blackSunGroup.userData.buildingDir; // outward from door (street side -)\n    const tangent = blackSunGroup.userData.tangent;\n\n    // Building geometric center on the floor.\n    const halfDepth = BUILDING_BASE_SIDE_M / 2;\n    const centerOnFloor = nearFace.clone().addScaledVector(buildingDir, halfDepth);\n\n    const group = new THREE.Group();\n    group.name = 'blacksunInterior';\n    group.userData.kind = 'blacksunInterior';\n\n    // Floor — book describes the Black Sun floor as \"highly polished\",\n    // mirror-like enough that avatars cast distinct reflections in it.\n    // We can't run a planar reflection cheaply here, but we can fake\n    // the read with a MeshStandardMaterial: very low roughness, near-\n    // black color, slight metalness so any scene light will read as a\n    // wet specular highlight on the surface. Drops back to MeshBasic\n    // if Standard fails to compile (older WebGL).\n    const floorGeom = new THREE.PlaneGeometry(\n        BUILDING_BASE_SIDE_M - 2 * FLOOR_INSET_M,\n        BUILDING_BASE_SIDE_M - 2 * FLOOR_INSET_M,\n    );\n    floorGeom.rotateX(-Math.PI / 2);\n    let floorMat;\n    try {\n        floorMat = new THREE.MeshStandardMaterial({\n            color: 0x050507,\n            metalness: 0.6,\n            roughness: 0.22,\n        });\n    } catch {\n        floorMat = new THREE.MeshBasicMaterial({ color: 0x050507 });\n    }\n    const floor = new THREE.Mesh(floorGeom, floorMat);\n    floor.position.copy(centerOnFloor);\n    floor.position.y = FLOOR_THICKNESS_M;\n    floor.userData.kind = 'blacksunInteriorFloor';\n    group.add(floor);\n\n    // Quadrant tints — render as subtle colored floor inlays so the\n    // four zones are visually distinguishable. Each quadrant occupies\n    // one quarter of the floor; the back-half of the building is the\n    // \"back\" (Movie Star + Hacker), the front-half is \"front\"\n    // (Nipponese + Rock Star). Side determined by tangent.\n    const half = QUADRANT_DIM / 2;\n    const quadrantSpec = [\n        { kind: 'hacker',    front: false, side: 'right' }, // NE\n        { kind: 'movieStar', front: false, side: 'left'  }, // NW\n        { kind: 'nipponese', front: true,  side: 'left'  }, // SW\n        { kind: 'rockStar',  front: true,  side: 'right' }, // SE\n    ];\n    for (const q of quadrantSpec) {\n        const inlayGeom = new THREE.PlaneGeometry(\n            QUADRANT_DIM - 0.5,\n            QUADRANT_DIM - 0.5,\n        );\n        inlayGeom.rotateX(-Math.PI / 2);\n        // Quadrant tints lifted from 6% → 14% so the four zones\n        // actually read as different territories from across the room\n        // (book describes them as visibly distinct). Still translucent\n        // — these are color washes on the polished floor, not solid\n        // panels.\n        const inlayMat = new THREE.MeshBasicMaterial({\n            color: QUADRANT_TINTS[q.kind],\n            transparent: true,\n            opacity: 0.14,\n        });\n        const inlay = new THREE.Mesh(inlayGeom, inlayMat);\n        // Front (Street-side, -buildingDir): door side.\n        // Back (away from Street, +buildingDir): far side.\n        const depthOffset = q.front ? -half : +half;\n        const lateralOffset = q.side === 'right' ? +half : -half;\n        const pos = centerOnFloor.clone()\n            .addScaledVector(buildingDir, depthOffset)\n            .addScaledVector(tangent, lateralOffset);\n        pos.y = FLOOR_THICKNESS_M + 0.02;\n        inlay.position.copy(pos);\n        inlay.userData.kind = `blacksunQuadrant:${q.kind}`;\n        inlay.userData.quadrant = q.kind;\n        group.add(inlay);\n    }\n\n    // The bar — central east-west wall behind the stage.\n    const barGeom = new THREE.BoxGeometry(QUADRANT_DIM * 1.5, 1.4, 1.0);\n    const barMat = new THREE.MeshBasicMaterial({ color: 0x202028 });\n    const bar = new THREE.Mesh(barGeom, barMat);\n    // Sits on the floor centerline, biased to the back.\n    const barOffset = +half * 0.4;\n    bar.position.copy(centerOnFloor).addScaledVector(buildingDir, barOffset);\n    bar.position.y = FLOOR_THICKNESS_M + 0.7;\n    // Orient: the bar's long axis is the tangent direction.\n    bar.lookAt(bar.position.clone().add(buildingDir));\n    bar.userData.kind = 'blacksunBar';\n    group.add(bar);\n\n    // The stage — circular raised platform centered on the bar's south side.\n    const stageGeom = new THREE.CylinderGeometry(6, 6, 0.5, 24);\n    const stageMat = new THREE.MeshBasicMaterial({ color: 0x100808 });\n    const stage = new THREE.Mesh(stageGeom, stageMat);\n    const stageOffset = -half * 0.4; // toward the door\n    stage.position.copy(centerOnFloor).addScaledVector(buildingDir, stageOffset);\n    stage.position.y = FLOOR_THICKNESS_M + 0.25;\n    stage.userData.kind = 'blacksunStage';\n    group.add(stage);\n\n    // Ceiling — one matte-black plane at building height. (Walls are\n    // implied by the hull.) Mostly so a downward look from inside\n    // shows a closed volume.\n    const ceilGeom = new THREE.PlaneGeometry(\n        BUILDING_BASE_SIDE_M - 2 * FLOOR_INSET_M,\n        BUILDING_BASE_SIDE_M - 2 * FLOOR_INSET_M,\n    );\n    ceilGeom.rotateX(Math.PI / 2);\n    const ceilMat = new THREE.MeshBasicMaterial({ color: 0x000000 });\n    const ceiling = new THREE.Mesh(ceilGeom, ceilMat);\n    ceiling.position.copy(centerOnFloor);\n    ceiling.position.y = BUILDING_HEIGHT_M - 0.5;\n    ceiling.userData.kind = 'blacksunCeiling';\n    group.add(ceiling);\n\n    return group;\n}\n\n/**\n * Run the avatar opacity ramp on threshold-cross. The ramp moves the\n * camera-owner avatar from translucent (Street fogbank) to solid\n * (interior) over ~250 ms, matching canon — see\n * `.aiwg/blacksun/04-access-protocol.md` §4.7.\n *\n * Returns a Promise that resolves when the ramp completes.\n */\nexport function runOpacityRamp(camera, durationMs = 250) {\n    return new Promise((resolve) => {\n        // Without an explicit avatar mesh in this build, the ramp is\n        // observable via a state-flag the test can read. Set a\n        // userData.opacityRamp on the camera that the renderer can\n        // optionally use as a post-effect; record start/end so the\n        // test can verify.\n        const start = performance.now();\n        camera.userData = camera.userData || {};\n        camera.userData.opacityRamp = { start, durationMs, complete: false };\n        const tick = () => {\n            const t = (performance.now() - start) / durationMs;\n            if (t >= 1) {\n                camera.userData.opacityRamp.complete = true;\n                resolve();\n                return;\n            }\n            requestAnimationFrame(tick);\n        };\n        requestAnimationFrame(tick);\n    });\n}\n","/**\n * Pyre — Phase 4 of the Black Sun framework.\n *\n * The eternal underground bonfire beneath the center of the Black Sun\n * (Snow Crash §H). Avatars delivered here by Graveyard Daemons are\n * cremated; the user may then re-sign-on with a fresh avatar.\n *\n * Visual: a small particle effect at the building's center, beneath\n * the floor. Triggers a brief flame burst on each cremation event.\n */\n\nimport * as THREE from 'three';\nimport {\n    BUILDING_BASE_SIDE_M,\n    BUILDING_NEAR_FACE_OFFSET_M,\n} from './BlackSunBuilding.js';\n\nconst PYRE_DEPTH_M = 8; // canonical \"underground\" — beneath the floor\nconst PYRE_FLAME_RADIUS_M = 1.5;\nconst PYRE_FLAME_HEIGHT_M = 2.4;\n\n/**\n * Build the Pyre attached to the given Black Sun group. Returns a\n * THREE.Group ready to be added to the scene root.\n */\nexport function buildPyre(blackSunGroup) {\n    if (!blackSunGroup?.userData?.nearFaceCenter) return null;\n    const nearFace = blackSunGroup.userData.nearFaceCenter;\n    const buildingDir = blackSunGroup.userData.buildingDir;\n    const halfDepth = BUILDING_BASE_SIDE_M / 2;\n    const center = nearFace.clone().addScaledVector(buildingDir, halfDepth);\n    center.y = -PYRE_DEPTH_M;\n\n    const group = new THREE.Group();\n    group.name = 'blacksunPyre';\n    group.userData.kind = 'blacksunPyre';\n    group.userData.center = { x: center.x, y: center.y, z: center.z };\n\n    // The flame — a stack of glowing meshes that pulses.\n    const flameGeom = new THREE.ConeGeometry(PYRE_FLAME_RADIUS_M, PYRE_FLAME_HEIGHT_M, 8);\n    const flameMat = new THREE.MeshBasicMaterial({\n        color: 0xff6020,\n        transparent: true,\n        opacity: 0.55,\n        depthWrite: false,\n    });\n    const flame = new THREE.Mesh(flameGeom, flameMat);\n    flame.position.copy(center);\n    flame.position.y = -PYRE_DEPTH_M + PYRE_FLAME_HEIGHT_M / 2;\n    flame.userData.kind = 'blacksunPyreFlame';\n    group.add(flame);\n\n    // A glowing core sphere for the bottom-most heat.\n    const coreGeom = new THREE.SphereGeometry(0.6, 12, 8);\n    const coreMat = new THREE.MeshBasicMaterial({\n        color: 0xffd060,\n        transparent: true,\n        opacity: 0.85,\n    });\n    const core = new THREE.Mesh(coreGeom, coreMat);\n    core.position.copy(flame.position);\n    core.position.y = -PYRE_DEPTH_M + 0.4;\n    core.userData.kind = 'blacksunPyreCore';\n    group.add(core);\n\n    // Lock the pyre's center so callers can derive Pyre position.\n    group.userData.pyrePosition = center.clone();\n\n    return group;\n}\n","/**\n * CoordinatorService — task-lease management for daemon agents.\n *\n * Multiple daemon instances may compete for the same task (two\n * Bouncers spotting the same offender, two Graveyard Daemons spotting\n * the same dismembered avatar). The Coordinator serializes them by\n * issuing leases — only one daemon holds the lease for a given task\n * at a time; others receive a \"taken\" rejection and idle.\n *\n * See `.aiwg/blacksun/09-open-agents-ai-mapping.md` §9.8.\n */\n\nconst DEFAULT_LEASE_TTL_MS = 30 * 1000;\n\nclass CoordinatorService {\n    constructor() {\n        this._leases = new Map(); // leaseKey -> { daemonId, taskType, targetId, expiresAt }\n        this._counter = 0;\n    }\n\n    /**\n     * Request a lease. Returns the lease object on success, or null on\n     * \"already taken\". Callers should check the return value before\n     * acting.\n     */\n    requestLease({ taskType, targetId, daemonId, ttlMs = DEFAULT_LEASE_TTL_MS }) {\n        if (!taskType || !targetId || !daemonId) return null;\n        this._gc();\n        const key = this._key(taskType, targetId);\n        if (this._leases.has(key)) {\n            const existing = this._leases.get(key);\n            if (existing.daemonId !== daemonId) return null;\n        }\n        const lease = {\n            id: `lease-${++this._counter}-${Date.now()}`,\n            key,\n            taskType,\n            targetId,\n            daemonId,\n            issuedAt: Date.now(),\n            expiresAt: Date.now() + ttlMs,\n        };\n        this._leases.set(key, lease);\n        return lease;\n    }\n\n    releaseLease(leaseId) {\n        for (const [key, lease] of this._leases.entries()) {\n            if (lease.id === leaseId) {\n                this._leases.delete(key);\n                return true;\n            }\n        }\n        return false;\n    }\n\n    /** Active leases (read-only snapshot). */\n    getActiveLeases() {\n        this._gc();\n        return Array.from(this._leases.values());\n    }\n\n    _key(taskType, targetId) {\n        return `${taskType}:${targetId}`;\n    }\n\n    _gc() {\n        const now = Date.now();\n        for (const [key, lease] of this._leases.entries()) {\n            if (lease.expiresAt < now) {\n                this._leases.delete(key);\n            }\n        }\n    }\n}\n\nlet _instance = null;\nexport function getCoordinator() {\n    if (!_instance) _instance = new CoordinatorService();\n    return _instance;\n}\n","/**\n * BouncerDaemon — Phase 4 of the Black Sun framework.\n *\n * Per `.aiwg/blacksun/09-open-agents-ai-mapping.md` §9.2 and the\n * canonical \"gorillas in tuxedos\" of Snow Crash. Phase 4 ships the\n * deterministic policy stub; the LLM-driven open-agents-ai variant\n * is a swap-in once the package is wired (the agent's tool surface\n * is the same).\n *\n * Triggers (canon):\n *   - Disruption (sustained loud behavior, harassment).\n *   - Pestering a celebrity (FOUNDER+ tier who is not engaging back).\n *   - Recording/taping a celebrity without consent.\n *   - Being contagious (attempting to render unsigned bitmap content).\n *\n * On trigger: request a coordinator lease on the offender → if\n * granted, apply cartoon ejection (mallet / safe / grab) → eject\n * through the front door → write audit-log entry.\n *\n * Mesh: low-poly gorilla-in-tuxedo silhouette.\n */\n\nimport * as THREE from 'three';\nimport { getCoordinator } from './CoordinatorService.js';\n\nlet _idCounter = 0;\n\nconst POLICY_TRIGGERS = new Set([\n    'disruption',\n    'pestering-celebrity',\n    'recording-celebrity',\n    'contagion',\n    'owner-override',\n]);\n\nexport class BouncerDaemon {\n    constructor({ scene, blackSunGroup, position }) {\n        this.id = `bouncer-${++_idCounter}`;\n        this.scene = scene;\n        this.blackSunGroup = blackSunGroup;\n        this._mesh = this._buildMesh();\n        if (position) this._mesh.position.copy(position);\n        this._mesh.userData.daemonId = this.id;\n        this._mesh.userData.daemonClass = 'bouncer';\n        if (this.scene) this.scene.add(this._mesh);\n        this._lease = null;\n    }\n\n    /**\n     * Decide whether to eject the given target avatar based on the\n     * supplied policy trigger. Returns a structured result.\n     *\n     * Phase 4 stub: deterministic — accept any trigger in\n     * POLICY_TRIGGERS that is paired with a target wallet, and\n     * acquire a coordinator lease before acting (so two bouncers\n     * don't double-eject).\n     *\n     * Production: replace this with an open-agents-ai agent run.\n     */\n    async evaluate({ targetWallet, trigger, evidence = null }) {\n        if (!targetWallet) {\n            return { action: 'noop', reason: 'no-target' };\n        }\n        if (!POLICY_TRIGGERS.has(trigger)) {\n            return { action: 'noop', reason: 'invalid-trigger' };\n        }\n        const coord = getCoordinator();\n        const lease = coord.requestLease({\n            taskType: 'eject',\n            targetId: targetWallet,\n            daemonId: this.id,\n        });\n        if (!lease) {\n            return { action: 'noop', reason: 'lease-taken' };\n        }\n        this._lease = lease;\n        // Audit-log + dispatch event the engine can consume to\n        // physically eject the target avatar.\n        const audit = {\n            kind: 'eject',\n            daemonId: this.id,\n            daemonClass: 'bouncer',\n            target: targetWallet,\n            trigger,\n            evidence,\n            leaseId: lease.id,\n            timestamp: Date.now(),\n        };\n        try {\n            window.dispatchEvent(new CustomEvent('noclip:blacksun:eject', { detail: audit }));\n        } catch { /* ignore */ }\n        return { action: 'eject', leaseId: lease.id, audit };\n    }\n\n    /** Release the active lease (caller invokes after physical ejection completes). */\n    releaseLease() {\n        if (!this._lease) return;\n        const coord = getCoordinator();\n        coord.releaseLease(this._lease.id);\n        this._lease = null;\n    }\n\n    dispose() {\n        if (this._mesh && this.scene) this.scene.remove(this._mesh);\n        this.releaseLease();\n    }\n\n    _buildMesh() {\n        const group = new THREE.Group();\n        group.name = `bouncer-${this.id}`;\n        // Body — boxy \"gorilla in tuxedo\" silhouette: dark torso + lighter shirt panel.\n        const torsoGeom = new THREE.BoxGeometry(0.9, 1.4, 0.6);\n        const torsoMat = new THREE.MeshBasicMaterial({ color: 0x0a0a12 });\n        const torso = new THREE.Mesh(torsoGeom, torsoMat);\n        torso.position.y = 1.0;\n        group.add(torso);\n\n        const shirtGeom = new THREE.PlaneGeometry(0.4, 1.1);\n        const shirtMat = new THREE.MeshBasicMaterial({ color: 0xeeeeee, side: THREE.DoubleSide });\n        const shirt = new THREE.Mesh(shirtGeom, shirtMat);\n        shirt.position.set(0, 1.0, 0.31);\n        group.add(shirt);\n\n        const headGeom = new THREE.SphereGeometry(0.32, 8, 6);\n        const headMat = new THREE.MeshBasicMaterial({ color: 0x2a2010 });\n        const head = new THREE.Mesh(headGeom, headMat);\n        head.position.y = 1.95;\n        group.add(head);\n        return group;\n    }\n}\n","/**\n * GraveyardDaemon — Phase 4 of the Black Sun framework.\n *\n * Per canon: \"small lithe persons swathed in black, like ninjas, not\n * even their eyes showing. They are quiet and efficient\" (Snow Crash\n * §H), and `.aiwg/blacksun/09-open-agents-ai-mapping.md` §9.3.\n *\n * Two jobs:\n *   1. Cleanup — collect dismembered avatars, deliver to the Pyre.\n *   2. Courier — carry hypercards between authorized senders.\n *\n * Phase 4 stub: deterministic task processor + courier API. Tunnel\n * traversal is logical (no animated ground transit yet — emerge,\n * collect, despawn, deliver via direct event).\n */\n\nimport * as THREE from 'three';\nimport { getCoordinator } from './CoordinatorService.js';\n\nlet _idCounter = 0;\n\nexport class GraveyardDaemon {\n    constructor({ scene, position }) {\n        this.id = `graveyard-${++_idCounter}`;\n        this.scene = scene;\n        this._mesh = this._buildMesh();\n        if (position) this._mesh.position.copy(position);\n        this._mesh.userData.daemonId = this.id;\n        this._mesh.userData.daemonClass = 'graveyard';\n        this._mesh.visible = false; // hidden until summoned\n        if (this.scene) this.scene.add(this._mesh);\n        this._lease = null;\n    }\n\n    /**\n     * Cleanup task: collect a dismembered avatar and deliver to the\n     * Pyre. Returns a structured result.\n     */\n    async cleanup({ targetWallet, dismemberedMesh = null, pyrePosition = null }) {\n        if (!targetWallet) return { action: 'noop', reason: 'no-target' };\n        const coord = getCoordinator();\n        const lease = coord.requestLease({\n            taskType: 'cleanup',\n            targetId: targetWallet,\n            daemonId: this.id,\n        });\n        if (!lease) return { action: 'noop', reason: 'lease-taken' };\n        this._lease = lease;\n        // Surface — emerge from a \"trapdoor\" near the target.\n        if (dismemberedMesh && dismemberedMesh.position) {\n            this._mesh.position.copy(dismemberedMesh.position);\n        }\n        this._mesh.visible = true;\n        // Logical traversal: dispatch a delivery event for the engine\n        // to consume; the engine handles the actual particle effect at\n        // the Pyre.\n        try {\n            window.dispatchEvent(new CustomEvent('noclip:blacksun:cremate', {\n                detail: {\n                    daemonId: this.id,\n                    target: targetWallet,\n                    pyrePosition: pyrePosition\n                        ? { x: pyrePosition.x, y: pyrePosition.y, z: pyrePosition.z }\n                        : null,\n                    timestamp: Date.now(),\n                    leaseId: lease.id,\n                },\n            }));\n        } catch { /* ignore */ }\n        // Despawn after a short delay.\n        setTimeout(() => {\n            this._mesh.visible = false;\n            this.releaseLease();\n        }, 1200);\n        return { action: 'cleanup', leaseId: lease.id };\n    }\n\n    /**\n     * Courier task: deliver a hypercard between two endpoints.\n     * Endpoints are world positions or named anchors (e.g.\n     * 'house:robit', 'pyre').\n     */\n    async deliver({ hypercard, fromAnchor, toAnchor }) {\n        if (!hypercard || !fromAnchor || !toAnchor) {\n            return { action: 'noop', reason: 'incomplete-courier' };\n        }\n        const coord = getCoordinator();\n        const lease = coord.requestLease({\n            taskType: 'courier',\n            targetId: hypercard.uuid || `${fromAnchor}->${toAnchor}`,\n            daemonId: this.id,\n        });\n        if (!lease) return { action: 'noop', reason: 'lease-taken' };\n        this._lease = lease;\n        try {\n            window.dispatchEvent(new CustomEvent('noclip:blacksun:courier-delivered', {\n                detail: {\n                    daemonId: this.id,\n                    hypercardUuid: hypercard.uuid || null,\n                    fromAnchor, toAnchor,\n                    timestamp: Date.now(),\n                    leaseId: lease.id,\n                },\n            }));\n        } catch { /* ignore */ }\n        setTimeout(() => this.releaseLease(), 800);\n        return { action: 'deliver', leaseId: lease.id };\n    }\n\n    releaseLease() {\n        if (!this._lease) return;\n        const coord = getCoordinator();\n        coord.releaseLease(this._lease.id);\n        this._lease = null;\n    }\n\n    dispose() {\n        if (this._mesh && this.scene) this.scene.remove(this._mesh);\n        this.releaseLease();\n    }\n\n    _buildMesh() {\n        const group = new THREE.Group();\n        const bodyGeom = new THREE.CylinderGeometry(0.18, 0.20, 1.6, 6);\n        const bodyMat = new THREE.MeshBasicMaterial({ color: 0x000000 });\n        const body = new THREE.Mesh(bodyGeom, bodyMat);\n        body.position.y = 0.8;\n        group.add(body);\n\n        const headGeom = new THREE.SphereGeometry(0.13, 6, 5);\n        const headMat = new THREE.MeshBasicMaterial({ color: 0x080808 });\n        const head = new THREE.Mesh(headGeom, headMat);\n        head.position.y = 1.7;\n        group.add(head);\n        return group;\n    }\n}\n","/**\n * DaemonRegistry — Phase 4 of the Black Sun framework.\n *\n * Spawns and manages the daemon ecology in the Black Sun. Per\n * `.aiwg/blacksun/06-daemon-taxonomy.md` §6.12, each daemon class\n * has its own lifecycle:\n *\n *   - Bouncer: persistent. ~6 instances spawn at Black Sun open.\n *   - Graveyard: persistent pool of ~4 idle in tunnel system.\n *   - Geisha / Drink-Server: persistent in their quadrants\n *     (deferred to v2 — atmospheric only).\n *\n * Phase 4 stub spawns the Bouncer and Graveyard pools at admission\n * time. The pools persist for the duration of the Black Sun visit and\n * are torn down on exit.\n */\n\nimport * as THREE from 'three';\nimport { BouncerDaemon } from './daemons/BouncerDaemon.js';\nimport { GraveyardDaemon } from './daemons/GraveyardDaemon.js';\nimport {\n    BUILDING_BASE_SIDE_M,\n} from './BlackSunBuilding.js';\n\nconst BOUNCER_POOL_SIZE = 6;\nconst GRAVEYARD_POOL_SIZE = 4;\n\nclass DaemonRegistry {\n    constructor() {\n        this._bouncers = [];\n        this._graveyards = [];\n        this._spawnedAt = 0;\n        this._scene = null;\n        this._blackSunGroup = null;\n    }\n\n    spawnAll({ scene, blackSunGroup }) {\n        if (this._spawnedAt) return; // idempotent\n        if (!scene || !blackSunGroup?.userData?.nearFaceCenter) return;\n        this._scene = scene;\n        this._blackSunGroup = blackSunGroup;\n        const nearFace = blackSunGroup.userData.nearFaceCenter;\n        const buildingDir = blackSunGroup.userData.buildingDir;\n        const tangent = blackSunGroup.userData.tangent;\n        const halfDepth = BUILDING_BASE_SIDE_M / 2;\n        const interiorCenter = nearFace.clone().addScaledVector(buildingDir, halfDepth);\n\n        // Spawn Bouncers along the back wall, evenly spaced along\n        // the tangent.\n        for (let i = 0; i < BOUNCER_POOL_SIZE; i++) {\n            const t = (i + 0.5) / BOUNCER_POOL_SIZE - 0.5; // -0.5..0.5\n            const pos = interiorCenter.clone()\n                .addScaledVector(buildingDir, halfDepth - 4)\n                .addScaledVector(tangent, t * (BUILDING_BASE_SIDE_M - 8));\n            pos.y = 0.05;\n            const bouncer = new BouncerDaemon({ scene, blackSunGroup, position: pos });\n            this._bouncers.push(bouncer);\n        }\n\n        // Spawn Graveyard Daemons under the floor (hidden, ready to\n        // emerge on cleanup demand).\n        for (let i = 0; i < GRAVEYARD_POOL_SIZE; i++) {\n            const t = (i + 0.5) / GRAVEYARD_POOL_SIZE - 0.5;\n            const pos = interiorCenter.clone()\n                .addScaledVector(tangent, t * (BUILDING_BASE_SIDE_M - 12));\n            pos.y = -1.0; // beneath the floor\n            const graveyard = new GraveyardDaemon({ scene, position: pos });\n            this._graveyards.push(graveyard);\n        }\n\n        this._spawnedAt = Date.now();\n    }\n\n    despawnAll() {\n        for (const b of this._bouncers) b.dispose();\n        this._bouncers = [];\n        for (const g of this._graveyards) g.dispose();\n        this._graveyards = [];\n        this._spawnedAt = 0;\n        this._scene = null;\n        this._blackSunGroup = null;\n    }\n\n    /** First idle bouncer for evaluating an offender. */\n    getAvailableBouncer() {\n        return this._bouncers[0] || null;\n    }\n\n    /** Bouncer at a specific pool index. Used for tests that need two\n     *  different daemons (lease-serialization race). */\n    getBouncerAt(index) {\n        return this._bouncers[index] || null;\n    }\n\n    /** First available graveyard daemon. */\n    getAvailableGraveyard() {\n        return this._graveyards[0] || null;\n    }\n\n    getCounts() {\n        return {\n            bouncers: this._bouncers.length,\n            graveyards: this._graveyards.length,\n            spawnedAt: this._spawnedAt,\n        };\n    }\n}\n\nlet _instance = null;\nexport function getDaemonRegistry() {\n    if (!_instance) _instance = new DaemonRegistry();\n    return _instance;\n}\n","/**\n * MetaverseScene — Phase 1 of the Black Sun framework.\n *\n * Implements the canonical Snow Crash Metaverse environment: a black sphere\n * of ~10,430 km radius, with a 100 m wide Street running along the equator,\n * a monorail down the centerline, streetlights at 50 m intervals.\n *\n * Phase 1 scope: shell only. No Black Sun building, no daemons, no crowd.\n * Phase 2 will add the building. Phase 3 the access gate. Phase 4 daemons.\n *\n * See .aiwg/blacksun/02-street-geometry.md for the canonical specs.\n */\n\nimport * as THREE from 'three';\nimport {\n    METAVERSE_SPHERE_RADIUS_KM,\n    METAVERSE_SPHERE_RADIUS_M,\n    STREET_WIDTH_M,\n    STREET_HALF_WIDTH_M,\n    TOTAL_LOCAL_PORTS,\n    EXPRESS_PORT_COUNT,\n    portToTheta,\n} from '../blacksun/constants.js';\nimport { buildBlackSun, distanceToPropertyLine } from '../blacksun/BlackSunBuilding.js';\nimport { buildCrowd } from '../blacksun/CrowdRenderer.js';\nimport { getAccessGate } from '../blacksun/AccessGate.js';\nimport { buildInterior, runOpacityRamp } from '../blacksun/Interior.js';\nimport { buildPyre } from '../blacksun/Pyre.js';\nimport { getDaemonRegistry } from '../blacksun/DaemonRegistry.js';\n\n// Re-export the constants for any caller that imports them from\n// MetaverseScene (legacy import surface kept for backwards compat).\nexport {\n    METAVERSE_SPHERE_RADIUS_KM,\n    METAVERSE_SPHERE_RADIUS_M,\n    STREET_WIDTH_M,\n    STREET_HALF_WIDTH_M,\n    TOTAL_LOCAL_PORTS,\n    EXPRESS_PORT_COUNT,\n    portToTheta,\n};\n\n// Eye height — canonical avatar standing height.\nconst EYE_HEIGHT_M = 1.6;\n\n// Local segment around the spawn port. Phase 1 renders only this much of\n// the Street; the rest of the equator is implied by the sphere's curvature\n// but does not need explicit geometry yet.\nconst LOCAL_SEGMENT_LENGTH_M = 1000; // 1 km\nconst STREETLIGHT_SPACING_M = 50;\nconst MONORAIL_HEIGHT_M = 8;\n\n/**\n * Compute world-space spawn position for a given port index.\n * The user materializes on the Street, oriented eastward (along +θ).\n */\nexport function portSpawnPose(portIndex) {\n    const theta = portToTheta(portIndex);\n    const r = METAVERSE_SPHERE_RADIUS_M;\n    const cos = Math.cos(theta);\n    const sin = Math.sin(theta);\n    return {\n        position: new THREE.Vector3(r * cos, EYE_HEIGHT_M, r * sin),\n        // Look along the +θ tangent direction.\n        lookAt: new THREE.Vector3(\n            r * cos - sin * 100,\n            EYE_HEIGHT_M,\n            r * sin + cos * 100,\n        ),\n        theta,\n    };\n}\n\nexport class MetaverseScene {\n    /**\n     * @param {{ scene: THREE.Scene, camera: THREE.PerspectiveCamera }} opts\n     */\n    constructor({ scene, camera }) {\n        this.scene = scene || null;\n        this.camera = camera || null;\n        this._root = new THREE.Group();\n        this._root.name = 'metaverseRoot';\n        this._root.userData.kind = 'metaverseRoot';\n\n        // Track which port the user is currently anchored at, so we can\n        // tear down and rebuild the local segment on port change without\n        // rebuilding the sphere.\n        this._currentPort = null;\n\n        this._buildBlackSphere();\n        // _buildLocalSegment is deferred until spawnAtPort runs — we need\n        // a port index to know where to lay the streetlights and pavement.\n    }\n\n    /** Add the metaverse root to the scene. Idempotent. */\n    attach() {\n        if (!this.scene || !this._root) return;\n        if (this._root.parent !== this.scene) {\n            this.scene.add(this._root);\n        }\n    }\n\n    /** Remove from scene. Geometry is retained in memory for fast re-attach. */\n    detach() {\n        if (!this.scene || !this._root) return;\n        if (this._root.parent === this.scene) {\n            this.scene.remove(this._root);\n        }\n    }\n\n    /**\n     * Spawn the user at the requested Local Port index, building the local\n     * Street segment around them if not already in place. If the requested\n     * port is the canonical Black-Sun port (0), also instantiate the\n     * building and the surrounding crowd.\n     */\n    spawnAtPort(portIndex) {\n        const pose = portSpawnPose(portIndex);\n        this._currentPort = pose;\n        this._buildLocalSegment(pose);\n        // The Black Sun is anchored at port 0. If the user spawns there\n        // (or anywhere within visual range — for now, only port 0),\n        // construct the building and crowd. Other ports get the bare\n        // Street stub.\n        const portInt = Math.max(0, Math.min(65535, Math.floor(portIndex || 0)));\n        if (portInt === 0) {\n            this._buildBlackSunAt(0);\n        } else {\n            this._teardownBlackSun();\n        }\n        if (this.camera) {\n            this.camera.position.copy(pose.position);\n            this.camera.up.set(0, 1, 0);\n            this.camera.lookAt(pose.lookAt);\n            this.camera.updateMatrixWorld(true);\n        }\n        return pose;\n    }\n\n    /**\n     * Returns the Black Sun building group (if currently instantiated)\n     * or null. Used by the property-line collider and downstream\n     * phases that need the building's transform.\n     */\n    getBlackSunGroup() {\n        return this._blackSunGroup || null;\n    }\n\n    /**\n     * Per-frame property-line collider. Called by PlanetScene's\n     * animation hook when the scene is in metaverse mode. If the\n     * camera is on the inside of the Black Sun's property line and\n     * has not been admitted (Phase 2: nobody is admitted; Phase 3\n     * will plug in the auth check), gently push the camera back to\n     * the property line. Returns true if a clamp was applied.\n     */\n    enforcePropertyLine(camera) {\n        if (!camera || !this._blackSunGroup) return false;\n        const dist = distanceToPropertyLine(this._blackSunGroup, camera.position);\n        // dist > 0 ⇒ outside the property line (street side).\n        // dist <= 0 ⇒ at or beyond the line; phase 2 always rejects.\n        if (dist > 0) return false;\n        // Push back along buildingDir (away from the door) until\n        // dist === MIN_OUTSIDE.\n        const MIN_OUTSIDE = 0.25;\n        const buildingDir = this._blackSunGroup.userData.buildingDir;\n        if (!buildingDir) return false;\n        const pushBack = -dist + MIN_OUTSIDE;\n        camera.position.addScaledVector(buildingDir, -pushBack);\n        return true;\n    }\n\n    _buildBlackSunAt(portIndex) {\n        if (this._blackSunGroup && this._blackSunGroup.userData.portIndex === portIndex) {\n            return; // already built at this port\n        }\n        this._teardownBlackSun();\n        const group = buildBlackSun(portIndex);\n        this._root.add(group);\n        this._blackSunGroup = group;\n        // Build the milling crowd in front of the door.\n        const crowd = buildCrowd(group);\n        this._root.add(crowd);\n        this._blackSunCrowd = crowd;\n    }\n\n    _teardownBlackSun() {\n        // Phase 3: also teardown the interior if present (it is only\n        // attached for admitted users) and reset admission state.\n        this._teardownInterior();\n        if (this._blackSunGroup) {\n            this._root.remove(this._blackSunGroup);\n            this._disposeNode(this._blackSunGroup);\n            this._blackSunGroup = null;\n        }\n        if (this._blackSunCrowd) {\n            this._root.remove(this._blackSunCrowd);\n            this._disposeNode(this._blackSunCrowd);\n            this._blackSunCrowd = null;\n        }\n    }\n\n    /**\n     * Phase 3 admission: present a wallet (and optional invitation /\n     * current-tier context) to the AccessGate. On success: hide the\n     * exterior crowd, build and attach the interior, run the opacity\n     * ramp. On failure: surface the denial reason for HUD display.\n     *\n     * Returns { admitted, tier, source, reason }.\n     */\n    async attemptThresholdCross({ wallet, invite = null, currentTier = null } = {}) {\n        if (!this._blackSunGroup) {\n            return { admitted: false, reason: 'no-blacksun' };\n        }\n        const gate = getAccessGate();\n        const result = await gate.attemptAdmit({ wallet, invite, currentTier });\n        if (!result.admitted) {\n            return result;\n        }\n        // Build and attach the interior.\n        this._buildInteriorOnce();\n        // Hide the crowd while inside (per .aiwg §4.7: outside crowd\n        // becomes silhouettes when the user is inside).\n        if (this._blackSunCrowd) this._blackSunCrowd.visible = false;\n        // Move camera to a spawn point just inside the door.\n        if (this.camera && this._blackSunGroup?.userData?.nearFaceCenter) {\n            const nf = this._blackSunGroup.userData.nearFaceCenter;\n            const dir = this._blackSunGroup.userData.buildingDir;\n            this.camera.position.set(\n                nf.x + dir.x * 2,\n                1.6,\n                nf.z + dir.z * 2,\n            );\n            this.camera.lookAt(this._blackSunGroup.position);\n        }\n        // Run opacity ramp (translucent → solid). Don't await — this\n        // returns immediately so the caller can continue rendering.\n        if (this.camera) runOpacityRamp(this.camera, 250);\n        this._admitted = true;\n        return result;\n    }\n\n    /**\n     * Exit the Black Sun. Releases the AccessGate session, attaches\n     * the crowd back, removes interior assets, returns the camera to\n     * the door's outside.\n     */\n    exitBlackSun() {\n        if (!this._admitted) return;\n        const gate = getAccessGate();\n        gate.release('exit');\n        this._teardownInterior();\n        if (this._blackSunCrowd) this._blackSunCrowd.visible = true;\n        // Move camera back to the Street side.\n        if (this.camera && this._blackSunGroup?.userData?.nearFaceCenter) {\n            const nf = this._blackSunGroup.userData.nearFaceCenter;\n            const dir = this._blackSunGroup.userData.buildingDir;\n            this.camera.position.set(\n                nf.x - dir.x * 5,\n                1.6,\n                nf.z - dir.z * 5,\n            );\n        }\n        this._admitted = false;\n    }\n\n    isAdmitted() {\n        return !!this._admitted;\n    }\n\n    _buildInteriorOnce() {\n        if (this._blackSunInterior) return;\n        const interior = buildInterior(this._blackSunGroup);\n        if (interior) {\n            this._root.add(interior);\n            this._blackSunInterior = interior;\n        }\n        // Phase 4: also build the Pyre and spawn the daemon ecology\n        // when admission opens. They're scoped to the same lifecycle\n        // as the interior — torn down in _teardownInterior on exit.\n        if (!this._pyre) {\n            const pyre = buildPyre(this._blackSunGroup);\n            if (pyre) {\n                this._root.add(pyre);\n                this._pyre = pyre;\n            }\n        }\n        const reg = getDaemonRegistry();\n        reg.spawnAll({ scene: this._root, blackSunGroup: this._blackSunGroup });\n    }\n\n    _teardownInterior() {\n        if (this._blackSunInterior) {\n            this._root.remove(this._blackSunInterior);\n            this._disposeNode(this._blackSunInterior);\n            this._blackSunInterior = null;\n        }\n        if (this._pyre) {\n            this._root.remove(this._pyre);\n            this._disposeNode(this._pyre);\n            this._pyre = null;\n        }\n        const reg = getDaemonRegistry();\n        reg.despawnAll();\n    }\n\n    /**\n     * Public Phase 4 hook: invoke the bouncer-daemon evaluation\n     * pipeline for a target avatar with a given trigger. Returns the\n     * decision the bouncer daemon made. Used by the scene engine /\n     * tests to verify ejection behavior without modeling actual\n     * disruptive avatars.\n     */\n    async invokeBouncerOn({ targetWallet, trigger, evidence = null }) {\n        const reg = getDaemonRegistry();\n        const bouncer = reg.getAvailableBouncer();\n        if (!bouncer) return { action: 'noop', reason: 'no-bouncer-available' };\n        const result = await bouncer.evaluate({ targetWallet, trigger, evidence });\n        if (result.action === 'eject') {\n            // Release the lease promptly in test mode; production\n            // should release after the physical ejection animation.\n            setTimeout(() => bouncer.releaseLease(), 100);\n        }\n        return result;\n    }\n\n    /**\n     * Public Phase 4 hook: invoke a Graveyard Daemon cleanup for a\n     * dismembered avatar. Returns the daemon's task result.\n     */\n    async invokeGraveyardCleanup({ targetWallet, dismemberedMesh = null }) {\n        const reg = getDaemonRegistry();\n        const graveyard = reg.getAvailableGraveyard();\n        if (!graveyard) return { action: 'noop', reason: 'no-graveyard-available' };\n        const pyrePos = this._pyre?.userData?.pyrePosition || null;\n        return graveyard.cleanup({ targetWallet, dismemberedMesh, pyrePosition: pyrePos });\n    }\n\n    /**\n     * Expose the daemon registry so tests / agent runtimes can\n     * address individual daemons by index. Production code should\n     * route through the public hooks above; this is for direct-\n     * driven scenarios (race tests, owner-override commands).\n     */\n    getDaemonRegistry() {\n        return getDaemonRegistry();\n    }\n\n    /** Returns the current port pose (read-only). */\n    getCurrentPose() {\n        return this._currentPort;\n    }\n\n    /** Frees all GPU resources. */\n    dispose() {\n        this.detach();\n        this._disposeNode(this._root);\n        this._root = null;\n    }\n\n    // ── Geometry construction ────────────────────────────────────────\n\n    _buildBlackSphere() {\n        // The sphere itself is enormous (10,430 km radius) — we don't render\n        // it as a proper mesh because nothing about it would be visible from\n        // a person standing on the surface. Instead we set the scene\n        // background color to black; the sphere is implied by horizon and\n        // the streetlights fading into the distance.\n        //\n        // The \"ground\" is rendered locally per-segment (see _buildLocalSegment).\n\n        // A subtle ground-plane fallback well below pavement level so any\n        // physics/raycast that escapes the local segment still hits something\n        // matte black.\n        const fallbackGround = new THREE.Mesh(\n            new THREE.PlaneGeometry(2_000_000, 2_000_000),\n            new THREE.MeshBasicMaterial({ color: 0x000000, side: THREE.DoubleSide }),\n        );\n        fallbackGround.rotation.x = -Math.PI / 2;\n        fallbackGround.position.y = -10_000;\n        fallbackGround.userData.kind = 'metaverseGroundFallback';\n        this._root.add(fallbackGround);\n    }\n\n    _buildLocalSegment(pose) {\n        // Tear down any prior local segment.\n        const existing = this._root.getObjectByName('metaverseLocalSegment');\n        if (existing) {\n            this._root.remove(existing);\n            this._disposeNode(existing);\n        }\n\n        const segment = new THREE.Group();\n        segment.name = 'metaverseLocalSegment';\n        segment.userData.kind = 'metaverseLocalSegment';\n\n        const theta = pose.theta;\n        const cos = Math.cos(theta);\n        const sin = Math.sin(theta);\n        const r = METAVERSE_SPHERE_RADIUS_M;\n\n        // Local frame at the spawn point:\n        //   - origin: pose.position projected to street level (y = 0)\n        //   - +tangent (forward): along +θ\n        //   - +normal (outward): along +radial\n        //   - +up: +Y world\n        const origin = new THREE.Vector3(r * cos, 0, r * sin);\n        const tangent = new THREE.Vector3(-sin, 0, cos);\n        const radial = new THREE.Vector3(cos, 0, sin);\n\n        // Pavement: 1 km × 100 m strip centered on origin, oriented along tangent.\n        const pavementGeom = new THREE.PlaneGeometry(LOCAL_SEGMENT_LENGTH_M, STREET_WIDTH_M);\n        // Plane is XZ-aligned by default after rotateX(-PI/2). We then\n        // rotate it to align with the tangent.\n        pavementGeom.rotateX(-Math.PI / 2);\n        const pavementMat = new THREE.MeshBasicMaterial({\n            color: 0x111118,\n            side: THREE.DoubleSide,\n        });\n        const pavement = new THREE.Mesh(pavementGeom, pavementMat);\n        pavement.position.copy(origin);\n        // Orient: lookAt builds a basis. The plane's local +X is the long axis.\n        pavement.lookAt(origin.clone().add(radial)); // rotate to face radial\n        // After lookAt, plane's +Z faces radial; its +X is along (up × radial)\n        // which is the tangent direction. That's what we want.\n        pavement.userData.kind = 'metaverseStreetPavement';\n        segment.add(pavement);\n\n        // Center stripe (a thin emissive line along the monorail track shadow).\n        const stripeGeom = new THREE.PlaneGeometry(LOCAL_SEGMENT_LENGTH_M, 0.4);\n        stripeGeom.rotateX(-Math.PI / 2);\n        const stripeMat = new THREE.MeshBasicMaterial({ color: 0x303040 });\n        const stripe = new THREE.Mesh(stripeGeom, stripeMat);\n        stripe.position.copy(origin);\n        stripe.position.y = 0.02; // tiny offset to avoid z-fighting\n        stripe.lookAt(origin.clone().add(radial));\n        segment.add(stripe);\n\n        // Streetlights — every STREETLIGHT_SPACING_M along the tangent, on\n        // both edges of the Street.\n        const lightCount = Math.floor(LOCAL_SEGMENT_LENGTH_M / STREETLIGHT_SPACING_M);\n        const halfCount = Math.floor(lightCount / 2);\n        for (let i = -halfCount; i <= halfCount; i++) {\n            for (const side of [-1, 1]) {\n                const along = i * STREETLIGHT_SPACING_M;\n                const across = side * (STREET_HALF_WIDTH_M - 2);\n                const post = origin.clone()\n                    .addScaledVector(tangent, along)\n                    .addScaledVector(radial, across);\n                segment.add(this._buildStreetlight(post));\n            }\n        }\n\n        // Monorail track — single rail at MONORAIL_HEIGHT_M above the\n        // centerline, running the full local segment length.\n        const monorailGeom = new THREE.BoxGeometry(LOCAL_SEGMENT_LENGTH_M, 0.6, 0.6);\n        const monorailMat = new THREE.MeshBasicMaterial({ color: 0x202028 });\n        const monorail = new THREE.Mesh(monorailGeom, monorailMat);\n        monorail.position.copy(origin);\n        monorail.position.y = MONORAIL_HEIGHT_M;\n        monorail.lookAt(origin.clone().add(radial).setY(MONORAIL_HEIGHT_M));\n        // After lookAt, +X aligns with tangent (long axis of monorail).\n        monorail.userData.kind = 'metaverseMonorail';\n        segment.add(monorail);\n\n        // Monorail support pylons every ~100 m.\n        for (let i = -Math.floor(LOCAL_SEGMENT_LENGTH_M / 200); i <= Math.floor(LOCAL_SEGMENT_LENGTH_M / 200); i++) {\n            const along = i * 200;\n            const post = origin.clone().addScaledVector(tangent, along);\n            const pylon = new THREE.Mesh(\n                new THREE.CylinderGeometry(0.4, 0.6, MONORAIL_HEIGHT_M, 6),\n                new THREE.MeshBasicMaterial({ color: 0x202028 }),\n            );\n            pylon.position.copy(post);\n            pylon.position.y = MONORAIL_HEIGHT_M / 2;\n            segment.add(pylon);\n        }\n\n        this._root.add(segment);\n    }\n\n    _buildStreetlight(basePos) {\n        const group = new THREE.Group();\n        group.name = 'streetlight';\n        group.position.copy(basePos);\n\n        const post = new THREE.Mesh(\n            new THREE.CylinderGeometry(0.08, 0.1, 6, 6),\n            new THREE.MeshBasicMaterial({ color: 0x18181c }),\n        );\n        post.position.y = 3;\n        group.add(post);\n\n        // The light fixture itself — emissive sphere.\n        const fixture = new THREE.Mesh(\n            new THREE.SphereGeometry(0.35, 8, 8),\n            new THREE.MeshBasicMaterial({ color: 0xffe4a8 }),\n        );\n        fixture.position.y = 6;\n        group.add(fixture);\n\n        return group;\n    }\n\n    _disposeNode(node) {\n        if (!node) return;\n        node.traverse?.((child) => {\n            if (child.geometry) child.geometry.dispose?.();\n            if (child.material) {\n                if (Array.isArray(child.material)) {\n                    child.material.forEach((m) => m.dispose?.());\n                } else {\n                    child.material.dispose?.();\n                }\n            }\n        });\n    }\n}\n\nlet _instance = null;\n/** Singleton accessor. */\nexport function getMetaverseScene(opts) {\n    if (!_instance) _instance = new MetaverseScene(opts);\n    return _instance;\n}\n","/** Shared status surface; an unavailable 3D button must leave the map intact. */\nexport async function showGraphicsUnavailableNotice() {\n  const { getAddressToast } = await import('../tags/AddressToast.js');\n  getAddressToast().showGovernanceNotice({\n    title: '3D graphics required',\n    detail: 'Add a GPU to your machine to load the photorealistic tiles. If you already have one, enable hardware acceleration and reload.',\n    tone: 'info', noticeKey: 'graphics-unavailable', autoHideMs: 10000,\n  });\n}\n\n/** Explicit, in-place graphics retry for embedded 3D-only presentations. */\nexport function showGraphicsStartupRecovery({ failures = [] } = {}) {\n  window.__noclipGraphicsRecovery?.dispose();\n  return new Promise(resolve => {\n    const root = document.createElement('section'); root.className = 'nca-graphics-recovery';\n    root.setAttribute('role', 'alert'); root.setAttribute('aria-label', 'Graphics startup');\n    const style = document.createElement('style');\n    style.textContent = `.nca-graphics-recovery { position:fixed; z-index:100001; left:50%; top:55%;\n      transform:translateX(-50%); width:min(420px,calc(100% - 40px)); box-sizing:border-box;\n      padding:18px; border:1px solid #ffffff30; border-radius:12px; background:#15191de8;\n      backdrop-filter:blur(20px); color:#eee; font:13px/1.5 system-ui,sans-serif; }\n      .nca-graphics-recovery p { margin:0 0 12px; }\n      .nca-graphics-recovery button { color:#f2d330; background:#202522; border:1px solid #766914;\n        border-radius:6px; min-height:44px; padding:8px 16px; font:inherit; cursor:pointer; }\n      .nca-graphics-recovery details { margin-top:12px; overflow-wrap:anywhere; }`;\n    const message = document.createElement('p');\n    message.textContent = 'The graphics driver has not accepted the 3D scene yet. Retry when it is ready.';\n    const button = document.createElement('button'); button.type = 'button'; button.textContent = 'Retry 3D';\n    const help = document.createElement('details'), summary = document.createElement('summary');\n    summary.textContent = 'Graphics details';\n    const reason = document.createElement('p');\n    reason.textContent = failures.map(f => `${f.profile}: ${f.reason}`).join(' · ')\n      + ' Check hardware acceleration if the driver continues to refuse WebGL 2.';\n    help.append(summary, reason); root.append(style, message, button, help);\n    const owner = { root, dispose() { button.removeEventListener('click', retry); root.remove();\n      if (window.__noclipGraphicsRecovery === owner) delete window.__noclipGraphicsRecovery; } };\n    function retry() { owner.dispose(); resolve(); }\n    button.addEventListener('click', retry); document.body.append(root);\n    window.__noclipGraphicsRecovery = owner; button.focus({ preventScroll:true });\n  });\n}\n","/**\n * PlanetScene\n *\n * Purpose:\n * - Public facade that provides the stable scene API described in API_README.md.\n * - Owns lifecycle: init/start/stop/dispose and state snapshots.\n *\n * API intention:\n * - constructor(container, options)\n * - async init()\n * - start(), stop(), dispose()\n * - getState(), restoreState(snapshot)\n * - api: exposes tuneables, overlays, streams, entities, assets, audio, events\n *\n * Relationships:\n * - Delegates to existing modules for parity in Phase 1.\n * - Emits events through EventBus and delegates persistence to UIController\n *   where possible.\n */\nimport { setSceneOcclusionProbe } from '../render/SceneOcclusion.js';\nimport * as THREE from 'three';\nimport { EventBus } from '../shared/EventBus.js';\nimport { XRDiagnostics } from '../vr/XRDiagnostics.js';\nimport { BrowserPerformanceTelemetry } from '../diagnostics/BrowserPerformanceTelemetry.js';\nimport { HYDRA_INTEROP_CONTRACT, normalizeInteropEnvelope } from '../shared/interopContract.js';\nimport { getBackendApiBase, getFallbackCesiumIonToken, getFallbackGoogleTilesKey } from '../shared/backend.js';\nimport { getNoclipGovernanceClient } from '../shared/NoclipGovernanceClient.js';\nimport { runCameraQuiescenceBarrier } from '../camera/CameraQuiescenceBarrier.js';\nimport { PerformanceMonitor } from '../../modules/performance-monitor.js';\nimport { SceneInitializer } from '../../modules/scene-initializer.js';\nimport { MapPresentationResources } from '../render/MapPresentationResources.js';\nimport { AnimationLoop } from '../../modules/animation-loop.js';\nimport { MotionTracker } from '../../modules/motion-tracker.js';\nimport { ElevationClient } from '../../modules/elevation-client.js';\nimport { ImageryManager } from '../../modules/imagery-manager.js';\nimport { get as getBasemap } from '../imagery/BasemapRegistry.js';\nimport { resolveMapSource } from '../imagery/MapSourceResolver.js';\nimport { MapSourceGlobe } from '../imagery/MapSourceGlobe.js';\nimport { OverviewImageSource } from '../imagery/OverviewImageSource.js';\nimport { getSceneStateStore } from '../../modules/scene-state-store.js';\nimport { TriTreeManager } from '../../modules/tritree-manager.js';\nimport { SurfaceController } from '../../modules/surface-camera-controller.js';\nimport { EventManager } from '../../modules/event-manager.js';\nimport { setTilesPendingNormals, setWireframeStyle } from '../../modules/tri-tile.js';\nimport { PLANET_RADIUS, VIEW_ALTITUDE_MIN_M, VIEW_ALTITUDE_MAX_M, DEG2RAD, EARTH_PRIME_MERIDIAN_OFFSET_RAD, DEFAULT_FORWARDER } from '../../modules/constants.js';\nimport { handleIncoming } from '../../modules/nkn-client.js';\nimport { WeatherSystem } from '../../modules/weather-system.js';\nimport { createOrbitalEarthMaterial } from '../../modules/earth-material.js';\nimport { UIController } from '../../modules/ui-controller.js';\nimport {\n    latLonToLocalDir,\n    dirToLatLonLocal,\n    raySphereIntersection,\n    rayEllipsoidIntersection,\n    worldPosToLatLonLocal,\n    ellipsoidRadiusForLocalDir,\n    ellipsoidRadiusForWorldDir\n} from '../../modules/geometry-utils.js';\nimport { getHudInfoStore } from '../../modules/hud-info-store.js';\nimport { OverlaySubsystem } from '../overlays/OverlaySubsystem.js';\nimport { createOverlaySceneApi } from '../overlays/OverlaySceneApi.js';\nimport { HydraOverlayIngress } from '../overlays/HydraOverlayIngress.js';\nimport { OverlayRegistry } from '../overlays/OverlayRegistry.js';\nimport { DataSourceLayerRenderer } from '../overlays/renderers/DataSourceLayerRenderer.js';\nimport { StreamHub } from '../streams/StreamHub.js';\nimport { EntitySystem } from '../entities/EntitySystem.js';\nimport { AssetSubsystem } from '../assets/AssetSubsystem.js';\nimport { FieldAssetLayer } from '../assets/FieldAssetLayer.js';\nimport { AccountNoteLayer } from '../notes/AccountNoteLayer.js';\nimport { AccessController } from '../access/AccessController.js';\nimport { initAsyncHarness } from '../async/AsyncHarness.js';\nimport { PresenceSystem } from '../presence/PresenceSystem.js';\nimport { AudioSystem } from '../audio/AudioSystem.js';\nimport { WindAudio } from '../audio/WindAudio.js';\nimport { RainSystem } from '../weather/RainSystem.js';\nimport { setWeatherBasis, weatherWindFrom, configuredCloudTopRadius, areWeatherCloudsEnabled } from '../weather/SceneWeatherState.js';\nimport { SplineSubsystem } from '../splines/SplineSubsystem.js';\nimport { BuildingOverlay } from '../overlays/BuildingOverlay.js';\nimport { createBuildingOverlayItem } from '../overlays/BuildingOverlayItem.js';\nimport { createTheaterOverlayItem } from '../overlays/TheaterOverlayItem.js';\nimport { AircraftOverlay } from '../overlays/AircraftOverlay.js';\nimport { MaritimeOverlay } from '../overlays/MaritimeOverlay.js';\nimport { IncidentOverlay } from '../overlays/IncidentOverlay.js';\nimport { TrafficCameraOverlay } from '../overlays/TrafficCameraOverlay.js';\nimport { RoadTrafficOverlay } from '../overlays/RoadTrafficOverlay.js';\nimport { RadioDataOverlay } from '../overlays/RadioDataOverlay.js';\nimport { GeocacheLayer } from '../geocaches/GeocacheLayer.js';\nimport { getAddressHoverOverlay } from '../overlays/AddressHoverOverlay.js';\nimport { SensorOverlay } from '../sensors/SensorOverlay.js';\nimport { MeshtasticOverlay } from '../meshtastic/MeshtasticOverlay.js';\nimport { WeatherVolumeOverlay } from '../weather/WeatherVolumeOverlay.js';\nimport { WEATHER_VOLUME_LAYERS } from '../weather/WeatherVolumeContract.js';\nimport { EnvironmentalOverlay } from '../environment/EnvironmentalOverlay.js';\nimport {\n    CONFLICT_BORDER_PALETTE,\n    GlobalSignalsOverlay,\n} from '../environment/GlobalSignalsOverlay.js';\nimport { getSensorManager } from '../sensors/SensorManager.js';\nimport { getSensorApiService } from '../sensors/SensorApiService.js';\nimport { getSensorEventStore } from '../sensors/SensorEventStore.js';\nimport { InfrastructureOverlay } from '../overlays/InfrastructureOverlay.js';\nimport {\n    getEnabledOpenInfraMapGroups,\n    hasEnabledOpenInfraMapGroup,\n} from '../overlays/OpenInfraMapContract.js';\nimport { resolveIncidentColor, resolveIncidentEmoji } from '../incidents/IncidentTypes.js';\nimport { GeoJsonLayer } from './GeoJsonLayer.js';\nimport { GeoBoundaryService } from '../geo/GeoBoundaryService.js';\nimport { SceneSettings } from '../settings/SceneSettings.js';\nimport {\n    buildTerrainImagerySettings,\n    buildTerrainElevationSettings,\n    buildTriTreeImageryConfigPatch,\n    buildImageryManagerConfigPatch,\n    hasImageryManagerConfigChanges,\n    buildElevationClientConfigPatch\n} from '../settings/tuneables-mapper.js';\nimport { PhysicsSystem } from '../../modules/physics-system.js';\nimport { ProximityTriggerManager } from '../audio/proximity-trigger.js';\nimport { ClickTriggerManager } from '../interaction/click-trigger.js';\nimport { VRManager } from '../vr/VRManager.js';\nimport { VrAccessGate } from '../vr/VrAccessGate.js';\nimport { LocalPlayer } from '../avatar/LocalPlayer.js';\nimport { PeerManager } from '../avatar/PeerManager.js';\nimport { AvatarFactory } from '../avatar/AvatarFactory.js';\nimport { MobileStereoRenderer } from '../../modules/mobile-stereo-renderer.js';\nimport { SceneBudgetGovernor } from '../../modules/scene-budget-governor.js';\nimport { PhotoAtmosphereEffect } from '../tiles/PhotoAtmosphereEffect.js';\nimport {\n    rememberWarmPhotorealSession,\n    takeWarmPhotorealSession,\n} from '../tiles/PhotorealWarmCache.js';\nimport { getAuthService } from '../auth/AuthService.js';\nimport { getLabelSystem } from '../labels/LabelSystem.js';\nimport { LunarFeatureLabels } from '../lunar/LunarFeatureLabels.js';\nimport {\n    LABEL_CATEGORIES,\n    getLabelCategory,\n    getLabelCategoryControlValue,\n    getLabelCategoryPatch,\n    getLabelCategoryValue,\n} from '../labels/LabelCategoryRegistry.js';\nimport {\n    agentEntityId,\n    resolveViewshedCategories,\n    sanitizeAgentValue,\n} from '../labels/SceneViewshedData.js';\nimport { getPhotoBuildingLabels } from '../labels/PhotoBuildingLabels.js';\nimport { getBusinessLabels } from '../labels/BusinessLabels.js';\nimport { getMotionTracker as getPathTracker } from '../tracking/MotionTracker.js';\nimport { getRouteStore } from '../routing/RouteStore.js';\nimport { RouteProgressTracker } from '../routing/RouteProgressTracker.js';\nimport { RoadContextService } from '../routing/RoadContextService.js';\nimport { ScenePuppetController } from '../agent/ScenePuppetController.js';\nimport { getRouteRibbonRenderer } from '../routing/RouteRibbonRenderer.js';\nimport { PlaceSearchSurfaceLayer } from '../overlays/PlaceSearchSurfaceLayer.js';\nimport { getDirectionsPanel } from '../ui/DirectionsPanel.js';\nimport { getEarthDaemonManager } from '../daemons/EarthDaemonManager.js';\nimport { getNavBanner } from '../ui/NavBanner.js';\nimport { MotionTrailRenderer } from '../tracking/MotionTrailRenderer.js';\nimport { createSceneMotionRuntime } from '../motion/createSceneMotionRuntime.js';\nimport { getSceneClock } from './SceneClock.js';\nimport { getOceanWaterLevel } from '../../modules/ocean-water-level.js';\nimport { getTimelinePanel } from '../ui/TimelinePanel.js';\nimport { writeLastStartupLocation } from './StartupLocation.js';\nimport { registerSceneClockIntents } from '../agent/intents/scene-clock-intents.js';\nimport { seedBuiltinBasemaps } from '../imagery/builtin-basemaps.js';\nimport { restoreActive as restoreActiveBasemap, setActive as setActiveBasemap } from '../imagery/BasemapRegistry.js';\nimport { getBasemapPicker } from '../ui/BasemapPicker.js';\nimport { registerBasemapIntents } from '../agent/intents/basemap-intents.js';\nimport { getDrawSystem } from '../draw/DrawSystem.js';\nimport { getDrawSurfaceLayer } from '../draw/DrawSurfaceLayer.js';\nimport { DrawInteractionController } from '../draw/DrawInteractionController.js';\nimport { getDrawingProjectManager } from '../draw/DrawingProjectManager.js';\nimport { getDrawToolbar } from '../ui/DrawToolbar.js';\nimport { getMeasurementReadout } from '../ui/MeasurementReadout.js';\nimport { registerDrawingIntents } from '../agent/intents/drawing-intents.js';\nimport { getIsochroneOverlay } from '../overlays/IsochroneOverlay.js';\nimport { registerIsochroneIntents } from '../agent/intents/isochrone-intents.js';\nimport { registerAddressingIntents } from '../agent/intents/addressing-intents.js';\nimport { registerCollabIntents } from '../agent/intents/collab-intents.js';\nimport { registerOfflineIntents } from '../agent/intents/offline-intents.js';\nimport { registerIndoorIntents } from '../agent/intents/indoor-intents.js';\nimport { registerMarketplaceIntents } from '../agent/intents/marketplace-intents.js';\nimport { registerCaptureIntents } from '../agent/intents/capture-intents.js';\nimport { registerRasterIntents } from '../agent/intents/raster-intents.js';\nimport { registerBigDataIntents } from '../agent/intents/big-data-intents.js';\nimport { registerWeatherIntents } from '../agent/intents/weather-intents.js';\nimport { registerSatelliteIntents } from '../agent/intents/satellite-intents.js';\nimport { registerStacIntents } from '../agent/intents/stac-intents.js';\nimport { registerSunStudyIntents } from '../agent/intents/sun-study-intents.js';\nimport { registerSceneInfoIntents } from '../agent/intents/scene-info-intents.js';\nimport { registerMapMatchingIntents } from '../agent/intents/map-matching-intents.js';\nimport { registerTrafficIntents } from '../agent/intents/traffic-intents.js';\nimport { registerPhotogrammetryIntents } from '../agent/intents/photogrammetry-intents.js';\nimport { registerARIntents } from '../agent/intents/ar-intents.js';\nimport { registerStorefrontIntents } from '../agent/intents/storefront-intents.js';\nimport { registerTransitIntents } from '../agent/intents/transit-intents.js';\nimport { registerBlackSunIntents } from '../agent/intents/blacksun-intents.js';\nimport { registerEarthDaemonIntents } from '../agent/intents/earth-daemon-intents.js';\nimport { MetaverseScene, portSpawnPose } from './MetaverseScene.js';\nimport { showGraphicsUnavailableNotice } from '../ui/GraphicsStartupRecovery.js';\n\nlet photorealisticTileLoaderModulePromise = null;\nlet satelliteOverlayClassPromise = null;\nlet commsSystemClassPromise = null;\nlet openInfraMapRendererClassPromise = null;\n\nfunction normalizeUrlLon(lon) {\n    if (!Number.isFinite(lon)) return null;\n    let value = lon;\n    while (value < -180) value += 360;\n    while (value > 180) value -= 360;\n    return value;\n}\n\nfunction isBootOriginUrlLatLon(latLon) {\n    if (!latLon) return false;\n    return Math.abs(latLon.lat) < 0.001 && Math.abs(latLon.lon) < 0.05;\n}\n\nfunction parseUrlFloatParam(params, name) {\n    const raw = String(params.get(name) ?? '').trim();\n    if (!raw) return null;\n    const value = Number(raw);\n    return Number.isFinite(value) ? value : null;\n}\n\nfunction readUrlLatLonPair(params, latName, lonNames) {\n    const lat = parseUrlFloatParam(params, latName);\n    let lon = null;\n    for (const lonName of lonNames) {\n        lon = parseUrlFloatParam(params, lonName);\n        if (lon !== null) break;\n    }\n    if (lat === null || lon === null || lat < -90 || lat > 90) return null;\n    const normalizedLon = normalizeUrlLon(lon);\n    if (normalizedLon === null) return null;\n    return {\n        lat,\n        lon: normalizedLon\n    };\n}\n\nfunction resolveUrlLatLonParams(params) {\n    const canonical = readUrlLatLonPair(params, 'latitude', ['longitude']);\n    const aliases = readUrlLatLonPair(params, 'lat', ['lon', 'lng']);\n    if (canonical && aliases && isBootOriginUrlLatLon(canonical) && !isBootOriginUrlLatLon(aliases)) {\n        return aliases;\n    }\n    return canonical || aliases || null;\n}\n\nfunction loadPhotorealisticTileLoaderModule() {\n    if (!photorealisticTileLoaderModulePromise) {\n        photorealisticTileLoaderModulePromise = import('../tiles/PhotorealisticTileLoader.js');\n    }\n    return photorealisticTileLoaderModulePromise;\n}\n\nfunction loadSatelliteOverlayClass() {\n    if (!satelliteOverlayClassPromise) {\n        satelliteOverlayClassPromise = import('../overlays/SatelliteOverlay.js')\n            .then((module) => module.SatelliteOverlay);\n    }\n    return satelliteOverlayClassPromise;\n}\n\nfunction loadCommsSystemClass() {\n    if (!commsSystemClassPromise) {\n        commsSystemClassPromise = import('../comms/CommsSystem.js')\n            .then((module) => module.CommsSystem);\n    }\n    return commsSystemClassPromise;\n}\n\nfunction loadOpenInfraMapRendererClass() {\n    if (!openInfraMapRendererClassPromise) {\n        openInfraMapRendererClassPromise = import('../overlays/OpenInfraMapRenderer.js')\n            .then((module) => module.OpenInfraMapRenderer);\n    }\n    return openInfraMapRendererClassPromise;\n}\n\nconst DEFAULT_WIREFRAME_STYLE = {\n    surfaceColor: '#b8b8b8',\n    lineColor: '#15191f',\n    accent: '#ffffff',\n    accentSoft: '#ffffff',\n    accentStrong: '#ffffff',\n};\n\n/**\n * Building coverage repair performs its own bounded, footprint-local surface\n * validation. It only needs one renderable provider model; it must not wait\n * for the much stricter whole-view infrastructure handoff (queue drain,\n * screen error, and stability window), which may remain false throughout\n * continuous native 3D Tiles refinement.\n */\nexport function hasPhotorealBuildingProbeSurface(quality) {\n    return quality?.rootLoaded === true\n        && Number(quality.visibleCount) > 0\n        && Number(quality.loadedModelCount) > 0;\n}\n\nexport function resolveSurfaceBuildingViewshed({\n    aglM,\n    configuredRadiusM,\n    verticalFovDeg,\n    aspect,\n    isMobile = false,\n} = {}) {\n    const hardMaxM = isMobile ? 420 : 900;\n    const configuredMaxM = Number.isFinite(configuredRadiusM)\n        ? THREE.MathUtils.clamp(configuredRadiusM, 150, hardMaxM)\n        : hardMaxM;\n    const agl = Number.isFinite(aglM) ? Math.max(0, aglM) : 25;\n    const farRadiusM = THREE.MathUtils.clamp(250 + agl * 10, 200, configuredMaxM);\n    const nearRadiusM = THREE.MathUtils.clamp(75 + agl * 0.75, 75, 160);\n    const vFov = THREE.MathUtils.degToRad(\n        Number.isFinite(verticalFovDeg) ? verticalFovDeg : 60\n    );\n    const safeAspect = Number.isFinite(aspect) ? THREE.MathUtils.clamp(aspect, 0.4, 4) : 1.6;\n    const horizontalFovDeg = THREE.MathUtils.clamp(\n        THREE.MathUtils.radToDeg(2 * Math.atan(Math.tan(vFov * 0.5) * safeAspect)) + 20,\n        55,\n        145\n    );\n    return { farRadiusM, nearRadiusM, horizontalFovDeg };\n}\n\nexport class PlanetScene {\n    constructor(container, options = {}) {\n        this.container = container;\n        this.options = options;\n        this._presentationMode = ['orbital-header', 'earth-full'].includes(options?.presentation)\n            ? options.presentation\n            : '';\n\n        this.api = null;\n        this.eventBus = new EventBus();\n\n        this._sceneInitializer = null;\n        this._animationLoop = null;\n        this._lightingSystem = null;\n        this._moonSystem = null;\n        this._triTree = null;\n        this._elevationClient = null;\n        this._imageryManager = null;\n        this._sceneStateStore = null;\n        this._sceneStateRestorePromise = null;\n        this._checkpointInterval = null;\n        this._checkpointUnloadHandler = null;\n        this._checkpointVisibilityHandler = null;\n        this._checkpointPageHideHandler = null;\n        this._lastCheckpointAt = 0;\n        this._checkpointIntervalMs = 10000;\n        this._sessionId = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n        this._surfaceController = null;\n        this._scenePuppet = null;\n        this._eventManager = null;\n        this.uiController = null;\n        // View state management (migrated from UIController)\n        this._urlStateLast = '';\n        this._urlSyncEnabled = true;\n        this._urlViewState = null;\n        this._urlViewStateMode = null;\n        this._urlViewStateEnforceUntilMs = 0;\n        this._urlViewStateAttempts = 0;\n        this._urlViewStateMaxAttempts = 6;\n        this._urlViewStateApplying = false;\n        this._initializingViewState = false;\n        this._urlViewStateLeaseId = 0;\n        this._urlViewStateCompletionTimer = null;\n        this._urlViewStateWatchdogTimer = null;\n        this._urlSyncControls = null;\n        this._urlSyncCanvas = null;\n        this._urlSyncWheelHandler = null;\n        this._urlSyncTouchHandler = null;\n        this._debugViewStateLogging = false;\n        this._weatherSystem = null;\n        this._overlaySubsystem = null;\n        this._hydraOverlayIngress = null;\n        this._overlayRegistry = null;\n        this._buildingOverlay = null;\n        this._aircraftOverlay = null;\n        this._satelliteOverlay = null;\n        this._maritimeOverlay = null;\n        this._incidentOverlay = null;\n        this._trafficCameraOverlay = null;\n        this._roadTrafficOverlay = null;\n        this._sensorOverlay = null;\n        this._radioDataOverlay = null;\n        this._geocacheLayer = null;\n        this._meshtasticOverlay = null;\n        this._infrastructureOverlay = null;\n        this._celestialLabelPosition = new THREE.Vector3();\n        this._openInfraMapRenderer = null;\n        this._openInfraMapRendererPromise = null;\n        this._photoInfraSuppressed = false;\n        this._photoInfraQualityReady = false;\n        this._photoInfraResnapRequested = false;\n        this._photoInfraQuality = null;\n        this._photoAltitudeSuspended = false;\n        // Settings updates can arrive while the async photorealistic module\n        // and provider session are still loading. Keep that transition\n        // single-flight.\n        this._photoInitializationInFlight = false;\n        this._photoLifecycleGeneration = 0;\n        this._photoDeferredInitialization = false;\n        this._photoDeferredConfig = null;\n        const requestedMapMode = String(\n            options.mapMode\n            || (typeof window !== 'undefined'\n                ? (window.__noclipMapMode\n                    || new URLSearchParams(window.location.search || '').get('map'))\n                : '3d')\n            || '3d'\n        ).toLowerCase();\n        this._mapPresentationMode = requestedMapMode === '2d' ? '2d' : '3d';\n        this._photoMapModeDeferred = false;\n        this._photoMapModeDeferredConfig = null;\n        this._photoTileLoader = null;\n        this._photoSurfaceEntryPending = null;\n        this._photoSurfaceEntryPhase = null;\n        this._photoInitializationPresentationHold = false;\n        // The direct atmosphere shell is part of the initial scene, but the\n        // Takram compositor owns a second set of complex GPU programs. Live\n        // r185 traces showed those programs saturating ANGLE's compiler queue\n        // while the first photoreal models were being prepared; an otherwise\n        // ordinary GL_ACTIVE_UNIFORMS query then blocked the main thread for\n        // 18 seconds. Keep the compositor dormant through scene construction;\n        // the boot entry gate starts its cooperative warm-up only after the\n        // render loop is presenting frames behind the overlay. Do not collapse\n        // this distinction: disabling the direct shell breaks orbit.\n        this._interactiveBootComplete = false;\n        this._atmosphereCloudActivationTimer = null;\n        this._atmosphereCloudActivationIdleHandle = null;\n        this._atmosphereCloudActivationUsesIdleCallback = false;\n        this._atmosphereCloudActivationStablePasses = 0;\n        this._atmosphereCloudActivationWindowStartedAt = 0;\n        this._sceneEntryAtmospherePromise = null;\n        this._deferredMapDataStreamingReady = false;\n        this._deferredVisualStreamingReady = false;\n        this._budgetGovernor = null;\n        this._webglContextLostHandler = null;\n        this._overviewGlobe = null;\n        this._overviewDayTexture = null;\n        this._overviewImageSource = null;\n        this._overviewDayTexturePromise = null;\n        this._overviewDayTextureGeneration = 0;\n        this._overviewDayTextureUniform = { value: null };\n        this._overviewDayTextureEnabledUniform = { value: 0 };\n        this._hoverLabelHandle = null; // temporary label for hovered building\n        this._hoverLabelBuildingId = null;\n        this._lastBuildingHoverUpdateMs = 0;\n        this._buildingHoverUpdateIntervalMs = 50;\n        this._hoverBusinessKey = null;\n        this._pathTracker = null; // Motion path tracker (GPS + manual)\n        this._streamHub = null;\n        this._entitySystem = null;\n        this._presenceSystem = null;\n        this._assetSubsystem = null;\n        this._accessController = null;\n        this._audioSystem = null;\n        this._vrAccessGate = null;\n        this._vrAccessRevocationHandler = null;\n        this._commsSystem = null;\n        this._interopHarness = {\n            createdAt: Date.now(),\n            updatedAt: Date.now(),\n            stages: {\n                overlaySubsystemReady: false,\n                streamHubReady: false,\n                commsReady: false\n            },\n            counters: {\n                overlayApplied: 0,\n                overlayErrors: 0,\n                locationPackets: 0,\n                commsSamples: 0,\n                commsFailures: 0\n            },\n            last: {\n                overlayAppliedAt: 0,\n                overlayAckAt: 0,\n                overlayErrorAt: 0,\n                locationPacketAt: 0,\n                commsSampleAt: 0,\n                commsTransport: '',\n                commsConnected: false,\n                commsFailureAt: 0,\n                commsFailureCode: '',\n                commsFailureScope: '',\n                commsFallbackCount: 0,\n                commsTicketReplayRejected: 0,\n                commsRateLimitedCount: 0,\n                commsFraudBlockedCount: 0,\n                commsKillSwitchBlockedCount: 0\n            }\n        };\n        this._interopHarnessAckHandler = null;\n        this._interopHarnessAppliedHandler = null;\n        this._interopHarnessCommsFailureHandler = null;\n        this._interopHarnessStatsInterval = null;\n        this._renderer = null;\n        this._scene = null;\n        this._camera = null;\n        this._controls = null;\n        this._audioListener = null;\n        this._audioUnlockHandlers = null;\n        this._audioUnlocked = false;\n        this._audioEnabledSetting = true;\n        this._earthAudioAnchor = null;\n        this._motionTracker = null;\n        this._audioTestHandle = null;\n        this._audioTestActive = false;\n        this._windAudio = null;\n        this._rainSystem = null;\n        this._sceneWeatherState = null;\n        this._weatherCoordinates = {};\n        this._weatherWorldPosition = new THREE.Vector3();\n        this._weatherLocalPosition = new THREE.Vector3();\n        this._windModulation = { gustiness: 0, worldDirection: new THREE.Vector3() };\n        this._windSettings = {\n            enabled: true,\n            volume: 0.2,\n            gustiness: 0.55,\n            mass: 0.6,\n            speedScale: 1,\n            maxSpeedMps: 70,\n            minSpeedMps: 0,\n            verticalScale: 1\n        };\n        this._speakSettings = {\n            enabled: false,\n            mode: 'push_to_talk',\n            pushToTalkKey: 'KeyV',\n            radiusM: 35\n        };\n        this._windPrevPos = new THREE.Vector3();\n        this._windHasPrev = false;\n        this._windTmpVec = new THREE.Vector3();\n        this._windTmpVecB = new THREE.Vector3();\n        this._windTmpVecC = new THREE.Vector3();\n        this._windTmpQuat = new THREE.Quaternion();\n        this._windTmpQuatB = new THREE.Quaternion();\n        this._windTmpVecD = new THREE.Vector3();\n        this._windTmpVecE = new THREE.Vector3();\n        this._windTmpVecF = new THREE.Vector3();\n        this._geoJsonLayer = null;\n        this._geoJsonLookupLayer = null;\n        this._geoJsonAdminLevel = 0;\n        this._geoJsonCountry = null;\n        this._geoJsonManualSource = null;\n        this._geoJsonAutoDepth = false;\n        this._geoJsonMaxAdminLevel = 3;\n        this._geoJsonFarMaxAdminLevelAltM = 12_000_000;\n        this._geoJsonFarMaxAdminLevel = 0;\n        // Graduated admin-border LOD: at altitude, only load coarse (low-ADM)\n        // borders; finer subdivisions load as the camera approaches. Loading all\n        // ADM levels everywhere is a major geojson memory sink. Bands are altitude\n        // (m MSL) → max ADM level; first matching (descending) band wins, else full\n        // depth (_geoJsonMaxAdminLevel). Governor memory pressure shifts one level\n        // coarser (see _resolveGeoJsonAltitudeMaxLevel).\n        this._geoJsonAdminAltBandsM = [\n            { altM: 2_500_000, level: 0 }, // > 2500 km: countries only\n            { altM:   600_000, level: 1 }, // > 600 km: + ADM1 (states/provinces)\n            { altM:   120_000, level: 2 }, // > 120 km: + ADM2 (counties)\n        ];\n        this._geoJsonAltitudeMaxAdminLevel = null;\n        this._geoJsonAltitudeOverrideActive = false;\n        this._geoJsonAltTmp = new THREE.Vector3();\n        this._geoJsonLabelScaleCapAltM = 3_000_000;\n        this._geoJsonLabelScaleReleaseAltM = 12_000_000;\n        this._geoJsonLabelBorderRetireAltM = 3_000_000;\n        this._geoJsonAutoLayers = new Map();\n        this._geoJsonAutoState = { iso3: null, maxLevel: 0, levels: [] };\n        this._geoJsonAutoSeq = 0;\n        this._geoJsonRenderMode = 'orbit';\n        this._geoJsonConflictDisposition = null;\n        this._geoJsonConflictMapState = null;\n        this._geoJsonRelationshipResolver = (feature) => this._resolveGeoJsonRelationshipColor(feature);\n        this._wireframeActive = false;\n        this._wireframePrevImagery = null;\n        this._wireframePrevGeoJson = null;\n        this._wireframeStyle = null;\n        this._wireframeStyleResolved = null;\n        this._raycastLinePrecision = null;\n        this._geoBoundaryService = null;\n        this._sceneSettings = null;\n        this.settings = null;\n        this.uiController = null;\n        this._overlayGeoContext = null;\n        this._overlayGeoContextTs = 0;\n        this._navGeoContext = null;\n        this._navGeoContextTs = 0;\n        this._navGeoPending = false;\n        this._navGeoInFlight = false;\n        this._navGeoSeq = 0;\n        this._navGeoInfo = null;\n        this._navGeoPollIntervalMs = 1500;\n        this._navGeoPollDeltaDeg = 0.1;\n        this._vrManager = null;\n        this._mobileStereoRenderer = null;\n        this._localPlayer = null;\n        this._motionRuntime = null;\n        this._motionPreviewSignatures = new Map();\n        this._peerManager = null;\n        this._avatarConfig = {};\n        this._avatarInitializationPromise = null;\n        this._overviewGlobeMode = true;\n        // Building auto-injection tracking\n        this._buildingAutoEnabled = false;\n        this._buildingAutoCenter = null;\n        this._buildingAutoHeadingDeg = null;\n        this._buildingAutoRequestKey = null;\n        this._buildingAutoRequestSeq = 0;\n        this._buildingAutoTs = 0;\n        this._buildingAutoPollIntervalMs = 750;\n        this._buildingAutoMinMoveM = 75;\n        this._buildingAutoElevationWaitMs = 1500;\n        this._buildingAutoElevationWaitUntil = 0;\n        this._buildingAutoElevationWaitStart = 0;\n        // Aircraft auto-injection tracking\n        this._aircraftAutoEnabled = false;\n        this._aircraftAutoCenter = null;\n        this._aircraftAutoTs = 0;\n        this._aircraftAutoPollIntervalMs = 2000;\n        this._aircraftAutoMinMoveM = 250;\n        this._aircraftAutoConfig = null;\n        // Satellite auto-injection tracking\n        this._satelliteAutoEnabled = false;\n        this._satelliteAutoCenter = null;\n        this._satelliteAutoTs = 0;\n        this._satelliteAutoPollIntervalMs = 2000;\n        this._satelliteAutoMinMoveM = 250;\n        this._satelliteAutoConfig = null;\n        this._radioDataAutoEnabled = false;\n        this._radioDataAutoCenter = null;\n        this._radioDataAutoCountry = '';\n        this._radioDataAutoTs = 0;\n        this._radioDataAutoPollIntervalMs = 60_000;\n        this._radioDataAutoMinMoveM = 25_000;\n        this._radioDataConfig = null;\n        this._geocacheAutoEnabled = false;\n        this._geocacheAutoCenter = null;\n        this._geocacheAutoTs = 0;\n        this._geocacheAutoPollIntervalMs = 300_000;\n        this._geocacheAutoMinMoveM = 5_000;\n        this._geocacheConfig = null;\n        // Maritime auto-injection tracking\n        this._maritimeAutoEnabled = false;\n        this._maritimeAutoCenter = null;\n        this._maritimeAutoTs = 0;\n        this._maritimeAutoPollIntervalMs = 2000;\n        this._maritimeAutoMinMoveM = 250;\n        this._maritimeAutoConfig = null;\n        // Incident auto-injection tracking\n        this._incidentAutoEnabled = false;\n        this._incidentAutoCenter = null;\n        this._incidentAutoTs = 0;\n        this._incidentAutoPollIntervalMs = 2000;\n        this._incidentAutoMinMoveM = 250;\n        this._incidentAutoConfig = null;\n        // Infrastructure auto-injection tracking\n        this._infrastructureAutoEnabled = true;\n        this._infrastructureAutoCenter = null;\n        this._infrastructureAutoTs = 0;\n        this._infrastructureAutoPollIntervalMs = 2000;\n        this._infrastructureAutoMinMoveM = 100;\n        this._infrastructureAutoElevationWaitUntil = 0;\n        this._infrastructureAutoElevationWaitStart = 0;\n        this._tmpElevationDir = new THREE.Vector3();\n        this._worldRoot = null;\n        this._cameraExclusiveState = null;\n        this._cameraExclusiveSequence = 0;\n        // Black Sun framework (Phase 1) — scene-mode flag. 'earth' is the\n        // default photoreal-tile globe; 'metaverse' is the Snow Crash black\n        // sphere with Street and (eventually) Black Sun. See\n        // .aiwg/blacksun/08-noclip-implementation.md §8.2 phase 1.\n        this._sceneMode = 'earth';\n        this._metaverseScene = null;\n        this._metaversePort = 0;\n        this._metaverseSavedBackground = null;\n        // Elevation localStorage properties removed — now unified in SceneStateStore\n        this._viewshedUpdateIntervalMs = 350;\n        this._viewshedLastUpdate = 0;\n        this._viewshedMaxItems = 8;\n        this._viewshedFrustum = new THREE.Frustum();\n        this._viewshedMatrix = new THREE.Matrix4();\n        this._viewshedTmpVec = new THREE.Vector3();\n        this._viewshedCameraPos = new THREE.Vector3();\n        this._viewshedHighlight = null;\n        this._viewshedHighlightGroup = null;\n        this._viewshedHighlightRings = null;\n        this._viewshedHighlightTmpPos = new THREE.Vector3();\n        this._viewshedHighlightTmpDir = new THREE.Vector3();\n        this._viewshedHighlightTmpQuat = new THREE.Quaternion();\n        this._viewshedHighlightTmpCam = new THREE.Vector3();\n        this._viewshedHighlightTmpCenter = new THREE.Vector3();\n        this._agentViewshedTmpPos = new THREE.Vector3();\n\n        this._tilesPendingNormals = new Set();\n        this._perf = new PerformanceMonitor();\n        this._browserPerformanceTelemetry = null;\n        this._perfStart = (name) => this._perf.start(name);\n        this._perfEnd = (name) => this._perf.end(name);\n        this._updateDebugPanel = () => this._perf.updateDebugPanel();\n        this._isMobile = null;\n        this._mobileTaskLastRun = new Map();\n        this._mobileOverlayBudgetSignature = null;\n        this._mobileSurfaceOverlayInSurface = false;\n        this._mobileSurfaceOverlayEnterTs = 0;\n        this._mobileBuildingBootstrapDelayMs = 0;\n        this._mobileInfrastructureBootstrapDelayMs = 0;\n        this._mobileInfrastructureAfterBuildingsDelayMs = 0;\n    }\n\n    /** Continue the same application without constructing any GPU resources. */\n    async initMapOnly({ failures = [], location = null } = {}) {\n        this.graphicsUnavailable = true;\n        this.graphicsFailures = failures;\n        this._sceneSettings = new SceneSettings({ url: '/refactor/data/settings/default.json' });\n        await this._sceneSettings.load();\n        this.settings = this._sceneSettings;\n        this._routeStore = getRouteStore({ eventBus: this.eventBus });\n        globalThis.__noclipRouteStore = this._routeStore;\n        this._routeProgressTracker = new RouteProgressTracker({ store: this._routeStore });\n        seedBuiltinBasemaps();\n        if (!restoreActiveBasemap()) setActiveBasemap('carto-dark');\n        if (Number.isFinite(location?.lat) && Number.isFinite(location?.lon)) {\n            getHudInfoStore().setData('nav.lat', location.lat);\n            getHudInfoStore().setData('nav.lon', location.lon);\n        }\n        this.api = this._buildApi();\n        this.setMapPresentationMode('2d');\n        this.eventBus.emit('scene:ready', { time: Date.now(), presentation: '2d', graphics: false });\n    }\n\n    canEnter3D({ notify = true } = {}) {\n        if (!this.graphicsUnavailable) return true;\n        if (notify) void showGraphicsUnavailableNotice();\n        return false;\n    }\n\n    async init() {\n        try {\n            this._isMobile = this._detectMobile();\n            // Apply the device-appropriate label registry cap early. This bounds\n            // per-label GPU/DOM memory; this alone does not identify the phone's\n            // process-termination cause. Mobile gets\n            // a tight cap + viewshed, desktop stays generous. Idempotent and safe\n            // even if an overlay created the label singleton first.\n            try {\n                getLabelSystem({ planetRadius: PLANET_RADIUS, isMobile: this._isMobile }).setMobile(this._isMobile);\n                if (typeof window !== 'undefined') {\n                    window.__noclipLabelSystem = getLabelSystem(); // in-view search uses the scene's instance\n                    window.__noclipLabelStats = () => { try { return getLabelSystem().getMemoryStats(); } catch { return null; } };\n                    // On-device memory profiler: call __noclipMemReport() in the\n                    // phone/browser console to see which subsystem dominates heap/\n                    // GPU estimates (labels vs photoreal tiles vs geometry).\n                    // Software-WebGL probes can load real photoreal content but\n                    // do not establish physical iPhone memory or thermal limits.\n                    // Reload-surviving diagnostics avoid crash-time capture.\n                    window.__noclipMemReport = () => {\n                        const r = {};\n                        try { const m = performance.memory; if (m) r.heapMB = +(m.usedJSHeapSize / 1048576).toFixed(1); } catch {}\n                        try {\n                            const info = this._renderer?.info;\n                            if (info) r.gpu = {\n                                geometries: info.memory?.geometries, textures: info.memory?.textures,\n                                programs: info.programs?.length, triangles: info.render?.triangles, calls: info.render?.calls,\n                            };\n                        } catch {}\n                        try { r.labels = getLabelSystem().getMemoryStats(); } catch {}\n                        try {\n                            const tb = this._photoTileLoader?._getTileCacheBytes?.();\n                            if (tb) r.tilesMB = {\n                                data: +((tb.dataBytes || 0) / 1048576).toFixed(1),\n                                gpu: +((tb.gpuBytes || 0) / 1048576).toFixed(1),\n                                used: +((tb.bytesUsed || 0) / 1048576).toFixed(1),\n                            };\n                            r.loadedModels = this._photoTileLoader?._loadedModelCount;\n                        } catch {}\n                        try {\n                            const elevation = this._elevationClient?.getStats?.();\n                            if (elevation) r.elevation = {\n                                records: elevation.totalVertices,\n                                maxRecords: this._elevationClient?.maxVertexRecords,\n                                pendingBatches: elevation.currentBatches,\n                                persistentQueue: elevation.persistentQueuePending,\n                            };\n                            const terrain = this._triTree?.debugStats;\n                            if (terrain) r.terrain = {\n                                tiles: terrain.tileCount,\n                                retiredSets: terrain.retiredTilesSets,\n                                retiredTiles: terrain.retiredTileCount,\n                                retirementCap: terrain.retirementMaxTiles,\n                            };\n                        } catch {}\n                        try {\n                            r.buildings = {\n                                entries: this._buildingOverlay?._entryMap?.size || 0,\n                                instances: this._buildingOverlay?._instances?.length || 0,\n                            };\n                        } catch {}\n                        return r;\n                    };\n                }\n            } catch { /* label system optional */ }\n            setTilesPendingNormals(this._tilesPendingNormals);\n\n            // Initialize AsyncHarness before any subsystem that might want to\n            // use frameClock / BudgetScheduler / workers / hover dispatch.\n            // Safe to call multiple times — returns existing singleton.\n            // Imported statically at file top; see refactor/async/README.md.\n            initAsyncHarness({ enableDebugGlobals: true });\n\n            window.bootLog?.('initializing Three.js renderer + scene');\n            this._sceneInitializer = new SceneInitializer(this.container, {\n                // Earth materials start the shared physical clear atmosphere.\n                // Optional cloud targets/variants remain deferred until entry.\n                atmosphereCloudStreamingEnabled: false,\n                // PMREM generation decodes an HDR texture and compiles another\n                // shader family. It is released with the optional visual stack\n                // after the first photoreal view has drained.\n                environmentStreamingEnabled: false,\n            });\n            this._sceneInitializer.getPhotorealTileLoader = () => this._photoTileLoader;\n            this._sceneInitializer.getOverviewGlobe = () => this._overviewGlobe;\n            // Default startup is a globe overview. Keep expensive 8K overlay\n            // textures out of memory until a local view replaces the fallback.\n            this._sceneInitializer.setEarthOverlayStreamingEnabled?.(false);\n            this._sceneInitializer.setPerformanceMonitor?.(this._perf);\n            const components = this._sceneInitializer.getComponents();\n            this._renderer = components.renderer;\n            this._xrDiagnostics = new XRDiagnostics({ scene: this });\n            window.__noclipXRDiagnostics = this._xrDiagnostics;\n            this._scene = components.scene;\n            this._camera = components.camera;\n            this._controls = components.controls;\n            this._lightingSystem = components.lightingSystem;\n            this._moonSystem = components.moonSystem;\n            this._worldRoot = new THREE.Group();\n            this._worldRoot.name = 'WorldRoot';\n            this._scene.add(this._worldRoot);\n            if (this._camera) {\n                // Preserve the camera-in-vrDolly hierarchy that scene-\n                // initializer set up (camera is a child of vrDolly so\n                // WebXR's headset pose lives in the dolly's local frame).\n                // Reparenting the camera here would orphan vrDolly —\n                // moving the dolly would no longer move the camera, and\n                // the XR session would render with the camera attached\n                // to _worldRoot at scene origin (= user spawning at\n                // 0,0,0 instead of on the planet surface). Move the\n                // ENTIRE dolly into _worldRoot so the rig keeps its\n                // camera child intact.\n                const dolly = this._sceneInitializer?.vrDolly;\n                if (dolly) {\n                    this._worldRoot.add(dolly);\n                } else {\n                    this._worldRoot.add(this._camera);\n                }\n            }\n            if (this._moonSystem?.moonMesh) {\n                this._worldRoot.add(this._moonSystem.moonMesh);\n            }\n            this._sceneInitializer?.setWorldRoot?.(this._worldRoot);\n            this._audioListener = new THREE.AudioListener();\n            this._camera.add(this._audioListener);\n\n            window.bootLog?.('initializing elevation client + terrain data');\n            this._elevationClient = new ElevationClient();\n            // Keep startup import bounded to avoid long main-thread stalls; snapshot/key warmup\n            // handles immediate local recall with higher precision for the current area.\n            this._elevationClient.persistentStartupImportMaxEntries = this._isMobile ? 4_000 : 28_000;\n            this._elevationClient.persistentNearbyImportBucketRadius = this._isMobile ? 2 : 3;\n            this._elevationClient.persistentNearbyImportMaxEntries = this._isMobile ? 8_000 : 70_000;\n            // Keep elevation cache active so reloads can recall recent terrain data.\n            this._elevationClient.setCacheEnabled(true);\n            this._elevationClient.setPersistentCacheEnabled(true);\n            // Restore the persistent elevation cache in the BACKGROUND\n            // rather than awaiting it inline. The startup-import path\n            // can pull up to 28k entries (desktop) or 12k (mobile)\n            // from IndexedDB, which can take a noticeable fraction of\n            // a second on cold devices and was visible to users as\n            // a stuck terrain-anchor boot stage.\n            // Fire-and-forget; the elevation client's per-query path\n            // works without the bulk import (it just falls through to\n            // remote fetches until the import completes).\n            this._restoreElevationCache().catch((err) => {\n                console.warn('[PlanetScene] elevation cache restore (background) failed:', err);\n            });\n            this._imageryManager = new ImageryManager();\n            window.bootLog?.('initializing terrain scene graph');\n            this._triTree = new TriTreeManager(\n                this._scene,\n                this._elevationClient,\n                this._imageryManager,\n                PLANET_RADIUS\n            );\n            // Default terrain source is Cesium photorealistic tiles. Keep the\n            // TriTree group as the planet anchor, but do not let its LOD/imagery\n            // pipeline start before scene settings have a chance to confirm mode.\n            this._setTriTreePhotorealSuppressed(true);\n            this._triTree.setPerformanceMonitor(this._perf);\n            if (this._worldRoot) {\n                this._worldRoot.add(this._triTree.group);\n            }\n            this._earthAudioAnchor = new THREE.Object3D();\n            this._earthAudioAnchor.name = 'EarthAudioAnchor';\n            this._triTree.group.add(this._earthAudioAnchor);\n\n            if (this._isMobile) {\n                this._applyMobileProfile();\n            }\n\n            this._elevationClient.planetGroup = this._triTree.group;\n            if (this._sceneInitializer?.setPlanetGroup) {\n                this._sceneInitializer.setPlanetGroup(this._triTree.group);\n            }\n            getBusinessLabels({\n                planetRadius: PLANET_RADIUS,\n                eventBus: this.eventBus,\n                parentGroup: this._triTree.group,\n                planetGroup: this._triTree.group,\n                mobile: this._isMobile\n            }).setEnabled?.(false);\n            // Navigation stack — route store + progress tracker + 3D ribbon.\n            this._routeStore = getRouteStore({ eventBus: this.eventBus });\n            globalThis.__noclipRouteStore = this._routeStore;\n            this._roadContext = new RoadContextService({\n                onUpdate: (context) => {\n                    const hudStore = getHudInfoStore();\n                    const fallback = context?.ref || context?.subclass || context?.class || '';\n                    const label = context?.name || fallback;\n                    hudStore?.setValue?.('nav.road', label || '--');\n                    hudStore?.setValue?.('nav.roadClass', context?.subclass || context?.class || '--');\n                    hudStore?.setValue?.(\n                        'nav.roadDistance',\n                        Number.isFinite(context?.distanceM) ? `${context.distanceM.toFixed(1)} m` : '--',\n                    );\n                    hudStore?.setData?.('nav.road', context || null);\n                    hudStore?.setData?.('nav.roadClass', context?.subclass || context?.class || null);\n                    hudStore?.setData?.('nav.roadDistance', context?.distanceM ?? null);\n                },\n                onSoundscapeUpdate: (roads, habitat) => {\n                    this._audioSystem?.setRoadSoundSources?.(roads);\n                    this._audioSystem?.setHabitatSoundContext?.(habitat);\n                },\n            });\n            globalThis.__noclipRoadContext = this._roadContext;\n            // SceneClock — single canonical timeline (WO-002). Exposed on\n            // window so lighting-system + future temporal overlays can read\n            // it without a tight import dependency.\n            this._sceneClock = getSceneClock();\n            globalThis.window.__noclipSceneClock = this._sceneClock;\n            // Expose the scene reference globally so the floating chat\n            // button (and any other detached UI) can dispatch agent\n            // commands via AgentCommandProcessor without walking the\n            // tree to find us.\n            globalThis.window.__noclipScene = this;\n            // One-liner performance RCA for the live browser (where jank\n            // actually reproduces). Usage in DevTools console:\n            //   __noclipPerf()      → enables instrumentation (first call)\n            //   …move around a few seconds…\n            //   __noclipPerf()      → prints CPU/GPU/render-pipeline breakdown\n            //   __noclipPerf(false) → disables instrumentation (zero overhead)\n            // The report flags CPU-bound vs GPU-bound and ranks every\n            // perf bucket (gpu.depth.render, gpu.main.render, cpu.lod.update,\n            // elevation.*, normals, …) so the dominant cost is unambiguous.\n            globalThis.window.__noclipPerf = (enable) => {\n                const perf = this._perf;\n                if (!perf) return 'perf monitor unavailable';\n                if (enable === false) { perf.disable(); return 'perf disabled (zero overhead)'; }\n                if (!perf.enabled) {\n                    perf.enable();\n                    perf.logHeavyFrames = true;\n                    perf.sections = {};\n                    return 'perf ENABLED — move around for a few seconds, then call __noclipPerf() again to read the report';\n                }\n                const snap = perf.getSnapshot();\n                console.log(snap);\n                try {\n                    const info = this._sceneInitializer?.renderer?.info?.render;\n                    if (info) console.log(`draw calls: ${info.calls} | triangles: ${(info.triangles / 1000).toFixed(0)}k | lines: ${info.lines}`);\n                } catch { /* ignore */ }\n                return snap;\n            };\n            // Expose the agent IntentRegistry on window so tests + the\n            // chat panel can dispatch intents without re-resolving the\n            // Vite-bundled module path. This is the same registry that\n            // the LLM tool-call pipeline uses; calling dispatchIntent\n            // here exercises the production code path.\n            try {\n                const reg = await import('../agent/IntentRegistry.js');\n                globalThis.window.__noclipAgent = {\n                    dispatchIntent: (command) => reg.dispatchIntent(command, {\n                        sceneApi: this.api,\n                        eventBus: this.eventBus,\n                    }),\n                    listIntents: () => reg.listIntents(),\n                    getIntent: (name) => reg.getIntent(name),\n                    generateToolSpec: (opts) => reg.generateToolSpec(opts),\n                };\n            } catch (err) {\n                console.warn('[PlanetScene] __noclipAgent expose skipped', err);\n            }\n            registerSceneClockIntents();\n            // TimelinePanel and BasemapPicker no longer auto-mount as\n            // floating fixed-position elements — that produced overlap\n            // with the mobile dock and visual fragmentation on desktop.\n            // We construct the singletons here (so registry/intent\n            // wiring still runs at scene init) but leave the embedded\n            // panel elements unmounted; HudManager places them inside\n            // the HUD dock (phones) and LeftSidebar (desktop/tablet).\n            this._timelinePanel = getTimelinePanel();\n            // Basemap registry (WO-003): seed builtins, restore active\n            // from localStorage, build the picker singleton, register\n            // agent intents.\n            seedBuiltinBasemaps();\n            if (!restoreActiveBasemap()) setActiveBasemap('carto-dark');\n            this._basemapPicker = getBasemapPicker();\n            registerBasemapIntents();\n            // WO-004 drawing tools — DrawSystem singleton + 3D surface layer\n            // attached to triTree.group; toolbar + measurement readout\n            // mount to document.body (HUD-overlay).\n            this._drawSurfaceLayer = getDrawSurfaceLayer({ getDrawSystem });\n            if (this._drawSurfaceLayer?.group) this._triTree.group.add(this._drawSurfaceLayer.group);\n            // DrawToolbar no longer auto-mounts as a mid-left floating\n            // panel — that conflicted with the dock buttons on phones\n            // and with the LeftSidebar on desktop. The singleton is\n            // still built here (so DrawSystem wires up + keyboard\n            // shortcuts bind) but its element waits for HudManager to\n            // place it inside the dock or sidebar.\n            this._drawToolbar = getDrawToolbar();\n            this._measurementReadout = getMeasurementReadout({ container: document.body });\n            registerDrawingIntents();\n            // WO-001 isochrone overlay — surface-following polygons\n            // listening for noclip:isochrone:set / cleared.\n            this._isochroneOverlay = getIsochroneOverlay({\n                parentGroup: this._triTree.group,\n                eventBus: this.eventBus,\n            });\n            registerIsochroneIntents();\n            // WO-005 alternative-addressing intents (handler is server-proxied).\n            registerAddressingIntents();\n            // WO-006..026 — lazy-loaded intent registration. Each call is\n            // idempotent (guarded by module-level _registered flag) and\n            // brings in its own UI + client via dynamic import when the\n            // intent is first dispatched.\n            try {\n                registerCollabIntents();\n                registerOfflineIntents();\n                registerIndoorIntents();\n                registerMarketplaceIntents();\n                registerCaptureIntents();\n                registerRasterIntents();\n                registerBigDataIntents();\n                registerWeatherIntents();\n                registerSatelliteIntents();\n                registerStacIntents();\n                registerSunStudyIntents();\n                // Raw scene-debug mutations are compiled out of ordinary\n                // production builds. The separately gated engineering entry\n                // point registers them only after capability verification.\n                registerSceneInfoIntents();\n                registerMapMatchingIntents();\n                registerTrafficIntents();\n                registerPhotogrammetryIntents();\n                registerARIntents();\n                registerStorefrontIntents();\n                registerTransitIntents();\n                registerBlackSunIntents();\n                registerEarthDaemonIntents();\n            } catch (err) {\n                console.warn('[PlanetScene] intent registration partial failure', err);\n            }\n            // WO-020 — attach AR session to the live renderer/camera/scene\n            // and mount a minimal HUD so users have a visible entry point.\n            // The session gracefully falls back to magic-window on iOS.\n            try {\n                Promise.all([\n                    import('../ar/ARSession.js'),\n                    import('../ar/ARHud.js'),\n                ]).then(([{ getARSession }, { getARHud }]) => {\n                    const session = getARSession({ renderer: this._renderer, scene: this._scene, camera: this._camera });\n                    // ARHud now defaults to embedded mode — no floating\n                    // top-right pill. The singleton holds session\n                    // subscription state; HudManager owns the dock\n                    // button surface that triggers toggle().\n                    this._arHud = getARHud({ session });\n                    // Notify HudManager so it can attach its dock\n                    // button to the freshly-built ARHud controller.\n                    try {\n                        const ev = new CustomEvent('noclip:ar:available', { detail: { arHud: this._arHud } });\n                        window.dispatchEvent(ev);\n                    } catch { /* ignore */ }\n                }).catch(() => { /* AR is optional — silently skip if import fails */ });\n            } catch (err) {\n                console.warn('[PlanetScene] AR mount skipped', err);\n            }\n            // Mount the agent chat button (bottom-right pill) — a quick\n            // chat surface that posts to /agent/chat (or the open-agents\n            // client once wired) and dispatches replies back to the\n            // command processor for in-scene intent execution.\n            try {\n                import('../ui/AgentChatButton.js').then((m) => {\n                    m.getAgentChatButton?.({ /* commandProcessor injected later */ });\n                }).catch(() => {});\n            } catch (err) {\n                console.warn('[PlanetScene] Agent chat mount skipped', err);\n            }\n            this._routeProgressTracker = new RouteProgressTracker({ store: this._routeStore });\n            this._placeSearchSurface = new PlaceSearchSurfaceLayer({ parentGroup: this._triTree.group,\n                surfaceController: this._surfaceController, labels: getLabelSystem(), routes: this._routeStore });\n            this._routeRibbon = getRouteRibbonRenderer({\n                parentGroup: this._triTree.group,\n                eventBus: this.eventBus,\n                // Give the ribbon a handle to the tritree so its drape\n                // loop can sample real surface radii (photoreal tile\n                // raycast first, then tritree elevation mesh) instead of\n                // defaulting to the bare ellipsoid — which was visibly\n                // floating ~35m in the air over photoreal cities.\n                triTree: this._triTree,\n                surfaceController: this._surfaceController,\n            });\n            // HUD panels for destination entry + turn-by-turn banner. Both are\n            // detached from the scene lifecycle — they bind to RouteStore\n            // events directly.\n            this._directionsPanel = getDirectionsPanel({\n                container: document.body,\n                getPlayerLatLon: () => this._currentPlayerLatLon(),\n            });\n            this._navBanner = getNavBanner({ container: document.body });\n            // Expose an opener for the HUD search row.\n            if (typeof window !== 'undefined') {\n                window.__noclipDirections = {\n                    open: () => this._directionsPanel?.open?.(),\n                    close: () => this._directionsPanel?.close?.(),\n                    toggle: () => this._directionsPanel?.toggle?.(),\n                    isVisible: () => !!this._directionsPanel?.isVisible?.(),\n                    setMode: (mode) => this._directionsPanel?.setMode?.(mode),\n                    getMode: () => this._directionsPanel?.getMode?.(),\n                    hasDestination: () => !!this._directionsPanel?.hasDestination?.(),\n                    isRouting: () => !!this._directionsPanel?.isRouting?.(),\n                    go: () => this._directionsPanel?.go?.(),\n                    cancelRoute: () => this._directionsPanel?.cancelRoute?.(),\n                    // Programmatic destination set (used by the agent's\n                    // navigate_to intent so it doesn't have to mimic a\n                    // user typing into the search bar).\n                    setDestination: ({ lat, lon, name, address } = {}) => {\n                        if (!this._directionsPanel) return false;\n                        if (!Number.isFinite(lat) || !Number.isFinite(lon)) return false;\n                        return this._directionsPanel.setDestinationDirect?.({ lat, lon, name, address });\n                    },\n                };\n            }\n            this._lastRouteUpdateMs = 0;\n\n            // All geojson borders rendered in teal so they share a\n            // single visual identity and stay out of the orange accent\n            // lane (which belongs to selection / route / highlight).\n            const geoJsonBorderColor = 0x14b8a6;\n            // Remembered as the fallback for borders that do not have a\n            // relationship/category color of their own. Terrain style never\n            // takes ownership of cartographic border color.\n            this._geoJsonThemeColor = geoJsonBorderColor;\n            this._geoJsonLayer = new GeoJsonLayer({\n                parentGroup: this._triTree.group,\n                planetRadius: PLANET_RADIUS,\n                url: '/refactor/data/geojson/world.geojson',\n                color: geoJsonBorderColor,\n                sceneInitializer: this._sceneInitializer,\n                deferUntilInteractive: true,\n            });\n            this._geoJsonLookupLayer = null;\n            this._geoBoundaryService = new GeoBoundaryService();\n            const autoLevels = [1, 2, 3];\n            // Border opacity halved again — boundaries are a ghost\n            // reference now (5% / 3.5% / 2.5%), so the wireframe\n            // tile palette stays the dominant read. Higher-level\n            // (more granular) admin lines fade fastest.\n            const autoOpacity = { 1: 0.05, 2: 0.035, 3: 0.025 };\n            const geoJsonColor = geoJsonBorderColor;\n            autoLevels.forEach((level) => {\n                const liftMeters = 12000 + (level - 1) * 1500;\n                const layer = new GeoJsonLayer({\n                    parentGroup: this._triTree.group,\n                    planetRadius: PLANET_RADIUS,\n                    color: geoJsonColor,\n                    opacity: autoOpacity[level] ?? 0.7,\n                    liftMeters,\n                    sceneInitializer: this._sceneInitializer,\n                    deferUntilInteractive: true,\n                });\n                layer.group.visible = false;\n                this._geoJsonAutoLayers.set(level, layer);\n            });\n\n            window.bootLog?.('loading scene settings');\n            this._sceneSettings = new SceneSettings({\n                url: '/refactor/data/settings/default.json',\n                applyScene: (sceneSettings) => this._applyTuneables(sceneSettings),\n                normalizeScene: (sceneSettings, current) => this._normalizeScenePatch(sceneSettings, current)\n            });\n            await this._sceneSettings.load();\n\n            // Pre-position camera from saved view state BEFORE applying settings.\n            // This ensures that when photorealistic tiles initialise (triggered by\n            // _applyTuneables → _handlePhotorealisticToggle), the camera is already\n            // at the user's last position so tile requests target the correct area.\n            this._prePositionCameraFromSavedState();\n\n            this._sceneSettings.apply();\n            this.settings = this._sceneSettings;\n            this._sceneStateStore = getSceneStateStore();\n\n            this._surfaceController = new SurfaceController(\n                this._camera,\n                this._renderer,\n                this._controls,\n                this._triTree\n            );\n            this._sceneInitializer.setXRSurfaceController(this._surfaceController);\n            // DOM overlays pinned into the scene (theater players) hide behind\n            // photoreal hills/buildings via this probe (refactor/render/SceneOcclusion.js).\n            setSceneOcclusionProbe({\n                isOccluded: (from, to) => this._surfaceController?.isPhotorealSegmentOccluded?.(from, to) === true,\n                prepareFrame: () => this._surfaceController?.preparePhotorealAcousticSampling?.(),\n            });\n            this._sceneInitializer.setXRSessionStartCallback(() => this._beginNativeCloudPreference());\n            this._sceneInitializer.setXRSessionEndCallback(() => this._endNativeCloudPreference());\n            this._drawSurfaceLayer?.setSurfaceController?.(this._surfaceController);\n            this._drawInteractionController = new DrawInteractionController({\n                scene: this,\n                system: getDrawSystem(),\n            });\n            if (!this._presentationMode) {\n                this._drawingProjectManager = getDrawingProjectManager();\n                void this._drawingProjectManager.start().catch((error) => {\n                    console.warn('[DrawingProjects] Initialization failed:', error);\n                });\n            }\n            getLabelSystem().setTerrainOcclusionResolver(\n                (cameraWorldPos, labelWorldPos) => (\n                    this._surfaceController?.isTerrainOccludedBetween?.(\n                        cameraWorldPos,\n                        labelWorldPos\n                    ) === true\n                )\n            );\n            getBusinessLabels({ surfaceController: this._surfaceController });\n            if (!this._presentationMode) {\n                this._fieldAssetLayer = new FieldAssetLayer({\n                    parentGroup: this._triTree.group,\n                    surfaceController: this._surfaceController,\n                }).start();\n                this._accountNoteLayer = new AccountNoteLayer({\n                    parentGroup: this._triTree.group,\n                    surfaceController: this._surfaceController,\n                }).start();\n            }\n            this._sceneInitializer?.setDepthOfFieldTargetProvider?.(() => {\n                const photo = this._photoTileLoader?.enabled ? this._photoTileLoader.group : null;\n                const terrain = photo || this._triTree?.group || null;\n                return terrain ? [terrain] : [];\n            });\n            // Wire the surface sampler into every GeoJsonLayer so the\n            // border spires compute their wall top/bottom relative to\n            // the actual photoreal surface (not the ellipsoid). Without\n            // this, mountain regions buried the spires and ocean\n            // trenches let them float in the air.\n            this._geoJsonLayer?.setSurfaceController?.(this._surfaceController);\n            this._geoJsonLookupLayer?.setSurfaceController?.(this._surfaceController);\n            for (const layer of (this._geoJsonAutoLayers?.values?.() || [])) {\n                layer?.setSurfaceController?.(this._surfaceController);\n            }\n            // Route ribbon draping — now that we have the surfaceController\n            // (which raycasts against photoreal tiles), wire it so the\n            // ribbon snaps to the live surface instead of floating above.\n            this._routeRibbon?.setSurfaceController?.(this._surfaceController);\n            this._placeSearchSurface?.setSurfaceController?.(this._surfaceController);\n            this._sceneInitializer.oceanStateProvider = () => this._surfaceController?.getOceanNavigationState?.();\n            this._surfaceController.oceanWaterLevel = getOceanWaterLevel();\n            this._scheduleOceanResolverSetup();\n            // Earth-world daemons: a singleton manager that can summon\n            // a black-satin avatar in front of the user, brief them\n            // via server-side TTS + speech bubble, and follow them.\n            // Mounts under the photoreal-tile group so it inherits\n            // planet rotation. Reuses the same character model + anims\n            // the player avatar loads.\n            this._earthDaemonManager = getEarthDaemonManager();\n            this._earthDaemonManager.setup({\n                scene: this._scene,\n                renderer: this._renderer,\n                parentGroup: this._triTree.group,\n                planetRadius: PLANET_RADIUS,\n                surfaceController: this._surfaceController,\n                getPlayerLatLon: () => this._currentPlayerLatLon(),\n                getPlayerPose: () => {\n                    const latLon = this._currentPlayerLatLon();\n                    if (!latLon) return null;\n                    const headingDeg = this._surfaceController?.getSurfaceHeadingDeg?.();\n                    const pitchDeg = this._surfaceController?.getSurfacePitchDeg?.();\n                    return {\n                        ...latLon,\n                        headingDeg: Number.isFinite(headingDeg) ? headingDeg : null,\n                        pitchDeg: Number.isFinite(pitchDeg) ? pitchDeg : null,\n                    };\n                },\n            });\n            this._eventManager = new EventManager(\n                this._renderer,\n                this._camera,\n                this._triTree,\n                this._surfaceController,\n                this._lightingSystem,\n                this._moonSystem,\n                this._geoJsonLookupLayer,\n                this.eventBus\n            );\n            this._eventManager.setGeoJsonOverlayInfo?.({\n                layer: this._geoJsonLayer,\n                adminLevel: this._geoJsonAdminLevel\n            });\n            this._eventManager.setGeoJsonLabelLayers?.([\n                this._geoJsonLayer,\n                this._geoJsonLookupLayer,\n                ...Array.from(this._geoJsonAutoLayers.values())\n            ]);\n            this._eventManager.sceneInitializer = this._sceneInitializer;\n            this._applyRaycastLinePrecision(this._raycastLinePrecision);\n\n            this._weatherSystem = new WeatherSystem({\n                atmosphereClouds: this._sceneInitializer?.atmosphereClouds || null,\n                lightingSystem: this._lightingSystem || null,\n                enabled: true\n            });\n            this._sceneInitializer?.setWeatherSystem?.(this._weatherSystem);\n            this._rainSystem = new RainSystem({ scene: this._scene, renderer: this._renderer,\n                camera: this._camera, planetGroup: this._triTree?.group, mobile: this._isMobile });\n            this._sceneInitializer?.setRainSystem(this._rainSystem);\n            this._weatherVisibilityHandler = () => {\n                if (document.hidden) this._suspendWeatherEffects();\n            };\n            document.addEventListener('visibilitychange', this._weatherVisibilityHandler);\n            this._eventManager.setWeatherProvider?.(this._weatherSystem);\n\n            this.eventBus.on('context:scene-selection-changed', (payload) => {\n                const keys = Array.isArray(payload?.keys) ? payload.keys : [];\n                this._applySceneSelectionKeys(keys);\n            });\n\n            this._overlayRegistry = new OverlayRegistry();\n            this._overlayRegistry.registerLayerRenderer('data_source', (options) => new DataSourceLayerRenderer(options));\n            this._accessController = new AccessController();\n            this._assetSubsystem = new AssetSubsystem({ renderer: this._renderer });\n            this._splineSubsystem = new SplineSubsystem({\n                scene: this._scene,\n                parentGroup: this._triTree.group,\n                planetRadius: PLANET_RADIUS\n            });\n            // Path tracking + trail rendering (separate from legacy MotionTracker)\n            this._pathTracker = getPathTracker({\n                scene: this,\n                eventBus: this.eventBus,\n            });\n            this._motionTrailRenderer = new MotionTrailRenderer({\n                parentGroup: this._triTree.group,\n                planetRadius: PLANET_RADIUS,\n            });\n\n            // Physics and trigger systems (audioSystem wired after init below)\n            this._physicsSystem = new PhysicsSystem({\n                scene: this._scene,\n                audioSystem: null,\n                // The base globe does not need the 2.4 MB Rapier runtime.\n                // A physics-enabled entity, character, or explicit API retry\n                // initializes it on demand while terrain colliders queue.\n                initializeOnConstruct: false\n            });\n            this._physicsSystem.setSurfaceCollisionResolver?.(\n                this._surfaceController.resolveDynamicSurfaceContact.bind(this._surfaceController)\n            );\n\n            // Enable terrain tile collision detection\n            this._triTree.setPhysicsSystem(this._physicsSystem);\n\n            this._proximityTriggerManager = new ProximityTriggerManager({\n                audioSystem: null\n            });\n\n            this._clickTriggerManager = new ClickTriggerManager({\n                camera: this._camera,\n                domElement: this._renderer.domElement,\n                audioSystem: null,\n                physicsSystem: this._physicsSystem\n            });\n            this._applyRaycastLinePrecision(this._raycastLinePrecision);\n            this._initializeOverlays();\n            this._registerAutoOverlayConfigHandlers();\n\n            this._streamHub = new StreamHub(this.eventBus);\n            this._interopHarness.stages.streamHubReady = true;\n            this._interopHarness.updatedAt = Date.now();\n            this._entitySystem = new EntitySystem({\n                parentGroup: this._triTree.group,\n                overlaySubsystem: this._overlaySubsystem,\n                accessController: this._accessController,\n                eventBus: this.eventBus,\n                planetRadius: PLANET_RADIUS\n            });\n            this._streamHub.register('location', (payload) => {\n                this._interopHarness.counters.locationPackets += 1;\n                this._interopHarness.last.locationPacketAt = Date.now();\n                this._interopHarness.updatedAt = Date.now();\n                this._entitySystem?.updateFromStream(payload);\n            });\n            const presenceOptions = this.options?.presence || {};\n            const nknEnabled = this._sceneSettings?.getSection?.('nkn.enabled') === true;\n            this._presenceSystem = new PresenceSystem({\n                camera: this._camera,\n                triTree: this._triTree,\n                surfaceController: this._surfaceController,\n                entitySystem: this._entitySystem,\n                eventBus: this.eventBus,\n                planetRadius: PLANET_RADIUS,\n                avatarConfig: this._avatarConfig,\n                ...presenceOptions,\n                useP2P: nknEnabled && presenceOptions.useP2P !== false\n            });\n            this._presenceSystem.setMapPresentation(this._mapPresentationMode);\n            if (this._presenceSystem.enabled && this._presenceSystem.autoConnect) {\n                this._presenceSystem.connect();\n            }\n\n            // Initialize avatar systems\n            this._localPlayer = new LocalPlayer({\n                surfaceController: this._surfaceController,\n                scene: this._scene,\n                triTree: this._triTree,\n                camera: this._camera,\n                eventBus: this.eventBus\n            });\n\n            this._peerManager = new PeerManager({\n                scene: this._scene,\n                triTree: this._triTree,\n                presenceSystem: this._presenceSystem,\n                eventBus: this.eventBus,\n                planetRadius: PLANET_RADIUS,\n                camera: this._camera,\n                surfaceController: this._surfaceController\n            });\n\n            // Wire up presence system with avatar systems\n            this._presenceSystem.setLocalPlayer(this._localPlayer);\n            this._presenceSystem.setPeerManager(this._peerManager);\n\n            // The globe overview is first-person and has no visible avatars.\n            // Defer decoding the character rig until a feature needs it.\n\n            this._audioSystem = new AudioSystem({\n                streamHub: this._streamHub,\n                entitySystem: this._entitySystem,\n                overlaySubsystem: this._overlaySubsystem,\n                accessController: this._accessController,\n                eventBus: this.eventBus\n            });\n            this._audioSystem.init(this._audioListener, {\n                camera: this._camera,\n                scene: this._scene,\n                parentGroup: this._triTree?.group,\n                mobile: this._isMobile,\n                surfaceController: this._surfaceController\n            });\n\n            // Wire audio into physics/trigger systems created earlier\n            this._physicsSystem.audioSystem = this._audioSystem;\n            this._proximityTriggerManager.audioSystem = this._audioSystem;\n            this._clickTriggerManager.audioSystem = this._audioSystem;\n            this._wireAudioUnlock();\n            this._windAudio = new WindAudio({\n                listener: this._audioListener,\n                eventBus: this.eventBus,\n                camera: this._camera,\n                parentGroup: this._triTree?.group,\n            });\n            this._applyWindSettings(this._windSettings);\n            this._windAudio.setEnabled(this._audioEnabledSetting && !!this._windSettings?.enabled);\n\n            this._hydraOverlayIngress = new HydraOverlayIngress({\n                overlaySubsystem: this._overlaySubsystem,\n                commsSystem: null,\n                eventBus: this.eventBus\n            });\n            this._overlaySubsystem?.setHydraIngress?.(this._hydraOverlayIngress);\n            if (!this._interopHarnessAckHandler) {\n                this._interopHarnessAckHandler = (payload = {}) => {\n                    const status = String(payload?.status || '').toLowerCase();\n                    this._interopHarness.last.overlayAckAt = Date.now();\n                    if (status && status !== 'ok') {\n                        this._interopHarness.counters.overlayErrors += 1;\n                        this._interopHarness.last.overlayErrorAt = Date.now();\n                        this._interopHarness.last.overlayErrorCode = String(payload?.error_code || payload?.errorCode || '');\n                    }\n                    this._interopHarness.updatedAt = Date.now();\n                };\n                this.eventBus.on('hydra:overlay:ack', this._interopHarnessAckHandler);\n            }\n            if (!this._interopHarnessAppliedHandler) {\n                this._interopHarnessAppliedHandler = () => {\n                    this._interopHarness.counters.overlayApplied += 1;\n                    this._interopHarness.last.overlayAppliedAt = Date.now();\n                    this._interopHarness.updatedAt = Date.now();\n                };\n                this.eventBus.on('hydra:overlay:ingress:applied', this._interopHarnessAppliedHandler);\n            }\n            if (!this._interopHarnessCommsFailureHandler) {\n                this._interopHarnessCommsFailureHandler = (payload = {}) => {\n                    this._interopHarness.counters.commsFailures += 1;\n                    this._interopHarness.last.commsFailureAt = Date.now();\n                    this._interopHarness.last.commsFailureCode = String(payload?.code || '').trim();\n                    this._interopHarness.last.commsFailureScope = String(payload?.scope || '').trim();\n                    this._interopHarness.updatedAt = Date.now();\n                };\n                this.eventBus.on('comms:interop:failure', this._interopHarnessCommsFailureHandler);\n            }\n            if (!this._interopHarnessStatsInterval) {\n                this._interopHarnessStatsInterval = setInterval(() => {\n                    const telemetry = this._commsSystem?.getInteropTelemetry?.();\n                    if (!telemetry) return;\n                    this._interopHarness.counters.commsSamples += 1;\n                    this._interopHarness.last.commsSampleAt = Date.now();\n                    this._interopHarness.last.commsTransport = String(telemetry.selectedTransport || '');\n                    this._interopHarness.last.commsConnected = !!telemetry.nknConnected;\n                    this._interopHarness.last.commsFallbackCount = Number(telemetry.fallbackCount || 0);\n                    this._interopHarness.last.commsTicketReplayRejected = Number(telemetry.ticketReplayRejected || 0);\n                    this._interopHarness.last.commsRateLimitedCount = Number(telemetry.rateLimitedCount || 0);\n                    this._interopHarness.last.commsFraudBlockedCount = Number(telemetry.fraudBlockedCount || 0);\n                    this._interopHarness.last.commsKillSwitchBlockedCount = Number(telemetry.killSwitchBlockedCount || 0);\n                    this._interopHarness.updatedAt = Date.now();\n                }, 2000);\n            }\n\n            // Wire up celestial body position getter BEFORE UIController\n            // so URL ?body= param can be consumed during UIController constructor\n            this._surfaceController.setBodyPositionGetter((bodyName) => {\n                if (bodyName === 'luna' && this._moonSystem?.position) {\n                    return this._moonSystem.position.clone();\n                }\n                if (bodyName === 'sol' && this._lightingSystem?.sun?.position) {\n                    return this._lightingSystem.sun.position.clone();\n                }\n                return null;\n            });\n\n            // UIController is required during startup; keep it in the main\n            // boot graph so stale lazy chunks cannot strand scene init.\n            const uiController = new UIController({\n                elevationClient: this._elevationClient,\n                triTree: this._triTree,\n                imageryManager: this._imageryManager,\n                lightingSystem: this._lightingSystem,\n                surfaceController: this._surfaceController,\n                camera: this._camera,\n                renderer: this._renderer,\n                sceneInitializer: this._sceneInitializer,\n                weatherSystem: this._weatherSystem,\n                eventBus: this.eventBus,\n                settings: this._sceneSettings,\n                onGeoJsonToggle: (visible) => {\n                    this._geoJsonLayer?.setVisible?.(visible);\n                },\n                onGeoJsonSelectionChange: (selection) => {\n                    if (!selection) return;\n                    this._applyGeoJsonSelection(selection.adminLevel, selection.country, selection.source);\n                },\n                onGeoJsonSourceChange: (url, source) => {\n                    const payload = source || url;\n                    if (!payload) return;\n                    this._applyGeoJsonSource(payload);\n                }\n            });\n            this.uiController = uiController;\n\n            // PlanetScene starts a URL-init lease only when it actually begins\n            // applying a short alias/metaverse state in `_applyUrlViewState`.\n            // The canonical legacy UIController owns its own initialization.\n\n            this._eventManager.onSidebarClose = () => uiController.closeSidebar();\n            this._eventManager.onHexSelectionChange = () => this._updateHexVisualization();\n            this._eventManager.onLODModeChange = (mode) => {\n                this._surfaceController?.setLODMode?.(mode);\n                uiController?.syncLodButtons?.();\n            };\n            this._eventManager.onEnterSurface = (focusDir) => {\n                this._handleSurfaceEnter({ reason: 'user', focusDir });\n            };\n            this._eventManager.enable();\n\n            // Update URL when body anchor changes\n            this._surfaceController.onBodyAnchorChange = () => {\n                this._syncCelestialSummaryLabel();\n                this._updateUrlFromView({ force: true });\n            };\n            this._syncCelestialSummaryLabel();\n\n            uiController.initNKN(handleIncoming);\n\n            uiController.onDebugToggle = () => {\n                this._perf.enabled = !this._perf.enabled;\n                this._perf.logHeavyFrames = this._perf.enabled;\n                uiController.elements.debugToggle.classList.toggle('active', this._perf.enabled);\n                uiController.elements.debugPanel.classList.toggle('open', this._perf.enabled);\n                if (this._perf.enabled) {\n                    this._perf.sections = {};\n                    this._perf.lastPanelUpdate = 0;\n                }\n            };\n\n            uiController.onAtmosphereToggle = (visible) => {\n                if (typeof this._sceneInitializer?.setAtmosphereEnabled === 'function') {\n                    this._sceneInitializer.setAtmosphereEnabled(visible);\n                    return;\n                }\n                const atmosphereMesh = this._sceneInitializer?.atmosphereMesh;\n                if (atmosphereMesh) atmosphereMesh.visible = visible;\n            };\n\n            if (this._isMobile && this._shouldForceMobileWireframeDefault()) {\n                this._enableMobileWireframeDefault();\n            }\n\n            await this._sceneInitializer.loadEarthMaterials(\n                this._triTree,\n                () => {\n                    // No-op callback for Phase 1 parity\n                },\n                () => {\n                    // Materials ready - apply initial UI values to atmosphere\n                    if (uiController && typeof uiController.applyInitialAtmosphereValues === 'function') {\n                        uiController.applyInitialAtmosphereValues();\n                    }\n                }\n            );\n            this._refreshOverviewGlobeMaterial();\n            await this._restoreFromEnvelope();\n\n            uiController.setPathRedrawCallback(() => {\n                this._updateHexVisualization();\n            });\n\n            // Initialize URL state sync (migrated from UIController.setupUrlStateSync)\n            this._setupUrlStateSync();\n\n            // Initialize VR Manager with the vrDolly from scene-initializer\n            // This ensures VR uses the same camera rig that's already positioned on the planet\n            this._vrAccessGate = new VrAccessGate({ eventBus: this.eventBus });\n            this._vrManager = new VRManager({\n                renderer: this._renderer,\n                scene: this._scene,\n                camera: this._camera,\n                worldRoot: this._worldRoot,\n                eventBus: this.eventBus,\n                planetRadius: PLANET_RADIUS,\n                vrDolly: this._sceneInitializer?.vrDolly,\n                labels: getLabelSystem(),\n                settings: this._sceneSettings,\n                presenceSystem: this._presenceSystem,\n                audioSystem: this._audioSystem,\n                onSurfaceSelect: (point, source) => this._selectXRSurface(point, source),\n                onSurfaceContext: (point, source) => {\n                    const target = this._surfaceTargetFromPoint(point, source);\n                    return target ? { lat: target.lat, lon: target.lon } : null;\n                },\n                onNavigate: (destination = {}) => {\n                    if (!Number.isFinite(destination.lat) || !Number.isFinite(destination.lon)) return false;\n                    const direction = latLonToLocalDir(destination.lat, destination.lon);\n                    const planetGroup = this._triTree?.group;\n                    if (planetGroup?.getWorldQuaternion) {\n                        direction.applyQuaternion(planetGroup.getWorldQuaternion(new THREE.Quaternion()));\n                    }\n                    this._surfaceController?.enterSurfaceAt?.(direction, {\n                        preserveAltitude: true,\n                        transitionDurationMs: 700,\n                        pathFacing: true,\n                    });\n                    return true;\n                },\n                weatherSystem: this._weatherSystem,\n                getSceneTime: () => this._sceneClock?.getTime?.() ?? Date.now(),\n                getLocation: () => {\n                    const location = this._currentPlayerLatLon?.() || {};\n                    return {\n                        ...location,\n                        altitudeM: this._surfaceController?.surfaceAltitudeMSL,\n                        aglM: this._surfaceController?.getActualSurfaceAltitudeMeters?.()\n                            ?? this._surfaceController?.getSurfaceAltitudeMeters?.(),\n                    };\n                },\n                surfaceController: this._surfaceController,\n                accessGate: this._vrAccessGate\n            });\n            this._applyRaycastLinePrecision(this._raycastLinePrecision);\n\n            // Also connect the surfaceController to the vrDolly\n            if (this._surfaceController && this._sceneInitializer?.vrDolly) {\n                this._surfaceController.setVRDolly(this._sceneInitializer.vrDolly);\n            }\n\n            this._mobileStereoRenderer = new MobileStereoRenderer({\n                renderer: this._renderer,\n                scene: this._scene,\n                camera: this._camera,\n                sceneInitializer: this._sceneInitializer\n            });\n            this._vrAccessRevocationHandler = (decision = {}) => {\n                if (!decision.allowed && this._mobileStereoRenderer?.isEnabled?.()) {\n                    this._mobileStereoRenderer.setEnabled(false);\n                }\n            };\n            this.eventBus?.on?.('vr:access-update', this._vrAccessRevocationHandler);\n\n            this._motionTracker = new MotionTracker({\n                eventBus: this.eventBus,\n                planetRadius: PLANET_RADIUS,\n                planetGroup: this._triTree?.group || null\n            });\n\n            this._motionRuntime = createSceneMotionRuntime({\n                camera: this._camera,\n                surfaceController: this._surfaceController,\n                planetGroup: this._triTree?.group,\n                localPlayer: this._localPlayer,\n                overlaySubsystem: this._overlaySubsystem,\n                eventBus: this.eventBus,\n                inputTarget: this._renderer?.domElement || globalThis.window,\n                isCameraBlocked: () => this._cameraExclusiveState !== null\n                    || this._mapPresentationMode === '2d'\n                    || this._renderer?.xr?.isPresenting === true,\n            });\n\n            window.bootLog?.('starting animation loop');\n            this._animationLoop = new AnimationLoop({\n                vrManager: this._vrManager,\n                renderer: this._renderer,\n                scene: this._scene,\n                camera: this._camera,\n                lightingSystem: this._lightingSystem,\n                moonSystem: this._moonSystem,\n                surfaceController: this._surfaceController,\n                triTree: this._triTree,\n                elevationClient: this._elevationClient,\n                sceneInitializer: this._sceneInitializer,\n                uiController: this.uiController,\n                weatherSystem: this._weatherSystem,\n                presenceSystem: this._presenceSystem,\n                worldRoot: this._worldRoot,\n                eventBus: this.eventBus,\n                motionTracker: this._motionTracker,\n                motionRuntime: this._motionRuntime,\n                audioSystem: this._audioSystem,\n                physicsSystem: this._physicsSystem,\n                proximityTriggerManager: this._proximityTriggerManager,\n                clickTriggerManager: this._clickTriggerManager,\n                stereoRenderer: this._mobileStereoRenderer,\n                onFrame: (dt, now) => {\n                    this._perfStart('scene.onFrame');\n                    try {\n                    this._nightVisionControl?.update();\n                    this._sarControl?.update();\n                    // One-shot diagnostic to confirm animation loop is running\n                    if (globalThis.__noclipDebugFrameLoop === true && !this._onFrameDiagDone) {\n                        this._onFrameDiagDone = true;\n                        console.warn('[PlanetScene] onFrame callback RUNNING — animation loop active');\n                    }\n                    const frameNow = Number.isFinite(now)\n                        ? now\n                        : (typeof performance !== 'undefined' ? performance.now() : Date.now());\n                    this._browserPerformanceTelemetry?.frame?.(dt, frameNow);\n                    const isMobile = !!this._isMobile;\n                    const overlayObserver = this._camera?.userData?.worldPosition || this._camera?.position;\n                    this._perfStart('photo.tiles.update');\n                    try {\n                        this._updatePhotorealisticTiles();\n                    } finally {\n                        this._perfEnd('photo.tiles.update');\n                    }\n                    this._updatePhotorealInfrastructureGate();\n\n                    if (!isMobile || this._shouldRunMobileTask('overlays.terrain', frameNow, 100)) {\n                        if (this._buildingOverlay?.enabled) this._buildingOverlay.update(dt);\n                        if (this._infrastructureOverlay?.enabled) this._infrastructureOverlay.update(dt);\n                        // Route ribbon drape loop — re-samples a slice of\n                        // the ribbon's vertices against the live surface\n                        // (photoreal first, then tritree) every ~500ms so\n                        // LOD swaps don't leave it buried or airborne.\n                        this._routeRibbon?.update?.(dt);\n                        this._placeSearchSurface?.update();\n                        // Earth-world daemons: per-frame mixer + follow + speech-\n                        // bubble billboard tick. Cheap when no daemon is active.\n                        this._earthDaemonManager?.update?.(dt);\n                        this._openInfraMapRenderer?.update?.(\n                            overlayObserver,\n                            this._triTree?.group\n                        );\n                    }\n                    if (!isMobile || this._shouldRunMobileTask('overlays.dynamic', frameNow, 180)) {\n                        // Compute camera altitude for orbit-distance scaling\n                        const _camAltKm = overlayObserver ? Math.max(0, (overlayObserver.length() - this._sceneInitializer?.planetRadius) / 1000) : 0;\n                        this._satelliteOverlay?.setCameraAltitude?.(_camAltKm);\n                        this._maritimeOverlay?.setCameraAltitude?.(_camAltKm);\n\n                        this._aircraftOverlay?.update?.(dt, overlayObserver);\n                        this._satelliteOverlay?.update?.(dt);\n                        this._maritimeOverlay?.update?.(dt);\n                        this._incidentOverlay?.update?.(dt);\n                        this._roadTrafficOverlay?.update?.(dt);\n                        this._trafficCameraOverlay?.update?.(dt);\n                        this._sensorOverlay?.update?.(dt);\n                        this._radioDataOverlay?.update?.(dt);\n                        this._meshtasticOverlay?.update?.(this._camera, dt * 1000);\n                        this._weatherVolumeOverlay?.update?.(dt);\n                        this._environmentalOverlay?.update?.(dt);\n                        this._globalSignalsOverlay?.update?.(dt);\n                    }\n                    // Surface business/address labels are useful in both TriTree\n                    // and photorealistic modes; photo building mesh semantics\n                    // still wait for the Cesium surface-quality gate.\n                    const photorealSemanticLabelsReady = this._shouldRunPhotorealSemanticLabels();\n                    const businessLabels = getBusinessLabels();\n                    if (photorealSemanticLabelsReady) {\n                        getPhotoBuildingLabels().update(overlayObserver);\n                    }\n                    if (this._shouldRunSurfaceBusinessLabels(overlayObserver)) {\n                        if (!businessLabels.enabled) businessLabels.setEnabled?.(true);\n                        businessLabels.update(overlayObserver);\n                    } else if (businessLabels.enabled) {\n                        businessLabels.setEnabled?.(false, { clearEntries: false });\n                    }\n                    // Navigation: push player lat/lon into progress tracker\n                    // at ~2 Hz — more frequent is wasteful for street speeds.\n                    if (this._routeStore?.isActive?.() && this._routeProgressTracker) {\n                        const nowMs = performance.now?.() || Date.now();\n                        if (nowMs - (this._lastRouteUpdateMs || 0) > 500) {\n                            this._lastRouteUpdateMs = nowMs;\n                            const ll = this._currentPlayerLatLon?.();\n                            if (ll) this._routeProgressTracker.update(ll.lat, ll.lon);\n                        }\n                    }\n                    // Local OpenMapTiles road/path context is independent of\n                    // active navigation. It updates at the same street-scale\n                    // cadence and keeps all vector decoding off the hot frame.\n                    // The boot map is a single Overpass-backed SVG document;\n                    // do not let this scene subsystem start a PBF request while\n                    // that document is the visible page.\n                    const bootMapOwnsViewport = globalThis.document?.getElementById?.('boot-overlay')?.isConnected === true;\n                    const roadContextSurfaceActive = this._surfaceController?.isInSurfaceMode?.()\n                        || this._surfaceController?.cameraMode === 'toSurface';\n                    if (roadContextSurfaceActive && !bootMapOwnsViewport) {\n                        const nowMs = performance.now?.() || Date.now();\n                        if (nowMs - (this._lastRoadContextUpdateMs || 0) > 500) {\n                            this._lastRoadContextUpdateMs = nowMs;\n                            const ll = this._currentPlayerLatLon?.();\n                            if (ll) {\n                                const speedMps = Number(getHudInfoStore()?.getData?.('nav.speed')) || 0;\n                                const routeProfile = this._routeStore?.isActive?.()\n                                    ? this._routeStore.getProfile?.()\n                                    : 'foot';\n                                this._roadContext?.update?.(ll.lat, ll.lon, {\n                                    headingDeg: this._surfaceController?.getSurfaceHeadingDeg?.(),\n                                    speedMps,\n                                    profile: routeProfile === 'transit' ? 'foot' : routeProfile,\n                                });\n                            }\n                        }\n                    } else {\n                        this._roadContext?.clear?.();\n                    }\n                    // Building hover label (temporary label on mouse-over)\n                    this._updateBuildingHoverLabel();\n                    // Keep surface target leaders bound to the camera focal ray\n                    // while the user moves, pans, or changes altitude.\n                    this._addressHoverOverlay?.update?.();\n                    // Viewport-stable label scaling, billboarding & leader-line updates\n                    this._syncCelestialSummaryLabel();\n                    this._perfStart('labels.update');\n                    try { getLabelSystem().update(this._hdControl?.getPresentationCamera?.() || this._camera); }\n                    finally { this._perfEnd('labels.update'); }\n                    this._splineSubsystem?.update?.(dt);\n\n                    // Update motion trail rendering (every 60 frames ≈ 1 Hz)\n                    this._trailFrameCount = (this._trailFrameCount || 0) + 1;\n                    if (this._trailFrameCount % 60 === 0 && this._motionTrailRenderer) {\n                        const tracker = getPathTracker();\n                        for (const sess of tracker.getSessions()) {\n                            if (sess.sampleCount > 1) {\n                                const trail = tracker.getTrail(sess.type);\n                                this._motionTrailRenderer.updateTrail(sess.id, trail, sess.type);\n                            }\n                        }\n                    }\n\n                    if (!isMobile || this._shouldRunMobileTask('geojson.update', frameNow, 200)) {\n                        this._updateGeoJsonRenderMode();\n                        this._updateGeoJsonAltitudeLimit();\n                        this._geoJsonLayer?.update?.(dt, this._camera);\n                        this._geoJsonLookupLayer?.update?.(dt, this._camera);\n                        if (this._geoJsonAutoLayers?.size) {\n                            for (const layer of this._geoJsonAutoLayers.values()) {\n                                layer?.update?.(dt, this._camera);\n                            }\n                        }\n                    }\n                    this._updateWeatherEffects(dt, frameNow);\n                    this._updateWindAudio(dt);\n                    if (!isMobile || this._shouldRunMobileTask('overlay.geoContext', frameNow, 120)) {\n                        this._updateOverlayGeoContext(frameNow);\n                    }\n                    if (!isMobile || this._shouldRunMobileTask('overlay.proximity', frameNow, 120)) {\n                        this._overlaySubsystem?.updateProximity?.(overlayObserver, frameNow);\n                    }\n                    this._updateNavGeoContext(frameNow);\n                    this._updateBuildingAutoInjection(frameNow);\n                    this._updateAircraftAutoInjection(frameNow);\n                    this._updateSatelliteAutoInjection(frameNow);\n                    this._updateMaritimeAutoInjection(frameNow);\n                    this._updateIncidentAutoInjection(frameNow);\n                    this._updateInfrastructureAutoInjection(frameNow);\n                    this._updateRadioDataAutoInjection(frameNow);\n                    this._updateGeocacheAutoInjection(frameNow);\n                    this._updateViewshed(frameNow);\n                    this._updateViewshedHighlight(now);\n                    this._perfStart('xr.interaction');\n                    try { this._vrManager?.updateTeleport?.(); }\n                    finally { this._perfEnd('xr.interaction'); }\n                    // Update avatar systems\n                    this._localPlayer?.update?.(dt);\n                    this._peerManager?.update?.(dt);\n                    this._commsSystem?.update?.(dt, frameNow);\n                    if (this._audioTestActive) {\n                        this._updateEarthAudioAnchor();\n                    }\n                    } finally { this._perfEnd('scene.onFrame'); }\n                },\n                setRenderScale: (value) => {\n                    if (this.uiController && typeof this.uiController.applyRenderScale === 'function') {\n                        this.uiController.applyRenderScale(value);\n                    } else if (this._sceneInitializer && typeof this._sceneInitializer.setRenderScale === 'function') {\n                        this._sceneInitializer.setRenderScale(value);\n                    }\n                },\n                perf: this._perf,\n                perfStart: this._perfStart,\n                perfEnd: this._perfEnd,\n                updateDebugPanel: this._updateDebugPanel,\n                onAfterRender: () => {\n                    if (!this._renderer.xr?.isPresenting) getLabelSystem().render(this._hdControl?.getPresentationCamera?.() || this._camera);\n                },\n                onBeforeFrame: (now) => this._browserPerformanceTelemetry?.beforeFrame(now),\n                onFrameComplete: (frame) => {\n                    this._browserPerformanceTelemetry?.frameCompleted(frame);\n                    this._hdControl?.frameCompleted(frame);\n                    this._sceneCanvasCapture?.frameCompleted(frame);\n                },\n                lowFpsAffectsTerrain: false,\n                tilesPendingNormals: this._tilesPendingNormals,\n                metricTiles: document.getElementById('metric-tiles'),\n                metricLevel: document.getElementById('metric-level'),\n                metricHex: document.getElementById('metric-hex'),\n                metricBatches: document.getElementById('metric-batches'),\n                metricVerts: document.getElementById('metric-verts'),\n                metricLatLon: document.getElementById('metric-latlon'),\n                metricReqs: document.getElementById('metric-reqs'),\n                metricResps: document.getElementById('metric-resps'),\n                metricKBOut: document.getElementById('metric-kbout'),\n                metricKBIn: document.getElementById('metric-kbin'),\n                metricPtsOut: document.getElementById('metric-points-out'),\n                metricPtsIn: document.getElementById('metric-points-in'),\n                metricRatio: document.getElementById('metric-ratio'),\n                metricCurrentTime: document.getElementById('metric-currentTime'),\n                metricSunDir: document.getElementById('metric-sunDir')\n            });\n\n            // Private operator diagnostics for the robit account. The client\n            // only arms after authenticated account resolution; the API repeats\n            // that account check before durably appending any sample.\n            this._browserPerformanceTelemetry = new BrowserPerformanceTelemetry({ scene: this });\n            if (this._browserPerformanceTelemetry.active) this._perf.enable();\n\n            this._sceneSettings?.apply();\n\n            // Canonical latitude/longitude URLs are consumed by the legacy\n            // UIController during its constructor, before PlanetScene owns\n            // the photoreal handoff. Re-enter the shared surface-entry path\n            // once settings have launched the provider so cold URL boots get\n            // the same underfoot-contact gate as an interactive landing.\n            if (this._surfaceController?.isInSurfaceMode?.()\n                && !this._photoSurfaceEntryPending) {\n                this._handleSurfaceEnter({\n                    reason: 'startup-surface',\n                    focusDir: this._surfaceController?.surfaceState?.up,\n                });\n            }\n\n            // GPU budget governor — monitors renderer.info and enforces triangle/draw-call limits\n            this._budgetGovernor = new SceneBudgetGovernor(this._renderer, {\n                isMobile: this._isMobile,\n            });\n            this._budgetGovernor.setTriTree(this._triTree);\n            this._budgetGovernor.setElevationClient(this._elevationClient);\n            if (this._buildingOverlay) {\n                this._budgetGovernor.addBuildingOverlay(this._buildingOverlay);\n            }\n            // Let the governor shed memory under JS-heap/GPU pressure by tightening\n            // optional caches, label viewsheds, and geojson detail. Subsystems are\n            // optional; setters no-op if absent.\n            try { this._budgetGovernor.setLabelSystem(getLabelSystem()); } catch { /* labels optional */ }\n            if (this._geoJsonLayer) this._budgetGovernor.setGeoJsonLayer(this._geoJsonLayer);\n            this._connectPhotorealisticPressure(this._photoTileLoader);\n            this._installWebglPressureHandlers();\n            this._animationLoop.budgetGovernor = this._budgetGovernor;\n\n            if (this._isMobile) {\n                this._applyMobileRuntimeBudgets();\n            }\n\n            this.uiController.onAutoRenderScaleToggle = (enabled) => {\n                this._animationLoop.setAutoRenderScaleEnabled(false);\n            };\n\n            this._bootstrapMobileUi();\n            this._startCheckpointPersistence();\n\n            this.api = this._buildApi();\n            window.bootLog?.('scene:ready — all systems online', 'success');\n            // The page boot overlay reveals the already-renderable direct\n            // shell, then notifyInteractiveBootComplete() warms the advanced\n            // atmosphere in a provider-aware background quiet window.\n            // Programmatic/headless consumers without that overlay still need\n            // the same autonomous activation handoff.\n            if (!this._interactiveBootComplete\n                && !document.getElementById?.('boot-overlay')) {\n                requestAnimationFrame(() => {\n                    this.notifyInteractiveBootComplete();\n                });\n            }\n            this.eventBus.emit('scene:ready', { time: Date.now() });\n        } catch (error) {\n            this.eventBus.emit('scene:error', { error, scope: 'init' });\n            throw error;\n        }\n    }\n\n    _initializeOverlays() {\n        window.bootLog?.('loading overlay subsystem');\n        this._overlaySubsystem = new OverlaySubsystem({\n            scene: this._scene,\n            parentGroup: this._triTree.group,\n            camera: this._camera,\n            registry: this._overlayRegistry,\n            assets: this._assetSubsystem,\n            access: this._accessController,\n            eventBus: this.eventBus,\n            planetRadius: PLANET_RADIUS,\n            splineSubsystem: this._splineSubsystem,\n            sceneInitializer: this._sceneInitializer,\n            proximityTriggerManager: this._proximityTriggerManager,\n            physicsSystem: this._physicsSystem,\n            clickTriggerManager: this._clickTriggerManager,\n            triTree: this._triTree,\n            surfaceController: this._surfaceController\n        });\n        this._interopHarness.stages.overlaySubsystemReady = true;\n        this._interopHarness.updatedAt = Date.now();\n        this._eventManager.setOverlaySubsystem?.(this._overlaySubsystem);\n\n        const buildingOptions = {\n            ...(this.options?.buildings || {}),\n            ...(this._sceneSettings?.getSection?.('scene.buildings') || {}),\n        };\n        this._buildingOverlay = new BuildingOverlay({\n            parentGroup: this._triTree.group,\n            triTree: this._triTree,\n            camera: this._camera,\n            surfaceController: this._surfaceController,\n            planetRadius: PLANET_RADIUS,\n            motionTracker: this._motionTracker,\n            eventBus: this.eventBus,\n            sceneInitializer: this._sceneInitializer,\n            perf: this._perf,\n            ...buildingOptions,\n            terrainMode: this._triTree.suppressTileDisplay ? 'quadtree' : 'tritree'\n        });\n\n        const flightOptions = this.options?.flights || {};\n        this._aircraftOverlay = new AircraftOverlay({\n            parentGroup: this._triTree.group,\n            planetRadius: PLANET_RADIUS,\n            eventBus: this.eventBus,\n            sceneInitializer: this._sceneInitializer,\n            surfaceController: this._surfaceController,\n            ...flightOptions\n        });\n\n        this._satelliteOverlay = null;\n\n        const maritimeOptions = this.options?.maritime || {};\n        this._maritimeOverlay = new MaritimeOverlay({\n            parentGroup: this._triTree.group,\n            planetRadius: PLANET_RADIUS,\n            eventBus: this.eventBus,\n            sceneInitializer: this._sceneInitializer,\n            surfaceController: this._surfaceController,\n            ...maritimeOptions\n        });\n\n        const incidentOptions = this.options?.incidents || {};\n        this._incidentOverlay = new IncidentOverlay({\n            parentGroup: this._triTree.group,\n            planetRadius: PLANET_RADIUS,\n            eventBus: this.eventBus,\n            sceneInitializer: this._sceneInitializer,\n            surfaceController: this._surfaceController,\n            camera: this._camera,\n            mobile: this._isMobile,\n            buildingResolver: (lat, lon) => (\n                this._buildingOverlay?.getBuildingAtLatLon?.(lat, lon) || null\n            ),\n            ...incidentOptions\n        });\n\n        const trafficCameraOptions = this.options?.trafficCameras || {};\n        const roadTrafficOptions = this.options?.roadTraffic || {};\n        this._roadTrafficOverlay = new RoadTrafficOverlay({\n            parentGroup: this._triTree.group,\n            planetRadius: PLANET_RADIUS,\n            camera: this._camera,\n            sceneInitializer: this._sceneInitializer,\n            surfaceController: this._surfaceController,\n            eventBus: this.eventBus,\n            deferUntilInteractive: true,\n            ...roadTrafficOptions\n        });\n\n        this._trafficCameraOverlay = new TrafficCameraOverlay({\n            parentGroup: this._triTree.group,\n            planetRadius: PLANET_RADIUS,\n            camera: this._camera,\n            domElement: this._renderer?.domElement,\n            sceneInitializer: this._sceneInitializer,\n            surfaceController: this._surfaceController,\n            eventBus: this.eventBus,\n            // Provider discovery is autonomous and may run during boot, but\n            // marker/label GPU work must never compete with r185's first\n            // underfoot photoreal programs.\n            deferUntilInteractive: true,\n            ...trafficCameraOptions\n        });\n\n        // Address hover overlay (Overpass/local building footprint + label)\n        this._addressHoverOverlay = getAddressHoverOverlay({\n            parentGroup: this._triTree.group,\n            surfaceController: this._surfaceController,\n            eventBus: this.eventBus,\n            spireHeightM: this._incidentOverlay?.spireHeightM,\n            buildingResolver: (lat, lon) => (\n                this._buildingOverlay?.getBuildingAtLatLon?.(lat, lon) || null\n            ),\n        });\n\n        this._sensorOverlay = new SensorOverlay({\n            parentGroup: this._triTree.group,\n            camera: this._camera,\n            terrainSampler: this._surfaceController?.sampleTerrainRadiusForDir\n                ? this._surfaceController.sampleTerrainRadiusForDir.bind(this._surfaceController)\n                : null,\n            sceneInitializer: this._sceneInitializer,\n            eventBus: this.eventBus,\n            surfaceController: this._surfaceController,\n        });\n\n        const radioDataOptions = {\n            ...(this._sceneSettings?.getSection?.('scene.radioData') || {}),\n            ...(this.options?.radioData || {}),\n        };\n        this._radioDataConfig = radioDataOptions;\n        this._radioDataAutoEnabled = radioDataOptions.enabled === true;\n        this._radioDataAutoPollIntervalMs = Number.isFinite(radioDataOptions.pollIntervalMs)\n            ? radioDataOptions.pollIntervalMs\n            : 60_000;\n        this._radioDataOverlay = new RadioDataOverlay({\n            parentGroup: this._triTree.group,\n            surfaceController: this._surfaceController,\n            sceneInitializer: this._sceneInitializer,\n            eventBus: this.eventBus,\n            ...radioDataOptions,\n        });\n\n        const geocacheOptions = {\n            ...(this._sceneSettings?.getSection?.('scene.geocaches') || {}),\n            ...(this.options?.geocaches || {}),\n        };\n        this._geocacheConfig = geocacheOptions;\n        this._geocacheAutoEnabled = geocacheOptions.enabled === true;\n        this._geocacheAutoPollIntervalMs = Number.isFinite(geocacheOptions.pollIntervalMs)\n            ? geocacheOptions.pollIntervalMs\n            : 300_000;\n        this._geocacheLayer = new GeocacheLayer({\n            parentGroup: this._triTree.group,\n            surfaceController: this._surfaceController,\n            eventBus: this.eventBus,\n            ...geocacheOptions,\n        });\n\n        const initialLabelSettings = this._presentationMode\n            ? {}\n            : (this._sceneSettings?.getSection?.('scene.labels') || {});\n        const meshtasticOptions = {\n            ...(this._sceneSettings?.getSection?.('scene.meshtastic') || {}),\n            ...(this.options?.meshtastic || {}),\n        };\n        this._meshtasticOverlay = new MeshtasticOverlay({\n            parentGroup: this._triTree.group,\n            planetRadius: PLANET_RADIUS,\n            eventBus: this.eventBus,\n            sceneInitializer: this._sceneInitializer,\n            surfaceController: this._surfaceController,\n            buildingResolver: (lat, lon) => (\n                this._buildingOverlay?.getBuildingAtLatLon?.(lat, lon) || null\n            ),\n            ...meshtasticOptions,\n            showLabels: getLabelCategoryValue(\n                initialLabelSettings,\n                'sensors',\n                meshtasticOptions.showLabels !== false,\n            ),\n        });\n\n        this._weatherVolumeOverlay = new WeatherVolumeOverlay({parentGroup:this._triTree.group,camera:this._camera,eventBus:this.eventBus,sceneInitializer:this._sceneInitializer});\n        this._weatherVolumeOverlay.setOptions(initialLabelSettings.weatherVolumes);\n        this._weatherVolumeOverlay.setGlobalEnabled(initialLabelSettings.enabled);\n        for (const layer of WEATHER_VOLUME_LAYERS) this._weatherVolumeOverlay.setLayerEnabled(layer.id,getLabelCategoryValue(initialLabelSettings,layer.id));\n        globalThis.window.__noclipWeatherVolumes = {status:()=>this._weatherVolumeOverlay?.status()};\n        this._environmentalOverlay = new EnvironmentalOverlay({\n            parentGroup: this._triTree.group,\n            camera: this._camera,\n            sceneClock: this._sceneClock,\n            sceneInitializer: this._sceneInitializer,\n            surfaceController: this._surfaceController,\n            terrainSampler: this._surfaceController?.sampleTerrainRadiusForDir\n                ? this._surfaceController.sampleTerrainRadiusForDir.bind(this._surfaceController)\n                : null,\n            eventBus: this.eventBus,\n            mobile: this._isMobile,\n        });\n        this._globalSignalsOverlay = new GlobalSignalsOverlay({\n            parentGroup: this._triTree.group,\n            camera: this._camera,\n            renderer: this._renderer,\n            surfaceController: this._surfaceController,\n            terrainSampler: this._surfaceController?.sampleTerrainRadiusForDir\n                ? this._surfaceController.sampleTerrainRadiusForDir.bind(this._surfaceController)\n                : null,\n            mobile: this._isMobile,\n            onSurfaceConflictDispositionChange: (disposition) => {\n                this._setSurfaceConflictBorderDisposition(disposition);\n            },\n            onConflictMapStateChange: (state) => {\n                this._setConflictBorderMapState(state);\n            },\n        });\n        globalThis.window.__noclipEnvironment = {\n            setLayerEnabled: (id, enabled) => (\n                this._environmentalOverlay?.setLayerEnabled?.(id, enabled)\n            ),\n            setSmokePresentation: (presentation) => (\n                this._environmentalOverlay?.setSmokePresentation?.(presentation)\n            ),\n            status: () => this._environmentalOverlay?.status?.(),\n        };\n        globalThis.window.__noclipSignals = {\n            setLayerEnabled: (id, enabled) => (\n                this._globalSignalsOverlay?.setLayerEnabled?.(id, enabled)\n            ),\n            status: () => this._globalSignalsOverlay?.status?.(),\n        };\n        // Scene settings are loaded before source overlays are constructed.\n        // Reconcile persisted opt-in state now so an enabled layer does not\n        // wait for a second settings mutation before it begins loading.\n        for (const id of [\n            'thermalDetections',\n            'wildfireEvents',\n            'smokePlumes',\n            'airQuality',\n            'environmentImagery',\n        ]) {\n            this._environmentalOverlay.setLayerEnabled(id, getLabelCategoryValue(initialLabelSettings, id));\n        }\n        for (const id of [\n            'radiationObservations',\n            'radiationHeatmap',\n            'spaceRadiation',\n            'armedConflict',\n            'violentCrime',\n            'reportedExplosions',\n            'seismicEvents',\n            'volcanoes',\n            'tsunamiAlerts',\n            'multiHazards',\n        ]) {\n            this._globalSignalsOverlay.setLayerEnabled(id, getLabelCategoryValue(initialLabelSettings, id));\n        }\n\n        // Initialize sensor manager with all dependencies\n        if (!this._presentationMode) {\n            const sensorManager = getSensorManager();\n            sensorManager.init({\n                settings: this.sceneSettings,\n                apiService: getSensorApiService(),\n                eventStore: getSensorEventStore(),\n                overlay: this._sensorOverlay,\n            });\n        }\n\n        const infrastructureOptions = this._resolveInfrastructureOverlayOptions();\n        let infraBackendUrl = null;\n        try { infraBackendUrl = getBackendApiBase(); } catch { /* */ }\n        this._infrastructureOverlay = new InfrastructureOverlay({\n            parentGroup: this._triTree.group,\n            triTree: this._triTree,\n            camera: this._camera,\n            planetRadius: PLANET_RADIUS,\n            motionTracker: this._motionTracker,\n            // Pass the SurfaceController so resnaps see the\n            // photorealistic-tile surface (not just procedural triTree\n            // elevation). Without this, power / comms ribbons float\n            // above photoreal tiles where the photoreal surface is\n            // higher than the triTree procedural mesh.\n            surfaceController: this._surfaceController,\n            eventBus: this.eventBus,\n            sceneInitializer: this._sceneInitializer,\n            perf: this._perf,\n            backendUrl: infraBackendUrl,\n            ...infrastructureOptions,\n            terrainMode: this._triTree.suppressTileDisplay ? 'quadtree' : 'tritree'\n        });\n\n        // Restore saved utility layer toggles → OpenInfraMap groups (default ON)\n        const savedInfraLayers = this._presentationMode\n            ? {}\n            : ((this._sceneSettings?.getSection?.('scene.infrastructure') || {}).layers || {});\n        if (globalThis.__noclipDebugInfra === true) {\n            console.info('[PS] Saved infra layers on init:', JSON.stringify(savedInfraLayers));\n        }\n        this._scheduleOpenInfraMapRendererSetup(savedInfraLayers);\n\n        this._eventManager.setBuildingOverlay?.(this._buildingOverlay);\n        this._eventManager.setAircraftOverlay?.(this._aircraftOverlay);\n        this._eventManager.setSatelliteOverlay?.(this._satelliteOverlay);\n        this._eventManager.setMaritimeOverlay?.(this._maritimeOverlay);\n        this._eventManager.setIncidentOverlay?.(this._incidentOverlay);\n\n        this._applyWireframeStyle();\n\n        this._overlayRegistry.registerItemRenderer('building_overlay', (item) =>\n            createBuildingOverlayItem(item, this._buildingOverlay)\n        );\n        this._overlayRegistry.registerItemRenderer('buildings', (item) =>\n            createBuildingOverlayItem(item, this._buildingOverlay)\n        );\n        this._overlayRegistry.registerItemRenderer('theater', (item) =>\n            createTheaterOverlayItem(item, this._commsSystem, this._audioSystem)\n        );\n    }\n\n    async _ensureSatelliteOverlay(config = null) {\n        if (this._satelliteOverlay) {\n            if (config) this._satelliteOverlay.applyConfig?.(config);\n            return this._satelliteOverlay;\n        }\n        const SatelliteOverlay = await loadSatelliteOverlayClass();\n        const satelliteOptions = this.options?.satellites || {};\n        this._satelliteOverlay = new SatelliteOverlay({\n            parentGroup: this._triTree.group,\n            planetRadius: PLANET_RADIUS,\n            eventBus: this.eventBus,\n            sceneInitializer: this._sceneInitializer,\n            surfaceController: this._surfaceController,\n            ...satelliteOptions\n        });\n        this._eventManager.setSatelliteOverlay?.(this._satelliteOverlay);\n        const initialConfig = config || this._satelliteAutoConfig || null;\n        if (initialConfig) {\n            this._satelliteOverlay.applyConfig?.(initialConfig);\n        }\n        this._satelliteOverlay.setLabelsEnabled?.(getLabelCategoryValue(\n            this.settings?.getSection?.('scene.labels') || {}, 'satellites', true\n        ));\n        return this._satelliteOverlay;\n    }\n\n    async _ensureCommsSystem() {\n        if (this._commsSystem) return this._commsSystem;\n        if (!this._streamHub || !this._audioSystem) return null;\n        const CommsSystem = await loadCommsSystemClass();\n        const commsOptions = this.options?.comms || {};\n        const nknEnabled = this._sceneSettings?.getSection?.('nkn.enabled') === true;\n        this._commsSystem = new CommsSystem({\n            eventBus: this.eventBus,\n            streamHub: this._streamHub,\n            audioSystem: this._audioSystem,\n            ...commsOptions,\n            useP2P: nknEnabled && commsOptions.useP2P !== false,\n            peerManager: this._peerManager,\n            camera: this._camera,\n            voiceSettings: this._speakSettings\n        });\n        this._hydraOverlayIngress && (this._hydraOverlayIngress.commsSystem = this._commsSystem);\n        this._commsSystem.setVoiceSettings?.(this._speakSettings);\n        this._interopHarness.stages.commsReady = true;\n        this._interopHarness.last.commsSampleAt = Date.now();\n        this._interopHarness.updatedAt = Date.now();\n        return this._commsSystem;\n    }\n\n    _scheduleOpenInfraMapRendererSetup(layers = {}) {\n        if (!hasEnabledOpenInfraMapGroup(layers)) return;\n        const run = () => {\n            void this._ensureOpenInfraMapRenderer(layers).catch((err) => {\n                console.error('[PS] OpenInfraMapRenderer creation FAILED:', err);\n            });\n        };\n        if (typeof requestIdleCallback === 'function') {\n            requestIdleCallback(run, { timeout: 2500 });\n        } else {\n            setTimeout(run, 1500);\n        }\n    }\n\n    async _ensureOpenInfraMapRenderer(layers = null) {\n        if (this._openInfraMapRenderer) {\n            if (layers) this._applyOpenInfraMapLayers(layers);\n            return this._openInfraMapRenderer;\n        }\n        if (this._openInfraMapRendererPromise) {\n            const renderer = await this._openInfraMapRendererPromise;\n            if (layers) this._applyOpenInfraMapLayers(layers);\n            return renderer;\n        }\n        this._openInfraMapRendererPromise = (async () => {\n            const OpenInfraMapRenderer = await loadOpenInfraMapRendererClass();\n            const renderer = new OpenInfraMapRenderer({\n                parentGroup: this._triTree.group,\n                planetRadius: PLANET_RADIUS,\n                eventBus: this.eventBus,\n                surfaceController: this._surfaceController,\n                backendUrl: getBackendApiBase(),\n            });\n            renderer.setTriTree(this._triTree);\n            this._openInfraMapRenderer = renderer;\n            renderer.setRenderSuppressed?.(this._photoInfraSuppressed === true);\n            if (layers) this._applyOpenInfraMapLayers(layers);\n            if (globalThis.__noclipDebugInfra === true) {\n                console.info('[PS] OpenInfraMapRenderer created OK');\n            }\n            return renderer;\n        })().finally(() => {\n            this._openInfraMapRendererPromise = null;\n        });\n        return this._openInfraMapRendererPromise;\n    }\n\n    _applyOpenInfraMapLayers(layers = {}) {\n        if (!this._openInfraMapRenderer) return;\n        const groups = getEnabledOpenInfraMapGroups(layers);\n        this._openInfraMapRenderer.setEnabledGroups?.(groups);\n        if (globalThis.__noclipDebugInfra === true) {\n            console.info('[PS] OpenInfraMap groups:', groups.join(','));\n        }\n    }\n\n    _resolveInfrastructureOverlayOptions() {\n        const infrastructureOptions = { ...(this.options?.infrastructure || {}) };\n        const infrastructureSettings = this._sceneSettings?.getSection?.('scene.infrastructure') || {};\n        const infrastructureLayers = infrastructureSettings.layers || {};\n        const isObjectLike = (value) => !!value && typeof value === 'object';\n        const assignIfDefined = (key, value) => {\n            if (value !== undefined) {\n                infrastructureOptions[key] = value;\n            }\n        };\n\n        if (typeof infrastructureSettings.enabled === 'boolean') {\n            assignIfDefined('enabled', infrastructureSettings.enabled);\n        }\n\n        const numericKeys = [\n            'radiusM',\n            'refreshDistanceM',\n            'surfaceOffsetM',\n            'roadWidthScale',\n            'roadStepM',\n            'bridgeHeightM',\n            'ribbonThicknessM',\n            'resnapIntervalMs',\n            'resnapBudget',\n            'drapeBudget',\n            'alignFreezeFrames',\n            'alignToleranceM',\n            'alignSampleStepM',\n            'alignMaxSamples',\n            'pauseDistanceMultiplier',\n            'motionMinSpeedMps',\n            'motionSpeedRefMps',\n            'motionAheadFactor',\n            'motionBehindFactor',\n            'motionQueryBias',\n            'motionRetentionFactor'\n        ];\n        numericKeys.forEach((key) => {\n            if (Number.isFinite(infrastructureSettings[key])) {\n                assignIfDefined(key, infrastructureSettings[key]);\n            }\n        });\n\n        if (typeof infrastructureSettings.pauseWhenFar === 'boolean') {\n            assignIfDefined('pauseWhenFar', infrastructureSettings.pauseWhenFar);\n        }\n        if (infrastructureSettings.pauseDistanceM === null) {\n            assignIfDefined('pauseDistanceM', null);\n        } else if (Number.isFinite(infrastructureSettings.pauseDistanceM)) {\n            assignIfDefined('pauseDistanceM', infrastructureSettings.pauseDistanceM);\n        }\n        if (typeof infrastructureSettings.tileDrivenResnap === 'boolean') {\n            assignIfDefined('tileDrivenResnap', infrastructureSettings.tileDrivenResnap);\n        }\n        if (typeof infrastructureSettings.motionEnabled === 'boolean') {\n            assignIfDefined('motionEnabled', infrastructureSettings.motionEnabled);\n        }\n        if (isObjectLike(infrastructureSettings.colors)) {\n            assignIfDefined('colors', infrastructureSettings.colors);\n        }\n        if (isObjectLike(infrastructureSettings.paint)) {\n            assignIfDefined('paint', infrastructureSettings.paint);\n        }\n\n        const resolveLayer = (value, fallback) => (typeof value === 'boolean' ? value : fallback);\n        infrastructureOptions.roadsEnabled = resolveLayer(infrastructureLayers.roads, false);\n        infrastructureOptions.bridgesEnabled = resolveLayer(infrastructureLayers.bridges, false);\n        infrastructureOptions.waterwaysEnabled = resolveLayer(infrastructureLayers.waterways, false);\n        infrastructureOptions.areasEnabled = resolveLayer(infrastructureLayers.areas, false);\n        infrastructureOptions.railwaysEnabled = resolveLayer(infrastructureLayers.railways, false);\n\n        return infrastructureOptions;\n    }\n\n    _registerAutoOverlayConfigHandlers() {\n        // Listen for buildings config changes from UI.\n        this.eventBus.on('buildings:config', (config) => {\n            if (typeof config?.enabled === 'boolean') {\n                this._buildingAutoEnabled = config.enabled;\n                if (config.enabled) {\n                    this._buildingAutoCenter = null;\n                    this._buildingAutoHeadingDeg = null;\n                    this._buildingAutoRequestKey = null;\n                    this._buildingAutoRequestSeq += 1;\n                    this._buildingAutoElevationWaitUntil = 0;\n                    this._buildingAutoElevationWaitStart = 0;\n                }\n            }\n        });\n\n        this.eventBus.on('flights:config', (config) => {\n            if (!config) return;\n            if (typeof config.enabled === 'boolean') {\n                this._aircraftAutoEnabled = config.enabled;\n                if (config.enabled) {\n                    this._aircraftAutoCenter = null;\n                }\n            }\n            this._aircraftAutoConfig = { ...(this._aircraftAutoConfig || {}), ...config };\n            if (Number.isFinite(config.pollIntervalMs)) {\n                this._aircraftAutoPollIntervalMs = config.pollIntervalMs;\n            }\n        });\n\n        this.eventBus.on('satellites:config', (config) => {\n            if (!config) return;\n            if (typeof config.enabled === 'boolean') {\n                this._satelliteAutoEnabled = config.enabled;\n                if (config.enabled) {\n                    this._satelliteAutoCenter = null;\n                }\n            }\n            this._satelliteAutoConfig = { ...(this._satelliteAutoConfig || {}), ...config };\n            if (Number.isFinite(config.pollIntervalMs)) {\n                this._satelliteAutoPollIntervalMs = config.pollIntervalMs;\n            }\n            if (config.enabled || this._satelliteOverlay) {\n                void this._ensureSatelliteOverlay(config).catch((err) => {\n                    console.warn('[PlanetScene] Satellite overlay load failed:', err);\n                });\n            }\n        });\n\n        this.eventBus.on('maritime:config', (config) => {\n            if (!config) return;\n            if (typeof config.enabled === 'boolean') {\n                this._maritimeAutoEnabled = config.enabled;\n                if (config.enabled) {\n                    this._maritimeAutoCenter = null;\n                }\n            }\n            this._maritimeAutoConfig = { ...(this._maritimeAutoConfig || {}), ...config };\n            if (Number.isFinite(config.pollIntervalMs)) {\n                this._maritimeAutoPollIntervalMs = config.pollIntervalMs;\n            }\n        });\n\n        this.eventBus.on('incidents:config', (config) => {\n            if (!config) return;\n            if (typeof config.enabled === 'boolean') {\n                this._incidentAutoEnabled = config.enabled;\n                if (config.enabled) {\n                    this._incidentAutoCenter = null;\n                }\n            }\n            this._incidentAutoConfig = { ...(this._incidentAutoConfig || {}), ...config };\n            if (Number.isFinite(config.pollIntervalMs)) {\n                this._incidentAutoPollIntervalMs = config.pollIntervalMs;\n            }\n        });\n\n        this.eventBus.on('trafficCameras:config', (config) => {\n            this._trafficCameraOverlay?.applyConfig?.(config || {});\n        });\n\n        this.eventBus.on('roadTraffic:config', (config) => {\n            this._roadTrafficOverlay?.applyConfig?.(config || {});\n        });\n\n        this.eventBus.on('radioData:config', (config) => {\n            if (!config) return;\n            this._radioDataConfig = {\n                ...(this._radioDataConfig || {}),\n                ...config,\n                feeds: { ...(this._radioDataConfig?.feeds || {}), ...(config.feeds || {}) },\n            };\n            if (typeof config.enabled === 'boolean') {\n                this._radioDataAutoEnabled = config.enabled;\n                this._radioDataAutoCenter = null;\n            }\n            if (Number.isFinite(config.pollIntervalMs)) this._radioDataAutoPollIntervalMs = config.pollIntervalMs;\n            this._radioDataOverlay?.applyConfig?.(this._radioDataConfig);\n        });\n\n        this.eventBus.on('geocaches:config', (config) => {\n            if (!config) return;\n            this._geocacheConfig = { ...(this._geocacheConfig || {}), ...config };\n            if (typeof config.enabled === 'boolean') {\n                this._geocacheAutoEnabled = config.enabled;\n                this._geocacheAutoCenter = null;\n            }\n            if (Number.isFinite(config.pollIntervalMs)) {\n                this._geocacheAutoPollIntervalMs = config.pollIntervalMs;\n            }\n            this._geocacheLayer?.applyConfig?.(this._geocacheConfig);\n        });\n\n        this.eventBus.on('infrastructure:config', (config) => {\n            if (!config) return;\n            if (typeof config.enabled === 'boolean') {\n                this._infrastructureAutoEnabled = config.enabled;\n                if (config.enabled) {\n                    this._infrastructureAutoCenter = null;\n                    this._infrastructureAutoElevationWaitUntil = 0;\n                    this._infrastructureAutoElevationWaitStart = 0;\n                }\n            }\n            if (this._infrastructureOverlay) {\n                this._infrastructureOverlay.applyConfig(config);\n            }\n            if (\n                config.enabled === true &&\n                this._infrastructureAutoEnabled &&\n                this._infrastructureOverlay?.enabled &&\n                this._surfaceController?.isInSurfaceMode?.()\n            ) {\n                const hudStore = getHudInfoStore();\n                const lat = hudStore?.getData?.('nav.lat');\n                const lon = hudStore?.getData?.('nav.lon');\n                if (Number.isFinite(lat) && Number.isFinite(lon)) {\n                    this._setInfrastructureAutoCenter(lat, lon);\n                }\n            }\n        });\n\n        // OpenInfraMap MVT layer group toggles\n        this.eventBus.on('openInfraMap:config', (config) => {\n            if (globalThis.__noclipDebugInfra === true) {\n                console.info('[PS] openInfraMap:config event received:', JSON.stringify(config), 'renderer:', !!this._openInfraMapRenderer);\n            }\n            if (!config) return;\n            if (config.layers && typeof config.layers === 'object') {\n                if (!hasEnabledOpenInfraMapGroup(config.layers) && !this._openInfraMapRenderer) return;\n                void this._ensureOpenInfraMapRenderer().then((renderer) => {\n                    renderer?.setEnabledGroups?.(getEnabledOpenInfraMapGroups(config.layers));\n                }).catch((err) => {\n                    console.warn('[PlanetScene] OpenInfraMap renderer load failed:', err);\n                });\n                return;\n            }\n            if (config.group && typeof config.enabled === 'boolean') {\n                if (config.enabled !== true && !this._openInfraMapRenderer) return;\n                void this._ensureOpenInfraMapRenderer().then((renderer) => {\n                    renderer?.setGroupEnabled(config.group, config.enabled);\n                }).catch((err) => {\n                    console.warn('[PlanetScene] OpenInfraMap renderer load failed:', err);\n                });\n            }\n        });\n    }\n\n    start() {\n        if (!this.canEnter3D({ notify: false })) return false;\n        // Late boot work may reach scene.start() after camera ownership has\n        // already transferred to the phone. Remember that request, but never\n        // let it reacquire WebGL while camera-exclusive mode owns the view.\n        if (this._cameraExclusiveState) {\n            this._cameraExclusiveState.animationRequested = true;\n            return false;\n        }\n        if (this._mapPresentationMode === '2d') return false;\n        if (this._mapPresentationResources && !this._mapPresentationResources.active) {\n            const ready = this.whenMapPresentationReady();\n            if (this._mapResumeStartPromise !== ready) {\n                this._mapResumeStartPromise = ready;\n                ready.then(restored => {\n                    if (restored && this._mapResumeStartPromise === ready) this.start();\n                }).catch(error => console.warn('[PlanetScene] Scene texture restoration failed', error));\n            }\n            return false;\n        }\n        if (!this._animationLoop) return false;\n        this._weatherVolumeOverlay?.setSuspended(false);\n        this._animationLoop.start();\n        return true;\n    }\n\n    /**\n     * Start the streamed atmosphere while the boot overlay still owns the\n     * screen, then resolve only after the compositor has successfully owned a\n     * frame (or its explicit direct-render fallback is established).\n     */\n    prepareAtmosphereForSceneEntry({ timeoutMs = 60_000 } = {}) {\n        if (this._sceneEntryAtmospherePromise) {\n            return this._sceneEntryAtmospherePromise;\n        }\n\n        const initializer = this._sceneInitializer;\n        if (!initializer?.setAtmosphereCloudStreamingEnabled) {\n            return Promise.resolve({\n                ready: true,\n                active: false,\n                mode: 'direct-fallback',\n                reason: 'atmosphere-initializer-unavailable',\n            });\n        }\n\n        initializer.setAtmosphereCloudStreamingEnabled(true);\n        const startedAt = (typeof performance !== 'undefined'\n            && Number.isFinite(performance.now?.()))\n            ? performance.now()\n            : Date.now();\n        const boundedTimeoutMs = Math.max(1_000, Number(timeoutMs) || 60_000);\n\n        this._sceneEntryAtmospherePromise = new Promise((resolve) => {\n            const poll = () => {\n                const state = initializer.getAtmosphereSceneEntryState?.() || {\n                    ready: false,\n                    active: false,\n                    mode: 'loading',\n                    reason: 'readiness-state-unavailable',\n                };\n                const now = (typeof performance !== 'undefined'\n                    && Number.isFinite(performance.now?.()))\n                    ? performance.now()\n                    : Date.now();\n                const elapsedMs = Math.max(0, now - startedAt);\n                const snapshot = { ...state, elapsedMs };\n                globalThis.__noclipBootAtmosphereState = snapshot;\n\n                if (state.ready === true) {\n                    resolve(snapshot);\n                    return;\n                }\n                if (elapsedMs >= boundedTimeoutMs) {\n                    resolve({\n                        ...snapshot,\n                        ready: true,\n                        active: false,\n                        mode: 'direct-timeout',\n                        reason: 'atmosphere-entry-timeout',\n                        timedOut: true,\n                    });\n                    return;\n                }\n                setTimeout(poll, 100);\n            };\n            poll();\n        });\n        return this._sceneEntryAtmospherePromise;\n    }\n\n    /**\n     * Mark the scene as user-visible and begin a non-blocking search for a GPU\n     * quiet window in which the advanced atmosphere and remaining deferred\n     * visual streams can start. The direct shell already owns the first frame.\n     */\n    notifyInteractiveBootComplete() {\n        if (this._interactiveBootComplete) return;\n        this._interactiveBootComplete = true;\n\n        // Road traffic is a bounded, region-local request whose response feeds\n        // both the surface ribbon overlay and the minimap snapshot. Start it as\n        // soon as the scene is interactive instead of withholding it behind\n        // the atmosphere/cloud quiet-window gate below, which may legitimately\n        // wait while photoreal tiles continue to stream.\n        this._roadTrafficOverlay?.setInteractiveReady?.(true);\n\n        if (this._mapPresentationMode === '2d') {\n            // Full-window 2D still consumes shared labels and traffic data,\n            // but hidden WebGL presentation work must remain dormant until\n            // the user explicitly returns to 3D.\n            this._releaseDeferredMapDataStreaming();\n            return;\n        }\n\n        this._atmosphereCloudActivationStablePasses = 0;\n        this._atmosphereCloudActivationWindowStartedAt = typeof performance !== 'undefined' && Number.isFinite(performance.now?.())\n            ? performance.now()\n            : Date.now();\n        this._scheduleDeferredAtmosphereCloudActivation(750);\n    }\n\n    _releaseDeferredMapDataStreaming() {\n        if (this._deferredMapDataStreamingReady) return;\n        this._deferredMapDataStreamingReady = true;\n        this._geoJsonLayer?.setInteractiveReady?.(true);\n        this._geoJsonLookupLayer?.setInteractiveReady?.(true);\n        this._geoJsonAutoLayers?.forEach?.((layer) => layer?.setInteractiveReady?.(true));\n        this._trafficCameraOverlay?.setInteractiveReady?.(true);\n    }\n\n    _releaseDeferredVisualStreaming() {\n        if (this._deferredVisualStreamingReady) return;\n        this._deferredVisualStreamingReady = true;\n\n        // These systems are presentation enhancements, not prerequisites for\n        // the first navigable photoreal view. Releasing them together keeps\n        // large GeoJSON parses, texture decodes, PMREM generation, and cloud\n        // shader compilation out of the native tile download/parse window.\n        this._releaseDeferredMapDataStreaming();\n        this._sceneInitializer?.setEnvironmentStreamingEnabled?.(true);\n        if (this._overviewGlobeMode !== true) {\n            this._sceneInitializer?.setEarthOverlayStreamingEnabled?.(true);\n            // The full surface stack now owns the shared live cloud texture;\n            // release the temporary handoff lease only after that owner is on.\n            this._sceneInitializer?.setOrbitalOverviewStreamingEnabled?.(false);\n            this._scheduleOceanResolverSetup();\n        }\n        this._sceneInitializer?.setAtmosphereCloudStreamingEnabled?.(true);\n    }\n\n    _scheduleDeferredAtmosphereCloudActivation(delayMs = 500) {\n        if (!this._interactiveBootComplete\n            || this._mapPresentationMode === '2d'\n            || this._atmosphereCloudActivationTimer\n            || this._atmosphereCloudActivationIdleHandle !== null\n            || this._deferredVisualStreamingReady) {\n            return;\n        }\n\n        this._atmosphereCloudActivationTimer = setTimeout(() => {\n            this._atmosphereCloudActivationTimer = null;\n            const check = () => {\n                this._atmosphereCloudActivationIdleHandle = null;\n                this._atmosphereCloudActivationUsesIdleCallback = false;\n                if (!this._interactiveBootComplete || !this._sceneInitializer) return;\n\n                const photoLoader = this._photoTileLoader;\n                const photoCoverage = photoLoader?.enabled\n                    ? photoLoader.getCoverageState?.()\n                    : null;\n                const photoProviderBusy = this._photoInitializationInFlight === true\n                    || !!(photoCoverage && (\n                        photoCoverage.ready !== true\n                        || (photoCoverage.pendingCount || 0) > 24\n                        || (photoCoverage.preparingModelCount || 0) > 0\n                    ));\n\n                const now = (typeof performance !== 'undefined' && Number.isFinite(performance.now?.()))\n                    ? performance.now()\n                    : Date.now();\n                const waitLimitMs = 20_000;\n                const allowWaitTimeout = (this._atmosphereCloudActivationWindowStartedAt || 0) > 0\n                    && (now - this._atmosphereCloudActivationWindowStartedAt) >= waitLimitMs;\n\n                if (photoProviderBusy) {\n                    this._atmosphereCloudActivationStablePasses = 0;\n                    if (allowWaitTimeout) {\n                        if (this._sceneInitializer?.atmosphereCloudsFailed) {\n                            if (globalThis.__noclipDebugAtmosphere === true) {\n                                console.warn('[PlanetScene] Atmosphere cloud activation forcing recovery despite active photoreal queue');\n                            }\n                            this._sceneInitializer.atmosphereCloudsFailed = false;\n                        }\n                        this._releaseDeferredVisualStreaming();\n                        return;\n                    }\n                    this._scheduleDeferredAtmosphereCloudActivation(500);\n                    return;\n                }\n\n                // A single zero can occur between tile deliveries. Require two\n                // separate idle observations so cloud compilation cannot race\n                // the next decoded model into the same driver queue.\n                this._atmosphereCloudActivationStablePasses += 1;\n                if (this._atmosphereCloudActivationStablePasses < 2) {\n                    this._scheduleDeferredAtmosphereCloudActivation(500);\n                    return;\n                }\n\n                this._releaseDeferredVisualStreaming();\n            };\n\n            if (typeof requestIdleCallback === 'function') {\n                // A timeout is required here. Without one this callback never\n                // ran while photoreal tiles streamed continuously, so the\n                // waitLimitMs escape hatch below was never even evaluated and\n                // clouds could be withheld for minutes. `check` only reads\n                // coverage counters and flips a boolean, so running it on a\n                // busy frame is nearly free — the expensive work it authorizes\n                // is itself idle-sliced downstream.\n                this._atmosphereCloudActivationUsesIdleCallback = true;\n                this._atmosphereCloudActivationIdleHandle = requestIdleCallback(check, { timeout: 400 });\n            } else {\n                this._atmosphereCloudActivationIdleHandle = setTimeout(check, 32);\n            }\n        }, Math.max(0, delayMs));\n    }\n\n    _cancelDeferredAtmosphereCloudActivation() {\n        if (this._atmosphereCloudActivationTimer) {\n            clearTimeout(this._atmosphereCloudActivationTimer);\n            this._atmosphereCloudActivationTimer = null;\n        }\n        if (this._atmosphereCloudActivationIdleHandle !== null) {\n            if (this._atmosphereCloudActivationUsesIdleCallback\n                && typeof cancelIdleCallback === 'function') {\n                cancelIdleCallback(this._atmosphereCloudActivationIdleHandle);\n            } else {\n                clearTimeout(this._atmosphereCloudActivationIdleHandle);\n            }\n            this._atmosphereCloudActivationIdleHandle = null;\n            this._atmosphereCloudActivationUsesIdleCallback = false;\n        }\n    }\n\n    stop() {\n        this._weatherVolumeOverlay?.setSuspended(true);\n        this._suspendWeatherEffects();\n        if (this._animationLoop) {\n            this._animationLoop.stop();\n        }\n    }\n\n    /**\n     * Transfer presentation ownership to a phone camera. This is deliberately\n     * stronger than the map-mode suspend path: camera/video buffers arrive on\n     * top of WebGL memory, so all disposable terrain textures and descendants\n     * must be released before the stream becomes live.\n     */\n    async beginCameraExclusiveMode({ reason = 'camera', timeoutMs = 8000 } = {}) {\n        if (this._cameraExclusiveState?.phase === 'restoring') {\n            await this._cameraExclusiveState.restorationPromise;\n            return this.beginCameraExclusiveMode({ reason, timeoutMs });\n        }\n        if (this._cameraExclusiveState) {\n            await this._cameraExclusiveState.readyPromise;\n            return this._cameraExclusiveState;\n        }\n\n        const labelSystem = getLabelSystem();\n        const governance = getNoclipGovernanceClient();\n        const photoConfig = {\n            ...(this._sceneSettings?.getSection?.('scene.terrain.photorealistic') || {}),\n        };\n        const state = {\n            id: `camera-exclusive-${++this._cameraExclusiveSequence}`,\n            reason,\n            startedAt: Date.now(),\n            phase: 'quiescing',\n            animationWasRunning: this._animationLoop?.running === true,\n            animationRequested: false,\n            worldRootVisible: this._worldRoot?.visible !== false,\n            photoRequested: photoConfig.enabled === true || this._photoTileLoader?.enabled === true,\n            photoConfig,\n            elevationRasterEnabled: this._elevationClient?.enableMapzenRasterTiles !== false,\n            presentationWasSuspended: this._sceneInitializer?._presentationSuspended === true,\n            governanceWasCameraExclusive: governance.snapshot().cameraExclusive === true,\n            audioWasEnabled: this._audioSystem?.enabled === true && this._audioEnabledSetting !== false,\n            windWasEnabled: this._windAudio?.enabled === true,\n            labelToken: null,\n            imageryToken: null,\n            triTreeToken: null,\n            overlayToken: null,\n            diagnostics: {},\n            readyPromise: null,\n            restorationPromise: null,\n        };\n        this._cameraExclusiveState = state;\n\n        state.readyPromise = runCameraQuiescenceBarrier([\n            {\n                name: 'earth-renderer',\n                run: async () => {\n                    this._photoLifecycleGeneration += 1;\n                    this._clearPhotoSatelliteFallback();\n                    this._animationLoop?.stop?.();\n                    if (this._worldRoot) this._worldRoot.visible = false;\n                    this._sceneInitializer?.setPresentationSuspended?.(true);\n                    this._cancelDeferredAtmosphereCloudActivation();\n                    await Promise.resolve();\n                    return { rendererStopped: this._animationLoop?.running !== true };\n                },\n                verify: (result) => result.rendererStopped === true\n                    && this._worldRoot?.visible !== true,\n                describe: (result) => result,\n            },\n            {\n                name: 'render-network-scheduling',\n                run: async () => {\n                    governance.beginCameraExclusiveMode();\n                    await Promise.resolve();\n                    return { nonCameraRequestsBlocked: governance.snapshot().cameraExclusive === true };\n                },\n                verify: (result) => result.nonCameraRequestsBlocked === true,\n                describe: (result) => result,\n            },\n            {\n                name: 'labels',\n                run: () => {\n                    state.labelToken = labelSystem.beginCameraExclusiveMode?.() || null;\n                    return state.labelToken;\n                },\n                verify: () => labelSystem._cameraExclusiveState === state.labelToken,\n                describe: (token) => ({ releasedDomLabels: token?.releasedDomLabels || 0 }),\n            },\n            {\n                name: 'imagery',\n                run: () => {\n                    state.imageryToken = this._imageryManager?.suspendAndReleaseTransient?.() || null;\n                    return state.imageryToken;\n                },\n                verify: () => !this._imageryManager || this._imageryManager._resourceSuspended === true,\n            },\n            {\n                name: 'terrain-and-elevation',\n                run: () => {\n                    state.triTreeToken = this._triTree?.beginCameraExclusiveMode?.() || null;\n                    this._elevationClient?.setMapzenRasterTilesEnabled?.(false);\n                    this._elevationClient?.applyMemoryPressure?.(1);\n                    return state.triTreeToken;\n                },\n                verify: () => !this._triTree\n                    || (this._triTree.suspended === true && this._triTree.group?.visible === false),\n                describe: (token) => ({\n                    releasedTiles: token?.releasedTiles || 0,\n                    releasedPooledGeometries: token?.releasedPooledGeometries || 0,\n                }),\n            },\n            {\n                name: 'overlay-streaming',\n                run: async () => {\n                    state.overlayToken = await this._overlaySubsystem?.beginCameraExclusiveMode?.({\n                        timeoutMs: Math.min(3000, timeoutMs),\n                    }) || null;\n                    return state.overlayToken;\n                },\n                verify: (token) => !this._overlaySubsystem || token?.modelDecoderIdle === true,\n                describe: (token) => ({\n                    cancelledPageLoads: token?.cancelledPageLoads || 0,\n                    cancelledBuilds: token?.cancelledBuilds || 0,\n                    cancelledModelLoads: token?.cancelledModelLoads || 0,\n                }),\n            },\n            {\n                name: 'photoreal-tiles',\n                run: () => {\n                    this._disposePhotorealisticTiles();\n                    return { disposed: this._photoTileLoader === null };\n                },\n                verify: (result) => result.disposed === true,\n                describe: (result) => result,\n            },\n            {\n                name: 'ambient-and-spatial-audio',\n                run: async () => {\n                    await this._audioSystem?.setEnabled?.(false);\n                    this._windAudio?.setEnabled?.(false);\n                    return {\n                        spatialAudioStopped: this._audioSystem?.isEnabled?.() !== true,\n                        windAudioStopped: this._windAudio?.enabled !== true,\n                    };\n                },\n                verify: (result) => result.spatialAudioStopped && result.windAudioStopped,\n                describe: (result) => result,\n            },\n            {\n                name: 'quiescence-settlement',\n                run: () => new Promise((resolve) => setTimeout(resolve, 0)),\n                verify: () => this._animationLoop?.running !== true\n                    && this._photoTileLoader === null\n                    && governance.snapshot().cameraExclusive === true,\n            },\n        ], { timeoutMs }).then((diagnostics) => {\n            state.phase = 'quiescent';\n            state.diagnostics = diagnostics;\n            this.eventBus?.emit?.('camera:scene:quiesced', {\n                tokenId: state.id,\n                diagnostics,\n            });\n            return state;\n        });\n\n        try {\n            return await state.readyPromise;\n        } catch (error) {\n            state.diagnostics = error?.diagnostics || {\n                status: 'failed',\n                failedSubsystem: 'unknown',\n            };\n            this.eventBus?.emit?.('camera:scene:quiescence_failed', {\n                tokenId: state.id,\n                diagnostics: state.diagnostics,\n            });\n            await this.endCameraExclusiveMode(state, { immediate: true });\n            throw error;\n        }\n    }\n\n    async endCameraExclusiveMode(\n        state = this._cameraExclusiveState,\n        { immediate = false } = {},\n    ) {\n        if (!state || state !== this._cameraExclusiveState) return false;\n        if (state.restorationPromise) return state.restorationPromise;\n        state.phase = 'restoring';\n        const pause = (milliseconds) => immediate\n            ? Promise.resolve()\n            : new Promise((resolve) => setTimeout(resolve, milliseconds));\n\n        state.restorationPromise = (async () => {\n            if (this._worldRoot) this._worldRoot.visible = state.worldRootVisible;\n            if ((state.animationWasRunning || state.animationRequested)\n                && this._mapPresentationMode !== '2d') {\n                this._animationLoop?.start?.();\n            }\n            this.eventBus?.emit?.('camera:scene:restore_stage', {\n                tokenId: state.id,\n                stage: 'core-ui',\n            });\n\n            await pause(50);\n            this._imageryManager?.resumeTransientResources?.(state.imageryToken);\n            this._triTree?.resumeAfterCameraExclusiveMode?.(state.triTreeToken);\n            this._elevationClient?.setMapzenRasterTilesEnabled?.(state.elevationRasterEnabled);\n            this._elevationClient?.applyMemoryPressure?.(0);\n            if (!state.governanceWasCameraExclusive) getNoclipGovernanceClient().endCameraExclusiveMode();\n            this.eventBus?.emit?.('camera:scene:restore_stage', {\n                tokenId: state.id,\n                stage: 'base-context',\n            });\n\n            await pause(100);\n            getLabelSystem().resumeAfterCameraExclusiveMode?.(state.labelToken);\n            this._overlaySubsystem?.resumeAfterCameraExclusiveMode?.(\n                state.overlayToken || this._overlaySubsystem?._cameraExclusiveState,\n            );\n            if (state.audioWasEnabled) await this._audioSystem?.setEnabled?.(true);\n            this._windAudio?.setEnabled?.(state.windWasEnabled);\n            this.eventBus?.emit?.('camera:scene:restore_stage', {\n                tokenId: state.id,\n                stage: 'labels-and-layers',\n            });\n\n            await pause(250);\n            this._sceneInitializer?.setPresentationSuspended?.(state.presentationWasSuspended);\n            this._cameraExclusiveState = null;\n            if (state.photoRequested && this._mapPresentationMode !== '2d') {\n                void this._handlePhotorealisticToggle(true, state.photoConfig);\n            }\n            this.eventBus?.emit?.('camera:scene:restore_stage', {\n                tokenId: state.id,\n                stage: 'photoreal-refinement',\n            });\n            this.eventBus?.emit?.('camera:scene:resumed', {\n                tokenId: state.id,\n                durationMs: Math.max(0, Date.now() - state.startedAt),\n                restorationStrategy: immediate ? 'failure-rollback' : 'staged',\n            });\n            return true;\n        })();\n        return state.restorationPromise;\n    }\n\n    /**\n     * Transfer presentation ownership between the fullscreen 2D map and the\n     * 3D scene. Retain CPU model/source ownership, but retire recoverable GPU\n     * texture copies before the full-screen map starts allocating.\n     */\n    setMapPresentationMode(mode) {\n        const nextMode = String(mode || '').toLowerCase() === '2d' ? '2d' : '3d';\n        if (nextMode === '3d' && !this.canEnter3D()) return '2d';\n        const previousMode = this._mapPresentationMode;\n        this._mapPresentationMode = nextMode;\n        this._presenceSystem?.setMapPresentation(nextMode);\n        if (typeof window !== 'undefined') window.__noclipMapMode = nextMode;\n\n        const photoConfig = this._photoMapModeDeferredConfig\n            || this._sceneSettings?.getSection?.('scene.terrain.photorealistic')\n            || {};\n        const photoRequested = photoConfig.enabled === true;\n\n        if (nextMode === '2d') {\n            this._clearPhotoSatelliteFallback();\n            this._surfaceController?.resetKeyboardLook?.();\n            this.stop();\n            this._sceneInitializer?.setPresentationSuspended?.(true);\n            this._photoMapModeDeferred = photoRequested\n                || this._photoInitializationInFlight\n                || !!this._photoTileLoader?.hasLoadedTiles;\n            this._photoMapModeDeferredConfig = { ...photoConfig };\n            this._photoSurfaceEntryPending = null;\n            this._photoSurfaceEntryPhase = null;\n            this._photoInitializationPresentationHold = false;\n            this._photoTileLoader?.cancelSurfaceFocus?.();\n            this._setOverviewGlobeVisible(false);\n            this._suspendPhotorealisticTiles();\n            this._cancelDeferredAtmosphereCloudActivation();\n            if (this._renderer?.properties) {\n                this._mapPresentationResources ||= new MapPresentationResources(this._renderer);\n                const roots = [this._sceneInitializer?.scene];\n                this._photoTileLoader?._tiles?.forEachLoadedModel?.(root => roots.push(root));\n                const clouds = this._sceneInitializer?.atmosphereClouds;\n                const extras = [clouds?.clouds, clouds?._orbitCloudsEffect, clouds?.aerialPerspective]\n                    .flatMap(effect => clouds?._cloudEffectTextures?.(effect) || []);\n                this._mapPresentationReady = this._mapPresentationResources.park(roots, extras);\n                this._mapPresentationReady.catch(error => console.warn('[PlanetScene] Map texture retirement failed', error));\n            }\n            if (this._interactiveBootComplete) this._releaseDeferredMapDataStreaming();\n            return nextMode;\n        }\n\n        if (previousMode === '2d' || this._photoMapModeDeferred) {\n            const ready = this._mapPresentationReady = this._mapPresentationResources?.resume()\n                || Promise.resolve(true);\n            ready.then(restored => {\n                if (restored && this._mapPresentationMode === '3d' && this._mapPresentationReady === ready) {\n                    this._sceneInitializer?.setPresentationSuspended?.(false);\n                    // The fullscreen map may have moved the shared geographic\n                    // view while native 3D traversal was suspended. Publish\n                    // the final pose and invalidate retained tile demand only\n                    // after its GPU textures are restored.\n                    this._animationLoop?.syncCameraWorldPosition?.();\n                    this._photoTileLoader?.refreshView?.(this._camera, this._renderer);\n                }\n            }).catch(error => console.warn('[PlanetScene] Presentation resource handoff failed', error));\n            this._photoMapModeDeferred = false;\n            this._photoMapModeDeferredConfig = null;\n            if (photoRequested) {\n                const surfaceMode = this._surfaceController?.cameraMode === 'surface'\n                    || this._surfaceController?.cameraMode === 'toSurface';\n                if (surfaceMode) {\n                    this._beginPhotoSurfaceEntry(\n                        'map-mode-3d',\n                        this._surfaceController?.surfaceState?.up || null\n                    );\n                } else {\n                    void this._handlePhotorealisticToggle(true, photoConfig);\n                }\n            }\n            if (this._interactiveBootComplete && !this._deferredVisualStreamingReady) {\n                this._atmosphereCloudActivationStablePasses = 0;\n                this._atmosphereCloudActivationWindowStartedAt = typeof performance !== 'undefined'\n                    && Number.isFinite(performance.now?.())\n                    ? performance.now()\n                    : Date.now();\n                this._scheduleDeferredAtmosphereCloudActivation(250);\n            }\n        }\n        return nextMode;\n    }\n\n    whenMapPresentationReady() {\n        return this._mapPresentationReady || Promise.resolve(true);\n    }\n\n    dispose() {\n        void this._lunarFeatureLabels?.dispose();\n        this._sceneInitializer?.disposeSky?.();\n        this._mapPresentationResources?.dispose();\n        this._drawInteractionController?.dispose?.();\n        this.stop();\n        getLabelSystem().setTerrainOcclusionResolver(null);\n        this._interactiveBootComplete = false;\n        this._deferredMapDataStreamingReady = false;\n        this._deferredVisualStreamingReady = false;\n        this._sceneEntryAtmospherePromise = null;\n        this._cancelDeferredAtmosphereCloudActivation();\n        this._removeWebglPressureHandlers();\n        this._teardownUrlStateSync();\n        this._disposeOverviewGlobe();\n        this._overviewImageSource?.dispose();\n        this._toggleEarthOvertones(false);\n        this._removeAudioUnlockHandlers();\n        this._weatherSystem?.setEnabled?.(false);\n        this._sarControl?.destroy();\n        this._hdControl?.destroy();\n        this._sceneCanvasCapture?.dispose();\n        this._sceneInitializer?.clearHdSceneProxy?.();\n        this._rainSystem?.dispose();\n        this._windAudio?.dispose();\n        this._audioSystem?.dispose();\n        document.removeEventListener('visibilitychange', this._weatherVisibilityHandler);\n        this._presenceSystem?.disconnect();\n        if (this._interopHarnessStatsInterval) {\n            clearInterval(this._interopHarnessStatsInterval);\n            this._interopHarnessStatsInterval = null;\n        }\n        if (this.eventBus?.off && this._interopHarnessAckHandler) {\n            this.eventBus.off('hydra:overlay:ack', this._interopHarnessAckHandler);\n            this._interopHarnessAckHandler = null;\n        }\n        if (this.eventBus?.off && this._interopHarnessAppliedHandler) {\n            this.eventBus.off('hydra:overlay:ingress:applied', this._interopHarnessAppliedHandler);\n            this._interopHarnessAppliedHandler = null;\n        }\n        if (this.eventBus?.off && this._interopHarnessCommsFailureHandler) {\n            this.eventBus.off('comms:interop:failure', this._interopHarnessCommsFailureHandler);\n            this._interopHarnessCommsFailureHandler = null;\n        }\n        this._hydraOverlayIngress?.dispose?.();\n        this._commsSystem?.dispose();\n        this._disposePhotorealisticTiles();\n        this._syncCheckpoint();\n        this._stopCheckpointPersistence();\n        this._elevationClient?.dispose?.();\n        this._motionRuntime?.dispose?.();\n        this._motionRuntime = null;\n        this._motionPreviewSignatures?.clear?.();\n        this._localPlayer?.dispose();\n        this._peerManager?.dispose();\n        this._vrManager?.dispose();\n        this._xrDiagnostics?.dispose();\n        this._browserPerformanceTelemetry?.dispose?.();\n        this._browserPerformanceTelemetry = null;\n        if (window.__noclipXRDiagnostics === this._xrDiagnostics) delete window.__noclipXRDiagnostics;\n        this._vrAccessGate?.dispose?.();\n        this._vrAccessGate = null;\n        if (this._vrAccessRevocationHandler) {\n            this.eventBus?.off?.('vr:access-update', this._vrAccessRevocationHandler);\n            this._vrAccessRevocationHandler = null;\n        }\n        getBusinessLabels().dispose();\n        this._fieldAssetLayer?.dispose?.();\n        this._fieldAssetLayer = null;\n        this._accountNoteLayer?.dispose?.();\n        this._accountNoteLayer = null;\n        this._routeProgressTracker?.dispose?.();\n        this._routeRibbon?.dispose?.();\n        this._placeSearchSurface?.dispose(); this._placeSearchSurface = null;\n        this._sceneInitializer?.oceanSurface?.dispose();\n        this._sceneInitializer?.regionalWaterMask?.dispose();\n        this._sceneInitializer?._solarOpticsRenderer?.dispose();\n        this._sceneInitializer?._photorealInteriorRenderer?.dispose();\n        if (this._sceneInitializer?._waterAttribution) this._sceneInitializer._waterAttribution.hidden = true;\n        if (this._sceneInitializer) this._sceneInitializer.oceanSurface = null;\n        if (this._sceneInitializer?._oceanContextGuard) document.removeEventListener('noclip:webglcontextlost', this._sceneInitializer._oceanContextGuard);\n        this._roadContext?.dispose?.();\n        this._roadContext = null;\n        this._scenePuppet?.dispose?.();\n        this._scenePuppet = null;\n        this._buildingOverlay?.dispose();\n        this._aircraftOverlay?.dispose();\n        this._satelliteOverlay?.dispose();\n        this._maritimeOverlay?.dispose();\n        this._incidentOverlay?.dispose();\n        this._trafficCameraOverlay?.dispose();\n        this._roadTrafficOverlay?.dispose();\n        this._roadTrafficOverlay = null;\n        this._sensorOverlay?.dispose();\n        this._radioDataOverlay?.dispose();\n        this._geocacheLayer?.dispose();\n        this._geocacheLayer = null;\n        this._meshtasticOverlay?.dispose();\n        this._meshtasticOverlay = null;\n        this._globalSignalsOverlay?.dispose();\n        this._globalSignalsOverlay = null;\n        this._weatherVolumeOverlay?.dispose();\n        this._weatherVolumeOverlay=null;\n        this._environmentalOverlay?.dispose();\n        this._environmentalOverlay = null;\n        getSensorManager()?.dispose?.();\n        this._infrastructureOverlay?.dispose();\n        this._overlaySubsystem?.dispose?.();\n        this._accessController?.dispose?.();\n        this._geoJsonLayer?.dispose();\n        this._geoJsonLookupLayer?.dispose();\n        if (this._viewshedHighlightGroup && this._viewshedHighlightGroup.parent) {\n            this._viewshedHighlightGroup.parent.remove(this._viewshedHighlightGroup);\n        }\n        if (this._viewshedHighlightRings) {\n            this._viewshedHighlightRings.forEach((mesh) => {\n                if (mesh.geometry) mesh.geometry.dispose();\n                if (mesh.material && mesh.material.dispose) mesh.material.dispose();\n            });\n        }\n        this._viewshedHighlightGroup = null;\n        this._viewshedHighlightRings = null;\n        if (this._geoJsonAutoLayers) {\n            this._geoJsonAutoLayers.forEach((layer) => layer?.dispose?.());\n            this._geoJsonAutoLayers.clear();\n        }\n        this.api = null;\n    }\n\n    getState() {\n        return this.captureViewState();\n    }\n\n    restoreState(snapshot) {\n        if (!snapshot) return;\n        try {\n            localStorage.setItem('nkn.globe.state', JSON.stringify(snapshot));\n        } catch (error) {\n            this.eventBus.emit('scene:error', { error, scope: 'restoreState' });\n        }\n        this._restoreViewState();\n    }\n\n    _getInteropHarnessState() {\n        const state = this._interopHarness || {};\n        return JSON.parse(JSON.stringify(state));\n    }\n\n    _resetInteropHarnessState() {\n        const now = Date.now();\n        this._interopHarness = {\n            createdAt: now,\n            updatedAt: now,\n            stages: {\n                overlaySubsystemReady: !!this._overlaySubsystem,\n                streamHubReady: !!this._streamHub,\n                commsReady: !!this._commsSystem\n            },\n            counters: {\n                overlayApplied: 0,\n                overlayErrors: 0,\n                locationPackets: 0,\n                commsSamples: 0,\n                commsFailures: 0\n            },\n            last: {\n                overlayAppliedAt: 0,\n                overlayAckAt: 0,\n                overlayErrorAt: 0,\n                locationPacketAt: 0,\n                commsSampleAt: 0,\n                commsTransport: '',\n                commsConnected: false,\n                commsFailureAt: 0,\n                commsFailureCode: '',\n                commsFailureScope: '',\n                commsFallbackCount: 0,\n                commsTicketReplayRejected: 0,\n                commsRateLimitedCount: 0,\n                commsFraudBlockedCount: 0,\n                commsKillSwitchBlockedCount: 0\n            }\n        };\n        return this._getInteropHarnessState();\n    }\n\n    _buildApi() {\n        if (!this._scenePuppet) {\n            this._scenePuppet = new ScenePuppetController({\n                routeStore: this._routeStore,\n                routeProgressTracker: this._routeProgressTracker,\n                applyPose: ({ lat, lon, bearingDeg, altitudeM }) => {\n                    const controller = this._surfaceController;\n                    if (!controller) return false;\n                    const yaw = (Number(bearingDeg) || 0) * DEG2RAD;\n                    if (controller.getCameraMode?.() !== 'surface') {\n                        controller.initializeSurfaceModeFromLatLon(lat, lon, null, yaw, 0, altitudeM);\n                    } else {\n                        controller.surfaceState.yaw = yaw;\n                        controller.surfaceState.pitch = 0;\n                        controller.updateSurfaceFromLatLon(lat, lon, altitudeM);\n                    }\n                    return true;\n                },\n            });\n            if (typeof window !== 'undefined') window.__noclipScenePuppet = this._scenePuppet;\n        }\n        return {\n            tuneables: {\n                get: () => this._sceneSettings?.getProjection?.('read')?.scene || {},\n                set: (partial) => {\n                    if (this._sceneSettings?.updateScene) {\n                        return this._sceneSettings.updateScene(partial);\n                    }\n                    return { applied: false, rejected: [{ path: '', reason: 'settings policy unavailable' }] };\n                }\n            },\n            cache: {\n                getStats: () => {\n                    const replayStats = this._triTree?._snapshotReplayStats || null;\n                    return {\n                        imagery: this._imageryManager?.getStats?.() || null,\n                        elevation: this._elevationClient?.getStats?.() || null,\n                        stateStore: this._sceneStateStore?.getStats?.() || null,\n                        replay: replayStats ? { ...replayStats } : null\n                    };\n                },\n                flush: async () => {\n                    this._checkpoint();\n                }\n            },\n            // Browser/debug-agent surface. This is intentionally separate from\n            // normal `navigate_to`: it can drive the camera along a route at a\n            // bounded speed and exposes explicit stop/status controls.\n            puppet: {\n                driveTo: (options) => this._scenePuppet.driveTo(options),\n                start: (route, options) => this._scenePuppet.start(route, options),\n                advance: (seconds) => this._scenePuppet.advance(seconds),\n                simulate: (route, options) => this._scenePuppet.simulate(route, options),\n                stop: (reason) => this._scenePuppet.stop(reason),\n                getStatus: () => this._scenePuppet.getStatus(),\n            },\n            interop: {\n                getHarnessState: () => this._getInteropHarnessState(),\n                resetHarnessState: () => this._resetInteropHarnessState(),\n                getContract: () => ({\n                    name: HYDRA_INTEROP_CONTRACT.name,\n                    version: HYDRA_INTEROP_CONTRACT.version,\n                    compat_min_version: HYDRA_INTEROP_CONTRACT.compatMinVersion,\n                    namespace: HYDRA_INTEROP_CONTRACT.namespace,\n                    schema: HYDRA_INTEROP_CONTRACT.schema\n                }),\n                getContractStatus: () => {\n                    const ingress = this._hydraOverlayIngress?.getInteropStatus?.() || null;\n                    const comms = this._commsSystem?.getInteropTelemetry?.() || null;\n                    return {\n                        expected: {\n                            name: HYDRA_INTEROP_CONTRACT.name,\n                            version: HYDRA_INTEROP_CONTRACT.version,\n                            compat_min_version: HYDRA_INTEROP_CONTRACT.compatMinVersion,\n                            namespace: HYDRA_INTEROP_CONTRACT.namespace,\n                            schema: HYDRA_INTEROP_CONTRACT.schema\n                        },\n                        ingress,\n                        comms\n                    };\n                },\n                getUsageAttribution: (limit = 30) => (\n                    this._commsSystem?.getMarketplaceUsageAttribution?.(limit) || []\n                ),\n                recordUsageAttribution: (event = {}) => (\n                    this._commsSystem?.recordMarketplaceUsageAttribution?.(event) || null\n                ),\n                getUsageDiagnostics: (limit = 30) => ({\n                    telemetry: this._commsSystem?.getInteropTelemetry?.() || null,\n                    usage: this._commsSystem?.getMarketplaceUsageAttribution?.(limit) || [],\n                    failures: {\n                        fallbackCount: Number(this._commsSystem?.getInteropTelemetry?.()?.fallbackCount || 0),\n                        ticketReplayRejected: Number(this._commsSystem?.getInteropTelemetry?.()?.ticketReplayRejected || 0),\n                        rateLimitedCount: Number(this._commsSystem?.getInteropTelemetry?.()?.rateLimitedCount || 0),\n                        fraudBlockedCount: Number(this._commsSystem?.getInteropTelemetry?.()?.fraudBlockedCount || 0),\n                        killSwitchBlockedCount: Number(this._commsSystem?.getInteropTelemetry?.()?.killSwitchBlockedCount || 0),\n                        lastFailureCode: String(this._commsSystem?.getInteropTelemetry?.()?.lastFailureCode || ''),\n                        lastFailureScope: String(this._commsSystem?.getInteropTelemetry?.()?.lastFailureScope || ''),\n                        lastFailureAt: Number(this._commsSystem?.getInteropTelemetry?.()?.lastFailureAt || 0),\n                    },\n                }),\n                getFailureTelemetry: () => ({\n                    interop: this._commsSystem?.getInteropTelemetry?.() || null,\n                    harness: this._getInteropHarnessState(),\n                }),\n                validateEnvelope: (envelope) => normalizeInteropEnvelope(envelope, {\n                    expectedContract: HYDRA_INTEROP_CONTRACT,\n                    requireTypeOrEvent: true\n                }),\n                markCheckpoint: (label) => {\n                    const key = String(label || 'manual');\n                    this._interopHarness.last[key] = Date.now();\n                    this._interopHarness.updatedAt = Date.now();\n                    return this._getInteropHarnessState();\n                }\n            },\n            motion: {\n                get: () => this._motionTracker?.getState() || null,\n                on: (handler) => {\n                    if (typeof handler !== 'function') return () => {};\n                    this.eventBus?.on('motion:update', handler);\n                    return () => this.eventBus?.off('motion:update', handler);\n                },\n                load: (descriptor) => this._motionRuntime?.loadCompiledExecution(descriptor) || null,\n                play: (id, generation) => this._motionRuntime?.play(id, generation) || null,\n                pause: (id, generation) => this._motionRuntime?.pause(id, generation) || null,\n                resume: (id, generation) => this._motionRuntime?.resume(id, generation) || null,\n                seek: (id, timeMs, options) => this._motionRuntime?.seek(id, timeMs, options) || null,\n                cancel: (id, reason, generation) => this._motionRuntime?.cancel(id, reason, generation) || false,\n                release: (id, reason, generation) => this._motionRuntime?.release(id, reason, generation) || false,\n                execution: (id) => this._motionRuntime?.getExecutionSnapshot(id) || null,\n                runtime: () => this._motionRuntime?.getRuntimeSnapshot() || null,\n                simulatedDevice: (id) => this._motionRuntime?.simulatedDevices?.getSnapshot?.(id) || null,\n                previewPath: ({ executionId, compiled, overlayId, timeMs = 0, play = false } = {}) => {\n                    if (!this._motionRuntime || !executionId || !compiled) return { applied: false, reason: 'MOTION_RUNTIME_UNAVAILABLE' };\n                    const signature = JSON.stringify(compiled.definition);\n                    let snapshot = this._motionRuntime.getExecutionSnapshot(executionId);\n                    if (!snapshot || ['completed', 'cancelled', 'failed'].includes(snapshot.state)\n                        || this._motionPreviewSignatures.get(executionId) !== signature) {\n                        snapshot = this._motionRuntime.loadCompiledExecution({\n                            id: executionId,\n                            compiled,\n                            mode: 'preview',\n                            timeMs,\n                            restoreOnComplete: true,\n                            targetContext: { overlayId },\n                        });\n                        this._motionPreviewSignatures.set(executionId, signature);\n                    }\n                    if (play) snapshot = this._motionRuntime.play(executionId, snapshot.generation);\n                    else {\n                        if (snapshot.state === 'created') snapshot = this._motionRuntime.pause(executionId, snapshot.generation);\n                        else if (snapshot.state === 'running') snapshot = this._motionRuntime.pause(executionId, snapshot.generation);\n                        snapshot = this._motionRuntime.seek(executionId, timeMs, { expectedGeneration: snapshot.generation });\n                    }\n                    return { applied: true, queued: true, executionId, generation: snapshot.generation, state: snapshot.state };\n                },\n                stopPreview: (executionId, reason = 'PREVIEW_STOPPED') => {\n                    this._motionPreviewSignatures.delete(executionId);\n                    return this._motionRuntime?.release(executionId, reason) || false;\n                },\n            },\n            mobileVr: {\n                isEnabled: () => this._mobileStereoRenderer?.isEnabled() || false,\n                enter: async () => {\n                    if (!this._mobileStereoRenderer) return false;\n                    const decision = await this._vrAccessGate?.check?.();\n                    if (decision && !decision.allowed) {\n                        return this._vrAccessGate.deny(decision, 'mobile-stereo');\n                    }\n                    this._mobileStereoRenderer.setEnabled(true);\n                    return true;\n                },\n                exit: () => this._mobileStereoRenderer?.setEnabled(false),\n                toggle: async () => {\n                    if (!this._mobileStereoRenderer) return false;\n                    if (this._mobileStereoRenderer.isEnabled()) {\n                        this._mobileStereoRenderer.setEnabled(false);\n                        return true;\n                    }\n                    const decision = await this._vrAccessGate?.check?.();\n                    if (decision && !decision.allowed) {\n                        return this._vrAccessGate.deny(decision, 'mobile-stereo');\n                    }\n                    this._mobileStereoRenderer.setEnabled(true);\n                    return true;\n                },\n                setIPD: (value) => this._mobileStereoRenderer?.setIPD(value),\n                getIPD: () => this._mobileStereoRenderer?.getIPD() ?? 0.06\n            },\n            overlays: {\n                ...createOverlaySceneApi(() => this._overlaySubsystem),\n                ingress: async (envelope, meta = {}) => {\n                    const result = await this._hydraOverlayIngress?.ingest?.(envelope, meta);\n                    if (!result) {\n                        return {\n                            ok: false,\n                            error: 'overlay ingress unavailable',\n                            error_code: 'INGRESS_UNAVAILABLE',\n                            status_code: 503\n                        };\n                    }\n                    if (result.ok === false) {\n                        this.eventBus?.emit?.('hydra:overlay:ingress:denied', {\n                            envelope: envelope || null,\n                            meta: meta || {},\n                            error: String(result.error || ''),\n                            error_code: String(result.error_code || ''),\n                            status_code: Number(result.status_code || 0) || 0,\n                        });\n                    }\n                    return result;\n                },\n                registerIngressSession: (session) => this._hydraOverlayIngress?.registerSession?.(session),\n                getIngress: () => this._hydraOverlayIngress,\n                highlightItem: (itemId, opts) => this._setOverlayItemHighlight(itemId, opts),\n                clearItemHighlight: () => this._clearOverlayItemHighlight()\n            },\n            buildings: {\n                load: (opts) => this._buildingOverlay?.load(opts),\n                setCenter: (lat, lon, opts) => this._buildingOverlay?.setCenter(lat, lon, opts),\n                refresh: () => this._buildingOverlay?.refresh(),\n                clear: () => this._buildingOverlay?.clear(),\n                dispose: () => this._buildingOverlay?.dispose()\n            },\n            places: {\n                ingest: (entities, options = {}) => {\n                    const labels = getBusinessLabels({\n                        planetRadius: PLANET_RADIUS,\n                        eventBus: this.eventBus,\n                        parentGroup: this._triTree?.group,\n                        planetGroup: this._triTree?.group,\n                        mobile: this._isMobile,\n                    });\n                    labels.setEnabled?.(true, { clearEntries: false });\n                    if (Number.isFinite(options?.radiusM)) {\n                        labels.radiusM = Math.max(labels.radiusM || 0, Number(options.radiusM));\n                    }\n                    labels.ingestBusinesses?.(entities, {\n                        centerLat: Number.isFinite(options?.centerLat) ? options.centerLat : null,\n                        centerLon: Number.isFinite(options?.centerLon) ? options.centerLon : null,\n                        prune: false,\n                    });\n                    this.eventBus?.emit?.('agent:entities:captured', {\n                        count: Array.isArray(entities) ? entities.length : 0,\n                        source: options?.source || 'Agent discovery',\n                        requestedKind: options?.requestedKind || '',\n                    });\n                    return {\n                        ok: true,\n                        count: Array.isArray(entities) ? entities.length : 0,\n                    };\n                },\n                clear: () => getBusinessLabels().clear?.(),\n                list: () => getBusinessLabels().getEntriesSnapshot?.() || [],\n            },\n            flights: {\n                setCenter: (lat, lon, opts) => this._aircraftOverlay?.setCenter(lat, lon, opts),\n                refresh: () => this._aircraftOverlay?.refresh(),\n                clear: () => this._aircraftOverlay?.clear(),\n                dispose: () => this._aircraftOverlay?.dispose(),\n                list: () => this._aircraftOverlay?.getEntriesSnapshot?.() || []\n            },\n            satellites: {\n                setCenter: async (lat, lon, opts) => {\n                    const overlay = await this._ensureSatelliteOverlay({ enabled: true });\n                    overlay?.setCenter(lat, lon, opts);\n                },\n                refresh: async () => {\n                    const overlay = await this._ensureSatelliteOverlay({ enabled: true });\n                    overlay?.refresh();\n                },\n                clear: () => this._satelliteOverlay?.clear(),\n                dispose: () => this._satelliteOverlay?.dispose(),\n                list: () => this._satelliteOverlay?.getEntriesSnapshot?.() || []\n            },\n            maritime: {\n                setCenter: (lat, lon, opts) => this._maritimeOverlay?.setCenter(lat, lon, opts),\n                refresh: () => this._maritimeOverlay?.refresh(),\n                clear: () => this._maritimeOverlay?.clear(),\n                dispose: () => this._maritimeOverlay?.dispose(),\n                list: () => this._maritimeOverlay?.getEntriesSnapshot?.() || []\n            },\n            incidents: {\n                setCenter: (lat, lon, opts) => this._incidentOverlay?.setCenter(lat, lon, opts),\n                refresh: () => this._incidentOverlay?.refresh(),\n                clear: () => this._incidentOverlay?.clear(),\n                dispose: () => this._incidentOverlay?.dispose(),\n                list: () => this._incidentOverlay?.getEntriesSnapshot?.() || []\n            },\n            trafficCameras: {\n                refresh: () => this._trafficCameraOverlay?.refresh?.(),\n                list: () => this._trafficCameraOverlay?.getEntriesSnapshot?.() || [],\n                status: () => this._trafficCameraOverlay?.getDiscoverySnapshot?.() || {}\n            },\n            roadTraffic: {\n                refresh: () => this._roadTrafficOverlay?.refresh?.(),\n                list: () => this._roadTrafficOverlay?.getEntriesSnapshot?.() || [],\n                events: () => this._roadTrafficOverlay?.getEventsSnapshot?.() || [],\n                status: () => this._roadTrafficOverlay?.getStatusSnapshot?.() || {}\n            },\n            sensors: {\n                getOverlay: () => this._sensorOverlay,\n                getManager: () => getSensorManager(),\n                getStatus: () => getSensorManager()?.getStatus?.() || {},\n            },\n            radioData: {\n                setCenter: (lat, lon, opts) => this._radioDataOverlay?.setCenter?.(lat, lon, opts),\n                refresh: () => this._radioDataOverlay?.refresh?.({ force: true }),\n                clear: () => this._radioDataOverlay?.clear?.(),\n                list: () => this._radioDataOverlay?.getSnapshot?.()?.items || [],\n                status: () => this._radioDataOverlay?.getSnapshot?.() || {},\n                applyConfig: (config) => this._radioDataOverlay?.applyConfig?.(config),\n            },\n            geocaches: {\n                setCenter: (lat, lon, opts) => this._geocacheLayer?.setCenter?.(lat, lon, opts),\n                refresh: () => this._geocacheLayer?.refresh?.({ force: true }),\n                clear: () => this._geocacheLayer?.clear?.(),\n                list: () => this._geocacheLayer?.getSnapshot?.()?.records || [],\n                status: () => this._geocacheLayer?.getSnapshot?.() || {},\n                applyConfig: (config) => this._geocacheLayer?.applyConfig?.(config),\n            },\n            meshtastic: {\n                setEnabled: (enabled) => this._meshtasticOverlay?.setEnabled?.(enabled),\n                setLabelsEnabled: (enabled) => this._meshtasticOverlay?.setLabelsEnabled?.(enabled),\n                list: () => this._meshtasticOverlay?.getEntriesSnapshot?.() || [],\n                getMarkers: () => this._meshtasticOverlay?.getMiniMapMarkers?.() || [],\n            },\n            infrastructure: {\n                setCenter: (lat, lon, opts) => this._infrastructureOverlay?.setCenter(lat, lon, opts),\n                refresh: () => this._infrastructureOverlay?.refresh(),\n                clear: () => this._infrastructureOverlay?.clear(),\n                dispose: () => this._infrastructureOverlay?.dispose(),\n                setLayerEnabled: (layer, enabled) => this._infrastructureOverlay?.setLayerEnabled(layer, enabled),\n                isLayerEnabled: (layer) => this._infrastructureOverlay?.isLayerEnabled(layer) ?? false,\n                getConfig: () => this._infrastructureOverlay?.getConfig() || {},\n                applyConfig: (config) => this._infrastructureOverlay?.applyConfig(config)\n            },\n            openInfraMap: {\n                setGroupEnabled: async (code, enabled) => (await this._ensureOpenInfraMapRenderer())?.setGroupEnabled(code, enabled),\n                isGroupEnabled: (code) => this._openInfraMapRenderer?.isGroupEnabled(code) ?? false,\n                status: () => this._openInfraMapRenderer?.getStatus?.() || {\n                    enabled: false,\n                    enabledGroups: [],\n                    visible: false,\n                    loadedTileCount: 0,\n                    meshCount: 0,\n                    pointCloudCount: 0,\n                },\n                clear: () => this._openInfraMapRenderer?.clear(),\n                dispose: () => this._openInfraMapRenderer?.dispose(),\n            },\n            // Earth-world daemons — black-satin avatar companion that\n            // teleports to the user, follows them, briefs them via\n            // server-side TTS + 3D speech bubble. Reuses the player\n            // avatar's character model + animation rig.\n            daemon: {\n                summon: (opts) => this._earthDaemonManager?.summon(opts),\n                brief: (text) => this._earthDaemonManager?.brief(text),\n                dismiss: () => this._earthDaemonManager?.dismiss(),\n                navigateTo: (opts) => this._earthDaemonManager?.navigateTo(opts),\n                look: (opts) => this._earthDaemonManager?.look(opts),\n                startDriver: (opts) => this._earthDaemonManager?.startDriver(opts),\n                stopDriver: (reason) => this._earthDaemonManager?.stopDriver(reason),\n                getDriverStatus: () => this._earthDaemonManager?.getDriverStatus() || { active: false },\n                getStatus: () => this._earthDaemonManager?.getStatus() || { active: false },\n                isReady: () => !!this._earthDaemonManager?.isReady?.(),\n            },\n            // Metaverse / Black Sun controls. Exposed to the agent\n            // intent registry so the in-app assistant can drop the\n            // user on the Street and (with proper credentials) take\n            // them across the threshold without leaving the chat.\n            metaverse: {\n                getMode: () => this._sceneMode,\n                getPort: () => this._metaversePort,\n                isInMetaverse: () => this._sceneMode === 'metaverse',\n                enter: (port = 0) => {\n                    const idx = Number.isFinite(port) ? Math.max(0, Math.min(65535, Math.floor(port))) : 0;\n                    this._metaversePort = idx;\n                    this.setSceneMode('metaverse');\n                    if (this._metaverseScene) {\n                        this._metaverseScene.spawnAtPort(idx);\n                    }\n                    return { mode: this._sceneMode, port: idx };\n                },\n                exit: () => {\n                    this.setSceneMode('earth');\n                    return { mode: this._sceneMode };\n                },\n                attemptThresholdCross: async ({ wallet, invite, currentTier } = {}) => {\n                    if (this._sceneMode !== 'metaverse' || !this._metaverseScene) {\n                        return { admitted: false, reason: 'not-in-metaverse' };\n                    }\n                    return await this._metaverseScene.attemptThresholdCross({ wallet, invite, currentTier });\n                },\n                exitBlackSun: () => {\n                    if (!this._metaverseScene) return { exited: false };\n                    this._metaverseScene.exitBlackSun();\n                    return { exited: true };\n                },\n                isAdmitted: () => !!this._metaverseScene?.isAdmitted?.(),\n            },\n            viewshed: {\n                snapshot: (options = {}) => this._buildAgentViewshedSnapshot(options),\n                getEntityDetails: (id, category = null) => this._getAgentViewshedEntityDetails(id, category),\n                highlight: (listKey, data) => this._setViewshedHighlight(listKey, data, 'viewshed'),\n                clearHighlight: () => this._clearViewshedHighlight()\n            },\n            streams: {\n                register: (name, source) => this._streamHub?.register(name, source),\n                push: (name, payload) => this._streamHub?.push(name, payload),\n                status: (name) => this._streamHub?.status(name) || { connected: false, buffered: 0, dropped: 0 }\n            },\n            comms: {\n                requestCall: async (targetUserId, opts) => (await this._ensureCommsSystem())?.requestCall(targetUserId, opts),\n                acceptCall: async (callId) => (await this._ensureCommsSystem())?.acceptCall(callId),\n                declineCall: async (callId) => (await this._ensureCommsSystem())?.declineCall(callId),\n                hangupCall: async (callId, reason) => (await this._ensureCommsSystem())?.hangupCall(callId, reason),\n                getCall: (callId) => this._commsSystem?.getCall(callId),\n                getStats: () => this._commsSystem?.getStats() || null,\n                getVideoStream: (streamId) => this._commsSystem?.getVideoStream(streamId),\n                getVideoTexture: (streamId) => this._commsSystem?.getVideoTexture(streamId),\n                getLocalVideoStream: (callId) => this._commsSystem?.getLocalVideoStream(callId),\n                getOverlayStreamIds: (target) => this._commsSystem?.getOverlayStreamIds?.(target),\n                getOverlayTransportInfo: (target) => this._commsSystem?.getOverlayTransportInfo?.(target),\n                pushOverlayVideoFrame: async (target, payload) => (await this._ensureCommsSystem())?.pushOverlayVideoFrame?.(target, payload),\n                pushOverlayAudioPacket: async (target, payload) => (await this._ensureCommsSystem())?.pushOverlayAudioPacket?.(target, payload),\n                setVoiceSettings: async (settings) => (await this._ensureCommsSystem())?.setVoiceSettings?.(settings),\n                getVoiceSettings: () => this._commsSystem?.getVoiceSettings?.() || null,\n                getInteropTelemetry: () => this._commsSystem?.getInteropTelemetry?.() || null\n            },\n            presence: {\n                connect: (opts) => this._presenceSystem?.connect(opts),\n                disconnect: () => this._presenceSystem?.disconnect(),\n                setEnabled: (enabled) => this._presenceSystem?.setEnabled(enabled),\n                status: () => this._presenceSystem?.getStatus() || { connected: false, id: null, peers: 0 },\n                peers: () => this._presenceSystem?.getPeers() || [],\n                setMapState: (state) => this._presenceSystem?.setMapState(state)\n            },\n            entities: {\n                upsert: (entity) => this._entitySystem?.upsert(entity),\n                remove: (entityId) => this._entitySystem?.remove(entityId),\n                bind: (entityId, itemId) => this._entitySystem?.bind(entityId, itemId)\n            },\n            assets: {\n                preload: async (files) => this._assetSubsystem?.preload(files),\n                get: (fileId) => this._assetSubsystem?.get(fileId) || null\n            },\n            audio: {\n                attachGlobal: (stream, opts) => this._audioSystem?.attachGlobal(stream, opts),\n                attachToEntity: (entityId, stream, opts) => this._audioSystem?.attachToEntity(entityId, stream, opts),\n                attachToItem: (itemId, stream, opts) => this._audioSystem?.attachToItem(itemId, stream, opts),\n                attachToObject: (object, stream, opts) => this._audioSystem?.attachToObject?.(object, stream, opts),\n                detach: (handleId) => this._audioSystem?.detach(handleId),\n                resume: () => this._audioSystem?.resume(),\n                start: () => this._audioSystem?.start(),\n                setEnabled: (enabled) => this._setAudioEnabled(enabled),\n                testOvertones: (enabled) => this._toggleEarthOvertones(enabled),\n                playSound: async (soundPath, position, opts) => this._audioSystem?.playSound(soundPath, position, opts),\n                triggerBlip: (position, intensity) => this._audioSystem?.triggerBlip(position, intensity),\n                triggerImpact: (position, opts) => this._audioSystem?.triggerImpact(position, opts),\n                isEnabled: () => this._audioSystem?.isEnabled() || false,\n                setMasterVolume: (volume) => this._audioSystem?.setMasterVolume(volume),\n                startAmbient: (volume, freq) => this._audioSystem?.startAmbient(volume, freq),\n                stopAmbient: () => this._audioSystem?.stopAmbient()\n            },\n            // Backwards-compatible alias\n            spatialAudio: {\n                playSound: async (soundPath, position, opts) => this._audioSystem?.playSound(soundPath, position, opts),\n                triggerBlip: (position, intensity) => this._audioSystem?.triggerBlip(position, intensity),\n                triggerImpact: (position, opts) => this._audioSystem?.triggerImpact(position, opts),\n                isEnabled: () => this._audioSystem?.isEnabled() || false,\n                setMasterVolume: (volume) => this._audioSystem?.setMasterVolume(volume)\n            },\n            tts: {\n                speak: (text, opts = {}) => this.eventBus.emit('tts:speak', { text, ...opts }),\n                stop: () => this.eventBus.emit('tts:stop', {})\n            },\n            physics: {\n                retryInitialization: async () => {\n                    const physics = this._physicsSystem;\n                    if (!physics) throw new Error('Physics system is not attached');\n                    await physics.initialize();\n                    if (this._physicsSystem === physics) this._triTree?._processPendingColliders();\n                    return !!physics.core;\n                },\n                addPhysicsObject: (object3d, opts) => this._physicsSystem?.addPhysicsObject(object3d, opts),\n                removePhysicsObject: (object3d) => this._physicsSystem?.removePhysicsObject(object3d),\n                addStaticCollider: (mesh) => this._physicsSystem?.addStaticCollider(mesh),\n                removeStaticCollider: (mesh) => this._physicsSystem?.removeStaticCollider(mesh),\n                spawnTestBall: (opts) => this._physicsSystem?.spawnTestBall(opts),\n                getStatus: () => {\n                    const isReady = !!(this._physicsSystem?.core?.RAPIER);\n                    const terrainColliders = this._triTree?._tileColliders?.size || 0;\n                    const pendingColliders = this._triTree?._pendingColliders?.size || 0;\n                    const totalStaticColliders = this._physicsSystem?.staticColliders?.size || 0;\n                    const dynamicObjects = this._physicsSystem?.dynamicObjects?.size || 0;\n\n                    return {\n                        ready: isReady,\n                        initializationState: this._physicsSystem?.initializationState || 'unavailable',\n                        terrainColliders,\n                        pendingColliders,\n                        totalStaticColliders,\n                        dynamicObjects,\n                        message: isReady\n                            ? `✅ Physics ready | ${terrainColliders} terrain tiles | ${dynamicObjects} dynamic objects`\n                            : this._physicsSystem?.initializationError\n                                ? 'Physics initialization failed; explicit retry is available'\n                                : `⏳ Physics initializing... ${pendingColliders} tiles waiting`\n                    };\n                }\n            },\n            triggers: {\n                addProximityTrigger: (id, opts) => this._proximityTriggerManager?.addTrigger(id, opts),\n                removeProximityTrigger: (id) => this._proximityTriggerManager?.removeTrigger(id),\n                addClickTrigger: (id, opts) => this._clickTriggerManager?.addTrigger(id, opts),\n                removeClickTrigger: (id) => this._clickTriggerManager?.removeTrigger(id)\n            },\n            access: {\n                setDecisions: (decisionSet) => this._accessController?.updateDecisions(decisionSet),\n                canPerform: (objectType, objectId, actionName) => this._accessController?.canPerform(objectType, objectId, actionName)\n            },\n            pointer: {\n                getHoverLatLon: () => this._eventManager?.getHoverLatLon?.() || null,\n                getHoverWorldPosition: () => this._eventManager?.getHoverWorldPosition?.() || null\n            },\n            weather: {\n                enable: (enabled) => this._sceneInitializer?.setWeatherConfig?.({ enabled: !!enabled }),\n                setAutoTarget: (autoTarget) => this._sceneInitializer?.setWeatherConfig?.({ autoTarget: !!autoTarget }),\n                setTarget: (lat, lon) => this._weatherSystem?.setTarget?.(lat, lon),\n                setRegion: (id, patch) => this._weatherSystem?.setRegion?.(id, patch),\n                clearRegion: (id) => this._weatherSystem?.clearRegion?.(id),\n                clearRegions: () => this._weatherSystem?.clearRegions?.(),\n                get: () => this._weatherSystem?.getWeatherData?.() || null,\n                getSceneState: () => this._sceneWeatherState ? { ...this._sceneWeatherState } : null,\n                getConfig: () => this._sceneInitializer?.getWeatherConfig?.() || null\n            },\n            vr: {\n                isAvailable: () => this._vrManager?.isAvailable() || false,\n                isAvailabilityPending: () => this._vrManager?.isAvailabilityPending() ?? true,\n                isInSession: () => this._vrManager?.isInSession() || false,\n                enter: () => this._vrManager?.enter(),\n                exit: () => this._vrManager?.exit(),\n                setTeleportEnabled: (enabled) => this._vrManager?.setTeleportEnabled(enabled),\n                onSessionStart: (cb) => this._vrManager?.onSessionStart(cb),\n                onSessionEnd: (cb) => this._vrManager?.onSessionEnd(cb),\n                getControllers: () => this._vrManager?.getControllers() || [],\n                getCameraRig: () => this._vrManager?.getCameraRig()\n            },\n            avatar: {\n                isReady: () => this._localPlayer?.isReady() || false,\n                ensureReady: () => this._initAvatarSystems(),\n                setFirstPerson: (enabled) => {\n                    if (enabled === false) void this._initAvatarSystems();\n                    this._localPlayer?.setFirstPerson(enabled);\n                },\n                setVisible: (visible) => {\n                    if (visible === true) void this._initAvatarSystems();\n                    this._localPlayer?.setVisible(visible);\n                },\n                getAnimationState: () => this._localPlayer?.getAnimationState() || null,\n                getAvailableAnimations: () => AvatarFactory.getInstance()?.getAnimationNames?.() || [],\n                getAvailableActionStates: () => this._localPlayer?.avatar?.getActionNames?.() || [],\n                getPeerCount: () => this._peerManager?.getPeerCount() || 0,\n                getPeerIds: () => this._peerManager?.getPeerIds() || []\n            },\n            marketplace: {\n                getSummary: () => {\n                    const peers = this._presenceSystem?.getPeers?.() || [];\n                    const providers = [];\n                    peers.forEach((peer) => {\n                        if (!peer || typeof peer !== 'object') return;\n                        const address = String(peer.nknAddress || peer.address || '').trim().toLowerCase();\n                        if (!address) return;\n                        const catalog = peer.marketplaceCatalog && typeof peer.marketplaceCatalog === 'object'\n                            ? peer.marketplaceCatalog\n                            : (peer.marketplace_catalog && typeof peer.marketplace_catalog === 'object' ? peer.marketplace_catalog : {});\n                        const summary = catalog.summary && typeof catalog.summary === 'object' ? catalog.summary : {};\n                        const servicesRaw = Array.isArray(catalog.services) ? catalog.services : [];\n                        const services = servicesRaw\n                            .map((entry) => {\n                                if (!entry || typeof entry !== 'object') return null;\n                                const serviceId = String(entry.service_id || entry.serviceId || entry.service || '').trim();\n                                if (!serviceId) return null;\n                                const status = String(entry.status || '').trim().toLowerCase();\n                                const healthy = entry.healthy === true || status === 'online';\n                                const marketState = healthy\n                                    ? 'online'\n                                    : (\n                                        status === 'degraded' ||\n                                        status === 'warn' ||\n                                        status === 'warning' ||\n                                        status === 'limited'\n                                            ? 'degraded'\n                                            : 'offline'\n                                    );\n                                return {\n                                    serviceId,\n                                    status,\n                                    healthy,\n                                    marketState,\n                                    selectedTransport: String(entry.selected_transport || entry.selectedTransport || entry.transport || 'nkn').trim().toLowerCase() || 'nkn',\n                                    visibility: String(entry.visibility || 'public').trim().toLowerCase() === 'friends' ? 'friends' : 'public',\n                                };\n                            })\n                            .filter(Boolean)\n                            .slice(0, 16);\n                        providers.push({\n                            address,\n                            network: String(peer.network || '').trim().toLowerCase() || (address.startsWith('noclip.') ? 'noclip' : 'hydra'),\n                            transport: String(peer.selectedTransport || peer.selected_transport || 'nkn').trim().toLowerCase() || 'nkn',\n                            visibility: String(peer.offerVisibility || 'public').trim().toLowerCase() === 'friends' ? 'friends' : 'public',\n                            providerFingerprint: String(peer.providerFingerprint || peer.provider_key_fingerprint || '').trim(),\n                            services,\n                            catalogSummary: summary,\n                            source: 'scene.marketplace',\n                            ts: Number(peer.lastSeenAt || peer.updatedAtMs || Date.now()) || Date.now(),\n                        });\n                    });\n                    const usage = this._commsSystem?.getMarketplaceUsageAttribution?.(1)?.[0] || null;\n                    const telemetry = this._commsSystem?.getInteropTelemetry?.() || {};\n                    const quote = usage\n                        ? {\n                            estimated_charge_micros: String(usage.amountMicros || usage.amount_micros || '').trim(),\n                            serviceId: String(usage.serviceId || usage.service_id || '').trim(),\n                            source: 'usage.attribution',\n                        }\n                        : { source: 'usage.attribution' };\n                    const credit = { source: 'runtime', text: 'Credits: --' };\n                    const failureSignals = Number(\n                        telemetry.fallbackCount ||\n                        telemetry.ticketReplayRejected ||\n                        telemetry.rateLimitedCount ||\n                        telemetry.fraudBlockedCount ||\n                        telemetry.killSwitchBlockedCount ||\n                        0\n                    );\n                    const statusTone = failureSignals > 0\n                        ? 'warn'\n                        : (providers.length ? 'ok' : 'muted');\n                    const statusText = failureSignals > 0\n                        ? `Marketplace protections active (${failureSignals} signal${failureSignals === 1 ? '' : 's'})`\n                        : (\n                            providers.length\n                                ? `Provider marketplace synced (${providers.length})`\n                                : 'Waiting for provider visibility updates.'\n                        );\n                    return {\n                        providers,\n                        quote,\n                        credit,\n                        failureTelemetry: {\n                            fallbackCount: Number(telemetry.fallbackCount || 0),\n                            ticketReplayRejected: Number(telemetry.ticketReplayRejected || 0),\n                            rateLimitedCount: Number(telemetry.rateLimitedCount || 0),\n                            fraudBlockedCount: Number(telemetry.fraudBlockedCount || 0),\n                            killSwitchBlockedCount: Number(telemetry.killSwitchBlockedCount || 0),\n                            lastFailureCode: String(telemetry.lastFailureCode || ''),\n                            lastFailureScope: String(telemetry.lastFailureScope || ''),\n                            lastFailureAt: Number(telemetry.lastFailureAt || 0),\n                        },\n                        statusText,\n                        statusTone,\n                        updatedAtMs: Date.now(),\n                    };\n                }\n            },\n            events: {\n                on: (eventName, handler) => this.eventBus.on(eventName, handler),\n                off: (eventName, handler) => this.eventBus.off(eventName, handler),\n                emit: (eventName, data) => this.eventBus.emit(eventName, data)\n            },\n            tracking: {\n                start: (type) => this._pathTracker?.startSession(type),\n                stop: (type) => this._pathTracker?.stopSession(type),\n                isTracking: (type) => this._pathTracker?.isTracking(type) || false,\n                getTrail: (type) => this._pathTracker?.getTrail(type) || [],\n                getSessions: () => this._pathTracker?.getSessions() || [],\n                setGps: (lat, lon, alt, acc) => this._pathTracker?.setGpsPosition(lat, lon, alt, acc),\n                showTrail: (type, visible) => this._motionTrailRenderer?.setTypeVisible(type, visible),\n                clearTrails: () => this._motionTrailRenderer?.clear(),\n            },\n            camera: {\n                surfaceController: this._surfaceController,\n                getCamera: () => this._camera,\n                getPosition: () => this._camera?.position?.clone() || null,\n                getMode: () => this._surfaceController?.getCameraMode?.() || 'orbit',\n                getBodyAnchor: () => this._surfaceController?.getBodyAnchor?.() || 'terra',\n                isInSurfaceMode: () => this._surfaceController?.isInSurfaceMode?.() || false,\n                getSurfacePosition: () => this._surfaceController?.getSurfacePosition?.() || null,\n                getSurfaceLatLon: () => this._surfaceController?.getSurfaceLatLon?.() || null,\n                beginSurfaceTravel: (focusDir, reason = 'agent-fly-to') => {\n                    // A direct surface relocation can occur outside the frame\n                    // loop (HUD Home/search, agents, map tools). Publish its\n                    // physical pose before arming the provider so traversal\n                    // never reads the previous logical camera position.\n                    this._animationLoop?.syncCameraWorldPosition?.();\n                    this._handleSurfaceEnter({ reason, focusDir });\n                    this._photoTileLoader?.forceNextUpdate?.();\n                }\n            }\n        };\n    }\n\n    _wireAudioUnlock() {\n        if (this._audioUnlocked || !this._renderer?.domElement) return;\n        const target = this._renderer.domElement;\n        const unlock = async () => {\n            if (this._audioUnlocked) return;\n            this._audioUnlocked = true;\n            this._removeAudioUnlockHandlers();\n            try {\n                await this._audioSystem?.start?.();\n                try {\n                    const { getInferenceManager } = await import('../voice/InferenceManager.js');\n                    getInferenceManager({ eventBus: this.eventBus })?.resumeAudio?.();\n                } catch (error) {}\n            } catch (error) {\n                this.eventBus.emit('audio:error', { error, scope: 'audio-unlock' });\n            }\n        };\n        this._audioUnlockHandlers = { target, unlock };\n        target.addEventListener('pointerdown', unlock, { once: true });\n        target.addEventListener('touchstart', unlock, { once: true });\n    }\n\n    _removeAudioUnlockHandlers() {\n        const handlers = this._audioUnlockHandlers;\n        if (!handlers) return;\n        const { target, unlock } = handlers;\n        target?.removeEventListener('pointerdown', unlock);\n        target?.removeEventListener('touchstart', unlock);\n        this._audioUnlockHandlers = null;\n    }\n\n    _setAudioEnabled(enabled) {\n        if (this._audioSystem?.setEnabled) {\n            this._audioSystem.setEnabled(enabled);\n        }\n        if (this._windAudio) {\n            this._windAudio.setEnabled(!!enabled && !!this._windSettings?.enabled);\n        }\n    }\n\n    _applyWindSettings(next = {}) {\n        if (!next || typeof next !== 'object') return;\n        this._windSettings = { ...this._windSettings, ...next };\n        if (this._windAudio) {\n            this._windAudio.applySettings(this._windSettings);\n            this._windAudio.setEnabled(this._audioEnabledSetting && !!this._windSettings?.enabled);\n        }\n    }\n\n    _normalizeSpeakSettings(next = {}) {\n        const source = (next && typeof next === 'object') ? next : {};\n        const mode = source.mode === 'always_on' ? 'always_on' : 'push_to_talk';\n        const radius = Number(source.radiusM);\n        const radiusM = Number.isFinite(radius)\n            ? THREE.MathUtils.clamp(radius, 5, 250)\n            : this._speakSettings.radiusM;\n        const pushToTalkKey = (typeof source.pushToTalkKey === 'string' && source.pushToTalkKey.trim())\n            ? source.pushToTalkKey.trim()\n            : this._speakSettings.pushToTalkKey;\n        return {\n            enabled: typeof source.enabled === 'boolean' ? source.enabled : this._speakSettings.enabled,\n            mode,\n            pushToTalkKey,\n            radiusM\n        };\n    }\n\n    _applySpeakSettings(next = {}) {\n        this._speakSettings = this._normalizeSpeakSettings({\n            ...this._speakSettings,\n            ...next\n        });\n        if (this._commsSystem) {\n            this._commsSystem.setVoiceSettings?.(this._speakSettings);\n        } else if (this._speakSettings.enabled) {\n            void this._ensureCommsSystem().catch((err) => {\n                console.warn('[PlanetScene] Comms system load failed:', err);\n            });\n        }\n    }\n\n    _suspendWeatherEffects() {\n        this._rainSystem?.suspend();\n        this._audioSystem?.suspendWeather();\n        this._windAudio?.setActive(false);\n        this._windHasPrev = false;\n    }\n\n    _updateWeatherEffects(dt, frameNowMs) {\n        if (!this._camera || !this._weatherSystem) return;\n        this._camera.getWorldPosition(this._weatherWorldPosition);\n        this._weatherLocalPosition.copy(this._weatherWorldPosition);\n        this._triTree?.group?.worldToLocal(this._weatherLocalPosition);\n        const coords = dirToLatLonLocal(this._weatherLocalPosition, this._weatherCoordinates);\n        const state = this._sceneWeatherState = this._weatherSystem.getSceneWeatherState(coords.latDeg, coords.lonDeg);\n        const active = this._surfaceController?.isInSurfaceMode?.() === true\n            && this._mapPresentationMode !== '2d' && !this._cameraExclusiveState\n            && !document.hidden && !this._sceneInitializer?.isRenderBlocked?.();\n        const atmosphere = this._sceneInitializer?.atmosphereClouds;\n        const config = this._sceneInitializer?._atmosphereCloudsConfig;\n        const cloudTop = atmosphere?.getLocalCloudTopRadius?.() ?? configuredCloudTopRadius(\n            config?.cloudLayers, this._surfaceController?._terrainRadius ?? PLANET_RADIUS,\n            config?.cloudTerrainClearance);\n        // This is a presentation bound, not a change to the surface forecast.\n        // Inactive stops particles/audio immediately; a zero rain rate would fade.\n        const rainActive = active && areWeatherCloudsEnabled(this.settings)\n            && this._weatherLocalPosition.length() < cloudTop;\n        this._rainSystem?.update(dt, state, coords.latDeg, coords.lonDeg, rainActive,\n            this._photoTileLoader?.enabled ? this._photoTileLoader.group : this._triTree?.group,\n            this._lightingSystem?.sunDirection, frameNowMs, cloudTop);\n        this._audioSystem?.updateWeather(state, rainActive && this._audioEnabledSetting);\n    }\n\n    _updateWindAudio(dt) {\n        this._updateSpatialAmbientAudio();\n        if (!this._windAudio || !Number.isFinite(dt) || dt <= 0) return;\n        const active = this._surfaceController?.isInSurfaceMode?.() === true\n            && this._mapPresentationMode !== '2d' && !this._cameraExclusiveState\n            && !document.hidden && this._audioEnabledSetting && !!this._windSettings?.enabled;\n        this._windAudio.setActive(active);\n        if (!active) { this._windHasPrev = false; return; }\n\n        // Measure travel in the Earth-fixed frame: daily planet rotation is not\n        // observer motion through the air. Retain full 3D velocity when flying.\n        const position = this._weatherLocalPosition;\n        const velocity = this._windTmpVec.set(0, 0, 0);\n        if (this._windHasPrev && dt <= 0.25) velocity.copy(position).sub(this._windPrevPos).multiplyScalar(1 / dt);\n        this._windPrevPos.copy(position); this._windHasPrev = true;\n        if (velocity.lengthSq() > 250000) velocity.set(0, 0, 0);\n        this._triTree?.group?.getWorldQuaternion(this._windTmpQuatB);\n        velocity.applyQuaternion(this._windTmpQuatB);\n        const coords = this._weatherCoordinates;\n        const east = this._windTmpVecB, up = this._windTmpVecC, south = this._windTmpVecD;\n        setWeatherBasis(coords.latDeg, coords.lonDeg, this._windTmpQuatB, east, up, south);\n        const state = this._sceneWeatherState;\n        const from = weatherWindFrom(state, east, south, this._windTmpVecE);\n        const verticalScale = Number.isFinite(this._windSettings?.verticalScale) ? this._windSettings.verticalScale : 1;\n        velocity.addScaledVector(up, velocity.dot(up) * (verticalScale - 1));\n        // Relative air FROM = meteorological FROM + observer travel velocity.\n        // Reported calm remains calm at rest. No altitude or humidity wind floor.\n        from.add(velocity);\n        const speed = from.length();\n        this._windModulation.worldDirection.copy(from).multiplyScalar(speed > 0 ? 1 / speed : 0);\n        this._camera.getWorldQuaternion(this._windTmpQuat);\n        const localFrom = this._windTmpVecF.copy(from).applyQuaternion(this._windTmpQuat.invert());\n        const dirDeg = speed > 0 ? Math.atan2(localFrom.x, -localFrom.z) * 180 / Math.PI : 0;\n        const excess = Number.isFinite(state?.windGustMps) && Number.isFinite(state?.windSpeedMps)\n            ? Math.max(0, state.windGustMps - state.windSpeedMps) : 0;\n        this._windModulation.gustiness = THREE.MathUtils.clamp(excess / Math.max(1, state?.windSpeedMps || 0), 0, 1);\n        this._windAudio.update(speed, dirDeg, this._windSettings?.mass, this._windModulation);\n    }\n\n    _updateSpatialAmbientAudio() {\n        if (!this._audioSystem?.updateSpatialAmbient) return;\n        const inSurface = this._surfaceController?.isInSurfaceMode?.() || false;\n        const photoConfig = this._sceneSettings?.getSection?.('scene.terrain.photorealistic') || {};\n        const photorealActive = photoConfig.enabled === true || this._photoTileLoader?.enabled === true;\n        const hudStore = getHudInfoStore();\n        const latitudeDeg = hudStore?.getData?.('nav.lat');\n        const longitudeDeg = hudStore?.getData?.('nav.lon');\n        const weather = this._weatherSystem?.getWeatherData?.();\n        this._audioSystem.updateSpatialAmbient({\n            active: inSurface && photorealActive && this._audioEnabledSetting,\n            sceneTimeMs: this._sceneClock?.getTime?.() ?? Date.now(),\n            utcOffsetSeconds: weather?.utcOffsetSeconds,\n            latitudeDeg: Number.isFinite(latitudeDeg) ? latitudeDeg : 0,\n            longitudeDeg: Number.isFinite(longitudeDeg) ? longitudeDeg : 0,\n            temperatureC: weather?.current?.temperature_2m,\n            humidityPercent: weather?.current?.relative_humidity_2m,\n            precipitationMm: Number.isFinite(weather?.current?.precipitation)\n                ? weather.current.precipitation\n                : weather?.current?.rain,\n            observerIsOcean: this._surfaceController?.getOceanNavigationState?.().isOcean === true,\n        });\n    }\n\n    _updateEarthAudioAnchor() {\n        if (!this._earthAudioAnchor || !this._camera) return;\n        let position = null;\n        const surfacePos = this._surfaceController?.getSurfacePosition?.();\n        if (surfacePos) {\n            position = surfacePos.clone();\n        } else if (this._camera.position.lengthSq() > 0) {\n            const baseRadius = ellipsoidRadiusForWorldDir(this._camera.position, this._triTree?.group || null);\n            position = this._camera.position.clone().normalize().multiplyScalar(baseRadius);\n        }\n        if (position) {\n            this._earthAudioAnchor.position.copy(position);\n        }\n    }\n\n    _toggleEarthOvertones(enabled) {\n        const next = !!enabled;\n        if (next === this._audioTestActive) return;\n        this._audioTestActive = next;\n\n        if (!next) {\n            if (this._audioTestHandle) {\n                this._audioSystem?.detach(this._audioTestHandle);\n            }\n            this._audioTestHandle = null;\n            return;\n        }\n\n        this._updateEarthAudioAnchor();\n        const base = 7.83;\n        const maxFreq = 2000;\n        const harmonics = [];\n        let n = 2;\n        while (base * n <= maxFreq) {\n            harmonics.push(base * n);\n            n += 1;\n        }\n\n        const handle = this._audioSystem?.attachToObject?.(this._earthAudioAnchor, null, {\n            frequency: base,\n            harmonics,\n            harmonicGain: 0.03,\n            gain: 0.18,\n            waveform: 'sine'\n        });\n        this._audioTestHandle = handle?.handleId || null;\n    }\n\n    _detectMobile() {\n        if (typeof this.options.isMobile === 'boolean') {\n            return this.options.isMobile;\n        }\n        if (typeof this.options.ui?.isMobile === 'boolean') {\n            return this.options.ui.isMobile;\n        }\n        // Quest/Oculus Browser intentionally advertises a desktop UA. It is\n        // still a thermally and memory constrained mobile runtime, so use the\n        // bounded resource cadence while preserving its full XR viewport.\n        const uaMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini|OculusBrowser|Quest/i.test(navigator.userAgent);\n        const hasTouch = ('ontouchstart' in window) || (navigator.maxTouchPoints > 0);\n        const coarsePointer = typeof window.matchMedia === 'function' &&\n            window.matchMedia('(pointer:coarse)').matches;\n        const narrowViewport = window.innerWidth <= 768;\n        return uaMobile || (hasTouch && (coarsePointer || narrowViewport));\n    }\n\n    _shouldForceMobileWireframeDefault() {\n        return this.options?.forceMobileWireframeDefault === true ||\n            this.options?.mobile?.forceWireframeDefault === true;\n    }\n\n    _shouldRunMobileTask(key, now, intervalMs) {\n        if (!this._isMobile) return true;\n        if (!Number.isFinite(intervalMs) || intervalMs <= 0) return true;\n        const prev = this._mobileTaskLastRun.get(key);\n        if (Number.isFinite(prev) && (now - prev) < intervalMs) {\n            return false;\n        }\n        this._mobileTaskLastRun.set(key, now);\n        return true;\n    }\n\n    _resolveMobileImageryProfile() {\n        const cores = (typeof navigator !== 'undefined' && Number.isFinite(navigator.hardwareConcurrency))\n            ? navigator.hardwareConcurrency\n            : 4;\n        const memoryGb = (typeof navigator !== 'undefined' && Number.isFinite(navigator.deviceMemory))\n            ? navigator.deviceMemory\n            : 4;\n        const phoneClass = typeof navigator !== 'undefined'\n            && /iPhone|iPod|Android.*Mobile/i.test(navigator.userAgent || '');\n        // iOS Safari does not expose navigator.deviceMemory.  The prior\n        // core-count shortcut mistook the host CPU in phone emulation for an\n        // 8GB mobile GPU and selected the largest cache profile. Require an\n        // explicit memory signal before selecting that high tier.\n        const hasMemorySignal = Number.isFinite(memoryGb) && memoryGb > 0;\n        const highTier = !phoneClass && hasMemorySignal && memoryGb >= 8;\n        const midTier = !phoneClass && !highTier && (memoryGb >= 5 || (!hasMemorySignal && cores >= 6));\n\n        if (highTier) {\n            return {\n                tri: {\n                    maxTileLevelCap: 17,\n                    surfaceStageMaxLODCap: 17,\n                    surfaceLodNearCap: 17,\n                    surfaceLodFarCap: 5,\n                    tileBudgetCap: 1300,\n                    splitBudgetCap: 10,\n                    mergeBudgetFloor: 10,\n                    maxScreenSpaceErrorFloor: 22,\n                    imageryZoomPerLevelCap: 1.0,\n                    imageryZoomPerLevelSurfaceCap: 1.0,\n                    imageryMaxZoomCap: 20,\n                    surfaceImageryFarMaxZoomCap: 20,\n                    imageryBudgetFloor: 12,\n                    imageryBudgetCap: 20,\n                    imageryMinBudgetFloor: 6,\n                    imageryFullCoverageMaxLevelCap: 6,\n                    basePreloadPerFrameFloor: 4,\n                    basePreloadPerFrameCap: 5,\n                    imageryResetCooldownMs: 1200,\n                    imageryResetCooldownMin: 800,\n                    imageryResetCooldownMax: 2200,\n                    surfaceStageCooldownMsFloor: 650,\n                    surfaceRingNearMeters: 3500,\n                    surfaceRingMidMeters: 11000,\n                    surfaceRingFarMeters: 30000,\n                    surfaceRingLodMidDrop: 5,\n                    surfaceRingLodFarDrop: 10,\n                    surfaceRingImageryMidDrop: 4,\n                    surfaceRingImageryFarDrop: 8,\n                    surfaceImageryFarAngleDeg: 24,\n                    imageryBootstrapMaxRingCap: 1,\n                    imageryBootstrapDeltaZoomFloor: 4,\n                    imageryBootstrapBudgetCap: 14,\n                    imageryCoverZoomGapFloor: 4,\n                    imageryCoverUnderfootZoomGapFloor: 6,\n                    imageryCoverMinZoomCap: 3,\n                    imageryCoverUnderfootMinZoomCap: 4\n                },\n                manager: {\n                    maxAtlasTilesFloor: 4,\n                    maxAtlasTilesCap: 4,\n                    padTilesCap: 0,\n                    maxTileCacheMBFloor: 48,\n                    maxTileCacheMBCap: 96,\n                    maxAtlasCacheMBFloor: 80,\n                    maxAtlasCacheMBCap: 160,\n                    textureAnisotropyFloor: 4,\n                    textureAnisotropyCap: 8,\n                    tileSizeFloor: 256,\n                    tileSizeCap: 256,\n                    maxConcurrentAtlasBuildsFloor: 4,\n                    maxConcurrentAtlasBuildsCap: 6,\n                    maxConcurrentTileLoadsFloor: 16,\n                    maxConcurrentTileLoadsCap: 24,\n                    contextBurstTileLoadsFloor: 6,\n                    contextBurstTileLoadsCap: 12,\n                    contextBurstAtlasBuildsFloor: 2,\n                    contextBurstAtlasBuildsCap: 4,\n                    atlasDrawBudgetMsFloor: 5,\n                    atlasDrawBudgetMsCap: 8,\n                    atlasDrawMinTilesFloor: 2,\n                    atlasDrawMinTilesCap: 4,\n                    tileRetryDelayMs: 350,\n                    tileRetryDelayMin: 120,\n                    tileRetryDelayMax: 700,\n                    atlasRetryDelayMs: 500,\n                    atlasRetryDelayMin: 180,\n                    atlasRetryDelayMax: 900,\n                    maxAtlasTileFetchesFloor: 96,\n                    maxAtlasTileFetchesCap: 128,\n                    atlasTileFetchConcurrencyFloor: 10,\n                    atlasTileFetchConcurrencyCap: 14,\n                    atlasParentFallbackMaxParentsFloor: 48,\n                    atlasParentFallbackMaxParentsCap: 96,\n                    maxQueuedTileRequestsFloor: 3072,\n                    maxQueuedTileRequestsCap: 6144,\n                    maxQueuedAtlasRequestsFloor: 768,\n                    maxQueuedAtlasRequestsCap: 1536\n                },\n                overlays: {\n                    buildingRadiusM: 320,\n                    buildingMaxFeatures: 220,\n                    buildingLodBudget: 28,\n                    buildingLodDetailRadiusM: 760,\n                    buildingLodImpostorRadiusM: 2000,\n                    buildingResnapBudget: 8,\n                    infrastructureRadiusM: 700,\n                    infrastructureRefreshDistanceM: 220,\n                    infrastructureResnapBudget: 1,\n                    infrastructureDrapeBudget: 520,\n                    infrastructureAlignMaxSamples: 40,\n                    infrastructureRoadStepM: 8,\n                    infrastructureMotionEnabled: false,\n                    autoBuildingPollIntervalMs: 1700,\n                    autoBuildingMinMoveM: 170,\n                    autoInfrastructurePollIntervalMs: 3600,\n                    autoInfrastructureMinMoveM: 220,\n                    autoBuildingBootstrapDelayMs: 1500,\n                    autoInfrastructureBootstrapDelayMs: 2800,\n                    autoInfrastructureAfterBuildingsDelayMs: 1400\n                }\n            };\n        }\n\n        if (midTier) {\n            return {\n                tri: {\n                    maxTileLevelCap: 16,\n                    surfaceStageMaxLODCap: 16,\n                    surfaceLodNearCap: 16,\n                    surfaceLodFarCap: 4,\n                    tileBudgetCap: 1150,\n                    splitBudgetCap: 8,\n                    mergeBudgetFloor: 8,\n                    maxScreenSpaceErrorFloor: 23,\n                    imageryZoomPerLevelCap: 1.0,\n                    imageryZoomPerLevelSurfaceCap: 1.0,\n                    imageryMaxZoomCap: 20,\n                    surfaceImageryFarMaxZoomCap: 20,\n                    imageryBudgetFloor: 9,\n                    imageryBudgetCap: 14,\n                    imageryMinBudgetFloor: 4,\n                    imageryFullCoverageMaxLevelCap: 5,\n                    basePreloadPerFrameFloor: 3,\n                    basePreloadPerFrameCap: 4,\n                    imageryResetCooldownMs: 1400,\n                    imageryResetCooldownMin: 900,\n                    imageryResetCooldownMax: 2500,\n                    surfaceStageCooldownMsFloor: 700,\n                    surfaceRingNearMeters: 2800,\n                    surfaceRingMidMeters: 9000,\n                    surfaceRingFarMeters: 24000,\n                    surfaceRingLodMidDrop: 6,\n                    surfaceRingLodFarDrop: 11,\n                    surfaceRingImageryMidDrop: 5,\n                    surfaceRingImageryFarDrop: 9,\n                    surfaceImageryFarAngleDeg: 20,\n                    imageryBootstrapMaxRingCap: 1,\n                    imageryBootstrapDeltaZoomFloor: 5,\n                    imageryBootstrapBudgetCap: 12,\n                    imageryCoverZoomGapFloor: 5,\n                    imageryCoverUnderfootZoomGapFloor: 6,\n                    imageryCoverMinZoomCap: 3,\n                    imageryCoverUnderfootMinZoomCap: 4\n                },\n                manager: {\n                    maxAtlasTilesFloor: 4,\n                    maxAtlasTilesCap: 4,\n                    padTilesCap: 0,\n                    maxTileCacheMBFloor: 32,\n                    maxTileCacheMBCap: 64,\n                    maxAtlasCacheMBFloor: 56,\n                    maxAtlasCacheMBCap: 112,\n                    textureAnisotropyFloor: 3,\n                    textureAnisotropyCap: 6,\n                    tileSizeFloor: 192,\n                    tileSizeCap: 256,\n                    maxConcurrentAtlasBuildsFloor: 3,\n                    maxConcurrentAtlasBuildsCap: 4,\n                    maxConcurrentTileLoadsFloor: 12,\n                    maxConcurrentTileLoadsCap: 16,\n                    contextBurstTileLoadsFloor: 4,\n                    contextBurstTileLoadsCap: 8,\n                    contextBurstAtlasBuildsFloor: 2,\n                    contextBurstAtlasBuildsCap: 3,\n                    atlasDrawBudgetMsFloor: 4,\n                    atlasDrawBudgetMsCap: 6,\n                    atlasDrawMinTilesFloor: 2,\n                    atlasDrawMinTilesCap: 3,\n                    tileRetryDelayMs: 400,\n                    tileRetryDelayMin: 120,\n                    tileRetryDelayMax: 800,\n                    atlasRetryDelayMs: 550,\n                    atlasRetryDelayMin: 180,\n                    atlasRetryDelayMax: 1000,\n                    maxAtlasTileFetchesFloor: 64,\n                    maxAtlasTileFetchesCap: 96,\n                    atlasTileFetchConcurrencyFloor: 8,\n                    atlasTileFetchConcurrencyCap: 12,\n                    atlasParentFallbackMaxParentsFloor: 32,\n                    atlasParentFallbackMaxParentsCap: 64,\n                    maxQueuedTileRequestsFloor: 2048,\n                    maxQueuedTileRequestsCap: 4096,\n                    maxQueuedAtlasRequestsFloor: 512,\n                    maxQueuedAtlasRequestsCap: 1024\n                },\n                overlays: {\n                    buildingRadiusM: 280,\n                    buildingMaxFeatures: 170,\n                    buildingLodBudget: 24,\n                    buildingLodDetailRadiusM: 700,\n                    buildingLodImpostorRadiusM: 1800,\n                    buildingResnapBudget: 6,\n                    infrastructureRadiusM: 580,\n                    infrastructureRefreshDistanceM: 240,\n                    infrastructureResnapBudget: 1,\n                    infrastructureDrapeBudget: 420,\n                    infrastructureAlignMaxSamples: 32,\n                    infrastructureRoadStepM: 9,\n                    infrastructureMotionEnabled: false,\n                    autoBuildingPollIntervalMs: 2000,\n                    autoBuildingMinMoveM: 190,\n                    autoInfrastructurePollIntervalMs: 4200,\n                    autoInfrastructureMinMoveM: 260,\n                    autoBuildingBootstrapDelayMs: 1900,\n                    autoInfrastructureBootstrapDelayMs: 3200,\n                    autoInfrastructureAfterBuildingsDelayMs: 1600\n                }\n            };\n        }\n\n        return {\n            tri: {\n                maxTileLevelCap: 15,\n                surfaceStageMaxLODCap: 15,\n                surfaceLodNearCap: 15,\n                surfaceLodFarCap: 3,\n                tileBudgetCap: 1000,\n                splitBudgetCap: 6,\n                mergeBudgetFloor: 6,\n                maxScreenSpaceErrorFloor: 24,\n                imageryZoomPerLevelCap: 1.0,\n                imageryZoomPerLevelSurfaceCap: 1.0,\n                imageryMaxZoomCap: 19,\n                surfaceImageryFarMaxZoomCap: 19,\n                imageryBudgetFloor: 8,\n                imageryBudgetCap: 10,\n                imageryMinBudgetFloor: 3,\n                imageryFullCoverageMaxLevelCap: 4,\n                basePreloadPerFrameFloor: 2,\n                basePreloadPerFrameCap: 3,\n                imageryResetCooldownMs: 1700,\n                imageryResetCooldownMin: 900,\n                imageryResetCooldownMax: 2800,\n                surfaceStageCooldownMsFloor: 750,\n                surfaceRingNearMeters: 2200,\n                surfaceRingMidMeters: 7000,\n                surfaceRingFarMeters: 18000,\n                surfaceRingLodMidDrop: 7,\n                surfaceRingLodFarDrop: 12,\n                surfaceRingImageryMidDrop: 6,\n                surfaceRingImageryFarDrop: 10,\n                surfaceImageryFarAngleDeg: 16,\n                imageryBootstrapMaxRingCap: 1,\n                imageryBootstrapDeltaZoomFloor: 5,\n                imageryBootstrapBudgetCap: 10,\n                imageryCoverZoomGapFloor: 5,\n                imageryCoverUnderfootZoomGapFloor: 7,\n                imageryCoverMinZoomCap: 2,\n                imageryCoverUnderfootMinZoomCap: 3\n            },\n            manager: {\n                maxAtlasTilesFloor: 4,\n                maxAtlasTilesCap: 4,\n                padTilesCap: 0,\n                maxTileCacheMBFloor: 24,\n                maxTileCacheMBCap: 48,\n                maxAtlasCacheMBFloor: 36,\n                maxAtlasCacheMBCap: 72,\n                textureAnisotropyFloor: 2,\n                textureAnisotropyCap: 4,\n                tileSizeFloor: 128,\n                tileSizeCap: 192,\n                maxConcurrentAtlasBuildsFloor: 2,\n                maxConcurrentAtlasBuildsCap: 3,\n                maxConcurrentTileLoadsFloor: 8,\n                maxConcurrentTileLoadsCap: 12,\n                contextBurstTileLoadsFloor: 3,\n                contextBurstTileLoadsCap: 6,\n                contextBurstAtlasBuildsFloor: 1,\n                contextBurstAtlasBuildsCap: 2,\n                atlasDrawBudgetMsFloor: 3,\n                atlasDrawBudgetMsCap: 4,\n                atlasDrawMinTilesFloor: 1,\n                atlasDrawMinTilesCap: 2,\n                tileRetryDelayMs: 450,\n                tileRetryDelayMin: 150,\n                tileRetryDelayMax: 900,\n                atlasRetryDelayMs: 650,\n                atlasRetryDelayMin: 220,\n                atlasRetryDelayMax: 1200,\n                maxAtlasTileFetchesFloor: 48,\n                maxAtlasTileFetchesCap: 72,\n                atlasTileFetchConcurrencyFloor: 6,\n                atlasTileFetchConcurrencyCap: 8,\n                atlasParentFallbackMaxParentsFloor: 24,\n                atlasParentFallbackMaxParentsCap: 48,\n                maxQueuedTileRequestsFloor: 1536,\n                maxQueuedTileRequestsCap: 3072,\n                maxQueuedAtlasRequestsFloor: 384,\n                maxQueuedAtlasRequestsCap: 768\n            },\n            overlays: {\n                buildingRadiusM: 220,\n                buildingMaxFeatures: 120,\n                buildingLodBudget: 18,\n                buildingLodDetailRadiusM: 560,\n                buildingLodImpostorRadiusM: 1400,\n                buildingResnapBudget: 4,\n                infrastructureRadiusM: 460,\n                infrastructureRefreshDistanceM: 280,\n                infrastructureResnapBudget: 1,\n                infrastructureDrapeBudget: 280,\n                infrastructureAlignMaxSamples: 24,\n                infrastructureRoadStepM: 10,\n                infrastructureMotionEnabled: false,\n                autoBuildingPollIntervalMs: 2400,\n                autoBuildingMinMoveM: 220,\n                autoInfrastructurePollIntervalMs: 5200,\n                autoInfrastructureMinMoveM: 320,\n                autoBuildingBootstrapDelayMs: 2300,\n                autoInfrastructureBootstrapDelayMs: 3800,\n                autoInfrastructureAfterBuildingsDelayMs: 1800\n            }\n        };\n    }\n\n    _beginNativeCloudPreference() {\n        if (!this._isMobile || !this._sceneSettings || this._nativeCloudsRestore !== undefined) return;\n        this._nativeCloudsRestore = this._sceneSettings.getSection('scene.atmosphere.clouds.enabled') === true;\n        // Phone presentation caps are not an immersive cloud preference. Use\n        // the same setting/action owner transiently; restore phone state on exit.\n        this._sceneSettings.updateScene({ atmosphere: { clouds: {\n            enabled: this._nativeCloudsRestore || (this._nativeCloudsPreferred ?? true),\n        } } }, { persist: false });\n    }\n\n    _endNativeCloudPreference() {\n        if (this._nativeCloudsRestore === undefined || !this._sceneSettings) return;\n        this._nativeCloudsPreferred = this._sceneSettings.getSection('scene.atmosphere.clouds.enabled') === true;\n        const enabled = this._nativeCloudsRestore; this._nativeCloudsRestore = undefined;\n        this._sceneSettings.updateScene({ atmosphere: { clouds: { enabled } } }, { persist: false });\n    }\n\n    _applyMobileProfile() {\n        // Reduce elevation vertex budget on mobile to lower memory pressure.\n        // Desktop default is 800K; mobile gets tier-appropriate limits.\n        this._applyMobileElevationSafetyCap();\n        // Desktop retains complete merged terrain subtrees for eight seconds\n        // to make a quick re-split instant. On a moving phone that overlaps\n        // new street terrain and is not bounded by subtree size, so retain a\n        // tiny geometry-only window and release stale elevation ownership.\n        this._triTree?.setRetirementPolicy?.({\n            graceMs: 750,\n            maxEntries: 12,\n            maxTiles: 180,\n            retainElevation: false,\n        });\n\n        this._applyMobileTextureSafetyCaps();\n        this._viewshedUpdateIntervalMs = 900;\n        this._viewshedMaxItems = 4;\n\n        if (typeof this._sceneInitializer?.setLensFlareEnabled === 'function') {\n            this._sceneInitializer.setLensFlareEnabled(false);\n        } else if (this._sceneInitializer?.lensFlare) {\n            this._sceneInitializer.lensFlare.visible = false;\n        }\n        this._sceneInitializer?.setAtmosphereCloudsConfig?.({\n            clouds: { enabled: this._sceneSettings?.getSection?.('scene.atmosphere.clouds.enabled') === true },\n            orbitClouds: { enabled: this._sceneSettings?.getSection?.('scene.atmosphere.orbitClouds.enabled') === true }\n        });\n        this._sceneInitializer?.setEarthOverlayConfig?.({\n            specularMap: { enabled: false },\n            simpleClouds: { enabled: this._sceneSettings?.getSection?.('scene.atmosphere.simpleClouds.enabled') === true },\n            water: { enabled: false }\n        });\n\n        this._applyMobileGentleImagery();\n        this._applyMobileLiteAtmosphere({ enable: false });\n        this._applyMobileRuntimeBudgets();\n        this._applyMobileLabelBudgets();\n    }\n\n    _applyMobileLabelBudgets() {\n        if (!this._isMobile) return;\n        try {\n            getLabelSystem().setMaxVisible(18);\n            getBusinessLabels({ mobile: true });\n        } catch {\n            // Non-critical: labels can initialize later and will be clamped\n            // again through _applyTuneables.\n        }\n    }\n\n    _applyMobileTextureSafetyCaps() {\n        if (!this._isMobile || !this._triTree || !this._imageryManager) return;\n\n        const profile = this._resolveMobileImageryProfile();\n        const clampNumber = (value, min, max, fallback = min) => {\n            const numeric = Number.isFinite(value) ? value : fallback;\n            return Math.min(max, Math.max(min, numeric));\n        };\n        const clampInt = (value, min, max, fallback = min) =>\n            Math.floor(clampNumber(value, min, max, fallback));\n\n        const tri = this._triTree;\n        tri.maxTileLevel = clampInt(tri.maxTileLevel, 10, profile.tri.maxTileLevelCap, profile.tri.maxTileLevelCap);\n        tri.surfaceStageMaxLOD = clampInt(\n            tri.surfaceStageMaxLOD,\n            10,\n            profile.tri.surfaceStageMaxLODCap,\n            profile.tri.surfaceStageMaxLODCap\n        );\n        tri.surfaceLodNear = clampInt(tri.surfaceLodNear, 8, profile.tri.surfaceLodNearCap, profile.tri.surfaceLodNearCap);\n        tri.surfaceLodFar = clampInt(tri.surfaceLodFar, 3, profile.tri.surfaceLodFarCap, profile.tri.surfaceLodFarCap);\n\n        tri.tileBudget = clampInt(tri.tileBudget, 800, profile.tri.tileBudgetCap, profile.tri.tileBudgetCap);\n        tri.splitBudget = clampInt(tri.splitBudget, 4, profile.tri.splitBudgetCap, profile.tri.splitBudgetCap);\n        tri.mergeBudget = Math.max(\n            Number.isFinite(tri.mergeBudget) ? Math.floor(tri.mergeBudget) : profile.tri.mergeBudgetFloor,\n            profile.tri.mergeBudgetFloor\n        );\n        tri.maxScreenSpaceError = Math.max(\n            Number.isFinite(tri.maxScreenSpaceError) ? tri.maxScreenSpaceError : profile.tri.maxScreenSpaceErrorFloor,\n            profile.tri.maxScreenSpaceErrorFloor\n        );\n\n        tri.imageryZoomPerLevel = clampNumber(\n            tri.imageryZoomPerLevel,\n            0.2,\n            profile.tri.imageryZoomPerLevelCap,\n            profile.tri.imageryZoomPerLevelCap\n        );\n        tri.imageryZoomPerLevelSurface = clampNumber(\n            tri.imageryZoomPerLevelSurface,\n            0.05,\n            profile.tri.imageryZoomPerLevelSurfaceCap,\n            profile.tri.imageryZoomPerLevelSurfaceCap\n        );\n\n        const clampedImageryMaxZoom = clampInt(\n            tri.imageryMaxZoom,\n            12,\n            profile.tri.imageryMaxZoomCap,\n            profile.tri.imageryMaxZoomCap\n        );\n        const clampedSurfaceImageryMax = Math.min(\n            Number.isFinite(tri.surfaceImageryMaxZoom) ? tri.surfaceImageryMaxZoom : clampedImageryMaxZoom,\n            clampedImageryMaxZoom\n        );\n        tri.surfaceImageryMaxZoom = clampedSurfaceImageryMax;\n        tri.surfaceImageryFarMaxZoom = clampInt(\n            tri.surfaceImageryFarMaxZoom,\n            6,\n            profile.tri.surfaceImageryFarMaxZoomCap,\n            profile.tri.surfaceImageryFarMaxZoomCap\n        );\n        tri.setImageryZoomRange?.(tri.imageryMinZoom, clampedImageryMaxZoom);\n        if (!Number.isFinite(tri.imageryResolutionBoost) || tri.imageryResolutionBoost < 1) {\n            tri.setImageryResolutionBoost?.(1);\n        }\n\n        const nextImageryBudget = clampInt(\n            Math.max(\n                Number.isFinite(tri.imageryBudgetPerFrame) ? tri.imageryBudgetPerFrame : profile.tri.imageryBudgetFloor,\n                profile.tri.imageryBudgetFloor\n            ),\n            profile.tri.imageryBudgetFloor,\n            profile.tri.imageryBudgetCap,\n            profile.tri.imageryBudgetFloor\n        );\n        tri.imageryBudgetPerFrame = nextImageryBudget;\n        tri.imageryMinBudget = clampInt(\n            Math.max(\n                Number.isFinite(tri.imageryMinBudget) ? tri.imageryMinBudget : profile.tri.imageryMinBudgetFloor,\n                profile.tri.imageryMinBudgetFloor\n            ),\n            2,\n            nextImageryBudget,\n            profile.tri.imageryMinBudgetFloor\n        );\n        tri.imageryFullCoverageMaxLevel = clampInt(\n            tri.imageryFullCoverageMaxLevel,\n            2,\n            profile.tri.imageryFullCoverageMaxLevelCap,\n            profile.tri.imageryFullCoverageMaxLevelCap\n        );\n        tri.basePreloadPerFrame = clampInt(\n            Math.max(\n                Number.isFinite(tri.basePreloadPerFrame) ? tri.basePreloadPerFrame : profile.tri.basePreloadPerFrameFloor,\n                profile.tri.basePreloadPerFrameFloor\n            ),\n            profile.tri.basePreloadPerFrameFloor,\n            profile.tri.basePreloadPerFrameCap,\n            profile.tri.basePreloadPerFrameFloor\n        );\n        tri.imageryResetCooldownMs = clampInt(\n            tri.imageryResetCooldownMs,\n            profile.tri.imageryResetCooldownMin,\n            profile.tri.imageryResetCooldownMax,\n            profile.tri.imageryResetCooldownMs\n        );\n\n        const capInt = (value, cap, floor = 0, fallback = cap) => {\n            const numeric = Number.isFinite(value) ? Math.floor(value) : fallback;\n            return Math.max(floor, Math.min(cap, numeric));\n        };\n\n        const ringNearMeters = capInt(\n            tri.surfaceRingNearMeters,\n            profile.tri.surfaceRingNearMeters,\n            800,\n            profile.tri.surfaceRingNearMeters\n        );\n        const ringMidMeters = capInt(\n            tri.surfaceRingMidMeters,\n            profile.tri.surfaceRingMidMeters,\n            ringNearMeters + 500,\n            profile.tri.surfaceRingMidMeters\n        );\n        const ringFarMeters = capInt(\n            tri.surfaceRingFarMeters,\n            profile.tri.surfaceRingFarMeters,\n            ringMidMeters + 1000,\n            profile.tri.surfaceRingFarMeters\n        );\n        tri.surfaceRingNearMeters = ringNearMeters;\n        tri.surfaceRingMidMeters = ringMidMeters;\n        tri.surfaceRingFarMeters = ringFarMeters;\n\n        tri.surfaceImageryFarAngleDeg = clampNumber(\n            tri.surfaceImageryFarAngleDeg,\n            8,\n            profile.tri.surfaceImageryFarAngleDeg,\n            profile.tri.surfaceImageryFarAngleDeg\n        );\n\n        tri.imageryBootstrapMaxRing = clampInt(\n            tri.imageryBootstrapMaxRing,\n            profile.tri.imageryBootstrapMaxRingCap,\n            0,\n            profile.tri.imageryBootstrapMaxRingCap\n        );\n        tri.imageryBootstrapDeltaZoom = Math.max(\n            Number.isFinite(tri.imageryBootstrapDeltaZoom)\n                ? Math.floor(tri.imageryBootstrapDeltaZoom)\n                : profile.tri.imageryBootstrapDeltaZoomFloor,\n            profile.tri.imageryBootstrapDeltaZoomFloor\n        );\n        tri.imageryBootstrapBudgetMax = capInt(\n            tri.imageryBootstrapBudgetMax,\n            profile.tri.imageryBootstrapBudgetCap,\n            1,\n            profile.tri.imageryBootstrapBudgetCap\n        );\n        tri.imageryCoverZoomGap = Math.max(\n            Number.isFinite(tri.imageryCoverZoomGap) ? Math.floor(tri.imageryCoverZoomGap) : profile.tri.imageryCoverZoomGapFloor,\n            profile.tri.imageryCoverZoomGapFloor\n        );\n        tri.imageryCoverUnderfootZoomGap = Math.max(\n            Number.isFinite(tri.imageryCoverUnderfootZoomGap)\n                ? Math.floor(tri.imageryCoverUnderfootZoomGap)\n                : profile.tri.imageryCoverUnderfootZoomGapFloor,\n            profile.tri.imageryCoverUnderfootZoomGapFloor\n        );\n        tri.imageryCoverMinZoom = capInt(\n            tri.imageryCoverMinZoom,\n            profile.tri.imageryCoverMinZoomCap,\n            0,\n            profile.tri.imageryCoverMinZoomCap\n        );\n        tri.imageryCoverUnderfootMinZoom = capInt(\n            tri.imageryCoverUnderfootMinZoom,\n            profile.tri.imageryCoverUnderfootMinZoomCap,\n            0,\n            profile.tri.imageryCoverUnderfootMinZoomCap\n        );\n\n        const nearRingLod = tri.surfaceStageMaxLOD;\n        const ringMidDrop = capInt(profile.tri.surfaceRingLodMidDrop, 12, 1, 5);\n        const ringFarDropRaw = Number.isFinite(profile.tri.surfaceRingLodFarDrop)\n            ? Math.floor(profile.tri.surfaceRingLodFarDrop)\n            : 10;\n        const ringFarDrop = Math.max(ringMidDrop + 1, Math.min(16, ringFarDropRaw));\n        let ringMidLod = Math.max(tri.surfaceStageMinLOD, nearRingLod - ringMidDrop);\n        let ringFarLod = Math.max(tri.surfaceStageMinLOD, nearRingLod - ringFarDrop);\n        ringMidLod = Math.min(ringMidLod, Math.max(tri.surfaceStageMinLOD, tri.surfaceLodNear - 1));\n        ringFarLod = Math.min(ringFarLod, tri.surfaceLodFar);\n        if (ringFarLod > ringMidLod) ringFarLod = ringMidLod;\n\n        const ringMidImageryDrop = capInt(profile.tri.surfaceRingImageryMidDrop, 12, 1, 4);\n        const ringFarImageryDropRaw = Number.isFinite(profile.tri.surfaceRingImageryFarDrop)\n            ? Math.floor(profile.tri.surfaceRingImageryFarDrop)\n            : 8;\n        const ringFarImageryDrop = Math.max(ringMidImageryDrop + 1, Math.min(14, ringFarImageryDropRaw));\n        let ringMidImageryCap = Math.max(tri.imageryMinZoom, clampedSurfaceImageryMax - ringMidImageryDrop);\n        let ringFarImageryCap = Math.max(tri.imageryMinZoom, clampedSurfaceImageryMax - ringFarImageryDrop);\n        if (ringFarImageryCap > ringMidImageryCap) ringFarImageryCap = ringMidImageryCap;\n\n        tri.surfaceRingLodCaps = {\n            near: nearRingLod,\n            mid: ringMidLod,\n            far: ringFarLod\n        };\n        tri.surfaceRingImageryCaps = {\n            near: clampedSurfaceImageryMax,\n            mid: ringMidImageryCap,\n            far: ringFarImageryCap\n        };\n        tri.surfaceRingImageryStartCaps = {\n            near: clampedSurfaceImageryMax,\n            mid: ringMidImageryCap,\n            far: ringFarImageryCap\n        };\n        tri.surfaceRingImageryUpgradeMs = {\n            mid: 0,\n            far: 0\n        };\n        tri.surfaceStageAdvanceMaxBatches = 1;\n        tri.surfaceStageCooldownMs = Math.max(\n            Number.isFinite(tri.surfaceStageCooldownMs) ? tri.surfaceStageCooldownMs : profile.tri.surfaceStageCooldownMsFloor,\n            profile.tri.surfaceStageCooldownMsFloor\n        );\n\n        const currentImagery = this._imageryManager.getConfig?.() || {};\n        this._imageryManager.setConfig({\n            maxAtlasTiles: clampInt(\n                Math.max(\n                    Number.isFinite(currentImagery.maxAtlasTiles) ? currentImagery.maxAtlasTiles : profile.manager.maxAtlasTilesFloor,\n                    profile.manager.maxAtlasTilesFloor\n                ),\n                profile.manager.maxAtlasTilesFloor,\n                profile.manager.maxAtlasTilesCap,\n                profile.manager.maxAtlasTilesFloor\n            ),\n            padTiles: clampInt(currentImagery.padTiles, 0, profile.manager.padTilesCap, 0),\n            maxTileCacheMB: clampInt(\n                Math.max(\n                    Number.isFinite(currentImagery.maxTileCacheMB) ? currentImagery.maxTileCacheMB : profile.manager.maxTileCacheMBFloor,\n                    profile.manager.maxTileCacheMBFloor\n                ),\n                profile.manager.maxTileCacheMBFloor,\n                profile.manager.maxTileCacheMBCap,\n                profile.manager.maxTileCacheMBFloor\n            ),\n            maxAtlasCacheMB: clampInt(\n                Math.max(\n                    Number.isFinite(currentImagery.maxAtlasCacheMB) ? currentImagery.maxAtlasCacheMB : profile.manager.maxAtlasCacheMBFloor,\n                    profile.manager.maxAtlasCacheMBFloor\n                ),\n                profile.manager.maxAtlasCacheMBFloor,\n                profile.manager.maxAtlasCacheMBCap,\n                profile.manager.maxAtlasCacheMBFloor\n            ),\n            textureAnisotropy: clampInt(\n                Math.max(\n                    Number.isFinite(currentImagery.textureAnisotropy) ? currentImagery.textureAnisotropy : profile.manager.textureAnisotropyFloor,\n                    profile.manager.textureAnisotropyFloor\n                ),\n                profile.manager.textureAnisotropyFloor,\n                profile.manager.textureAnisotropyCap,\n                profile.manager.textureAnisotropyFloor\n            ),\n            useMobileTiles: (typeof currentImagery.useMobileTiles === 'boolean')\n                ? currentImagery.useMobileTiles\n                : true,\n            tileSize: clampInt(\n                Math.max(\n                    Number.isFinite(currentImagery.tileSize) ? currentImagery.tileSize : profile.manager.tileSizeFloor,\n                    profile.manager.tileSizeFloor\n                ),\n                profile.manager.tileSizeFloor,\n                profile.manager.tileSizeCap,\n                profile.manager.tileSizeFloor\n            ),\n            maxConcurrentAtlasBuilds: clampInt(\n                Math.max(\n                    Number.isFinite(currentImagery.maxConcurrentAtlasBuilds)\n                        ? currentImagery.maxConcurrentAtlasBuilds\n                        : profile.manager.maxConcurrentAtlasBuildsFloor,\n                    profile.manager.maxConcurrentAtlasBuildsFloor\n                ),\n                profile.manager.maxConcurrentAtlasBuildsFloor,\n                profile.manager.maxConcurrentAtlasBuildsCap,\n                profile.manager.maxConcurrentAtlasBuildsFloor\n            ),\n            maxConcurrentTileLoads: clampInt(\n                Math.max(\n                    Number.isFinite(currentImagery.maxConcurrentTileLoads)\n                        ? currentImagery.maxConcurrentTileLoads\n                        : profile.manager.maxConcurrentTileLoadsFloor,\n                    profile.manager.maxConcurrentTileLoadsFloor\n                ),\n                profile.manager.maxConcurrentTileLoadsFloor,\n                profile.manager.maxConcurrentTileLoadsCap,\n                profile.manager.maxConcurrentTileLoadsFloor\n            ),\n            contextBurstTileLoads: clampInt(\n                Math.max(\n                    Number.isFinite(currentImagery.contextBurstTileLoads)\n                        ? currentImagery.contextBurstTileLoads\n                        : profile.manager.contextBurstTileLoadsFloor,\n                    profile.manager.contextBurstTileLoadsFloor\n                ),\n                profile.manager.contextBurstTileLoadsFloor,\n                profile.manager.contextBurstTileLoadsCap,\n                profile.manager.contextBurstTileLoadsFloor\n            ),\n            contextBurstAtlasBuilds: clampInt(\n                Math.max(\n                    Number.isFinite(currentImagery.contextBurstAtlasBuilds)\n                        ? currentImagery.contextBurstAtlasBuilds\n                        : profile.manager.contextBurstAtlasBuildsFloor,\n                    profile.manager.contextBurstAtlasBuildsFloor\n                ),\n                profile.manager.contextBurstAtlasBuildsFloor,\n                profile.manager.contextBurstAtlasBuildsCap,\n                profile.manager.contextBurstAtlasBuildsFloor\n            ),\n            atlasDrawBudgetMs: clampNumber(\n                Math.max(\n                    Number.isFinite(currentImagery.atlasDrawBudgetMs)\n                        ? currentImagery.atlasDrawBudgetMs\n                        : profile.manager.atlasDrawBudgetMsFloor,\n                    profile.manager.atlasDrawBudgetMsFloor\n                ),\n                profile.manager.atlasDrawBudgetMsFloor,\n                profile.manager.atlasDrawBudgetMsCap,\n                profile.manager.atlasDrawBudgetMsFloor\n            ),\n            atlasDrawMinTiles: clampInt(\n                Math.max(\n                    Number.isFinite(currentImagery.atlasDrawMinTiles)\n                        ? currentImagery.atlasDrawMinTiles\n                        : profile.manager.atlasDrawMinTilesFloor,\n                    profile.manager.atlasDrawMinTilesFloor\n                ),\n                profile.manager.atlasDrawMinTilesFloor,\n                profile.manager.atlasDrawMinTilesCap,\n                profile.manager.atlasDrawMinTilesFloor\n            ),\n            tileRetryDelayMs: clampInt(\n                currentImagery.tileRetryDelayMs,\n                profile.manager.tileRetryDelayMin,\n                profile.manager.tileRetryDelayMax,\n                profile.manager.tileRetryDelayMs\n            ),\n            atlasRetryDelayMs: clampInt(\n                currentImagery.atlasRetryDelayMs,\n                profile.manager.atlasRetryDelayMin,\n                profile.manager.atlasRetryDelayMax,\n                profile.manager.atlasRetryDelayMs\n            ),\n            maxAtlasTileFetches: clampInt(\n                Math.max(\n                    Number.isFinite(currentImagery.maxAtlasTileFetches)\n                        ? currentImagery.maxAtlasTileFetches\n                        : profile.manager.maxAtlasTileFetchesFloor,\n                    profile.manager.maxAtlasTileFetchesFloor\n                ),\n                profile.manager.maxAtlasTileFetchesFloor,\n                profile.manager.maxAtlasTileFetchesCap,\n                profile.manager.maxAtlasTileFetchesFloor\n            ),\n            atlasTileFetchConcurrency: clampInt(\n                Math.max(\n                    Number.isFinite(currentImagery.atlasTileFetchConcurrency)\n                        ? currentImagery.atlasTileFetchConcurrency\n                        : profile.manager.atlasTileFetchConcurrencyFloor,\n                    profile.manager.atlasTileFetchConcurrencyFloor\n                ),\n                profile.manager.atlasTileFetchConcurrencyFloor,\n                profile.manager.atlasTileFetchConcurrencyCap,\n                profile.manager.atlasTileFetchConcurrencyFloor\n            ),\n            atlasParentFallbackEnabled: true,\n            atlasParentFallbackMaxParents: clampInt(\n                Math.max(\n                    Number.isFinite(currentImagery.atlasParentFallbackMaxParents)\n                        ? currentImagery.atlasParentFallbackMaxParents\n                        : profile.manager.atlasParentFallbackMaxParentsFloor,\n                    profile.manager.atlasParentFallbackMaxParentsFloor\n                ),\n                profile.manager.atlasParentFallbackMaxParentsFloor,\n                profile.manager.atlasParentFallbackMaxParentsCap,\n                profile.manager.atlasParentFallbackMaxParentsFloor\n            ),\n            maxQueuedTileRequests: clampInt(\n                Math.max(\n                    Number.isFinite(currentImagery.maxQueuedTileRequests)\n                        ? currentImagery.maxQueuedTileRequests\n                        : profile.manager.maxQueuedTileRequestsFloor,\n                    profile.manager.maxQueuedTileRequestsFloor\n                ),\n                profile.manager.maxQueuedTileRequestsFloor,\n                profile.manager.maxQueuedTileRequestsCap,\n                profile.manager.maxQueuedTileRequestsFloor\n            ),\n            maxQueuedAtlasRequests: clampInt(\n                Math.max(\n                    Number.isFinite(currentImagery.maxQueuedAtlasRequests)\n                        ? currentImagery.maxQueuedAtlasRequests\n                        : profile.manager.maxQueuedAtlasRequestsFloor,\n                    profile.manager.maxQueuedAtlasRequestsFloor\n                ),\n                profile.manager.maxQueuedAtlasRequestsFloor,\n                profile.manager.maxQueuedAtlasRequestsCap,\n                profile.manager.maxQueuedAtlasRequestsFloor\n            )\n        });\n    }\n\n    _applyMobileGentleImagery() {\n        if (!this._triTree || !this._imageryManager) return;\n        this._applyMobileTextureSafetyCaps();\n    }\n\n    _applyMobileLiteAtmosphere({ enable = true } = {}) {\n        if (!this._sceneInitializer) return;\n        if (enable) {\n            this._sceneInitializer.setAtmosphereEnabled(true);\n        }\n        this._sceneInitializer.setAtmosphereDepthScale(0.4);\n        this._sceneInitializer.setAtmosphereDepthUpdateMs(250);\n        if (typeof this._sceneInitializer.setAtmosphereDepthThresholds === 'function') {\n            this._sceneInitializer.setAtmosphereDepthThresholds({\n                moveEps: 80,\n                rotateEps: 0.08,\n                planetRotateEps: 0.02\n            });\n        } else {\n            this._sceneInitializer.atmosphereDepthMoveEps = 80;\n            this._sceneInitializer.atmosphereDepthRotateEps = 0.08;\n            this._sceneInitializer.atmosphereDepthPlanetRotateEps = 0.02;\n        }\n        this._sceneInitializer.setAtmosphereScattering({\n            sampleScale: 0.35,\n            rayleighStrength: 0.55,\n            rayleighScaleHeight: 8000,\n            mieStrength: 0.35,\n            mieScaleHeight: 1200,\n            mieG: 0.7,\n            sunIntensity: 2.0\n        });\n        if (this._sceneInitializer.atmosphereMaterial) {\n            this._sceneInitializer.setAtmosphereAerialPerspective({\n                aerialPerspectiveStrength: 0.35,\n                aerialPerspectiveDensity: 0.00015,\n                aerialPerspectiveHeightFalloff: 10000,\n                minAtmospherePathLength: 0,\n                atmosphereAlphaScale: 0.6,\n                atmosphereDepthClamp: 0.9\n            });\n        }\n        if (this._sceneInitializer.earthMaterial) {\n            this._sceneInitializer.setTerrainAerialPerspective({\n                aerialPerspectiveStrength: 0.25,\n                aerialPerspectiveDensity: 0.00008,\n                aerialPerspectiveHeightFalloff: 8000\n            });\n        }\n    }\n\n    _applyMobileRuntimeBudgets() {\n        if (!this._isMobile) return;\n        // Settings are applied after the initial mobile profile. Reassert this\n        // ownership cap here so a desktop-sized saved setting cannot restore a\n        // 180k+ record cache on a phone.\n        this._applyMobileElevationSafetyCap();\n        this._applyMobileTextureSafetyCaps();\n        const profile = this._resolveMobileImageryProfile();\n        const overlayProfile = profile?.overlays || null;\n\n        if (this._renderer?.shadowMap) {\n            this._renderer.shadowMap.enabled = false;\n            this._renderer.shadowMap.autoUpdate = false;\n            this._renderer.shadowMap.needsUpdate = false;\n        }\n        if (this._lightingSystem?.sun) {\n            this._lightingSystem.sun.castShadow = false;\n            if (this._lightingSystem.sun.shadow?.mapSize?.set) {\n                this._lightingSystem.sun.shadow.mapSize.set(1024, 1024);\n            }\n        }\n\n        if (this._elevationClient?.setConfig) {\n            const currentBatch = Number.isFinite(this._elevationClient.batchSize)\n                ? this._elevationClient.batchSize\n                : 0;\n            const currentConcurrent = Number.isFinite(this._elevationClient.maxConcurrentBatches)\n                ? this._elevationClient.maxConcurrentBatches\n                : 0;\n            const currentInterval = Number.isFinite(this._elevationClient.minIntervalMs)\n                ? this._elevationClient.minIntervalMs\n                : 30;\n            this._elevationClient.setConfig({\n                batchSize: Math.max(currentBatch, 256),\n                maxConcurrent: Math.max(currentConcurrent, 16),\n                minIntervalMs: Math.min(currentInterval, 10)\n            });\n        }\n\n        this._sceneInitializer?.setEarthOverlayConfig?.({\n            specularMap: { enabled: false },\n            simpleClouds: { enabled: this._sceneSettings?.getSection?.('scene.atmosphere.simpleClouds.enabled') === true },\n            water: { enabled: false }\n        });\n\n        if (overlayProfile) {\n            if (Number.isFinite(overlayProfile.autoBuildingPollIntervalMs)) {\n                this._buildingAutoPollIntervalMs = Math.max(\n                    this._buildingAutoPollIntervalMs,\n                    overlayProfile.autoBuildingPollIntervalMs\n                );\n            }\n            if (Number.isFinite(overlayProfile.autoBuildingMinMoveM)) {\n                this._buildingAutoMinMoveM = Math.max(\n                    this._buildingAutoMinMoveM,\n                    overlayProfile.autoBuildingMinMoveM\n                );\n            }\n            if (Number.isFinite(overlayProfile.autoInfrastructurePollIntervalMs)) {\n                this._infrastructureAutoPollIntervalMs = Math.max(\n                    this._infrastructureAutoPollIntervalMs,\n                    overlayProfile.autoInfrastructurePollIntervalMs\n                );\n            }\n            if (Number.isFinite(overlayProfile.autoInfrastructureMinMoveM)) {\n                this._infrastructureAutoMinMoveM = Math.max(\n                    this._infrastructureAutoMinMoveM,\n                    overlayProfile.autoInfrastructureMinMoveM\n                );\n            }\n            if (Number.isFinite(overlayProfile.autoBuildingBootstrapDelayMs)) {\n                this._mobileBuildingBootstrapDelayMs = Math.max(\n                    this._mobileBuildingBootstrapDelayMs,\n                    overlayProfile.autoBuildingBootstrapDelayMs\n                );\n            }\n            if (Number.isFinite(overlayProfile.autoInfrastructureBootstrapDelayMs)) {\n                this._mobileInfrastructureBootstrapDelayMs = Math.max(\n                    this._mobileInfrastructureBootstrapDelayMs,\n                    overlayProfile.autoInfrastructureBootstrapDelayMs\n                );\n            }\n            if (Number.isFinite(overlayProfile.autoInfrastructureAfterBuildingsDelayMs)) {\n                this._mobileInfrastructureAfterBuildingsDelayMs = Math.max(\n                    this._mobileInfrastructureAfterBuildingsDelayMs,\n                    overlayProfile.autoInfrastructureAfterBuildingsDelayMs\n                );\n            }\n\n            const buildingPatch = {\n                radiusM: overlayProfile.buildingRadiusM,\n                maxFeatures: overlayProfile.buildingMaxFeatures,\n                lodBudget: overlayProfile.buildingLodBudget,\n                lodDetailRadiusM: overlayProfile.buildingLodDetailRadiusM,\n                lodImpostorRadiusM: overlayProfile.buildingLodImpostorRadiusM,\n                resnapBudget: overlayProfile.buildingResnapBudget\n            };\n            const infrastructurePatch = {\n                radiusM: overlayProfile.infrastructureRadiusM,\n                refreshDistanceM: overlayProfile.infrastructureRefreshDistanceM,\n                resnapBudget: overlayProfile.infrastructureResnapBudget,\n                drapeBudget: overlayProfile.infrastructureDrapeBudget,\n                alignMaxSamples: overlayProfile.infrastructureAlignMaxSamples,\n                roadStepM: overlayProfile.infrastructureRoadStepM,\n                motionEnabled: overlayProfile.infrastructureMotionEnabled\n            };\n            const signature = JSON.stringify({ buildingPatch, infrastructurePatch });\n            if (signature !== this._mobileOverlayBudgetSignature) {\n                this._mobileOverlayBudgetSignature = signature;\n                this.eventBus?.emit?.('buildings:config', buildingPatch);\n                this.eventBus?.emit?.('infrastructure:config', infrastructurePatch);\n            }\n        }\n\n        if (!this._animationLoop) return;\n\n        const currentScale = this._renderer?.getPixelRatio?.() ?? this._sceneInitializer?.renderScale;\n        if (Number.isFinite(currentScale) && currentScale < 1.0) {\n            this._sceneInitializer?.setRenderScale?.(1.0);\n        }\n\n        const currentNormalsBudget = Number.isFinite(this._animationLoop.maxNormalsPerFrame)\n            ? this._animationLoop.maxNormalsPerFrame\n            : 32;\n        const currentMorphBudget = Number.isFinite(this._animationLoop.maxElevationMorphTilesPerFrame)\n            ? this._animationLoop.maxElevationMorphTilesPerFrame\n            : 24;\n        const currentFinalizeBudget = Number.isFinite(this._animationLoop.maxGeometryFinalizeTilesPerFrame)\n            ? this._animationLoop.maxGeometryFinalizeTilesPerFrame\n            : 24;\n        const currentMorphMsBudget = Number.isFinite(this._animationLoop.maxElevationMorphMsPerFrame)\n            ? this._animationLoop.maxElevationMorphMsPerFrame\n            : 2.5;\n        const currentFinalizeMsBudget = Number.isFinite(this._animationLoop.maxGeometryFinalizeMsPerFrame)\n            ? this._animationLoop.maxGeometryFinalizeMsPerFrame\n            : 2.0;\n        this._animationLoop.setTerrainWorkBudgets?.({\n            maxNormalsPerFrame: Math.min(32, Math.max(currentNormalsBudget, 16)),\n            maxElevationMorphTilesPerFrame: Math.min(24, Math.max(currentMorphBudget, 12)),\n            maxGeometryFinalizeTilesPerFrame: Math.min(24, Math.max(currentFinalizeBudget, 12)),\n            maxElevationMorphMsPerFrame: Math.min(2.5, Math.max(currentMorphMsBudget, 1.8)),\n            maxGeometryFinalizeMsPerFrame: Math.min(2.0, Math.max(currentFinalizeMsBudget, 1.6))\n        });\n\n        this._animationLoop.setAutoRenderScaleEnabled?.(false);\n    }\n\n    _applyMobileElevationSafetyCap() {\n        if (!this._isMobile || !this._elevationClient) return;\n        const profile = this._resolveMobileImageryProfile();\n        const isLow = profile.tri.tileBudgetCap <= 1000;\n        const isMid = !isLow && profile.tri.tileBudgetCap <= 1150;\n        const hardCap = isLow ? 48_000 : isMid ? 72_000 : 96_000;\n        const configured = Number.isFinite(this._elevationClient.maxVertexRecords)\n            ? this._elevationClient.maxVertexRecords\n            : hardCap;\n        const mobileVertexCap = Math.min(configured, hardCap);\n        this._elevationClient.setMemoryBudgetBaseline?.(mobileVertexCap);\n        this._elevationClient.setConfig?.({\n            maxVertexRecords: mobileVertexCap,\n            sampleStrideMultiplier: isLow ? 3 : 2,\n            ringNearMeters: isLow ? 8_000 : 12_000,\n            ringMidMeters: isLow ? 28_000 : 40_000,\n        });\n    }\n\n    _syncMobileSurfaceOverlayBootstrapState(now) {\n        if (!this._isMobile) return;\n        const timestamp = Number.isFinite(now)\n            ? now\n            : (typeof performance !== 'undefined' ? performance.now() : Date.now());\n        const inSurface = this._surfaceController?.isInSurfaceMode?.() || false;\n        if (inSurface) {\n            if (!this._mobileSurfaceOverlayInSurface) {\n                this._mobileSurfaceOverlayInSurface = true;\n                this._mobileSurfaceOverlayEnterTs = timestamp;\n            }\n            return;\n        }\n        this._mobileSurfaceOverlayInSurface = false;\n        this._mobileSurfaceOverlayEnterTs = 0;\n    }\n\n    _isMobileOverlayBootstrapLocked(kind, timestamp) {\n        if (!this._isMobile) return false;\n        if (!this._mobileSurfaceOverlayInSurface) return false;\n        if (!Number.isFinite(this._mobileSurfaceOverlayEnterTs)) return false;\n\n        const elapsedMs = timestamp - this._mobileSurfaceOverlayEnterTs;\n        if (!Number.isFinite(elapsedMs) || elapsedMs < 0) return false;\n\n        if (kind === 'building') {\n            const delayMs = Number.isFinite(this._mobileBuildingBootstrapDelayMs)\n                ? this._mobileBuildingBootstrapDelayMs\n                : 0;\n            return !this._buildingAutoCenter && elapsedMs < delayMs;\n        }\n\n        if (kind === 'infrastructure') {\n            const baseDelayMs = Number.isFinite(this._mobileInfrastructureBootstrapDelayMs)\n                ? this._mobileInfrastructureBootstrapDelayMs\n                : 0;\n            if (!this._infrastructureAutoCenter && elapsedMs < baseDelayMs) {\n                return true;\n            }\n            const afterBuildingsDelayMs = Number.isFinite(this._mobileInfrastructureAfterBuildingsDelayMs)\n                ? this._mobileInfrastructureAfterBuildingsDelayMs\n                : 0;\n            if (!this._infrastructureAutoCenter &&\n                !this._buildingAutoCenter &&\n                elapsedMs < (baseDelayMs + afterBuildingsDelayMs)) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    _bootstrapMobileUi() {\n        if (!this._isMobile) return;\n\n        const mobileToggle = document.getElementById('mobile-hud-toggle');\n        const mobileModal = document.getElementById('mobile-hud-modal');\n        const mobileClose = document.getElementById('mobile-hud-modal-close');\n        const mobileContent = document.getElementById('mobile-hud-modal-content');\n\n        const sidebar = document.getElementById('sidebar');\n        const overlaySidebar = document.getElementById('overlay-sidebar');\n        if (sidebar && mobileContent && sidebar.parentElement !== mobileContent) {\n            mobileContent.appendChild(sidebar);\n        }\n        if (overlaySidebar && mobileContent && overlaySidebar.parentElement !== mobileContent) {\n            mobileContent.appendChild(overlaySidebar);\n        }\n\n        mobileToggle?.addEventListener('click', () => {\n            mobileModal?.classList.toggle('active');\n        });\n\n        mobileClose?.addEventListener('click', () => {\n            mobileModal?.classList.remove('active');\n        });\n\n        mobileModal?.addEventListener('click', (e) => {\n            if (e.target === mobileModal) {\n                mobileModal.classList.remove('active');\n            }\n        });\n\n        // Double-tap handling is owned by EventManager on the renderer element.\n    }\n\n    _enableMobileWireframeDefault() {\n        setTimeout(() => {\n            const current = this._sceneSettings?.getSection?.('scene.debug.wireframe');\n            if (current !== true && this._sceneSettings?.updateScene) {\n                this._sceneSettings.updateScene({ debug: { wireframe: true } });\n                if (globalThis.__noclipDebugWireframe === true) {\n                    console.log('Mobile: Wireframe mode enabled by default');\n                }\n                return;\n            }\n            const wireframeCheckbox = document.getElementById('cfg-wireframe');\n            if (wireframeCheckbox && !wireframeCheckbox.checked) {\n                wireframeCheckbox.checked = true;\n                wireframeCheckbox.dispatchEvent(new Event('change'));\n                if (globalThis.__noclipDebugWireframe === true) {\n                    console.log('Mobile: Wireframe mode enabled by default');\n                }\n            }\n        }, 100);\n    }\n\n    _updateHexVisualization() {\n        if (!this._eventManager || !this._sceneInitializer || !this._triTree) return;\n        const hexSelection = this._eventManager.getHexSelection();\n        const metricHex = document.getElementById('metric-hex');\n        if (!metricHex) return;\n        this._sceneInitializer.updateHexVisualization(hexSelection, metricHex, this._triTree);\n    }\n\n    _updateOverlayGeoContext(now) {\n        if ((!this._overlaySubsystem && !this._fieldAssetLayer)\n            || !this._surfaceController\n            || !this._triTree\n            || !this._camera) return;\n        const timestamp = Number.isFinite(now) ? now : performance.now();\n        const minIntervalMs = 250;\n        if (this._overlayGeoContextTs && timestamp - this._overlayGeoContextTs < minIntervalMs) {\n            return;\n        }\n\n        let targetPos = null;\n        if (this._surfaceController.isInSurfaceMode()) {\n            targetPos = this._surfaceController.getSurfacePosition();\n        } else {\n            const viewDir = new THREE.Vector3();\n            this._camera.getWorldDirection(viewDir);\n            const cameraPos = this._camera?.userData?.worldPosition || this._camera.position;\n            const planetGroup = this._triTree?.group || null;\n            targetPos = rayEllipsoidIntersection(cameraPos, viewDir, planetGroup) ||\n                raySphereIntersection(cameraPos, viewDir);\n        }\n        if (!targetPos) return;\n\n        const ll = worldPosToLatLonLocal(targetPos, this._triTree?.group);\n        if (!ll) return;\n        const lat = ll.latDeg;\n        const lon = ll.lonDeg;\n        const prev = this._overlayGeoContext;\n        if (prev) {\n            const deltaLat = Math.abs(prev.lat - lat);\n            const deltaLon = Math.abs(prev.lon - lon);\n            if (deltaLat < 0.01 && deltaLon < 0.01) return;\n        }\n        this._overlayGeoContext = { lat, lon };\n        this._overlayGeoContextTs = timestamp;\n        this._overlaySubsystem?.setGeoContext?.({ lat, lon });\n        this._fieldAssetLayer?.setGeoContext?.({ lat, lon });\n    }\n\n    _updateNavGeoContext(now) {\n        // Resolving a country builds the full world boundary index. The globe\n        // overview does not present local navigation context, so delay that\n        // parse until local detail is requested.\n        if (this._overviewGlobeMode === true) return;\n        const hudStore = getHudInfoStore();\n        const lat = hudStore?.getData?.('nav.lat');\n        const lon = hudStore?.getData?.('nav.lon');\n        if (!Number.isFinite(lat) || !Number.isFinite(lon)) return;\n        const timestamp = Number.isFinite(now)\n            ? now\n            : (typeof performance !== 'undefined' ? performance.now() : Date.now());\n        const prev = this._navGeoContext;\n        const withinInterval = this._navGeoContextTs\n            ? (timestamp - this._navGeoContextTs) < this._navGeoPollIntervalMs\n            : false;\n        const withinDelta = prev\n            ? (Math.abs(prev.lat - lat) < this._navGeoPollDeltaDeg &&\n                Math.abs(prev.lon - lon) < this._navGeoPollDeltaDeg)\n            : false;\n        const needsSeed = !this._navGeoInfo?.countryName && !this._navGeoInfo?.iso3;\n\n        if (this._navGeoInFlight) {\n            this._navGeoPending = true;\n            this._navGeoContext = { lat, lon };\n            this._navGeoContextTs = timestamp;\n            return;\n        }\n\n        if (prev && withinInterval && withinDelta && !needsSeed) return;\n        this._navGeoContext = { lat, lon };\n        this._navGeoContextTs = timestamp;\n        this._resolveNavGeoContext(lat, lon);\n    }\n\n    /**\n     * Build the bounded, authoritative scene-awareness payload consumed by the\n     * agent. It joins post-culling LabelSystem state, the HUD's point/entity\n     * frustum results, and camera-relevant geometry/raster/volume layers.\n     */\n    _buildAgentViewshedSnapshot({\n        categories = null,\n        includeDetails = true,\n        maxItems = 120,\n        maxItemsPerCategory = 32,\n    } = {}) {\n        const generatedAt = new Date().toISOString();\n        const categoryFilter = categories instanceof Set\n            ? categories\n            : resolveViewshedCategories(categories);\n        const totalLimit = Math.max(1, Math.min(240, Math.floor(Number(maxItems) || 120)));\n        const categoryLimit = Math.max(1, Math.min(64, Math.floor(Number(maxItemsPerCategory) || 32)));\n        const labelSettings = this._sceneSettings?.getSection?.('scene.labels') || {};\n        const labelsMasterEnabled = labelSettings.enabled !== false;\n\n        if (this._camera && this._triTree?.group) {\n            this._camera.updateMatrixWorld(true);\n            this._triTree.group.updateMatrixWorld(true);\n            this._viewshedMatrix.multiplyMatrices(\n                this._camera.projectionMatrix,\n                this._camera.matrixWorldInverse,\n            );\n            this._viewshedFrustum.setFromProjectionMatrix(this._viewshedMatrix);\n        }\n\n        const isGeoVisible = (lat, lon, altitudeM = 0) => {\n            if (!this._camera || !this._triTree?.group) return false;\n            const localDirection = latLonToLocalDir(Number(lat), Number(lon));\n            if (!localDirection) return false;\n            const radius = ellipsoidRadiusForLocalDir(localDirection) + (Number(altitudeM) || 0);\n            const position = this._getWorldPositionFromLatLon(\n                Number(lat),\n                Number(lon),\n                radius,\n                this._agentViewshedTmpPos,\n            );\n            return !!position && this._viewshedFrustum.containsPoint(position);\n        };\n\n        const labelSnapshot = getLabelSystem()?.getVisibleSnapshot?.({\n            categories: categoryFilter,\n            maxItems: 200,\n            includeMetadata: true,\n        }) || { counts: {}, items: [], visibleCount: 0, truncated: false };\n        const environment = this._environmentalOverlay?.getAgentSnapshot?.({\n            isGeoVisible,\n            limitPerLayer: categoryLimit,\n        }) || { layers: {} };\n        const signals = this._globalSignalsOverlay?.getAgentSnapshot?.({\n            isGeoVisible,\n            limitPerLayer: categoryLimit,\n        }) || { layers: {} };\n        const namedPlaces = getBusinessLabels()?.getEntriesSnapshot?.() || [];\n        const coreSourceLayers = {\n            aircraft: { category: 'aircraft', enabled: this._aircraftOverlay?.enabled === true, loadedCount: this._aircraftOverlay?.getEntriesSnapshot?.()?.length || 0 },\n            maritime: { category: 'maritime', enabled: this._maritimeOverlay?.enabled === true, loadedCount: this._maritimeOverlay?.getEntriesSnapshot?.()?.length || 0 },\n            satellites: { category: 'satellites', enabled: this._satelliteOverlay?.enabled === true, loadedCount: this._satelliteOverlay?.getEntriesSnapshot?.()?.length || 0 },\n            incidents: { category: 'incidents', enabled: this._incidentOverlay?.enabled === true, loadedCount: this._incidentOverlay?.getEntriesSnapshot?.()?.length || 0 },\n            sensors: {\n                category: 'sensors',\n                enabled: this._sensorOverlay?.enabled === true || this._meshtasticOverlay?.enabled === true,\n                loadedCount: this._meshtasticOverlay?.getEntriesSnapshot?.()?.length || 0,\n                metadata: sanitizeAgentValue(getSensorManager()?.getStatus?.() || {}),\n            },\n            trafficCameras: { category: 'trafficCameras', enabled: this._trafficCameraOverlay?.enabled === true, loadedCount: this._trafficCameraOverlay?.getEntriesSnapshot?.()?.length || 0, metadata: sanitizeAgentValue(this._trafficCameraOverlay?.getDiscoverySnapshot?.() || {}) },\n            roadTraffic: { category: 'roadTraffic', enabled: this._roadTrafficOverlay?.enabled === true, loadedCount: this._roadTrafficOverlay?.getEntriesSnapshot?.()?.length || 0, metadata: sanitizeAgentValue(this._roadTrafficOverlay?.getStatusSnapshot?.() || {}) },\n            buildings: { category: 'buildings', enabled: this._buildingOverlay?.enabled === true, loadedCount: this._buildingOverlay?.getEntriesSnapshot?.()?.length || 0 },\n            places: { category: 'places', enabled: getBusinessLabels()?.enabled === true, loadedCount: namedPlaces.filter((entry) => entry?.type !== 'natural' && entry?.kind !== 'natural').length },\n            natural: { category: 'natural', enabled: getBusinessLabels()?.enabled === true, loadedCount: namedPlaces.filter((entry) => entry?.type === 'natural' || entry?.kind === 'natural').length },\n            infrastructure: { category: 'infrastructure', enabled: this._infrastructureOverlay?.enabled === true, loadedCount: this._infrastructureOverlay?.getEntriesSnapshot?.()?.length || 0 },\n            geocaches: {\n                category: 'geocaches',\n                enabled: this._geocacheLayer?.enabled === true,\n                loadedCount: this._geocacheLayer?.getSnapshot?.()?.records?.length || 0,\n                metadata: sanitizeAgentValue(this._geocacheLayer?.getSnapshot?.() || {}),\n            },\n        };\n        const sourceLayers = {\n            ...coreSourceLayers,\n            ...(environment.layers || {}),\n            ...(signals.layers || {}),\n        };\n\n        const byCategory = new Map();\n        const dedupe = new Map();\n        const sourceVisibleCounts = {};\n        const appendItem = (rawItem) => {\n            if (!rawItem || typeof rawItem !== 'object') return;\n            const category = rawItem.category || 'overlays';\n            if (categoryFilter && !categoryFilter.has(category)) return;\n            const id = String(rawItem.id ?? rawItem.labelId ?? `${category}:unknown`);\n            const key = `${category}:${id}`;\n            const existing = dedupe.get(key);\n            if (existing) {\n                Object.assign(existing, {\n                    ...rawItem,\n                    metadata: {\n                        ...(existing.metadata || {}),\n                        ...(rawItem.metadata || {}),\n                    },\n                });\n                return;\n            }\n            const item = sanitizeAgentValue({ ...rawItem, id, category }, { maxDepth: 5 });\n            if (!item) return;\n            dedupe.set(key, item);\n            if (!byCategory.has(category)) byCategory.set(category, []);\n            byCategory.get(category).push(item);\n        };\n\n        for (const item of labelSnapshot.items || []) appendItem(item);\n        for (const [category, layer] of Object.entries(sourceLayers)) {\n            if (categoryFilter && !categoryFilter.has(category)) continue;\n            sourceVisibleCounts[category] = Number(layer?.visibleCount) || 0;\n            for (const item of layer?.items || []) appendItem(item);\n        }\n\n        const hudCategoryMap = Object.freeze({\n            aircraft: 'aircraft',\n            satellites: 'satellites',\n            maritime: 'maritime',\n            buildings: 'buildings',\n            businesses: 'places',\n            natural: 'natural',\n            infrastructure: 'infrastructure',\n            incidents: 'incidents',\n        });\n        const hudStore = getHudInfoStore();\n        for (const [hudName, category] of Object.entries(hudCategoryMap)) {\n            if (categoryFilter && !categoryFilter.has(category)) continue;\n            const rows = hudStore?.getData?.(`viewshed.${hudName}`);\n            if (!Array.isArray(rows)) continue;\n            sourceVisibleCounts[category] = Math.max(sourceVisibleCounts[category] || 0, rows.length);\n            for (const row of rows) {\n                const entry = row?.entry && typeof row.entry === 'object' ? row.entry : {};\n                const id = agentEntityId(entry, `${category}:${row?.id ?? 'visible'}`);\n                const title = entry.callsign\n                    || entry.name\n                    || entry.address\n                    || entry.callType\n                    || entry.kindLabel\n                    || id;\n                const observedAt = entry.observed_at\n                    || entry.observedAt\n                    || entry.timestamp\n                    || entry.updated_at\n                    || entry.updatedAt\n                    || entry.lastSeen\n                    || null;\n                appendItem({\n                    id,\n                    category,\n                    type: row?.type || category,\n                    title: String(title || category),\n                    lat: Number.isFinite(Number(entry.lat)) ? Number(entry.lat) : null,\n                    lon: Number.isFinite(Number(entry.lon)) ? Number(entry.lon) : null,\n                    distanceM: Number.isFinite(Number(row?.distanceM)) ? Number(row.distanceM) : null,\n                    observedAt,\n                    source: entry.source || entry.provider || null,\n                    sourceUrl: entry.sourceUrl || entry.source_url || null,\n                    rendered: true,\n                    pointEntityVisible: true,\n                    metadata: { ...entry, viewshed: { ...row, entry: undefined } },\n                });\n            }\n        }\n\n        for (const items of byCategory.values()) {\n            items.sort((a, b) => (\n                (Number(a.distanceM ?? Infinity) - Number(b.distanceM ?? Infinity))\n                || String(a.title || '').localeCompare(String(b.title || ''))\n            ));\n        }\n        const selectedByCategory = new Map();\n        let selectionCount = 0;\n        if (includeDetails) {\n            for (let index = 0; index < categoryLimit && selectionCount < totalLimit; index += 1) {\n                let selectedThisPass = 0;\n                for (const category of LABEL_CATEGORIES) {\n                    if (categoryFilter && !categoryFilter.has(category.id)) continue;\n                    const item = byCategory.get(category.id)?.[index];\n                    if (!item) continue;\n                    if (!selectedByCategory.has(category.id)) selectedByCategory.set(category.id, []);\n                    selectedByCategory.get(category.id).push(item);\n                    selectionCount += 1;\n                    selectedThisPass += 1;\n                    if (selectionCount >= totalLimit) break;\n                }\n                if (!selectedThisPass) break;\n            }\n        }\n\n        const categoriesOut = [];\n        const summaries = {};\n        const details = {};\n        let visibleCount = 0;\n        let returnedCount = 0;\n        let truncated = labelSnapshot.truncated === true;\n        for (const category of LABEL_CATEGORIES) {\n            if (categoryFilter && !categoryFilter.has(category.id)) continue;\n            const layer = sourceLayers[category.id] || null;\n            const allItems = byCategory.get(category.id) || [];\n            allItems.sort((a, b) => (\n                (Number(a.distanceM ?? Infinity) - Number(b.distanceM ?? Infinity))\n                || String(a.title || '').localeCompare(String(b.title || ''))\n            ));\n            const categoryVisible = Math.max(\n                allItems.length,\n                Number(labelSnapshot.counts?.[category.id]) || 0,\n                Number(sourceVisibleCounts[category.id]) || 0,\n            );\n            const enabled = labelsMasterEnabled\n                && getLabelCategoryValue(labelSettings, category.id, true)\n                && (layer ? layer.enabled !== false : true);\n            const selected = includeDetails ? (selectedByCategory.get(category.id) || []) : [];\n            summaries[category.id] = categoryVisible;\n            if (includeDetails) details[category.id] = selected;\n            visibleCount += categoryVisible;\n            returnedCount += selected.length;\n            truncated ||= allItems.length > selected.length || layer?.truncated === true;\n            categoriesOut.push({\n                id: category.id,\n                group: category.group,\n                label: category.label,\n                description: category.description,\n                enabled,\n                visibleCount: categoryVisible,\n                returnedCount: selected.length,\n                sourceState: layer ? sanitizeAgentValue({ ...layer, items: undefined }) : null,\n            });\n        }\n\n        return {\n            generatedAt,\n            authoritative: true,\n            coordinateOrder: 'latitude, longitude',\n            visibilityBasis: 'post-culling labels plus camera/frustum/horizon-filtered visible geometry and active non-geographic layers',\n            currentSceneOnly: true,\n            summaries,\n            categories: categoriesOut,\n            ...(includeDetails ? { details } : {}),\n            visibleCount,\n            returnedCount,\n            truncated,\n        };\n    }\n\n    _getAgentViewshedEntityDetails(id, category = null) {\n        const wantedId = String(id ?? '').trim();\n        if (!wantedId) return null;\n        const filter = category ? [category] : null;\n        const snapshot = this._buildAgentViewshedSnapshot({\n            categories: filter,\n            includeDetails: true,\n            maxItems: 240,\n            maxItemsPerCategory: 64,\n        });\n        for (const [categoryId, items] of Object.entries(snapshot.details || {})) {\n            const item = items.find((entry) => (\n                String(entry?.id ?? '') === wantedId\n                || String(entry?.labelId ?? '') === wantedId\n            ));\n            if (item) {\n                return {\n                    found: true,\n                    category: getLabelCategory(categoryId)?.label || categoryId,\n                    item,\n                    generatedAt: snapshot.generatedAt,\n                    authoritative: true,\n                };\n            }\n        }\n        return {\n            found: false,\n            id: wantedId,\n            category: category || null,\n            generatedAt: snapshot.generatedAt,\n            authoritative: true,\n            reason: 'The entity is not in the current post-culling visible snapshot.',\n        };\n    }\n\n    _updateViewshed(now) {\n        if (!this._camera || !this._triTree?.group) return;\n        const hudStore = getHudInfoStore();\n        if (!hudStore) return;\n\n        const timestamp = Number.isFinite(now)\n            ? now\n            : (typeof performance !== 'undefined' ? performance.now() : Date.now());\n        if (timestamp - this._viewshedLastUpdate < this._viewshedUpdateIntervalMs) return;\n        this._viewshedLastUpdate = timestamp;\n\n        this._camera.updateMatrixWorld(true);\n        this._triTree.group.updateMatrixWorld(true);\n        this._viewshedMatrix.multiplyMatrices(this._camera.projectionMatrix, this._camera.matrixWorldInverse);\n        this._viewshedFrustum.setFromProjectionMatrix(this._viewshedMatrix);\n\n        const cameraPos = this._camera.userData?.worldPosition\n            || this._camera.getWorldPosition(this._viewshedCameraPos);\n        const earthMatrix = this._triTree.group.matrixWorld;\n        const maxItems = this._viewshedMaxItems;\n        const tmpVec = this._viewshedTmpVec;\n\n        const formatDistance = (distanceM) => {\n            if (!Number.isFinite(distanceM)) return '--';\n            if (distanceM >= 100000) return `${(distanceM / 1000).toFixed(0)} km`;\n            if (distanceM >= 1000) return `${(distanceM / 1000).toFixed(1)} km`;\n            return `${distanceM.toFixed(0)} m`;\n        };\n\n        const formatAltitude = (altitudeM) => {\n            if (!Number.isFinite(altitudeM)) return null;\n            if (Math.abs(altitudeM) >= 10000) {\n                return `${(altitudeM / 1000).toFixed(1)} km`;\n            }\n            return `${altitudeM.toFixed(0)} m`;\n        };\n\n        const toWorldPosition = (lat, lon, altitudeM = 0) => {\n            if (!Number.isFinite(lat) || !Number.isFinite(lon)) return null;\n            const latRad = lat * DEG2RAD;\n            const lonRad = lon * DEG2RAD - (EARTH_PRIME_MERIDIAN_OFFSET_RAD || 0);\n            const sinLat = Math.sin(latRad);\n            const cosLat = Math.cos(latRad);\n            tmpVec.set(\n                cosLat * Math.sin(lonRad),\n                sinLat,\n                cosLat * Math.cos(lonRad)\n            );\n            const baseRadius = ellipsoidRadiusForLocalDir(tmpVec);\n            const radius = baseRadius + (Number.isFinite(altitudeM) ? altitudeM : 0);\n            tmpVec.multiplyScalar(radius);\n            tmpVec.applyMatrix4(earthMatrix);\n            return tmpVec;\n        };\n\n        const toWorldPositionFromRadius = (lat, lon, radius) => {\n            if (!Number.isFinite(lat) || !Number.isFinite(lon)) return null;\n            const latRad = lat * DEG2RAD;\n            const lonRad = lon * DEG2RAD - (EARTH_PRIME_MERIDIAN_OFFSET_RAD || 0);\n            const sinLat = Math.sin(latRad);\n            const cosLat = Math.cos(latRad);\n            tmpVec.set(\n                cosLat * Math.sin(lonRad),\n                sinLat,\n                cosLat * Math.cos(lonRad)\n            ).multiplyScalar(radius || PLANET_RADIUS);\n            tmpVec.applyMatrix4(earthMatrix);\n            return tmpVec;\n        };\n\n        const resolveViewshedId = (type, entry) => {\n            if (!entry) return null;\n            switch (type) {\n                case 'aircraft':\n                    return entry.rawId || entry.id || entry.callsign || null;\n                case 'satellite':\n                    return entry.noradCatId || entry.id || entry.name || null;\n                case 'maritime':\n                    return entry.mmsi || entry.id || entry.name || null;\n                case 'building':\n                    return entry.id || entry.name || null;\n                case 'business':\n                case 'natural':\n                case 'infrastructure':\n                    return entry.id || entry.key || entry.osmId || entry.name || null;\n                case 'incident':\n                    return entry.id || entry.address || null;\n                default:\n                    return entry.id || null;\n            }\n        };\n\n        const resolveViewshedSizeM = (type, entry) => {\n            switch (type) {\n                case 'building': {\n                    const height = Number.isFinite(entry?.height) ? entry.height : null;\n                    return height ? Math.max(8, height) : 16;\n                }\n                case 'incident': {\n                    const scale = Number.isFinite(this._incidentOverlay?.markerScaleM)\n                        ? this._incidentOverlay.markerScaleM\n                        : 1000;\n                    return Math.max(1, scale);\n                }\n                case 'business':\n                    return 18;\n                case 'natural':\n                    return 36;\n                case 'infrastructure':\n                    return Number.isFinite(entry?.sizeM) ? Math.max(8, entry.sizeM) : 24;\n                case 'aircraft':\n                    return 24;\n                case 'satellite':\n                    return 40;\n                case 'maritime':\n                    return 30;\n                default:\n                    return 20;\n            }\n        };\n\n        const collect = (entries, positionForEntry, labelForEntry, metaForEntry) => {\n            const matches = [];\n            for (const entry of entries) {\n                const pos = positionForEntry(entry);\n                if (!pos) continue;\n                if (!this._viewshedFrustum.containsPoint(pos)) continue;\n                const distance = cameraPos.distanceTo(pos);\n                const meta = metaForEntry ? metaForEntry(entry) : null;\n                matches.push({ entry, distance, meta });\n            }\n            matches.sort((a, b) => a.distance - b.distance);\n            const limited = matches.slice(0, maxItems);\n            return {\n                list: limited.map(({ entry, distance }) => labelForEntry(entry, distance)),\n                data: limited.map(({ entry, distance, meta }) => ({\n                    entry,\n                    distanceM: distance,\n                    ...(meta || {})\n                }))\n            };\n        };\n\n        const aircraftEntries = this._aircraftOverlay?.getEntriesSnapshot?.() || [];\n        const aircraftOffset = Number.isFinite(this._aircraftOverlay?.altitudeOffsetM)\n            ? this._aircraftOverlay.altitudeOffsetM\n            : 0;\n        const aircraft = collect(\n            aircraftEntries,\n            (entry) => {\n                const altitude = Number.isFinite(entry.altitudeM) ? entry.altitudeM : 0;\n                return toWorldPosition(entry.lat, entry.lon, altitude + aircraftOffset);\n            },\n            (entry, distance) => {\n                const label = (typeof entry.callsign === 'string' && entry.callsign.trim())\n                    || entry.rawId\n                    || entry.id\n                    || 'Aircraft';\n                const altitude = formatAltitude(entry.altitudeM);\n                return `${label} | ${formatDistance(distance)}${altitude ? ` | ${altitude}` : ''}`;\n            },\n            (entry) => ({\n                id: resolveViewshedId('aircraft', entry),\n                type: 'aircraft',\n                sizeM: resolveViewshedSizeM('aircraft', entry),\n                color: 0x00aaff\n            })\n        );\n        hudStore.setList('viewshed.aircraft', aircraft.list);\n        hudStore.setData('viewshed.aircraft', aircraft.data);\n\n        const satelliteEntries = this._satelliteOverlay?.getEntriesSnapshot?.() || [];\n        const satelliteOffset = Number.isFinite(this._satelliteOverlay?.altitudeOffsetM)\n            ? this._satelliteOverlay.altitudeOffsetM\n            : 0;\n        const satellites = collect(\n            satelliteEntries,\n            (entry) => {\n                const altitude = Number.isFinite(entry.altitudeM) ? entry.altitudeM : 0;\n                return toWorldPosition(entry.lat, entry.lon, altitude + satelliteOffset);\n            },\n            (entry, distance) => {\n                const label = (typeof entry.name === 'string' && entry.name.trim())\n                    || entry.noradCatId\n                    || entry.id\n                    || 'Satellite';\n                const altitude = formatAltitude(entry.altitudeM);\n                return `${label} | ${formatDistance(distance)}${altitude ? ` | ${altitude}` : ''}`;\n            },\n            (entry) => ({\n                id: resolveViewshedId('satellite', entry),\n                type: 'satellite',\n                sizeM: resolveViewshedSizeM('satellite', entry),\n                color: 0xaa88ff\n            })\n        );\n        hudStore.setList('viewshed.satellites', satellites.list);\n        hudStore.setData('viewshed.satellites', satellites.data);\n\n        const maritimeEntries = this._maritimeOverlay?.getEntriesSnapshot?.() || [];\n        const maritimeOffset = Number.isFinite(this._maritimeOverlay?.altitudeOffsetM)\n            ? this._maritimeOverlay.altitudeOffsetM\n            : 0;\n        const maritime = collect(\n            maritimeEntries,\n            (entry) => {\n                return toWorldPosition(entry.lat, entry.lon, maritimeOffset);\n            },\n            (entry, distance) => {\n                const label = (typeof entry.name === 'string' && entry.name.trim())\n                    || entry.mmsi\n                    || entry.id\n                    || 'Vessel';\n                return `${label} | ${formatDistance(distance)}`;\n            },\n            (entry) => ({\n                id: resolveViewshedId('maritime', entry),\n                type: 'maritime',\n                sizeM: resolveViewshedSizeM('maritime', entry),\n                color: 0x00ccaa\n            })\n        );\n        hudStore.setList('viewshed.maritime', maritime.list);\n        hudStore.setData('viewshed.maritime', maritime.data);\n\n        const buildingEntries = this._buildingOverlay?.getEntriesSnapshot?.() || [];\n        const buildingOffset = Number.isFinite(this._buildingOverlay?.surfaceOffsetM)\n            ? this._buildingOverlay.surfaceOffsetM\n            : 0;\n        const buildings = collect(\n            buildingEntries,\n            (entry) => {\n                let baseRadius = entry.surfaceRadius;\n                if (!Number.isFinite(baseRadius)) {\n                    const dir = latLonToLocalDir(entry.lat, entry.lon);\n                    baseRadius = dir ? ellipsoidRadiusForLocalDir(dir) : PLANET_RADIUS;\n                }\n                return toWorldPositionFromRadius(entry.lat, entry.lon, baseRadius + buildingOffset);\n            },\n            (entry, distance) => {\n                const address = typeof entry.address === 'string' ? entry.address.trim() : '';\n                const hasAddress = address && address.toLowerCase() !== 'unknown address';\n                const name = (typeof entry.name === 'string' && entry.name.trim()) || '';\n                const label = (hasAddress ? address : name) || 'Building';\n                return `${label} | ${formatDistance(distance)}`;\n            },\n            (entry) => ({\n                id: resolveViewshedId('building', entry),\n                type: 'building',\n                sizeM: resolveViewshedSizeM('building', entry),\n                color: 0xff8800\n            })\n        );\n        hudStore.setList('viewshed.buildings', buildings.list);\n        hudStore.setData('viewshed.buildings', buildings.data);\n\n        const namedPlaceEntries = getBusinessLabels()?.getEntriesSnapshot?.() || [];\n        const businessEntries = namedPlaceEntries.filter((entry) => entry?.type !== 'natural' && entry?.kind !== 'natural');\n        const businesses = collect(\n            businessEntries,\n            (entry) => toWorldPosition(entry.lat, entry.lon, Number.isFinite(entry.altitudeM) ? entry.altitudeM : 28),\n            (entry, distance) => {\n                const label = (typeof entry.name === 'string' && entry.name.trim())\n                    || entry.kindLabel\n                    || 'Business';\n                const kind = entry.kindLabel ? ` | ${entry.kindLabel}` : '';\n                const address = typeof entry.address === 'string' && entry.address.trim()\n                    ? ` | ${entry.address.trim()}`\n                    : '';\n                return `${label} | ${formatDistance(distance)}${kind}${address}`;\n            },\n            (entry) => ({\n                id: resolveViewshedId('business', entry),\n                type: 'business',\n                sizeM: resolveViewshedSizeM('business', entry),\n                color: Number.isFinite(entry.color) ? entry.color : 0x6ee7b7,\n                colorHex: entry.colorHex || entry.hex || null,\n                address: entry.address || '',\n                category: entry.category || entry.kindLabel || '',\n                phone: entry.phone || '',\n                website: entry.website || ''\n            })\n        );\n        hudStore.setList('viewshed.businesses', businesses.list);\n        hudStore.setData('viewshed.businesses', businesses.data);\n\n        const naturalEntries = namedPlaceEntries.filter((entry) => entry?.type === 'natural' || entry?.kind === 'natural');\n        const natural = collect(\n            naturalEntries,\n            (entry) => toWorldPosition(entry.lat, entry.lon, Number.isFinite(entry.altitudeM) ? entry.altitudeM : 28),\n            (entry, distance) => {\n                const label = (typeof entry.name === 'string' && entry.name.trim())\n                    || entry.kindLabel\n                    || 'Natural Feature';\n                const kind = entry.kindLabel ? ` | ${entry.kindLabel}` : '';\n                return `${label} | ${formatDistance(distance)}${kind}`;\n            },\n            (entry) => ({\n                id: resolveViewshedId('natural', entry),\n                type: 'natural',\n                sizeM: resolveViewshedSizeM('natural', entry),\n                color: Number.isFinite(entry.color) ? entry.color : 0x8fd16a,\n                colorHex: entry.colorHex || entry.hex || null\n            })\n        );\n        hudStore.setList('viewshed.natural', natural.list);\n        hudStore.setData('viewshed.natural', natural.data);\n\n        const infrastructureEntries = this._infrastructureOverlay?.getEntriesSnapshot?.() || [];\n        const infrastructure = collect(\n            infrastructureEntries,\n            (entry) => {\n                const baseRadius = Number.isFinite(entry.surfaceRadius)\n                    ? entry.surfaceRadius\n                    : this._sampleTerrainRadius(entry.lat, entry.lon);\n                return toWorldPositionFromRadius(entry.lat, entry.lon, baseRadius + 2);\n            },\n            (entry, distance) => {\n                const label = (typeof entry.name === 'string' && entry.name.trim())\n                    || entry.kindLabel\n                    || 'Infrastructure';\n                const kind = entry.kindLabel ? ` | ${entry.kindLabel}` : '';\n                return `${label} | ${formatDistance(distance)}${kind}`;\n            },\n            (entry) => ({\n                id: resolveViewshedId('infrastructure', entry),\n                type: 'infrastructure',\n                sizeM: resolveViewshedSizeM('infrastructure', entry),\n                color: Number.isFinite(entry.color) ? entry.color : 0xffcc00,\n                colorHex: entry.colorHex || null\n            })\n        );\n        hudStore.setList('viewshed.infrastructure', infrastructure.list);\n        hudStore.setData('viewshed.infrastructure', infrastructure.data);\n\n        const incidentEntries = this._incidentOverlay?.getEntriesSnapshot?.() || [];\n        const incidentOffset = Number.isFinite(this._incidentOverlay?.surfaceOffsetM)\n            ? this._incidentOverlay.surfaceOffsetM\n            : 0;\n        const incidents = collect(\n            incidentEntries,\n            (entry) => {\n                return toWorldPosition(entry.lat, entry.lon, incidentOffset);\n            },\n            (entry, distance) => {\n                const callType = entry.callType ? String(entry.callType).trim() : '';\n                const emoji = resolveIncidentEmoji(callType);\n                const address = entry.address ? String(entry.address).trim() : '';\n                const detail = address || entry.id || 'Incident';\n                const label = emoji ? `${emoji} ${detail}` : detail;\n                return `${label} | ${formatDistance(distance)}`;\n            },\n            (entry) => ({\n                id: resolveViewshedId('incident', entry),\n                type: 'incident',\n                sizeM: resolveViewshedSizeM('incident', entry),\n                color: resolveIncidentColor(entry.callType)\n            })\n        );\n        hudStore.setList('viewshed.incidents', incidents.list);\n        hudStore.setData('viewshed.incidents', incidents.data);\n    }\n\n    _getViewshedAccent() {\n        return this._wireframeStyleResolved?.accent\n            || this._wireframeStyle?.accent\n            || DEFAULT_WIREFRAME_STYLE.accent;\n    }\n\n    _updateViewshedHighlightAccent() {\n        if (!this._viewshedHighlightRings || !this._viewshedHighlightRings.length) return;\n        const accent = this._resolveViewshedDataColor(this._viewshedHighlight?.data) || this._getViewshedAccent();\n        if (!accent) return;\n        const mid = this._viewshedHighlightRings[1];\n        if (mid?.material?.color) {\n            mid.material.color.set(accent);\n            mid.material.needsUpdate = true;\n        }\n    }\n\n    _ensureViewshedHighlight() {\n        if (this._viewshedHighlightGroup || !this._scene) return;\n        const group = new THREE.Group();\n        group.name = 'ViewshedHighlight';\n        group.visible = false;\n\n        const blackMat = new THREE.MeshBasicMaterial({\n            color: 0x000000,\n            transparent: true,\n            opacity: 0.85,\n            side: THREE.DoubleSide,\n            depthWrite: false\n        });\n        const accent = this._getViewshedAccent();\n        const accentMat = new THREE.MeshBasicMaterial({\n            color: accent || 0xffffff,\n            transparent: true,\n            opacity: 0.9,\n            side: THREE.DoubleSide,\n            depthWrite: false\n        });\n\n        const outer = new THREE.Mesh(new THREE.RingGeometry(0.92, 1, 64), blackMat);\n        const mid = new THREE.Mesh(new THREE.RingGeometry(0.66, 0.9, 64), accentMat);\n        const inner = new THREE.Mesh(new THREE.RingGeometry(0.55, 0.64, 64), blackMat);\n        [outer, mid, inner].forEach((mesh) => {\n            mesh.renderOrder = 30;\n            mesh.frustumCulled = false;\n            group.add(mesh);\n        });\n\n        this._scene.add(group);\n        this._viewshedHighlightGroup = group;\n        this._viewshedHighlightRings = [outer, mid, inner];\n    }\n\n    _setViewshedHighlight(listKey, data, source = 'viewshed') {\n        if (!listKey || !data || (!data.entry && !data.object3d && !data.worldPosition)) {\n            this._clearViewshedHighlight();\n            return;\n        }\n        this._viewshedHighlight = { listKey, data, source };\n        this._ensureViewshedHighlight();\n        if (this._viewshedHighlightGroup) {\n            this._viewshedHighlightGroup.visible = true;\n        }\n        const color = this._resolveViewshedDataColor(data) || this._getViewshedAccent();\n        const mid = this._viewshedHighlightRings?.[1];\n        if (mid?.material?.color && color) {\n            mid.material.color.set(color);\n            mid.material.needsUpdate = true;\n        }\n    }\n\n    _clearViewshedHighlight() {\n        this._viewshedHighlight = null;\n        if (this._viewshedHighlightGroup) {\n            this._viewshedHighlightGroup.visible = false;\n        }\n    }\n\n    _getViewshedHighlightType(listKey, data) {\n        if (data?.type) return data.type;\n        if (!listKey) return null;\n        if (listKey.includes('aircraft')) return 'aircraft';\n        if (listKey.includes('satellites')) return 'satellite';\n        if (listKey.includes('maritime')) return 'maritime';\n        if (listKey.includes('buildings')) return 'building';\n        if (listKey.includes('businesses')) return 'business';\n        if (listKey.includes('natural')) return 'natural';\n        if (listKey.includes('infrastructure')) return 'infrastructure';\n        if (listKey.includes('incidents')) return 'incident';\n        return null;\n    }\n\n    _resolveViewshedDataColor(data) {\n        const value = data?.color ?? data?.colorHex ?? data?.hex ?? null;\n        if (Number.isFinite(value)) return value;\n        if (typeof value === 'string') {\n            const clean = value.trim();\n            if (clean.startsWith('#')) {\n                const parsed = Number.parseInt(clean.slice(1), 16);\n                if (Number.isFinite(parsed)) return parsed;\n            }\n            try {\n                return new THREE.Color(clean).getHex();\n            } catch {\n                return null;\n            }\n        }\n        return null;\n    }\n\n    _getWorldPositionFromLatLon(lat, lon, radius, out) {\n        if (!Number.isFinite(lat) || !Number.isFinite(lon) || !this._triTree?.group) return null;\n        const localDir = latLonToLocalDir(lat, lon);\n        if (!localDir) return null;\n        const worldDir = this._viewshedHighlightTmpDir.copy(localDir);\n        this._triTree.group.getWorldQuaternion(this._viewshedHighlightTmpQuat);\n        worldDir.applyQuaternion(this._viewshedHighlightTmpQuat).normalize();\n        const earthPos = this._triTree.group.getWorldPosition(this._viewshedHighlightTmpCenter);\n        const baseRadius = ellipsoidRadiusForLocalDir(localDir);\n        const radiusValue = Number.isFinite(radius) ? radius : baseRadius;\n        return out.copy(worldDir).multiplyScalar(radiusValue).add(earthPos);\n    }\n\n    _sampleTerrainRadius(lat, lon) {\n        if (!this._triTree?.group || typeof this._triTree.sampleTerrainRadiusForDir !== 'function') {\n            const dir = latLonToLocalDir(lat, lon);\n            return dir ? ellipsoidRadiusForLocalDir(dir) : PLANET_RADIUS;\n        }\n        const localDir = latLonToLocalDir(lat, lon);\n        if (!localDir) return PLANET_RADIUS;\n        const worldDir = this._viewshedHighlightTmpDir.copy(localDir);\n        this._triTree.group.getWorldQuaternion(this._viewshedHighlightTmpQuat);\n        worldDir.applyQuaternion(this._viewshedHighlightTmpQuat).normalize();\n        const sampled = this._triTree.sampleTerrainRadiusForDir(worldDir);\n        return Number.isFinite(sampled) ? sampled : PLANET_RADIUS;\n    }\n\n    _resolveViewshedHighlightTarget(listKey, data) {\n        const type = this._getViewshedHighlightType(listKey, data);\n        if (!type) return null;\n        if (type === 'overlay-item') {\n            if (data?.object3d?.getWorldPosition) {\n                return data.object3d.getWorldPosition(this._viewshedHighlightTmpPos);\n            }\n            if (data?.worldPosition && Number.isFinite(data.worldPosition.x)) {\n                return this._viewshedHighlightTmpPos.copy(data.worldPosition);\n            }\n            return null;\n        }\n        if (!data?.entry || !this._triTree?.group) return null;\n        const entry = data.entry;\n        const aircraftOffset = Number.isFinite(this._aircraftOverlay?.altitudeOffsetM)\n            ? this._aircraftOverlay.altitudeOffsetM\n            : 0;\n        const satelliteOffset = Number.isFinite(this._satelliteOverlay?.altitudeOffsetM)\n            ? this._satelliteOverlay.altitudeOffsetM\n            : 0;\n        const maritimeOffset = Number.isFinite(this._maritimeOverlay?.altitudeOffsetM)\n            ? this._maritimeOverlay.altitudeOffsetM\n            : 0;\n        const buildingOffset = Number.isFinite(this._buildingOverlay?.surfaceOffsetM)\n            ? this._buildingOverlay.surfaceOffsetM\n            : 0;\n        const incidentOffset = Number.isFinite(this._incidentOverlay?.surfaceOffsetM)\n            ? this._incidentOverlay.surfaceOffsetM\n            : 0;\n\n        switch (type) {\n            case 'aircraft': {\n                const altitude = Number.isFinite(entry.altitudeM) ? entry.altitudeM : 0;\n                const localDir = latLonToLocalDir(entry.lat, entry.lon);\n                const baseRadius = localDir ? ellipsoidRadiusForLocalDir(localDir) : PLANET_RADIUS;\n                const radius = baseRadius + altitude + aircraftOffset;\n                return this._getWorldPositionFromLatLon(entry.lat, entry.lon, radius, this._viewshedHighlightTmpPos);\n            }\n            case 'satellite': {\n                const altitude = Number.isFinite(entry.altitudeM) ? entry.altitudeM : 0;\n                const localDir = latLonToLocalDir(entry.lat, entry.lon);\n                const baseRadius = localDir ? ellipsoidRadiusForLocalDir(localDir) : PLANET_RADIUS;\n                const radius = baseRadius + altitude + satelliteOffset;\n                return this._getWorldPositionFromLatLon(entry.lat, entry.lon, radius, this._viewshedHighlightTmpPos);\n            }\n            case 'maritime': {\n                const localDir = latLonToLocalDir(entry.lat, entry.lon);\n                const baseRadius = localDir ? ellipsoidRadiusForLocalDir(localDir) : PLANET_RADIUS;\n                const radius = baseRadius + maritimeOffset;\n                return this._getWorldPositionFromLatLon(entry.lat, entry.lon, radius, this._viewshedHighlightTmpPos);\n            }\n            case 'building': {\n                const baseRadius = Number.isFinite(entry.surfaceRadius)\n                    ? entry.surfaceRadius\n                    : this._sampleTerrainRadius(entry.lat, entry.lon);\n                return this._getWorldPositionFromLatLon(entry.lat, entry.lon, baseRadius + buildingOffset, this._viewshedHighlightTmpPos);\n            }\n            case 'incident': {\n                const baseRadius = this._sampleTerrainRadius(entry.lat, entry.lon);\n                return this._getWorldPositionFromLatLon(entry.lat, entry.lon, baseRadius + incidentOffset, this._viewshedHighlightTmpPos);\n            }\n            case 'business':\n            case 'natural': {\n                const localDir = latLonToLocalDir(entry.lat, entry.lon);\n                const baseRadius = localDir ? ellipsoidRadiusForLocalDir(localDir) : PLANET_RADIUS;\n                const altitude = Number.isFinite(entry.altitudeM) ? entry.altitudeM : 28;\n                return this._getWorldPositionFromLatLon(entry.lat, entry.lon, baseRadius + altitude, this._viewshedHighlightTmpPos);\n            }\n            case 'infrastructure': {\n                const baseRadius = Number.isFinite(entry.surfaceRadius)\n                    ? entry.surfaceRadius\n                    : this._sampleTerrainRadius(entry.lat, entry.lon);\n                return this._getWorldPositionFromLatLon(entry.lat, entry.lon, baseRadius + 2, this._viewshedHighlightTmpPos);\n            }\n            default:\n                return null;\n        }\n    }\n\n    _resolveOverlayHighlightSize(itemEntry) {\n        const props = itemEntry?.data?.current?.properties || {};\n        if (Number.isFinite(props.size_m)) return props.size_m;\n        if (Number.isFinite(props.radius_m)) return props.radius_m * 2;\n        if (Number.isFinite(props.point_radius_m)) return props.point_radius_m * 2;\n        const modelSize = itemEntry?.object3d?.userData?.modelSize;\n        if (modelSize) {\n            const maxDim = Math.max(modelSize.x || 0, modelSize.y || 0, modelSize.z || 0);\n            if (Number.isFinite(maxDim) && maxDim > 0) {\n                const scale = itemEntry.object3d?.scale;\n                const scaleMax = scale\n                    ? Math.max(scale.x || 1, scale.y || 1, scale.z || 1)\n                    : 1;\n                return maxDim * scaleMax;\n            }\n        }\n        return null;\n    }\n\n    _setOverlayItemHighlight(itemId, opts = {}) {\n        if (itemId === null || itemId === undefined || !this._overlaySubsystem) {\n            this._clearOverlayItemHighlight();\n            return;\n        }\n        const overlayId = opts?.overlayId || null;\n        const itemEntry = overlayId && this._overlaySubsystem.findItemInOverlay\n            ? this._overlaySubsystem.findItemInOverlay(overlayId, itemId)\n            : this._overlaySubsystem.findItem?.(itemId);\n        if (!itemEntry?.object3d) {\n            this._clearOverlayItemHighlight();\n            return;\n        }\n        let current = itemEntry.object3d;\n        while (current) {\n            if (current.visible === false) {\n                this._clearOverlayItemHighlight();\n                return;\n            }\n            current = current.parent;\n        }\n        const props = itemEntry.data?.current?.properties || {};\n        if (props.visible === false) {\n            this._clearOverlayItemHighlight();\n            return;\n        }\n        const sizeM = this._resolveOverlayHighlightSize(itemEntry);\n        this._setViewshedHighlight('overlay.item', {\n            type: 'overlay-item',\n            entry: itemEntry.data,\n            object3d: itemEntry.object3d,\n            sizeM: sizeM || null\n        }, 'overlay');\n    }\n\n    _clearOverlayItemHighlight() {\n        if (this._viewshedHighlight?.source !== 'overlay') return;\n        this._clearViewshedHighlight();\n    }\n\n    _updateViewshedHighlight() {\n        if (!this._viewshedHighlightGroup || !this._viewshedHighlight || !this._camera) {\n            if (this._viewshedHighlightGroup) this._viewshedHighlightGroup.visible = false;\n            return;\n        }\n        const targetPos = this._resolveViewshedHighlightTarget(\n            this._viewshedHighlight.listKey,\n            this._viewshedHighlight.data\n        );\n        if (!targetPos) {\n            this._viewshedHighlightGroup.visible = false;\n            return;\n        }\n        const cameraPos = this._camera.userData?.worldPosition\n            ? this._viewshedHighlightTmpCam.copy(this._camera.userData.worldPosition)\n            : this._camera.getWorldPosition(this._viewshedHighlightTmpCam);\n        const toTarget = this._viewshedHighlightTmpDir.copy(targetPos).sub(cameraPos);\n        const distance = toTarget.length();\n        if (!Number.isFinite(distance) || distance <= 0.1) {\n            this._viewshedHighlightGroup.visible = false;\n            return;\n        }\n        const sizeM = Number.isFinite(this._viewshedHighlight.data?.sizeM)\n            ? this._viewshedHighlight.data.sizeM\n            : 0;\n        const angleRad = THREE.MathUtils.degToRad(0.2);\n        const radiusFromDistance = Math.tan(angleRad) * distance;\n        const minRadius = Math.max(2, sizeM * 0.6);\n        const ringRadius = THREE.MathUtils.clamp(\n            Math.max(radiusFromDistance, sizeM),\n            minRadius,\n            6000\n        );\n        const minDist = Math.max(3, ringRadius * 1.2);\n        const maxDist = Math.max(minDist, distance - ringRadius * 0.5);\n        const ringDistance = THREE.MathUtils.clamp(distance * 0.8, minDist, maxDist);\n        toTarget.normalize();\n        this._viewshedHighlightGroup.position.copy(cameraPos).addScaledVector(toTarget, ringDistance);\n        this._viewshedHighlightGroup.scale.setScalar(ringRadius);\n        this._viewshedHighlightGroup.lookAt(cameraPos);\n        this._viewshedHighlightGroup.visible = true;\n    }\n\n    async _resolveNavGeoContext(lat, lon) {\n        if (!this._geoBoundaryService) return;\n        const seq = ++this._navGeoSeq;\n        this._navGeoInFlight = true;\n        try {\n            // Get building info synchronously (point-in-polygon test)\n            const buildingInfo = this._buildingOverlay?.getBuildingAtLatLon?.(lat, lon) || null;\n\n            const countryInfoPromise = this._geoBoundaryService.getCountryAtLatLon(lat, lon);\n            let iso3 = null;\n            let countryName = null;\n            if (countryName || iso3) {\n                this._navGeoInfo = { iso3, countryName, admin: null };\n                this._applyGeoJsonRelationshipColors();\n                this._updateNavHud(countryName, null, buildingInfo);\n                if (this._geoJsonAutoDepth) {\n                    this._refreshGeoJsonAutoDepth({ force: false });\n                }\n            }\n            const countryInfo = await countryInfoPromise;\n            if (seq !== this._navGeoSeq) return;\n            const resolvedIso3 = countryInfo?.iso3 || iso3 || null;\n            const resolvedName = countryInfo?.name || countryName || resolvedIso3 || null;\n            iso3 = resolvedIso3;\n            countryName = resolvedName;\n            this._navGeoInfo = { iso3, countryName, admin: null };\n            this._applyGeoJsonRelationshipColors();\n            this._updateNavHud(countryName, null, buildingInfo);\n            if (this._geoJsonAutoDepth) {\n                this._refreshGeoJsonAutoDepth({ force: false });\n            }\n            const adminInfo = await this._resolveNavAdmin(lat, lon, iso3);\n            if (seq !== this._navGeoSeq) return;\n            this._navGeoInfo = { iso3, countryName, admin: adminInfo };\n            this._applyGeoJsonRelationshipColors();\n            this._updateNavHud(countryName, adminInfo, buildingInfo);\n            // Refresh auto-depth layers now that hierarchy is available for parent filtering\n            if (this._geoJsonAutoDepth && adminInfo?.hierarchy) {\n                this._refreshGeoJsonAutoDepth({ force: false });\n            }\n        } finally {\n            this._navGeoInFlight = false;\n            if (this._navGeoPending) {\n                this._navGeoPending = false;\n                this._updateNavGeoContext(\n                    typeof performance !== 'undefined' ? performance.now() : Date.now()\n                );\n            }\n        }\n    }\n\n    _isUnderfootElevationReady() {\n        if (this._surfaceController?.photoTileGroup) {\n            return this._getFreshPhotorealUnderfootState?.()?.ready === true;\n        }\n        if (!this._triTree || !this._camera) return true;\n        const camPos = this._camera?.userData?.worldPosition || this._camera.position;\n        if (!camPos || !Number.isFinite(camPos.x)) return true;\n        const dir = this._tmpElevationDir.copy(camPos).normalize();\n        const leaf = typeof this._triTree.findLeafTileForWorldDir === 'function'\n            ? this._triTree.findLeafTileForWorldDir(dir)\n            : null;\n        if (!leaf) return true;\n        if (leaf.elevationHasData) return true;\n        if (leaf.elevationFillComplete) return true;\n        if (Number.isFinite(leaf.elevationSeededCount) && leaf.elevationSeededCount > 0) return true;\n        return false;\n    }\n\n    /**\n     * Update building auto-injection based on camera position.\n     * Only active when in surface mode and buildings are enabled.\n     */\n    _updateBuildingAutoInjection(now) {\n        if (!this._buildingAutoEnabled) return;\n        if (!this._buildingOverlay?.enabled) return;\n        if (!this._surfaceController?.isInSurfaceMode?.()) return;\n\n        const hudStore = getHudInfoStore();\n        const lat = hudStore?.getData?.('nav.lat');\n        const lon = hudStore?.getData?.('nav.lon');\n        if (!Number.isFinite(lat) || !Number.isFinite(lon)) return;\n\n        const timestamp = Number.isFinite(now)\n            ? now\n            : (typeof performance !== 'undefined' ? performance.now() : Date.now());\n        this._syncMobileSurfaceOverlayBootstrapState(timestamp);\n\n        if (this._isMobile && this._isMobileOverlayBootstrapLocked('building', timestamp)) {\n            return;\n        }\n        if (this._isMobile && this._infrastructureOverlay?._inflight && !this._buildingAutoCenter) {\n            return;\n        }\n\n        if (Number.isFinite(this._buildingAutoElevationWaitUntil) &&\n            timestamp < this._buildingAutoElevationWaitUntil) {\n            return;\n        }\n\n        // Rate limit checks\n        const withinInterval = this._buildingAutoTs\n            ? (timestamp - this._buildingAutoTs) < this._buildingAutoPollIntervalMs\n            : false;\n\n        if (withinInterval && (this._buildingAutoCenter || this._buildingAutoRequestKey)) return;\n\n        const headingDeg = this._surfaceController?.getSurfaceHeadingDeg?.();\n\n        // Calculate distance and view rotation from the last completed query.\n        const prev = this._buildingAutoCenter;\n        let needsUpdate = !prev;\n\n        if (prev) {\n            // Simple degree-based distance check (approximation is fine here)\n            const dLat = (lat - prev.lat) * 111000; // ~111km per degree latitude\n            const dLon = (lon - prev.lon) * 111000 * Math.cos(lat * Math.PI / 180);\n            const distM = Math.sqrt(dLat * dLat + dLon * dLon);\n            needsUpdate = distM >= this._buildingAutoMinMoveM;\n        }\n        if (!needsUpdate && Number.isFinite(headingDeg)) {\n            const previousHeading = this._buildingAutoHeadingDeg;\n            const headingDelta = Number.isFinite(previousHeading)\n                ? Math.abs((((headingDeg - previousHeading) % 360) + 540) % 360 - 180)\n                : Infinity;\n            needsUpdate = headingDelta >= 18;\n        }\n\n        if (!needsUpdate) return;\n\n        const elevationReady = this._isUnderfootElevationReady();\n        if (!elevationReady) {\n            if (!this._buildingAutoElevationWaitStart) {\n                this._buildingAutoElevationWaitStart = timestamp;\n            }\n            const waitedMs = timestamp - this._buildingAutoElevationWaitStart;\n            const waitMs = Number.isFinite(this._buildingAutoElevationWaitMs)\n                ? this._buildingAutoElevationWaitMs\n                : 0;\n            if (waitMs > 0 && waitedMs < waitMs) {\n                this._buildingAutoElevationWaitUntil = timestamp + 250;\n                return;\n            }\n        }\n        this._buildingAutoElevationWaitUntil = 0;\n        this._buildingAutoElevationWaitStart = 0;\n\n        // Get config from scene settings or use defaults\n        const buildingsConfig = this._sceneSettings?.getSection?.('scene.buildings') || {};\n        const configuredRadiusM = Number.isFinite(buildingsConfig.radiusM)\n            ? buildingsConfig.radiusM\n            : 900;\n        const aglM = this._surfaceController?.getSurfaceAltitudeMeters?.();\n        const view = resolveSurfaceBuildingViewshed({\n            aglM,\n            configuredRadiusM,\n            verticalFovDeg: this._camera?.fov,\n            aspect: this._camera?.aspect,\n            isMobile: this._isMobile,\n        });\n        const radiusM = view.farRadiusM;\n        const configuredFalloff = Number.isFinite(buildingsConfig.falloffStartM)\n            ? buildingsConfig.falloffStartM\n            : radiusM * 0.8;\n        const falloffStartM = Math.min(configuredFalloff, radiusM * 0.82);\n\n        // Only auto-inject if there's no active overlay-controlled building region\n        // (Check if building overlay is already being managed by an overlay item)\n        if (this._buildingOverlay.__activeItemId) return;\n\n        const requestKey = [\n            lat.toFixed(5),\n            lon.toFixed(5),\n            Number.isFinite(headingDeg) ? headingDeg.toFixed(1) : 'none',\n            Math.round(radiusM),\n        ].join(':');\n        if (this._buildingAutoRequestKey === requestKey) return;\n\n        const requestSeq = ++this._buildingAutoRequestSeq;\n        this._buildingAutoRequestKey = requestKey;\n        this._buildingAutoTs = timestamp;\n        Promise.resolve(this._buildingOverlay.setCenter(lat, lon, {\n            radiusM,\n            falloffStartM,\n            refreshDistanceM: this._buildingAutoMinMoveM,\n            viewshedDriven: Number.isFinite(headingDeg),\n            headingDeg,\n            horizontalFovDeg: view.horizontalFovDeg,\n            nearRadiusM: view.nearRadiusM,\n            headingRefreshDeg: 18,\n        })).then((applied) => {\n            if (requestSeq !== this._buildingAutoRequestSeq || applied !== true) return;\n            this._buildingAutoCenter = { lat, lon };\n            this._buildingAutoHeadingDeg = Number.isFinite(headingDeg) ? headingDeg : null;\n        }).catch((error) => {\n            if (requestSeq === this._buildingAutoRequestSeq) {\n                console.warn('[PlanetScene] Building viewshed refresh failed:', error);\n            }\n        }).finally(() => {\n            if (requestSeq === this._buildingAutoRequestSeq) {\n                this._buildingAutoRequestKey = null;\n            }\n        });\n    }\n\n    /**\n     * Update aircraft auto-injection based on camera position.\n     * Active in surface and orbit modes while flights are enabled.\n     */\n    _updateAircraftAutoInjection(now) {\n        if (!this._aircraftAutoEnabled) return;\n        if (!this._aircraftOverlay) return;\n        const hudStore = getHudInfoStore();\n        let location = null;\n        if (!this._surfaceController?.isInSurfaceMode?.() && this._camera && this._triTree?.group) {\n            this._aircraftAutoCamera ||= new THREE.Vector3();\n            this._camera.getWorldPosition(this._aircraftAutoCamera);\n            location = worldPosToLatLonLocal(this._aircraftAutoCamera, this._triTree.group);\n        }\n        const lat = location?.latDeg ?? hudStore?.getData?.('nav.lat');\n        const lon = location?.lonDeg ?? hudStore?.getData?.('nav.lon');\n        if (!Number.isFinite(lat) || !Number.isFinite(lon)) return;\n\n        const timestamp = Number.isFinite(now)\n            ? now\n            : (typeof performance !== 'undefined' ? performance.now() : Date.now());\n\n        const withinInterval = this._aircraftAutoTs\n            ? (timestamp - this._aircraftAutoTs) < this._aircraftAutoPollIntervalMs\n            : false;\n\n        if (withinInterval && this._aircraftAutoCenter) return;\n\n        const prev = this._aircraftAutoCenter;\n        let needsUpdate = !prev;\n\n        if (prev) {\n            const dLat = (lat - prev.lat) * 111000;\n            const dLon = (lon - prev.lon) * 111000 * Math.cos(lat * Math.PI / 180);\n            const distM = Math.sqrt(dLat * dLat + dLon * dLon);\n            needsUpdate = distM >= this._aircraftAutoMinMoveM;\n        }\n\n        if (!needsUpdate) return;\n\n        this._aircraftAutoCenter = { lat, lon };\n        this._aircraftAutoTs = timestamp;\n\n        const config = this._aircraftAutoConfig || {};\n        const radiusNm = Number.isFinite(config.radiusNm) ? config.radiusNm : 80;\n        const coneAngleDeg = Number.isFinite(config.coneAngleDeg) ? config.coneAngleDeg : 170;\n        const maxAircraft = Number.isFinite(config.maxAircraft) ? config.maxAircraft : 200;\n        const pollIntervalMs = Number.isFinite(config.pollIntervalMs) ? config.pollIntervalMs : 2000;\n\n        this._aircraftOverlay.setCenter(lat, lon, {\n            radiusNm,\n            coneAngleDeg,\n            maxAircraft,\n            pollIntervalMs\n        });\n    }\n\n    /**\n     * Update satellite auto-injection based on camera position.\n     * Only active when in surface mode and satellites are enabled.\n     */\n    _updateSatelliteAutoInjection(now) {\n        if (!this._satelliteAutoEnabled) return;\n        if (!this._satelliteOverlay) {\n            void this._ensureSatelliteOverlay({\n                ...(this._satelliteAutoConfig || {}),\n                enabled: true\n            }).catch((err) => {\n                console.warn('[PlanetScene] Satellite overlay load failed:', err);\n            });\n            return;\n        }\n        if (!this._surfaceController?.isInSurfaceMode?.()) return;\n\n        const hudStore = getHudInfoStore();\n        const lat = hudStore?.getData?.('nav.lat');\n        const lon = hudStore?.getData?.('nav.lon');\n        if (!Number.isFinite(lat) || !Number.isFinite(lon)) return;\n\n        const timestamp = Number.isFinite(now)\n            ? now\n            : (typeof performance !== 'undefined' ? performance.now() : Date.now());\n\n        const withinInterval = this._satelliteAutoTs\n            ? (timestamp - this._satelliteAutoTs) < this._satelliteAutoPollIntervalMs\n            : false;\n\n        if (withinInterval && this._satelliteAutoCenter) return;\n\n        const prev = this._satelliteAutoCenter;\n        let needsUpdate = !prev;\n\n        if (prev) {\n            const dLat = (lat - prev.lat) * 111000;\n            const dLon = (lon - prev.lon) * 111000 * Math.cos(lat * Math.PI / 180);\n            const distM = Math.sqrt(dLat * dLat + dLon * dLon);\n            needsUpdate = distM >= this._satelliteAutoMinMoveM;\n        }\n\n        if (!needsUpdate) return;\n\n        this._satelliteAutoCenter = { lat, lon };\n        this._satelliteAutoTs = timestamp;\n\n        const config = this._satelliteAutoConfig || {};\n        const coneAngleDeg = Number.isFinite(config.coneAngleDeg) ? config.coneAngleDeg : 180;\n        const maxSatellites = Number.isFinite(config.maxSatellites) ? config.maxSatellites : 200;\n        const pollIntervalMs = Number.isFinite(config.pollIntervalMs) ? config.pollIntervalMs : 600000;\n\n        this._satelliteOverlay.setCenter(lat, lon, {\n            coneAngleDeg,\n            maxSatellites,\n            pollIntervalMs\n        });\n    }\n\n    /**\n     * Update maritime auto-injection based on camera position.\n     * Only active when in surface mode and maritime is enabled.\n     */\n    _updateMaritimeAutoInjection(now) {\n        if (!this._maritimeAutoEnabled) return;\n        if (!this._maritimeOverlay) return;\n        if (!this._surfaceController?.isInSurfaceMode?.()) return;\n\n        const hudStore = getHudInfoStore();\n        const lat = hudStore?.getData?.('nav.lat');\n        const lon = hudStore?.getData?.('nav.lon');\n        if (!Number.isFinite(lat) || !Number.isFinite(lon)) return;\n\n        const timestamp = Number.isFinite(now)\n            ? now\n            : (typeof performance !== 'undefined' ? performance.now() : Date.now());\n\n        const withinInterval = this._maritimeAutoTs\n            ? (timestamp - this._maritimeAutoTs) < this._maritimeAutoPollIntervalMs\n            : false;\n\n        if (withinInterval && this._maritimeAutoCenter) return;\n\n        const prev = this._maritimeAutoCenter;\n        let needsUpdate = !prev;\n\n        if (prev) {\n            const dLat = (lat - prev.lat) * 111000;\n            const dLon = (lon - prev.lon) * 111000 * Math.cos(lat * Math.PI / 180);\n            const distM = Math.sqrt(dLat * dLat + dLon * dLon);\n            needsUpdate = distM >= this._maritimeAutoMinMoveM;\n        }\n\n        if (!needsUpdate) return;\n\n        this._maritimeAutoCenter = { lat, lon };\n        this._maritimeAutoTs = timestamp;\n\n        const config = this._maritimeAutoConfig || {};\n        const radiusNm = Number.isFinite(config.radiusNm) ? config.radiusNm : 80;\n        const coneAngleDeg = Number.isFinite(config.coneAngleDeg) ? config.coneAngleDeg : 180;\n        const maxVessels = Number.isFinite(config.maxVessels) ? config.maxVessels : 200;\n        const pollIntervalMs = Number.isFinite(config.pollIntervalMs) ? config.pollIntervalMs : 60000;\n\n        this._maritimeOverlay.setCenter(lat, lon, {\n            radiusNm,\n            coneAngleDeg,\n            maxVessels,\n            pollIntervalMs\n        });\n    }\n\n    /**\n     * Update incident auto-injection based on camera position.\n     * Only active when in surface mode and incidents are enabled.\n     */\n    _updateIncidentAutoInjection(now) {\n        if (!this._incidentAutoEnabled) return;\n        if (!this._incidentOverlay) return;\n        if (!this._surfaceController?.isInSurfaceMode?.()) return;\n\n        const hudStore = getHudInfoStore();\n        const lat = hudStore?.getData?.('nav.lat');\n        const lon = hudStore?.getData?.('nav.lon');\n        if (!Number.isFinite(lat) || !Number.isFinite(lon)) return;\n\n        const timestamp = Number.isFinite(now)\n            ? now\n            : (typeof performance !== 'undefined' ? performance.now() : Date.now());\n\n        const withinInterval = this._incidentAutoTs\n            ? (timestamp - this._incidentAutoTs) < this._incidentAutoPollIntervalMs\n            : false;\n\n        if (withinInterval && this._incidentAutoCenter) return;\n\n        const prev = this._incidentAutoCenter;\n        let needsUpdate = !prev;\n\n        if (prev) {\n            const dLat = (lat - prev.lat) * 111000;\n            const dLon = (lon - prev.lon) * 111000 * Math.cos(lat * Math.PI / 180);\n            const distM = Math.sqrt(dLat * dLat + dLon * dLon);\n            needsUpdate = distM >= this._incidentAutoMinMoveM;\n        }\n\n        if (!needsUpdate) return;\n\n        this._incidentAutoCenter = { lat, lon };\n        this._incidentAutoTs = timestamp;\n\n        const config = this._incidentAutoConfig || {};\n        const radiusM = Number.isFinite(config.radiusM) ? config.radiusM : 150000;\n        const maxIncidents = Number.isFinite(config.maxIncidents) ? config.maxIncidents : 200;\n        const pollIntervalMs = Number.isFinite(config.pollIntervalMs) ? config.pollIntervalMs : 60000;\n\n        this._incidentOverlay.setCenter(lat, lon, {\n            radiusM,\n            maxIncidents,\n            pollIntervalMs\n        });\n    }\n\n    /**\n     * Keep public radio-network products bounded to the active scene region.\n     * Unlike surface-only infrastructure, receiver and propagation context is\n     * also meaningful in orbit, so the canonical nav coordinates own this\n     * center in every camera mode.\n     */\n    _updateRadioDataAutoInjection(now) {\n        if (!this._radioDataAutoEnabled || !this._radioDataOverlay) return;\n        const feeds = this._radioDataConfig?.feeds || {};\n        if (!Object.values(feeds).some((enabled) => enabled === true)) return;\n        this._radioDataOverlay.setSurfaceMode?.(\n            this._surfaceController?.isInSurfaceMode?.() === true\n        );\n        const hudStore = getHudInfoStore();\n        const lat = hudStore?.getData?.('nav.lat');\n        const lon = hudStore?.getData?.('nav.lon');\n        if (!Number.isFinite(lat) || !Number.isFinite(lon)) return;\n        const timestamp = Number.isFinite(now)\n            ? now\n            : (typeof performance !== 'undefined' ? performance.now() : Date.now());\n        const country = String(this._navGeoInfo?.countryName || '').trim();\n        const previous = this._radioDataAutoCenter;\n        const moved = previous\n            ? Math.hypot(\n                (lat - previous.lat) * 111_000,\n                (lon - previous.lon) * 111_000 * Math.cos(lat * Math.PI / 180),\n            )\n            : Infinity;\n        const due = !this._radioDataAutoTs\n            || (timestamp - this._radioDataAutoTs) >= this._radioDataAutoPollIntervalMs;\n        const contextChanged = moved >= this._radioDataAutoMinMoveM\n            || country !== this._radioDataAutoCountry;\n        // Display distance is evaluated from the live scene coordinate even\n        // between the larger movement thresholds that trigger a new request.\n        this._radioDataOverlay.setCenter(lat, lon, { country, refresh: false });\n        if (!due && !contextChanged) return;\n        this._radioDataAutoTs = timestamp;\n        if (contextChanged) {\n            this._radioDataAutoCenter = { lat, lon };\n            this._radioDataAutoCountry = country;\n            this._radioDataOverlay.setCenter(lat, lon, { country, force: true });\n        } else {\n            void this._radioDataOverlay.refresh();\n        }\n    }\n\n    /** Keep public geocache inventory centered on the canonical scene location. */\n    _updateGeocacheAutoInjection(now) {\n        if (!this._geocacheAutoEnabled || !this._geocacheLayer) return;\n        const hudStore = getHudInfoStore();\n        const lat = hudStore?.getData?.('nav.lat');\n        const lon = hudStore?.getData?.('nav.lon');\n        if (!Number.isFinite(lat) || !Number.isFinite(lon)) return;\n        const timestamp = Number.isFinite(now)\n            ? now\n            : (typeof performance !== 'undefined' ? performance.now() : Date.now());\n        const previous = this._geocacheAutoCenter;\n        const moved = previous\n            ? Math.hypot(\n                (lat - previous.lat) * 111_000,\n                (lon - previous.lon) * 111_000 * Math.cos(lat * Math.PI / 180),\n            )\n            : Infinity;\n        const due = !this._geocacheAutoTs\n            || (timestamp - this._geocacheAutoTs) >= this._geocacheAutoPollIntervalMs;\n        const contextChanged = moved >= this._geocacheAutoMinMoveM;\n        this._geocacheLayer.setCenter(lat, lon, { refresh: false });\n        if (!due && !contextChanged) return;\n        this._geocacheAutoTs = timestamp;\n        if (contextChanged) {\n            this._geocacheAutoCenter = { lat, lon };\n            this._geocacheLayer.setCenter(lat, lon, { force: true });\n        } else {\n            void this._geocacheLayer.refresh();\n        }\n    }\n\n    /**\n     * Apply infrastructure overlay center from HUD coordinates immediately.\n     */\n    _setInfrastructureAutoCenter(lat, lon, now) {\n        if (!this._infrastructureOverlay?.enabled) return;\n        if (!Number.isFinite(lat) || !Number.isFinite(lon)) return;\n\n        const timestamp = Number.isFinite(now)\n            ? now\n            : (typeof performance !== 'undefined' ? performance.now() : Date.now());\n\n        this._infrastructureAutoCenter = { lat, lon };\n        this._infrastructureAutoTs = timestamp;\n        this._infrastructureAutoElevationWaitUntil = 0;\n        this._infrastructureAutoElevationWaitStart = 0;\n\n        const infraConfig = this._sceneSettings?.getSection?.('scene.infrastructure') || {};\n        const overlayRadius = Number.isFinite(this._infrastructureOverlay?.radiusM)\n            ? this._infrastructureOverlay.radiusM\n            : 800;\n        const radiusM = Number.isFinite(infraConfig.radiusM) ? infraConfig.radiusM : overlayRadius;\n\n        this._infrastructureOverlay.setCenter(lat, lon, {\n            radiusM,\n            refreshDistanceM: this._infrastructureAutoMinMoveM,\n            force: true,\n            immediate: true\n        });\n    }\n\n    /**\n     * Update infrastructure auto-injection based on camera position.\n     * Only active when in surface mode and infrastructure is enabled.\n     */\n    _updateInfrastructureAutoInjection(now) {\n        if (!this._infrastructureAutoEnabled) return;\n        if (!this._infrastructureOverlay?.enabled) return;\n        if (!this._surfaceController?.isInSurfaceMode?.()) return;\n\n        const hudStore = getHudInfoStore();\n        const lat = hudStore?.getData?.('nav.lat');\n        const lon = hudStore?.getData?.('nav.lon');\n        if (!Number.isFinite(lat) || !Number.isFinite(lon)) return;\n\n        const timestamp = Number.isFinite(now)\n            ? now\n            : (typeof performance !== 'undefined' ? performance.now() : Date.now());\n        this._syncMobileSurfaceOverlayBootstrapState(timestamp);\n\n        if (this._isMobile && this._isMobileOverlayBootstrapLocked('infrastructure', timestamp)) {\n            return;\n        }\n        if (this._isMobile && this._buildingOverlay?._inflight) {\n            return;\n        }\n        if (this._isMobile && this._infrastructureOverlay?._inflight && !this._infrastructureAutoCenter) {\n            return;\n        }\n\n        if (Number.isFinite(this._infrastructureAutoElevationWaitUntil) &&\n            timestamp < this._infrastructureAutoElevationWaitUntil) {\n            return;\n        }\n\n        const withinInterval = this._infrastructureAutoTs\n            ? (timestamp - this._infrastructureAutoTs) < this._infrastructureAutoPollIntervalMs\n            : false;\n\n        if (withinInterval && this._infrastructureAutoCenter) return;\n\n        const prev = this._infrastructureAutoCenter;\n        let needsUpdate = !prev;\n\n        if (prev) {\n            const dLat = (lat - prev.lat) * 111000;\n            const dLon = (lon - prev.lon) * 111000 * Math.cos(lat * Math.PI / 180);\n            const distM = Math.sqrt(dLat * dLat + dLon * dLon);\n            needsUpdate = distM >= this._infrastructureAutoMinMoveM;\n        }\n\n        if (!needsUpdate) return;\n\n        const elevationReady = this._isUnderfootElevationReady();\n        if (!elevationReady) {\n            if (!this._infrastructureAutoElevationWaitStart) {\n                this._infrastructureAutoElevationWaitStart = timestamp;\n            }\n            const waitedMs = timestamp - this._infrastructureAutoElevationWaitStart;\n            if (waitedMs < 4000) {\n                this._infrastructureAutoElevationWaitUntil = timestamp + 250;\n                return;\n            }\n        }\n        this._infrastructureAutoElevationWaitUntil = 0;\n        this._infrastructureAutoElevationWaitStart = 0;\n\n        this._setInfrastructureAutoCenter(lat, lon, timestamp);\n    }\n\n    _extractGeoJsonIso3(props) {\n        if (!props) return null;\n        const candidates = [\n            props.iso3,\n            props.iso_a3,\n            props.adm0_a3,\n            props.sov_a3,\n            props.iso_a3_eh,\n            props.adm0_a3_us,\n            props.adm0_a3_un,\n            props.adm0_a3_wb,\n            props.brk_a3,\n            props.gu_a3,\n            props.su_a3,\n            props.country_iso3,\n            props.shapeGroup\n        ];\n        for (const value of candidates) {\n            if (typeof value !== 'string') continue;\n            const trimmed = value.trim().toUpperCase();\n            if (/^[A-Z]{3}$/.test(trimmed)) return trimmed;\n        }\n        return null;\n    }\n\n    async _resolveNavAdmin(lat, lon, iso3) {\n        const maxLevel = this._normalizeGeoJsonLevel(this._geoJsonMaxAdminLevel);\n        if (!iso3 || maxLevel <= 0) return null;\n\n        // Get full hierarchy for hierarchical filtering\n        const hierarchy = await this._geoBoundaryService.getAdminHierarchyAtLatLon(iso3, lat, lon, maxLevel);\n\n        // Find the deepest level for display\n        let deepestAdmin = null;\n        for (let level = maxLevel; level >= 1; level--) {\n            const key = `adm${level}`;\n            if (hierarchy?.[key]?.name) {\n                deepestAdmin = { name: hierarchy[key].name, level, label: `ADM${level}` };\n                break;\n            }\n        }\n\n        // Return both the deepest admin and the full hierarchy\n        if (deepestAdmin) {\n            deepestAdmin.hierarchy = hierarchy;\n        }\n        return deepestAdmin;\n    }\n\n    _updateNavHud(countryName, adminInfo, buildingInfo = null) {\n        const hudStore = getHudInfoStore();\n        if (!hudStore) return;\n        hudStore.setValue('nav.country', countryName || '--');\n        hudStore.setData('nav.country', countryName || null);\n        const adminValue = adminInfo?.name\n            ? `${adminInfo.label ? `${adminInfo.label} ` : ''}${adminInfo.name}`\n            : '--';\n        hudStore.setValue('nav.admin', adminValue);\n        hudStore.setData('nav.admin', adminInfo ? { ...adminInfo } : null);\n\n        // Building info\n        if (buildingInfo) {\n            const bldgName = this._formatBuildingName(buildingInfo.tags);\n            hudStore.setValue('nav.building', bldgName || '--');\n            hudStore.setValue('nav.buildingAddr', buildingInfo.address || '--');\n            // Format height with units, levels as integer\n            const heightStr = Number.isFinite(buildingInfo.height)\n                ? `${buildingInfo.height.toFixed(1)}m`\n                : '--';\n            const levelsStr = Number.isFinite(buildingInfo.levels)\n                ? String(buildingInfo.levels)\n                : '--';\n            hudStore.setValue('nav.buildingHeight', heightStr);\n            hudStore.setValue('nav.buildingLevels', levelsStr);\n            hudStore.setData('nav.building', buildingInfo);\n            hudStore.setData('nav.buildingAddr', buildingInfo.address || null);\n            hudStore.setData('nav.buildingHeight', buildingInfo.height || null);\n            hudStore.setData('nav.buildingLevels', buildingInfo.levels || null);\n        } else {\n            hudStore.setValue('nav.building', '--');\n            hudStore.setValue('nav.buildingAddr', '--');\n            hudStore.setValue('nav.buildingHeight', '--');\n            hudStore.setValue('nav.buildingLevels', '--');\n            hudStore.setData('nav.building', null);\n            hudStore.setData('nav.buildingAddr', null);\n            hudStore.setData('nav.buildingHeight', null);\n            hudStore.setData('nav.buildingLevels', null);\n        }\n    }\n\n    _updateGeoJsonRenderMode() {\n        const inSurface = this._surfaceController?.isInSurfaceMode?.() || false;\n        const nextMode = inSurface ? 'surface' : 'orbit';\n        if (this._geoJsonRenderMode === nextMode) return;\n        this._geoJsonRenderMode = nextMode;\n        this._geoJsonLayer?.setMode?.(nextMode);\n        this._geoJsonLookupLayer?.setMode?.(nextMode);\n        this._geoJsonAutoLayers?.forEach((layer) => layer?.setMode?.(nextMode));\n        this._applyWireframeBorderColor(this._wireframeActive);\n    }\n\n    /**\n     * Show a temporary label on the building under the mouse cursor.\n     * Works with both TriTree BuildingOverlay (OSM) and Cesium tile buildings.\n     */\n    _updateBuildingHoverLabel() {\n        const nowMs = typeof performance !== 'undefined' ? performance.now() : Date.now();\n        if (nowMs - this._lastBuildingHoverUpdateMs < this._buildingHoverUpdateIntervalMs) return;\n        this._lastBuildingHoverUpdateMs = nowMs;\n        if (globalThis.__noclipDebugPhotoLabels === true && !this._hoverDiagOnce) {\n            this._hoverDiagOnce = true;\n            console.warn('[PlanetScene] _updateBuildingHoverLabel FIRST CALL');\n        }\n        const businessLabels = getBusinessLabels();\n        const labelRaycaster = this._eventManager?.clickRaycaster || null;\n        if (labelRaycaster && this._camera) {\n            labelRaycaster.camera = this._camera;\n        }\n        const businessLabelHit = labelRaycaster\n            ? businessLabels.findLabelAtRaycast(labelRaycaster, this._camera)\n            : null;\n        if (businessLabelHit) {\n            this._showBusinessHover(businessLabelHit);\n            return;\n        }\n\n        // ── TriTree mode: use BuildingOverlay hover ──\n        const hovered = this._buildingOverlay?.getHoveredBuilding?.();\n        if (hovered) {\n            this._clearBusinessHover();\n            const hoverId = hovered.id ?? null;\n            if (hoverId === this._hoverLabelBuildingId) return;\n            this._clearHoverLabel();\n            this._hoverLabelBuildingId = hoverId;\n\n            const name = hovered.tags?.name || hovered.tags?.building || '';\n            const address = hovered.address || '';\n            const primary = name || address || 'Building';\n            const subText = name && address ? address : '';\n\n            let labelPos = null;\n            if (this._buildingOverlay?._instances) {\n                for (const entry of this._buildingOverlay._instances) {\n                    if (entry.info?.id === hoverId && entry.group) {\n                        const height = Number.isFinite(entry.info?.height) ? entry.info.height : 10;\n                        labelPos = entry.group.position.clone();\n                        if (entry.terrainNormal) {\n                            labelPos.addScaledVector(entry.terrainNormal, height);\n                        }\n                        break;\n                    }\n                }\n            }\n            if (!labelPos) return;\n\n            const ls = getLabelSystem();\n            this._hoverLabelHandle = ls.createLabel(primary, {\n                position: labelPos,\n                type: 'building',\n                objectRadius: 8,\n                subText,\n            });\n            if (this._hoverLabelHandle?.group) {\n                const parent = this._buildingOverlay?.group || this._triTree?.group;\n                if (parent) parent.add(this._hoverLabelHandle.group);\n            }\n            // Emit hover event for address toast\n            if (this.eventBus?.emit) {\n                const tags = hovered.tags || {};\n                const addrParts = [tags['addr:housenumber'], tags['addr:street'], tags['addr:city']].filter(Boolean);\n                this.eventBus.emit('building:hover', {\n                    name: tags.name || '',\n                    address: address || addrParts.join(' '),\n                    lat: hovered.center?.lat ?? null,\n                    lon: hovered.center?.lon ?? null,\n                    footprint: hovered.footprint || null,\n                    height: hovered.height ?? null,\n                    meta: [tags.amenity, tags.shop, tags.tourism, tags['building:levels'] ? tags['building:levels'] + ' floors' : ''].filter(Boolean).join(' · '),\n                    category: tags.shop || tags.amenity || tags.office || tags.tourism || 'building',\n                    phone: tags.phone || tags['contact:phone'] || '',\n                    website: tags.website || tags['contact:website'] || '',\n                    email: tags.email || tags['contact:email'] || '',\n                    fax: tags.fax || tags['contact:fax'] || '',\n                    contact: {\n                        phone: tags.phone || tags['contact:phone'] || '',\n                        website: tags.website || tags['contact:website'] || '',\n                        email: tags.email || tags['contact:email'] || '',\n                        fax: tags.fax || tags['contact:fax'] || ''\n                    },\n                    osm: hovered.osmId ? { type: 'way', id: hovered.osmId } : null,\n                    tags\n                });\n            }\n            return;\n        }\n\n        // ── Cesium mode: raycast tile mesh → match OSM building ──\n        const photoBldg = getPhotoBuildingLabels();\n        // Log periodically to confirm this path is reached\n        if (globalThis.__noclipDebugPhotoLabels === true) {\n            this._hoverDiagCount = (this._hoverDiagCount || 0) + 1;\n        }\n        if (globalThis.__noclipDebugPhotoLabels === true && this._hoverDiagCount % 300 === 1) {\n            console.warn(`[PS] hover path: photoBldg.enabled=${photoBldg.enabled}, raycaster=${!!this._eventManager?.clickRaycaster}, entries=${photoBldg._entries?.size || 0}`);\n        }\n        if (photoBldg.enabled && this._eventManager?.clickRaycaster) {\n            const result = photoBldg.findBuildingAtRaycast(\n                this._eventManager.clickRaycaster,\n                this._camera\n            );\n            photoBldg.showHoverLabel(result);\n            if (result) {\n                this._clearBusinessHover();\n                const e = result.entry;\n                if (e.key !== this._hoverLabelBuildingId) {\n                    this._hoverLabelBuildingId = e.key;\n                    // Emit for address toast\n                    if (this.eventBus?.emit) {\n                        this.eventBus.emit('building:hover', {\n                            name: e.name || '',\n                            address: e.address || '',\n                            lat: e.lat ?? null,\n                            lon: e.lon ?? null,\n                            footprint: e.footprint || null,\n                            height: e.height ?? null,\n                            meta: e.height ? `${Math.round(e.height)}m` : '',\n                            category: e.category || 'building',\n                            phone: e.phone || '',\n                            website: e.website || '',\n                            email: e.email || '',\n                            fax: e.fax || '',\n                            contact: {\n                                phone: e.phone || '',\n                                website: e.website || '',\n                                email: e.email || '',\n                                fax: e.fax || ''\n                            },\n                            osm: e.osmId ? { type: e.osmType || 'way', id: e.osmId } : null,\n                            tags: e.tags || null\n                        });\n                    }\n                }\n                return; // Building found — done\n            }\n            // No building under cursor on photorealistic tiles — clear and fall through to surface:hover\n            if (this._hoverLabelBuildingId) {\n                this._hoverLabelBuildingId = null;\n                if (this.eventBus?.emit) this.eventBus.emit('building:hover:clear');\n            }\n        }\n\n        const hoverLL = this._eventManager?.getHoverLatLon?.();\n        const businessNear = hoverLL\n            ? businessLabels.findBusinessNearLatLon(hoverLL.lat, hoverLL.lon)\n            : null;\n        if (businessNear) {\n            this._showBusinessHover(businessNear);\n            return;\n        }\n        this._clearBusinessHover();\n\n        // Nothing hovered — clear building toast, emit surface hover for geocoding\n        if (this._hoverLabelBuildingId) {\n            this._clearHoverLabel();\n            getPhotoBuildingLabels()._clearHoverLabel?.();\n            this._hoverLabelBuildingId = null;\n            if (this.eventBus?.emit) this.eventBus.emit('building:hover:clear');\n        }\n        // Emit surface hover with lat/lon for reverse geocoding toast\n        if (hoverLL && this.eventBus?.emit) {\n            // Throttle: only emit when position changes meaningfully\n            const prevLat = this._lastSurfaceHoverLat || 0;\n            const prevLon = this._lastSurfaceHoverLon || 0;\n            if (Math.abs(hoverLL.lat - prevLat) > 0.00001 || Math.abs(hoverLL.lon - prevLon) > 0.00001) {\n                this._lastSurfaceHoverLat = hoverLL.lat;\n                this._lastSurfaceHoverLon = hoverLL.lon;\n                this.eventBus.emit('surface:hover', {\n                    lat: hoverLL.lat,\n                    lon: hoverLL.lon,\n                    country: hoverLL.country || null,\n                    subdivision: hoverLL.subdivision || null,\n                });\n            }\n        }\n    }\n\n    _showBusinessHover(result) {\n        const businessLabels = getBusinessLabels();\n        const entry = result?.entry;\n        if (!entry) return;\n        this._clearHoverLabel();\n        getPhotoBuildingLabels()._clearHoverLabel?.();\n        this._hoverLabelBuildingId = null;\n        businessLabels.showHover(result);\n        if (this._hoverBusinessKey === entry.key) return;\n        this._hoverBusinessKey = entry.key;\n        const data = businessLabels.toToastData(entry);\n        if (data && this.eventBus?.emit) {\n            this.eventBus.emit('building:hover', data);\n        }\n        // Notify 2D overlays (minimap) so they can cross-highlight the matching pin.\n        try {\n            if (typeof document !== 'undefined' && typeof CustomEvent !== 'undefined') {\n                document.dispatchEvent(new CustomEvent('noclip:business-selected', {\n                    detail: { source: '3d', id: entry.key, data },\n                }));\n            }\n        } catch { /* ignore DOM dispatch failures */ }\n    }\n\n    _clearBusinessHover() {\n        if (!this._hoverBusinessKey) return;\n        getBusinessLabels().clearHover();\n        this._hoverBusinessKey = null;\n    }\n\n    /**\n     * Player lat/lon — prefers GPS when available (it's the definitive source\n     * during live navigation) and falls back to the in-scene avatar position\n     * so routing still works while browsing without GPS.\n     */\n    _currentPlayerLatLon() {\n        // Try the avatar/local-player world position first\n        try {\n            const playerPos = this._localPlayer?.getWorldPosition?.()\n                || this._localPlayer?.position\n                || null;\n            if (playerPos?.lengthSq?.() > 0 && this._triTree?.group) {\n                const ll = worldPosToLatLonLocal(playerPos, this._triTree.group);\n                if (ll && Number.isFinite(ll.latDeg) && Number.isFinite(ll.lonDeg)) {\n                    return { lat: ll.latDeg, lon: ll.lonDeg };\n                }\n            }\n        } catch {}\n        // Fallback: last known browser GPS\n        try {\n            if (typeof window !== 'undefined') {\n                const cache = window.__noclipLastGPS;\n                if (cache && Number.isFinite(cache.lat) && Number.isFinite(cache.lon)) {\n                    return cache;\n                }\n            }\n        } catch {}\n        // Camera target as last resort\n        try {\n            const target = this._camera?.position;\n            if (target && this._triTree?.group) {\n                const ll = worldPosToLatLonLocal(target, this._triTree.group);\n                if (ll && Number.isFinite(ll.latDeg) && Number.isFinite(ll.lonDeg)) {\n                    return { lat: ll.latDeg, lon: ll.lonDeg };\n                }\n            }\n        } catch {}\n        return null;\n    }\n\n    /**\n     * Resolve one deliberate scene gesture against the surface the user can\n     * actually see.  The surface controller owns photoreal parent/child LOD\n     * filtering, so this never reuses the stale hover snapshot or selects a\n     * retired coarse parent below the current wireframe/textured surface.\n     */\n    getSurfaceTargetAtClient(clientX, clientY) {\n        const point = this._surfaceController?.getSurfacePointFromClient?.(\n            Number(clientX),\n            Number(clientY),\n        );\n        return this._surfaceTargetFromPoint(point, this._surfaceController?._lastGeoHitSource || 'surface');\n    }\n\n    _selectXRSurface(point, source) {\n        const target = this._surfaceTargetFromPoint(point, source);\n        if (!target) return null;\n        this.eventBus?.emit('xr:surface-select', { ...target, name: 'Surface target', category: 'surface-target',\n            address: `${target.lat.toFixed(5)}, ${target.lon.toFixed(5)}`, meta: 'Resolving Mapsource address' });\n        return this._addressHoverOverlay?._labelHandle || null;\n    }\n\n    _surfaceTargetFromPoint(point, source) {\n        if (!point?.isVector3 || point.lengthSq() < 1) return null;\n        const ll = worldPosToLatLonLocal(point, this._triTree?.group || null);\n        if (!ll || !Number.isFinite(ll.latDeg) || !Number.isFinite(ll.lonDeg)) return null;\n        const surfaceRadius = point.length();\n        const ellipsoidRadius = ellipsoidRadiusForWorldDir(point, this._triTree?.group || null);\n        return {\n            lat: ll.latDeg,\n            lon: ll.lonDeg,\n            elevation_m: Number.isFinite(ellipsoidRadius)\n                ? surfaceRadius - ellipsoidRadius\n                : null,\n            surfaceRadius,\n            surfaceSource: source,\n        };\n    }\n\n    _clearHoverLabel() {\n        if (this._hoverLabelHandle) {\n            if (this._hoverLabelHandle.group?.parent) {\n                this._hoverLabelHandle.group.parent.remove(this._hoverLabelHandle.group);\n            }\n            this._hoverLabelHandle.dispose();\n            this._hoverLabelHandle = null;\n        }\n    }\n\n    _applyGeoJsonLabelTuning() {\n        const tuning = {\n            scaleCapAltM: this._geoJsonLabelScaleCapAltM,\n            scaleReleaseAltM: this._geoJsonLabelScaleReleaseAltM,\n            borderRetireAltM: this._geoJsonLabelBorderRetireAltM\n        };\n        this._geoJsonLayer?.setLabelTuning?.(tuning);\n        this._geoJsonLookupLayer?.setLabelTuning?.(tuning);\n        if (this._geoJsonAutoLayers?.size) {\n            for (const layer of this._geoJsonAutoLayers.values()) {\n                layer?.setLabelTuning?.(tuning);\n            }\n        }\n    }\n\n    _getCameraAltitudeMSL() {\n        if (!this._camera) return null;\n        const camPosWorld = this._camera.userData?.worldPosition || this._camera.position;\n        if (!camPosWorld) return null;\n        const camPosLocal = this._geoJsonAltTmp.copy(camPosWorld);\n        this._triTree?.group?.worldToLocal?.(camPosLocal);\n        const camDist = camPosLocal.length();\n        if (!Number.isFinite(camDist) || camDist <= 0) return null;\n        const dir = camPosLocal.normalize();\n        const baseRadius = ellipsoidRadiusForLocalDir(dir);\n        return camDist - baseRadius;\n    }\n\n    _resolveGeoJsonAltitudeMaxLevel(altitudeM) {\n        if (!Number.isFinite(altitudeM)) return null;\n\n        // Outermost (orbital) cap — config-driven, preserved.\n        const altThreshold = Number.isFinite(this._geoJsonFarMaxAdminLevelAltM)\n            ? this._geoJsonFarMaxAdminLevelAltM\n            : null;\n        let level = null;\n        if (Number.isFinite(altThreshold) && altThreshold >= 0 && altitudeM >= altThreshold) {\n            level = this._normalizeGeoJsonLevel(this._geoJsonFarMaxAdminLevel);\n        } else {\n            // Graduated bands: coarser admin detail the higher we are.\n            const bands = this._geoJsonAdminAltBandsM;\n            if (Array.isArray(bands)) {\n                for (const band of bands) {\n                    if (Number.isFinite(band?.altM) && altitudeM >= band.altM) {\n                        level = this._normalizeGeoJsonLevel(band.level);\n                        break;\n                    }\n                }\n            }\n        }\n\n        // Memory pressure (governor) shifts one ADM level coarser.\n        const pressure = this._geoJsonLayer?.getMemoryPressure?.() ?? 0;\n        if (pressure >= 0.5) {\n            const base = Number.isFinite(level) ? level : this._normalizeGeoJsonLevel(this._geoJsonMaxAdminLevel);\n            level = Math.max(0, base - 1);\n        }\n\n        return Number.isFinite(level) ? level : null;\n    }\n\n    _updateGeoJsonAltitudeLimit(force = false) {\n        const altitude = this._getCameraAltitudeMSL();\n        if (!Number.isFinite(altitude)) return;\n        const capLevel = this._resolveGeoJsonAltitudeMaxLevel(altitude);\n        const prev = this._geoJsonAltitudeMaxAdminLevel;\n        if (!force && capLevel === prev) return;\n        this._geoJsonAltitudeMaxAdminLevel = capLevel;\n\n        if (this._geoJsonAutoDepth) {\n            this._refreshGeoJsonAutoDepth({ force: true });\n            return;\n        }\n\n        if (Number.isFinite(capLevel)) {\n            if (capLevel < this._geoJsonAdminLevel) {\n                this._geoJsonAltitudeOverrideActive = true;\n                this._applyGeoJsonSelection(capLevel, this._geoJsonCountry, this._geoJsonManualSource, { preserveState: true });\n                return;\n            }\n        }\n\n        if (this._geoJsonAltitudeOverrideActive) {\n            this._geoJsonAltitudeOverrideActive = false;\n            this._applyGeoJsonSelection(this._geoJsonAdminLevel, this._geoJsonCountry, this._geoJsonManualSource, { preserveState: true });\n        }\n    }\n\n    _formatBuildingName(tags = {}) {\n        if (!tags) return '';\n        return tags.name\n            || tags['addr:housename']\n            || tags.amenity\n            || tags.shop\n            || (tags.building && tags.building !== 'yes' ? tags.building : '');\n    }\n\n    _normalizeGeoJsonLevel(value) {\n        const numeric = Number.isFinite(value) ? value : Number.parseInt(value, 10);\n        if (!Number.isFinite(numeric)) return 0;\n        if (numeric < 0 || numeric > 3) return 0;\n        return numeric;\n    }\n\n    _normalizeGeoJsonCountry(value) {\n        if (typeof value !== 'string') return null;\n        const trimmed = value.trim().toUpperCase();\n        if (!/^[A-Z]{3}$/.test(trimmed)) return null;\n        return trimmed;\n    }\n\n    _applySceneSelectionKeys(keys) {\n        const nextKeys = Array.isArray(keys) ? keys : [];\n        this._geoJsonLayer?.setSceneSelection?.(nextKeys);\n        this._geoJsonLookupLayer?.setSceneSelection?.(nextKeys);\n        if (this._geoJsonAutoLayers && this._geoJsonAutoLayers.size) {\n            for (const layer of this._geoJsonAutoLayers.values()) {\n                layer?.setSceneSelection?.(nextKeys);\n            }\n        }\n    }\n\n    _resolveGeoJsonUrl(source) {\n        if (!source || typeof source !== 'string') return null;\n        if (source.startsWith('./') || source.startsWith('/') || source.startsWith('http')) {\n            return source;\n        }\n        return `/refactor/data/geojson/${source}`;\n    }\n\n    _applyGeoJsonSelection(adminLevel, country, source = null, { preserveState = false } = {}) {\n        const level = this._normalizeGeoJsonLevel(adminLevel);\n        const iso3 = this._normalizeGeoJsonCountry(country);\n        if (!preserveState) {\n            this._geoJsonAdminLevel = level;\n            this._geoJsonCountry = iso3;\n            this._geoJsonManualSource = null;\n        }\n        this._eventManager?.setGeoJsonOverlayInfo?.({\n            layer: this._geoJsonLayer,\n            adminLevel: level\n        });\n        const reload = this._geoJsonLayer?.group?.visible;\n        if (level === 0) {\n            this._geoJsonLayer?.setCountryFilter?.(iso3, { reload: false });\n            this._geoJsonLayer?.setUrl?.('/refactor/data/geojson/world.geojson', { reload });\n            if (!preserveState) {\n                this._geoJsonManualSource = 'world.geojson';\n            }\n            return;\n        }\n        if (!iso3) {\n            this._geoJsonLayer?.setCountryFilter?.(null, { reload: false });\n            this._geoJsonLayer?.setUrl?.('/refactor/data/geojson/world.geojson', { reload });\n            return;\n        }\n        const file = source || `ADM${level}/${iso3}.geojson`;\n        const url = this._resolveGeoJsonUrl(file);\n        this._geoJsonLayer?.setCountryFilter?.(null, { reload: false });\n        if (!preserveState) {\n            this._geoJsonManualSource = file;\n        }\n        if (url) {\n            this._geoJsonLayer?.setUrl?.(url, { reload });\n        }\n    }\n\n    _applyGeoJsonSource(source) {\n        if (!source) return;\n        const match = String(source).match(/ADM([1-3])[\\\\/]([A-Za-z]{3})\\.geojson/i);\n        if (match) {\n            this._geoJsonAdminLevel = this._normalizeGeoJsonLevel(match[1]);\n            this._geoJsonCountry = this._normalizeGeoJsonCountry(match[2]);\n        } else {\n            this._geoJsonAdminLevel = 0;\n            this._geoJsonCountry = null;\n        }\n        this._geoJsonManualSource = source;\n        this._eventManager?.setGeoJsonOverlayInfo?.({\n            layer: this._geoJsonLayer,\n            adminLevel: this._geoJsonAdminLevel\n        });\n        const url = this._resolveGeoJsonUrl(source);\n        if (!url) return;\n        this._geoJsonLayer?.setCountryFilter?.(null, { reload: false });\n        this._geoJsonLayer?.setUrl?.(url, { reload: this._geoJsonLayer?.group?.visible });\n    }\n\n    _setGeoJsonManualSelection(adminLevel, country) {\n        this._geoJsonAdminLevel = this._normalizeGeoJsonLevel(adminLevel);\n        this._geoJsonCountry = this._normalizeGeoJsonCountry(country);\n        this._geoJsonManualSource = null;\n    }\n\n    _applyGeoJsonBaseLayer() {\n        const reload = this._geoJsonLayer?.group?.visible;\n        this._geoJsonLayer?.setCountryFilter?.(null, { reload: false });\n        this._geoJsonLayer?.setUrl?.('/refactor/data/geojson/world.geojson', { reload });\n    }\n\n    _setGeoJsonVisible(visible) {\n        // Administrative boundaries are a provider-independent cartographic\n        // overlay. Keep the enabled state through the overview→photoreal or\n        // overview→TriTree handoff instead of treating the loading globe as a\n        // reason to suppress the global country outline.\n        const show = !!visible;\n        if (!show) {\n            // Invalidate an administrative-depth lookup that started while\n            // borders were visible. Its late completion must not re-enable a\n            // regional spire layer after the label/overlay gate closes.\n            this._geoJsonAutoSeq = (this._geoJsonAutoSeq || 0) + 1;\n        }\n        this._geoJsonLayer?.setVisible?.(show);\n        if (this._geoJsonAutoDepth) {\n            this._setGeoJsonAutoLayersVisible(show);\n            if (show) {\n                this._refreshGeoJsonAutoDepth({ force: true });\n            }\n        }\n    }\n\n    _syncGeoJsonOverlayVisibility() {\n        const labels = this._sceneSettings?.getSection?.('scene.labels') || {};\n        const debugVisible = this._sceneSettings?.getSection?.('scene.debug.geoJson');\n        const visible = labels.enabled !== false\n            && debugVisible !== false\n            && getLabelCategoryControlValue(\n                this._sceneSettings,\n                labels,\n                'administrative',\n            );\n        this._setGeoJsonVisible(visible);\n    }\n\n    _setGeoJsonLabelsEnabled(enabled) {\n        const next = !!enabled;\n        this._geoJsonLayer?.setLabelsEnabled?.(next);\n        this._geoJsonLookupLayer?.setLabelsEnabled?.(next);\n        this._geoJsonAutoLayers?.forEach?.((layer) => layer?.setLabelsEnabled?.(next));\n    }\n\n    _setGeoJsonAutoLayersVisible(visible) {\n        if (!this._geoJsonAutoLayers) return;\n        const show = !!visible;\n        this._geoJsonAutoLayers.forEach((layer) => {\n            const hasUrl = !!layer?.url;\n            layer?.setVisible?.(show && hasUrl);\n        });\n    }\n\n    _hideGeoJsonAutoLayers() {\n        if (!this._geoJsonAutoLayers) return;\n        this._geoJsonAutoLayers.forEach((layer) => layer?.setVisible?.(false));\n    }\n\n    _setGeoJsonAutoDepth(enabled) {\n        const next = !!enabled;\n        if (this._geoJsonAutoDepth === next) return;\n        this._geoJsonAutoDepth = next;\n        if (this._geoJsonAutoDepth) {\n            this._applyGeoJsonBaseLayer();\n            this._refreshGeoJsonAutoDepth({ force: true });\n        } else {\n            this._hideGeoJsonAutoLayers();\n            this._applyGeoJsonSelection(this._geoJsonAdminLevel, this._geoJsonCountry, this._geoJsonManualSource);\n        }\n    }\n\n    _setGeoJsonMaxAdminLevel(level) {\n        const next = this._normalizeGeoJsonLevel(level);\n        if (this._geoJsonMaxAdminLevel === next) return;\n        this._geoJsonMaxAdminLevel = next;\n        if (this._geoJsonAutoDepth) {\n            this._refreshGeoJsonAutoDepth({ force: true });\n        }\n    }\n\n    async _refreshGeoJsonAutoDepth({ force = false } = {}) {\n        if (!this._geoJsonAutoDepth) return;\n        if (!this._geoBoundaryService) return;\n        const visible = this._geoJsonLayer?.group?.visible ?? false;\n        if (!visible) {\n            this._setGeoJsonAutoLayersVisible(false);\n            return;\n        }\n\n        const iso3 = this._navGeoInfo?.iso3 || null;\n        const maxLevel = this._normalizeGeoJsonLevel(this._geoJsonMaxAdminLevel);\n        const altitudeCap = Number.isFinite(this._geoJsonAltitudeMaxAdminLevel)\n            ? this._geoJsonAltitudeMaxAdminLevel\n            : null;\n        const effectiveMaxLevel = Number.isFinite(altitudeCap)\n            ? Math.min(maxLevel, altitudeCap)\n            : maxLevel;\n        const hierarchy = this._navGeoInfo?.admin?.hierarchy || null;\n        this._applyGeoJsonBaseLayer();\n\n        if (!iso3 || effectiveMaxLevel <= 0) {\n            this._setGeoJsonAutoLayersVisible(false);\n            this._eventManager?.setGeoJsonOverlayInfo?.({\n                layer: this._geoJsonLayer,\n                adminLevel: 0\n            });\n            this._geoJsonAutoState = { iso3: null, maxLevel: effectiveMaxLevel, levels: [], hierarchy: null };\n            return;\n        }\n\n        // Check if hierarchy has changed - this requires reload to apply parent filters\n        const hierarchyChanged = this._hasHierarchyChanged(hierarchy, this._geoJsonAutoState.hierarchy);\n\n        const needsReload = force ||\n            iso3 !== this._geoJsonAutoState.iso3 ||\n            effectiveMaxLevel !== this._geoJsonAutoState.maxLevel ||\n            hierarchyChanged;\n\n        let available = [];\n        if (needsReload) {\n            const seq = ++this._geoJsonAutoSeq;\n            for (let level = 1; level <= effectiveMaxLevel; level++) {\n                const hasLevel = await this._geoBoundaryService.hasCountryAtLevel(level, iso3);\n                if (seq !== this._geoJsonAutoSeq) return;\n                if (hasLevel) available.push(level);\n            }\n        } else {\n            available = (this._geoJsonAutoState.levels || []).filter((level) => level <= effectiveMaxLevel);\n        }\n\n        const visibleLevels = new Set(available);\n        this._geoJsonAutoLayers.forEach((layer, level) => {\n            if (!layer) return;\n            if (visibleLevels.has(level)) {\n                if (needsReload) {\n                    const file = `ADM${level}/${iso3}.geojson`;\n                    const url = this._resolveGeoJsonUrl(file);\n\n                    // Apply hierarchical parent filter for levels > 1\n                    // ADM2 features are filtered by their ADM1 parent name\n                    // ADM3 features are filtered by their ADM2 parent name\n                    const parentLevel = level - 1;\n                    const parentKey = parentLevel >= 1 ? `adm${parentLevel}` : null;\n                    const parentName = parentKey && hierarchy?.[parentKey]?.name || null;\n\n                    if (parentName && parentLevel >= 1) {\n                        // Set parent filter before setting URL - this filters subdivisions\n                        // to only show those within the current parent region\n                        layer.setParentFilter(parentName, parentLevel, { reload: false });\n                    } else {\n                        // Clear any existing parent filter for ADM1 or when no hierarchy\n                        layer.clearParentFilter({ reload: false });\n                    }\n\n                    layer.setUrl(url, { reload: true });\n                }\n                layer.setVisible(true);\n            } else {\n                layer.setVisible(false);\n            }\n        });\n\n        const deepest = available.length ? Math.max(...available) : 0;\n        const overlayLayer = deepest ? this._geoJsonAutoLayers.get(deepest) : this._geoJsonLayer;\n        this._eventManager?.setGeoJsonOverlayInfo?.({\n            layer: overlayLayer,\n            adminLevel: deepest\n        });\n        this._geoJsonAutoState = { iso3, maxLevel: effectiveMaxLevel, levels: available, hierarchy };\n    }\n\n    /**\n     * Check if the admin hierarchy has meaningfully changed.\n     * Used to determine if GeoJSON layers need to reload with new parent filters.\n     */\n    _hasHierarchyChanged(newHierarchy, oldHierarchy) {\n        if (!newHierarchy && !oldHierarchy) return false;\n        if (!newHierarchy || !oldHierarchy) return true;\n\n        // Check if any admin level names have changed\n        for (let level = 1; level <= 4; level++) {\n            const key = `adm${level}`;\n            const newName = newHierarchy[key]?.name || null;\n            const oldName = oldHierarchy[key]?.name || null;\n            if (newName !== oldName) return true;\n        }\n        return false;\n    }\n\n    _getTuneables() {\n        const rendererScale = this._sceneInitializer?.renderScale ?? this._renderer?.getPixelRatio?.();\n        const autoRender = this._animationLoop?.autoRenderScale || {};\n        const renderCadenceMs = this._animationLoop?.renderCadenceMs ?? 0;\n        const frameDiscard = this._animationLoop?.frameDiscard || {};\n        const baseAtmosphereConfig = this._sceneInitializer?.getAtmosphereCloudsConfig?.() || {\n            enabled: this._sceneInitializer?.isAtmosphereEnabled?.() ?? false\n        };\n        const overlayAtmosphereConfig = this._sceneInitializer?.getEarthOverlayConfig?.() || {};\n        const atmosphereConfig = {\n            ...baseAtmosphereConfig,\n            ...overlayAtmosphereConfig\n        };\n        const weatherConfig = this._sceneInitializer?.getWeatherConfig?.() || {};\n        const terrainImagery = buildTerrainImagerySettings({\n            imageryManager: this._imageryManager,\n            triTree: this._triTree\n        });\n        const terrainElevation = buildTerrainElevationSettings({\n            elevationClient: this._elevationClient,\n            triTree: this._triTree\n        });\n        const geoJsonUrl = this._geoJsonLayer?.url || null;\n        const geoJsonBase = '/refactor/data/geojson/';\n        const geoJsonSource = geoJsonUrl\n            ? (geoJsonUrl.startsWith(geoJsonBase) ? geoJsonUrl.slice(geoJsonBase.length) : geoJsonUrl)\n            : null;\n\n        return {\n            renderer: {\n                renderScale: rendererScale,\n                autoRenderScale: {\n                    enabled: !!autoRender.enabled,\n                    targetFps: autoRender.targetFps,\n                    minScale: autoRender.minScale,\n                    maxScale: autoRender.maxScale\n                },\n                renderCadenceMs,\n                frameDiscard: {\n                    enabled: !!frameDiscard.enabled,\n                    waitThresholdMs: frameDiscard.waitThresholdMs\n                }\n            },\n            audio: {\n                enabled: this._audioEnabledSetting\n            },\n            lighting: {\n                date: this._lightingSystem?.currentDate || new Date(),\n                timeSpeed: this._lightingSystem?.timeSpeed ?? 0,\n                simplified: !!this._lightingSystem?.useSimplified,\n                sunIntensity: this._lightingSystem?.sun?.intensity ?? 0,\n                ambientIntensity: this._lightingSystem?.ambient?.intensity ?? 0\n            },\n            atmosphere: atmosphereConfig,\n            weather: weatherConfig,\n            terrain: {\n                lod: {\n                    minLevel: this._triTree?.minBaseLevel,\n                    maxLevel: this._triTree?.maxTileLevel,\n                    tileBudget: this._triTree?.tileBudget,\n                    splitBudget: this._triTree?.splitBudget,\n                    mergeBudget: this._triTree?.mergeBudget,\n                    maxScreenSpaceError: this._triTree?.maxScreenSpaceError\n                },\n                surface: {\n                    staging: {\n                        minLOD: this._triTree?.surfaceStageMinLOD,\n                        maxLOD: this._triTree?.surfaceStageMaxLOD,\n                        cooldownMs: this._triTree?.surfaceStageCooldownMs,\n                        cullAngleDeg: this._triTree?.surfaceCullAngleDeg,\n                        focusAngleDeg: this._triTree?.surfaceStageFocusAngleDeg\n                    },\n                    falloff: {\n                        nearLOD: this._triTree?.surfaceLodNear,\n                        farLOD: this._triTree?.surfaceLodFar,\n                        power: this._triTree?.surfaceLodFalloffPower,\n                        startDeg: this._triTree?.surfaceLodFalloffStartDeg\n                    }\n                },\n                orbit: {\n                    falloff: {\n                        marginDeg: this._triTree?.orbitFalloffMarginDeg,\n                        anchorDeg: this._triTree?.orbitFalloffAnchorDeg,\n                        power: this._triTree?.orbitLodFalloffPower\n                    }\n                },\n                imagery: terrainImagery,\n                elevation: terrainElevation\n            },\n            camera: {\n                mode: this._surfaceController?.isInSurfaceMode?.() ? 'surface' : 'orbit',\n                orbit: {\n                    minDistance: this._controls?.minDistance,\n                    maxDistance: this._controls?.maxDistance,\n                    damping: this._controls?.dampingFactor\n                },\n                surface: {\n                    moveSpeed: this._surfaceController?.SURFACE_MOVE_SPEED,\n                    altitudeSpeedMax: this._surfaceController?.SURFACE_WALK_ALT_SCALE_MAX,\n                    verticalSpeed: this._surfaceController?.SURFACE_VERTICAL_SPEED,\n                    fovMin: this._surfaceController?.SURFACE_FOV_MIN,\n                    fovMax: this._surfaceController?.SURFACE_FOV_MAX\n                }\n            },\n            avatar: JSON.parse(JSON.stringify(this._avatarConfig || {})),\n            debug: {\n                wireframe: this._triTree?.renderRules?.wireframe ?? false,\n                geoJson: this._geoJsonLayer?.group?.visible ?? false,\n                geoJsonAdminLevel: this._geoJsonAdminLevel ?? 0,\n                geoJsonCountry: this._geoJsonCountry ?? null,\n                geoJsonSource,\n                geoJsonAutoDepth: this._geoJsonAutoDepth ?? false,\n                geoJsonMaxAdminLevel: this._geoJsonMaxAdminLevel ?? 3,\n                neighborDetection: this._triTree?.enableNeighborDetection ?? true,\n                raycastLinePrecision: this._raycastLinePrecision,\n                wireframeStyle: this._wireframeStyle || { ...DEFAULT_WIREFRAME_STYLE }\n            }\n        };\n    }\n\n    _mergeAvatarConfig(base, patch) {\n        if (!patch || typeof patch !== 'object') return base || {};\n        const output = Array.isArray(base) ? base.slice() : { ...(base || {}) };\n        Object.entries(patch).forEach(([key, value]) => {\n            if (value && typeof value === 'object' && !Array.isArray(value)) {\n                output[key] = this._mergeAvatarConfig(output[key], value);\n            } else {\n                output[key] = value;\n            }\n        });\n        return output;\n    }\n\n    _applyAvatarConfig(config = {}) {\n        if (!config || typeof config !== 'object') return;\n        this._avatarConfig = this._mergeAvatarConfig(this._avatarConfig, config);\n        this._localPlayer?.applyConfig?.(this._avatarConfig);\n        this._peerManager?.applyConfig?.(this._avatarConfig);\n        this._presenceSystem?.setAvatarConfig?.(this._avatarConfig);\n    }\n\n    _applyRaycastLinePrecision(value) {\n        const precision = Number.isFinite(value) ? value : Number.parseFloat(value);\n        if (!Number.isFinite(precision)) return;\n        const next = Math.max(0, precision);\n        this._raycastLinePrecision = next;\n\n        const applyToRaycaster = (raycaster) => {\n            if (!raycaster) return;\n            raycaster.linePrecision = next;\n            if (raycaster.params) {\n                if (!raycaster.params.Line) raycaster.params.Line = {};\n                raycaster.params.Line.threshold = next;\n            }\n        };\n\n        applyToRaycaster(this._triTree?._terrainRaycaster);\n        applyToRaycaster(this._surfaceController?.surfaceRaycaster);\n        applyToRaycaster(this._surfaceController?._orbitRaycaster);\n        applyToRaycaster(this._surfaceController?._geoRaycaster);\n        applyToRaycaster(this._eventManager?.clickRaycaster);\n        applyToRaycaster(this._clickTriggerManager?.raycaster);\n        applyToRaycaster(this._vrManager?._teleportRay);\n    }\n\n    _resolveWireframeStyle(style) {\n        const base = { ...DEFAULT_WIREFRAME_STYLE, ...(style || {}) };\n        const accent = base.accent || DEFAULT_WIREFRAME_STYLE.accent;\n        const accentSoft = base.accentSoft || accent;\n        const accentStrong = base.accentStrong || accent;\n        const surfaceColor = base.surfaceColor || DEFAULT_WIREFRAME_STYLE.surfaceColor;\n        const lineColor = base.lineColor || base.terrainLine || DEFAULT_WIREFRAME_STYLE.lineColor;\n\n        return {\n            surfaceColor,\n            lineColor,\n            accent,\n            accentSoft,\n            accentStrong,\n            // Legacy consumers still receive their old keys, but every one\n            // Flat geometry retains one authored albedo. A second authored\n            // color is used only by crease-filtered geometry outlines.\n            terrainLine: lineColor,\n            terrainLineOverlay: true,\n            terrainFillMin: surfaceColor,\n            terrainFillMax: surfaceColor,\n            terrainMaterial: 'gradient',\n            buildingFill: surfaceColor,\n            buildingLine: lineColor,\n            topoEnabled: false\n        };\n    }\n\n    _applyWireframeStyle(stylePatch = null) {\n        const base = this._wireframeStyle || { ...DEFAULT_WIREFRAME_STYLE };\n        if (stylePatch && typeof stylePatch === 'object') {\n            this._wireframeStyle = { ...base, ...stylePatch };\n        } else if (!this._wireframeStyle) {\n            this._wireframeStyle = { ...DEFAULT_WIREFRAME_STYLE };\n        }\n\n        const resolved = this._resolveWireframeStyle(this._wireframeStyle);\n        this._wireframeStyleResolved = resolved;\n\n        if (typeof document !== 'undefined') {\n            const root = document.documentElement;\n            if (root) {\n                // Terrain color is user-configurable, while the operator UI now\n                // has a fixed NCLP dashboard palette. Keep these concerns apart\n                // so a wireframe preset cannot recolor application controls.\n                root.style.setProperty('--scene-wireframe-accent', resolved.accent);\n                root.style.setProperty('--scene-wireframe-accent-soft', resolved.accentSoft);\n                root.style.setProperty('--scene-wireframe-accent-strong', resolved.accentStrong);\n                const accentRgb = this._toCssRgb(resolved.accent);\n                if (accentRgb) root.style.setProperty('--scene-wireframe-accent-rgb', accentRgb);\n            }\n        }\n        this._updateViewshedHighlightAccent();\n\n        setWireframeStyle({\n            fillMinColor: resolved.terrainFillMin,\n            fillMaxColor: resolved.terrainFillMax,\n            lineColor: resolved.terrainLine,\n            lineOverlayEnabled: resolved.terrainLineOverlay,\n            fillMode: resolved.terrainMaterial,\n            topoEnabled: false\n        });\n\n        // Refresh wireframe overlays on all tiles when line overlay setting changes\n        if (this._triTree && this._triTree.renderRules?.wireframe) {\n            this._triTree.refreshWireframeOverlays?.();\n        }\n        // Sync flat albedo plus the crease-filtered photoreal outline. Takram\n        // continues to provide the textured path's physical sun/sky shading.\n        if (this._photoTileLoader?.enabled && this._photoTileLoader._wireframeEnabled) {\n            this._photoTileLoader.setWireframeMode(true, {\n                surfaceColor: resolved.surfaceColor,\n                lineColor: resolved.lineColor,\n            });\n        }\n\n        this._buildingOverlay?.applyWireframeStyle?.({\n            fill: resolved.buildingFill,\n            line: resolved.buildingLine\n        });\n\n        this._eventManager?.setWireframeStyle?.({\n            accent: resolved.accent,\n            accentSoft: resolved.accentSoft,\n            accentStrong: resolved.accentStrong,\n            highlight: resolved.lineColor\n        });\n    }\n\n    /**\n     * Keep country/admin border colors independent of terrain presentation.\n     * This compatibility hook still tracks wireframe state for settings and\n     * relationship updates, but wireframe never recolors the cartographic\n     * overlay or disables its per-feature palette.\n     * @param {boolean} on\n     */\n    _applyWireframeBorderColor(on) {\n        this._wireframeActive = !!on;\n        const conflictColor = this._geoJsonRenderMode === 'surface'\n            ? this._geoJsonConflictDisposition?.color\n            : null;\n        const color = conflictColor ?? this._geoJsonThemeColor ?? 0x14b8a6;\n        const layers = [\n            this._geoJsonLayer,\n            ...(this._geoJsonAutoLayers?.values?.() || []),\n        ].filter(Boolean);\n        for (const layer of layers) {\n            layer.setColor?.(color);\n            layer.setFeatureColorsEnabled?.(true);\n        }\n    }\n\n    _geoJsonRelationshipFeatureKeys(feature) {\n        const properties = feature?.properties || {};\n        return [...new Set([\n            this._extractGeoJsonIso3(properties),\n            properties.iso_a2,\n            properties.admin,\n            properties.name,\n            properties.name_long,\n            properties.country,\n            properties.country_name,\n        ].map((value) => String(value ?? '').trim().toUpperCase()).filter(Boolean))];\n    }\n\n    _resolveGeoJsonRelationshipColor(feature) {\n        const state = this._geoJsonConflictMapState;\n        if (!state?.enabled) return this._geoJsonThemeColor ?? 0x14b8a6;\n        const keys = this._geoJsonRelationshipFeatureKeys(feature);\n        const currentIso = String(this._navGeoInfo?.iso3 || '').toUpperCase();\n        const currentName = String(this._navGeoInfo?.countryName || '').toUpperCase();\n        const disposition = keys.map((key) => state.regions?.[key]).find(Boolean)\n            || (keys.includes(currentIso) || keys.includes(currentName)\n                ? CONFLICT_BORDER_PALETTE.friendly\n                : CONFLICT_BORDER_PALETTE.neutral);\n        return disposition.color;\n    }\n\n    _applyGeoJsonRelationshipColors() {\n        const resolver = this._geoJsonConflictMapState?.enabled\n            ? this._geoJsonRelationshipResolver\n            : null;\n        const layers = [\n            this._geoJsonLayer,\n            ...(this._geoJsonAutoLayers?.values?.() || []),\n        ].filter(Boolean);\n        for (const layer of layers) {\n            layer.setFeatureColorResolver?.(resolver);\n            layer.setFeatureColorsEnabled?.(true);\n        }\n    }\n\n    _setConflictBorderMapState(state) {\n        this._geoJsonConflictMapState = state?.enabled\n            ? { ...state, regions: { ...(state.regions || {}) } }\n            : null;\n        this._applyGeoJsonRelationshipColors();\n    }\n\n    _setSurfaceConflictBorderDisposition(disposition) {\n        const next = disposition && Number.isFinite(disposition.color)\n            ? { ...disposition }\n            : null;\n        if (this._geoJsonConflictDisposition?.id === next?.id\n            && this._geoJsonConflictDisposition?.eventCount === next?.eventCount) return;\n        this._geoJsonConflictDisposition = next;\n        this._applyWireframeBorderColor(this._wireframeActive);\n    }\n\n    _toCssRgb(colorValue) {\n        if (!colorValue) return null;\n        try {\n            const color = new THREE.Color(colorValue);\n            const r = Math.round(color.r * 255);\n            const g = Math.round(color.g * 255);\n            const b = Math.round(color.b * 255);\n            return `${r}, ${g}, ${b}`;\n        } catch (err) {\n            return null;\n        }\n    }\n\n    _normalizeScenePatch(patch, current = {}) {\n        if (!patch || typeof patch !== 'object') return patch;\n        const isPlainObject = (value) => {\n            if (!value || typeof value !== 'object') return false;\n            return Object.prototype.toString.call(value) === '[object Object]';\n        };\n        const next = { ...patch };\n        const nextDebug = isPlainObject(patch.debug) ? { ...patch.debug } : {};\n        const nextAtmosphere = isPlainObject(patch.atmosphere) ? { ...patch.atmosphere } : {};\n        const currentAtmosphere = current?.atmosphere || {};\n        const nextTerrain = isPlainObject(patch.terrain) ? { ...patch.terrain } : {};\n        const currentTerrain = current?.terrain || {};\n        const currentImagery = currentTerrain?.imagery || {};\n        // Wireframe is a material presentation mode only. It must not rewrite\n        // atmosphere/cloud preferences because its monochrome albedo uses the\n        // same deferred sun, sky, depth, and aerial-composition path as\n        // textured photoreal terrain.\n\n        let effectiveAtmosphereEnabled;\n        if (Object.prototype.hasOwnProperty.call(nextAtmosphere, 'enabled')) {\n            effectiveAtmosphereEnabled = !!nextAtmosphere.enabled;\n        } else if (typeof currentAtmosphere.enabled === 'boolean') {\n            effectiveAtmosphereEnabled = currentAtmosphere.enabled;\n        } else {\n            effectiveAtmosphereEnabled = true;\n        }\n\n        if (this._isMobile && effectiveAtmosphereEnabled) {\n            const nextSimpleClouds = isPlainObject(nextAtmosphere.simpleClouds)\n                ? { ...nextAtmosphere.simpleClouds }\n                : {};\n            // Mobile defaults stay off. Explicit cloud choices survive every\n            // later settings patch; capability defaults are not hard vetoes.\n            if (typeof nextSimpleClouds.enabled !== 'boolean') {\n                nextSimpleClouds.enabled = currentAtmosphere.simpleClouds?.enabled === true;\n            }\n            nextAtmosphere.simpleClouds = nextSimpleClouds;\n        }\n\n        if (Object.keys(nextDebug).length > 0) {\n            next.debug = nextDebug;\n        }\n        if (Object.keys(nextAtmosphere).length > 0) {\n            next.atmosphere = nextAtmosphere;\n        }\n        if (Object.keys(nextTerrain).length > 0) {\n            next.terrain = nextTerrain;\n        }\n\n        const effectiveTileSource = nextTerrain.tileSource\n            || currentTerrain.tileSource\n            || 'tritree';\n\n        // ── Keep tile-source mode and photorealistic loader in lockstep ──\n        // `quadtree` is the Cesium photorealistic mode in the settings UI.\n        // Saved/default settings can drift into tileSource=quadtree with the\n        // nested loader flag false, which suppresses TriTree but never starts\n        // Cesium until the user flips the menu. Normalize that contradiction.\n        const hasTerrainProviderPatch = Object.prototype.hasOwnProperty.call(nextTerrain, 'tileSource')\n            || Object.prototype.hasOwnProperty.call(nextTerrain.photorealistic || {}, 'enabled');\n        if (effectiveTileSource === 'quadtree'\n            && (hasTerrainProviderPatch || currentTerrain.photorealistic?.enabled !== true)) {\n            const nextPhoto = isPlainObject(nextTerrain.photorealistic)\n                ? { ...nextTerrain.photorealistic }\n                : {};\n            if (nextPhoto.enabled !== true) {\n                nextPhoto.enabled = true;\n                nextTerrain.photorealistic = nextPhoto;\n                next.terrain = nextTerrain;\n            }\n        } else if (Object.prototype.hasOwnProperty.call(nextTerrain, 'tileSource')) {\n            const nextPhoto = isPlainObject(nextTerrain.photorealistic)\n                ? { ...nextTerrain.photorealistic }\n                : {};\n            if (nextPhoto.enabled !== false) {\n                nextPhoto.enabled = false;\n                nextTerrain.photorealistic = nextPhoto;\n                next.terrain = nextTerrain;\n            }\n        }\n\n        // ── Terrain-provider ownership for generated buildings ──\n        // TriTree has no native buildings, so its OSM layer remains automatic.\n        // Generated solids and texture projection are forbidden with photoreal\n        // terrain, even when old settings or API patches request repair.\n        const hasExplicitTerrainMode = Object.prototype.hasOwnProperty.call(nextTerrain, 'tileSource');\n        if (hasExplicitTerrainMode || isPlainObject(patch.buildings)) {\n            const nextBuildings = isPlainObject(patch.buildings)\n                ? { ...patch.buildings }\n                : {};\n            if (hasExplicitTerrainMode && effectiveTileSource === 'tritree') {\n                nextBuildings.enabled = true;\n                nextBuildings.photorealFallbackEnabled = false;\n            } else if (effectiveTileSource !== 'tritree') {\n                nextBuildings.enabled = false;\n                nextBuildings.photorealFallbackEnabled = false;\n            } else if (effectiveTileSource === 'tritree') {\n                // A buildings-only patch cannot leave the photoreal repair\n                // sampler armed after the terrain provider is already TriTree.\n                nextBuildings.photorealFallbackEnabled = false;\n            }\n            next.buildings = nextBuildings;\n        }\n\n        return next;\n    }\n\n    _scheduleOceanResolverSetup() {\n        if (this._oceanResolverSetupScheduled) return;\n        this._oceanResolverSetupScheduled = true;\n        // Native coastal tiles can arrive before the optional world-country\n        // index. Swimming must consume them immediately, not wait for idle\n        // loading or inherit the coarse country's land/sea verdict.\n        const resolveRegional = (latitude, longitude) => {\n            const mapped = this._sceneInitializer?.regionalWaterMask?.sample(latitude, longitude);\n            return mapped ? { ...mapped, seaLevelMeters: 0 } : null;\n        };\n        this._surfaceController?.setOceanResolver?.(resolveRegional);\n        this._elevationClient?.setOceanResolver?.(resolveRegional);\n        const run = () => {\n            this._configureOceanResolver().catch((err) => {\n                console.warn('[PlanetScene] ocean resolver setup failed:', err);\n            });\n        };\n        if (typeof requestIdleCallback === 'function') {\n            requestIdleCallback(run, { timeout: 12000 });\n        } else {\n            setTimeout(run, 8000);\n        }\n    }\n\n    async _configureOceanResolver() {\n        if (!this._elevationClient || !this._geoBoundaryService) return;\n        if (typeof this._geoBoundaryService.getWorldIndex !== 'function') return;\n\n        try {\n            const world = await this._geoBoundaryService.getWorldIndex();\n            const worldIndex = world?.index || null;\n            if (!worldIndex) return;\n\n            const oceanCache = new Map();\n            const cacheLimit = 250_000;\n            const quantize = 0.001; // degrees\n            const keyFor = (lat, lon) => {\n                const qLat = Math.round(lat / quantize);\n                const qLon = Math.round(lon / quantize);\n                return `${qLat},${qLon}`;\n            };\n\n            const resolveOcean = (latDeg, lonDeg) => {\n                if (!Number.isFinite(latDeg) || !Number.isFinite(lonDeg)) return null;\n                const mapped = this._sceneInitializer?.regionalWaterMask?.sample(latDeg, lonDeg);\n                if (mapped) return mapped.isOcean\n                    ? { ...mapped, seaLevelMeters: 0 } : { ...mapped, isOcean: false };\n                const key = keyFor(latDeg, lonDeg);\n                let cached = oceanCache.get(key);\n                if (cached === undefined) {\n                    const feature = worldIndex.getFeatureAtLatLon(latDeg, lonDeg);\n                    cached = feature ? 0 : 1;\n                    oceanCache.set(key, cached);\n                    if (oceanCache.size > cacheLimit) oceanCache.clear();\n                }\n                if (cached) {\n                    return { isOcean: true, waterMask: 1, seaLevelMeters: 0 };\n                }\n                return null;\n            };\n            this._elevationClient.setOceanResolver(resolveOcean);\n            this._surfaceController?.setOceanResolver?.(resolveOcean);\n        } catch (err) {\n            console.warn('[PlanetScene] Ocean resolver init failed', err);\n        }\n    }\n\n    // ── Photorealistic 3D Tiles ──────────────────────────────────────\n\n    async _enablePhotoSatelliteFallback(reason) {\n        if (this._photoSatelliteFallback || this._photoSatelliteFallbackPromise\n            || this._mapPresentationMode === '2d' || this._cameraExclusiveState\n            || (this._surfaceController?.getBodyAnchor?.() || 'terra') !== 'terra') return;\n        const generation = this._photoSatelliteFallbackGeneration || 0;\n        const lifecycle = this._photoLifecycleGeneration;\n        this._photoSatelliteFallbackPromise = (async () => {\n            const spec = getBasemap('esri-world-imagery');\n            if (!spec) throw new Error('Satellite source is not registered');\n            const source = await resolveMapSource({ ...spec, backendOnly: true,\n                backendTilePath: 'v1/maps/tiles/esri-world-imagery/{z}/{x}/{y}' });\n            if (generation !== (this._photoSatelliteFallbackGeneration || 0)\n                || lifecycle !== this._photoLifecycleGeneration\n                || this._mapPresentationMode === '2d' || this._cameraExclusiveState) return;\n            const terrain = new MapSourceGlobe({ parent: this._triTree?.group,\n                material: this._sceneInitializer?.earthMaterial, source, mobile: this._isMobile,\n                onSurfaceChange: changes => this._refreshSurfaceAnchorsForTerrainChanges(changes) });\n            this._photoSatelliteTerrain = terrain;\n            this._photoSatelliteFallback = true;\n            this._photoInitializationPresentationHold = true;\n            this._photoTileLoader?.setPresentationEnabled?.(false);\n            this._setTriTreePhotorealSuppressed(true);\n            this._setOverviewGlobeVisible(false);\n            if (this._surfaceController) {\n                this._surfaceController.mapSourceTerrainGroup = terrain.group;\n                this._surfaceController._photoTerrainRadius = null;\n            }\n            if (typeof document !== 'undefined') {\n                const attribution = document.createElement('a');\n                attribution.className = 'nca-satellite-attribution';\n                attribution.href = 'https://www.esri.com/en-us/arcgis/products/arcgis-living-atlas/overview';\n                attribution.target = '_blank'; attribution.rel = 'noopener noreferrer';\n                attribution.textContent = `${source.attribution} · OpenStreetMap / OpenMapTiles · Mapzen Terrain / Mapsource`;\n                document.body.appendChild(attribution);\n                this._photoSatelliteAttribution = attribution;\n            }\n            this.eventBus?.emit?.('photo:status', { status: 'disconnected',\n                source: 'satellite-fallback', detail: 'Satellite terrain', error: reason });\n        })().catch(error => {\n            console.warn('[PlanetScene] Satellite terrain unavailable:', error.message);\n        }).finally(() => {\n            if (generation === (this._photoSatelliteFallbackGeneration || 0)) {\n                this._photoSatelliteFallbackPromise = null;\n            }\n        });\n        return this._photoSatelliteFallbackPromise;\n    }\n\n    _clearPhotoSatelliteFallback() {\n        this._photoSatelliteFallbackGeneration = (this._photoSatelliteFallbackGeneration || 0) + 1;\n        this._photoSatelliteFallbackPromise = null;\n        const active = this._photoSatelliteFallback;\n        this._photoSatelliteFallback = false;\n        this._photoSatelliteAttribution?.remove();\n        this._photoSatelliteAttribution = null;\n        if (!active) return;\n        this._photoSatelliteTerrain?.dispose();\n        this._photoSatelliteTerrain = null;\n        if (this._surfaceController) {\n            this._surfaceController.mapSourceTerrainGroup = null;\n            this._surfaceController._photoTerrainRadius = null;\n        }\n        this._setTriTreePhotorealSuppressed(true);\n    }\n\n    /**\n     * Enable or disable photorealistic 3D tiles (BYO API key).\n     * @param {boolean} enabled\n     * @param {Object} photoConfig  terrain.photorealistic patch\n     */\n    async _handlePhotorealisticToggle(enabled, photoConfig = {}, options = {}) {\n        if (this._cameraExclusiveState) {\n            this._cameraExclusiveState.photoRequested = enabled === true;\n            this._cameraExclusiveState.photoConfig = { ...photoConfig };\n            return;\n        }\n\n        if (!enabled) {\n            this._clearPhotoSatelliteFallback();\n            this._photoDeferredInitialization = false;\n            this._photoDeferredConfig = null;\n            this._photoMapModeDeferred = false;\n            this._photoMapModeDeferredConfig = null;\n            this._photoSurfaceEntryPending = null;\n            this._photoSurfaceEntryPhase = null;\n            this._photoInitializationPresentationHold = false;\n            this._setOverviewGlobeVisible(false);\n            this._suspendPhotorealisticTiles();\n            this._photoAltitudeSuspended = false;\n            // Restore tritree tile display and resume LOD work\n            this._setTriTreePhotorealSuppressed(false);\n            this._refreshSurfaceAnchorsForTerrainChanges([{\n                global: true,\n                source: 'terrain-mode',\n                reason: 'photoreal-disabled',\n            }]);\n            // Remove the temporary photoreal terrain-quality presentation\n            // hold. Infrastructure enablement itself is user-owned and is\n            // never rewritten by a terrain-provider change.\n            this._setPhotorealInfrastructureSuppressed(false);\n            this._buildingOverlay?.setPhotorealFallbackMode?.(false);\n            this._photoInfraQualityReady = false;\n            this._photoInfraResnapRequested = false;\n            // Deactivate photo building labels\n            getPhotoBuildingLabels().deactivate();\n            this.eventBus?.emit?.('photo:status', { status: 'disconnected' });\n            return;\n        }\n\n        const lifecycleGeneration = this._photoLifecycleGeneration;\n        const lifecycleInvalidated = () => (\n            lifecycleGeneration !== this._photoLifecycleGeneration\n            || !!this._cameraExclusiveState\n        );\n\n        if (this._mapPresentationMode === '2d') {\n            this._photoMapModeDeferred = true;\n            this._photoMapModeDeferredConfig = { ...photoConfig };\n            // Keep the terrain-provider contract mutually exclusive without\n            // starting the hidden provider or enabling TriTree underneath it.\n            this._setTriTreePhotorealSuppressed(true);\n            this._setOverviewGlobeVisible(false);\n            this._suspendPhotorealisticTiles();\n            return;\n        }\n\n        this._photoAltitudeSuspended = false;\n        this._setTriTreePhotorealSuppressed(true);\n        this._buildingOverlay?.setSurfaceController?.(this._surfaceController);\n        this._buildingOverlay?.setPhotorealFallbackMode?.(true);\n        // The compact overview is a loading cover only. Whether entering the\n        // surface or already in orbit, retain it until the bounded native tile\n        // traversal has a renderable provider model, then swap ownership.\n        if (this._overviewGlobeMode === true) {\n            this._photoInitializationPresentationHold = this._overviewGlobeMode === true;\n            // `_overviewGlobeMode` is the desired ownership state and is set\n            // before the mesh exists during cold boot. Materialize the clean\n            // loading globe here so a provider/session failure cannot leave a\n            // star-only frame with neither Earth renderer visible.\n            this._setOverviewGlobeVisible(true);\n        }\n\n        // Already running or still initialising. In particular, emitting the\n        // \"validating\" status below updates the settings model synchronously;\n        // without this guard, that update re-enters this async method and can\n        // start an unbounded number of provider/session initialisations.\n        if (this._photoTileLoader?.enabled || this._photoInitializationInFlight) return;\n        // A failed community pool is retried only on an explicit enable/view\n        // transition, not every status/settings notification.\n        if (this._photoSatelliteFallback && !options.explicitSurfaceEntry) return;\n\n        this._photoDeferredInitialization = false;\n        this._photoDeferredConfig = null;\n        if (!this._photoInitializationPresentationHold) {\n            this._setOverviewGlobeVisible(false);\n        }\n        this._photoInitializationInFlight = true;\n        this._photoCoverageStartedAt = performance.now();\n\n        // Infrastructure remains independently user-selectable in photoreal\n        // mode. Suppress presentation during provider attachment, then the\n        // quality gate below resnaps it to stable provider terrain and reveals\n        // it without mutating its source/category setting.\n        this._photoInfraQualityReady = false;\n        this._photoInfraResnapRequested = false;\n        this._setPhotorealInfrastructureSuppressed(true);\n\n        // Try to resume a suspended loader (same provider = instant, no re-fetch)\n        const provider = photoConfig.provider\n            || this._sceneSettings?.getSection?.('scene.terrain.photorealistic.provider')\n            || 'cesiumIon';\n        let loader;\n        try {\n            const { getPhotorealisticTileLoader } = await loadPhotorealisticTileLoaderModule();\n            loader = getPhotorealisticTileLoader();\n        } catch (err) {\n            console.error('[PlanetScene] Failed to load photorealistic tile module:', err);\n            this.eventBus?.emit?.('photo:status', { status: 'disconnected', error: err.message });\n            this._photoInitializationInFlight = false;\n            void this._enablePhotoSatelliteFallback('Photoreal terrain module unavailable');\n            return;\n        }\n        if (lifecycleInvalidated()) {\n            loader.dispose?.();\n            this._photoInitializationInFlight = false;\n            if (!this._cameraExclusiveState) {\n                queueMicrotask(() => void this._handlePhotorealisticToggle(true, photoConfig));\n            }\n            return;\n        }\n        if (loader.hasLoadedTiles && loader.loadedProvider === provider) {\n            this._photoTileLoader = loader;\n            this._connectPhotorealisticPressure(loader);\n            loader.resume();\n            if (this._mapPresentationMode === '2d') {\n                this._photoMapModeDeferred = true;\n                this._photoMapModeDeferredConfig = { ...photoConfig };\n                loader.suspend?.();\n                this._photoInitializationInFlight = false;\n                return;\n            }\n            if (this._mapPresentationMode === '2d') {\n                this._photoMapModeDeferred = true;\n                this._photoMapModeDeferredConfig = { ...photoConfig };\n                loader.suspend?.();\n                return;\n            }\n            this._reattachPhotorealisticTiles(loader, photoConfig);\n            this._photoInitializationInFlight = false;\n            return;\n        }\n\n        // Different provider or no cached tiles — full init needed.\n        // Tear down any stale loader from a different provider.\n        if (loader.hasLoadedTiles && loader.loadedProvider !== provider) {\n            this._disposePhotorealisticTiles();\n        }\n\n        const credentialId = photoConfig.credentialId\n            || this._sceneSettings?.getSection?.('scene.terrain.photorealistic.credentialId')\n            || null;\n        const apiToken = photoConfig.apiToken || null;\n\n        // Signal validating state to UI\n        this.eventBus?.emit?.('photo:status', { status: 'validating' });\n\n        try {\n            this._photoTileLoader = loader;\n            this._connectPhotorealisticPressure(loader);\n\n            // Helper: init via backend proxy when session provides a rootUrl\n            const authSvc = getAuthService();\n            const proxyFetchOpts = () => {\n                const at = authSvc.accessToken;\n                return at ? { headers: { Authorization: `Bearer ${at}` } } : {};\n            };\n\n            const proxyFallbackFor = (session, providerName = 'cesiumIon', fetchOptions = null) => {\n                if (!session?.rootUrl) return null;\n                return {\n                    rootUrl: session.rootUrl,\n                    provider: providerName,\n                    fetchOptions,\n                };\n            };\n\n            const initCesiumSession = async (session, fetchOptions = null) => {\n                const fallback = proxyFallbackFor(session, 'cesiumIon', fetchOptions);\n                if (session?.endpoint) {\n                    try {\n                        await loader.initCesiumEndpoint(session.endpoint, fallback);\n                    } catch (err) {\n                        if (!fallback?.rootUrl) throw err;\n                        console.warn('[PlanetScene] Cesium direct endpoint init failed; using proxy fallback:', err);\n                        await loader.initProxy(fallback.rootUrl, fallback.provider, fallback.fetchOptions);\n                    }\n                    return true;\n                }\n                if (fallback?.rootUrl) {\n                    await loader.initProxy(fallback.rootUrl, fallback.provider, fallback.fetchOptions);\n                    return true;\n                }\n                return false;\n            };\n\n            // Wire up callbacks before initialising. Direct Cesium BYO/community\n            // sessions start in-browser and switch to the backend proxy only\n            // after the renderer reports browser-side fetch failures.\n            loader.onProxyFallbackRequired = ({ fallback, reason }) => {\n                setTimeout(async () => {\n                    if (lifecycleInvalidated()) return;\n                    try {\n                        this.eventBus?.emit?.('photo:status', {\n                            status: 'validating',\n                            detail: 'proxy-fallback',\n                            error: reason,\n                        });\n                        await loader.initProxy(fallback.rootUrl, fallback.provider || 'cesiumIon', fallback.fetchOptions);\n                        if (lifecycleInvalidated()) {\n                            loader.dispose?.();\n                            return;\n                        }\n                        this._photoAtmosphereEffect = null;\n                        this._reattachPhotorealisticTiles(loader, photoConfig);\n                        this.eventBus?.emit?.('photo:status', {\n                            status: 'valid',\n                            source: 'proxy-fallback',\n                        });\n                    } catch (err) {\n                        console.error('[PlanetScene] Photorealistic proxy fallback failed:', err);\n                        loader.suspend?.();\n                        this._photoAltitudeSuspended = false;\n                        void this._enablePhotoSatelliteFallback('Photoreal proxy unavailable');\n                        this.eventBus?.emit?.('photo:status', {\n                            status: 'disconnected',\n                            error: err?.message || 'Proxy fallback failed',\n                        });\n                    }\n                }, 0);\n            };\n\n            // Fatal Cesium failures try the backend forwarding/cache path. TriTree\n            // stays suppressed so we do not run two terrain pipelines in parallel.\n            loader.onFatalError = (reason) => {\n                // Guard: only fire once per loader lifetime\n                if (loader._fatalFired) return;\n                loader._fatalFired = true;\n                // A rate-limited provider yields immediately to the Mapsource stack.\n                if (reason === 'rate-limited') {\n                    loader.suspend?.();\n                    void this._enablePhotoSatelliteFallback(reason);\n                    return;\n                }\n                setTimeout(async () => {\n                    if (lifecycleInvalidated()) return;\n                    console.warn(`[PlanetScene] Photorealistic tiles fatal error: ${reason}; trying backend forwarding fallback`);\n                    this._setTriTreePhotorealSuppressed(true);\n                    this.eventBus?.emit?.('photo:status', {\n                        status: 'validating',\n                        detail: 'server-fallback',\n                        error: reason,\n                    });\n                    try {\n                        const session = await this._createCommunityPhotoSession(provider);\n                        const fallback = proxyFallbackFor(session, provider);\n                        if (fallback?.rootUrl) {\n                            await loader.initProxy(fallback.rootUrl, fallback.provider, fallback.fetchOptions);\n                            if (lifecycleInvalidated()) {\n                                loader.dispose?.();\n                                return;\n                            }\n                            this._photoAtmosphereEffect = null;\n                            this._reattachPhotorealisticTiles(loader, photoConfig);\n                            this.eventBus?.emit?.('photo:status', {\n                                status: 'valid',\n                                source: 'server-fallback',\n                            });\n                            return;\n                        }\n                    } catch (err) {\n                        console.warn('[PlanetScene] Backend forwarding fallback failed:', err);\n                    }\n                    loader.suspend?.();\n                    this._photoAltitudeSuspended = false;\n                    void this._enablePhotoSatelliteFallback(reason);\n                    this.eventBus?.emit?.('photo:status', { status: 'rate-limited', error: reason });\n                }, 0);\n            };\n\n            if (provider === 'cesiumIon') {\n                const token = apiToken || getFallbackCesiumIonToken();\n                if (token) {\n                    // Direct mode — no backend caching (env var fallback)\n                    await loader.initCesiumIon(token);\n                } else if (credentialId) {\n                    // BYO session — use Cesium endpoint directly in-browser first;\n                    // retain backend forwarding/cache as a fallback root.\n                    const session = await this._createPhotoSession(credentialId, provider);\n                    if (lifecycleInvalidated()) return;\n                    if (!(await initCesiumSession(session, proxyFetchOpts()))) {\n                        if (lifecycleInvalidated()) return;\n                        console.warn('[PlanetScene] No Cesium Ion token from session');\n                        this.eventBus?.emit?.('photo:status', { status: 'disconnected', error: 'No token from session' });\n                        return;\n                    }\n                } else {\n                    // Community pool — direct browser endpoint first; proxy/cached\n                    // backend session only if the browser cannot load it.\n                    const communitySession = await this._createCommunityPhotoSession(provider);\n                    if (lifecycleInvalidated()) return;\n                    if (!(await initCesiumSession(communitySession))) {\n                        if (lifecycleInvalidated()) return;\n                        console.warn('[PlanetScene] No Cesium Ion token available (set VITE_CESIUM_ION_TOKEN, provide BYO key, or wait for community keys)');\n                        this.eventBus?.emit?.('photo:status', { status: 'disconnected', error: 'No Cesium Ion token available' });\n                        return;\n                    }\n                }\n            } else if (provider === 'google') {\n                const fallbackKey = getFallbackGoogleTilesKey();\n                if (credentialId) {\n                    await loader.initGoogleProxy(credentialId);\n                } else if (apiToken || fallbackKey) {\n                    await loader.initGoogleDirect(apiToken || fallbackKey);\n                } else {\n                    // Community pool for Google provider\n                    const communitySession = await this._createCommunityPhotoSession(provider);\n                    if (lifecycleInvalidated()) return;\n                    if (communitySession?.rootUrl) {\n                        await loader.initProxy(communitySession.rootUrl, 'google');\n                    } else {\n                        console.warn('[PlanetScene] No Google tiles key available (set VITE_GOOGLE_TILES_KEY, provide BYO key, or wait for community keys)');\n                        this.eventBus?.emit?.('photo:status', { status: 'disconnected', error: 'No Google tiles key available' });\n                        return;\n                    }\n                }\n            }\n\n            if (lifecycleInvalidated()) {\n                loader.dispose?.();\n                return;\n            }\n            this._reattachPhotorealisticTiles(loader, photoConfig);\n        } catch (err) {\n            if (!lifecycleInvalidated()) {\n                console.error('[PlanetScene] Failed to init photorealistic tiles:', err);\n            }\n            this._disposePhotorealisticTiles();\n            if (!lifecycleInvalidated()) {\n                this.eventBus?.emit?.('photo:status', { status: 'disconnected', error: err.message });\n            }\n        } finally {\n            this._photoInitializationInFlight = false;\n            if (!lifecycleInvalidated() && !this._photoTileLoader?.enabled) {\n                void this._enablePhotoSatelliteFallback('Photoreal terrain unavailable');\n            }\n            if (lifecycleInvalidated() && !this._cameraExclusiveState) {\n                const currentPhotoConfig = this._sceneSettings?.getSection?.('scene.terrain.photorealistic') || photoConfig;\n                if (currentPhotoConfig.enabled === true) {\n                    queueMicrotask(() => void this._handlePhotorealisticToggle(true, currentPhotoConfig));\n                }\n            }\n            if (this._photoSurfaceEntryPending && !this._photoTileLoader?.enabled) {\n                this._failPhotoSurfaceEntry('Terrain service is unavailable');\n            }\n        }\n    }\n\n    async _createPhotoSession(credentialId, provider = 'cesiumIon') {\n        if (!credentialId) return null;\n        const warm = takeWarmPhotorealSession({ provider, credentialId });\n        if (warm) return warm;\n        try {\n            const authSvc = getAuthService();\n            const resp = await authSvc.authenticatedFetch(`${getBackendApiBase()}/earth/photorealistic/session`, {\n                method: 'POST',\n                body: JSON.stringify({ credential_id: credentialId }),\n            });\n            if (!resp.ok) return null;\n            const data = await resp.json();\n            const session = data.session || data;\n            rememberWarmPhotorealSession(session, { provider, credentialId });\n            return session;\n        } catch (err) {\n            console.warn('[PlanetScene] Photo session creation failed:', err);\n            return null;\n        }\n    }\n\n    /**\n     * Request a community-pool session from the backend.\n     * No auth required — the backend picks a random community-shared credential.\n     */\n    async _createCommunityPhotoSession(provider) {\n        const warm = takeWarmPhotorealSession({ provider });\n        if (warm) return warm;\n        try {\n            const resp = await getNoclipGovernanceClient().request(`${getBackendApiBase()}/earth/photorealistic/community/session`, {\n                method: 'POST',\n                governanceLane: 'scene',\n                headers: { 'Content-Type': 'application/json' },\n                body: JSON.stringify({ provider }),\n            });\n            if (!resp.ok) return null;\n            const data = await resp.json();\n            const session = data.session || data;\n            rememberWarmPhotorealSession(session, { provider });\n            return session;\n        } catch (err) {\n            console.warn('[PlanetScene] Community photo session failed:', err);\n            return null;\n        }\n    }\n\n    /**\n     * Wire up a (new or resumed) photorealistic tile loader to the scene:\n     * scene graph, surface controller, overlays, atmosphere, wireframe.\n     */\n    _reattachPhotorealisticTiles(loader, photoConfig = {}) {\n        if (this._cameraExclusiveState) {\n            loader?.dispose?.();\n            if (this._photoTileLoader === loader) this._photoTileLoader = null;\n            return false;\n        }\n        // Add to planet group so tiles inherit axial tilt + daily rotation.\n        if (!loader.group.parent) {\n            const planetGroup = this._triTree?.group;\n            if (planetGroup) {\n                planetGroup.add(loader.group);\n            } else if (this._worldRoot) {\n                this._worldRoot.add(loader.group);\n            } else {\n                this._scene?.add(loader.group);\n            }\n        }\n\n        // Photoreal and TriTree are mutually exclusive terrain systems. The\n        // boot overlay owns cold-start coverage; no TriTree geometry is ever\n        // rendered underneath the photoreal parent/child hierarchy.\n        this._setTriTreePhotorealSuppressed(true);\n        // Surface/context residency follows the authoritative interaction\n        // mode. Using camera radius alone makes terrain elevation consume the\n        // 2.5 km threshold: at ~1.2 km MSL, only ~1.3 km AGL remains before\n        // the loader mistakenly applies its orbit depth/cache budget.\n        loader.setCameraModeProvider?.(\n            () => this._surfaceController?.getCameraMode?.()\n                || this._surfaceController?.cameraMode\n                || 'orbit'\n        );\n        const holdForTileCoverage = this._photoSatelliteFallback === true\n            || (this._photoInitializationPresentationHold === true && this._overviewGlobeMode === true);\n        loader.setPresentationEnabled?.(!holdForTileCoverage);\n        if (!holdForTileCoverage) {\n            this._setOverviewGlobeVisible(false);\n        }\n\n        // Enable terrain raycasting against photorealistic tiles for camera altitude\n        if (this._surfaceController) this._surfaceController.photoTileGroup = loader.group;\n        this._buildingOverlay?.setSurfaceController?.(this._surfaceController);\n        this._buildingOverlay?.setPhotorealFallbackMode?.(true);\n        this._buildingOverlay?.refreshTerrainAnchors?.([{\n            global: true,\n            source: 'photoreal',\n            reason: 'provider-attached',\n        }]);\n        if (this._surfaceController?.cameraMode === 'surface'\n            || this._surfaceController?.cameraMode === 'toSurface') {\n            // Provider/session initialization is asynchronous. The pending\n            // focus direction was captured in world space before that work\n            // began, while Earth and the controller's landing endpoint keep\n            // rotating. Reusing the snapshot can move the 250 m contact OBB\n            // completely off the live camera before the first traversal.\n            // surfaceState.up is the same landing direction advanced by\n            // applyEarthRotation(), so hand the loader the current world-space\n            // target when it finally attaches.\n            loader.primeSurfaceFocus?.(\n                this._photoSurfaceEntryPending?.reason || 'reattach-surface',\n                this._getLivePhotoSurfaceFocusDirection()\n            );\n        }\n        loader.forceNextUpdate?.();\n\n        // Tell the infrastructure overlay to forget its prior TriTree-only\n        // samples. The controller switch explicitly queues existing entries;\n        // subsequent updates are driven only by regional photo-tile changes.\n        if (this._infrastructureOverlay?.setSurfaceController) {\n            this._infrastructureOverlay.setSurfaceController(this._surfaceController);\n        }\n        this._photoInfraQualityReady = false;\n        this._photoInfraResnapRequested = false;\n        this._setPhotorealInfrastructureSuppressed(true);\n\n        // Building augmentation is intentionally dormant in photoreal mode,\n        // including its OSM label/raycast worker. TriTree's BuildingOverlay\n        // supplies both geometry and labels when that provider is selected.\n        getPhotoBuildingLabels().deactivate();\n\n        // Inject atmosphere effects (night, clouds, light pollution, specular)\n        const earthUniforms = this._sceneInitializer?.earthMaterial?.uniforms;\n        if (earthUniforms && !this._photoAtmosphereEffect) {\n            const atmEffect = new PhotoAtmosphereEffect(earthUniforms);\n            loader.setAtmosphereEffect(atmEffect);\n            this._photoAtmosphereEffect = atmEffect;\n        }\n\n        // If wireframe mode is already active, apply the same flat/outline\n        // style to this newly initialized hierarchy.\n        const wireframeActive = this._triTree?.renderRules?.wireframe ?? false;\n        if (wireframeActive) {\n            const rs = this._wireframeStyleResolved || {};\n            loader.setWireframeMode(true, {\n                surfaceColor: rs.surfaceColor,\n                lineColor: rs.lineColor,\n            });\n        }\n\n        // Signal connected to UI\n        this.eventBus?.emit?.('photo:status', { status: 'valid' });\n    }\n\n    _getPhotorealContactWorldPosition() {\n        // The camera is parented beneath the rotating world root. `position`\n        // is therefore parent-relative and cannot be used to raycast ECEF tile\n        // geometry. In XR the tracked eye additionally moves inside the room;\n        // contact must use the stable navigation anchor or that room offset is\n        // applied a second time when the dolly is recomposed.\n        const stableXRContact = this._surfaceController?.getPhotorealContactWorldPosition?.(\n            this._photoContactWorldPosition\n                || (this._photoContactWorldPosition = new THREE.Vector3())\n        );\n        if (stableXRContact?.lengthSq?.() > 0) return stableXRContact;\n        // AnimationLoop publishes the authoritative non-XR world position.\n        return this._camera?.userData?.worldPosition || this._camera?.position;\n    }\n\n    _getFreshPhotorealUnderfootState(\n        worldPosition = this._getPhotorealContactWorldPosition()\n    ) {\n        const visibleState = this._surfaceController?.getPhotorealUnderfootState?.(\n            worldPosition, { providerOnly: true }\n        ) || {\n            ready: false,\n            reason: 'underfoot-branch-loading',\n            radius: null,\n        };\n        if (!this._photoTileLoader?._bootUnderfootFocusActive) {\n            return visibleState;\n        }\n\n        // A focused descendant can be fully downloaded, normal-processed, and\n        // raycastable while native REPLACE keeps it detached until unrelated\n        // siblings finish. During the boot-covered contact phase only, accept\n        // that exact center mesh so the broader primary-view wave does not\n        // gate the physical floor. Normal gameplay continues to require the\n        // currently renderable surface above.\n        const focusedState = this._photoTileLoader.getFocusedLoadedUnderfootState?.(\n            this._surfaceController?.surfaceState?.up || worldPosition\n        );\n        // A coarse visible ancestor can already produce a valid hit while the\n        // exact focused descendant beneath the camera has finished parsing but\n        // awaits sibling replacement. Prefer that descendant immediately so\n        // the physical floor follows the upgraded geometry, not the parent.\n        // Resolve physics as soon as the finest leaf parses, but reveal it\n        // only after native REPLACE/fade presents the same physical surface.\n        // Otherwise the camera can stand on the child beneath a still-visible\n        // coarse parent. This is a native handoff condition, not a delay.\n        if (focusedState?.ready) return {\n            ...focusedState,\n            presentationReady: visibleState.ready === true\n                && Math.abs(visibleState.radius - focusedState.radius) <= 0.1,\n        };\n        return focusedState || visibleState;\n    }\n\n    _updatePhotorealisticTiles() {\n        this._photoSatelliteTerrain?.update(this._camera, this._lightingSystem?.sunDirection);\n        if (!this._photoSatelliteFallback && this._photoCoverageStartedAt\n            && performance.now() - this._photoCoverageStartedAt > 10000\n            && this._photoInitializationPresentationHold) {\n            void this._enablePhotoSatelliteFallback('Photoreal terrain is still loading');\n        }\n        const surfaceModeActive = this._surfaceController?.cameraMode === 'surface'\n            || this._surfaceController?.cameraMode === 'toSurface';\n        if (this._photoSurfaceEntryPending && !surfaceModeActive) {\n            this._cancelPhotoSurfaceEntry();\n        }\n        if (!this._photoTileLoader) {\n            if (this._photoDeferredInitialization\n                && !this._photoInitializationInFlight\n                && !this._shouldDeferPhotorealisticInitialization()) {\n                const photoConfig = this._photoDeferredConfig || {};\n                this._photoDeferredInitialization = false;\n                this._photoDeferredConfig = null;\n                void this._handlePhotorealisticToggle(true, photoConfig);\n            }\n            return;\n        }\n        if (!this._photoTileLoader.enabled) return;\n        const walkingContactProbe = this._surfaceController?.isSurfaceWalkingTopologyActive;\n        const walkingPhotoContactActive = this._surfaceController?.cameraMode === 'toSurface'\n            || (typeof walkingContactProbe === 'function'\n                ? walkingContactProbe.call(this._surfaceController) === true\n                : (this._surfaceController?.cameraMode === 'surface'\n                    && (!Number.isFinite(this._surfaceController?.surfaceAltitudeMeters)\n                        || this._surfaceController.surfaceAltitudeMeters <= 8)));\n        let contactReleasedBeforeTraversal = false;\n\n        if (this._surfaceController?.cameraMode === 'surface'\n            && this._photoTileLoader._bootUnderfootFocusActive) {\n            // The final URL/camera placement can settle after the async tile\n            // provider attached. Follow that authoritative live position\n            // without restarting the native refinement epoch.\n            this._photoTileLoader.syncBootUnderfootFocus?.(\n                this._surfaceController.surfaceState?.up\n            );\n        }\n\n        // Release a proven contact branch BEFORE this frame's single native\n        // traversal. Releasing after update leaves an unchanged camera with a\n        // contact-only selection: UpdateOnChangePlugin then correctly skips a\n        // redundant frame and the boot gate never receives primary coverage.\n        // The strict ray hit and exact camera-floor adoption still happen\n        // before release, so this ordering cannot reveal or traverse without\n        // a verified physical surface.\n        if (surfaceModeActive && this._photoTileLoader._bootUnderfootFocusActive) {\n            const contactWorldPosition = this._getPhotorealContactWorldPosition();\n            const underfoot = this._getFreshPhotorealUnderfootState(\n                contactWorldPosition\n            );\n            if (underfoot?.ready\n                && this._surfaceController.adoptPhotorealUnderfootRadius?.(\n                    underfoot.radius,\n                    contactWorldPosition,\n                    { walkableVerified: false }\n                )) {\n                if (underfoot.presentationReady !== false) {\n                    this._photoTileLoader.releaseBootUnderfootFocus?.();\n                    contactReleasedBeforeTraversal = true;\n                }\n            }\n        }\n        // Lazy-create atmosphere effect if earthMaterial wasn't ready during attach\n        if (!this._photoAtmosphereEffect) {\n            const earthUniforms = this._sceneInitializer?.earthMaterial?.uniforms;\n            if (earthUniforms) {\n                const atmEffect = new PhotoAtmosphereEffect(earthUniforms);\n                this._photoTileLoader.setAtmosphereEffect(atmEffect);\n                this._photoAtmosphereEffect = atmEffect;\n            }\n        }\n        if (this._photoAtmosphereEffect) {\n            this._photoAtmosphereEffect.update(this._triTree?.group);\n        }\n        if (this._wireframeActive && this._lightingSystem?.sunDirection) {\n            this._photoTileLoader.setWireframeSunDirection?.(\n                this._lightingSystem.sunDirection\n            );\n        }\n        // adoptPhotorealUnderfootRadius() may have re-applied the surface\n        // camera above a newly arrived child LOD after AnimationLoop published\n        // its logical pose. Refresh before native traversal so the tile system\n        // and renderer can never operate on different camera altitudes.\n        this._animationLoop?.syncCameraWorldPosition?.();\n        this._photoTileLoader.update(this._camera, this._renderer);\n        const terrainSurfaceChanges = this._photoTileLoader.consumeTerrainSurfaceChanges?.() || [];\n        if (terrainSurfaceChanges.length > 0) {\n            this._refreshSurfaceAnchorsForTerrainChanges(terrainSurfaceChanges);\n        }\n        const modelSeq = this._photoTileLoader._modelChangeSeq | 0;\n        const photoGeometryChanged = modelSeq !== this._lastPhotoModelSeq;\n        // A deferred orbit boot can attach the photoreal provider only after\n        // the user begins entering surface mode. Advance the focused underfoot\n        // handoff here as part of the normal render loop: once a fresh center\n        // mesh exists, make it the camera's physical floor immediately. Keep\n        // the contact focus until the next frame, when the pre-traversal block\n        // above releases it and the same native update can fill the primary\n        // view. This is also safe during cold boot; the HTML boot gate still\n        // waits for primary-view coverage before revealing the scene.\n        // This probe also runs on every near-surface model change after boot.\n        // Tile traversal happens after normal camera placement, so without a\n        // same-frame contact update a newly loaded child can render over the\n        // eye for one frame. Geometry changes are asynchronous and sparse;\n        // the bounded centre ray is never performed as a general frame task.\n        if (!contactReleasedBeforeTraversal\n            && surfaceModeActive\n            && (this._photoTileLoader._bootUnderfootFocusActive\n                || (photoGeometryChanged && walkingPhotoContactActive))) {\n            const contactWorldPosition = this._getPhotorealContactWorldPosition();\n            const bootContact = this._photoTileLoader._bootUnderfootFocusActive === true;\n            const underfoot = bootContact\n                ? this._getFreshPhotorealUnderfootState(contactWorldPosition)\n                : null;\n            if ((bootContact && underfoot?.ready) || !bootContact) {\n                const adopted = bootContact\n                    ? this._surfaceController.adoptPhotorealUnderfootRadius?.(\n                        underfoot.radius,\n                        contactWorldPosition,\n                        { walkableVerified: false }\n                    )\n                    : this._surfaceController.refreshPhotorealWalkableContact?.(\n                        contactWorldPosition\n                    );\n                if (adopted) {\n                    // This adoption happens after the frame's ordinary camera\n                    // publication. Republish the corrected physical pose now;\n                    // otherwise consumers retain the old logical world radius\n                    // until another input/frame, which made drag appear to be\n                    // the only reliable altitude correction.\n                    this._animationLoop?.syncCameraWorldPosition?.();\n                }\n                // Camera safety is immediate; focus release is deliberately\n                // deferred to the next frame's pre-traversal handoff above.\n            }\n        }\n        // The exact focused centre hit is only the boot safety skin; it may be\n        // a roof or canopy. Once that focus has been released and the normal\n        // primary traversal has attached surrounding geometry, immediately\n        // fit the bounded exterior rings and establish pedestrian ground.\n        // Failed fits remain pending and retry only on a later model change,\n        // avoiding nine-ray work in the ordinary render loop.\n        if (contactReleasedBeforeTraversal\n            && walkingPhotoContactActive\n            && this._surfaceController?.needsPhotorealWalkableCalibration?.()) {\n            const contactWorldPosition = this._getPhotorealContactWorldPosition();\n            if (this._surfaceController.refreshPhotorealWalkableContact?.(\n                contactWorldPosition\n            )) {\n                this._animationLoop?.syncCameraWorldPosition?.();\n            }\n        }\n        if (photoGeometryChanged\n            && walkingPhotoContactActive\n            && this._surfaceController?.enforceSurfaceFloor?.({ useSample: true })) {\n            // Native traversal can attach a higher child after the ordinary\n            // camera pass. Resolve contact before that child reaches desktop,\n            // mobile or either XR eye; DOM labels must share the corrected pose.\n            this._animationLoop?.syncCameraWorldPosition?.();\n        }\n        // Photoreal tiles stream/refine asynchronously. The atmosphere depth\n        // pre-pass (which the aurora/clouds occlude against) is throttled to\n        // camera motion, so newly loaded tiles would otherwise be missing from\n        // the depth texture and the aurora would bleed through them while the\n        // view is settled. Invalidate the depth whenever tile geometry changed.\n        if (photoGeometryChanged) {\n            // A DA3 item can be created after the regional visibility event\n            // that introduced its first usable tile. Wake only the bounded\n            // pending/held anchor index on this sparse native model sequence;\n            // never restore a periodic whole-overlay terrain sweep.\n            this._overlaySubsystem?.refreshPendingTerrainPositions?.({\n                cause: 'photo-model-change',\n                sequence: modelSeq,\n            });\n            this._lastPhotoModelSeq = modelSeq;\n            this._sceneInitializer?.markAtmosphereDepthDirty?.();\n        }\n        this._updatePhotoOverviewHandoff(surfaceModeActive);\n        this._updatePhotoSurfaceEntryHandoff(surfaceModeActive);\n        const now = typeof performance !== 'undefined' && typeof performance.now === 'function'\n            ? performance.now()\n            : Date.now();\n        if (!this._lastPhotoTileTelemetryAt || now - this._lastPhotoTileTelemetryAt > 650) {\n            this._lastPhotoTileTelemetryAt = now;\n            const telemetry = this._photoTileLoader.getTileTelemetry?.();\n            if (telemetry) {\n                this.eventBus?.emit?.('photo:telemetry', telemetry);\n            }\n        }\n    }\n\n    _refreshSurfaceAnchorsForTerrainChanges(changes) {\n        if (!Array.isArray(changes) || changes.length === 0) return;\n        // Refresh both terrain roots once, then every affected owner samples\n        // with skipWorldMatrixUpdate:true. This keeps a tile handoff immediate\n        // without recursively updating the photoreal hierarchy per label.\n        this._surfaceController?.prepareTerrainSamplingBatch?.();\n        this._incidentOverlay?.refreshTerrainAnchors?.(changes);\n        this._addressHoverOverlay?.refreshTerrainAnchors?.(changes);\n        this._routeRibbon?.refreshTerrainAnchors?.(changes);\n        this._placeSearchSurface?.refreshTerrainAnchors(changes);\n        this._roadTrafficOverlay?.refreshTerrainAnchors?.(changes);\n        this._trafficCameraOverlay?.refreshTerrainAnchors?.(changes);\n        this._sensorOverlay?.refreshTerrainAnchors?.(changes);\n        this._radioDataOverlay?.refreshTerrainAnchors?.(changes);\n        this._geocacheLayer?.refreshTerrainAnchors?.(changes);\n        this._meshtasticOverlay?.refreshTerrainAnchors?.(changes);\n        this._environmentalOverlay?.refreshTerrainAnchors?.(changes);\n        this._buildingOverlay?.refreshTerrainAnchors?.(changes);\n        this._overlaySubsystem?.refreshTerrainPositions?.(changes);\n        this._infrastructureOverlay?.refreshTerrainAnchors?.(changes);\n        this._openInfraMapRenderer?.refreshTerrainAnchors?.(changes);\n        getBusinessLabels().refreshTerrainAnchors?.(changes);\n        getPhotoBuildingLabels().refreshTerrainAnchors?.(changes);\n        this._fieldAssetLayer?.refreshTerrainAnchors?.(changes);\n        this._accountNoteLayer?.refreshTerrainAnchors?.(changes);\n    }\n\n    _shouldDeferPhotorealisticInitialization() {\n        const observer = this._camera?.userData?.worldPosition || this._camera?.position;\n        const distance = observer?.length?.();\n        // Provider initialization is now altitude-independent. High-orbit\n        // traversal is protected inside PhotorealisticTileLoader by a depth-1,\n        // low-resolution, low-concurrency budget, so the overview is needed\n        // only until that photoreal coverage is ready.\n        return !Number.isFinite(distance);\n    }\n\n    _shouldDeferLocalVisualStreaming() {\n        if (this._photoSatelliteFallback) return false;\n        if (this._deferredVisualStreamingReady) return false;\n        if (this._photoInitializationInFlight\n            || this._photoDeferredInitialization\n            || this._photoTileLoader?.enabled) {\n            return true;\n        }\n        const terrain = this._sceneSettings?.getSection?.('scene.terrain') || {};\n        return terrain.tileSource === 'quadtree'\n            || terrain.photorealistic?.enabled === true;\n    }\n\n    _setOverviewGlobeVisible(visible) {\n        const overview = visible === true;\n        this._overviewGlobeMode = overview;\n        // RENDER OWNERSHIP INVARIANT: unlike July 19's real terrain, the\n        // standalone overview globe does not provide a valid atmosphere\n        // compositor G-buffer. Select its direct atmosphere path by content,\n        // never by an altitude threshold; otherwise lighting visibly changes\n        // at the threshold while the camera rises through a continuous orbit.\n        this._sceneInitializer?.setAtmosphereOrbitalOverviewActive?.(overview);\n        // The overview owns only a transient loading presentation. Night-light\n        // data remains shared as an irradiance input across the handoff and is\n        // never displayed as replacement Earth imagery.\n        if (overview) {\n            this._sceneInitializer?.setOrbitalOverviewStreamingEnabled?.(true);\n            this._sceneInitializer?.setEarthOverlayStreamingEnabled?.(false);\n            void this._ensureOverviewDayTexture();\n        } else {\n            const deferLocalVisualStreaming = this._shouldDeferLocalVisualStreaming();\n            this._sceneInitializer?.setEarthOverlayStreamingEnabled?.(\n                !deferLocalVisualStreaming\n            );\n            // Keep the lightweight cloud/night field leased until the full\n            // photoreal visual stack is allowed to stream. Turning both owners\n            // off here disposed the cloud map exactly at the overview handoff,\n            // producing a one-frame flash followed by a clear globe.\n            this._sceneInitializer?.setOrbitalOverviewStreamingEnabled?.(\n                deferLocalVisualStreaming\n            );\n            this._releaseOverviewDayTexture();\n        }\n        const terrainImageryEnabled = this._sceneSettings?.getSection?.('scene.terrain.imagery.enabled') === true;\n        // Lunar imagery is a compact celestial asset, not part of the local\n        // Earth surface stack. Overview mode must not strip the Moon's albedo\n        // and displacement maps while the body remains visible.\n        this._moonSystem?.setImageryEnabled?.(terrainImageryEnabled);\n        this._syncGeoJsonOverlayVisibility();\n        if (!overview && !this._shouldDeferLocalVisualStreaming()) {\n            this._scheduleOceanResolverSetup();\n        }\n        const triTreeGroup = this._triTree?.group;\n        if (!triTreeGroup) return;\n        if (!this._overviewGlobe) {\n            const geometry = new THREE.SphereGeometry(PLANET_RADIUS, 96, 48);\n            const material = createOrbitalEarthMaterial(this._getOverviewGlobeUniforms());\n            const globe = new THREE.Mesh(geometry, material);\n            globe.name = 'OverviewGlobeFallback';\n            globe.renderOrder = -2;\n            globe.frustumCulled = true;\n            triTreeGroup.add(globe);\n            this._overviewGlobe = globe;\n        }\n        this._overviewGlobe.visible = visible === true;\n    }\n\n    _disposeOverviewGlobe() {\n        this._overviewGlobeMode = false;\n        // Image acquisition can precede creation of the cover mesh. Always\n        // cancel/retire that owner, including early init failure/disposal.\n        this._releaseOverviewDayTexture();\n        const globe = this._overviewGlobe;\n        if (!globe) return;\n        globe.parent?.remove(globe);\n        globe.geometry?.dispose?.();\n        if (Array.isArray(globe.material)) {\n            globe.material.forEach((material) => material?.dispose?.());\n        } else {\n            globe.material?.dispose?.();\n        }\n        this._overviewGlobe = null;\n    }\n\n    _refreshOverviewGlobeMaterial() {\n        const globe = this._overviewGlobe;\n        if (!globe) return;\n        const previous = globe.material;\n        globe.material = createOrbitalEarthMaterial(this._getOverviewGlobeUniforms());\n        previous?.dispose?.();\n    }\n\n    _getOverviewGlobeUniforms() {\n        this._overviewDayTextureUniform ||= { value: this._overviewDayTexture || null };\n        this._overviewDayTextureEnabledUniform ||= { value: this._overviewDayTexture ? 1 : 0 };\n        return {\n            ...(this._sceneInitializer?.earthMaterial?.uniforms || {}),\n            orbitalDayTexture: this._overviewDayTextureUniform,\n            orbitalDayTextureEnabled: this._overviewDayTextureEnabledUniform,\n        };\n    }\n\n    _ensureOverviewDayTexture() {\n        // RENDERER OWNERSHIP INVARIANT: this is a standalone overview asset.\n        // Never source this mesh from TriTree, never leave it underneath\n        // photoreal tiles, and never make surface boot depend on this request.\n        // See AGENTS.md \"Orbital and surface renderer ownership\".\n        if (typeof document === 'undefined') return Promise.resolve(null);\n        this._overviewDayTextureUniform ||= { value: null };\n        this._overviewDayTextureEnabledUniform ||= { value: 0 };\n        if (this._overviewDayTexture) return Promise.resolve(this._overviewDayTexture);\n        if (this._overviewDayTexturePromise) return this._overviewDayTexturePromise;\n        const generation = this._overviewDayTextureGeneration;\n        this._overviewImageSource ||= new OverviewImageSource();\n        const promise = this._overviewImageSource.acquire().then((image) => {\n            const stillWanted = generation === this._overviewDayTextureGeneration\n                && this._overviewGlobeMode === true;\n            if (!image || !stillWanted) return null;\n            const texture = new THREE.Texture(image);\n            texture.name = 'OverviewEarthDay';\n            texture.colorSpace = THREE.SRGBColorSpace;\n            texture.wrapS = THREE.RepeatWrapping;\n            texture.wrapT = THREE.ClampToEdgeWrapping;\n            // Preserve north-up orientation and the original full-resolution\n            // mip chain. Bitmap decode applies this flip before WebGL upload;\n            // the owned HTML compatibility source uses the ordinary GPU flip.\n            texture.flipY = true;\n            texture.anisotropy = Math.min(4, this._renderer?.capabilities?.getMaxAnisotropy?.() || 1);\n            texture.needsUpdate = true;\n            this._overviewDayTexture = texture;\n            this._overviewDayTextureUniform.value = texture;\n            this._overviewDayTextureEnabledUniform.value = 1;\n            return texture;\n        }).catch((error) => {\n            console.warn('[PlanetScene] Overview day texture failed to load', error);\n            return null;\n        }).finally(() => {\n            if (this._overviewDayTexturePromise === promise) {\n                this._overviewDayTexturePromise = null;\n            }\n        });\n        this._overviewDayTexturePromise = promise;\n        return promise;\n    }\n\n    _releaseOverviewDayTexture() {\n        this._overviewDayTextureGeneration++;\n        const texture = this._overviewDayTexture;\n        this._overviewDayTexture = null;\n        this._overviewDayTextureUniform ||= { value: null };\n        this._overviewDayTextureEnabledUniform ||= { value: 0 };\n        this._overviewDayTextureUniform.value = null;\n        this._overviewDayTextureEnabledUniform.value = 0;\n        this._overviewDayTexturePromise = null;\n        // No rendered uniform may reference a closed bitmap. Retire GPU state\n        // first, then close decoded pixels and cancel pending acquisition.\n        try { texture?.dispose?.(); }\n        finally { this._overviewImageSource?.release(); }\n    }\n\n    _setPhotorealInfrastructureSuppressed(suppressed) {\n        const next = suppressed === true;\n        this._photoInfraSuppressed = next;\n        // Always propagate. Either renderer may be attached after the state\n        // changed, and an early return would let that late renderer bypass the\n        // provider-quality/resnap hold.\n        this._openInfraMapRenderer?.setRenderSuppressed?.(next);\n        this._infrastructureOverlay?.setRenderSuppressed?.(next);\n    }\n\n    _shouldRunPhotorealSemanticLabels() {\n        if (!this._photoTileLoader?.enabled) return false;\n        if (this._photoInfraSuppressed) return false;\n        if (!this._photoInfraQualityReady) return false;\n        if (this._surfaceController?.isInSurfaceMode?.() === false) return false;\n        const quality = this._photoInfraQuality;\n        return quality?.ready === true;\n    }\n\n    _shouldRunSurfaceBusinessLabels(observerPos = null) {\n        if (!this._surfaceController?.isInSurfaceMode?.()) return false;\n        const agl = this._surfaceController?.getSurfaceAltitudeMeters?.();\n        if (Number.isFinite(agl)) return agl <= 12000;\n        if (observerPos?.isVector3) {\n            const altitude = observerPos.length() - (this._sceneInitializer?.planetRadius || PLANET_RADIUS);\n            return !Number.isFinite(altitude) || altitude <= 14000;\n        }\n        return true;\n    }\n\n    _updatePhotorealInfrastructureGate() {\n        const photoActive = !!this._photoTileLoader?.enabled;\n        if (!photoActive) {\n            this._photoInfraQuality = null;\n            this._photoInfraQualityReady = false;\n            this._photoInfraResnapRequested = false;\n            this._buildingOverlay?.setPhotorealSurfaceQualityReady?.(false);\n            this._setPhotorealInfrastructureSuppressed(false);\n            return;\n        }\n\n        const quality = this._photoTileLoader.getSurfaceQuality?.({\n            // Utility and classic infrastructure sample the actual provider\n            // hierarchy at every rendered vertex. One stable visible tile is\n            // therefore sufficient to begin a partial, correctly mated\n            // reveal; waiting for a globally drained refinement queue can\n            // suppress infrastructure forever in an actively moving view.\n            mode: 'coarse',\n            stableMs: 250,\n            minVisibleTiles: 1,\n        })\n            || { ready: false, reason: 'no-quality-api' };\n        this._photoInfraQuality = quality;\n        this._buildingOverlay?.setPhotorealSurfaceQualityReady?.(\n            hasPhotorealBuildingProbeSurface(quality)\n        );\n\n        if (!quality.ready) {\n            // Surface-quality readiness is a one-way reveal for the current\n            // provider session. Camera movement makes the native replacement\n            // queue temporarily non-ready; hiding an already mated overlay on\n            // those dips produced the visible utility \"flap\". Keep its last\n            // Earth-fixed representation visible while photoreal tiles refine.\n            this._setPhotorealInfrastructureSuppressed(!this._photoInfraQualityReady);\n            return;\n        }\n\n        if (!this._photoInfraQualityReady) {\n            this._photoInfraQualityReady = true;\n            this._photoInfraResnapRequested = false;\n        }\n\n        if (!this._photoInfraResnapRequested) {\n            this._photoInfraResnapRequested = true;\n            this._openInfraMapRenderer?.forceTerrainResnap?.();\n            this._infrastructureOverlay?.forceTerrainResnap?.();\n        }\n        // Each renderer swaps mated geometry atomically. Never hide the whole\n        // overlay while those bounded first-provider resnaps drain.\n        this._setPhotorealInfrastructureSuppressed(false);\n    }\n\n    /**\n     * Suspend photorealistic tiles — hides and stops updates but keeps\n     * GPU resources alive so switching back is instant (no re-fetch).\n     */\n    _suspendPhotorealisticTiles() {\n        if (this._surfaceController) {\n            this._surfaceController.photoTileGroup = null;\n            this._surfaceController._photoTerrainRadius = null;\n        }\n        this._photoAtmosphereEffect = null;\n        getPhotoBuildingLabels().deactivate();\n        if (this._photoTileLoader) {\n            this._photoTileLoader.suspend();\n        }\n    }\n\n    /**\n     * Connect the independently loaded photoreal tile manager to the shared\n     * scene governor. The loader often appears after init(), so this cannot be\n     * a one-time constructor dependency.\n     */\n    _connectPhotorealisticPressure(loader) {\n        this._budgetGovernor?.setPhotogrammetryManager?.(loader || null);\n        // Poll one owned scalar, never scan native models in the render loop.\n        // Replacing/clearing the provider also fences old asynchronous recovery.\n        this._sceneInitializer?.setRenderReadinessProvider?.(loader\n            ? () => loader.isImageRecoveryReady?.() !== false : null);\n    }\n\n    /**\n     * A recoverable WebGL loss is the browser's strongest GPU-pressure signal.\n     * Immediately shed optional caches while SceneInitializer parks rendering;\n     * otherwise restoration simply rebuilds the same overloaded scene.\n     */\n    _installWebglPressureHandlers() {\n        if (this._webglContextLostHandler || typeof document === 'undefined') return;\n        this._webglContextLostHandler = () => {\n            try { getLabelSystem().applyMemoryPressure?.(1); } catch { /* labels optional */ }\n            this._geoJsonLayer?.applyMemoryPressure?.(1);\n            this._elevationClient?.applyMemoryPressure?.(1);\n            this._triTree?.applyMemoryPressure?.(1);\n            this._photoTileLoader?.handleContextLoss?.();\n        };\n        document.addEventListener('noclip:webglcontextlost', this._webglContextLostHandler);\n    }\n\n    _removeWebglPressureHandlers() {\n        if (!this._webglContextLostHandler || typeof document === 'undefined') return;\n        document.removeEventListener('noclip:webglcontextlost', this._webglContextLostHandler);\n        this._webglContextLostHandler = null;\n    }\n\n    /**\n     * Fully destroy photorealistic tiles — releases all GPU resources.\n     * Used on scene dispose, NOT on tile-source switching.\n     */\n    _disposePhotorealisticTiles() {\n        this._clearPhotoSatelliteFallback();\n        if (this._surfaceController) {\n            this._surfaceController.photoTileGroup = null;\n            this._surfaceController._photoTerrainRadius = null;\n        }\n        this._photoAtmosphereEffect = null;\n        this._connectPhotorealisticPressure(null);\n        if (this._photoTileLoader) {\n            const loader = this._photoTileLoader;\n            if (this._photoTileLoader.group.parent) {\n                this._photoTileLoader.group.parent.remove(this._photoTileLoader.group);\n            }\n            this._photoTileLoader = null;\n            // Release the live WebGL resources synchronously. The module-level\n            // destroy below only clears singleton ownership and is safe after\n            // this idempotent disposal.\n            loader.dispose?.();\n            loadPhotorealisticTileLoaderModule()\n                .then(({ destroyPhotorealisticTileLoader }) => {\n                    destroyPhotorealisticTileLoader?.();\n                })\n                .catch((err) => {\n                    console.warn('[PlanetScene] Photorealistic tile disposal failed:', err);\n                    loader?.dispose?.();\n                });\n        }\n        this._photoAltitudeSuspended = false;\n    }\n\n    _setTriTreePhotorealSuppressed(suppressed) {\n        if (!this._triTree) return;\n        const next = !!suppressed;\n        this._triTree.suppressTileDisplay = next;\n        this._triTree.suspended = next;\n        // This is a resource gate, not visibility suppression. It aborts\n        // requests, cancels builders and disposes generated geometry on exit.\n        const terrainMode = next || this._photoSatelliteFallback ? 'quadtree' : 'tritree';\n        this._buildingOverlay?.setTerrainMode?.(terrainMode);\n        this._infrastructureOverlay?.setTerrainMode?.(terrainMode);\n        if (next) {\n            this._buildingAutoRequestSeq += 1;\n            this._buildingAutoRequestKey = null;\n            this._buildingAutoCenter = null;\n            this._infrastructureAutoCenter = null;\n        }\n        // TriTree and RAW ELEVATION now share the exact Mapzen Float32\n        // GeoTIFF pyramid. Photoreal mode suspends this regional sampler with\n        // TriTree instead of continuing to feed the retired point endpoint.\n        this._elevationClient?.setMapzenRasterTilesEnabled?.(!next);\n        if (!next && !this._photoSatelliteFallback) {\n            // TriTree contains no provider buildings. Its OSM-derived building\n            // layer is therefore a required automatic companion, not an\n            // independent opt-in left over from photoreal mode.\n            this._buildingAutoEnabled = true;\n            const config = { enabled: true, photorealFallbackEnabled: false };\n            this._buildingOverlay?.applyConfig?.(config);\n            this.eventBus?.emit?.('buildings:config', config);\n        }\n    }\n\n    _applyTuneables(partial = {}) {\n        if (!partial || typeof partial !== 'object') return;\n\n        const rendererOpts = partial.renderer || {};\n        if (Number.isFinite(rendererOpts.renderScale)) {\n            if (this.uiController && typeof this.uiController.applyRenderScale === 'function') {\n                this.uiController.applyRenderScale(rendererOpts.renderScale);\n            } else if (this._sceneInitializer?.setRenderScale) {\n                this._sceneInitializer.setRenderScale(rendererOpts.renderScale);\n            }\n        }\n\n        if (rendererOpts.autoRenderScale) {\n            this._animationLoop?.setAutoRenderScaleEnabled(false);\n        }\n\n        if (Number.isFinite(rendererOpts.renderCadenceMs)) {\n            this._animationLoop?.setRenderCadenceMs?.(rendererOpts.renderCadenceMs);\n        }\n\n        if (rendererOpts.frameDiscard && this._animationLoop?.setFrameDiscard) {\n            this._animationLoop.setFrameDiscard(rendererOpts.frameDiscard);\n        }\n\n        if (rendererOpts.bloom && this._sceneInitializer?.setBloomConfig) {\n            this._sceneInitializer.setBloomConfig(rendererOpts.bloom);\n        }\n\n        if (partial.lens && this._sceneInitializer?.setLensConfig) {\n            this._sceneInitializer.setLensConfig(partial.lens);\n        }\n\n        if (rendererOpts.depthOfField && this._sceneInitializer?.setDepthOfFieldConfig) {\n            this._sceneInitializer.setDepthOfFieldConfig(rendererOpts.depthOfField);\n        }\n\n        if (rendererOpts.emissive && this._sceneInitializer?.setEmissiveConfig) {\n            this._sceneInitializer.setEmissiveConfig(rendererOpts.emissive);\n        }\n\n        if (rendererOpts.motionBlur && this._sceneInitializer?.setMotionBlurConfig) {\n            this._sceneInitializer.setMotionBlurConfig(rendererOpts.motionBlur);\n        }\n\n        if (rendererOpts.speedFov && this._sceneInitializer?.setSpeedFovConfig) {\n            this._sceneInitializer.setSpeedFovConfig(rendererOpts.speedFov);\n        }\n\n        const audio = partial.audio || {};\n        if (typeof audio.enabled === 'boolean') {\n            this._audioEnabledSetting = audio.enabled;\n            this._setAudioEnabled(audio.enabled);\n        }\n        if (audio.wind) {\n            this._applyWindSettings(audio.wind);\n        }\n        if (audio.speak) {\n            this._applySpeakSettings(audio.speak);\n        }\n\n        const lighting = partial.lighting || {};\n        if (Object.prototype.hasOwnProperty.call(lighting, 'date')) {\n            if (lighting.date === null) {\n                this._lightingSystem?.setFollowSystemTime?.(true);\n            } else if (lighting.date instanceof Date) {\n                this._lightingSystem?.setFollowSystemTime?.(false);\n                this._lightingSystem?.setDate(lighting.date);\n            } else if (typeof lighting.date === 'string' || typeof lighting.date === 'number') {\n                const parsed = new Date(lighting.date);\n                if (!Number.isNaN(parsed.valueOf())) {\n                    this._lightingSystem?.setFollowSystemTime?.(false);\n                    this._lightingSystem?.setDate(parsed);\n                }\n            }\n        }\n        if (Number.isFinite(lighting.timeSpeed)) {\n            this._lightingSystem?.setTimeSpeed(lighting.timeSpeed);\n        }\n        if (typeof lighting.simplified === 'boolean') {\n            this._lightingSystem?.setSimplifiedMode(lighting.simplified);\n        }\n        if (Number.isFinite(lighting.sunIntensity)) {\n            this._lightingSystem?.setIntensity(lighting.sunIntensity);\n        }\n        if (Number.isFinite(lighting.ambientIntensity)) {\n            this._lightingSystem?.setAmbientIntensity(lighting.ambientIntensity);\n        }\n\n        // Flashlight settings\n        const flashlightConfig = lighting.flashlight || {};\n        const flashlight = this._sceneInitializer?.flashlight;\n        if (flashlight) {\n            if (typeof flashlightConfig.enabled === 'boolean') {\n                flashlight.enabled = flashlightConfig.enabled;\n            }\n            if (Number.isFinite(flashlightConfig.intensity)) {\n                flashlight.setIntensity(flashlightConfig.intensity);\n            }\n            if (Number.isFinite(flashlightConfig.distance)) {\n                flashlight.setDistance(flashlightConfig.distance);\n            }\n            if (Number.isFinite(flashlightConfig.angle)) {\n                flashlight.setAngle(flashlightConfig.angle);\n            }\n            if (Number.isFinite(flashlightConfig.penumbra)) {\n                flashlight.light.penumbra = flashlightConfig.penumbra;\n            }\n            if (flashlightConfig.color !== undefined) {\n                flashlight.setColor(flashlightConfig.color);\n            }\n        }\n\n        // Labels\n        const labels = partial.labels || {};\n        const labelSystem = getLabelSystem();\n        if (this._presentationMode) {\n            labelSystem.setGlobalEnabled(false);\n        } else if (typeof labels.enabled === 'boolean') {\n            labelSystem.setGlobalEnabled(labels.enabled);\n            // Administrative border walls/ribbons are label-overlay\n            // presentation, so the global label gate owns their visibility as\n            // well as their text. The persisted border preference is retained\n            // and restored when labels are enabled again.\n            this._syncGeoJsonOverlayVisibility();\n        }\n        if (labels.weatherVolumes) this._weatherVolumeOverlay?.setOptions(labels.weatherVolumes);\n        if (labels.skyKinds && typeof labels.skyKinds === 'object' && this._sceneInitializer) {\n            // Kept on the initializer too: the sky may finish loading later.\n            this._sceneInitializer.skyLabelKinds = { ...labels.skyKinds };\n            this._sceneInitializer.skyFeatures?.setLabelKinds?.(labels.skyKinds);\n        }\n        if (typeof labels.enabled === 'boolean') this._weatherVolumeOverlay?.setGlobalEnabled(labels.enabled);\n        if (typeof labels.smokePresentation === 'string') {\n            this._environmentalOverlay?.setSmokePresentation?.(\n                labels.smokePresentation\n            );\n        }\n        if (labels.temporalFilter && typeof labels.temporalFilter === 'object') {\n            labelSystem.setTemporalFilter(labels.temporalFilter);\n        }\n        for (const { category, enabled } of this._presentationMode ? [] : getLabelCategoryPatch(labels)) {\n            for (const type of category.types) labelSystem.setTypeEnabled(type, enabled);\n            // Source overlays may maintain their own DOM/GPU label resource.\n            // Keep those source-specific switches synchronized with the\n            // canonical type gate above without making the control plane own\n            // source fetching or marker visibility.\n            if (WEATHER_VOLUME_LAYERS.some(layer=>layer.id===category.id)) this._weatherVolumeOverlay?.setLayerEnabled(category.id,enabled);\n            switch (category.id) {\n                case 'aircraft': this._aircraftOverlay?.setLabelsEnabled(enabled); break;\n                case 'maritime': this._maritimeOverlay?.setLabelsEnabled(enabled); break;\n                case 'satellites': this._satelliteOverlay?.setLabelsEnabled(enabled); break;\n                case 'buildings': this._buildingOverlay?.setLabelsEnabled(enabled); break;\n                case 'incidents': this._incidentOverlay?.setLabelsEnabled(enabled); break;\n                case 'infrastructure': this._infrastructureOverlay?.setLabelsEnabled(enabled); break;\n                case 'administrative':\n                    this._setGeoJsonLabelsEnabled(enabled);\n                    this._syncGeoJsonOverlayVisibility();\n                    break;\n                case 'trafficCameras': this._trafficCameraOverlay?.setLabelsEnabled?.(enabled); break;\n                case 'roadTraffic': this._roadTrafficOverlay?.setLabelsEnabled?.(enabled); break;\n                case 'sensors': this._meshtasticOverlay?.setLabelsEnabled?.(enabled); break;\n                case 'thermalDetections':\n                case 'wildfireEvents':\n                case 'smokePlumes':\n                case 'airQuality':\n                case 'environmentImagery':\n                    this._environmentalOverlay?.setLayerEnabled?.(category.id, enabled);\n                    break;\n                case 'radiationObservations':\n                case 'radiationHeatmap':\n                case 'spaceRadiation':\n                case 'armedConflict':\n                case 'violentCrime':\n                case 'reportedExplosions':\n                case 'seismicEvents':\n                case 'volcanoes':\n                case 'tsunamiAlerts':\n                case 'multiHazards':\n                    this._globalSignalsOverlay?.setLayerEnabled?.(category.id, enabled);\n                    break;\n                default: break;\n            }\n        }\n        if (Number.isFinite(labels.viewConeDeg)) {\n            labelSystem.setViewCone(labels.viewConeDeg);\n        }\n        if (Number.isFinite(labels.scaleMultiplier)) {\n            labelSystem.setScaleMultiplier(labels.scaleMultiplier);\n        }\n        if (Number.isFinite(labels.maxVisible)) {\n            const maxVisible = this._isMobile\n                ? Math.min(labels.maxVisible, 28)\n                : labels.maxVisible;\n            labelSystem.setMaxVisible(maxVisible);\n        } else if (this._isMobile) {\n            labelSystem.setMaxVisible(28);\n        }\n        if (labels.presentation && typeof labels.presentation === 'object') {\n            labelSystem.setDomLabelPresentation(labels.presentation);\n        }\n        if (labels.dynamics && typeof labels.dynamics === 'object') {\n            labelSystem.setDomLabelDynamics(labels.dynamics);\n        }\n\n        // Process wireframe toggle BEFORE atmosphere to ensure correct state\n        // when both are in the same patch (e.g., disabling wireframe and restoring atmosphere)\n        const debug = partial.debug || {};\n        if (Object.prototype.hasOwnProperty.call(debug, 'wireframeStyle')) {\n            this._applyWireframeStyle(debug.wireframeStyle);\n        }\n        const atmosphere = partial.atmosphere || {};\n        if (typeof debug.wireframe === 'boolean') {\n            const nextWireframe = debug.wireframe;\n            if (globalThis.__noclipDebugWireframe === true) {\n                console.warn(`[PlanetScene] WIREFRAME TOGGLE → ${nextWireframe}, photoLoader=${!!this._photoTileLoader}, photoEnabled=${this._photoTileLoader?.enabled}`);\n            }\n\n            if (this._triTree) {\n                this._triTree.setRenderRules({ wireframe: nextWireframe });\n            }\n\n            // Apply the authored flat albedo and crease outline to photorealistic tiles. Their\n            // layer-29 membership stays active so sun/sky shading, depth, and\n            // atmosphere remain identical to the textured material path.\n            if (this._photoTileLoader?.enabled) {\n                const rs = this._wireframeStyleResolved || {};\n                if (globalThis.__noclipDebugWireframe === true) {\n                    console.warn('[PlanetScene] Calling setWireframeMode on photoTileLoader');\n                }\n                this._photoTileLoader.setWireframeMode(nextWireframe, nextWireframe ? {\n                    surfaceColor: rs.surfaceColor,\n                    lineColor: rs.lineColor,\n                } : undefined);\n            }\n\n            // Borders are a cartographic overlay. The compatibility hook\n            // records the mode transition but deliberately preserves their\n            // configured/per-feature colors.\n            this._applyWireframeBorderColor(nextWireframe);\n\n            const disableLensFlare = nextWireframe || !!this._isMobile;\n            this._sceneInitializer?.setLensFlareEnabled?.(!disableLensFlare);\n        }\n\n        if (typeof atmosphere.enabled === 'boolean') {\n            const nextEnabled = atmosphere.enabled;\n            if (typeof this._sceneInitializer?.setAtmosphereEnabled === 'function') {\n                this._sceneInitializer.setAtmosphereEnabled(nextEnabled);\n            } else if (this._sceneInitializer?.atmosphereMesh) {\n                this._sceneInitializer.atmosphereMesh.visible = nextEnabled;\n            }\n            if (this._isMobile && nextEnabled && this._renderer?.xr?.isPresenting !== true) {\n                this._applyMobileLiteAtmosphere();\n                this._applyMobileGentleImagery();\n            }\n        }\n        const { enabled: _enabled, ...atmosphereConfig } = atmosphere;\n        if (Object.keys(atmosphereConfig).length > 0) {\n            this._sceneInitializer?.setAtmosphereCloudsConfig(atmosphereConfig);\n        }\n        const overlayConfig = {};\n        if (Object.prototype.hasOwnProperty.call(atmosphere, 'specularMap')) {\n            overlayConfig.specularMap = atmosphere.specularMap;\n        }\n        if (Object.prototype.hasOwnProperty.call(atmosphere, 'simpleClouds')) {\n            overlayConfig.simpleClouds = atmosphere.simpleClouds;\n        }\n        if (Object.prototype.hasOwnProperty.call(atmosphere, 'lightPollution')) {\n            overlayConfig.lightPollution = atmosphere.lightPollution;\n        }\n        if (Object.prototype.hasOwnProperty.call(atmosphere, 'water')) {\n            overlayConfig.water = atmosphere.water;\n        }\n        if (Object.keys(overlayConfig).length > 0) {\n            this._sceneInitializer?.setEarthOverlayConfig?.(overlayConfig);\n        }\n\n        // Handle night-side terrain visibility settings\n        const nightSettings = atmosphere.nightSettings || {};\n        if (Object.keys(nightSettings).length > 0) {\n            this._sceneInitializer?.setTerrainNightSettings?.(nightSettings);\n            const uniforms = this._sceneInitializer?.earthMaterial?.uniforms;\n            const nightStart = uniforms?.nightTransitionStart?.value;\n            const nightEnd = uniforms?.nightTransitionEnd?.value;\n            if (Number.isFinite(nightStart) && Number.isFinite(nightEnd)) {\n                const min = Math.min(nightStart, nightEnd);\n                const max = Math.max(nightStart, nightEnd);\n                this._sceneInitializer?.setAtmosphereCloudsConfig?.({\n                    nightIrradianceSunDotMin: min,\n                    nightIrradianceSunDotMax: max\n                });\n            }\n        }\n\n        const weather = partial.weather || {};\n        if (Object.keys(weather).length > 0) {\n            this._sceneInitializer?.setWeatherConfig?.(weather);\n        }\n\n        const terrain = partial.terrain || {};\n        const lod = terrain.lod || {};\n        if (this._triTree) {\n            if (Number.isFinite(lod.tileBudget) || Number.isFinite(lod.splitBudget) || Number.isFinite(lod.mergeBudget)) {\n                this._triTree.setBudgets({\n                    tileBudget: lod.tileBudget,\n                    splitBudget: lod.splitBudget,\n                    mergeBudget: lod.mergeBudget\n                });\n            }\n            if (Number.isFinite(lod.minLevel) || Number.isFinite(lod.maxLevel)) {\n                this._triTree.setLODRange(lod.minLevel, lod.maxLevel);\n            }\n            if (Number.isFinite(lod.maxScreenSpaceError)) {\n                this._triTree.maxScreenSpaceError = lod.maxScreenSpaceError;\n            }\n            if (typeof lod.seamInterpolation === 'boolean') {\n                this._triTree.enableSeamInterpolation = lod.seamInterpolation;\n                this._triTree._seamDirty = true;\n                if (lod.seamInterpolation) {\n                    this._triTree.requestNeighborRebuild?.();\n                } else {\n                    this._triTree.clearSeamCaches?.();\n                }\n            }\n            if (lod.adaptiveSplit && typeof this._triTree.setAdaptiveSplitBudgetConfig === 'function') {\n                this._triTree.setAdaptiveSplitBudgetConfig({\n                    enabled: lod.adaptiveSplit.enabled,\n                    targetMs: lod.adaptiveSplit.targetFrameMs,\n                    minScale: lod.adaptiveSplit.minScale,\n                    maxScale: lod.adaptiveSplit.maxScale,\n                    emaAlpha: lod.adaptiveSplit.emaAlpha,\n                    dropLerp: lod.adaptiveSplit.dropLerp,\n                    riseLerp: lod.adaptiveSplit.riseLerp\n                });\n            }\n            if (lod.frameWork && typeof this._triTree.setFrameWorkBudgets === 'function') {\n                this._triTree.setFrameWorkBudgets({\n                    lodMutationMsPerFrame: lod.frameWork.lodMutationMsPerFrame,\n                    imageryPreparationMsPerFrame: lod.frameWork.imageryPreparationMsPerFrame\n                });\n            }\n        }\n        if (this._animationLoop && lod.frameWork) {\n            this._animationLoop.setTerrainWorkBudgets?.({\n                maxElevationMorphTilesPerFrame: lod.frameWork.elevationMorphTilesPerFrame,\n                maxGeometryFinalizeTilesPerFrame: lod.frameWork.geometryFinalizeTilesPerFrame,\n                maxElevationMorphMsPerFrame: lod.frameWork.elevationMorphMsPerFrame,\n                maxGeometryFinalizeMsPerFrame: lod.frameWork.geometryFinalizeMsPerFrame,\n                maxNormalsPerFrame: lod.frameWork.normalsPerFrame,\n                maxNormalsMsPerFrame: lod.frameWork.normalsMsPerFrame\n            });\n        }\n\n        const surface = terrain.surface || {};\n        if (this._triTree) {\n            if (surface.staging) {\n                this._triTree.setSurfaceStagingConfig({\n                    minLOD: surface.staging.minLOD,\n                    maxLOD: surface.staging.maxLOD,\n                    cooldownMs: surface.staging.cooldownMs,\n                    cullAngleDeg: surface.staging.cullAngleDeg,\n                    focusAngleDeg: surface.staging.focusAngleDeg,\n                    instantRampEnabled: surface.staging.instantRampEnabled,\n                    instantRampCooldownMs: surface.staging.instantRampCooldownMs,\n                    instantRampDownCooldownMs: surface.staging.instantRampDownCooldownMs,\n                    instantRampUpStep: surface.staging.instantRampUpStep,\n                    instantRampDownStep: surface.staging.instantRampDownStep,\n                    instantRampDownHysteresis: surface.staging.instantRampDownHysteresis,\n                    viewCullEnabled: surface.staging.viewCullEnabled,\n                    viewBufferDeg: surface.staging.viewBufferDeg,\n                    peripheralLodDrop: surface.staging.peripheralLodDrop,\n                    viewCenterImageryBoost: surface.staging.viewCenterImageryBoost\n                });\n            }\n            if (surface.falloff) {\n                this._triTree.setSurfaceFalloffConfig({\n                    nearLOD: surface.falloff.nearLOD,\n                    farLOD: surface.falloff.farLOD,\n                    falloffPower: surface.falloff.power,\n                    startDeg: surface.falloff.startDeg\n                });\n            }\n        }\n\n        const orbit = terrain.orbit || {};\n        if (this._triTree && orbit.falloff) {\n            this._triTree.setOrbitFalloffConfig({\n                marginDeg: orbit.falloff.marginDeg,\n                anchorDeg: orbit.falloff.anchorDeg,\n                power: orbit.falloff.power\n            });\n        }\n\n        const imagery = terrain.imagery || {};\n        const currentImagery = this._imageryManager?.getConfig?.() || {};\n        if (this._triTree) {\n            this._triTree.setImageryConfig(buildTriTreeImageryConfigPatch(imagery, currentImagery));\n            const minZoomChanged = Number.isFinite(imagery.minZoom) && imagery.minZoom !== this._triTree.imageryMinZoom;\n            const maxZoomChanged = Number.isFinite(imagery.maxZoom) && imagery.maxZoom !== this._triTree.imageryMaxZoom;\n            if (minZoomChanged || maxZoomChanged) {\n                this._triTree.setImageryZoomRange(imagery.minZoom, imagery.maxZoom);\n            }\n            // Handle imagery resolution boost independently of terrain LOD\n            if (Number.isFinite(imagery.resolutionBoost) && imagery.resolutionBoost !== this._triTree.imageryResolutionBoost) {\n                this._triTree.setImageryResolutionBoost(imagery.resolutionBoost);\n            }\n        }\n        if (typeof imagery.enabled === 'boolean') {\n            this._moonSystem?.setImageryEnabled?.(imagery.enabled);\n        }\n        if (imagery.config && this._imageryManager?.setConfig) {\n            const nextConfig = buildImageryManagerConfigPatch(imagery.config);\n            if (hasImageryManagerConfigChanges(nextConfig, currentImagery)) {\n                this._imageryManager.setConfig(nextConfig);\n            }\n        }\n\n        const photogrammetry = terrain.photogrammetry || {};\n        if (this._triTree && typeof this._triTree.setPhotogramConfig === 'function') {\n            this._triTree.setPhotogramConfig(photogrammetry);\n        }\n\n        // Terrain renderers are mutually exclusive. Keep accepting the legacy\n        // debug setting for schema compatibility, but never display TriTree\n        // while photorealistic terrain is requested.\n        if (typeof terrain.debugDualMode === 'boolean' && this._triTree) {\n            const photoActive = terrain.photorealistic?.enabled === true || !!this._photoTileLoader?.enabled;\n            this._setTriTreePhotorealSuppressed(photoActive);\n        }\n\n        // ── Debug tritree elevation offset (meters) ─────────────────────\n        if (Number.isFinite(terrain.debugTriTreeOffsetM) && this._triTree?.group) {\n            // Scale the tritree group uniformly to shift its surface by offsetM meters\n            const offsetM = terrain.debugTriTreeOffsetM;\n            const scaleFactor = 1 + offsetM / PLANET_RADIUS;\n            this._triTree.group.scale.setScalar(scaleFactor);\n        }\n\n        // ── Photorealistic 3D Tiles (BYO key) ──────────────────────────\n        const photo = terrain.photorealistic || {};\n        if (!this._presentationMode && typeof photo.enabled === 'boolean') {\n            this._handlePhotorealisticToggle(photo.enabled, photo);\n        } else if (this._presentationMode) {\n            this._setTriTreePhotorealSuppressed(true);\n            this._setOverviewGlobeVisible(true);\n        }\n\n        const elevation = terrain.elevation || {};\n        if (this._elevationClient && Object.keys(elevation).length > 0) {\n            const elevationConfigPatch = buildElevationClientConfigPatch(elevation);\n            if (Object.keys(elevationConfigPatch).length > 0) {\n                this._elevationClient.setConfig(elevationConfigPatch);\n            }\n            if (typeof elevation.persistentCacheEnabled === 'boolean') {\n                this._elevationClient.setPersistentCacheEnabled(elevation.persistentCacheEnabled);\n            }\n            if (typeof elevation.cacheEnabled === 'boolean' ||\n                typeof elevation.persistentCacheEnabled === 'boolean') {\n                const cacheEnabled = !!this._elevationClient.isCacheEnabled?.();\n                const persistentEnabled = !!this._elevationClient.isPersistentCacheEnabled?.();\n                if (cacheEnabled && persistentEnabled) {\n                    this._restoreElevationCache();\n                    // Elevation persistence now handled by unified checkpoint\n                } else {\n                    // Elevation persistence now handled by unified checkpoint\n                }\n            }\n        }\n        if (this._triTree && elevation) {\n            if (typeof this._triTree.setElevationFetchMode === 'function') {\n                if (typeof elevation.fetchMode === 'string') {\n                    this._triTree.setElevationFetchMode(elevation.fetchMode);\n                }\n            }\n            const queueResetDistanceM = Number.isFinite(elevation.queueResetDistanceM)\n                ? elevation.queueResetDistanceM\n                : (Number.isFinite(elevation.queueResetKm) ? elevation.queueResetKm * 1000 : null);\n            if (Number.isFinite(queueResetDistanceM)) {\n                this._triTree.elevationQueueResetDistance = Math.max(10000, queueResetDistanceM);\n            }\n            const queueResetAngleDeg = Number.isFinite(elevation.queueResetAngleDeg)\n                ? elevation.queueResetAngleDeg\n                : (Number.isFinite(elevation.queueResetAngle) ? elevation.queueResetAngle : null);\n            if (Number.isFinite(queueResetAngleDeg)) {\n                this._triTree.elevationQueueResetAngleDeg = Math.max(0, queueResetAngleDeg);\n            }\n            if (typeof this._triTree.setElevationCascadeConfig === 'function') {\n                this._triTree.setElevationCascadeConfig({\n                    enabled: typeof elevation.cascadeEnabled === 'boolean'\n                        ? elevation.cascadeEnabled\n                        : undefined,\n                    coarseReadyRatio: Number.isFinite(elevation.cascadeCoarseReadyRatio)\n                        ? elevation.cascadeCoarseReadyRatio\n                        : (Number.isFinite(elevation.cascadeReadyRatio)\n                            ? elevation.cascadeReadyRatio\n                            : undefined),\n                    tileReadyRatio: Number.isFinite(elevation.cascadeTileReadyRatio)\n                        ? elevation.cascadeTileReadyRatio\n                        : undefined,\n                    minVisibleTiles: Number.isFinite(elevation.cascadeMinVisibleTiles)\n                        ? elevation.cascadeMinVisibleTiles\n                        : undefined,\n                    coarseMaxLevel: Number.isFinite(elevation.cascadeCoarseMaxLevel)\n                        ? elevation.cascadeCoarseMaxLevel\n                        : undefined\n                });\n            }\n\n            // Force-complete has been retired; keep it disabled regardless of config payload.\n            this._triTree.elevationStallForceCompleteEnabled = false;\n            this._triTree.elevationForceCompleteStallMs = 0;\n        }\n\n        const camera = partial.camera || {};\n        if (camera.mode && this._surfaceController) {\n            const urlState = this._getUrlViewState() || null;\n            const hasUrlOverride = !!(urlState && (urlState.hasOrientation || Number.isFinite(urlState.altitude)));\n            let savedMode = null;\n            try {\n                const raw = localStorage.getItem('nkn.globe.state');\n                if (raw) {\n                    const parsed = JSON.parse(raw);\n                    savedMode = parsed?.mode || null;\n                }\n            } catch (error) {\n                savedMode = null;\n            }\n            const persistEnabled = !!(document.getElementById('cfg-statePersist')?.checked);\n            const shouldRespectSaved = persistEnabled && savedMode && savedMode !== camera.mode;\n            if (!shouldRespectSaved && !hasUrlOverride) {\n                if (camera.mode === 'surface' && !this._surfaceController.isInSurfaceMode()) {\n                    const cameraPos = this._camera?.userData?.worldPosition || this._camera?.position;\n                    const dir = cameraPos ? cameraPos.clone().normalize() : null;\n                    if (dir) {\n                        this._surfaceController.enterSurfaceAt(dir);\n                    }\n                } else if (camera.mode === 'orbit' && this._surfaceController.isInSurfaceMode()) {\n                    this._surfaceController.exitSurfaceMode();\n                }\n            }\n        }\n        // Saved Earth orbit settings are not valid constraints for Moon/Sun\n        // anchoring. Applying them after a body URL has been restored pulls\n        // the camera back inside the selected body.\n        if (camera.orbit && this._controls && this._surfaceController?.getBodyAnchor?.() === 'terra') {\n            if (Number.isFinite(camera.orbit.minDistance)) this._controls.minDistance = camera.orbit.minDistance;\n            if (Number.isFinite(camera.orbit.maxDistance)) this._controls.maxDistance = camera.orbit.maxDistance;\n            if (Number.isFinite(camera.orbit.damping)) this._controls.dampingFactor = camera.orbit.damping;\n        }\n        if (camera.surface && this._surfaceController) {\n            if (Number.isFinite(camera.surface.moveSpeed)) this._surfaceController.SURFACE_MOVE_SPEED = camera.surface.moveSpeed;\n            if (Number.isFinite(camera.surface.altitudeSpeedMax)) this._surfaceController.SURFACE_WALK_ALT_SCALE_MAX = camera.surface.altitudeSpeedMax;\n            if (Number.isFinite(camera.surface.verticalSpeed)) this._surfaceController.SURFACE_VERTICAL_SPEED = camera.surface.verticalSpeed;\n            if (Number.isFinite(camera.surface.fovMin)) this._surfaceController.SURFACE_FOV_MIN = camera.surface.fovMin;\n            if (Number.isFinite(camera.surface.fovMax)) this._surfaceController.SURFACE_FOV_MAX = camera.surface.fovMax;\n        }\n        if (camera.navigation && this._surfaceController) {\n            this._surfaceController.setNavigationConfig({\n                profile: camera.navigation.profile,\n                runSpeed: camera.navigation.runSpeed,\n                zoomSpeed: camera.navigation.zoomSpeed,\n                rotateSpeed: camera.navigation.rotateSpeed,\n                dragSpeed: camera.navigation.dragSpeed\n            });\n        }\n\n        const avatar = partial.avatar || {};\n        if (Object.keys(avatar).length > 0) {\n            this._applyAvatarConfig(avatar);\n        }\n\n        const pathfinding = partial.pathfinding || {};\n        if (this._sceneInitializer && Object.keys(pathfinding).length > 0) {\n            const next = { ...(this._sceneInitializer.pathWeights || {}) };\n            if (Number.isFinite(pathfinding.lateralMaxDeg)) next.lateralMaxDeg = pathfinding.lateralMaxDeg;\n            if (Number.isFinite(pathfinding.stepsS)) next.stepsS = pathfinding.stepsS;\n            if (Number.isFinite(pathfinding.stepsT)) next.stepsT = pathfinding.stepsT;\n            if (Number.isFinite(pathfinding.smooth)) next.smoothIterations = pathfinding.smooth;\n\n            const costs = pathfinding.costs || {};\n            if (Number.isFinite(costs.uphill)) next.weightUphill = costs.uphill;\n            if (Number.isFinite(costs.downhill)) next.weightDownhill = costs.downhill;\n            if (Number.isFinite(costs.elevDelta)) next.weightElevDelta = costs.elevDelta;\n            if (Number.isFinite(costs.slopeSq)) next.weightSlopeSq = costs.slopeSq;\n            if (Number.isFinite(costs.lateral)) next.weightLateral = costs.lateral;\n            if (Number.isFinite(costs.distance)) next.weightDistance = costs.distance;\n            if (Number.isFinite(costs.high)) next.weightHigh = costs.high;\n            if (Number.isFinite(costs.rough)) next.weightRough = costs.rough;\n\n            this._sceneInitializer.pathWeights = next;\n        }\n\n        // Buildings overlay settings (propagate to BuildingOverlay via EventBus)\n        const buildings = partial.buildings || {};\n        if (Object.keys(buildings).length > 0) {\n            if (typeof buildings.enabled === 'boolean') {\n                this._buildingAutoEnabled = buildings.enabled;\n            }\n            this.eventBus?.emit?.('buildings:config', buildings);\n        }\n\n        // Infrastructure overlay settings\n        const infrastructure = partial.infrastructure || {};\n        if (this._infrastructureOverlay && Object.keys(infrastructure).length > 0) {\n            // The classic overlay owns roads/bridges/waterways/areas/railways.\n            // OpenInfraMap utility products are MVT-owned and must not also\n            // enter the Overpass query/build path as duplicate geometry.\n            const classicLayerKeys = new Set(['roads', 'bridges', 'waterways', 'areas', 'railways']);\n            const classicLayers = Object.fromEntries(\n                Object.entries(infrastructure.layers || {})\n                    .filter(([key]) => classicLayerKeys.has(key)),\n            );\n            this._infrastructureOverlay.applyConfig({\n                ...infrastructure,\n                ...(infrastructure.layers ? { layers: classicLayers } : {}),\n            });\n        }\n        // OpenInfraMap MVT vector tile layer groups (driven by utility layer toggles)\n        if (infrastructure.layers) {\n            if (globalThis.__noclipDebugInfra === true) {\n                console.info('[PS] _applyTuneables infrastructure.layers:', JSON.stringify(infrastructure.layers));\n            }\n            const applyLayers = (renderer) => renderer?.setEnabledGroups?.(\n                getEnabledOpenInfraMapGroups(infrastructure.layers),\n            );\n            if (this._openInfraMapRenderer) {\n                applyLayers(this._openInfraMapRenderer);\n            } else if (hasEnabledOpenInfraMapGroup(infrastructure.layers)) {\n                void this._ensureOpenInfraMapRenderer(infrastructure.layers).then(applyLayers).catch((err) => {\n                    console.warn('[PlanetScene] OpenInfraMap renderer load failed:', err);\n                });\n            }\n        }\n\n        const meshtastic = partial.meshtastic || {};\n        if (this._meshtasticOverlay && Object.keys(meshtastic).length > 0) {\n            this._meshtasticOverlay.applyConfig(meshtastic);\n        }\n\n        const radioData = partial.radioData || {};\n        if (Object.keys(radioData).length > 0) {\n            this._radioDataConfig = {\n                ...(this._radioDataConfig || {}),\n                ...radioData,\n                feeds: { ...(this._radioDataConfig?.feeds || {}), ...(radioData.feeds || {}) },\n            };\n            if (typeof radioData.enabled === 'boolean') {\n                this._radioDataAutoEnabled = radioData.enabled;\n                this._radioDataAutoCenter = null;\n            }\n            if (Number.isFinite(radioData.pollIntervalMs)) {\n                this._radioDataAutoPollIntervalMs = radioData.pollIntervalMs;\n            }\n            this._radioDataOverlay?.applyConfig?.(this._radioDataConfig);\n            this.eventBus?.emit?.('radioData:config', this._radioDataConfig);\n        }\n\n        const geocaches = partial.geocaches || {};\n        if (Object.keys(geocaches).length > 0) {\n            this._geocacheConfig = { ...(this._geocacheConfig || {}), ...geocaches };\n            if (typeof geocaches.enabled === 'boolean') {\n                this._geocacheAutoEnabled = geocaches.enabled;\n                this._geocacheAutoCenter = null;\n            }\n            if (Number.isFinite(geocaches.pollIntervalMs)) {\n                this._geocacheAutoPollIntervalMs = geocaches.pollIntervalMs;\n            }\n            this._geocacheLayer?.applyConfig?.(this._geocacheConfig);\n        }\n\n        // Note: debug.wireframe is handled earlier (before atmosphere) - don't re-apply here\n        if (this._triTree) {\n            if (typeof debug.neighborDetection === 'boolean') {\n                this._triTree.enableNeighborDetection = debug.neighborDetection;\n            }\n            if (typeof debug.invertFocusDir === 'boolean') {\n                this._triTree.debugInvertFocusDir = debug.invertFocusDir;\n            }\n            if (typeof debug.negateFocusX === 'boolean') {\n                this._triTree.debugNegateFocusX = debug.negateFocusX;\n            }\n            if (typeof debug.negateFocusZ === 'boolean') {\n                this._triTree.debugNegateFocusZ = debug.negateFocusZ;\n            }\n            if (typeof debug.invertCameraDir === 'boolean') {\n                this._triTree.debugInvertCameraDir = debug.invertCameraDir;\n            }\n            if (typeof debug.invertCameraPos === 'boolean') {\n                this._triTree.debugInvertCameraPos = debug.invertCameraPos;\n            }\n            if (typeof debug.negateCamPosX === 'boolean') {\n                this._triTree.debugNegateCamPosX = debug.negateCamPosX;\n            }\n            if (typeof debug.negateCamPosZ === 'boolean') {\n                this._triTree.debugNegateCamPosZ = debug.negateCamPosZ;\n            }\n            if (typeof debug.invertQuaternion === 'boolean') {\n                this._triTree.debugInvertQuaternion = debug.invertQuaternion;\n            }\n            if (typeof debug.disableViewportCulling === 'boolean') {\n                this._triTree.debugDisableViewportCulling = debug.disableViewportCulling;\n            }\n        }\n        if (Object.prototype.hasOwnProperty.call(debug, 'raycastLinePrecision')) {\n            this._applyRaycastLinePrecision(debug.raycastLinePrecision);\n        }\n        if (Object.prototype.hasOwnProperty.call(debug, 'geoJsonAutoDepth')) {\n            this._setGeoJsonAutoDepth(debug.geoJsonAutoDepth);\n        }\n        if (Object.prototype.hasOwnProperty.call(debug, 'geoJsonMaxAdminLevel')) {\n            this._setGeoJsonMaxAdminLevel(debug.geoJsonMaxAdminLevel);\n        }\n        if (Object.prototype.hasOwnProperty.call(debug, 'geoJsonFarMaxAdminLevelAltM')) {\n            const nextAlt = Number.isFinite(debug.geoJsonFarMaxAdminLevelAltM)\n                ? debug.geoJsonFarMaxAdminLevelAltM\n                : Number.parseFloat(debug.geoJsonFarMaxAdminLevelAltM);\n            if (Number.isFinite(nextAlt)) {\n                this._geoJsonFarMaxAdminLevelAltM = Math.max(0, nextAlt);\n                this._updateGeoJsonAltitudeLimit(true);\n            }\n        }\n        if (Object.prototype.hasOwnProperty.call(debug, 'geoJsonFarMaxAdminLevel')) {\n            this._geoJsonFarMaxAdminLevel = this._normalizeGeoJsonLevel(debug.geoJsonFarMaxAdminLevel);\n            this._updateGeoJsonAltitudeLimit(true);\n        }\n        if (typeof debug.geoJson === 'boolean') {\n            this._syncGeoJsonOverlayVisibility();\n        }\n        if (typeof debug.geoJsonAurora === 'boolean') {\n            this._geoJsonLayer?.setAuroraEnabled?.(debug.geoJsonAurora);\n        }\n        if (typeof debug.geoJsonLabels === 'boolean') {\n            this._setGeoJsonLabelsEnabled(debug.geoJsonLabels);\n        }\n        let labelTuningDirty = false;\n        if (Object.prototype.hasOwnProperty.call(debug, 'geoJsonLabelScaleCapAltM')) {\n            const next = Number.isFinite(debug.geoJsonLabelScaleCapAltM)\n                ? debug.geoJsonLabelScaleCapAltM\n                : Number.parseFloat(debug.geoJsonLabelScaleCapAltM);\n            if (Number.isFinite(next)) {\n                this._geoJsonLabelScaleCapAltM = Math.max(0, next);\n                labelTuningDirty = true;\n            }\n        }\n        if (Object.prototype.hasOwnProperty.call(debug, 'geoJsonLabelScaleReleaseAltM')) {\n            const next = Number.isFinite(debug.geoJsonLabelScaleReleaseAltM)\n                ? debug.geoJsonLabelScaleReleaseAltM\n                : Number.parseFloat(debug.geoJsonLabelScaleReleaseAltM);\n            if (Number.isFinite(next)) {\n                this._geoJsonLabelScaleReleaseAltM = Math.max(0, next);\n                labelTuningDirty = true;\n            }\n        }\n        if (Object.prototype.hasOwnProperty.call(debug, 'geoJsonLabelBorderRetireAltM')) {\n            const next = Number.isFinite(debug.geoJsonLabelBorderRetireAltM)\n                ? debug.geoJsonLabelBorderRetireAltM\n                : Number.parseFloat(debug.geoJsonLabelBorderRetireAltM);\n            if (Number.isFinite(next)) {\n                this._geoJsonLabelBorderRetireAltM = Math.max(0, next);\n                labelTuningDirty = true;\n            }\n        }\n        if (labelTuningDirty) {\n            this._applyGeoJsonLabelTuning();\n        }\n        const hasAdminLevel = Object.prototype.hasOwnProperty.call(debug, 'geoJsonAdminLevel');\n        const hasCountry = Object.prototype.hasOwnProperty.call(debug, 'geoJsonCountry');\n        const hasSource = typeof debug.geoJsonSource === 'string' && debug.geoJsonSource.length > 0;\n        if (this._geoJsonAutoDepth) {\n            if (hasAdminLevel || hasCountry) {\n                const nextLevel = hasAdminLevel ? debug.geoJsonAdminLevel : this._geoJsonAdminLevel;\n                const nextCountry = hasCountry ? debug.geoJsonCountry : this._geoJsonCountry;\n                this._setGeoJsonManualSelection(nextLevel, nextCountry);\n            }\n            if (hasSource) {\n                this._geoJsonManualSource = debug.geoJsonSource;\n            }\n        } else if (hasAdminLevel || hasCountry) {\n            const nextLevel = hasAdminLevel ? debug.geoJsonAdminLevel : this._geoJsonAdminLevel;\n            const nextCountry = hasCountry ? debug.geoJsonCountry : this._geoJsonCountry;\n            this._applyGeoJsonSelection(nextLevel, nextCountry, debug.geoJsonSource);\n        } else if (hasSource) {\n            this._applyGeoJsonSource(debug.geoJsonSource);\n        }\n        if (this._lightingSystem) {\n            if (typeof debug.flipRotation180 === 'boolean') {\n                this._lightingSystem.debugFlipRotation180 = debug.flipRotation180;\n            }\n            if (typeof debug.negateSunX === 'boolean') {\n                this._lightingSystem.debugNegateSunX = debug.negateSunX;\n            }\n            if (typeof debug.negateSunZ === 'boolean') {\n                this._lightingSystem.debugNegateSunZ = debug.negateSunZ;\n            }\n        }\n        if (this._isMobile) {\n            this._applyMobileRuntimeBudgets();\n        }\n    }\n\n    async _restoreElevationCache() {\n        if (!this._elevationClient) return;\n        if (!this._elevationClient.isPersistentCacheEnabled?.()) return;\n        try {\n            await this._elevationClient.initPersistentCache();\n        } catch (err) {\n            console.warn('[PlanetScene] Failed to init persistent elevation cache:', err);\n        }\n    }\n\n    _buildSceneSnapshot() {\n        const viewState = this.captureViewState({ includeElevationCache: false }) || null;\n        const latLon = viewState?.surfaceLatLon || viewState?.orbitLatLon || null;\n        const lat = latLon ? Number(latLon.lat) : null;\n        const lon = latLon ? Number(latLon.lon) : null;\n\n        // TriTree tile export (may be empty in photorealistic-only mode)\n        let tiles = [];\n        if (this._triTree && typeof this._triTree.exportVisibleTileSnapshot === 'function') {\n            tiles = this._triTree.exportVisibleTileSnapshot() || [];\n        }\n\n        const imagerySnapshot = buildTerrainImagerySettings({\n            imageryManager: this._imageryManager,\n            triTree: this._triTree\n        });\n\n        // Determine active tile source for restore\n        const tileSource = this._photoTileLoader?.enabled\n            ? 'photorealistic'\n            : 'tritree';\n\n        // Still produce a snapshot even without TriTree tiles — view state\n        // alone is valuable for restoring camera position on reload.\n        if (tiles.length === 0 && !viewState) return null;\n\n        return {\n            ts: Date.now(),\n            lat: Number.isFinite(lat) ? lat : null,\n            lon: Number.isFinite(lon) ? lon : null,\n            view: viewState ? {\n                mode: viewState.mode,\n                surfaceLatLon: viewState.surfaceLatLon,\n                orbitLatLon: viewState.orbitLatLon,\n                orbitRadius: viewState.orbitRadius,\n                surfaceAltitude: viewState.surfaceAltitude,\n                surfaceOrientation: viewState.surfaceOrientation\n            } : null,\n            tileSource,\n            tiles,\n            imagery: imagerySnapshot\n        };\n    }\n\n    _buildEnvelope() {\n        const snapshot = this._buildSceneSnapshot();\n        if (!snapshot) return null;\n        return {\n            id: 'current',\n            version: 2,\n            ts: snapshot.ts,\n            sessionId: this._sessionId,\n            view: snapshot.view,\n            tileSource: snapshot.tileSource || 'tritree',\n            tileSnapshot: snapshot.tiles || [],\n            imageryConfig: snapshot.imagery || null,\n            lat: snapshot.lat,\n            lon: snapshot.lon\n        };\n    }\n\n    _drainPendingElevationWrites() {\n        if (!this._elevationClient) return [];\n        if (typeof this._elevationClient.drainPendingPersistentWrites === 'function') {\n            return this._elevationClient.drainPendingPersistentWrites();\n        }\n        return this._elevationClient._cacheWriteQueue?.splice(0) || [];\n    }\n\n    _requeuePendingElevationWrites(entries, { front = true } = {}) {\n        if (!Array.isArray(entries) || entries.length === 0 || !this._elevationClient) return;\n        if (typeof this._elevationClient.requeuePendingPersistentWrites === 'function') {\n            this._elevationClient.requeuePendingPersistentWrites(entries, { front });\n            return;\n        }\n        if (this._elevationClient._cacheWriteQueue) {\n            if (front) {\n                this._elevationClient._cacheWriteQueue.unshift(...entries);\n            } else {\n                this._elevationClient._cacheWriteQueue.push(...entries);\n            }\n        }\n    }\n\n    _checkpoint() {\n        if (!this._sceneStateStore?.db) return;\n        const now = Date.now();\n        if ((now - this._lastCheckpointAt) < this._checkpointIntervalMs) return;\n\n        const envelope = this._buildEnvelope();\n        const elevationEntries = this._drainPendingElevationWrites();\n\n        if (!envelope) {\n            if (elevationEntries.length > 0) {\n                this._sceneStateStore.writeElevationBatch(elevationEntries).catch((err) => {\n                    console.warn('[PlanetScene] Elevation-only checkpoint write failed:', err);\n                    this._requeuePendingElevationWrites(elevationEntries, { front: true });\n                });\n            }\n            this._lastCheckpointAt = now;\n            return;\n        }\n\n        this._sceneStateStore.writeCheckpoint(envelope, elevationEntries, [], [], []).catch((err) => {\n            console.warn('[PlanetScene] Checkpoint write failed:', err);\n            this._requeuePendingElevationWrites(elevationEntries, { front: true });\n        });\n        this._lastCheckpointAt = now;\n    }\n\n    _syncCheckpoint() {\n        if (!this._sceneStateStore?.db) return;\n\n        const envelope = this._buildEnvelope();\n        const elevationEntries = this._drainPendingElevationWrites();\n        if (!envelope) {\n            if (elevationEntries.length > 0) {\n                this._sceneStateStore.writeElevationBatch(elevationEntries).catch((err) => {\n                    console.warn('[PlanetScene] Elevation-only sync checkpoint failed:', err);\n                    this._requeuePendingElevationWrites(elevationEntries, { front: true });\n                });\n            }\n            return;\n        }\n\n        // Synchronous transaction start — browser completes IDB readwrite even on page termination.\n        this._sceneStateStore.writeSyncCheckpoint(envelope, elevationEntries, [], [], []);\n    }\n\n    _startCheckpointPersistence() {\n        if (typeof window === 'undefined') return;\n        if (this._checkpointInterval) return;\n\n        this._checkpointInterval = window.setInterval(\n            () => this._checkpoint(),\n            this._checkpointIntervalMs\n        );\n        this._checkpointUnloadHandler = () => this._syncCheckpoint();\n        this._checkpointVisibilityHandler = () => {\n            if (document.visibilityState === 'hidden') this._syncCheckpoint();\n        };\n        this._checkpointPageHideHandler = () => this._syncCheckpoint();\n\n        window.addEventListener('beforeunload', this._checkpointUnloadHandler);\n        window.addEventListener('pagehide', this._checkpointPageHideHandler);\n        if (typeof document !== 'undefined') {\n            document.addEventListener('visibilitychange', this._checkpointVisibilityHandler);\n        }\n    }\n\n    _stopCheckpointPersistence() {\n        if (this._checkpointInterval) {\n            clearInterval(this._checkpointInterval);\n            this._checkpointInterval = null;\n        }\n        if (this._checkpointUnloadHandler && typeof window !== 'undefined') {\n            window.removeEventListener('beforeunload', this._checkpointUnloadHandler);\n            this._checkpointUnloadHandler = null;\n        }\n        if (this._checkpointPageHideHandler && typeof window !== 'undefined') {\n            window.removeEventListener('pagehide', this._checkpointPageHideHandler);\n            this._checkpointPageHideHandler = null;\n        }\n        if (this._checkpointVisibilityHandler && typeof document !== 'undefined') {\n            document.removeEventListener('visibilitychange', this._checkpointVisibilityHandler);\n            this._checkpointVisibilityHandler = null;\n        }\n    }\n\n    /**\n     * Pre-position camera from the canonical URL or localStorage before\n     * settings apply.\n     * Ensures tile loaders (both TriTree and photorealistic) begin\n     * fetching tiles at the correct viewport on startup.\n     */\n    _prePositionCameraFromSavedState() {\n        try {\n            const urlState = this._readUrlViewState?.();\n            if (urlState?.body !== 'luna'\n                && urlState?.body !== 'sol'\n                && Number.isFinite(urlState?.lat)\n                && Number.isFinite(urlState?.lon)) {\n                this._syncEarthRotationForUrl();\n                const dir = latLonToLocalDir(urlState.lat, urlState.lon);\n                if (this._triTree?.group?.getWorldQuaternion) {\n                    const planetQuat = new THREE.Quaternion();\n                    this._triTree.group.getWorldQuaternion(planetQuat);\n                    dir.applyQuaternion(planetQuat);\n                }\n                const ellipsoidR = ellipsoidRadiusForWorldDir(dir, this._triTree?.group);\n                const altitude = Number.isFinite(urlState.altitude)\n                    ? Math.max(0, urlState.altitude)\n                    : 0;\n                const position = dir.multiplyScalar(ellipsoidR + altitude);\n                this._camera.position.copy(position);\n                if (this._camera.userData?.worldPosition?.isVector3) {\n                    this._camera.userData.worldPosition.copy(position);\n                }\n                this._camera.lookAt(0, 0, 0);\n                this._camera.updateMatrixWorld(true);\n                return;\n            }\n\n            const raw = localStorage.getItem('nkn.globe.state');\n            if (!raw) return;\n            const state = JSON.parse(raw);\n            if (!state?.camera) return;\n\n            const { x, y, z } = state.camera;\n            if (!Number.isFinite(x) || !Number.isFinite(y) || !Number.isFinite(z)) return;\n\n            this._camera.position.set(x, y, z);\n\n            // Restore orbit target if available\n            if (state.target && this._controls) {\n                const t = state.target;\n                if (Number.isFinite(t.x) && Number.isFinite(t.y) && Number.isFinite(t.z)) {\n                    this._controls.target.set(t.x, t.y, t.z);\n                }\n            }\n\n            this._camera.updateMatrixWorld(true);\n        } catch { /* non-critical — default camera position used */ }\n    }\n\n    async _restoreFromEnvelope() {\n        if (this._sceneStateRestorePromise) return this._sceneStateRestorePromise;\n        this._sceneStateRestorePromise = (async () => {\n            // Initialize unified store (triggers migration from legacy IDBs if needed)\n            await this._sceneStateStore?.init?.();\n\n            if (this._elevationClient &&\n                this._elevationClient.isPersistentCacheEnabled?.() &&\n                typeof this._elevationClient.initPersistentCache === 'function') {\n                await this._elevationClient.initPersistentCache().catch((err) => {\n                    console.warn('[PlanetScene] Persistent elevation cache warmup failed:', err);\n                });\n            }\n            if (!this._sceneStateStore || !this._triTree) return null;\n\n            const urlState = this._getUrlViewState() || null;\n            const lat = urlState ? Number(urlState.lat) : null;\n            const lon = urlState ? Number(urlState.lon) : null;\n            const hasUrlState = Number.isFinite(lat) && Number.isFinite(lon);\n            const urlLatLon = hasUrlState ? { lat, lon } : null;\n\n            // Read unified envelope — no age/distance filters\n            const envelope = await this._sceneStateStore.readEnvelope();\n            const snapshot = envelope ? {\n                tiles: envelope.tileSnapshot || [],\n                view: envelope.view || null,\n                imagery: envelope.imageryConfig || null,\n                lat: envelope.lat,\n                lon: envelope.lon,\n                ts: envelope.ts\n            } : null;\n\n            const resolvePreferredImageryVersionId = (imagerySnapshot = null) => {\n                const snapshotVersionId = imagerySnapshot?.versionId;\n                if (snapshotVersionId && String(snapshotVersionId).toLowerCase() !== 'latest') {\n                    return snapshotVersionId;\n                }\n                const configuredVersionId = this._imageryManager?.getConfig?.()?.versionId || this._imageryManager?.versionId;\n                if (configuredVersionId && String(configuredVersionId).toLowerCase() !== 'latest') {\n                    return configuredVersionId;\n                }\n                return null;\n            };\n\n            // Uncapped imagery prewarm\n            const prewarmImagerySnapshotTiles = async (tiles, preferVersionId = null) => {\n                if (!Array.isArray(tiles) || tiles.length === 0) return;\n                if (!this._imageryManager || typeof this._imageryManager.prewarmPersistentForSnapshotTiles !== 'function') return;\n                await this._imageryManager.prewarmPersistentForSnapshotTiles(tiles, {\n                    preferVersionId\n                }).catch((err) => {\n                    console.warn('[PlanetScene] Persistent snapshot-atlas prewarm failed:', err);\n                });\n            };\n            const prewarmImageryHotset = async (preferVersionId = null) => {\n                if (!this._imageryManager || typeof this._imageryManager.prewarmPersistentHotset !== 'function') return;\n                await this._imageryManager.prewarmPersistentHotset({\n                    preferVersionId\n                }).catch((err) => {\n                    console.warn('[PlanetScene] Persistent imagery hotset prewarm failed:', err);\n                });\n            };\n\n            // Uncapped elevation prewarm\n            const prewarmElevationForLatLon = async (sourceLatLon = null, snapshotTiles = null) => {\n                if (!sourceLatLon || !this._elevationClient) return;\n                if (typeof this._elevationClient.prewarmPersistentCacheAtLatLon !== 'function') return;\n                const latDeg = Number(sourceLatLon.lat);\n                const lonDeg = Number(sourceLatLon.lon);\n                if (!Number.isFinite(latDeg) || !Number.isFinite(lonDeg)) return;\n                const warmed = await this._elevationClient.prewarmPersistentCacheAtLatLon(latDeg, lonDeg, {\n                    force: true\n                }).catch((err) => {\n                    console.warn('[PlanetScene] Persistent elevation location prewarm failed:', err);\n                    return null;\n                });\n                if (Number.isFinite(warmed?.imported) && warmed.imported > 0) {\n                    console.log(`[PlanetScene] Warmed ${warmed.imported} persistent elevation entries`);\n                }\n            };\n            const prewarmElevationSnapshotKeys = async (tiles = [], {\n                focusWorldDir = null\n            } = {}) => {\n                if (!Array.isArray(tiles) || tiles.length === 0) return;\n                if (!this._triTree || !this._elevationClient) return;\n                if (typeof this._triTree.collectSnapshotElevationKeys !== 'function') return;\n                if (typeof this._elevationClient.prewarmPersistentCacheByKeys !== 'function') return;\n                const keyCap = this._isMobile ? 110000 : 200000;\n                const keys = this._triTree.collectSnapshotElevationKeys(tiles, {\n                    maxTiles: this._isMobile ? 640 : 1400,\n                    maxKeys: keyCap,\n                    focusWorldDir\n                });\n                if (!Array.isArray(keys) || keys.length === 0) return;\n                const warmed = await this._elevationClient.prewarmPersistentCacheByKeys(keys, {\n                    maxEntries: keyCap\n                }).catch((err) => {\n                    console.warn('[PlanetScene] Persistent elevation key prewarm failed:', err);\n                    return null;\n                });\n                if (Number.isFinite(warmed?.imported) && warmed.imported > 0) {\n                    console.log(\n                        `[PlanetScene] Warmed ${warmed.imported}/${warmed.requested} ` +\n                        'persistent elevation entries from snapshot keys'\n                    );\n                }\n            };\n\n            // Determine what was saved — view-only snapshots are valid for\n            // photorealistic mode where TriTree tiles weren't active.\n            const hasTiles = snapshot && Array.isArray(snapshot.tiles) && snapshot.tiles.length > 0;\n            const savedTileSource = envelope?.tileSource || 'tritree';\n\n            if (!snapshot) {\n                await prewarmElevationForLatLon(urlLatLon, null);\n                await prewarmImageryHotset(resolvePreferredImageryVersionId(null));\n                return null;\n            }\n\n            // When the last session used photorealistic tiles, skip TriTree\n            // tile/imagery restore but still apply view state for camera\n            // positioning (photorealistic tiles will start at correct location).\n            if (savedTileSource === 'photorealistic' || !hasTiles) {\n                if (!hasTiles) {\n                    await prewarmElevationForLatLon(urlLatLon, null);\n                    await prewarmImageryHotset(resolvePreferredImageryVersionId(null));\n                }\n                if (snapshot.view && !hasUrlState) {\n                    this._applyViewStateSnapshot(snapshot.view, {\n                        updateUrl: true,\n                        applyElevationCache: true,\n                        allowPersistToggle: false\n                    });\n                }\n                return envelope;\n            }\n\n            const imagery = snapshot.imagery || null;\n            if (imagery && this._triTree) {\n                const current = this._imageryManager?.getConfig?.() || {};\n                const triTreeConfigPatch = buildTriTreeImageryConfigPatch(imagery, current);\n                triTreeConfigPatch.imageryInheritanceEnabled = true;\n                if (this._triTree.setImageryConfig) {\n                    this._triTree.setImageryConfig(triTreeConfigPatch);\n                }\n                if (Number.isFinite(imagery.minZoom) || Number.isFinite(imagery.maxZoom)) {\n                    this._triTree.setImageryZoomRange(imagery.minZoom, imagery.maxZoom);\n                }\n                if (Number.isFinite(imagery.resolutionBoost)) {\n                    this._triTree.setImageryResolutionBoost(imagery.resolutionBoost);\n                }\n                if (imagery.config && this._imageryManager?.setConfig) {\n                    const imageryManagerPatch = buildImageryManagerConfigPatch(imagery.config);\n                    if (hasImageryManagerConfigChanges(imageryManagerPatch, current)) {\n                        this._imageryManager.setConfig(imageryManagerPatch);\n                    }\n                }\n            }\n            const applyImagery = imagery ? imagery.enabled !== false : true;\n            const snapshotLatLon = snapshot?.view?.surfaceLatLon ||\n                snapshot?.view?.orbitLatLon ||\n                (Number.isFinite(snapshot?.lat) && Number.isFinite(snapshot?.lon)\n                    ? { lat: snapshot.lat, lon: snapshot.lon }\n                    : null);\n            const latLonSource = urlLatLon || snapshotLatLon;\n            const preferVersionId = resolvePreferredImageryVersionId(imagery);\n            let focusWorldDir = null;\n            if (latLonSource &&\n                Number.isFinite(latLonSource.lat) &&\n                Number.isFinite(latLonSource.lon)) {\n                focusWorldDir = latLonToLocalDir(latLonSource.lat, latLonSource.lon);\n                if (this._triTree?.group?.getWorldQuaternion) {\n                    const worldQ = new THREE.Quaternion();\n                    this._triTree.group.getWorldQuaternion(worldQ);\n                    focusWorldDir.applyQuaternion(worldQ).normalize();\n                }\n            } else if (this._camera?.position?.lengthSq?.() > 1e-8) {\n                focusWorldDir = this._camera.position.clone().normalize();\n            }\n            await Promise.all([\n                prewarmElevationSnapshotKeys(snapshot.tiles, { focusWorldDir }),\n                prewarmElevationForLatLon(latLonSource, snapshot.tiles)\n            ]);\n            await Promise.all([\n                prewarmImagerySnapshotTiles(snapshot.tiles, preferVersionId),\n                prewarmImageryHotset(preferVersionId)\n            ]);\n\n            // Full-footprint replay — no budget limits\n            this._triTree.restoreTilesFromSnapshot(snapshot.tiles, {\n                applyImagery,\n                forceVisible: false,\n                applyElevationFromCache: true,\n                focusWorldDir,\n                deferRemainder: false\n            });\n\n            if (snapshot.view && !hasUrlState) {\n                this._applyViewStateSnapshot(snapshot.view, {\n                    updateUrl: true,\n                    applyElevationCache: true,\n                    allowPersistToggle: false\n                });\n            }\n            return envelope;\n        })().catch((err) => {\n            console.warn('[PlanetScene] Failed to restore from envelope:', err);\n            return null;\n        });\n        return this._sceneStateRestorePromise;\n    }\n\n    /**\n     * Initialize avatar systems asynchronously\n     */\n    async _initAvatarSystems() {\n        if (this._avatarInitializationPromise) return this._avatarInitializationPromise;\n        this._avatarInitializationPromise = this._startAvatarSystems();\n        const initialized = await this._avatarInitializationPromise;\n        if (!initialized) this._avatarInitializationPromise = null;\n        return initialized;\n    }\n\n    async _startAvatarSystems() {\n        try {\n            // Initialize LocalPlayer\n            const localReady = await this._localPlayer?.init();\n            if (localReady) {\n                console.log('[PlanetScene] LocalPlayer initialized');\n            }\n\n            // Initialize PeerManager\n            const peerReady = await this._peerManager?.init();\n            if (peerReady) {\n                console.log('[PlanetScene] PeerManager initialized');\n            }\n\n            if (this._avatarConfig && Object.keys(this._avatarConfig).length > 0) {\n                this._localPlayer?.applyConfig?.(this._avatarConfig);\n                this._peerManager?.applyConfig?.(this._avatarConfig);\n                this._presenceSystem?.setAvatarConfig?.(this._avatarConfig);\n            }\n\n            // Presence may have received peers while the rig was deferred.\n            // Hydrate the current states so no peer update is lost.\n            for (const [peerId, entry] of (this._presenceSystem?._peers || [])) {\n                if (entry?.state) this._peerManager?.handlePeerUpdate?.(peerId, entry.state);\n            }\n\n            this.eventBus?.emit?.('avatars:ready', {\n                localPlayer: localReady,\n                peerManager: peerReady\n            });\n            return !!(localReady || peerReady);\n        } catch (error) {\n            console.error('[PlanetScene] Avatar system init failed:', error);\n            this.eventBus?.emit?.('avatars:error', { error });\n            return false;\n        }\n    }\n\n    /**\n     * Spline API - Create connections between points on the globe\n     */\n    createSpline(config) {\n        return this._splineSubsystem?.createSpline(config);\n    }\n\n    createSplineBetweenAssets(asset1, asset2, config = {}) {\n        return this._splineSubsystem?.createAssetRelationship(asset1, asset2, config);\n    }\n\n    getSpline(id) {\n        return this._splineSubsystem?.getSpline(id);\n    }\n\n    updateSpline(id, props) {\n        this._splineSubsystem?.updateSpline(id, props);\n    }\n\n    removeSpline(id) {\n        this._splineSubsystem?.removeSpline(id);\n    }\n\n    // ─────────────────────────────────────────────────────────────\n    // View State Management (migrated from UIController)\n    // ─────────────────────────────────────────────────────────────\n\n    captureAgentViewImage({ width = 320, height = 180 } = {}) {\n        if (!this._renderer || !this._scene || !this._camera || typeof document === 'undefined') {\n            return { ok: false, error: 'renderer unavailable' };\n        }\n        const w = Math.max(64, Math.min(320, Math.floor(Number(width) || 320)));\n        const h = Math.max(64, Math.min(180, Math.floor(Number(height) || 180)));\n        const target = new THREE.WebGLRenderTarget(w, h, {\n            format: THREE.RGBAFormat,\n            type: THREE.UnsignedByteType,\n            depthBuffer: true,\n            stencilBuffer: false,\n        });\n        const pixels = new Uint8Array(w * h * 4);\n        const previousTarget = this._renderer.getRenderTarget?.() || null;\n        const previousXr = this._renderer.xr ? this._renderer.xr.enabled : null;\n        const previousAutoClear = this._renderer.autoClear;\n        try {\n            if (this._renderer.xr) this._renderer.xr.enabled = false;\n            this._renderer.autoClear = true;\n            this._renderer.setRenderTarget(target);\n            this._renderer.clear(true, true, true);\n            this._renderer.render(this._scene, this._camera);\n            this._renderer.readRenderTargetPixels(target, 0, 0, w, h, pixels);\n            const canvas = document.createElement('canvas');\n            canvas.width = w;\n            canvas.height = h;\n            const context = canvas.getContext('2d');\n            if (!context) return { ok: false, error: 'canvas unavailable' };\n            const imageData = context.createImageData(w, h);\n            const rowBytes = w * 4;\n            for (let y = 0; y < h; y += 1) {\n                const source = (h - 1 - y) * rowBytes;\n                imageData.data.set(pixels.subarray(source, source + rowBytes), y * rowBytes);\n            }\n            context.putImageData(imageData, 0, 0);\n            return {\n                ok: true,\n                width: w,\n                height: h,\n                mime: 'image/jpeg',\n                dataUrl: canvas.toDataURL('image/jpeg', 0.72),\n            };\n        } catch (error) {\n            return { ok: false, error: String(error?.message || error) };\n        } finally {\n            this._renderer.setRenderTarget(previousTarget);\n            if (this._renderer.xr && previousXr !== null) this._renderer.xr.enabled = previousXr;\n            this._renderer.autoClear = previousAutoClear;\n            target.dispose();\n        }\n    }\n\n    captureViewState({ includeElevationCache = false } = {}) {\n        // Map-only navigation persists its geographic URL separately. There\n        // is no 3D camera snapshot to replace the user's last valid pose.\n        if (!this._camera) return null;\n        const rawMode = this._surfaceController?.getCameraMode?.() || 'orbit';\n        const mode = (rawMode === 'surface' || rawMode === 'toSurface') ? 'surface' : 'orbit';\n\n        const camera = this._camera;\n        const controls = this._surfaceController ? this._surfaceController.controls : null;\n        const target = controls ? controls.target.clone() : new THREE.Vector3();\n        const worldPos = camera?.userData?.worldPosition;\n        const camPos = worldPos ? worldPos.clone() : camera.position.clone();\n        const camQuat = new THREE.Quaternion();\n        camera.getWorldQuaternion(camQuat);\n        const surfacePos = this._surfaceController ? this._surfaceController.getSurfacePosition() : null;\n        const planetGroup = this._triTree?.group || null;\n        const lodMode = this._surfaceController?.getLODMode?.() || 'orbit';\n        const surfaceAltitude = this._surfaceController?.getSurfaceAltitudeMeters?.() ?? null;\n        const surfaceTerrainRadius = surfacePos ? surfacePos.length() : null;\n        const surfaceLatLon = surfacePos ? worldPosToLatLonLocal(surfacePos, planetGroup) : null;\n        const renderedSurfaceLatLon = mode === 'surface'\n            ? worldPosToLatLonLocal(camPos, planetGroup)\n            : null;\n        const activeCameraTransition = this._surfaceController?.camTransition || null;\n        let cameraTransition = null;\n        if (activeCameraTransition) {\n            const elapsedMs = Math.max(0, performance.now() - activeCameraTransition.t0);\n            const durationMs = Math.max(0, Number(activeCameraTransition.dur) || 0);\n            const destination = activeCameraTransition.endPos\n                ? worldPosToLatLonLocal(activeCameraTransition.endPos, planetGroup)\n                : null;\n            cameraTransition = {\n                active: true,\n                nextMode: activeCameraTransition.nextMode || null,\n                elapsedMs,\n                durationMs,\n                progress: durationMs > 0 ? THREE.MathUtils.clamp(elapsedMs / durationMs, 0, 1) : 1,\n                destinationLatLon: destination\n                    ? { lat: destination.latDeg, lon: destination.lonDeg }\n                    : null,\n            };\n        }\n\n        let orbitLatLon = null;\n        let orbitRadius = null;\n        if (mode === 'orbit') {\n            orbitRadius = camPos.length();\n            const viewDir = new THREE.Vector3();\n            camera.getWorldDirection(viewDir);\n            const hit = rayEllipsoidIntersection(camPos, viewDir, planetGroup) ||\n                raySphereIntersection(camPos, viewDir);\n            const baseRadius = ellipsoidRadiusForWorldDir(camPos, planetGroup);\n            const targetPos = hit || camPos.clone().normalize().multiplyScalar(baseRadius);\n            orbitLatLon = worldPosToLatLonLocal(targetPos, planetGroup);\n        }\n\n        let surfaceOrientation = null;\n        if (mode === 'surface' && this._surfaceController && this._surfaceController.surfaceState) {\n            surfaceOrientation = {\n                yaw: this._surfaceController.surfaceState.yaw,\n                pitch: this._surfaceController.surfaceState.pitch\n            };\n        }\n\n        let vrState = null;\n        const isVRMode = this._surfaceController?.isVRMode?.() ?? false;\n        if (isVRMode || this._sceneInitializer?.isXRPresenting?.()) {\n            const dolly = this._sceneInitializer?.vrDolly;\n            if (dolly) {\n                vrState = {\n                    wasInVR: true,\n                    dollyPosition: { x: dolly.position.x, y: dolly.position.y, z: dolly.position.z },\n                    dollyRotationY: dolly.rotation.y\n                };\n            }\n        }\n\n        return {\n            mode,\n            cameraMode: rawMode,\n            lodMode,\n            camera: { x: camPos.x, y: camPos.y, z: camPos.z },\n            quaternion: { x: camQuat.x, y: camQuat.y, z: camQuat.z, w: camQuat.w },\n            target: { x: target.x, y: target.y, z: target.z },\n            surface: surfacePos ? { x: surfacePos.x, y: surfacePos.y, z: surfacePos.z } : null,\n            surfaceLatLon: surfaceLatLon ? { lat: surfaceLatLon.latDeg, lon: surfaceLatLon.lonDeg } : null,\n            renderedSurfaceLatLon: renderedSurfaceLatLon\n                ? { lat: renderedSurfaceLatLon.latDeg, lon: renderedSurfaceLatLon.lonDeg }\n                : null,\n            cameraTransition,\n            surfaceOrientation,\n            surfaceAltitude,\n            surfaceTerrainRadius,\n            orbitLatLon: orbitLatLon ? { lat: orbitLatLon.latDeg, lon: orbitLatLon.lonDeg } : null,\n            orbitRadius,\n            vrState\n        };\n    }\n\n    _applyViewStateSnapshot(state, { updateUrl = true, applyElevationCache = true, allowPersistToggle = true } = {}) {\n        if (!state || !state.camera) {\n            console.warn('[VIEW STATE] Invalid state - missing camera data');\n            return;\n        }\n\n        if (this._triTree && this._lightingSystem\n            && typeof this._triTree.setEarthRotation === 'function'\n            && typeof this._lightingSystem.getEarthRotationAngle === 'function') {\n            const angle = this._lightingSystem.getEarthRotationAngle();\n            this._triTree.setEarthRotation(angle);\n            this._triTree.group?.updateMatrixWorld?.(true);\n        }\n\n        const { camera: savedCamera, target, surface, mode } = state;\n\n        const isSurfaceMode = mode === 'surface' && this._surfaceController;\n        const lodMode = isSurfaceMode ? 'zoom' : (state.lodMode || 'orbit');\n        if (this._surfaceController && typeof this._surfaceController.setLODMode === 'function') {\n            this._surfaceController.setLODMode(lodMode);\n        }\n\n        // Sync LOD buttons\n        const btnLodOrbit = document.getElementById('btnLodOrbit');\n        const btnLodZoom = document.getElementById('btnLodZoom');\n        if (btnLodOrbit && btnLodZoom) {\n            btnLodOrbit.classList.toggle('active', lodMode === 'orbit');\n            btnLodZoom.classList.toggle('active', lodMode === 'zoom');\n        }\n        this.uiController?.syncLodButtons?.();\n\n        const resolveWorldDirFromLatLon = (lat, lon) => {\n            if (!Number.isFinite(lat) || !Number.isFinite(lon)) return null;\n            const localDir = latLonToLocalDir(lat, lon);\n            if (this._triTree?.group && typeof this._triTree.group.getWorldQuaternion === 'function') {\n                const worldQuat = this._triTree.group.getWorldQuaternion(new THREE.Quaternion());\n                return localDir.applyQuaternion(worldQuat);\n            }\n            return localDir;\n        };\n\n        if (isSurfaceMode && typeof this._surfaceController.initializeSurfaceMode === 'function') {\n            console.log('[VIEW STATE] Saved state indicates surface mode, activating surface controls...');\n\n            const yaw = state.surfaceOrientation ? state.surfaceOrientation.yaw : 0;\n            const pitch = state.surfaceOrientation ? state.surfaceOrientation.pitch : 0;\n\n            const surfaceLatLon = state.surfaceLatLon;\n            let surfaceDir = null;\n            if (surfaceLatLon && Number.isFinite(surfaceLatLon.lat) && Number.isFinite(surfaceLatLon.lon)) {\n                surfaceDir = resolveWorldDirFromLatLon(surfaceLatLon.lat, surfaceLatLon.lon);\n            }\n\n            const surfaceVec = (surface && Number.isFinite(surface.x) && Number.isFinite(surface.y) && Number.isFinite(surface.z))\n                ? new THREE.Vector3(surface.x, surface.y, surface.z)\n                : null;\n            const cameraVec = new THREE.Vector3(savedCamera.x, savedCamera.y, savedCamera.z);\n            if (!surfaceDir) {\n                surfaceDir = surfaceVec && surfaceVec.lengthSq() > 0\n                    ? surfaceVec.clone().normalize()\n                    : cameraVec;\n                if (surfaceDir.lengthSq() > 0) {\n                    surfaceDir.normalize();\n                } else {\n                    surfaceDir = new THREE.Vector3(0, 1, 0);\n                }\n            }\n\n            const terrainRadius = Number.isFinite(state.surfaceTerrainRadius)\n                ? state.surfaceTerrainRadius\n                : (surfaceVec ? surfaceVec.length() : null);\n            const altitude = Number.isFinite(state.surfaceAltitude)\n                ? state.surfaceAltitude\n                : null;\n\n            const restoreLease = this._beginUrlViewStateLease('restore-view-state');\n\n            this._surfaceController.initializeSurfaceMode(surfaceDir, yaw, pitch, altitude, terrainRadius);\n\n            if (this._triTree && typeof this._triTree.initializeSurfaceLODCascade === 'function') {\n                this._triTree.initializeSurfaceLODCascade();\n            }\n\n            this._handleSurfaceEnter({\n                reason: 'restore',\n                focusDir: this._surfaceController?.surfaceState?.up,\n            });\n\n            this._urlViewStateCompletionTimer = setTimeout(() => {\n                if (!this._finishUrlViewStateLease(restoreLease, 'restore-view-state')) return;\n                console.log('[VIEW STATE] Initialization complete, state saves now enabled');\n                if (updateUrl) {\n                    this._updateUrlFromView({ force: true });\n                }\n            }, 500);\n        } else {\n            const orbitLatLon = state.orbitLatLon;\n            const orbitRadius = Number.isFinite(state.orbitRadius) ? state.orbitRadius : null;\n            const orbitDir = (orbitLatLon && Number.isFinite(orbitLatLon.lat) && Number.isFinite(orbitLatLon.lon))\n                ? resolveWorldDirFromLatLon(orbitLatLon.lat, orbitLatLon.lon)\n                : null;\n\n            if (orbitDir && orbitRadius) {\n                const pos = orbitDir.multiplyScalar(orbitRadius);\n                this._camera.position.copy(pos);\n                this._camera.lookAt(0, 0, 0);\n                if (this._surfaceController && this._surfaceController.controls) {\n                    this._surfaceController.controls.target.set(0, 0, 0);\n                    this._surfaceController.controls.update();\n                }\n            } else {\n                this._camera.position.set(savedCamera.x, savedCamera.y, savedCamera.z);\n\n                if (state.quaternion) {\n                    this._camera.quaternion.set(\n                        state.quaternion.x,\n                        state.quaternion.y,\n                        state.quaternion.z,\n                        state.quaternion.w\n                    );\n                }\n\n                if (this._surfaceController && this._surfaceController.controls && target) {\n                    this._surfaceController.controls.target.set(target.x, target.y, target.z);\n                    this._surfaceController.controls.update();\n                }\n            }\n        }\n\n        // Restore VR dolly position\n        if (state.vrState && state.vrState.wasInVR && this._sceneInitializer?.vrDolly) {\n            const dolly = this._sceneInitializer.vrDolly;\n            const dollyPos = state.vrState.dollyPosition;\n            if (dollyPos && Number.isFinite(dollyPos.x) && Number.isFinite(dollyPos.y) && Number.isFinite(dollyPos.z)) {\n                dolly.position.set(dollyPos.x, dollyPos.y, dollyPos.z);\n            }\n            if (Number.isFinite(state.vrState.dollyRotationY)) {\n                dolly.rotation.set(0, state.vrState.dollyRotationY, 0);\n            }\n            dolly.updateMatrixWorld(true);\n        }\n\n        const cfgStatePersist = document.getElementById('cfg-statePersist');\n        if (allowPersistToggle && cfgStatePersist) cfgStatePersist.checked = true;\n        if (updateUrl) {\n            this._updateUrlFromView({ force: true });\n        }\n    }\n\n    _restoreViewState() {\n        const raw = localStorage.getItem('nkn.globe.state');\n        if (!raw) return;\n        let state = null;\n        try {\n            state = JSON.parse(raw);\n        } catch (e) {\n            console.warn('[VIEW STATE] Failed to parse saved view state', e);\n            return;\n        }\n        this._applyViewStateSnapshot(state, { updateUrl: true, applyElevationCache: true, allowPersistToggle: true });\n    }\n\n    // ─────────────────────────────────────────────────────────────\n    // URL State Sync (migrated from UIController)\n    // ─────────────────────────────────────────────────────────────\n\n    _readUrlViewState() {\n        if (typeof window === 'undefined') return null;\n        const params = new URLSearchParams(window.location.search);\n        // Black Sun framework: ?metaverse=1&port=N supersedes\n        // latitude/longitude/altitude. If metaverse mode is requested,\n        // return a state that carries only the metaverse fields. The\n        // caller dispatches to the metaverse spawn instead of the\n        // surface controller.\n        const metaverseParam = params.get('metaverse');\n        if (metaverseParam === '1' || metaverseParam === 'true') {\n            const portRaw = Number.parseInt(params.get('port'), 10);\n            const port = Number.isFinite(portRaw)\n                ? Math.max(0, Math.min(65535, portRaw))\n                : 0;\n            return {\n                metaverse: true,\n                port,\n                lat: null,\n                lon: null,\n                altitude: null,\n                headingDeg: null,\n                pitchDeg: null,\n                hasOrientation: false,\n                body: null,\n            };\n        }\n        const body = params.get('body');\n        const urlLatLon = resolveUrlLatLonParams(params);\n        const hasLatLon = !!urlLatLon;\n        if (!hasLatLon && !body) return null;\n        const altitudeRaw = Number.parseFloat(params.get('altitude'));\n        const heading = Number.parseFloat(params.get('heading'));\n        const pitch = Number.parseFloat(params.get('pitch'));\n        const hasHeading = Number.isFinite(heading);\n        const hasPitch = Number.isFinite(pitch);\n        const validBodies = ['terra', 'luna', 'sol'];\n        // Reject bogus altitudes (e.g. from a stale URL generated by a\n        // collapsed camera state) before they can re-seed the\n        // controller. Mirror the bounds used in _updateUrlFromView.\n        const ALT_URL_MIN = VIEW_ALTITUDE_MIN_M;\n        const ALT_URL_MAX = VIEW_ALTITUDE_MAX_M;\n        const altitude = Number.isFinite(altitudeRaw)\n            && altitudeRaw >= ALT_URL_MIN\n            && altitudeRaw <= ALT_URL_MAX\n                ? altitudeRaw\n                : null;\n        return {\n            lat: hasLatLon ? urlLatLon.lat : null,\n            lon: hasLatLon ? urlLatLon.lon : null,\n            altitude: Number.isFinite(altitude) ? altitude : null,\n            headingDeg: hasHeading ? heading : null,\n            pitchDeg: hasPitch ? pitch : null,\n            hasOrientation: hasHeading || hasPitch,\n            body: (body && validBodies.includes(body.toLowerCase())) ? body.toLowerCase() : null\n        };\n    }\n\n    _getUrlViewState() {\n        return this._readUrlViewState() || this._urlViewState || null;\n    }\n\n    _syncEarthRotationForUrl() {\n        if (!this._triTree || !this._triTree.group) return;\n        if (!this._lightingSystem || typeof this._lightingSystem.getEarthRotationAngle !== 'function') return;\n        const angle = this._lightingSystem.getEarthRotationAngle();\n        if (!Number.isFinite(angle)) return;\n        if (typeof this._triTree.setEarthRotation === 'function') {\n            this._triTree.setEarthRotation(angle);\n        } else {\n            this._triTree.group.rotation.y = angle;\n        }\n        this._triTree.group.updateMatrixWorld?.(true);\n    }\n\n    _applyUrlViewState(stateOverride = null, { store = true } = {}) {\n        const state = stateOverride || this._readUrlViewState();\n        if (!state) return false;\n        if (this._urlViewStateApplying) return true;\n        const leaseId = this._beginUrlViewStateLease('url-view-state');\n\n        // Metaverse mode (Black Sun framework) takes precedence over the\n        // Earth-coords path. If metaverse=1 is in the URL, switch the\n        // scene mode and spawn at the requested port.\n        if (state.metaverse === true) {\n            const port = Number.isFinite(state.port) ? state.port : 0;\n            this._metaversePort = port;\n            this.setSceneMode('metaverse');\n            // Clear init-blocking flags — metaverse mode does not use the\n            // surface-controller URL-enforce window.\n            this._finishUrlViewStateLease(leaseId, 'metaverse');\n            return true;\n        }\n\n        if (!this._surfaceController || typeof this._surfaceController.initializeSurfaceModeFromLatLon !== 'function') {\n            this._finishUrlViewStateLease(leaseId, 'missing-surface-controller');\n            return false;\n        }\n\n        if (state.body && state.body !== 'terra' && typeof this._surfaceController.setBodyAnchorImmediate === 'function') {\n            this._surfaceController.setBodyAnchorImmediate(state.body);\n        }\n\n        if ((state.body && state.body !== 'terra') || state.lat === null || state.lon === null) {\n            this._finishUrlViewStateLease(leaseId, 'non-terra-or-empty-coordinates');\n            return true;\n        }\n\n        this._syncEarthRotationForUrl();\n\n        const altitude = Number.isFinite(state.altitude) ? state.altitude : null;\n        const hasHeading = Number.isFinite(state.headingDeg);\n        const hasPitch = Number.isFinite(state.pitchDeg);\n        const hasOrientation = state.hasOrientation || hasHeading || hasPitch;\n        const surfaceThreshold = Number.isFinite(this._surfaceController?.SURFACE_ALTITUDE_MAX)\n            ? this._surfaceController.SURFACE_ALTITUDE_MAX\n            : 100000;\n        const hasAltitude = Number.isFinite(altitude);\n        const useSurface = (hasAltitude && altitude <= surfaceThreshold)\n            || (!hasAltitude && hasOrientation);\n\n        if (store) {\n            this._urlViewState = state;\n            this._urlViewStateMode = useSurface ? 'surface' : 'orbit';\n            this._urlViewStateEnforceUntilMs = Date.now() + 5000;\n            this._urlViewStateAttempts = 0;\n        }\n\n        if (useSurface) {\n            const yaw = hasHeading ? THREE.MathUtils.degToRad(state.headingDeg) : 0;\n            const pitch = hasPitch ? THREE.MathUtils.degToRad(state.pitchDeg) : 0;\n\n            const upDir = latLonToLocalDir(state.lat, state.lon);\n            if (this._triTree?.group?.getWorldQuaternion) {\n                const planetQuat = new THREE.Quaternion();\n                this._triTree.group.getWorldQuaternion(planetQuat);\n                upDir.applyQuaternion(planetQuat);\n            }\n            const terrainR = this._surfaceController?.sampleTerrainRadiusForDir\n                ? this._surfaceController.sampleTerrainRadiusForDir(upDir)\n                : PLANET_RADIUS;\n            const ellipsoidR = ellipsoidRadiusForWorldDir(upDir, this._triTree?.group);\n            const terrainElev = Number.isFinite(terrainR) ? (terrainR - ellipsoidR) : 0;\n            // URL altitude is the displayed surface altitude (above terrain).\n            // Don't subtract terrainElev — that was already factored in when the URL was written.\n            // Subtracting it caused altitude to double on reload when terrain wasn't loaded yet.\n            let surfaceAlt = Number.isFinite(altitude) ? altitude : null;\n            const minSurfaceAlt = Number.isFinite(this._surfaceController?.SURFACE_ALTITUDE_MIN)\n                ? this._surfaceController.SURFACE_ALTITUDE_MIN\n                : 1.6;\n            if (Number.isFinite(surfaceAlt)) {\n                surfaceAlt = Math.max(minSurfaceAlt, surfaceAlt);\n            }\n            this._surfaceController.initializeSurfaceModeFromLatLon(\n                state.lat,\n                state.lon,\n                terrainR,\n                yaw,\n                pitch,\n                surfaceAlt\n            );\n            // Don't call setSurfaceAltitudeMSL here — initializeSurfaceModeFromLatLon already\n            // set the altitude via surfaceAlt. Calling setSurfaceAltitudeMSL with the same value\n            // caused a double-application when terrain elevation was involved.\n            if (this._triTree && typeof this._triTree.initializeSurfaceLODCascade === 'function') {\n                this._triTree.initializeSurfaceLODCascade();\n            }\n            this._handleSurfaceEnter({\n                reason: 'url',\n                focusDir: this._surfaceController?.surfaceState?.up,\n            });\n            this._urlViewStateCompletionTimer = setTimeout(() => {\n                if (!this._finishUrlViewStateLease(leaseId, 'surface-url-view-state')) return;\n                if (!this._urlViewState || Date.now() > this._urlViewStateEnforceUntilMs) {\n                    this._updateUrlFromView({ force: true });\n                }\n            }, 500);\n            return true;\n        }\n\n        const dir = latLonToLocalDir(state.lat, state.lon);\n        if (this._triTree?.group?.getWorldQuaternion) {\n            const planetQuat = new THREE.Quaternion();\n            this._triTree.group.getWorldQuaternion(planetQuat);\n            dir.applyQuaternion(planetQuat);\n        }\n        const ellipsoidR = ellipsoidRadiusForWorldDir(dir, this._triTree?.group);\n        const baseRadius = Number.isFinite(altitude)\n            ? ellipsoidR + altitude\n            : (this._camera?.position?.length?.() || PLANET_RADIUS + surfaceThreshold);\n        const pos = dir.multiplyScalar(baseRadius);\n        this._camera.position.copy(pos);\n        this._camera.lookAt(0, 0, 0);\n        if (this._surfaceController?.setLODMode) {\n            this._surfaceController.setLODMode('orbit');\n        }\n        if (this._surfaceController?.controls) {\n            this._surfaceController.controls.target.set(0, 0, 0);\n            this._surfaceController.controls.update();\n        }\n\n        this._finishUrlViewStateLease(leaseId, 'orbit-url-view-state');\n        if (!this._urlViewState || Date.now() > this._urlViewStateEnforceUntilMs) {\n            this._updateUrlFromView({ force: true });\n        }\n        return true;\n    }\n\n    _enforceUrlViewState() {\n        if (!this._urlViewState || this._urlViewStateApplying || this._initializingViewState) return;\n        if (Date.now() > this._urlViewStateEnforceUntilMs) {\n            this._urlViewState = null;\n            this._urlViewStateMode = null;\n            return;\n        }\n        const wantsSurface = this._urlViewStateMode === 'surface';\n        const inSurface = !!this._surfaceController?.isInSurfaceMode?.();\n        if (wantsSurface && !inSurface) {\n            if (this._urlViewStateAttempts >= this._urlViewStateMaxAttempts) {\n                this._urlViewState = null;\n                this._urlViewStateMode = null;\n                return;\n            }\n            this._urlViewStateAttempts += 1;\n            this._applyUrlViewState(this._urlViewState, { store: false });\n        }\n    }\n\n    // ── Black Sun framework — Phase 1: scene-mode switch ──────────────\n    //\n    // setSceneMode('earth' | 'metaverse') flips the rendered universe\n    // between the photoreal Earth (default) and the canonical Snow Crash\n    // black-sphere Metaverse. Mode changes hide the Earth pipeline and\n    // attach the Metaverse scene; reverse on switch back. See\n    // .aiwg/blacksun/02-street-geometry.md and 08-noclip-implementation.md.\n\n    getSceneMode() {\n        return this._sceneMode;\n    }\n\n    setSceneMode(mode) {\n        const next = mode === 'metaverse' ? 'metaverse' : 'earth';\n        if (next === this._sceneMode) return;\n        if (next === 'metaverse') {\n            this._enterMetaverseMode();\n        } else {\n            this._exitMetaverseMode();\n        }\n        this._sceneMode = next;\n        try {\n            // Notify any UI consumers (HUD toggle button, agents, etc.).\n            window.dispatchEvent(new CustomEvent('noclip:scene-mode', {\n                detail: { mode: next },\n            }));\n        } catch { /* ignore */ }\n        if (typeof this._updateUrlFromView === 'function') {\n            this._updateUrlFromView({ force: true });\n        }\n    }\n\n    setMetaversePort(portIndex) {\n        const idx = Math.max(0, Math.min(65535, Math.floor(portIndex || 0)));\n        this._metaversePort = idx;\n        if (this._sceneMode === 'metaverse' && this._metaverseScene) {\n            this._metaverseScene.spawnAtPort(idx);\n        }\n    }\n\n    getMetaversePort() {\n        return this._metaversePort;\n    }\n\n    _enterMetaverseMode() {\n        // Hide the Earth pipeline. We do not destroy it — the user can\n        // toggle back instantly. Hiding worldRoot suppresses all Earth\n        // geometry; pausing the photoreal tile loader prevents continued\n        // network activity while in the Metaverse.\n        if (this._worldRoot) this._worldRoot.visible = false;\n        if (this._triTree?.setActive) {\n            try { this._triTree.setActive(false); } catch { /* ignore */ }\n        }\n        if (this._scene && this._scene.background !== undefined) {\n            this._metaverseSavedBackground = this._scene.background;\n            this._scene.background = new THREE.Color(0x000000);\n        }\n        // Atmosphere is part of the Earth pipeline — hide if available.\n        if (this._sceneInitializer?.atmosphereGroup) {\n            this._sceneInitializer.atmosphereGroup.visible = false;\n        }\n        // Build/attach the metaverse scene.\n        if (!this._metaverseScene) {\n            this._metaverseScene = new MetaverseScene({\n                scene: this._scene,\n                camera: this._camera,\n            });\n        }\n        this._metaverseScene.attach();\n        this._metaverseScene.spawnAtPort(this._metaversePort);\n    }\n\n    _exitMetaverseMode() {\n        if (this._metaverseScene) {\n            this._metaverseScene.detach();\n        }\n        if (this._scene && this._metaverseSavedBackground !== null) {\n            this._scene.background = this._metaverseSavedBackground;\n            this._metaverseSavedBackground = null;\n        }\n        if (this._sceneInitializer?.atmosphereGroup) {\n            this._sceneInitializer.atmosphereGroup.visible = true;\n        }\n        if (this._triTree?.setActive) {\n            try { this._triTree.setActive(true); } catch { /* ignore */ }\n        }\n        if (this._worldRoot) this._worldRoot.visible = true;\n    }\n\n    _syncCelestialSummaryLabel() {\n        const body = this._surfaceController?.getBodyAnchor?.() || 'terra';\n        let label = 'EARTH';\n        let radius = PLANET_RADIUS;\n        let target = this._celestialLabelPosition.set(0, 0, 0);\n\n        if (body === 'luna') {\n            label = 'MOON';\n            radius = this._moonSystem?.moonMesh?.geometry?.parameters?.radius || 1_737_400;\n            const moonMesh = this._moonSystem?.moonMesh;\n            if (moonMesh?.getWorldPosition) {\n                moonMesh.getWorldPosition(target);\n            } else if (this._moonSystem?.position) {\n                target.copy(this._moonSystem.position);\n            }\n        } else if (body === 'sol') {\n            label = 'SOL';\n            radius = this._sceneInitializer?.sunMesh?.geometry?.parameters?.radius || 696_340_000;\n            const sunMesh = this._sceneInitializer?.sunMesh;\n            if (sunMesh?.getWorldPosition) {\n                sunMesh.getWorldPosition(target);\n            } else if (this._lightingSystem?.sun?.position) {\n                target.copy(this._lightingSystem.sun.position);\n            }\n        } else if (this._triTree?.group?.getWorldPosition) {\n            this._triTree.group.getWorldPosition(target);\n        }\n\n        getLabelSystem().setCelestialSummary({ body, label, position: target, radius });\n        if (body === 'luna' && !this._lunarFeatureLabels && this._moonSystem?.moonMesh) {\n            this._lunarFeatureLabels = new LunarFeatureLabels({ moonSystem: this._moonSystem, labels: getLabelSystem() });\n        }\n        this._lunarFeatureLabels?.update(this._camera, {\n            focused: body === 'luna', now: performance.now(),\n            height: this._renderer?.domElement?.clientHeight || 800,\n        });\n        this._sceneInitializer?.setAstronomicalLensFlareSuppressed?.(body === 'sol');\n    }\n\n    _updateUrlFromView({ force = false } = {}) {\n        if (typeof window === 'undefined') return;\n        if (!this._urlSyncEnabled) return;\n        // Diagnostic counters — used by Playwright tests + production\n        // debugging to see why URL state failed to update without\n        // having to instrument from the outside.\n        if (!this._urlWriteDiag) this._urlWriteDiag = { calls: 0, exit: null, lastWritten: null };\n        this._urlWriteDiag.calls++;\n        this._urlWriteDiag.exit = 'enter';\n        if (this._initializingViewState || this._urlViewStateApplying) {\n            this._urlWriteDiag.exit = 'initializing-view-state';\n            return;\n        }\n        this._enforceUrlViewState();\n\n        const camera = this._camera;\n        if (!camera) { this._urlWriteDiag.exit = 'no-camera'; return; }\n\n        // Metaverse mode (Black Sun framework) — write metaverse=1&port=N\n        // and strip Earth-specific params (latitude/longitude/altitude/\n        // heading/pitch). The reader at _readUrlViewState mirrors this:\n        // metaverse=1 supersedes the Earth params on load.\n        if (this._sceneMode === 'metaverse') {\n            const params = new URLSearchParams(window.location.search);\n            params.set('metaverse', '1');\n            const port = Number.isFinite(this._metaversePort) ? this._metaversePort : 0;\n            params.set('port', String(Math.max(0, Math.min(65535, port | 0))));\n            params.delete('latitude');\n            params.delete('longitude');\n            params.delete('lat');\n            params.delete('lon');\n            params.delete('lng');\n            params.delete('altitude');\n            params.delete('heading');\n            params.delete('pitch');\n            params.delete('body');\n            const nextUrl = `${window.location.pathname}?${params.toString()}${window.location.hash || ''}`;\n            if (!force && nextUrl === this._urlStateLast) {\n                this._urlWriteDiag.exit = 'unchanged';\n                return;\n            }\n            this._urlStateLast = nextUrl;\n            window.history.replaceState(null, '', nextUrl);\n            this._urlWriteDiag.exit = 'wrote';\n            this._urlWriteDiag.lastWritten = port;\n            return;\n        }\n\n        const bodyAnchor = this._surfaceController?.getBodyAnchor?.() || 'terra';\n        if (bodyAnchor !== 'terra') {\n            const params = new URLSearchParams(window.location.search);\n            params.set('body', bodyAnchor);\n            params.delete('latitude');\n            params.delete('longitude');\n            params.delete('lat');\n            params.delete('lon');\n            params.delete('lng');\n            params.delete('altitude');\n            params.delete('heading');\n            params.delete('pitch');\n            params.delete('metaverse');\n            params.delete('port');\n            const nextUrl = `${window.location.pathname}?${params.toString()}${window.location.hash || ''}`;\n            if (!force && nextUrl === this._urlStateLast) return;\n            this._urlStateLast = nextUrl;\n            window.history.replaceState(null, '', nextUrl);\n            return;\n        }\n\n        if (this._urlViewState && Date.now() <= this._urlViewStateEnforceUntilMs) {\n            const wantsSurface = this._urlViewStateMode === 'surface';\n            const inSurface = !!this._surfaceController?.isInSurfaceMode?.();\n            if ((wantsSurface && !inSurface) || (!wantsSurface && inSurface)) {\n                this._urlWriteDiag.exit = 'enforce-mode-mismatch';\n                return;\n            }\n        }\n\n        const planetGroup = this._triTree?.group || null;\n        // Use the camera's WORLD position, not its local one. The camera\n        // is parented inside vrDolly inside worldRoot (see\n        // scene-initializer.js#_initSceneObjects + PlanetScene parent\n        // setup). When dolly is at scene origin, local==world, but if\n        // dolly ever drifts off origin (post-VR teardown, surface-rig\n        // re-anchor, etc.), `camera.position.clone()` returns a small\n        // local offset and the URL writer ends up serializing\n        // `position - planetRadius ≈ -6.27M` as the altitude. Computing\n        // world position via getWorldPosition() walks the parent chain\n        // and is correct regardless of hierarchy state.\n        const camPos = camera.getWorldPosition(new THREE.Vector3());\n\n        let latLon = null;\n        if (this._surfaceController?.isInSurfaceMode?.()) {\n            const surfacePos = this._surfaceController.getSurfacePosition?.();\n            if (surfacePos) {\n                latLon = worldPosToLatLonLocal(surfacePos, planetGroup);\n            }\n        }\n\n        if (!latLon) {\n            const baseRadius = ellipsoidRadiusForWorldDir(camPos, planetGroup);\n            if (this._surfaceController?.isInSurfaceMode?.()) {\n                this._urlWriteDiag.exit = 'surface-no-latlon';\n                return;\n            }\n            const targetPos = camPos.clone().normalize().multiplyScalar(baseRadius);\n            latLon = worldPosToLatLonLocal(targetPos, planetGroup);\n        }\n\n        if (!latLon || !Number.isFinite(latLon.latDeg) || !Number.isFinite(latLon.lonDeg)) {\n            this._urlWriteDiag.exit = 'no-latlon';\n            return;\n        }\n\n        const inSurfaceMode = this._surfaceController?.isInSurfaceMode?.();\n        // Block URL writes only when surface mode is actively driven by\n        // unreliable terrain samples — i.e., the *non*-photoreal path\n        // where altitude is derived from terrain raycasts. In photoreal\n        // mode the URL altitude comes from the user-commanded\n        // `surfaceAltitudeMeters` (explicit scroll/keypress/intent),\n        // which is always safe to serialize regardless of terrain\n        // sampler health. Without this carve-out, scrolling in\n        // photoreal mode never updates the URL because the photo-tile\n        // raycaster reports unreliable on entry until many tiles load.\n        const photoActive = !!this._surfaceController?.photoTileGroup;\n        if (inSurfaceMode && !photoActive\n            && this._surfaceController\n            && this._surfaceController._terrainSampleReliable === false) {\n            this._urlWriteDiag.exit = 'terrain-unreliable';\n            return;\n        }\n        let altitude = null;\n        if (inSurfaceMode) {\n            // Read the controller's canonical commanded altitude\n            // directly. `surfaceAltitudeMeters` is the user-set value\n            // (eye-height default, scroll-adjusted, intent-driven) and\n            // is the SAME field the URL reader at _applyUrlViewState\n            // populates from inbound `altitude=` params. Reading it\n            // back unchanged makes URL ↔ camera round-trip stable\n            // regardless of photoreal sampler state, ground EMA, or\n            // terrain-tile health.\n            //\n            // Read the controller's already-resolved value without causing a\n            // second terrain query. It is commanded AGL while grounded and\n            // calculated AGL while fixed-ASL airborne glide owns placement.\n            altitude = this._surfaceController?.surfaceAltitudeMeters;\n            if (!Number.isFinite(altitude)) {\n                altitude = this._surfaceController?.getSurfaceAltitudeMSL?.();\n            }\n            const maxAlt = Number.isFinite(this._surfaceController?.SURFACE_ALTITUDE_MAX)\n                ? this._surfaceController.SURFACE_ALTITUDE_MAX\n                : null;\n            if (Number.isFinite(maxAlt) && Number.isFinite(altitude) && altitude > maxAlt) {\n                altitude = maxAlt;\n            }\n        } else {\n            const ellipsoidR = ellipsoidRadiusForWorldDir(camPos, planetGroup);\n            altitude = camPos.length() - ellipsoidR;\n            if (!Number.isFinite(altitude)) {\n                altitude = this._surfaceController?.surfaceAltitudeMeters;\n            }\n        }\n        const headingDeg = inSurfaceMode ? this._surfaceController?.getSurfaceHeadingDeg?.() : null;\n        const pitchDeg = inSurfaceMode ? this._surfaceController?.getSurfacePitchDeg?.() : null;\n\n        const params = new URLSearchParams(window.location.search);\n        const mapMode = String(window.__noclipMapMode || params.get('map') || '3d').toLowerCase() === '2d'\n            ? '2d'\n            : '3d';\n        window.__noclipMapMode = mapMode;\n        params.set('map', mapMode);\n        params.set('latitude', latLon.latDeg.toFixed(6));\n        params.set('longitude', latLon.lonDeg.toFixed(6));\n        params.delete('lat');\n        params.delete('lon');\n        params.delete('lng');\n        // Defensive bounds on the URL altitude value. A bad camera state\n        // (e.g. collapsed ECEF radius) must not be round-tripped through\n        // the URL where it would re-load as garbage. Reject anything\n        // outside the supported Earth camera navigation envelope.\n        // Values outside this range indicate a controller bug, not a\n        // legitimate camera position, and should not be serialized.\n        const ALT_URL_MIN = VIEW_ALTITUDE_MIN_M;        // Dead Sea region\n        const ALT_URL_MAX = VIEW_ALTITUDE_MAX_M;  // matches the astronomical camera envelope\n        const altitudeWriteable = Number.isFinite(altitude)\n            && altitude >= ALT_URL_MIN\n            && altitude <= ALT_URL_MAX;\n        if (altitudeWriteable) {\n            params.set('altitude', altitude.toFixed(2));\n            this._urlWriteDiag.lastWritten = altitude;\n        } else {\n            params.delete('altitude');\n            this._urlWriteDiag.exit = `altitude-not-writeable:${altitude}`;\n        }\n        if (Number.isFinite(headingDeg)) {\n            params.set('heading', headingDeg.toFixed(2));\n        } else {\n            params.delete('heading');\n        }\n        if (Number.isFinite(pitchDeg)) {\n            params.set('pitch', pitchDeg.toFixed(2));\n        } else {\n            params.delete('pitch');\n        }\n\n        params.delete('body');\n        // Strip metaverse-mode params when in Earth mode so a stale\n        // `?metaverse=1` from a previous session doesn't survive.\n        params.delete('metaverse');\n        params.delete('port');\n\n        const nextUrl = `${window.location.pathname}?${params.toString()}${window.location.hash || ''}`;\n        writeLastStartupLocation({\n            lat: latLon.latDeg,\n            lon: latLon.lonDeg,\n            altitude: altitudeWriteable ? altitude : null,\n            heading: headingDeg,\n            pitch: pitchDeg,\n        });\n        if (!force && nextUrl === this._urlStateLast) {\n            this._urlWriteDiag.exit = 'unchanged';\n            return;\n        }\n        this._urlStateLast = nextUrl;\n        window.history.replaceState(null, '', nextUrl);\n        this._urlWriteDiag.exit = 'wrote';\n    }\n\n    _setupUrlStateSync() {\n        if (typeof window === 'undefined') return;\n        if (!this._urlSyncEnabled) return;\n        this._teardownUrlStateSync({ keepLease: true });\n\n        // Diagnostic — exposed on window via __noclipScene for tests.\n        this._urlSyncDiag = {\n            setupCalled: true,\n            wheelBound: false,\n            throttledCalls: 0,\n            initBlocked: 0,\n        };\n\n        this._throttledUpdateUrlState = this._throttle(() => {\n            this._urlSyncDiag.throttledCalls++;\n            // Skip writes while the URL→camera enforcement window is\n            // active. This prevents serializing camera state that\n            // hasn't been driven from the inbound URL params yet.\n            if (this._initializingViewState) {\n                this._urlSyncDiag.initBlocked++;\n                return;\n            }\n            this._updateUrlFromView();\n        }, 500);\n\n        if (this._surfaceController && this._surfaceController.controls) {\n            this._urlSyncControls = this._surfaceController.controls;\n            this._urlSyncControls.addEventListener('change', this._throttledUpdateUrlState);\n        }\n\n        // OrbitControls only fires 'change' when its own internal state\n        // (target, azimuth, polar, distance) changes. In surface mode\n        // applySurfaceCamera writes camera.position directly — so wheel\n        // scrolling, which adjusts surfaceAltitudeMeters and re-places\n        // the camera each frame, never reaches the URL writer through\n        // the controls.change channel. Bind wheel events on the canvas\n        // and the surfaceAltitudeMeters poll below to close that gap\n        // so the URL altitude=… parameter stays live with scroll.\n        const canvas = this._renderer?.domElement;\n        if (canvas) {\n            this._urlSyncCanvas = canvas;\n            this._urlSyncWheelHandler = this._throttledUpdateUrlState;\n            this._urlSyncTouchHandler = this._throttledUpdateUrlState;\n            canvas.addEventListener('wheel', this._urlSyncWheelHandler, { passive: true });\n            // Touch-driven altitude pinch follows the same smoothed target\n            // path as wheel — bind touch events too.\n            canvas.addEventListener('touchmove', this._urlSyncTouchHandler, { passive: true });\n            this._urlSyncDiag.wheelBound = true;\n        }\n\n        // Per-frame fallback for altitude-only mutations that don't\n        // fire wheel events: Q/E keys, programmatic setSurfaceAltitude,\n        // intent dispatches, jump/teleport. We poll the surface\n        // controller's canonical altitude state at 200 ms cadence\n        // (well under the 500 ms throttle, so a Q-keypress reaches\n        // the URL within a couple of throttle windows). Gated on\n        // `cameraMode === 'surface'` AND `!_initializingViewState`\n        // so we never write during URL-driven scene boot — that was\n        // the source of stale-state writes the previous always-on\n        // poll produced.\n        this._lastUrlPolledAlt = null;\n        const pollAltitude = () => {\n            if (this._initializingViewState) return;\n            const sc = this._surfaceController;\n            if (!sc) return;\n            if (sc.cameraMode !== 'surface') return;\n            const alt = sc.surfaceAltitudeMeters;\n            if (!Number.isFinite(alt)) return;\n            if (this._lastUrlPolledAlt === null\n                || Math.abs(alt - this._lastUrlPolledAlt) >= 0.05) {\n                this._lastUrlPolledAlt = alt;\n                this._throttledUpdateUrlState();\n            }\n        };\n        if (this._urlAltitudePollInterval) clearInterval(this._urlAltitudePollInterval);\n        this._urlAltitudePollInterval = setInterval(pollAltitude, 200);\n\n        // Apply URL state on init for Black Sun metaverse URLs and for\n        // short Earth-coordinate aliases. The legacy UIController still\n        // handles canonical latitude/longitude links; it never learned\n        // lat/lon/lng aliases, so PlanetScene owns that path here.\n        const initialUrlState = this._readUrlViewState();\n        const initialParams = new URLSearchParams(window.location.search || '');\n        const hasShortEarthAliases = initialParams.has('lat') || initialParams.has('lon') || initialParams.has('lng');\n        if (initialUrlState && (initialUrlState.metaverse === true || hasShortEarthAliases)) {\n            this._applyUrlViewState(initialUrlState, { store: true });\n        } else if (!initialUrlState) {\n            this._updateUrlFromView({ force: true });\n        }\n    }\n\n    _throttle(fn, ms) {\n        let last = 0;\n        let timeout = null;\n        const throttled = (...args) => {\n            const now = Date.now();\n            const remaining = ms - (now - last);\n            if (remaining <= 0) {\n                if (timeout) { clearTimeout(timeout); timeout = null; }\n                last = now;\n                fn(...args);\n            } else if (!timeout) {\n                timeout = setTimeout(() => {\n                    last = Date.now();\n                    timeout = null;\n                    fn(...args);\n                }, remaining);\n            }\n        };\n        throttled.cancel = () => {\n            if (timeout) clearTimeout(timeout);\n            timeout = null;\n        };\n        return throttled;\n    }\n\n    _beginUrlViewStateLease(reason = 'url-view-state') {\n        this._cancelUrlViewStateLease({ invalidate: false });\n        const leaseId = ++this._urlViewStateLeaseId;\n        this._initializingViewState = true;\n        this._urlViewStateApplying = true;\n        this._urlViewStateWatchdogTimer = setTimeout(() => {\n            if (this._finishUrlViewStateLease(leaseId, `${reason}:watchdog`)\n                && globalThis.__noclipDebugUrlSync === true) {\n                console.warn(`[URL-SYNC] URL initialization lease ${leaseId} exceeded its watchdog window`);\n            }\n        }, 3000);\n        return leaseId;\n    }\n\n    _finishUrlViewStateLease(leaseId, _reason = 'complete') {\n        if (leaseId !== this._urlViewStateLeaseId) return false;\n        this._cancelUrlViewStateLease({ invalidate: false });\n        this._initializingViewState = false;\n        this._urlViewStateApplying = false;\n        return true;\n    }\n\n    _cancelUrlViewStateLease({ invalidate = true } = {}) {\n        if (this._urlViewStateCompletionTimer) clearTimeout(this._urlViewStateCompletionTimer);\n        if (this._urlViewStateWatchdogTimer) clearTimeout(this._urlViewStateWatchdogTimer);\n        this._urlViewStateCompletionTimer = null;\n        this._urlViewStateWatchdogTimer = null;\n        if (invalidate) this._urlViewStateLeaseId += 1;\n    }\n\n    _teardownUrlStateSync({ keepLease = false } = {}) {\n        if (this._urlAltitudePollInterval) clearInterval(this._urlAltitudePollInterval);\n        this._urlAltitudePollInterval = null;\n        this._urlSyncControls?.removeEventListener?.('change', this._throttledUpdateUrlState);\n        this._urlSyncCanvas?.removeEventListener?.('wheel', this._urlSyncWheelHandler);\n        this._urlSyncCanvas?.removeEventListener?.('touchmove', this._urlSyncTouchHandler);\n        this._urlSyncControls = null;\n        this._urlSyncCanvas = null;\n        this._urlSyncWheelHandler = null;\n        this._urlSyncTouchHandler = null;\n        this._throttledUpdateUrlState?.cancel?.();\n        if (!keepLease) {\n            this._cancelUrlViewStateLease();\n            this._initializingViewState = false;\n            this._urlViewStateApplying = false;\n        }\n    }\n\n    // ─────────────────────────────────────────────────────────────\n    // Surface Enter (migrated from UIController)\n    // ─────────────────────────────────────────────────────────────\n\n    _emitPhotoSurfaceEntryStatus(phase, detail = {}) {\n        if (!phase || phase === this._photoSurfaceEntryPhase) return;\n        this._photoSurfaceEntryPhase = phase;\n        this.eventBus?.emit?.('surface:photoreal-status', {\n            phase,\n            active: !['ready', 'cancelled', 'error'].includes(phase),\n            ...detail,\n        });\n    }\n\n    _getLivePhotoSurfaceFocusDirection() {\n        const liveDirection = this._surfaceController?.surfaceState?.up;\n        if (liveDirection?.isVector3 && liveDirection.lengthSq() > 0) {\n            return liveDirection;\n        }\n        return this._photoSurfaceEntryPending?.focusDir || null;\n    }\n\n    _beginPhotoSurfaceEntry(reason, focusDir = null) {\n        const photoConfig = this._photoDeferredConfig\n            || this._sceneSettings?.getSection?.('scene.terrain.photorealistic')\n            || {};\n        if (photoConfig.enabled === false) return;\n        if (this._mapPresentationMode === '2d') {\n            this._photoMapModeDeferred = true;\n            this._photoMapModeDeferredConfig = { ...photoConfig };\n            return;\n        }\n\n        const exactFocus = focusDir?.isVector3\n            ? focusDir\n            : this._surfaceController?.surfaceState?.up || null;\n        this._photoSurfaceEntryPending = {\n            reason: reason ? `surface-enter:${reason}` : 'surface-enter',\n            focusDir: exactFocus || null,\n            startedAt: typeof performance !== 'undefined' && performance.now\n                ? performance.now()\n                : Date.now(),\n        };\n        this._photoSurfaceEntryPhase = null;\n        this._photoInitializationPresentationHold = this._overviewGlobeMode === true || this._photoSatelliteFallback === true;\n        this._emitPhotoSurfaceEntryStatus('prewarming', {\n            message: 'Preparing terrain',\n        });\n\n        if (this._photoTileLoader?.enabled) {\n            if (this._photoInitializationPresentationHold) {\n                this._photoTileLoader.setPresentationEnabled?.(false);\n            }\n            this._photoTileLoader.primeSurfaceFocus?.(\n                this._photoSurfaceEntryPending.reason,\n                this._photoSurfaceEntryPending.focusDir\n            );\n            this._photoTileLoader.forceNextUpdate?.();\n            return;\n        }\n\n        this._photoDeferredInitialization = false;\n        this._photoDeferredConfig = null;\n        void this._handlePhotorealisticToggle(true, photoConfig, {\n            explicitSurfaceEntry: true,\n        });\n    }\n\n    _updatePhotoOverviewHandoff(surfaceModeActive) {\n        const loader = this._photoTileLoader;\n        if (surfaceModeActive\n            || this._photoSurfaceEntryPending\n            || !this._photoInitializationPresentationHold\n            || (!this._overviewGlobeMode && !this._photoSatelliteFallback)\n            || !loader?.enabled) {\n            return;\n        }\n\n        const coverage = loader.getCoverageState?.() || {};\n        if (!coverage.rootLoaded\n            || coverage.loadedModelCount <= 0\n            || coverage.visibleCount <= 0) {\n            return;\n        }\n\n        // No rendered frame occurs between relinquishing the coarse loading\n        // globe and exposing provider geometry. The photo group was refining\n        // while hidden, so this is a one-frame ownership swap rather than a\n        // texture crossfade or overlapping z-fighting surface.\n        this._setOverviewGlobeVisible(false);\n        this._clearPhotoSatelliteFallback();\n        loader.setPresentationEnabled?.(true);\n        this._photoInitializationPresentationHold = false;\n        this.eventBus?.emit?.('photo:status', {\n            status: 'valid',\n            detail: 'orbit-photoreal-ready',\n        });\n    }\n\n    _updatePhotoSurfaceEntryHandoff(surfaceModeActive) {\n        const pending = this._photoSurfaceEntryPending;\n        const loader = this._photoTileLoader;\n        if (!pending || !loader?.enabled) return;\n        if (!surfaceModeActive) {\n            this._cancelPhotoSurfaceEntry();\n            return;\n        }\n\n        if (loader.isSurfaceEntryReady?.()) {\n            // No frame is rendered between these two calls: the standalone\n            // overview relinquishes ownership before the prepared tile group\n            // becomes visible, so the two Earth renderers never overlap.\n            if (this._overviewGlobeMode) this._setOverviewGlobeVisible(false);\n            this._clearPhotoSatelliteFallback();\n            loader.setPresentationEnabled?.(true);\n            this._photoInitializationPresentationHold = false;\n            this._photoSurfaceEntryPending = null;\n            this._emitPhotoSurfaceEntryStatus('ready', {\n                message: 'Terrain ready',\n            });\n            return;\n        }\n\n        const coverage = loader.getCoverageState?.() || {};\n        const phase = coverage.phase === 'underfoot-focus'\n            ? 'contact'\n            : (coverage.rootLoaded ? 'coverage' : 'prewarming');\n        this._emitPhotoSurfaceEntryStatus(phase, {\n            message: phase === 'contact'\n                ? 'Resolving ground contact'\n                : (phase === 'coverage' ? 'Filling the landing view' : 'Preparing terrain'),\n        });\n    }\n\n    _cancelPhotoSurfaceEntry() {\n        if (!this._photoSurfaceEntryPending) return;\n        this._photoSurfaceEntryPending = null;\n        this._photoTileLoader?.cancelSurfaceFocus?.();\n        this._photoInitializationPresentationHold = this._overviewGlobeMode === true;\n        if (this._overviewGlobeMode) {\n            this._photoTileLoader?.setPresentationEnabled?.(false);\n        }\n        this._emitPhotoSurfaceEntryStatus('cancelled', {\n            message: 'Surface entry cancelled',\n        });\n    }\n\n    _failPhotoSurfaceEntry(message = 'Terrain could not be loaded') {\n        if (!this._photoSurfaceEntryPending) return;\n        this._photoSurfaceEntryPending = null;\n        this._photoInitializationPresentationHold = false;\n        if (!this._photoSatelliteFallback && !this._photoSatelliteFallbackPromise) {\n            void this._enablePhotoSatelliteFallback(message);\n        }\n        this._emitPhotoSurfaceEntryStatus('error', { message });\n    }\n\n    _handleSurfaceEnter({ reason = '', focusDir = null } = {}) {\n        // Surface mode is the first point where a local avatar can be useful.\n        void this._initAvatarSystems();\n        this._scheduleOceanResolverSetup();\n        this._beginPhotoSurfaceEntry(reason, focusDir);\n        if (!this._elevationClient) return;\n        const relay = document.getElementById('relay')?.value?.trim()\n            || localStorage.getItem('nkn.globe.relay')\n            || DEFAULT_FORWARDER;\n        const dataset = document.getElementById('dataset')?.value?.trim()\n            || localStorage.getItem('nkn.globe.dataset')\n            || 'mapzen';\n        this._elevationClient.setRelayAndDataset(relay, dataset);\n        const multiClient = this.uiController?.multiClient;\n        if (multiClient) {\n            this._elevationClient.setMultiClient(multiClient);\n        }\n        if (typeof this._elevationClient.kickSurfaceMode === 'function') {\n            this._elevationClient.kickSurfaceMode();\n        } else if (typeof this._elevationClient.clearPendingRequests === 'function') {\n            this._elevationClient.clearPendingRequests();\n        }\n        if (typeof this._elevationClient.tick === 'function') {\n            this._elevationClient.tick();\n        }\n        if (reason) {\n            console.log(`[elev] surface fetch kick (${reason})`);\n        }\n    }\n\n    syncUIFromSettings() {\n        this.uiController?.syncUIFromSettings?.();\n    }\n\n    setNknEnabled(enabled) {\n        const next = enabled === true;\n        this.uiController?.setNknEnabled?.(next);\n        this._presenceSystem?.setUseP2P?.(next);\n        this._commsSystem?.setUseP2P?.(next);\n    }\n}\n"],"file":"assets/66614499192c/planet-scene-BSBp92xG.js"}