PageSourceSearch

https://witch-and-hound-anime.com/js/whts_script.js?1002

js witch-and-hound-anime.com collected 2026-09-26 10:33:09 UTC 19,482 bytes, 906 lines download raw bytes

1
2
3
4
5function InitIntersectionObserver(){
6
7	const isIntersectionObserverSupported = 'IntersectionObserver' in window && 'IntersectionObserverEntry' in window;
8
9	if ( isIntersectionObserverSupported ){
10
11		var _blur_reveal_trigger = $('.blur-reveal-trigger');
12
13		if ( _blur_reveal_trigger.length > 0 ){
14
15			const brt_options = {
16				root: null,
17				rootMargin: '0px',
18				threshold: 0.05
19			};
20
21			const brt_callback = function( entries, observer ){
22
23				entries.forEach(function(entry){
24
25					if ( entry.isIntersecting ){
26
27						$(entry.target).addClass('blur-reveal-start');
28
29						observer.unobserve(entry.target);
30
31					}
32
33				});
34			};
35
36			const brt_observer = new IntersectionObserver( brt_callback, brt_options );
37
38			_blur_reveal_trigger.each(function(){
39
40				brt_observer.observe(this);
41
42			});
43
44		}
45
46		if ( $('#backtotop').length > 0 ){
47
48			const trigger = document.getElementById('whts_footer');
49			const fixedElement = document.getElementById('backtotop');
50
51			const observerOptions = {
52				root: null,
53				rootMargin: '0px',
54				threshold: 0.2
55			};
56
57			const observer = new IntersectionObserver((entries) => {
58				entries.forEach(entry => {
59
60					//console.log(entry.isIntersecting);
61					//console.log(entry.boundingClientRect.top);
62
63					if (!entry.isIntersecting) {
64
65						fixedElement.classList.remove('visible');
66
67					} else if (entry.isIntersecting ) {
68
69						fixedElement.classList.add('visible');
70
71					}
72				});
73			}, observerOptions);
74
75			observer.observe(trigger);
76
77		}else {
78
79			//$(this).addClass('visible');
80
81		}
82
83	}else {
84
85		$('.blur-reveal-trigger').each(function(){
86
87			$(this).addClass('blur-reveal-start');
88
89		});
90
91	}
92
93}
94
95
96
97
98$(document).ready(function(){
99
100
101	if ( !( 'console' in window ) ){
102		window.console = {};
103		window.console.log = function(arg){
104			return arg;
105		};
106	}
107
108	//console.log('ready 1.');
109
110
111
112
113
114
115
116	$.easing.easeOutExpoSmooth = function(x) {
117		const k = 6;
118		return (1 - Math.pow(2, -k * x)) / (1 - Math.pow(2, -k));
119	};
120
121	$('#backtotop').each(function(){
122
123		$(this).unbind('click').bind( 'click', function(){
124
125			$('body, html').stop().animate( { scrollTop: '0px' }, 1250, 'easeOutExpoSmooth' );
126
127			return false;
128
129		});
130
131	});
132
133
134
135
136
137
138
139
140	/*
141	Light Box ‚à‚Ç‚« V2
142	*/
143	$('.modal_trigger').each(function(){
144
145		if ( $('body.sp').length != 0 ) return false;
146
147		if ( $('#overlay').length == 0 ){
148
149			$('body').append('<div id="overlay"><div id="modal_loading"><div id="modal_loading_icon"></div></div><div id="modal_close"><div id="modal_close_in"></div></div></div><div id="modal"><div id="modal_inner"></div></div>');
150
151			$.ilight = {};
152			$.ilight.close = function(){
153
154				$('#overlay').trigger('click');
155
156				//return this;
157
158			};
159
160			$.ilight.resize = function( iw, ih, fit_mode ){
161
162				var pd_width = iw;
163				var pd_height = ih;
164
165				if ( pd_width > 800 ){
166
167					pd_width = 800;
168
169					pd_height = pd_width / iw * ih;
170
171				}
172
173				//var close_button_pos_height = Math.abs(parseInt($('#modal_close').css('bottom').replace( 'px', '' )));
174
175				var close_button_pos_height = 0;
176
177				//console.log('close_button_pos_height: ' + close_button_pos_height);
178
179				var ol_tb_padding = 20;
180				var ol_rl_padding = 20 + ( close_button_pos_height * 1 );
181				var ol_tb_img_padding = 2;
182				var ol_rl_img_padding = 2;
183
184				if ( fit_mode == '1' ){
185
186					ol_tb_padding = 0;
187					ol_tb_img_padding = 0;
188
189					//console.log('fit_mode: ' + fit_mode);
190
191				}
192
193				var ol_width = $(window).width() - ( ol_tb_padding * 2 );
194				var ol_height = $(window).outerHeight() - ( ol_rl_padding * 2 );
195
196				var ol_img_width = ol_width - ( ol_tb_img_padding * 2 );
197				var ol_img_height = ol_height - ( ol_rl_img_padding * 2 );
198
199				var ol_img_mt = 0;
200				var ol_img_ml = 0;
201
202				if ( ol_img_width > pd_width && ol_img_height > pd_height ){
203
204					ol_width = pd_width + ( ol_tb_img_padding * 2 );
205					ol_height = pd_height + ( ol_rl_img_padding * 2 );
206					ol_img_width = pd_width;
207					ol_img_height = pd_height;
208
209				}else {
210
211					// DVLPTM5
212
213					var buf_width = parseInt( pd_width * ( ol_img_height / pd_height ) ); // c‚Éfit‚µ‚½ê‡‚Ì•
214					var buf_height = parseInt( pd_height * ( ol_img_width / pd_width ) ); // ‰¡‚Éfit‚µ‚½ê‡‚̍‚‚³
215
216					if ( buf_width <= ol_img_width ){ // cfit‚̏ꍇ‚ÉƒŠƒTƒCƒY‚µ‚½•‚ªƒEƒBƒ“ƒhƒ
216E•‚æ‚è‚à¬‚³‚¢ê‡A‰æ‘œ‚͉æ–ʂɎû‚Ü‚Á‚Ä‚¢‚é
217
218						ol_img_width = buf_width;
219						ol_width = buf_width;
220
221					}else { // ‚»‚¤‚łȂ¢ê‡‚͉¡fit‡‚킹
222
223						ol_img_height = buf_height;
224						ol_height = buf_height;
225
226					}
227
228					//console.log('ol_img_width: ' + ol_img_width + ', buf_width: ' + buf_width);
229					//console.log('ol_img_height: ' + ol_img_height + ', buf_height: ' + buf_height);
230
231				}
232
233				$('#modal').css({
234					marginTop: -parseInt( ( ol_height / 2 ) + ( close_button_pos_height / 2 ) ) + 'px',
235					marginLeft: -parseInt( ol_width / 2 ) + 'px',
236					width: ol_img_width + 'px',
237					height: ol_img_height + 'px',
238					cursor: 'pointer'
239				});
240
241				$('#modal_inner').width(ol_img_width).height(ol_img_height);
242
243				//$('#overlay').css({ display: 'block', height: $(window).outerHeight() + 'px', width: $(window).width() + 'px' });
244				$('#overlay').css({ display: 'block', height: '', width: $(window).width() + 'px' });
245
246			};
247
248			$('#overlay').unbind('click').bind( 'click', function(){
249
250				$('#modal_loading').css({ opacity: 0.0 });
251
252				$.data( $('#modal_inner').get(0), 'owidth', false );
253				$.data( $('#modal_inner').get(0), 'oheight', false );
254
255				$('#modal').stop().animate( { opacity: 0.0 }, 150, 'linear', function(){
256
257					$(this).css({ display: 'none' });
258
259					$('#overlay').stop().animate( { opacity: 0.0 }, 150, 'linear', function(){
260
261						$(this).css({ display: 'none' });
262
263						$('#modal_inner').html('');
264
265						$(document).unbind('mousewheel.stop DOMMouseScroll.stop');
266
267					});
268
269				});
270
271			});
272
273			$(window).unbind('resize.ilight').bind( 'resize.ilight', function(){
274
275				if ( $.data( $('#modal_inner').get(0), 'owidth' ) && $.data( $('#modal_inner').get(0), 'oheight' ) ){
276
277					$.ilight.resize( $.data( $('#modal_inner').get(0), 'owidth' ), $.data( $('#modal_inner').get(0), 'oheight' ), $.data( $('#modal_inner').get(0), 'fit_mode' ) );
278
279				}
280
281			});
282
283		}
284
285		if ( $(this).attr('data-mode') && $(this).attr('data-mode') == 'iframe' ){
286
287			$(this).unbind('click').bind( 'click', function(){
288
289				$('#modal_inner').html('<iframe src="'+$(this).attr('data-src')+'" width="100%" height="100%" frameborder="0" allowfullscreen></iframe>');
290
291				$.data( $('#modal_inner').get(0), 'owidth', parseInt($(this).attr('data-width')) );
292				$.data( $('#modal_inner').get(0), 'oheight', parseInt($(this).attr('data-height')) );
293
294				$.ilight.resize( parseInt($(this).attr('data-width')), parseInt($(this).attr('data-height')) );
295
296				$('#modal').stop().css({ display: 'block' }).animate( { opacity: 1.0 }, 250, 'linear', function(){} );
297
298				$('#modal').unbind('click').bind( 'click', function(){
299
300					$.ilight.close();
301
302				});
303
304				//$('#overlay').css({ display: 'block', height: $(window).outerHeight() + 'px', width: $(window).width() + 'px' });
305				$('#overlay').css({ display: 'block', height: '', width: $(window).width() + 'px' });
306
307				$('#overlay').stop().animate( { opacity: 1.0 }, 250, 'linear', function(){} );
308
309				$(document).bind( 'mousewheel.stop DOMMouseScroll.stop', function(e){
310
311					/* IE7, IE8, Chrome, Safari */
312					//if ( !e ){
313
314					//	e = window.event;
315
316					//}
317
318					/* Chrome, Safari, Firefox */
319					//if ( e.preventDefault ){
320
321					//	e.preventDefault();
322
323					//}
324
325					/* IE7, IE8 */
326					//e.returnValue = false;
327
328					// https://qiita.com/yukiTTT/items/773356c2483b96c9d4e0
329
330					//function handleTouchMove(event){
331
332					//	event.preventDefault();
333
334					//}
335
336					//ƒXƒNƒ[ƒ‹‹ÖŽ~
337					//document.addEventListener('touchmove', handleTouchMove, { passive: false });
338
339					//ƒXƒNƒ[ƒ‹•œ‹A
340					//document.removeEventListener('touchmove', handleTouchMove, { passive: false });
341
342				});
343
344				return false;
345
346			});
347
348			return true;
349
350		}
351
352		if ( $(this).attr('data-modal-mode') == 'direct' ){ // —vC³
353
354			$(this).each(function(){
355
356				var _this = $(this);
357
358				$(this).unbind('click').bind( 'click', function(){
359
360					var preloader = new Image;
361					preloader.onload = function(){
362
363						$('#modal_loading').css({ opacity: 0.0 });
364
365						//$('#modal_inner').html('<img src="'+preloader.src+'" width="100%" height="100%" style="margin-top: '+ol_img_mt+'px; margin-left: '+ol_img_ml+'px;">');
366						$('#modal_inner').html('<img src="'+preloader.src+'" width="100%" height="100%">');
367
368						$.data( $('#modal_inner').get(0), 'owidth', preloader.width );
369						$.data( $('#modal_inner').get(0), 'oheight', preloader.height );
370
371						$.data( $('#modal_inner').get(0), 'fit_mode', _this.attr('data-rlfit') );
372
373						$.ilight.resize( preloader.width, preloader.height, _this.attr('data-rlfit') );
374
375						$('#modal').stop().css({ display: 'block' }).animate( { opacity: 1.0 }, 250, 'linear', function(){} );
376
377						$('#modal').unbind('click').bind( 'click', function(){
378
379							$.ilight.close();
380
381						});
382
383					};
384
385					$('#modal_loading').css({ opacity: 1.0 });
386
387					//$('#overlay').css({ display: 'block', height: $(window).outerHeight() + 'px', width: $(window).width() + 'px' });
388					$('#overlay').css({ display: 'block', height: '', width: $(window).width() + 'px' });
389
390					$('#overlay').stop().animate( { opacity: 1.0 }, 250, 'linear', function(){} );
391
392					preloader.src = _this.attr('href');
393
394					return false;
395
396				});
397
398			});
399
400		}
401
402		$('img',$(this)).each(function(){
403
404			if ( $(this).parent().attr('href') ){
405
406				var _this = $(this).parent();
407
408				$(this).parent().unbind('click').bind( 'click', function(){
409
410					var preloader = new Image;
411					preloader.onload = function(){
412
413						$('#modal_loading').css({ opacity: 0.0 });
414
415						//$('#modal_inner').html('<img src="'+preloader.src+'" width="100%" height="100%" style="margin-top: '+ol_img_mt+'px; margin-left: '+ol_img_ml+'px;">');
416						$('#modal_inner').html('<img src="'+preloader.src+'" width="100%" height="100%">');
417
418						$.data( $('#modal_inner').get(0), 'owidth', preloader.width );
419						$.data( $('#modal_inner').get(0), 'oheight', preloader.height );
420
421						$.ilight.resize( preloader.width, preloader.height );
422
423						$('#modal').stop().css({ display: 'block' }).animate( { opacity: 1.0 }, 250, 'linear', function(){} );
424
425						$('#modal').unbind('click').bind( 'click', function(){
426
427							$.ilight.close();
428
429						});
430
431					};
432
433					$('#modal_loading').css({ opacity: 1.0 });
434
435					//$('#overlay').css({ display: 'block', height: $(window).outerHeight() + 'px', width: $(window).width() + 'px' });
436					$('#overlay').css({ display: 'block', height: '', width: $(window).width() + 'px' });
437
438					$('#overlay').stop().animate( { opacity: 1.0 }, 250, 'linear', function(){} );
439
440					preloader.src = _this.attr('href');
441
442					return false;
443
444				});
445
446			}else {
447
448				return true;
449
450			}
451
452		});
453
454	});
455
456
457
458	$('#loading').each(function(){
459
460/*
461		$('#loading').hide();
462		InitIntersectionObserver();
463		return;
464*/
465
466		const anim = lottie.loadAnimation({
467			container: document.getElementById("loading_logo"),
468			renderer: "svg",
469			//renderer: "canvas",
470			loop: false,
471			autoplay: true,
472			path: "./images/json/mj_logomotion_offbg_002.json",
473			rendererSettings: {
474				preserveAspectRatio: "xMidYMid meet"
475			}
476		});
477
478		//window.addEventListener("resize", () => {
479		//	anim.resize();
480		//});
481
482		//const observer = new ResizeObserver(() => {
483		//	anim.resize();
484		//});
485
486		//observer.observe(container);
487
488		anim.addEventListener("DOMLoaded", () => {
489
490			$(window).on( 'resize.loading', function(){
491
492				if ( anim && typeof anim.resize === "function") {
493
494					anim.resize();
495
496				}
497
498			});
499
500		});
501
502		//$(this).data( 'animobj', anim );
503
504		$(this).data( 'complete', false );
505
506		if ( $(this).data('onload') !== true ){ // load‚̂ق¤‚ªæ‚ÉŽÀs‚³‚ê‚Ä‚¢‚éê‡‚ª‚ ‚é
507
508			$(this).data( 'onload', false );
509
510		}
511
512		anim.addEventListener("complete", () => {
513
514			if ( $('#loading').data('onload') == true ){
515
516				setTimeout(function(){
517
518					$('#loading').stop().animate( { opacity: 0.0 }, 750, 'linear', function(){
519
520						$('#loading').hide();
521
522						$(window).off('resize.loading');
523
524						InitIntersectionObserver();
525
526					});
527
528				}, 100 );
529
530			}else {
531
532				$('#loading').data( 'complete', true );
533
534			}
535
536			//console.log('complete');
537
538			//$('#debug').text('complete');
539
540		});
541
542	});
543
544
545
546	$(window).trigger('resize');
547
548
549	//$(window).trigger('scroll');
550
551
552});
553
554
555
556
557
558$(window).bind( 'resize', function(){
559
560
561
562});
563
564
565
566
567
568$(window).bind( 'scroll', function(){
569
570
571
572});
573
574
575
576
577$(window).on( 'load', function(){
578
579
580
581
582
583
584	$('#ytPlayer').each(function(){
585
586
587		const iframe = document.getElementById('ytPlayer');
588
589		if (!iframe) {
590			return;
591		}
592
593		const src = iframe.getAttribute('src');
594
595		document.addEventListener('visibilitychange', () => {
596			if (document.visibilityState !== 'visible') {
597				return;
598			}
599
600			iframe.setAttribute('src', '');
601			requestAnimationFrame(() => {
602				iframe.setAttribute('src', src);
603			});
604		});
605
606		return false;
607
608		//(function () {
609			const videoId = 'Lzi5zhjLIlU';
610
611			const tag = document.createElement('script');
612			tag.src = 'https://www.youtube.com/iframe_api?origin=https%3A%2F%2Fwitch-and-hound-anime.com';
613			document.head.appendChild(tag);
614
615			window.onYouTubeIframeAPIReady = function () {
616				new YT.Player('ytPlayer', {
617					videoId: videoId,
618					host: 'https://www.youtube-nocookie.com',
619					playerVars: {
620						autoplay: 1,
621						mute: 1,
622						controls: 0,
623						disablekb: 1,
624						fs: 0,
625						iv_load_policy: 3,
626						modestbranding: 1,
627						playsinline: 1,
628						rel: 0,
629						loop: 1,
630						playlist: videoId,
631						origin: location.origin
632						//origin: 'https://witch-and-hound-anime.com'
633					},
634					events: {
635						onReady: function (event) {
636							event.target.mute();
637							event.target.playVideo();
638						}
639					}
640				});
641			};
642		//})();
643
644	});
645
646
647
648
649
650	$('#loading').each(function(){
651
652		if ( $('#loading').data('complete') == true ){
653
654			setTimeout(function(){
655
656				$('#loading').stop().animate( { opacity: 0.0 }, 750, 'linear', function(){
657
658					$('#loading').hide();
659
660					$(window).off('resize.loading');
661
662					InitIntersectionObserver();
663
664				});
665
666			}, 100 );
667
668		}
669
670		$('#loading').data( 'onload', true );
671
672		//console.log('onload');
673
674		//$('#debug').text('onload');
675
676	});
677
678
679
680	(async () => {
681		const config = {
682			targetId: 'whts_top_fixed_bg',
683			pcImage: './images/ts_fv_bg01.jpg',
684			spImage: './images/ts_fv_bg01_sp.jpg',
685
686			objectPosition: 'center', // center / top / right / bottom / left
687
688			fps: 24,
689			//fps: 60,
690			glitchChance: 0.025,
691
692			ghostScale: 1.004,
693			ghostAlphaMin: 0.15,
694			ghostAlphaMax: 0.25,
695			ghostOffsetMin: 13,
696			ghostOffsetMax: 88,
697			ghostFade: 0.82,
698
699			parallax: false,
700			parallaxHorizontal: true,
701			parallaxVertical: false
702
703/*
704			ghostScale: 1.004,
705			ghostAlphaMin: 0.35,
706			ghostAlphaMax: 0.65,
707			ghostOffsetMin: 3,
708			ghostOffsetMax: 6,
709			ghostFade: 0.82
710*/
711		};
712
713		if (!window.PIXI || !window.PIXI.filters?.RGBSplitFilter) return;
714
715		const target = document.getElementById(config.targetId);
716		if (!target) return;
717
718		const app = new PIXI.Application();
719
720		await app.init({
721			backgroundAlpha: 0,
722			antialias: true,
723			resolution: window.devicePixelRatio || 1,
724			autoDensity: true
725		});
726
727		const isMobile = matchMedia('(max-width: 750px), (pointer: coarse)').matches;
728		const imageUrl = isMobile ? config.spImage : config.pcImage;
729		const texture = await PIXI.Assets.load(imageUrl);
730
731		target.appendChild(app.canvas);
732
733		const base = new PIXI.Sprite(texture);
734		const ghost = new PIXI.Sprite(texture);
735
736		app.stage.addChild(base);
737		app.stage.addChild(ghost);
738
739		const rgb = new PIXI.filters.RGBSplitFilter();
740		ghost.filters = [rgb];
741
742		ghost.alpha = 0;
743		ghost.blendMode = 'screen';
744
745		let cw = 0;
746		let ch = 0;
747		let ghostPower = 0;
748		let last = 0;
749
750/*
751		function applyCover(sprite, overscan = 1) {
752			const iw = texture.width;
753			const ih = texture.height;
754			const scale = Math.max(cw / iw, ch / ih) * overscan;
755
756			sprite.scale.set(scale);
757
758			const sw = iw * scale;
759			const sh = ih * scale;
760
761			let x = (cw - sw) / 2;
762			let y = (ch - sh) / 2;
763
764			if (config.objectPosition === 'top') y = 0;
765			if (config.objectPosition === 'bottom') y = ch - sh;
766			if (config.objectPosition === 'left') x = 0;
767			if (config.objectPosition === 'right') x = cw - sw;
768
769			sprite.position.set(x, y);
770		}
771*/
772
773		function getScrollProgress() {
774			const maxScroll = Math.max(1, document.documentElement.scrollHeight - window.innerHeight);
775			return Math.min(1, Math.max(0, window.scrollY / maxScroll));
776		}
777
778		function getBasePosition(sw, sh) {
779			let x = (cw - sw) / 2;
780			let y = (ch - sh) / 2;
781
782			if (config.objectPosition === 'top') y = 0;
783			if (config.objectPosition === 'bottom') y = ch - sh;
784			if (config.objectPosition === 'left') x = 0;
785			if (config.objectPosition === 'right') x = cw - sw;
786
787			return { x, y };
788		}
789
790		function applyCover(sprite, overscan = 1) {
791			const iw = texture.width;
792			const ih = texture.height;
793			const scale = Math.max(cw / iw, ch / ih) * overscan;
794
795			sprite.scale.set(scale);
796
797			const sw = iw * scale;
798			const sh = ih * scale;
799
800			let { x, y } = getBasePosition(sw, sh);
801
802			if (config.parallax) {
803				const progress = getScrollProgress();
804
805				const extraX = Math.max(0, sw - cw);
806				const extraY = Math.max(0, sh - ch);
807
808				if (config.parallaxVertical && extraY > 0) {
809					// ƒXƒNƒ[ƒ‹ã•”: ‰æ‘œã‘¤ / ƒXƒNƒ[ƒ‹‰º•”: ‰æ‘œ‰º‘¤
810					y = -extraY * progress;
811				}
812
813				if (config.parallaxHorizontal && extraX > 0) {
814					// ƒXƒNƒ[ƒ‹ã•”: ‰æ‘œ‰E‘¤ / ƒXƒNƒ[ƒ‹‰º•”: ‰æ‘œ¶‘¤
815					x = -extraX * (1 - progress);
816				}
817			}
818
819			sprite.position.set(x, y);
820		}
821
822		function updateLayout() {
823			applyCover(base, 1);
824			applyCover(ghost, config.ghostScale);
825		}
826
827		function resize() {
828			const rect = target.getBoundingClientRect();
829
830			cw = Math.max(1, Math.round(rect.width));
831			ch = Math.max(1, Math.round(rect.height));
832
833			// 750pxˆÈ‰º‚ÍbottomA‚»‚êˆÈŠO‚Ícenter
834			//config.objectPosition = window.innerWidth <= 750
835			//	? 'bottom'
836			//	: 'center';
837
838			app.renderer.resize(cw, ch);
839
840			//applyCover(base, 1);
841			//applyCover(ghost, config.ghostScale);
842
843			updateLayout();
844		}
845
846		function randomRange(min, max) {
847			return min + Math.random() * (max - min);
848		}
849
850		function triggerGhost() {
851			const alpha = randomRange(config.ghostAlphaMin, config.ghostAlphaMax);
852			const power = randomRange(config.ghostOffsetMin, config.ghostOffsetMax);
853			const dir = Math.random() < 0.5 ? -1 : 1;
854
855			ghost.alpha = alpha;
856			ghostPower = power;
857
858			rgb.red = [power * dir, 0];
859			rgb.green = [-power * 0.35 * dir, 0];
860			rgb.blue = [-power * dir, 0];
861		}
862
863		function updateGhost() {
864			if (ghost.alpha <= 0) return;
865
866			ghost.alpha *= config.ghostFade;
867
868			const p = ghostPower * ghost.alpha;
869			const dir = Math.random() < 0.5 ? -1 : 1;
870
871			rgb.red = [p * dir, 0];
872			rgb.green = [-p * 0.35 * dir, 0];
873			rgb.blue = [-p * dir, 0];
874
875			if (ghost.alpha < 0.01) {
876				ghost.alpha = 0;
877				rgb.red = [0, 0];
878				rgb.green = [0, 0];
879				rgb.blue = [0, 0];
880			}
881		}
882
883		window.addEventListener('resize', resize, { passive: true });
884		window.addEventListener('scroll', updateLayout, { passive: true });
885		resize();
886
887		app.ticker.add(() => {
888			const now = performance.now();
889			if (now - last < 1000 / config.fps) return;
890			last = now;
891
892			if (Math.random() < config.glitchChance) {
893				triggerGhost();
894			}
895
896			updateGhost();
897		});
898	})();
899
900
901	$(window).trigger('resize');
902
903	$(window).trigger('scroll');
904
905
906});

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.