1self.skipWaiting(); 2 3const wait = (ev, asyncFn) => ev.waitUntil(asyncFn()); 4 5self.addEventListener("activate", (ev) => { 6 wait(ev, async () => { 7 await self.clients.claim(); 8 9 if (self.registration.navigationPreload) { 10 await self.registration.navigationPreload.enable(); 11 } 12 }); 13}); 14 15self.addEventListener("fetch", (event) => { 16 if (event.request.mode === "navigate") { 17 event.respondWith( 18 (async () => { 19 try { 20 const preloadResp = await event.preloadResponse; 21 if (preloadResp) { 22 return preloadResp; 23 } 24 25 return await fetch(event.request); 26 } catch (_e) { 27 return new Response( 28 ` 29 <!DOCTYPE html> 30 <html lang="en" dir="ltr"> 31 32 <head> 33 <meta charset="UTF-8"> 34 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 35 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 36 <title>No Internet Connection!</title> 37 <script> 38 !localStorage.dark && ("dark" in localStorage || !matchMedia("(prefers-color-scheme:dark)").matches) || document.documentElement.classList.add("dark"); 39 </script> 40 <style> 41 * { 42 --bg-color: white; 43 --text-color: black; 44 } 45 46 .dark, 47 .dark * { 48 --bg-color: #282828; 49 --text-color: #ebebeb; 50 } 51 52 @keyframes slide-in-blurred-top { 53 0% { 54 transform: translateY(-1000px) scaleY(2.5) scaleX(0.2); 55 transform-origin: 50% 0%; 56 filter: blur(40px); 57 opacity: 0; 58 } 59 100% { 60 transform: translateY(0) scaleY(1) scaleX(1); 61 transform-origin: 50% 50%; 62 filter: blur(0); 63 opacity: 1; 64 } 65 } 66 .slide-in-blurred-top { 67 animation: slide-in-blurred-top 0.6s cubic-bezier(0.230, 1.000, 0.320, 1.000) both; 68 } 69 70 body { 71 background-color: var(--bg-color); 72 color: var(--text-color); 73 display: flex; 74 flex-direction: column; 75 gap: 1rem; 76 margin: 0; 77 padding: 5rem 0; 78 justify-content: center; 79 align-items: center; 80 width: 100%; 81 height: 100%; 82 direction: ltr; 83 text-align: left; 84 } 85 * { 86 font-family: -apple-system, BlinkMacSystemFont, Arial, sans-serif; 87 line-height: 1.6; 88 } 89 .retry-btn { 90 background-color: #198b6f; 91 color: white; 92 border-radius: 9999px; 93 font-size: 0.9rem; 94 font-weight: bold; 95 padding: 0.4rem 1.2rem; 96 text-decoration: none; 97 transition: background-color 0.3s ease; 98 } 99 .retry-btn:hover, 100 .retry-btn:focus { 101 background-color: #0c7259; 102 } 103 .retry-btn:active { 104 background-color: #26a385; 105 } 106 </style> 107 </head> 108 109 <body> 110 <svg class="slide-in-blurred-top" style="animation-delay:0.7s;width:10rem;height:10rem;" width="450" height="450" stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><g id="Wi-Fi_Off"><g><path d="M10.37,6.564a12.392,12.392,0,0,1,10.71,3.93c.436.476,1.141-.233.708-.708A13.324,13.324,0,0,0,10.37,5.564c-.631.076-.638,1.077,0,1Z"></path><path d="M13.907,10.283A8.641,8.641,0,0,1,18.349,12.9c.434.477,1.139-.232.707-.707a9.586,9.586,0,0,0-4.883-2.871c-.626-.146-.893.818-.266.965Z"></path><circle cx="12.003" cy="16.922" r="1.12"></circle><path d="M19.773,19.06a.5.5,0,0,1-.71.71l-5.84-5.84A4.478,4.478,0,0,0,8.7,15.24c-.43.48-1.14-.23-.71-.7a5.47,5.47,0,0,1,4.06-1.78l-2.37-2.37a8.693,8.693,0,0,0-4.03,2.53c-.43.48-1.13-.23-.7-.71A9.439,9.439,0,0,1,8.893,9.6L6.883,7.59a12.557,12.557,0,0,0-3.96,2.94.5.5,0,1,1-.7-.71,13.109,13.109,0,0,1,3.91-2.98l-1.9-1.9a.5.5,0,0,1,.71-.71Z"></path></g></g></svg> 111 112 <div class="slide-in-blurred-top" style="animation-delay:0.9s;display:flex;align-items:center;justify-content:center;gap:1rem;margin-bottom:1rem;"> 113 <h1 style="margin:0;font-weight:normal;font-size:1.6rem;opacity:0.5;"> 114 No Internet Connection! 115 </h1> 116 </div> 117 118 119 <a href="" class="slide-in-blurred-top retry-btn" style="animation-delay:1.1s;"> 120 Retry 121 </a> 122 123 <script> 124 navigator.serviceWorker 125 .register("/sw.js", { scope: "/" }) 126 .then((reg) =>
126 reg.update()) 127 .catch(console.warn); 128 </script> 129 </body> 130 131 </html> 132 `.trim(), 133 { 134 status: 503, 135 statusText: "Service Unavailable", 136 headers: { "content-type": "text/html; charset=UTF-8" }, 137 } 138 ); 139 } 140 })() 141 ); 142 } 143}); 144 145self.addEventListener("push", (ev) => { 146 wait(ev, async () => { 147 try { 148 const data = (() => { 149 if (ev.data) { 150 try { 151 return ev.data.json(); 152 } catch (e) {} 153 } 154 return { title: "New Notification", link: "/panel/login" }; 155 })(); 156 157 data.tag = "app.sw.notification"; 158 data.renotify = true; 159 await self.registration.showNotification(data.title, data); 160 } catch (error) { 161 console.warn(error); 162 } 163 164 await self.registration.update(); 165 }); 166}); 167 168self.addEventListener("notificationclick", (ev) => { 169 ev.notification.close(); 170 171 wait(ev, async () => { 172 const { link } = ev.notification.data || {}; 173 await self.clients.openWindow(link || "/"); 174 }); 175});
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.