1/** 2 * Idle Aquarium sitewide background â ocean art, plants, fish, caustics wash. 3 */ 4(function (global) { 5 'use strict'; 6 7 var CSS_HREF = '/css/aquariumBackground.css'; 8 var AQUARIUM_SCRIPT = '/scripts/code stuffs/aquarium.js'; 9 var GLOW_SCRIPT = '/scripts/followers/fishBuddyGlow.js'; 10 var CAUSTICS_SCRIPTS = [ 11 '/scripts/dependencies/webglCaustics.js', 12 '/scripts/dependencies/causticsTextureLoader.js', 13 '/scripts/dependencies/webglAurora.js' 14 ]; 15 16 var activeScene = null; 17 var cssLoaded = false; 18 var visible = false; 19 20 function loadScript(src) { 21 if (global.PupwifeScriptLoad && typeof global.PupwifeScriptLoad.once === 'function') { 22 return global.PupwifeScriptLoad.once(src); 23 } 24 return new Promise(function (resolve, reject) { 25 if (document.querySelector('script[src="' + src + '"]')) { 26 resolve(); 27 return; 28 } 29 var s = document.createElement('script'); 30 s.src = src; 31 s.async = false; 32 s.onload = function () { resolve(); }; 33 s.onerror = function () { reject(new Error('Failed to load ' + src)); }; 34 document.body.appendChild(s); 35 }); 36 } 37 38 function ensureStylesheet() { 39 if (cssLoaded || document.querySelector('link[data-site-aquarium-bg="1"]')) { 40 cssLoaded = true; 41 return Promise.resolve(); 42 } 43 return new Promise(function (resolve, reject) { 44 var link = document.createElement('link'); 45 link.rel = 'stylesheet'; 46 link.href = CSS_HREF; 47 link.setAttribute('data-site-aquarium-bg', '1'); 48 link.onload = function () { 49 cssLoaded = true; 50 resolve(); 51 }; 52 link.onerror = function () { reject(new Error('Failed to load ' + CSS_HREF)); }; 53 document.head.appendChild(link); 54 }); 55 } 56 57 function insertBeforePageWrap(node) { 58 var anchor = document.getElementById('page-wrap') || 59 document.getElementById('citrusos-boot') || 60 document.body.firstChild; 61 if (anchor && anchor.parentNode) { 62 anchor.parentNode.insertBefore(node, anchor); 63 } else { 64 document.body.appendChild(node); 65 } 66 } 67 68 function ensureShellMarkup() { 69 var root = document.getElementById('site-aquarium-root'); 70 if (!root) { 71 root = document.createElement('div'); 72 root.id = 'site-aquarium-root'; 73 root.setAttribute('aria-hidden', 'true'); 74 insertBeforePageWrap(root); 75 } 76 77 if (!document.getElementById('site-aquarium-ocean')) { 78 var ocean = document.createElement('div'); 79 ocean.id = 'site-aquarium-ocean'; 80 root.appendChild(ocean); 81 } 82 83 if (!document.getElementById('site-aquarium-plants')) { 84 var plants = document.createElement('div'); 85 plants.id = 'site-aquarium-plants'; 86 plants.className = 'plants'; 87 root.appendChild(plants); 88 } 89 90 if (!document.getElementById('site-aquarium-fish')) { 91 var fish = document.createElement('div'); 92 fish.id = 'site-aquarium-fish'; 93 root.appendChild(fish); 94 } 95 96 if (!document.getElementById('fish-glow-overlay')) { 97 var glow = document.createElement('div'); 98 glow.id = 'fish-glow-overlay'; 99 glow.style.cssText = 'position:fixed;inset:0;pointer-events:none;z-index:4;'; 100 insertBeforePageWrap(glow); 101 } 102 103 return root; 104 } 105 106 function setShellVisible(show) { 107 var root = document.getElementById('site-aquarium-root'); 108 var ocean = document.getElementById('site-aquarium-ocean'); 109 var plants = document.getElementById('site-aquarium-plants'); 110 var fish = document.getElementById('site-aquarium-fish'); 111 var display = show ? '' : 'none'; 112 if (root) root.style.display = display; 113 if (ocean) ocean.style.display = display; 114 if (plants) plants.style.display = display; 115 if (fish) fish.style.display = display; 116 visible = show; 117 } 118 119 function loadCausticsStack(ctx) { 120 if (ctx && typeof ctx.ensureCausticsStack === 'function') { 121 return ctx.ensureCausticsStack().then(function () { 122 if (typeof global.setCausticsTexture === 'function') { 123 global.setCausticsTexture('/images/your_noise.webp', 0.69); 124 } else if (global.__causticsTextureLoader && 125 typeof global.__causticsTextureLoader.loadDefaultNoise === 'function') { 126 global.__causticsTextureLoader.loadDefaultNoise(); 127 } 128 }); 129 } 130 var chain = Promise.resolve(); 131 if (typeof global.THREE === 'undefined' && global.SiteBackgroun
131ds && global.SiteBackgrounds.THREE_CDN) { 132 chain = chain.then(function () { return loadScript(global.SiteBackgrounds.THREE_CDN); }); 133 } 134 CAUSTICS_SCRIPTS.forEach(function (src) { 135 chain = chain.then(function () { return loadScript(src); }); 136 }); 137 return chain; 138 } 139 140 function loadAquariumScene() { 141 global.__aquariumDeferAutoBoot = true; 142 return loadScript(AQUARIUM_SCRIPT).then(function () { 143 if (!global.AquariumScene || typeof global.AquariumScene.boot !== 'function') { 144 throw new Error('AquariumScene unavailable'); 145 } 146 }); 147 } 148 149 function loadGlowIfNeeded() { 150 if (document.querySelector('script[src="' + GLOW_SCRIPT + '"]')) { 151 return Promise.resolve(); 152 } 153 if (typeof global.THREE === 'undefined' && global.SiteBackgrounds && global.SiteBackgrounds.THREE_CDN) { 154 return loadScript(global.SiteBackgrounds.THREE_CDN).then(function () { 155 return loadScript(GLOW_SCRIPT); 156 }); 157 } 158 return loadScript(GLOW_SCRIPT); 159 } 160 161 function bootScene() { 162 if (activeScene) return activeScene; 163 var fishMount = document.getElementById('site-aquarium-fish'); 164 var plantsMount = document.getElementById('site-aquarium-plants'); 165 if (!fishMount || !global.AquariumScene) return null; 166 activeScene = global.AquariumScene.boot({ 167 aquariumEl: fishMount, 168 plantsEl: plantsMount, 169 skipKeydown: true 170 }); 171 return activeScene; 172 } 173 174 function init(ctx) { 175 ensureShellMarkup(); 176 return ensureStylesheet() 177 .then(function () { return loadCausticsStack(ctx); }) 178 .then(function () { return loadAquariumScene(); }) 179 .then(function () { return loadGlowIfNeeded(); }) 180 .then(function () { 181 setShellVisible(true); 182 bootScene(); 183 if (activeScene && typeof activeScene.resume === 'function') { 184 activeScene.resume(); 185 } 186 global.__spaBackgroundReady = true; 187 return true; 188 }) 189 .catch(function (err) { 190 console.warn('[aquariumBackground] init failed', err); 191 return false; 192 }); 193 } 194 195 function stop() { 196 if (activeScene && typeof activeScene.pause === 'function') { 197 activeScene.pause(); 198 } 199 } 200 201 function hide() { 202 setShellVisible(false); 203 stop(); 204 } 205 206 function destroy(removeShell) { 207 stop(); 208 if (activeScene && typeof activeScene.destroy === 'function') { 209 activeScene.destroy(); 210 } 211 activeScene = null; 212 if (removeShell) { 213 var root = document.getElementById('site-aquarium-root'); 214 if (root && root.parentNode) root.parentNode.removeChild(root); 215 } else { 216 hide(); 217 } 218 } 219 220 global.AquariumBackground = { 221 init: init, 222 stop: stop, 223 hide: hide, 224 destroy: destroy, 225 show: function () { 226 setShellVisible(true); 227 if (!activeScene) bootScene(); 228 if (activeScene && typeof activeScene.resume === 'function') activeScene.resume(); 229 } 230 }; 231})(typeof window !== 'undefined' ? window : this);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.