viral-viewer-2 7.3.8 → 7.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- import { B as S, a as V, V as Z } from "./index-CGEo-Ugd.mjs";
1
+ import { B as S, a as V, V as Z } from "./index-Bk3DGGBD.mjs";
2
2
  (function() {
3
3
  var s = "b9H79Tebbbe9ok9Geueu9Geub9Gbb9Gruuuuuuueu9Gvuuuuueu9Gduueu9Gluuuueu9Gvuuuuub9Gouuuuuub9Gluuuub9GiuuueuiE8AdilveoveovrrwrrrDDoDrbqqbelve9Weiiviebeoweuec;G:Qdkr:PlCo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bb8F9TW79O9V9Wt9FW9U9J9V9KW9wWVtW949c919M9MWV9mW4W2be8A9TW79O9V9Wt9FW9U9J9V9KW9wWVtW949c919M9MWVbd8F9TW79O9V9Wt9FW9U9J9V9KW9wWVtW949c919M9MWV9c9V919U9KbiE9TW79O9V9Wt9FW9U9J9V9KW9wWVtW949wWV79P9V9UblY9TW79O9V9Wt9FW9U9J9V9KW69U9KW949c919M9MWVbv8E9TW79O9V9Wt9FW9U9J9V9KW69U9KW949c919M9MWV9c9V919U9Kbo8A9TW79O9V9Wt9FW9U9J9V9KW69U9KW949wWV79P9V9UbrE9TW79O9V9Wt9FW9U9J9V9KW69U9KW949tWG91W9U9JWbwa9TW79O9V9Wt9FW9U9J9V9KW69U9KW949tWG91W9U9JW9c9V919U9KbDL9TW79O9V9Wt9FW9U9J9V9KWS9P2tWV9p9JtbqK9TW79O9V9Wt9FW9U9J9V9KWS9P2tWV9r919HtbkL9TW79O9V9Wt9FW9U9J9V9KWS9P2tWVT949WbxY9TW79O9V9Wt9FW9U9J9V9KWS9P2tWVJ9V29VVbmE9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94J9H9J9OWbza9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94J9H9J9OW9ttV9P9WbHa9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94SWt9J9O9sW9T9H9WbOK9TW79O9V9Wt9F79W9Ht9P9H29t9VVt9sW9T9H9WbAl79IV9RbXDwebcekdKYq;i28Adbk:Bhdhud9:8Jjjjjbc;qw9Rgr8KjjjjbcbhwdnaeTmbabcbyd;C:kjjbaoaocb9iEgDc:GeV86bbarc;adfcbcjdz:xjjjb8AdnaiTmbarc;adfadalz:wjjjb8Akarc;abfalfcbcbcjdal9RalcFe0Ez:xjjjb8Aarc;abfarc;adfalz:wjjjb8AarcUf9cb83ibarc8Wf9cb83ibarcyf9cb83ibarcaf9cb83ibarcKf9cb83ibarczf9cb83ibar9cb83iwar9cb83ibcj;abal9Uc;WFbGcjdalca0Ehqdnaicd6mbavcd9imbaDTmbadcefhkaqci2gxal2hmarc;alfclfhParc;qlfceVhsarc;qofclVhzarc;qofcKfhHarc;qofczfhOcbhAincdhCcbhodnavci6mbaH9cb83ibaO9cb83ibar9cb83i;yoar9cb83i;qoadaAfgoybbhXcbhQincbhwcbhLdninaoalfhKaoybbgYaX7aLVhLawcP0meaKhoaYhXawcefgwaQfai6mbkkcbhXarc;qofhwincwh8AcwhEdnaLaX93gocFeGg3cs0mbclhEa3ci0mba3cb9hcethEkdnaocw4cFeGg3cs0mbclh8Aa3ci0mba3cb9hceth8Aka8AaEfh3awydbh5cwh8AcwhEdnaocz4cFeGg8Ecs0mbclhEa8Eci0mba8Ecb9hcethEka3a5fh3dnaocFFFFb0mbclh8AaocFFF8F0mbaocFFFr0ceth8Akawa3aEfa8AfBdbawclfhwaXcefgXcw9hmbkaKhoaYhXaQczfgQai6mbkcbhocehwazhLinawaoaLydbarc;qofaocdtfydb6EhoaLclfhLawcefgwcw9hmbkcihCkcbh3arc;qlfcbcjdz:xjjjb8Aarc;alfcwfcbBdbar9cb83i;alaoclth8Fadhaaqhhakh5inarc;qlfadcba3cufgoaoa30Eal2falz:wjjjb8Aaiahaiah6Ehgdnaqaia39Ra3aqfai6EgYcsfc9WGgoaY9nmbarc;qofaYfcbaoaY9Rz:xjjjb8Akada3al2fh8Jcbh8Kina8Ka8FVcl4hQarc;alfa8Kcdtfh8LaAh8Mcbh8Nina8NaAfhwdndndndndndna8KPldebidkasa8Mc98GgLfhoa5aLfh8Aarc;qlfawc98GgLfRbbhXcwhwinaoRbbawtaXVhXaocefhoawcwfgwca9hmbkaYTmla8Ncith8Ea8JaLfhEcbhKinaERbbhLcwhoa8AhwinawRbbaotaLVhLawcefhwaocwfgoca9hmbkarc;qofaKfaLaX7aQ93a8E486bba8Aalfh8AaEalfhEaLhXaKcefgKaY9hmbxlkkaYTmia8Mc9:Ghoa8NcitcwGhEarc;qlfawceVfRbbcwtarc;qlfawc9:GfRbbVhLarc;qofhwaghXinawa5aofRbbcwtaaaofRbbVg8AaL9RgLcetaLcztcz91cs47cFFiGaE486bbaoalfhoawcefhwa8AhLa3aXcufgX9hmbxikkaYTmda8Jawfhoarc;qlfawfRbbhLarc;qofhwaghXinawaoRbbg8AaL9RgLcetaLcKtcK91cr4786bbawcefhwaoalfhoa8AhLa3aXcufgX9hmbxdkkaYTmeka8LydbhEcbhKarc;qofhoincdhLcbhwinaLaoawfRbbcb9hfhLawcefgwcz9hmbkclhXcbhwinaXaoawfRbbcd0fhXawcefgwcz9hmbkcwh8Acbhwina8AaoawfRbbcP0fh8Aawcefgwcz9hmbkaLaXaLaX6Egwa8Aawa8A6Egwczawcz6EaEfhEaoczfhoaKczfgKaY6mbka8LaEBdbka8Mcefh8Ma8Ncefg8Ncl9hmbka8Kcefg8KaC9hmbkaaamfhaahaxfhha5amfh5a3axfg3ai6mbkcbhocehwaPhLinawaoaLydbarc;alfaocdtfydb6EhoaLclfhLawcefgXhwaCaX9hmbkaraAcd4fa8FcdVaoaocdSE86bbaAclfgAal6mbkkabaefh8Kabcefhoalcd4gecbaDEhkadcefhOarc;abfceVhHcbhmdndninaiam9nmearc;qofcbcjdz:xjjjb8Aa8Kao9Rak6mdadamal2gwfhxcbh8JaOawfhzaocbakz:xjjjbghakfh5aqaiam9Ramaqfai6Egscsfgocl4cifcd4hCaoc9WGg8LThPindndndndndndndndndndnaDTmbara8Jcd4fRbbgLciGPlbedlbkasTmdaxa8Jfhoarc;abfa8JfRbbhLarc;qofhwashXinawaoRbbg8AaL9RgLcetaLcKtcK91cr4786bbawcefhwaoalfhoa8AhLaXcufgXmbxikkasTmia8JcitcwGhEarc;abfa8JceVfRbbcwtarc;abfa8Jc9:GgofRbbVhLaxaofhoarc;qofhwashXinawao8Vbbg8AaL9RgLcetaLcztcz91cs47cFFiGaE486bbawcefhwaoalfhoa8AhLaXcufgXmbxdkkaHa8Jc98GgEfhoazaEfh8Aarc;abfaEfRbbhXcwhwinaoRbbawtaXVhXaocefhoawcwfgwca9hmbkasTmbaLcl4hYa8JcitcKGh3axaEfhEcbhKinaERbbhLcwhoa8AhwinawRbbaotaLVhLawcefhwaocwfgoca9hmbkarc;qofaKfaLaX7aY93a3486bba8Aalfh8AaEalfhEaLhXaKcefgKas9hmbkkaDmbcbhoxlka8LTmbcbhodninarc;qofaofgwcwf8Pibaw8Pib:e9qTmeaoczfgoa8L9pmdxbkkdnavmbcehoxikcbhEaChKaChYinarc;qofaEfgocwf8Pibhyao8Pibh8PcdhLcbhwinaLaoawfRbbcb9hfhLawcefgwcz9hmbkclhXcbhwinaXaoawfRbbcd0fhXawcefgwcz9hmbkcwh8Acbhwina8AaoawfRbbcP0fh8Aawcefgwcz9hmbkaLaXaLaX6Egoa8Aaoa8A6Egoczaocz6EaYfhYaocucbaya8P:e9cb9sEgwaoaw6EaKfhKaEczfgEa8L9pmdxbkkaha8Jcd4fgoaoRbbcda8JcetcoGtV86bbxikdnaKas6mbaYas6mbaha8Jcd4fgoaoRbbcia8JcetcoGtV86bba8Ka59Ras6mra5arc;qofasz:wjjjbasfh5xikaKaY9phokaha8Jcd4fgwawRbbaoa8JcetcoGtV86bbka8Ka59RaC6mla5cbaCz:xjjjbgAaCfhYdndna8LmbaPhoxekdna8KaY9RcK9pmbaPhoxekaocdtc:q1jjbfcj1jjbaDEg5ydxggcetc;:FFFeGh8Fcuh3cuagtcu7cFeGhacbh8Marc;qofhLinarc;qofa8MfhQczhEdndndnagPDbeeeeeeedekcucbaQcwf8PibaQ8Pib:e9cb9sEhExekcbhoa8FhEinaEaaaLaofRbb9nfhEaocefgocz9hmbkkcih8Ecbh8Ainczhwdndndna5a8AcdtfydbgKPDbeeeeeeedekcucbaQcwf8PibaQ8Pib:e9cb9sEhwxekaKcetc;:FFFeGhwcuaKtcu7cFeGhXcbhoinawaXaLaofRbb9nfhwaocefgocz9hmbkkdndnawaE6mbaKa39hmeawaE9hmea5a8EcdtfydbcwSmeka8Ah8EawhEka8Acefg8Aci9hmbkaAa8Mco4fgoaoRbba8Ea8Mci4coGtV86bbdndndna5a8Ecdtfydbg3PDdbbbbbbbebkdncwa39Tg8ETmbcua3tcu7hwdndna3ceSmbcbh8NaLhQinaQhoa8Eh8AcbhXinaoRbbgEawcFeGgKaEaK6EaXa3tVhXaocefhoa8Acufg8AmbkaYaX86bbaQa8EfhQaYcefhYa8Na8Efg8Ncz6mbxdkkcbh8NaLhQinaQhoa8Eh8AcbhXinaoRbbgEawcFeGgKaEaK6EaXcetVhXaocefhoa8Acufg8AmbkaYaX:T9cFe:d9c:c:qj:bw9:9c:q;c1:I1e:d9c:b:c:e1z9:9ca188bbaQa8EfhQaYcefhYa8Na8Efg8Ncz6mbkkcbhoinaYaLaofRbbgX86bbaYaXawcFeG9pfhYaocefgocz9hmbxikkdna3ceSmbinaYcb86bbaYcefhYxbkkinaYcb86bbaYcefhYxbkkaYaQ8Pbb83bbaYcwfaQcwf8Pbb83bbaYczfhYka8Mczfg8Ma8L9pgomeaLczfhLa8KaY9RcK9pmbkkaoTmlaYh5aYTmlka8Jcefg8Jal9hmbkarc;abfaxascufal2falz:wjjjb8Aasamfhma5hoa5mbkcbhwxdkdna8Kao9RakalfgwcKcaaDEgLawaL0EgX9pmbcbhwxdkdnawaL9pmbaocbaXaw9Rgwz:xjjjbawfhokaoarc;adfalz:wjjjbalfhodnaDTmbaoaraez:wjjjbaefhokaoab9Rhwxekcbhwkarc;qwf8Kjjjjbawk5babaeadaialcdcbyd;C:kjjbz:bjjjbk9reduaecd4gdaefgicaaica0Eabcj;abae9Uc;WFbGcjdaeca0Egifcufai9Uae2aiadfaicl4cifcd4f2fcefkmbcbabBd;C:kjjbk:Ese5u8Jjjjjbc;ae9Rgl8Kjjjjbcbhvdnaici9UgocHfae0mbabcbyd;m:kjjbgrc;GeV86bbalc;abfcFecjez:xjjjb8AalcUfgw9cu83ibalc8WfgD9cu83ibalcyfgq9cu83ibalcafgk9cu83ibalcKfgx9cu83ibalczfgm9cu83ibal9cu83iwal9cu83ibabaefc9WfhPabcefgsaofhednaiTmbcmcsarcb9kgzEhHcbhOcbhAcbhCcbhXcbhQindnaeaP9nmbcbhvxikaQcufhvadaCcdtfgLydbhKaLcwfydbhYaLclfydbh8AcbhEdndndninalc;abfavcsGcitfgoydlh3dndndnaoydbgoaK9hmba3a8ASmekdnaoa8A9hmba3aY9hmbaEcefhExekaoaY9hmea3aK9hmeaEcdfhEkaEc870mdaXcufhvaLaEciGcx2goc;i1jjbfydbcdtfydbh3aLaoc;e1jjbfydbcdtfydbh8AaLaoc;a1jjbfydbcdtfydbhKcbhodnindnalavcsGcdtfydba39hmbaohYxdkcuhYavcufhvaocefgocz9hmbkkaOa3aOSgvaYce9iaYaH9oVgoGfhOdndndncbcsavEaYaoEgvcs9hmbarce9imba3a3aAa3cefaASgvEgAcefSmecmcsavEhvkasavaEcdtc;WeGV86bbavcs9hmea3aA9Rgvcetavc8F917hvinaeavcFb0crtavcFbGV86bbaecefheavcje6hoavcr4hvaoTmbka3hAxvkcPhvasaEcdtcPV86bba3hAkavTmiavaH9omicdhocehEaQhYxlkavcufhvaEclfgEc;ab9hmbkkdnaLceaYaOSceta8AaOSEcx2gvc;a1jjbfydbcdtfydbgKTaLavc;e1jjbfydbcdtfydbg8AceSGaLavc;i1jjbfydbcdtfydbg3cdSGaOcb9hGazGg5ce9hmbaw9cu83ibaD9cu83ibaq9cu83ibak9cu83ibax9cu83ibam9cu83ibal9cu83iwal9cu83ibcbhOkcbhEaXcufgvhodnindnalaocsGcdtfydba8A9hmbaEhYxdkcuhYaocufhoaEcefgEcz9hmbkkcbhodnindnalavcsGcdtfydba39hmbaohExdkcuhEavcufhvaocefgocz9hmbkkaOaKaOSg8EfhLdndnaYcm0mbaYcefhYxekcbcsa8AaLSgvEhYaLavfhLkdndnaEcm0mbaEcefhExekcbcsa3aLSgvEhEaLavfhLkc9:cua8EEh8FcbhvaEaYcltVgacFeGhodndndninavc:W1jjbfRbbaoSmeavcefgvcz9hmbxdkka5aKaO9havcm0VVmbasavc;WeV86bbxekasa8F86bbaeaa86bbaecefhekdna8EmbaKaA9Rgvcetavc8F917hvinaeavcFb0gocrtavcFbGV86bbavcr4hvaecefheaombkaKhAkdnaYcs9hmba8AaA9Rgvcetavc8F917hvinaeavcFb0gocrtavcFbGV86bbavcr4hvaecefheaombka8AhAkdnaEcs9hmba3aA9Rgvcetavc8F917hvinaeavcFb0gocrtavcFbGV86bbavcr4hvaecefheaombka3hAkalaXcdtfaKBdbaXcefcsGhvdndnaYPzbeeeeeeeeeeeeeebekalavcdtfa8ABdbaXcdfcsGhvkdndnaEPzbeeeeeeeeeeeeeebekalavcdtfa3BdbavcefcsGhvkcihoalc;abfaQcitfgEaKBdlaEa8ABdbaQcefcsGhYcdhEavhXaLhOxekcdhoalaXcdtfa3BdbcehEaXcefcsGhXaQhYkalc;abfaYcitfgva8ABdlava3Bdbalc;abfaQaEfcsGcitfgva3BdlavaKBdbascefhsaQaofcsGhQaCcifgCai6mbkkdnaeaP9nmbcbhvxekcbhvinaeavfavc:W1jjbfRbb86bbavcefgvcz9hmbkaeab9Ravfhvkalc;aef8KjjjjbavkZeeucbhddninadcefgdc8F0meceadtae6mbkkadcrfcFeGcr9Uci2cdfabci9U2cHfkmbcbabBd;m:kjjbk:Adewu8Jjjjjbcz9Rhlcbhvdnaicvfae0mbcbhvabcbRb;m:kjjbc;qeV86bbal9cb83iwabcefhoabaefc98fhrdnaiTmbcbhwcbhDindnaoar6mbcbskadaDcdtfydbgqalcwfawaqav9Rgvavc8F91gv7av9Rc507gwcdtfgkydb9Rgvc8E91c9:Gavcdt7awVhvinaoavcFb0gecrtavcFbGV86bbavcr4hvaocefhoaembkakaqBdbaqhvaDcefgDai9hmbkkdnaoar9nmbcbskaocbBbbaoab9RclfhvkavkBeeucbhddninadcefgdc8F0meceadtae6mbkkadcwfcFeGcr9Uab2cvfk:bvli99dui99ludnaeTmbcuadcetcuftcu7:Zhvdndncuaicuftcu7:ZgoJbbbZMgr:lJbbb9p9DTmbar:Ohwxekcjjjj94hwkcbhicbhDinalclfIdbgrJbbbbJbbjZalIdbgq:lar:lMalcwfIdbgk:lMgr:varJbbbb9BEgrNhxaqarNhrdndnakJbbbb9GTmbaxhqxekJbbjZar:l:tgqaq:maxJbbbb9GEhqJbbjZax:l:tgxax:marJbbbb9GEhrkdndnalcxfIdbgxJbbj:;axJbbj:;9GEgkJbbjZakJbbjZ9FEavNJbbbZJbbb:;axJbbbb9GEMgx:lJbbb9p9DTmbax:Ohmxekcjjjj94hmkdndnaqJbbj:;aqJbbj:;9GEgxJbbjZaxJbbjZ9FEaoNJbbbZJbbb:;aqJbbbb9GEMgq:lJbbb9p9DTmbaq:OhPxekcjjjj94hPkdndnarJbbj:;arJbbj:;9GEgqJbbjZaqJbbjZ9FEaoNJbbbZJbbb:;arJbbbb9GEMgr:lJbbb9p9DTmbar:Ohsxekcjjjj94hskdndnadcl9hmbabaifgzas86bbazcifam86bbazcdfaw86bbazcefaP86bbxekabaDfgzas87ebazcofam87ebazclfaw87ebazcdfaP87ebkalczfhlaiclfhiaDcwfhDaecufgembkkk;hlld99eud99eudnaeTmbdndncuaicuftcu7:ZgvJbbbZMgo:lJbbb9p9DTmbao:Ohixekcjjjj94hikaic;8FiGhrinabcofcicdalclfIdb:lalIdb:l9EgialcwfIdb:lalaicdtfIdb:l9EEgialcxfIdb:lalaicdtfIdb:l9EEgiarV87ebdndnJbbj:;JbbjZalaicdtfIdbJbbbb9DEgoalaicd7cdtfIdbJ;Zl:1ZNNgwJbbj:;awJbbj:;9GEgDJbbjZaDJbbjZ9FEavNJbbbZJbbb:;awJbbbb9GEMgw:lJbbb9p9DTmbaw:Ohqxekcjjjj94hqkabcdfaq87ebdndnalaicefciGcdtfIdbJ;Zl:1ZNaoNgwJbbj:;awJbbj:;9GEgDJbbjZaDJbbjZ9FEavNJbbbZJbbb:;awJbbbb9GEMgw:lJbbb9p9DTmbaw:Ohqxekcjjjj94hqkabaq87ebdndnaoalaicufciGcdtfIdbJ;Zl:1ZNNgoJbbj:;aoJbbj:;9GEgwJbbjZawJbbjZ9FEavNJbbbZJbbb:;aoJbbbb9GEMgo:lJbbb9p9DTmbao:Ohixekcjjjj94hikabclfai87ebabcwfhbalczfhlaecufgembkkk;3viDue99eu8Jjjjjbcjd9Rgo8Kjjjjbadcd4hrdndndndnavcd9hmbadcl6meaohwarhDinawc:CuBdbawclfhwaDcufgDmbkaeTmiadcl6mdarcdthqalhkcbhxinaohwakhDarhminawawydbgPcbaDIdbgs:8cL4cFeGc:cufasJbbbb9BEgzaPaz9kEBdbaDclfhDawclfhwamcufgmmbkakaqfhkaxcefgxaeSmixbkkaeTmdxekaeTmekarcdthkavce9hhqadcl6hdcbhxindndndnaqmbadmdc:CuhDalhwarhminaDcbawIdbgs:8cL4cFeGc:cufasJbbbb9BEgPaDaP9kEhDawclfhwamcufgmmbxdkkc:CuhDdndnavPleddbdkadmdaohwalhmarhPinawcbamIdbgs:8cL4cFeGgzc;:bazc;:b0Ec:cufasJbbbb9BEBdbamclfhmawclfhwaPcufgPmbxdkkadmecbhwarhminaoawfcbalawfIdbgs:8cL4cFeGgPc8AaPc8A0Ec:cufasJbbbb9BEBdbawclfhwamcufgmmbkkadmbcbhwarhPinaDhmdnavceSmbaoawfydbhmkdndnalawfIdbgscjjj;8iamai9RcefgmcLt9R::NJbbbZJbbb:;asJbbbb9GEMgs:lJbbb9p9DTmbas:Ohzxekcjjjj94hzkabawfazcFFFrGamcKtVBdbawclfhwaPcufgPmbkkabakfhbalakfhlaxcefgxae9hmbkkaocjdf8Kjjjjbk:Ylvdud99due99iudnaeTmbceaicufgvthocuaitcu7:Zhrcuavtcu7:Zhwcbhvadcl9hhDcbhqindndnalcwfIdbgkJbbbbakJbbbb9GEgkJbbjZakJbbjZ9FEarNJbbbZMgk:lJbbb9p9DTmbak:Ohixekcjjjj94hikdndnalIdbgkJbbbbakJbbbb9GEgkJbbjZakJbbjZ9FEarNJbbbZMgk:lJbbb9p9DTmbak:Ohdxekcjjjj94hdkadai9Rcd9TgxaifhidndnalclfIdbgkJbbbbakJbbbb9GEgkJbbjZakJbbjZ9FEarNJbbbZMgk:lJbbb9p9DTmbak:Ohdxekcjjjj94hdkadai9Rcd9ThddndnalcxfIdbgkJbbbbakJbbbb9GEgkJbbjZakJbbjZ9FEawNJbbbZMgk:lJbbb9p9DTmbak:Ohmxekcjjjj94hmkadaifhiaoamVhmdndnaDmbabavfgPai86bbaPcifam86bbaPcdfad86bbaPcefax86bbxekabaqfgPai87ebaPcofam87ebaPclfad87ebaPcdfax87ebkalczfhlavclfhvaqcwfhqaecufgembkkk;YqdXui998Jjjjjbc:qd9Rgv8Kjjjjbavc:Sefcbc;Kbz:xjjjb8AcbhodnadTmbcbhoaiTmbdndnabaeSmbaehrxekavcuadcdtgwadcFFFFi0Ecbyd;q:kjjbHjjjjbbgrBd:SeavceBd:mdaraeawz:wjjjb8Akavc:GefcwfcbBdbav9cb83i:Geavc:Gefaradaiavc:Sefz:pjjjbavyd:GehDadci9Ugqcbyd;q:kjjbHjjjjbbheavc:Sefavyd:mdgkcdtfaeBdbavakcefgwBd:mdaecbaqz:xjjjbhxavc:SefawcdtfcuaicdtaicFFFFi0Ecbyd;q:kjjbHjjjjbbgmBdbavakcdfgPBd:mdalc;ebfhsaDheamhwinawalIdbasaeydbgzcwazcw6EcdtfIdbMUdbaeclfheawclfhwaicufgimbkavc:SefaPcdtfcuaqcdtadcFFFF970Ecbyd;q:kjjbHjjjjbbgPBdbdnadci6mbarheaPhwaqhiinawamaeydbcdtfIdbamaeclfydbcdtfIdbMamaecwfydbcdtfIdbMUdbaecxfheawclfhwaicufgimbkkakcifhoalc;ebfhHavc;qbfhOavheavyd:KehAavyd:OehCcbhzcbhwcbhXcehQinaehLcihkarawci2gKcdtfgeydbhsaeclfydbhdabaXcx2fgicwfaecwfydbgYBdbaiclfadBdbaiasBdbaxawfce86bbaOaYBdwaOadBdlaOasBdbaPawcdtfcbBdbdnazTmbcihkaLhiinaOakcdtfaiydbgeBdbakaeaY9haeas9haead9hGGfhkaiclfhiazcufgzmbkkaXcefhXcbhzinaCaAarazaKfcdtfydbcdtgifydbcdtfgYheaDaifgdydbgshidnasTmbdninaeydbawSmeaeclfheaicufgiTmdxbkkaeaYascdtfc98fydbBdbadadydbcufBdbkazcefgzci9hmbkdndnakTmbcuhwJbbbbh8Acbhdavyd:KehYavyd:OehKindndnaDaOadcdtfydbcdtgzfydbgembadcefhdxekadcs0hiamazfgsIdbhEasalcbadcefgdaiEcdtfIdbaHaecwaecw6EcdtfIdbMg3Udba3aE:th3aecdthiaKaYazfydbcdtfheinaPaeydbgzcdtfgsa3asIdbMgEUdbaEa8Aa8AaE9DgsEh8AazawasEhwaeclfheaic98fgimbkkadak9hmbkawcu9hmekaQaq9pmdindnaxaQfRbbmbaQhwxdkaqaQcefgQ9hmbxikkakczakcz6EhzaOheaLhOawcu9hmbkkaocdtavc:Seffc98fhedninaoTmeaeydbcbyd;u:kjjbH:bjjjbbaec98fheaocufhoxbkkavc:qdf8Kjjjjbk;IlevucuaicdtgvaicFFFFi0Egocbyd;q:kjjbHjjjjbbhralalyd9GgwcdtfarBdbalawcefBd9GabarBdbaocbyd;q:kjjbHjjjjbbhralalyd9GgocdtfarBdbalaocefBd9GabarBdlcuadcdtadcFFFFi0Ecbyd;q:kjjbHjjjjbbhralalyd9GgocdtfarBdbalaocefBd9GabarBdwabydbcbavz:xjjjb8Aadci9UhDdnadTmbabydbhoaehladhrinaoalydbcdtfgvavydbcefBdbalclfhlarcufgrmbkkdnaiTmbabydbhlabydlhrcbhvaihoinaravBdbarclfhralydbavfhvalclfhlaocufgombkkdnadci6mbabydlhrabydwhvcbhlinaecwfydbhoaeclfydbhdaraeydbcdtfgwawydbgwcefBdbavawcdtfalBdbaradcdtfgdadydbgdcefBdbavadcdtfalBdbaraocdtfgoaoydbgocefBdbavaocdtfalBdbaecxfheaDalcefgl9hmbkkdnaiTmbabydlheabydbhlinaeaeydbalydb9RBdbalclfhlaeclfheaicufgimbkkkQbabaeadaic;K1jjbz:ojjjbkQbabaeadaic;m:jjjbz:ojjjbk9DeeuabcFeaicdtz:xjjjbhlcbhbdnadTmbindnalaeydbcdtfgiydbcu9hmbaiabBdbabcefhbkaeclfheadcufgdmbkkabk:Vvioud9:du8Jjjjjbc;Wa9Rgl8Kjjjjbcbhvalcxfcbc;Kbz:xjjjb8AalcuadcitgoadcFFFFe0Ecbyd;q:kjjbHjjjjbbgrBdxalceBd2araeadaicezNjjjbalcuaoadcjjjjoGEcbyd;q:kjjbHjjjjbbgwBdzadcdthednadTmbabhiinaiavBdbaiclfhiadavcefgv9hmbkkawaefhDalabBdwalawBdl9cbhqindnadTmbaq9cq9:hkarhvaDhiadheinaiav8Pibak1:NcFrG87ebavcwfhvaicdfhiaecufgembkkalclfaq:NceGcdtfydbhxalclfaq9ce98gq:NceGcdtfydbhmalc;Wbfcbcjaz:xjjjb8AaDhvadhidnadTmbinalc;Wbfav8VebcdtfgeaeydbcefBdbavcdfhvaicufgimbkkcbhvcbhiinalc;WbfavfgeydbhoaeaiBdbaoaifhiavclfgvcja9hmbkadhvdndnadTmbinalc;WbfaDamydbgicetf8VebcdtfgeaeydbgecefBdbaxaecdtfaiBdbamclfhmavcufgvmbkaq9cv9smdcbhvinabawydbcdtfavBdbawclfhwadavcefgv9hmbxdkkaq9cv9smekkclhvdninavc98Smealcxfavfydbcbyd;u:kjjbH:bjjjbbavc98fhvxbkkalc;Waf8Kjjjjbk:Jwliuo99iud9:cbhv8Jjjjjbca9Rgoczfcwfcbyd:8:kjjbBdbaocb8Pd:0:kjjb83izaocwfcbyd;i:kjjbBdbaocb8Pd;a:kjjb83ibaicd4hrdndnadmbJFFuFhwJFFuuhDJFFuuhqJFFuFhkJFFuuhxJFFuFhmxekarcdthPaehsincbhiinaoczfaifgzasaifIdbgwazIdbgDaDaw9EEUdbaoaifgzawazIdbgDaDaw9DEUdbaiclfgicx9hmbkasaPfhsavcefgvad9hmbkaoIdKhDaoIdwhwaoIdChqaoIdlhkaoIdzhxaoIdbhmkdnadTmbJbbbbJbFu9hJbbbbamax:tgmamJbbbb9DEgmakaq:tgkakam9DEgkawaD:tgwawak9DEgw:vawJbbbb9BEhwdnalmbarcdthoindndnaeclfIdbaq:tawNJbbbZMgk:lJbbb9p9DTmbak:Ohixekcjjjj94hikai:S9cC:ghHdndnaeIdbax:tawNJbbbZMgk:lJbbb9p9DTmbak:Ohixekcjjjj94hikaHai:S:ehHdndnaecwfIdbaD:tawNJbbbZMgk:lJbbb9p9DTmbak:Ohixekcjjjj94hikabaHai:T9cy:g:e83ibaeaofheabcwfhbadcufgdmbxdkkarcdthoindndnaeIdbax:tawNJbbbZMgk:lJbbb9p9DTmbak:Ohixekcjjjj94hikai:SgH9ca:gaH9cz:g9cjjj;4s:d:eaH9cFe:d:e9cF:bj;4:pj;ar:d9c:bd9:9c:p;G:d;4j:E;ar:d9cH9:9c;d;H:W:y:m:g;d;Hb:d9cv9:9c;j:KM;j:KM;j:Kd:dhOdndnaeclfIdbaq:tawNJbbbZMgk:lJbbb9p9DTmbak:Ohixekcjjjj94hikai:SgH9ca:gaH9cz:g9cjjj;4s:d:eaH9cFe:d:e9cF:bj;4:pj;ar:d9c:bd9:9c:p;G:d;4j:E;ar:d9cH9:9c;d;H:W:y:m:g;d;Hb:d9cq9:9cM;j:KM;j:KM;jl:daO:ehOdndnaecwfIdbaD:tawNJbbbZMgk:lJbbb9p9DTmbak:Ohixekcjjjj94hikabaOai:SgH9ca:gaH9cz:g9cjjj;4s:d:eaH9cFe:d:e9cF:bj;4:pj;ar:d9c:bd9:9c:p;G:d;4j:E;ar:d9cH9:9c;d;H:W:y:m:g;d;Hb:d9cC9:9c:KM;j:KM;j:KMD:d:e83ibaeaofheabcwfhbadcufgdmbkkk9teiucbcbyd;y:kjjbgeabcifc98GfgbBd;y:kjjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik;teeeudndnaeabVciGTmbabhixekdndnadcz9pmbabhixekabhiinaiaeydbBdbaiaeydlBdlaiaeydwBdwaiaeydxBdxaeczfheaiczfhiadc9Wfgdcs0mbkkadcl6mbinaiaeydbBdbaeclfheaiclfhiadc98fgdci0mbkkdnadTmbinaiaeRbb86bbaicefhiaecefheadcufgdmbkkabk:3eedudndnabciGTmbabhixekaecFeGc:b:c:ew2hldndnadcz9pmbabhixekabhiinaialBdxaialBdwaialBdlaialBdbaiczfhiadc9Wfgdcs0mbkkadcl6mbinaialBdbaiclfhiadc98fgdci0mbkkdnadTmbinaiae86bbaicefhiadcufgdmbkkabk9teiucbcbyd;y:kjjbgeabcrfc94GfgbBd;y:kjjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik9:eiuZbhedndncbyd;y:kjjbgdaecztgi9nmbcuheadai9RcFFifcz4nbcuSmekadhekcbabae9Rcifc98Gcbyd;y:kjjbfgdBd;y:kjjbdnadZbcztge9nmbadae9RcFFifcz4nb8Akkk;Qddbcjwk;mdbbbbdbbblbbbwbbbbbbbebbbdbbblbbbwbbbbbbbbbbbbbbbb4:h9w9N94:P:gW:j9O:ye9Pbbbbbbebbbdbbbebbbdbbbbbbbdbbbbbbbebbbbbbb:l29hZ;69:9kZ;N;76Z;rg97Z;z;o9xZ8J;B85Z;:;u9yZ;b;k9HZ:2;Z9DZ9e:l9mZ59A8KZ:r;T3Z:A:zYZ79OHZ;j4::8::Y:D9V8:bbbb9s:49:Z8R:hBZ9M9M;M8:L;z;o8:;8:PG89q;x:J878R:hQ8::M:B;e87bbbbbbjZbbjZbbjZ:E;V;N8::Y:DsZ9i;H;68:xd;R8:;h0838:;W:NoZbbbb:WV9O8:uf888:9i;H;68:9c9G;L89;n;m9m89;D8Ko8:bbbbf:8tZ9m836ZS:2AZL;zPZZ818EZ9e:lxZ;U98F8:819E;68:FFuuFFuuFFuuFFuFFFuFFFuFbc;mqkzebbbebbbdbbb9G:vbb", D = new Uint8Array([
4
4
  32,
@@ -1,3 +1,4 @@
1
1
  import { ViralBatchedMesh } from "./viral-batched-mesh";
2
+ import { ViralBatchedMeshV3 } from "./viral-batched-mesh-v3";
2
3
  import { ViralBIMWorld } from "./viral-bim-world";
3
- export { ViralBIMWorld, ViralBatchedMesh };
4
+ export { ViralBIMWorld, ViralBatchedMesh, ViralBatchedMeshV3 };
@@ -0,0 +1,283 @@
1
+ import { BatchedMesh, Box3, Color, type Material, Object3D } from "three";
2
+ import { type LineMaterial } from "three/examples/jsm/Addons";
3
+ import { type BufferElement } from "../..";
4
+ /**
5
+ * Inject per-instance alpha support into a material for use with BatchedMesh.
6
+ *
7
+ * Three.js's built-in BatchedMesh shader reads only `.rgb` from the colors texture,
8
+ * discarding the alpha channel. This injection:
9
+ * 1. Reads `.a` from `batchingColorTexture` in the vertex shader
10
+ * 2. Passes it as a varying `vBatchAlpha` to the fragment shader
11
+ * 3. Applies alpha to `gl_FragColor.a` and discards fully transparent fragments
12
+ *
13
+ * This enables: per-instance hide (alpha=0 → discard), ghost (alpha=0.1),
14
+ * selection outline detection (alpha=0.99).
15
+ */
16
+ export declare function injectBatchedMeshAlphaShader(material: Material): void;
17
+ /**
18
+ * Special alpha value to mark selected vertices for fast outline detection.
19
+ * The AlphaSelectionOutlinePass detects this value with ZERO extra render passes.
20
+ */
21
+ export declare const SELECTION_ALPHA_V3 = 0.99;
22
+ /**
23
+ * ViralBatchedMeshV3 — Wraps Three.js `BatchedMesh` for high-performance BIM rendering.
24
+ *
25
+ * Key advantages over ViralBatchedMesh (V1):
26
+ * - **Per-element frustum culling** — Only visible elements are rendered when zoomed in
27
+ * - **Automatic depth sorting** — Opaque front-to-back (reduces overdraw), transparent back-to-front
28
+ * - **WEBGL_multi_draw** — Single draw call with multiple ranges (automatic)
29
+ * - **GPU-native visibility** — `setVisibleAt()` fully skips hidden elements (no vertex shader cost)
30
+ * - **O(1) raycast→element lookup** — `batchId` on intersection replaces linear `findElementByFaceIndex`
31
+ *
32
+ * Each BIM element's geometry is added as a separate "geometry" in the inner `BatchedMesh`,
33
+ * with one instance per element at identity matrix (positions are already in world space).
34
+ */
35
+ export declare class ViralBatchedMeshV3 extends Object3D {
36
+ /**
37
+ * The inner Three.js BatchedMesh that does the actual rendering.
38
+ * Exposed for direct access when needed (e.g. adding to selectables).
39
+ */
40
+ innerMesh: BatchedMesh;
41
+ globalMaterialIndex: number;
42
+ _bufferElements: BufferElement[];
43
+ private _originalColor;
44
+ /**
45
+ * Map: "modelId:elementId" → instanceId[] (one element can have multiple solids)
46
+ */
47
+ private _elementToInstances;
48
+ /**
49
+ * Reverse map: instanceId → { modelId, elementId }
50
+ * Used for O(1) raycast lookup via `batchId`.
51
+ */
52
+ private _instanceToElement;
53
+ /**
54
+ * instanceId → geometryId (for bounding box lookups)
55
+ */
56
+ private _instanceToGeometry;
57
+ private _selectedElements;
58
+ private _hidingElements;
59
+ private _isolatingElements;
60
+ private _hiddenSet;
61
+ private _isolatedSet;
62
+ private _elementOpacityMap;
63
+ private _elementOriginalColors;
64
+ private _temporaryColors;
65
+ private _ghostColors;
66
+ private _instanceColors;
67
+ private _currentMaxInstances;
68
+ private _currentMaxVertices;
69
+ private _currentMaxIndices;
70
+ private _usedInstances;
71
+ private _usedVertices;
72
+ private _usedIndices;
73
+ private _depthPrePassMesh;
74
+ private _originalTransparent;
75
+ private _originalDepthWrite;
76
+ private _originalRenderOrder;
77
+ constructor(material: Material, initialCapacity?: {
78
+ maxInstances?: number;
79
+ maxVertices?: number;
80
+ maxIndices?: number;
81
+ });
82
+ /**
83
+ * Set color AND alpha for an instance.
84
+ * Three.js `setColorAt` only writes RGB; the alpha channel in the colors texture
85
+ * must be written manually for our custom shader to pick up.
86
+ */
87
+ private _setColorAlphaAt;
88
+ /**
89
+ * Add buffer elements to this batched mesh.
90
+ * Each BufferElement becomes a geometry + instance in the inner BatchedMesh.
91
+ */
92
+ addBufferElements(bufferElements: BufferElement[], materialColor: Color): void;
93
+ /**
94
+ * Append more elements to this batched mesh (streaming/incremental loading).
95
+ */
96
+ batch(newBufferElements: BufferElement[]): void;
97
+ private _ensureCapacity;
98
+ /**
99
+ * O(1) raycast result → element identification.
100
+ * Use `intersection.batchId` from Three.js BatchedMesh raycast.
101
+ */
102
+ findElementByBatchId(batchId: number): {
103
+ modelId: string;
104
+ elementId: string;
105
+ } | null;
106
+ /**
107
+ * Compatibility shim: same signature as ViralBatchedMesh.findElementByFaceIndex.
108
+ * For BatchedMesh, we use batchId instead, but this allows gradual migration.
109
+ * @deprecated Use findElementByBatchId(intersection.batchId) instead
110
+ */
111
+ findElementByFaceIndex(_faceIndex: number): {
112
+ modelId: string;
113
+ elementId: string;
114
+ } | null;
115
+ /**
116
+ * Get buffer elements matching the given element IDs.
117
+ */
118
+ getElements(elements: {
119
+ modelId: string;
120
+ elementId: string;
121
+ }[]): BufferElement[];
122
+ getElementsByModel(modelIndex: number): BufferElement[];
123
+ select(elements: {
124
+ modelId: string;
125
+ elementId: string;
126
+ }[], excepts?: {
127
+ elements: {
128
+ modelId: string;
129
+ elementId: string;
130
+ }[];
131
+ color: {
132
+ r: number;
133
+ g: number;
134
+ b: number;
135
+ };
136
+ }[]): void;
137
+ get selectedElements(): {
138
+ modelId: string;
139
+ elementId: string;
140
+ }[];
141
+ unselect(): void;
142
+ hide(elements?: {
143
+ modelId: string;
144
+ elementId: string;
145
+ }[]): void;
146
+ isolate(elements?: {
147
+ modelId: string;
148
+ elementId: string;
149
+ }[]): {
150
+ modelId: string;
151
+ elementId: string;
152
+ }[];
153
+ isolateModel(modelIds: string[]): void;
154
+ show(elements: {
155
+ modelId: string;
156
+ elementId: string;
157
+ }[]): void;
158
+ reset(): void;
159
+ isElementVisible(modelId: string, elementId: string): boolean;
160
+ setElementOpacity(elements: {
161
+ modelId: string;
162
+ elementId: string;
163
+ }[], opacity: number): void;
164
+ getElementOpacity(modelId: string, elementId: string): number;
165
+ setElementGhost(elements: {
166
+ modelId: string;
167
+ elementId: string;
168
+ }[], ghostOpacity?: number, desaturate?: boolean, ghostColor?: {
169
+ r: number;
170
+ g: number;
171
+ b: number;
172
+ }): void;
173
+ ghostExcept(focusElements: {
174
+ modelId: string;
175
+ elementId: string;
176
+ }[], ghostOpacity?: number, ghostColor?: {
177
+ r: number;
178
+ g: number;
179
+ b: number;
180
+ }): void;
181
+ resetElementOpacity(): void;
182
+ changeColor(elements: {
183
+ modelId: string;
184
+ elementId: string;
185
+ }[], color: {
186
+ r: number;
187
+ g: number;
188
+ b: number;
189
+ }, isTemporary?: boolean): void;
190
+ clearTemporaryColors(elements?: {
191
+ modelId: string;
192
+ elementId: string;
193
+ }[] | null): void;
194
+ resetColor(elements: {
195
+ modelId: string;
196
+ elementId: string;
197
+ }[] | null, _excepts?: {
198
+ elements: {
199
+ modelId: string;
200
+ elementId: string;
201
+ }[];
202
+ color: {
203
+ r: number;
204
+ g: number;
205
+ b: number;
206
+ };
207
+ }[]): void;
208
+ private _edgeLines;
209
+ private _edgeRanges;
210
+ private _edgeThreshold;
211
+ private _edgeMaterial;
212
+ enableEdgePerElement(material: LineMaterial, thresholdDeg?: number): void;
213
+ disableEdge(): void;
214
+ enableEdge(): void;
215
+ refreshEdgesIfAny(): void;
216
+ private _buildMergedEdges;
217
+ isolateEdge(elements?: {
218
+ modelId: string;
219
+ elementId: string;
220
+ }[]): void;
221
+ hideEdge(elements?: {
222
+ modelId: string;
223
+ elementId: string;
224
+ }[]): void;
225
+ edgeReset(): void;
226
+ getElementBoxs(elements: {
227
+ modelId: string;
228
+ elementId: string;
229
+ }[]): Box3 | null;
230
+ getTotalVertexCount(): number;
231
+ getObjectCount(): number;
232
+ get isBatching(): boolean;
233
+ private _isGeneratedLights;
234
+ private _pointLight;
235
+ enableLights(): void;
236
+ disableLights(): void;
237
+ private _calculateCenter;
238
+ private _getFarthestDistance;
239
+ /**
240
+ * Create a depth-only pre-pass mesh that writes depth ONLY for focused (opaque) elements.
241
+ *
242
+ * Strategy: Build a **separate** geometry containing only focused elements' vertices.
243
+ * A plain Mesh renders this geometry with a depth-only MeshBasicMaterial (colorWrite=false,
244
+ * depthWrite=true). Ghost elements are excluded entirely — their geometry is not in the
245
+ * pre-pass mesh, so they never write depth.
246
+ *
247
+ * This ensures opaque elements correctly occlude what's behind them in the depth buffer,
248
+ * while ghost elements (rendered by the main BatchedMesh with depthWrite=false and
249
+ * transparent=true) blend properly without blocking opaque geometry behind them.
250
+ *
251
+ * Since V3 uses identity transforms (positions are already in world space),
252
+ * the pre-pass mesh renders at the correct positions.
253
+ *
254
+ * **Previous approach** (shared geometry + per-vertex color attribute) was buggy:
255
+ * Adding a `color` attribute to the shared BatchedMesh geometry caused the BatchedMesh
256
+ * shader to recompile with `USE_COLOR`, applying both vertex colors AND batching texture
257
+ * colors simultaneously, corrupting rendering. Also, a plain Mesh cannot properly render
258
+ * BatchedMesh geometry which uses WEBGL_multi_draw with internal draw ranges.
259
+ */
260
+ private _createDepthPrePass;
261
+ private _removeDepthPrePass;
262
+ private _getEffectiveAlpha;
263
+ private _getResetColor;
264
+ /**
265
+ * Check if any element currently has opacity below 1.0 (ghost/semi-transparent).
266
+ */
267
+ private _hasTransparentElements;
268
+ /**
269
+ * Update material transparency state based on current element opacities.
270
+ *
271
+ * When any element has opacity < 1.0:
272
+ * - Enables `transparent = true` for proper WebGL alpha blending
273
+ * - Disables `depthWrite` to prevent ghost elements from occluding opaque ones
274
+ * - Creates a depth pre-pass that writes depth ONLY for opaque (focused) elements
275
+ * - Sets `renderOrder = 1` so the main mesh renders after the depth pre-pass
276
+ *
277
+ * When all elements are fully opaque:
278
+ * - Restores opaque rendering (transparent = false, depthWrite = true)
279
+ * - Removes the depth pre-pass
280
+ */
281
+ private _updateMaterialTransparency;
282
+ dispose(): void;
283
+ }
@@ -2,6 +2,7 @@ import { Box3, Mesh } from "three";
2
2
  import { type BufferElement } from "../..";
3
3
  import { WorkerThreadPool } from "../worker/base/worker-pool";
4
4
  import { ViralBatchedMesh } from "./viral-batched-mesh";
5
+ import type { ViralBatchedMeshV3 } from "./viral-batched-mesh-v3";
5
6
  import type { ViralBIMModel } from "./viral-bim.model";
6
7
  import { ViralInstancedMeshV2 } from "./viral-instanced-mesh-v2";
7
8
  /**
@@ -29,6 +30,10 @@ export declare class ViralBIMWorld extends Mesh {
29
30
  addBatchedMesh(mesh: ViralBatchedMesh): void;
30
31
  getBatchedMesh(globalMaterialIndex: number): ViralBatchedMesh | undefined;
31
32
  getBatchedMeshes(): ViralBatchedMesh[];
33
+ protected _batchedMeshesV3: ViralBatchedMeshV3[];
34
+ addBatchedMeshV3(mesh: ViralBatchedMeshV3): void;
35
+ getBatchedMeshV3(globalMaterialIndex: number): ViralBatchedMeshV3 | undefined;
36
+ getBatchedMeshesV3(): ViralBatchedMeshV3[];
32
37
  /**
33
38
  * Get diagnostic info about merged model structure
34
39
  */
@@ -107,4 +107,27 @@ export declare class ViralDataManager {
107
107
  groupBy(keyword?: string): GroupByResult[];
108
108
  unGroupBy(): void;
109
109
  private _shallowCompare;
110
+ /**
111
+ * Get all level/storey IDs for a model
112
+ */
113
+ getLevels(modelId: number): number[];
114
+ /**
115
+ * Get all room/space IDs for a model
116
+ */
117
+ getRooms(modelId: number): number[];
118
+ /**
119
+ * Get all element IDs on a specific level
120
+ */
121
+ getElementsByLevel(modelId: number, levelId: number): number[];
122
+ /**
123
+ * Get all room IDs on a specific level
124
+ */
125
+ getRoomsByLevel(modelId: number, levelId: number): number[];
126
+ /**
127
+ * Isolate all elements belonging to a specific level
128
+ */
129
+ isolateByLevel(modelId: number, levelId: number): {
130
+ modelId: string;
131
+ elementId: string;
132
+ }[];
110
133
  }
@@ -14,9 +14,13 @@ export declare class ViralRenderer {
14
14
  private performRender;
15
15
  accumulateTAAFrames(sampleFrames?: number): void;
16
16
  /**
17
- * Log standard WebGL render statistics
17
+ * Log standard WebGL render statistics including frustum culling info
18
18
  */
19
19
  private logRenderStats;
20
+ /**
21
+ * Compute how many mesh objects are inside the camera frustum
22
+ */
23
+ private computeFrustumStats;
20
24
  /**
21
25
  * Get detailed rendering performance info
22
26
  */
@@ -343,4 +343,11 @@ export declare class ViralVisibilityManager {
343
343
  showHideByPercentage(value?: number): void;
344
344
  randomColor: number;
345
345
  changeRandomColor(value?: number): void;
346
+ /**
347
+ * Isolate elements by level - shows only elements on the specified level
348
+ */
349
+ isolateLevel(modelId: number, levelId: number): {
350
+ modelId: string;
351
+ elementId: string;
352
+ }[];
346
353
  }
@@ -5,6 +5,14 @@ export declare class LoadBatchedElementWorker {
5
5
  viralViewerApi: ViralViewerApi;
6
6
  workerPool: WorkerThreadPool;
7
7
  workerPool2: WorkerThreadPool;
8
+ /**
9
+ * Feature flag: when true, uses ViralBatchedMeshV3 (Three.js BatchedMesh)
10
+ * instead of ViralBatchedMesh (V1) for batched geometry.
11
+ *
12
+ * V3 benefits: per-element frustum culling, automatic depth sorting,
13
+ * GPU-native visibility, O(1) raycast lookup.
14
+ */
15
+ useBatchedMeshV3: boolean;
8
16
  private lastRenderTime;
9
17
  private elementBuffer;
10
18
  private readonly BATCH_THRESHOLD_VERTICES;
@@ -42,6 +50,11 @@ export declare class LoadBatchedElementWorker {
42
50
  * Create single merged mesh (traditional implementation)
43
51
  */
44
52
  private createSingleMergedMesh;
53
+ /**
54
+ * Create single merged mesh using Three.js BatchedMesh (V3).
55
+ * Per-element frustum culling, automatic depth sorting, GPU-native visibility.
56
+ */
57
+ private createSingleMergedMeshV3;
45
58
  private createSingleInstancedMesh;
46
59
  /**
47
60
  * Create optimized material for merging with per-element opacity support
@@ -54,6 +67,12 @@ export declare class LoadBatchedElementWorker {
54
67
  * where the alpha channel controls per-element transparency
55
68
  */
56
69
  private injectPerElementOpacityShader;
70
+ /**
71
+ * Create optimized material for V3 (Three.js BatchedMesh).
72
+ * Unlike V1, V3 doesn't use vertexColors — it uses BatchedMesh's per-instance colors.
73
+ * Alpha is injected via custom shader reading from batchingColorTexture.
74
+ */
75
+ private createOptimizedMaterialV3;
57
76
  /**
58
77
  * Throttled render to avoid excessive render calls
59
78
  */
@@ -66,6 +85,11 @@ export declare class LoadBatchedElementWorker {
66
85
  * 🚀 Flush accumulated elements for a specific material
67
86
  */
68
87
  private flushBuffer;
88
+ /**
89
+ * V3 flush: appends elements to existing ViralBatchedMeshV3 or creates a new one.
90
+ * No 500K vertex limit — BatchedMesh handles capacity internally.
91
+ */
92
+ private flushBufferV3;
69
93
  /**
70
94
  * 🚀 Flush all remaining buffers (call this when loading is complete)
71
95
  */
@@ -98,6 +98,28 @@ export declare class DataTree {
98
98
  buildGraphIndex(): void;
99
99
  getLinkedElements(id: number): number[];
100
100
  getNeighborsByType(id: number, type: string): number[];
101
+ /**
102
+ * Get all level/storey IDs in this model.
103
+ * Uses HAS_LEVEL relationships (building→storey) from both Revit and IFC.
104
+ * Falls back to collecting unique ToId from ON_LEVEL relationships.
105
+ */
106
+ getLevels(): number[];
107
+ /**
108
+ * Get all room/space IDs in this model.
109
+ * Uses HAS_ROOM relationships (storey→room) from both Revit and IFC.
110
+ * Falls back to collecting unique ToId from IN_SPACE relationships.
111
+ */
112
+ getRooms(): number[];
113
+ /**
114
+ * Get all element IDs on a specific level.
115
+ * Uses ON_LEVEL relationships (element→level) via the inverse index.
116
+ */
117
+ getElementsByLevel(levelId: number): number[];
118
+ /**
119
+ * Get all room IDs on a specific level.
120
+ * Uses HAS_ROOM relationships (storey→room) from the outgoing edges.
121
+ */
122
+ getRoomsByLevel(levelId: number): number[];
101
123
  /**
102
124
  * Calculate hierarchical depth for nodes using BFS from root nodes
103
125
  * Root nodes (no incoming edges) get level 0, their children get level 1, etc.
@@ -11,6 +11,12 @@ export interface ViewerOptions {
11
11
  */
12
12
  adaptiveEdges?: boolean;
13
13
  adaptiveAmbientOcclusion?: boolean;
14
+ /**
15
+ * Use Three.js BatchedMesh (V3) instead of custom ViralBatchedMesh (V1).
16
+ * Enables per-element frustum culling, GPU-sorted rendering, and better performance.
17
+ * Default: false (V1 path)
18
+ */
19
+ useBatchedMeshV3?: boolean;
14
20
  /**
15
21
  * from 0 to 1, step 0.1
16
22
  */
@@ -4,8 +4,7 @@ export declare class ViralDraggableModal {
4
4
  private modal;
5
5
  private modalTitle;
6
6
  private modalBody;
7
- private modalBodyLeft;
8
- private modalBodyRight;
7
+ private _currentModelId;
9
8
  properties: {
10
9
  [key: string]: {
11
10
  [key: string]: string;
@@ -15,7 +14,6 @@ export declare class ViralDraggableModal {
15
14
  private rawModalStyle;
16
15
  isDragging: boolean;
17
16
  isResizing: boolean;
18
- isResizingColumns: boolean;
19
17
  offsetX: number;
20
18
  offsetY: number;
21
19
  private minWidth;
@@ -26,4 +24,27 @@ export declare class ViralDraggableModal {
26
24
  hide(): void;
27
25
  updatePosition(clientX: number, clientY: number): void;
28
26
  updateModalContent(modelId: number, elementId: number): void;
27
+ /**
28
+ * Group properties for display.
29
+ * Handles three cases:
30
+ * 1. Pre-flattened dot-notation keys ("GlobalId.name") → group by prefix
31
+ * 2. Nested objects (GlobalId: {type,value,name}) → expand children
32
+ * 3. Simple values (expressID: 123) → single row
33
+ */
34
+ private _groupProperties;
35
+ /**
36
+ * Check if a value is an IFC REF (type === 5, pointing to another expressID)
37
+ */
38
+ private _isIfcRef;
39
+ private _resolveDisplayValue;
40
+ /**
41
+ * Check if a property value is a nested object that should be shown as a collapsible group.
42
+ * Skips simple {value, type, name} IFC wrappers and ViralutionParameter objects.
43
+ */
44
+ private _isNestedObject;
45
+ /**
46
+ * Extract displayable child entries from a nested object.
47
+ * Returns [key, displayValue] pairs.
48
+ */
49
+ private _getChildEntries;
29
50
  }
@@ -0,0 +1,48 @@
1
+ import type { ViralViewerApi } from "../../viral-viewer-api";
2
+ export declare class ViralMeshDebugPanel {
3
+ viralViewerApi: ViralViewerApi;
4
+ private panel;
5
+ private listContainer;
6
+ private isVisible;
7
+ private activeTab;
8
+ private styleElement;
9
+ private _coloringActive;
10
+ private _savedMaterials;
11
+ private _savedV3Materials;
12
+ private _savedInstancedMaterials;
13
+ constructor(viralViewerApi: ViralViewerApi);
14
+ private inject;
15
+ private createButton;
16
+ private injectStyles;
17
+ private attachEventListeners;
18
+ show(): void;
19
+ hide(): void;
20
+ toggle(): void;
21
+ private getEntries;
22
+ private getFilteredEntries;
23
+ private badgeFor;
24
+ private refreshList;
25
+ private getCategoryCounts;
26
+ private renderBatchEntry;
27
+ private renderInstancedEntry;
28
+ private isolateMesh;
29
+ private isolateInternalMesh;
30
+ private showAllMeshes;
31
+ private hideAllMeshes;
32
+ private clearIsolation;
33
+ private generateDistinctColor;
34
+ private createColorMaterial;
35
+ private getTargetCategories;
36
+ /**
37
+ * Isolate the current tab's category: show only that type, hide others.
38
+ */
39
+ private isolateCategory;
40
+ /**
41
+ * Apply distinct colors per globalMaterialIndex to currently visible meshes
42
+ * in the active tab's category.
43
+ */
44
+ private applyColors;
45
+ private restoreColors;
46
+ logAllDetails(): void;
47
+ dispose(): void;
48
+ }