PageSourceSearch

https://robohon.com/assets/renewal/js/common.js

js robohon.com collected 2026-10-02 06:23:52 UTC 23,380 bytes, 940 lines download raw bytes

1class SmoothScroll {
2	//コンストラクタ
3	constructor(args) {
4		this._easing = {
5			/*
6			time = 現在秒 (現在
7			begin = 最初の値
8			change = 変動する値
9			duration = 何秒かけて動くか
10			*/
11			liner : function(t, b, c, d) {
12				return c * t / d + b;
13			},
14			quinticIn : function(t, b, c, d) {
15				t /= d;
16				return c * t * t * t * t * t + b;
17			},
18			quinticOut : function(t, b, c, d) {
19				t /= d;
20				t = t - 1;
21				return -c * (t * t * t * t - 1) + b;
22			}
23		};
24
25		this._options = {
26			noScroll : 'no-smoothscroll',
27			setHash : false,
28			duration : 500,
29			interval : 10,
30			animation : 'quinticOut',
31			callback : function(){}
32		};
33
34		for (var i in args) {
35			//設定されていない時は上書きしない
36			if (!this._options.hasOwnProperty(i)) {
37				continue;
38			}
39			this._options[i] = args[i];
40		}
41	}
42
43	getOffsetMarginHeight(ele) {
44		const targetStyle = window.getComputedStyle(ele);
45		return ele.offsetHeight + parseInt(targetStyle.getPropertyValue('margin-top')) + parseInt(targetStyle.getPropertyValue('margin-bottom'));
46	}
47
48	//対象スクロール取得
49	getParentScroll(ele) {
50		let obj;
51
52		while(ele) {
53			if (ele.nodeName.toLowerCase().indexOf('body') >= 0) {
54				obj = window;
55				break;
56			}
57			else if (window.getComputedStyle(ele).getPropertyValue('overflow') != 'auto') {
58				ele = ele.parentElement;
59			}
60			else {
61				obj = ele;
62				break;
63			}
64		}
65		return obj;
66	}
67
68	//スクロール対象の制限
69	getParentScrollPosition(ele) {
70		let obj = new Object();
71
72		if (ele == window) {
73			obj.parent = window;
74			obj.limit = window.scrollHeight - window.innerHeight;
75			obj.from = document.documentElement.scrollTop || document.body.scrollTop;
76		}
77		else {
78			const offsetHeight = this.getOffsetMarginHeight(ele);
79			obj.limit = ele.scrollHeight - offsetHeight;
80			obj.from = ele.scrollTop;
81		}
82
83		return obj;
84	}
85
86	scroll(target) {
87		if (target.classList.contains(this._options.noScroll)) {
88			return;
89		}
90
91		clearTimeout(this._timer);
92		const now = new Date();
93		const scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
94		const scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft;
95		const scroll = this.getParentScroll(target);
96		const scrollPosition = this.getParentScrollPosition(scroll);
97		const _self = this;
98		let toY = target.getBoundingClientRect().top + window.pageYOffset;
99
100		scroll.scrollTo(scrollLeft, scrollPosition.from);
101
102		if (scrollPosition.limit < toY) {
103			toY = scrollPosition.limit;
104		}
105
106		if (toY < 0) {
107			toY = 0;
108		}
109
110		if (this._options.setHash) {
111			this._options.callback = function(){
112				window.location.hash = hash;
113			}
114		}
115
116		const run = function() {
117			var time = new Date() - now;
118			var next = _self._easing[_self._options.animation](time, scrollPosition.from, toY - scrollPosition.from, _self._options.duration);
119
120			if (time < _self._options.duration - _self._options.interval) {
121				scroll.scrollTo(scrollLeft, parseInt(next));
122				_self._timer = setTimeout(function(){run()}, _self._options.interval);
123			}
124			else {
125				clearTimeout(_self._timer);
126				scroll.scrollTo(scrollLeft, parseInt(toY));
127				_self._options.callback();
128			}
129		}
130		run();
131	}
132
133	setEventHandler() {
134		const self = this;
135		document.addEventListener('click', function (event) {
136			const target = event.target;
137			if (target.closest('a') && target.closest('a').href) {
138				const url = new URL(target.closest('a').href);
139				const hash = url.hash.split('#')[1];
140				if (target.closest('a').classList.contains(self._options.noScroll)) {
141					return;
142				}
143
144				if (document.getElementById(hash)) {
145					event.preventDefault();
146					self.scroll(document.getElementById(hash));
147				}
148			}
149		});
150	}
151};
152
153class ModalWindow {
154	getModalWindows() {
155		return document.querySelectorAll('.modal-window-current, .modal-window-open');
156	}
157
158	getCurrentModalWindow() {
159		let current = document.querySelector('.modal-window-current');
160		if (current) {
161			return current;
162		}
163		return null;
164	}
165
166	async showModalWindow(hash) {
167		if (this.isAnimation()) {
168			return;
169		}
170
171		let modal = document.querySelector(hash + '.modal-window');
172
173		const modals = this.getModalWindows();
174		for (let i = 0; i < modals.length; i++) {
175			modals[i].classList.remove('modal-window-current');
176		}
177
178		modal.classList.add('is-animation');
179		modal.classList.add('modal-window-current');
180		modal.classList.add('modal-window-open');
181		modal.addEventListener('transitionend', function(event) {
182			modal.classList.remove('is-animation');
183		});
184	}
185
186	isAnimation() {
187		const modals = this.getModalWindows();
188		let flag = false;
189		for (let i = 0; i < modals.length; i++) {
190			if (modals[i].classList.contains('is-animation')) {
191				flag = true;
192			}
193		}
194		return flag;
195	}
196
197	hideModalWindow(target) {
198		target.classList.add('is-animation');
199		target.classList.remove('modal-window-current');
200		target.classList.remove('modal-window-open');
201	}
202
203	hideAllModalWindow() {
204		const modals = this.getModalWindows();
205		for (let i = 0; i < modals.length; i++) {
206			const modal = modals[i];
207			this.hideModalWindow(modal);
208		}
209	}
210
211	getStyle(target) {
212		let style = target.currentStyle || window.getComputedStyle(target);
213		return style;
214	}
215}
216
217class Slider {
218	constructor(args) {
219		this.distance = 50;
220		this.parent = args.parent;
221		this.prev = args.parent.querySelector('.slide-list-prev');
222		this.next = args.parent.querySelector('.slide-list-next');
223		this.items = args.parent.querySelector('.slide-list-item');
224		this.element = args.parent.querySelector('.slide-list-item ul');
225		this.indicator = args.parent.querySelector('.slide-list-indicator');
226		this.loop = args.loop;
227		this.step = args.step;
228		this.center = args.center;
229		this.shuffle = args.shuffle;
230
231		//event
232		const self = this;
233		this.eventCancel = function(event) {
234			event.preventDefault();
235		}
236
237		this.prevClickEvent = function() {
238			self.prevShow();
239		}
240
241		this.nextClickEvent = function() {
242			self.nextShow();
243		}
244
245		this.touchStartEvent = function(event) {
246			if (!self.isTouch()) {
247				event.preventDefault();
248			}
249
250			if (self.isAnimation()) {
251				return;
252			}
253			self.touched = true;
254			self.element.classList.remove('is-animation');
255			const pageX = self.isTouch() ? event.changedTouches[0].pageX : event.pageX;
256			self.getX();
257			self.startX = pageX;
258			self.offsetX = self.getX();
259
260			const a = self.element.querySelectorAll('a');
261			for (let i = 0; i < a.length; i++) {
262				a[i].removeEventListener('click', self.eventCancel);
263			}
264		}
265
266		this.touchMoveEvent = function(event) {
267			if (self.isAnimation() || !self.touched) {
268				return;
269			}
270
271			const pageX = self.isTouch() ? event.changedTouches[0].pageX : event.pageX;
272			let moveX = pageX - self.startX;
273			if (!self.loop) {
274				const x = self.getX();
275				const limit = self.getAllListItems()[self.getLastIndex()].offsetLeft;
276				if (x >= self.defaultX || x <= -limit + self.defaultX) {
277					moveX /= 3;
278				}
279			}
280
281			const to = self.offsetX + moveX;
282			self.setX(to);
283
284			const a = self.element.querySelectorAll('a');
285			for (let i = 0; i < a.length; i++) {
286				a[i].addEventListener('click', self.eventCancel);
287			}
288		}
289
290		this.touchEndEvent = function(event) {
291			if (self.isAnimation()) {
292				return;
293			}
294			const pageX = self.isTouch() ? event.changedTouches[0].pageX : event.pageX;
295			const direction = self.getDirection(self.startX, pageX);
296			if (direction == 'left') {
297				self.nextShow();
298			}
299			else if (direction == 'right') {
300				self.prevShow();
301			}
302		}
303
304		this.windowTouchEndEvent = function() {
305			if (!self.touched) {
306				return;
307			}
308
309			self.show(self.current, true);
310			self.touched = false;
311		}
312
313		this.transitionEndEvent = function(event) {
314			const target = event.target;
315			if (target == self.element) {
316				self.element.classList.remove('is-animation');
317				self.resetPosition();
318			}
319		}
320
321		this.indicatorClickEvent = function(event) {
322			const target = event.target;
323			if (target.closest('.' + self.parent.className.replace(' ', '.')) && target.closest('.' + self.indicator.className.replace(' ', '.')) && target.tagName.toLowerCase() == 'a') {
324				event.preventDefault();
325				if (target.closest('li.current')) {
326					return;
327				}
328
329				const all = self.indicator.querySelectorAll('a');
330				let index = Array.prototype.indexOf.call(all, target);
331				index = self.getIndex(index);
332				self.show(index, true);
333			}
334		}
335	}
336
337	set setCenter(val) {
338		this.center = val;
339	}
340
341	set setStep(val) {
342		this.step = val;
343		this.checkStep();
344	}
345
346	checkStep() {
347		if (this.loop) {
348			this.step = 1;
349		}
350	}
351
352	getIndex(index) {
353		const rows = this.getRowListItems();
354		const lists = Array.prototype.slice.call(this.getAllListItems());
355		return lists.indexOf(rows[index]);
356	}
357
358	getFirstIndex() {
359		return this.getIndex(0);
360	}
361
362	getLastIndex() {
363		const li = this.getAllListItems();
364		let remainder = li.length % this.step;
365		if (remainder == 0) {
366			remainder = this.step;
367		}
368		return (li.length - remainder);
369	}
370
371	setCurrentPosition() {
372		if (this.current > this.getLastIndex()) {
373			this.current = this.getLastIndex();
374		}
375		else {
376			const index = Math.floor(this.current / this.step) * this.step;
377			this.current = index;
378		}
379	}
380
381	isAnimation() {
382		if (this.element.classList.contains('is-animation')) {
383			return true;
384		}
385		else {
386			return false;
387		}
388	}
389
390	isTouch() {
391		return ('ontouchstart' in window);
392	}
393
394	geTouchEvent() {
395		const obj = new Object();
396		obj.touchstart = this.isTouch() ? 'touchstart' : 'mousedown';
397		obj.touchmove = this.isTouch() ? 'touchmove' : 'mousemove';
398		obj.touchend = this.isTouch() ? 'touchend' : 'mouseup';
399		return obj;
400	}
401
402	removeEventHandler() {
403		const self = this;
404		const touchevent = this.geTouchEvent();
405		if (this.prev) {
406			this.prev.removeEventListener('click', self.prevClickEvent);
407		}
408
409		if (this.next) {
410			this.next.removeEventListener('click', self.nextClickEvent);
411		}
412
413		this.items.removeEventListener(touchevent.touchstart, self.touchStartEvent);
414		this.items.removeEventListener(touchevent.touchmove, self.touchMoveEvent);
415		this.items.removeEventListener(touchevent.touchend, self.touchEndEvent);
416		window.removeEventListener(touchevent.touchend, self.windowTouchEndEvent);
417		document.removeEventListener('click', self.indicatorClickEvent);
418		document.removeEventListener('transitionend', self.transitionEndEvent);
419	}
420
421	setEventHandler() {
422		const self = this;
423		const touchevent = this.geTouchEvent();
424		if (this.prev) {
425			this.prev.addEventListener('click', self.prevClickEvent);
426		}
427
428		if (this.next) {
429			this.next.addEventListener('click', self.nextClickEvent);
430		}
431
432		this.items.addEventListener(touchevent.touchstart, self.touchStartEvent);
433		this.items.addEventListener(touchevent.touchmove, self.touchMoveEvent);
434		this.items.addEventListener(touchevent.touchend, self.touchEndEvent);
435		window.addEventListener(touchevent.touchend, self.windowTouchEndEvent);
436		document.addEventListener('click', self.indicatorClickEvent);
437		document.addEventListener('transitionend', self.transitionEndEvent);
438	}
439
440	initialize() {
441		this.checkStep();
442
443		const shuffle = ([...array]) => {
444			for (let i = array.length - 1; i >= 0; i--) {
445				const j = Math.floor(Math.random() * (i + 1));
446				[array[i], array[j]] = [array[j], array[i]];
447			}
448			return array;
449		}
450		//shuffle
451		if (this.shuffle) {
452			let lists = this.element.querySelectorAll('li');
453			lists = shuffle(lists);
454			for (let i = 0; i < lists.length; i++) {
455				const li = lists[i];
456				this.element.appendChild(li);
457			}
458		}
459
460		this.addRowClass();
461		this.addCopy();
462		this.current = this.getFirstIndex();
463		this.setEventHandler();
464	}
465
466	resize() {
467		this.addCopy();
468		this.defaultX = this.getDefaultX();
469		this.touched = false;
470		this.addIndicator();
471		this.setCurrentPosition();
472		this.show(this.current, false);
473	}
474
475	reset() {
476		this.removeCopy();
477		this.defaultX = 0;
478		this.touched = false;
479		this.removeIndicator();
480		this.removeEventHandler();
481		this.setX(0);
482	}
483
484	getDirection(start, end) {
485		const distance = start - end;
486		if (distance < 0) {
487			if (Math.abs(distance) < this.distance) return false;
488			return 'right';
489		}
490		else if(distance >= this.distance) {
491			return 'left';
492		}
493	}
494
495	getAllListItems() {
496		return this.element.querySelectorAll('li');
497	}
498
499	getRowListItems() {
500		return this.element.querySelectorAll('.slide-list-row');
501	}
502
503	getPrev() {
504		const index = this.current - this.step;
505		if (this.getAllListItems()[index]) {
506			return index;
507		}
508		return false;
509	}
510
511	getNext() {
512		const index = this.current + this.step;
513		if (this.getAllListItems()[index]) {
514			return index;
515		}
516		return false;
517	}
518
519	prevShow() {
520		if (this.getPrev() !== false) {
521			const index = this.getPrev();
522			this.show(index, true);
523		}
524	}
525
526	nextShow() {
527		if (this.getNext() !== false) {
528			const index = this.getNext();
529			this.show(index, true);
530		}
531	}
532
533	resetPosition() {
534		if (!this.loop) {
535			return;
536		}
537
538		const count = this.getCountInScreen();
539		const lists = this.getAllListItems();
540		const first = count;
541		const firstNode = lists[first];
542		const last = lists.length - count - 1;
543		const lastNode = lists[last];
544
545		if (this.current <= first) {
546			const index = this.getIndex(firstNode.getAttribute('data-num'));
547			this.show(index, false);
548		}
549
550		if (this.current >= last) {
551			const index = this.getIndex(lastNode.getAttribute('data-num'));
552			this.show(index, false);
553		}
554
555	}
556
557	show(index, animation) {
558		if (this.isAnimation()) {
559			return;
560		}
561
562		this.current = index;
563		this.addCurrentIndicator(index);
564		const li = this.getAllListItems()[index];
565		let to = - li.offsetLeft + this.defaultX;
566		const diff = Math.abs(Math.abs(to) - Math.abs(this.getX()));
567
568		if (this.prev) {
569			if (this.getPrev() !== false) {
570				this.prev.style.display = '';
571			}
572			else {
573				this.prev.style.display = 'none';
574			}
575		}
576
577		if (this.next) {
578			if (this.getNext() !== false) {
579				this.next.style.display = '';
580			}
581			else {
582				this.next.style.display = 'none';
583			}
584		}
585
586		if (animation && diff > 1) {
587			this.element.classList.add('is-animation');
588		}
589
590		this.setX(to);
591	}
592
593	getX() {
594		let x = parseInt(this.element.style.left);
595		if (!x) {
596			x = this.defaultX;
597		}
598		return x;
599	}
600
601	setX(x) {
602		this.element.style.left = x + 'px';
603	}
604
605	getCountInScreen() {
606		const lists = this.getAllListItems();
607		let index = this.element.offsetWidth / lists[0].offsetWidth;
608		return Math.floor(index);
609	}
610
611	getDefaultX() {
612		if (!this.center) {
613			return 0;
614		}
615
616		const li = this.getAllListItems()[0];
617		const margin = (this.element.offsetWidth - li.offsetWidth) / 2;
618		return margin;
619	}
620
621	removeCopy() {
622		const clones = this.element.querySelectorAll('.slide-list-clone');
623		if (clones.length > 0) {
624			for (let i = 0; i < clones.length; i++) {
625				clones[i].parentNode.removeChild(clones[i]);
626			}
627		}
628	}
629
630	addCopy() {
631		if (!this.loop) {
632			return;
633		}
634
635		this.removeCopy();
636		const count = this.getCountInScreen();
637		const rows = this.getRowListItems();
638		let repeat = Math.ceil(count / rows.length);
639		if (count == rows.length) {
640			repeat ++;
641		}
642
643		for (let i = 0; i < repeat; i++) {
644			for (let j = rows.length - 1; j >= 0; j--) {
645				const clone = rows[j].cloneNode(true);
646				clone.classList.replace('slide-list-row', 'slide-list-clone');
647				this.element.insertBefore(clone, this.element.firstChild);
648			}
649
650			for (let j = 0; j < rows.length; j++) {
651				const clone = rows[j].cloneNode(true);
652				clone.classList.replace('slide-list-row', 'slide-list-clone');
653				this.element.appendChild(clone);
654			}
655		}
656	}
657
658	addRowClass() {
659		const lists = this.element.querySelectorAll('li');
660		for (let i = 0; i < lists.length; i++) {
661			lists[i].classList.add('slide-list-row');
662			lists[i].setAttribute('data-num', i);
663		}
664	}
665
666	addIndicator() {
667		if (!this.indicator) {
668			return;
669		}
670
671		let html = '';
672		const rows = this.getRowListItems();
673		const remainder = Math.ceil(rows.length / this.step);
674		for (let i = 0; i < remainder; i++) {
675			html += '<li><a href="javascript:void(0);"></a></li>';
676		}
677		this.indicator.querySelector('ul').innerHTML = html;
678	}
679
680	removeIndicator() {
681		if (!this.indicator) {
682			return;
683		}
684
685		this.indicator.querySelector('ul').innerHTML = '';
686	}
687
688	addCurrentIndicator(index) {
689		if (!this.indicator) {
690			return;
691		}
692
693		const li = this.indicator.querySelectorAll('ul li');
694		for (let i = 0; i < li.length; i++) {
695			li[i].classList.remove('current');
696		}
697		let current = this.getAllListItems()[index].getAttribute('data-num');
698		current = Math.ceil(current / this.step);
699		if (li[current]) {
700			li[current].classList.add('current');
701		}
702	}
703}
704
705class Bubble {
706	constructor(args) {
707		this.parent = args.parent;
708		this.classname = 'icon-bubble';
709		this.count = 15;
710		this.interval = 30;
711		this.maxSize = 0;
712		this.minSize = 0;
713		this.maxDistance = 20;
714		this.minDistance = 1;
715	}
716
717	initialize() {
718		this.remove();
719		this.create();
720		this.move();
721	}
722
723	set setCount(val) {
724		this.count = val;
725	}
726
727	get getMaxSize() {
728		return this.maxSize;
729	}
730
731	set setMaxSize(val) {
732		this.maxSize = val;
733	}
734
735	get getMinSize() {
736		return this.minSize;
737	}
738
739	set setMinSize(val) {
740		this.minSize = val;
741	}
742
743	getTranslateValues(element) {
744		const style = window.getComputedStyle(element)
745		const matrix = style['transform'] || style.webkitTransform || style.mozTransform
746
747		// No transform property. Simply return 0 values.
748		if (matrix === 'none' || typeof matrix === 'undefined') {
749			return {
750				x: 0,
751				y: 0,
752				z: 0
753			}
754		}
755
756		// Can either be 2d or 3d transform
757		const matrixType = matrix.includes('3d') ? '3d' : '2d'
758		const matrixValues = matrix.match(/matrix.*\((.+)\)/)[1].split(', ')
759
760		// 2d matrices have 6 values
761		// Last 2 values are X and Y.
762		// 2d matrices does not have Z value.
763		if (matrixType === '2d') {
764			return {
765				x: matrixValues[4],
766				y: matrixValues[5],
767				z: 0
768			}
769		}
770
771		// 3d matrices have 16 values
772		// The 13th, 14th, and 15th values are X, Y, and Z
773		if (matrixType === '3d') {
774			return {
775				x: matrixValues[12],
776				y: matrixValues[13],
777				z: matrixValues[14]
778			}
779		}
780	}
781
782	getRandomInt(min, max) {
783		return Math.floor(Math.random() * (max - min + 1)) + min;
784	}
785
786	resetPosition(node) {
787		const leftPosition = this.getRandomInt(0, this.parent.offsetWidth);
788		node.style.top = this.parent.offsetHeight + 'px';
789		node.style.left = leftPosition + 'px';
790		node.style.transform = 'translate(0, 0)';
791		//node.x = leftPosition;
792	}
793
794	remove() {
795		const nodes = this.parent.querySelectorAll('.' + this.classname);
796		for (let i = 0; i < nodes.length; i++) {
797			const node = nodes[i];
798			node.parentNode.removeChild(node);
799		}
800	}
801
802	create() {
803		for (let i = 0; i < this.count; i++) {
804			//雪作成
805			const node = document.createElement('canvas');
806			const size = this.getRandomInt(this.minSize, this.maxSize);
807			const bubbleTypeClass = this.classname + this.getRandomInt(1, 5);
808			this.resetPosition(node);
809			node.className = this.classname;
810			node.classList.add(bubbleTypeClass);
811			//node.style.top = this.getRandomInt(this.parent.offsetHeight, this.parent.offsetHeight * 2) + 'px';
812			node.style.top = this.getRandomInt(0, this.parent.offsetHeight) + 'px';
813			node.style.width = size + 'px';
814			node.style.height = size + 'px';
815			node.distance = this.getRandomInt(this.minDistance, this.maxDistance);
816			node.degree = this.getRandomInt(1, 2);
817			node.move = 0;
818			node.size = size;
819			this.parent.appendChild(node);
820		}
821	}
822
823	move() {
824		const self = this;
825		const nodes = this.parent.querySelectorAll('.' + this.classname);
826		const move = function() {
827			for (let i = 0; i < nodes.length; i++) {
828				const node = nodes[i];
829				const position = self.getTranslateValues(node);
830				const top = position.y;
831				node.move -= node.degree;
832				if (parseInt(node.style.top) + node.size <= Math.abs(top)) {
833					self.resetPosition(node);
834				}
835				else {
836					const y = top - node.degree + 'px';
837					const x = Math.cos(node.move * Math.PI / 180) * node.distance + 'px';
838					node.style.transform = 'translate(' + x + ', ' + y + ')';
839				}
840/*
841				const node = nodes[i];
842				const top = parseInt(node.style.top);
843				node.move -= node.degree;
844
845				if (top <= -node.size) {
846					self.resetPosition(node);
847				}
848				else {
849					node.style.top = top - node.degree + 'px';
850					node.style.left = node.x + Math.cos(node.move * Math.PI / 180) * node.distance + 'px';
851				}
852*/
853			}
854			window.requestAnimationFrame(move);
855			//setTimeout(function(){move();}, 300);
856		}
857		move();
858	}
859};
860
861function fixedMenuToggle() {
862	const scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
863	const fixedmenu = document.querySelector('.fixed-menu');
864        if (!fixedmenu) {
865            return;
866        }
867
868	if (scrollTop > 100) {
869		fixedmenu.classList.add('fixed-menu-view');
870	}
871	else {
872		fixedmenu.classList.remove('fixed-menu-view');
873	}
874}
875
876function globalNavToggle() {
877	const body = document.body;
878	const headerMenu = document.querySelector('#header .header-menu');
879	const globalNav = document.querySelector('#header .global-nav');
880	if (headerMenu.classList.contains('header-menu-open')) {
881		body.classList.remove('menu-open');
882		headerMenu.classList.remove('header-menu-open');
883		globalNav.classList.remove('global-nav-open');
884		//document.body.style.overflow = 'auto';
885		returnScroll();
886	}
887	else {
888		body.classList.add('menu-open');
889		headerMenu.classList.add('header-menu-open');
890		globalNav.classList.add('global-nav-open');
891		//document.body.style.overflow = 'hidden';
892		noScroll();
893	}
894}
895
896let current_scrollY = 0;
897function noScroll(scrollTop) {
898	if (scrollTop >= 0) {
899		current_scrollY = scrollTop;
900	}
901	else {
902		current_scrollY = document.scrollingElement.scrollTop;
903	}
904	document.body.style.position = 'fixed';
905	document.body.style.top = (-1 * current_scrollY) + 'px';
906}
907
908function returnScroll() {
909	if (document.body.style.position != 'fixed') {
910		return;
911	}
912	document.body.style.position = '';
913	document.body.style.top = '';
914	document.scrollingElement.scrollTop = current_scrollY;
915}
916
917function isInViewPort(element) {
918	const bounding = element.getBoundingClientRect();
919	if (bounding.bottom - window.innerHeight <= 0) {
920		return true;
921	} else {
922		return false;
923	}
924}
925
926function setTrigger() {
927
928	if (!document.querySelector('.wf-active')) {
929		setTimeout(function(){setTrigger();}, 100);
930	}
931	const trigger = document.querySelectorAll('.wf-active [data-trigger="0"]');
932
933	//const trigger = document.querySelectorAll('[data-trigger="0"]');
934	for (let i = 0; i < trigger.length; i++) {
935		const item = trigger[i];
936		if (isInViewPort(item)) {
937			item.setAttribute('data-trigger', '1');
938		}
939	}
940}

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.