PageSourceSearch

https://ecogra.org/wp-content/themes/ecogra/inc/js/vendor/scrollreveal.js

js ecogra.org collected 2026-09-24 17:34:05 UTC 42,717 bytes, 1,546 lines download raw bytes

vendor: 6,939 bytes, lines 1-212
1/*! @license ScrollReveal v4.0.5
2
3	Copyright 2018 Fisssion LLC.
4
5	Licensed under the GNU General Public License 3.0 for
6	compatible open source projects and non-commercial use.
7
8	For commercial sites, themes, projects, and applications,
9	keep your source code private/proprietary by purchasing
10	a commercial license from https://scrollrevealjs.org/
11*/
12(function (global, factory) {
13	typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
14	typeof define === 'function' && define.amd ? define(factory) :
15	(global.ScrollReveal = factory());
16}(this, (function () { 'use strict';
17
18var defaults = {
19	delay: 0,
20	distance: '0',
21	duration: 600,
22	easing: 'cubic-bezier(0.5, 0, 0, 1)',
23	interval: 0,
24	opacity: 0,
25	origin: 'bottom',
26	rotate: {
27		x: 0,
28		y: 0,
29		z: 0
30	},
31	scale: 1,
32	cleanup: false,
33	container: document.documentElement,
34	desktop: true,
35	mobile: true,
36	reset: false,
37	useDelay: 'always',
38	viewFactor: 0.0,
39	viewOffset: {
40		top: 0,
41		right: 0,
42		bottom: 0,
43		left: 0
44	},
45	afterReset: function afterReset() {},
46	afterReveal: function afterReveal() {},
47	beforeReset: function beforeReset() {},
48	beforeReveal: function beforeReveal() {}
49}
50
51function failure() {
52	document.documentElement.classList.remove('sr');
53
54	return {
55		clean: function clean() {},
56		destroy: function destroy() {},
57		reveal: function reveal() {},
58		sync: function sync() {},
59		get noop() {
60			return true
61		}
62	}
63}
64
65function success() {
66	document.documentElement.classList.add('sr');
67
68	if (document.body) {
69		document.body.style.height = '100%';
70	} else {
71		document.addEventListener('DOMContentLoaded', function () {
72			document.body.style.height = '100%';
73		});
74	}
75}
76
77var mount = { success: success, failure: failure }
78
79/*! @license is-dom-node v1.0.4
80
81	Copyright 2018 Fisssion LLC.
82
83	Permission is hereby granted, free of charge, to any person obtaining a copy
84	of this software and associated documentation files (the "Software"), to deal
85	in the Software without restriction, including without limitation the rights
86	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
87	copies of the Software, and to permit persons to whom the Software is
88	furnished to do so, subject to the following conditions:
89
90	The above copyright notice and this permission notice shall be included in all
91	copies or substantial portions of the Software.
92
93	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
94	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
95	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
96	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
97	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
98	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
99	SOFTWARE.
100
101*/
102function isDomNode(x) {
103	return typeof window.Node === 'object'
104		? x instanceof window.Node
105		: x !== null &&
106				typeof x === 'object' &&
107				typeof x.nodeType === 'number' &&
108				typeof x.nodeName === 'string'
109}
110
111/*! @license is-dom-node-list v1.2.1
112
113	Copyright 2018 Fisssion LLC.
114
115	Permission is hereby granted, free of charge, to any person obtaining a copy
116	of this software and associated documentation files (the "Software"), to deal
117	in the Software without restriction, including without limitation the rights
118	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
119	copies of the Software, and to permit persons to whom the Software is
120	furnished to do so, subject to the following conditions:
121
122	The above copyright notice and this permission notice shall be included in all
123	copies or substantial portions of the Software.
124
125	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
126	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
127	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
128	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
129	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
130	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
131	SOFTWARE.
132
133*/
134function isDomNodeList(x) {
135	var prototypeToString = Object.prototype.toString.call(x);
136	var regex = /^\[object (HTMLCollection|NodeList|Object)\]$/;
137
138	return typeof window.NodeList === 'object'
139		? x instanceof window.NodeList
140		: x !== null &&
141				typeof x === 'object' &&
142				typeof x.length === 'number' &&
143				regex.test(prototypeToString) &&
144				(x.length === 0 || isDomNode(x[0]))
145}
146
147/*! @license Tealight v0.3.6
148
149	Copyright 2018 Fisssion LLC.
150
151	Permission is hereby granted, free of charge, to any person obtaining a copy
152	of this software and associated documentation files (the "Software"), to deal
153	in the Software without restriction, including without limitation the rights
154	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
155	copies of the Software, and to permit persons to whom the Software is
156	furnished to do so, subject to the following conditions:
157
158	The above copyright notice and this permission notice shall be included in all
159	copies or substantial portions of the Software.
160
161	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
162	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
163	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
164	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
165	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
166	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
167	SOFTWARE.
168
169*/
170function tealight(target, context) {
171  if ( context === void 0 ) { context = document; }
172
173  if (target instanceof Array) { return target.filter(isDomNode); }
174  if (isDomNode(target)) { return [target]; }
175  if (isDomNodeList(target)) { return Array.prototype.slice.call(target); }
176  if (typeof target === "string") {
177    try {
178      var query = context.querySelectorAll(target);
179      return Array.prototype.slice.call(query);
180    } catch (err) {
181      return [];
182    }
183  }
184  return [];
185}
186
187function isObject(x) {
188	return (
189		x !== null &&
190		x instanceof Object &&
191		(x.constructor === Object ||
192			Object.prototype.toString.call(x) === '[object Object]')
193	)
194}
195
196function each(collection, callback) {
197	if (isObject(collection)) {
198		var keys = Object.keys(collection);
199		return keys.forEach(function (key) { return callback(collection[key], key, collection); })
200	}
201	if (collection instanceof Array) {
202		return collection.forEach(function (item, i) { return callback(item, i, collection); })
203	}
204	throw new TypeError('Expected either an array or object literal.')
205}
206
207function logger(message) {
208	var details = [], len = arguments.length - 1;
209	while ( len-- > 0 ) details[ len ] = arguments[ len + 1 ];
210
211	if (this.constructor.debug && console) {
212		var report = "%cScrollReveal: " + message;
vendor: 4,558 bytes, lines 213-382
213		details.forEach(function (detail) { return (report += "\n — " + detail); });
214		console.log(report, 'color: #ea654b;'); // eslint-disable-line no-console
215	}
216}
217
218function rinse() {
219	var this$1 = this;
220
221	var struct = function () { return ({
222		active: [],
223		stale: []
224	}); };
225
226	var elementIds = struct();
227	var sequenceIds = struct();
228	var containerIds = struct();
229
230	/**
231	 * Take stock of active element IDs.
232	 */
233	try {
234		each(tealight('[data-sr-id]'), function (node) {
235			var id = parseInt(node.getAttribute('data-sr-id'));
236			elementIds.active.push(id);
237		});
238	} catch (e) {
239		throw e
240	}
241	/**
242	 * Destroy stale elements.
243	 */
244	each(this.store.elements, function (element) {
245		if (elementIds.active.indexOf(element.id) === -1) {
246			elementIds.stale.push(element.id);
247		}
248	});
249
250	each(elementIds.stale, function (staleId) { return delete this$1.store.elements[staleId]; });
251
252	/**
253	 * Take stock of active container and sequence IDs.
254	 */
255	each(this.store.elements, function (element) {
256		if (containerIds.active.indexOf(element.containerId) === -1) {
257			containerIds.active.push(element.containerId);
258		}
259		if (element.hasOwnProperty('sequence')) {
260			if (sequenceIds.active.indexOf(element.sequence.id) === -1) {
261				sequenceIds.active.push(element.sequence.id);
262			}
263		}
264	});
265
266	/**
267	 * Destroy stale containers.
268	 */
269	each(this.store.containers, function (container) {
270		if (containerIds.active.indexOf(container.id) === -1) {
271			containerIds.stale.push(container.id);
272		}
273	});
274
275	each(containerIds.stale, function (staleId) {
276		var stale = this$1.store.containers[staleId].node;
277		stale.removeEventListener('scroll', this$1.delegate);
278		stale.removeEventListener('resize', this$1.delegate);
279		delete this$1.store.containers[staleId];
280	});
281
282	/**
283	 * Destroy stale sequences.
284	 */
285	each(this.store.sequences, function (sequence) {
286		if (sequenceIds.active.indexOf(sequence.id) === -1) {
287			sequenceIds.stale.push(sequence.id);
288		}
289	});
290
291	each(sequenceIds.stale, function (staleId) { return delete this$1.store.sequences[staleId]; });
292}
293
294function clean(target) {
295	var this$1 = this;
296
297	var dirty;
298	try {
299		each(tealight(target), function (node) {
300			var id = node.getAttribute('data-sr-id');
301			if (id !== null) {
302				dirty = true;
303				var element = this$1.store.elements[id];
304				if (element.callbackTimer) {
305					window.clearTimeout(element.callbackTimer.clock);
306				}
307				node.setAttribute('style', element.styles.inline.generated);
308				node.removeAttribute('data-sr-id');
309				delete this$1.store.elements[id];
310			}
311		});
312	} catch (e) {
313		return logger.call(this, 'Clean failed.', e.message)
314	}
315
316	if (dirty) {
317		try {
318			rinse.call(this);
319		} catch (e) {
320			return logger.call(this, 'Clean failed.', e.message)
321		}
322	}
323}
324
325function destroy() {
326	var this$1 = this;
327
328	/**
329	 * Remove all generated styles and element ids
330	 */
331	each(this.store.elements, function (element) {
332		element.node.setAttribute('style', element.styles.inline.generated);
333		element.node.removeAttribute('data-sr-id');
334	});
335
336	/**
337	 * Remove all event listeners.
338	 */
339	each(this.store.containers, function (container) {
340		var target =
341			container.node === document.documentElement ? window : container.node;
342		target.removeEventListener('scroll', this$1.delegate);
343		target.removeEventListener('resize', this$1.delegate);
344	});
345
346	/**
347	 * Clear all data from the store
348	 */
349	this.store = {
350		containers: {},
351		elements: {},
352		history: [],
353		sequences: {}
354	};
355}
356
357/*! @license Rematrix v0.3.0
358
359	Copyright 2018 Julian Lloyd.
360
361	Permission is hereby granted, free of charge, to any person obtaining a copy
362	of this software and associated documentation files (the "Software"), to deal
363	in the Software without restriction, including without limitation the rights
364	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
365	copies of the Software, and to permit persons to whom the Software is
366	furnished to do so, subject to the following conditions:
367
368	The above copyright notice and this permission notice shall be included in
369	all copies or substantial portions of the Software.
370
371	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
372	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
373	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
374	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
375	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
376	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
377	THE SOFTWARE.
378*/
379/**
380 * @module Rematrix
381 */
382
vendor: 5,827 bytes, lines 383-616
383/**
384 * Transformation matrices in the browser come in two flavors:
385 *
386 *  - `matrix` using 6 values (short)
387 *  - `matrix3d` using 16 values (long)
388 *
389 * This utility follows this [conversion guide](https://goo.gl/EJlUQ1)
390 * to expand short form matrices to their equivalent long form.
391 *
392 * @param  {array} source - Accepts both short and long form matrices.
393 * @return {array}
394 */
395function format(source) {
396	if (source.constructor !== Array) {
397		throw new TypeError('Expected array.')
398	}
399	if (source.length === 16) {
400		return source
401	}
402	if (source.length === 6) {
403		var matrix = identity();
404		matrix[0] = source[0];
405		matrix[1] = source[1];
406		matrix[4] = source[2];
407		matrix[5] = source[3];
408		matrix[12] = source[4];
409		matrix[13] = source[5];
410		return matrix
411	}
412	throw new RangeError('Expected array with either 6 or 16 values.')
413}
414
415/**
416 * Returns a matrix representing no transformation. The product of any matrix
417 * multiplied by the identity matrix will be the original matrix.
418 *
419 * > **Tip:** Similar to how `5 * 1 === 5`, where `1` is the identity.
420 *
421 * @return {array}
422 */
423function identity() {
424	var matrix = [];
425	for (var i = 0; i < 16; i++) {
426		i % 5 == 0 ? matrix.push(1) : matrix.push(0);
427	}
428	return matrix
429}
430
431/**
432 * Returns a 4x4 matrix describing the combined transformations
433 * of both arguments.
434 *
435 * > **Note:** Order is very important. For example, rotating 45°
436 * along the Z-axis, followed by translating 500 pixels along the
437 * Y-axis... is not the same as translating 500 pixels along the
438 * Y-axis, followed by rotating 45° along on the Z-axis.
439 *
440 * @param  {array} m - Accepts both short and long form matrices.
441 * @param  {array} x - Accepts both short and long form matrices.
442 * @return {array}
443 */
444function multiply(m, x) {
445	var fm = format(m);
446	var fx = format(x);
447	var product = [];
448
449	for (var i = 0; i < 4; i++) {
450		var row = [fm[i], fm[i + 4], fm[i + 8], fm[i + 12]];
451		for (var j = 0; j < 4; j++) {
452			var k = j * 4;
453			var col = [fx[k], fx[k + 1], fx[k + 2], fx[k + 3]];
454			var result =
455				row[0] * col[0] + row[1] * col[1] + row[2] * col[2] + row[3] * col[3];
456
457			product[i + k] = result;
458		}
459	}
460
461	return product
462}
463
464/**
465 * Attempts to return a 4x4 matrix describing the CSS transform
466 * matrix passed in, but will return the identity matrix as a
467 * fallback.
468 *
469 * > **Tip:** This method is used to convert a CSS matrix (retrieved as a
470 * `string` from computed styles) to its equivalent array format.
471 *
472 * @param  {string} source - `matrix` or `matrix3d` CSS Transform value.
473 * @return {array}
474 */
475function parse(source) {
476	if (typeof source === 'string') {
477		var match = source.match(/matrix(3d)?\(([^)]+)\)/);
478		if (match) {
479			var raw = match[2].split(', ').map(parseFloat);
480			return format(raw)
481		}
482	}
483	return identity()
484}
485
486/**
487 * Returns a 4x4 matrix describing X-axis rotation.
488 *
489 * @param  {number} angle - Measured in degrees.
490 * @return {array}
491 */
492function rotateX(angle) {
493	var theta = Math.PI / 180 * angle;
494	var matrix = identity();
495
496	matrix[5] = matrix[10] = Math.cos(theta);
497	matrix[6] = matrix[9] = Math.sin(theta);
498	matrix[9] *= -1;
499
500	return matrix
501}
502
503/**
504 * Returns a 4x4 matrix describing Y-axis rotation.
505 *
506 * @param  {number} angle - Measured in degrees.
507 * @return {array}
508 */
509function rotateY(angle) {
510	var theta = Math.PI / 180 * angle;
511	var matrix = identity();
512
513	matrix[0] = matrix[10] = Math.cos(theta);
514	matrix[2] = matrix[8] = Math.sin(theta);
515	matrix[2] *= -1;
516
517	return matrix
518}
519
520/**
521 * Returns a 4x4 matrix describing Z-axis rotation.
522 *
523 * @param  {number} angle - Measured in degrees.
524 * @return {array}
525 */
526function rotateZ(angle) {
527	var theta = Math.PI / 180 * angle;
528	var matrix = identity();
529
530	matrix[0] = matrix[5] = Math.cos(theta);
531	matrix[1] = matrix[4] = Math.sin(theta);
532	matrix[4] *= -1;
533
534	return matrix
535}
536
537/**
538 * Returns a 4x4 matrix describing 2D scaling. The first argument
539 * is used for both X and Y-axis scaling, unless an optional
540 * second argument is provided to explicitly define Y-axis scaling.
541 *
542 * @param  {number} scalar    - Decimal multiplier.
543 * @param  {number} [scalarY] - Decimal multiplier.
544 * @return {array}
545 */
546function scale(scalar, scalarY) {
547	var matrix = identity();
548
549	matrix[0] = scalar;
550	matrix[5] = typeof scalarY === 'number' ? scalarY : scalar;
551
552	return matrix
553}
554
555/**
556 * Returns a 4x4 matrix describing X-axis translation.
557 *
558 * @param  {number} distance - Measured in pixels.
559 * @return {array}
560 */
561function translateX(distance) {
562	var matrix = identity();
563	matrix[12] = distance;
564	return matrix
565}
566
567/**
568 * Returns a 4x4 matrix describing Y-axis translation.
569 *
570 * @param  {number} distance - Measured in pixels.
571 * @return {array}
572 */
573function translateY(distance) {
574	var matrix = identity();
575	matrix[13] = distance;
576	return matrix
577}
578
579var getPrefixedCssProp = (function () {
580	var properties = {};
581	var style = document.documentElement.style;
582
583	function getPrefixedCssProperty(name, source) {
584		if ( source === void 0 ) source = style;
585
586		if (name && typeof name === 'string') {
587			if (properties[name]) {
588				return properties[name]
589			}
590			if (typeof source[name] === 'string') {
591				return (properties[name] = name)
592			}
593			if (typeof source[("-webkit-" + name)] === 'string') {
594				return (properties[name] = "-webkit-" + name)
595			}
596			throw new RangeError(("Unable to find \"" + name + "\" style property."))
597		}
598		throw new TypeError('Expected a string.')
599	}
600
601	getPrefixedCssProperty.clearCache = function () { return (properties = {}); };
602
603	return getPrefixedCssProperty
604})();
605
606function style(element) {
607	var computed = window.getComputedStyle(element.node);
608	var position = computed.position;
609	var config = element.config;
610
611	/**
612	 * Generate inline styles
613	 */
614	var inline = {};
615	var inlineStyle = element.node.getAttribute('style') || '';
616	var inlineMatch = inlineStyle.match(/[\w-]+\s*:\s*[^;
vendor: 14,490 bytes, lines 616-1147
616]+\s*/gi) || [];
617
618	inline.computed = inlineMatch ? inlineMatch.map(function (m) { return m.trim(); }).join('; ') + ';' : '';
619
620	inline.generated = inlineMatch.some(function (m) { return m.match(/visibility\s?:\s?visible/i); })
621		? inline.computed
622		: inlineMatch.concat( ['visibility: visible']).map(function (m) { return m.trim(); }).join('; ') + ';';
623
624	/**
625	 * Generate opacity styles
626	 */
627	var computedOpacity = parseFloat(computed.opacity);
628	var configOpacity = !isNaN(parseFloat(config.opacity))
629		? parseFloat(config.opacity)
630		: parseFloat(computed.opacity);
631
632	var opacity = {
633		computed: computedOpacity !== configOpacity ? ("opacity: " + computedOpacity + ";") : '',
634		generated: computedOpacity !== configOpacity ? ("opacity: " + configOpacity + ";") : ''
635	};
636
637	/**
638	 * Generate transformation styles
639	 */
640	var transformations = [];
641
642	if (parseFloat(config.distance)) {
643		var axis = config.origin === 'top' || config.origin === 'bottom' ? 'Y' : 'X';
644
645		/**
646		 * Let’s make sure our our pixel distances are negative for top and left.
647		 * e.g. { origin: 'top', distance: '25px' } starts at `top: -25px` in CSS.
648		 */
649		var distance = config.distance;
650		if (config.origin === 'top' || config.origin === 'left') {
651			distance = /^-/.test(distance) ? distance.substr(1) : ("-" + distance);
652		}
653
654		var ref = distance.match(/(^-?\d+\.?\d?)|(em$|px$|%$)/g);
655		var value = ref[0];
656		var unit = ref[1];
657
658		switch (unit) {
659			case 'em':
660				distance = parseInt(computed.fontSize) * value;
661				break
662			case 'px':
663				distance = value;
664				break
665			case '%':
666				/**
667				 * Here we use `getBoundingClientRect` instead of
668				 * the existing data attached to `element.geometry`
669				 * because only the former includes any transformations
670				 * current applied to the element.
671				 *
672				 * If that behavior ends up being unintuitive, this
673				 * logic could instead utilize `element.geometry.height`
674				 * and `element.geoemetry.width` for the distaince calculation
675				 */
676				distance =
677					axis === 'Y'
678						? element.node.getBoundingClientRect().height * value / 100
679						: element.node.getBoundingClientRect().width * value / 100;
680				break
681			default:
682				throw new RangeError('Unrecognized or missing distance unit.')
683		}
684
685		if (axis === 'Y') {
686			transformations.push(translateY(distance));
687		} else {
688			transformations.push(translateX(distance));
689		}
690	}
691
692	if (config.rotate.x) { transformations.push(rotateX(config.rotate.x)); }
693	if (config.rotate.y) { transformations.push(rotateY(config.rotate.y)); }
694	if (config.rotate.z) { transformations.push(rotateZ(config.rotate.z)); }
695	if (config.scale !== 1) {
696		if (config.scale === 0) {
697			/**
698			 * The CSS Transforms matrix interpolation specification
699			 * basically disallows transitions of non-invertible
700			 * matrixes, which means browsers won't transition
701			 * elements with zero scale.
702			 *
703			 * That’s inconvenient for the API and developer
704			 * experience, so we simply nudge their value
705			 * slightly above zero; this allows browsers
706			 * to transition our element as expected.
707			 *
708			 * `0.0002` was the smallest number
709			 * that performed across browsers.
710			 */
711			transformations.push(scale(0.0002));
712		} else {
713			transformations.push(scale(config.scale));
714		}
715	}
716
717	var transform = {};
718	if (transformations.length) {
719		transform.property = getPrefixedCssProp('transform');
720		/**
721		 * The default computed transform value should be one of:
722		 * undefined || 'none' || 'matrix()' || 'matrix3d()'
723		 */
724		transform.computed = {
725			raw: computed[transform.property],
726			matrix: parse(computed[transform.property])
727		};
728
729		transformations.unshift(transform.computed.matrix);
730		var product = transformations.reduce(multiply);
731
732		transform.generated = {
733			initial: ((transform.property) + ": matrix3d(" + (product.join(', ')) + ");"),
734			final: ((transform.property) + ": matrix3d(" + (transform.computed.matrix.join(
735				', '
736			)) + ");")
737		};
738	} else {
739		transform.generated = {
740			initial: '',
741			final: ''
742		};
743	}
744
745	/**
746	 * Generate transition styles
747	 */
748	var transition = {};
749	if (opacity.generated || transform.generated.initial) {
750		transition.property = getPrefixedCssProp('transition');
751		transition.computed = computed[transition.property];
752		transition.fragments = [];
753
754		var delay = config.delay;
755		var duration = config.duration;
756		var easing = config.easing;
757
758		if (opacity.generated) {
759			transition.fragments.push({
760				delayed: ("opacity " + (duration / 1000) + "s " + easing + " " + (delay / 1000) + "s"),
761				instant: ("opacity " + (duration / 1000) + "s " + easing + " 0s")
762			});
763		}
764
765		if (transform.generated.initial) {
766			transition.fragments.push({
767				delayed: ((transform.property) + " " + (duration / 1000) + "s " + easing + " " + (delay /
768					1000) + "s"),
769				instant: ((transform.property) + " " + (duration / 1000) + "s " + easing + " 0s")
770			});
771		}
772
773		/**
774		 * The default computed transition property should be one of:
775		 * undefined || '' || 'all 0s ease 0s' || 'all 0s 0s cubic-bezier()'
776		 */
777		if (transition.computed && !transition.computed.match(/all 0s/)) {
778			transition.fragments.unshift({
779				delayed: transition.computed,
780				instant: transition.computed
781			});
782		}
783
784		var composed = transition.fragments.reduce(
785			function (composition, fragment, i) {
786				composition.delayed +=
787					i === 0 ? fragment.delayed : (", " + (fragment.delayed));
788				composition.instant +=
789					i === 0 ? fragment.instant : (", " + (fragment.instant));
790				return composition
791			},
792			{
793				delayed: '',
794				instant: ''
795			}
796		);
797
798		transition.generated = {
799			delayed: ((transition.property) + ": " + (composed.delayed) + ";"),
800			instant: ((transition.property) + ": " + (composed.instant) + ";")
801		};
802	} else {
803		transition.generated = {
804			delayed: '',
805			instant: ''
806		};
807	}
808
809	return {
810		inline: inline,
811		opacity: opacity,
812		position: position,
813		transform: transform,
814		transition: transition
815	}
816}
817
818function animate(element, force) {
819	if ( force === void 0 ) force = {};
820
821	var pristine = force.pristine || this.pristine;
822	var delayed =
823		element.config.useDelay === 'always' ||
824		(element.config.useDelay === 'onload' && pristine) ||
825		(element.config.useDelay === 'once' && !element.seen);
826
827	var shouldReveal = element.visible && !element.revealed;
828	var shouldReset = !element.visible && element.revealed && element.config.reset;
829
830	if (force.reveal || shouldReveal) {
831		return triggerReveal.call(this, element, delayed)
832	}
833
834	if (force.reset || shouldReset) {
835		return triggerReset.call(this, element)
836	}
837}
838
839function triggerReveal(element, delayed) {
840	var styles = [
841		element.styles.inline.generated,
842		element.styles.opacity.computed,
843		element.styles.transform.generated.final
844	];
845	if (delayed) {
846		styles.push(element.styles.transition.generated.delayed);
847	} else {
848		styles.push(element.styles.transition.generated.instant);
849	}
850	element.revealed = element.seen = true;
851	element.node.setAttribute('style', styles.filter(function (s) { return s !== ''; }).join(' '));
852	registerCallbacks.call(this, element, delayed);
853}
854
855function triggerReset(element) {
856	var styles = [
857		element.styles.inline.generated,
858		element.styles.opacity.generated,
859		element.styles.transform.generated.initial,
860		element.styles.transition.generated.instant
861	];
862	element.revealed = false;
863	element.node.setAttribute('style', styles.filter(function (s) { return s !== ''; }).join(' '));
864	registerCallbacks.call(this, element);
865}
866
867function registerCallbacks(element, isDelayed) {
868	var this$1 = this;
869
870	var duration = isDelayed
871		? element.config.duration + element.config.delay
872		: element.config.duration;
873
874	var beforeCallback = element.revealed
875		? element.config.beforeReveal
876		: element.config.beforeReset;
877
878	var afterCallback = element.revealed
879		? element.config.afterReveal
880		: element.config.afterReset;
881
882	var elapsed = 0;
883	if (element.callbackTimer) {
884		elapsed = Date.now() - element.callbackTimer.start;
885		window.clearTimeout(element.callbackTimer.clock);
886	}
887
888	beforeCallback(element.node);
889
890	element.callbackTimer = {
891		start: Date.now(),
892		clock: window.setTimeout(function () {
893			afterCallback(element.node);
894			element.callbackTimer = null;
895			if (element.revealed && !element.config.reset && element.config.cleanup) {
896				clean.call(this$1, element.node);
897			}
898		}, duration - elapsed)
899	};
900}
901
902var nextUniqueId = (function () {
903	var uid = 0;
904	return function () { return uid++; }
905})();
906
907function sequence(element, pristine) {
908	if ( pristine === void 0 ) pristine = this.pristine;
909
910	/**
911	 * We first check if the element should reset.
912	 */
913	if (!element.visible && element.revealed && element.config.reset) {
914		return animate.call(this, element, { reset: true })
915	}
916
917	var seq = this.store.sequences[element.sequence.id];
918	var i = element.sequence.index;
919
920	if (seq) {
921		var visible = new SequenceModel(seq, 'visible', this.store);
922		var revealed = new SequenceModel(seq, 'revealed', this.store);
923
924		seq.models = { visible: visible, revealed: revealed };
925
926		/**
927		 * If the sequence has no revealed members,
928		 * then we reveal the first visible element
929		 * within that sequence.
930		 *
931		 * The sequence then cues a recursive call
932		 * in both directions.
933		 */
934		if (!revealed.body.length) {
935			var nextId = seq.members[visible.body[0]];
936			var nextElement = this.store.elements[nextId];
937
938			if (nextElement) {
939				cue.call(this, seq, visible.body[0], -1, pristine);
940				cue.call(this, seq, visible.body[0], +1, pristine);
941				return animate.call(this, nextElement, { reveal: true, pristine: pristine })
942			}
943		}
944
945		/**
946		 * If our element isn’t resetting, we check the
947		 * element sequence index against the head, and
948		 * then the foot of the sequence.
949		 */
950		if (
951			!seq.blocked.head &&
952			i === [].concat( revealed.head ).pop() &&
953			i >= [].concat( visible.body ).shift()
954		) {
955			cue.call(this, seq, i, -1, pristine);
956			return animate.call(this, element, { reveal: true, pristine: pristine })
957		}
958
959		if (
960			!seq.blocked.foot &&
961			i === [].concat( revealed.foot ).shift() &&
962			i <= [].concat( visible.body ).pop()
963		) {
964			cue.call(this, seq, i, +1, pristine);
965			return animate.call(this, element, { reveal: true, pristine: pristine })
966		}
967	}
968}
969
970function Sequence(interval) {
971	var i = Math.abs(interval);
972	if (!isNaN(i)) {
973		this.id = nextUniqueId();
974		this.interval = Math.max(i, 16);
975		this.members = [];
976		this.models = {};
977		this.blocked = {
978			head: false,
979			foot: false
980		};
981	} else {
982		throw new RangeError('Invalid sequence interval.')
983	}
984}
985
986function SequenceModel(seq, prop, store) {
987	var this$1 = this;
988
989	this.head = [];
990	this.body = [];
991	this.foot = [];
992
993	each(seq.members, function (id, index) {
994		var element = store.elements[id];
995		if (element && element[prop]) {
996			this$1.body.push(index);
997		}
998	});
999
1000	if (this.body.length) {
1001		each(seq.members, function (id, index) {
1002			var element = store.elements[id];
1003			if (element && !element[prop]) {
1004				if (index < this$1.body[0]) {
1005					this$1.head.push(index);
1006				} else {
1007					this$1.foot.push(index);
1008				}
1009			}
1010		});
1011	}
1012}
1013
1014function cue(seq, i, direction, pristine) {
1015	var this$1 = this;
1016
1017	var blocked = ['head', null, 'foot'][1 + direction];
1018	var nextId = seq.members[i + direction];
1019	var nextElement = this.store.elements[nextId];
1020
1021	seq.blocked[blocked] = true;
1022
1023	setTimeout(function () {
1024		seq.blocked[blocked] = false;
1025		if (nextElement) {
1026			sequence.call(this$1, nextElement, pristine);
1027		}
1028	}, seq.interval);
1029}
1030
1031function initialize() {
1032	var this$1 = this;
1033
1034	rinse.call(this);
1035
1036	each(this.store.elements, function (element) {
1037		var styles = [element.styles.inline.generated];
1038
1039		if (element.visible) {
1040			styles.push(element.styles.opacity.computed);
1041			styles.push(element.styles.transform.generated.final);
1042			element.revealed = true;
1043		} else {
1044			styles.push(element.styles.opacity.generated);
1045			styles.push(element.styles.transform.generated.initial);
1046			element.revealed = false;
1047		}
1048
1049		element.node.setAttribute('style', styles.filter(function (s) { return s !== ''; }).join(' '));
1050	});
1051
1052	each(this.store.containers, function (container) {
1053		var target =
1054			container.node === document.documentElement ? window : container.node;
1055		target.addEventListener('scroll', this$1.delegate);
1056		target.addEventListener('resize', this$1.delegate);
1057	});
1058
1059	/**
1060	 * Manually invoke delegate once to capture
1061	 * element and container dimensions, container
1062	 * scroll position, and trigger any valid reveals
1063	 */
1064	this.delegate();
1065
1066	/**
1067	 * Wipe any existing `setTimeout` now
1068	 * that initialization has completed.
1069	 */
1070	this.initTimeout = null;
1071}
1072
1073function isMobile(agent) {
1074	if ( agent === void 0 ) agent = navigator.userAgent;
1075
1076	return /Android|iPhone|iPad|iPod/i.test(agent)
1077}
1078
1079function deepAssign(target) {
1080	var sources = [], len = arguments.length - 1;
1081	while ( len-- > 0 ) sources[ len ] = arguments[ len + 1 ];
1082
1083	if (isObject(target)) {
1084		each(sources, function (source) {
1085			each(source, function (data, key) {
1086				if (isObject(data)) {
1087					if (!target[key] || !isObject(target[key])) {
1088						target[key] = {};
1089					}
1090					deepAssign(target[key], data);
1091				} else {
1092					target[key] = data;
1093				}
1094			});
1095		});
1096		return target
1097	} else {
1098		throw new TypeError('Target must be an object literal.')
1099	}
1100}
1101
1102function reveal(target, options, syncing) {
1103	var this$1 = this;
1104	if ( options === void 0 ) options = {};
1105	if ( syncing === void 0 ) syncing = false;
1106
1107	var containerBuffer = [];
1108	var sequence$$1;
1109	var interval = options.interval || defaults.interval;
1110
1111	try {
1112		if (interval) {
1113			sequence$$1 = new Sequence(interval);
1114		}
1115
1116		var nodes = tealight(target);
1117		if (!nodes.length) {
1118			throw new Error('Invalid reveal target.')
1119		}
1120
1121		var elements = nodes.reduce(function (elementBuffer, elementNode) {
1122			var element = {};
1123			var existingId = elementNode.getAttribute('data-sr-id');
1124
1125			if (existingId) {
1126				deepAssign(element, this$1.store.elements[existingId]);
1127
1128				/**
1129				 * In order to prevent previously generated styles
1130				 * from throwing off the new styles, the style tag
1131				 * has to be reverted to its pre-reveal state.
1132				 */
1133				element.node.setAttribute('style', element.styles.inline.computed);
1134			} else {
1135				element.id = nextUniqueId();
1136				element.node = elementNode;
1137				element.seen = false;
1138				element.revealed = false;
1139				element.visible = false;
1140			}
1141
1142			var config = deepAssign({}, element.config || this$1.defaults, options);
1143
1144			if ((!config.mobile && isMobile()) || (!config.desktop && !isMobile())) {
1145				if (existingId) {
1146					clean.call(this$1, element);
1147				}
vendor: 10,903 bytes, lines 1148-1546
1148				return elementBuffer // skip elements that are disabled
1149			}
1150
1151			var containerNode = tealight(config.container)[0];
1152			if (!containerNode) {
1153				throw new Error('Invalid container.')
1154			}
1155			if (!containerNode.contains(elementNode)) {
1156				return elementBuffer // skip elements found outside the container
1157			}
1158
1159			var containerId;
1160			{
1161				containerId = getContainerId(
1162					containerNode,
1163					containerBuffer,
1164					this$1.store.containers
1165				);
1166				if (containerId === null) {
1167					containerId = nextUniqueId();
1168					containerBuffer.push({ id: containerId, node: containerNode });
1169				}
1170			}
1171
1172			element.config = config;
1173			element.containerId = containerId;
1174			element.styles = style(element);
1175
1176			if (sequence$$1) {
1177				element.sequence = {
1178					id: sequence$$1.id,
1179					index: sequence$$1.members.length
1180				};
1181				sequence$$1.members.push(element.id);
1182			}
1183
1184			elementBuffer.push(element);
1185			return elementBuffer
1186		}, []);
1187
1188		/**
1189		 * Modifying the DOM via setAttribute needs to be handled
1190		 * separately from reading computed styles in the map above
1191		 * for the browser to batch DOM changes (limiting reflows)
1192		 */
1193		each(elements, function (element) {
1194			this$1.store.elements[element.id] = element;
1195			element.node.setAttribute('data-sr-id', element.id);
1196		});
1197	} catch (e) {
1198		return logger.call(this, 'Reveal failed.', e.message)
1199	}
1200
1201	/**
1202	 * Now that element set-up is complete...
1203	 * Let’s commit any container and sequence data we have to the store.
1204	 */
1205	each(containerBuffer, function (container) {
1206		this$1.store.containers[container.id] = {
1207			id: container.id,
1208			node: container.node
1209		};
1210	});
1211	if (sequence$$1) {
1212		this.store.sequences[sequence$$1.id] = sequence$$1;
1213	}
1214
1215	/**
1216	 * If reveal wasn't invoked by sync, we want to
1217	 * make sure to add this call to the history.
1218	 */
1219	if (syncing !== true) {
1220		this.store.history.push({ target: target, options: options });
1221
1222		/**
1223		 * Push initialization to the event queue, giving
1224		 * multiple reveal calls time to be interpreted.
1225		 */
1226		if (this.initTimeout) {
1227			window.clearTimeout(this.initTimeout);
1228		}
1229		this.initTimeout = window.setTimeout(initialize.bind(this), 0);
1230	}
1231}
1232
1233function getContainerId(node) {
1234	var collections = [], len = arguments.length - 1;
1235	while ( len-- > 0 ) collections[ len ] = arguments[ len + 1 ];
1236
1237	var id = null;
1238	each(collections, function (collection) {
1239		each(collection, function (container) {
1240			if (id === null && container.node === node) {
1241				id = container.id;
1242			}
1243		});
1244	});
1245	return id
1246}
1247
1248/**
1249 * Re-runs the reveal method for each record stored in history,
1250 * for capturing new content asynchronously loaded into the DOM.
1251 */
1252function sync() {
1253	var this$1 = this;
1254
1255	each(this.store.history, function (record) {
1256		reveal.call(this$1, record.target, record.options, true);
1257	});
1258
1259	initialize.call(this);
1260}
1261
1262var polyfill = function (x) { return (x > 0) - (x < 0) || +x; };
1263var mathSign = Math.sign || polyfill
1264
1265/*! @license miniraf v1.0.0
1266
1267	Copyright 2018 Fisssion LLC.
1268
1269	Permission is hereby granted, free of charge, to any person obtaining a copy
1270	of this software and associated documentation files (the "Software"), to deal
1271	in the Software without restriction, including without limitation the rights
1272	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1273	copies of the Software, and to permit persons to whom the Software is
1274	furnished to do so, subject to the following conditions:
1275
1276	The above copyright notice and this permission notice shall be included in all
1277	copies or substantial portions of the Software.
1278
1279	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1280	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1281	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1282	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1283	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
1284	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
1285	SOFTWARE.
1286
1287*/
1288var polyfill$1 = (function () {
1289	var clock = Date.now();
1290
1291	return function (callback) {
1292		var currentTime = Date.now();
1293		if (currentTime - clock > 16) {
1294			clock = currentTime;
1295			callback(currentTime);
1296		} else {
1297			setTimeout(function () { return polyfill$1(callback); }, 0);
1298		}
1299	}
1300})();
1301
1302var index = window.requestAnimationFrame ||
1303	window.webkitRequestAnimationFrame ||
1304	window.mozRequestAnimationFrame ||
1305	polyfill$1;
1306
1307function getGeometry(target, isContainer) {
1308	/**
1309	 * We want to ignore padding and scrollbars for container elements.
1310	 * More information here: https://goo.gl/vOZpbz
1311	 */
1312	var height = isContainer ? target.node.clientHeight : target.node.offsetHeight;
1313	var width = isContainer ? target.node.clientWidth : target.node.offsetWidth;
1314
1315	var offsetTop = 0;
1316	var offsetLeft = 0;
1317	var node = target.node;
1318
1319	do {
1320		if (!isNaN(node.offsetTop)) {
1321			offsetTop += node.offsetTop;
1322		}
1323		if (!isNaN(node.offsetLeft)) {
1324			offsetLeft += node.offsetLeft;
1325		}
1326		node = node.offsetParent;
1327	} while (node)
1328
1329	return {
1330		bounds: {
1331			top: offsetTop,
1332			right: offsetLeft + width,
1333			bottom: offsetTop + height,
1334			left: offsetLeft
1335		},
1336		height: height,
1337		width: width
1338	}
1339}
1340
1341function getScrolled(container) {
1342	var top, left;
1343	if (container.node === document.documentElement) {
1344		top = window.pageYOffset;
1345		left = window.pageXOffset;
1346	} else {
1347		top = container.node.scrollTop;
1348		left = container.node.scrollLeft;
1349	}
1350	return { top: top, left: left }
1351}
1352
1353function isElementVisible(element) {
1354	if ( element === void 0 ) element = {};
1355
1356	var container = this.store.containers[element.containerId];
1357	if (!container) { return }
1358
1359	var viewFactor = Math.max(0, Math.min(1, element.config.viewFactor));
1360	var viewOffset = element.config.viewOffset;
1361
1362	var elementBounds = {
1363		top: element.geometry.bounds.top + element.geometry.height * viewFactor,
1364		right: element.geometry.bounds.right - element.geometry.width * viewFactor,
1365		bottom: element.geometry.bounds.bottom - element.geometry.height * viewFactor,
1366		left: element.geometry.bounds.left + element.geometry.width * viewFactor
1367	};
1368
1369	var containerBounds = {
1370		top: container.geometry.bounds.top + container.scroll.top + viewOffset.top,
1371		right: container.geometry.bounds.right + container.scroll.left - viewOffset.right,
1372		bottom:
1373			container.geometry.bounds.bottom + container.scroll.top - viewOffset.bottom,
1374		left: container.geometry.bounds.left + container.scroll.left + viewOffset.left
1375	};
1376
1377	return (
1378		(elementBounds.top < containerBounds.bottom &&
1379			elementBounds.right > containerBounds.left &&
1380			elementBounds.bottom > containerBounds.top &&
1381			elementBounds.left < containerBounds.right) ||
1382		element.styles.position === 'fixed'
1383	)
1384}
1385
1386function delegate(
1387	event,
1388	elements
1389) {
1390	var this$1 = this;
1391	if ( event === void 0 ) event = { type: 'init' };
1392	if ( elements === void 0 ) elements = this.store.elements;
1393
1394	index(function () {
1395		var stale = event.type === 'init' || event.type === 'resize';
1396
1397		each(this$1.store.containers, function (container) {
1398			if (stale) {
1399				container.geometry = getGeometry.call(this$1, container, true);
1400			}
1401			var scroll = getScrolled.call(this$1, container);
1402			if (container.scroll) {
1403				container.direction = {
1404					x: mathSign(scroll.left - container.scroll.left),
1405					y: mathSign(scroll.top - container.scroll.top)
1406				};
1407			}
1408			container.scroll = scroll;
1409		});
1410
1411		/**
1412		 * Due to how the sequencer is implemented, it’s
1413		 * important that we update the state of all
1414		 * elements, before any animation logic is
1415		 * evaluated (in the second loop below).
1416		 */
1417		each(elements, function (element) {
1418			if (stale) {
1419				element.geometry = getGeometry.call(this$1, element);
1420			}
1421			element.visible = isElementVisible.call(this$1, element);
1422		});
1423
1424		each(elements, function (element) {
1425			if (element.sequence) {
1426				sequence.call(this$1, element);
1427			} else {
1428				animate.call(this$1, element);
1429			}
1430		});
1431
1432		this$1.pristine = false;
1433	});
1434}
1435
1436function transformSupported() {
1437	var style = document.documentElement.style;
1438	return 'transform' in style || 'WebkitTransform' in style
1439}
1440
1441function transitionSupported() {
1442	var style = document.documentElement.style;
1443	return 'transition' in style || 'WebkitTransition' in style
1444}
1445
1446var version = "4.0.5";
1447
1448var boundDelegate;
1449var boundDestroy;
1450var boundReveal;
1451var boundClean;
1452var boundSync;
1453var config;
1454var debug;
1455var instance;
1456
1457function ScrollReveal(options) {
1458	if ( options === void 0 ) options = {};
1459
1460	var invokedWithoutNew =
1461		typeof this === 'undefined' ||
1462		Object.getPrototypeOf(this) !== ScrollReveal.prototype;
1463
1464	if (invokedWithoutNew) {
1465		return new ScrollReveal(options)
1466	}
1467
1468	if (!ScrollReveal.isSupported()) {
1469		logger.call(this, 'Instantiation failed.', 'This browser is not supported.');
1470		return mount.failure()
1471	}
1472
1473	var buffer;
1474	try {
1475		buffer = config
1476			? deepAssign({}, config, options)
1477			: deepAssign({}, defaults, options);
1478	} catch (e) {
1479		logger.call(this, 'Invalid configuration.', e.message);
1480		return mount.failure()
1481	}
1482
1483	try {
1484		var container = tealight(buffer.container)[0];
1485		if (!container) {
1486			throw new Error('Invalid container.')
1487		}
1488	} catch (e) {
1489		logger.call(this, e.message);
1490		return mount.failure()
1491	}
1492
1493	config = buffer;
1494
1495	if ((!config.mobile && isMobile()) || (!config.desktop && !isMobile())) {
1496		logger.call(
1497			this,
1498			'This device is disabled.',
1499			("desktop: " + (config.desktop)),
1500			("mobile: " + (config.mobile))
1501		);
1502		return mount.failure()
1503	}
1504
1505	mount.success();
1506
1507	this.store = {
1508		containers: {},
1509		elements: {},
1510		history: [],
1511		sequences: {}
1512	};
1513
1514	this.pristine = true;
1515
1516	boundDelegate = boundDelegate || delegate.bind(this);
1517	boundDestroy = boundDestroy || destroy.bind(this);
1518	boundReveal = boundReveal || reveal.bind(this);
1519	boundClean = boundClean || clean.bind(this);
1520	boundSync = boundSync || sync.bind(this);
1521
1522	Object.defineProperty(this, 'delegate', { get: function () { return boundDelegate; } });
1523	Object.defineProperty(this, 'destroy', { get: function () { return boundDestroy; } });
1524	Object.defineProperty(this, 'reveal', { get: function () { return boundReveal; } });
1525	Object.defineProperty(this, 'clean', { get: function () { return boundClean; } });
1526	Object.defineProperty(this, 'sync', { get: function () { return boundSync; } });
1527
1528	Object.defineProperty(this, 'defaults', { get: function () { return config; } });
1529	Object.defineProperty(this, 'version', { get: function () { return version; } });
1530	Object.defineProperty(this, 'noop', { get: function () { return false; } });
1531
1532	return instance ? instance : (instance = this)
1533}
1534
1535ScrollReveal.isSupported = function () { return transformSupported() && transitionSupported(); };
1536
1537Object.defineProperty(ScrollReveal, 'debug', {
1538	get: function () { return debug || false; },
1539	set: function (value) { return (debug = typeof value === 'boolean' ? value : debug); }
1540});
1541
1542ScrollReveal();
1543
1544return ScrollReveal;
1545
1546})));

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.