PageSourceSearch

https://wgt.jetzt/pwa-sw.js

js wgt.jetzt collected 2026-10-02 23:58:00 UTC 32,482 bytes, 843 lines download raw bytes

1const CACHE_VERSION = '2.0.1.5';
2
3const BASE_CACHE_FILES = [
4    'https://wgt.jetzt/wp-content/uploads/2020/03/wgt_app_icon.png',
5'',
6'https://wgt.jetzt/wp-content/uploads/2020/03/wgt_icon_ios.jpg',
7'',
8'https://wgt.jetzt/wp-content/uploads/2020/03/splash_screen_iphone8.jpg',
9'https://wgt.jetzt/wp-content/plugins/pwa-for-wp/images/logo-512x512.png',
10'https://wgt.jetzt/offline/https://wgt.jetzt/404-not-found/',
11'https://wgt.jetzt/code-fuer-demokratie-digitale-ideen-fuer-eine-starke-demokratie/',
12'https://wgt.jetzt/turniertag-in-stuttgart-am-sportplatz-beim-zueblinparkhaus/',
13'https://wgt.jetzt/unsere-jgr-ostereieraktion-war-wieder-eine-wertschaetzende-und-inspirierende-erfahrung/',
14'https://wgt.jetzt/kleidertausch/',
15'https://wgt.jetzt/iftar-cup-trifft-skatepark-eroeffnung-saisonstart-im-skatepark-weingarten/',
16'https://wgt.jetzt/das-quatschmobil-ist-wieder-im-stadtgebiet-unterwegs/',
17'https://wgt.jetzt/spiel-und-spass-im-haus-der-familie/',
18'https://wgt.jetzt/diese-botschaften-hatte-tiktok-star-qualle-in-weingarten-dabei/',
19'https://wgt.jetzt/in-zwei-wochen-wird-getauscht-und-getanzt/',
20'https://wgt.jetzt/sport-und-action-zum-jahresabschluss/',
21'https://wgt.jetzt/404-nicht-gefunden/',
22
23];
24
25const OFFLINE_CACHE_FILES = [
26     'https://wgt.jetzt/offline/',
27];
28
29const NOT_FOUND_CACHE_FILES = [
30    'https://wgt.jetzt/404-nicht-gefunden/',
31];
32
33const OFFLINE_PAGE = 'https://wgt.jetzt/offline/';
34const NOT_FOUND_PAGE = 'https://wgt.jetzt/404-nicht-gefunden/';
35
36const CACHE_VERSIONS = {
37    content: 'content-v' + CACHE_VERSION,
38    notFound: '404-v' + CACHE_VERSION,
39    offline: 'offline-v' + CACHE_VERSION,
40};
41
42// Define MAX_TTL's in SECONDS for specific file extensions
43const MAX_TTL = {
44    '/': 3600,
45    html: 3600,
46    json: 3600,
47    js: 3600,
48    css: 3600,
49    png: 3600,
50    jpg: 3600,
51};
52
53const CACHE_STRATEGY = {
54    default: 'networkFirst',
55    css_js: 'cacheFirst',
56    images: 'cacheFirst',
57    fonts: 'cacheFirst',
58};
59
60const CACHE_BLACKLIST =  [
61//    (str) => {
62//        return !str.includes('/wp-admin/') || !str.startsWith('https://wgt.jetzt//wp-admin/');
63//    },
64];
65const neverCacheUrls = [/\/wp-admin/,/\/wp-login/,/preview=true/,/\/cart/,/ajax/,/login/,];
66
67const PWA_VISIBILITY_BYPASS_PATHS = [];
68
69/**
70 * Same path rules as frontend visibility_excludes: exact path or subpaths.
71 * @param {string} pathname request URL pathname
72 * @returns {boolean}
73 */
74function pwaForWpVisibilityBypassPath(pathname) {
75    if (!PWA_VISIBILITY_BYPASS_PATHS.length) {
76        return false;
77    }
78    var norm = pathname.replace(/\/+$/, '');
79    if (norm === '') {
80        norm = '/';
81    }
82    for (var i = 0; i < PWA_VISIBILITY_BYPASS_PATHS.length; i++) {
83        var prefix = String(PWA_VISIBILITY_BYPASS_PATHS[i]).replace(/\/+$/, '');
84        if (norm === prefix || norm.indexOf(prefix + '/') === 0) {
85            return true;
86        }
87    }
88    return false;
89}
90
91const SUPPORTED_METHODS = [
92    'GET',
93];
94// Check if current url is in the neverCacheUrls list
95function pwaForWpcheckNeverCacheList(url) {
96    if ( this.match(url) ) {
97        return false;
98    }
99    return true;
100}
101/**
102 * pwaForWpisBlackListed
103 * @param {string} url
104 * @returns {boolean}
105 */
106function pwaForWpisBlackListed(url) {
107    return (CACHE_BLACKLIST.length > 0) ? !CACHE_BLACKLIST.filter((rule) => {
108        if(typeof rule === 'function') {
109            return !rule(url);
110        } else {
111            return false;
112        }
113    }).length : false
114}
115
116/**
117 * pwaForWpgetFileExtension
118 * @param {string} url
119 * @returns {string}
120 */
121function pwaForWpgetFileExtension(url) {
122    
123    if (typeof url === 'string') {
124     
125        let split_two = url.split('?');
126        let split_url = split_two[0];
127
128        let extension = split_url.split('.').reverse()[0].split('?')[0];		
129        return (extension.endsWith('/')) ? '/' : extension;
130        
131    }else{
132        return null;
133    }            
134}
135/**
136 * pwaForWpgetTTL
137 * @param {string} url
138 */
139function pwaForWpgetTTL(url) {
140    if (typeof url === 'string') {
141        let extension = pwaForWpgetFileExtension(url);
142        if (typeof MAX_TTL[extension] === 'number') {
143            return MAX_TTL[extension];
144        } else {
145            return MAX_TTL["/"];
146        }
147    } else {
148        return MAX_TTL["/"];
149    }
150}
151
152/**
153 * pwaForWpinstallServiceWorker
154 * @returns {Promise}
155 */
156function pwaForWpinstallServiceWorker() {
157    return Promise.all(
158        [
159            caches.open(CACHE_VERSIONS.content)
160                .then(
161                    (cache) => {
162                        
163                        if(BASE_CACHE_FILES.length >0){
164                        
165                            for (var i = 0; i < BASE_CACHE_FILES.length; i++) {
166                            
167                             pwaForWpprecacheUrl(BASE_CACHE_FILES[i]) 
168                       
169                            }
170                            
171                        }
172                        
173                        //return cache.addAll(BASE_CACHE_FILES);
174                    }
175                ),
176            caches.open(CACHE_VERSIONS.offline)
177                .then(
178                    (cache) => {
179                        return cache.addAll(OFFLINE_CACHE_FILES);
180                    }
181                ),
182            caches.open(CACHE_VERSIONS.notFound)
183                .then(
184                    (cache) => {
185                        return cache.addAll(NOT_FOUND_CACHE_FILES);
186                    }
187                )
188        ]
189    )
190        .then(() => {
191            return self.skipWaiting();
192        });
193}
194
195/**
196 * pwaForWpcleanupLegacyCache
197 * @returns {Promise}
198 */
199function pwaForWpcleanupLegacyCache() {
200
201    let currentCaches = Object.keys(CACHE_VERSIONS)
202        .map(
203            (key) => {
204                return CACHE_VERSIONS[key];
205            }
206        );
207
208    return new Promise(
209        (resolve, reject) => {
210
211            caches.keys()
212                .then(
213                    (keys) => {
214                        return legacyKeys = keys.filter(
215                            (key) => {
216                                return !~currentCaches.indexOf(key);
217                            }
218                        );
219                    }
220                )
221                .then(
222                    (legacy) => {
223                        if (legacy.length) {
224                            Promise.all(
225                                legacy.map(
226                                    (legacyKey) => {
227                                        return caches.delete(legacyKey)
228                                    }
229                                )
230                            )
231                                .then(
232                                    () => {
233                                        resolve()
234                                    }
235                                )
236                                .catch(
237                                    (err) => {
238                                        reject(err);
239                                    }
240                                );
241                        } else {
242                            resolve();
243                        }
244                    }
245                )
246                .catch(
247                    () => {
248                        reject();
249                    }
250                );
251
252        }
253    );
254}
255
256function pwaForWpprecacheUrl(url) {
257
258    if(!pwaForWpisBlackListed(url)) {
259        caches.open(CACHE_VERSIONS.content)
260            .then((cache) => {
261                cache.match(url)
262                    .then((response) => {
263                        if(!response) {
264                            return fetch(url)
265                        } else {
266                            // already in cache, nothing to do.
267                            return null
268                        }
269                    })
270                    .then((response) => {
271                        if(response) {						                                                     
272                             fetch(url).then(dataWrappedByPromise => dataWrappedByPromise.text())									
273                             .then(data => {
274							 if(data){
275                                const regex = /<img[^>]+src="(https:\/\/[^">]+)"/g;
276                                let m;
277                                while ((m = regex.exec(data)) !== null) {
278                                    if (m.index === regex.lastIndex) {
279                                            regex.lastIndex++;
280                                    }
281                                    m.forEach((match, groupIndex) => {
282                                            if(groupIndex == 1){
283                                                if(new URL(match).origin == location.origin){
284                                                    fetch(match).
285                                                            then((imagedata) => {
286                                                                    //console.log(imagedata);
287                                                                    cache.put(match, imagedata.clone());
288
289                                                    });
290                                                }
291                                            }
292                                    });
293                                }
294
295
296                            }
297
298
299					});
300											                                                                                						
301                            return cache.put(url, response.clone());
302                        } else {
303                            return null;
304                        }
305                    });
306            })
307    }
308}
309
310var fetchRengeData = function(event){
311    var pos = Number(/^bytes\=(\d+)\-$/g.exec(event.request.headers.get('range'))[1]);
312            console.log('Range request for', event.request.url, ', starting position:', pos);
313            event.respondWith(
314              caches.open(CACHE_VERSIONS.content)
315              .then(function(cache) {
316                return cache.match(event.request.url);
317              }).then(function(res) {
318                if (!res) {
319                  return fetch(event.request)
320                  .then(res => {
321                    return res.arrayBuffer();
322                  });
323                }
324                return res.arrayBuffer();
325              }).then(function(ab) {
326                return new Response(
327                  ab.slice(pos),
328                  {
329                    status: 206,
330                    statusText: 'Partial Content',
331                    headers: [
332                      // ['Content-Type', 'video/webm'],
333                      ['Content-Range', 'bytes ' + pos + '-' +
334                        (ab.byteLength - 1) + '/' + ab.byteLength]]
335                  });
336              }));
337}
338
339let cachingStrategy = {
340        notGetMethods: function(event){
341            // If non-GET request, try the network first, fall back to the offline page
342            if (event.request.method !== 'GET') {
343                event.respondWith(
344                    fetch(event.request)
345                        .catch(error => {
346                            return caches.match(offlinePage);
347                        })
348                );
349                return false;
350            }
351        },
352
353        fetchFromCache: function(event){
354           /* return new Promise(
355                            (resolve) => {*/
356                return caches.open(CACHE_VERSIONS.content)
357                    .then(
358                        (cache) => {
359
360                            return cache.match(event.request)
361                                .then(
362                                    (response) => {
363
364                                        if (response) {
365
366                                            let headers = response.headers.entries();
367                                            let date = null;
368
369                                            for (let pair of headers) {
370                                                if (pair[0] === 'date') {
371                                                    date = new Date(pair[1]);
372                                                }
373                                            }
374
375                                            if (date) {
376                                                let age = parseInt((new Date().getTime() - date.getTime())/1000);
377                                                let ttl = pwaForWpgetTTL(event.request.url);
378
379                                                if (age > ttl) {
380
381                                                    return new Promise(
382                                                        (resolve) => {
383
384                                                            return fetch(event.request.clone())
385                                                                .then(
386                                                                    (updatedResponse) => {
387                                                                        if (updatedResponse) {
388                                                                            cache.put(event.request, updatedResponse.clone());
389                                                                            resolve(updatedResponse);
390                                                                        } else {
391                                                                            resolve(response)
392                                                                        }
393                                                                    }
394                                                                )
395                                                                .catch(
396                                                                    () => {
397                                                                        resolve(response);
398                                                                    }
399                                                                );
400
401                                                        }
402                                                    )
403                                                        .catch(
404                                                            (err) => {
405                                                                return response;
406                                                            }
407                                                        );
408                                                } else {
409                                                    return response;
410                                                }
411
412                                            } else {
413                                                return response;
414                                            }
415
416                                        } else {
417                                            return null;
418                                        }
419                                    }
420                                )
421                                .then(
422                                    (response) => {
423                                        if (response) {
424                                            return response;
425                                        } else {
426                                            return fetch(event.request.clone(), {cache: "no-store"})
427                                                .then(
428                                                    (response) => {
429
430                                                        if(response.status < 300) {
431                                                            if (~SUPPORTED_METHODS.indexOf(event.request.method) && !pwaForWpisBlackListed(event.request.url)) {
432                                                                cache.put(event.request, response.clone());
433                                                            }
434                                                                return response;
435                                                        } else {
436                                                            return caches.open(CACHE_VERSIONS.notFound).then((cache) => {
437                                                                return cache.match(NOT_FOUND_PAGE);
438                                                            })
439                                                        }
440                                                    }
441                                                )
442                                                .then((response) => {
443                                                    if (response) {
444                                                        return response;
445                                                    }
446                                                    return cachingStrategy.Offlinepage();
447                                                })
448                                                .catch(
449                                                    () => {
450                                                        return cachingStrategy.Offlinepage();
451                                                    }
452                                                );
453                                        }
454                                    }
455                                )
456                                .catch(
457                                    (error) => {
458                                        console.error('  Error in fetch handler:', error);
459                                        return cachingStrategy.Offlinepage();
460                                    }
461                                );
462                        }
463                    )
464            /*})*/
465
466        },
467        fetchnetwork: function(event){
468            return caches.open(CACHE_VERSIONS.content)
469                    .then(
470                        (cache) => {
471                           return fetch(event.request.clone()).then(function (response) {
472
473                                if(response.status < 300) {
474                                    if (~SUPPORTED_METHODS.indexOf(event.request.method) && !pwaForWpisBlackListed(event.request.url)) {
475                                        cache.put(event.request, response.clone());
476                                    }
477                                        return response;
478                                }else if(response.status==404){
479                                    return cachingStrategy.Notfoundpage();
480                                }
481                                return cache.match(event.request).then(function (cached) {
482                                    return cached || cachingStrategy.Offlinepage();
483                                });
484                              }).catch(
485                                   function () {
486                                        return cache.match(event.request).then(function (cached) {
487                                            return cached || cachingStrategy.Offlinepage();
488                                        });
489                                    }
490                              );
491                        }
492                    ).catch(
493                           (err) => {
494                                return cachingStrategy.Offlinepage();
495                            }
496                      )
497        },
498        addCache: function(event,updatedResponse){
499            cache.put(event.request, updatedResponse.clone());
500             resolve(updatedResponse);
501        },
502        Offlinepage: function(){
503            var fallbackHtml = '<html><head><title>Offline</title></head><body><h1>You are offline</h1><p>Please check your internet connection.</p></body></html>';
504            var fallback = new Response(fallbackHtml, {
505                status: 503,
506                statusText: 'Service Unavailable',
507                headers: new Headers({
508                    'Content-Type': 'text/html; charset=UTF-8'
509                })
510            });
511            return caches.open(CACHE_VERSIONS.offline).then(function (cache) {
512                return cache.match(OFFLINE_PAGE).then(function (r) {
513                    return r || cache.match(OFFLINE_PAGE, { ignoreSearch: true });
514                });
515            }).then(function (response) {
516                return response || fallback;
517            }).catch(function () {
518                return fallback;
519            });
520        },
521        Notfoundpage: function(){
522            return caches.open(CACHE_VERSIONS.notFound).then((cache) => {
523                return cache.match(NOT_FOUND_PAGE);
524            }).then(function (response) {
525                if (response) {
526                    return response;
527                }
528                return new Response('<html><head><title>Page Not Found</title></head><body><h1>404 - Page Not Found</h1></body></html>', {
529                    status: 404,
530                    statusText: 'Not Found',
531                    headers: new Headers({
532                        'Content-Type': 'text/html; charset=UTF-8'
533                    })
534                });
535            });
536        },
537        /*Strategies*/
538        networkOnlyStrategy: function(event){
539            return caches.open(CACHE_VERSIONS.content)
540                    .then(
541                        (cache) => {
542                           return fetch(event.request.clone()).then(function (response) {
543                                if(response.status < 300) {
544                                    if (~SUPPORTED_METHODS.indexOf(event.request.method) && !pwaForWpisBlackListed(event.request.url)) {
545                                        cache.put(event.request, response.clone());
546                                    }
547                                    return response;
548                                }else if(response.status==404){
549                                    return cachingStrategy.Notfoundpage();
550                                }
551                                return cache.match(event.request).then(function (cached) {
552                                    return cached || cachingStrategy.Offlinepage();
553                                });
554                              }).catch(
555                                (err) => {
556                                        return cachingStrategy.Offlinepage();
557                                    }
558                              )
559                        }
560                    ).catch(
561                        (err) => {
562                           return cachingStrategy.Offlinepage()
563                        }
564                    );
565        },
566        cacheFirstStrategy: function(events){
567            return cachingStrategy.fetchFromCache(events).catch(
568                        (err) => {
569                           return cachingStrategy.Offlinepage()
570                        }
571                    );
572        },
573        NeworkFirstStrategy: function(events){
574            return cachingStrategy.fetchnetwork(events).catch(
575                        (err) => {
576                            return cachingStrategy.fetchFromCache(events)
577                        }
578                    ).catch(
579                        (err) => {
580                           return cachingStrategy.Offlinepage()
581                        }
582                    );
583        }
584
585
586}
587
588/**
589 * Guarantees event.respondWith() always receives a Promise<Response>.
590 * Fixes networkFirst when a branch resolves with undefined (e.g. missing 404/offline cache).
591 */
592function pwaForWpEnsureResponse(promise) {
593    return Promise.resolve(promise).then(function (res) {
594        if (res && res instanceof Response) {
595            return res;
596        }
597        return cachingStrategy.Offlinepage();
598    }).catch(function () {
599        return cachingStrategy.Offlinepage();
600    });
601}
602
603
604self.addEventListener(
605    'install', event => {
606        event.waitUntil(
607            Promise.all([
608                pwaForWpinstallServiceWorker(),
609                self.skipWaiting(),
610            ])
611        );
612    }
613);
614
615// The activate handler takes care of cleaning up old caches.
616self.addEventListener(
617    'activate', event => {
618        event.waitUntil(
619            Promise.all(
620                [
621                    pwaForWpcleanupLegacyCache(),
622                    self.clients.claim(),
623                    self.skipWaiting(),
624                ]
625            )
626                .catch(
627                    (err) => {
628                        self.skipWaiting();
629                    }
630                )
631        );
632    }
633);
634self.addEventListener('online', event => {
635    if (navigator.onLine && navigator.standalone === true) {
636        isReachable(event.request.url).then(function(online) {
637          if (online) {
638            //handle online status
639            caches.delete(event.request.url);
640            console.log('online');
641          } else {
642            console.log('no connectivity');
643          }
644        });
645    } else {
646        //handle offline status
647        console.log('offline');
648    }
649});
650
651function isReachable(url) {
652  /**
653   * Note: fetch() still "succeeds" for 404s on subdirectories,
654   * which is ok when only testing for domain reachability.
655   */
656  return fetch(url, { method: 'HEAD', mode: 'no-cors' })
657    .then(function(resp) {
658      return resp && (resp.ok || resp.type === 'opaque');
659    })
660    .catch(function(err) {
661      console.warn('[conn test failure]:', err);
662    });
663}
664
665self.addEventListener(
666    'fetch', event => {
667        // Return if the current request url is in the never cache list
668        if ( ! neverCacheUrls.every(pwaForWpcheckNeverCacheList, event.request.url) ) {
669           //console.log( 'PWA ServiceWorker: URL exists in excluded list of cache.' + event.request.url);
670          return;
671        }
672        if(! neverCacheUrls.every(pwaForWpcheckNeverCacheList, event.request.referrer) ){
673           //console.log( 'PWA ServiceWorker: Ref-URL exists in excluded list of cache.' + event.request.referrer);
674            return;
675        }
676        if(pwaForWpisBlackListed(event.request.url)){
677            return;   
678        }
679
680        const url = new URL(event.request.url);
681
682        if (pwaForWpVisibilityBypassPath(url.pathname)) {
683            return;
684        }
685
686        path_array = url.pathname.split('/')
687        if (event.request.method === 'POST' && path_array.includes('activity')) {
688            return event.respondWith((async () => {
689                const formData = await event.request.formData();
690                const title = formData.get('title');
691                const text = formData.get('text');
692                const link = formData.get('url');
693                const image = formData.get('externalMedia');
694                const reader = new FileReader();
695
696                reader.onload = async (event) => {
697                    const imageData = event.target.result;
698
699                    const db = await openDatabase();
700                    await saveData(db, {
701                        id: 'sharedData',
702                        title: title,
703                        text: text,
704                        url: link,
705                        image: imageData
706                    });
707
708                    console.log('Data saved to IndexedDB');
709           
710                    // return Response.redirect('/?share-target', 303);
711                    return Response.redirect(url.pathname+'/?share-target', 303);
712                };
713
714                reader.readAsDataURL(image);
715                return Response.redirect(url.pathname+'/?share-target', 303);
716                // return Response.redirect('/?share-target', 303);
717            })());
718        }
719        
720        // Return if request url protocal isn't http or https
721        if ( ! event.request.url.match(/^(http|https):\/\//i) )
722            return;
723        if ( event.request.referrer.match(/^(wp-admin):\/\//i) )
724            return;
725                       
726        if ( new URL(event.request.url).origin !== location.origin )
727                            return;
728
729        if(event.request.method !== 'GET' ){
730            event.respondWith(
731                fetch(event.request)
732                    .catch(error => {
733                        return caches.open(CACHE_VERSIONS.offline).then(function(cache) {
734                                        return cache.match(OFFLINE_PAGE);
735                                      }).then(function(res) {
736                                        return res || new Response('', { status: 503, statusText: 'Service Unavailable' });
737                                      });
738                    })
739            );
740            return false;
741        }
742        const destination = event.request.destination;
743        switch (destination) {
744            case 'style':
745            case 'script':
746              cachingStrategyType = CACHE_STRATEGY.css_js;
747              break;
748            case 'document':
749              cachingStrategyType = CACHE_STRATEGY.default
750              break;
751            case 'image': 
752                cachingStrategyType = CACHE_STRATEGY.images;
753              break;
754            case 'font': 
755                cachingStrategyType = CACHE_STRATEGY.fonts;
756            break;
757            // All `XMLHttpRequest` or `fetch()` calls where
758            // `Request.destination` is the empty string default value
759            default: 
760              cachingStrategyType = CACHE_STRATEGY.default
761        }
762        var cache = null;
763        switch(cachingStrategyType){
764            case "networkFirst":
765               cache = cachingStrategy.NeworkFirstStrategy(event)
766            break;
767            case "networkOnly":
768               cache = cachingStrategy.networkOnlyStrategy(event)
769            break;
770            //break;
771            case "cacheFirst":
772            case "staleWhileRevalidate": 
773            default:
774               cache = cachingStrategy.cacheFirstStrategy(event)
775            break;
776        }
777        event.respondWith(pwaForWpEnsureResponse(cache));
778
779    }
780);
781
782function openDatabase() {
783    return new Promise((resolve, reject) => {
784      const request = indexedDB.open('shareTargetDB', 1);
785  
786      request.onupgradeneeded = (event) => {
787        const db = event.target.result;
788        db.createObjectStore('sharedData', { keyPath: 'id' });
789      };
790  
791      request.onsuccess = (event) => {
792        resolve(event.target.result);
793      };
794  
795      request.onerror = (event) => {
796        reject(event.target.error);
797      };
798    });
799  }
800  
801  function saveData(db, data) {
802    return new Promise((resolve, reject) => {
803      const transaction = db.transaction('sharedData', 'readwrite');
804      const store = transaction.objectStore('sharedData');
805  
806      const request = store.put(data);
807  
808      request.onsuccess = () => {
809        resolve();
810      };
811  
812      request.onerror = (event) => {
813        reject(event.target.error);
814      };
815    });
816  }
817
818
819self.addEventListener('message', (event) => {
820
821    if(
822        typeof event.data === 'object' &&
823        typeof event.data.action === 'string'
824    ) {
825        switch(event.data.action) {
826            case 'cache' :               
827                pwaForWpprecacheUrl(event.data.url);
828                break;
829            
830            default :
831                console.log('Unknown action: ' + event.data.action);
832                break;
833        }
834    }
835
836});
837
838importScripts("https://storage.googleapis.com/workbox-cdn/releases/3.6.1/workbox-sw.js");
839                                if(workbox.googleAnalytics){
840                                  try{
841                                    workbox.googleAnalytics.initialize();
842                                  } catch (e){}
843                                }

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.