PageSourceSearch

https://wxuas.com/js/domain-map-webpack.js?v=6MM1xIE0HGpzr2DULxbupDz1XTOdDrJhZjXxHvMP5TY

js wxuas.com collected 2026-10-04 02:40:38 UTC 1,871,453 bytes, 63,452 lines download raw bytes

1/******/ (() => { // webpackBootstrap
2/******/ 	var __webpack_modules__ = ({
3
4/***/ 755:
vendor: 6,901 bytes, lines 4-268
4
5/***/ (function(module, exports) {
6
7var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
8 * jQuery JavaScript Library v3.6.1
9 * https://jquery.com/
10 *
11 * Includes Sizzle.js
12 * https://sizzlejs.com/
13 *
14 * Copyright OpenJS Foundation and other contributors
15 * Released under the MIT license
16 * https://jquery.org/license
17 *
18 * Date: 2022-08-26T17:52Z
19 */
20( function( global, factory ) {
21
22	"use strict";
23
24	if (  true && typeof module.exports === "object" ) {
25
26		// For CommonJS and CommonJS-like environments where a proper `window`
27		// is present, execute the factory and get jQuery.
28		// For environments that do not have a `window` with a `document`
29		// (such as Node.js), expose a factory as module.exports.
30		// This accentuates the need for the creation of a real `window`.
31		// e.g. var jQuery = require("jquery")(window);
32		// See ticket trac-14549 for more info.
33		module.exports = global.document ?
34			factory( global, true ) :
35			function( w ) {
36				if ( !w.document ) {
37					throw new Error( "jQuery requires a window with a document" );
38				}
39				return factory( w );
40			};
41	} else {
42		factory( global );
43	}
44
45// Pass this if window is not defined yet
46} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
47
48// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1
49// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode
50// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common
51// enough that all such attempts are guarded in a try block.
52"use strict";
53
54var arr = [];
55
56var getProto = Object.getPrototypeOf;
57
58var slice = arr.slice;
59
60var flat = arr.flat ? function( array ) {
61	return arr.flat.call( array );
62} : function( array ) {
63	return arr.concat.apply( [], array );
64};
65
66
67var push = arr.push;
68
69var indexOf = arr.indexOf;
70
71var class2type = {};
72
73var toString = class2type.toString;
74
75var hasOwn = class2type.hasOwnProperty;
76
77var fnToString = hasOwn.toString;
78
79var ObjectFunctionString = fnToString.call( Object );
80
81var support = {};
82
83var isFunction = function isFunction( obj ) {
84
85		// Support: Chrome <=57, Firefox <=52
86		// In some browsers, typeof returns "function" for HTML <object> elements
87		// (i.e., `typeof document.createElement( "object" ) === "function"`).
88		// We don't want to classify *any* DOM node as a function.
89		// Support: QtWeb <=3.8.5, WebKit <=534.34, wkhtmltopdf tool <=0.12.5
90		// Plus for old WebKit, typeof returns "function" for HTML collections
91		// (e.g., `typeof document.getElementsByTagName("div") === "function"`). (gh-4756)
92		return typeof obj === "function" && typeof obj.nodeType !== "number" &&
93			typeof obj.item !== "function";
94	};
95
96
97var isWindow = function isWindow( obj ) {
98		return obj != null && obj === obj.window;
99	};
100
101
102var document = window.document;
103
104
105
106	var preservedScriptAttributes = {
107		type: true,
108		src: true,
109		nonce: true,
110		noModule: true
111	};
112
113	function DOMEval( code, node, doc ) {
114		doc = doc || document;
115
116		var i, val,
117			script = doc.createElement( "script" );
118
119		script.text = code;
120		if ( node ) {
121			for ( i in preservedScriptAttributes ) {
122
123				// Support: Firefox 64+, Edge 18+
124				// Some browsers don't support the "nonce" property on scripts.
125				// On the other hand, just using `getAttribute` is not enough as
126				// the `nonce` attribute is reset to an empty string whenever it
127				// becomes browsing-context connected.
128				// See https://github.com/whatwg/html/issues/2369
129				// See https://html.spec.whatwg.org/#nonce-attributes
130				// The `node.getAttribute` check was added for the sake of
131				// `jQuery.globalEval` so that it can fake a nonce-containing node
132				// via an object.
133				val = node[ i ] || node.getAttribute && node.getAttribute( i );
134				if ( val ) {
135					script.setAttribute( i, val );
136				}
137			}
138		}
139		doc.head.appendChild( script ).parentNode.removeChild( script );
140	}
141
142
143function toType( obj ) {
144	if ( obj == null ) {
145		return obj + "";
146	}
147
148	// Support: Android <=2.3 only (functionish RegExp)
149	return typeof obj === "object" || typeof obj === "function" ?
150		class2type[ toString.call( obj ) ] || "object" :
151		typeof obj;
152}
153/* global Symbol */
154// Defining this global in .eslintrc.json would create a danger of using the global
155// unguarded in another place, it seems safer to define global only for this module
156
157
158
159var
160	version = "3.6.1",
161
162	// Define a local copy of jQuery
163	jQuery = function( selector, context ) {
164
165		// The jQuery object is actually just the init constructor 'enhanced'
166		// Need init if jQuery is called (just allow error to be thrown if not included)
167		return new jQuery.fn.init( selector, context );
168	};
169
170jQuery.fn = jQuery.prototype = {
171
172	// The current version of jQuery being used
173	jquery: version,
174
175	constructor: jQuery,
176
177	// The default length of a jQuery object is 0
178	length: 0,
179
180	toArray: function() {
181		return slice.call( this );
182	},
183
184	// Get the Nth element in the matched element set OR
185	// Get the whole matched element set as a clean array
186	get: function( num ) {
187
188		// Return all the elements in a clean array
189		if ( num == null ) {
190			return slice.call( this );
191		}
192
193		// Return just the one element from the set
194		return num < 0 ? this[ num + this.length ] : this[ num ];
195	},
196
197	// Take an array of elements and push it onto the stack
198	// (returning the new matched element set)
199	pushStack: function( elems ) {
200
201		// Build a new jQuery matched element set
202		var ret = jQuery.merge( this.constructor(), elems );
203
204		// Add the old object onto the stack (as a reference)
205		ret.prevObject = this;
206
207		// Return the newly-formed element set
208		return ret;
209	},
210
211	// Execute a callback for every element in the matched set.
212	each: function( callback ) {
213		return jQuery.each( this, callback );
214	},
215
216	map: function( callback ) {
217		return this.pushStack( jQuery.map( this, function( elem, i ) {
218			return callback.call( elem, i, elem );
219		} ) );
220	},
221
222	slice: function() {
223		return this.pushStack( slice.apply( this, arguments ) );
224	},
225
226	first: function() {
227		return this.eq( 0 );
228	},
229
230	last: function() {
231		return this.eq( -1 );
232	},
233
234	even: function() {
235		return this.pushStack( jQuery.grep( this, function( _elem, i ) {
236			return ( i + 1 ) % 2;
237		} ) );
238	},
239
240	odd: function() {
241		return this.pushStack( jQuery.grep( this, function( _elem, i ) {
242			return i % 2;
243		} ) );
244	},
245
246	eq: function( i ) {
247		var len = this.length,
248			j = +i + ( i < 0 ? len : 0 );
249		return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );
250	},
251
252	end: function() {
253		return this.prevObject || this.constructor();
254	},
255
256	// For internal use only.
257	// Behaves like an Array's method, not like a jQuery method.
258	push: push,
259	sort: arr.sort,
260	splice: arr.splice
261};
262
263jQuery.extend = jQuery.fn.extend = function() {
264	var options, name, src, copy, copyIsArray, clone,
265		target = arguments[ 0 ] || {},
266		i = 1,
267		length = arguments.length,
268		deep = false;
vendor: 78,348 bytes, lines 269-3092
269
270	// Handle a deep copy situation
271	if ( typeof target === "boolean" ) {
272		deep = target;
273
274		// Skip the boolean and the target
275		target = arguments[ i ] || {};
276		i++;
277	}
278
279	// Handle case when target is a string or something (possible in deep copy)
280	if ( typeof target !== "object" && !isFunction( target ) ) {
281		target = {};
282	}
283
284	// Extend jQuery itself if only one argument is passed
285	if ( i === length ) {
286		target = this;
287		i--;
288	}
289
290	for ( ; i < length; i++ ) {
291
292		// Only deal with non-null/undefined values
293		if ( ( options = arguments[ i ] ) != null ) {
294
295			// Extend the base object
296			for ( name in options ) {
297				copy = options[ name ];
298
299				// Prevent Object.prototype pollution
300				// Prevent never-ending loop
301				if ( name === "__proto__" || target === copy ) {
302					continue;
303				}
304
305				// Recurse if we're merging plain objects or arrays
306				if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
307					( copyIsArray = Array.isArray( copy ) ) ) ) {
308					src = target[ name ];
309
310					// Ensure proper type for the source value
311					if ( copyIsArray && !Array.isArray( src ) ) {
312						clone = [];
313					} else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) {
314						clone = {};
315					} else {
316						clone = src;
317					}
318					copyIsArray = false;
319
320					// Never move original objects, clone them
321					target[ name ] = jQuery.extend( deep, clone, copy );
322
323				// Don't bring in undefined values
324				} else if ( copy !== undefined ) {
325					target[ name ] = copy;
326				}
327			}
328		}
329	}
330
331	// Return the modified object
332	return target;
333};
334
335jQuery.extend( {
336
337	// Unique for each copy of jQuery on the page
338	expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
339
340	// Assume jQuery is ready without the ready module
341	isReady: true,
342
343	error: function( msg ) {
344		throw new Error( msg );
345	},
346
347	noop: function() {},
348
349	isPlainObject: function( obj ) {
350		var proto, Ctor;
351
352		// Detect obvious negatives
353		// Use toString instead of jQuery.type to catch host objects
354		if ( !obj || toString.call( obj ) !== "[object Object]" ) {
355			return false;
356		}
357
358		proto = getProto( obj );
359
360		// Objects with no prototype (e.g., `Object.create( null )`) are plain
361		if ( !proto ) {
362			return true;
363		}
364
365		// Objects with prototype are plain iff they were constructed by a global Object function
366		Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor;
367		return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString;
368	},
369
370	isEmptyObject: function( obj ) {
371		var name;
372
373		for ( name in obj ) {
374			return false;
375		}
376		return true;
377	},
378
379	// Evaluates a script in a provided context; falls back to the global one
380	// if not specified.
381	globalEval: function( code, options, doc ) {
382		DOMEval( code, { nonce: options && options.nonce }, doc );
383	},
384
385	each: function( obj, callback ) {
386		var length, i = 0;
387
388		if ( isArrayLike( obj ) ) {
389			length = obj.length;
390			for ( ; i < length; i++ ) {
391				if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
392					break;
393				}
394			}
395		} else {
396			for ( i in obj ) {
397				if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
398					break;
399				}
400			}
401		}
402
403		return obj;
404	},
405
406	// results is for internal usage only
407	makeArray: function( arr, results ) {
408		var ret = results || [];
409
410		if ( arr != null ) {
411			if ( isArrayLike( Object( arr ) ) ) {
412				jQuery.merge( ret,
413					typeof arr === "string" ?
414						[ arr ] : arr
415				);
416			} else {
417				push.call( ret, arr );
418			}
419		}
420
421		return ret;
422	},
423
424	inArray: function( elem, arr, i ) {
425		return arr == null ? -1 : indexOf.call( arr, elem, i );
426	},
427
428	// Support: Android <=4.0 only, PhantomJS 1 only
429	// push.apply(_, arraylike) throws on ancient WebKit
430	merge: function( first, second ) {
431		var len = +second.length,
432			j = 0,
433			i = first.length;
434
435		for ( ; j < len; j++ ) {
436			first[ i++ ] = second[ j ];
437		}
438
439		first.length = i;
440
441		return first;
442	},
443
444	grep: function( elems, callback, invert ) {
445		var callbackInverse,
446			matches = [],
447			i = 0,
448			length = elems.length,
449			callbackExpect = !invert;
450
451		// Go through the array, only saving the items
452		// that pass the validator function
453		for ( ; i < length; i++ ) {
454			callbackInverse = !callback( elems[ i ], i );
455			if ( callbackInverse !== callbackExpect ) {
456				matches.push( elems[ i ] );
457			}
458		}
459
460		return matches;
461	},
462
463	// arg is for internal usage only
464	map: function( elems, callback, arg ) {
465		var length, value,
466			i = 0,
467			ret = [];
468
469		// Go through the array, translating each of the items to their new values
470		if ( isArrayLike( elems ) ) {
471			length = elems.length;
472			for ( ; i < length; i++ ) {
473				value = callback( elems[ i ], i, arg );
474
475				if ( value != null ) {
476					ret.push( value );
477				}
478			}
479
480		// Go through every key on the object,
481		} else {
482			for ( i in elems ) {
483				value = callback( elems[ i ], i, arg );
484
485				if ( value != null ) {
486					ret.push( value );
487				}
488			}
489		}
490
491		// Flatten any nested arrays
492		return flat( ret );
493	},
494
495	// A global GUID counter for objects
496	guid: 1,
497
498	// jQuery.support is not used in Core but other projects attach their
499	// properties to it so it needs to exist.
500	support: support
501} );
502
503if ( typeof Symbol === "function" ) {
504	jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];
505}
506
507// Populate the class2type map
508jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
509	function( _i, name ) {
510		class2type[ "[object " + name + "]" ] = name.toLowerCase();
511	} );
512
513function isArrayLike( obj ) {
514
515	// Support: real iOS 8.2 only (not reproducible in simulator)
516	// `in` check used to prevent JIT error (gh-2145)
517	// hasOwn isn't used here due to false negatives
518	// regarding Nodelist length in IE
519	var length = !!obj && "length" in obj && obj.length,
520		type = toType( obj );
521
522	if ( isFunction( obj ) || isWindow( obj ) ) {
523		return false;
524	}
525
526	return type === "array" || length === 0 ||
527		typeof length === "number" && length > 0 && ( length - 1 ) in obj;
528}
529var Sizzle =
530/*!
531 * Sizzle CSS Selector Engine v2.3.6
532 * https://sizzlejs.com/
533 *
534 * Copyright JS Foundation and other contributors
535 * Released under the MIT license
536 * https://js.foundation/
537 *
538 * Date: 2021-02-16
539 */
540( function( window ) {
541var i,
542	support,
543	Expr,
544	getText,
545	isXML,
546	tokenize,
547	compile,
548	select,
549	outermostContext,
550	sortInput,
551	hasDuplicate,
552
553	// Local document vars
554	setDocument,
555	document,
556	docElem,
557	documentIsHTML,
558	rbuggyQSA,
559	rbuggyMatches,
560	matches,
561	contains,
562
563	// Instance-specific data
564	expando = "sizzle" + 1 * new Date(),
565	preferredDoc = window.document,
566	dirruns = 0,
567	done = 0,
568	classCache = createCache(),
569	tokenCache = createCache(),
570	compilerCache = createCache(),
571	nonnativeSelectorCache = createCache(),
572	sortOrder = function( a, b ) {
573		if ( a === b ) {
574			hasDuplicate = true;
575		}
576		return 0;
577	},
578
579	// Instance methods
580	hasOwn = ( {} ).hasOwnProperty,
581	arr = [],
582	pop = arr.pop,
583	pushNative = arr.push,
584	push = arr.push,
585	slice = arr.slice,
586
587	// Use a stripped-down indexOf as it's faster than native
588	// https://jsperf.com/thor-indexof-vs-for/5
589	indexOf = function( list, elem ) {
590		var i = 0,
591			len = list.length;
592		for ( ; i < len; i++ ) {
593			if ( list[ i ] === elem ) {
594				return i;
595			}
596		}
597		return -1;
598	},
599
600	booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|" +
601		"ismap|loop|multiple|open|readonly|required|scoped",
602
603	// Regular expressions
604
605	// http://www.w3.org/TR/css3-selectors/#whitespace
606	whitespace = "[\\x20\\t\\r\\n\\f]",
607
608	// https://www.w3.org/TR/css-syntax-3/#ident-token-diagram
609	identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace +
610		"?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+",
611
612	// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
613	attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
614
615		// Operator (capture 2)
616		"*([*^$|!~]?=)" + whitespace +
617
618		// "Attribute values must be CSS identifiers [capture 5]
619		// or strings [capture 3 or capture 4]"
620		"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" +
621		whitespace + "*\\]",
622
623	pseudos = ":(" + identifier + ")(?:\\((" +
624
625		// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
626		// 1. quoted (capture 3; capture 4 or capture 5)
627		"('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
628
629		// 2. simple (capture 6)
630		"((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
631
632		// 3. anything else (capture 2)
633		".*" +
634		")\\)|)",
635
636	// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
637	rwhitespace = new RegExp( whitespace + "+", "g" ),
638	rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" +
639		whitespace + "+$", "g" ),
640
641	rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
642	rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace +
643		"*" ),
644	rdescend = new RegExp( whitespace + "|>" ),
645
646	rpseudo = new RegExp( pseudos ),
647	ridentifier = new RegExp( "^" + identifier + "$" ),
648
649	matchExpr = {
650		"ID": new RegExp( "^#(" + identifier + ")" ),
651		"CLASS": new RegExp( "^\\.(" + identifier + ")" ),
652		"TAG": new RegExp( "^(" + identifier + "|[*])" ),
653		"ATTR": new RegExp( "^" + attributes ),
654		"PSEUDO": new RegExp( "^" + pseudos ),
655		"CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" +
656			whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" +
657			whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
658		"bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
659
660		// For use in libraries implementing .is()
661		// We use this for POS matching in `select`
662		"needsContext": new RegExp( "^" + whitespace +
663			"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace +
664			"*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
665	},
666
667	rhtml = /HTML$/i,
668	rinputs = /^(?:input|select|textarea|button)$/i,
669	rheader = /^h\d$/i,
670
671	rnative = /^[^{]+\{\s*\[native \w/,
672
673	// Easily-parseable/retrievable ID or TAG or CLASS selectors
674	rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
675
676	rsibling = /[+~]/,
677
678	// CSS escapes
679	// http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
680	runescape = new RegExp( "\\\\[\\da-fA-F]{1,6}" + whitespace + "?|\\\\([^\\r\\n\\f])", "g" ),
681	funescape = function( escape, nonHex ) {
682		var high = "0x" + escape.slice( 1 ) - 0x10000;
683
684		return nonHex ?
685
686			// Strip the backslash prefix from a non-hex escape sequence
687			nonHex :
688
689			// Replace a hexadecimal escape sequence with the encoded Unicode code point
690			// Support: IE <=11+
691			// For values outside the Basic Multilingual Plane (BMP), manually construct a
692			// surrogate pair
693			high < 0 ?
694				String.fromCharCode( high + 0x10000 ) :
695				String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
696	},
697
698	// CSS string/identifier serialization
699	// https://drafts.csswg.org/cssom/#common-serializing-idioms
700	rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,
701	fcssescape = function( ch, asCodePoint ) {
702		if ( asCodePoint ) {
703
704			// U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER
705			if ( ch === "\0" ) {
706				return "\uFFFD";
707			}
708
709			// Control characters and (dependent upon position) numbers get escaped as code points
710			return ch.slice( 0, -1 ) + "\\" +
711				ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " ";
712		}
713
714		// Other potentially-special ASCII characters get backslash-escaped
715		return "\\" + ch;
716	},
717
718	// Used for iframes
719	// See setDocument()
720	// Removing the function wrapper causes a "Permission Denied"
721	// error in IE
722	unloadHandler = function() {
723		setDocument();
724	},
725
726	inDisabledFieldset = addCombinator(
727		function( elem ) {
728			return elem.disabled === true && elem.nodeName.toLowerCase() === "fieldset";
729		},
730		{ dir: "parentNode", next: "legend" }
731	);
732
733// Optimize for push.apply( _, NodeList )
734try {
735	push.apply(
736		( arr = slice.call( preferredDoc.childNodes ) ),
737		preferredDoc.childNodes
738	);
739
740	// Support: Android<4.0
741	// Detect silently failing push.apply
742	// eslint-disable-next-line no-unused-expressions
743	arr[ preferredDoc.childNodes.length ].nodeType;
744} catch ( e ) {
745	push = { apply: arr.length ?
746
747		// Leverage slice if possible
748		function( target, els ) {
749			pushNative.apply( target, slice.call( els ) );
750		} :
751
752		// Support: IE<9
753		// Otherwise append directly
754		function( target, els ) {
755			var j = target.length,
756				i = 0;
757
758			// Can't trust NodeList.length
759			while ( ( target[ j++ ] = els[ i++ ] ) ) {}
760			target.length = j - 1;
761		}
762	};
763}
764
765function Sizzle( selector, context, results, seed ) {
766	var m, i, elem, nid, match, groups, newSelector,
767		newContext = context && context.ownerDocument,
768
769		// nodeType defaults to 9, since context defaults to document
770		nodeType = context ? context.nodeType : 9;
771
772	results = results || [];
773
774	// Return early from calls with invalid selector or context
775	if ( typeof selector !== "string" || !selector ||
776		nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
777
778		return results;
779	}
780
781	// Try to shortcut find operations (as opposed to filters) in HTML documents
782	if ( !seed ) {
783		setDocument( context );
784		context = context || document;
785
786		if ( documentIsHTML ) {
787
788			// If the selector is sufficiently simple, try using a "get*By*" DOM method
789			// (excepting DocumentFragment context, where the methods don't exist)
790			if ( nodeType !== 11 && ( match = rquickExpr.exec( selector ) ) ) {
791
792				// ID selector
793				if ( ( m = match[ 1 ] ) ) {
794
795					// Document context
796					if ( nodeType === 9 ) {
797						if ( ( elem = context.getElementById( m ) ) ) {
798
799							// Support: IE, Opera, Webkit
800							// TODO: identify versions
801							// getElementById can match elements by name instead of ID
802							if ( elem.id === m ) {
803								results.push( elem );
804								return results;
805							}
806						} else {
807							return results;
808						}
809
810					// Element context
811					} else {
812
813						// Support: IE, Opera, Webkit
814						// TODO: identify versions
815						// getElementById can match elements by name instead of ID
816						if ( newContext && ( elem = newContext.getElementById( m ) ) &&
817							contains( context, elem ) &&
818							elem.id === m ) {
819
820							results.push( elem );
821							return results;
822						}
823					}
824
825				// Type selector
826				} else if ( match[ 2 ] ) {
827					push.apply( results, context.getElementsByTagName( selector ) );
828					return results;
829
830				// Class selector
831				} else if ( ( m = match[ 3 ] ) && support.getElementsByClassName &&
832					context.getElementsByClassName ) {
833
834					push.apply( results, context.getElementsByClassName( m ) );
835					return results;
836				}
837			}
838
839			// Take advantage of querySelectorAll
840			if ( support.qsa &&
841				!nonnativeSelectorCache[ selector + " " ] &&
842				( !rbuggyQSA || !rbuggyQSA.test( selector ) ) &&
843
844				// Support: IE 8 only
845				// Exclude object elements
846				( nodeType !== 1 || context.nodeName.toLowerCase() !== "object" ) ) {
847
848				newSelector = selector;
849				newContext = context;
850
851				// qSA considers elements outside a scoping root when evaluating child or
852				// descendant combinators, which is not what we want.
853				// In such cases, we work around the behavior by prefixing every selector in the
854				// list with an ID selector referencing the scope context.
855				// The technique has to be used as well when a leading combinator is used
856				// as such selectors are not recognized by querySelectorAll.
857				// Thanks to Andrew Dupont for this technique.
858				if ( nodeType === 1 &&
859					( rdescend.test( selector ) || rcombinators.test( selector ) ) ) {
860
861					// Expand context for sibling selectors
862					newContext = rsibling.test( selector ) && testContext( context.parentNode ) ||
863						context;
864
865					// We can use :scope instead of the ID hack if the browser
866					// supports it & if we're not changing the context.
867					if ( newContext !== context || !support.scope ) {
868
869						// Capture the context ID, setting it first if necessary
870						if ( ( nid = context.getAttribute( "id" ) ) ) {
871							nid = nid.replace( rcssescape, fcssescape );
872						} else {
873							context.setAttribute( "id", ( nid = expando ) );
874						}
875					}
876
877					// Prefix every selector in the list
878					groups = tokenize( selector );
879					i = groups.length;
880					while ( i-- ) {
881						groups[ i ] = ( nid ? "#" + nid : ":scope" ) + " " +
882							toSelector( groups[ i ] );
883					}
884					newSelector = groups.join( "," );
885				}
886
887				try {
888					push.apply( results,
889						newContext.querySelectorAll( newSelector )
890					);
891					return results;
892				} catch ( qsaError ) {
893					nonnativeSelectorCache( selector, true );
894				} finally {
895					if ( nid === expando ) {
896						context.removeAttribute( "id" );
897					}
898				}
899			}
900		}
901	}
902
903	// All others
904	return select( selector.replace( rtrim, "$1" ), context, results, seed );
905}
906
907/**
908 * Create key-value caches of limited size
909 * @returns {function(string, object)} Returns the Object data after storing it on itself with
910 *	property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
911 *	deleting the oldest entry
912 */
913function createCache() {
914	var keys = [];
915
916	function cache( key, value ) {
917
918		// Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
919		if ( keys.push( key + " " ) > Expr.cacheLength ) {
920
921			// Only keep the most recent entries
922			delete cache[ keys.shift() ];
923		}
924		return ( cache[ key + " " ] = value );
925	}
926	return cache;
927}
928
929/**
930 * Mark a function for special use by Sizzle
931 * @param {Function} fn The function to mark
932 */
933function markFunction( fn ) {
934	fn[ expando ] = true;
935	return fn;
936}
937
938/**
939 * Support testing using an element
940 * @param {Function} fn Passed the created element and returns a boolean result
941 */
942function assert( fn ) {
943	var el = document.createElement( "fieldset" );
944
945	try {
946		return !!fn( el );
947	} catch ( e ) {
948		return false;
949	} finally {
950
951		// Remove from its parent by default
952		if ( el.parentNode ) {
953			el.parentNode.removeChild( el );
954		}
955
956		// release memory in IE
957		el = null;
958	}
959}
960
961/**
962 * Adds the same handler for all of the specified attrs
963 * @param {String} attrs Pipe-separated list of attributes
964 * @param {Function} handler The method that will be applied
965 */
966function addHandle( attrs, handler ) {
967	var arr = attrs.split( "|" ),
968		i = arr.length;
969
970	while ( i-- ) {
971		Expr.attrHandle[ arr[ i ] ] = handler;
972	}
973}
974
975/**
976 * Checks document order of two siblings
977 * @param {Element} a
978 * @param {Element} b
979 * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
980 */
981function siblingCheck( a, b ) {
982	var cur = b && a,
983		diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
984			a.sourceIndex - b.sourceIndex;
985
986	// Use IE sourceIndex if available on both nodes
987	if ( diff ) {
988		return diff;
989	}
990
991	// Check if b follows a
992	if ( cur ) {
993		while ( ( cur = cur.nextSibling ) ) {
994			if ( cur === b ) {
995				return -1;
996			}
997		}
998	}
999
1000	return a ? 1 : -1;
1001}
1002
1003/**
1004 * Returns a function to use in pseudos for input types
1005 * @param {String} type
1006 */
1007function createInputPseudo( type ) {
1008	return function( elem ) {
1009		var name = elem.nodeName.toLowerCase();
1010		return name === "input" && elem.type === type;
1011	};
1012}
1013
1014/**
1015 * Returns a function to use in pseudos for buttons
1016 * @param {String} type
1017 */
1018function createButtonPseudo( type ) {
1019	return function( elem ) {
1020		var name = elem.nodeName.toLowerCase();
1021		return ( name === "input" || name === "button" ) && elem.type === type;
1022	};
1023}
1024
1025/**
1026 * Returns a function to use in pseudos for :enabled/:disabled
1027 * @param {Boolean} disabled true for :disabled; false for :enabled
1028 */
1029function createDisabledPseudo( disabled ) {
1030
1031	// Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable
1032	return function( elem ) {
1033
1034		// Only certain elements can match :enabled or :disabled
1035		// https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled
1036		// https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled
1037		if ( "form" in elem ) {
1038
1039			// Check for inherited disabledness on relevant non-disabled elements:
1040			// * listed form-associated elements in a disabled fieldset
1041			//   https://html.spec.whatwg.org/multipage/forms.html#category-listed
1042			//   https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled
1043			// * option elements in a disabled optgroup
1044			//   https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled
1045			// All such elements have a "form" property.
1046			if ( elem.parentNode && elem.disabled === false ) {
1047
1048				// Option elements defer to a parent optgroup if present
1049				if ( "label" in elem ) {
1050					if ( "label" in elem.parentNode ) {
1051						return elem.parentNode.disabled === disabled;
1052					} else {
1053						return elem.disabled === disabled;
1054					}
1055				}
1056
1057				// Support: IE 6 - 11
1058				// Use the isDisabled shortcut property to check for disabled fieldset ancestors
1059				return elem.isDisabled === disabled ||
1060
1061					// Where there is no isDisabled, check manually
1062					/* jshint -W018 */
1063					elem.isDisabled !== !disabled &&
1064					inDisabledFieldset( elem ) === disabled;
1065			}
1066
1067			return elem.disabled === disabled;
1068
1069		// Try to winnow out elements that can't be disabled before trusting the disabled property.
1070		// Some victims get caught in our net (label, legend, menu, track), but it shouldn't
1071		// even exist on them, let alone have a boolean value.
1072		} else if ( "label" in elem ) {
1073			return elem.disabled === disabled;
1074		}
1075
1076		// Remaining elements are neither :enabled nor :disabled
1077		return false;
1078	};
1079}
1080
1081/**
1082 * Returns a function to use in pseudos for positionals
1083 * @param {Function} fn
1084 */
1085function createPositionalPseudo( fn ) {
1086	return markFunction( function( argument ) {
1087		argument = +argument;
1088		return markFunction( function( seed, matches ) {
1089			var j,
1090				matchIndexes = fn( [], seed.length, argument ),
1091				i = matchIndexes.length;
1092
1093			// Match elements found at the specified indexes
1094			while ( i-- ) {
1095				if ( seed[ ( j = matchIndexes[ i ] ) ] ) {
1096					seed[ j ] = !( matches[ j ] = seed[ j ] );
1097				}
1098			}
1099		} );
1100	} );
1101}
1102
1103/**
1104 * Checks a node for validity as a Sizzle context
1105 * @param {Element|Object=} context
1106 * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
1107 */
1108function testContext( context ) {
1109	return context && typeof context.getElementsByTagName !== "undefined" && context;
1110}
1111
1112// Expose support vars for convenience
1113support = Sizzle.support = {};
1114
1115/**
1116 * Detects XML nodes
1117 * @param {Element|Object} elem An element or a document
1118 * @returns {Boolean} True iff elem is a non-HTML XML node
1119 */
1120isXML = Sizzle.isXML = function( elem ) {
1121	var namespace = elem && elem.namespaceURI,
1122		docElem = elem && ( elem.ownerDocument || elem ).documentElement;
1123
1124	// Support: IE <=8
1125	// Assume HTML when documentElement doesn't yet exist, such as inside loading iframes
1126	// https://bugs.jquery.com/ticket/4833
1127	return !rhtml.test( namespace || docElem && docElem.nodeName || "HTML" );
1128};
1129
1130/**
1131 * Sets document-related variables once based on the current document
1132 * @param {Element|Object} [doc] An element or document object to use to set the document
1133 * @returns {Object} Returns the current document
1134 */
1135setDocument = Sizzle.setDocument = function( node ) {
1136	var hasCompare, subWindow,
1137		doc = node ? node.ownerDocument || node : preferredDoc;
1138
1139	// Return early if doc is invalid or already selected
1140	// Support: IE 11+, Edge 17 - 18+
1141	// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
1142	// two documents; shallow comparisons work.
1143	// eslint-disable-next-line eqeqeq
1144	if ( doc == document || doc.nodeType !== 9 || !doc.documentElement ) {
1145		return document;
1146	}
1147
1148	// Update global variables
1149	document = doc;
1150	docElem = document.documentElement;
1151	documentIsHTML = !isXML( document );
1152
1153	// Support: IE 9 - 11+, Edge 12 - 18+
1154	// Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)
1155	// Support: IE 11+, Edge 17 - 18+
1156	// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
1157	// two documents; shallow comparisons work.
1158	// eslint-disable-next-line eqeqeq
1159	if ( preferredDoc != document &&
1160		( subWindow = document.defaultView ) && subWindow.top !== subWindow ) {
1161
1162		// Support: IE 11, Edge
1163		if ( subWindow.addEventListener ) {
1164			subWindow.addEventListener( "unload", unloadHandler, false );
1165
1166		// Support: IE 9 - 10 only
1167		} else if ( subWindow.attachEvent ) {
1168			subWindow.attachEvent( "onunload", unloadHandler );
1169		}
1170	}
1171
1172	// Support: IE 8 - 11+, Edge 12 - 18+, Chrome <=16 - 25 only, Firefox <=3.6 - 31 only,
1173	// Safari 4 - 5 only, Opera <=11.6 - 12.x only
1174	// IE/Edge & older browsers don't support the :scope pseudo-class.
1175	// Support: Safari 6.0 only
1176	// Safari 6.0 supports :scope but it's an alias of :root there.
1177	support.scope = assert( function( el ) {
1178		docElem.appendChild( el ).appendChild( document.createElement( "div" ) );
1179		return typeof el.querySelectorAll !== "undefined" &&
1180			!el.querySelectorAll( ":scope fieldset div" ).length;
1181	} );
1182
1183	/* Attributes
1184	---------------------------------------------------------------------- */
1185
1186	// Support: IE<8
1187	// Verify that getAttribute really returns attributes and not properties
1188	// (excepting IE8 booleans)
1189	support.attributes = assert( function( el ) {
1190		el.className = "i";
1191		return !el.getAttribute( "className" );
1192	} );
1193
1194	/* getElement(s)By*
1195	---------------------------------------------------------------------- */
1196
1197	// Check if getElementsByTagName("*") returns only elements
1198	support.getElementsByTagName = assert( function( el ) {
1199		el.appendChild( document.createComment( "" ) );
1200		return !el.getElementsByTagName( "*" ).length;
1201	} );
1202
1203	// Support: IE<9
1204	support.getElementsByClassName = rnative.test( document.getElementsByClassName );
1205
1206	// Support: IE<10
1207	// Check if getElementById returns elements by name
1208	// The broken getElementById methods don't pick up programmatically-set names,
1209	// so use a roundabout getElementsByName test
1210	support.getById = assert( function( el ) {
1211		docElem.appendChild( el ).id = expando;
1212		return !document.getElementsByName || !document.getElementsByName( expando ).length;
1213	} );
1214
1215	// ID filter and find
1216	if ( support.getById ) {
1217		Expr.filter[ "ID" ] = function( id ) {
1218			var attrId = id.replace( runescape, funescape );
1219			return function( elem ) {
1220				return elem.getAttribute( "id" ) === attrId;
1221			};
1222		};
1223		Expr.find[ "ID" ] = function( id, context ) {
1224			if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
1225				var elem = context.getElementById( id );
1226				return elem ? [ elem ] : [];
1227			}
1228		};
1229	} else {
1230		Expr.filter[ "ID" ] =  function( id ) {
1231			var attrId = id.replace( runescape, funescape );
1232			return function( elem ) {
1233				var node = typeof elem.getAttributeNode !== "undefined" &&
1234					elem.getAttributeNode( "id" );
1235				return node && node.value === attrId;
1236			};
1237		};
1238
1239		// Support: IE 6 - 7 only
1240		// getElementById is not reliable as a find shortcut
1241		Expr.find[ "ID" ] = function( id, context ) {
1242			if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
1243				var node, i, elems,
1244					elem = context.getElementById( id );
1245
1246				if ( elem ) {
1247
1248					// Verify the id attribute
1249					node = elem.getAttributeNode( "id" );
1250					if ( node && node.value === id ) {
1251						return [ elem ];
1252					}
1253
1254					// Fall back on getElementsByName
1255					elems = context.getElementsByName( id );
1256					i = 0;
1257					while ( ( elem = elems[ i++ ] ) ) {
1258						node = elem.getAttributeNode( "id" );
1259						if ( node && node.value === id ) {
1260							return [ elem ];
1261						}
1262					}
1263				}
1264
1265				return [];
1266			}
1267		};
1268	}
1269
1270	// Tag
1271	Expr.find[ "TAG" ] = support.getElementsByTagName ?
1272		function( tag, context ) {
1273			if ( typeof context.getElementsByTagName !== "undefined" ) {
1274				return context.getElementsByTagName( tag );
1275
1276			// DocumentFragment nodes don't have gEBTN
1277			} else if ( support.qsa ) {
1278				return context.querySelectorAll( tag );
1279			}
1280		} :
1281
1282		function( tag, context ) {
1283			var elem,
1284				tmp = [],
1285				i = 0,
1286
1287				// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
1288				results = context.getElementsByTagName( tag );
1289
1290			// Filter out possible comments
1291			if ( tag === "*" ) {
1292				while ( ( elem = results[ i++ ] ) ) {
1293					if ( elem.nodeType === 1 ) {
1294						tmp.push( elem );
1295					}
1296				}
1297
1298				return tmp;
1299			}
1300			return results;
1301		};
1302
1303	// Class
1304	Expr.find[ "CLASS" ] = support.getElementsByClassName && function( className, context ) {
1305		if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) {
1306			return context.getElementsByClassName( className );
1307		}
1308	};
1309
1310	/* QSA/matchesSelector
1311	---------------------------------------------------------------------- */
1312
1313	// QSA and matchesSelector support
1314
1315	// matchesSelector(:active) reports false when true (IE9/Opera 11.5)
1316	rbuggyMatches = [];
1317
1318	// qSa(:focus) reports false when true (Chrome 21)
1319	// We allow this because of a bug in IE8/9 that throws an error
1320	// whenever `document.activeElement` is accessed on an iframe
1321	// So, we allow :focus to pass through QSA all the time to avoid the IE error
1322	// See https://bugs.jquery.com/ticket/13378
1323	rbuggyQSA = [];
1324
1325	if ( ( support.qsa = rnative.test( document.querySelectorAll ) ) ) {
1326
1327		// Build QSA regex
1328		// Regex strategy adopted from Diego Perini
1329		assert( function( el ) {
1330
1331			var input;
1332
1333			// Select is set to empty string on purpose
1334			// This is to test IE's treatment of not explicitly
1335			// setting a boolean content attribute,
1336			// since its presence should be enough
1337			// https://bugs.jquery.com/ticket/12359
1338			docElem.appendChild( el ).innerHTML = "<a id='" + expando + "'></a>" +
1339				"<select id='" + expando + "-\r\\' msallowcapture=''>" +
1340				"<option selected=''></option></select>";
1341
1342			// Support: IE8, Opera 11-12.16
1343			// Nothing should be selected when empty strings follow ^= or $= or *=
1344			// The test attribute must be unknown in Opera but "safe" for WinRT
1345			// https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
1346			if ( el.querySelectorAll( "[msallowcapture^='']" ).length ) {
1347				rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
1348			}
1349
1350			// Support: IE8
1351			// Boolean attributes and "value" are not treated correctly
1352			if ( !el.querySelectorAll( "[selected]" ).length ) {
1353				rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
1354			}
1355
1356			// Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
1357			if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
1358				rbuggyQSA.push( "~=" );
1359			}
1360
1361			// Support: IE 11+, Edge 15 - 18+
1362			// IE 11/Edge don't find elements on a `[name='']` query in some cases.
1363			// Adding a temporary attribute to the document before the selection works
1364			// around the issue.
1365			// Interestingly, IE 10 & older don't seem to have the issue.
1366			input = document.createElement( "input" );
1367			input.setAttribute( "name", "" );
1368			el.appendChild( input );
1369			if ( !el.querySelectorAll( "[name='']" ).length ) {
1370				rbuggyQSA.push( "\\[" + whitespace + "*name" + whitespace + "*=" +
1371					whitespace + "*(?:''|\"\")" );
1372			}
1373
1374			// Webkit/Opera - :checked should return selected option elements
1375			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
1376			// IE8 throws error here and will not see later tests
1377			if ( !el.querySelectorAll( ":checked" ).length ) {
1378				rbuggyQSA.push( ":checked" );
1379			}
1380
1381			// Support: Safari 8+, iOS 8+
1382			// https://bugs.webkit.org/show_bug.cgi?id=136851
1383			// In-page `selector#id sibling-combinator selector` fails
1384			if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) {
1385				rbuggyQSA.push( ".#.+[+~]" );
1386			}
1387
1388			// Support: Firefox <=3.6 - 5 only
1389			// Old Firefox doesn't throw on a badly-escaped identifier.
1390			el.querySelectorAll( "\\\f" );
1391			rbuggyQSA.push( "[\\r\\n\\f]" );
1392		} );
1393
1394		assert( function( el ) {
1395			el.innerHTML = "<a href='' disabled='disabled'></a>" +
1396				"<select disabled='disabled'><option/></select>";
1397
1398			// Support: Windows 8 Native Apps
1399			// The type and name attributes are restricted during .innerHTML assignment
1400			var input = document.createElement( "input" );
1401			input.setAttribute( "type", "hidden" );
1402			el.appendChild( input ).setAttribute( "name", "D" );
1403
1404			// Support: IE8
1405			// Enforce case-sensitivity of name attribute
1406			if ( el.querySelectorAll( "[name=d]" ).length ) {
1407				rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
1408			}
1409
1410			// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
1411			// IE8 throws error here and will not see later tests
1412			if ( el.querySelectorAll( ":enabled" ).length !== 2 ) {
1413				rbuggyQSA.push( ":enabled", ":disabled" );
1414			}
1415
1416			// Support: IE9-11+
1417			// IE's :disabled selector does not pick up the children of disabled fieldsets
1418			docElem.appendChild( el ).disabled = true;
1419			if ( el.querySelectorAll( ":disabled" ).length !== 2 ) {
1420				rbuggyQSA.push( ":enabled", ":disabled" );
1421			}
1422
1423			// Support: Opera 10 - 11 only
1424			// Opera 10-11 does not throw on post-comma invalid pseudos
1425			el.querySelectorAll( "*,:x" );
1426			rbuggyQSA.push( ",.*:" );
1427		} );
1428	}
1429
1430	if ( ( support.matchesSelector = rnative.test( ( matches = docElem.matches ||
1431		docElem.webkitMatchesSelector ||
1432		docElem.mozMatchesSelector ||
1433		docElem.oMatchesSelector ||
1434		docElem.msMatchesSelector ) ) ) ) {
1435
1436		assert( function( el ) {
1437
1438			// Check to see if it's possible to do matchesSelector
1439			// on a disconnected node (IE 9)
1440			support.disconnectedMatch = matches.call( el, "*" );
1441
1442			// This should fail with an exception
1443			// Gecko does not error, returns false instead
1444			matches.call( el, "[s!='']:x" );
1445			rbuggyMatches.push( "!=", pseudos );
1446		} );
1447	}
1448
1449	rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( "|" ) );
1450	rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join( "|" ) );
1451
1452	/* Contains
1453	---------------------------------------------------------------------- */
1454	hasCompare = rnative.test( docElem.compareDocumentPosition );
1455
1456	// Element contains another
1457	// Purposefully self-exclusive
1458	// As in, an element does not contain itself
1459	contains = hasCompare || rnative.test( docElem.contains ) ?
1460		function( a, b ) {
1461			var adown = a.nodeType === 9 ? a.documentElement : a,
1462				bup = b && b.parentNode;
1463			return a === bup || !!( bup && bup.nodeType === 1 && (
1464				adown.contains ?
1465					adown.contains( bup ) :
1466					a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
1467			) );
1468		} :
1469		function( a, b ) {
1470			if ( b ) {
1471				while ( ( b = b.parentNode ) ) {
1472					if ( b === a ) {
1473						return true;
1474					}
1475				}
1476			}
1477			return false;
1478		};
1479
1480	/* Sorting
1481	---------------------------------------------------------------------- */
1482
1483	// Document order sorting
1484	sortOrder = hasCompare ?
1485	function( a, b ) {
1486
1487		// Flag for duplicate removal
1488		if ( a === b ) {
1489			hasDuplicate = true;
1490			return 0;
1491		}
1492
1493		// Sort on method existence if only one input has compareDocumentPosition
1494		var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
1495		if ( compare ) {
1496			return compare;
1497		}
1498
1499		// Calculate position if both inputs belong to the same document
1500		// Support: IE 11+, Edge 17 - 18+
1501		// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
1502		// two documents; shallow comparisons work.
1503		// eslint-disable-next-line eqeqeq
1504		compare = ( a.ownerDocument || a ) == ( b.ownerDocument || b ) ?
1505			a.compareDocumentPosition( b ) :
1506
1507			// Otherwise we know they are disconnected
1508			1;
1509
1510		// Disconnected nodes
1511		if ( compare & 1 ||
1512			( !support.sortDetached && b.compareDocumentPosition( a ) === compare ) ) {
1513
1514			// Choose the first element that is related to our preferred document
1515			// Support: IE 11+, Edge 17 - 18+
1516			// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
1517			// two documents; shallow comparisons work.
1518			// eslint-disable-next-line eqeqeq
1519			if ( a == document || a.ownerDocument == preferredDoc &&
1520				contains( preferredDoc, a ) ) {
1521				return -1;
1522			}
1523
1524			// Support: IE 11+, Edge 17 - 18+
1525			// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
1526			// two documents; shallow comparisons work.
1527			// eslint-disable-next-line eqeqeq
1528			if ( b == document || b.ownerDocument == preferredDoc &&
1529				contains( preferredDoc, b ) ) {
1530				return 1;
1531			}
1532
1533			// Maintain original order
1534			return sortInput ?
1535				( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
1536				0;
1537		}
1538
1539		return compare & 4 ? -1 : 1;
1540	} :
1541	function( a, b ) {
1542
1543		// Exit early if the nodes are identical
1544		if ( a === b ) {
1545			hasDuplicate = true;
1546			return 0;
1547		}
1548
1549		var cur,
1550			i = 0,
1551			aup = a.parentNode,
1552			bup = b.parentNode,
1553			ap = [ a ],
1554			bp = [ b ];
1555
1556		// Parentless nodes are either documents or disconnected
1557		if ( !aup || !bup ) {
1558
1559			// Support: IE 11+, Edge 17 - 18+
1560			// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
1561			// two documents; shallow comparisons work.
1562			/* eslint-disable eqeqeq */
1563			return a == document ? -1 :
1564				b == document ? 1 :
1565				/* eslint-enable eqeqeq */
1566				aup ? -1 :
1567				bup ? 1 :
1568				sortInput ?
1569				( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
1570				0;
1571
1572		// If the nodes are siblings, we can do a quick check
1573		} else if ( aup === bup ) {
1574			return siblingCheck( a, b );
1575		}
1576
1577		// Otherwise we need full lists of their ancestors for comparison
1578		cur = a;
1579		while ( ( cur = cur.parentNode ) ) {
1580			ap.unshift( cur );
1581		}
1582		cur = b;
1583		while ( ( cur = cur.parentNode ) ) {
1584			bp.unshift( cur );
1585		}
1586
1587		// Walk down the tree looking for a discrepancy
1588		while ( ap[ i ] === bp[ i ] ) {
1589			i++;
1590		}
1591
1592		return i ?
1593
1594			// Do a sibling check if the nodes have a common ancestor
1595			siblingCheck( ap[ i ], bp[ i ] ) :
1596
1597			// Otherwise nodes in our document sort first
1598			// Support: IE 11+, Edge 17 - 18+
1599			// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
1600			// two documents; shallow comparisons work.
1601			/* eslint-disable eqeqeq */
1602			ap[ i ] == preferredDoc ? -1 :
1603			bp[ i ] == preferredDoc ? 1 :
1604			/* eslint-enable eqeqeq */
1605			0;
1606	};
1607
1608	return document;
1609};
1610
1611Sizzle.matches = function( expr, elements ) {
1612	return Sizzle( expr, null, null, elements );
1613};
1614
1615Sizzle.matchesSelector = function( elem, expr ) {
1616	setDocument( elem );
1617
1618	if ( support.matchesSelector && documentIsHTML &&
1619		!nonnativeSelectorCache[ expr + " " ] &&
1620		( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
1621		( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {
1622
1623		try {
1624			var ret = matches.call( elem, expr );
1625
1626			// IE 9's matchesSelector returns false on disconnected nodes
1627			if ( ret || support.disconnectedMatch ||
1628
1629				// As well, disconnected nodes are said to be in a document
1630				// fragment in IE 9
1631				elem.document && elem.document.nodeType !== 11 ) {
1632				return ret;
1633			}
1634		} catch ( e ) {
1635			nonnativeSelectorCache( expr, true );
1636		}
1637	}
1638
1639	return Sizzle( expr, document, null, [ elem ] ).length > 0;
1640};
1641
1642Sizzle.contains = function( context, elem ) {
1643
1644	// Set document vars if needed
1645	// Support: IE 11+, Edge 17 - 18+
1646	// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
1647	// two documents; shallow comparisons work.
1648	// eslint-disable-next-line eqeqeq
1649	if ( ( context.ownerDocument || context ) != document ) {
1650		setDocument( context );
1651	}
1652	return contains( context, elem );
1653};
1654
1655Sizzle.attr = function( elem, name ) {
1656
1657	// Set document vars if needed
1658	// Support: IE 11+, Edge 17 - 18+
1659	// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
1660	// two documents; shallow comparisons work.
1661	// eslint-disable-next-line eqeqeq
1662	if ( ( elem.ownerDocument || elem ) != document ) {
1663		setDocument( elem );
1664	}
1665
1666	var fn = Expr.attrHandle[ name.toLowerCase() ],
1667
1668		// Don't get fooled by Object.prototype properties (jQuery #13807)
1669		val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
1670			fn( elem, name, !documentIsHTML ) :
1671			undefined;
1672
1673	return val !== undefined ?
1674		val :
1675		support.attributes || !documentIsHTML ?
1676			elem.getAttribute( name ) :
1677			( val = elem.getAttributeNode( name ) ) && val.specified ?
1678				val.value :
1679				null;
1680};
1681
1682Sizzle.escape = function( sel ) {
1683	return ( sel + "" ).replace( rcssescape, fcssescape );
1684};
1685
1686Sizzle.error = function( msg ) {
1687	throw new Error( "Syntax error, unrecognized expression: " + msg );
1688};
1689
1690/**
1691 * Document sorting and removing duplicates
1692 * @param {ArrayLike} results
1693 */
1694Sizzle.uniqueSort = function( results ) {
1695	var elem,
1696		duplicates = [],
1697		j = 0,
1698		i = 0;
1699
1700	// Unless we *know* we can detect duplicates, assume their presence
1701	hasDuplicate = !support.detectDuplicates;
1702	sortInput = !support.sortStable && results.slice( 0 );
1703	results.sort( sortOrder );
1704
1705	if ( hasDuplicate ) {
1706		while ( ( elem = results[ i++ ] ) ) {
1707			if ( elem === results[ i ] ) {
1708				j = duplicates.push( i );
1709			}
1710		}
1711		while ( j-- ) {
1712			results.splice( duplicates[ j ], 1 );
1713		}
1714	}
1715
1716	// Clear input after sorting to release objects
1717	// See https://github.com/jquery/sizzle/pull/225
1718	sortInput = null;
1719
1720	return results;
1721};
1722
1723/**
1724 * Utility function for retrieving the text value of an array of DOM nodes
1725 * @param {Array|Element} elem
1726 */
1727getText = Sizzle.getText = function( elem ) {
1728	var node,
1729		ret = "",
1730		i = 0,
1731		nodeType = elem.nodeType;
1732
1733	if ( !nodeType ) {
1734
1735		// If no nodeType, this is expected to be an array
1736		while ( ( node = elem[ i++ ] ) ) {
1737
1738			// Do not traverse comment nodes
1739			ret += getText( node );
1740		}
1741	} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
1742
1743		// Use textContent for elements
1744		// innerText usage removed for consistency of new lines (jQuery #11153)
1745		if ( typeof elem.textContent === "string" ) {
1746			return elem.textContent;
1747		} else {
1748
1749			// Traverse its children
1750			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
1751				ret += getText( elem );
1752			}
1753		}
1754	} else if ( nodeType === 3 || nodeType === 4 ) {
1755		return elem.nodeValue;
1756	}
1757
1758	// Do not include comment or processing instruction nodes
1759
1760	return ret;
1761};
1762
1763Expr = Sizzle.selectors = {
1764
1765	// Can be adjusted by the user
1766	cacheLength: 50,
1767
1768	createPseudo: markFunction,
1769
1770	match: matchExpr,
1771
1772	attrHandle: {},
1773
1774	find: {},
1775
1776	relative: {
1777		">": { dir: "parentNode", first: true },
1778		" ": { dir: "parentNode" },
1779		"+": { dir: "previousSibling", first: true },
1780		"~": { dir: "previousSibling" }
1781	},
1782
1783	preFilter: {
1784		"ATTR": function( match ) {
1785			match[ 1 ] = match[ 1 ].replace( runescape, funescape );
1786
1787			// Move the given value to match[3] whether quoted or unquoted
1788			match[ 3 ] = ( match[ 3 ] || match[ 4 ] ||
1789				match[ 5 ] || "" ).replace( runescape, funescape );
1790
1791			if ( match[ 2 ] === "~=" ) {
1792				match[ 3 ] = " " + match[ 3 ] + " ";
1793			}
1794
1795			return match.slice( 0, 4 );
1796		},
1797
1798		"CHILD": function( match ) {
1799
1800			/* matches from matchExpr["CHILD"]
1801				1 type (only|nth|...)
1802				2 what (child|of-type)
1803				3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
1804				4 xn-component of xn+y argument ([+-]?\d*n|)
1805				5 sign of xn-component
1806				6 x of xn-component
1807				7 sign of y-component
1808				8 y of y-component
1809			*/
1810			match[ 1 ] = match[ 1 ].toLowerCase();
1811
1812			if ( match[ 1 ].slice( 0, 3 ) === "nth" ) {
1813
1814				// nth-* requires argument
1815				if ( !match[ 3 ] ) {
1816					Sizzle.error( match[ 0 ] );
1817				}
1818
1819				// numeric x and y parameters for Expr.filter.CHILD
1820				// remember that false/true cast respectively to 0/1
1821				match[ 4 ] = +( match[ 4 ] ?
1822					match[ 5 ] + ( match[ 6 ] || 1 ) :
1823					2 * ( match[ 3 ] === "even" || match[ 3 ] === "odd" ) );
1824				match[ 5 ] = +( ( match[ 7 ] + match[ 8 ] ) || match[ 3 ] === "odd" );
1825
1826				// other types prohibit arguments
1827			} else if ( match[ 3 ] ) {
1828				Sizzle.error( match[ 0 ] );
1829			}
1830
1831			return match;
1832		},
1833
1834		"PSEUDO": function( match ) {
1835			var excess,
1836				unquoted = !match[ 6 ] && match[ 2 ];
1837
1838			if ( matchExpr[ "CHILD" ].test( match[ 0 ] ) ) {
1839				return null;
1840			}
1841
1842			// Accept quoted arguments as-is
1843			if ( match[ 3 ] ) {
1844				match[ 2 ] = match[ 4 ] || match[ 5 ] || "";
1845
1846			// Strip excess characters from unquoted arguments
1847			} else if ( unquoted && rpseudo.test( unquoted ) &&
1848
1849				// Get excess from tokenize (recursively)
1850				( excess = tokenize( unquoted, true ) ) &&
1851
1852				// advance to the next closing parenthesis
1853				( excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length ) ) {
1854
1855				// excess is a negative index
1856				match[ 0 ] = match[ 0 ].slice( 0, excess );
1857				match[ 2 ] = unquoted.slice( 0, excess );
1858			}
1859
1860			// Return only captures needed by the pseudo filter method (type and argument)
1861			return match.slice( 0, 3 );
1862		}
1863	},
1864
1865	filter: {
1866
1867		"TAG": function( nodeNameSelector ) {
1868			var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
1869			return nodeNameSelector === "*" ?
1870				function() {
1871					return true;
1872				} :
1873				function( elem ) {
1874					return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
1875				};
1876		},
1877
1878		"CLASS": function( className ) {
1879			var pattern = classCache[ className + " " ];
1880
1881			return pattern ||
1882				( pattern = new RegExp( "(^|" + whitespace +
1883					")" + className + "(" + whitespace + "|$)" ) ) && classCache(
1884						className, function( elem ) {
1885							return pattern.test(
1886								typeof elem.className === "string" && elem.className ||
1887								typeof elem.getAttribute !== "undefined" &&
1888									elem.getAttribute( "class" ) ||
1889								""
1890							);
1891				} );
1892		},
1893
1894		"ATTR": function( name, operator, check ) {
1895			return function( elem ) {
1896				var result = Sizzle.attr( elem, name );
1897
1898				if ( result == null ) {
1899					return operator === "!=";
1900				}
1901				if ( !operator ) {
1902					return true;
1903				}
1904
1905				result += "";
1906
1907				/* eslint-disable max-len */
1908
1909				return operator === "=" ? result === check :
1910					operator === "!=" ? result !== check :
1911					operator === "^=" ? check && result.indexOf( check ) === 0 :
1912					operator === "*=" ? check && result.indexOf( check ) > -1 :
1913					operator === "$=" ? check && result.slice( -check.length ) === check :
1914					operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 :
1915					operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
1916					false;
1917				/* eslint-enable max-len */
1918
1919			};
1920		},
1921
1922		"CHILD": function( type, what, _argument, first, last ) {
1923			var simple = type.slice( 0, 3 ) !== "nth",
1924				forward = type.slice( -4 ) !== "last",
1925				ofType = what === "of-type";
1926
1927			return first === 1 && last === 0 ?
1928
1929				// Shortcut for :nth-*(n)
1930				function( elem ) {
1931					return !!elem.parentNode;
1932				} :
1933
1934				function( elem, _context, xml ) {
1935					var cache, uniqueCache, outerCache, node, nodeIndex, start,
1936						dir = simple !== forward ? "nextSibling" : "previousSibling",
1937						parent = elem.parentNode,
1938						name = ofType && elem.nodeName.toLowerCase(),
1939						useCache = !xml && !ofType,
1940						diff = false;
1941
1942					if ( parent ) {
1943
1944						// :(first|last|only)-(child|of-type)
1945						if ( simple ) {
1946							while ( dir ) {
1947								node = elem;
1948								while ( ( node = node[ dir ] ) ) {
1949									if ( ofType ?
1950										node.nodeName.toLowerCase() === name :
1951										node.nodeType === 1 ) {
1952
1953										return false;
1954									}
1955								}
1956
1957								// Reverse direction for :only-* (if we haven't yet done so)
1958								start = dir = type === "only" && !start && "nextSibling";
1959							}
1960							return true;
1961						}
1962
1963						start = [ forward ? parent.firstChild : parent.lastChild ];
1964
1965						// non-xml :nth-child(...) stores cache data on `parent`
1966						if ( forward && useCache ) {
1967
1968							// Seek `elem` from a previously-cached index
1969
1970							// ...in a gzip-friendly way
1971							node = parent;
1972							outerCache = node[ expando ] || ( node[ expando ] = {} );
1973
1974							// Support: IE <9 only
1975							// Defend against cloned attroperties (jQuery gh-1709)
1976							uniqueCache = outerCache[ node.uniqueID ] ||
1977								( outerCache[ node.uniqueID ] = {} );
1978
1979							cache = uniqueCache[ type ] || [];
1980							nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
1981							diff = nodeIndex && cache[ 2 ];
1982							node = nodeIndex && parent.childNodes[ nodeIndex ];
1983
1984							while ( ( node = ++nodeIndex && node && node[ dir ] ||
1985
1986								// Fallback to seeking `elem` from the start
1987								( diff = nodeIndex = 0 ) || start.pop() ) ) {
1988
1989								// When found, cache indexes on `parent` and break
1990								if ( node.nodeType === 1 && ++diff && node === elem ) {
1991									uniqueCache[ type ] = [ dirruns, nodeIndex, diff ];
1992									break;
1993								}
1994							}
1995
1996						} else {
1997
1998							// Use previously-cached element index if available
1999							if ( useCache ) {
2000
2001								// ...in a gzip-friendly way
2002								node = elem;
2003								outerCache = node[ expando ] || ( node[ expando ] = {} );
2004
2005								// Support: IE <9 only
2006								// Defend against cloned attroperties (jQuery gh-1709)
2007								uniqueCache = outerCache[ node.uniqueID ] ||
2008									( outerCache[ node.uniqueID ] = {} );
2009
2010								cache = uniqueCache[ type ] || [];
2011								nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
2012								diff = nodeIndex;
2013							}
2014
2015							// xml :nth-child(...)
2016							// or :nth-last-child(...) or :nth(-last)?-of-type(...)
2017							if ( diff === false ) {
2018
2019								// Use the same loop as above to seek `elem` from the start
2020								while ( ( node = ++nodeIndex && node && node[ dir ] ||
2021									( diff = nodeIndex = 0 ) || start.pop() ) ) {
2022
2023									if ( ( ofType ?
2024										node.nodeName.toLowerCase() === name :
2025										node.nodeType === 1 ) &&
2026										++diff ) {
2027
2028										// Cache the index of each encountered element
2029										if ( useCache ) {
2030											outerCache = node[ expando ] ||
2031												( node[ expando ] = {} );
2032
2033											// Support: IE <9 only
2034											// Defend against cloned attroperties (jQuery gh-1709)
2035											uniqueCache = outerCache[ node.uniqueID ] ||
2036												( outerCache[ node.uniqueID ] = {} );
2037
2038											uniqueCache[ type ] = [ dirruns, diff ];
2039										}
2040
2041										if ( node === elem ) {
2042											break;
2043										}
2044									}
2045								}
2046							}
2047						}
2048
2049						// Incorporate the offset, then check against cycle size
2050						diff -= last;
2051						return diff === first || ( diff % first === 0 && diff / first >= 0 );
2052					}
2053				};
2054		},
2055
2056		"PSEUDO": function( pseudo, argument ) {
2057
2058			// pseudo-class names are case-insensitive
2059			// http://www.w3.org/TR/selectors/#pseudo-classes
2060			// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
2061			// Remember that setFilters inherits from pseudos
2062			var args,
2063				fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
2064					Sizzle.error( "unsupported pseudo: " + pseudo );
2065
2066			// The user may use createPseudo to indicate that
2067			// arguments are needed to create the filter function
2068			// just as Sizzle does
2069			if ( fn[ expando ] ) {
2070				return fn( argument );
2071			}
2072
2073			// But maintain support for old signatures
2074			if ( fn.length > 1 ) {
2075				args = [ pseudo, pseudo, "", argument ];
2076				return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
2077					markFunction( function( seed, matches ) {
2078						var idx,
2079							matched = fn( seed, argument ),
2080							i = matched.length;
2081						while ( i-- ) {
2082							idx = indexOf( seed, matched[ i ] );
2083							seed[ idx ] = !( matches[ idx ] = matched[ i ] );
2084						}
2085					} ) :
2086					function( elem ) {
2087						return fn( elem, 0, args );
2088					};
2089			}
2090
2091			return fn;
2092		}
2093	},
2094
2095	pseudos: {
2096
2097		// Potentially complex pseudos
2098		"not": markFunction( function( selector ) {
2099
2100			// Trim the selector passed to compile
2101			// to avoid treating leading and trailing
2102			// spaces as combinators
2103			var input = [],
2104				results = [],
2105				matcher = compile( selector.replace( rtrim, "$1" ) );
2106
2107			return matcher[ expando ] ?
2108				markFunction( function( seed, matches, _context, xml ) {
2109					var elem,
2110						unmatched = matcher( seed, null, xml, [] ),
2111						i = seed.length;
2112
2113					// Match elements unmatched by `matcher`
2114					while ( i-- ) {
2115						if ( ( elem = unmatched[ i ] ) ) {
2116							seed[ i ] = !( matches[ i ] = elem );
2117						}
2118					}
2119				} ) :
2120				function( elem, _context, xml ) {
2121					input[ 0 ] = elem;
2122					matcher( input, null, xml, results );
2123
2124					// Don't keep the element (issue #299)
2125					input[ 0 ] = null;
2126					return !results.pop();
2127				};
2128		} ),
2129
2130		"has": markFunction( function( selector ) {
2131			return function( elem ) {
2132				return Sizzle( selector, elem ).length > 0;
2133			};
2134		} ),
2135
2136		"contains": markFunction( function( text ) {
2137			text = text.replace( runescape, funescape );
2138			return function( elem ) {
2139				return ( elem.textContent || getText( elem ) ).indexOf( text ) > -1;
2140			};
2141		} ),
2142
2143		// "Whether an element is represented by a :lang() selector
2144		// is based solely on the element's language value
2145		// being equal to the identifier C,
2146		// or beginning with the identifier C immediately followed by "-".
2147		// The matching of C against the element's language value is performed case-insensitively.
2148		// The identifier C does not have to be a valid language name."
2149		// http://www.w3.org/TR/selectors/#lang-pseudo
2150		"lang": markFunction( function( lang ) {
2151
2152			// lang value must be a valid identifier
2153			if ( !ridentifier.test( lang || "" ) ) {
2154				Sizzle.error( "unsupported lang: " + lang );
2155			}
2156			lang = lang.replace( runescape, funescape ).toLowerCase();
2157			return function( elem ) {
2158				var elemLang;
2159				do {
2160					if ( ( elemLang = documentIsHTML ?
2161						elem.lang :
2162						elem.getAttribute( "xml:lang" ) || elem.getAttribute( "lang" ) ) ) {
2163
2164						elemLang = elemLang.toLowerCase();
2165						return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
2166					}
2167				} while ( ( elem = elem.parentNode ) && elem.nodeType === 1 );
2168				return false;
2169			};
2170		} ),
2171
2172		// Miscellaneous
2173		"target": function( elem ) {
2174			var hash = window.location && window.location.hash;
2175			return hash && hash.slice( 1 ) === elem.id;
2176		},
2177
2178		"root": function( elem ) {
2179			return elem === docElem;
2180		},
2181
2182		"focus": function( elem ) {
2183			return elem === document.activeElement &&
2184				( !document.hasFocus || document.hasFocus() ) &&
2185				!!( elem.type || elem.href || ~elem.tabIndex );
2186		},
2187
2188		// Boolean properties
2189		"enabled": createDisabledPseudo( false ),
2190		"disabled": createDisabledPseudo( true ),
2191
2192		"checked": function( elem ) {
2193
2194			// In CSS3, :checked should return both checked and selected elements
2195			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
2196			var nodeName = elem.nodeName.toLowerCase();
2197			return ( nodeName === "input" && !!elem.checked ) ||
2198				( nodeName === "option" && !!elem.selected );
2199		},
2200
2201		"selected": function( elem ) {
2202
2203			// Accessing this property makes selected-by-default
2204			// options in Safari work properly
2205			if ( elem.parentNode ) {
2206				// eslint-disable-next-line no-unused-expressions
2207				elem.parentNode.selectedIndex;
2208			}
2209
2210			return elem.selected === true;
2211		},
2212
2213		// Contents
2214		"empty": function( elem ) {
2215
2216			// http://www.w3.org/TR/selectors/#empty-pseudo
2217			// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
2218			//   but not by others (comment: 8; processing instruction: 7; etc.)
2219			// nodeType < 6 works because attributes (2) do not appear as children
2220			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
2221				if ( elem.nodeType < 6 ) {
2222					return false;
2223				}
2224			}
2225			return true;
2226		},
2227
2228		"parent": function( elem ) {
2229			return !Expr.pseudos[ "empty" ]( elem );
2230		},
2231
2232		// Element/input types
2233		"header": function( elem ) {
2234			return rheader.test( elem.nodeName );
2235		},
2236
2237		"input": function( elem ) {
2238			return rinputs.test( elem.nodeName );
2239		},
2240
2241		"button": function( elem ) {
2242			var name = elem.nodeName.toLowerCase();
2243			return name === "input" && elem.type === "button" || name === "button";
2244		},
2245
2246		"text": function( elem ) {
2247			var attr;
2248			return elem.nodeName.toLowerCase() === "input" &&
2249				elem.type === "text" &&
2250
2251				// Support: IE<8
2252				// New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
2253				( ( attr = elem.getAttribute( "type" ) ) == null ||
2254					attr.toLowerCase() === "text" );
2255		},
2256
2257		// Position-in-collection
2258		"first": createPositionalPseudo( function() {
2259			return [ 0 ];
2260		} ),
2261
2262		"last": createPositionalPseudo( function( _matchIndexes, length ) {
2263			return [ length - 1 ];
2264		} ),
2265
2266		"eq": createPositionalPseudo( function( _matchIndexes, length, argument ) {
2267			return [ argument < 0 ? argument + length : argument ];
2268		} ),
2269
2270		"even": createPositionalPseudo( function( matchIndexes, length ) {
2271			var i = 0;
2272			for ( ; i < length; i += 2 ) {
2273				matchIndexes.push( i );
2274			}
2275			return matchIndexes;
2276		} ),
2277
2278		"odd": createPositionalPseudo( function( matchIndexes, length ) {
2279			var i = 1;
2280			for ( ; i < length; i += 2 ) {
2281				matchIndexes.push( i );
2282			}
2283			return matchIndexes;
2284		} ),
2285
2286		"lt": createPositionalPseudo( function( matchIndexes, length, argument ) {
2287			var i = argument < 0 ?
2288				argument + length :
2289				argument > length ?
2290					length :
2291					argument;
2292			for ( ; --i >= 0; ) {
2293				matchIndexes.push( i );
2294			}
2295			return matchIndexes;
2296		} ),
2297
2298		"gt": createPositionalPseudo( function( matchIndexes, length, argument ) {
2299			var i = argument < 0 ? argument + length : argument;
2300			for ( ; ++i < length; ) {
2301				matchIndexes.push( i );
2302			}
2303			return matchIndexes;
2304		} )
2305	}
2306};
2307
2308Expr.pseudos[ "nth" ] = Expr.pseudos[ "eq" ];
2309
2310// Add button/input type pseudos
2311for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
2312	Expr.pseudos[ i ] = createInputPseudo( i );
2313}
2314for ( i in { submit: true, reset: true } ) {
2315	Expr.pseudos[ i ] = createButtonPseudo( i );
2316}
2317
2318// Easy API for creating new setFilters
2319function setFilters() {}
2320setFilters.prototype = Expr.filters = Expr.pseudos;
2321Expr.setFilters = new setFilters();
2322
2323tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
2324	var matched, match, tokens, type,
2325		soFar, groups, preFilters,
2326		cached = tokenCache[ selector + " " ];
2327
2328	if ( cached ) {
2329		return parseOnly ? 0 : cached.slice( 0 );
2330	}
2331
2332	soFar = selector;
2333	groups = [];
2334	preFilters = Expr.preFilter;
2335
2336	while ( soFar ) {
2337
2338		// Comma and first run
2339		if ( !matched || ( match = rcomma.exec( soFar ) ) ) {
2340			if ( match ) {
2341
2342				// Don't consume trailing commas as valid
2343				soFar = soFar.slice( match[ 0 ].length ) || soFar;
2344			}
2345			groups.push( ( tokens = [] ) );
2346		}
2347
2348		matched = false;
2349
2350		// Combinators
2351		if ( ( match = rcombinators.exec( soFar ) ) ) {
2352			matched = match.shift();
2353			tokens.push( {
2354				value: matched,
2355
2356				// Cast descendant combinators to space
2357				type: match[ 0 ].replace( rtrim, " " )
2358			} );
2359			soFar = soFar.slice( matched.length );
2360		}
2361
2362		// Filters
2363		for ( type in Expr.filter ) {
2364			if ( ( match = matchExpr[ type ].exec( soFar ) ) && ( !preFilters[ type ] ||
2365				( match = preFilters[ type ]( match ) ) ) ) {
2366				matched = match.shift();
2367				tokens.push( {
2368					value: matched,
2369					type: type,
2370					matches: match
2371				} );
2372				soFar = soFar.slice( matched.length );
2373			}
2374		}
2375
2376		if ( !matched ) {
2377			break;
2378		}
2379	}
2380
2381	// Return the length of the invalid excess
2382	// if we're just parsing
2383	// Otherwise, throw an error or return tokens
2384	return parseOnly ?
2385		soFar.length :
2386		soFar ?
2387			Sizzle.error( selector ) :
2388
2389			// Cache the tokens
2390			tokenCache( selector, groups ).slice( 0 );
2391};
2392
2393function toSelector( tokens ) {
2394	var i = 0,
2395		len = tokens.length,
2396		selector = "";
2397	for ( ; i < len; i++ ) {
2398		selector += tokens[ i ].value;
2399	}
2400	return selector;
2401}
2402
2403function addCombinator( matcher, combinator, base ) {
2404	var dir = combinator.dir,
2405		skip = combinator.next,
2406		key = skip || dir,
2407		checkNonElements = base && key === "parentNode",
2408		doneName = done++;
2409
2410	return combinator.first ?
2411
2412		// Check against closest ancestor/preceding element
2413		function( elem, context, xml ) {
2414			while ( ( elem = elem[ dir ] ) ) {
2415				if ( elem.nodeType === 1 || checkNonElements ) {
2416					return matcher( elem, context, xml );
2417				}
2418			}
2419			return false;
2420		} :
2421
2422		// Check against all ancestor/preceding elements
2423		function( elem, context, xml ) {
2424			var oldCache, uniqueCache, outerCache,
2425				newCache = [ dirruns, doneName ];
2426
2427			// We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
2428			if ( xml ) {
2429				while ( ( elem = elem[ dir ] ) ) {
2430					if ( elem.nodeType === 1 || checkNonElements ) {
2431						if ( matcher( elem, context, xml ) ) {
2432							return true;
2433						}
2434					}
2435				}
2436			} else {
2437				while ( ( elem = elem[ dir ] ) ) {
2438					if ( elem.nodeType === 1 || checkNonElements ) {
2439						outerCache = elem[ expando ] || ( elem[ expando ] = {} );
2440
2441						// Support: IE <9 only
2442						// Defend against cloned attroperties (jQuery gh-1709)
2443						uniqueCache = outerCache[ elem.uniqueID ] ||
2444							( outerCache[ elem.uniqueID ] = {} );
2445
2446						if ( skip && skip === elem.nodeName.toLowerCase() ) {
2447							elem = elem[ dir ] || elem;
2448						} else if ( ( oldCache = uniqueCache[ key ] ) &&
2449							oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
2450
2451							// Assign to newCache so results back-propagate to previous elements
2452							return ( newCache[ 2 ] = oldCache[ 2 ] );
2453						} else {
2454
2455							// Reuse newcache so results back-propagate to previous elements
2456							uniqueCache[ key ] = newCache;
2457
2458							// A match means we're done; a fail means we have to keep checking
2459							if ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) {
2460								return true;
2461							}
2462						}
2463					}
2464				}
2465			}
2466			return false;
2467		};
2468}
2469
2470function elementMatcher( matchers ) {
2471	return matchers.length > 1 ?
2472		function( elem, context, xml ) {
2473			var i = matchers.length;
2474			while ( i-- ) {
2475				if ( !matchers[ i ]( elem, context, xml ) ) {
2476					return false;
2477				}
2478			}
2479			return true;
2480		} :
2481		matchers[ 0 ];
2482}
2483
2484function multipleContexts( selector, contexts, results ) {
2485	var i = 0,
2486		len = contexts.length;
2487	for ( ; i < len; i++ ) {
2488		Sizzle( selector, contexts[ i ], results );
2489	}
2490	return results;
2491}
2492
2493function condense( unmatched, map, filter, context, xml ) {
2494	var elem,
2495		newUnmatched = [],
2496		i = 0,
2497		len = unmatched.length,
2498		mapped = map != null;
2499
2500	for ( ; i < len; i++ ) {
2501		if ( ( elem = unmatched[ i ] ) ) {
2502			if ( !filter || filter( elem, context, xml ) ) {
2503				newUnmatched.push( elem );
2504				if ( mapped ) {
2505					map.push( i );
2506				}
2507			}
2508		}
2509	}
2510
2511	return newUnmatched;
2512}
2513
2514function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
2515	if ( postFilter && !postFilter[ expando ] ) {
2516		postFilter = setMatcher( postFilter );
2517	}
2518	if ( postFinder && !postFinder[ expando ] ) {
2519		postFinder = setMatcher( postFinder, postSelector );
2520	}
2521	return markFunction( function( seed, results, context, xml ) {
2522		var temp, i, elem,
2523			preMap = [],
2524			postMap = [],
2525			preexisting = results.length,
2526
2527			// Get initial elements from seed or context
2528			elems = seed || multipleContexts(
2529				selector || "*",
2530				context.nodeType ? [ context ] : context,
2531				[]
2532			),
2533
2534			// Prefilter to get matcher input, preserving a map for seed-results synchronization
2535			matcherIn = preFilter && ( seed || !selector ) ?
2536				condense( elems, preMap, preFilter, context, xml ) :
2537				elems,
2538
2539			matcherOut = matcher ?
2540
2541				// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
2542				postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
2543
2544					// ...intermediate processing is necessary
2545					[] :
2546
2547					// ...otherwise use results directly
2548					results :
2549				matcherIn;
2550
2551		// Find primary matches
2552		if ( matcher ) {
2553			matcher( matcherIn, matcherOut, context, xml );
2554		}
2555
2556		// Apply postFilter
2557		if ( postFilter ) {
2558			temp = condense( matcherOut, postMap );
2559			postFilter( temp, [], context, xml );
2560
2561			// Un-match failing elements by moving them back to matcherIn
2562			i = temp.length;
2563			while ( i-- ) {
2564				if ( ( elem = temp[ i ] ) ) {
2565					matcherOut[ postMap[ i ] ] = !( matcherIn[ postMap[ i ] ] = elem );
2566				}
2567			}
2568		}
2569
2570		if ( seed ) {
2571			if ( postFinder || preFilter ) {
2572				if ( postFinder ) {
2573
2574					// Get the final matcherOut by condensing this intermediate into postFinder contexts
2575					temp = [];
2576					i = matcherOut.length;
2577					while ( i-- ) {
2578						if ( ( elem = matcherOut[ i ] ) ) {
2579
2580							// Restore matcherIn since elem is not yet a final match
2581							temp.push( ( matcherIn[ i ] = elem ) );
2582						}
2583					}
2584					postFinder( null, ( matcherOut = [] ), temp, xml );
2585				}
2586
2587				// Move matched elements from seed to results to keep them synchronized
2588				i = matcherOut.length;
2589				while ( i-- ) {
2590					if ( ( elem = matcherOut[ i ] ) &&
2591						( temp = postFinder ? indexOf( seed, elem ) : preMap[ i ] ) > -1 ) {
2592
2593						seed[ temp ] = !( results[ temp ] = elem );
2594					}
2595				}
2596			}
2597
2598		// Add elements to results, through postFinder if defined
2599		} else {
2600			matcherOut = condense(
2601				matcherOut === results ?
2602					matcherOut.splice( preexisting, matcherOut.length ) :
2603					matcherOut
2604			);
2605			if ( postFinder ) {
2606				postFinder( null, results, matcherOut, xml );
2607			} else {
2608				push.apply( results, matcherOut );
2609			}
2610		}
2611	} );
2612}
2613
2614function matcherFromTokens( tokens ) {
2615	var checkContext, matcher, j,
2616		len = tokens.length,
2617		leadingRelative = Expr.relative[ tokens[ 0 ].type ],
2618		implicitRelative = leadingRelative || Expr.relative[ " " ],
2619		i = leadingRelative ? 1 : 0,
2620
2621		// The foundational matcher ensures that elements are reachable from top-level context(s)
2622		matchContext = addCombinator( function( elem ) {
2623			return elem === checkContext;
2624		}, implicitRelative, true ),
2625		matchAnyContext = addCombinator( function( elem ) {
2626			return indexOf( checkContext, elem ) > -1;
2627		}, implicitRelative, true ),
2628		matchers = [ function( elem, context, xml ) {
2629			var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
2630				( checkContext = context ).nodeType ?
2631					matchContext( elem, context, xml ) :
2632					matchAnyContext( elem, context, xml ) );
2633
2634			// Avoid hanging onto element (issue #299)
2635			checkContext = null;
2636			return ret;
2637		} ];
2638
2639	for ( ; i < len; i++ ) {
2640		if ( ( matcher = Expr.relative[ tokens[ i ].type ] ) ) {
2641			matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ];
2642		} else {
2643			matcher = Expr.filter[ tokens[ i ].type ].apply( null, tokens[ i ].matches );
2644
2645			// Return special upon seeing a positional matcher
2646			if ( matcher[ expando ] ) {
2647
2648				// Find the next relative operator (if any) for proper handling
2649				j = ++i;
2650				for ( ; j < len; j++ ) {
2651					if ( Expr.relative[ tokens[ j ].type ] ) {
2652						break;
2653					}
2654				}
2655				return setMatcher(
2656					i > 1 && elementMatcher( matchers ),
2657					i > 1 && toSelector(
2658
2659					// If the preceding token was a descendant combinator, insert an implicit any-element `*`
2660					tokens
2661						.slice( 0, i - 1 )
2662						.concat( { value: tokens[ i - 2 ].type === " " ? "*" : "" } )
2663					).replace( rtrim, "$1" ),
2664					matcher,
2665					i < j && matcherFromTokens( tokens.slice( i, j ) ),
2666					j < len && matcherFromTokens( ( tokens = tokens.slice( j ) ) ),
2667					j < len && toSelector( tokens )
2668				);
2669			}
2670			matchers.push( matcher );
2671		}
2672	}
2673
2674	return elementMatcher( matchers );
2675}
2676
2677function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
2678	var bySet = setMatchers.length > 0,
2679		byElement = elementMatchers.length > 0,
2680		superMatcher = function( seed, context, xml, results, outermost ) {
2681			var elem, j, matcher,
2682				matchedCount = 0,
2683				i = "0",
2684				unmatched = seed && [],
2685				setMatched = [],
2686				contextBackup = outermostContext,
2687
2688				// We must always have either seed elements or outermost context
2689				elems = seed || byElement && Expr.find[ "TAG" ]( "*", outermost ),
2690
2691				// Use integer dirruns iff this is the outermost matcher
2692				dirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 ),
2693				len = elems.length;
2694
2695			if ( outermost ) {
2696
2697				// Support: IE 11+, Edge 17 - 18+
2698				// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
2699				// two documents; shallow comparisons work.
2700				// eslint-disable-next-line eqeqeq
2701				outermostContext = context == document || context || outermost;
2702			}
2703
2704			// Add elements passing elementMatchers directly to results
2705			// Support: IE<9, Safari
2706			// Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
2707			for ( ; i !== len && ( elem = elems[ i ] ) != null; i++ ) {
2708				if ( byElement && elem ) {
2709					j = 0;
2710
2711					// Support: IE 11+, Edge 17 - 18+
2712					// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
2713					// two documents; shallow comparisons work.
2714					// eslint-disable-next-line eqeqeq
2715					if ( !context && elem.ownerDocument != document ) {
2716						setDocument( elem );
2717						xml = !documentIsHTML;
2718					}
2719					while ( ( matcher = elementMatchers[ j++ ] ) ) {
2720						if ( matcher( elem, context || document, xml ) ) {
2721							results.push( elem );
2722							break;
2723						}
2724					}
2725					if ( outermost ) {
2726						dirruns = dirrunsUnique;
2727					}
2728				}
2729
2730				// Track unmatched elements for set filters
2731				if ( bySet ) {
2732
2733					// They will have gone through all possible matchers
2734					if ( ( elem = !matcher && elem ) ) {
2735						matchedCount--;
2736					}
2737
2738					// Lengthen the array for every element, matched or not
2739					if ( seed ) {
2740						unmatched.push( elem );
2741					}
2742				}
2743			}
2744
2745			// `i` is now the count of elements visited above, and adding it to `matchedCount`
2746			// makes the latter nonnegative.
2747			matchedCount += i;
2748
2749			// Apply set filters to unmatched elements
2750			// NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
2751			// equals `i`), unless we didn't visit _any_ elements in the above loop because we have
2752			// no element matchers and no seed.
2753			// Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
2754			// case, which will result in a "00" `matchedCount` that differs from `i` but is also
2755			// numerically zero.
2756			if ( bySet && i !== matchedCount ) {
2757				j = 0;
2758				while ( ( matcher = setMatchers[ j++ ] ) ) {
2759					matcher( unmatched, setMatched, context, xml );
2760				}
2761
2762				if ( seed ) {
2763
2764					// Reintegrate element matches to eliminate the need for sorting
2765					if ( matchedCount > 0 ) {
2766						while ( i-- ) {
2767							if ( !( unmatched[ i ] || setMatched[ i ] ) ) {
2768								setMatched[ i ] = pop.call( results );
2769							}
2770						}
2771					}
2772
2773					// Discard index placeholder values to get only actual matches
2774					setMatched = condense( setMatched );
2775				}
2776
2777				// Add matches to results
2778				push.apply( results, setMatched );
2779
2780				// Seedless set matches succeeding multiple successful matchers stipulate sorting
2781				if ( outermost && !seed && setMatched.length > 0 &&
2782					( matchedCount + setMatchers.length ) > 1 ) {
2783
2784					Sizzle.uniqueSort( results );
2785				}
2786			}
2787
2788			// Override manipulation of globals by nested matchers
2789			if ( outermost ) {
2790				dirruns = dirrunsUnique;
2791				outermostContext = contextBackup;
2792			}
2793
2794			return unmatched;
2795		};
2796
2797	return bySet ?
2798		markFunction( superMatcher ) :
2799		superMatcher;
2800}
2801
2802compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
2803	var i,
2804		setMatchers = [],
2805		elementMatchers = [],
2806		cached = compilerCache[ selector + " " ];
2807
2808	if ( !cached ) {
2809
2810		// Generate a function of recursive functions that can be used to check each element
2811		if ( !match ) {
2812			match = tokenize( selector );
2813		}
2814		i = match.length;
2815		while ( i-- ) {
2816			cached = matcherFromTokens( match[ i ] );
2817			if ( cached[ expando ] ) {
2818				setMatchers.push( cached );
2819			} else {
2820				elementMatchers.push( cached );
2821			}
2822		}
2823
2824		// Cache the compiled function
2825		cached = compilerCache(
2826			selector,
2827			matcherFromGroupMatchers( elementMatchers, setMatchers )
2828		);
2829
2830		// Save selector and tokenization
2831		cached.selector = selector;
2832	}
2833	return cached;
2834};
2835
2836/**
2837 * A low-level selection function that works with Sizzle's compiled
2838 *  selector functions
2839 * @param {String|Function} selector A selector or a pre-compiled
2840 *  selector function built with Sizzle.compile
2841 * @param {Element} context
2842 * @param {Array} [results]
2843 * @param {Array} [seed] A set of elements to match against
2844 */
2845select = Sizzle.select = function( selector, context, results, seed ) {
2846	var i, tokens, token, type, find,
2847		compiled = typeof selector === "function" && selector,
2848		match = !seed && tokenize( ( selector = compiled.selector || selector ) );
2849
2850	results = results || [];
2851
2852	// Try to minimize operations if there is only one selector in the list and no seed
2853	// (the latter of which guarantees us context)
2854	if ( match.length === 1 ) {
2855
2856		// Reduce context if the leading compound selector is an ID
2857		tokens = match[ 0 ] = match[ 0 ].slice( 0 );
2858		if ( tokens.length > 2 && ( token = tokens[ 0 ] ).type === "ID" &&
2859			context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[ 1 ].type ] ) {
2860
2861			context = ( Expr.find[ "ID" ]( token.matches[ 0 ]
2862				.replace( runescape, funescape ), context ) || [] )[ 0 ];
2863			if ( !context ) {
2864				return results;
2865
2866			// Precompiled matchers will still verify ancestry, so step up a level
2867			} else if ( compiled ) {
2868				context = context.parentNode;
2869			}
2870
2871			selector = selector.slice( tokens.shift().value.length );
2872		}
2873
2874		// Fetch a seed set for right-to-left matching
2875		i = matchExpr[ "needsContext" ].test( selector ) ? 0 : tokens.length;
2876		while ( i-- ) {
2877			token = tokens[ i ];
2878
2879			// Abort if we hit a combinator
2880			if ( Expr.relative[ ( type = token.type ) ] ) {
2881				break;
2882			}
2883			if ( ( find = Expr.find[ type ] ) ) {
2884
2885				// Search, expanding context for leading sibling combinators
2886				if ( ( seed = find(
2887					token.matches[ 0 ].replace( runescape, funescape ),
2888					rsibling.test( tokens[ 0 ].type ) && testContext( context.parentNode ) ||
2889						context
2890				) ) ) {
2891
2892					// If seed is empty or no tokens remain, we can return early
2893					tokens.splice( i, 1 );
2894					selector = seed.length && toSelector( tokens );
2895					if ( !selector ) {
2896						push.apply( results, seed );
2897						return results;
2898					}
2899
2900					break;
2901				}
2902			}
2903		}
2904	}
2905
2906	// Compile and execute a filtering function if one is not provided
2907	// Provide `match` to avoid retokenization if we modified the selector above
2908	( compiled || compile( selector, match ) )(
2909		seed,
2910		context,
2911		!documentIsHTML,
2912		results,
2913		!context || rsibling.test( selector ) && testContext( context.parentNode ) || context
2914	);
2915	return results;
2916};
2917
2918// One-time assignments
2919
2920// Sort stability
2921support.sortStable = expando.split( "" ).sort( sortOrder ).join( "" ) === expando;
2922
2923// Support: Chrome 14-35+
2924// Always assume duplicates if they aren't passed to the comparison function
2925support.detectDuplicates = !!hasDuplicate;
2926
2927// Initialize against the default document
2928setDocument();
2929
2930// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
2931// Detached nodes confoundingly follow *each other*
2932support.sortDetached = assert( function( el ) {
2933
2934	// Should return 1, but returns 4 (following)
2935	return el.compareDocumentPosition( document.createElement( "fieldset" ) ) & 1;
2936} );
2937
2938// Support: IE<8
2939// Prevent attribute/property "interpolation"
2940// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
2941if ( !assert( function( el ) {
2942	el.innerHTML = "<a href='#'></a>";
2943	return el.firstChild.getAttribute( "href" ) === "#";
2944} ) ) {
2945	addHandle( "type|href|height|width", function( elem, name, isXML ) {
2946		if ( !isXML ) {
2947			return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
2948		}
2949	} );
2950}
2951
2952// Support: IE<9
2953// Use defaultValue in place of getAttribute("value")
2954if ( !support.attributes || !assert( function( el ) {
2955	el.innerHTML = "<input/>";
2956	el.firstChild.setAttribute( "value", "" );
2957	return el.firstChild.getAttribute( "value" ) === "";
2958} ) ) {
2959	addHandle( "value", function( elem, _name, isXML ) {
2960		if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
2961			return elem.defaultValue;
2962		}
2963	} );
2964}
2965
2966// Support: IE<9
2967// Use getAttributeNode to fetch booleans when getAttribute lies
2968if ( !assert( function( el ) {
2969	return el.getAttribute( "disabled" ) == null;
2970} ) ) {
2971	addHandle( booleans, function( elem, name, isXML ) {
2972		var val;
2973		if ( !isXML ) {
2974			return elem[ name ] === true ? name.toLowerCase() :
2975				( val = elem.getAttributeNode( name ) ) && val.specified ?
2976					val.value :
2977					null;
2978		}
2979	} );
2980}
2981
2982return Sizzle;
2983
2984} )( window );
2985
2986
2987
2988jQuery.find = Sizzle;
2989jQuery.expr = Sizzle.selectors;
2990
2991// Deprecated
2992jQuery.expr[ ":" ] = jQuery.expr.pseudos;
2993jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;
2994jQuery.text = Sizzle.getText;
2995jQuery.isXMLDoc = Sizzle.isXML;
2996jQuery.contains = Sizzle.contains;
2997jQuery.escapeSelector = Sizzle.escape;
2998
2999
3000
3001
3002var dir = function( elem, dir, until ) {
3003	var matched = [],
3004		truncate = until !== undefined;
3005
3006	while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {
3007		if ( elem.nodeType === 1 ) {
3008			if ( truncate && jQuery( elem ).is( until ) ) {
3009				break;
3010			}
3011			matched.push( elem );
3012		}
3013	}
3014	return matched;
3015};
3016
3017
3018var siblings = function( n, elem ) {
3019	var matched = [];
3020
3021	for ( ; n; n = n.nextSibling ) {
3022		if ( n.nodeType === 1 && n !== elem ) {
3023			matched.push( n );
3024		}
3025	}
3026
3027	return matched;
3028};
3029
3030
3031var rneedsContext = jQuery.expr.match.needsContext;
3032
3033
3034
3035function nodeName( elem, name ) {
3036
3037	return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
3038
3039}
3040var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i );
3041
3042
3043
3044// Implement the identical functionality for filter and not
3045function winnow( elements, qualifier, not ) {
3046	if ( isFunction( qualifier ) ) {
3047		return jQuery.grep( elements, function( elem, i ) {
3048			return !!qualifier.call( elem, i, elem ) !== not;
3049		} );
3050	}
3051
3052	// Single element
3053	if ( qualifier.nodeType ) {
3054		return jQuery.grep( elements, function( elem ) {
3055			return ( elem === qualifier ) !== not;
3056		} );
3057	}
3058
3059	// Arraylike of elements (jQuery, arguments, Array)
3060	if ( typeof qualifier !== "string" ) {
3061		return jQuery.grep( elements, function( elem ) {
3062			return ( indexOf.call( qualifier, elem ) > -1 ) !== not;
3063		} );
3064	}
3065
3066	// Filtered directly for both simple and complex selectors
3067	return jQuery.filter( qualifier, elements, not );
3068}
3069
3070jQuery.filter = function( expr, elems, not ) {
3071	var elem = elems[ 0 ];
3072
3073	if ( not ) {
3074		expr = ":not(" + expr + ")";
3075	}
3076
3077	if ( elems.length === 1 && elem.nodeType === 1 ) {
3078		return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [];
3079	}
3080
3081	return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
3082		return elem.nodeType === 1;
3083	} ) );
3084};
3085
3086jQuery.fn.extend( {
3087	find: function( selector ) {
3088		var i, ret,
3089			len = this.length,
3090			self = this;
3091
3092		if ( typeof selector !== "string" ) {
vendor: 4,670 bytes, lines 3093-3278
3093			return this.pushStack( jQuery( selector ).filter( function() {
3094				for ( i = 0; i < len; i++ ) {
3095					if ( jQuery.contains( self[ i ], this ) ) {
3096						return true;
3097					}
3098				}
3099			} ) );
3100		}
3101
3102		ret = this.pushStack( [] );
3103
3104		for ( i = 0; i < len; i++ ) {
3105			jQuery.find( selector, self[ i ], ret );
3106		}
3107
3108		return len > 1 ? jQuery.uniqueSort( ret ) : ret;
3109	},
3110	filter: function( selector ) {
3111		return this.pushStack( winnow( this, selector || [], false ) );
3112	},
3113	not: function( selector ) {
3114		return this.pushStack( winnow( this, selector || [], true ) );
3115	},
3116	is: function( selector ) {
3117		return !!winnow(
3118			this,
3119
3120			// If this is a positional/relative selector, check membership in the returned set
3121			// so $("p:first").is("p:last") won't return true for a doc with two "p".
3122			typeof selector === "string" && rneedsContext.test( selector ) ?
3123				jQuery( selector ) :
3124				selector || [],
3125			false
3126		).length;
3127	}
3128} );
3129
3130
3131// Initialize a jQuery object
3132
3133
3134// A central reference to the root jQuery(document)
3135var rootjQuery,
3136
3137	// A simple way to check for HTML strings
3138	// Prioritize #id over <tag> to avoid XSS via location.hash (trac-9521)
3139	// Strict HTML recognition (trac-11290: must start with <)
3140	// Shortcut simple #id case for speed
3141	rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,
3142
3143	init = jQuery.fn.init = function( selector, context, root ) {
3144		var match, elem;
3145
3146		// HANDLE: $(""), $(null), $(undefined), $(false)
3147		if ( !selector ) {
3148			return this;
3149		}
3150
3151		// Method init() accepts an alternate rootjQuery
3152		// so migrate can support jQuery.sub (gh-2101)
3153		root = root || rootjQuery;
3154
3155		// Handle HTML strings
3156		if ( typeof selector === "string" ) {
3157			if ( selector[ 0 ] === "<" &&
3158				selector[ selector.length - 1 ] === ">" &&
3159				selector.length >= 3 ) {
3160
3161				// Assume that strings that start and end with <> are HTML and skip the regex check
3162				match = [ null, selector, null ];
3163
3164			} else {
3165				match = rquickExpr.exec( selector );
3166			}
3167
3168			// Match html or make sure no context is specified for #id
3169			if ( match && ( match[ 1 ] || !context ) ) {
3170
3171				// HANDLE: $(html) -> $(array)
3172				if ( match[ 1 ] ) {
3173					context = context instanceof jQuery ? context[ 0 ] : context;
3174
3175					// Option to run scripts is true for back-compat
3176					// Intentionally let the error be thrown if parseHTML is not present
3177					jQuery.merge( this, jQuery.parseHTML(
3178						match[ 1 ],
3179						context && context.nodeType ? context.ownerDocument || context : document,
3180						true
3181					) );
3182
3183					// HANDLE: $(html, props)
3184					if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {
3185						for ( match in context ) {
3186
3187							// Properties of context are called as methods if possible
3188							if ( isFunction( this[ match ] ) ) {
3189								this[ match ]( context[ match ] );
3190
3191							// ...and otherwise set as attributes
3192							} else {
3193								this.attr( match, context[ match ] );
3194							}
3195						}
3196					}
3197
3198					return this;
3199
3200				// HANDLE: $(#id)
3201				} else {
3202					elem = document.getElementById( match[ 2 ] );
3203
3204					if ( elem ) {
3205
3206						// Inject the element directly into the jQuery object
3207						this[ 0 ] = elem;
3208						this.length = 1;
3209					}
3210					return this;
3211				}
3212
3213			// HANDLE: $(expr, $(...))
3214			} else if ( !context || context.jquery ) {
3215				return ( context || root ).find( selector );
3216
3217			// HANDLE: $(expr, context)
3218			// (which is just equivalent to: $(context).find(expr)
3219			} else {
3220				return this.constructor( context ).find( selector );
3221			}
3222
3223		// HANDLE: $(DOMElement)
3224		} else if ( selector.nodeType ) {
3225			this[ 0 ] = selector;
3226			this.length = 1;
3227			return this;
3228
3229		// HANDLE: $(function)
3230		// Shortcut for document ready
3231		} else if ( isFunction( selector ) ) {
3232			return root.ready !== undefined ?
3233				root.ready( selector ) :
3234
3235				// Execute immediately if ready is not present
3236				selector( jQuery );
3237		}
3238
3239		return jQuery.makeArray( selector, this );
3240	};
3241
3242// Give the init function the jQuery prototype for later instantiation
3243init.prototype = jQuery.fn;
3244
3245// Initialize central reference
3246rootjQuery = jQuery( document );
3247
3248
3249var rparentsprev = /^(?:parents|prev(?:Until|All))/,
3250
3251	// Methods guaranteed to produce a unique set when starting from a unique set
3252	guaranteedUnique = {
3253		children: true,
3254		contents: true,
3255		next: true,
3256		prev: true
3257	};
3258
3259jQuery.fn.extend( {
3260	has: function( target ) {
3261		var targets = jQuery( target, this ),
3262			l = targets.length;
3263
3264		return this.filter( function() {
3265			var i = 0;
3266			for ( ; i < l; i++ ) {
3267				if ( jQuery.contains( this, targets[ i ] ) ) {
3268					return true;
3269				}
3270			}
3271		} );
3272	},
3273
3274	closest: function( selectors, context ) {
3275		var cur,
3276			i = 0,
3277			l = this.length,
3278			matched = [],
vendor: 15,549 bytes, lines 3279-3864
3279			targets = typeof selectors !== "string" && jQuery( selectors );
3280
3281		// Positional selectors never match, since there's no _selection_ context
3282		if ( !rneedsContext.test( selectors ) ) {
3283			for ( ; i < l; i++ ) {
3284				for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {
3285
3286					// Always skip document fragments
3287					if ( cur.nodeType < 11 && ( targets ?
3288						targets.index( cur ) > -1 :
3289
3290						// Don't pass non-elements to Sizzle
3291						cur.nodeType === 1 &&
3292							jQuery.find.matchesSelector( cur, selectors ) ) ) {
3293
3294						matched.push( cur );
3295						break;
3296					}
3297				}
3298			}
3299		}
3300
3301		return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );
3302	},
3303
3304	// Determine the position of an element within the set
3305	index: function( elem ) {
3306
3307		// No argument, return index in parent
3308		if ( !elem ) {
3309			return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
3310		}
3311
3312		// Index in selector
3313		if ( typeof elem === "string" ) {
3314			return indexOf.call( jQuery( elem ), this[ 0 ] );
3315		}
3316
3317		// Locate the position of the desired element
3318		return indexOf.call( this,
3319
3320			// If it receives a jQuery object, the first element is used
3321			elem.jquery ? elem[ 0 ] : elem
3322		);
3323	},
3324
3325	add: function( selector, context ) {
3326		return this.pushStack(
3327			jQuery.uniqueSort(
3328				jQuery.merge( this.get(), jQuery( selector, context ) )
3329			)
3330		);
3331	},
3332
3333	addBack: function( selector ) {
3334		return this.add( selector == null ?
3335			this.prevObject : this.prevObject.filter( selector )
3336		);
3337	}
3338} );
3339
3340function sibling( cur, dir ) {
3341	while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}
3342	return cur;
3343}
3344
3345jQuery.each( {
3346	parent: function( elem ) {
3347		var parent = elem.parentNode;
3348		return parent && parent.nodeType !== 11 ? parent : null;
3349	},
3350	parents: function( elem ) {
3351		return dir( elem, "parentNode" );
3352	},
3353	parentsUntil: function( elem, _i, until ) {
3354		return dir( elem, "parentNode", until );
3355	},
3356	next: function( elem ) {
3357		return sibling( elem, "nextSibling" );
3358	},
3359	prev: function( elem ) {
3360		return sibling( elem, "previousSibling" );
3361	},
3362	nextAll: function( elem ) {
3363		return dir( elem, "nextSibling" );
3364	},
3365	prevAll: function( elem ) {
3366		return dir( elem, "previousSibling" );
3367	},
3368	nextUntil: function( elem, _i, until ) {
3369		return dir( elem, "nextSibling", until );
3370	},
3371	prevUntil: function( elem, _i, until ) {
3372		return dir( elem, "previousSibling", until );
3373	},
3374	siblings: function( elem ) {
3375		return siblings( ( elem.parentNode || {} ).firstChild, elem );
3376	},
3377	children: function( elem ) {
3378		return siblings( elem.firstChild );
3379	},
3380	contents: function( elem ) {
3381		if ( elem.contentDocument != null &&
3382
3383			// Support: IE 11+
3384			// <object> elements with no `data` attribute has an object
3385			// `contentDocument` with a `null` prototype.
3386			getProto( elem.contentDocument ) ) {
3387
3388			return elem.contentDocument;
3389		}
3390
3391		// Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only
3392		// Treat the template element as a regular one in browsers that
3393		// don't support it.
3394		if ( nodeName( elem, "template" ) ) {
3395			elem = elem.content || elem;
3396		}
3397
3398		return jQuery.merge( [], elem.childNodes );
3399	}
3400}, function( name, fn ) {
3401	jQuery.fn[ name ] = function( until, selector ) {
3402		var matched = jQuery.map( this, fn, until );
3403
3404		if ( name.slice( -5 ) !== "Until" ) {
3405			selector = until;
3406		}
3407
3408		if ( selector && typeof selector === "string" ) {
3409			matched = jQuery.filter( selector, matched );
3410		}
3411
3412		if ( this.length > 1 ) {
3413
3414			// Remove duplicates
3415			if ( !guaranteedUnique[ name ] ) {
3416				jQuery.uniqueSort( matched );
3417			}
3418
3419			// Reverse order for parents* and prev-derivatives
3420			if ( rparentsprev.test( name ) ) {
3421				matched.reverse();
3422			}
3423		}
3424
3425		return this.pushStack( matched );
3426	};
3427} );
3428var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g );
3429
3430
3431
3432// Convert String-formatted options into Object-formatted ones
3433function createOptions( options ) {
3434	var object = {};
3435	jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) {
3436		object[ flag ] = true;
3437	} );
3438	return object;
3439}
3440
3441/*
3442 * Create a callback list using the following parameters:
3443 *
3444 *	options: an optional list of space-separated options that will change how
3445 *			the callback list behaves or a more traditional option object
3446 *
3447 * By default a callback list will act like an event callback list and can be
3448 * "fired" multiple times.
3449 *
3450 * Possible options:
3451 *
3452 *	once:			will ensure the callback list can only be fired once (like a Deferred)
3453 *
3454 *	memory:			will keep track of previous values and will call any callback added
3455 *					after the list has been fired right away with the latest "memorized"
3456 *					values (like a Deferred)
3457 *
3458 *	unique:			will ensure a callback can only be added once (no duplicate in the list)
3459 *
3460 *	stopOnFalse:	interrupt callings when a callback returns false
3461 *
3462 */
3463jQuery.Callbacks = function( options ) {
3464
3465	// Convert options from String-formatted to Object-formatted if needed
3466	// (we check in cache first)
3467	options = typeof options === "string" ?
3468		createOptions( options ) :
3469		jQuery.extend( {}, options );
3470
3471	var // Flag to know if list is currently firing
3472		firing,
3473
3474		// Last fire value for non-forgettable lists
3475		memory,
3476
3477		// Flag to know if list was already fired
3478		fired,
3479
3480		// Flag to prevent firing
3481		locked,
3482
3483		// Actual callback list
3484		list = [],
3485
3486		// Queue of execution data for repeatable lists
3487		queue = [],
3488
3489		// Index of currently firing callback (modified by add/remove as needed)
3490		firingIndex = -1,
3491
3492		// Fire callbacks
3493		fire = function() {
3494
3495			// Enforce single-firing
3496			locked = locked || options.once;
3497
3498			// Execute callbacks for all pending executions,
3499			// respecting firingIndex overrides and runtime changes
3500			fired = firing = true;
3501			for ( ; queue.length; firingIndex = -1 ) {
3502				memory = queue.shift();
3503				while ( ++firingIndex < list.length ) {
3504
3505					// Run callback and check for early termination
3506					if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&
3507						options.stopOnFalse ) {
3508
3509						// Jump to end and forget the data so .add doesn't re-fire
3510						firingIndex = list.length;
3511						memory = false;
3512					}
3513				}
3514			}
3515
3516			// Forget the data if we're done with it
3517			if ( !options.memory ) {
3518				memory = false;
3519			}
3520
3521			firing = false;
3522
3523			// Clean up if we're done firing for good
3524			if ( locked ) {
3525
3526				// Keep an empty list if we have data for future add calls
3527				if ( memory ) {
3528					list = [];
3529
3530				// Otherwise, this object is spent
3531				} else {
3532					list = "";
3533				}
3534			}
3535		},
3536
3537		// Actual Callbacks object
3538		self = {
3539
3540			// Add a callback or a collection of callbacks to the list
3541			add: function() {
3542				if ( list ) {
3543
3544					// If we have memory from a past run, we should fire after adding
3545					if ( memory && !firing ) {
3546						firingIndex = list.length - 1;
3547						queue.push( memory );
3548					}
3549
3550					( function add( args ) {
3551						jQuery.each( args, function( _, arg ) {
3552							if ( isFunction( arg ) ) {
3553								if ( !options.unique || !self.has( arg ) ) {
3554									list.push( arg );
3555								}
3556							} else if ( arg && arg.length && toType( arg ) !== "string" ) {
3557
3558								// Inspect recursively
3559								add( arg );
3560							}
3561						} );
3562					} )( arguments );
3563
3564					if ( memory && !firing ) {
3565						fire();
3566					}
3567				}
3568				return this;
3569			},
3570
3571			// Remove a callback from the list
3572			remove: function() {
3573				jQuery.each( arguments, function( _, arg ) {
3574					var index;
3575					while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
3576						list.splice( index, 1 );
3577
3578						// Handle firing indexes
3579						if ( index <= firingIndex ) {
3580							firingIndex--;
3581						}
3582					}
3583				} );
3584				return this;
3585			},
3586
3587			// Check if a given callback is in the list.
3588			// If no argument is given, return whether or not list has callbacks attached.
3589			has: function( fn ) {
3590				return fn ?
3591					jQuery.inArray( fn, list ) > -1 :
3592					list.length > 0;
3593			},
3594
3595			// Remove all callbacks from the list
3596			empty: function() {
3597				if ( list ) {
3598					list = [];
3599				}
3600				return this;
3601			},
3602
3603			// Disable .fire and .add
3604			// Abort any current/pending executions
3605			// Clear all callbacks and values
3606			disable: function() {
3607				locked = queue = [];
3608				list = memory = "";
3609				return this;
3610			},
3611			disabled: function() {
3612				return !list;
3613			},
3614
3615			// Disable .fire
3616			// Also disable .add unless we have memory (since it would have no effect)
3617			// Abort any pending executions
3618			lock: function() {
3619				locked = queue = [];
3620				if ( !memory && !firing ) {
3621					list = memory = "";
3622				}
3623				return this;
3624			},
3625			locked: function() {
3626				return !!locked;
3627			},
3628
3629			// Call all callbacks with the given context and arguments
3630			fireWith: function( context, args ) {
3631				if ( !locked ) {
3632					args = args || [];
3633					args = [ context, args.slice ? args.slice() : args ];
3634					queue.push( args );
3635					if ( !firing ) {
3636						fire();
3637					}
3638				}
3639				return this;
3640			},
3641
3642			// Call all the callbacks with the given arguments
3643			fire: function() {
3644				self.fireWith( this, arguments );
3645				return this;
3646			},
3647
3648			// To know if the callbacks have already been called at least once
3649			fired: function() {
3650				return !!fired;
3651			}
3652		};
3653
3654	return self;
3655};
3656
3657
3658function Identity( v ) {
3659	return v;
3660}
3661function Thrower( ex ) {
3662	throw ex;
3663}
3664
3665function adoptValue( value, resolve, reject, noValue ) {
3666	var method;
3667
3668	try {
3669
3670		// Check for promise aspect first to privilege synchronous behavior
3671		if ( value && isFunction( ( method = value.promise ) ) ) {
3672			method.call( value ).done( resolve ).fail( reject );
3673
3674		// Other thenables
3675		} else if ( value && isFunction( ( method = value.then ) ) ) {
3676			method.call( value, resolve, reject );
3677
3678		// Other non-thenables
3679		} else {
3680
3681			// Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer:
3682			// * false: [ value ].slice( 0 ) => resolve( value )
3683			// * true: [ value ].slice( 1 ) => resolve()
3684			resolve.apply( undefined, [ value ].slice( noValue ) );
3685		}
3686
3687	// For Promises/A+, convert exceptions into rejections
3688	// Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in
3689	// Deferred#then to conditionally suppress rejection.
3690	} catch ( value ) {
3691
3692		// Support: Android 4.0 only
3693		// Strict mode functions invoked without .call/.apply get global-object context
3694		reject.apply( undefined, [ value ] );
3695	}
3696}
3697
3698jQuery.extend( {
3699
3700	Deferred: function( func ) {
3701		var tuples = [
3702
3703				// action, add listener, callbacks,
3704				// ... .then handlers, argument index, [final state]
3705				[ "notify", "progress", jQuery.Callbacks( "memory" ),
3706					jQuery.Callbacks( "memory" ), 2 ],
3707				[ "resolve", "done", jQuery.Callbacks( "once memory" ),
3708					jQuery.Callbacks( "once memory" ), 0, "resolved" ],
3709				[ "reject", "fail", jQuery.Callbacks( "once memory" ),
3710					jQuery.Callbacks( "once memory" ), 1, "rejected" ]
3711			],
3712			state = "pending",
3713			promise = {
3714				state: function() {
3715					return state;
3716				},
3717				always: function() {
3718					deferred.done( arguments ).fail( arguments );
3719					return this;
3720				},
3721				"catch": function( fn ) {
3722					return promise.then( null, fn );
3723				},
3724
3725				// Keep pipe for back-compat
3726				pipe: function( /* fnDone, fnFail, fnProgress */ ) {
3727					var fns = arguments;
3728
3729					return jQuery.Deferred( function( newDefer ) {
3730						jQuery.each( tuples, function( _i, tuple ) {
3731
3732							// Map tuples (progress, done, fail) to arguments (done, fail, progress)
3733							var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ];
3734
3735							// deferred.progress(function() { bind to newDefer or newDefer.notify })
3736							// deferred.done(function() { bind to newDefer or newDefer.resolve })
3737							// deferred.fail(function() { bind to newDefer or newDefer.reject })
3738							deferred[ tuple[ 1 ] ]( function() {
3739								var returned = fn && fn.apply( this, arguments );
3740								if ( returned && isFunction( returned.promise ) ) {
3741									returned.promise()
3742										.progress( newDefer.notify )
3743										.done( newDefer.resolve )
3744										.fail( newDefer.reject );
3745								} else {
3746									newDefer[ tuple[ 0 ] + "With" ](
3747										this,
3748										fn ? [ returned ] : arguments
3749									);
3750								}
3751							} );
3752						} );
3753						fns = null;
3754					} ).promise();
3755				},
3756				then: function( onFulfilled, onRejected, onProgress ) {
3757					var maxDepth = 0;
3758					function resolve( depth, deferred, handler, special ) {
3759						return function() {
3760							var that = this,
3761								args = arguments,
3762								mightThrow = function() {
3763									var returned, then;
3764
3765									// Support: Promises/A+ section 2.3.3.3.3
3766									// https://promisesaplus.com/#point-59
3767									// Ignore double-resolution attempts
3768									if ( depth < maxDepth ) {
3769										return;
3770									}
3771
3772									returned = handler.apply( that, args );
3773
3774									// Support: Promises/A+ section 2.3.1
3775									// https://promisesaplus.com/#point-48
3776									if ( returned === deferred.promise() ) {
3777										throw new TypeError( "Thenable self-resolution" );
3778									}
3779
3780									// Support: Promises/A+ sections 2.3.3.1, 3.5
3781									// https://promisesaplus.com/#point-54
3782									// https://promisesaplus.com/#point-75
3783									// Retrieve `then` only once
3784									then = returned &&
3785
3786										// Support: Promises/A+ section 2.3.4
3787										// https://promisesaplus.com/#point-64
3788										// Only check objects and functions for thenability
3789										( typeof returned === "object" ||
3790											typeof returned === "function" ) &&
3791										returned.then;
3792
3793									// Handle a returned thenable
3794									if ( isFunction( then ) ) {
3795
3796										// Special processors (notify) just wait for resolution
3797										if ( special ) {
3798											then.call(
3799												returned,
3800												resolve( maxDepth, deferred, Identity, special ),
3801												resolve( maxDepth, deferred, Thrower, special )
3802											);
3803
3804										// Normal processors (resolve) also hook into progress
3805										} else {
3806
3807											// ...and disregard older resolution values
3808											maxDepth++;
3809
3810											then.call(
3811												returned,
3812												resolve( maxDepth, deferred, Identity, special ),
3813												resolve( maxDepth, deferred, Thrower, special ),
3814												resolve( maxDepth, deferred, Identity,
3815													deferred.notifyWith )
3816											);
3817										}
3818
3819									// Handle all other returned values
3820									} else {
3821
3822										// Only substitute handlers pass on context
3823										// and multiple values (non-spec behavior)
3824										if ( handler !== Identity ) {
3825											that = undefined;
3826											args = [ returned ];
3827										}
3828
3829										// Process the value(s)
3830										// Default process is resolve
3831										( special || deferred.resolveWith )( that, args );
3832									}
3833								},
3834
3835								// Only normal processors (resolve) catch and reject exceptions
3836								process = special ?
3837									mightThrow :
3838									function() {
3839										try {
3840											mightThrow();
3841										} catch ( e ) {
3842
3843											if ( jQuery.Deferred.exceptionHook ) {
3844												jQuery.Deferred.exceptionHook( e,
3845													process.stackTrace );
3846											}
3847
3848											// Support: Promises/A+ section 2.3.3.3.4.1
3849											// https://promisesaplus.com/#point-61
3850											// Ignore post-resolution exceptions
3851											if ( depth + 1 >= maxDepth ) {
3852
3853												// Only substitute handlers pass on context
3854												// and multiple values (non-spec behavior)
3855												if ( handler !== Thrower ) {
3856													that = undefined;
3857													args = [ e ];
3858												}
3859
3860												deferred.rejectWith( that, args );
3861											}
3862										}
3863									};
3864
vendor: 10,679 bytes, lines 3865-4313
3865							// Support: Promises/A+ section 2.3.3.3.1
3866							// https://promisesaplus.com/#point-57
3867							// Re-resolve promises immediately to dodge false rejection from
3868							// subsequent errors
3869							if ( depth ) {
3870								process();
3871							} else {
3872
3873								// Call an optional hook to record the stack, in case of exception
3874								// since it's otherwise lost when execution goes async
3875								if ( jQuery.Deferred.getStackHook ) {
3876									process.stackTrace = jQuery.Deferred.getStackHook();
3877								}
3878								window.setTimeout( process );
3879							}
3880						};
3881					}
3882
3883					return jQuery.Deferred( function( newDefer ) {
3884
3885						// progress_handlers.add( ... )
3886						tuples[ 0 ][ 3 ].add(
3887							resolve(
3888								0,
3889								newDefer,
3890								isFunction( onProgress ) ?
3891									onProgress :
3892									Identity,
3893								newDefer.notifyWith
3894							)
3895						);
3896
3897						// fulfilled_handlers.add( ... )
3898						tuples[ 1 ][ 3 ].add(
3899							resolve(
3900								0,
3901								newDefer,
3902								isFunction( onFulfilled ) ?
3903									onFulfilled :
3904									Identity
3905							)
3906						);
3907
3908						// rejected_handlers.add( ... )
3909						tuples[ 2 ][ 3 ].add(
3910							resolve(
3911								0,
3912								newDefer,
3913								isFunction( onRejected ) ?
3914									onRejected :
3915									Thrower
3916							)
3917						);
3918					} ).promise();
3919				},
3920
3921				// Get a promise for this deferred
3922				// If obj is provided, the promise aspect is added to the object
3923				promise: function( obj ) {
3924					return obj != null ? jQuery.extend( obj, promise ) : promise;
3925				}
3926			},
3927			deferred = {};
3928
3929		// Add list-specific methods
3930		jQuery.each( tuples, function( i, tuple ) {
3931			var list = tuple[ 2 ],
3932				stateString = tuple[ 5 ];
3933
3934			// promise.progress = list.add
3935			// promise.done = list.add
3936			// promise.fail = list.add
3937			promise[ tuple[ 1 ] ] = list.add;
3938
3939			// Handle state
3940			if ( stateString ) {
3941				list.add(
3942					function() {
3943
3944						// state = "resolved" (i.e., fulfilled)
3945						// state = "rejected"
3946						state = stateString;
3947					},
3948
3949					// rejected_callbacks.disable
3950					// fulfilled_callbacks.disable
3951					tuples[ 3 - i ][ 2 ].disable,
3952
3953					// rejected_handlers.disable
3954					// fulfilled_handlers.disable
3955					tuples[ 3 - i ][ 3 ].disable,
3956
3957					// progress_callbacks.lock
3958					tuples[ 0 ][ 2 ].lock,
3959
3960					// progress_handlers.lock
3961					tuples[ 0 ][ 3 ].lock
3962				);
3963			}
3964
3965			// progress_handlers.fire
3966			// fulfilled_handlers.fire
3967			// rejected_handlers.fire
3968			list.add( tuple[ 3 ].fire );
3969
3970			// deferred.notify = function() { deferred.notifyWith(...) }
3971			// deferred.resolve = function() { deferred.resolveWith(...) }
3972			// deferred.reject = function() { deferred.rejectWith(...) }
3973			deferred[ tuple[ 0 ] ] = function() {
3974				deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments );
3975				return this;
3976			};
3977
3978			// deferred.notifyWith = list.fireWith
3979			// deferred.resolveWith = list.fireWith
3980			// deferred.rejectWith = list.fireWith
3981			deferred[ tuple[ 0 ] + "With" ] = list.fireWith;
3982		} );
3983
3984		// Make the deferred a promise
3985		promise.promise( deferred );
3986
3987		// Call given func if any
3988		if ( func ) {
3989			func.call( deferred, deferred );
3990		}
3991
3992		// All done!
3993		return deferred;
3994	},
3995
3996	// Deferred helper
3997	when: function( singleValue ) {
3998		var
3999
4000			// count of uncompleted subordinates
4001			remaining = arguments.length,
4002
4003			// count of unprocessed arguments
4004			i = remaining,
4005
4006			// subordinate fulfillment data
4007			resolveContexts = Array( i ),
4008			resolveValues = slice.call( arguments ),
4009
4010			// the primary Deferred
4011			primary = jQuery.Deferred(),
4012
4013			// subordinate callback factory
4014			updateFunc = function( i ) {
4015				return function( value ) {
4016					resolveContexts[ i ] = this;
4017					resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
4018					if ( !( --remaining ) ) {
4019						primary.resolveWith( resolveContexts, resolveValues );
4020					}
4021				};
4022			};
4023
4024		// Single- and empty arguments are adopted like Promise.resolve
4025		if ( remaining <= 1 ) {
4026			adoptValue( singleValue, primary.done( updateFunc( i ) ).resolve, primary.reject,
4027				!remaining );
4028
4029			// Use .then() to unwrap secondary thenables (cf. gh-3000)
4030			if ( primary.state() === "pending" ||
4031				isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) {
4032
4033				return primary.then();
4034			}
4035		}
4036
4037		// Multiple arguments are aggregated like Promise.all array elements
4038		while ( i-- ) {
4039			adoptValue( resolveValues[ i ], updateFunc( i ), primary.reject );
4040		}
4041
4042		return primary.promise();
4043	}
4044} );
4045
4046
4047// These usually indicate a programmer mistake during development,
4048// warn about them ASAP rather than swallowing them by default.
4049var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;
4050
4051jQuery.Deferred.exceptionHook = function( error, stack ) {
4052
4053	// Support: IE 8 - 9 only
4054	// Console exists when dev tools are open, which can happen at any time
4055	if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) {
4056		window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack );
4057	}
4058};
4059
4060
4061
4062
4063jQuery.readyException = function( error ) {
4064	window.setTimeout( function() {
4065		throw error;
4066	} );
4067};
4068
4069
4070
4071
4072// The deferred used on DOM ready
4073var readyList = jQuery.Deferred();
4074
4075jQuery.fn.ready = function( fn ) {
4076
4077	readyList
4078		.then( fn )
4079
4080		// Wrap jQuery.readyException in a function so that the lookup
4081		// happens at the time of error handling instead of callback
4082		// registration.
4083		.catch( function( error ) {
4084			jQuery.readyException( error );
4085		} );
4086
4087	return this;
4088};
4089
4090jQuery.extend( {
4091
4092	// Is the DOM ready to be used? Set to true once it occurs.
4093	isReady: false,
4094
4095	// A counter to track how many items to wait for before
4096	// the ready event fires. See trac-6781
4097	readyWait: 1,
4098
4099	// Handle when the DOM is ready
4100	ready: function( wait ) {
4101
4102		// Abort if there are pending holds or we're already ready
4103		if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
4104			return;
4105		}
4106
4107		// Remember that the DOM is ready
4108		jQuery.isReady = true;
4109
4110		// If a normal DOM Ready event fired, decrement, and wait if need be
4111		if ( wait !== true && --jQuery.readyWait > 0 ) {
4112			return;
4113		}
4114
4115		// If there are functions bound, to execute
4116		readyList.resolveWith( document, [ jQuery ] );
4117	}
4118} );
4119
4120jQuery.ready.then = readyList.then;
4121
4122// The ready event handler and self cleanup method
4123function completed() {
4124	document.removeEventListener( "DOMContentLoaded", completed );
4125	window.removeEventListener( "load", completed );
4126	jQuery.ready();
4127}
4128
4129// Catch cases where $(document).ready() is called
4130// after the browser event has already occurred.
4131// Support: IE <=9 - 10 only
4132// Older IE sometimes signals "interactive" too soon
4133if ( document.readyState === "complete" ||
4134	( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {
4135
4136	// Handle it asynchronously to allow scripts the opportunity to delay ready
4137	window.setTimeout( jQuery.ready );
4138
4139} else {
4140
4141	// Use the handy event callback
4142	document.addEventListener( "DOMContentLoaded", completed );
4143
4144	// A fallback to window.onload, that will always work
4145	window.addEventListener( "load", completed );
4146}
4147
4148
4149
4150
4151// Multifunctional method to get and set values of a collection
4152// The value/s can optionally be executed if it's a function
4153var access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
4154	var i = 0,
4155		len = elems.length,
4156		bulk = key == null;
4157
4158	// Sets many values
4159	if ( toType( key ) === "object" ) {
4160		chainable = true;
4161		for ( i in key ) {
4162			access( elems, fn, i, key[ i ], true, emptyGet, raw );
4163		}
4164
4165	// Sets one value
4166	} else if ( value !== undefined ) {
4167		chainable = true;
4168
4169		if ( !isFunction( value ) ) {
4170			raw = true;
4171		}
4172
4173		if ( bulk ) {
4174
4175			// Bulk operations run against the entire set
4176			if ( raw ) {
4177				fn.call( elems, value );
4178				fn = null;
4179
4180			// ...except when executing function values
4181			} else {
4182				bulk = fn;
4183				fn = function( elem, _key, value ) {
4184					return bulk.call( jQuery( elem ), value );
4185				};
4186			}
4187		}
4188
4189		if ( fn ) {
4190			for ( ; i < len; i++ ) {
4191				fn(
4192					elems[ i ], key, raw ?
4193						value :
4194						value.call( elems[ i ], i, fn( elems[ i ], key ) )
4195				);
4196			}
4197		}
4198	}
4199
4200	if ( chainable ) {
4201		return elems;
4202	}
4203
4204	// Gets
4205	if ( bulk ) {
4206		return fn.call( elems );
4207	}
4208
4209	return len ? fn( elems[ 0 ], key ) : emptyGet;
4210};
4211
4212
4213// Matches dashed string for camelizing
4214var rmsPrefix = /^-ms-/,
4215	rdashAlpha = /-([a-z])/g;
4216
4217// Used by camelCase as callback to replace()
4218function fcamelCase( _all, letter ) {
4219	return letter.toUpperCase();
4220}
4221
4222// Convert dashed to camelCase; used by the css and data modules
4223// Support: IE <=9 - 11, Edge 12 - 15
4224// Microsoft forgot to hump their vendor prefix (trac-9572)
4225function camelCase( string ) {
4226	return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
4227}
4228var acceptData = function( owner ) {
4229
4230	// Accepts only:
4231	//  - Node
4232	//    - Node.ELEMENT_NODE
4233	//    - Node.DOCUMENT_NODE
4234	//  - Object
4235	//    - Any
4236	return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );
4237};
4238
4239
4240
4241
4242function Data() {
4243	this.expando = jQuery.expando + Data.uid++;
4244}
4245
4246Data.uid = 1;
4247
4248Data.prototype = {
4249
4250	cache: function( owner ) {
4251
4252		// Check if the owner object already has a cache
4253		var value = owner[ this.expando ];
4254
4255		// If not, create one
4256		if ( !value ) {
4257			value = {};
4258
4259			// We can accept data for non-element nodes in modern browsers,
4260			// but we should not, see trac-8335.
4261			// Always return an empty object.
4262			if ( acceptData( owner ) ) {
4263
4264				// If it is a node unlikely to be stringify-ed or looped over
4265				// use plain assignment
4266				if ( owner.nodeType ) {
4267					owner[ this.expando ] = value;
4268
4269				// Otherwise secure it in a non-enumerable property
4270				// configurable must be true to allow the property to be
4271				// deleted when data is removed
4272				} else {
4273					Object.defineProperty( owner, this.expando, {
4274						value: value,
4275						configurable: true
4276					} );
4277				}
4278			}
4279		}
4280
4281		return value;
4282	},
4283	set: function( owner, data, value ) {
4284		var prop,
4285			cache = this.cache( owner );
4286
4287		// Handle: [ owner, key, value ] args
4288		// Always use camelCase key (gh-2257)
4289		if ( typeof data === "string" ) {
4290			cache[ camelCase( data ) ] = value;
4291
4292		// Handle: [ owner, { properties } ] args
4293		} else {
4294
4295			// Copy the properties one-by-one to the cache object
4296			for ( prop in data ) {
4297				cache[ camelCase( prop ) ] = data[ prop ];
4298			}
4299		}
4300		return cache;
4301	},
4302	get: function( owner, key ) {
4303		return key === undefined ?
4304			this.cache( owner ) :
4305
4306			// Always use camelCase key (gh-2257)
4307			owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ];
4308	},
4309	access: function( owner, key, value ) {
4310
4311		// In cases where either:
4312		//
4313		//   1. No key was specified
vendor: 4,579 bytes, lines 4314-4497
4314		//   2. A string key was specified, but no value provided
4315		//
4316		// Take the "read" path and allow the get method to determine
4317		// which value to return, respectively either:
4318		//
4319		//   1. The entire cache object
4320		//   2. The data stored at the key
4321		//
4322		if ( key === undefined ||
4323				( ( key && typeof key === "string" ) && value === undefined ) ) {
4324
4325			return this.get( owner, key );
4326		}
4327
4328		// When the key is not a string, or both a key and value
4329		// are specified, set or extend (existing objects) with either:
4330		//
4331		//   1. An object of properties
4332		//   2. A key and value
4333		//
4334		this.set( owner, key, value );
4335
4336		// Since the "set" path can have two possible entry points
4337		// return the expected data based on which path was taken[*]
4338		return value !== undefined ? value : key;
4339	},
4340	remove: function( owner, key ) {
4341		var i,
4342			cache = owner[ this.expando ];
4343
4344		if ( cache === undefined ) {
4345			return;
4346		}
4347
4348		if ( key !== undefined ) {
4349
4350			// Support array or space separated string of keys
4351			if ( Array.isArray( key ) ) {
4352
4353				// If key is an array of keys...
4354				// We always set camelCase keys, so remove that.
4355				key = key.map( camelCase );
4356			} else {
4357				key = camelCase( key );
4358
4359				// If a key with the spaces exists, use it.
4360				// Otherwise, create an array by matching non-whitespace
4361				key = key in cache ?
4362					[ key ] :
4363					( key.match( rnothtmlwhite ) || [] );
4364			}
4365
4366			i = key.length;
4367
4368			while ( i-- ) {
4369				delete cache[ key[ i ] ];
4370			}
4371		}
4372
4373		// Remove the expando if there's no more data
4374		if ( key === undefined || jQuery.isEmptyObject( cache ) ) {
4375
4376			// Support: Chrome <=35 - 45
4377			// Webkit & Blink performance suffers when deleting properties
4378			// from DOM nodes, so set to undefined instead
4379			// https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)
4380			if ( owner.nodeType ) {
4381				owner[ this.expando ] = undefined;
4382			} else {
4383				delete owner[ this.expando ];
4384			}
4385		}
4386	},
4387	hasData: function( owner ) {
4388		var cache = owner[ this.expando ];
4389		return cache !== undefined && !jQuery.isEmptyObject( cache );
4390	}
4391};
4392var dataPriv = new Data();
4393
4394var dataUser = new Data();
4395
4396
4397
4398//	Implementation Summary
4399//
4400//	1. Enforce API surface and semantic compatibility with 1.9.x branch
4401//	2. Improve the module's maintainability by reducing the storage
4402//		paths to a single mechanism.
4403//	3. Use the same single mechanism to support "private" and "user" data.
4404//	4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
4405//	5. Avoid exposing implementation details on user objects (eg. expando properties)
4406//	6. Provide a clear path for implementation upgrade to WeakMap in 2014
4407
4408var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
4409	rmultiDash = /[A-Z]/g;
4410
4411function getData( data ) {
4412	if ( data === "true" ) {
4413		return true;
4414	}
4415
4416	if ( data === "false" ) {
4417		return false;
4418	}
4419
4420	if ( data === "null" ) {
4421		return null;
4422	}
4423
4424	// Only convert to a number if it doesn't change the string
4425	if ( data === +data + "" ) {
4426		return +data;
4427	}
4428
4429	if ( rbrace.test( data ) ) {
4430		return JSON.parse( data );
4431	}
4432
4433	return data;
4434}
4435
4436function dataAttr( elem, key, data ) {
4437	var name;
4438
4439	// If nothing was found internally, try to fetch any
4440	// data from the HTML5 data-* attribute
4441	if ( data === undefined && elem.nodeType === 1 ) {
4442		name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase();
4443		data = elem.getAttribute( name );
4444
4445		if ( typeof data === "string" ) {
4446			try {
4447				data = getData( data );
4448			} catch ( e ) {}
4449
4450			// Make sure we set the data so it isn't changed later
4451			dataUser.set( elem, key, data );
4452		} else {
4453			data = undefined;
4454		}
4455	}
4456	return data;
4457}
4458
4459jQuery.extend( {
4460	hasData: function( elem ) {
4461		return dataUser.hasData( elem ) || dataPriv.hasData( elem );
4462	},
4463
4464	data: function( elem, name, data ) {
4465		return dataUser.access( elem, name, data );
4466	},
4467
4468	removeData: function( elem, name ) {
4469		dataUser.remove( elem, name );
4470	},
4471
4472	// TODO: Now that all calls to _data and _removeData have been replaced
4473	// with direct calls to dataPriv methods, these can be deprecated.
4474	_data: function( elem, name, data ) {
4475		return dataPriv.access( elem, name, data );
4476	},
4477
4478	_removeData: function( elem, name ) {
4479		dataPriv.remove( elem, name );
4480	}
4481} );
4482
4483jQuery.fn.extend( {
4484	data: function( key, value ) {
4485		var i, name, data,
4486			elem = this[ 0 ],
4487			attrs = elem && elem.attributes;
4488
4489		// Gets all values
4490		if ( key === undefined ) {
4491			if ( this.length ) {
4492				data = dataUser.get( elem );
4493
4494				if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) {
4495					i = attrs.length;
4496					while ( i-- ) {
4497
vendor: 4,119 bytes, lines 4498-4672
4498						// Support: IE 11 only
4499						// The attrs elements can be null (trac-14894)
4500						if ( attrs[ i ] ) {
4501							name = attrs[ i ].name;
4502							if ( name.indexOf( "data-" ) === 0 ) {
4503								name = camelCase( name.slice( 5 ) );
4504								dataAttr( elem, name, data[ name ] );
4505							}
4506						}
4507					}
4508					dataPriv.set( elem, "hasDataAttrs", true );
4509				}
4510			}
4511
4512			return data;
4513		}
4514
4515		// Sets multiple values
4516		if ( typeof key === "object" ) {
4517			return this.each( function() {
4518				dataUser.set( this, key );
4519			} );
4520		}
4521
4522		return access( this, function( value ) {
4523			var data;
4524
4525			// The calling jQuery object (element matches) is not empty
4526			// (and therefore has an element appears at this[ 0 ]) and the
4527			// `value` parameter was not undefined. An empty jQuery object
4528			// will result in `undefined` for elem = this[ 0 ] which will
4529			// throw an exception if an attempt to read a data cache is made.
4530			if ( elem && value === undefined ) {
4531
4532				// Attempt to get data from the cache
4533				// The key will always be camelCased in Data
4534				data = dataUser.get( elem, key );
4535				if ( data !== undefined ) {
4536					return data;
4537				}
4538
4539				// Attempt to "discover" the data in
4540				// HTML5 custom data-* attrs
4541				data = dataAttr( elem, key );
4542				if ( data !== undefined ) {
4543					return data;
4544				}
4545
4546				// We tried really hard, but the data doesn't exist.
4547				return;
4548			}
4549
4550			// Set the data...
4551			this.each( function() {
4552
4553				// We always store the camelCased key
4554				dataUser.set( this, key, value );
4555			} );
4556		}, null, value, arguments.length > 1, null, true );
4557	},
4558
4559	removeData: function( key ) {
4560		return this.each( function() {
4561			dataUser.remove( this, key );
4562		} );
4563	}
4564} );
4565
4566
4567jQuery.extend( {
4568	queue: function( elem, type, data ) {
4569		var queue;
4570
4571		if ( elem ) {
4572			type = ( type || "fx" ) + "queue";
4573			queue = dataPriv.get( elem, type );
4574
4575			// Speed up dequeue by getting out quickly if this is just a lookup
4576			if ( data ) {
4577				if ( !queue || Array.isArray( data ) ) {
4578					queue = dataPriv.access( elem, type, jQuery.makeArray( data ) );
4579				} else {
4580					queue.push( data );
4581				}
4582			}
4583			return queue || [];
4584		}
4585	},
4586
4587	dequeue: function( elem, type ) {
4588		type = type || "fx";
4589
4590		var queue = jQuery.queue( elem, type ),
4591			startLength = queue.length,
4592			fn = queue.shift(),
4593			hooks = jQuery._queueHooks( elem, type ),
4594			next = function() {
4595				jQuery.dequeue( elem, type );
4596			};
4597
4598		// If the fx queue is dequeued, always remove the progress sentinel
4599		if ( fn === "inprogress" ) {
4600			fn = queue.shift();
4601			startLength--;
4602		}
4603
4604		if ( fn ) {
4605
4606			// Add a progress sentinel to prevent the fx queue from being
4607			// automatically dequeued
4608			if ( type === "fx" ) {
4609				queue.unshift( "inprogress" );
4610			}
4611
4612			// Clear up the last queue stop function
4613			delete hooks.stop;
4614			fn.call( elem, next, hooks );
4615		}
4616
4617		if ( !startLength && hooks ) {
4618			hooks.empty.fire();
4619		}
4620	},
4621
4622	// Not public - generate a queueHooks object, or return the current one
4623	_queueHooks: function( elem, type ) {
4624		var key = type + "queueHooks";
4625		return dataPriv.get( elem, key ) || dataPriv.access( elem, key, {
4626			empty: jQuery.Callbacks( "once memory" ).add( function() {
4627				dataPriv.remove( elem, [ type + "queue", key ] );
4628			} )
4629		} );
4630	}
4631} );
4632
4633jQuery.fn.extend( {
4634	queue: function( type, data ) {
4635		var setter = 2;
4636
4637		if ( typeof type !== "string" ) {
4638			data = type;
4639			type = "fx";
4640			setter--;
4641		}
4642
4643		if ( arguments.length < setter ) {
4644			return jQuery.queue( this[ 0 ], type );
4645		}
4646
4647		return data === undefined ?
4648			this :
4649			this.each( function() {
4650				var queue = jQuery.queue( this, type, data );
4651
4652				// Ensure a hooks for this queue
4653				jQuery._queueHooks( this, type );
4654
4655				if ( type === "fx" && queue[ 0 ] !== "inprogress" ) {
4656					jQuery.dequeue( this, type );
4657				}
4658			} );
4659	},
4660	dequeue: function( type ) {
4661		return this.each( function() {
4662			jQuery.dequeue( this, type );
4663		} );
4664	},
4665	clearQueue: function( type ) {
4666		return this.queue( type || "fx", [] );
4667	},
4668
4669	// Get a promise resolved when queues of a certain type
4670	// are emptied (fx is the type by default)
4671	promise: function( type, obj ) {
4672		var tmp,
vendor: 6,339 bytes, lines 4673-4921
4673			count = 1,
4674			defer = jQuery.Deferred(),
4675			elements = this,
4676			i = this.length,
4677			resolve = function() {
4678				if ( !( --count ) ) {
4679					defer.resolveWith( elements, [ elements ] );
4680				}
4681			};
4682
4683		if ( typeof type !== "string" ) {
4684			obj = type;
4685			type = undefined;
4686		}
4687		type = type || "fx";
4688
4689		while ( i-- ) {
4690			tmp = dataPriv.get( elements[ i ], type + "queueHooks" );
4691			if ( tmp && tmp.empty ) {
4692				count++;
4693				tmp.empty.add( resolve );
4694			}
4695		}
4696		resolve();
4697		return defer.promise( obj );
4698	}
4699} );
4700var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source;
4701
4702var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" );
4703
4704
4705var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
4706
4707var documentElement = document.documentElement;
4708
4709
4710
4711	var isAttached = function( elem ) {
4712			return jQuery.contains( elem.ownerDocument, elem );
4713		},
4714		composed = { composed: true };
4715
4716	// Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only
4717	// Check attachment across shadow DOM boundaries when possible (gh-3504)
4718	// Support: iOS 10.0-10.2 only
4719	// Early iOS 10 versions support `attachShadow` but not `getRootNode`,
4720	// leading to errors. We need to check for `getRootNode`.
4721	if ( documentElement.getRootNode ) {
4722		isAttached = function( elem ) {
4723			return jQuery.contains( elem.ownerDocument, elem ) ||
4724				elem.getRootNode( composed ) === elem.ownerDocument;
4725		};
4726	}
4727var isHiddenWithinTree = function( elem, el ) {
4728
4729		// isHiddenWithinTree might be called from jQuery#filter function;
4730		// in that case, element will be second argument
4731		elem = el || elem;
4732
4733		// Inline style trumps all
4734		return elem.style.display === "none" ||
4735			elem.style.display === "" &&
4736
4737			// Otherwise, check computed style
4738			// Support: Firefox <=43 - 45
4739			// Disconnected elements can have computed display: none, so first confirm that elem is
4740			// in the document.
4741			isAttached( elem ) &&
4742
4743			jQuery.css( elem, "display" ) === "none";
4744	};
4745
4746
4747
4748function adjustCSS( elem, prop, valueParts, tween ) {
4749	var adjusted, scale,
4750		maxIterations = 20,
4751		currentValue = tween ?
4752			function() {
4753				return tween.cur();
4754			} :
4755			function() {
4756				return jQuery.css( elem, prop, "" );
4757			},
4758		initial = currentValue(),
4759		unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
4760
4761		// Starting value computation is required for potential unit mismatches
4762		initialInUnit = elem.nodeType &&
4763			( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) &&
4764			rcssNum.exec( jQuery.css( elem, prop ) );
4765
4766	if ( initialInUnit && initialInUnit[ 3 ] !== unit ) {
4767
4768		// Support: Firefox <=54
4769		// Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144)
4770		initial = initial / 2;
4771
4772		// Trust units reported by jQuery.css
4773		unit = unit || initialInUnit[ 3 ];
4774
4775		// Iteratively approximate from a nonzero starting point
4776		initialInUnit = +initial || 1;
4777
4778		while ( maxIterations-- ) {
4779
4780			// Evaluate and update our best guess (doubling guesses that zero out).
4781			// Finish if the scale equals or crosses 1 (making the old*new product non-positive).
4782			jQuery.style( elem, prop, initialInUnit + unit );
4783			if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) {
4784				maxIterations = 0;
4785			}
4786			initialInUnit = initialInUnit / scale;
4787
4788		}
4789
4790		initialInUnit = initialInUnit * 2;
4791		jQuery.style( elem, prop, initialInUnit + unit );
4792
4793		// Make sure we update the tween properties later on
4794		valueParts = valueParts || [];
4795	}
4796
4797	if ( valueParts ) {
4798		initialInUnit = +initialInUnit || +initial || 0;
4799
4800		// Apply relative offset (+=/-=) if specified
4801		adjusted = valueParts[ 1 ] ?
4802			initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :
4803			+valueParts[ 2 ];
4804		if ( tween ) {
4805			tween.unit = unit;
4806			tween.start = initialInUnit;
4807			tween.end = adjusted;
4808		}
4809	}
4810	return adjusted;
4811}
4812
4813
4814var defaultDisplayMap = {};
4815
4816function getDefaultDisplay( elem ) {
4817	var temp,
4818		doc = elem.ownerDocument,
4819		nodeName = elem.nodeName,
4820		display = defaultDisplayMap[ nodeName ];
4821
4822	if ( display ) {
4823		return display;
4824	}
4825
4826	temp = doc.body.appendChild( doc.createElement( nodeName ) );
4827	display = jQuery.css( temp, "display" );
4828
4829	temp.parentNode.removeChild( temp );
4830
4831	if ( display === "none" ) {
4832		display = "block";
4833	}
4834	defaultDisplayMap[ nodeName ] = display;
4835
4836	return display;
4837}
4838
4839function showHide( elements, show ) {
4840	var display, elem,
4841		values = [],
4842		index = 0,
4843		length = elements.length;
4844
4845	// Determine new display value for elements that need to change
4846	for ( ; index < length; index++ ) {
4847		elem = elements[ index ];
4848		if ( !elem.style ) {
4849			continue;
4850		}
4851
4852		display = elem.style.display;
4853		if ( show ) {
4854
4855			// Since we force visibility upon cascade-hidden elements, an immediate (and slow)
4856			// check is required in this first loop unless we have a nonempty display value (either
4857			// inline or about-to-be-restored)
4858			if ( display === "none" ) {
4859				values[ index ] = dataPriv.get( elem, "display" ) || null;
4860				if ( !values[ index ] ) {
4861					elem.style.display = "";
4862				}
4863			}
4864			if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) {
4865				values[ index ] = getDefaultDisplay( elem );
4866			}
4867		} else {
4868			if ( display !== "none" ) {
4869				values[ index ] = "none";
4870
4871				// Remember what we're overwriting
4872				dataPriv.set( elem, "display", display );
4873			}
4874		}
4875	}
4876
4877	// Set the display of the elements in a second loop to avoid constant reflow
4878	for ( index = 0; index < length; index++ ) {
4879		if ( values[ index ] != null ) {
4880			elements[ index ].style.display = values[ index ];
4881		}
4882	}
4883
4884	return elements;
4885}
4886
4887jQuery.fn.extend( {
4888	show: function() {
4889		return showHide( this, true );
4890	},
4891	hide: function() {
4892		return showHide( this );
4893	},
4894	toggle: function( state ) {
4895		if ( typeof state === "boolean" ) {
4896			return state ? this.show() : this.hide();
4897		}
4898
4899		return this.each( function() {
4900			if ( isHiddenWithinTree( this ) ) {
4901				jQuery( this ).show();
4902			} else {
4903				jQuery( this ).hide();
4904			}
4905		} );
4906	}
4907} );
4908var rcheckableType = ( /^(?:checkbox|radio)$/i );
4909
4910var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]*)/i );
4911
4912var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i );
4913
4914
4915
4916( function() {
4917	var fragment = document.createDocumentFragment(),
4918		div = fragment.appendChild( document.createElement( "div" ) ),
4919		input = document.createElement( "input" );
4920
4921	// Support: Android 4.0 - 4.3 only
vendor: 4,796 bytes, lines 4922-5109
4922	// Check state lost if the name is set (trac-11217)
4923	// Support: Windows Web Apps (WWA)
4924	// `name` and `type` must use .setAttribute for WWA (trac-14901)
4925	input.setAttribute( "type", "radio" );
4926	input.setAttribute( "checked", "checked" );
4927	input.setAttribute( "name", "t" );
4928
4929	div.appendChild( input );
4930
4931	// Support: Android <=4.1 only
4932	// Older WebKit doesn't clone checked state correctly in fragments
4933	support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
4934
4935	// Support: IE <=11 only
4936	// Make sure textarea (and checkbox) defaultValue is properly cloned
4937	div.innerHTML = "<textarea>x</textarea>";
4938	support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
4939
4940	// Support: IE <=9 only
4941	// IE <=9 replaces <option> tags with their contents when inserted outside of
4942	// the select element.
4943	div.innerHTML = "<option></option>";
4944	support.option = !!div.lastChild;
4945} )();
4946
4947
4948// We have to close these tags to support XHTML (trac-13200)
4949var wrapMap = {
4950
4951	// XHTML parsers do not magically insert elements in the
4952	// same way that tag soup parsers do. So we cannot shorten
4953	// this by omitting <tbody> or other required elements.
4954	thead: [ 1, "<table>", "</table>" ],
4955	col: [ 2, "<table><colgroup>", "</colgroup></table>" ],
4956	tr: [ 2, "<table><tbody>", "</tbody></table>" ],
4957	td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
4958
4959	_default: [ 0, "", "" ]
4960};
4961
4962wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
4963wrapMap.th = wrapMap.td;
4964
4965// Support: IE <=9 only
4966if ( !support.option ) {
4967	wrapMap.optgroup = wrapMap.option = [ 1, "<select multiple='multiple'>", "</select>" ];
4968}
4969
4970
4971function getAll( context, tag ) {
4972
4973	// Support: IE <=9 - 11 only
4974	// Use typeof to avoid zero-argument method invocation on host objects (trac-15151)
4975	var ret;
4976
4977	if ( typeof context.getElementsByTagName !== "undefined" ) {
4978		ret = context.getElementsByTagName( tag || "*" );
4979
4980	} else if ( typeof context.querySelectorAll !== "undefined" ) {
4981		ret = context.querySelectorAll( tag || "*" );
4982
4983	} else {
4984		ret = [];
4985	}
4986
4987	if ( tag === undefined || tag && nodeName( context, tag ) ) {
4988		return jQuery.merge( [ context ], ret );
4989	}
4990
4991	return ret;
4992}
4993
4994
4995// Mark scripts as having already been evaluated
4996function setGlobalEval( elems, refElements ) {
4997	var i = 0,
4998		l = elems.length;
4999
5000	for ( ; i < l; i++ ) {
5001		dataPriv.set(
5002			elems[ i ],
5003			"globalEval",
5004			!refElements || dataPriv.get( refElements[ i ], "globalEval" )
5005		);
5006	}
5007}
5008
5009
5010var rhtml = /<|&#?\w+;/;
5011
5012function buildFragment( elems, context, scripts, selection, ignored ) {
5013	var elem, tmp, tag, wrap, attached, j,
5014		fragment = context.createDocumentFragment(),
5015		nodes = [],
5016		i = 0,
5017		l = elems.length;
5018
5019	for ( ; i < l; i++ ) {
5020		elem = elems[ i ];
5021
5022		if ( elem || elem === 0 ) {
5023
5024			// Add nodes directly
5025			if ( toType( elem ) === "object" ) {
5026
5027				// Support: Android <=4.0 only, PhantomJS 1 only
5028				// push.apply(_, arraylike) throws on ancient WebKit
5029				jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
5030
5031			// Convert non-html into a text node
5032			} else if ( !rhtml.test( elem ) ) {
5033				nodes.push( context.createTextNode( elem ) );
5034
5035			// Convert html into DOM nodes
5036			} else {
5037				tmp = tmp || fragment.appendChild( context.createElement( "div" ) );
5038
5039				// Deserialize a standard representation
5040				tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
5041				wrap = wrapMap[ tag ] || wrapMap._default;
5042				tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];
5043
5044				// Descend through wrappers to the right content
5045				j = wrap[ 0 ];
5046				while ( j-- ) {
5047					tmp = tmp.lastChild;
5048				}
5049
5050				// Support: Android <=4.0 only, PhantomJS 1 only
5051				// push.apply(_, arraylike) throws on ancient WebKit
5052				jQuery.merge( nodes, tmp.childNodes );
5053
5054				// Remember the top-level container
5055				tmp = fragment.firstChild;
5056
5057				// Ensure the created nodes are orphaned (trac-12392)
5058				tmp.textContent = "";
5059			}
5060		}
5061	}
5062
5063	// Remove wrapper from fragment
5064	fragment.textContent = "";
5065
5066	i = 0;
5067	while ( ( elem = nodes[ i++ ] ) ) {
5068
5069		// Skip elements already in the context collection (trac-4087)
5070		if ( selection && jQuery.inArray( elem, selection ) > -1 ) {
5071			if ( ignored ) {
5072				ignored.push( elem );
5073			}
5074			continue;
5075		}
5076
5077		attached = isAttached( elem );
5078
5079		// Append to fragment
5080		tmp = getAll( fragment.appendChild( elem ), "script" );
5081
5082		// Preserve script evaluation history
5083		if ( attached ) {
5084			setGlobalEval( tmp );
5085		}
5086
5087		// Capture executables
5088		if ( scripts ) {
5089			j = 0;
5090			while ( ( elem = tmp[ j++ ] ) ) {
5091				if ( rscriptType.test( elem.type || "" ) ) {
5092					scripts.push( elem );
5093				}
5094			}
5095		}
5096	}
5097
5098	return fragment;
5099}
5100
5101
5102var rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
5103
5104function returnTrue() {
5105	return true;
5106}
5107
5108function returnFalse() {
5109	return false;
vendor: 10,171 bytes, lines 5110-5464
5110}
5111
5112// Support: IE <=9 - 11+
5113// focus() and blur() are asynchronous, except when they are no-op.
5114// So expect focus to be synchronous when the element is already active,
5115// and blur to be synchronous when the element is not already active.
5116// (focus and blur are always synchronous in other supported browsers,
5117// this just defines when we can count on it).
5118function expectSync( elem, type ) {
5119	return ( elem === safeActiveElement() ) === ( type === "focus" );
5120}
5121
5122// Support: IE <=9 only
5123// Accessing document.activeElement can throw unexpectedly
5124// https://bugs.jquery.com/ticket/13393
5125function safeActiveElement() {
5126	try {
5127		return document.activeElement;
5128	} catch ( err ) { }
5129}
5130
5131function on( elem, types, selector, data, fn, one ) {
5132	var origFn, type;
5133
5134	// Types can be a map of types/handlers
5135	if ( typeof types === "object" ) {
5136
5137		// ( types-Object, selector, data )
5138		if ( typeof selector !== "string" ) {
5139
5140			// ( types-Object, data )
5141			data = data || selector;
5142			selector = undefined;
5143		}
5144		for ( type in types ) {
5145			on( elem, type, selector, data, types[ type ], one );
5146		}
5147		return elem;
5148	}
5149
5150	if ( data == null && fn == null ) {
5151
5152		// ( types, fn )
5153		fn = selector;
5154		data = selector = undefined;
5155	} else if ( fn == null ) {
5156		if ( typeof selector === "string" ) {
5157
5158			// ( types, selector, fn )
5159			fn = data;
5160			data = undefined;
5161		} else {
5162
5163			// ( types, data, fn )
5164			fn = data;
5165			data = selector;
5166			selector = undefined;
5167		}
5168	}
5169	if ( fn === false ) {
5170		fn = returnFalse;
5171	} else if ( !fn ) {
5172		return elem;
5173	}
5174
5175	if ( one === 1 ) {
5176		origFn = fn;
5177		fn = function( event ) {
5178
5179			// Can use an empty set, since event contains the info
5180			jQuery().off( event );
5181			return origFn.apply( this, arguments );
5182		};
5183
5184		// Use same guid so caller can remove using origFn
5185		fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
5186	}
5187	return elem.each( function() {
5188		jQuery.event.add( this, types, fn, data, selector );
5189	} );
5190}
5191
5192/*
5193 * Helper functions for managing events -- not part of the public interface.
5194 * Props to Dean Edwards' addEvent library for many of the ideas.
5195 */
5196jQuery.event = {
5197
5198	global: {},
5199
5200	add: function( elem, types, handler, data, selector ) {
5201
5202		var handleObjIn, eventHandle, tmp,
5203			events, t, handleObj,
5204			special, handlers, type, namespaces, origType,
5205			elemData = dataPriv.get( elem );
5206
5207		// Only attach events to objects that accept data
5208		if ( !acceptData( elem ) ) {
5209			return;
5210		}
5211
5212		// Caller can pass in an object of custom data in lieu of the handler
5213		if ( handler.handler ) {
5214			handleObjIn = handler;
5215			handler = handleObjIn.handler;
5216			selector = handleObjIn.selector;
5217		}
5218
5219		// Ensure that invalid selectors throw exceptions at attach time
5220		// Evaluate against documentElement in case elem is a non-element node (e.g., document)
5221		if ( selector ) {
5222			jQuery.find.matchesSelector( documentElement, selector );
5223		}
5224
5225		// Make sure that the handler has a unique ID, used to find/remove it later
5226		if ( !handler.guid ) {
5227			handler.guid = jQuery.guid++;
5228		}
5229
5230		// Init the element's event structure and main handler, if this is the first
5231		if ( !( events = elemData.events ) ) {
5232			events = elemData.events = Object.create( null );
5233		}
5234		if ( !( eventHandle = elemData.handle ) ) {
5235			eventHandle = elemData.handle = function( e ) {
5236
5237				// Discard the second event of a jQuery.event.trigger() and
5238				// when an event is called after a page has unloaded
5239				return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ?
5240					jQuery.event.dispatch.apply( elem, arguments ) : undefined;
5241			};
5242		}
5243
5244		// Handle multiple events separated by a space
5245		types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
5246		t = types.length;
5247		while ( t-- ) {
5248			tmp = rtypenamespace.exec( types[ t ] ) || [];
5249			type = origType = tmp[ 1 ];
5250			namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
5251
5252			// There *must* be a type, no attaching namespace-only handlers
5253			if ( !type ) {
5254				continue;
5255			}
5256
5257			// If event changes its type, use the special event handlers for the changed type
5258			special = jQuery.event.special[ type ] || {};
5259
5260			// If selector defined, determine special event api type, otherwise given type
5261			type = ( selector ? special.delegateType : special.bindType ) || type;
5262
5263			// Update special based on newly reset type
5264			special = jQuery.event.special[ type ] || {};
5265
5266			// handleObj is passed to all event handlers
5267			handleObj = jQuery.extend( {
5268				type: type,
5269				origType: origType,
5270				data: data,
5271				handler: handler,
5272				guid: handler.guid,
5273				selector: selector,
5274				needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
5275				namespace: namespaces.join( "." )
5276			}, handleObjIn );
5277
5278			// Init the event handler queue if we're the first
5279			if ( !( handlers = events[ type ] ) ) {
5280				handlers = events[ type ] = [];
5281				handlers.delegateCount = 0;
5282
5283				// Only use addEventListener if the special events handler returns false
5284				if ( !special.setup ||
5285					special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
5286
5287					if ( elem.addEventListener ) {
5288						elem.addEventListener( type, eventHandle );
5289					}
5290				}
5291			}
5292
5293			if ( special.add ) {
5294				special.add.call( elem, handleObj );
5295
5296				if ( !handleObj.handler.guid ) {
5297					handleObj.handler.guid = handler.guid;
5298				}
5299			}
5300
5301			// Add to the element's handler list, delegates in front
5302			if ( selector ) {
5303				handlers.splice( handlers.delegateCount++, 0, handleObj );
5304			} else {
5305				handlers.push( handleObj );
5306			}
5307
5308			// Keep track of which events have ever been used, for event optimization
5309			jQuery.event.global[ type ] = true;
5310		}
5311
5312	},
5313
5314	// Detach an event or set of events from an element
5315	remove: function( elem, types, handler, selector, mappedTypes ) {
5316
5317		var j, origCount, tmp,
5318			events, t, handleObj,
5319			special, handlers, type, namespaces, origType,
5320			elemData = dataPriv.hasData( elem ) && dataPriv.get( elem );
5321
5322		if ( !elemData || !( events = elemData.events ) ) {
5323			return;
5324		}
5325
5326		// Once for each type.namespace in types; type may be omitted
5327		types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
5328		t = types.length;
5329		while ( t-- ) {
5330			tmp = rtypenamespace.exec( types[ t ] ) || [];
5331			type = origType = tmp[ 1 ];
5332			namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
5333
5334			// Unbind all events (on this namespace, if provided) for the element
5335			if ( !type ) {
5336				for ( type in events ) {
5337					jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
5338				}
5339				continue;
5340			}
5341
5342			special = jQuery.event.special[ type ] || {};
5343			type = ( selector ? special.delegateType : special.bindType ) || type;
5344			handlers = events[ type ] || [];
5345			tmp = tmp[ 2 ] &&
5346				new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" );
5347
5348			// Remove matching events
5349			origCount = j = handlers.length;
5350			while ( j-- ) {
5351				handleObj = handlers[ j ];
5352
5353				if ( ( mappedTypes || origType === handleObj.origType ) &&
5354					( !handler || handler.guid === handleObj.guid ) &&
5355					( !tmp || tmp.test( handleObj.namespace ) ) &&
5356					( !selector || selector === handleObj.selector ||
5357						selector === "**" && handleObj.selector ) ) {
5358					handlers.splice( j, 1 );
5359
5360					if ( handleObj.selector ) {
5361						handlers.delegateCount--;
5362					}
5363					if ( special.remove ) {
5364						special.remove.call( elem, handleObj );
5365					}
5366				}
5367			}
5368
5369			// Remove generic event handler if we removed something and no more handlers exist
5370			// (avoids potential for endless recursion during removal of special event handlers)
5371			if ( origCount && !handlers.length ) {
5372				if ( !special.teardown ||
5373					special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
5374
5375					jQuery.removeEvent( elem, type, elemData.handle );
5376				}
5377
5378				delete events[ type ];
5379			}
5380		}
5381
5382		// Remove data and the expando if it's no longer used
5383		if ( jQuery.isEmptyObject( events ) ) {
5384			dataPriv.remove( elem, "handle events" );
5385		}
5386	},
5387
5388	dispatch: function( nativeEvent ) {
5389
5390		var i, j, ret, matched, handleObj, handlerQueue,
5391			args = new Array( arguments.length ),
5392
5393			// Make a writable jQuery.Event from the native event object
5394			event = jQuery.event.fix( nativeEvent ),
5395
5396			handlers = (
5397				dataPriv.get( this, "events" ) || Object.create( null )
5398			)[ event.type ] || [],
5399			special = jQuery.event.special[ event.type ] || {};
5400
5401		// Use the fix-ed jQuery.Event rather than the (read-only) native event
5402		args[ 0 ] = event;
5403
5404		for ( i = 1; i < arguments.length; i++ ) {
5405			args[ i ] = arguments[ i ];
5406		}
5407
5408		event.delegateTarget = this;
5409
5410		// Call the preDispatch hook for the mapped type, and let it bail if desired
5411		if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
5412			return;
5413		}
5414
5415		// Determine handlers
5416		handlerQueue = jQuery.event.handlers.call( this, event, handlers );
5417
5418		// Run delegates first; they may want to stop propagation beneath us
5419		i = 0;
5420		while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {
5421			event.currentTarget = matched.elem;
5422
5423			j = 0;
5424			while ( ( handleObj = matched.handlers[ j++ ] ) &&
5425				!event.isImmediatePropagationStopped() ) {
5426
5427				// If the event is namespaced, then each handler is only invoked if it is
5428				// specially universal or its namespaces are a superset of the event's.
5429				if ( !event.rnamespace || handleObj.namespace === false ||
5430					event.rnamespace.test( handleObj.namespace ) ) {
5431
5432					event.handleObj = handleObj;
5433					event.data = handleObj.data;
5434
5435					ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||
5436						handleObj.handler ).apply( matched.elem, args );
5437
5438					if ( ret !== undefined ) {
5439						if ( ( event.result = ret ) === false ) {
5440							event.preventDefault();
5441							event.stopPropagation();
5442						}
5443					}
5444				}
5445			}
5446		}
5447
5448		// Call the postDispatch hook for the mapped type
5449		if ( special.postDispatch ) {
5450			special.postDispatch.call( this, event );
5451		}
5452
5453		return event.result;
5454	},
5455
5456	handlers: function( event, handlers ) {
5457		var i, handleObj, sel, matchedHandlers, matchedSelectors,
5458			handlerQueue = [],
5459			delegateCount = handlers.delegateCount,
5460			cur = event.target;
5461
5462		// Find delegate handlers
5463		if ( delegateCount &&
5464
vendor: 21,304 bytes, lines 5465-6225
5465			// Support: IE <=9
5466			// Black-hole SVG <use> instance trees (trac-13180)
5467			cur.nodeType &&
5468
5469			// Support: Firefox <=42
5470			// Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861)
5471			// https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click
5472			// Support: IE 11 only
5473			// ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343)
5474			!( event.type === "click" && event.button >= 1 ) ) {
5475
5476			for ( ; cur !== this; cur = cur.parentNode || this ) {
5477
5478				// Don't check non-elements (trac-13208)
5479				// Don't process clicks on disabled elements (trac-6911, trac-8165, trac-11382, trac-11764)
5480				if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) {
5481					matchedHandlers = [];
5482					matchedSelectors = {};
5483					for ( i = 0; i < delegateCount; i++ ) {
5484						handleObj = handlers[ i ];
5485
5486						// Don't conflict with Object.prototype properties (trac-13203)
5487						sel = handleObj.selector + " ";
5488
5489						if ( matchedSelectors[ sel ] === undefined ) {
5490							matchedSelectors[ sel ] = handleObj.needsContext ?
5491								jQuery( sel, this ).index( cur ) > -1 :
5492								jQuery.find( sel, this, null, [ cur ] ).length;
5493						}
5494						if ( matchedSelectors[ sel ] ) {
5495							matchedHandlers.push( handleObj );
5496						}
5497					}
5498					if ( matchedHandlers.length ) {
5499						handlerQueue.push( { elem: cur, handlers: matchedHandlers } );
5500					}
5501				}
5502			}
5503		}
5504
5505		// Add the remaining (directly-bound) handlers
5506		cur = this;
5507		if ( delegateCount < handlers.length ) {
5508			handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } );
5509		}
5510
5511		return handlerQueue;
5512	},
5513
5514	addProp: function( name, hook ) {
5515		Object.defineProperty( jQuery.Event.prototype, name, {
5516			enumerable: true,
5517			configurable: true,
5518
5519			get: isFunction( hook ) ?
5520				function() {
5521					if ( this.originalEvent ) {
5522						return hook( this.originalEvent );
5523					}
5524				} :
5525				function() {
5526					if ( this.originalEvent ) {
5527						return this.originalEvent[ name ];
5528					}
5529				},
5530
5531			set: function( value ) {
5532				Object.defineProperty( this, name, {
5533					enumerable: true,
5534					configurable: true,
5535					writable: true,
5536					value: value
5537				} );
5538			}
5539		} );
5540	},
5541
5542	fix: function( originalEvent ) {
5543		return originalEvent[ jQuery.expando ] ?
5544			originalEvent :
5545			new jQuery.Event( originalEvent );
5546	},
5547
5548	special: {
5549		load: {
5550
5551			// Prevent triggered image.load events from bubbling to window.load
5552			noBubble: true
5553		},
5554		click: {
5555
5556			// Utilize native event to ensure correct state for checkable inputs
5557			setup: function( data ) {
5558
5559				// For mutual compressibility with _default, replace `this` access with a local var.
5560				// `|| data` is dead code meant only to preserve the variable through minification.
5561				var el = this || data;
5562
5563				// Claim the first handler
5564				if ( rcheckableType.test( el.type ) &&
5565					el.click && nodeName( el, "input" ) ) {
5566
5567					// dataPriv.set( el, "click", ... )
5568					leverageNative( el, "click", returnTrue );
5569				}
5570
5571				// Return false to allow normal processing in the caller
5572				return false;
5573			},
5574			trigger: function( data ) {
5575
5576				// For mutual compressibility with _default, replace `this` access with a local var.
5577				// `|| data` is dead code meant only to preserve the variable through minification.
5578				var el = this || data;
5579
5580				// Force setup before triggering a click
5581				if ( rcheckableType.test( el.type ) &&
5582					el.click && nodeName( el, "input" ) ) {
5583
5584					leverageNative( el, "click" );
5585				}
5586
5587				// Return non-false to allow normal event-path propagation
5588				return true;
5589			},
5590
5591			// For cross-browser consistency, suppress native .click() on links
5592			// Also prevent it if we're currently inside a leveraged native-event stack
5593			_default: function( event ) {
5594				var target = event.target;
5595				return rcheckableType.test( target.type ) &&
5596					target.click && nodeName( target, "input" ) &&
5597					dataPriv.get( target, "click" ) ||
5598					nodeName( target, "a" );
5599			}
5600		},
5601
5602		beforeunload: {
5603			postDispatch: function( event ) {
5604
5605				// Support: Firefox 20+
5606				// Firefox doesn't alert if the returnValue field is not set.
5607				if ( event.result !== undefined && event.originalEvent ) {
5608					event.originalEvent.returnValue = event.result;
5609				}
5610			}
5611		}
5612	}
5613};
5614
5615// Ensure the presence of an event listener that handles manually-triggered
5616// synthetic events by interrupting progress until reinvoked in response to
5617// *native* events that it fires directly, ensuring that state changes have
5618// already occurred before other listeners are invoked.
5619function leverageNative( el, type, expectSync ) {
5620
5621	// Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add
5622	if ( !expectSync ) {
5623		if ( dataPriv.get( el, type ) === undefined ) {
5624			jQuery.event.add( el, type, returnTrue );
5625		}
5626		return;
5627	}
5628
5629	// Register the controller as a special universal handler for all event namespaces
5630	dataPriv.set( el, type, false );
5631	jQuery.event.add( el, type, {
5632		namespace: false,
5633		handler: function( event ) {
5634			var notAsync, result,
5635				saved = dataPriv.get( this, type );
5636
5637			if ( ( event.isTrigger & 1 ) && this[ type ] ) {
5638
5639				// Interrupt processing of the outer synthetic .trigger()ed event
5640				// Saved data should be false in such cases, but might be a leftover capture object
5641				// from an async native handler (gh-4350)
5642				if ( !saved.length ) {
5643
5644					// Store arguments for use when handling the inner native event
5645					// There will always be at least one argument (an event object), so this array
5646					// will not be confused with a leftover capture object.
5647					saved = slice.call( arguments );
5648					dataPriv.set( this, type, saved );
5649
5650					// Trigger the native event and capture its result
5651					// Support: IE <=9 - 11+
5652					// focus() and blur() are asynchronous
5653					notAsync = expectSync( this, type );
5654					this[ type ]();
5655					result = dataPriv.get( this, type );
5656					if ( saved !== result || notAsync ) {
5657						dataPriv.set( this, type, false );
5658					} else {
5659						result = {};
5660					}
5661					if ( saved !== result ) {
5662
5663						// Cancel the outer synthetic event
5664						event.stopImmediatePropagation();
5665						event.preventDefault();
5666
5667						// Support: Chrome 86+
5668						// In Chrome, if an element having a focusout handler is blurred by
5669						// clicking outside of it, it invokes the handler synchronously. If
5670						// that handler calls `.remove()` on the element, the data is cleared,
5671						// leaving `result` undefined. We need to guard against this.
5672						return result && result.value;
5673					}
5674
5675				// If this is an inner synthetic event for an event with a bubbling surrogate
5676				// (focus or blur), assume that the surrogate already propagated from triggering the
5677				// native event and prevent that from happening again here.
5678				// This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the
5679				// bubbling surrogate propagates *after* the non-bubbling base), but that seems
5680				// less bad than duplication.
5681				} else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) {
5682					event.stopPropagation();
5683				}
5684
5685			// If this is a native event triggered above, everything is now in order
5686			// Fire an inner synthetic event with the original arguments
5687			} else if ( saved.length ) {
5688
5689				// ...and capture the result
5690				dataPriv.set( this, type, {
5691					value: jQuery.event.trigger(
5692
5693						// Support: IE <=9 - 11+
5694						// Extend with the prototype to reset the above stopImmediatePropagation()
5695						jQuery.extend( saved[ 0 ], jQuery.Event.prototype ),
5696						saved.slice( 1 ),
5697						this
5698					)
5699				} );
5700
5701				// Abort handling of the native event
5702				event.stopImmediatePropagation();
5703			}
5704		}
5705	} );
5706}
5707
5708jQuery.removeEvent = function( elem, type, handle ) {
5709
5710	// This "if" is needed for plain objects
5711	if ( elem.removeEventListener ) {
5712		elem.removeEventListener( type, handle );
5713	}
5714};
5715
5716jQuery.Event = function( src, props ) {
5717
5718	// Allow instantiation without the 'new' keyword
5719	if ( !( this instanceof jQuery.Event ) ) {
5720		return new jQuery.Event( src, props );
5721	}
5722
5723	// Event object
5724	if ( src && src.type ) {
5725		this.originalEvent = src;
5726		this.type = src.type;
5727
5728		// Events bubbling up the document may have been marked as prevented
5729		// by a handler lower down the tree; reflect the correct value.
5730		this.isDefaultPrevented = src.defaultPrevented ||
5731				src.defaultPrevented === undefined &&
5732
5733				// Support: Android <=2.3 only
5734				src.returnValue === false ?
5735			returnTrue :
5736			returnFalse;
5737
5738		// Create target properties
5739		// Support: Safari <=6 - 7 only
5740		// Target should not be a text node (trac-504, trac-13143)
5741		this.target = ( src.target && src.target.nodeType === 3 ) ?
5742			src.target.parentNode :
5743			src.target;
5744
5745		this.currentTarget = src.currentTarget;
5746		this.relatedTarget = src.relatedTarget;
5747
5748	// Event type
5749	} else {
5750		this.type = src;
5751	}
5752
5753	// Put explicitly provided properties onto the event object
5754	if ( props ) {
5755		jQuery.extend( this, props );
5756	}
5757
5758	// Create a timestamp if incoming event doesn't have one
5759	this.timeStamp = src && src.timeStamp || Date.now();
5760
5761	// Mark it as fixed
5762	this[ jQuery.expando ] = true;
5763};
5764
5765// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
5766// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
5767jQuery.Event.prototype = {
5768	constructor: jQuery.Event,
5769	isDefaultPrevented: returnFalse,
5770	isPropagationStopped: returnFalse,
5771	isImmediatePropagationStopped: returnFalse,
5772	isSimulated: false,
5773
5774	preventDefault: function() {
5775		var e = this.originalEvent;
5776
5777		this.isDefaultPrevented = returnTrue;
5778
5779		if ( e && !this.isSimulated ) {
5780			e.preventDefault();
5781		}
5782	},
5783	stopPropagation: function() {
5784		var e = this.originalEvent;
5785
5786		this.isPropagationStopped = returnTrue;
5787
5788		if ( e && !this.isSimulated ) {
5789			e.stopPropagation();
5790		}
5791	},
5792	stopImmediatePropagation: function() {
5793		var e = this.originalEvent;
5794
5795		this.isImmediatePropagationStopped = returnTrue;
5796
5797		if ( e && !this.isSimulated ) {
5798			e.stopImmediatePropagation();
5799		}
5800
5801		this.stopPropagation();
5802	}
5803};
5804
5805// Includes all common event props including KeyEvent and MouseEvent specific props
5806jQuery.each( {
5807	altKey: true,
5808	bubbles: true,
5809	cancelable: true,
5810	changedTouches: true,
5811	ctrlKey: true,
5812	detail: true,
5813	eventPhase: true,
5814	metaKey: true,
5815	pageX: true,
5816	pageY: true,
5817	shiftKey: true,
5818	view: true,
5819	"char": true,
5820	code: true,
5821	charCode: true,
5822	key: true,
5823	keyCode: true,
5824	button: true,
5825	buttons: true,
5826	clientX: true,
5827	clientY: true,
5828	offsetX: true,
5829	offsetY: true,
5830	pointerId: true,
5831	pointerType: true,
5832	screenX: true,
5833	screenY: true,
5834	targetTouches: true,
5835	toElement: true,
5836	touches: true,
5837	which: true
5838}, jQuery.event.addProp );
5839
5840jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateType ) {
5841	jQuery.event.special[ type ] = {
5842
5843		// Utilize native event if possible so blur/focus sequence is correct
5844		setup: function() {
5845
5846			// Claim the first handler
5847			// dataPriv.set( this, "focus", ... )
5848			// dataPriv.set( this, "blur", ... )
5849			leverageNative( this, type, expectSync );
5850
5851			// Return false to allow normal processing in the caller
5852			return false;
5853		},
5854		trigger: function() {
5855
5856			// Force setup before trigger
5857			leverageNative( this, type );
5858
5859			// Return non-false to allow normal event-path propagation
5860			return true;
5861		},
5862
5863		// Suppress native focus or blur if we're currently inside
5864		// a leveraged native-event stack
5865		_default: function( event ) {
5866			return dataPriv.get( event.target, type );
5867		},
5868
5869		delegateType: delegateType
5870	};
5871} );
5872
5873// Create mouseenter/leave events using mouseover/out and event-time checks
5874// so that event delegation works in jQuery.
5875// Do the same for pointerenter/pointerleave and pointerover/pointerout
5876//
5877// Support: Safari 7 only
5878// Safari sends mouseenter too often; see:
5879// https://bugs.chromium.org/p/chromium/issues/detail?id=470258
5880// for the description of the bug (it existed in older Chrome versions as well).
5881jQuery.each( {
5882	mouseenter: "mouseover",
5883	mouseleave: "mouseout",
5884	pointerenter: "pointerover",
5885	pointerleave: "pointerout"
5886}, function( orig, fix ) {
5887	jQuery.event.special[ orig ] = {
5888		delegateType: fix,
5889		bindType: fix,
5890
5891		handle: function( event ) {
5892			var ret,
5893				target = this,
5894				related = event.relatedTarget,
5895				handleObj = event.handleObj;
5896
5897			// For mouseenter/leave call the handler if related is outside the target.
5898			// NB: No relatedTarget if the mouse left/entered the browser window
5899			if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {
5900				event.type = handleObj.origType;
5901				ret = handleObj.handler.apply( this, arguments );
5902				event.type = fix;
5903			}
5904			return ret;
5905		}
5906	};
5907} );
5908
5909jQuery.fn.extend( {
5910
5911	on: function( types, selector, data, fn ) {
5912		return on( this, types, selector, data, fn );
5913	},
5914	one: function( types, selector, data, fn ) {
5915		return on( this, types, selector, data, fn, 1 );
5916	},
5917	off: function( types, selector, fn ) {
5918		var handleObj, type;
5919		if ( types && types.preventDefault && types.handleObj ) {
5920
5921			// ( event )  dispatched jQuery.Event
5922			handleObj = types.handleObj;
5923			jQuery( types.delegateTarget ).off(
5924				handleObj.namespace ?
5925					handleObj.origType + "." + handleObj.namespace :
5926					handleObj.origType,
5927				handleObj.selector,
5928				handleObj.handler
5929			);
5930			return this;
5931		}
5932		if ( typeof types === "object" ) {
5933
5934			// ( types-object [, selector] )
5935			for ( type in types ) {
5936				this.off( type, selector, types[ type ] );
5937			}
5938			return this;
5939		}
5940		if ( selector === false || typeof selector === "function" ) {
5941
5942			// ( types [, fn] )
5943			fn = selector;
5944			selector = undefined;
5945		}
5946		if ( fn === false ) {
5947			fn = returnFalse;
5948		}
5949		return this.each( function() {
5950			jQuery.event.remove( this, types, fn, selector );
5951		} );
5952	}
5953} );
5954
5955
5956var
5957
5958	// Support: IE <=10 - 11, Edge 12 - 13 only
5959	// In IE/Edge using regex groups here causes severe slowdowns.
5960	// See https://connect.microsoft.com/IE/feedback/details/1736512/
5961	rnoInnerhtml = /<script|<style|<link/i,
5962
5963	// checked="checked" or checked
5964	rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
5965
5966	rcleanScript = /^\s*<!\[CDATA\[|\]\]>\s*$/g;
5967
5968// Prefer a tbody over its parent table for containing new rows
5969function manipulationTarget( elem, content ) {
5970	if ( nodeName( elem, "table" ) &&
5971		nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) {
5972
5973		return jQuery( elem ).children( "tbody" )[ 0 ] || elem;
5974	}
5975
5976	return elem;
5977}
5978
5979// Replace/restore the type attribute of script elements for safe DOM manipulation
5980function disableScript( elem ) {
5981	elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type;
5982	return elem;
5983}
5984function restoreScript( elem ) {
5985	if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) {
5986		elem.type = elem.type.slice( 5 );
5987	} else {
5988		elem.removeAttribute( "type" );
5989	}
5990
5991	return elem;
5992}
5993
5994function cloneCopyEvent( src, dest ) {
5995	var i, l, type, pdataOld, udataOld, udataCur, events;
5996
5997	if ( dest.nodeType !== 1 ) {
5998		return;
5999	}
6000
6001	// 1. Copy private data: events, handlers, etc.
6002	if ( dataPriv.hasData( src ) ) {
6003		pdataOld = dataPriv.get( src );
6004		events = pdataOld.events;
6005
6006		if ( events ) {
6007			dataPriv.remove( dest, "handle events" );
6008
6009			for ( type in events ) {
6010				for ( i = 0, l = events[ type ].length; i < l; i++ ) {
6011					jQuery.event.add( dest, type, events[ type ][ i ] );
6012				}
6013			}
6014		}
6015	}
6016
6017	// 2. Copy user data
6018	if ( dataUser.hasData( src ) ) {
6019		udataOld = dataUser.access( src );
6020		udataCur = jQuery.extend( {}, udataOld );
6021
6022		dataUser.set( dest, udataCur );
6023	}
6024}
6025
6026// Fix IE bugs, see support tests
6027function fixInput( src, dest ) {
6028	var nodeName = dest.nodeName.toLowerCase();
6029
6030	// Fails to persist the checked state of a cloned checkbox or radio button.
6031	if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
6032		dest.checked = src.checked;
6033
6034	// Fails to return the selected option to the default selected state when cloning options
6035	} else if ( nodeName === "input" || nodeName === "textarea" ) {
6036		dest.defaultValue = src.defaultValue;
6037	}
6038}
6039
6040function domManip( collection, args, callback, ignored ) {
6041
6042	// Flatten any nested arrays
6043	args = flat( args );
6044
6045	var fragment, first, scripts, hasScripts, node, doc,
6046		i = 0,
6047		l = collection.length,
6048		iNoClone = l - 1,
6049		value = args[ 0 ],
6050		valueIsFunction = isFunction( value );
6051
6052	// We can't cloneNode fragments that contain checked, in WebKit
6053	if ( valueIsFunction ||
6054			( l > 1 && typeof value === "string" &&
6055				!support.checkClone && rchecked.test( value ) ) ) {
6056		return collection.each( function( index ) {
6057			var self = collection.eq( index );
6058			if ( valueIsFunction ) {
6059				args[ 0 ] = value.call( this, index, self.html() );
6060			}
6061			domManip( self, args, callback, ignored );
6062		} );
6063	}
6064
6065	if ( l ) {
6066		fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );
6067		first = fragment.firstChild;
6068
6069		if ( fragment.childNodes.length === 1 ) {
6070			fragment = first;
6071		}
6072
6073		// Require either new content or an interest in ignored elements to invoke the callback
6074		if ( first || ignored ) {
6075			scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
6076			hasScripts = scripts.length;
6077
6078			// Use the original fragment for the last item
6079			// instead of the first because it can end up
6080			// being emptied incorrectly in certain situations (trac-8070).
6081			for ( ; i < l; i++ ) {
6082				node = fragment;
6083
6084				if ( i !== iNoClone ) {
6085					node = jQuery.clone( node, true, true );
6086
6087					// Keep references to cloned scripts for later restoration
6088					if ( hasScripts ) {
6089
6090						// Support: Android <=4.0 only, PhantomJS 1 only
6091						// push.apply(_, arraylike) throws on ancient WebKit
6092						jQuery.merge( scripts, getAll( node, "script" ) );
6093					}
6094				}
6095
6096				callback.call( collection[ i ], node, i );
6097			}
6098
6099			if ( hasScripts ) {
6100				doc = scripts[ scripts.length - 1 ].ownerDocument;
6101
6102				// Reenable scripts
6103				jQuery.map( scripts, restoreScript );
6104
6105				// Evaluate executable scripts on first document insertion
6106				for ( i = 0; i < hasScripts; i++ ) {
6107					node = scripts[ i ];
6108					if ( rscriptType.test( node.type || "" ) &&
6109						!dataPriv.access( node, "globalEval" ) &&
6110						jQuery.contains( doc, node ) ) {
6111
6112						if ( node.src && ( node.type || "" ).toLowerCase()  !== "module" ) {
6113
6114							// Optional AJAX dependency, but won't run scripts if not present
6115							if ( jQuery._evalUrl && !node.noModule ) {
6116								jQuery._evalUrl( node.src, {
6117									nonce: node.nonce || node.getAttribute( "nonce" )
6118								}, doc );
6119							}
6120						} else {
6121
6122							// Unwrap a CDATA section containing script contents. This shouldn't be
6123							// needed as in XML documents they're already not visible when
6124							// inspecting element contents and in HTML documents they have no
6125							// meaning but we're preserving that logic for backwards compatibility.
6126							// This will be removed completely in 4.0. See gh-4904.
6127							DOMEval( node.textContent.replace( rcleanScript, "" ), node, doc );
6128						}
6129					}
6130				}
6131			}
6132		}
6133	}
6134
6135	return collection;
6136}
6137
6138function remove( elem, selector, keepData ) {
6139	var node,
6140		nodes = selector ? jQuery.filter( selector, elem ) : elem,
6141		i = 0;
6142
6143	for ( ; ( node = nodes[ i ] ) != null; i++ ) {
6144		if ( !keepData && node.nodeType === 1 ) {
6145			jQuery.cleanData( getAll( node ) );
6146		}
6147
6148		if ( node.parentNode ) {
6149			if ( keepData && isAttached( node ) ) {
6150				setGlobalEval( getAll( node, "script" ) );
6151			}
6152			node.parentNode.removeChild( node );
6153		}
6154	}
6155
6156	return elem;
6157}
6158
6159jQuery.extend( {
6160	htmlPrefilter: function( html ) {
6161		return html;
6162	},
6163
6164	clone: function( elem, dataAndEvents, deepDataAndEvents ) {
6165		var i, l, srcElements, destElements,
6166			clone = elem.cloneNode( true ),
6167			inPage = isAttached( elem );
6168
6169		// Fix IE cloning issues
6170		if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&
6171				!jQuery.isXMLDoc( elem ) ) {
6172
6173			// We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2
6174			destElements = getAll( clone );
6175			srcElements = getAll( elem );
6176
6177			for ( i = 0, l = srcElements.length; i < l; i++ ) {
6178				fixInput( srcElements[ i ], destElements[ i ] );
6179			}
6180		}
6181
6182		// Copy the events from the original to the clone
6183		if ( dataAndEvents ) {
6184			if ( deepDataAndEvents ) {
6185				srcElements = srcElements || getAll( elem );
6186				destElements = destElements || getAll( clone );
6187
6188				for ( i = 0, l = srcElements.length; i < l; i++ ) {
6189					cloneCopyEvent( srcElements[ i ], destElements[ i ] );
6190				}
6191			} else {
6192				cloneCopyEvent( elem, clone );
6193			}
6194		}
6195
6196		// Preserve script evaluation history
6197		destElements = getAll( clone, "script" );
6198		if ( destElements.length > 0 ) {
6199			setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
6200		}
6201
6202		// Return the cloned set
6203		return clone;
6204	},
6205
6206	cleanData: function( elems ) {
6207		var data, elem, type,
6208			special = jQuery.event.special,
6209			i = 0;
6210
6211		for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) {
6212			if ( acceptData( elem ) ) {
6213				if ( ( data = elem[ dataPriv.expando ] ) ) {
6214					if ( data.events ) {
6215						for ( type in data.events ) {
6216							if ( special[ type ] ) {
6217								jQuery.event.remove( elem, type );
6218
6219							// This is a shortcut to avoid jQuery.event.remove's overhead
6220							} else {
6221								jQuery.removeEvent( elem, type, data.handle );
6222							}
6223						}
6224					}
6225
vendor: 1,119 bytes, lines 6226-6270
6226					// Support: Chrome <=35 - 45+
6227					// Assign undefined instead of using delete, see Data#remove
6228					elem[ dataPriv.expando ] = undefined;
6229				}
6230				if ( elem[ dataUser.expando ] ) {
6231
6232					// Support: Chrome <=35 - 45+
6233					// Assign undefined instead of using delete, see Data#remove
6234					elem[ dataUser.expando ] = undefined;
6235				}
6236			}
6237		}
6238	}
6239} );
6240
6241jQuery.fn.extend( {
6242	detach: function( selector ) {
6243		return remove( this, selector, true );
6244	},
6245
6246	remove: function( selector ) {
6247		return remove( this, selector );
6248	},
6249
6250	text: function( value ) {
6251		return access( this, function( value ) {
6252			return value === undefined ?
6253				jQuery.text( this ) :
6254				this.empty().each( function() {
6255					if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
6256						this.textContent = value;
6257					}
6258				} );
6259		}, null, value, arguments.length );
6260	},
6261
6262	append: function() {
6263		return domManip( this, arguments, function( elem ) {
6264			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
6265				var target = manipulationTarget( this, elem );
6266				target.appendChild( elem );
6267			}
6268		} );
6269	},
6270
vendor: 4,664 bytes, lines 6271-6471
6271	prepend: function() {
6272		return domManip( this, arguments, function( elem ) {
6273			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
6274				var target = manipulationTarget( this, elem );
6275				target.insertBefore( elem, target.firstChild );
6276			}
6277		} );
6278	},
6279
6280	before: function() {
6281		return domManip( this, arguments, function( elem ) {
6282			if ( this.parentNode ) {
6283				this.parentNode.insertBefore( elem, this );
6284			}
6285		} );
6286	},
6287
6288	after: function() {
6289		return domManip( this, arguments, function( elem ) {
6290			if ( this.parentNode ) {
6291				this.parentNode.insertBefore( elem, this.nextSibling );
6292			}
6293		} );
6294	},
6295
6296	empty: function() {
6297		var elem,
6298			i = 0;
6299
6300		for ( ; ( elem = this[ i ] ) != null; i++ ) {
6301			if ( elem.nodeType === 1 ) {
6302
6303				// Prevent memory leaks
6304				jQuery.cleanData( getAll( elem, false ) );
6305
6306				// Remove any remaining nodes
6307				elem.textContent = "";
6308			}
6309		}
6310
6311		return this;
6312	},
6313
6314	clone: function( dataAndEvents, deepDataAndEvents ) {
6315		dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
6316		deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
6317
6318		return this.map( function() {
6319			return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
6320		} );
6321	},
6322
6323	html: function( value ) {
6324		return access( this, function( value ) {
6325			var elem = this[ 0 ] || {},
6326				i = 0,
6327				l = this.length;
6328
6329			if ( value === undefined && elem.nodeType === 1 ) {
6330				return elem.innerHTML;
6331			}
6332
6333			// See if we can take a shortcut and just use innerHTML
6334			if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
6335				!wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {
6336
6337				value = jQuery.htmlPrefilter( value );
6338
6339				try {
6340					for ( ; i < l; i++ ) {
6341						elem = this[ i ] || {};
6342
6343						// Remove element nodes and prevent memory leaks
6344						if ( elem.nodeType === 1 ) {
6345							jQuery.cleanData( getAll( elem, false ) );
6346							elem.innerHTML = value;
6347						}
6348					}
6349
6350					elem = 0;
6351
6352				// If using innerHTML throws an exception, use the fallback method
6353				} catch ( e ) {}
6354			}
6355
6356			if ( elem ) {
6357				this.empty().append( value );
6358			}
6359		}, null, value, arguments.length );
6360	},
6361
6362	replaceWith: function() {
6363		var ignored = [];
6364
6365		// Make the changes, replacing each non-ignored context element with the new content
6366		return domManip( this, arguments, function( elem ) {
6367			var parent = this.parentNode;
6368
6369			if ( jQuery.inArray( this, ignored ) < 0 ) {
6370				jQuery.cleanData( getAll( this ) );
6371				if ( parent ) {
6372					parent.replaceChild( elem, this );
6373				}
6374			}
6375
6376		// Force callback invocation
6377		}, ignored );
6378	}
6379} );
6380
6381jQuery.each( {
6382	appendTo: "append",
6383	prependTo: "prepend",
6384	insertBefore: "before",
6385	insertAfter: "after",
6386	replaceAll: "replaceWith"
6387}, function( name, original ) {
6388	jQuery.fn[ name ] = function( selector ) {
6389		var elems,
6390			ret = [],
6391			insert = jQuery( selector ),
6392			last = insert.length - 1,
6393			i = 0;
6394
6395		for ( ; i <= last; i++ ) {
6396			elems = i === last ? this : this.clone( true );
6397			jQuery( insert[ i ] )[ original ]( elems );
6398
6399			// Support: Android <=4.0 only, PhantomJS 1 only
6400			// .get() because push.apply(_, arraylike) throws on ancient WebKit
6401			push.apply( ret, elems.get() );
6402		}
6403
6404		return this.pushStack( ret );
6405	};
6406} );
6407var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
6408
6409var rcustomProp = /^--/;
6410
6411
6412var getStyles = function( elem ) {
6413
6414		// Support: IE <=11 only, Firefox <=30 (trac-15098, trac-14150)
6415		// IE throws on elements created in popups
6416		// FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
6417		var view = elem.ownerDocument.defaultView;
6418
6419		if ( !view || !view.opener ) {
6420			view = window;
6421		}
6422
6423		return view.getComputedStyle( elem );
6424	};
6425
6426var swap = function( elem, options, callback ) {
6427	var ret, name,
6428		old = {};
6429
6430	// Remember the old values, and insert the new ones
6431	for ( name in options ) {
6432		old[ name ] = elem.style[ name ];
6433		elem.style[ name ] = options[ name ];
6434	}
6435
6436	ret = callback.call( elem );
6437
6438	// Revert the old values
6439	for ( name in options ) {
6440		elem.style[ name ] = old[ name ];
6441	}
6442
6443	return ret;
6444};
6445
6446
6447var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" );
6448
6449var whitespace = "[\\x20\\t\\r\\n\\f]";
6450
6451
6452var rtrimCSS = new RegExp(
6453	"^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$",
6454	"g"
6455);
6456
6457
6458
6459
6460( function() {
6461
6462	// Executing both pixelPosition & boxSizingReliable tests require only one layout
6463	// so they're executed at the same time to save the second computation.
6464	function computeStyleTests() {
6465
6466		// This is a singleton, we need to execute it only once
6467		if ( !div ) {
6468			return;
6469		}
6470
6471		container.style.cssText = "position:absolute;
vendor: 4,131 bytes, lines 6471-6590
6471left:-11111px;width:60px;" +
6472			"margin-top:1px;padding:0;border:0";
6473		div.style.cssText =
6474			"position:relative;display:block;box-sizing:border-box;overflow:scroll;" +
6475			"margin:auto;border:1px;padding:1px;" +
6476			"width:60%;top:1%";
6477		documentElement.appendChild( container ).appendChild( div );
6478
6479		var divStyle = window.getComputedStyle( div );
6480		pixelPositionVal = divStyle.top !== "1%";
6481
6482		// Support: Android 4.0 - 4.3 only, Firefox <=3 - 44
6483		reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12;
6484
6485		// Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3
6486		// Some styles come back with percentage values, even though they shouldn't
6487		div.style.right = "60%";
6488		pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36;
6489
6490		// Support: IE 9 - 11 only
6491		// Detect misreporting of content dimensions for box-sizing:border-box elements
6492		boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36;
6493
6494		// Support: IE 9 only
6495		// Detect overflow:scroll screwiness (gh-3699)
6496		// Support: Chrome <=64
6497		// Don't get tricked when zoom affects offsetWidth (gh-4029)
6498		div.style.position = "absolute";
6499		scrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12;
6500
6501		documentElement.removeChild( container );
6502
6503		// Nullify the div so it wouldn't be stored in the memory and
6504		// it will also be a sign that checks already performed
6505		div = null;
6506	}
6507
6508	function roundPixelMeasures( measure ) {
6509		return Math.round( parseFloat( measure ) );
6510	}
6511
6512	var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal,
6513		reliableTrDimensionsVal, reliableMarginLeftVal,
6514		container = document.createElement( "div" ),
6515		div = document.createElement( "div" );
6516
6517	// Finish early in limited (non-browser) environments
6518	if ( !div.style ) {
6519		return;
6520	}
6521
6522	// Support: IE <=9 - 11 only
6523	// Style of cloned element affects source element cloned (trac-8908)
6524	div.style.backgroundClip = "content-box";
6525	div.cloneNode( true ).style.backgroundClip = "";
6526	support.clearCloneStyle = div.style.backgroundClip === "content-box";
6527
6528	jQuery.extend( support, {
6529		boxSizingReliable: function() {
6530			computeStyleTests();
6531			return boxSizingReliableVal;
6532		},
6533		pixelBoxStyles: function() {
6534			computeStyleTests();
6535			return pixelBoxStylesVal;
6536		},
6537		pixelPosition: function() {
6538			computeStyleTests();
6539			return pixelPositionVal;
6540		},
6541		reliableMarginLeft: function() {
6542			computeStyleTests();
6543			return reliableMarginLeftVal;
6544		},
6545		scrollboxSize: function() {
6546			computeStyleTests();
6547			return scrollboxSizeVal;
6548		},
6549
6550		// Support: IE 9 - 11+, Edge 15 - 18+
6551		// IE/Edge misreport `getComputedStyle` of table rows with width/height
6552		// set in CSS while `offset*` properties report correct values.
6553		// Behavior in IE 9 is more subtle than in newer versions & it passes
6554		// some versions of this test; make sure not to make it pass there!
6555		//
6556		// Support: Firefox 70+
6557		// Only Firefox includes border widths
6558		// in computed dimensions. (gh-4529)
6559		reliableTrDimensions: function() {
6560			var table, tr, trChild, trStyle;
6561			if ( reliableTrDimensionsVal == null ) {
6562				table = document.createElement( "table" );
6563				tr = document.createElement( "tr" );
6564				trChild = document.createElement( "div" );
6565
6566				table.style.cssText = "position:absolute;left:-11111px;border-collapse:separate";
6567				tr.style.cssText = "border:1px solid";
6568
6569				// Support: Chrome 86+
6570				// Height set through cssText does not get applied.
6571				// Computed height then comes back as 0.
6572				tr.style.height = "1px";
6573				trChild.style.height = "9px";
6574
6575				// Support: Android 8 Chrome 86+
6576				// In our bodyBackground.html iframe,
6577				// display for all div elements is set to "inline",
6578				// which causes a problem only in Android 8 Chrome 86.
6579				// Ensuring the div is display: block
6580				// gets around this issue.
6581				trChild.style.display = "block";
6582
6583				documentElement
6584					.appendChild( table )
6585					.appendChild( tr )
6586					.appendChild( trChild );
6587
6588				trStyle = window.getComputedStyle( tr );
6589				reliableTrDimensionsVal = ( parseInt( trStyle.height, 10 ) +
6590					parseInt( trStyle.borderTopWidth, 10 ) +
vendor: 11,424 bytes, lines 6591-6985
6591					parseInt( trStyle.borderBottomWidth, 10 ) ) === tr.offsetHeight;
6592
6593				documentElement.removeChild( table );
6594			}
6595			return reliableTrDimensionsVal;
6596		}
6597	} );
6598} )();
6599
6600
6601function curCSS( elem, name, computed ) {
6602	var width, minWidth, maxWidth, ret,
6603		isCustomProp = rcustomProp.test( name ),
6604
6605		// Support: Firefox 51+
6606		// Retrieving style before computed somehow
6607		// fixes an issue with getting wrong values
6608		// on detached elements
6609		style = elem.style;
6610
6611	computed = computed || getStyles( elem );
6612
6613	// getPropertyValue is needed for:
6614	//   .css('filter') (IE 9 only, trac-12537)
6615	//   .css('--customProperty) (gh-3144)
6616	if ( computed ) {
6617		ret = computed.getPropertyValue( name ) || computed[ name ];
6618
6619		// trim whitespace for custom property (issue gh-4926)
6620		if ( isCustomProp ) {
6621
6622			// rtrim treats U+000D CARRIAGE RETURN and U+000C FORM FEED
6623			// as whitespace while CSS does not, but this is not a problem
6624			// because CSS preprocessing replaces them with U+000A LINE FEED
6625			// (which *is* CSS whitespace)
6626			// https://www.w3.org/TR/css-syntax-3/#input-preprocessing
6627			ret = ret.replace( rtrimCSS, "$1" );
6628		}
6629
6630		if ( ret === "" && !isAttached( elem ) ) {
6631			ret = jQuery.style( elem, name );
6632		}
6633
6634		// A tribute to the "awesome hack by Dean Edwards"
6635		// Android Browser returns percentage for some values,
6636		// but width seems to be reliably pixels.
6637		// This is against the CSSOM draft spec:
6638		// https://drafts.csswg.org/cssom/#resolved-values
6639		if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) {
6640
6641			// Remember the original values
6642			width = style.width;
6643			minWidth = style.minWidth;
6644			maxWidth = style.maxWidth;
6645
6646			// Put in the new values to get a computed value out
6647			style.minWidth = style.maxWidth = style.width = ret;
6648			ret = computed.width;
6649
6650			// Revert the changed values
6651			style.width = width;
6652			style.minWidth = minWidth;
6653			style.maxWidth = maxWidth;
6654		}
6655	}
6656
6657	return ret !== undefined ?
6658
6659		// Support: IE <=9 - 11 only
6660		// IE returns zIndex value as an integer.
6661		ret + "" :
6662		ret;
6663}
6664
6665
6666function addGetHookIf( conditionFn, hookFn ) {
6667
6668	// Define the hook, we'll check on the first run if it's really needed.
6669	return {
6670		get: function() {
6671			if ( conditionFn() ) {
6672
6673				// Hook not needed (or it's not possible to use it due
6674				// to missing dependency), remove it.
6675				delete this.get;
6676				return;
6677			}
6678
6679			// Hook needed; redefine it so that the support test is not executed again.
6680			return ( this.get = hookFn ).apply( this, arguments );
6681		}
6682	};
6683}
6684
6685
6686var cssPrefixes = [ "Webkit", "Moz", "ms" ],
6687	emptyStyle = document.createElement( "div" ).style,
6688	vendorProps = {};
6689
6690// Return a vendor-prefixed property or undefined
6691function vendorPropName( name ) {
6692
6693	// Check for vendor prefixed names
6694	var capName = name[ 0 ].toUpperCase() + name.slice( 1 ),
6695		i = cssPrefixes.length;
6696
6697	while ( i-- ) {
6698		name = cssPrefixes[ i ] + capName;
6699		if ( name in emptyStyle ) {
6700			return name;
6701		}
6702	}
6703}
6704
6705// Return a potentially-mapped jQuery.cssProps or vendor prefixed property
6706function finalPropName( name ) {
6707	var final = jQuery.cssProps[ name ] || vendorProps[ name ];
6708
6709	if ( final ) {
6710		return final;
6711	}
6712	if ( name in emptyStyle ) {
6713		return name;
6714	}
6715	return vendorProps[ name ] = vendorPropName( name ) || name;
6716}
6717
6718
6719var
6720
6721	// Swappable if display is none or starts with table
6722	// except "table", "table-cell", or "table-caption"
6723	// See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
6724	rdisplayswap = /^(none|table(?!-c[ea]).+)/,
6725	cssShow = { position: "absolute", visibility: "hidden", display: "block" },
6726	cssNormalTransform = {
6727		letterSpacing: "0",
6728		fontWeight: "400"
6729	};
6730
6731function setPositiveNumber( _elem, value, subtract ) {
6732
6733	// Any relative (+/-) values have already been
6734	// normalized at this point
6735	var matches = rcssNum.exec( value );
6736	return matches ?
6737
6738		// Guard against undefined "subtract", e.g., when used as in cssHooks
6739		Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) :
6740		value;
6741}
6742
6743function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) {
6744	var i = dimension === "width" ? 1 : 0,
6745		extra = 0,
6746		delta = 0;
6747
6748	// Adjustment may not be necessary
6749	if ( box === ( isBorderBox ? "border" : "content" ) ) {
6750		return 0;
6751	}
6752
6753	for ( ; i < 4; i += 2 ) {
6754
6755		// Both box models exclude margin
6756		if ( box === "margin" ) {
6757			delta += jQuery.css( elem, box + cssExpand[ i ], true, styles );
6758		}
6759
6760		// If we get here with a content-box, we're seeking "padding" or "border" or "margin"
6761		if ( !isBorderBox ) {
6762
6763			// Add padding
6764			delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
6765
6766			// For "border" or "margin", add border
6767			if ( box !== "padding" ) {
6768				delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
6769
6770			// But still keep track of it otherwise
6771			} else {
6772				extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
6773			}
6774
6775		// If we get here with a border-box (content + padding + border), we're seeking "content" or
6776		// "padding" or "margin"
6777		} else {
6778
6779			// For "content", subtract padding
6780			if ( box === "content" ) {
6781				delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
6782			}
6783
6784			// For "content" or "padding", subtract border
6785			if ( box !== "margin" ) {
6786				delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
6787			}
6788		}
6789	}
6790
6791	// Account for positive content-box scroll gutter when requested by providing computedVal
6792	if ( !isBorderBox && computedVal >= 0 ) {
6793
6794		// offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border
6795		// Assuming integer scroll gutter, subtract the rest and round down
6796		delta += Math.max( 0, Math.ceil(
6797			elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -
6798			computedVal -
6799			delta -
6800			extra -
6801			0.5
6802
6803		// If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter
6804		// Use an explicit zero to avoid NaN (gh-3964)
6805		) ) || 0;
6806	}
6807
6808	return delta;
6809}
6810
6811function getWidthOrHeight( elem, dimension, extra ) {
6812
6813	// Start with computed style
6814	var styles = getStyles( elem ),
6815
6816		// To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322).
6817		// Fake content-box until we know it's needed to know the true value.
6818		boxSizingNeeded = !support.boxSizingReliable() || extra,
6819		isBorderBox = boxSizingNeeded &&
6820			jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
6821		valueIsBorderBox = isBorderBox,
6822
6823		val = curCSS( elem, dimension, styles ),
6824		offsetProp = "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 );
6825
6826	// Support: Firefox <=54
6827	// Return a confounding non-pixel value or feign ignorance, as appropriate.
6828	if ( rnumnonpx.test( val ) ) {
6829		if ( !extra ) {
6830			return val;
6831		}
6832		val = "auto";
6833	}
6834
6835
6836	// Support: IE 9 - 11 only
6837	// Use offsetWidth/offsetHeight for when box sizing is unreliable.
6838	// In those cases, the computed value can be trusted to be border-box.
6839	if ( ( !support.boxSizingReliable() && isBorderBox ||
6840
6841		// Support: IE 10 - 11+, Edge 15 - 18+
6842		// IE/Edge misreport `getComputedStyle` of table rows with width/height
6843		// set in CSS while `offset*` properties report correct values.
6844		// Interestingly, in some cases IE 9 doesn't suffer from this issue.
6845		!support.reliableTrDimensions() && nodeName( elem, "tr" ) ||
6846
6847		// Fall back to offsetWidth/offsetHeight when value is "auto"
6848		// This happens for inline elements with no explicit setting (gh-3571)
6849		val === "auto" ||
6850
6851		// Support: Android <=4.1 - 4.3 only
6852		// Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602)
6853		!parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) &&
6854
6855		// Make sure the element is visible & connected
6856		elem.getClientRects().length ) {
6857
6858		isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
6859
6860		// Where available, offsetWidth/offsetHeight approximate border box dimensions.
6861		// Where not available (e.g., SVG), assume unreliable box-sizing and interpret the
6862		// retrieved value as a content box dimension.
6863		valueIsBorderBox = offsetProp in elem;
6864		if ( valueIsBorderBox ) {
6865			val = elem[ offsetProp ];
6866		}
6867	}
6868
6869	// Normalize "" and auto
6870	val = parseFloat( val ) || 0;
6871
6872	// Adjust for the element's box model
6873	return ( val +
6874		boxModelAdjustment(
6875			elem,
6876			dimension,
6877			extra || ( isBorderBox ? "border" : "content" ),
6878			valueIsBorderBox,
6879			styles,
6880
6881			// Provide the current computed size to request scroll gutter calculation (gh-3589)
6882			val
6883		)
6884	) + "px";
6885}
6886
6887jQuery.extend( {
6888
6889	// Add in style property hooks for overriding the default
6890	// behavior of getting and setting a style property
6891	cssHooks: {
6892		opacity: {
6893			get: function( elem, computed ) {
6894				if ( computed ) {
6895
6896					// We should always get a number back from opacity
6897					var ret = curCSS( elem, "opacity" );
6898					return ret === "" ? "1" : ret;
6899				}
6900			}
6901		}
6902	},
6903
6904	// Don't automatically add "px" to these possibly-unitless properties
6905	cssNumber: {
6906		"animationIterationCount": true,
6907		"columnCount": true,
6908		"fillOpacity": true,
6909		"flexGrow": true,
6910		"flexShrink": true,
6911		"fontWeight": true,
6912		"gridArea": true,
6913		"gridColumn": true,
6914		"gridColumnEnd": true,
6915		"gridColumnStart": true,
6916		"gridRow": true,
6917		"gridRowEnd": true,
6918		"gridRowStart": true,
6919		"lineHeight": true,
6920		"opacity": true,
6921		"order": true,
6922		"orphans": true,
6923		"widows": true,
6924		"zIndex": true,
6925		"zoom": true
6926	},
6927
6928	// Add in properties whose names you wish to fix before
6929	// setting or getting the value
6930	cssProps: {},
6931
6932	// Get and set the style property on a DOM Node
6933	style: function( elem, name, value, extra ) {
6934
6935		// Don't set styles on text and comment nodes
6936		if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
6937			return;
6938		}
6939
6940		// Make sure that we're working with the right name
6941		var ret, type, hooks,
6942			origName = camelCase( name ),
6943			isCustomProp = rcustomProp.test( name ),
6944			style = elem.style;
6945
6946		// Make sure that we're working with the right name. We don't
6947		// want to query the value if it is a CSS custom property
6948		// since they are user-defined.
6949		if ( !isCustomProp ) {
6950			name = finalPropName( origName );
6951		}
6952
6953		// Gets hook for the prefixed version, then unprefixed version
6954		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
6955
6956		// Check if we're setting a value
6957		if ( value !== undefined ) {
6958			type = typeof value;
6959
6960			// Convert "+=" or "-=" to relative numbers (trac-7345)
6961			if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {
6962				value = adjustCSS( elem, name, ret );
6963
6964				// Fixes bug trac-9237
6965				type = "number";
6966			}
6967
6968			// Make sure that null and NaN values aren't set (trac-7116)
6969			if ( value == null || value !== value ) {
6970				return;
6971			}
6972
6973			// If a number was passed in, add the unit (except for certain CSS properties)
6974			// The isCustomProp check can be removed in jQuery 4.0 when we only auto-append
6975			// "px" to a few hardcoded values.
6976			if ( type === "number" && !isCustomProp ) {
6977				value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" );
6978			}
6979
6980			// background-* props affect original clone's values
6981			if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) {
6982				style[ name ] = "inherit";
6983			}
6984
6985			// If a hook was provided, use that value, otherwise just set the specified value
vendor: 16,052 bytes, lines 6986-7590
6986			if ( !hooks || !( "set" in hooks ) ||
6987				( value = hooks.set( elem, value, extra ) ) !== undefined ) {
6988
6989				if ( isCustomProp ) {
6990					style.setProperty( name, value );
6991				} else {
6992					style[ name ] = value;
6993				}
6994			}
6995
6996		} else {
6997
6998			// If a hook was provided get the non-computed value from there
6999			if ( hooks && "get" in hooks &&
7000				( ret = hooks.get( elem, false, extra ) ) !== undefined ) {
7001
7002				return ret;
7003			}
7004
7005			// Otherwise just get the value from the style object
7006			return style[ name ];
7007		}
7008	},
7009
7010	css: function( elem, name, extra, styles ) {
7011		var val, num, hooks,
7012			origName = camelCase( name ),
7013			isCustomProp = rcustomProp.test( name );
7014
7015		// Make sure that we're working with the right name. We don't
7016		// want to modify the value if it is a CSS custom property
7017		// since they are user-defined.
7018		if ( !isCustomProp ) {
7019			name = finalPropName( origName );
7020		}
7021
7022		// Try prefixed name followed by the unprefixed name
7023		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
7024
7025		// If a hook was provided get the computed value from there
7026		if ( hooks && "get" in hooks ) {
7027			val = hooks.get( elem, true, extra );
7028		}
7029
7030		// Otherwise, if a way to get the computed value exists, use that
7031		if ( val === undefined ) {
7032			val = curCSS( elem, name, styles );
7033		}
7034
7035		// Convert "normal" to computed value
7036		if ( val === "normal" && name in cssNormalTransform ) {
7037			val = cssNormalTransform[ name ];
7038		}
7039
7040		// Make numeric if forced or a qualifier was provided and val looks numeric
7041		if ( extra === "" || extra ) {
7042			num = parseFloat( val );
7043			return extra === true || isFinite( num ) ? num || 0 : val;
7044		}
7045
7046		return val;
7047	}
7048} );
7049
7050jQuery.each( [ "height", "width" ], function( _i, dimension ) {
7051	jQuery.cssHooks[ dimension ] = {
7052		get: function( elem, computed, extra ) {
7053			if ( computed ) {
7054
7055				// Certain elements can have dimension info if we invisibly show them
7056				// but it must have a current display style that would benefit
7057				return rdisplayswap.test( jQuery.css( elem, "display" ) ) &&
7058
7059					// Support: Safari 8+
7060					// Table columns in Safari have non-zero offsetWidth & zero
7061					// getBoundingClientRect().width unless display is changed.
7062					// Support: IE <=11 only
7063					// Running getBoundingClientRect on a disconnected node
7064					// in IE throws an error.
7065					( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ?
7066					swap( elem, cssShow, function() {
7067						return getWidthOrHeight( elem, dimension, extra );
7068					} ) :
7069					getWidthOrHeight( elem, dimension, extra );
7070			}
7071		},
7072
7073		set: function( elem, value, extra ) {
7074			var matches,
7075				styles = getStyles( elem ),
7076
7077				// Only read styles.position if the test has a chance to fail
7078				// to avoid forcing a reflow.
7079				scrollboxSizeBuggy = !support.scrollboxSize() &&
7080					styles.position === "absolute",
7081
7082				// To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991)
7083				boxSizingNeeded = scrollboxSizeBuggy || extra,
7084				isBorderBox = boxSizingNeeded &&
7085					jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
7086				subtract = extra ?
7087					boxModelAdjustment(
7088						elem,
7089						dimension,
7090						extra,
7091						isBorderBox,
7092						styles
7093					) :
7094					0;
7095
7096			// Account for unreliable border-box dimensions by comparing offset* to computed and
7097			// faking a content-box to get border and padding (gh-3699)
7098			if ( isBorderBox && scrollboxSizeBuggy ) {
7099				subtract -= Math.ceil(
7100					elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -
7101					parseFloat( styles[ dimension ] ) -
7102					boxModelAdjustment( elem, dimension, "border", false, styles ) -
7103					0.5
7104				);
7105			}
7106
7107			// Convert to pixels if value adjustment is needed
7108			if ( subtract && ( matches = rcssNum.exec( value ) ) &&
7109				( matches[ 3 ] || "px" ) !== "px" ) {
7110
7111				elem.style[ dimension ] = value;
7112				value = jQuery.css( elem, dimension );
7113			}
7114
7115			return setPositiveNumber( elem, value, subtract );
7116		}
7117	};
7118} );
7119
7120jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,
7121	function( elem, computed ) {
7122		if ( computed ) {
7123			return ( parseFloat( curCSS( elem, "marginLeft" ) ) ||
7124				elem.getBoundingClientRect().left -
7125					swap( elem, { marginLeft: 0 }, function() {
7126						return elem.getBoundingClientRect().left;
7127					} )
7128			) + "px";
7129		}
7130	}
7131);
7132
7133// These hooks are used by animate to expand properties
7134jQuery.each( {
7135	margin: "",
7136	padding: "",
7137	border: "Width"
7138}, function( prefix, suffix ) {
7139	jQuery.cssHooks[ prefix + suffix ] = {
7140		expand: function( value ) {
7141			var i = 0,
7142				expanded = {},
7143
7144				// Assumes a single number if not a string
7145				parts = typeof value === "string" ? value.split( " " ) : [ value ];
7146
7147			for ( ; i < 4; i++ ) {
7148				expanded[ prefix + cssExpand[ i ] + suffix ] =
7149					parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
7150			}
7151
7152			return expanded;
7153		}
7154	};
7155
7156	if ( prefix !== "margin" ) {
7157		jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
7158	}
7159} );
7160
7161jQuery.fn.extend( {
7162	css: function( name, value ) {
7163		return access( this, function( elem, name, value ) {
7164			var styles, len,
7165				map = {},
7166				i = 0;
7167
7168			if ( Array.isArray( name ) ) {
7169				styles = getStyles( elem );
7170				len = name.length;
7171
7172				for ( ; i < len; i++ ) {
7173					map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
7174				}
7175
7176				return map;
7177			}
7178
7179			return value !== undefined ?
7180				jQuery.style( elem, name, value ) :
7181				jQuery.css( elem, name );
7182		}, name, value, arguments.length > 1 );
7183	}
7184} );
7185
7186
7187function Tween( elem, options, prop, end, easing ) {
7188	return new Tween.prototype.init( elem, options, prop, end, easing );
7189}
7190jQuery.Tween = Tween;
7191
7192Tween.prototype = {
7193	constructor: Tween,
7194	init: function( elem, options, prop, end, easing, unit ) {
7195		this.elem = elem;
7196		this.prop = prop;
7197		this.easing = easing || jQuery.easing._default;
7198		this.options = options;
7199		this.start = this.now = this.cur();
7200		this.end = end;
7201		this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
7202	},
7203	cur: function() {
7204		var hooks = Tween.propHooks[ this.prop ];
7205
7206		return hooks && hooks.get ?
7207			hooks.get( this ) :
7208			Tween.propHooks._default.get( this );
7209	},
7210	run: function( percent ) {
7211		var eased,
7212			hooks = Tween.propHooks[ this.prop ];
7213
7214		if ( this.options.duration ) {
7215			this.pos = eased = jQuery.easing[ this.easing ](
7216				percent, this.options.duration * percent, 0, 1, this.options.duration
7217			);
7218		} else {
7219			this.pos = eased = percent;
7220		}
7221		this.now = ( this.end - this.start ) * eased + this.start;
7222
7223		if ( this.options.step ) {
7224			this.options.step.call( this.elem, this.now, this );
7225		}
7226
7227		if ( hooks && hooks.set ) {
7228			hooks.set( this );
7229		} else {
7230			Tween.propHooks._default.set( this );
7231		}
7232		return this;
7233	}
7234};
7235
7236Tween.prototype.init.prototype = Tween.prototype;
7237
7238Tween.propHooks = {
7239	_default: {
7240		get: function( tween ) {
7241			var result;
7242
7243			// Use a property on the element directly when it is not a DOM element,
7244			// or when there is no matching style property that exists.
7245			if ( tween.elem.nodeType !== 1 ||
7246				tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {
7247				return tween.elem[ tween.prop ];
7248			}
7249
7250			// Passing an empty string as a 3rd parameter to .css will automatically
7251			// attempt a parseFloat and fallback to a string if the parse fails.
7252			// Simple values such as "10px" are parsed to Float;
7253			// complex values such as "rotate(1rad)" are returned as-is.
7254			result = jQuery.css( tween.elem, tween.prop, "" );
7255
7256			// Empty strings, null, undefined and "auto" are converted to 0.
7257			return !result || result === "auto" ? 0 : result;
7258		},
7259		set: function( tween ) {
7260
7261			// Use step hook for back compat.
7262			// Use cssHook if its there.
7263			// Use .style if available and use plain properties where available.
7264			if ( jQuery.fx.step[ tween.prop ] ) {
7265				jQuery.fx.step[ tween.prop ]( tween );
7266			} else if ( tween.elem.nodeType === 1 && (
7267				jQuery.cssHooks[ tween.prop ] ||
7268					tween.elem.style[ finalPropName( tween.prop ) ] != null ) ) {
7269				jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
7270			} else {
7271				tween.elem[ tween.prop ] = tween.now;
7272			}
7273		}
7274	}
7275};
7276
7277// Support: IE <=9 only
7278// Panic based approach to setting things on disconnected nodes
7279Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
7280	set: function( tween ) {
7281		if ( tween.elem.nodeType && tween.elem.parentNode ) {
7282			tween.elem[ tween.prop ] = tween.now;
7283		}
7284	}
7285};
7286
7287jQuery.easing = {
7288	linear: function( p ) {
7289		return p;
7290	},
7291	swing: function( p ) {
7292		return 0.5 - Math.cos( p * Math.PI ) / 2;
7293	},
7294	_default: "swing"
7295};
7296
7297jQuery.fx = Tween.prototype.init;
7298
7299// Back compat <1.8 extension point
7300jQuery.fx.step = {};
7301
7302
7303
7304
7305var
7306	fxNow, inProgress,
7307	rfxtypes = /^(?:toggle|show|hide)$/,
7308	rrun = /queueHooks$/;
7309
7310function schedule() {
7311	if ( inProgress ) {
7312		if ( document.hidden === false && window.requestAnimationFrame ) {
7313			window.requestAnimationFrame( schedule );
7314		} else {
7315			window.setTimeout( schedule, jQuery.fx.interval );
7316		}
7317
7318		jQuery.fx.tick();
7319	}
7320}
7321
7322// Animations created synchronously will run synchronously
7323function createFxNow() {
7324	window.setTimeout( function() {
7325		fxNow = undefined;
7326	} );
7327	return ( fxNow = Date.now() );
7328}
7329
7330// Generate parameters to create a standard animation
7331function genFx( type, includeWidth ) {
7332	var which,
7333		i = 0,
7334		attrs = { height: type };
7335
7336	// If we include width, step value is 1 to do all cssExpand values,
7337	// otherwise step value is 2 to skip over Left and Right
7338	includeWidth = includeWidth ? 1 : 0;
7339	for ( ; i < 4; i += 2 - includeWidth ) {
7340		which = cssExpand[ i ];
7341		attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
7342	}
7343
7344	if ( includeWidth ) {
7345		attrs.opacity = attrs.width = type;
7346	}
7347
7348	return attrs;
7349}
7350
7351function createTween( value, prop, animation ) {
7352	var tween,
7353		collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ),
7354		index = 0,
7355		length = collection.length;
7356	for ( ; index < length; index++ ) {
7357		if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {
7358
7359			// We're done with this property
7360			return tween;
7361		}
7362	}
7363}
7364
7365function defaultPrefilter( elem, props, opts ) {
7366	var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display,
7367		isBox = "width" in props || "height" in props,
7368		anim = this,
7369		orig = {},
7370		style = elem.style,
7371		hidden = elem.nodeType && isHiddenWithinTree( elem ),
7372		dataShow = dataPriv.get( elem, "fxshow" );
7373
7374	// Queue-skipping animations hijack the fx hooks
7375	if ( !opts.queue ) {
7376		hooks = jQuery._queueHooks( elem, "fx" );
7377		if ( hooks.unqueued == null ) {
7378			hooks.unqueued = 0;
7379			oldfire = hooks.empty.fire;
7380			hooks.empty.fire = function() {
7381				if ( !hooks.unqueued ) {
7382					oldfire();
7383				}
7384			};
7385		}
7386		hooks.unqueued++;
7387
7388		anim.always( function() {
7389
7390			// Ensure the complete handler is called before this completes
7391			anim.always( function() {
7392				hooks.unqueued--;
7393				if ( !jQuery.queue( elem, "fx" ).length ) {
7394					hooks.empty.fire();
7395				}
7396			} );
7397		} );
7398	}
7399
7400	// Detect show/hide animations
7401	for ( prop in props ) {
7402		value = props[ prop ];
7403		if ( rfxtypes.test( value ) ) {
7404			delete props[ prop ];
7405			toggle = toggle || value === "toggle";
7406			if ( value === ( hidden ? "hide" : "show" ) ) {
7407
7408				// Pretend to be hidden if this is a "show" and
7409				// there is still data from a stopped show/hide
7410				if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
7411					hidden = true;
7412
7413				// Ignore all other no-op show/hide data
7414				} else {
7415					continue;
7416				}
7417			}
7418			orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
7419		}
7420	}
7421
7422	// Bail out if this is a no-op like .hide().hide()
7423	propTween = !jQuery.isEmptyObject( props );
7424	if ( !propTween && jQuery.isEmptyObject( orig ) ) {
7425		return;
7426	}
7427
7428	// Restrict "overflow" and "display" styles during box animations
7429	if ( isBox && elem.nodeType === 1 ) {
7430
7431		// Support: IE <=9 - 11, Edge 12 - 15
7432		// Record all 3 overflow attributes because IE does not infer the shorthand
7433		// from identically-valued overflowX and overflowY and Edge just mirrors
7434		// the overflowX value there.
7435		opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
7436
7437		// Identify a display type, preferring old show/hide data over the CSS cascade
7438		restoreDisplay = dataShow && dataShow.display;
7439		if ( restoreDisplay == null ) {
7440			restoreDisplay = dataPriv.get( elem, "display" );
7441		}
7442		display = jQuery.css( elem, "display" );
7443		if ( display === "none" ) {
7444			if ( restoreDisplay ) {
7445				display = restoreDisplay;
7446			} else {
7447
7448				// Get nonempty value(s) by temporarily forcing visibility
7449				showHide( [ elem ], true );
7450				restoreDisplay = elem.style.display || restoreDisplay;
7451				display = jQuery.css( elem, "display" );
7452				showHide( [ elem ] );
7453			}
7454		}
7455
7456		// Animate inline elements as inline-block
7457		if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) {
7458			if ( jQuery.css( elem, "float" ) === "none" ) {
7459
7460				// Restore the original display value at the end of pure show/hide animations
7461				if ( !propTween ) {
7462					anim.done( function() {
7463						style.display = restoreDisplay;
7464					} );
7465					if ( restoreDisplay == null ) {
7466						display = style.display;
7467						restoreDisplay = display === "none" ? "" : display;
7468					}
7469				}
7470				style.display = "inline-block";
7471			}
7472		}
7473	}
7474
7475	if ( opts.overflow ) {
7476		style.overflow = "hidden";
7477		anim.always( function() {
7478			style.overflow = opts.overflow[ 0 ];
7479			style.overflowX = opts.overflow[ 1 ];
7480			style.overflowY = opts.overflow[ 2 ];
7481		} );
7482	}
7483
7484	// Implement show/hide animations
7485	propTween = false;
7486	for ( prop in orig ) {
7487
7488		// General show/hide setup for this element animation
7489		if ( !propTween ) {
7490			if ( dataShow ) {
7491				if ( "hidden" in dataShow ) {
7492					hidden = dataShow.hidden;
7493				}
7494			} else {
7495				dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } );
7496			}
7497
7498			// Store hidden/visible for toggle so `.stop().toggle()` "reverses"
7499			if ( toggle ) {
7500				dataShow.hidden = !hidden;
7501			}
7502
7503			// Show elements before animating them
7504			if ( hidden ) {
7505				showHide( [ elem ], true );
7506			}
7507
7508			/* eslint-disable no-loop-func */
7509
7510			anim.done( function() {
7511
7512				/* eslint-enable no-loop-func */
7513
7514				// The final step of a "hide" animation is actually hiding the element
7515				if ( !hidden ) {
7516					showHide( [ elem ] );
7517				}
7518				dataPriv.remove( elem, "fxshow" );
7519				for ( prop in orig ) {
7520					jQuery.style( elem, prop, orig[ prop ] );
7521				}
7522			} );
7523		}
7524
7525		// Per-property setup
7526		propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
7527		if ( !( prop in dataShow ) ) {
7528			dataShow[ prop ] = propTween.start;
7529			if ( hidden ) {
7530				propTween.end = propTween.start;
7531				propTween.start = 0;
7532			}
7533		}
7534	}
7535}
7536
7537function propFilter( props, specialEasing ) {
7538	var index, name, easing, value, hooks;
7539
7540	// camelCase, specialEasing and expand cssHook pass
7541	for ( index in props ) {
7542		name = camelCase( index );
7543		easing = specialEasing[ name ];
7544		value = props[ index ];
7545		if ( Array.isArray( value ) ) {
7546			easing = value[ 1 ];
7547			value = props[ index ] = value[ 0 ];
7548		}
7549
7550		if ( index !== name ) {
7551			props[ name ] = value;
7552			delete props[ index ];
7553		}
7554
7555		hooks = jQuery.cssHooks[ name ];
7556		if ( hooks && "expand" in hooks ) {
7557			value = hooks.expand( value );
7558			delete props[ name ];
7559
7560			// Not quite $.extend, this won't overwrite existing keys.
7561			// Reusing 'index' because we have the correct "name"
7562			for ( index in value ) {
7563				if ( !( index in props ) ) {
7564					props[ index ] = value[ index ];
7565					specialEasing[ index ] = easing;
7566				}
7567			}
7568		} else {
7569			specialEasing[ name ] = easing;
7570		}
7571	}
7572}
7573
7574function Animation( elem, properties, options ) {
7575	var result,
7576		stopped,
7577		index = 0,
7578		length = Animation.prefilters.length,
7579		deferred = jQuery.Deferred().always( function() {
7580
7581			// Don't match elem in the :animated selector
7582			delete tick.elem;
7583		} ),
7584		tick = function() {
7585			if ( stopped ) {
7586				return false;
7587			}
7588			var currentTime = fxNow || createFxNow(),
7589				remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
7590
vendor: 9,542 bytes, lines 7591-7981
7591				// Support: Android 2.3 only
7592				// Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (trac-12497)
7593				temp = remaining / animation.duration || 0,
7594				percent = 1 - temp,
7595				index = 0,
7596				length = animation.tweens.length;
7597
7598			for ( ; index < length; index++ ) {
7599				animation.tweens[ index ].run( percent );
7600			}
7601
7602			deferred.notifyWith( elem, [ animation, percent, remaining ] );
7603
7604			// If there's more to do, yield
7605			if ( percent < 1 && length ) {
7606				return remaining;
7607			}
7608
7609			// If this was an empty animation, synthesize a final progress notification
7610			if ( !length ) {
7611				deferred.notifyWith( elem, [ animation, 1, 0 ] );
7612			}
7613
7614			// Resolve the animation and report its conclusion
7615			deferred.resolveWith( elem, [ animation ] );
7616			return false;
7617		},
7618		animation = deferred.promise( {
7619			elem: elem,
7620			props: jQuery.extend( {}, properties ),
7621			opts: jQuery.extend( true, {
7622				specialEasing: {},
7623				easing: jQuery.easing._default
7624			}, options ),
7625			originalProperties: properties,
7626			originalOptions: options,
7627			startTime: fxNow || createFxNow(),
7628			duration: options.duration,
7629			tweens: [],
7630			createTween: function( prop, end ) {
7631				var tween = jQuery.Tween( elem, animation.opts, prop, end,
7632					animation.opts.specialEasing[ prop ] || animation.opts.easing );
7633				animation.tweens.push( tween );
7634				return tween;
7635			},
7636			stop: function( gotoEnd ) {
7637				var index = 0,
7638
7639					// If we are going to the end, we want to run all the tweens
7640					// otherwise we skip this part
7641					length = gotoEnd ? animation.tweens.length : 0;
7642				if ( stopped ) {
7643					return this;
7644				}
7645				stopped = true;
7646				for ( ; index < length; index++ ) {
7647					animation.tweens[ index ].run( 1 );
7648				}
7649
7650				// Resolve when we played the last frame; otherwise, reject
7651				if ( gotoEnd ) {
7652					deferred.notifyWith( elem, [ animation, 1, 0 ] );
7653					deferred.resolveWith( elem, [ animation, gotoEnd ] );
7654				} else {
7655					deferred.rejectWith( elem, [ animation, gotoEnd ] );
7656				}
7657				return this;
7658			}
7659		} ),
7660		props = animation.props;
7661
7662	propFilter( props, animation.opts.specialEasing );
7663
7664	for ( ; index < length; index++ ) {
7665		result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );
7666		if ( result ) {
7667			if ( isFunction( result.stop ) ) {
7668				jQuery._queueHooks( animation.elem, animation.opts.queue ).stop =
7669					result.stop.bind( result );
7670			}
7671			return result;
7672		}
7673	}
7674
7675	jQuery.map( props, createTween, animation );
7676
7677	if ( isFunction( animation.opts.start ) ) {
7678		animation.opts.start.call( elem, animation );
7679	}
7680
7681	// Attach callbacks from options
7682	animation
7683		.progress( animation.opts.progress )
7684		.done( animation.opts.done, animation.opts.complete )
7685		.fail( animation.opts.fail )
7686		.always( animation.opts.always );
7687
7688	jQuery.fx.timer(
7689		jQuery.extend( tick, {
7690			elem: elem,
7691			anim: animation,
7692			queue: animation.opts.queue
7693		} )
7694	);
7695
7696	return animation;
7697}
7698
7699jQuery.Animation = jQuery.extend( Animation, {
7700
7701	tweeners: {
7702		"*": [ function( prop, value ) {
7703			var tween = this.createTween( prop, value );
7704			adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );
7705			return tween;
7706		} ]
7707	},
7708
7709	tweener: function( props, callback ) {
7710		if ( isFunction( props ) ) {
7711			callback = props;
7712			props = [ "*" ];
7713		} else {
7714			props = props.match( rnothtmlwhite );
7715		}
7716
7717		var prop,
7718			index = 0,
7719			length = props.length;
7720
7721		for ( ; index < length; index++ ) {
7722			prop = props[ index ];
7723			Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];
7724			Animation.tweeners[ prop ].unshift( callback );
7725		}
7726	},
7727
7728	prefilters: [ defaultPrefilter ],
7729
7730	prefilter: function( callback, prepend ) {
7731		if ( prepend ) {
7732			Animation.prefilters.unshift( callback );
7733		} else {
7734			Animation.prefilters.push( callback );
7735		}
7736	}
7737} );
7738
7739jQuery.speed = function( speed, easing, fn ) {
7740	var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
7741		complete: fn || !fn && easing ||
7742			isFunction( speed ) && speed,
7743		duration: speed,
7744		easing: fn && easing || easing && !isFunction( easing ) && easing
7745	};
7746
7747	// Go to the end state if fx are off
7748	if ( jQuery.fx.off ) {
7749		opt.duration = 0;
7750
7751	} else {
7752		if ( typeof opt.duration !== "number" ) {
7753			if ( opt.duration in jQuery.fx.speeds ) {
7754				opt.duration = jQuery.fx.speeds[ opt.duration ];
7755
7756			} else {
7757				opt.duration = jQuery.fx.speeds._default;
7758			}
7759		}
7760	}
7761
7762	// Normalize opt.queue - true/undefined/null -> "fx"
7763	if ( opt.queue == null || opt.queue === true ) {
7764		opt.queue = "fx";
7765	}
7766
7767	// Queueing
7768	opt.old = opt.complete;
7769
7770	opt.complete = function() {
7771		if ( isFunction( opt.old ) ) {
7772			opt.old.call( this );
7773		}
7774
7775		if ( opt.queue ) {
7776			jQuery.dequeue( this, opt.queue );
7777		}
7778	};
7779
7780	return opt;
7781};
7782
7783jQuery.fn.extend( {
7784	fadeTo: function( speed, to, easing, callback ) {
7785
7786		// Show any hidden elements after setting opacity to 0
7787		return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show()
7788
7789			// Animate to the value specified
7790			.end().animate( { opacity: to }, speed, easing, callback );
7791	},
7792	animate: function( prop, speed, easing, callback ) {
7793		var empty = jQuery.isEmptyObject( prop ),
7794			optall = jQuery.speed( speed, easing, callback ),
7795			doAnimation = function() {
7796
7797				// Operate on a copy of prop so per-property easing won't be lost
7798				var anim = Animation( this, jQuery.extend( {}, prop ), optall );
7799
7800				// Empty animations, or finishing resolves immediately
7801				if ( empty || dataPriv.get( this, "finish" ) ) {
7802					anim.stop( true );
7803				}
7804			};
7805
7806		doAnimation.finish = doAnimation;
7807
7808		return empty || optall.queue === false ?
7809			this.each( doAnimation ) :
7810			this.queue( optall.queue, doAnimation );
7811	},
7812	stop: function( type, clearQueue, gotoEnd ) {
7813		var stopQueue = function( hooks ) {
7814			var stop = hooks.stop;
7815			delete hooks.stop;
7816			stop( gotoEnd );
7817		};
7818
7819		if ( typeof type !== "string" ) {
7820			gotoEnd = clearQueue;
7821			clearQueue = type;
7822			type = undefined;
7823		}
7824		if ( clearQueue ) {
7825			this.queue( type || "fx", [] );
7826		}
7827
7828		return this.each( function() {
7829			var dequeue = true,
7830				index = type != null && type + "queueHooks",
7831				timers = jQuery.timers,
7832				data = dataPriv.get( this );
7833
7834			if ( index ) {
7835				if ( data[ index ] && data[ index ].stop ) {
7836					stopQueue( data[ index ] );
7837				}
7838			} else {
7839				for ( index in data ) {
7840					if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
7841						stopQueue( data[ index ] );
7842					}
7843				}
7844			}
7845
7846			for ( index = timers.length; index--; ) {
7847				if ( timers[ index ].elem === this &&
7848					( type == null || timers[ index ].queue === type ) ) {
7849
7850					timers[ index ].anim.stop( gotoEnd );
7851					dequeue = false;
7852					timers.splice( index, 1 );
7853				}
7854			}
7855
7856			// Start the next in the queue if the last step wasn't forced.
7857			// Timers currently will call their complete callbacks, which
7858			// will dequeue but only if they were gotoEnd.
7859			if ( dequeue || !gotoEnd ) {
7860				jQuery.dequeue( this, type );
7861			}
7862		} );
7863	},
7864	finish: function( type ) {
7865		if ( type !== false ) {
7866			type = type || "fx";
7867		}
7868		return this.each( function() {
7869			var index,
7870				data = dataPriv.get( this ),
7871				queue = data[ type + "queue" ],
7872				hooks = data[ type + "queueHooks" ],
7873				timers = jQuery.timers,
7874				length = queue ? queue.length : 0;
7875
7876			// Enable finishing flag on private data
7877			data.finish = true;
7878
7879			// Empty the queue first
7880			jQuery.queue( this, type, [] );
7881
7882			if ( hooks && hooks.stop ) {
7883				hooks.stop.call( this, true );
7884			}
7885
7886			// Look for any active animations, and finish them
7887			for ( index = timers.length; index--; ) {
7888				if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
7889					timers[ index ].anim.stop( true );
7890					timers.splice( index, 1 );
7891				}
7892			}
7893
7894			// Look for any animations in the old queue and finish them
7895			for ( index = 0; index < length; index++ ) {
7896				if ( queue[ index ] && queue[ index ].finish ) {
7897					queue[ index ].finish.call( this );
7898				}
7899			}
7900
7901			// Turn off finishing flag
7902			delete data.finish;
7903		} );
7904	}
7905} );
7906
7907jQuery.each( [ "toggle", "show", "hide" ], function( _i, name ) {
7908	var cssFn = jQuery.fn[ name ];
7909	jQuery.fn[ name ] = function( speed, easing, callback ) {
7910		return speed == null || typeof speed === "boolean" ?
7911			cssFn.apply( this, arguments ) :
7912			this.animate( genFx( name, true ), speed, easing, callback );
7913	};
7914} );
7915
7916// Generate shortcuts for custom animations
7917jQuery.each( {
7918	slideDown: genFx( "show" ),
7919	slideUp: genFx( "hide" ),
7920	slideToggle: genFx( "toggle" ),
7921	fadeIn: { opacity: "show" },
7922	fadeOut: { opacity: "hide" },
7923	fadeToggle: { opacity: "toggle" }
7924}, function( name, props ) {
7925	jQuery.fn[ name ] = function( speed, easing, callback ) {
7926		return this.animate( props, speed, easing, callback );
7927	};
7928} );
7929
7930jQuery.timers = [];
7931jQuery.fx.tick = function() {
7932	var timer,
7933		i = 0,
7934		timers = jQuery.timers;
7935
7936	fxNow = Date.now();
7937
7938	for ( ; i < timers.length; i++ ) {
7939		timer = timers[ i ];
7940
7941		// Run the timer and safely remove it when done (allowing for external removal)
7942		if ( !timer() && timers[ i ] === timer ) {
7943			timers.splice( i--, 1 );
7944		}
7945	}
7946
7947	if ( !timers.length ) {
7948		jQuery.fx.stop();
7949	}
7950	fxNow = undefined;
7951};
7952
7953jQuery.fx.timer = function( timer ) {
7954	jQuery.timers.push( timer );
7955	jQuery.fx.start();
7956};
7957
7958jQuery.fx.interval = 13;
7959jQuery.fx.start = function() {
7960	if ( inProgress ) {
7961		return;
7962	}
7963
7964	inProgress = true;
7965	schedule();
7966};
7967
7968jQuery.fx.stop = function() {
7969	inProgress = null;
7970};
7971
7972jQuery.fx.speeds = {
7973	slow: 600,
7974	fast: 200,
7975
7976	// Default speed
7977	_default: 400
7978};
7979
7980
7981// Based off of the plugin by Clint Helfers, with permission.
vendor: 5,177 bytes, lines 7982-8202
7982jQuery.fn.delay = function( time, type ) {
7983	time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
7984	type = type || "fx";
7985
7986	return this.queue( type, function( next, hooks ) {
7987		var timeout = window.setTimeout( next, time );
7988		hooks.stop = function() {
7989			window.clearTimeout( timeout );
7990		};
7991	} );
7992};
7993
7994
7995( function() {
7996	var input = document.createElement( "input" ),
7997		select = document.createElement( "select" ),
7998		opt = select.appendChild( document.createElement( "option" ) );
7999
8000	input.type = "checkbox";
8001
8002	// Support: Android <=4.3 only
8003	// Default value for a checkbox should be "on"
8004	support.checkOn = input.value !== "";
8005
8006	// Support: IE <=11 only
8007	// Must access selectedIndex to make default options select
8008	support.optSelected = opt.selected;
8009
8010	// Support: IE <=11 only
8011	// An input loses its value after becoming a radio
8012	input = document.createElement( "input" );
8013	input.value = "t";
8014	input.type = "radio";
8015	support.radioValue = input.value === "t";
8016} )();
8017
8018
8019var boolHook,
8020	attrHandle = jQuery.expr.attrHandle;
8021
8022jQuery.fn.extend( {
8023	attr: function( name, value ) {
8024		return access( this, jQuery.attr, name, value, arguments.length > 1 );
8025	},
8026
8027	removeAttr: function( name ) {
8028		return this.each( function() {
8029			jQuery.removeAttr( this, name );
8030		} );
8031	}
8032} );
8033
8034jQuery.extend( {
8035	attr: function( elem, name, value ) {
8036		var ret, hooks,
8037			nType = elem.nodeType;
8038
8039		// Don't get/set attributes on text, comment and attribute nodes
8040		if ( nType === 3 || nType === 8 || nType === 2 ) {
8041			return;
8042		}
8043
8044		// Fallback to prop when attributes are not supported
8045		if ( typeof elem.getAttribute === "undefined" ) {
8046			return jQuery.prop( elem, name, value );
8047		}
8048
8049		// Attribute hooks are determined by the lowercase version
8050		// Grab necessary hook if one is defined
8051		if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
8052			hooks = jQuery.attrHooks[ name.toLowerCase() ] ||
8053				( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );
8054		}
8055
8056		if ( value !== undefined ) {
8057			if ( value === null ) {
8058				jQuery.removeAttr( elem, name );
8059				return;
8060			}
8061
8062			if ( hooks && "set" in hooks &&
8063				( ret = hooks.set( elem, value, name ) ) !== undefined ) {
8064				return ret;
8065			}
8066
8067			elem.setAttribute( name, value + "" );
8068			return value;
8069		}
8070
8071		if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
8072			return ret;
8073		}
8074
8075		ret = jQuery.find.attr( elem, name );
8076
8077		// Non-existent attributes return null, we normalize to undefined
8078		return ret == null ? undefined : ret;
8079	},
8080
8081	attrHooks: {
8082		type: {
8083			set: function( elem, value ) {
8084				if ( !support.radioValue && value === "radio" &&
8085					nodeName( elem, "input" ) ) {
8086					var val = elem.value;
8087					elem.setAttribute( "type", value );
8088					if ( val ) {
8089						elem.value = val;
8090					}
8091					return value;
8092				}
8093			}
8094		}
8095	},
8096
8097	removeAttr: function( elem, value ) {
8098		var name,
8099			i = 0,
8100
8101			// Attribute names can contain non-HTML whitespace characters
8102			// https://html.spec.whatwg.org/multipage/syntax.html#attributes-2
8103			attrNames = value && value.match( rnothtmlwhite );
8104
8105		if ( attrNames && elem.nodeType === 1 ) {
8106			while ( ( name = attrNames[ i++ ] ) ) {
8107				elem.removeAttribute( name );
8108			}
8109		}
8110	}
8111} );
8112
8113// Hooks for boolean attributes
8114boolHook = {
8115	set: function( elem, value, name ) {
8116		if ( value === false ) {
8117
8118			// Remove boolean attributes when set to false
8119			jQuery.removeAttr( elem, name );
8120		} else {
8121			elem.setAttribute( name, name );
8122		}
8123		return name;
8124	}
8125};
8126
8127jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( _i, name ) {
8128	var getter = attrHandle[ name ] || jQuery.find.attr;
8129
8130	attrHandle[ name ] = function( elem, name, isXML ) {
8131		var ret, handle,
8132			lowercaseName = name.toLowerCase();
8133
8134		if ( !isXML ) {
8135
8136			// Avoid an infinite loop by temporarily removing this function from the getter
8137			handle = attrHandle[ lowercaseName ];
8138			attrHandle[ lowercaseName ] = ret;
8139			ret = getter( elem, name, isXML ) != null ?
8140				lowercaseName :
8141				null;
8142			attrHandle[ lowercaseName ] = handle;
8143		}
8144		return ret;
8145	};
8146} );
8147
8148
8149
8150
8151var rfocusable = /^(?:input|select|textarea|button)$/i,
8152	rclickable = /^(?:a|area)$/i;
8153
8154jQuery.fn.extend( {
8155	prop: function( name, value ) {
8156		return access( this, jQuery.prop, name, value, arguments.length > 1 );
8157	},
8158
8159	removeProp: function( name ) {
8160		return this.each( function() {
8161			delete this[ jQuery.propFix[ name ] || name ];
8162		} );
8163	}
8164} );
8165
8166jQuery.extend( {
8167	prop: function( elem, name, value ) {
8168		var ret, hooks,
8169			nType = elem.nodeType;
8170
8171		// Don't get/set properties on text, comment and attribute nodes
8172		if ( nType === 3 || nType === 8 || nType === 2 ) {
8173			return;
8174		}
8175
8176		if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
8177
8178			// Fix name and attach hooks
8179			name = jQuery.propFix[ name ] || name;
8180			hooks = jQuery.propHooks[ name ];
8181		}
8182
8183		if ( value !== undefined ) {
8184			if ( hooks && "set" in hooks &&
8185				( ret = hooks.set( elem, value, name ) ) !== undefined ) {
8186				return ret;
8187			}
8188
8189			return ( elem[ name ] = value );
8190		}
8191
8192		if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
8193			return ret;
8194		}
8195
8196		return elem[ name ];
8197	},
8198
8199	propHooks: {
8200		tabIndex: {
8201			get: function( elem ) {
8202
vendor: 6,126 bytes, lines 8203-8462
8203				// Support: IE <=9 - 11 only
8204				// elem.tabIndex doesn't always return the
8205				// correct value when it hasn't been explicitly set
8206				// Use proper attribute retrieval (trac-12072)
8207				var tabindex = jQuery.find.attr( elem, "tabindex" );
8208
8209				if ( tabindex ) {
8210					return parseInt( tabindex, 10 );
8211				}
8212
8213				if (
8214					rfocusable.test( elem.nodeName ) ||
8215					rclickable.test( elem.nodeName ) &&
8216					elem.href
8217				) {
8218					return 0;
8219				}
8220
8221				return -1;
8222			}
8223		}
8224	},
8225
8226	propFix: {
8227		"for": "htmlFor",
8228		"class": "className"
8229	}
8230} );
8231
8232// Support: IE <=11 only
8233// Accessing the selectedIndex property
8234// forces the browser to respect setting selected
8235// on the option
8236// The getter ensures a default option is selected
8237// when in an optgroup
8238// eslint rule "no-unused-expressions" is disabled for this code
8239// since it considers such accessions noop
8240if ( !support.optSelected ) {
8241	jQuery.propHooks.selected = {
8242		get: function( elem ) {
8243
8244			/* eslint no-unused-expressions: "off" */
8245
8246			var parent = elem.parentNode;
8247			if ( parent && parent.parentNode ) {
8248				parent.parentNode.selectedIndex;
8249			}
8250			return null;
8251		},
8252		set: function( elem ) {
8253
8254			/* eslint no-unused-expressions: "off" */
8255
8256			var parent = elem.parentNode;
8257			if ( parent ) {
8258				parent.selectedIndex;
8259
8260				if ( parent.parentNode ) {
8261					parent.parentNode.selectedIndex;
8262				}
8263			}
8264		}
8265	};
8266}
8267
8268jQuery.each( [
8269	"tabIndex",
8270	"readOnly",
8271	"maxLength",
8272	"cellSpacing",
8273	"cellPadding",
8274	"rowSpan",
8275	"colSpan",
8276	"useMap",
8277	"frameBorder",
8278	"contentEditable"
8279], function() {
8280	jQuery.propFix[ this.toLowerCase() ] = this;
8281} );
8282
8283
8284
8285
8286	// Strip and collapse whitespace according to HTML spec
8287	// https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace
8288	function stripAndCollapse( value ) {
8289		var tokens = value.match( rnothtmlwhite ) || [];
8290		return tokens.join( " " );
8291	}
8292
8293
8294function getClass( elem ) {
8295	return elem.getAttribute && elem.getAttribute( "class" ) || "";
8296}
8297
8298function classesToArray( value ) {
8299	if ( Array.isArray( value ) ) {
8300		return value;
8301	}
8302	if ( typeof value === "string" ) {
8303		return value.match( rnothtmlwhite ) || [];
8304	}
8305	return [];
8306}
8307
8308jQuery.fn.extend( {
8309	addClass: function( value ) {
8310		var classNames, cur, curValue, className, i, finalValue;
8311
8312		if ( isFunction( value ) ) {
8313			return this.each( function( j ) {
8314				jQuery( this ).addClass( value.call( this, j, getClass( this ) ) );
8315			} );
8316		}
8317
8318		classNames = classesToArray( value );
8319
8320		if ( classNames.length ) {
8321			return this.each( function() {
8322				curValue = getClass( this );
8323				cur = this.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
8324
8325				if ( cur ) {
8326					for ( i = 0; i < classNames.length; i++ ) {
8327						className = classNames[ i ];
8328						if ( cur.indexOf( " " + className + " " ) < 0 ) {
8329							cur += className + " ";
8330						}
8331					}
8332
8333					// Only assign if different to avoid unneeded rendering.
8334					finalValue = stripAndCollapse( cur );
8335					if ( curValue !== finalValue ) {
8336						this.setAttribute( "class", finalValue );
8337					}
8338				}
8339			} );
8340		}
8341
8342		return this;
8343	},
8344
8345	removeClass: function( value ) {
8346		var classNames, cur, curValue, className, i, finalValue;
8347
8348		if ( isFunction( value ) ) {
8349			return this.each( function( j ) {
8350				jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );
8351			} );
8352		}
8353
8354		if ( !arguments.length ) {
8355			return this.attr( "class", "" );
8356		}
8357
8358		classNames = classesToArray( value );
8359
8360		if ( classNames.length ) {
8361			return this.each( function() {
8362				curValue = getClass( this );
8363
8364				// This expression is here for better compressibility (see addClass)
8365				cur = this.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
8366
8367				if ( cur ) {
8368					for ( i = 0; i < classNames.length; i++ ) {
8369						className = classNames[ i ];
8370
8371						// Remove *all* instances
8372						while ( cur.indexOf( " " + className + " " ) > -1 ) {
8373							cur = cur.replace( " " + className + " ", " " );
8374						}
8375					}
8376
8377					// Only assign if different to avoid unneeded rendering.
8378					finalValue = stripAndCollapse( cur );
8379					if ( curValue !== finalValue ) {
8380						this.setAttribute( "class", finalValue );
8381					}
8382				}
8383			} );
8384		}
8385
8386		return this;
8387	},
8388
8389	toggleClass: function( value, stateVal ) {
8390		var classNames, className, i, self,
8391			type = typeof value,
8392			isValidValue = type === "string" || Array.isArray( value );
8393
8394		if ( isFunction( value ) ) {
8395			return this.each( function( i ) {
8396				jQuery( this ).toggleClass(
8397					value.call( this, i, getClass( this ), stateVal ),
8398					stateVal
8399				);
8400			} );
8401		}
8402
8403		if ( typeof stateVal === "boolean" && isValidValue ) {
8404			return stateVal ? this.addClass( value ) : this.removeClass( value );
8405		}
8406
8407		classNames = classesToArray( value );
8408
8409		return this.each( function() {
8410			if ( isValidValue ) {
8411
8412				// Toggle individual class names
8413				self = jQuery( this );
8414
8415				for ( i = 0; i < classNames.length; i++ ) {
8416					className = classNames[ i ];
8417
8418					// Check each className given, space separated list
8419					if ( self.hasClass( className ) ) {
8420						self.removeClass( className );
8421					} else {
8422						self.addClass( className );
8423					}
8424				}
8425
8426			// Toggle whole class name
8427			} else if ( value === undefined || type === "boolean" ) {
8428				className = getClass( this );
8429				if ( className ) {
8430
8431					// Store className if set
8432					dataPriv.set( this, "__className__", className );
8433				}
8434
8435				// If the element has a class name or if we're passed `false`,
8436				// then remove the whole classname (if there was one, the above saved it).
8437				// Otherwise bring back whatever was previously saved (if anything),
8438				// falling back to the empty string if nothing was stored.
8439				if ( this.setAttribute ) {
8440					this.setAttribute( "class",
8441						className || value === false ?
8442							"" :
8443							dataPriv.get( this, "__className__" ) || ""
8444					);
8445				}
8446			}
8447		} );
8448	},
8449
8450	hasClass: function( selector ) {
8451		var className, elem,
8452			i = 0;
8453
8454		className = " " + selector + " ";
8455		while ( ( elem = this[ i++ ] ) ) {
8456			if ( elem.nodeType === 1 &&
8457				( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) {
8458				return true;
8459			}
8460		}
8461
8462		return false;
vendor: 1,385 bytes, lines 8463-8532
8463	}
8464} );
8465
8466
8467
8468
8469var rreturn = /\r/g;
8470
8471jQuery.fn.extend( {
8472	val: function( value ) {
8473		var hooks, ret, valueIsFunction,
8474			elem = this[ 0 ];
8475
8476		if ( !arguments.length ) {
8477			if ( elem ) {
8478				hooks = jQuery.valHooks[ elem.type ] ||
8479					jQuery.valHooks[ elem.nodeName.toLowerCase() ];
8480
8481				if ( hooks &&
8482					"get" in hooks &&
8483					( ret = hooks.get( elem, "value" ) ) !== undefined
8484				) {
8485					return ret;
8486				}
8487
8488				ret = elem.value;
8489
8490				// Handle most common string cases
8491				if ( typeof ret === "string" ) {
8492					return ret.replace( rreturn, "" );
8493				}
8494
8495				// Handle cases where value is null/undef or number
8496				return ret == null ? "" : ret;
8497			}
8498
8499			return;
8500		}
8501
8502		valueIsFunction = isFunction( value );
8503
8504		return this.each( function( i ) {
8505			var val;
8506
8507			if ( this.nodeType !== 1 ) {
8508				return;
8509			}
8510
8511			if ( valueIsFunction ) {
8512				val = value.call( this, i, jQuery( this ).val() );
8513			} else {
8514				val = value;
8515			}
8516
8517			// Treat null/undefined as ""; convert numbers to string
8518			if ( val == null ) {
8519				val = "";
8520
8521			} else if ( typeof val === "number" ) {
8522				val += "";
8523
8524			} else if ( Array.isArray( val ) ) {
8525				val = jQuery.map( val, function( value ) {
8526					return value == null ? "" : value + "";
8527				} );
8528			}
8529
8530			hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
8531
8532			// If set returns undefined, fall back to normal setting
vendor: 8,269 bytes, lines 8533-8847
8533			if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) {
8534				this.value = val;
8535			}
8536		} );
8537	}
8538} );
8539
8540jQuery.extend( {
8541	valHooks: {
8542		option: {
8543			get: function( elem ) {
8544
8545				var val = jQuery.find.attr( elem, "value" );
8546				return val != null ?
8547					val :
8548
8549					// Support: IE <=10 - 11 only
8550					// option.text throws exceptions (trac-14686, trac-14858)
8551					// Strip and collapse whitespace
8552					// https://html.spec.whatwg.org/#strip-and-collapse-whitespace
8553					stripAndCollapse( jQuery.text( elem ) );
8554			}
8555		},
8556		select: {
8557			get: function( elem ) {
8558				var value, option, i,
8559					options = elem.options,
8560					index = elem.selectedIndex,
8561					one = elem.type === "select-one",
8562					values = one ? null : [],
8563					max = one ? index + 1 : options.length;
8564
8565				if ( index < 0 ) {
8566					i = max;
8567
8568				} else {
8569					i = one ? index : 0;
8570				}
8571
8572				// Loop through all the selected options
8573				for ( ; i < max; i++ ) {
8574					option = options[ i ];
8575
8576					// Support: IE <=9 only
8577					// IE8-9 doesn't update selected after form reset (trac-2551)
8578					if ( ( option.selected || i === index ) &&
8579
8580							// Don't return options that are disabled or in a disabled optgroup
8581							!option.disabled &&
8582							( !option.parentNode.disabled ||
8583								!nodeName( option.parentNode, "optgroup" ) ) ) {
8584
8585						// Get the specific value for the option
8586						value = jQuery( option ).val();
8587
8588						// We don't need an array for one selects
8589						if ( one ) {
8590							return value;
8591						}
8592
8593						// Multi-Selects return an array
8594						values.push( value );
8595					}
8596				}
8597
8598				return values;
8599			},
8600
8601			set: function( elem, value ) {
8602				var optionSet, option,
8603					options = elem.options,
8604					values = jQuery.makeArray( value ),
8605					i = options.length;
8606
8607				while ( i-- ) {
8608					option = options[ i ];
8609
8610					/* eslint-disable no-cond-assign */
8611
8612					if ( option.selected =
8613						jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1
8614					) {
8615						optionSet = true;
8616					}
8617
8618					/* eslint-enable no-cond-assign */
8619				}
8620
8621				// Force browsers to behave consistently when non-matching value is set
8622				if ( !optionSet ) {
8623					elem.selectedIndex = -1;
8624				}
8625				return values;
8626			}
8627		}
8628	}
8629} );
8630
8631// Radios and checkboxes getter/setter
8632jQuery.each( [ "radio", "checkbox" ], function() {
8633	jQuery.valHooks[ this ] = {
8634		set: function( elem, value ) {
8635			if ( Array.isArray( value ) ) {
8636				return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );
8637			}
8638		}
8639	};
8640	if ( !support.checkOn ) {
8641		jQuery.valHooks[ this ].get = function( elem ) {
8642			return elem.getAttribute( "value" ) === null ? "on" : elem.value;
8643		};
8644	}
8645} );
8646
8647
8648
8649
8650// Return jQuery for attributes-only inclusion
8651
8652
8653support.focusin = "onfocusin" in window;
8654
8655
8656var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
8657	stopPropagationCallback = function( e ) {
8658		e.stopPropagation();
8659	};
8660
8661jQuery.extend( jQuery.event, {
8662
8663	trigger: function( event, data, elem, onlyHandlers ) {
8664
8665		var i, cur, tmp, bubbleType, ontype, handle, special, lastElement,
8666			eventPath = [ elem || document ],
8667			type = hasOwn.call( event, "type" ) ? event.type : event,
8668			namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : [];
8669
8670		cur = lastElement = tmp = elem = elem || document;
8671
8672		// Don't do events on text and comment nodes
8673		if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
8674			return;
8675		}
8676
8677		// focus/blur morphs to focusin/out; ensure we're not firing them right now
8678		if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
8679			return;
8680		}
8681
8682		if ( type.indexOf( "." ) > -1 ) {
8683
8684			// Namespaced trigger; create a regexp to match event type in handle()
8685			namespaces = type.split( "." );
8686			type = namespaces.shift();
8687			namespaces.sort();
8688		}
8689		ontype = type.indexOf( ":" ) < 0 && "on" + type;
8690
8691		// Caller can pass in a jQuery.Event object, Object, or just an event type string
8692		event = event[ jQuery.expando ] ?
8693			event :
8694			new jQuery.Event( type, typeof event === "object" && event );
8695
8696		// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
8697		event.isTrigger = onlyHandlers ? 2 : 3;
8698		event.namespace = namespaces.join( "." );
8699		event.rnamespace = event.namespace ?
8700			new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) :
8701			null;
8702
8703		// Clean up the event in case it is being reused
8704		event.result = undefined;
8705		if ( !event.target ) {
8706			event.target = elem;
8707		}
8708
8709		// Clone any incoming data and prepend the event, creating the handler arg list
8710		data = data == null ?
8711			[ event ] :
8712			jQuery.makeArray( data, [ event ] );
8713
8714		// Allow special events to draw outside the lines
8715		special = jQuery.event.special[ type ] || {};
8716		if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
8717			return;
8718		}
8719
8720		// Determine event propagation path in advance, per W3C events spec (trac-9951)
8721		// Bubble up to document, then to window; watch for a global ownerDocument var (trac-9724)
8722		if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) {
8723
8724			bubbleType = special.delegateType || type;
8725			if ( !rfocusMorph.test( bubbleType + type ) ) {
8726				cur = cur.parentNode;
8727			}
8728			for ( ; cur; cur = cur.parentNode ) {
8729				eventPath.push( cur );
8730				tmp = cur;
8731			}
8732
8733			// Only add window if we got to document (e.g., not plain obj or detached DOM)
8734			if ( tmp === ( elem.ownerDocument || document ) ) {
8735				eventPath.push( tmp.defaultView || tmp.parentWindow || window );
8736			}
8737		}
8738
8739		// Fire handlers on the event path
8740		i = 0;
8741		while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {
8742			lastElement = cur;
8743			event.type = i > 1 ?
8744				bubbleType :
8745				special.bindType || type;
8746
8747			// jQuery handler
8748			handle = ( dataPriv.get( cur, "events" ) || Object.create( null ) )[ event.type ] &&
8749				dataPriv.get( cur, "handle" );
8750			if ( handle ) {
8751				handle.apply( cur, data );
8752			}
8753
8754			// Native handler
8755			handle = ontype && cur[ ontype ];
8756			if ( handle && handle.apply && acceptData( cur ) ) {
8757				event.result = handle.apply( cur, data );
8758				if ( event.result === false ) {
8759					event.preventDefault();
8760				}
8761			}
8762		}
8763		event.type = type;
8764
8765		// If nobody prevented the default action, do it now
8766		if ( !onlyHandlers && !event.isDefaultPrevented() ) {
8767
8768			if ( ( !special._default ||
8769				special._default.apply( eventPath.pop(), data ) === false ) &&
8770				acceptData( elem ) ) {
8771
8772				// Call a native DOM method on the target with the same name as the event.
8773				// Don't do default actions on window, that's where global variables be (trac-6170)
8774				if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) {
8775
8776					// Don't re-trigger an onFOO event when we call its FOO() method
8777					tmp = elem[ ontype ];
8778
8779					if ( tmp ) {
8780						elem[ ontype ] = null;
8781					}
8782
8783					// Prevent re-triggering of the same event, since we already bubbled it above
8784					jQuery.event.triggered = type;
8785
8786					if ( event.isPropagationStopped() ) {
8787						lastElement.addEventListener( type, stopPropagationCallback );
8788					}
8789
8790					elem[ type ]();
8791
8792					if ( event.isPropagationStopped() ) {
8793						lastElement.removeEventListener( type, stopPropagationCallback );
8794					}
8795
8796					jQuery.event.triggered = undefined;
8797
8798					if ( tmp ) {
8799						elem[ ontype ] = tmp;
8800					}
8801				}
8802			}
8803		}
8804
8805		return event.result;
8806	},
8807
8808	// Piggyback on a donor event to simulate a different one
8809	// Used only for `focus(in | out)` events
8810	simulate: function( type, elem, event ) {
8811		var e = jQuery.extend(
8812			new jQuery.Event(),
8813			event,
8814			{
8815				type: type,
8816				isSimulated: true
8817			}
8818		);
8819
8820		jQuery.event.trigger( e, null, elem );
8821	}
8822
8823} );
8824
8825jQuery.fn.extend( {
8826
8827	trigger: function( type, data ) {
8828		return this.each( function() {
8829			jQuery.event.trigger( type, data, this );
8830		} );
8831	},
8832	triggerHandler: function( type, data ) {
8833		var elem = this[ 0 ];
8834		if ( elem ) {
8835			return jQuery.event.trigger( type, data, elem, true );
8836		}
8837	}
8838} );
8839
8840
8841// Support: Firefox <=44
8842// Firefox doesn't have focus(in | out) events
8843// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787
8844//
8845// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1
8846// focus(in | out) events fire after focus & blur events,
8847// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order
vendor: 4,255 bytes, lines 8848-9017
8848// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857
8849if ( !support.focusin ) {
8850	jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) {
8851
8852		// Attach a single capturing handler on the document while someone wants focusin/focusout
8853		var handler = function( event ) {
8854			jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) );
8855		};
8856
8857		jQuery.event.special[ fix ] = {
8858			setup: function() {
8859
8860				// Handle: regular nodes (via `this.ownerDocument`), window
8861				// (via `this.document`) & document (via `this`).
8862				var doc = this.ownerDocument || this.document || this,
8863					attaches = dataPriv.access( doc, fix );
8864
8865				if ( !attaches ) {
8866					doc.addEventListener( orig, handler, true );
8867				}
8868				dataPriv.access( doc, fix, ( attaches || 0 ) + 1 );
8869			},
8870			teardown: function() {
8871				var doc = this.ownerDocument || this.document || this,
8872					attaches = dataPriv.access( doc, fix ) - 1;
8873
8874				if ( !attaches ) {
8875					doc.removeEventListener( orig, handler, true );
8876					dataPriv.remove( doc, fix );
8877
8878				} else {
8879					dataPriv.access( doc, fix, attaches );
8880				}
8881			}
8882		};
8883	} );
8884}
8885var location = window.location;
8886
8887var nonce = { guid: Date.now() };
8888
8889var rquery = ( /\?/ );
8890
8891
8892
8893// Cross-browser xml parsing
8894jQuery.parseXML = function( data ) {
8895	var xml, parserErrorElem;
8896	if ( !data || typeof data !== "string" ) {
8897		return null;
8898	}
8899
8900	// Support: IE 9 - 11 only
8901	// IE throws on parseFromString with invalid input.
8902	try {
8903		xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" );
8904	} catch ( e ) {}
8905
8906	parserErrorElem = xml && xml.getElementsByTagName( "parsererror" )[ 0 ];
8907	if ( !xml || parserErrorElem ) {
8908		jQuery.error( "Invalid XML: " + (
8909			parserErrorElem ?
8910				jQuery.map( parserErrorElem.childNodes, function( el ) {
8911					return el.textContent;
8912				} ).join( "\n" ) :
8913				data
8914		) );
8915	}
8916	return xml;
8917};
8918
8919
8920var
8921	rbracket = /\[\]$/,
8922	rCRLF = /\r?\n/g,
8923	rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
8924	rsubmittable = /^(?:input|select|textarea|keygen)/i;
8925
8926function buildParams( prefix, obj, traditional, add ) {
8927	var name;
8928
8929	if ( Array.isArray( obj ) ) {
8930
8931		// Serialize array item.
8932		jQuery.each( obj, function( i, v ) {
8933			if ( traditional || rbracket.test( prefix ) ) {
8934
8935				// Treat each array item as a scalar.
8936				add( prefix, v );
8937
8938			} else {
8939
8940				// Item is non-scalar (array or object), encode its numeric index.
8941				buildParams(
8942					prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]",
8943					v,
8944					traditional,
8945					add
8946				);
8947			}
8948		} );
8949
8950	} else if ( !traditional && toType( obj ) === "object" ) {
8951
8952		// Serialize object item.
8953		for ( name in obj ) {
8954			buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
8955		}
8956
8957	} else {
8958
8959		// Serialize scalar item.
8960		add( prefix, obj );
8961	}
8962}
8963
8964// Serialize an array of form elements or a set of
8965// key/values into a query string
8966jQuery.param = function( a, traditional ) {
8967	var prefix,
8968		s = [],
8969		add = function( key, valueOrFunction ) {
8970
8971			// If value is a function, invoke it and use its return value
8972			var value = isFunction( valueOrFunction ) ?
8973				valueOrFunction() :
8974				valueOrFunction;
8975
8976			s[ s.length ] = encodeURIComponent( key ) + "=" +
8977				encodeURIComponent( value == null ? "" : value );
8978		};
8979
8980	if ( a == null ) {
8981		return "";
8982	}
8983
8984	// If an array was passed in, assume that it is an array of form elements.
8985	if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
8986
8987		// Serialize the form elements
8988		jQuery.each( a, function() {
8989			add( this.name, this.value );
8990		} );
8991
8992	} else {
8993
8994		// If traditional, encode the "old" way (the way 1.3.2 or older
8995		// did it), otherwise encode params recursively.
8996		for ( prefix in a ) {
8997			buildParams( prefix, a[ prefix ], traditional, add );
8998		}
8999	}
9000
9001	// Return the resulting serialization
9002	return s.join( "&" );
9003};
9004
9005jQuery.fn.extend( {
9006	serialize: function() {
9007		return jQuery.param( this.serializeArray() );
9008	},
9009	serializeArray: function() {
9010		return this.map( function() {
9011
9012			// Can add propHook for "elements" to filter or add form elements
9013			var elements = jQuery.prop( this, "elements" );
9014			return elements ? jQuery.makeArray( elements ) : this;
9015		} ).filter( function() {
9016			var type = this.type;
9017
vendor: 32,437 bytes, lines 9018-10271
9018			// Use .is( ":disabled" ) so that fieldset[disabled] works
9019			return this.name && !jQuery( this ).is( ":disabled" ) &&
9020				rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
9021				( this.checked || !rcheckableType.test( type ) );
9022		} ).map( function( _i, elem ) {
9023			var val = jQuery( this ).val();
9024
9025			if ( val == null ) {
9026				return null;
9027			}
9028
9029			if ( Array.isArray( val ) ) {
9030				return jQuery.map( val, function( val ) {
9031					return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
9032				} );
9033			}
9034
9035			return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
9036		} ).get();
9037	}
9038} );
9039
9040
9041var
9042	r20 = /%20/g,
9043	rhash = /#.*$/,
9044	rantiCache = /([?&])_=[^&]*/,
9045	rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
9046
9047	// trac-7653, trac-8125, trac-8152: local protocol detection
9048	rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
9049	rnoContent = /^(?:GET|HEAD)$/,
9050	rprotocol = /^\/\//,
9051
9052	/* Prefilters
9053	 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
9054	 * 2) These are called:
9055	 *    - BEFORE asking for a transport
9056	 *    - AFTER param serialization (s.data is a string if s.processData is true)
9057	 * 3) key is the dataType
9058	 * 4) the catchall symbol "*" can be used
9059	 * 5) execution will start with transport dataType and THEN continue down to "*" if needed
9060	 */
9061	prefilters = {},
9062
9063	/* Transports bindings
9064	 * 1) key is the dataType
9065	 * 2) the catchall symbol "*" can be used
9066	 * 3) selection will start with transport dataType and THEN go to "*" if needed
9067	 */
9068	transports = {},
9069
9070	// Avoid comment-prolog char sequence (trac-10098); must appease lint and evade compression
9071	allTypes = "*/".concat( "*" ),
9072
9073	// Anchor tag for parsing the document origin
9074	originAnchor = document.createElement( "a" );
9075
9076originAnchor.href = location.href;
9077
9078// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
9079function addToPrefiltersOrTransports( structure ) {
9080
9081	// dataTypeExpression is optional and defaults to "*"
9082	return function( dataTypeExpression, func ) {
9083
9084		if ( typeof dataTypeExpression !== "string" ) {
9085			func = dataTypeExpression;
9086			dataTypeExpression = "*";
9087		}
9088
9089		var dataType,
9090			i = 0,
9091			dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || [];
9092
9093		if ( isFunction( func ) ) {
9094
9095			// For each dataType in the dataTypeExpression
9096			while ( ( dataType = dataTypes[ i++ ] ) ) {
9097
9098				// Prepend if requested
9099				if ( dataType[ 0 ] === "+" ) {
9100					dataType = dataType.slice( 1 ) || "*";
9101					( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );
9102
9103				// Otherwise append
9104				} else {
9105					( structure[ dataType ] = structure[ dataType ] || [] ).push( func );
9106				}
9107			}
9108		}
9109	};
9110}
9111
9112// Base inspection function for prefilters and transports
9113function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
9114
9115	var inspected = {},
9116		seekingTransport = ( structure === transports );
9117
9118	function inspect( dataType ) {
9119		var selected;
9120		inspected[ dataType ] = true;
9121		jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
9122			var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
9123			if ( typeof dataTypeOrTransport === "string" &&
9124				!seekingTransport && !inspected[ dataTypeOrTransport ] ) {
9125
9126				options.dataTypes.unshift( dataTypeOrTransport );
9127				inspect( dataTypeOrTransport );
9128				return false;
9129			} else if ( seekingTransport ) {
9130				return !( selected = dataTypeOrTransport );
9131			}
9132		} );
9133		return selected;
9134	}
9135
9136	return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
9137}
9138
9139// A special extend for ajax options
9140// that takes "flat" options (not to be deep extended)
9141// Fixes trac-9887
9142function ajaxExtend( target, src ) {
9143	var key, deep,
9144		flatOptions = jQuery.ajaxSettings.flatOptions || {};
9145
9146	for ( key in src ) {
9147		if ( src[ key ] !== undefined ) {
9148			( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
9149		}
9150	}
9151	if ( deep ) {
9152		jQuery.extend( true, target, deep );
9153	}
9154
9155	return target;
9156}
9157
9158/* Handles responses to an ajax request:
9159 * - finds the right dataType (mediates between content-type and expected dataType)
9160 * - returns the corresponding response
9161 */
9162function ajaxHandleResponses( s, jqXHR, responses ) {
9163
9164	var ct, type, finalDataType, firstDataType,
9165		contents = s.contents,
9166		dataTypes = s.dataTypes;
9167
9168	// Remove auto dataType and get content-type in the process
9169	while ( dataTypes[ 0 ] === "*" ) {
9170		dataTypes.shift();
9171		if ( ct === undefined ) {
9172			ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" );
9173		}
9174	}
9175
9176	// Check if we're dealing with a known content-type
9177	if ( ct ) {
9178		for ( type in contents ) {
9179			if ( contents[ type ] && contents[ type ].test( ct ) ) {
9180				dataTypes.unshift( type );
9181				break;
9182			}
9183		}
9184	}
9185
9186	// Check to see if we have a response for the expected dataType
9187	if ( dataTypes[ 0 ] in responses ) {
9188		finalDataType = dataTypes[ 0 ];
9189	} else {
9190
9191		// Try convertible dataTypes
9192		for ( type in responses ) {
9193			if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) {
9194				finalDataType = type;
9195				break;
9196			}
9197			if ( !firstDataType ) {
9198				firstDataType = type;
9199			}
9200		}
9201
9202		// Or just use first one
9203		finalDataType = finalDataType || firstDataType;
9204	}
9205
9206	// If we found a dataType
9207	// We add the dataType to the list if needed
9208	// and return the corresponding response
9209	if ( finalDataType ) {
9210		if ( finalDataType !== dataTypes[ 0 ] ) {
9211			dataTypes.unshift( finalDataType );
9212		}
9213		return responses[ finalDataType ];
9214	}
9215}
9216
9217/* Chain conversions given the request and the original response
9218 * Also sets the responseXXX fields on the jqXHR instance
9219 */
9220function ajaxConvert( s, response, jqXHR, isSuccess ) {
9221	var conv2, current, conv, tmp, prev,
9222		converters = {},
9223
9224		// Work with a copy of dataTypes in case we need to modify it for conversion
9225		dataTypes = s.dataTypes.slice();
9226
9227	// Create converters map with lowercased keys
9228	if ( dataTypes[ 1 ] ) {
9229		for ( conv in s.converters ) {
9230			converters[ conv.toLowerCase() ] = s.converters[ conv ];
9231		}
9232	}
9233
9234	current = dataTypes.shift();
9235
9236	// Convert to each sequential dataType
9237	while ( current ) {
9238
9239		if ( s.responseFields[ current ] ) {
9240			jqXHR[ s.responseFields[ current ] ] = response;
9241		}
9242
9243		// Apply the dataFilter if provided
9244		if ( !prev && isSuccess && s.dataFilter ) {
9245			response = s.dataFilter( response, s.dataType );
9246		}
9247
9248		prev = current;
9249		current = dataTypes.shift();
9250
9251		if ( current ) {
9252
9253			// There's only work to do if current dataType is non-auto
9254			if ( current === "*" ) {
9255
9256				current = prev;
9257
9258			// Convert response if prev dataType is non-auto and differs from current
9259			} else if ( prev !== "*" && prev !== current ) {
9260
9261				// Seek a direct converter
9262				conv = converters[ prev + " " + current ] || converters[ "* " + current ];
9263
9264				// If none found, seek a pair
9265				if ( !conv ) {
9266					for ( conv2 in converters ) {
9267
9268						// If conv2 outputs current
9269						tmp = conv2.split( " " );
9270						if ( tmp[ 1 ] === current ) {
9271
9272							// If prev can be converted to accepted input
9273							conv = converters[ prev + " " + tmp[ 0 ] ] ||
9274								converters[ "* " + tmp[ 0 ] ];
9275							if ( conv ) {
9276
9277								// Condense equivalence converters
9278								if ( conv === true ) {
9279									conv = converters[ conv2 ];
9280
9281								// Otherwise, insert the intermediate dataType
9282								} else if ( converters[ conv2 ] !== true ) {
9283									current = tmp[ 0 ];
9284									dataTypes.unshift( tmp[ 1 ] );
9285								}
9286								break;
9287							}
9288						}
9289					}
9290				}
9291
9292				// Apply converter (if not an equivalence)
9293				if ( conv !== true ) {
9294
9295					// Unless errors are allowed to bubble, catch and return them
9296					if ( conv && s.throws ) {
9297						response = conv( response );
9298					} else {
9299						try {
9300							response = conv( response );
9301						} catch ( e ) {
9302							return {
9303								state: "parsererror",
9304								error: conv ? e : "No conversion from " + prev + " to " + current
9305							};
9306						}
9307					}
9308				}
9309			}
9310		}
9311	}
9312
9313	return { state: "success", data: response };
9314}
9315
9316jQuery.extend( {
9317
9318	// Counter for holding the number of active queries
9319	active: 0,
9320
9321	// Last-Modified header cache for next request
9322	lastModified: {},
9323	etag: {},
9324
9325	ajaxSettings: {
9326		url: location.href,
9327		type: "GET",
9328		isLocal: rlocalProtocol.test( location.protocol ),
9329		global: true,
9330		processData: true,
9331		async: true,
9332		contentType: "application/x-www-form-urlencoded; charset=UTF-8",
9333
9334		/*
9335		timeout: 0,
9336		data: null,
9337		dataType: null,
9338		username: null,
9339		password: null,
9340		cache: null,
9341		throws: false,
9342		traditional: false,
9343		headers: {},
9344		*/
9345
9346		accepts: {
9347			"*": allTypes,
9348			text: "text/plain",
9349			html: "text/html",
9350			xml: "application/xml, text/xml",
9351			json: "application/json, text/javascript"
9352		},
9353
9354		contents: {
9355			xml: /\bxml\b/,
9356			html: /\bhtml/,
9357			json: /\bjson\b/
9358		},
9359
9360		responseFields: {
9361			xml: "responseXML",
9362			text: "responseText",
9363			json: "responseJSON"
9364		},
9365
9366		// Data converters
9367		// Keys separate source (or catchall "*") and destination types with a single space
9368		converters: {
9369
9370			// Convert anything to text
9371			"* text": String,
9372
9373			// Text to html (true = no transformation)
9374			"text html": true,
9375
9376			// Evaluate text as a json expression
9377			"text json": JSON.parse,
9378
9379			// Parse text as xml
9380			"text xml": jQuery.parseXML
9381		},
9382
9383		// For options that shouldn't be deep extended:
9384		// you can add your own custom options here if
9385		// and when you create one that shouldn't be
9386		// deep extended (see ajaxExtend)
9387		flatOptions: {
9388			url: true,
9389			context: true
9390		}
9391	},
9392
9393	// Creates a full fledged settings object into target
9394	// with both ajaxSettings and settings fields.
9395	// If target is omitted, writes into ajaxSettings.
9396	ajaxSetup: function( target, settings ) {
9397		return settings ?
9398
9399			// Building a settings object
9400			ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
9401
9402			// Extending ajaxSettings
9403			ajaxExtend( jQuery.ajaxSettings, target );
9404	},
9405
9406	ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
9407	ajaxTransport: addToPrefiltersOrTransports( transports ),
9408
9409	// Main method
9410	ajax: function( url, options ) {
9411
9412		// If url is an object, simulate pre-1.5 signature
9413		if ( typeof url === "object" ) {
9414			options = url;
9415			url = undefined;
9416		}
9417
9418		// Force options to be an object
9419		options = options || {};
9420
9421		var transport,
9422
9423			// URL without anti-cache param
9424			cacheURL,
9425
9426			// Response headers
9427			responseHeadersString,
9428			responseHeaders,
9429
9430			// timeout handle
9431			timeoutTimer,
9432
9433			// Url cleanup var
9434			urlAnchor,
9435
9436			// Request state (becomes false upon send and true upon completion)
9437			completed,
9438
9439			// To know if global events are to be dispatched
9440			fireGlobals,
9441
9442			// Loop variable
9443			i,
9444
9445			// uncached part of the url
9446			uncached,
9447
9448			// Create the final options object
9449			s = jQuery.ajaxSetup( {}, options ),
9450
9451			// Callbacks context
9452			callbackContext = s.context || s,
9453
9454			// Context for global events is callbackContext if it is a DOM node or jQuery collection
9455			globalEventContext = s.context &&
9456				( callbackContext.nodeType || callbackContext.jquery ) ?
9457				jQuery( callbackContext ) :
9458				jQuery.event,
9459
9460			// Deferreds
9461			deferred = jQuery.Deferred(),
9462			completeDeferred = jQuery.Callbacks( "once memory" ),
9463
9464			// Status-dependent callbacks
9465			statusCode = s.statusCode || {},
9466
9467			// Headers (they are sent all at once)
9468			requestHeaders = {},
9469			requestHeadersNames = {},
9470
9471			// Default abort message
9472			strAbort = "canceled",
9473
9474			// Fake xhr
9475			jqXHR = {
9476				readyState: 0,
9477
9478				// Builds headers hashtable if needed
9479				getResponseHeader: function( key ) {
9480					var match;
9481					if ( completed ) {
9482						if ( !responseHeaders ) {
9483							responseHeaders = {};
9484							while ( ( match = rheaders.exec( responseHeadersString ) ) ) {
9485								responseHeaders[ match[ 1 ].toLowerCase() + " " ] =
9486									( responseHeaders[ match[ 1 ].toLowerCase() + " " ] || [] )
9487										.concat( match[ 2 ] );
9488							}
9489						}
9490						match = responseHeaders[ key.toLowerCase() + " " ];
9491					}
9492					return match == null ? null : match.join( ", " );
9493				},
9494
9495				// Raw string
9496				getAllResponseHeaders: function() {
9497					return completed ? responseHeadersString : null;
9498				},
9499
9500				// Caches the header
9501				setRequestHeader: function( name, value ) {
9502					if ( completed == null ) {
9503						name = requestHeadersNames[ name.toLowerCase() ] =
9504							requestHeadersNames[ name.toLowerCase() ] || name;
9505						requestHeaders[ name ] = value;
9506					}
9507					return this;
9508				},
9509
9510				// Overrides response content-type header
9511				overrideMimeType: function( type ) {
9512					if ( completed == null ) {
9513						s.mimeType = type;
9514					}
9515					return this;
9516				},
9517
9518				// Status-dependent callbacks
9519				statusCode: function( map ) {
9520					var code;
9521					if ( map ) {
9522						if ( completed ) {
9523
9524							// Execute the appropriate callbacks
9525							jqXHR.always( map[ jqXHR.status ] );
9526						} else {
9527
9528							// Lazy-add the new callbacks in a way that preserves old ones
9529							for ( code in map ) {
9530								statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
9531							}
9532						}
9533					}
9534					return this;
9535				},
9536
9537				// Cancel the request
9538				abort: function( statusText ) {
9539					var finalText = statusText || strAbort;
9540					if ( transport ) {
9541						transport.abort( finalText );
9542					}
9543					done( 0, finalText );
9544					return this;
9545				}
9546			};
9547
9548		// Attach deferreds
9549		deferred.promise( jqXHR );
9550
9551		// Add protocol if not provided (prefilters might expect it)
9552		// Handle falsy url in the settings object (trac-10093: consistency with old signature)
9553		// We also use the url parameter if available
9554		s.url = ( ( url || s.url || location.href ) + "" )
9555			.replace( rprotocol, location.protocol + "//" );
9556
9557		// Alias method option to type as per ticket trac-12004
9558		s.type = options.method || options.type || s.method || s.type;
9559
9560		// Extract dataTypes list
9561		s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ];
9562
9563		// A cross-domain request is in order when the origin doesn't match the current origin.
9564		if ( s.crossDomain == null ) {
9565			urlAnchor = document.createElement( "a" );
9566
9567			// Support: IE <=8 - 11, Edge 12 - 15
9568			// IE throws exception on accessing the href property if url is malformed,
9569			// e.g. http://example.com:80x/
9570			try {
9571				urlAnchor.href = s.url;
9572
9573				// Support: IE <=8 - 11 only
9574				// Anchor's host property isn't correctly set when s.url is relative
9575				urlAnchor.href = urlAnchor.href;
9576				s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !==
9577					urlAnchor.protocol + "//" + urlAnchor.host;
9578			} catch ( e ) {
9579
9580				// If there is an error parsing the URL, assume it is crossDomain,
9581				// it can be rejected by the transport if it is invalid
9582				s.crossDomain = true;
9583			}
9584		}
9585
9586		// Convert data if not already a string
9587		if ( s.data && s.processData && typeof s.data !== "string" ) {
9588			s.data = jQuery.param( s.data, s.traditional );
9589		}
9590
9591		// Apply prefilters
9592		inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
9593
9594		// If request was aborted inside a prefilter, stop there
9595		if ( completed ) {
9596			return jqXHR;
9597		}
9598
9599		// We can fire global events as of now if asked to
9600		// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (trac-15118)
9601		fireGlobals = jQuery.event && s.global;
9602
9603		// Watch for a new set of requests
9604		if ( fireGlobals && jQuery.active++ === 0 ) {
9605			jQuery.event.trigger( "ajaxStart" );
9606		}
9607
9608		// Uppercase the type
9609		s.type = s.type.toUpperCase();
9610
9611		// Determine if request has content
9612		s.hasContent = !rnoContent.test( s.type );
9613
9614		// Save the URL in case we're toying with the If-Modified-Since
9615		// and/or If-None-Match header later on
9616		// Remove hash to simplify url manipulation
9617		cacheURL = s.url.replace( rhash, "" );
9618
9619		// More options handling for requests with no content
9620		if ( !s.hasContent ) {
9621
9622			// Remember the hash so we can put it back
9623			uncached = s.url.slice( cacheURL.length );
9624
9625			// If data is available and should be processed, append data to url
9626			if ( s.data && ( s.processData || typeof s.data === "string" ) ) {
9627				cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data;
9628
9629				// trac-9682: remove data so that it's not used in an eventual retry
9630				delete s.data;
9631			}
9632
9633			// Add or update anti-cache param if needed
9634			if ( s.cache === false ) {
9635				cacheURL = cacheURL.replace( rantiCache, "$1" );
9636				uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce.guid++ ) +
9637					uncached;
9638			}
9639
9640			// Put hash and anti-cache on the URL that will be requested (gh-1732)
9641			s.url = cacheURL + uncached;
9642
9643		// Change '%20' to '+' if this is encoded form body content (gh-2658)
9644		} else if ( s.data && s.processData &&
9645			( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) {
9646			s.data = s.data.replace( r20, "+" );
9647		}
9648
9649		// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
9650		if ( s.ifModified ) {
9651			if ( jQuery.lastModified[ cacheURL ] ) {
9652				jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
9653			}
9654			if ( jQuery.etag[ cacheURL ] ) {
9655				jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
9656			}
9657		}
9658
9659		// Set the correct header, if data is being sent
9660		if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
9661			jqXHR.setRequestHeader( "Content-Type", s.contentType );
9662		}
9663
9664		// Set the Accepts header for the server, depending on the dataType
9665		jqXHR.setRequestHeader(
9666			"Accept",
9667			s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?
9668				s.accepts[ s.dataTypes[ 0 ] ] +
9669					( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
9670				s.accepts[ "*" ]
9671		);
9672
9673		// Check for headers option
9674		for ( i in s.headers ) {
9675			jqXHR.setRequestHeader( i, s.headers[ i ] );
9676		}
9677
9678		// Allow custom headers/mimetypes and early abort
9679		if ( s.beforeSend &&
9680			( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) {
9681
9682			// Abort if not done already and return
9683			return jqXHR.abort();
9684		}
9685
9686		// Aborting is no longer a cancellation
9687		strAbort = "abort";
9688
9689		// Install callbacks on deferreds
9690		completeDeferred.add( s.complete );
9691		jqXHR.done( s.success );
9692		jqXHR.fail( s.error );
9693
9694		// Get transport
9695		transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
9696
9697		// If no transport, we auto-abort
9698		if ( !transport ) {
9699			done( -1, "No Transport" );
9700		} else {
9701			jqXHR.readyState = 1;
9702
9703			// Send global event
9704			if ( fireGlobals ) {
9705				globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
9706			}
9707
9708			// If request was aborted inside ajaxSend, stop there
9709			if ( completed ) {
9710				return jqXHR;
9711			}
9712
9713			// Timeout
9714			if ( s.async && s.timeout > 0 ) {
9715				timeoutTimer = window.setTimeout( function() {
9716					jqXHR.abort( "timeout" );
9717				}, s.timeout );
9718			}
9719
9720			try {
9721				completed = false;
9722				transport.send( requestHeaders, done );
9723			} catch ( e ) {
9724
9725				// Rethrow post-completion exceptions
9726				if ( completed ) {
9727					throw e;
9728				}
9729
9730				// Propagate others as results
9731				done( -1, e );
9732			}
9733		}
9734
9735		// Callback for when everything is done
9736		function done( status, nativeStatusText, responses, headers ) {
9737			var isSuccess, success, error, response, modified,
9738				statusText = nativeStatusText;
9739
9740			// Ignore repeat invocations
9741			if ( completed ) {
9742				return;
9743			}
9744
9745			completed = true;
9746
9747			// Clear timeout if it exists
9748			if ( timeoutTimer ) {
9749				window.clearTimeout( timeoutTimer );
9750			}
9751
9752			// Dereference transport for early garbage collection
9753			// (no matter how long the jqXHR object will be used)
9754			transport = undefined;
9755
9756			// Cache response headers
9757			responseHeadersString = headers || "";
9758
9759			// Set readyState
9760			jqXHR.readyState = status > 0 ? 4 : 0;
9761
9762			// Determine if successful
9763			isSuccess = status >= 200 && status < 300 || status === 304;
9764
9765			// Get response data
9766			if ( responses ) {
9767				response = ajaxHandleResponses( s, jqXHR, responses );
9768			}
9769
9770			// Use a noop converter for missing script but not if jsonp
9771			if ( !isSuccess &&
9772				jQuery.inArray( "script", s.dataTypes ) > -1 &&
9773				jQuery.inArray( "json", s.dataTypes ) < 0 ) {
9774				s.converters[ "text script" ] = function() {};
9775			}
9776
9777			// Convert no matter what (that way responseXXX fields are always set)
9778			response = ajaxConvert( s, response, jqXHR, isSuccess );
9779
9780			// If successful, handle type chaining
9781			if ( isSuccess ) {
9782
9783				// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
9784				if ( s.ifModified ) {
9785					modified = jqXHR.getResponseHeader( "Last-Modified" );
9786					if ( modified ) {
9787						jQuery.lastModified[ cacheURL ] = modified;
9788					}
9789					modified = jqXHR.getResponseHeader( "etag" );
9790					if ( modified ) {
9791						jQuery.etag[ cacheURL ] = modified;
9792					}
9793				}
9794
9795				// if no content
9796				if ( status === 204 || s.type === "HEAD" ) {
9797					statusText = "nocontent";
9798
9799				// if not modified
9800				} else if ( status === 304 ) {
9801					statusText = "notmodified";
9802
9803				// If we have data, let's convert it
9804				} else {
9805					statusText = response.state;
9806					success = response.data;
9807					error = response.error;
9808					isSuccess = !error;
9809				}
9810			} else {
9811
9812				// Extract error from statusText and normalize for non-aborts
9813				error = statusText;
9814				if ( status || !statusText ) {
9815					statusText = "error";
9816					if ( status < 0 ) {
9817						status = 0;
9818					}
9819				}
9820			}
9821
9822			// Set data for the fake xhr object
9823			jqXHR.status = status;
9824			jqXHR.statusText = ( nativeStatusText || statusText ) + "";
9825
9826			// Success/Error
9827			if ( isSuccess ) {
9828				deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
9829			} else {
9830				deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
9831			}
9832
9833			// Status-dependent callbacks
9834			jqXHR.statusCode( statusCode );
9835			statusCode = undefined;
9836
9837			if ( fireGlobals ) {
9838				globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
9839					[ jqXHR, s, isSuccess ? success : error ] );
9840			}
9841
9842			// Complete
9843			completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
9844
9845			if ( fireGlobals ) {
9846				globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
9847
9848				// Handle the global AJAX counter
9849				if ( !( --jQuery.active ) ) {
9850					jQuery.event.trigger( "ajaxStop" );
9851				}
9852			}
9853		}
9854
9855		return jqXHR;
9856	},
9857
9858	getJSON: function( url, data, callback ) {
9859		return jQuery.get( url, data, callback, "json" );
9860	},
9861
9862	getScript: function( url, callback ) {
9863		return jQuery.get( url, undefined, callback, "script" );
9864	}
9865} );
9866
9867jQuery.each( [ "get", "post" ], function( _i, method ) {
9868	jQuery[ method ] = function( url, data, callback, type ) {
9869
9870		// Shift arguments if data argument was omitted
9871		if ( isFunction( data ) ) {
9872			type = type || callback;
9873			callback = data;
9874			data = undefined;
9875		}
9876
9877		// The url can be an options object (which then must have .url)
9878		return jQuery.ajax( jQuery.extend( {
9879			url: url,
9880			type: method,
9881			dataType: type,
9882			data: data,
9883			success: callback
9884		}, jQuery.isPlainObject( url ) && url ) );
9885	};
9886} );
9887
9888jQuery.ajaxPrefilter( function( s ) {
9889	var i;
9890	for ( i in s.headers ) {
9891		if ( i.toLowerCase() === "content-type" ) {
9892			s.contentType = s.headers[ i ] || "";
9893		}
9894	}
9895} );
9896
9897
9898jQuery._evalUrl = function( url, options, doc ) {
9899	return jQuery.ajax( {
9900		url: url,
9901
9902		// Make this explicit, since user can override this through ajaxSetup (trac-11264)
9903		type: "GET",
9904		dataType: "script",
9905		cache: true,
9906		async: false,
9907		global: false,
9908
9909		// Only evaluate the response if it is successful (gh-4126)
9910		// dataFilter is not invoked for failure responses, so using it instead
9911		// of the default converter is kludgy but it works.
9912		converters: {
9913			"text script": function() {}
9914		},
9915		dataFilter: function( response ) {
9916			jQuery.globalEval( response, options, doc );
9917		}
9918	} );
9919};
9920
9921
9922jQuery.fn.extend( {
9923	wrapAll: function( html ) {
9924		var wrap;
9925
9926		if ( this[ 0 ] ) {
9927			if ( isFunction( html ) ) {
9928				html = html.call( this[ 0 ] );
9929			}
9930
9931			// The elements to wrap the target around
9932			wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );
9933
9934			if ( this[ 0 ].parentNode ) {
9935				wrap.insertBefore( this[ 0 ] );
9936			}
9937
9938			wrap.map( function() {
9939				var elem = this;
9940
9941				while ( elem.firstElementChild ) {
9942					elem = elem.firstElementChild;
9943				}
9944
9945				return elem;
9946			} ).append( this );
9947		}
9948
9949		return this;
9950	},
9951
9952	wrapInner: function( html ) {
9953		if ( isFunction( html ) ) {
9954			return this.each( function( i ) {
9955				jQuery( this ).wrapInner( html.call( this, i ) );
9956			} );
9957		}
9958
9959		return this.each( function() {
9960			var self = jQuery( this ),
9961				contents = self.contents();
9962
9963			if ( contents.length ) {
9964				contents.wrapAll( html );
9965
9966			} else {
9967				self.append( html );
9968			}
9969		} );
9970	},
9971
9972	wrap: function( html ) {
9973		var htmlIsFunction = isFunction( html );
9974
9975		return this.each( function( i ) {
9976			jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html );
9977		} );
9978	},
9979
9980	unwrap: function( selector ) {
9981		this.parent( selector ).not( "body" ).each( function() {
9982			jQuery( this ).replaceWith( this.childNodes );
9983		} );
9984		return this;
9985	}
9986} );
9987
9988
9989jQuery.expr.pseudos.hidden = function( elem ) {
9990	return !jQuery.expr.pseudos.visible( elem );
9991};
9992jQuery.expr.pseudos.visible = function( elem ) {
9993	return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );
9994};
9995
9996
9997
9998
9999jQuery.ajaxSettings.xhr = function() {
10000	try {
10001		return new window.XMLHttpRequest();
10002	} catch ( e ) {}
10003};
10004
10005var xhrSuccessStatus = {
10006
10007		// File protocol always yields status code 0, assume 200
10008		0: 200,
10009
10010		// Support: IE <=9 only
10011		// trac-1450: sometimes IE returns 1223 when it should be 204
10012		1223: 204
10013	},
10014	xhrSupported = jQuery.ajaxSettings.xhr();
10015
10016support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
10017support.ajax = xhrSupported = !!xhrSupported;
10018
10019jQuery.ajaxTransport( function( options ) {
10020	var callback, errorCallback;
10021
10022	// Cross domain only allowed if supported through XMLHttpRequest
10023	if ( support.cors || xhrSupported && !options.crossDomain ) {
10024		return {
10025			send: function( headers, complete ) {
10026				var i,
10027					xhr = options.xhr();
10028
10029				xhr.open(
10030					options.type,
10031					options.url,
10032					options.async,
10033					options.username,
10034					options.password
10035				);
10036
10037				// Apply custom fields if provided
10038				if ( options.xhrFields ) {
10039					for ( i in options.xhrFields ) {
10040						xhr[ i ] = options.xhrFields[ i ];
10041					}
10042				}
10043
10044				// Override mime type if needed
10045				if ( options.mimeType && xhr.overrideMimeType ) {
10046					xhr.overrideMimeType( options.mimeType );
10047				}
10048
10049				// X-Requested-With header
10050				// For cross-domain requests, seeing as conditions for a preflight are
10051				// akin to a jigsaw puzzle, we simply never set it to be sure.
10052				// (it can always be set on a per-request basis or even using ajaxSetup)
10053				// For same-domain requests, won't change header if already provided.
10054				if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) {
10055					headers[ "X-Requested-With" ] = "XMLHttpRequest";
10056				}
10057
10058				// Set headers
10059				for ( i in headers ) {
10060					xhr.setRequestHeader( i, headers[ i ] );
10061				}
10062
10063				// Callback
10064				callback = function( type ) {
10065					return function() {
10066						if ( callback ) {
10067							callback = errorCallback = xhr.onload =
10068								xhr.onerror = xhr.onabort = xhr.ontimeout =
10069									xhr.onreadystatechange = null;
10070
10071							if ( type === "abort" ) {
10072								xhr.abort();
10073							} else if ( type === "error" ) {
10074
10075								// Support: IE <=9 only
10076								// On a manual native abort, IE9 throws
10077								// errors on any property access that is not readyState
10078								if ( typeof xhr.status !== "number" ) {
10079									complete( 0, "error" );
10080								} else {
10081									complete(
10082
10083										// File: protocol always yields status 0; see trac-8605, trac-14207
10084										xhr.status,
10085										xhr.statusText
10086									);
10087								}
10088							} else {
10089								complete(
10090									xhrSuccessStatus[ xhr.status ] || xhr.status,
10091									xhr.statusText,
10092
10093									// Support: IE <=9 only
10094									// IE9 has no XHR2 but throws on binary (trac-11426)
10095									// For XHR2 non-text, let the caller handle it (gh-2498)
10096									( xhr.responseType || "text" ) !== "text"  ||
10097									typeof xhr.responseText !== "string" ?
10098										{ binary: xhr.response } :
10099										{ text: xhr.responseText },
10100									xhr.getAllResponseHeaders()
10101								);
10102							}
10103						}
10104					};
10105				};
10106
10107				// Listen to events
10108				xhr.onload = callback();
10109				errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" );
10110
10111				// Support: IE 9 only
10112				// Use onreadystatechange to replace onabort
10113				// to handle uncaught aborts
10114				if ( xhr.onabort !== undefined ) {
10115					xhr.onabort = errorCallback;
10116				} else {
10117					xhr.onreadystatechange = function() {
10118
10119						// Check readyState before timeout as it changes
10120						if ( xhr.readyState === 4 ) {
10121
10122							// Allow onerror to be called first,
10123							// but that will not handle a native abort
10124							// Also, save errorCallback to a variable
10125							// as xhr.onerror cannot be accessed
10126							window.setTimeout( function() {
10127								if ( callback ) {
10128									errorCallback();
10129								}
10130							} );
10131						}
10132					};
10133				}
10134
10135				// Create the abort callback
10136				callback = callback( "abort" );
10137
10138				try {
10139
10140					// Do send the request (this may raise an exception)
10141					xhr.send( options.hasContent && options.data || null );
10142				} catch ( e ) {
10143
10144					// trac-14683: Only rethrow if this hasn't been notified as an error yet
10145					if ( callback ) {
10146						throw e;
10147					}
10148				}
10149			},
10150
10151			abort: function() {
10152				if ( callback ) {
10153					callback();
10154				}
10155			}
10156		};
10157	}
10158} );
10159
10160
10161
10162
10163// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432)
10164jQuery.ajaxPrefilter( function( s ) {
10165	if ( s.crossDomain ) {
10166		s.contents.script = false;
10167	}
10168} );
10169
10170// Install script dataType
10171jQuery.ajaxSetup( {
10172	accepts: {
10173		script: "text/javascript, application/javascript, " +
10174			"application/ecmascript, application/x-ecmascript"
10175	},
10176	contents: {
10177		script: /\b(?:java|ecma)script\b/
10178	},
10179	converters: {
10180		"text script": function( text ) {
10181			jQuery.globalEval( text );
10182			return text;
10183		}
10184	}
10185} );
10186
10187// Handle cache's special case and crossDomain
10188jQuery.ajaxPrefilter( "script", function( s ) {
10189	if ( s.cache === undefined ) {
10190		s.cache = false;
10191	}
10192	if ( s.crossDomain ) {
10193		s.type = "GET";
10194	}
10195} );
10196
10197// Bind script tag hack transport
10198jQuery.ajaxTransport( "script", function( s ) {
10199
10200	// This transport only deals with cross domain or forced-by-attrs requests
10201	if ( s.crossDomain || s.scriptAttrs ) {
10202		var script, callback;
10203		return {
10204			send: function( _, complete ) {
10205				script = jQuery( "<script>" )
10206					.attr( s.scriptAttrs || {} )
10207					.prop( { charset: s.scriptCharset, src: s.url } )
10208					.on( "load error", callback = function( evt ) {
10209						script.remove();
10210						callback = null;
10211						if ( evt ) {
10212							complete( evt.type === "error" ? 404 : 200, evt.type );
10213						}
10214					} );
10215
10216				// Use native DOM manipulation to avoid our domManip AJAX trickery
10217				document.head.appendChild( script[ 0 ] );
10218			},
10219			abort: function() {
10220				if ( callback ) {
10221					callback();
10222				}
10223			}
10224		};
10225	}
10226} );
10227
10228
10229
10230
10231var oldCallbacks = [],
10232	rjsonp = /(=)\?(?=&|$)|\?\?/;
10233
10234// Default jsonp settings
10235jQuery.ajaxSetup( {
10236	jsonp: "callback",
10237	jsonpCallback: function() {
10238		var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce.guid++ ) );
10239		this[ callback ] = true;
10240		return callback;
10241	}
10242} );
10243
10244// Detect, normalize options and install callbacks for jsonp requests
10245jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
10246
10247	var callbackName, overwritten, responseContainer,
10248		jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
10249			"url" :
10250			typeof s.data === "string" &&
10251				( s.contentType || "" )
10252					.indexOf( "application/x-www-form-urlencoded" ) === 0 &&
10253				rjsonp.test( s.data ) && "data"
10254		);
10255
10256	// Handle iff the expected data type is "jsonp" or we have a parameter to set
10257	if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
10258
10259		// Get callback name, remembering preexisting value associated with it
10260		callbackName = s.jsonpCallback = isFunction( s.jsonpCallback ) ?
10261			s.jsonpCallback() :
10262			s.jsonpCallback;
10263
10264		// Insert callback into url or form data
10265		if ( jsonProp ) {
10266			s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
10267		} else if ( s.jsonp !== false ) {
10268			s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
10269		}
10270
10271		// Use data converter to retrieve json after script execution
vendor: 8,362 bytes, lines 10272-10583
10272		s.converters[ "script json" ] = function() {
10273			if ( !responseContainer ) {
10274				jQuery.error( callbackName + " was not called" );
10275			}
10276			return responseContainer[ 0 ];
10277		};
10278
10279		// Force json dataType
10280		s.dataTypes[ 0 ] = "json";
10281
10282		// Install callback
10283		overwritten = window[ callbackName ];
10284		window[ callbackName ] = function() {
10285			responseContainer = arguments;
10286		};
10287
10288		// Clean-up function (fires after converters)
10289		jqXHR.always( function() {
10290
10291			// If previous value didn't exist - remove it
10292			if ( overwritten === undefined ) {
10293				jQuery( window ).removeProp( callbackName );
10294
10295			// Otherwise restore preexisting value
10296			} else {
10297				window[ callbackName ] = overwritten;
10298			}
10299
10300			// Save back as free
10301			if ( s[ callbackName ] ) {
10302
10303				// Make sure that re-using the options doesn't screw things around
10304				s.jsonpCallback = originalSettings.jsonpCallback;
10305
10306				// Save the callback name for future use
10307				oldCallbacks.push( callbackName );
10308			}
10309
10310			// Call if it was a function and we have a response
10311			if ( responseContainer && isFunction( overwritten ) ) {
10312				overwritten( responseContainer[ 0 ] );
10313			}
10314
10315			responseContainer = overwritten = undefined;
10316		} );
10317
10318		// Delegate to script
10319		return "script";
10320	}
10321} );
10322
10323
10324
10325
10326// Support: Safari 8 only
10327// In Safari 8 documents created via document.implementation.createHTMLDocument
10328// collapse sibling forms: the second one becomes a child of the first one.
10329// Because of that, this security measure has to be disabled in Safari 8.
10330// https://bugs.webkit.org/show_bug.cgi?id=137337
10331support.createHTMLDocument = ( function() {
10332	var body = document.implementation.createHTMLDocument( "" ).body;
10333	body.innerHTML = "<form></form><form></form>";
10334	return body.childNodes.length === 2;
10335} )();
10336
10337
10338// Argument "data" should be string of html
10339// context (optional): If specified, the fragment will be created in this context,
10340// defaults to document
10341// keepScripts (optional): If true, will include scripts passed in the html string
10342jQuery.parseHTML = function( data, context, keepScripts ) {
10343	if ( typeof data !== "string" ) {
10344		return [];
10345	}
10346	if ( typeof context === "boolean" ) {
10347		keepScripts = context;
10348		context = false;
10349	}
10350
10351	var base, parsed, scripts;
10352
10353	if ( !context ) {
10354
10355		// Stop scripts or inline event handlers from being executed immediately
10356		// by using document.implementation
10357		if ( support.createHTMLDocument ) {
10358			context = document.implementation.createHTMLDocument( "" );
10359
10360			// Set the base href for the created document
10361			// so any parsed elements with URLs
10362			// are based on the document's URL (gh-2965)
10363			base = context.createElement( "base" );
10364			base.href = document.location.href;
10365			context.head.appendChild( base );
10366		} else {
10367			context = document;
10368		}
10369	}
10370
10371	parsed = rsingleTag.exec( data );
10372	scripts = !keepScripts && [];
10373
10374	// Single tag
10375	if ( parsed ) {
10376		return [ context.createElement( parsed[ 1 ] ) ];
10377	}
10378
10379	parsed = buildFragment( [ data ], context, scripts );
10380
10381	if ( scripts && scripts.length ) {
10382		jQuery( scripts ).remove();
10383	}
10384
10385	return jQuery.merge( [], parsed.childNodes );
10386};
10387
10388
10389/**
10390 * Load a url into a page
10391 */
10392jQuery.fn.load = function( url, params, callback ) {
10393	var selector, type, response,
10394		self = this,
10395		off = url.indexOf( " " );
10396
10397	if ( off > -1 ) {
10398		selector = stripAndCollapse( url.slice( off ) );
10399		url = url.slice( 0, off );
10400	}
10401
10402	// If it's a function
10403	if ( isFunction( params ) ) {
10404
10405		// We assume that it's the callback
10406		callback = params;
10407		params = undefined;
10408
10409	// Otherwise, build a param string
10410	} else if ( params && typeof params === "object" ) {
10411		type = "POST";
10412	}
10413
10414	// If we have elements to modify, make the request
10415	if ( self.length > 0 ) {
10416		jQuery.ajax( {
10417			url: url,
10418
10419			// If "type" variable is undefined, then "GET" method will be used.
10420			// Make value of this field explicit since
10421			// user can override it through ajaxSetup method
10422			type: type || "GET",
10423			dataType: "html",
10424			data: params
10425		} ).done( function( responseText ) {
10426
10427			// Save response for use in complete callback
10428			response = arguments;
10429
10430			self.html( selector ?
10431
10432				// If a selector was specified, locate the right elements in a dummy div
10433				// Exclude scripts to avoid IE 'Permission Denied' errors
10434				jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) :
10435
10436				// Otherwise use the full result
10437				responseText );
10438
10439		// If the request succeeds, this function gets "data", "status", "jqXHR"
10440		// but they are ignored because response was set above.
10441		// If it fails, this function gets "jqXHR", "status", "error"
10442		} ).always( callback && function( jqXHR, status ) {
10443			self.each( function() {
10444				callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] );
10445			} );
10446		} );
10447	}
10448
10449	return this;
10450};
10451
10452
10453
10454
10455jQuery.expr.pseudos.animated = function( elem ) {
10456	return jQuery.grep( jQuery.timers, function( fn ) {
10457		return elem === fn.elem;
10458	} ).length;
10459};
10460
10461
10462
10463
10464jQuery.offset = {
10465	setOffset: function( elem, options, i ) {
10466		var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
10467			position = jQuery.css( elem, "position" ),
10468			curElem = jQuery( elem ),
10469			props = {};
10470
10471		// Set position first, in-case top/left are set even on static elem
10472		if ( position === "static" ) {
10473			elem.style.position = "relative";
10474		}
10475
10476		curOffset = curElem.offset();
10477		curCSSTop = jQuery.css( elem, "top" );
10478		curCSSLeft = jQuery.css( elem, "left" );
10479		calculatePosition = ( position === "absolute" || position === "fixed" ) &&
10480			( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1;
10481
10482		// Need to be able to calculate position if either
10483		// top or left is auto and position is either absolute or fixed
10484		if ( calculatePosition ) {
10485			curPosition = curElem.position();
10486			curTop = curPosition.top;
10487			curLeft = curPosition.left;
10488
10489		} else {
10490			curTop = parseFloat( curCSSTop ) || 0;
10491			curLeft = parseFloat( curCSSLeft ) || 0;
10492		}
10493
10494		if ( isFunction( options ) ) {
10495
10496			// Use jQuery.extend here to allow modification of coordinates argument (gh-1848)
10497			options = options.call( elem, i, jQuery.extend( {}, curOffset ) );
10498		}
10499
10500		if ( options.top != null ) {
10501			props.top = ( options.top - curOffset.top ) + curTop;
10502		}
10503		if ( options.left != null ) {
10504			props.left = ( options.left - curOffset.left ) + curLeft;
10505		}
10506
10507		if ( "using" in options ) {
10508			options.using.call( elem, props );
10509
10510		} else {
10511			curElem.css( props );
10512		}
10513	}
10514};
10515
10516jQuery.fn.extend( {
10517
10518	// offset() relates an element's border box to the document origin
10519	offset: function( options ) {
10520
10521		// Preserve chaining for setter
10522		if ( arguments.length ) {
10523			return options === undefined ?
10524				this :
10525				this.each( function( i ) {
10526					jQuery.offset.setOffset( this, options, i );
10527				} );
10528		}
10529
10530		var rect, win,
10531			elem = this[ 0 ];
10532
10533		if ( !elem ) {
10534			return;
10535		}
10536
10537		// Return zeros for disconnected and hidden (display: none) elements (gh-2310)
10538		// Support: IE <=11 only
10539		// Running getBoundingClientRect on a
10540		// disconnected node in IE throws an error
10541		if ( !elem.getClientRects().length ) {
10542			return { top: 0, left: 0 };
10543		}
10544
10545		// Get document-relative position by adding viewport scroll to viewport-relative gBCR
10546		rect = elem.getBoundingClientRect();
10547		win = elem.ownerDocument.defaultView;
10548		return {
10549			top: rect.top + win.pageYOffset,
10550			left: rect.left + win.pageXOffset
10551		};
10552	},
10553
10554	// position() relates an element's margin box to its offset parent's padding box
10555	// This corresponds to the behavior of CSS absolute positioning
10556	position: function() {
10557		if ( !this[ 0 ] ) {
10558			return;
10559		}
10560
10561		var offsetParent, offset, doc,
10562			elem = this[ 0 ],
10563			parentOffset = { top: 0, left: 0 };
10564
10565		// position:fixed elements are offset from the viewport, which itself always has zero offset
10566		if ( jQuery.css( elem, "position" ) === "fixed" ) {
10567
10568			// Assume position:fixed implies availability of getBoundingClientRect
10569			offset = elem.getBoundingClientRect();
10570
10571		} else {
10572			offset = this.offset();
10573
10574			// Account for the *real* offset parent, which can be the document or its root element
10575			// when a statically positioned element is identified
10576			doc = elem.ownerDocument;
10577			offsetParent = elem.offsetParent || doc.documentElement;
10578			while ( offsetParent &&
10579				( offsetParent === doc.body || offsetParent === doc.documentElement ) &&
10580				jQuery.css( offsetParent, "position" ) === "static" ) {
10581
10582				offsetParent = offsetParent.parentNode;
10583			}
vendor: 8,798 bytes, lines 10584-10875
10584			if ( offsetParent && offsetParent !== elem && offsetParent.nodeType === 1 ) {
10585
10586				// Incorporate borders into its offset, since they are outside its content origin
10587				parentOffset = jQuery( offsetParent ).offset();
10588				parentOffset.top += jQuery.css( offsetParent, "borderTopWidth", true );
10589				parentOffset.left += jQuery.css( offsetParent, "borderLeftWidth", true );
10590			}
10591		}
10592
10593		// Subtract parent offsets and element margins
10594		return {
10595			top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
10596			left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
10597		};
10598	},
10599
10600	// This method will return documentElement in the following cases:
10601	// 1) For the element inside the iframe without offsetParent, this method will return
10602	//    documentElement of the parent window
10603	// 2) For the hidden or detached element
10604	// 3) For body or html element, i.e. in case of the html node - it will return itself
10605	//
10606	// but those exceptions were never presented as a real life use-cases
10607	// and might be considered as more preferable results.
10608	//
10609	// This logic, however, is not guaranteed and can change at any point in the future
10610	offsetParent: function() {
10611		return this.map( function() {
10612			var offsetParent = this.offsetParent;
10613
10614			while ( offsetParent && jQuery.css( offsetParent, "position" ) === "static" ) {
10615				offsetParent = offsetParent.offsetParent;
10616			}
10617
10618			return offsetParent || documentElement;
10619		} );
10620	}
10621} );
10622
10623// Create scrollLeft and scrollTop methods
10624jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
10625	var top = "pageYOffset" === prop;
10626
10627	jQuery.fn[ method ] = function( val ) {
10628		return access( this, function( elem, method, val ) {
10629
10630			// Coalesce documents and windows
10631			var win;
10632			if ( isWindow( elem ) ) {
10633				win = elem;
10634			} else if ( elem.nodeType === 9 ) {
10635				win = elem.defaultView;
10636			}
10637
10638			if ( val === undefined ) {
10639				return win ? win[ prop ] : elem[ method ];
10640			}
10641
10642			if ( win ) {
10643				win.scrollTo(
10644					!top ? val : win.pageXOffset,
10645					top ? val : win.pageYOffset
10646				);
10647
10648			} else {
10649				elem[ method ] = val;
10650			}
10651		}, method, val, arguments.length );
10652	};
10653} );
10654
10655// Support: Safari <=7 - 9.1, Chrome <=37 - 49
10656// Add the top/left cssHooks using jQuery.fn.position
10657// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
10658// Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347
10659// getComputedStyle returns percent when specified for top/left/bottom/right;
10660// rather than make the css module depend on the offset module, just check for it here
10661jQuery.each( [ "top", "left" ], function( _i, prop ) {
10662	jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
10663		function( elem, computed ) {
10664			if ( computed ) {
10665				computed = curCSS( elem, prop );
10666
10667				// If curCSS returns percentage, fallback to offset
10668				return rnumnonpx.test( computed ) ?
10669					jQuery( elem ).position()[ prop ] + "px" :
10670					computed;
10671			}
10672		}
10673	);
10674} );
10675
10676
10677// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
10678jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
10679	jQuery.each( {
10680		padding: "inner" + name,
10681		content: type,
10682		"": "outer" + name
10683	}, function( defaultExtra, funcName ) {
10684
10685		// Margin is only for outerHeight, outerWidth
10686		jQuery.fn[ funcName ] = function( margin, value ) {
10687			var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
10688				extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
10689
10690			return access( this, function( elem, type, value ) {
10691				var doc;
10692
10693				if ( isWindow( elem ) ) {
10694
10695					// $( window ).outerWidth/Height return w/h including scrollbars (gh-1729)
10696					return funcName.indexOf( "outer" ) === 0 ?
10697						elem[ "inner" + name ] :
10698						elem.document.documentElement[ "client" + name ];
10699				}
10700
10701				// Get document width or height
10702				if ( elem.nodeType === 9 ) {
10703					doc = elem.documentElement;
10704
10705					// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
10706					// whichever is greatest
10707					return Math.max(
10708						elem.body[ "scroll" + name ], doc[ "scroll" + name ],
10709						elem.body[ "offset" + name ], doc[ "offset" + name ],
10710						doc[ "client" + name ]
10711					);
10712				}
10713
10714				return value === undefined ?
10715
10716					// Get width or height on the element, requesting but not forcing parseFloat
10717					jQuery.css( elem, type, extra ) :
10718
10719					// Set width or height on the element
10720					jQuery.style( elem, type, value, extra );
10721			}, type, chainable ? margin : undefined, chainable );
10722		};
10723	} );
10724} );
10725
10726
10727jQuery.each( [
10728	"ajaxStart",
10729	"ajaxStop",
10730	"ajaxComplete",
10731	"ajaxError",
10732	"ajaxSuccess",
10733	"ajaxSend"
10734], function( _i, type ) {
10735	jQuery.fn[ type ] = function( fn ) {
10736		return this.on( type, fn );
10737	};
10738} );
10739
10740
10741
10742
10743jQuery.fn.extend( {
10744
10745	bind: function( types, data, fn ) {
10746		return this.on( types, null, data, fn );
10747	},
10748	unbind: function( types, fn ) {
10749		return this.off( types, null, fn );
10750	},
10751
10752	delegate: function( selector, types, data, fn ) {
10753		return this.on( types, selector, data, fn );
10754	},
10755	undelegate: function( selector, types, fn ) {
10756
10757		// ( namespace ) or ( selector, types [, fn] )
10758		return arguments.length === 1 ?
10759			this.off( selector, "**" ) :
10760			this.off( types, selector || "**", fn );
10761	},
10762
10763	hover: function( fnOver, fnOut ) {
10764		return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
10765	}
10766} );
10767
10768jQuery.each(
10769	( "blur focus focusin focusout resize scroll click dblclick " +
10770	"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
10771	"change select submit keydown keypress keyup contextmenu" ).split( " " ),
10772	function( _i, name ) {
10773
10774		// Handle event binding
10775		jQuery.fn[ name ] = function( data, fn ) {
10776			return arguments.length > 0 ?
10777				this.on( name, null, data, fn ) :
10778				this.trigger( name );
10779		};
10780	}
10781);
10782
10783
10784
10785
10786// Support: Android <=4.0 only
10787// Make sure we trim BOM and NBSP
10788// Require that the "whitespace run" starts from a non-whitespace
10789// to avoid O(N^2) behavior when the engine would try matching "\s+$" at each space position.
10790var rtrim = /^[\s\uFEFF\xA0]+|([^\s\uFEFF\xA0])[\s\uFEFF\xA0]+$/g;
10791
10792// Bind a function to a context, optionally partially applying any
10793// arguments.
10794// jQuery.proxy is deprecated to promote standards (specifically Function#bind)
10795// However, it is not slated for removal any time soon
10796jQuery.proxy = function( fn, context ) {
10797	var tmp, args, proxy;
10798
10799	if ( typeof context === "string" ) {
10800		tmp = fn[ context ];
10801		context = fn;
10802		fn = tmp;
10803	}
10804
10805	// Quick check to determine if target is callable, in the spec
10806	// this throws a TypeError, but we will just return undefined.
10807	if ( !isFunction( fn ) ) {
10808		return undefined;
10809	}
10810
10811	// Simulated bind
10812	args = slice.call( arguments, 2 );
10813	proxy = function() {
10814		return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
10815	};
10816
10817	// Set the guid of unique handler to the same of original handler, so it can be removed
10818	proxy.guid = fn.guid = fn.guid || jQuery.guid++;
10819
10820	return proxy;
10821};
10822
10823jQuery.holdReady = function( hold ) {
10824	if ( hold ) {
10825		jQuery.readyWait++;
10826	} else {
10827		jQuery.ready( true );
10828	}
10829};
10830jQuery.isArray = Array.isArray;
10831jQuery.parseJSON = JSON.parse;
10832jQuery.nodeName = nodeName;
10833jQuery.isFunction = isFunction;
10834jQuery.isWindow = isWindow;
10835jQuery.camelCase = camelCase;
10836jQuery.type = toType;
10837
10838jQuery.now = Date.now;
10839
10840jQuery.isNumeric = function( obj ) {
10841
10842	// As of jQuery 3.0, isNumeric is limited to
10843	// strings and numbers (primitives or objects)
10844	// that can be coerced to finite numbers (gh-2662)
10845	var type = jQuery.type( obj );
10846	return ( type === "number" || type === "string" ) &&
10847
10848		// parseFloat NaNs numeric-cast false positives ("")
10849		// ...but misinterprets leading-number strings, particularly hex literals ("0x...")
10850		// subtraction forces infinities to NaN
10851		!isNaN( obj - parseFloat( obj ) );
10852};
10853
10854jQuery.trim = function( text ) {
10855	return text == null ?
10856		"" :
10857		( text + "" ).replace( rtrim, "$1" );
10858};
10859
10860
10861
10862// Register as a named AMD module, since jQuery can be concatenated with other
10863// files that may use define, but not via a proper concatenation script that
10864// understands anonymous AMD modules. A named AMD is safest and most robust
10865// way to register. Lowercase jquery is used because AMD module names are
10866// derived from file names, and jQuery is normally delivered in a lowercase
10867// file name. Do this after creating the global so that if an AMD module wants
10868// to call noConflict to hide this version of jQuery, it will work.
10869
10870// Note that for maximum portability, libraries that are not jQuery should
10871// declare themselves as anonymous modules, and avoid setting a global if an
10872// AMD loader is present. jQuery is a special case. For more information, see
10873// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
10874
10875if ( t
vendor: 6,946 bytes, lines 10875-10924
10875rue ) {
10876	!(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = (function() {
10877		return jQuery;
10878	}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
10879		__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
10880}
10881
10882
10883
10884
10885var
10886
10887	// Map over jQuery in case of overwrite
10888	_jQuery = window.jQuery,
10889
10890	// Map over the $ in case of overwrite
10891	_$ = window.$;
10892
10893jQuery.noConflict = function( deep ) {
10894	if ( window.$ === jQuery ) {
10895		window.$ = _$;
10896	}
10897
10898	if ( deep && window.jQuery === jQuery ) {
10899		window.jQuery = _jQuery;
10900	}
10901
10902	return jQuery;
10903};
10904
10905// Expose jQuery and $ identifiers, even in AMD
10906// (trac-7102#comment:10, https://github.com/jquery/jquery/pull/557)
10907// and CommonJS for browser emulators (trac-13566)
10908if ( typeof noGlobal === "undefined" ) {
10909	window.jQuery = window.$ = jQuery;
10910}
10911
10912
10913
10914
10915return jQuery;
10916} );
10917
10918
10919/***/ }),
10920
10921/***/ 582:
10922/***/ (function(module) {
10923
10924!function(t,i){ true?module.exports=i():0}(this,function(){"use strict";function t(t,r,e,a,h){!function t(n,r,e,a,h){for(;a>e;){if(a-e>600){var o=a-e+1,s=r-e+1,l=Math.log(o),f=.5*Math.exp(2*l/3),u=.5*Math.sqrt(l*f*(o-f)/o)*(s-o/2<0?-1:1),m=Math.max(e,Math.floor(r-s*f/o+u)),c=Math.min(a,Math.floor(r+(o-s)*f/o+u));t(n,r,m,c,h)}var p=n[r],d=e,x=a;for(i(n,e,r),h(n[a],p)>0&&i(n,e,a);d<x;){for(i(n,d,x),d++,x--;h(n[d],p)<0;)d++;for(;h(n[x],p)>0;)x--}0===h(n[e],p)?i(n,e,x):i(n,++x,a),x<=r&&(e=x+1),r<=x&&(a=x-1)}}(t,r,e||0,a||t.length-1,h||n)}function i(t,i,n){var r=t[i];t[i]=t[n],t[n]=r}function n(t,i){return t<i?-1:t>i?1:0}var r=function(t){void 0===t&&(t=9),this._maxEntries=Math.max(4,t),this._minEntries=Math.max(2,Math.ceil(.4*this._maxEntries)),this.clear()};function e(t,i,n){if(!n)return i.indexOf(t);for(var r=0;r<i.length;r++)if(n(t,i[r]))return r;return-1}function a(t,i){h(t,0,t.children.length,i,t)}function h(t,i,n,r,e){e||(e=p(null)),e.minX=1/0,e.minY=1/0,e.maxX=-1/0,e.maxY=-1/0;for(var a=i;a<n;a++){var h=t.children[a];o(e,t.leaf?r(h):h)}return e}function o(t,i){return t.minX=Math.min(t.minX,i.minX),t.minY=Math.min(t.minY,i.minY),t.maxX=Math.max(t.maxX,i.maxX),t.maxY=Math.max(t.maxY,i.maxY),t}function s(t,i){return t.minX-i.minX}function l(t,i){return t.minY-i.minY}function f(t){return(t.maxX-t.minX)*(t.maxY-t.minY)}function u(t){return t.maxX-t.minX+(t.maxY-t.minY)}function m(t,i){return t.minX<=i.minX&&t.minY<=i.minY&&i.maxX<=t.maxX&&i.maxY<=t.maxY}function c(t,i){return i.minX<=t.maxX&&i.minY<=t.maxY&&i.maxX>=t.minX&&i.maxY>=t.minY}function p(t){return{children:t,height:1,leaf:!0,minX:1/0,minY:1/0,maxX:-1/0,maxY:-1/0}}function d(i,n,r,e,a){for(var h=[n,r];h.length;)if(!((r=h.pop())-(n=h.pop())<=e)){var o=n+Math.ceil((r-n)/e/2)*e;t(i,o,n,r,a),h.push(n,o,o,r)}}return r.prototype.all=function(){return this._all(this.data,[])},r.prototype.search=function(t){var i=this.data,n=[];if(!c(t,i))return n;for(var r=this.toBBox,e=[];i;){for(var a=0;a<i.children.length;a++){var h=i.children[a],o=i.leaf?r(h):h;c(t,o)&&(i.leaf?n.push(h):m(t,o)?this._all(h,n):e.push(h))}i=e.pop()}return n},r.prototype.collides=function(t){var i=this.data;if(!c(t,i))return!1;for(var n=[];i;){for(var r=0;r<i.children.length;r++){var e=i.children[r],a=i.leaf?this.toBBox(e):e;if(c(t,a)){if(i.leaf||m(t,a))return!0;n.push(e)}}i=n.pop()}return!1},r.prototype.load=function(t){if(!t||!t.length)return this;if(t.length<this._minEntries){for(var i=0;i<t.length;i++)this.insert(t[i]);return this}var n=this._build(t.slice(),0,t.length-1,0);if(this.data.children.length)if(this.data.height===n.height)this._splitRoot(this.data,n);else{if(this.data.height<n.height){var r=this.data;this.data=n,n=r}this._insert(n,this.data.height-n.height-1,!0)}else this.data=n;return this},r.prototype.insert=function(t){return t&&this._insert(t,this.data.height-1),this},r.prototype.clear=function(){return this.data=p([]),this},r.prototype.remove=function(t,i){if(!t)return this;for(var n,r,a,h=this.data,o=this.toBBox(t),s=[],l=[];h||s.length;){if(h||(h=s.pop(),r=s[s.length-1],n=l.pop(),a=!0),h.leaf){var f=e(t,h.children,i);if(-1!==f)return h.children.splice(f,1),s.push(h),this._condense(s),this}a||h.leaf||!m(h,o)?r?(n++,h=r.children[n],a=!1):h=null:(s.push(h),l.push(n),n=0,r=h,h=h.children[0])}return this},r.prototype.toBBox=function(t){return t},r.prototype.compareMinX=function(t,i){return t.minX-i.minX},r.prototype.compareMinY=function(t,i){return t.minY-i.minY},r.prototype.toJSON=function(){return this.data},r.prototype.fromJSON=function(t){return this.data=t,this},r.prototype._all=function(t,i){for(var n=[];t;)t.leaf?i.push.apply(i,t.children):n.push.apply(n,t.children),t=n.pop();return i},r.prototype._build=function(t,i,n,r){var e,h=n-i+1,o=this._maxEntries;if(h<=o)return a(e=p(t.slice(i,n+1)),this.toBBox),e;r||(r=Math.ceil(Math.log(h)/Math.log(o)),o=Math.ceil(h/Math.pow(o,r-1))),(e=p([])).leaf=!1,e.height=r;var s=Math.ceil(h/o),l=s*Math.ceil(Math.sqrt(o));d(t,i,n,l,this.compareMinX);for(var f=i;f<=n;f+=l){var u=Math.min(f+l-1,n);d(t,f,u,s,this.compareMinY);for(var m=f;m<=u;m+=s){var c=Math.min(m+s-1,u);e.children.push(this._build(t,m,c,r-1))}}return a(e,this.toBBox),e},r.prototype._chooseSubtree=function(t,i,n,r){for(;r.push(i),!i.leaf&&r.length-1!==n;){for(var e=1/0,a=1/0,h=void 0,o=0;o<i.children.length;o++){var s=i.children[o],l=f(s),u=(m=t,c=s,(Math.max(c.maxX,m.maxX)-Math.min(c.minX,m.minX))*(Math.max(c.maxY,m.maxY)-Math.min(c.minY,m.minY))-l);u<a?(a=u,e=l<e?l:e,h=s):u===a&&l<e&&(e=l,h=s)}i=h||i.children[0]}var m,c;return i},r.prototype._insert=function(t,i,n){var r=n?t:this.toBBox(t),e=[],a=this._chooseSubtree(r,this.data,i,e);for(a.children.push(t),o(a,r);i>=0&&e[i].children.length>this._maxEntries;)this._split(e,i),i--;this._adjustParentBBoxes(r,e,i)},r.prototype._split=function(t,i){var n=t[i],r=n.children.length,e=this._minEntries;this._chooseSplitAxis(n,e,r);var h=this._chooseSplitIndex(n,e,r),o=p(n.children.splice(h,n.children.length-h));o.height=n.height,o.leaf=n.leaf,a(n,this.toBBox),a(o,this.toBBox),i?t[i-1].children.push(o):this._splitRoot(n,o)},r.prototype._splitRoot=function(t,i){this.data=p([t,i]),this.data.height=t.height+1,this.data.leaf=!1,a(this.data,this.toBBox)},r.prototype._chooseSplitIndex=function(t,i,n){for(var r,e,a,o,s,l,u,m=1/0,c=1/0,p=i;p<=n-i;p++){var d=h(t,0,p,this.toBBox),x=h(t,p,n,this.toBBox),v=(e=d,a=x,o=void 0,s=void 0,l=void 0,u=void 0,o=Math.max(e.minX,a.minX),s=Math.max(e.minY,a.minY),l=Math.min(e.maxX,a.maxX),u=Math.min(e.maxY,a.maxY),Math.max(0,l-o)*Math.max(0,u-s)),M=f(d)+f(x);v<m?(m=v,r=p,c=M<c?M:c):v===m&&M<c&&(c=M,r=p)}return r||n-i},r.prototype._chooseSplitAxis=function(t,i,n){var r=t.leaf?this.compareMinX:s,e=t.leaf?this.compareMinY:l;this._allDistMargin(t,i,n,r)<this._allDistMargin(t,i,n,e)&&t.children.sort(r)},r.prototype._allDistMargin=function(t,i,n,r){t.children.sort(r);for(var e=this.toBBox,a=h(t,0,i,e),s=h(t,n-i,n,e),l=u(a)+u(s),f=i;f<n-i;f++){var m=t.children[f];o(a,t.leaf?e(m):m),l+=u(a)}for(var c=n-i-1;c>=i;c--){var p=t.children[c];
10924o(s,t.leaf?e(p):p),l+=u(s)}return l},r.prototype._adjustParentBBoxes=function(t,i,n){for(var r=n;r>=0;r--)o(i[r],t)},r.prototype._condense=function(t){for(var i=t.length-1,n=void 0;i>=0;i--)0===t[i].children.length?i>0?(n=t[i-1].children).splice(n.indexOf(t[i]),1):this.clear():a(t[i],this.toBBox)},r});
10925
10926
10927/***/ })
10928
10929/******/ 	});
10930/************************************************************************/
10931/******/ 	// The module cache
10932/******/ 	var __webpack_module_cache__ = {};
10933/******/ 	
10934/******/ 	// The require function
10935/******/ 	function __webpack_require__(moduleId) {
10936/******/ 		// Check if module is in cache
10937/******/ 		var cachedModule = __webpack_module_cache__[moduleId];
10938/******/ 		if (cachedModule !== undefined) {
10939/******/ 			return cachedModule.exports;
10940/******/ 		}
10941/******/ 		// Create a new module (and put it into the cache)
10942/******/ 		var module = __webpack_module_cache__[moduleId] = {
10943/******/ 			// no module.id needed
10944/******/ 			// no module.loaded needed
10945/******/ 			exports: {}
10946/******/ 		};
10947/******/ 	
10948/******/ 		// Execute the module function
10949/******/ 		__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
10950/******/ 	
10951/******/ 		// Return the exports of the module
10952/******/ 		return module.exports;
10953/******/ 	}
10954/******/ 	
10955/************************************************************************/
10956/******/ 	/* webpack/runtime/global */
10957/******/ 	(() => {
10958/******/ 		__webpack_require__.g = (function() {
10959/******/ 			if (typeof globalThis === 'object') return globalThis;
10960/******/ 			try {
10961/******/ 				return this || new Function('return this')();
10962/******/ 			} catch (e) {
10963/******/ 				if (typeof window === 'object') return window;
10964/******/ 			}
10965/******/ 		})();
10966/******/ 	})();
10967/******/ 	
10968/************************************************************************/
10969var __webpack_exports__ = {};
10970// This entry need to be wrapped in an IIFE because it need to be in strict mode.
10971(() => {
10972"use strict";
10973
10974;// CONCATENATED MODULE: ./node_modules/ol/events/Event.js
10975/**
10976 * @module ol/events/Event
10977 */
10978
10979/**
10980 * @classdesc
10981 * Stripped down implementation of the W3C DOM Level 2 Event interface.
10982 * See https://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-interface.
10983 *
10984 * This implementation only provides `type` and `target` properties, and
10985 * `stopPropagation` and `preventDefault` methods. It is meant as base class
10986 * for higher level events defined in the library, and works with
10987 * {@link module:ol/events/Target~Target}.
10988 */
10989class BaseEvent {
10990  /**
10991   * @param {string} type Type.
10992   */
10993  constructor(type) {
10994    /**
10995     * @type {boolean}
10996     */
10997    this.propagationStopped;
10998
10999    /**
11000     * @type {boolean}
11001     */
11002    this.defaultPrevented;
11003
11004    /**
11005     * The event type.
11006     * @type {string}
11007     * @api
11008     */
11009    this.type = type;
11010
11011    /**
11012     * The event target.
11013     * @type {Object}
11014     * @api
11015     */
11016    this.target = null;
11017  }
11018
11019  /**
11020   * Prevent default. This means that no emulated `click`, `singleclick` or `doubleclick` events
11021   * will be fired.
11022   * @api
11023   */
11024  preventDefault() {
11025    this.defaultPrevented = true;
11026  }
11027
11028  /**
11029   * Stop event propagation.
11030   * @api
11031   */
11032  stopPropagation() {
11033    this.propagationStopped = true;
11034  }
11035}
11036
11037/**
11038 * @param {Event|import("./Event.js").default} evt Event
11039 */
11040function stopPropagation(evt) {
11041  evt.stopPropagation();
11042}
11043
11044/**
11045 * @param {Event|import("./Event.js").default} evt Event
11046 */
11047function preventDefault(evt) {
11048  evt.preventDefault();
11049}
11050
11051/* harmony default export */ const Event = (BaseEvent);
11052
11053;// CONCATENATED MODULE: ./node_modules/ol/ObjectEventType.js
11054/**
11055 * @module ol/ObjectEventType
11056 */
11057
11058/**
11059 * @enum {string}
11060 */
11061/* harmony default export */ const ObjectEventType = ({
11062  /**
11063   * Triggered when a property is changed.
11064   * @event module:ol/Object.ObjectEvent#propertychange
11065   * @api
11066   */
11067  PROPERTYCHANGE: 'propertychange',
11068});
11069
11070/**
11071 * @typedef {'propertychange'} Types
11072 */
11073
11074;// CONCATENATED MODULE: ./node_modules/ol/Disposable.js
11075/**
11076 * @module ol/Disposable
11077 */
11078
11079/**
11080 * @classdesc
11081 * Objects that need to clean up after themselves.
11082 */
11083class Disposable {
11084  constructor() {
11085    /**
11086     * The object has already been disposed.
11087     * @type {boolean}
11088     * @protected
11089     */
11090    this.disposed = false;
11091  }
11092
11093  /**
11094   * Clean up.
11095   */
11096  dispose() {
11097    if (!this.disposed) {
11098      this.disposed = true;
11099      this.disposeInternal();
11100    }
11101  }
11102
11103  /**
11104   * Extension point for disposable objects.
11105   * @protected
11106   */
11107  disposeInternal() {}
11108}
11109
11110/* harmony default export */ const ol_Disposable = (Disposable);
11111
11112;// CONCATENATED MODULE: ./node_modules/ol/array.js
11113/**
11114 * @module ol/array
11115 */
11116
11117/**
11118 * Performs a binary search on the provided sorted list and returns the index of the item if found. If it can't be found it'll return -1.
11119 * https://github.com/darkskyapp/binary-search
11120 *
11121 * @param {Array<*>} haystack Items to search through.
11122 * @param {*} needle The item to look for.
11123 * @param {Function} [comparator] Comparator function.
11124 * @return {number} The index of the item if found, -1 if not.
11125 */
11126function binarySearch(haystack, needle, comparator) {
11127  let mid, cmp;
11128  comparator = comparator || numberSafeCompareFunction;
11129  let low = 0;
11130  let high = haystack.length;
11131  let found = false;
11132
11133  while (low < high) {
11134    /* Note that "(low + high) >>> 1" may overflow, and results in a typecast
11135     * to double (which gives the wrong results). */
11136    mid = low + ((high - low) >> 1);
11137    cmp = +comparator(haystack[mid], needle);
11138
11139    if (cmp < 0.0) {
11140      /* Too low. */
11141      low = mid + 1;
11142    } else {
11143      /* Key found or too high */
11144      high = mid;
11145      found = !cmp;
11146    }
11147  }
11148
11149  /* Key not found. */
11150  return found ? low : ~low;
11151}
11152
11153/**
11154 * Compare function for array sort that is safe for numbers.
11155 * @param {*} a The first object to be compared.
11156 * @param {*} b The second object to be compared.
11157 * @return {number} A negative number, zero, or a positive number as the first
11158 *     argument is less than, equal to, or greater than the second.
11159 */
11160function numberSafeCompareFunction(a, b) {
11161  return a > b ? 1 : a < b ? -1 : 0;
11162}
11163
11164/**
11165 * {@link module:ol/tilegrid/TileGrid~TileGrid#getZForResolution} can use a function
11166 * of this type to determine which nearest resolution to use.
11167 *
11168 * This function takes a `{number}` representing a value between two array entries,
11169 * a `{number}` representing the value of the nearest higher entry and
11170 * a `{number}` representing the value of the nearest lower entry
11171 * as arguments and returns a `{number}`. If a negative number or zero is returned
11172 * the lower value will be used, if a positive number is returned the higher value
11173 * will be used.
11174 * @typedef {function(number, number, number): number} NearestDirectionFunction
11175 * @api
11176 */
11177
11178/**
11179 * @param {Array<number>} arr Array in descending order.
11180 * @param {number} target Target.
11181 * @param {number|NearestDirectionFunction} direction
11182 *    0 means return the nearest,
11183 *    > 0 means return the largest nearest,
11184 *    < 0 means return the smallest nearest.
11185 * @return {number} Index.
11186 */
11187function linearFindNearest(arr, target, direction) {
11188  const n = arr.length;
11189  if (arr[0] <= target) {
11190    return 0;
11191  } else if (target <= arr[n - 1]) {
11192    return n - 1;
11193  } else {
11194    let i;
11195    if (direction > 0) {
11196      for (i = 1; i < n; ++i) {
11197        if (arr[i] < target) {
11198          return i - 1;
11199        }
11200      }
11201    } else if (direction < 0) {
11202      for (i = 1; i < n; ++i) {
11203        if (arr[i] <= target) {
11204          return i;
11205        }
11206      }
11207    } else {
11208      for (i = 1; i < n; ++i) {
11209        if (arr[i] == target) {
11210          return i;
11211        } else if (arr[i] < target) {
11212          if (typeof direction === 'function') {
11213            if (direction(target, arr[i - 1], arr[i]) > 0) {
11214              return i - 1;
11215            } else {
11216              return i;
11217            }
11218          } else if (arr[i - 1] - target < target - arr[i]) {
11219            return i - 1;
11220          } else {
11221            return i;
11222          }
11223        }
11224      }
11225    }
11226    return n - 1;
11227  }
11228}
11229
11230/**
11231 * @param {Array<*>} arr Array.
11232 * @param {number} begin Begin index.
11233 * @param {number} end End index.
11234 */
11235function reverseSubArray(arr, begin, end) {
11236  while (begin < end) {
11237    const tmp = arr[begin];
11238    arr[begin] = arr[end];
11239    arr[end] = tmp;
11240    ++begin;
11241    --end;
11242  }
11243}
11244
11245/**
11246 * @param {Array<VALUE>} arr The array to modify.
11247 * @param {!Array<VALUE>|VALUE} data The elements or arrays of elements to add to arr.
11248 * @template VALUE
11249 */
11250function array_extend(arr, data) {
11251  const extension = Array.isArray(data) ? data : [data];
11252  const length = extension.length;
11253  for (let i = 0; i < length; i++) {
11254    arr[arr.length] = extension[i];
11255  }
11256}
11257
11258/**
11259 * @param {Array<VALUE>} arr The array to modify.
11260 * @param {VALUE} obj The element to remove.
11261 * @template VALUE
11262 * @return {boolean} If the element was removed.
11263 */
11264function remove(arr, obj) {
11265  const i = arr.indexOf(obj);
11266  const found = i > -1;
11267  if (found) {
11268    arr.splice(i, 1);
11269  }
11270  return found;
11271}
11272
11273/**
11274 * @param {Array|Uint8ClampedArray} arr1 The first array to compare.
11275 * @param {Array|Uint8ClampedArray} arr2 The second array to compare.
11276 * @return {boolean} Whether the two arrays are equal.
11277 */
11278function equals(arr1, arr2) {
11279  const len1 = arr1.length;
11280  if (len1 !== arr2.length) {
11281    return false;
11282  }
11283  for (let i = 0; i < len1; i++) {
11284    if (arr1[i] !== arr2[i]) {
11285      return false;
11286    }
11287  }
11288  return true;
11289}
11290
11291/**
11292 * Sort the passed array such that the relative order of equal elements is preserved.
11293 * See https://en.wikipedia.org/wiki/Sorting_algorithm#Stability for details.
11294 * @param {Array<*>} arr The array to sort (modifies original).
11295 * @param {!function(*, *): number} compareFnc Comparison function.
11296 * @api
11297 */
11298function stableSort(arr, compareFnc) {
11299  const length = arr.length;
11300  const tmp = Array(arr.length);
11301  let i;
11302  for (i = 0; i < length; i++) {
11303    tmp[i] = {index: i, value: arr[i]};
11304  }
11305  tmp.sort(function (a, b) {
11306    return compareFnc(a.value, b.value) || a.index - b.index;
11307  });
11308  for (i = 0; i < arr.length; i++) {
11309    arr[i] = tmp[i].value;
11310  }
11311}
11312
11313/**
11314 * @param {Array<*>} arr The array to test.
11315 * @param {Function} [func] Comparison function.
11316 * @param {boolean} [strict] Strictly sorted (default false).
11317 * @return {boolean} Return index.
11318 */
11319function isSorted(arr, func, strict) {
11320  const compare = func || numberSafeCompareFunction;
11321  return arr.every(function (currentVal, index) {
11322    if (index === 0) {
11323      return true;
11324    }
11325    const res = compare(arr[index - 1], currentVal);
11326    return !(res > 0 || (strict && res === 0));
11327  });
11328}
11329
11330;// CONCATENATED MODULE: ./node_modules/ol/functions.js
11331/**
11332 * @module ol/functions
11333 */
11334
11335
11336
11337/**
11338 * Always returns true.
11339 * @return {boolean} true.
11340 */
11341function TRUE() {
11342  return true;
11343}
11344
11345/**
11346 * Always returns false.
11347 * @return {boolean} false.
11348 */
11349function functions_FALSE() {
11350  return false;
11351}
11352
11353/**
11354 * A reusable function, used e.g. as a default for callbacks.
11355 *
11356 * @return {void} Nothing.
11357 */
11358function VOID() {}
11359
11360/**
11361 * Wrap a function in another function that remembers the last return.  If the
11362 * returned function is called twice in a row with the same arguments and the same
11363 * this object, it will return the value from the first call in the second call.
11364 *
11365 * @param {function(...any): ReturnType} fn The function to memoize.
11366 * @return {function(...any): ReturnType} The memoized function.
11367 * @template ReturnType
11368 */
11369function memoizeOne(fn) {
11370  let called = false;
11371
11372  /** @type {ReturnType} */
11373  let lastResult;
11374
11375  /** @type {Array<any>} */
11376  let lastArgs;
11377
11378  let lastThis;
11379
11380  return function () {
11381    const nextArgs = Array.prototype.slice.call(arguments);
11382    if (!called || this !== lastThis || !equals(nextArgs, lastArgs)) {
11383      called = true;
11384      lastThis = this;
11385      lastArgs = nextArgs;
11386      lastResult = fn.apply(this, arguments);
11387    }
11388    return lastResult;
11389  };
11390}
11391
11392/**
11393 * @template T
11394 * @param {function(): (T | Promise<T>)} getter A function that returns a value or a promise for a value.
11395 * @return {Promise<T>} A promise for the value.
11396 */
11397function toPromise(getter) {
11398  function promiseGetter() {
11399    let value;
11400    try {
11401      value = getter();
11402    } catch (err) {
11403      return Promise.reject(err);
11404    }
11405    if (value instanceof Promise) {
11406      return value;
11407    }
11408    return Promise.resolve(value);
11409  }
11410  return promiseGetter();
11411}
11412
11413;// CONCATENATED MODULE: ./node_modules/ol/obj.js
11414/**
11415 * @module ol/obj
11416 */
11417
11418/**
11419 * Removes all properties from an object.
11420 * @param {Object} object The object to clear.
11421 */
11422function clear(object) {
11423  for (const property in object) {
11424    delete object[property];
11425  }
11426}
11427
11428/**
11429 * Determine if an object has any properties.
11430 * @param {Object} object The object to check.
11431 * @return {boolean} The object is empty.
11432 */
11433function obj_isEmpty(object) {
11434  let property;
11435  for (property in object) {
11436    return false;
11437  }
11438  return !property;
11439}
11440
11441;// CONCATENATED MODULE: ./node_modules/ol/events/Target.js
11442/**
11443 * @module ol/events/Target
11444 */
11445
11446
11447
11448
11449
11450/**
11451 * @typedef {EventTarget|Target} EventTargetLike
11452 */
11453
11454/**
11455 * @classdesc
11456 * A simplified implementation of the W3C DOM Level 2 EventTarget interface.
11457 * See https://www.w3.org/TR/2000/REC-DOM-Level-2-Events-20001113/events.html#Events-EventTarget.
11458 *
11459 * There are two important simplifications compared to the specification:
11460 *
11461 * 1. The handling of `useCapture` in `addEventListener` and
11462 *    `removeEventListener`. There is no real capture model.
11463 * 2. The handling of `stopPropagation` and `preventDefault` on `dispatchEvent`.
11464 *    There is no event target hierarchy. When a listener calls
11465 *    `stopPropagation` or `preventDefault` on an event object, it means that no
11466 *    more listeners after this one will be called. Same as when the listener
11467 *    returns false.
11468 */
11469class Target extends ol_Disposable {
11470  /**
11471   * @param {*} [target] Default event target for dispatched events.
11472   */
11473  constructor(target) {
11474    super();
11475
11476    /**
11477     * @private
11478     * @type {*}
11479     */
11480    this.eventTarget_ = target;
11481
11482    /**
11483     * @private
11484     * @type {Object<string, number>}
11485     */
11486    this.pendingRemovals_ = null;
11487
11488    /**
11489     * @private
11490     * @type {Object<string, number>}
11491     */
11492    this.dispatching_ = null;
11493
11494    /**
11495     * @private
11496     * @type {Object<string, Array<import("../events.js").Listener>>}
11497     */
11498    this.listeners_ = null;
11499  }
11500
11501  /**
11502   * @param {string} type Type.
11503   * @param {import("../events.js").Listener} listener Listener.
11504   */
11505  addEventListener(type, listener) {
11506    if (!type || !listener) {
11507      return;
11508    }
11509    const listeners = this.listeners_ || (this.listeners_ = {});
11510    const listenersForType = listeners[type] || (listeners[type] = []);
11511    if (!listenersForType.includes(listener)) {
11512      listenersForType.push(listener);
11513    }
11514  }
11515
11516  /**
11517   * Dispatches an event and calls all listeners listening for events
11518   * of this type. The event parameter can either be a string or an
11519   * Object with a `type` property.
11520   *
11521   * @param {import("./Event.js").default|string} event Event object.
11522   * @return {boolean|undefined} `false` if anyone called preventDefault on the
11523   *     event object or if any of the listeners returned false.
11524   * @api
11525   */
11526  dispatchEvent(event) {
11527    const isString = typeof event === 'string';
11528    const type = isString ? event : event.type;
11529    const listeners = this.listeners_ && this.listeners_[type];
11530    if (!listeners) {
11531      return;
11532    }
11533
11534    const evt = isString ? new Event(event) : /** @type {Event} */ (event);
11535    if (!evt.target) {
11536      evt.target = this.eventTarget_ || this;
11537    }
11538    const dispatching = this.dispatching_ || (this.dispatching_ = {});
11539    const pendingRemovals =
11540      this.pendingRemovals_ || (this.pendingRemovals_ = {});
11541    if (!(type in dispatching)) {
11542      dispatching[type] = 0;
11543      pendingRemovals[type] = 0;
11544    }
11545    ++dispatching[type];
11546    let propagate;
11547    for (let i = 0, ii = listeners.length; i < ii; ++i) {
11548      if ('handleEvent' in listeners[i]) {
11549        propagate = /** @type {import("../events.js").ListenerObject} */ (
11550          listeners[i]
11551        ).handleEvent(evt);
11552      } else {
11553        propagate = /** @type {import("../events.js").ListenerFunction} */ (
11554          listeners[i]
11555        ).call(this, evt);
11556      }
11557      if (propagate === false || evt.propagationStopped) {
11558        propagate = false;
11559        break;
11560      }
11561    }
11562    if (--dispatching[type] === 0) {
11563      let pr = pendingRemovals[type];
11564      delete pendingRemovals[type];
11565      while (pr--) {
11566        this.removeEventListener(type, VOID);
11567      }
11568      delete dispatching[type];
11569    }
11570    return propagate;
11571  }
11572
11573  /**
11574   * Clean up.
11575   */
11576  disposeInternal() {
11577    this.listeners_ && clear(this.listeners_);
11578  }
11579
11580  /**
11581   * Get the listeners for a specified event type. Listeners are returned in the
11582   * order that they will be called in.
11583   *
11584   * @param {string} type Type.
11585   * @return {Array<import("../events.js").Listener>|undefined} Listeners.
11586   */
11587  getListeners(type) {
11588    return (this.listeners_ && this.listeners_[type]) || undefined;
11589  }
11590
11591  /**
11592   * @param {string} [type] Type. If not provided,
11593   *     `true` will be returned if this event target has any listeners.
11594   * @return {boolean} Has listeners.
11595   */
11596  hasListener(type) {
11597    if (!this.listeners_) {
11598      return false;
11599    }
11600    return type
11601      ? type in this.listeners_
11602      : Object.keys(this.listeners_).length > 0;
11603  }
11604
11605  /**
11606   * @param {string} type Type.
11607   * @param {import("../events.js").Listener} listener Listener.
11608   */
11609  removeEventListener(type, listener) {
11610    const listeners = this.listeners_ && this.listeners_[type];
11611    if (listeners) {
11612      const index = listeners.indexOf(listener);
11613      if (index !== -1) {
11614        if (this.pendingRemovals_ && type in this.pendingRemovals_) {
11615          // make listener a no-op, and remove later in #dispatchEvent()
11616          listeners[index] = VOID;
11617          ++this.pendingRemovals_[type];
11618        } else {
11619          listeners.splice(index, 1);
11620          if (listeners.length === 0) {
11621            delete this.listeners_[type];
11622          }
11623        }
11624      }
11625    }
11626  }
11627}
11628
11629/* harmony default export */ const events_Target = (Target);
11630
11631;// CONCATENATED MODULE: ./node_modules/ol/events/EventType.js
11632/**
11633 * @module ol/events/EventType
11634 */
11635
11636/**
11637 * @enum {string}
11638 * @const
11639 */
11640/* harmony default export */ const EventType = ({
11641  /**
11642   * Generic change event. Triggered when the revision counter is increased.
11643   * @event module:ol/events/Event~BaseEvent#change
11644   * @api
11645   */
11646  CHANGE: 'change',
11647
11648  /**
11649   * Generic error event. Triggered when an error occurs.
11650   * @event module:ol/events/Event~BaseEvent#error
11651   * @api
11652   */
11653  ERROR: 'error',
11654
11655  BLUR: 'blur',
11656  CLEAR: 'clear',
11657  CONTEXTMENU: 'contextmenu',
11658  CLICK: 'click',
11659  DBLCLICK: 'dblclick',
11660  DRAGENTER: 'dragenter',
11661  DRAGOVER: 'dragover',
11662  DROP: 'drop',
11663  FOCUS: 'focus',
11664  KEYDOWN: 'keydown',
11665  KEYPRESS: 'keypress',
11666  LOAD: 'load',
11667  RESIZE: 'resize',
11668  TOUCHMOVE: 'touchmove',
11669  WHEEL: 'wheel',
11670});
11671
11672;// CONCATENATED MODULE: ./node_modules/ol/events.js
11673/**
11674 * @module ol/events
11675 */
11676
11677
11678/**
11679 * Key to use with {@link module:ol/Observable.unByKey}.
11680 * @typedef {Object} EventsKey
11681 * @property {ListenerFunction} listener Listener.
11682 * @property {import("./events/Target.js").EventTargetLike} target Target.
11683 * @property {string} type Type.
11684 * @api
11685 */
11686
11687/**
11688 * Listener function. This function is called with an event object as argument.
11689 * When the function returns `false`, event propagation will stop.
11690 *
11691 * @typedef {function((Event|import("./events/Event.js").default)): (void|boolean)} ListenerFunction
11692 * @api
11693 */
11694
11695/**
11696 * @typedef {Object} ListenerObject
11697 * @property {ListenerFunction} handleEvent HandleEvent listener function.
11698 */
11699
11700/**
11701 * @typedef {ListenerFunction|ListenerObject} Listener
11702 */
11703
11704/**
11705 * Registers an event listener on an event target. Inspired by
11706 * https://google.github.io/closure-library/api/source/closure/goog/events/events.js.src.html
11707 *
11708 * This function efficiently binds a `listener` to a `this` object, and returns
11709 * a key for use with {@link module:ol/events.unlistenByKey}.
11710 *
11711 * @param {import("./events/Target.js").EventTargetLike} target Event target.
11712 * @param {string} type Event type.
11713 * @param {ListenerFunction} listener Listener.
11714 * @param {Object} [thisArg] Object referenced by the `this` keyword in the
11715 *     listener. Default is the `target`.
11716 * @param {boolean} [once] If true, add the listener as one-off listener.
11717 * @return {EventsKey} Unique key for the listener.
11718 */
11719function listen(target, type, listener, thisArg, once) {
11720  if (thisArg && thisArg !== target) {
11721    listener = listener.bind(thisArg);
11722  }
11723  if (once) {
11724    const originalListener = listener;
11725    listener = function () {
11726      target.removeEventListener(type, listener);
11727      originalListener.apply(this, arguments);
11728    };
11729  }
11730  const eventsKey = {
11731    target: target,
11732    type: type,
11733    listener: listener,
11734  };
11735  target.addEventListener(type, listener);
11736  return eventsKey;
11737}
11738
11739/**
11740 * Registers a one-off event listener on an event target. Inspired by
11741 * https://google.github.io/closure-library/api/source/closure/goog/events/events.js.src.html
11742 *
11743 * This function efficiently binds a `listener` as self-unregistering listener
11744 * to a `this` object, and returns a key for use with
11745 * {@link module:ol/events.unlistenByKey} in case the listener needs to be
11746 * unregistered before it is called.
11747 *
11748 * When {@link module:ol/events.listen} is called with the same arguments after this
11749 * function, the self-unregistering listener will be turned into a permanent
11750 * listener.
11751 *
11752 * @param {import("./events/Target.js").EventTargetLike} target Event target.
11753 * @param {string} type Event type.
11754 * @param {ListenerFunction} listener Listener.
11755 * @param {Object} [thisArg] Object referenced by the `this` keyword in the
11756 *     listener. Default is the `target`.
11757 * @return {EventsKey} Key for unlistenByKey.
11758 */
11759function listenOnce(target, type, listener, thisArg) {
11760  return listen(target, type, listener, thisArg, true);
11761}
11762
11763/**
11764 * Unregisters event listeners on an event target. Inspired by
11765 * https://google.github.io/closure-library/api/source/closure/goog/events/events.js.src.html
11766 *
11767 * The argument passed to this function is the key returned from
11768 * {@link module:ol/events.listen} or {@link module:ol/events.listenOnce}.
11769 *
11770 * @param {EventsKey} key The key.
11771 */
11772function unlistenByKey(key) {
11773  if (key && key.target) {
11774    key.target.removeEventListener(key.type, key.listener);
11775    clear(key);
11776  }
11777}
11778
11779;// CONCATENATED MODULE: ./node_modules/ol/Observable.js
11780/**
11781 * @module ol/Observable
11782 */
11783
11784
11785
11786
11787/***
11788 * @template {string} Type
11789 * @template {Event|import("./events/Event.js").default} EventClass
11790 * @template Return
11791 * @typedef {(type: Type, listener: (event: EventClass) => ?) => Return} OnSignature
11792 */
11793
11794/***
11795 * @template {string} Type
11796 * @template Return
11797 * @typedef {(type: Type[], listener: (event: Event|import("./events/Event").default) => ?) => Return extends void ? void : Return[]} CombinedOnSignature
11798 */
11799
11800/**
11801 * @typedef {'change'|'error'} EventTypes
11802 */
11803
11804/***
11805 * @template Return
11806 * @typedef {OnSignature<EventTypes, import("./events/Event.js").default, Return> & CombinedOnSignature<EventTypes, Return>} ObservableOnSignature
11807 */
11808
11809/**
11810 * @classdesc
11811 * Abstract base class; normally only used for creating subclasses and not
11812 * instantiated in apps.
11813 * An event target providing convenient methods for listener registration
11814 * and unregistration. A generic `change` event is always available through
11815 * {@link module:ol/Observable~Observable#changed}.
11816 *
11817 * @fires import("./events/Event.js").default
11818 * @api
11819 */
11820class Observable extends events_Target {
11821  constructor() {
11822    super();
11823
11824    this.on =
11825      /** @type {ObservableOnSignature<import("./events").EventsKey>} */ (
11826        this.onInternal
11827      );
11828
11829    this.once =
11830      /** @type {ObservableOnSignature<import("./events").EventsKey>} */ (
11831        this.onceInternal
11832      );
11833
11834    this.un = /** @type {ObservableOnSignature<void>} */ (this.unInternal);
11835
11836    /**
11837     * @private
11838     * @type {number}
11839     */
11840    this.revision_ = 0;
11841  }
11842
11843  /**
11844   * Increases the revision counter and dispatches a 'change' event.
11845   * @api
11846   */
11847  changed() {
11848    ++this.revision_;
11849    this.dispatchEvent(EventType.CHANGE);
11850  }
11851
11852  /**
11853   * Get the version number for this object.  Each time the object is modified,
11854   * its version number will be incremented.
11855   * @return {number} Revision.
11856   * @api
11857   */
11858  getRevision() {
11859    return this.revision_;
11860  }
11861
11862  /**
11863   * @param {string|Array<string>} type Type.
11864   * @param {function((Event|import("./events/Event").default)): ?} listener Listener.
11865   * @return {import("./events.js").EventsKey|Array<import("./events.js").EventsKey>} Event key.
11866   * @protected
11867   */
11868  onInternal(type, listener) {
11869    if (Array.isArray(type)) {
11870      const len = type.length;
11871      const keys = new Array(len);
11872      for (let i = 0; i < len; ++i) {
11873        keys[i] = listen(this, type[i], listener);
11874      }
11875      return keys;
11876    } else {
11877      return listen(this, /** @type {string} */ (type), listener);
11878    }
11879  }
11880
11881  /**
11882   * @param {string|Array<string>} type Type.
11883   * @param {function((Event|import("./events/Event").default)): ?} listener Listener.
11884   * @return {import("./events.js").EventsKey|Array<import("./events.js").EventsKey>} Event key.
11885   * @protected
11886   */
11887  onceInternal(type, listener) {
11888    let key;
11889    if (Array.isArray(type)) {
11890      const len = type.length;
11891      key = new Array(len);
11892      for (let i = 0; i < len; ++i) {
11893        key[i] = listenOnce(this, type[i], listener);
11894      }
11895    } else {
11896      key = listenOnce(this, /** @type {string} */ (type), listener);
11897    }
11898    /** @type {Object} */ (listener).ol_key = key;
11899    return key;
11900  }
11901
11902  /**
11903   * Unlisten for a certain type of event.
11904   * @param {string|Array<string>} type Type.
11905   * @param {function((Event|import("./events/Event").default)): ?} listener Listener.
11906   * @protected
11907   */
11908  unInternal(type, listener) {
11909    const key = /** @type {Object} */ (listener).ol_key;
11910    if (key) {
11911      unByKey(key);
11912    } else if (Array.isArray(type)) {
11913      for (let i = 0, ii = type.length; i < ii; ++i) {
11914        this.removeEventListener(type[i], listener);
11915      }
11916    } else {
11917      this.removeEventListener(type, listener);
11918    }
11919  }
11920}
11921
11922/**
11923 * Listen for a certain type of event.
11924 * @function
11925 * @param {string|Array<string>} type The event type or array of event types.
11926 * @param {function((Event|import("./events/Event").default)): ?} listener The listener function.
11927 * @return {import("./events.js").EventsKey|Array<import("./events.js").EventsKey>} Unique key for the listener. If
11928 *     called with an array of event types as the first argument, the return
11929 *     will be an array of keys.
11930 * @api
11931 */
11932Observable.prototype.on;
11933
11934/**
11935 * Listen once for a certain type of event.
11936 * @function
11937 * @param {string|Array<string>} type The event type or array of event types.
11938 * @param {function((Event|import("./events/Event").default)): ?} listener The listener function.
11939 * @return {import("./events.js").EventsKey|Array<import("./events.js").EventsKey>} Unique key for the listener. If
11940 *     called with an array of event types as the first argument, the return
11941 *     will be an array of keys.
11942 * @api
11943 */
11944Observable.prototype.once;
11945
11946/**
11947 * Unlisten for a certain type of event.
11948 * @function
11949 * @param {string|Array<string>} type The event type or array of event types.
11950 * @param {function((Event|import("./events/Event").default)): ?} listener The listener function.
11951 * @api
11952 */
11953Observable.prototype.un;
11954
11955/**
11956 * Removes an event listener using the key returned by `on()` or `once()`.
11957 * @param {import("./events.js").EventsKey|Array<import("./events.js").EventsKey>} key The key returned by `on()`
11958 *     or `once()` (or an array of keys).
11959 * @api
11960 */
11961function unByKey(key) {
11962  if (Array.isArray(key)) {
11963    for (let i = 0, ii = key.length; i < ii; ++i) {
11964      unlistenByKey(key[i]);
11965    }
11966  } else {
11967    unlistenByKey(/** @type {import("./events.js").EventsKey} */ (key));
11968  }
11969}
11970
11971/* harmony default export */ const ol_Observable = (Observable);
11972
11973;// CONCATENATED MODULE: ./node_modules/ol/util.js
11974/**
11975 * @module ol/util
11976 */
11977
11978/**
11979 * @return {never} Any return.
11980 */
11981function util_abstract() {
11982  throw new Error('Unimplemented abstract method.');
11983}
11984
11985/**
11986 * Counter for getUid.
11987 * @type {number}
11988 * @private
11989 */
11990let uidCounter_ = 0;
11991
11992/**
11993 * Gets a unique ID for an object. This mutates the object so that further calls
11994 * with the same object as a parameter returns the same value. Unique IDs are generated
11995 * as a strictly increasing sequence. Adapted from goog.getUid.
11996 *
11997 * @param {Object} obj The object to get the unique ID for.
11998 * @return {string} The unique ID for the object.
11999 * @api
12000 */
12001function getUid(obj) {
12002  return obj.ol_uid || (obj.ol_uid = String(++uidCounter_));
12003}
12004
12005/**
12006 * OpenLayers version.
12007 * @type {string}
12008 */
12009const VERSION = '7.0.0';
12010
12011;// CONCATENATED MODULE: ./node_modules/ol/Object.js
12012/**
12013 * @module ol/Object
12014 */
12015
12016
12017
12018
12019
12020
12021/**
12022 * @classdesc
12023 * Events emitted by {@link module:ol/Object~BaseObject} instances are instances of this type.
12024 */
12025class ObjectEvent extends Event {
12026  /**
12027   * @param {string} type The event type.
12028   * @param {string} key The property name.
12029   * @param {*} oldValue The old value for `key`.
12030   */
12031  constructor(type, key, oldValue) {
12032    super(type);
12033
12034    /**
12035     * The name of the property whose value is changing.
12036     * @type {string}
12037     * @api
12038     */
12039    this.key = key;
12040
12041    /**
12042     * The old value. To get the new value use `e.target.get(e.key)` where
12043     * `e` is the event object.
12044     * @type {*}
12045     * @api
12046     */
12047    this.oldValue = oldValue;
12048  }
12049}
12050
12051/***
12052 * @template Return
12053 * @typedef {import("./Observable").OnSignature<import("./Observable").EventTypes, import("./events/Event.js").default, Return> &
12054 *    import("./Observable").OnSignature<import("./ObjectEventType").Types, ObjectEvent, Return> &
12055 *    import("./Observable").CombinedOnSignature<import("./Observable").EventTypes|import("./ObjectEventType").Types, Return>} ObjectOnSignature
12056 */
12057
12058/**
12059 * @classdesc
12060 * Abstract base class; normally only used for creating subclasses and not
12061 * instantiated in apps.
12062 * Most non-trivial classes inherit from this.
12063 *
12064 * This extends {@link module:ol/Observable~Observable} with observable
12065 * properties, where each property is observable as well as the object as a
12066 * whole.
12067 *
12068 * Classes that inherit from this have pre-defined properties, to which you can
12069 * add your owns. The pre-defined properties are listed in this documentation as
12070 * 'Observable Properties', and have their own accessors; for example,
12071 * {@link module:ol/Map~Map} has a `target` property, accessed with
12072 * `getTarget()` and changed with `setTarget()`. Not all properties are however
12073 * settable. There are also general-purpose accessors `get()` and `set()`. For
12074 * example, `get('target')` is equivalent to `getTarget()`.
12075 *
12076 * The `set` accessors trigger a change event, and you can monitor this by
12077 * registering a listener. For example, {@link module:ol/View~View} has a
12078 * `center` property, so `view.on('change:center', function(evt) {...});` would
12079 * call the function whenever the value of the center property changes. Within
12080 * the function, `evt.target` would be the view, so `evt.target.getCenter()`
12081 * would return the new center.
12082 *
12083 * You can add your own observable properties with
12084 * `object.set('prop', 'value')`, and retrieve that with `object.get('prop')`.
12085 * You can listen for changes on that property value with
12086 * `object.on('change:prop', listener)`. You can get a list of all
12087 * properties with {@link module:ol/Object~BaseObject#getProperties}.
12088 *
12089 * Note that the observable properties are separate from standard JS properties.
12090 * You can, for example, give your map object a title with
12091 * `map.title='New title'` and with `map.set('title', 'Another title')`. The
12092 * first will be a `hasOwnProperty`; the second will appear in
12093 * `getProperties()`. Only the second is observable.
12094 *
12095 * Properties can be deleted by using the unset method. E.g.
12096 * object.unset('foo').
12097 *
12098 * @fires ObjectEvent
12099 * @api
12100 */
12101class BaseObject extends ol_Observable {
12102  /**
12103   * @param {Object<string, *>} [values] An object with key-value pairs.
12104   */
12105  constructor(values) {
12106    super();
12107
12108    /***
12109     * @type {ObjectOnSignature<import("./events").EventsKey>}
12110     */
12111    this.on;
12112
12113    /***
12114     * @type {ObjectOnSignature<import("./events").EventsKey>}
12115     */
12116    this.once;
12117
12118    /***
12119     * @type {ObjectOnSignature<void>}
12120     */
12121    this.un;
12122
12123    // Call {@link module:ol/util.getUid} to ensure that the order of objects' ids is
12124    // the same as the order in which they were created.  This also helps to
12125    // ensure that object properties are always added in the same order, which
12126    // helps many JavaScript engines generate faster code.
12127    getUid(this);
12128
12129    /**
12130     * @private
12131     * @type {Object<string, *>}
12132     */
12133    this.values_ = null;
12134
12135    if (values !== undefined) {
12136      this.setProperties(values);
12137    }
12138  }
12139
12140  /**
12141   * Gets a value.
12142   * @param {string} key Key name.
12143   * @return {*} Value.
12144   * @api
12145   */
12146  get(key) {
12147    let value;
12148    if (this.values_ && this.values_.hasOwnProperty(key)) {
12149      value = this.values_[key];
12150    }
12151    return value;
12152  }
12153
12154  /**
12155   * Get a list of object property names.
12156   * @return {Array<string>} List of property names.
12157   * @api
12158   */
12159  getKeys() {
12160    return (this.values_ && Object.keys(this.values_)) || [];
12161  }
12162
12163  /**
12164   * Get an object of all property names and values.
12165   * @return {Object<string, *>} Object.
12166   * @api
12167   */
12168  getProperties() {
12169    return (this.values_ && Object.assign({}, this.values_)) || {};
12170  }
12171
12172  /**
12173   * @return {boolean} The object has properties.
12174   */
12175  hasProperties() {
12176    return !!this.values_;
12177  }
12178
12179  /**
12180   * @param {string} key Key name.
12181   * @param {*} oldValue Old value.
12182   */
12183  notify(key, oldValue) {
12184    let eventType;
12185    eventType = `change:${key}`;
12186    if (this.hasListener(eventType)) {
12187      this.dispatchEvent(new ObjectEvent(eventType, key, oldValue));
12188    }
12189    eventType = ObjectEventType.PROPERTYCHANGE;
12190    if (this.hasListener(eventType)) {
12191      this.dispatchEvent(new ObjectEvent(eventType, key, oldValue));
12192    }
12193  }
12194
12195  /**
12196   * @param {string} key Key name.
12197   * @param {import("./events.js").Listener} listener Listener.
12198   */
12199  addChangeListener(key, listener) {
12200    this.addEventListener(`change:${key}`, listener);
12201  }
12202
12203  /**
12204   * @param {string} key Key name.
12205   * @param {import("./events.js").Listener} listener Listener.
12206   */
12207  removeChangeListener(key, listener) {
12208    this.removeEventListener(`change:${key}`, listener);
12209  }
12210
12211  /**
12212   * Sets a value.
12213   * @param {string} key Key name.
12214   * @param {*} value Value.
12215   * @param {boolean} [silent] Update without triggering an event.
12216   * @api
12217   */
12218  set(key, value, silent) {
12219    const values = this.values_ || (this.values_ = {});
12220    if (silent) {
12221      values[key] = value;
12222    } else {
12223      const oldValue = values[key];
12224      values[key] = value;
12225      if (oldValue !== value) {
12226        this.notify(key, oldValue);
12227      }
12228    }
12229  }
12230
12231  /**
12232   * Sets a collection of key-value pairs.  Note that this changes any existing
12233   * properties and adds new ones (it does not remove any existing properties).
12234   * @param {Object<string, *>} values Values.
12235   * @param {boolean} [silent] Update without triggering an event.
12236   * @api
12237   */
12238  setProperties(values, silent) {
12239    for (const key in values) {
12240      this.set(key, values[key], silent);
12241    }
12242  }
12243
12244  /**
12245   * Apply any properties from another object without triggering events.
12246   * @param {BaseObject} source The source object.
12247   * @protected
12248   */
12249  applyProperties(source) {
12250    if (!source.values_) {
12251      return;
12252    }
12253    Object.assign(this.values_ || (this.values_ = {}), source.values_);
12254  }
12255
12256  /**
12257   * Unsets a property.
12258   * @param {string} key Key name.
12259   * @param {boolean} [silent] Unset without triggering an event.
12260   * @api
12261   */
12262  unset(key, silent) {
12263    if (this.values_ && key in this.values_) {
12264      const oldValue = this.values_[key];
12265      delete this.values_[key];
12266      if (obj_isEmpty(this.values_)) {
12267        this.values_ = null;
12268      }
12269      if (!silent) {
12270        this.notify(key, oldValue);
12271      }
12272    }
12273  }
12274}
12275
12276/* harmony default export */ const ol_Object = (BaseObject);
12277
12278;// CONCATENATED MODULE: ./node_modules/ol/AssertionError.js
12279/**
12280 * @module ol/AssertionError
12281 */
12282
12283
12284/**
12285 * Error object thrown when an assertion failed. This is an ECMA-262 Error,
12286 * extended with a `code` property.
12287 * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error.
12288 */
12289class AssertionError extends Error {
12290  /**
12291   * @param {number} code Error code.
12292   */
12293  constructor(code) {
12294    const path = VERSION === 'latest' ? VERSION : 'v' + VERSION.split('-')[0];
12295    const message =
12296      'Assertion failed. See https://openlayers.org/en/' +
12297      path +
12298      '/doc/errors/#' +
12299      code +
12300      ' for details.';
12301
12302    super(message);
12303
12304    /**
12305     * Error code. The meaning of the code can be found on
12306     * https://openlayers.org/en/latest/doc/errors/ (replace `latest` with
12307     * the version found in the OpenLayers script's header comment if a version
12308     * other than the latest is used).
12309     * @type {number}
12310     * @api
12311     */
12312    this.code = code;
12313
12314    /**
12315     * @type {string}
12316     */
12317    this.name = 'AssertionError';
12318
12319    // Re-assign message, see https://github.com/Rich-Harris/buble/issues/40
12320    this.message = message;
12321  }
12322}
12323
12324/* harmony default export */ const ol_AssertionError = (AssertionError);
12325
12326;// CONCATENATED MODULE: ./node_modules/ol/asserts.js
12327/**
12328 * @module ol/asserts
12329 */
12330
12331
12332/**
12333 * @param {*} assertion Assertion we expected to be truthy.
12334 * @param {number} errorCode Error code.
12335 */
12336function asserts_assert(assertion, errorCode) {
12337  if (!assertion) {
12338    throw new ol_AssertionError(errorCode);
12339  }
12340}
12341
12342;// CONCATENATED MODULE: ./node_modules/ol/Feature.js
12343/**
12344 * @module ol/Feature
12345 */
12346
12347
12348
12349
12350
12351/**
12352 * @typedef {typeof Feature|typeof import("./render/Feature.js").default} FeatureClass
12353 */
12354
12355/**
12356 * @typedef {Feature|import("./render/Feature.js").default} FeatureLike
12357 */
12358
12359/***
12360 * @template Return
12361 * @typedef {import("./Observable").OnSignature<import("./Observable").EventTypes, import("./events/Event.js").default, Return> &
12362 *   import("./Observable").OnSignature<import("./ObjectEventType").Types|'change:geometry', import("./Object").ObjectEvent, Return> &
12363 *   import("./Observable").CombinedOnSignature<import("./Observable").EventTypes|import("./ObjectEventType").Types
12364 *     |'change:geometry', Return>} FeatureOnSignature
12365 */
12366
12367/***
12368 * @template Geometry
12369 * @typedef {Object<string, *> & { geometry?: Geometry }} ObjectWithGeometry
12370 */
12371
12372/**
12373 * @classdesc
12374 * A vector object for geographic features with a geometry and other
12375 * attribute properties, similar to the features in vector file formats like
12376 * GeoJSON.
12377 *
12378 * Features can be styled individually with `setStyle`; otherwise they use the
12379 * style of their vector layer.
12380 *
12381 * Note that attribute properties are set as {@link module:ol/Object~BaseObject} properties on
12382 * the feature object, so they are observable, and have get/set accessors.
12383 *
12384 * Typically, a feature has a single geometry property. You can set the
12385 * geometry using the `setGeometry` method and get it with `getGeometry`.
12386 * It is possible to store more than one geometry on a feature using attribute
12387 * properties. By default, the geometry used for rendering is identified by
12388 * the property name `geometry`. If you want to use another geometry property
12389 * for rendering, use the `setGeometryName` method to change the attribute
12390 * property associated with the geometry for the feature.  For example:
12391 *
12392 * ```js
12393 *
12394 * import Feature from 'ol/Feature';
12395 * import Polygon from 'ol/geom/Polygon';
12396 * import Point from 'ol/geom/Point';
12397 *
12398 * const feature = new Feature({
12399 *   geometry: new Polygon(polyCoords),
12400 *   labelPoint: new Point(labelCoords),
12401 *   name: 'My Polygon',
12402 * });
12403 *
12404 * // get the polygon geometry
12405 * const poly = feature.getGeometry();
12406 *
12407 * // Render the feature as a point using the coordinates from labelPoint
12408 * feature.setGeometryName('labelPoint');
12409 *
12410 * // get the point geometry
12411 * const point = feature.getGeometry();
12412 * ```
12413 *
12414 * @api
12415 * @template {import("./geom/Geometry.js").default} [Geometry=import("./geom/Geometry.js").default]
12416 */
12417class Feature extends ol_Object {
12418  /**
12419   * @param {Geometry|ObjectWithGeometry<Geometry>} [geometryOrProperties]
12420   *     You may pass a Geometry object directly, or an object literal containing
12421   *     properties. If you pass an object literal, you may include a Geometry
12422   *     associated with a `geometry` key.
12423   */
12424  constructor(geometryOrProperties) {
12425    super();
12426
12427    /***
12428     * @type {FeatureOnSignature<import("./events").EventsKey>}
12429     */
12430    this.on;
12431
12432    /***
12433     * @type {FeatureOnSignature<import("./events").EventsKey>}
12434     */
12435    this.once;
12436
12437    /***
12438     * @type {FeatureOnSignature<void>}
12439     */
12440    this.un;
12441
12442    /**
12443     * @private
12444     * @type {number|string|undefined}
12445     */
12446    this.id_ = undefined;
12447
12448    /**
12449     * @type {string}
12450     * @private
12451     */
12452    this.geometryName_ = 'geometry';
12453
12454    /**
12455     * User provided style.
12456     * @private
12457     * @type {import("./style/Style.js").StyleLike}
12458     */
12459    this.style_ = null;
12460
12461    /**
12462     * @private
12463     * @type {import("./style/Style.js").StyleFunction|undefined}
12464     */
12465    this.styleFunction_ = undefined;
12466
12467    /**
12468     * @private
12469     * @type {?import("./events.js").EventsKey}
12470     */
12471    this.geometryChangeKey_ = null;
12472
12473    this.addChangeListener(this.geometryName_, this.handleGeometryChanged_);
12474
12475    if (geometryOrProperties) {
12476      if (
12477        typeof (
12478          /** @type {?} */ (geometryOrProperties).getSimplifiedGeometry
12479        ) === 'function'
12480      ) {
12481        const geometry = /** @type {Geometry} */ (geometryOrProperties);
12482        this.setGeometry(geometry);
12483      } else {
12484        /** @type {Object<string, *>} */
12485        const properties = geometryOrProperties;
12486        this.setProperties(properties);
12487      }
12488    }
12489  }
12490
12491  /**
12492   * Clone this feature. If the original feature has a geometry it
12493   * is also cloned. The feature id is not set in the clone.
12494   * @return {Feature<Geometry>} The clone.
12495   * @api
12496   */
12497  clone() {
12498    const clone = /** @type {Feature<Geometry>} */ (
12499      new Feature(this.hasProperties() ? this.getProperties() : null)
12500    );
12501    clone.setGeometryName(this.getGeometryName());
12502    const geometry = this.getGeometry();
12503    if (geometry) {
12504      clone.setGeometry(/** @type {Geometry} */ (geometry.clone()));
12505    }
12506    const style = this.getStyle();
12507    if (style) {
12508      clone.setStyle(style);
12509    }
12510    return clone;
12511  }
12512
12513  /**
12514   * Get the feature's default geometry.  A feature may have any number of named
12515   * geometries.  The "default" geometry (the one that is rendered by default) is
12516   * set when calling {@link module:ol/Feature~Feature#setGeometry}.
12517   * @return {Geometry|undefined} The default geometry for the feature.
12518   * @api
12519   * @observable
12520   */
12521  getGeometry() {
12522    return /** @type {Geometry|undefined} */ (this.get(this.geometryName_));
12523  }
12524
12525  /**
12526   * Get the feature identifier.  This is a stable identifier for the feature and
12527   * is either set when reading data from a remote source or set explicitly by
12528   * calling {@link module:ol/Feature~Feature#setId}.
12529   * @return {number|string|undefined} Id.
12530   * @api
12531   */
12532  getId() {
12533    return this.id_;
12534  }
12535
12536  /**
12537   * Get the name of the feature's default geometry.  By default, the default
12538   * geometry is named `geometry`.
12539   * @return {string} Get the property name associated with the default geometry
12540   *     for this feature.
12541   * @api
12542   */
12543  getGeometryName() {
12544    return this.geometryName_;
12545  }
12546
12547  /**
12548   * Get the feature's style. Will return what was provided to the
12549   * {@link module:ol/Feature~Feature#setStyle} method.
12550   * @return {import("./style/Style.js").StyleLike|undefined} The feature style.
12551   * @api
12552   */
12553  getStyle() {
12554    return this.style_;
12555  }
12556
12557  /**
12558   * Get the feature's style function.
12559   * @return {import("./style/Style.js").StyleFunction|undefined} Return a function
12560   * representing the current style of this feature.
12561   * @api
12562   */
12563  getStyleFunction() {
12564    return this.styleFunction_;
12565  }
12566
12567  /**
12568   * @private
12569   */
12570  handleGeometryChange_() {
12571    this.changed();
12572  }
12573
12574  /**
12575   * @private
12576   */
12577  handleGeometryChanged_() {
12578    if (this.geometryChangeKey_) {
12579      unlistenByKey(this.geometryChangeKey_);
12580      this.geometryChangeKey_ = null;
12581    }
12582    const geometry = this.getGeometry();
12583    if (geometry) {
12584      this.geometryChangeKey_ = listen(
12585        geometry,
12586        EventType.CHANGE,
12587        this.handleGeometryChange_,
12588        this
12589      );
12590    }
12591    this.changed();
12592  }
12593
12594  /**
12595   * Set the default geometry for the feature.  This will update the property
12596   * with the name returned by {@link module:ol/Feature~Feature#getGeometryName}.
12597   * @param {Geometry|undefined} geometry The new geometry.
12598   * @api
12599   * @observable
12600   */
12601  setGeometry(geometry) {
12602    this.set(this.geometryName_, geometry);
12603  }
12604
12605  /**
12606   * Set the style for the feature to override the layer style.  This can be a
12607   * single style object, an array of styles, or a function that takes a
12608   * resolution and returns an array of styles. To unset the feature style, call
12609   * `setStyle()` without arguments or a falsey value.
12610   * @param {import("./style/Style.js").StyleLike} [style] Style for this feature.
12611   * @api
12612   * @fires module:ol/events/Event~BaseEvent#event:change
12613   */
12614  setStyle(style) {
12615    this.style_ = style;
12616    this.styleFunction_ = !style ? undefined : createStyleFunction(style);
12617    this.changed();
12618  }
12619
12620  /**
12621   * Set the feature id.  The feature id is considered stable and may be used when
12622   * requesting features or comparing identifiers returned from a remote source.
12623   * The feature id can be used with the
12624   * {@link module:ol/source/Vector~VectorSource#getFeatureById} method.
12625   * @param {number|string|undefined} id The feature id.
12626   * @api
12627   * @fires module:ol/events/Event~BaseEvent#event:change
12628   */
12629  setId(id) {
12630    this.id_ = id;
12631    this.changed();
12632  }
12633
12634  /**
12635   * Set the property name to be used when getting the feature's default geometry.
12636   * When calling {@link module:ol/Feature~Feature#getGeometry}, the value of the property with
12637   * this name will be returned.
12638   * @param {string} name The property name of the default geometry.
12639   * @api
12640   */
12641  setGeometryName(name) {
12642    this.removeChangeListener(this.geometryName_, this.handleGeometryChanged_);
12643    this.geometryName_ = name;
12644    this.addChangeListener(this.geometryName_, this.handleGeometryChanged_);
12645    this.handleGeometryChanged_();
12646  }
12647}
12648
12649/**
12650 * Convert the provided object into a feature style function.  Functions passed
12651 * through unchanged.  Arrays of Style or single style objects wrapped
12652 * in a new feature style function.
12653 * @param {!import("./style/Style.js").StyleFunction|!Array<import("./style/Style.js").default>|!import("./style/Style.js").default} obj
12654 *     A feature style function, a single style, or an array of styles.
12655 * @return {import("./style/Style.js").StyleFunction} A style function.
12656 */
12657function createStyleFunction(obj) {
12658  if (typeof obj === 'function') {
12659    return obj;
12660  } else {
12661    /**
12662     * @type {Array<import("./style/Style.js").default>}
12663     */
12664    let styles;
12665    if (Array.isArray(obj)) {
12666      styles = obj;
12667    } else {
12668      asserts_assert(typeof (/** @type {?} */ (obj).getZIndex) === 'function', 41); // Expected an `import("./style/Style.js").Style` or an array of `import("./style/Style.js").Style`
12669      const style = /** @type {import("./style/Style.js").default} */ (obj);
12670      styles = [style];
12671    }
12672    return function () {
12673      return styles;
12674    };
12675  }
12676}
12677/* harmony default export */ const ol_Feature = (Feature);
12678
12679;// CONCATENATED MODULE: ./node_modules/ol/ViewHint.js
12680/**
12681 * @module ol/ViewHint
12682 */
12683
12684/**
12685 * @enum {number}
12686 */
12687/* harmony default export */ const ViewHint = ({
12688  ANIMATING: 0,
12689  INTERACTING: 1,
12690});
12691
12692;// CONCATENATED MODULE: ./node_modules/ol/ViewProperty.js
12693/**
12694 * @module ol/ViewProperty
12695 */
12696
12697/**
12698 * @enum {string}
12699 */
12700/* harmony default export */ const ViewProperty = ({
12701  CENTER: 'center',
12702  RESOLUTION: 'resolution',
12703  ROTATION: 'rotation',
12704});
12705
12706;// CONCATENATED MODULE: ./node_modules/ol/tilegrid/common.js
12707/**
12708 * @module ol/tilegrid/common
12709 */
12710
12711/**
12712 * Default maximum zoom for default tile grids.
12713 * @type {number}
12714 */
12715const DEFAULT_MAX_ZOOM = 42;
12716
12717/**
12718 * Default tile size.
12719 * @type {number}
12720 */
12721const DEFAULT_TILE_SIZE = 256;
12722
12723;// CONCATENATED MODULE: ./node_modules/ol/proj/Units.js
12724/**
12725 * @module ol/proj/Units
12726 */
12727
12728/**
12729 * @typedef {'radians' | 'degrees' | 'ft' | 'm' | 'pixels' | 'tile-pixels' | 'us-ft'} Units
12730 * Projection units.
12731 */
12732
12733/**
12734 * See http://duff.ess.washington.edu/data/raster/drg/docs/geotiff.txt
12735 * @type {Object<number, Units>}
12736 */
12737const unitByCode = {
12738  '9001': 'm',
12739  '9002': 'ft',
12740  '9003': 'us-ft',
12741  '9101': 'radians',
12742  '9102': 'degrees',
12743};
12744
12745/**
12746 * @param {number} code Unit code.
12747 * @return {Units} Units.
12748 */
12749function fromCode(code) {
12750  return unitByCode[code];
12751}
12752
12753/**
12754 * @typedef {Object} MetersPerUnitLookup
12755 * @property {number} radians Radians
12756 * @property {number} degrees Degrees
12757 * @property {number} ft  Feet
12758 * @property {number} m Meters
12759 * @property {number} us-ft US feet
12760 */
12761
12762/**
12763 * Meters per unit lookup table.
12764 * @const
12765 * @type {MetersPerUnitLookup}
12766 * @api
12767 */
12768const Units_METERS_PER_UNIT = {
12769  // use the radius of the Normal sphere
12770  'radians': 6370997 / (2 * Math.PI),
12771  'degrees': (2 * Math.PI * 6370997) / 360,
12772  'ft': 0.3048,
12773  'm': 1,
12774  'us-ft': 1200 / 3937,
12775};
12776
12777;// CONCATENATED MODULE: ./node_modules/ol/proj/Projection.js
12778/**
12779 * @module ol/proj/Projection
12780 */
12781
12782
12783/**
12784 * @typedef {Object} Options
12785 * @property {string} code The SRS identifier code, e.g. `EPSG:4326`.
12786 * @property {import("./Units.js").Units} [units] Units. Required unless a
12787 * proj4 projection is defined for `code`.
12788 * @property {import("../extent.js").Extent} [extent] The validity extent for the SRS.
12789 * @property {string} [axisOrientation='enu'] The axis orientation as specified in Proj4.
12790 * @property {boolean} [global=false] Whether the projection is valid for the whole globe.
12791 * @property {number} [metersPerUnit] The meters per unit for the SRS.
12792 * If not provided, the `units` are used to get the meters per unit from the {@link METERS_PER_UNIT}
12793 * lookup table.
12794 * @property {import("../extent.js").Extent} [worldExtent] The world extent for the SRS.
12795 * @property {function(number, import("../coordinate.js").Coordinate):number} [getPointResolution]
12796 * Function to determine resolution at a point. The function is called with a
12797 * `number` view resolution and a {@link module:ol/coordinate~Coordinate} as arguments, and returns
12798 * the `number` resolution in projection units at the passed coordinate. If this is `undefined`,
12799 * the default {@link module:ol/proj.getPointResolution} function will be used.
12800 */
12801
12802/**
12803 * @classdesc
12804 * Projection definition class. One of these is created for each projection
12805 * supported in the application and stored in the {@link module:ol/proj} namespace.
12806 * You can use these in applications, but this is not required, as API params
12807 * and options use {@link module:ol/proj~ProjectionLike} which means the simple string
12808 * code will suffice.
12809 *
12810 * You can use {@link module:ol/proj.get} to retrieve the object for a particular
12811 * projection.
12812 *
12813 * The library includes definitions for `EPSG:4326` and `EPSG:3857`, together
12814 * with the following aliases:
12815 * * `EPSG:4326`: CRS:84, urn:ogc:def:crs:EPSG:6.6:4326,
12816 *     urn:ogc:def:crs:OGC:1.3:CRS84, urn:ogc:def:crs:OGC:2:84,
12817 *     http://www.opengis.net/gml/srs/epsg.xml#4326,
12818 *     urn:x-ogc:def:crs:EPSG:4326
12819 * * `EPSG:3857`: EPSG:102100, EPSG:102113, EPSG:900913,
12820 *     urn:ogc:def:crs:EPSG:6.18:3:3857,
12821 *     http://www.opengis.net/gml/srs/epsg.xml#3857
12822 *
12823 * If you use [proj4js](https://github.com/proj4js/proj4js), aliases can
12824 * be added using `proj4.defs()`. After all required projection definitions are
12825 * added, call the {@link module:ol/proj/proj4.register} function.
12826 *
12827 * @api
12828 */
12829class Projection {
12830  /**
12831   * @param {Options} options Projection options.
12832   */
12833  constructor(options) {
12834    /**
12835     * @private
12836     * @type {string}
12837     */
12838    this.code_ = options.code;
12839
12840    /**
12841     * Units of projected coordinates. When set to `TILE_PIXELS`, a
12842     * `this.extent_` and `this.worldExtent_` must be configured properly for each
12843     * tile.
12844     * @private
12845     * @type {import("./Units.js").Units}
12846     */
12847    this.units_ = /** @type {import("./Units.js").Units} */ (options.units);
12848
12849    /**
12850     * Validity extent of the projection in projected coordinates. For projections
12851     * with `TILE_PIXELS` units, this is the extent of the tile in
12852     * tile pixel space.
12853     * @private
12854     * @type {import("../extent.js").Extent}
12855     */
12856    this.extent_ = options.extent !== undefined ? options.extent : null;
12857
12858    /**
12859     * Extent of the world in EPSG:4326. For projections with
12860     * `TILE_PIXELS` units, this is the extent of the tile in
12861     * projected coordinate space.
12862     * @private
12863     * @type {import("../extent.js").Extent}
12864     */
12865    this.worldExtent_ =
12866      options.worldExtent !== undefined ? options.worldExtent : null;
12867
12868    /**
12869     * @private
12870     * @type {string}
12871     */
12872    this.axisOrientation_ =
12873      options.axisOrientation !== undefined ? options.axisOrientation : 'enu';
12874
12875    /**
12876     * @private
12877     * @type {boolean}
12878     */
12879    this.global_ = options.global !== undefined ? options.global : false;
12880
12881    /**
12882     * @private
12883     * @type {boolean}
12884     */
12885    this.canWrapX_ = !!(this.global_ && this.extent_);
12886
12887    /**
12888     * @private
12889     * @type {function(number, import("../coordinate.js").Coordinate):number|undefined}
12890     */
12891    this.getPointResolutionFunc_ = options.getPointResolution;
12892
12893    /**
12894     * @private
12895     * @type {import("../tilegrid/TileGrid.js").default}
12896     */
12897    this.defaultTileGrid_ = null;
12898
12899    /**
12900     * @private
12901     * @type {number|undefined}
12902     */
12903    this.metersPerUnit_ = options.metersPerUnit;
12904  }
12905
12906  /**
12907   * @return {boolean} The projection is suitable for wrapping the x-axis
12908   */
12909  canWrapX() {
12910    return this.canWrapX_;
12911  }
12912
12913  /**
12914   * Get the code for this projection, e.g. 'EPSG:4326'.
12915   * @return {string} Code.
12916   * @api
12917   */
12918  getCode() {
12919    return this.code_;
12920  }
12921
12922  /**
12923   * Get the validity extent for this projection.
12924   * @return {import("../extent.js").Extent} Extent.
12925   * @api
12926   */
12927  getExtent() {
12928    return this.extent_;
12929  }
12930
12931  /**
12932   * Get the units of this projection.
12933   * @return {import("./Units.js").Units} Units.
12934   * @api
12935   */
12936  getUnits() {
12937    return this.units_;
12938  }
12939
12940  /**
12941   * Get the amount of meters per unit of this projection.  If the projection is
12942   * not configured with `metersPerUnit` or a units identifier, the return is
12943   * `undefined`.
12944   * @return {number|undefined} Meters.
12945   * @api
12946   */
12947  getMetersPerUnit() {
12948    return this.metersPerUnit_ || Units_METERS_PER_UNIT[this.units_];
12949  }
12950
12951  /**
12952   * Get the world extent for this projection.
12953   * @return {import("../extent.js").Extent} Extent.
12954   * @api
12955   */
12956  getWorldExtent() {
12957    return this.worldExtent_;
12958  }
12959
12960  /**
12961   * Get the axis orientation of this projection.
12962   * Example values are:
12963   * enu - the default easting, northing, elevation.
12964   * neu - northing, easting, up - useful for "lat/long" geographic coordinates,
12965   *     or south orientated transverse mercator.
12966   * wnu - westing, northing, up - some planetary coordinate systems have
12967   *     "west positive" coordinate systems
12968   * @return {string} Axis orientation.
12969   * @api
12970   */
12971  getAxisOrientation() {
12972    return this.axisOrientation_;
12973  }
12974
12975  /**
12976   * Is this projection a global projection which spans the whole world?
12977   * @return {boolean} Whether the projection is global.
12978   * @api
12979   */
12980  isGlobal() {
12981    return this.global_;
12982  }
12983
12984  /**
12985   * Set if the projection is a global projection which spans the whole world
12986   * @param {boolean} global Whether the projection is global.
12987   * @api
12988   */
12989  setGlobal(global) {
12990    this.global_ = global;
12991    this.canWrapX_ = !!(global && this.extent_);
12992  }
12993
12994  /**
12995   * @return {import("../tilegrid/TileGrid.js").default} The default tile grid.
12996   */
12997  getDefaultTileGrid() {
12998    return this.defaultTileGrid_;
12999  }
13000
13001  /**
13002   * @param {import("../tilegrid/TileGrid.js").default} tileGrid The default tile grid.
13003   */
13004  setDefaultTileGrid(tileGrid) {
13005    this.defaultTileGrid_ = tileGrid;
13006  }
13007
13008  /**
13009   * Set the validity extent for this projection.
13010   * @param {import("../extent.js").Extent} extent Extent.
13011   * @api
13012   */
13013  setExtent(extent) {
13014    this.extent_ = extent;
13015    this.canWrapX_ = !!(this.global_ && extent);
13016  }
13017
13018  /**
13019   * Set the world extent for this projection.
13020   * @param {import("../extent.js").Extent} worldExtent World extent
13021   *     [minlon, minlat, maxlon, maxlat].
13022   * @api
13023   */
13024  setWorldExtent(worldExtent) {
13025    this.worldExtent_ = worldExtent;
13026  }
13027
13028  /**
13029   * Set the getPointResolution function (see {@link module:ol/proj.getPointResolution}
13030   * for this projection.
13031   * @param {function(number, import("../coordinate.js").Coordinate):number} func Function
13032   * @api
13033   */
13034  setGetPointResolution(func) {
13035    this.getPointResolutionFunc_ = func;
13036  }
13037
13038  /**
13039   * Get the custom point resolution function for this projection (if set).
13040   * @return {function(number, import("../coordinate.js").Coordinate):number|undefined} The custom point
13041   * resolution function (if set).
13042   */
13043  getPointResolutionFunc() {
13044    return this.getPointResolutionFunc_;
13045  }
13046}
13047
13048/* harmony default export */ const proj_Projection = (Projection);
13049
13050;// CONCATENATED MODULE: ./node_modules/ol/proj/epsg3857.js
13051/**
13052 * @module ol/proj/epsg3857
13053 */
13054
13055
13056/**
13057 * Radius of WGS84 sphere
13058 *
13059 * @const
13060 * @type {number}
13061 */
13062const RADIUS = 6378137;
13063
13064/**
13065 * @const
13066 * @type {number}
13067 */
13068const HALF_SIZE = Math.PI * RADIUS;
13069
13070/**
13071 * @const
13072 * @type {import("../extent.js").Extent}
13073 */
13074const EXTENT = [-HALF_SIZE, -HALF_SIZE, HALF_SIZE, HALF_SIZE];
13075
13076/**
13077 * @const
13078 * @type {import("../extent.js").Extent}
13079 */
13080const WORLD_EXTENT = [-180, -85, 180, 85];
13081
13082/**
13083 * Maximum safe value in y direction
13084 * @const
13085 * @type {number}
13086 */
13087const MAX_SAFE_Y = RADIUS * Math.log(Math.tan(Math.PI / 2));
13088
13089/**
13090 * @classdesc
13091 * Projection object for web/spherical Mercator (EPSG:3857).
13092 */
13093class EPSG3857Projection extends proj_Projection {
13094  /**
13095   * @param {string} code Code.
13096   */
13097  constructor(code) {
13098    super({
13099      code: code,
13100      units: 'm',
13101      extent: EXTENT,
13102      global: true,
13103      worldExtent: WORLD_EXTENT,
13104      getPointResolution: function (resolution, point) {
13105        return resolution / Math.cosh(point[1] / RADIUS);
13106      },
13107    });
13108  }
13109}
13110
13111/**
13112 * Projections equal to EPSG:3857.
13113 *
13114 * @const
13115 * @type {Array<import("./Projection.js").default>}
13116 */
13117const PROJECTIONS = [
13118  new EPSG3857Projection('EPSG:3857'),
13119  new EPSG3857Projection('EPSG:102100'),
13120  new EPSG3857Projection('EPSG:102113'),
13121  new EPSG3857Projection('EPSG:900913'),
13122  new EPSG3857Projection('http://www.opengis.net/def/crs/EPSG/0/3857'),
13123  new EPSG3857Projection('http://www.opengis.net/gml/srs/epsg.xml#3857'),
13124];
13125
13126/**
13127 * Transformation from EPSG:4326 to EPSG:3857.
13128 *
13129 * @param {Array<number>} input Input array of coordinate values.
13130 * @param {Array<number>} [output] Output array of coordinate values.
13131 * @param {number} [dimension] Dimension (default is `2`).
13132 * @return {Array<number>} Output array of coordinate values.
13133 */
13134function fromEPSG4326(input, output, dimension) {
13135  const length = input.length;
13136  dimension = dimension > 1 ? dimension : 2;
13137  if (output === undefined) {
13138    if (dimension > 2) {
13139      // preserve values beyond second dimension
13140      output = input.slice();
13141    } else {
13142      output = new Array(length);
13143    }
13144  }
13145  for (let i = 0; i < length; i += dimension) {
13146    output[i] = (HALF_SIZE * input[i]) / 180;
13147    let y = RADIUS * Math.log(Math.tan((Math.PI * (+input[i + 1] + 90)) / 360));
13148    if (y > MAX_SAFE_Y) {
13149      y = MAX_SAFE_Y;
13150    } else if (y < -MAX_SAFE_Y) {
13151      y = -MAX_SAFE_Y;
13152    }
13153    output[i + 1] = y;
13154  }
13155  return output;
13156}
13157
13158/**
13159 * Transformation from EPSG:3857 to EPSG:4326.
13160 *
13161 * @param {Array<number>} input Input array of coordinate values.
13162 * @param {Array<number>} [output] Output array of coordinate values.
13163 * @param {number} [dimension] Dimension (default is `2`).
13164 * @return {Array<number>} Output array of coordinate values.
13165 */
13166function toEPSG4326(input, output, dimension) {
13167  const length = input.length;
13168  dimension = dimension > 1 ? dimension : 2;
13169  if (output === undefined) {
13170    if (dimension > 2) {
13171      // preserve values beyond second dimension
13172      output = input.slice();
13173    } else {
13174      output = new Array(length);
13175    }
13176  }
13177  for (let i = 0; i < length; i += dimension) {
13178    output[i] = (180 * input[i]) / HALF_SIZE;
13179    output[i + 1] =
13180      (360 * Math.atan(Math.exp(input[i + 1] / RADIUS))) / Math.PI - 90;
13181  }
13182  return output;
13183}
13184
13185;// CONCATENATED MODULE: ./node_modules/ol/proj/epsg4326.js
13186/**
13187 * @module ol/proj/epsg4326
13188 */
13189
13190
13191/**
13192 * Semi-major radius of the WGS84 ellipsoid.
13193 *
13194 * @const
13195 * @type {number}
13196 */
13197const epsg4326_RADIUS = 6378137;
13198
13199/**
13200 * Extent of the EPSG:4326 projection which is the whole world.
13201 *
13202 * @const
13203 * @type {import("../extent.js").Extent}
13204 */
13205const epsg4326_EXTENT = [-180, -90, 180, 90];
13206
13207/**
13208 * @const
13209 * @type {number}
13210 */
13211const epsg4326_METERS_PER_UNIT = (Math.PI * epsg4326_RADIUS) / 180;
13212
13213/**
13214 * @classdesc
13215 * Projection object for WGS84 geographic coordinates (EPSG:4326).
13216 *
13217 * Note that OpenLayers does not strictly comply with the EPSG definition.
13218 * The EPSG registry defines 4326 as a CRS for Latitude,Longitude (y,x).
13219 * OpenLayers treats EPSG:4326 as a pseudo-projection, with x,y coordinates.
13220 */
13221class EPSG4326Projection extends proj_Projection {
13222  /**
13223   * @param {string} code Code.
13224   * @param {string} [axisOrientation] Axis orientation.
13225   */
13226  constructor(code, axisOrientation) {
13227    super({
13228      code: code,
13229      units: 'degrees',
13230      extent: epsg4326_EXTENT,
13231      axisOrientation: axisOrientation,
13232      global: true,
13233      metersPerUnit: epsg4326_METERS_PER_UNIT,
13234      worldExtent: epsg4326_EXTENT,
13235    });
13236  }
13237}
13238
13239/**
13240 * Projections equal to EPSG:4326.
13241 *
13242 * @const
13243 * @type {Array<import("./Projection.js").default>}
13244 */
13245const epsg4326_PROJECTIONS = [
13246  new EPSG4326Projection('CRS:84'),
13247  new EPSG4326Projection('EPSG:4326', 'neu'),
13248  new EPSG4326Projection('urn:ogc:def:crs:OGC:1.3:CRS84'),
13249  new EPSG4326Projection('urn:ogc:def:crs:OGC:2:84'),
13250  new EPSG4326Projection('http://www.opengis.net/def/crs/OGC/1.3/CRS84'),
13251  new EPSG4326Projection('http://www.opengis.net/gml/srs/epsg.xml#4326', 'neu'),
13252  new EPSG4326Projection('http://www.opengis.net/def/crs/EPSG/0/4326', 'neu'),
13253];
13254
13255;// CONCATENATED MODULE: ./node_modules/ol/proj/projections.js
13256/**
13257 * @module ol/proj/projections
13258 */
13259
13260/**
13261 * @type {Object<string, import("./Projection.js").default>}
13262 */
13263let cache = {};
13264
13265/**
13266 * Clear the projections cache.
13267 */
13268function projections_clear() {
13269  cache = {};
13270}
13271
13272/**
13273 * Get a cached projection by code.
13274 * @param {string} code The code for the projection.
13275 * @return {import("./Projection.js").default} The projection (if cached).
13276 */
13277function get(code) {
13278  return (
13279    cache[code] ||
13280    cache[code.replace(/urn:(x-)?ogc:def:crs:EPSG:(.*:)?(\w+)$/, 'EPSG:$3')] ||
13281    null
13282  );
13283}
13284
13285/**
13286 * Add a projection to the cache.
13287 * @param {string} code The projection code.
13288 * @param {import("./Projection.js").default} projection The projection to cache.
13289 */
13290function add(code, projection) {
13291  cache[code] = projection;
13292}
13293
13294;// CONCATENATED MODULE: ./node_modules/ol/proj/transforms.js
13295/**
13296 * @module ol/proj/transforms
13297 */
13298
13299
13300/**
13301 * @private
13302 * @type {!Object<string, Object<string, import("../proj.js").TransformFunction>>}
13303 */
13304let transforms = {};
13305
13306/**
13307 * Clear the transform cache.
13308 */
13309function transforms_clear() {
13310  transforms = {};
13311}
13312
13313/**
13314 * Registers a conversion function to convert coordinates from the source
13315 * projection to the destination projection.
13316 *
13317 * @param {import("./Projection.js").default} source Source.
13318 * @param {import("./Projection.js").default} destination Destination.
13319 * @param {import("../proj.js").TransformFunction} transformFn Transform.
13320 */
13321function transforms_add(source, destination, transformFn) {
13322  const sourceCode = source.getCode();
13323  const destinationCode = destination.getCode();
13324  if (!(sourceCode in transforms)) {
13325    transforms[sourceCode] = {};
13326  }
13327  transforms[sourceCode][destinationCode] = transformFn;
13328}
13329
13330/**
13331 * Unregisters the conversion function to convert coordinates from the source
13332 * projection to the destination projection.  This method is used to clean up
13333 * cached transforms during testing.
13334 *
13335 * @param {import("./Projection.js").default} source Source projection.
13336 * @param {import("./Projection.js").default} destination Destination projection.
13337 * @return {import("../proj.js").TransformFunction} transformFn The unregistered transform.
13338 */
13339function transforms_remove(source, destination) {
13340  const sourceCode = source.getCode();
13341  const destinationCode = destination.getCode();
13342  const transform = transforms[sourceCode][destinationCode];
13343  delete transforms[sourceCode][destinationCode];
13344  if (isEmpty(transforms[sourceCode])) {
13345    delete transforms[sourceCode];
13346  }
13347  return transform;
13348}
13349
13350/**
13351 * Get a transform given a source code and a destination code.
13352 * @param {string} sourceCode The code for the source projection.
13353 * @param {string} destinationCode The code for the destination projection.
13354 * @return {import("../proj.js").TransformFunction|undefined} The transform function (if found).
13355 */
13356function transforms_get(sourceCode, destinationCode) {
13357  let transform;
13358  if (sourceCode in transforms && destinationCode in transforms[sourceCode]) {
13359    transform = transforms[sourceCode][destinationCode];
13360  }
13361  return transform;
13362}
13363
13364;// CONCATENATED MODULE: ./node_modules/ol/extent/Relationship.js
13365/**
13366 * @module ol/extent/Relationship
13367 */
13368
13369/**
13370 * Relationship to an extent.
13371 * @enum {number}
13372 */
13373/* harmony default export */ const Relationship = ({
13374  UNKNOWN: 0,
13375  INTERSECTING: 1,
13376  ABOVE: 2,
13377  RIGHT: 4,
13378  BELOW: 8,
13379  LEFT: 16,
13380});
13381
13382;// CONCATENATED MODULE: ./node_modules/ol/extent.js
13383/**
13384 * @module ol/extent
13385 */
13386
13387
13388
13389/**
13390 * An array of numbers representing an extent: `[minx, miny, maxx, maxy]`.
13391 * @typedef {Array<number>} Extent
13392 * @api
13393 */
13394
13395/**
13396 * Extent corner.
13397 * @typedef {'bottom-left' | 'bottom-right' | 'top-left' | 'top-right'} Corner
13398 */
13399
13400/**
13401 * Build an extent that includes all given coordinates.
13402 *
13403 * @param {Array<import("./coordinate.js").Coordinate>} coordinates Coordinates.
13404 * @return {Extent} Bounding extent.
13405 * @api
13406 */
13407function boundingExtent(coordinates) {
13408  const extent = createEmpty();
13409  for (let i = 0, ii = coordinates.length; i < ii; ++i) {
13410    extendCoordinate(extent, coordinates[i]);
13411  }
13412  return extent;
13413}
13414
13415/**
13416 * @param {Array<number>} xs Xs.
13417 * @param {Array<number>} ys Ys.
13418 * @param {Extent} [dest] Destination extent.
13419 * @private
13420 * @return {Extent} Extent.
13421 */
13422function _boundingExtentXYs(xs, ys, dest) {
13423  const minX = Math.min.apply(null, xs);
13424  const minY = Math.min.apply(null, ys);
13425  const maxX = Math.max.apply(null, xs);
13426  const maxY = Math.max.apply(null, ys);
13427  return createOrUpdate(minX, minY, maxX, maxY, dest);
13428}
13429
13430/**
13431 * Return extent increased by the provided value.
13432 * @param {Extent} extent Extent.
13433 * @param {number} value The amount by which the extent should be buffered.
13434 * @param {Extent} [dest] Extent.
13435 * @return {Extent} Extent.
13436 * @api
13437 */
13438function buffer(extent, value, dest) {
13439  if (dest) {
13440    dest[0] = extent[0] - value;
13441    dest[1] = extent[1] - value;
13442    dest[2] = extent[2] + value;
13443    dest[3] = extent[3] + value;
13444    return dest;
13445  } else {
13446    return [
13447      extent[0] - value,
13448      extent[1] - value,
13449      extent[2] + value,
13450      extent[3] + value,
13451    ];
13452  }
13453}
13454
13455/**
13456 * Creates a clone of an extent.
13457 *
13458 * @param {Extent} extent Extent to clone.
13459 * @param {Extent} [dest] Extent.
13460 * @return {Extent} The clone.
13461 */
13462function clone(extent, dest) {
13463  if (dest) {
13464    dest[0] = extent[0];
13465    dest[1] = extent[1];
13466    dest[2] = extent[2];
13467    dest[3] = extent[3];
13468    return dest;
13469  } else {
13470    return extent.slice();
13471  }
13472}
13473
13474/**
13475 * @param {Extent} extent Extent.
13476 * @param {number} x X.
13477 * @param {number} y Y.
13478 * @return {number} Closest squared distance.
13479 */
13480function closestSquaredDistanceXY(extent, x, y) {
13481  let dx, dy;
13482  if (x < extent[0]) {
13483    dx = extent[0] - x;
13484  } else if (extent[2] < x) {
13485    dx = x - extent[2];
13486  } else {
13487    dx = 0;
13488  }
13489  if (y < extent[1]) {
13490    dy = extent[1] - y;
13491  } else if (extent[3] < y) {
13492    dy = y - extent[3];
13493  } else {
13494    dy = 0;
13495  }
13496  return dx * dx + dy * dy;
13497}
13498
13499/**
13500 * Check if the passed coordinate is contained or on the edge of the extent.
13501 *
13502 * @param {Extent} extent Extent.
13503 * @param {import("./coordinate.js").Coordinate} coordinate Coordinate.
13504 * @return {boolean} The coordinate is contained in the extent.
13505 * @api
13506 */
13507function containsCoordinate(extent, coordinate) {
13508  return containsXY(extent, coordinate[0], coordinate[1]);
13509}
13510
13511/**
13512 * Check if one extent contains another.
13513 *
13514 * An extent is deemed contained if it lies completely within the other extent,
13515 * including if they share one or more edges.
13516 *
13517 * @param {Extent} extent1 Extent 1.
13518 * @param {Extent} extent2 Extent 2.
13519 * @return {boolean} The second extent is contained by or on the edge of the
13520 *     first.
13521 * @api
13522 */
13523function containsExtent(extent1, extent2) {
13524  return (
13525    extent1[0] <= extent2[0] &&
13526    extent2[2] <= extent1[2] &&
13527    extent1[1] <= extent2[1] &&
13528    extent2[3] <= extent1[3]
13529  );
13530}
13531
13532/**
13533 * Check if the passed coordinate is contained or on the edge of the extent.
13534 *
13535 * @param {Extent} extent Extent.
13536 * @param {number} x X coordinate.
13537 * @param {number} y Y coordinate.
13538 * @return {boolean} The x, y values are contained in the extent.
13539 * @api
13540 */
13541function containsXY(extent, x, y) {
13542  return extent[0] <= x && x <= extent[2] && extent[1] <= y && y <= extent[3];
13543}
13544
13545/**
13546 * Get the relationship between a coordinate and extent.
13547 * @param {Extent} extent The extent.
13548 * @param {import("./coordinate.js").Coordinate} coordinate The coordinate.
13549 * @return {import("./extent/Relationship.js").default} The relationship (bitwise compare with
13550 *     import("./extent/Relationship.js").Relationship).
13551 */
13552function coordinateRelationship(extent, coordinate) {
13553  const minX = extent[0];
13554  const minY = extent[1];
13555  const maxX = extent[2];
13556  const maxY = extent[3];
13557  const x = coordinate[0];
13558  const y = coordinate[1];
13559  let relationship = Relationship.UNKNOWN;
13560  if (x < minX) {
13561    relationship = relationship | Relationship.LEFT;
13562  } else if (x > maxX) {
13563    relationship = relationship | Relationship.RIGHT;
13564  }
13565  if (y < minY) {
13566    relationship = relationship | Relationship.BELOW;
13567  } else if (y > maxY) {
13568    relationship = relationship | Relationship.ABOVE;
13569  }
13570  if (relationship === Relationship.UNKNOWN) {
13571    relationship = Relationship.INTERSECTING;
13572  }
13573  return relationship;
13574}
13575
13576/**
13577 * Create an empty extent.
13578 * @return {Extent} Empty extent.
13579 * @api
13580 */
13581function createEmpty() {
13582  return [Infinity, Infinity, -Infinity, -Infinity];
13583}
13584
13585/**
13586 * Create a new extent or update the provided extent.
13587 * @param {number} minX Minimum X.
13588 * @param {number} minY Minimum Y.
13589 * @param {number} maxX Maximum X.
13590 * @param {number} maxY Maximum Y.
13591 * @param {Extent} [dest] Destination extent.
13592 * @return {Extent} Extent.
13593 */
13594function createOrUpdate(minX, minY, maxX, maxY, dest) {
13595  if (dest) {
13596    dest[0] = minX;
13597    dest[1] = minY;
13598    dest[2] = maxX;
13599    dest[3] = maxY;
13600    return dest;
13601  } else {
13602    return [minX, minY, maxX, maxY];
13603  }
13604}
13605
13606/**
13607 * Create a new empty extent or make the provided one empty.
13608 * @param {Extent} [dest] Extent.
13609 * @return {Extent} Extent.
13610 */
13611function createOrUpdateEmpty(dest) {
13612  return createOrUpdate(Infinity, Infinity, -Infinity, -Infinity, dest);
13613}
13614
13615/**
13616 * @param {import("./coordinate.js").Coordinate} coordinate Coordinate.
13617 * @param {Extent} [dest] Extent.
13618 * @return {Extent} Extent.
13619 */
13620function createOrUpdateFromCoordinate(coordinate, dest) {
13621  const x = coordinate[0];
13622  const y = coordinate[1];
13623  return createOrUpdate(x, y, x, y, dest);
13624}
13625
13626/**
13627 * @param {Array<import("./coordinate.js").Coordinate>} coordinates Coordinates.
13628 * @param {Extent} [dest] Extent.
13629 * @return {Extent} Extent.
13630 */
13631function createOrUpdateFromCoordinates(coordinates, dest) {
13632  const extent = createOrUpdateEmpty(dest);
13633  return extendCoordinates(extent, coordinates);
13634}
13635
13636/**
13637 * @param {Array<number>} flatCoordinates Flat coordinates.
13638 * @param {number} offset Offset.
13639 * @param {number} end End.
13640 * @param {number} stride Stride.
13641 * @param {Extent} [dest] Extent.
13642 * @return {Extent} Extent.
13643 */
13644function createOrUpdateFromFlatCoordinates(
13645  flatCoordinates,
13646  offset,
13647  end,
13648  stride,
13649  dest
13650) {
13651  const extent = createOrUpdateEmpty(dest);
13652  return extendFlatCoordinates(extent, flatCoordinates, offset, end, stride);
13653}
13654
13655/**
13656 * @param {Array<Array<import("./coordinate.js").Coordinate>>} rings Rings.
13657 * @param {Extent} [dest] Extent.
13658 * @return {Extent} Extent.
13659 */
13660function createOrUpdateFromRings(rings, dest) {
13661  const extent = createOrUpdateEmpty(dest);
13662  return extendRings(extent, rings);
13663}
13664
13665/**
13666 * Determine if two extents are equivalent.
13667 * @param {Extent} extent1 Extent 1.
13668 * @param {Extent} extent2 Extent 2.
13669 * @return {boolean} The two extents are equivalent.
13670 * @api
13671 */
13672function extent_equals(extent1, extent2) {
13673  return (
13674    extent1[0] == extent2[0] &&
13675    extent1[2] == extent2[2] &&
13676    extent1[1] == extent2[1] &&
13677    extent1[3] == extent2[3]
13678  );
13679}
13680
13681/**
13682 * Determine if two extents are approximately equivalent.
13683 * @param {Extent} extent1 Extent 1.
13684 * @param {Extent} extent2 Extent 2.
13685 * @param {number} tolerance Tolerance in extent coordinate units.
13686 * @return {boolean} The two extents differ by less than the tolerance.
13687 */
13688function approximatelyEquals(extent1, extent2, tolerance) {
13689  return (
13690    Math.abs(extent1[0] - extent2[0]) < tolerance &&
13691    Math.abs(extent1[2] - extent2[2]) < tolerance &&
13692    Math.abs(extent1[1] - extent2[1]) < tolerance &&
13693    Math.abs(extent1[3] - extent2[3]) < tolerance
13694  );
13695}
13696
13697/**
13698 * Modify an extent to include another extent.
13699 * @param {Extent} extent1 The extent to be modified.
13700 * @param {Extent} extent2 The extent that will be included in the first.
13701 * @return {Extent} A reference to the first (extended) extent.
13702 * @api
13703 */
13704function extent_extend(extent1, extent2) {
13705  if (extent2[0] < extent1[0]) {
13706    extent1[0] = extent2[0];
13707  }
13708  if (extent2[2] > extent1[2]) {
13709    extent1[2] = extent2[2];
13710  }
13711  if (extent2[1] < extent1[1]) {
13712    extent1[1] = extent2[1];
13713  }
13714  if (extent2[3] > extent1[3]) {
13715    extent1[3] = extent2[3];
13716  }
13717  return extent1;
13718}
13719
13720/**
13721 * @param {Extent} extent Extent.
13722 * @param {import("./coordinate.js").Coordinate} coordinate Coordinate.
13723 */
13724function extendCoordinate(extent, coordinate) {
13725  if (coordinate[0] < extent[0]) {
13726    extent[0] = coordinate[0];
13727  }
13728  if (coordinate[0] > extent[2]) {
13729    extent[2] = coordinate[0];
13730  }
13731  if (coordinate[1] < extent[1]) {
13732    extent[1] = coordinate[1];
13733  }
13734  if (coordinate[1] > extent[3]) {
13735    extent[3] = coordinate[1];
13736  }
13737}
13738
13739/**
13740 * @param {Extent} extent Extent.
13741 * @param {Array<import("./coordinate.js").Coordinate>} coordinates Coordinates.
13742 * @return {Extent} Extent.
13743 */
13744function extendCoordinates(extent, coordinates) {
13745  for (let i = 0, ii = coordinates.length; i < ii; ++i) {
13746    extendCoordinate(extent, coordinates[i]);
13747  }
13748  return extent;
13749}
13750
13751/**
13752 * @param {Extent} extent Extent.
13753 * @param {Array<number>} flatCoordinates Flat coordinates.
13754 * @param {number} offset Offset.
13755 * @param {number} end End.
13756 * @param {number} stride Stride.
13757 * @return {Extent} Extent.
13758 */
13759function extendFlatCoordinates(
13760  extent,
13761  flatCoordinates,
13762  offset,
13763  end,
13764  stride
13765) {
13766  for (; offset < end; offset += stride) {
13767    extendXY(extent, flatCoordinates[offset], flatCoordinates[offset + 1]);
13768  }
13769  return extent;
13770}
13771
13772/**
13773 * @param {Extent} extent Extent.
13774 * @param {Array<Array<import("./coordinate.js").Coordinate>>} rings Rings.
13775 * @return {Extent} Extent.
13776 */
13777function extendRings(extent, rings) {
13778  for (let i = 0, ii = rings.length; i < ii; ++i) {
13779    extendCoordinates(extent, rings[i]);
13780  }
13781  return extent;
13782}
13783
13784/**
13785 * @param {Extent} extent Extent.
13786 * @param {number} x X.
13787 * @param {number} y Y.
13788 */
13789function extendXY(extent, x, y) {
13790  extent[0] = Math.min(extent[0], x);
13791  extent[1] = Math.min(extent[1], y);
13792  extent[2] = Math.max(extent[2], x);
13793  extent[3] = Math.max(extent[3], y);
13794}
13795
13796/**
13797 * This function calls `callback` for each corner of the extent. If the
13798 * callback returns a truthy value the function returns that value
13799 * immediately. Otherwise the function returns `false`.
13800 * @param {Extent} extent Extent.
13801 * @param {function(import("./coordinate.js").Coordinate): S} callback Callback.
13802 * @return {S|boolean} Value.
13803 * @template S
13804 */
13805function forEachCorner(extent, callback) {
13806  let val;
13807  val = callback(getBottomLeft(extent));
13808  if (val) {
13809    return val;
13810  }
13811  val = callback(getBottomRight(extent));
13812  if (val) {
13813    return val;
13814  }
13815  val = callback(getTopRight(extent));
13816  if (val) {
13817    return val;
13818  }
13819  val = callback(getTopLeft(extent));
13820  if (val) {
13821    return val;
13822  }
13823  return false;
13824}
13825
13826/**
13827 * Get the size of an extent.
13828 * @param {Extent} extent Extent.
13829 * @return {number} Area.
13830 * @api
13831 */
13832function getArea(extent) {
13833  let area = 0;
13834  if (!extent_isEmpty(extent)) {
13835    area = extent_getWidth(extent) * extent_getHeight(extent);
13836  }
13837  return area;
13838}
13839
13840/**
13841 * Get the bottom left coordinate of an extent.
13842 * @param {Extent} extent Extent.
13843 * @return {import("./coordinate.js").Coordinate} Bottom left coordinate.
13844 * @api
13845 */
13846function getBottomLeft(extent) {
13847  return [extent[0], extent[1]];
13848}
13849
13850/**
13851 * Get the bottom right coordinate of an extent.
13852 * @param {Extent} extent Extent.
13853 * @return {import("./coordinate.js").Coordinate} Bottom right coordinate.
13854 * @api
13855 */
13856function getBottomRight(extent) {
13857  return [extent[2], extent[1]];
13858}
13859
13860/**
13861 * Get the center coordinate of an extent.
13862 * @param {Extent} extent Extent.
13863 * @return {import("./coordinate.js").Coordinate} Center.
13864 * @api
13865 */
13866function getCenter(extent) {
13867  return [(extent[0] + extent[2]) / 2, (extent[1] + extent[3]) / 2];
13868}
13869
13870/**
13871 * Get a corner coordinate of an extent.
13872 * @param {Extent} extent Extent.
13873 * @param {Corner} corner Corner.
13874 * @return {import("./coordinate.js").Coordinate} Corner coordinate.
13875 */
13876function getCorner(extent, corner) {
13877  let coordinate;
13878  if (corner === 'bottom-left') {
13879    coordinate = getBottomLeft(extent);
13880  } else if (corner === 'bottom-right') {
13881    coordinate = getBottomRight(extent);
13882  } else if (corner === 'top-left') {
13883    coordinate = getTopLeft(extent);
13884  } else if (corner === 'top-right') {
13885    coordinate = getTopRight(extent);
13886  } else {
13887    asserts_assert(false, 13); // Invalid corner
13888  }
13889  return coordinate;
13890}
13891
13892/**
13893 * @param {Extent} extent1 Extent 1.
13894 * @param {Extent} extent2 Extent 2.
13895 * @return {number} Enlarged area.
13896 */
13897function getEnlargedArea(extent1, extent2) {
13898  const minX = Math.min(extent1[0], extent2[0]);
13899  const minY = Math.min(extent1[1], extent2[1]);
13900  const maxX = Math.max(extent1[2], extent2[2]);
13901  const maxY = Math.max(extent1[3], extent2[3]);
13902  return (maxX - minX) * (maxY - minY);
13903}
13904
13905/**
13906 * @param {import("./coordinate.js").Coordinate} center Center.
13907 * @param {number} resolution Resolution.
13908 * @param {number} rotation Rotation.
13909 * @param {import("./size.js").Size} size Size.
13910 * @param {Extent} [dest] Destination extent.
13911 * @return {Extent} Extent.
13912 */
13913function getForViewAndSize(center, resolution, rotation, size, dest) {
13914  const [x0, y0, x1, y1, x2, y2, x3, y3] = getRotatedViewport(
13915    center,
13916    resolution,
13917    rotation,
13918    size
13919  );
13920  return createOrUpdate(
13921    Math.min(x0, x1, x2, x3),
13922    Math.min(y0, y1, y2, y3),
13923    Math.max(x0, x1, x2, x3),
13924    Math.max(y0, y1, y2, y3),
13925    dest
13926  );
13927}
13928
13929/**
13930 * @param {import("./coordinate.js").Coordinate} center Center.
13931 * @param {number} resolution Resolution.
13932 * @param {number} rotation Rotation.
13933 * @param {import("./size.js").Size} size Size.
13934 * @return {Array<number>} Linear ring representing the viewport.
13935 */
13936function getRotatedViewport(center, resolution, rotation, size) {
13937  const dx = (resolution * size[0]) / 2;
13938  const dy = (resolution * size[1]) / 2;
13939  const cosRotation = Math.cos(rotation);
13940  const sinRotation = Math.sin(rotation);
13941  const xCos = dx * cosRotation;
13942  const xSin = dx * sinRotation;
13943  const yCos = dy * cosRotation;
13944  const ySin = dy * sinRotation;
13945  const x = center[0];
13946  const y = center[1];
13947  return [
13948    x - xCos + ySin,
13949    y - xSin - yCos,
13950    x - xCos - ySin,
13951    y - xSin + yCos,
13952    x + xCos - ySin,
13953    y + xSin + yCos,
13954    x + xCos + ySin,
13955    y + xSin - yCos,
13956    x - xCos + ySin,
13957    y - xSin - yCos,
13958  ];
13959}
13960
13961/**
13962 * Get the height of an extent.
13963 * @param {Extent} extent Extent.
13964 * @return {number} Height.
13965 * @api
13966 */
13967function extent_getHeight(extent) {
13968  return extent[3] - extent[1];
13969}
13970
13971/**
13972 * @param {Extent} extent1 Extent 1.
13973 * @param {Extent} extent2 Extent 2.
13974 * @return {number} Intersection area.
13975 */
13976function getIntersectionArea(extent1, extent2) {
13977  const intersection = getIntersection(extent1, extent2);
13978  return getArea(intersection);
13979}
13980
13981/**
13982 * Get the intersection of two extents.
13983 * @param {Extent} extent1 Extent 1.
13984 * @param {Extent} extent2 Extent 2.
13985 * @param {Extent} [dest] Optional extent to populate with intersection.
13986 * @return {Extent} Intersecting extent.
13987 * @api
13988 */
13989function getIntersection(extent1, extent2, dest) {
13990  const intersection = dest ? dest : createEmpty();
13991  if (intersects(extent1, extent2)) {
13992    if (extent1[0] > extent2[0]) {
13993      intersection[0] = extent1[0];
13994    } else {
13995      intersection[0] = extent2[0];
13996    }
13997    if (extent1[1] > extent2[1]) {
13998      intersection[1] = extent1[1];
13999    } else {
14000      intersection[1] = extent2[1];
14001    }
14002    if (extent1[2] < extent2[2]) {
14003      intersection[2] = extent1[2];
14004    } else {
14005      intersection[2] = extent2[2];
14006    }
14007    if (extent1[3] < extent2[3]) {
14008      intersection[3] = extent1[3];
14009    } else {
14010      intersection[3] = extent2[3];
14011    }
14012  } else {
14013    createOrUpdateEmpty(intersection);
14014  }
14015  return intersection;
14016}
14017
14018/**
14019 * @param {Extent} extent Extent.
14020 * @return {number} Margin.
14021 */
14022function getMargin(extent) {
14023  return extent_getWidth(extent) + extent_getHeight(extent);
14024}
14025
14026/**
14027 * Get the size (width, height) of an extent.
14028 * @param {Extent} extent The extent.
14029 * @return {import("./size.js").Size} The extent size.
14030 * @api
14031 */
14032function getSize(extent) {
14033  return [extent[2] - extent[0], extent[3] - extent[1]];
14034}
14035
14036/**
14037 * Get the top left coordinate of an extent.
14038 * @param {Extent} extent Extent.
14039 * @return {import("./coordinate.js").Coordinate} Top left coordinate.
14040 * @api
14041 */
14042function getTopLeft(extent) {
14043  return [extent[0], extent[3]];
14044}
14045
14046/**
14047 * Get the top right coordinate of an extent.
14048 * @param {Extent} extent Extent.
14049 * @return {import("./coordinate.js").Coordinate} Top right coordinate.
14050 * @api
14051 */
14052function getTopRight(extent) {
14053  return [extent[2], extent[3]];
14054}
14055
14056/**
14057 * Get the width of an extent.
14058 * @param {Extent} extent Extent.
14059 * @return {number} Width.
14060 * @api
14061 */
14062function extent_getWidth(extent) {
14063  return extent[2] - extent[0];
14064}
14065
14066/**
14067 * Determine if one extent intersects another.
14068 * @param {Extent} extent1 Extent 1.
14069 * @param {Extent} extent2 Extent.
14070 * @return {boolean} The two extents intersect.
14071 * @api
14072 */
14073function intersects(extent1, extent2) {
14074  return (
14075    extent1[0] <= extent2[2] &&
14076    extent1[2] >= extent2[0] &&
14077    extent1[1] <= extent2[3] &&
14078    extent1[3] >= extent2[1]
14079  );
14080}
14081
14082/**
14083 * Determine if an extent is empty.
14084 * @param {Extent} extent Extent.
14085 * @return {boolean} Is empty.
14086 * @api
14087 */
14088function extent_isEmpty(extent) {
14089  return extent[2] < extent[0] || extent[3] < extent[1];
14090}
14091
14092/**
14093 * @param {Extent} extent Extent.
14094 * @param {Extent} [dest] Extent.
14095 * @return {Extent} Extent.
14096 */
14097function returnOrUpdate(extent, dest) {
14098  if (dest) {
14099    dest[0] = extent[0];
14100    dest[1] = extent[1];
14101    dest[2] = extent[2];
14102    dest[3] = extent[3];
14103    return dest;
14104  } else {
14105    return extent;
14106  }
14107}
14108
14109/**
14110 * @param {Extent} extent Extent.
14111 * @param {number} value Value.
14112 */
14113function scaleFromCenter(extent, value) {
14114  const deltaX = ((extent[2] - extent[0]) / 2) * (value - 1);
14115  const deltaY = ((extent[3] - extent[1]) / 2) * (value - 1);
14116  extent[0] -= deltaX;
14117  extent[2] += deltaX;
14118  extent[1] -= deltaY;
14119  extent[3] += deltaY;
14120}
14121
14122/**
14123 * Determine if the segment between two coordinates intersects (crosses,
14124 * touches, or is contained by) the provided extent.
14125 * @param {Extent} extent The extent.
14126 * @param {import("./coordinate.js").Coordinate} start Segment start coordinate.
14127 * @param {import("./coordinate.js").Coordinate} end Segment end coordinate.
14128 * @return {boolean} The segment intersects the extent.
14129 */
14130function intersectsSegment(extent, start, end) {
14131  let intersects = false;
vendor: 5,289 bytes, lines 14132-14311
14132  const startRel = coordinateRelationship(extent, start);
14133  const endRel = coordinateRelationship(extent, end);
14134  if (
14135    startRel === Relationship.INTERSECTING ||
14136    endRel === Relationship.INTERSECTING
14137  ) {
14138    intersects = true;
14139  } else {
14140    const minX = extent[0];
14141    const minY = extent[1];
14142    const maxX = extent[2];
14143    const maxY = extent[3];
14144    const startX = start[0];
14145    const startY = start[1];
14146    const endX = end[0];
14147    const endY = end[1];
14148    const slope = (endY - startY) / (endX - startX);
14149    let x, y;
14150    if (!!(endRel & Relationship.ABOVE) && !(startRel & Relationship.ABOVE)) {
14151      // potentially intersects top
14152      x = endX - (endY - maxY) / slope;
14153      intersects = x >= minX && x <= maxX;
14154    }
14155    if (
14156      !intersects &&
14157      !!(endRel & Relationship.RIGHT) &&
14158      !(startRel & Relationship.RIGHT)
14159    ) {
14160      // potentially intersects right
14161      y = endY - (endX - maxX) * slope;
14162      intersects = y >= minY && y <= maxY;
14163    }
14164    if (
14165      !intersects &&
14166      !!(endRel & Relationship.BELOW) &&
14167      !(startRel & Relationship.BELOW)
14168    ) {
14169      // potentially intersects bottom
14170      x = endX - (endY - minY) / slope;
14171      intersects = x >= minX && x <= maxX;
14172    }
14173    if (
14174      !intersects &&
14175      !!(endRel & Relationship.LEFT) &&
14176      !(startRel & Relationship.LEFT)
14177    ) {
14178      // potentially intersects left
14179      y = endY - (endX - minX) * slope;
14180      intersects = y >= minY && y <= maxY;
14181    }
14182  }
14183  return intersects;
14184}
14185
14186/**
14187 * Apply a transform function to the extent.
14188 * @param {Extent} extent Extent.
14189 * @param {import("./proj.js").TransformFunction} transformFn Transform function.
14190 * Called with `[minX, minY, maxX, maxY]` extent coordinates.
14191 * @param {Extent} [dest] Destination extent.
14192 * @param {number} [stops] Number of stops per side used for the transform.
14193 * By default only the corners are used.
14194 * @return {Extent} Extent.
14195 * @api
14196 */
14197function applyTransform(extent, transformFn, dest, stops) {
14198  let coordinates = [];
14199  if (stops > 1) {
14200    const width = extent[2] - extent[0];
14201    const height = extent[3] - extent[1];
14202    for (let i = 0; i < stops; ++i) {
14203      coordinates.push(
14204        extent[0] + (width * i) / stops,
14205        extent[1],
14206        extent[2],
14207        extent[1] + (height * i) / stops,
14208        extent[2] - (width * i) / stops,
14209        extent[3],
14210        extent[0],
14211        extent[3] - (height * i) / stops
14212      );
14213    }
14214  } else {
14215    coordinates = [
14216      extent[0],
14217      extent[1],
14218      extent[2],
14219      extent[1],
14220      extent[2],
14221      extent[3],
14222      extent[0],
14223      extent[3],
14224    ];
14225  }
14226  transformFn(coordinates, coordinates, 2);
14227  const xs = [];
14228  const ys = [];
14229  for (let i = 0, l = coordinates.length; i < l; i += 2) {
14230    xs.push(coordinates[i]);
14231    ys.push(coordinates[i + 1]);
14232  }
14233  return _boundingExtentXYs(xs, ys, dest);
14234}
14235
14236/**
14237 * Modifies the provided extent in-place to be within the real world
14238 * extent.
14239 *
14240 * @param {Extent} extent Extent.
14241 * @param {import("./proj/Projection.js").default} projection Projection
14242 * @return {Extent} The extent within the real world extent.
14243 */
14244function wrapX(extent, projection) {
14245  const projectionExtent = projection.getExtent();
14246  const center = getCenter(extent);
14247  if (
14248    projection.canWrapX() &&
14249    (center[0] < projectionExtent[0] || center[0] >= projectionExtent[2])
14250  ) {
14251    const worldWidth = extent_getWidth(projectionExtent);
14252    const worldsAway = Math.floor(
14253      (center[0] - projectionExtent[0]) / worldWidth
14254    );
14255    const offset = worldsAway * worldWidth;
14256    extent[0] -= offset;
14257    extent[2] -= offset;
14258  }
14259  return extent;
14260}
14261
14262/**
14263 * Fits the extent to the real world
14264 *
14265 * If the extent does not cross the anti meridian, this will return the extent in an array
14266 * If the extent crosses the anti meridian, the extent will be sliced, so each part fits within the
14267 * real world
14268 *
14269 *
14270 * @param {Extent} extent Extent.
14271 * @param {import("./proj/Projection.js").default} projection Projection
14272 * @return {Array<Extent>} The extent within the real world extent.
14273 */
14274function wrapAndSliceX(extent, projection) {
14275  if (projection.canWrapX()) {
14276    const projectionExtent = projection.getExtent();
14277
14278    if (!isFinite(extent[0]) || !isFinite(extent[2])) {
14279      return [[projectionExtent[0], extent[1], projectionExtent[2], extent[3]]];
14280    }
14281
14282    wrapX(extent, projection);
14283    const worldWidth = extent_getWidth(projectionExtent);
14284
14285    if (extent_getWidth(extent) > worldWidth) {
14286      // the extent wraps around on itself
14287      return [[projectionExtent[0], extent[1], projectionExtent[2], extent[3]]];
14288    } else if (extent[0] < projectionExtent[0]) {
14289      // the extent crosses the anti meridian, so it needs to be sliced
14290      return [
14291        [extent[0] + worldWidth, extent[1], projectionExtent[2], extent[3]],
14292        [projectionExtent[0], extent[1], extent[2], extent[3]],
14293      ];
14294    } else if (extent[2] > projectionExtent[2]) {
14295      // the extent crosses the anti meridian, so it needs to be sliced
14296      return [
14297        [extent[0], extent[1], projectionExtent[2], extent[3]],
14298        [projectionExtent[0], extent[1], extent[2] - worldWidth, extent[3]],
14299      ];
14300    }
14301  }
14302
14303  return [extent];
14304}
14305
14306;// CONCATENATED MODULE: ./node_modules/ol/math.js
14307/**
14308 * @module ol/math
14309 */
14310
14311/**
14312 * Takes a number and clamps it to within the provided bounds.
14313 * @param {number} value The input number.
14314 * @param {number} min The minimum value to return.
14315 * @param {number} max The maximum value to return.
14316 * @return {number} The input number if it is within bounds, or the nearest
14317 *     number within the bounds.
14318 */
14319function math_clamp(value, min, max) {
14320  return Math.min(Math.max(value, min), max);
14321}
14322
14323/**
14324 * Returns the square of the closest distance between the point (x, y) and the
14325 * line segment (x1, y1) to (x2, y2).
14326 * @param {number} x X.
14327 * @param {number} y Y.
14328 * @param {number} x1 X1.
14329 * @param {number} y1 Y1.
14330 * @param {number} x2 X2.
14331 * @param {number} y2 Y2.
14332 * @return {number} Squared distance.
14333 */
14334function squaredSegmentDistance(x, y, x1, y1, x2, y2) {
14335  const dx = x2 - x1;
14336  const dy = y2 - y1;
14337  if (dx !== 0 || dy !== 0) {
14338    const t = ((x - x1) * dx + (y - y1) * dy) / (dx * dx + dy * dy);
14339    if (t > 1) {
14340      x1 = x2;
14341      y1 = y2;
14342    } else if (t > 0) {
14343      x1 += dx * t;
14344      y1 += dy * t;
14345    }
14346  }
14347  return math_squaredDistance(x, y, x1, y1);
14348}
14349
14350/**
14351 * Returns the square of the distance between the points (x1, y1) and (x2, y2).
14352 * @param {number} x1 X1.
14353 * @param {number} y1 Y1.
14354 * @param {number} x2 X2.
14355 * @param {number} y2 Y2.
14356 * @return {number} Squared distance.
14357 */
14358function math_squaredDistance(x1, y1, x2, y2) {
14359  const dx = x2 - x1;
14360  const dy = y2 - y1;
14361  return dx * dx + dy * dy;
14362}
14363
14364/**
14365 * Solves system of linear equations using Gaussian elimination method.
14366 *
14367 * @param {Array<Array<number>>} mat Augmented matrix (n x n + 1 column)
14368 *                                     in row-major order.
14369 * @return {Array<number>} The resulting vector.
14370 */
14371function solveLinearSystem(mat) {
14372  const n = mat.length;
14373
14374  for (let i = 0; i < n; i++) {
14375    // Find max in the i-th column (ignoring i - 1 first rows)
14376    let maxRow = i;
14377    let maxEl = Math.abs(mat[i][i]);
14378    for (let r = i + 1; r < n; r++) {
14379      const absValue = Math.abs(mat[r][i]);
14380      if (absValue > maxEl) {
14381        maxEl = absValue;
14382        maxRow = r;
14383      }
14384    }
14385
14386    if (maxEl === 0) {
14387      return null; // matrix is singular
14388    }
14389
14390    // Swap max row with i-th (current) row
14391    const tmp = mat[maxRow];
14392    mat[maxRow] = mat[i];
14393    mat[i] = tmp;
14394
14395    // Subtract the i-th row to make all the remaining rows 0 in the i-th column
14396    for (let j = i + 1; j < n; j++) {
14397      const coef = -mat[j][i] / mat[i][i];
14398      for (let k = i; k < n + 1; k++) {
14399        if (i == k) {
14400          mat[j][k] = 0;
14401        } else {
14402          mat[j][k] += coef * mat[i][k];
14403        }
14404      }
14405    }
14406  }
14407
14408  // Solve Ax=b for upper triangular matrix A (mat)
14409  const x = new Array(n);
14410  for (let l = n - 1; l >= 0; l--) {
14411    x[l] = mat[l][n] / mat[l][l];
14412    for (let m = l - 1; m >= 0; m--) {
14413      mat[m][n] -= mat[m][l] * x[l];
14414    }
14415  }
14416  return x;
14417}
14418
14419/**
14420 * Converts radians to to degrees.
14421 *
14422 * @param {number} angleInRadians Angle in radians.
14423 * @return {number} Angle in degrees.
14424 */
14425function math_toDegrees(angleInRadians) {
14426  return (angleInRadians * 180) / Math.PI;
14427}
14428
14429/**
14430 * Converts degrees to radians.
14431 *
14432 * @param {number} angleInDegrees Angle in degrees.
14433 * @return {number} Angle in radians.
14434 */
14435function math_toRadians(angleInDegrees) {
14436  return (angleInDegrees * Math.PI) / 180;
14437}
14438
14439/**
14440 * Returns the modulo of a / b, depending on the sign of b.
14441 *
14442 * @param {number}
14442 a Dividend.
14443 * @param {number} b Divisor.
14444 * @return {number} Modulo.
14445 */
14446function math_modulo(a, b) {
14447  const r = a % b;
14448  return r * b < 0 ? r + b : r;
14449}
14450
14451/**
14452 * Calculates the linearly interpolated value of x between a and b.
14453 *
14454 * @param {number} a Number
14455 * @param {number} b Number
14456 * @param {number} x Value to be interpolated.
14457 * @return {number} Interpolated value.
14458 */
14459function lerp(a, b, x) {
14460  return a + x * (b - a);
14461}
14462
14463/**
14464 * Returns a number with a limited number of decimal digits.
14465 * @param {number} n The input number.
14466 * @param {number} decimals The maximum number of decimal digits.
14467 * @return {number} The input number with a limited number of decimal digits.
14468 */
14469function math_toFixed(n, decimals) {
14470  const factor = Math.pow(10, decimals);
14471  return Math.round(n * factor) / factor;
14472}
14473
14474/**
14475 * Rounds a number to the nearest integer value considering only the given number
14476 * of decimal digits (with rounding on the final digit).
14477 * @param {number} n The input number.
14478 * @param {number} decimals The maximum number of decimal digits.
14479 * @return {number} The nearest integer.
14480 */
14481function round(n, decimals) {
14482  return Math.round(math_toFixed(n, decimals));
14483}
14484
14485/**
14486 * Rounds a number to the next smaller integer considering only the given number
14487 * of decimal digits (with rounding on the final digit).
14488 * @param {number} n The input number.
14489 * @param {number} decimals The maximum number of decimal digits.
14490 * @return {number} The next smaller integer.
14491 */
14492function floor(n, decimals) {
14493  return Math.floor(math_toFixed(n, decimals));
14494}
14495
14496/**
14497 * Rounds a number to the next bigger integer considering only the given number
14498 * of decimal digits (with rounding on the final digit).
14499 * @param {number} n The input number.
14500 * @param {number} decimals The maximum number of decimal digits.
14501 * @return {number} The next bigger integer.
14502 */
14503function ceil(n, decimals) {
14504  return Math.ceil(math_toFixed(n, decimals));
14505}
14506
14507;// CONCATENATED MODULE: ./node_modules/ol/coordinate.js
14508/**
14509 * @module ol/coordinate
14510 */
14511
14512
14513
14514
14515/**
14516 * An array of numbers representing an xy coordinate. Example: `[16, 48]`.
14517 * @typedef {Array<number>} Coordinate
14518 * @api
14519 */
14520
14521/**
14522 * A function that takes a {@link module:ol/coordinate~Coordinate} and
14523 * transforms it into a `{string}`.
14524 *
14525 * @typedef {function((Coordinate|undefined)): string} CoordinateFormat
14526 * @api
14527 */
14528
14529/**
14530 * Add `delta` to `coordinate`. `coordinate` is modified in place and returned
14531 * by the function.
14532 *
14533 * Example:
14534 *
14535 *     import {add} from 'ol/coordinate';
14536 *
14537 *     const coord = [7.85, 47.983333];
14538 *     add(coord, [-2, 4]);
14539 *     // coord is now [5.85, 51.983333]
14540 *
14541 * @param {Coordinate} coordinate Coordinate.
14542 * @param {Coordinate} delta Delta.
14543 * @return {Coordinate} The input coordinate adjusted by
14544 * the given delta.
14545 * @api
14546 */
14547function coordinate_add(coordinate, delta) {
14548  coordinate[0] += +delta[0];
14549  coordinate[1] += +delta[1];
14550  return coordinate;
14551}
14552
14553/**
14554 * Calculates the point closest to the passed coordinate on the passed circle.
14555 *
14556 * @param {Coordinate} coordinate The coordinate.
14557 * @param {import("./geom/Circle.js").default} circle The circle.
14558 * @return {Coordinate} Closest point on the circumference.
14559 */
14560function closestOnCircle(coordinate, circle) {
14561  const r = circle.getRadius();
14562  const center = circle.getCenter();
14563  const x0 = center[0];
14564  const y0 = center[1];
14565  const x1 = coordinate[0];
14566  const y1 = coordinate[1];
14567
14568  let dx = x1 - x0;
14569  const dy = y1 - y0;
14570  if (dx === 0 && dy === 0) {
14571    dx = 1;
14572  }
14573  const d = Math.sqrt(dx * dx + dy * dy);
14574
14575  const x = x0 + (r * dx) / d;
14576  const y = y0 + (r * dy) / d;
14577
14578  return [x, y];
14579}
14580
14581/**
14582 * Calculates the point closest to the passed coordinate on the passed segment.
14583 * This is the foot of the perpendicular of the coordinate to the segment when
14584 * the foot is on the segment, or the closest segment coordinate when the foot
14585 * is outside the segment.
14586 *
14587 * @param {Coordinate} coordinate The coordinate.
14588 * @param {Array<Coordinate>} segment The two coordinates
14589 * of the segment.
14590 * @return {Coordinate} The foot of the perpendicular of
14591 * the coordinate to the segment.
14592 */
14593function closestOnSegment(coordinate, segment) {
14594  const x0 = coordinate[0];
14595  const y0 = coordinate[1];
14596  const start = segment[0];
14597  const end = segment[1];
14598  const x1 = start[0];
14599  const y1 = start[1];
14600  const x2 = end[0];
14601  const y2 = end[1];
14602  const dx = x2 - x1;
14603  const dy = y2 - y1;
14604  const along =
14605    dx === 0 && dy === 0
14606      ? 0
14607      : (dx * (x0 - x1) + dy * (y0 - y1)) / (dx * dx + dy * dy || 0);
14608  let x, y;
14609  if (along <= 0) {
14610    x = x1;
14611    y = y1;
14612  } else if (along >= 1) {
14613    x = x2;
14614    y = y2;
14615  } else {
14616    x = x1 + along * dx;
14617    y = y1 + along * dy;
14618  }
14619  return [x, y];
14620}
14621
14622/**
14623 * Returns a {@link module:ol/coordinate~CoordinateFormat} function that can be
14624 * used to format
14625 * a {Coordinate} to a string.
14626 *
14627 * Example without specifying the fractional digits:
14628 *
14629 *     import {createStringXY} from 'ol/coordinate';
14630 *
14631 *     const coord = [7.85, 47.983333];
14632 *     const stringifyFunc = createStringXY();
14633 *     const out = stringifyFunc(coord);
14634 *     // out is now '8, 48'
14635 *
14636 * Example with explicitly specifying 2 fractional digits:
14637 *
14638 *     import {createStringXY} from 'ol/coordinate';
14639 *
14640 *     const coord = [7.85, 47.983333];
14641 *     const stringifyFunc = createStringXY(2);
14642 *     const out = stringifyFunc(coord);
14643 *     // out is now '7.85, 47.98'
14644 *
14645 * @param {number} [fractionDigits] The number of digits to include
14646 *    after the decimal point. Default is `0`.
14647 * @return {CoordinateFormat} Coordinate format.
14648 * @api
14649 */
14650function createStringXY(fractionDigits) {
14651  return (
14652    /**
14653     * @param {Coordinate} coordinate Coordinate.
14654     * @return {string} String XY.
14655     */
14656    function (coordinate) {
14657      return toStringXY(coordinate, fractionDigits);
14658    }
14659  );
14660}
14661
14662/**
14663 * @param {string} hemispheres Hemispheres.
14664 * @param {number} degrees Degrees.
14665 * @param {number} [fractionDigits] The number of digits to include
14666 *    after the decimal point. Default is `0`.
14667 * @return {string} String.
14668 */
14669function degreesToStringHDMS(hemispheres, degrees, fractionDigits) {
14670  const normalizedDegrees = modulo(degrees + 180, 360) - 180;
14671  const x = Math.abs(3600 * normalizedDegrees);
14672  const decimals = fractionDigits || 0;
14673
14674  let deg = Math.floor(x / 3600);
14675  let min = Math.floor((x - deg * 3600) / 60);
14676  let sec = toFixed(x - deg * 3600 - min * 60, decimals);
14677
14678  if (sec >= 60) {
14679    sec = 0;
14680    min += 1;
14681  }
14682
14683  if (min >= 60) {
14684    min = 0;
14685    deg += 1;
14686  }
14687
14688  let hdms = deg + '\u00b0';
14689  if (min !== 0 || sec !== 0) {
14690    hdms += ' ' + padNumber(min, 2) + '\u2032';
14691  }
14692  if (sec !== 0) {
14693    hdms += ' ' + padNumber(sec, 2, decimals) + '\u2033';
14694  }
14695  if (normalizedDegrees !== 0) {
14696    hdms += ' ' + hemispheres.charAt(normalizedDegrees < 0 ? 1 : 0);
14697  }
14698
14699  return hdms;
14700}
14701
14702/**
14703 * Transforms the given {@link module:ol/coordinate~Coordinate} to a string
14704 * using the given string template. The strings `{x}` and `{y}` in the template
14705 * will be replaced with the first and second coordinate values respectively.
14706 *
14707 * Example without specifying the fractional digits:
14708 *
14709 *     import {format} from 'ol/coordinate';
14710 *
14711 *     const coord = [7.85, 47.983333];
14712 *     const template = 'Coordinate is ({x}|{y}).';
14713 *     const out = format(coord, template);
14714 *     // out is now 'Coordinate is (8|48).'
14715 *
14716 * Example explicitly specifying the fractional digits:
14717 *
14718 *     import {format} from 'ol/coordinate';
14719 *
14720 *     const coord = [7.85, 47.983333];
14721 *     const template = 'Coordinate is ({x}|{y}).';
14722 *     const out = format(coord, template, 2);
14723 *     // out is now 'Coordinate is (7.85|47.98).'
14724 *
14725 * @param {Coordinate} coordinate Coordinate.
14726 * @param {string} template A template string with `{x}` and `{y}` placeholders
14727 *     that will be replaced by first and second coordinate values.
14728 * @param {number} [fractionDigits] The number of digits to include
14729 *    after the decimal point. Default is `0`.
14730 * @return {string} Formatted coordinate.
14731 * @api
14732 */
14733function format(coordinate, template, fractionDigits) {
14734  if (coordinate) {
14735    return template
14736      .replace('{x}', coordinate[0].toFixed(fractionDigits))
14737      .replace('{y}', coordinate[1].toFixed(fractionDigits));
14738  } else {
14739    return '';
14740  }
14741}
14742
14743/**
14744 * @param {Coordinate} coordinate1 First coordinate.
14745 * @param {Coordinate} coordinate2 Second coordinate.
14746 * @return {boolean} The two coordinates are equal.
14747 */
14748function coordinate_equals(coordinate1, coordinate2) {
14749  let equals = true;
14750  for (let i = coordinate1.length - 1; i >= 0; --i) {
14751    if (coordinate1[i] != coordinate2[i]) {
14752      equals = false;
14753      break;
14754    }
14755  }
14756  return equals;
14757}
14758
14759/**
14760 * Rotate `coordinate` by `angle`. `coordinate` is modified in place and
14761 * returned by the function.
14762 *
14763 * Example:
14764 *
14765 *     import {rotate} from 'ol/coordinate';
14766 *
14767 *     const coord = [7.85, 47.983333];
14768 *     const rotateRadians = Math.PI / 2; // 90 degrees
14769 *     rotate(coord, rotateRadians);
14770 *     // coord is now [-47.983333, 7.85]
14771 *
14772 * @param {Coordinate} coordinate Coordinate.
14773 * @param {number} angle Angle in radian.
14774 * @return {Coordinate} Coordinate.
14775 * @api
14776 */
14777function rotate(coordinate, angle) {
14778  const cosAngle = Math.cos(angle);
14779  const sinAngle = Math.sin(angle);
14780  const x = coordinate[0] * cosAngle - coordinate[1] * sinAngle;
14781  const y = coordinate[1] * cosAngle + coordinate[0] * sinAngle;
14782  coordinate[0] = x;
14783  coordinate[1] = y;
14784  return coordinate;
14785}
14786
14787/**
14788 * Scale `coordinate` by `scale`. `coordinate` is modified in place and returned
14789 * by the function.
14790 *
14791 * Example:
14792 *
14793 *     import {scale as scaleCoordinate} from 'ol/coordinate';
14794 *
14795 *     const coord = [7.85, 47.983333];
14796 *     const scale = 1.2;
14797 *     scaleCoordinate(coord, scale);
14798 *     // coord is now [9.42, 57.5799996]
14799 *
14800 * @param {Coordinate} coordinate Coordinate.
14801 * @param {number} scale Scale factor.
14802 * @return {Coordinate} Coordinate.
14803 */
14804function scale(coordinate, scale) {
14805  coordinate[0] *= scale;
14806  coordinate[1] *= scale;
14807  return coordinate;
14808}
14809
14810/**
14811 * @param {Coordinate} coord1 First coordinate.
14812 * @param {Coordinate} coord2 Second coordinate.
14813 * @return {number} Squared distance between coord1 and coord2.
14814 */
14815function coordinate_squaredDistance(coord1, coord2) {
14816  const dx = coord1[0] - coord2[0];
14817  const dy = coord1[1] - coord2[1];
14818  return dx * dx + dy * dy;
14819}
14820
14821/**
14822 * @param {Coordinate} coord1 First coordinate.
14823 * @param {Coordinate} coord2 Second coordinate.
14824 * @return {number} Distance between coord1 and coord2.
14825 */
14826function distance(coord1, coord2) {
14827  return Math.sqrt(coordinate_squaredDistance(coord1, coord2));
14828}
14829
14830/**
14831 * Calculate the squared distance from a coordinate to a line segment.
14832 *
14833 * @param {Coordinate} coordinate Coordinate of the point.
14834 * @param {Array<Coordinate>} segment Line segment (2
14835 * coordinates).
14836 * @return {number} Squared distance from the point to the line segment.
14837 */
14838function squaredDistanceToSegment(coordinate, segment) {
14839  return coordinate_squaredDistance(coordinate, closestOnSegment(coordinate, segment));
14840}
14841
14842/**
14843 * Format a geographic coordinate with the hemisphere, degrees, minutes, and
14844 * seconds.
14845 *
14846 * Example without specifying fractional digits:
14847 *
14848 *     import {toStringHDMS} from 'ol/coordinate';
14849 *
14850 *     const coord = [7.85, 47.983333];
14851 *     const out = toStringHDMS(coord);
14852 *     // out is now '47° 58′ 60″ N 7° 50′ 60″ E'
14853 *
14854 * Example explicitly specifying 1 fractional digit:
14855 *
14856 *     import {toStringHDMS} from 'ol/coordinate';
14857 *
14858 *     const coord = [7.85, 47.983333];
14859 *     const out = toStringHDMS(coord, 1);
14860 *     // out is now '47° 58′ 60.0″ N 7° 50′ 60.0″ E'
14861 *
14862 * @param {Coordinate} coordinate Coordinate.
14863 * @param {number} [fractionDigits] The number of digits to include
14864 *    after the decimal point. Default is `0`.
14865 * @return {string} Hemisphere, degrees, minutes and seconds.
14866 * @api
14867 */
14868function toStringHDMS(coordinate, fractionDigits) {
14869  if (coordinate) {
14870    return (
14871      degreesToStringHDMS('NS', coordinate[1], fractionDigits) +
14872      ' ' +
14873      degreesToStringHDMS('EW', coordinate[0], fractionDigits)
14874    );
14875  } else {
14876    return '';
14877  }
14878}
14879
14880/**
14881 * Format a coordinate as a comma delimited string.
14882 *
14883 * Example without specifying fractional digits:
14884 *
14885 *     import {toStringXY} from 'ol/coordinate';
14886 *
14887 *     const coord = [7.85, 47.983333];
14888 *     const out = toStringXY(coord);
14889 *     // out is now '8, 48'
14890 *
14891 * Example explicitly specifying 1 fractional digit:
14892 *
14893 *     import {toStringXY} from 'ol/coordinate';
14894 *
14895 *     const coord = [7.85, 47.983333];
14896 *     const out = toStringXY(coord, 1);
14897 *     // out is now '7.8, 48.0'
14898 *
14899 * @param {Coordinate} coordinate Coordinate.
14900 * @param {number} [fractionDigits] The number of digits to include
14901 *    after the decimal point. Default is `0`.
14902 * @return {string} XY.
14903 * @api
14904 */
14905function toStringXY(coordinate, fractionDigits) {
14906  return format(coordinate, '{x}, {y}', fractionDigits);
14907}
14908
14909/**
14910 * Modifies the provided coordinate in-place to be within the real world
14911 * extent. The lower projection extent boundary is inclusive, the upper one
14912 * exclusive.
14913 *
14914 * @param {Coordinate} coordinate Coordinate.
14915 * @param {import("./proj/Projection.js").default} projection Projection.
14916 * @return {Coordinate} The coordinate within the real world extent.
14917 */
14918function coordinate_wrapX(coordinate, projection) {
14919  if (projection.canWrapX()) {
14920    const worldWidth = extent_getWidth(projection.getExtent());
14921    const worldsAway = coordinate_getWorldsAway(coordinate, projection, worldWidth);
14922    if (worldsAway) {
14923      coordinate[0] -= worldsAway * worldWidth;
14924    }
14925  }
14926  return coordinate;
14927}
14928/**
14929 * @param {Coordinate} coordinate Coordinate.
14930 * @param {import("./proj/Projection.js").default} projection Projection.
14931 * @param {number} [sourceExtentWidth] Width of the source extent.
14932 * @return {number} Offset in world widths.
14933 */
14934function coordinate_getWorldsAway(coordinate, projection, sourceExtentWidth) {
14935  const projectionExtent = projection.getExtent();
14936  let worldsAway = 0;
14937  if (
14938    projection.canWrapX() &&
14939    (coordinate[0] < projectionExtent[0] || coordinate[0] > projectionExtent[2])
14940  ) {
14941    sourceExtentWidth = sourceExtentWidth || extent_getWidth(projectionExtent);
14942    worldsAway = Math.floor(
14943      (coordinate[0] - projectionExtent[0]) / sourceExtentWidth
14944    );
14945  }
14946  return worldsAway;
14947}
14948
14949;// CONCATENATED MODULE: ./node_modules/ol/sphere.js
14950/**
14951 * @module ol/sphere
14952 */
14953
14954
14955/**
14956 * Object literal with options for the {@link getLength} or {@link getArea}
14957 * functions.
14958 * @typedef {Object} SphereMetricOptions
14959 * @property {import("./proj.js").ProjectionLike} [projection='EPSG:3857']
14960 * Projection of the  geometry.  By default, the geometry is assumed to be in
14961 * Web Mercator.
14962 * @property {number} [radius=6371008.8] Sphere radius.  By default, the
14963 * [mean Earth radius](https://en.wikipedia.org/wiki/Earth_radius#Mean_radius)
14964 * for the WGS84 ellipsoid is used.
14965 */
14966
14967/**
14968 * The mean Earth radius (1/3 * (2a + b)) for the WGS84 ellipsoid.
14969 * https://en.wikipedia.org/wiki/Earth_radius#Mean_radius
14970 * @type {number}
14971 */
14972const DEFAULT_RADIUS = 6371008.8;
14973
14974/**
14975 * Get the great circle distance (in meters) between two geographic coordinates.
14976 * @param {Array} c1 Starting coordinate.
14977 * @param {Array} c2 Ending coordinate.
14978 * @param {number} [radius] The sphere radius to use.  Defaults to the Earth's
14979 *     mean radius using the WGS84 ellipsoid.
14980 * @return {number} The great circle distance between the points (in meters).
14981 * @api
14982 */
14983function getDistance(c1, c2, radius) {
vendor: 7,264 bytes, lines 14984-15196
14984  radius = radius || DEFAULT_RADIUS;
14985  const lat1 = math_toRadians(c1[1]);
14986  const lat2 = math_toRadians(c2[1]);
14987  const deltaLatBy2 = (lat2 - lat1) / 2;
14988  const deltaLonBy2 = math_toRadians(c2[0] - c1[0]) / 2;
14989  const a =
14990    Math.sin(deltaLatBy2) * Math.sin(deltaLatBy2) +
14991    Math.sin(deltaLonBy2) *
14992      Math.sin(deltaLonBy2) *
14993      Math.cos(lat1) *
14994      Math.cos(lat2);
14995  return 2 * radius * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
14996}
14997
14998/**
14999 * Get the cumulative great circle length of linestring coordinates (geographic).
15000 * @param {Array} coordinates Linestring coordinates.
15001 * @param {number} radius The sphere radius to use.
15002 * @return {number} The length (in meters).
15003 */
15004function getLengthInternal(coordinates, radius) {
15005  let length = 0;
15006  for (let i = 0, ii = coordinates.length; i < ii - 1; ++i) {
15007    length += getDistance(coordinates[i], coordinates[i + 1], radius);
15008  }
15009  return length;
15010}
15011
15012/**
15013 * Get the spherical length of a geometry.  This length is the sum of the
15014 * great circle distances between coordinates.  For polygons, the length is
15015 * the sum of all rings.  For points, the length is zero.  For multi-part
15016 * geometries, the length is the sum of the length of each part.
15017 * @param {import("./geom/Geometry.js").default} geometry A geometry.
15018 * @param {SphereMetricOptions} [options] Options for the
15019 * length calculation.  By default, geometries are assumed to be in 'EPSG:3857'.
15020 * You can change this by providing a `projection` option.
15021 * @return {number} The spherical length (in meters).
15022 * @api
15023 */
15024function getLength(geometry, options) {
15025  options = options || {};
15026  const radius = options.radius || DEFAULT_RADIUS;
15027  const projection = options.projection || 'EPSG:3857';
15028  const type = geometry.getType();
15029  if (type !== 'GeometryCollection') {
15030    geometry = geometry.clone().transform(projection, 'EPSG:4326');
15031  }
15032  let length = 0;
15033  let coordinates, coords, i, ii, j, jj;
15034  switch (type) {
15035    case 'Point':
15036    case 'MultiPoint': {
15037      break;
15038    }
15039    case 'LineString':
15040    case 'LinearRing': {
15041      coordinates = /** @type {import("./geom/SimpleGeometry.js").default} */ (
15042        geometry
15043      ).getCoordinates();
15044      length = getLengthInternal(coordinates, radius);
15045      break;
15046    }
15047    case 'MultiLineString':
15048    case 'Polygon': {
15049      coordinates = /** @type {import("./geom/SimpleGeometry.js").default} */ (
15050        geometry
15051      ).getCoordinates();
15052      for (i = 0, ii = coordinates.length; i < ii; ++i) {
15053        length += getLengthInternal(coordinates[i], radius);
15054      }
15055      break;
15056    }
15057    case 'MultiPolygon': {
15058      coordinates = /** @type {import("./geom/SimpleGeometry.js").default} */ (
15059        geometry
15060      ).getCoordinates();
15061      for (i = 0, ii = coordinates.length; i < ii; ++i) {
15062        coords = coordinates[i];
15063        for (j = 0, jj = coords.length; j < jj; ++j) {
15064          length += getLengthInternal(coords[j], radius);
15065        }
15066      }
15067      break;
15068    }
15069    case 'GeometryCollection': {
15070      const geometries =
15071        /** @type {import("./geom/GeometryCollection.js").default} */ (
15072          geometry
15073        ).getGeometries();
15074      for (i = 0, ii = geometries.length; i < ii; ++i) {
15075        length += getLength(geometries[i], options);
15076      }
15077      break;
15078    }
15079    default: {
15080      throw new Error('Unsupported geometry type: ' + type);
15081    }
15082  }
15083  return length;
15084}
15085
15086/**
15087 * Returns the spherical area for a list of coordinates.
15088 *
15089 * [Reference](https://trs.jpl.nasa.gov/handle/2014/40409)
15090 * Robert. G. Chamberlain and William H. Duquette, "Some Algorithms for
15091 * Polygons on a Sphere", JPL Publication 07-03, Jet Propulsion
15092 * Laboratory, Pasadena, CA, June 2007
15093 *
15094 * @param {Array<import("./coordinate.js").Coordinate>} coordinates List of coordinates of a linear
15095 * ring. If the ring is oriented clockwise, the area will be positive,
15096 * otherwise it will be negative.
15097 * @param {number} radius The sphere radius.
15098 * @return {number} Area (in square meters).
15099 */
15100function getAreaInternal(coordinates, radius) {
15101  let area = 0;
15102  const len = coordinates.length;
15103  let x1 = coordinates[len - 1][0];
15104  let y1 = coordinates[len - 1][1];
15105  for (let i = 0; i < len; i++) {
15106    const x2 = coordinates[i][0];
15107    const y2 = coordinates[i][1];
15108    area +=
15109      toRadians(x2 - x1) *
15110      (2 + Math.sin(toRadians(y1)) + Math.sin(toRadians(y2)));
15111    x1 = x2;
15112    y1 = y2;
15113  }
15114  return (area * radius * radius) / 2.0;
15115}
15116
15117/**
15118 * Get the spherical area of a geometry.  This is the area (in meters) assuming
15119 * that polygon edges are segments of great circles on a sphere.
15120 * @param {import("./geom/Geometry.js").default} geometry A geometry.
15121 * @param {SphereMetricOptions} [options] Options for the area
15122 *     calculation.  By default, geometries are assumed to be in 'EPSG:3857'.
15123 *     You can change this by providing a `projection` option.
15124 * @return {number} The spherical area (in square meters).
15125 * @api
15126 */
15127function sphere_getArea(geometry, options) {
15128  options = options || {};
15129  const radius = options.radius || DEFAULT_RADIUS;
15130  const projection = options.projection || 'EPSG:3857';
15131  const type = geometry.getType();
15132  if (type !== 'GeometryCollection') {
15133    geometry = geometry.clone().transform(projection, 'EPSG:4326');
15134  }
15135  let area = 0;
15136  let coordinates, coords, i, ii, j, jj;
15137  switch (type) {
15138    case 'Point':
15139    case 'MultiPoint':
15140    case 'LineString':
15141    case 'MultiLineString':
15142    case 'LinearRing': {
15143      break;
15144    }
15145    case 'Polygon': {
15146      coordinates = /** @type {import("./geom/Polygon.js").default} */ (
15147        geometry
15148      ).getCoordinates();
15149      area = Math.abs(getAreaInternal(coordinates[0], radius));
15150      for (i = 1, ii = coordinates.length; i < ii; ++i) {
15151        area -= Math.abs(getAreaInternal(coordinates[i], radius));
15152      }
15153      break;
15154    }
15155    case 'MultiPolygon': {
15156      coordinates = /** @type {import("./geom/SimpleGeometry.js").default} */ (
15157        geometry
15158      ).getCoordinates();
15159      for (i = 0, ii = coordinates.length; i < ii; ++i) {
15160        coords = coordinates[i];
15161        area += Math.abs(getAreaInternal(coords[0], radius));
15162        for (j = 1, jj = coords.length; j < jj; ++j) {
15163          area -= Math.abs(getAreaInternal(coords[j], radius));
15164        }
15165      }
15166      break;
15167    }
15168    case 'GeometryCollection': {
15169      const geometries =
15170        /** @type {import("./geom/GeometryCollection.js").default} */ (
15171          geometry
15172        ).getGeometries();
15173      for (i = 0, ii = geometries.length; i < ii; ++i) {
15174        area += sphere_getArea(geometries[i], options);
15175      }
15176      break;
15177    }
15178    default: {
15179      throw new Error('Unsupported geometry type: ' + type);
15180    }
15181  }
15182  return area;
15183}
15184
15185/**
15186 * Returns the coordinate at the given distance and bearing from `c1`.
15187 *
15188 * @param {import("./coordinate.js").Coordinate} c1 The origin point (`[lon, lat]` in degrees).
15189 * @param {number} distance The great-circle distance between the origin
15190 *     point and the target point.
15191 * @param {number} bearing The bearing (in radians).
15192 * @param {number} [radius] The sphere radius to use.  Defaults to the Earth's
15193 *     mean radius using the WGS84 ellipsoid.
15194 * @return {import("./coordinate.js").Coordinate} The target point.
15195 */
15196function offset(c1, distance, bearing, radius) {
15197  radius = radius || DEFAULT_RADIUS;
15198  const lat1 = toRadians(c1[1]);
15199  const lon1 = toRadians(c1[0]);
15200  const dByR = distance / radius;
15201  const lat = Math.asin(
15202    Math.sin(lat1) * Math.cos(dByR) +
15203      Math.cos(lat1) * Math.sin(dByR) * Math.cos(bearing)
15204  );
15205  const lon =
15206    lon1 +
15207    Math.atan2(
15208      Math.sin(bearing) * Math.sin(dByR) * Math.cos(lat1),
15209      Math.cos(dByR) - Math.sin(lat1) * Math.sin(lat)
15210    );
15211  return [toDegrees(lon), toDegrees(lat)];
15212}
15213
15214;// CONCATENATED MODULE: ./node_modules/ol/proj.js
15215/**
15216 * @module ol/proj
15217 */
15218
15219/**
15220 * The ol/proj module stores:
15221 * * a list of {@link module:ol/proj/Projection~Projection}
15222 * objects, one for each projection supported by the application
15223 * * a list of transform functions needed to convert coordinates in one projection
15224 * into another.
15225 *
15226 * The static functions are the methods used to maintain these.
15227 * Each transform function can handle not only simple coordinate pairs, but also
15228 * large arrays of coordinates such as vector geometries.
15229 *
15230 * When loaded, the library adds projection objects for EPSG:4326 (WGS84
15231 * geographic coordinates) and EPSG:3857 (Web or Spherical Mercator, as used
15232 * for example by Bing Maps or OpenStreetMap), together with the relevant
15233 * transform functions.
15234 *
15235 * Additional transforms may be added by using the http://proj4js.org/
15236 * library (version 2.2 or later). You can use the full build supplied by
15237 * Proj4js, or create a custom build to support those projections you need; see
15238 * the Proj4js website for how to do this. You also need the Proj4js definitions
15239 * for the required projections. These definitions can be obtained from
15240 * https://epsg.io/, and are a JS function, so can be loaded in a script
15241 * tag (as in the examples) or pasted into your application.
15242 *
15243 * After all required projection definitions are added to proj4's registry (by
15244 * using `proj4.defs()`), simply call `register(proj4)` from the `ol/proj/proj4`
15245 * package. Existing transforms are not changed by this function. See
15246 * examples/wms-image-custom-proj for an example of this.
15247 *
15248 * Additional projection definitions can be registered with `proj4.defs()` any
15249 * time. Just make sure to call `register(proj4)` again; for example, with user-supplied data where you don't
15250 * know in advance what projections are needed, you can initially load minimal
15251 * support and then load whichever are requested.
15252 *
15253 * Note that Proj4js does not support projection extents. If you want to add
15254 * one for creating default tile grids, you can add it after the Projection
15255 * object has been created with `setExtent`, for example,
15256 * `get('EPSG:1234').setExtent(extent)`.
15257 *
15258 * In addition to Proj4js support, any transform functions can be added with
15259 * {@link module:ol/proj.addCoordinateTransforms}. To use this, you must first create
15260 * a {@link module:ol/proj/Projection~Projection} object for the new projection and add it with
15261 * {@link module:ol/proj.addProjection}. You can then add the forward and inverse
15262 * functions with {@link module:ol/proj.addCoordinateTransforms}. See
15263 * examples/wms-custom-proj for an example of this.
15264 *
15265 * Note that if no transforms are needed and you only need to define the
15266 * projection, just add a {@link module:ol/proj/Projection~Projection} with
15267 * {@link module:ol/proj.addProjection}. See examples/wms-no-proj for an example of
15268 * this.
15269 */
15270
15271
15272
15273
15274
15275
15276
15277
15278
15279
15280
15281/**
15282 * A projection as {@link module:ol/proj/Projection~Projection}, SRS identifier
15283 * string or undefined.
15284 * @typedef {Projection|string|undefined} ProjectionLike
15285 * @api
15286 */
15287
15288/**
15289 * A transform function accepts an array of input coordinate values, an optional
15290 * output array, and an optional dimension (default should be 2).  The function
15291 * transforms the input coordinate values, populates the output array, and
15292 * returns the output array.
15293 *
15294 * @typedef {function(Array<number>, Array<number>=, number=): Array<number>} TransformFunction
15295 * @api
15296 */
15297
15298
15299
15300
15301
15302let showCoordinateWarning = true;
15303
15304/**
15305 * @param {boolean} [disable = true] Disable console info about `useGeographic()`
15306 */
15307function disableCoordinateWarning(disable) {
15308  const hide = disable === undefined ? true : disable;
15309  showCoordinateWarning = !hide;
15310}
15311
15312/**
15313 * @param {Array<number>} input Input coordinate array.
15314 * @param {Array<number>} [output] Output array of coordinate values.
15315 * @param {number} [dimension] Dimension.
15316 * @return {Array<number>} Output coordinate array (new array, same coordinate
15317 *     values).
15318 */
15319function cloneTransform(input, output, dimension) {
15320  if (output !== undefined) {
15321    for (let i = 0, ii = input.length; i < ii; ++i) {
15322      output[i] = input[i];
15323    }
15324    output = output;
15325  } else {
15326    output = input.slice();
15327  }
15328  return output;
15329}
15330
15331/**
15332 * @param {Array<number>} input Input coordinate array.
15333 * @param {Array<number>} [output] Output array of coordinate values.
15334 * @param {number} [dimension] Dimension.
15335 * @return {Array<number>} Input coordinate array (same array as input).
15336 */
15337function identityTransform(input, output, dimension) {
15338  if (output !== undefined && input !== output) {
15339    for (let i = 0, ii = input.length; i < ii; ++i) {
15340      output[i] = input[i];
15341    }
15342    input = output;
15343  }
15344  return input;
15345}
15346
15347/**
15348 * Add a Projection object to the list of supported projections that can be
15349 * looked up by their code.
15350 *
15351 * @param {Projection} projection Projection instance.
15352 * @api
15353 */
15354function addProjection(projection) {
15355  add(projection.getCode(), projection);
15356  transforms_add(projection, projection, cloneTransform);
15357}
15358
15359/**
15360 * @param {Array<Projection>} projections Projections.
15361 */
15362function addProjections(projections) {
15363  projections.forEach(addProjection);
15364}
15365
15366/**
15367 * Fetches a Projection object for the code specified.
15368 *
15369 * @param {ProjectionLike} projectionLike Either a code string which is
15370 *     a combination of authority and identifier such as "EPSG:4326", or an
15371 *     existing projection object, or undefined.
15372 * @return {Projection|null} Projection object, or null if not in list.
15373 * @api
15374 */
15375function proj_get(projectionLike) {
15376  return typeof projectionLike === 'string'
15377    ? get(/** @type {string} */ (projectionLike))
15378    : /** @type {Projection} */ (projectionLike) || null;
15379}
15380
15381/**
15382 * Get the resolution of the point in degrees or distance units.
15383 * For projections with degrees as the unit this will simply return the
15384 * provided resolution. For other projections the point resolution is
15385 * by default estimated by transforming the `point` pixel to EPSG:4326,
15386 * measuring its width and height on the normal sphere,
15387 * and taking the average of the width and height.
15388 * A custom function can be provided for a specific projection, either
15389 * by setting the `getPointResolution` option in the
15390 * {@link module:ol/proj/Projection~Projection} constructor or by using
15391 * {@link module:ol/proj/Projection~Projection#setGetPointResolution} to change an existing
15392 * projection object.
15393 * @param {ProjectionLike} projection The projection.
15394 * @param {number} resolution Nominal resolution in projection units.
15395 * @param {import("./coordinate.js").Coordinate} point Point to find adjusted resolution at.
15396 * @param {import("./proj/Units.js").Units} [units] Units to get the point resolution in.
15397 * Default is the projection's units.
15398 * @return {number} Point resolution.
15399 * @api
15400 */
15401function getPointResolution(projection, resolution, point, units) {
15402  projection = proj_get(projection);
15403  let pointResolution;
15404  const getter = projection.getPointResolutionFunc();
15405  if (getter) {
15406    pointResolution = getter(resolution, point);
15407    if (units && units !== projection.getUnits()) {
15408      const metersPerUnit = projection.getMetersPerUnit();
15409      if (metersPerUnit) {
15410        pointResolution =
15411          (pointResolution * metersPerUnit) / Units_METERS_PER_UNIT[units];
15412      }
15413    }
15414  } else {
15415    const projUnits = projection.getUnits();
15416    if ((projUnits == 'degrees' && !units) || units == 'degrees') {
15417      pointResolution = resolution;
15418    } else {
15419      // Estimate point resolution by transforming the center pixel to EPSG:4326,
15420      // measuring its width and height on the normal sphere, and taking the
15421      // average of the width and height.
15422      const toEPSG4326 = getTransformFromProjections(
15423        projection,
15424        proj_get('EPSG:4326')
15425      );
15426      if (toEPSG4326 === identityTransform && projUnits !== 'degrees') {
15427        // no transform is available
15428        pointResolution = resolution * projection.getMetersPerUnit();
15429      } else {
15430        let vertices = [
15431          point[0] - resolution / 2,
15432          point[1],
15433          point[0] + resolution / 2,
15434          point[1],
15435          point[0],
15436          point[1] - resolution / 2,
15437          point[0],
15438          point[1] + resolution / 2,
15439        ];
15440        vertices = toEPSG4326(vertices, vertices, 2);
15441        const width = getDistance(vertices.slice(0, 2), vertices.slice(2, 4));
15442        const height = getDistance(vertices.slice(4, 6), vertices.slice(6, 8));
15443        pointResolution = (width + height) / 2;
15444      }
15445      const metersPerUnit = units
15446        ? Units_METERS_PER_UNIT[units]
15447        : projection.getMetersPerUnit();
15448      if (metersPerUnit !== undefined) {
15449        pointResolution /= metersPerUnit;
15450      }
15451    }
15452  }
15453  return pointResolution;
15454}
15455
15456/**
15457 * Registers transformation functions that don't alter coordinates. Those allow
15458 * to transform between projections with equal meaning.
15459 *
15460 * @param {Array<Projection>} projections Projections.
15461 * @api
15462 */
15463function addEquivalentProjections(projections) {
15464  addProjections(projections);
15465  projections.forEach(function (source) {
15466    projections.forEach(function (destination) {
15467      if (source !== destination) {
15468        transforms_add(source, destination, cloneTransform);
15469      }
15470    });
15471  });
15472}
15473
15474/**
15475 * Registers transformation functions to convert coordinates in any projection
15476 * in projection1 to any projection in projection2.
15477 *
15478 * @param {Array<Projection>} projections1 Projections with equal
15479 *     meaning.
15480 * @param {Array<Projection>} projections2 Projections with equal
15481 *     meaning.
15482 * @param {TransformFunction} forwardTransform Transformation from any
15483 *   projection in projection1 to any projection in projection2.
15484 * @param {TransformFunction} inverseTransform Transform from any projection
15485 *   in projection2 to any projection in projection1..
15486 */
15487function addEquivalentTransforms(
15488  projections1,
15489  projections2,
15490  forwardTransform,
15491  inverseTransform
15492) {
15493  projections1.forEach(function (projection1) {
15494    projections2.forEach(function (projection2) {
15495      transforms_add(projection1, projection2, forwardTransform);
15496      transforms_add(projection2, projection1, inverseTransform);
15497    });
15498  });
15499}
15500
15501/**
15502 * Clear all cached projections and transforms.
15503 */
15504function clearAllProjections() {
15505  clearProj();
15506  clearTransformFuncs();
15507}
15508
15509/**
15510 * @param {Projection|string|undefined} projection Projection.
15511 * @param {string} defaultCode Default code.
15512 * @return {Projection} Projection.
15513 */
15514function createProjection(projection, defaultCode) {
15515  if (!projection) {
15516    return proj_get(defaultCode);
15517  } else if (typeof projection === 'string') {
15518    return proj_get(projection);
15519  } else {
15520    return /** @type {Projection} */ (projection);
15521  }
15522}
15523
15524/**
15525 * Creates a {@link module:ol/proj~TransformFunction} from a simple 2D coordinate transform
15526 * function.
15527 * @param {function(import("./coordinate.js").Coordinate): import("./coordinate.js").Coordinate} coordTransform Coordinate
15528 *     transform.
15529 * @return {TransformFunction} Transform function.
15530 */
15531function createTransformFromCoordinateTransform(coordTransform) {
15532  return (
15533    /**
15534     * @param {Array<number>} input Input.
15535     * @param {Array<number>} [output] Output.
15536     * @param {number} [dimension] Dimension.
15537     * @return {Array<number>} Output.
15538     */
15539    function (input, output, dimension) {
15540      const length = input.length;
15541      dimension = dimension !== undefined ? dimension : 2;
15542      output = output !== undefined ? output : new Array(length);
15543      for (let i = 0; i < length; i += dimension) {
15544        const point = coordTransform(input.slice(i, i + dimension));
15545        const pointLength = point.length;
15546        for (let j = 0, jj = dimension; j < jj; ++j) {
15547          output[i + j] = j >= pointLength ? input[i + j] : point[j];
15548        }
15549      }
15550      return output;
15551    }
15552  );
15553}
15554
15555/**
15556 * Registers coordinate transform functions to convert coordinates between the
15557 * source projection and the destination projection.
15558 * The forward and inverse functions convert coordinate pairs; this function
15559 * converts these into the functions used internally which also handle
15560 * extents and coordinate arrays.
15561 *
15562 * @param {ProjectionLike} source Source projection.
15563 * @param {ProjectionLike} destination Destination projection.
15564 * @param {function(import("./coordinate.js").Coordinate): import("./coordinate.js").Coordinate} forward The forward transform
15565 *     function (that is, from the source projection to the destination
15566 *     projection) that takes a {@link module:ol/coordinate~Coordinate} as argument and returns
15567 *     the transformed {@link module:ol/coordinate~Coordinate}.
15568 * @param {function(import("./coordinate.js").Coordinate): import("./coordinate.js").Coordinate} inverse The inverse transform
15569 *     function (that is, from the destination projection to the source
15570 *     projection) that takes a {@link module:ol/coordinate~Coordinate} as argument and returns
15571 *     the transformed {@link module:ol/coordinate~Coordinate}. If the transform function can only
15572 *     transform less dimensions than the input coordinate, it is supposeed to return a coordinate
15573 *     with only the length it can transform. The other dimensions will be taken unchanged from the
15574 *     source.
15575 * @api
15576 */
15577function addCoordinateTransforms(source, destination, forward, inverse) {
15578  const sourceProj = proj_get(source);
15579  const destProj = proj_get(destination);
15580  addTransformFunc(
15581    sourceProj,
15582    destProj,
15583    createTransformFromCoordinateTransform(forward)
15584  );
15585  addTransformFunc(
15586    destProj,
15587    sourceProj,
15588    createTransformFromCoordinateTransform(inverse)
15589  );
15590}
15591
15592/**
15593 * Transforms a coordinate from longitude/latitude to a different projection.
15594 * @param {import("./coordinate.js").Coordinate} coordinate Coordinate as longitude and latitude, i.e.
15595 *     an array with longitude as 1st and latitude as 2nd element.
15596 * @param {ProjectionLike} [projection] Target projection. The
15597 *     default is Web Mercator, i.e. 'EPSG:3857'.
15598 * @return {import("./coordinate.js").Coordinate} Coordinate projected to the target projection.
15599 * @api
15600 */
15601function fromLonLat(coordinate, projection) {
15602  disableCoordinateWarning();
15603  return transform(
15604    coordinate,
15605    'EPSG:4326',
15606    projection !== undefined ? projection : 'EPSG:3857'
15607  );
15608}
15609
15610/**
15611 * Transforms a coordinate to longitude/latitude.
15612 * @param {import("./coordinate.js").Coordinate} coordinate Projected coordinate.
15613 * @param {ProjectionLike} [projection] Projection of the coordinate.
15614 *     The default is Web Mercator, i.e. 'EPSG:3857'.
15615 * @return {import("./coordinate.js").Coordinate} Coordinate as longitude and latitude, i.e. an array
15616 *     with longitude as 1st and latitude as 2nd element.
15617 * @api
15618 */
15619function toLonLat(coordinate, projection) {
15620  const lonLat = transform(
15621    coordinate,
15622    projection !== undefined ? projection : 'EPSG:3857',
15623    'EPSG:4326'
15624  );
15625  const lon = lonLat[0];
15626  if (lon < -180 || lon > 180) {
15627    lonLat[0] = math_modulo(lon + 180, 360) - 180;
15628  }
15629  return lonLat;
15630}
15631
15632/**
15633 * Checks if two projections are the same, that is every coordinate in one
15634 * projection does represent the same geographic point as the same coordinate in
15635 * the other projection.
15636 *
15637 * @param {Projection} projection1 Projection 1.
15638 * @param {Projection} projection2 Projection 2.
15639 * @return {boolean} Equivalent.
15640 * @api
15641 */
15642function equivalent(projection1, projection2) {
15643  if (projection1 === projection2) {
15644    return true;
15645  }
15646  const equalUnits = projection1.getUnits() === projection2.getUnits();
15647  if (projection1.getCode() === projection2.getCode()) {
15648    return equalUnits;
15649  } else {
15650    const transformFunc = getTransformFromProjections(projection1, projection2);
15651    return transformFunc === cloneTransform && equalUnits;
15652  }
15653}
15654
15655/**
15656 * Searches in the list of transform functions for the function for converting
15657 * coordinates from the source projection to the destination projection.
15658 *
15659 * @param {Projection} sourceProjection Source Projection object.
15660 * @param {Projection} destinationProjection Destination Projection
15661 *     object.
15662 * @return {TransformFunction} Transform function.
15663 */
15664function getTransformFromProjections(
15665  sourceProjection,
15666  destinationProjection
15667) {
15668  const sourceCode = sourceProjection.getCode();
15669  const destinationCode = destinationProjection.getCode();
15670  let transformFunc = transforms_get(sourceCode, destinationCode);
15671  if (!transformFunc) {
15672    transformFunc = identityTransform;
15673  }
15674  return transformFunc;
15675}
15676
15677/**
15678 * Given the projection-like objects, searches for a transformation
15679 * function to convert a coordinates array from the source projection to the
15680 * destination projection.
15681 *
15682 * @param {ProjectionLike} source Source.
15683 * @param {ProjectionLike} destination Destination.
15684 * @return {TransformFunction} Transform function.
15685 * @api
15686 */
15687function getTransform(source, destination) {
15688  const sourceProjection = proj_get(source);
15689  const destinationProjection = proj_get(destination);
15690  return getTransformFromProjections(sourceProjection, destinationProjection);
15691}
15692
15693/**
15694 * Transforms a coordinate from source projection to destination projection.
15695 * This returns a new coordinate (and does not modify the original).
15696 *
15697 * See {@link module:ol/proj.transformExtent} for extent transformation.
15698 * See the transform method of {@link module:ol/geom/Geometry~Geometry} and its
15699 * subclasses for geometry transforms.
15700 *
15701 * @param {import("./coordinate.js").Coordinate} coordinate Coordinate.
15702 * @param {ProjectionLike} source Source projection-like.
15703 * @param {ProjectionLike} destination Destination projection-like.
15704 * @return {import("./coordinate.js").Coordinate} Coordinate.
15705 * @api
15706 */
15707function transform(coordinate, source, destination) {
15708  const transformFunc = getTransform(source, destination);
15709  return transformFunc(coordinate, undefined, coordinate.length);
15710}
15711
15712/**
15713 * Transforms an extent from source projection to destination projection.  This
15714 * returns a new extent (and does not modify the original).
15715 *
15716 * @param {import("./extent.js").Extent} extent The extent to transform.
15717 * @param {ProjectionLike} source Source projection-like.
15718 * @param {ProjectionLike} destination Destination projection-like.
15719 * @param {number} [stops] Number of stops per side used for the transform.
15720 * By default only the corners are used.
15721 * @return {import("./extent.js").Extent} The transformed extent.
15722 * @api
15723 */
15724function proj_transformExtent(extent, source, destination, stops) {
15725  const transformFunc = getTransform(source, destination);
15726  return applyTransform(extent, transformFunc, undefined, stops);
15727}
15728
15729/**
15730 * Transforms the given point to the destination projection.
15731 *
15732 * @param {import("./coordinate.js").Coordinate} point Point.
15733 * @param {Projection} sourceProjection Source projection.
15734 * @param {Projection} destinationProjection Destination projection.
15735 * @return {import("./coordinate.js").Coordinate} Point.
15736 */
15737function transformWithProjections(
15738  point,
15739  sourceProjection,
15740  destinationProjection
15741) {
15742  const transformFunc = getTransformFromProjections(
15743    sourceProjection,
15744    destinationProjection
15745  );
15746  return transformFunc(point);
15747}
15748
15749/**
15750 * @type {Projection|null}
15751 */
15752let userProjection = null;
15753
15754/**
15755 * Set the projection for coordinates supplied from and returned by API methods.
15756 * This includes all API methods except for those interacting with tile grids.
15757 * @param {ProjectionLike} projection The user projection.
15758 * @api
15759 */
15760function setUserProjection(projection) {
15761  userProjection = proj_get(projection);
15762}
15763
15764/**
15765 * Clear the user projection if set.
15766 * @api
15767 */
15768function clearUserProjection() {
15769  userProjection = null;
15770}
15771
15772/**
15773 * Get the projection for coordinates supplied from and returned by API methods.
15774 * Note that this method is not yet a part of the stable API.  Support for user
15775 * projections is not yet complete and should be considered experimental.
15776 * @return {Projection|null} The user projection (or null if not set).
15777 * @api
15778 */
15779function getUserProjection() {
15780  return userProjection;
15781}
15782
15783/**
15784 * Use geographic coordinates (WGS-84 datum) in API methods.  This includes all API
15785 * methods except for those interacting with tile grids.
15786 * @api
15787 */
15788function useGeographic() {
15789  setUserProjection('EPSG:4326');
15790}
15791
15792/**
15793 * Return a coordinate transformed into the user projection.  If no user projection
15794 * is set, the original coordinate is returned.
15795 * @param {Array<number>} coordinate Input coordinate.
15796 * @param {ProjectionLike} sourceProjection The input coordinate projection.
15797 * @return {Array<number>} The input coordinate in the user projection.
15798 */
15799function toUserCoordinate(coordinate, sourceProjection) {
15800  if (!userProjection) {
15801    return coordinate;
15802  }
15803  return transform(coordinate, sourceProjection, userProjection);
15804}
15805
15806/**
15807 * Return a coordinate transformed from the user projection.  If no user projection
15808 * is set, the original coordinate is returned.
15809 * @param {Array<number>} coordinate Input coordinate.
15810 * @param {ProjectionLike} destProjection The destination projection.
15811 * @return {Array<number>} The input coordinate transformed.
15812 */
15813function fromUserCoordinate(coordinate, destProjection) {
15814  if (!userProjection) {
15815    if (
15816      showCoordinateWarning &&
15817      !coordinate_equals(coordinate, [0, 0]) &&
15818      coordinate[0] >= -180 &&
15819      coordinate[0] <= 180 &&
15820      coordinate[1] >= -90 &&
15821      coordinate[1] <= 90
15822    ) {
15823      showCoordinateWarning = false;
15824      // eslint-disable-next-line no-console
15825      console.warn(
15826        'Call useGeographic() from ol/proj once to work with [longitude, latitude] coordinates.'
15827      );
15828    }
15829    return coordinate;
15830  }
15831  return transform(coordinate, userProjection, destProjection);
15832}
15833
15834/**
15835 * Return an extent transformed into the user projection.  If no user projection
15836 * is set, the original extent is returned.
15837 * @param {import("./extent.js").Extent} extent Input extent.
15838 * @param {ProjectionLike} sourceProjection The input extent projection.
15839 * @return {import("./extent.js").Extent} The input extent in the user projection.
15840 */
15841function proj_toUserExtent(extent, sourceProjection) {
15842  if (!userProjection) {
15843    return extent;
15844  }
15845  return proj_transformExtent(extent, sourceProjection, userProjection);
15846}
15847
15848/**
15849 * Return an extent transformed from the user projection.  If no user projection
15850 * is set, the original extent is returned.
15851 * @param {import("./extent.js").Extent} extent Input extent.
15852 * @param {ProjectionLike} destProjection The destination projection.
15853 * @return {import("./extent.js").Extent} The input extent transformed.
15854 */
15855function proj_fromUserExtent(extent, destProjection) {
15856  if (!userProjection) {
15857    return extent;
15858  }
15859  return proj_transformExtent(extent, userProjection, destProjection);
15860}
15861
15862/**
15863 * Return the resolution in user projection units per pixel. If no user projection
15864 * is set, or source or user projection are missing units, the original resolution
15865 * is returned.
15866 * @param {number} resolution Resolution in input projection units per pixel.
15867 * @param {ProjectionLike} sourceProjection The input projection.
15868 * @return {number} Resolution in user projection units per pixel.
15869 */
15870function toUserResolution(resolution, sourceProjection) {
15871  if (!userProjection) {
15872    return resolution;
15873  }
15874  const sourceUnits = proj_get(sourceProjection).getUnits();
15875  const userUnits = userProjection.getUnits();
15876  return sourceUnits && userUnits
15877    ? (resolution * Units_METERS_PER_UNIT[sourceUnits]) / Units_METERS_PER_UNIT[userUnits]
15878    : resolution;
15879}
15880
15881/**
15882 * Return the resolution in user projection units per pixel. If no user projection
15883 * is set, or source or user projection are missing units, the original resolution
15884 * is returned.
15885 * @param {number} resolution Resolution in user projection units per pixel.
15886 * @param {ProjectionLike} destProjection The destination projection.
15887 * @return {number} Resolution in destination projection units per pixel.
15888 */
15889function proj_fromUserResolution(resolution, destProjection) {
15890  if (!userProjection) {
15891    return resolution;
15892  }
15893  const sourceUnits = proj_get(destProjection).getUnits();
15894  const userUnits = userProjection.getUnits();
15895  return sourceUnits && userUnits
15896    ? (resolution * METERS_PER_UNIT[userUnits]) / METERS_PER_UNIT[sourceUnits]
15897    : resolution;
15898}
15899
15900/**
15901 * Creates a safe coordinate transform function from a coordinate transform function.
15902 * "Safe" means that it can handle wrapping of x-coordinates for global projections,
15903 * and that coordinates exceeding the source projection validity extent's range will be
15904 * clamped to the validity range.
15905 * @param {Projection} sourceProj Source projection.
15906 * @param {Projection} destProj Destination projection.
15907 * @param {function(import("./coordinate.js").Coordinate): import("./coordinate.js").Coordinate} transform Transform function (source to destiation).
15908 * @return {function(import("./coordinate.js").Coordinate): import("./coordinate.js").Coordinate} Safe transform function (source to destiation).
15909 */
15910function createSafeCoordinateTransform(sourceProj, destProj, transform) {
15911  return function (coord) {
15912    let transformed, worldsAway;
15913    if (sourceProj.canWrapX()) {
15914      const sourceExtent = sourceProj.getExtent();
15915      const sourceExtentWidth = getWidth(sourceExtent);
15916      coord = coord.slice(0);
15917      worldsAway = getWorldsAway(coord, sourceProj, sourceExtentWidth);
15918      if (worldsAway) {
15919        // Move x to the real world
15920        coord[0] = coord[0] - worldsAway * sourceExtentWidth;
15921      }
15922      coord[0] = clamp(coord[0], sourceExtent[0], sourceExtent[2]);
15923      coord[1] = clamp(coord[1], sourceExtent[1], sourceExtent[3]);
15924      transformed = transform(coord);
15925    } else {
15926      transformed = transform(coord);
15927    }
15928    if (worldsAway && destProj.canWrapX()) {
15929      // Move transformed coordinate back to the offset world
15930      transformed[0] += worldsAway * getWidth(destProj.getExtent());
15931    }
15932    return transformed;
15933  };
15934}
15935
15936/**
15937 * Add transforms to and from EPSG:4326 and EPSG:3857.  This function is called
15938 * by when this module is executed and should only need to be called again after
15939 * `clearAllProjections()` is called (e.g. in tests).
15940 */
15941function addCommon() {
15942  // Add transformations that don't alter coordinates to convert within set of
15943  // projections with equal meaning.
15944  addEquivalentProjections(PROJECTIONS);
15945  addEquivalentProjections(epsg4326_PROJECTIONS);
15946  // Add transformations to convert EPSG:4326 like coordinates to EPSG:3857 like
15947  // coordinates and back.
15948  addEquivalentTransforms(
15949    epsg4326_PROJECTIONS,
15950    PROJECTIONS,
15951    fromEPSG4326,
15952    toEPSG4326
15953  );
15954}
15955
15956addCommon();
15957
15958;// CONCATENATED MODULE: ./node_modules/ol/centerconstraint.js
15959/**
15960 * @module ol/centerconstraint
15961 */
15962
15963
15964/**
15965 * @typedef {function((import("./coordinate.js").Coordinate|undefined), number, import("./size.js").Size, boolean=, Array<number>=): (import("./coordinate.js").Coordinate|undefined)} Type
15966 */
15967
15968/**
15969 * @param {import("./extent.js").Extent} extent Extent.
15970 * @param {boolean} onlyCenter If true, the constraint will only apply to the view center.
15971 * @param {boolean} smooth If true, the view will be able to go slightly out of the given extent
15972 * (only during interaction and animation).
15973 * @return {Type} The constraint.
15974 */
15975function createExtent(extent, onlyCenter, smooth) {
15976  return (
15977    /**
15978     * @param {import("./coordinate.js").Coordinate|undefined} center Center.
15979     * @param {number|undefined} resolution Resolution.
15980     * @param {import("./size.js").Size} size Viewport size; unused if `onlyCenter` was specified.
15981     * @param {boolean} [isMoving] True if an interaction or animation is in progress.
15982     * @param {Array<number>} [centerShift] Shift between map center and viewport center.
15983     * @return {import("./coordinate.js").Coordinate|undefined} Center.
15984     */
15985    function (center, resolution, size, isMoving, centerShift) {
15986      if (!center) {
15987        return undefined;
15988      }
15989      if (!resolution && !onlyCenter) {
15990        return center;
15991      }
15992      const viewWidth = onlyCenter ? 0 : size[0] * resolution;
15993      const viewHeight = onlyCenter ? 0 : size[1] * resolution;
15994      const shiftX = centerShift ? centerShift[0] : 0;
15995      const shiftY = centerShift ? centerShift[1] : 0;
15996      let minX = extent[0] + viewWidth / 2 + shiftX;
15997      let maxX = extent[2] - viewWidth / 2 + shiftX;
15998      let minY = extent[1] + viewHeight / 2 + shiftY;
15999      let maxY = extent[3] - viewHeight / 2 + shiftY;
16000
16001      // note: when zooming out of bounds, min and max values for x and y may
16002      // end up inverted (min > max); this has to be accounted for
16003      if (minX > maxX) {
16004        minX = (maxX + minX) / 2;
16005        maxX = minX;
16006      }
16007      if (minY > maxY) {
16008        minY = (maxY + minY) / 2;
16009        maxY = minY;
16010      }
16011
16012      let x = math_clamp(center[0], minX, maxX);
16013      let y = math_clamp(center[1], minY, maxY);
16014
16015      // during an interaction, allow some overscroll
16016      if (isMoving && smooth && resolution) {
16017        const ratio = 30 * resolution;
16018        x +=
16019          -ratio * Math.log(1 + Math.max(0, minX - center[0]) / ratio) +
16020          ratio * Math.log(1 + Math.max(0, center[0] - maxX) / ratio);
16021        y +=
16022          -ratio * Math.log(1 + Math.max(0, minY - center[1]) / ratio) +
16023          ratio * Math.log(1 + Math.max(0, center[1] - maxY) / ratio);
16024      }
16025
16026      return [x, y];
16027    }
16028  );
16029}
16030
16031/**
16032 * @param {import("./coordinate.js").Coordinate} [center] Center.
16033 * @return {import("./coordinate.js").Coordinate|undefined} Center.
16034 */
16035function none(center) {
16036  return center;
16037}
16038
16039;// CONCATENATED MODULE: ./node_modules/ol/resolutionconstraint.js
16040/**
16041 * @module ol/resolutionconstraint
16042 */
16043
16044
16045
16046
16047/**
16048 * @typedef {function((number|undefined), number, import("./size.js").Size, boolean=): (number|undefined)} Type
16049 */
16050
16051/**
16052 * Returns a modified resolution taking into account the viewport size and maximum
16053 * allowed extent.
16054 * @param {number} resolution Resolution
16055 * @param {import("./extent.js").Extent} maxExtent Maximum allowed extent.
16056 * @param {import("./size.js").Size} viewportSize Viewport size.
16057 * @param {boolean} showFullExtent Whether to show the full extent.
16058 * @return {number} Capped resolution.
16059 */
16060function getViewportClampedResolution(
16061  resolution,
16062  maxExtent,
16063  viewportSize,
16064  showFullExtent
16065) {
16066  const xResolution = extent_getWidth(maxExtent) / viewportSize[0];
16067  const yResolution = extent_getHeight(maxExtent) / viewportSize[1];
16068
16069  if (showFullExtent) {
16070    return Math.min(resolution, Math.max(xResolution, yResolution));
16071  }
16072  return Math.min(resolution, Math.min(xResolution, yResolution));
16073}
16074
16075/**
16076 * Returns a modified resolution to be between maxResolution and minResolution while
16077 * still allowing the value to be slightly out of bounds.
16078 * Note: the computation is based on the logarithm function (ln):
16079 *  - at 1, ln(x) is 0
16080 *  - above 1, ln(x) keeps increasing but at a much slower pace than x
16081 * The final result is clamped to prevent getting too far away from bounds.
16082 * @param {number} resolution Resolution.
16083 * @param {number} maxResolution Max resolution.
16084 * @param {number} minResolution Min resolution.
16085 * @return {number} Smoothed resolution.
16086 */
16087function getSmoothClampedResolution(resolution, maxResolution, minResolution) {
16088  let result = Math.min(resolution, maxResolution);
16089  const ratio = 50;
16090
16091  result *=
16092    Math.log(1 + ratio * Math.max(0, resolution / maxResolution - 1)) / ratio +
16093    1;
16094  if (minResolution) {
16095    result = Math.max(result, minResolution);
16096    result /=
16097      Math.log(1 + ratio * Math.max(0, minResolution / resolution - 1)) /
16098        ratio +
16099      1;
16100  }
16101  return math_clamp(result, minResolution / 2, maxResolution * 2);
16102}
16103
16104/**
16105 * @param {Array<number>} resolutions Resolutions.
16106 * @param {boolean} [smooth] If true, the view will be able to slightly exceed resolution limits. Default: true.
16107 * @param {import("./extent.js").Extent} [maxExtent] Maximum allowed extent.
16108 * @param {boolean} [showFullExtent] If true, allows us to show the full extent. Default: false.
16109 * @return {Type} Zoom function.
16110 */
16111function createSnapToResolutions(
16112  resolutions,
16113  smooth,
16114  maxExtent,
16115  showFullExtent
16116) {
16117  smooth = smooth !== undefined ? smooth : true;
16118  return (
16119    /**
16120     * @param {number|undefined} resolution Resolution.
16121     * @param {number} direction Direction.
16122     * @param {import("./size.js").Size} size Viewport size.
16123     * @param {boolean} [isMoving] True if an interaction or animation is in progress.
16124     * @return {number|undefined} Resolution.
16125     */
16126    function (resolution, direction, size, isMoving) {
16127      if (resolution !== undefined) {
16128        const maxResolution = resolutions[0];
16129        const minResolution = resolutions[resolutions.length - 1];
16130        const cappedMaxRes = maxExtent
16131          ? getViewportClampedResolution(
16132              maxResolution,
16133              maxExtent,
16134              size,
16135              showFullExtent
16136            )
16137          : maxResolution;
16138
16139        // during interacting or animating, allow intermediary values
16140        if (isMoving) {
16141          if (!smooth) {
16142            return math_clamp(resolution, minResolution, cappedMaxRes);
16143          }
16144          return getSmoothClampedResolution(
16145            resolution,
16146            cappedMaxRes,
16147            minResolution
16148          );
16149        }
16150
16151        const capped = Math.min(cappedMaxRes, resolution);
16152        const z = Math.floor(linearFindNearest(resolutions, capped, direction));
16153        if (resolutions[z] > cappedMaxRes && z < resolutions.length - 1) {
16154          return resolutions[z + 1];
16155        }
16156        return resolutions[z];
16157      } else {
16158        return undefined;
16159      }
16160    }
16161  );
16162}
16163
16164/**
16165 * @param {number} power Power.
16166 * @param {number} maxResolution Maximum resolution.
16167 * @param {number} [minResolution] Minimum resolution.
16168 * @param {boolean} [smooth] If true, the view will be able to slightly exceed resolution limits. Default: true.
16169 * @param {import("./extent.js").Extent} [maxExtent] Maximum allowed extent.
16170 * @param {boolean} [showFullExtent] If true, allows us to show the full extent. Default: false.
16171 * @return {Type} Zoom function.
16172 */
16173function createSnapToPower(
16174  power,
16175  maxResolution,
16176  minResolution,
16177  smooth,
16178  maxExtent,
16179  showFullExtent
16180) {
16181  smooth = smooth !== undefined ? smooth : true;
16182  minResolution = minResolution !== undefined ? minResolution : 0;
16183
16184  return (
16185    /**
16186     * @param {number|undefined} resolution Resolution.
16187     * @param {number} direction Direction.
16188     * @param {import("./size.js").Size} size Viewport size.
16189     * @param {boolean} [isMoving] True if an interaction or animation is in progress.
16190     * @return {number|undefined} Resolution.
16191     */
16192    function (resolution, direction, size, isMoving) {
16193      if (resolution !== undefined) {
16194        const cappedMaxRes = maxExtent
16195          ? getViewportClampedResolution(
16196              maxResolution,
16197              maxExtent,
16198              size,
16199              showFullExtent
16200            )
16201          : maxResolution;
16202
16203        // during interacting or animating, allow intermediary values
16204        if (isMoving) {
16205          if (!smooth) {
16206            return math_clamp(resolution, minResolution, cappedMaxRes);
16207          }
16208          return getSmoothClampedResolution(
16209            resolution,
16210            cappedMaxRes,
16211            minResolution
16212          );
16213        }
16214
16215        const tolerance = 1e-9;
16216        const minZoomLevel = Math.ceil(
16217          Math.log(maxResolution / cappedMaxRes) / Math.log(power) - tolerance
16218        );
16219        const offset = -direction * (0.5 - tolerance) + 0.5;
16220        const capped = Math.min(cappedMaxRes, resolution);
16221        const cappedZoomLevel = Math.floor(
16222          Math.log(maxResolution / capped) / Math.log(power) + offset
16223        );
16224        const zoomLevel = Math.max(minZoomLevel, cappedZoomLevel);
16225        const newResolution = maxResolution / Math.pow(power, zoomLevel);
16226        return math_clamp(newResolution, minResolution, cappedMaxRes);
16227      } else {
16228        return undefined;
16229      }
16230    }
16231  );
16232}
16233
16234/**
16235 * @param {number} maxResolution Max resolution.
16236 * @param {number} minResolution Min resolution.
16237 * @param {boolean} [smooth] If true, the view will be able to slightly exceed resolution limits. Default: true.
16238 * @param {import("./extent.js").Extent} [maxExtent] Maximum allowed extent.
16239 * @param {boolean} [showFullExtent] If true, allows us to show the full extent. Default: false.
16240 * @return {Type} Zoom function.
16241 */
16242function createMinMaxResolution(
16243  maxResolution,
16244  minResolution,
16245  smooth,
16246  maxExtent,
16247  showFullExtent
16248) {
16249  smooth = smooth !== undefined ? smooth : true;
16250
16251  return (
16252    /**
16253     * @param {number|undefined} resolution Resolution.
16254     * @param {number} direction Direction.
16255     * @param {import("./size.js").Size} size Viewport size.
16256     * @param {boolean} [isMoving] True if an interaction or animation is in progress.
16257     * @return {number|undefined} Resolution.
16258     */
16259    function (resolution, direction, size, isMoving) {
16260      if (resolution !== undefined) {
16261        const cappedMaxRes = maxExtent
16262          ? getViewportClampedResolution(
16263              maxResolution,
16264              maxExtent,
16265              size,
16266              showFullExtent
16267            )
16268          : maxResolution;
16269
16270        if (!smooth || !isMoving) {
16271          return math_clamp(resolution, minResolution, cappedMaxRes);
16272        }
16273        return getSmoothClampedResolution(
16274          resolution,
16275          cappedMaxRes,
16276          minResolution
16277        );
16278      } else {
16279        return undefined;
16280      }
16281    }
16282  );
16283}
16284
16285;// CONCATENATED MODULE: ./node_modules/ol/rotationconstraint.js
16286/**
16287 * @module ol/rotationconstraint
16288 */
16289
16290
16291/**
16292 * @typedef {function((number|undefined), boolean=): (number|undefined)} Type
16293 */
16294
16295/**
16296 * @param {number|undefined} rotation Rotation.
16297 * @return {number|undefined} Rotation.
16298 */
16299function disable(rotation) {
16300  if (rotation !== undefined) {
16301    return 0;
16302  } else {
16303    return undefined;
16304  }
16305}
16306
16307/**
16308 * @param {number|undefined} rotation Rotation.
16309 * @return {number|undefined} Rotation.
16310 */
16311function rotationconstraint_none(rotation) {
16312  if (rotation !== undefined) {
16313    return rotation;
16314  } else {
16315    return undefined;
16316  }
16317}
16318
16319/**
16320 * @param {number} n N.
16321 * @return {Type} Rotation constraint.
16322 */
16323function createSnapToN(n) {
16324  const theta = (2 * Math.PI) / n;
16325  return (
16326    /**
16327     * @param {number|undefined} rotation Rotation.
16328     * @param {boolean} [isMoving] True if an interaction or animation is in progress.
16329     * @return {number|undefined} Rotation.
16330     */
16331    function (rotation, isMoving) {
16332      if (isMoving) {
16333        return rotation;
16334      }
16335
16336      if (rotation !== undefined) {
16337        rotation = Math.floor(rotation / theta + 0.5) * theta;
16338        return rotation;
16339      } else {
16340        return undefined;
16341      }
16342    }
16343  );
16344}
16345
16346/**
16347 * @param {number} [tolerance] Tolerance.
16348 * @return {Type} Rotation constraint.
16349 */
16350function createSnapToZero(tolerance) {
16351  tolerance = tolerance || math_toRadians(5);
16352  return (
16353    /**
16354     * @param {number|undefined} rotation Rotation.
16355     * @param {boolean} [isMoving] True if an interaction or animation is in progress.
16356     * @return {number|undefined} Rotation.
16357     */
16358    function (rotation, isMoving) {
16359      if (isMoving) {
16360        return rotation;
16361      }
16362
16363      if (rotation !== undefined) {
16364        if (Math.abs(rotation) <= tolerance) {
16365          return 0;
16366        } else {
16367          return rotation;
16368        }
16369      } else {
16370        return undefined;
16371      }
16372    }
16373  );
16374}
16375
16376;// CONCATENATED MODULE: ./node_modules/ol/easing.js
16377/**
16378 * @module ol/easing
16379 */
16380
16381/**
16382 * Start slow and speed up.
16383 * @param {number} t Input between 0 and 1.
16384 * @return {number} Output between 0 and 1.
16385 * @api
16386 */
16387function easeIn(t) {
16388  return Math.pow(t, 3);
16389}
16390
16391/**
16392 * Start fast and slow down.
16393 * @param {number} t Input between 0 and 1.
16394 * @return {number} Output between 0 and 1.
16395 * @api
16396 */
16397function easeOut(t) {
16398  return 1 - easeIn(1 - t);
16399}
16400
16401/**
16402 * Start slow, speed up, and then slow down again.
16403 * @param {number} t Input between 0 and 1.
16404 * @return {number} Output between 0 and 1.
16405 * @api
16406 */
16407function inAndOut(t) {
16408  return 3 * t * t - 2 * t * t * t;
16409}
16410
16411/**
16412 * Maintain a constant speed over time.
16413 * @param {number} t Input between 0 and 1.
16414 * @return {number} Output between 0 and 1.
16415 * @api
16416 */
16417function linear(t) {
16418  return t;
16419}
16420
16421/**
16422 * Start slow, speed up, and at the very end slow down again.  This has the
16423 * same general behavior as {@link module:ol/easing.inAndOut}, but the final
16424 * slowdown is delayed.
16425 * @param {number} t Input between 0 and 1.
16426 * @return {number} Output between 0 and 1.
16427 * @api
16428 */
16429function upAndDown(t) {
16430  if (t < 0.5) {
16431    return inAndOut(2 * t);
16432  } else {
16433    return 1 - inAndOut(2 * (t - 0.5));
16434  }
16435}
16436
16437;// CONCATENATED MODULE: ./node_modules/ol/has.js
16438/**
16439 * @module ol/has
16440 */
16441
16442const ua =
16443  typeof navigator !== 'undefined' && typeof navigator.userAgent !== 'undefined'
16444    ? navigator.userAgent.toLowerCase()
16445    : '';
16446
16447/**
16448 * User agent string says we are dealing with Firefox as browser.
16449 * @type {boolean}
16450 */
16451const FIREFOX = ua.includes('firefox');
16452
16453/**
16454 * User agent string says we are dealing with Safari as browser.
16455 * @type {boolean}
16456 */
16457const SAFARI = ua.includes('safari') && !ua.includes('chrom');
16458
16459/**
16460 * https://bugs.webkit.org/show_bug.cgi?id=237906
16461 * @type {boolean}
16462 */
16463const SAFARI_BUG_237906 =
16464  SAFARI &&
16465  (ua.includes('version/15.4') ||
16466    /cpu (os|iphone os) 15_4 like mac os x/.test(ua));
16467
16468/**
16469 * User agent string says we are dealing with a WebKit engine.
16470 * @type {boolean}
16471 */
16472const WEBKIT = ua.includes('webkit') && !ua.includes('edge');
16473
16474/**
16475 * User agent string says we are dealing with a Mac as platform.
16476 * @type {boolean}
16477 */
16478const has_MAC = ua.includes('macintosh');
16479
16480/**
16481 * The ratio between physical pixels and device-independent pixels
16482 * (dips) on the device (`window.devicePixelRatio`).
16483 * @const
16484 * @type {number}
16485 * @api
16486 */
16487const DEVICE_PIXEL_RATIO =
16488  typeof devicePixelRatio !== 'undefined' ? devicePixelRatio : 1;
16489
16490/**
16491 * The execution context is a worker with OffscreenCanvas available.
16492 * @const
16493 * @type {boolean}
16494 */
16495const WORKER_OFFSCREEN_CANVAS =
16496  typeof WorkerGlobalScope !== 'undefined' &&
16497  typeof OffscreenCanvas !== 'undefined' &&
16498  self instanceof WorkerGlobalScope; //eslint-disable-line
16499
16500/**
16501 * Image.prototype.decode() is supported.
16502 * @type {boolean}
16503 */
16504const IMAGE_DECODE =
16505  typeof Image !== 'undefined' && Image.prototype.decode;
16506
16507/**
16508 * @type {boolean}
16509 */
16510const PASSIVE_EVENT_LISTENERS = (function () {
16511  let passive = false;
16512  try {
16513    const options = Object.defineProperty({}, 'passive', {
16514      get: function () {
16515        passive = true;
16516      },
16517    });
16518
16519    window.addEventListener('_', null, options);
16520    window.removeEventListener('_', null, options);
16521  } catch (error) {
16522    // passive not supported
16523  }
16524  return passive;
16525})();
16526
16527;// CONCATENATED MODULE: ./node_modules/ol/transform.js
16528/**
16529 * @module ol/transform
16530 */
16531
16532
16533
16534/**
16535 * An array representing an affine 2d transformation for use with
16536 * {@link module:ol/transform} functions. The array has 6 elements.
16537 * @typedef {!Array<number>} Transform
16538 * @api
16539 */
16540
16541/**
16542 * Collection of affine 2d transformation functions. The functions work on an
16543 * array of 6 elements. The element order is compatible with the [SVGMatrix
16544 * interface](https://developer.mozilla.org/en-US/docs/Web/API/SVGMatrix) and is
16545 * a subset (elements a to f) of a 3×3 matrix:
16546 * ```
16547 * [ a c e ]
16548 * [ b d f ]
16549 * [ 0 0 1 ]
16550 * ```
16551 */
16552
16553/**
16554 * @private
16555 * @type {Transform}
16556 */
16557const tmp_ = new Array(6);
16558
16559/**
16560 * Create an identity transform.
16561 * @return {!Transform} Identity transform.
16562 */
16563function create() {
16564  return [1, 0, 0, 1, 0, 0];
16565}
16566
16567/**
16568 * Resets the given transform to an identity transform.
16569 * @param {!Transform} transform Transform.
16570 * @return {!Transform} Transform.
16571 */
16572function transform_reset(transform) {
16573  return set(transform, 1, 0, 0, 1, 0, 0);
16574}
16575
16576/**
16577 * Multiply the underlying matrices of two transforms and return the result in
16578 * the first transform.
16579 * @param {!Transform} transform1 Transform parameters of matrix 1.
16580 * @param {!Transform} transform2 Transform parameters of matrix 2.
16581 * @return {!Transform} transform1 multiplied with transform2.
16582 */
16583function multiply(transform1, transform2) {
16584  const a1 = transform1[0];
16585  const b1 = transform1[1];
16586  const c1 = transform1[2];
16587  const d1 = transform1[3];
16588  const e1 = transform1[4];
16589  const f1 = transform1[5];
16590  const a2 = transform2[0];
16591  const b2 = transform2[1];
16592  const c2 = transform2[2];
16593  const d2 = transform2[3];
16594  const e2 = transform2[4];
16595  const f2 = transform2[5];
16596
16597  transform1[0] = a1 * a2 + c1 * b2;
16598  transform1[1] = b1 * a2 + d1 * b2;
16599  transform1[2] = a1 * c2 + c1 * d2;
16600  transform1[3] = b1 * c2 + d1 * d2;
16601  transform1[4] = a1 * e2 + c1 * f2 + e1;
16602  transform1[5] = b1 * e2 + d1 * f2 + f1;
16603
16604  return transform1;
16605}
16606
16607/**
16608 * Set the transform components a-f on a given transform.
16609 * @param {!Transform} transform Transform.
16610 * @param {number} a The a component of the transform.
16611 * @param {number} b The b component of the transform.
16612 * @param {number} c The c component of the transform.
16613 * @param {number} d The d component of the transform.
16614 * @param {number} e The e component of the transform.
16615 * @param {number} f The f component of the transform.
16616 * @return {!Transform} Matrix with transform applied.
16617 */
16618function set(transform, a, b, c, d, e, f) {
16619  transform[0] = a;
16620  transform[1] = b;
16621  transform[2] = c;
16622  transform[3] = d;
16623  transform[4] = e;
16624  transform[5] = f;
16625  return transform;
16626}
16627
16628/**
16629 * Set transform on one matrix from another matrix.
16630 * @param {!Transform} transform1 Matrix to set transform to.
16631 * @param {!Transform} transform2 Matrix to set transform from.
16632 * @return {!Transform} transform1 with transform from transform2 applied.
16633 */
16634function setFromArray(transform1, transform2) {
16635  transform1[0] = transform2[0];
16636  transform1[1] = transform2[1];
16637  transform1[2] = transform2[2];
16638  transform1[3] = transform2[3];
16639  transform1[4] = transform2[4];
16640  transform1[5] = transform2[5];
16641  return transform1;
16642}
16643
16644/**
16645 * Transforms the given coordinate with the given transform returning the
16646 * resulting, transformed coordinate. The coordinate will be modified in-place.
16647 *
16648 * @param {Transform} transform The transformation.
16649 * @param {import("./coordinate.js").Coordinate|import("./pixel.js").Pixel} coordinate The coordinate to transform.
16650 * @return {import("./coordinate.js").Coordinate|import("./pixel.js").Pixel} return coordinate so that operations can be
16651 *     chained together.
16652 */
16653function apply(transform, coordinate) {
16654  const x = coordinate[0];
16655  const y = coordinate[1];
16656  coordinate[0] = transform[0] * x + transform[2] * y + transform[4];
16657  coordinate[1] = transform[1] * x + transform[3] * y + transform[5];
16658  return coordinate;
16659}
16660
16661/**
16662 * Applies rotation to the given transform.
16663 * @param {!Transform} transform Transform.
16664 * @param {number} angle Angle in radians.
16665 * @return {!Transform} The rotated transform.
16666 */
16667function transform_rotate(transform, angle) {
16668  const cos = Math.cos(angle);
16669  const sin = Math.sin(angle);
16670  return multiply(transform, set(tmp_, cos, sin, -sin, cos, 0, 0));
16671}
16672
16673/**
16674 * Applies scale to a given transform.
16675 * @param {!Transform} transform Transform.
16676 * @param {number} x Scale factor x.
16677 * @param {number} y Scale factor y.
16678 * @return {!Transform} The scaled transform.
16679 */
16680function transform_scale(transform, x, y) {
16681  return multiply(transform, set(tmp_, x, 0, 0, y, 0, 0));
16682}
16683
16684/**
16685 * Creates a scale transform.
16686 * @param {!Transform} target Transform to overwrite.
16687 * @param {number} x Scale factor x.
16688 * @param {number} y Scale factor y.
16689 * @return {!Transform} The scale transform.
16690 */
16691function makeScale(target, x, y) {
16692  return set(target, x, 0, 0, y, 0, 0);
16693}
16694
16695/**
16696 * Applies translation to the given transform.
16697 * @param {!Transform} transform Transform.
16698 * @param {number} dx Translation x.
16699 * @param {number} dy Translation y.
16700 * @return {!Transform} The translated transform.
16701 */
16702function translate(transform, dx, dy) {
16703  return multiply(transform, set(tmp_, 1, 0, 0, 1, dx, dy));
16704}
16705
16706/**
16707 * Creates a composite transform given an initial translation, scale, rotation, and
16708 * final translation (in that order only, not commutative).
16709 * @param {!Transform} transform The transform (will be modified in place).
16710 * @param {number} dx1 Initial translation x.
16711 * @param {number} dy1 Initial translation y.
16712 * @param {number} sx Scale factor x.
16713 * @param {number} sy Scale factor y.
16714 * @param {number} angle Rotation (in counter-clockwise radians).
16715 * @param {number} dx2 Final translation x.
16716 * @param {number} dy2 Final translation y.
16717 * @return {!Transform} The composite transform.
16718 */
16719function compose(transform, dx1, dy1, sx, sy, angle, dx2, dy2) {
16720  const sin = Math.sin(angle);
16721  const cos = Math.cos(angle);
16722  transform[0] = sx * cos;
16723  transform[1] = sy * sin;
16724  transform[2] = -sx * sin;
16725  transform[3] = sy * cos;
16726  transform[4] = dx2 * sx * cos - dy2 * sx * sin + dx1;
16727  transform[5] = dx2 * sy * sin + dy2 * sy * cos + dy1;
16728  return transform;
16729}
16730
16731/**
16732 * Creates a composite transform given an initial translation, scale, rotation, and
16733 * final translation (in that order only, not commutative). The resulting transform
16734 * string can be applied as `transform` property of an HTMLElement's style.
16735 * @param {number} dx1 Initial translation x.
16736 * @param {number} dy1 Initial translation y.
16737 * @param {number} sx Scale factor x.
16738 * @param {number} sy Scale factor y.
16739 * @param {number} angle Rotation (in counter-clockwise radians).
16740 * @param {number} dx2 Final translation x.
16741 * @param {number} dy2 Final translation y.
16742 * @return {string} The composite css transform.
16743 * @api
16744 */
16745function composeCssTransform(dx1, dy1, sx, sy, angle, dx2, dy2) {
16746  return transform_toString(compose(create(), dx1, dy1, sx, sy, angle, dx2, dy2));
16747}
16748
16749/**
16750 * Invert the given transform.
16751 * @param {!Transform} source The source transform to invert.
16752 * @return {!Transform} The inverted (source) transform.
16753 */
16754function invert(source) {
16755  return makeInverse(source, source);
16756}
16757
16758/**
16759 * Invert the given transform.
16760 * @param {!Transform} target Transform to be set as the inverse of
16761 *     the source transform.
16762 * @param {!Transform} source The source transform to invert.
16763 * @return {!Transform} The inverted (target) transform.
16764 */
16765function makeInverse(target, source) {
16766  const det = determinant(source);
16767  asserts_assert(det !== 0, 32); // Transformation matrix cannot be inverted
16768
16769  const a = source[0];
16770  const b = source[1];
16771  const c = source[2];
16772  const d = source[3];
16773  const e = source[4];
16774  const f = source[5];
16775
16776  target[0] = d / det;
16777  target[1] = -b / det;
16778  target[2] = -c / det;
16779  target[3] = a / det;
16780  target[4] = (c * f - d * e) / det;
16781  target[5] = -(a * f - b * e) / det;
16782
16783  return target;
16784}
16785
16786/**
16787 * Returns the determinant of the given matrix.
16788 * @param {!Transform} mat Matrix.
16789 * @return {number} Determinant.
16790 */
16791function determinant(mat) {
16792  return mat[0] * mat[3] - mat[1] * mat[2];
16793}
16794
16795/**
16796 * @type {HTMLElement}
16797 * @private
16798 */
16799let transformStringDiv;
16800
16801/**
16802 * A rounded string version of the transform.  This can be used
16803 * for CSS transforms.
16804 * @param {!Transform} mat Matrix.
16805 * @return {string} The transform as a string.
16806 */
16807function transform_toString(mat) {
16808  const transformString = 'matrix(' + mat.join(', ') + ')';
16809  if (WORKER_OFFSCREEN_CANVAS) {
16810    return transformString;
16811  }
16812  const node =
16813    transformStringDiv || (transformStringDiv = document.createElement('div'));
16814  node.style.transform = transformString;
16815  return node.style.transform;
16816}
16817
16818;// CONCATENATED MODULE: ./node_modules/ol/geom/flat/transform.js
16819/**
16820 * @module ol/geom/flat/transform
16821 */
16822
16823/**
16824 * @param {Array<number>} flatCoordinates Flat coordinates.
16825 * @param {number} offset Offset.
16826 * @param {number} end End.
16827 * @param {number} stride Stride.
16828 * @param {import("../../transform.js").Transform} transform Transform.
16829 * @param {Array<number>} [dest] Destination.
16830 * @return {Array<number>} Transformed coordinates.
16831 */
16832function transform2D(
16833  flatCoordinates,
16834  offset,
16835  end,
16836  stride,
16837  transform,
16838  dest
16839) {
16840  dest = dest ? dest : [];
16841  let i = 0;
16842  for (let j = offset; j < end; j += stride) {
16843    const x = flatCoordinates[j];
16844    const y = flatCoordinates[j + 1];
16845    dest[i++] = transform[0] * x + transform[2] * y + transform[4];
16846    dest[i++] = transform[1] * x + transform[3] * y + transform[5];
16847  }
16848  if (dest && dest.length != i) {
16849    dest.length = i;
16850  }
16851  return dest;
16852}
16853
vendor: 9,004 bytes, lines 16854-17187
16854/**
16855 * @param {Array<number>} flatCoordinates Flat coordinates.
16856 * @param {number} offset Offset.
16857 * @param {number} end End.
16858 * @param {number} stride Stride.
16859 * @param {number} angle Angle.
16860 * @param {Array<number>} anchor Rotation anchor point.
16861 * @param {Array<number>} [dest] Destination.
16862 * @return {Array<number>} Transformed coordinates.
16863 */
16864function flat_transform_rotate(
16865  flatCoordinates,
16866  offset,
16867  end,
16868  stride,
16869  angle,
16870  anchor,
16871  dest
16872) {
16873  dest = dest ? dest : [];
16874  const cos = Math.cos(angle);
16875  const sin = Math.sin(angle);
16876  const anchorX = anchor[0];
16877  const anchorY = anchor[1];
16878  let i = 0;
16879  for (let j = offset; j < end; j += stride) {
16880    const deltaX = flatCoordinates[j] - anchorX;
16881    const deltaY = flatCoordinates[j + 1] - anchorY;
16882    dest[i++] = anchorX + deltaX * cos - deltaY * sin;
16883    dest[i++] = anchorY + deltaX * sin + deltaY * cos;
16884    for (let k = j + 2; k < j + stride; ++k) {
16885      dest[i++] = flatCoordinates[k];
16886    }
16887  }
16888  if (dest && dest.length != i) {
16889    dest.length = i;
16890  }
16891  return dest;
16892}
16893
16894/**
16895 * Scale the coordinates.
16896 * @param {Array<number>} flatCoordinates Flat coordinates.
16897 * @param {number} offset Offset.
16898 * @param {number} end End.
16899 * @param {number} stride Stride.
16900 * @param {number} sx Scale factor in the x-direction.
16901 * @param {number} sy Scale factor in the y-direction.
16902 * @param {Array<number>} anchor Scale anchor point.
16903 * @param {Array<number>} [dest] Destination.
16904 * @return {Array<number>} Transformed coordinates.
16905 */
16906function flat_transform_scale(
16907  flatCoordinates,
16908  offset,
16909  end,
16910  stride,
16911  sx,
16912  sy,
16913  anchor,
16914  dest
16915) {
16916  dest = dest ? dest : [];
16917  const anchorX = anchor[0];
16918  const anchorY = anchor[1];
16919  let i = 0;
16920  for (let j = offset; j < end; j += stride) {
16921    const deltaX = flatCoordinates[j] - anchorX;
16922    const deltaY = flatCoordinates[j + 1] - anchorY;
16923    dest[i++] = anchorX + sx * deltaX;
16924    dest[i++] = anchorY + sy * deltaY;
16925    for (let k = j + 2; k < j + stride; ++k) {
16926      dest[i++] = flatCoordinates[k];
16927    }
16928  }
16929  if (dest && dest.length != i) {
16930    dest.length = i;
16931  }
16932  return dest;
16933}
16934
16935/**
16936 * @param {Array<number>} flatCoordinates Flat coordinates.
16937 * @param {number} offset Offset.
16938 * @param {number} end End.
16939 * @param {number} stride Stride.
16940 * @param {number} deltaX Delta X.
16941 * @param {number} deltaY Delta Y.
16942 * @param {Array<number>} [dest] Destination.
16943 * @return {Array<number>} Transformed coordinates.
16944 */
16945function transform_translate(
16946  flatCoordinates,
16947  offset,
16948  end,
16949  stride,
16950  deltaX,
16951  deltaY,
16952  dest
16953) {
16954  dest = dest ? dest : [];
16955  let i = 0;
16956  for (let j = offset; j < end; j += stride) {
16957    dest[i++] = flatCoordinates[j] + deltaX;
16958    dest[i++] = flatCoordinates[j + 1] + deltaY;
16959    for (let k = j + 2; k < j + stride; ++k) {
16960      dest[i++] = flatCoordinates[k];
16961    }
16962  }
16963  if (dest && dest.length != i) {
16964    dest.length = i;
16965  }
16966  return dest;
16967}
16968
16969;// CONCATENATED MODULE: ./node_modules/ol/geom/Geometry.js
16970/**
16971 * @module ol/geom/Geometry
16972 */
16973
16974
16975
16976
16977
16978
16979
16980
16981/**
16982 * @typedef {'XY' | 'XYZ' | 'XYM' | 'XYZM'} GeometryLayout
16983 * The coordinate layout for geometries, indicating whether a 3rd or 4th z ('Z')
16984 * or measure ('M') coordinate is available.
16985 */
16986
16987/**
16988 * @typedef {'Point' | 'LineString' | 'LinearRing' | 'Polygon' | 'MultiPoint' | 'MultiLineString' | 'MultiPolygon' | 'GeometryCollection' | 'Circle'} Type
16989 * The geometry type.  One of `'Point'`, `'LineString'`, `'LinearRing'`,
16990 * `'Polygon'`, `'MultiPoint'`, `'MultiLineString'`, `'MultiPolygon'`,
16991 * `'GeometryCollection'`, or `'Circle'`.
16992 */
16993
16994/**
16995 * @type {import("../transform.js").Transform}
16996 */
16997const tmpTransform = create();
16998
16999/**
17000 * @classdesc
17001 * Abstract base class; normally only used for creating subclasses and not
17002 * instantiated in apps.
17003 * Base class for vector geometries.
17004 *
17005 * To get notified of changes to the geometry, register a listener for the
17006 * generic `change` event on your geometry instance.
17007 *
17008 * @abstract
17009 * @api
17010 */
17011class Geometry extends ol_Object {
17012  constructor() {
17013    super();
17014
17015    /**
17016     * @private
17017     * @type {import("../extent.js").Extent}
17018     */
17019    this.extent_ = createEmpty();
17020
17021    /**
17022     * @private
17023     * @type {number}
17024     */
17025    this.extentRevision_ = -1;
17026
17027    /**
17028     * @protected
17029     * @type {number}
17030     */
17031    this.simplifiedGeometryMaxMinSquaredTolerance = 0;
17032
17033    /**
17034     * @protected
17035     * @type {number}
17036     */
17037    this.simplifiedGeometryRevision = 0;
17038
17039    /**
17040     * Get a transformed and simplified version of the geometry.
17041     * @abstract
17042     * @param {number} revision The geometry revision.
17043     * @param {number} squaredTolerance Squared tolerance.
17044     * @param {import("../proj.js").TransformFunction} [transform] Optional transform function.
17045     * @return {Geometry} Simplified geometry.
17046     */
17047    this.simplifyTransformedInternal = memoizeOne(function (
17048      revision,
17049      squaredTolerance,
17050      transform
17051    ) {
17052      if (!transform) {
17053        return this.getSimplifiedGeometry(squaredTolerance);
17054      }
17055      const clone = this.clone();
17056      clone.applyTransform(transform);
17057      return clone.getSimplifiedGeometry(squaredTolerance);
17058    });
17059  }
17060
17061  /**
17062   * Get a transformed and simplified version of the geometry.
17063   * @abstract
17064   * @param {number} squaredTolerance Squared tolerance.
17065   * @param {import("../proj.js").TransformFunction} [transform] Optional transform function.
17066   * @return {Geometry} Simplified geometry.
17067   */
17068  simplifyTransformed(squaredTolerance, transform) {
17069    return this.simplifyTransformedInternal(
17070      this.getRevision(),
17071      squaredTolerance,
17072      transform
17073    );
17074  }
17075
17076  /**
17077   * Make a complete copy of the geometry.
17078   * @abstract
17079   * @return {!Geometry} Clone.
17080   */
17081  clone() {
17082    return util_abstract();
17083  }
17084
17085  /**
17086   * @abstract
17087   * @param {number} x X.
17088   * @param {number} y Y.
17089   * @param {import("../coordinate.js").Coordinate} closestPoint Closest point.
17090   * @param {number} minSquaredDistance Minimum squared distance.
17091   * @return {number} Minimum squared distance.
17092   */
17093  closestPointXY(x, y, closestPoint, minSquaredDistance) {
17094    return util_abstract();
17095  }
17096
17097  /**
17098   * @param {number} x X.
17099   * @param {number} y Y.
17100   * @return {boolean} Contains (x, y).
17101   */
17102  containsXY(x, y) {
17103    const coord = this.getClosestPoint([x, y]);
17104    return coord[0] === x && coord[1] === y;
17105  }
17106
17107  /**
17108   * Return the closest point of the geometry to the passed point as
17109   * {@link module:ol/coordinate~Coordinate coordinate}.
17110   * @param {import("../coordinate.js").Coordinate} point Point.
17111   * @param {import("../coordinate.js").Coordinate} [closestPoint] Closest point.
17112   * @return {import("../coordinate.js").Coordinate} Closest point.
17113   * @api
17114   */
17115  getClosestPoint(point, closestPoint) {
17116    closestPoint = closestPoint ? closestPoint : [NaN, NaN];
17117    this.closestPointXY(point[0], point[1], closestPoint, Infinity);
17118    return closestPoint;
17119  }
17120
17121  /**
17122   * Returns true if this geometry includes the specified coordinate. If the
17123   * coordinate is on the boundary of the geometry, returns false.
17124   * @param {import("../coordinate.js").Coordinate} coordinate Coordinate.
17125   * @return {boolean} Contains coordinate.
17126   * @api
17127   */
17128  intersectsCoordinate(coordinate) {
17129    return this.containsXY(coordinate[0], coordinate[1]);
17130  }
17131
17132  /**
17133   * @abstract
17134   * @param {import("../extent.js").Extent} extent Extent.
17135   * @protected
17136   * @return {import("../extent.js").Extent} extent Extent.
17137   */
17138  computeExtent(extent) {
17139    return util_abstract();
17140  }
17141
17142  /**
17143   * Get the extent of the geometry.
17144   * @param {import("../extent.js").Extent} [extent] Extent.
17145   * @return {import("../extent.js").Extent} extent Extent.
17146   * @api
17147   */
17148  getExtent(extent) {
17149    if (this.extentRevision_ != this.getRevision()) {
17150      const extent = this.computeExtent(this.extent_);
17151      if (isNaN(extent[0]) || isNaN(extent[1])) {
17152        createOrUpdateEmpty(extent);
17153      }
17154      this.extentRevision_ = this.getRevision();
17155    }
17156    return returnOrUpdate(this.extent_, extent);
17157  }
17158
17159  /**
17160   * Rotate the geometry around a given coordinate. This modifies the geometry
17161   * coordinates in place.
17162   * @abstract
17163   * @param {number} angle Rotation angle in radians.
17164   * @param {import("../coordinate.js").Coordinate} anchor The rotation center.
17165   * @api
17166   */
17167  rotate(angle, anchor) {
17168    util_abstract();
17169  }
17170
17171  /**
17172   * Scale the geometry (with an optional origin).  This modifies the geometry
17173   * coordinates in place.
17174   * @abstract
17175   * @param {number} sx The scaling factor in the x-direction.
17176   * @param {number} [sy] The scaling factor in the y-direction (defaults to sx).
17177   * @param {import("../coordinate.js").Coordinate} [anchor] The scale origin (defaults to the center
17178   *     of the geometry extent).
17179   * @api
17180   */
17181  scale(sx, sy, anchor) {
17182    util_abstract();
17183  }
17184
17185  /**
17186   * Create a simplified version of this geometry.  For linestrings, this uses
17187   * the [Douglas Peucker](https://en.wikipedia.org/wiki/Ramer-Douglas-Peucker_algorithm)
17188   * algorithm.  For polygons, a quantization-based
17189   * simplification is used to preserve topology.
17190   * @param {number} tolerance The tolerance distance for simplification.
17191   * @return {Geometry} A new, simplified version of the original geometry.
17192   * @api
17193   */
17194  simplify(tolerance) {
17195    return this.getSimplifiedGeometry(tolerance * tolerance);
17196  }
17197
17198  /**
17199   * Create a simplified version of this geometry using the Douglas Peucker
17200   * algorithm.
17201   * See https://en.wikipedia.org/wiki/Ramer-Douglas-Peucker_algorithm.
17202   * @abstract
17203   * @param {number} squaredTolerance Squared tolerance.
17204   * @return {Geometry} Simplified geometry.
17205   */
17206  getSimplifiedGeometry(squaredTolerance) {
17207    return util_abstract();
17208  }
17209
17210  /**
17211   * Get the type of this geometry.
17212   * @abstract
17213   * @return {Type} Geometry type.
17214   */
17215  getType() {
17216    return util_abstract();
17217  }
17218
17219  /**
17220   * Apply a transform function to the coordinates of the geometry.
17221   * The geometry is modified in place.
17222   * If you do not want the geometry modified in place, first `clone()` it and
17223   * then use this function on the clone.
17224   * @abstract
17225   * @param {import("../proj.js").TransformFunction} transformFn Transform function.
17226   * Called with a flat array of geometry coordinates.
17227   */
17228  applyTransform(transformFn) {
17229    util_abstract();
17230  }
17231
17232  /**
17233   * Test if the geometry and the passed extent intersect.
17234   * @abstract
17235   * @param {import("../extent.js").Extent} extent Extent.
17236   * @return {boolean} `true` if the geometry and the extent intersect.
17237   */
17238  intersectsExtent(extent) {
17239    return util_abstract();
17240  }
17241
17242  /**
17243   * Translate the geometry.  This modifies the geometry coordinates in place.  If
17244   * instead you want a new geometry, first `clone()` this geometry.
17245   * @abstract
17246   * @param {number} deltaX Delta X.
17247   * @param {number} deltaY Delta Y.
17248   * @api
17249   */
17250  translate(deltaX, deltaY) {
17251    util_abstract();
17252  }
17253
17254  /**
17255   * Transform each coordinate of the geometry from one coordinate reference
17256   * system to another. The geometry is modified in place.
17257   * For example, a line will be transformed to a line and a circle to a circle.
17258   * If you do not want the geometry modified in place, first `clone()` it and
17259   * then use this function on the clone.
17260   *
17261   * @param {import("../proj.js").ProjectionLike} source The current projection.  Can be a
17262   *     string identifier or a {@link module:ol/proj/Projection~Projection} object.
17263   * @param {import("../proj.js").ProjectionLike} destination The desired projection.  Can be a
17264   *     string identifier or a {@link module:ol/proj/Projection~Projection} object.
17265   * @return {Geometry} This geometry.  Note that original geometry is
17266   *     modified in place.
17267   * @api
17268   */
17269  transform(source, destination) {
17270    /** @type {import("../proj/Projection.js").default} */
17271    const sourceProj = proj_get(source);
17272    const transformFn =
17273      sourceProj.getUnits() == 'tile-pixels'
17274        ? function (inCoordinates, outCoordinates, stride) {
17275            const pixelExtent = sourceProj.getExtent();
17276            const projectedExtent = sourceProj.getWorldExtent();
17277            const scale = extent_getHeight(projectedExtent) / extent_getHeight(pixelExtent);
17278            compose(
17279              tmpTransform,
17280              projectedExtent[0],
17281              projectedExtent[3],
17282              scale,
17283              -scale,
17284              0,
17285              0,
17286              0
17287            );
17288            transform2D(
17289              inCoordinates,
17290              0,
17291              inCoordinates.length,
17292              stride,
17293              tmpTransform,
17294              outCoordinates
17295            );
17296            return getTransform(sourceProj, destination)(
17297              inCoordinates,
17298              outCoordinates,
17299              stride
17300            );
17301          }
17302        : getTransform(sourceProj, destination);
17303    this.applyTransform(transformFn);
17304    return this;
17305  }
17306}
17307
17308/* harmony default export */ const geom_Geometry = (Geometry);
17309
17310;// CONCATENATED MODULE: ./node_modules/ol/geom/SimpleGeometry.js
17311/**
17312 * @module ol/geom/SimpleGeometry
17313 */
17314
17315
17316
17317
17318
17319/**
17320 * @classdesc
17321 * Abstract base class; only used for creating subclasses; do not instantiate
17322 * in apps, as cannot be rendered.
17323 *
17324 * @abstract
17325 * @api
17326 */
17327class SimpleGeometry extends geom_Geometry {
17328  constructor() {
17329    super();
17330
17331    /**
17332     * @protected
17333     * @type {import("./Geometry.js").GeometryLayout}
17334     */
17335    this.layout = 'XY';
17336
17337    /**
17338     * @protected
17339     * @type {number}
17340     */
17341    this.stride = 2;
17342
17343    /**
17344     * @protected
17345     * @type {Array<number>}
17346     */
17347    this.flatCoordinates = null;
17348  }
17349
17350  /**
17351   * @param {import("../extent.js").Extent} extent Extent.
17352   * @protected
17353   * @return {import("../extent.js").Extent} extent Extent.
17354   */
17355  computeExtent(extent) {
17356    return createOrUpdateFromFlatCoordinates(
17357      this.flatCoordinates,
17358      0,
17359      this.flatCoordinates.length,
17360      this.stride,
17361      extent
17362    );
17363  }
17364
17365  /**
17366   * @abstract
17367   * @return {Array<*> | null} Coordinates.
17368   */
17369  getCoordinates() {
17370    return util_abstract();
17371  }
17372
17373  /**
17374   * Return the first coordinate of the geometry.
17375   * @return {import("../coordinate.js").Coordinate} First coordinate.
17376   * @api
17377   */
17378  getFirstCoordinate() {
17379    return this.flatCoordinates.slice(0, this.stride);
17380  }
17381
17382  /**
17383   * @return {Array<number>} Flat coordinates.
17384   */
17385  getFlatCoordinates() {
17386    return this.flatCoordinates;
17387  }
17388
17389  /**
17390   * Return the last coordinate of the geometry.
17391   * @return {import("../coordinate.js").Coordinate} Last point.
17392   * @api
17393   */
17394  getLastCoordinate() {
17395    return this.flatCoordinates.slice(
17396      this.flatCoordinates.length - this.stride
17397    );
17398  }
17399
17400  /**
17401   * Return the {@link import("./Geometry.js").GeometryLayout layout} of the geometry.
17402   * @return {import("./Geometry.js").GeometryLayout} Layout.
17403   * @api
17404   */
17405  getLayout() {
17406    return this.layout;
17407  }
17408
17409  /**
17410   * Create a simplified version of this geometry using the Douglas Peucker algorithm.
17411   * @param {number} squaredTolerance Squared tolerance.
17412   * @return {SimpleGeometry} Simplified geometry.
17413   */
17414  getSimplifiedGeometry(squaredTolerance) {
17415    if (this.simplifiedGeometryRevision !== this.getRevision()) {
17416      this.simplifiedGeometryMaxMinSquaredTolerance = 0;
17417      this.simplifiedGeometryRevision = this.getRevision();
17418    }
17419    // If squaredTolerance is negative or if we know that simplification will not
17420    // have any effect then just return this.
17421    if (
17422      squaredTolerance < 0 ||
17423      (this.simplifiedGeometryMaxMinSquaredTolerance !== 0 &&
17424        squaredTolerance <= this.simplifiedGeometryMaxMinSquaredTolerance)
17425    ) {
17426      return this;
17427    }
17428
17429    const simplifiedGeometry =
17430      this.getSimplifiedGeometryInternal(squaredTolerance);
17431    const simplifiedFlatCoordinates = simplifiedGeometry.getFlatCoordinates();
17432    if (simplifiedFlatCoordinates.length < this.flatCoordinates.length) {
17433      return simplifiedGeometry;
17434    } else {
17435      // Simplification did not actually remove any coordinates.  We now know
17436      // that any calls to getSimplifiedGeometry with a squaredTolerance less
17437      // than or equal to the current squaredTolerance will also not have any
17438      // effect.  This allows us to short circuit simplification (saving CPU
17439      // cycles) and prevents the cache of simplified geometries from filling
17440      // up with useless identical copies of this geometry (saving memory).
17441      this.simplifiedGeometryMaxMinSquaredTolerance = squaredTolerance;
17442      return this;
17443    }
17444  }
17445
17446  /**
17447   * @param {number} squaredTolerance Squared tolerance.
17448   * @return {SimpleGeometry} Simplified geometry.
17449   * @protected
17450   */
17451  getSimplifiedGeometryInternal(squaredTolerance) {
17452    return this;
17453  }
17454
17455  /**
17456   * @return {number} Stride.
17457   */
17458  getStride() {
17459    return this.stride;
17460  }
17461
17462  /**
17463   * @param {import("./Geometry.js").GeometryLayout} layout Layout.
17464   * @param {Array<number>} flatCoordinates Flat coordinates.
17465   */
17466  setFlatCoordinates(layout, flatCoordinates) {
17467    this.stride = getStrideForLayout(layout);
17468    this.layout = layout;
17469    this.flatCoordinates = flatCoordinates;
17470  }
17471
17472  /**
17473   * @abstract
17474   * @param {!Array<*>} coordinates Coordinates.
17475   * @param {import("./Geometry.js").GeometryLayout} [layout] Layout.
17476   */
17477  setCoordinates(coordinates, layout) {
17478    util_abstract();
17479  }
17480
17481  /**
17482   * @param {import("./Geometry.js").GeometryLayout|undefined} layout Layout.
17483   * @param {Array<*>} coordinates Coordinates.
17484   * @param {number} nesting Nesting.
17485   * @protected
17486   */
17487  setLayout(layout, coordinates, nesting) {
17488    /** @type {number} */
17489    let stride;
17490    if (layout) {
17491      stride = getStrideForLayout(layout);
17492    } else {
17493      for (let i = 0; i < nesting; ++i) {
17494        if (coordinates.length === 0) {
17495          this.layout = 'XY';
17496          this.stride = 2;
17497          return;
17498        } else {
17499          coordinates = /** @type {Array} */ (coordinates[0]);
17500        }
17501      }
17502      stride = coordinates.length;
17503      layout = getLayoutForStride(stride);
17504    }
17505    this.layout = layout;
17506    this.stride = stride;
17507  }
17508
17509  /**
17510   * Apply a transform function to the coordinates of the geometry.
17511   * The geometry is modified in place.
17512   * If you do not want the geometry modified in place, first `clone()` it and
17513   * then use this function on the clone.
17514   * @param {import("../proj.js").TransformFunction} transformFn Transform function.
17515   * Called with a flat array of geometry coordinates.
17516   * @api
17517   */
17518  applyTransform(transformFn) {
17519    if (this.flatCoordinates) {
17520      transformFn(this.flatCoordinates, this.flatCoordinates, this.stride);
17521      this.changed();
17522    }
17523  }
17524
17525  /**
17526   * Rotate the geometry around a given coordinate. This modifies the geometry
17527   * coordinates in place.
17528   * @param {number} angle Rotation angle in counter-clockwise radians.
17529   * @param {import("../coordinate.js").Coordinate} anchor The rotation center.
17530   * @api
17531   */
17532  rotate(angle, anchor) {
17533    const flatCoordinates = this.getFlatCoordinates();
17534    if (flatCoordinates) {
17535      const stride = this.getStride();
17536      flat_transform_rotate(
17537        flatCoordinates,
17538        0,
17539        flatCoordinates.length,
17540        stride,
17541        angle,
17542        anchor,
17543        flatCoordinates
17544      );
17545      this.changed();
17546    }
17547  }
17548
17549  /**
17550   * Scale the geometry (with an optional origin).  This modifies the geometry
17551   * coordinates in place.
17552   * @param {number} sx The scaling factor in the x-direction.
17553   * @param {number} [sy] The scaling factor in the y-direction (defaults to sx).
17554   * @param {import("../coordinate.js").Coordinate} [anchor] The scale origin (defaults to the center
17555   *     of the geometry extent).
17556   * @api
17557   */
17558  scale(sx, sy, anchor) {
17559    if (sy === undefined) {
17560      sy = sx;
17561    }
17562    if (!anchor) {
17563      anchor = getCenter(this.getExtent());
17564    }
17565    const flatCoordinates = this.getFlatCoordinates();
17566    if (flatCoordinates) {
17567      const stride = this.getStride();
17568      flat_transform_scale(
17569        flatCoordinates,
17570        0,
17571        flatCoordinates.length,
17572        stride,
17573        sx,
17574        sy,
17575        anchor,
17576        flatCoordinates
17577      );
17578      this.changed();
17579    }
17580  }
17581
17582  /**
17583   * Translate the geometry.  This modifies the geometry coordinates in place.  If
17584   * instead you want a new geometry, first `clone()` this geometry.
17585   * @param {number} deltaX Delta X.
17586   * @param {number} deltaY Delta Y.
17587   * @api
17588   */
17589  translate(deltaX, deltaY) {
17590    const flatCoordinates = this.getFlatCoordinates();
17591    if (flatCoordinates) {
17592      const stride = this.getStride();
17593      transform_translate(
17594        flatCoordinates,
17595        0,
17596        flatCoordinates.length,
17597        stride,
17598        deltaX,
17599        deltaY,
17600        flatCoordinates
17601      );
17602      this.changed();
17603    }
17604  }
17605}
17606
17607/**
17608 * @param {number} stride Stride.
17609 * @return {import("./Geometry.js").GeometryLayout} layout Layout.
17610 */
17611function getLayoutForStride(stride) {
17612  let layout;
17613  if (stride == 2) {
17614    layout = 'XY';
17615  } else if (stride == 3) {
17616    layout = 'XYZ';
17617  } else if (stride == 4) {
17618    layout = 'XYZM';
17619  }
17620  return /** @type {import("./Geometry.js").GeometryLayout} */ (layout);
17621}
17622
17623/**
17624 * @param {import("./Geometry.js").GeometryLayout} layout Layout.
17625 * @return {number} Stride.
17626 */
17627function getStrideForLayout(layout) {
17628  let stride;
17629  if (layout == 'XY') {
17630    stride = 2;
17631  } else if (layout == 'XYZ' || layout == 'XYM') {
17632    stride = 3;
17633  } else if (layout == 'XYZM') {
17634    stride = 4;
17635  }
17636  return /** @type {number} */ (stride);
17637}
17638
17639/**
17640 * @param {SimpleGeometry} simpleGeometry Simple geometry.
17641 * @param {import("../transform.js").Transform} transform Transform.
17642 * @param {Array<number>} [dest] Destination.
17643 * @return {Array<number>} Transformed flat coordinates.
17644 */
17645function transformGeom2D(simpleGeometry, transform, dest) {
17646  const flatCoordinates = simpleGeometry.getFlatCoordinates();
17647  if (!flatCoordinates) {
17648    return null;
17649  } else {
17650    const stride = simpleGeometry.getStride();
17651    return transform2D(
17652      flatCoordinates,
17653      0,
17654      flatCoordinates.length,
17655      stride,
17656      transform,
17657      dest
17658    );
17659  }
17660}
17661
17662/* harmony default export */ const geom_SimpleGeometry = (SimpleGeometry);
17663
17664;// CONCATENATED MODULE: ./node_modules/ol/geom/flat/closest.js
17665/**
17666 * @module ol/geom/flat/closest
17667 */
17668
17669
17670/**
17671 * Returns the point on the 2D line segment flatCoordinates[offset1] to
17672 * flatCoordinates[offset2] that is closest to the point (x, y).  Extra
17673 * dimensions are linearly interpolated.
17674 * @param {Array<number>} flatCoordinates Flat coordinates.
17675 * @param {number} offset1 Offset 1.
17676 * @param {number} offset2 Offset 2.
17677 * @param {number} stride Stride.
17678 * @param {number} x X.
17679 * @param {number} y Y.
17680 * @param {Array<number>} closestPoint Closest point.
17681 */
17682function assignClosest(
17683  flatCoordinates,
17684  offset1,
17685  offset2,
17686  stride,
17687  x,
17688  y,
17689  closestPoint
17690) {
17691  const x1 = flatCoordinates[offset1];
17692  const y1 = flatCoordinates[offset1 + 1];
17693  const dx = flatCoordinates[offset2] - x1;
17694  const dy = flatCoordinates[offset2 + 1] - y1;
17695  let offset;
17696  if (dx === 0 && dy === 0) {
17697    offset = offset1;
17698  } else {
17699    const t = ((x - x1) * dx + (y - y1) * dy) / (dx * dx + dy * dy);
17700    if (t > 1) {
17701      offset = offset2;
17702    } else if (t > 0) {
17703      for (let i = 0; i < stride; ++i) {
17704        closestPoint[i] = lerp(
17705          flatCoordinates[offset1 + i],
17706          flatCoordinates[offset2 + i],
17707          t
17708        );
17709      }
17710      closestPoint.length = stride;
17711      return;
17712    } else {
17713      offset = offset1;
17714    }
17715  }
17716  for (let i = 0; i < stride; ++i) {
17717    closestPoint[i] = flatCoordinates[offset + i];
17718  }
17719  closestPoint.length = stride;
17720}
17721
17722/**
17723 * Return the squared of the largest distance between any pair of consecutive
17724 * coordinates.
17725 * @param {Array<number>} flatCoordinates Flat coordinates.
17726 * @param {number} offset Offset.
17727 * @param {number} end End.
17728 * @param {number} stride Stride.
17729 * @param {number} max Max squared delta.
17730 * @return {number} Max squared delta.
17731 */
17732function maxSquaredDelta(flatCoordinates, offset, end, stride, max) {
17733  let x1 = flatCoordinates[offset];
17734  let y1 = flatCoordinates[offset + 1];
17735  for (offset += stride; offset < end; offset += stride) {
17736    const x2 = flatCoordinates[offset];
17737    const y2 = flatCoordinates[offset + 1];
17738    const squaredDelta = math_squaredDistance(x1, y1, x2, y2);
17739    if (squaredDelta > max) {
17740      max = squaredDelta;
17741    }
17742    x1 = x2;
17743    y1 = y2;
17744  }
17745  return max;
17746}
17747
17748/**
17749 * @param {Array<number>} flatCoordinates Flat coordinates.
17750 * @param {number} offset Offset.
17751 * @param {Array<number>} ends Ends.
17752 * @param {number} stride Stride.
17753 * @param {number} max Max squared delta.
17754 * @return {number} Max squared delta.
17755 */
17756function arrayMaxSquaredDelta(
17757  flatCoordinates,
17758  offset,
17759  ends,
17760  stride,
17761  max
17762) {
17763  for (let i = 0, ii = ends.length; i < ii; ++i) {
17764    const end = ends[i];
17765    max = maxSquaredDelta(flatCoordinates, offset, end, stride, max);
17766    offset = end;
17767  }
17768  return max;
17769}
17770
17771/**
17772 * @param {Array<number>} flatCoordinates Flat coordinates.
17773 * @param {number} offset Offset.
17774 * @param {Array<Array<number>>} endss Endss.
17775 * @param {number} stride Stride.
17776 * @param {number} max Max squared delta.
17777 * @return {number} Max squared delta.
17778 */
17779function multiArrayMaxSquaredDelta(
17780  flatCoordinates,
17781  offset,
17782  endss,
17783  stride,
17784  max
17785) {
17786  for (let i = 0, ii = endss.length; i < ii; ++i) {
17787    const ends = endss[i];
17788    max = arrayMaxSquaredDelta(flatCoordinates, offset, ends, stride, max);
17789    offset = ends[ends.length - 1];
17790  }
17791  return max;
17792}
17793
17794/**
17795 * @param {Array<number>} flatCoordinates Flat coordinates.
17796 * @param {number} offset Offset.
17797 * @param {number} end End.
17798 * @param {number} stride Stride.
17799 * @param {number} maxDelta Max delta.
17800 * @param {boolean} isRing Is ring.
17801 * @param {number} x X.
17802 * @param {number} y Y.
17803 * @param {Array<number>} closestPoint Closest point.
17804 * @param {number} minSquaredDistance Minimum squared distance.
17805 * @param {Array<number>} [tmpPoint] Temporary point object.
17806 * @return {number} Minimum squared distance.
17807 */
17808function assignClosestPoint(
17809  flatCoordinates,
17810  offset,
17811  end,
17812  stride,
17813  maxDelta,
17814  isRing,
17815  x,
17816  y,
17817  closestPoint,
17818  minSquaredDistance,
17819  tmpPoint
17820) {
17821  if (offset == end) {
17822    return minSquaredDistance;
17823  }
17824  let i, squaredDistance;
17825  if (maxDelta === 0) {
17826    // All points are identical, so just test the first point.
17827    squaredDistance = math_squaredDistance(
17828      x,
17829      y,
17830      flatCoordinates[offset],
17831      flatCoordinates[offset + 1]
17832    );
17833    if (squaredDistance < minSquaredDistance) {
17834      for (i = 0; i < stride; ++i) {
17835        closestPoint[i] = flatCoordinates[offset + i];
17836      }
17837      closestPoint.length = stride;
17838      return squaredDistance;
17839    } else {
17840      return minSquaredDistance;
17841    }
17842  }
17843  tmpPoint = tmpPoint ? tmpPoint : [NaN, NaN];
17844  let index = offset + stride;
17845  while (index < end) {
17846    assignClosest(
17847      flatCoordinates,
17848      index - stride,
17849      index,
17850      stride,
17851      x,
17852      y,
17853      tmpPoint
17854    );
17855    squaredDistance = math_squaredDistance(x, y, tmpPoint[0], tmpPoint[1]);
17856    if (squaredDistance < minSquaredDistance) {
17857      minSquaredDistance = squaredDistance;
17858      for (i = 0; i < stride; ++i) {
17859        closestPoint[i] = tmpPoint[i];
17860      }
17861      closestPoint.length = stride;
17862      index += stride;
17863    } else {
17864      // Skip ahead multiple points, because we know that all the skipped
17865      // points cannot be any closer than the closest point we have found so
17866      // far.  We know this because we know how close the current point is, how
17867      // close the closest point we have found so far is, and the maximum
17868      // distance between consecutive points.  For example, if we're currently
17869      // at distance 10, the best we've found so far is 3, and that the maximum
17870      // distance between consecutive points is 2, then we'll need to skip at
17871      // least (10 - 3) / 2 == 3 (rounded down) points to have any chance of
17872      // finding a closer point.  We use Math.max(..., 1) to ensure that we
17873      // always advance at least one point, to avoid an infinite loop.
17874      index +=
17875        stride *
17876        Math.max(
17877          ((Math.sqrt(squaredDistance) - Math.sqrt(minSquaredDistance)) /
17878            maxDelta) |
17879            0,
17880          1
17881        );
17882    }
17883  }
17884  if (isRing) {
17885    // Check the closing segment.
17886    assignClosest(
17887      flatCoordinates,
17888      end - stride,
17889      offset,
17890      stride,
17891      x,
17892      y,
17893      tmpPoint
17894    );
17895    squaredDistance = math_squaredDistance(x, y, tmpPoint[0], tmpPoint[1]);
17896    if (squaredDistance < minSquaredDistance) {
17897      minSquaredDistance = squaredDistance;
17898      for (i = 0; i < stride; ++i) {
17899        closestPoint[i] = tmpPoint[i];
17900      }
17901      closestPoint.length = stride;
17902    }
17903  }
17904  return minSquaredDistance;
17905}
17906
17907/**
17908 * @param {Array<number>} flatCoordinates Flat coordinates.
17909 * @param {number} offset Offset.
17910 * @param {Array<number>} ends Ends.
17911 * @param {number} stride Stride.
17912 * @param {number} maxDelta Max delta.
17913 * @param {boolean} isRing Is ring.
17914 * @param {number} x X.
17915 * @param {number} y Y.
17916 * @param {Array<number>} closestPoint Closest point.
17917 * @param {number} minSquaredDistance Minimum squared distance.
17918 * @param {Array<number>} [tmpPoint] Temporary point object.
17919 * @return {number} Minimum squared distance.
17920 */
17921function assignClosestArrayPoint(
17922  flatCoordinates,
17923  offset,
17924  ends,
17925  stride,
17926  maxDelta,
17927  isRing,
17928  x,
17929  y,
17930  closestPoint,
17931  minSquaredDistance,
17932  tmpPoint
17933) {
17934  tmpPoint = tmpPoint ? tmpPoint : [NaN, NaN];
17935  for (let i = 0, ii = ends.length; i < ii; ++i) {
17936    const end = ends[i];
17937    minSquaredDistance = assignClosestPoint(
17938      flatCoordinates,
17939      offset,
17940      end,
vendor: 5,110 bytes, lines 17941-18132
17941      stride,
17942      maxDelta,
17943      isRing,
17944      x,
17945      y,
17946      closestPoint,
17947      minSquaredDistance,
17948      tmpPoint
17949    );
17950    offset = end;
17951  }
17952  return minSquaredDistance;
17953}
17954
17955/**
17956 * @param {Array<number>} flatCoordinates Flat coordinates.
17957 * @param {number} offset Offset.
17958 * @param {Array<Array<number>>} endss Endss.
17959 * @param {number} stride Stride.
17960 * @param {number} maxDelta Max delta.
17961 * @param {boolean} isRing Is ring.
17962 * @param {number} x X.
17963 * @param {number} y Y.
17964 * @param {Array<number>} closestPoint Closest point.
17965 * @param {number} minSquaredDistance Minimum squared distance.
17966 * @param {Array<number>} [tmpPoint] Temporary point object.
17967 * @return {number} Minimum squared distance.
17968 */
17969function assignClosestMultiArrayPoint(
17970  flatCoordinates,
17971  offset,
17972  endss,
17973  stride,
17974  maxDelta,
17975  isRing,
17976  x,
17977  y,
17978  closestPoint,
17979  minSquaredDistance,
17980  tmpPoint
17981) {
17982  tmpPoint = tmpPoint ? tmpPoint : [NaN, NaN];
17983  for (let i = 0, ii = endss.length; i < ii; ++i) {
17984    const ends = endss[i];
17985    minSquaredDistance = assignClosestArrayPoint(
17986      flatCoordinates,
17987      offset,
17988      ends,
17989      stride,
17990      maxDelta,
17991      isRing,
17992      x,
17993      y,
17994      closestPoint,
17995      minSquaredDistance,
17996      tmpPoint
17997    );
17998    offset = ends[ends.length - 1];
17999  }
18000  return minSquaredDistance;
18001}
18002
18003;// CONCATENATED MODULE: ./node_modules/ol/geom/flat/deflate.js
18004/**
18005 * @module ol/geom/flat/deflate
18006 */
18007
18008/**
18009 * @param {Array<number>} flatCoordinates Flat coordinates.
18010 * @param {number} offset Offset.
18011 * @param {import("../../coordinate.js").Coordinate} coordinate Coordinate.
18012 * @param {number} stride Stride.
18013 * @return {number} offset Offset.
18014 */
18015function deflateCoordinate(flatCoordinates, offset, coordinate, stride) {
18016  for (let i = 0, ii = coordinate.length; i < ii; ++i) {
18017    flatCoordinates[offset++] = coordinate[i];
18018  }
18019  return offset;
18020}
18021
18022/**
18023 * @param {Array<number>} flatCoordinates Flat coordinates.
18024 * @param {number} offset Offset.
18025 * @param {Array<import("../../coordinate.js").Coordinate>} coordinates Coordinates.
18026 * @param {number} stride Stride.
18027 * @return {number} offset Offset.
18028 */
18029function deflateCoordinates(
18030  flatCoordinates,
18031  offset,
18032  coordinates,
18033  stride
18034) {
18035  for (let i = 0, ii = coordinates.length; i < ii; ++i) {
18036    const coordinate = coordinates[i];
18037    for (let j = 0; j < stride; ++j) {
18038      flatCoordinates[offset++] = coordinate[j];
18039    }
18040  }
18041  return offset;
18042}
18043
18044/**
18045 * @param {Array<number>} flatCoordinates Flat coordinates.
18046 * @param {number} offset Offset.
18047 * @param {Array<Array<import("../../coordinate.js").Coordinate>>} coordinatess Coordinatess.
18048 * @param {number} stride Stride.
18049 * @param {Array<number>} [ends] Ends.
18050 * @return {Array<number>} Ends.
18051 */
18052function deflateCoordinatesArray(
18053  flatCoordinates,
18054  offset,
18055  coordinatess,
18056  stride,
18057  ends
18058) {
18059  ends = ends ? ends : [];
18060  let i = 0;
18061  for (let j = 0, jj = coordinatess.length; j < jj; ++j) {
18062    const end = deflateCoordinates(
18063      flatCoordinates,
18064      offset,
18065      coordinatess[j],
18066      stride
18067    );
18068    ends[i++] = end;
18069    offset = end;
18070  }
18071  ends.length = i;
18072  return ends;
18073}
18074
18075/**
18076 * @param {Array<number>} flatCoordinates Flat coordinates.
18077 * @param {number} offset Offset.
18078 * @param {Array<Array<Array<import("../../coordinate.js").Coordinate>>>} coordinatesss Coordinatesss.
18079 * @param {number} stride Stride.
18080 * @param {Array<Array<number>>} [endss] Endss.
18081 * @return {Array<Array<number>>} Endss.
18082 */
18083function deflateMultiCoordinatesArray(
18084  flatCoordinates,
18085  offset,
18086  coordinatesss,
18087  stride,
18088  endss
18089) {
18090  endss = endss ? endss : [];
18091  let i = 0;
18092  for (let j = 0, jj = coordinatesss.length; j < jj; ++j) {
18093    const ends = deflateCoordinatesArray(
18094      flatCoordinates,
18095      offset,
18096      coordinatesss[j],
18097      stride,
18098      endss[i]
18099    );
18100    if (ends.length === 0) {
18101      ends[0] = offset;
18102    }
18103    endss[i++] = ends;
18104    offset = ends[ends.length - 1];
18105  }
18106  endss.length = i;
18107  return endss;
18108}
18109
18110;// CONCATENATED MODULE: ./node_modules/ol/geom/flat/simplify.js
18111/**
18112 * @module ol/geom/flat/simplify
18113 */
18114// Based on simplify-js https://github.com/mourner/simplify-js
18115// Copyright (c) 2012, Vladimir Agafonkin
18116// All rights reserved.
18117//
18118// Redistribution and use in source and binary forms, with or without
18119// modification, are permitted provided that the following conditions are met:
18120//
18121//    1. Redistributions of source code must retain the above copyright notice,
18122//       this list of conditions and the following disclaimer.
18123//
18124//    2. Redistributions in binary form must reproduce the above copyright
18125//       notice, this list of conditions and the following disclaimer in the
18126//       documentation and/or other materials provided with the distribution.
18127//
18128// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18129// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18130// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18131// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
18132// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18133// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
18134// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
18135// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
18136// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
18137// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
18138// POSSIBILITY OF SUCH DAMAGE.
18139
18140
18141
18142/**
18143 * @param {Array<number>} flatCoordinates Flat coordinates.
18144 * @param {number} offset Offset.
18145 * @param {number} end End.
18146 * @param {number} stride Stride.
18147 * @param {number} squaredTolerance Squared tolerance.
18148 * @param {boolean} highQuality Highest quality.
18149 * @param {Array<number>} [simplifiedFlatCoordinates] Simplified flat
18150 *     coordinates.
18151 * @return {Array<number>} Simplified line string.
18152 */
18153function simplifyLineString(
18154  flatCoordinates,
18155  offset,
18156  end,
18157  stride,
18158  squaredTolerance,
18159  highQuality,
18160  simplifiedFlatCoordinates
18161) {
18162  simplifiedFlatCoordinates =
18163    simplifiedFlatCoordinates !== undefined ? simplifiedFlatCoordinates : [];
18164  if (!highQuality) {
18165    end = radialDistance(
18166      flatCoordinates,
18167      offset,
18168      end,
18169      stride,
18170      squaredTolerance,
18171      simplifiedFlatCoordinates,
18172      0
18173    );
18174    flatCoordinates = simplifiedFlatCoordinates;
18175    offset = 0;
18176    stride = 2;
18177  }
18178  simplifiedFlatCoordinates.length = douglasPeucker(
18179    flatCoordinates,
18180    offset,
18181    end,
18182    stride,
18183    squaredTolerance,
18184    simplifiedFlatCoordinates,
18185    0
18186  );
18187  return simplifiedFlatCoordinates;
18188}
18189
18190/**
18191 * @param {Array<number>} flatCoordinates Flat coordinates.
18192 * @param {number} offset Offset.
18193 * @param {number} end End.
18194 * @param {number} stride Stride.
18195 * @param {number} squaredTolerance Squared tolerance.
18196 * @param {Array<number>} simplifiedFlatCoordinates Simplified flat
18197 *     coordinates.
18198 * @param {number} simplifiedOffset Simplified offset.
18199 * @return {number} Simplified offset.
18200 */
18201function douglasPeucker(
18202  flatCoordinates,
18203  offset,
18204  end,
18205  stride,
18206  squaredTolerance,
18207  simplifiedFlatCoordinates,
18208  simplifiedOffset
18209) {
18210  const n = (end - offset) / stride;
18211  if (n < 3) {
18212    for (; offset < end; offset += stride) {
18213      simplifiedFlatCoordinates[simplifiedOffset++] = flatCoordinates[offset];
18214      simplifiedFlatCoordinates[simplifiedOffset++] =
18215        flatCoordinates[offset + 1];
18216    }
18217    return simplifiedOffset;
18218  }
18219  /** @type {Array<number>} */
18220  const markers = new Array(n);
18221  markers[0] = 1;
18222  markers[n - 1] = 1;
18223  /** @type {Array<number>} */
18224  const stack = [offset, end - stride];
18225  let index = 0;
18226  while (stack.length > 0) {
18227    const last = stack.pop();
18228    const first = stack.pop();
18229    let maxSquaredDistance = 0;
18230    const x1 = flatCoordinates[first];
18231    const y1 = flatCoordinates[first + 1];
18232    const x2 = flatCoordinates[last];
18233    const y2 = flatCoordinates[last + 1];
18234    for (let i = first + stride; i < last; i += stride) {
18235      const x = flatCoordinates[i];
18236      const y = flatCoordinates[i + 1];
18237      const squaredDistance = squaredSegmentDistance(x, y, x1, y1, x2, y2);
18238      if (squaredDistance > maxSquaredDistance) {
18239        index = i;
18240        maxSquaredDistance = squaredDistance;
18241      }
18242    }
18243    if (maxSquaredDistance > squaredTolerance) {
18244      markers[(index - offset) / stride] = 1;
18245      if (first + stride < index) {
18246        stack.push(first, index);
18247      }
18248      if (index + stride < last) {
18249        stack.push(index, last);
18250      }
18251    }
18252  }
18253  for (let i = 0; i < n; ++i) {
18254    if (markers[i]) {
18255      simplifiedFlatCoordinates[simplifiedOffset++] =
18256        flatCoordinates[offset + i * stride];
18257      simplifiedFlatCoordinates[simplifiedOffset++] =
18258        flatCoordinates[offset + i * stride + 1];
18259    }
18260  }
18261  return simplifiedOffset;
18262}
18263
18264/**
18265 * @param {Array<number>} flatCoordinates Flat coordinates.
18266 * @param {number} offset Offset.
18267 * @param {Array<number>} ends Ends.
18268 * @param {number} stride Stride.
18269 * @param {number} squaredTolerance Squared tolerance.
18270 * @param {Array<number>} simplifiedFlatCoordinates Simplified flat
18271 *     coordinates.
18272 * @param {number} simplifiedOffset Simplified offset.
18273 * @param {Array<number>} simplifiedEnds Simplified ends.
18274 * @return {number} Simplified offset.
18275 */
18276function douglasPeuckerArray(
18277  flatCoordinates,
18278  offset,
18279  ends,
18280  stride,
18281  squaredTolerance,
18282  simplifiedFlatCoordinates,
18283  simplifiedOffset,
18284  simplifiedEnds
18285) {
18286  for (let i = 0, ii = ends.length; i < ii; ++i) {
18287    const end = ends[i];
18288    simplifiedOffset = douglasPeucker(
18289      flatCoordinates,
18290      offset,
18291      end,
18292      stride,
18293      squaredTolerance,
18294      simplifiedFlatCoordinates,
18295      simplifiedOffset
18296    );
18297    simplifiedEnds.push(simplifiedOffset);
18298    offset = end;
18299  }
18300  return simplifiedOffset;
18301}
18302
18303/**
18304 * @param {Array<number>} flatCoordinates Flat coordinates.
18305 * @param {number} offset Offset.
18306 * @param {Array<Array<number>>} endss Endss.
18307 * @param {number} stride Stride.
18308 * @param {number} squaredTolerance Squared tolerance.
18309 * @param {Array<number>} simplifiedFlatCoordinates Simplified flat
18310 *     coordinates.
18311 * @param {number} simplifiedOffset Simplified offset.
18312 * @param {Array<Array<number>>} simplifiedEndss Simplified endss.
18313 * @return {number} Simplified offset.
18314 */
18315function douglasPeuckerMultiArray(
18316  flatCoordinates,
18317  offset,
18318  endss,
18319  stride,
18320  squaredTolerance,
18321  simplifiedFlatCoordinates,
18322  simplifiedOffset,
18323  simplifiedEndss
18324) {
18325  for (let i = 0, ii = endss.length; i < ii; ++i) {
18326    const ends = endss[i];
18327    const simplifiedEnds = [];
18328    simplifiedOffset = douglasPeuckerArray(
18329      flatCoordinates,
18330      offset,
18331      ends,
18332      stride,
18333      squaredTolerance,
18334      simplifiedFlatCoordinates,
18335      simplifiedOffset,
18336      simplifiedEnds
18337    );
18338    simplifiedEndss.push(simplifiedEnds);
18339    offset = ends[ends.length - 1];
18340  }
18341  return simplifiedOffset;
18342}
18343
18344/**
18345 * @param {Array<number>} flatCoordinates Flat coordinates.
18346 * @param {number} offset Offset.
18347 * @param {number} end End.
18348 * @param {number} stride Stride.
18349 * @param {number} squaredTolerance Squared tolerance.
18350 * @param {Array<number>} simplifiedFlatCoordinates Simplified flat
18351 *     coordinates.
18352 * @param {number} simplifiedOffset Simplified offset.
18353 * @return {number} Simplified offset.
18354 */
18355function radialDistance(
18356  flatCoordinates,
18357  offset,
18358  end,
18359  stride,
18360  squaredTolerance,
18361  simplifiedFlatCoordinates,
18362  simplifiedOffset
18363) {
18364  if (end <= offset + stride) {
18365    // zero or one point, no simplification possible, so copy and return
18366    for (; offset < end; offset += stride) {
18367      simplifiedFlatCoordinates[simplifiedOffset++] = flatCoordinates[offset];
18368      simplifiedFlatCoordinates[simplifiedOffset++] =
18369        flatCoordinates[offset + 1];
18370    }
18371    return simplifiedOffset;
18372  }
18373  let x1 = flatCoordinates[offset];
18374  let y1 = flatCoordinates[offset + 1];
18375  // copy first point
18376  simplifiedFlatCoordinates[simplifiedOffset++] = x1;
18377  simplifiedFlatCoordinates[simplifiedOffset++] = y1;
18378  let x2 = x1;
18379  let y2 = y1;
18380  for (offset += stride; offset < end; offset += stride) {
18381    x2 = flatCoordinates[offset];
18382    y2 = flatCoordinates[offset + 1];
18383    if (squaredDistance(x1, y1, x2, y2) > squaredTolerance) {
18384      // copy point at offset
18385      simplifiedFlatCoordinates[simplifiedOffset++] = x2;
18386      simplifiedFlatCoordinates[simplifiedOffset++] = y2;
18387      x1 = x2;
18388      y1 = y2;
18389    }
18390  }
18391  if (x2 != x1 || y2 != y1) {
18392    // copy last point
18393    simplifiedFlatCoordinates[simplifiedOffset++] = x2;
18394    simplifiedFlatCoordinates[simplifiedOffset++] = y2;
18395  }
18396  return simplifiedOffset;
18397}
18398
18399/**
18400 * @param {number} value Value.
18401 * @param {number} tolerance Tolerance.
18402 * @return {number} Rounded value.
18403 */
18404function snap(value, tolerance) {
18405  return tolerance * Math.round(value / tolerance);
18406}
18407
18408/**
18409 * Simplifies a line string using an algorithm designed by Tim Schaub.
18410 * Coordinates are snapped to the nearest value in a virtual grid and
18411 * consecutive duplicate coordinates are discarded.  This effectively preserves
18412 * topology as the simplification of any subsection of a line string is
18413 * independent of the rest of the line string.  This means that, for examples,
18414 * the common edge between two polygons will be simplified to the same line
18415 * string independently in both polygons.  This implementation uses a single
18416 * pass over the coordinates and eliminates intermediate collinear points.
18417 * @param {Array<number>} flatCoordinates Flat coordinates.
18418 * @param {number} offset Offset.
18419 * @param {number} end End.
18420 * @param {number} stride Stride.
18421 * @param {number} tolerance Tolerance.
18422 * @param {Array<number>} simplifiedFlatCoordinates Simplified flat
18423 *     coordinates.
18424 * @param {number} simplifiedOffset Simplified offset.
18425 * @return {number} Simplified offset.
18426 */
18427function quantize(
18428  flatCoordinates,
18429  offset,
18430  end,
18431  stride,
18432  tolerance,
18433  simplifiedFlatCoordinates,
18434  simplifiedOffset
18435) {
18436  // do nothing if the line is empty
18437  if (offset == end) {
18438    return simplifiedOffset;
18439  }
18440  // snap the first coordinate (P1)
18441  let x1 = snap(flatCoordinates[offset], tolerance);
18442  let y1 = snap(flatCoordinates[offset + 1], tolerance);
18443  offset += stride;
18444  // add the first coordinate to the output
18445  simplifiedFlatCoordinates[simplifiedOffset++] = x1;
18446  simplifiedFlatCoordinates[simplifiedOffset++] = y1;
18447  // find the next coordinate that does not snap to the same value as the first
18448  // coordinate (P2)
18449  let x2, y2;
18450  do {
18451    x2 = snap(flatCoordinates[offset], tolerance);
18452    y2 = snap(flatCoordinates[offset + 1], tolerance);
18453    offset += stride;
18454    if (offset == end) {
18455      // all coordinates snap to the same value, the line collapses to a point
18456      // push the last snapped value anyway to ensure that the output contains
18457      // at least two points
18458      // FIXME should we really return at least two points anyway?
18459      simplifiedFlatCoordinates[simplifiedOffset++] = x2;
18460      simplifiedFlatCoordinates[simplifiedOffset++] = y2;
18461      return simplifiedOffset;
18462    }
18463  } while (x2 == x1 && y2 == y1);
18464  while (offset < end) {
18465    // snap the next coordinate (P3)
18466    const x3 = snap(flatCoordinates[offset], tolerance);
18467    const y3 = snap(flatCoordinates[offset + 1], tolerance);
18468    offset += stride;
18469    // skip P3 if it is equal to P2
18470    if (x3 == x2 && y3 == y2) {
18471      continue;
18472    }
18473    // calculate the delta between P1 and P2
18474    const dx1 = x2 - x1;
18475    const dy1 = y2 - y1;
18476    // calculate the delta between P3 and P1
18477    const dx2 = x3 - x1;
18478    const dy2 = y3 - y1;
18479    // if P1, P2, and P3 are colinear and P3 is further from P1 than P2 is from
18480    // P1 in the same direction then P2 is on the straight line between P1 and
18481    // P3
18482    if (
18483      dx1 * dy2 == dy1 * dx2 &&
18484      ((dx1 < 0 && dx2 < dx1) || dx1 == dx2 || (dx1 > 0 && dx2 > dx1)) &&
18485      ((dy1 < 0 && dy2 < dy1) || dy1 == dy2 || (dy1 > 0 && dy2 > dy1))
18486    ) {
18487      // discard P2 and set P2 = P3
18488      x2 = x3;
18489      y2 = y3;
18490      continue;
18491    }
18492    // either P1, P2, and P3 are not colinear, or they are colinear but P3 is
18493    // between P3 and P1 or on the opposite half of the line to P2.  add P2,
18494    // and continue with P1 = P2 and P2 = P3
18495    simplifiedFlatCoordinates[simplifiedOffset++] = x2;
18496    simplifiedFlatCoordinates[simplifiedOffset++] = y2;
18497    x1 = x2;
18498    y1 = y2;
18499    x2 = x3;
18500    y2 = y3;
18501  }
18502  // add the last point (P2)
18503  simplifiedFlatCoordinates[simplifiedOffset++] = x2;
18504  simplifiedFlatCoordinates[simplifiedOffset++] = y2;
18505  return simplifiedOffset;
18506}
18507
18508/**
18509 * @param {Array<number>} flatCoordinates Flat coordinates.
18510 * @param {number} offset Offset.
18511 * @param {Array<number>} ends Ends.
18512 * @param {number} stride Stride.
18513 * @param {number} tolerance Tolerance.
18514 * @param {Array<number>} simplifiedFlatCoordinates Simplified flat
18515 *     coordinates.
18516 * @param {number} simplifiedOffset Simplified offset.
18517 * @param {Array<number>} simplifiedEnds Simplified ends.
18518 * @return {number} Simplified offset.
18519 */
18520function quantizeArray(
18521  flatCoordinates,
18522  offset,
18523  ends,
18524  stride,
18525  tolerance,
18526  simplifiedFlatCoordinates,
18527  simplifiedOffset,
18528  simplifiedEnds
18529) {
18530  for (let i = 0, ii = ends.length; i < ii; ++i) {
18531    const end = ends[i];
18532    simplifiedOffset = quantize(
18533      flatCoordinates,
18534      offset,
18535      end,
18536      stride,
18537      tolerance,
18538      simplifiedFlatCoordinates,
18539      simplifiedOffset
18540    );
18541    simplifiedEnds.push(simplifiedOffset);
18542    offset = end;
18543  }
18544  return simplifiedOffset;
18545}
18546
18547/**
18548 * @param {Array<number>} flatCoordinates Flat coordinates.
18549 * @param {number} offset Offset.
18550 * @param {Array<Array<number>>} endss Endss.
18551 * @param {number} stride Stride.
18552 * @param {number} tolerance Tolerance.
18553 * @param {Array<number>} simplifiedFlatCoordinates Simplified flat
18554 *     coordinates.
18555 * @param {number} simplifiedOffset Simplified offset.
18556 * @param {Array<Array<number>>} simplifiedEndss Simplified endss.
18557 * @return {number} Simplified offset.
18558 */
18559function quantizeMultiArray(
18560  flatCoordinates,
18561  offset,
18562  endss,
18563  stride,
18564  tolerance,
18565  simplifiedFlatCoordinates,
18566  simplifiedOffset,
18567  simplifiedEndss
18568) {
18569  for (let i = 0, ii = endss.length; i < ii; ++i) {
18570    const ends = endss[i];
18571    const simplifiedEnds = [];
18572    simplifiedOffset = quantizeArray(
18573      flatCoordinates,
18574      offset,
18575      ends,
18576      stride,
18577      tolerance,
18578      simplifiedFlatCoordinates,
18579      simplifiedOffset,
18580      simplifiedEnds
18581    );
18582    simplifiedEndss.push(simplifiedEnds);
18583    offset = ends[ends.length - 1];
18584  }
18585  return simplifiedOffset;
18586}
18587
18588;// CONCATENATED MODULE: ./node_modules/ol/geom/flat/inflate.js
18589/**
18590 * @module ol/geom/flat/inflate
18591 */
18592
18593/**
18594 * @param {Array<number>} flatCoordinates Flat coordinates.
18595 * @param {number} offset Offset.
18596 * @param {number} end End.
18597 * @param {number} stride Stride.
18598 * @param {Array<import("../../coordinate.js").Coordinate>} [coordinates] Coordinates.
18599 * @return {Array<import("../../coordinate.js").Coordinate>} Coordinates.
18600 */
18601function inflateCoordinates(
18602  flatCoordinates,
18603  offset,
18604  end,
18605  stride,
18606  coordinates
18607) {
18608  coordinates = coordinates !== undefined ? coordinates : [];
18609  let i = 0;
18610  for (let j = offset; j < end; j += stride) {
18611    coordinates[i++] = flatCoordinates.slice(j, j + stride);
18612  }
18613  coordinates.length = i;
18614  return coordinates;
18615}
18616
18617/**
18618 * @param {Array<number>} flatCoordinates Flat coordinates.
18619 * @param {number} offset Offset.
18620 * @param {Array<number>} ends Ends.
18621 * @param {number} stride Stride.
18622 * @param {Array<Array<import("../../coordinate.js").Coordinate>>} [coordinatess] Coordinatess.
18623 * @return {Array<Array<import("../../coordinate.js").Coordinate>>} Coordinatess.
18624 */
18625function inflateCoordinatesArray(
18626  flatCoordinates,
18627  offset,
18628  ends,
18629  stride,
18630  coordinatess
18631) {
18632  coordinatess = coordinatess !== undefined ? coordinatess : [];
18633  let i = 0;
18634  for (let j = 0, jj = ends.length; j < jj; ++j) {
18635    const end = ends[j];
18636    coordinatess[i++] = inflateCoordinates(
18637      flatCoordinates,
18638      offset,
18639      end,
18640      stride,
18641      coordinatess[i]
18642    );
18643    offset = end;
18644  }
18645  coordinatess.length = i;
18646  return coordinatess;
18647}
18648
18649/**
18650 * @param {Array<number>} flatCoordinates Flat coordinates.
18651 * @param {number} offset Offset.
18652 * @param {Array<Array<number>>} endss Endss.
18653 * @param {number} stride Stride.
18654 * @param {Array<Array<Array<import("../../coordinate.js").Coordinate>>>} [coordinatesss]
18655 *     Coordinatesss.
18656 * @return {Array<Array<Array<import("../../coordinate.js").Coordinate>>>} Coordinatesss.
18657 */
18658function inflateMultiCoordinatesArray(
18659  flatCoordinates,
18660  offset,
18661  endss,
18662  stride,
18663  coordinatesss
18664) {
18665  coordinatesss = coordinatesss !== undefined ? coordinatesss : [];
18666  let i = 0;
18667  for (let j = 0, jj = endss.length; j < jj; ++j) {
18668    const ends = endss[j];
18669    coordinatesss[i++] =
18670      ends.length === 1 && ends[0] === offset
18671        ? []
18672        : inflateCoordinatesArray(
18673            flatCoordinates,
18674            offset,
18675            ends,
18676            stride,
18677            coordinatesss[i]
18678          );
18679    offset = ends[ends.length - 1];
18680  }
18681  coordinatesss.length = i;
18682  return coordinatesss;
18683}
18684
18685;// CONCATENATED MODULE: ./node_modules/ol/geom/flat/area.js
18686/**
18687 * @module ol/geom/flat/area
18688 */
18689
18690/**
18691 * @param {Array<number>} flatCoordinates Flat coordinates.
18692 * @param {number} offset Offset.
18693 * @param {number} end End.
18694 * @param {number} stride Stride.
18695 * @return {number} Area.
18696 */
18697function linearRing(flatCoordinates, offset, end, stride) {
18698  let twiceArea = 0;
18699  let x1 = flatCoordinates[end - stride];
18700  let y1 = flatCoordinates[end - stride + 1];
18701  for (; offset < end; offset += stride) {
18702    const x2 = flatCoordinates[offset];
18703    const y2 = flatCoordinates[offset + 1];
18704    twiceArea += y1 * x2 - x1 * y2;
18705    x1 = x2;
18706    y1 = y2;
18707  }
18708  return twiceArea / 2;
18709}
18710
18711/**
18712 * @param {Array<number>} flatCoordinates Flat coordinates.
18713 * @param {number} offset Offset.
18714 * @param {Array<number>} ends Ends.
18715 * @param {number} stride Stride.
18716 * @return {number} Area.
18717 */
18718function linearRings(flatCoordinates, offset, ends, stride) {
18719  let area = 0;
18720  for (let i = 0, ii = ends.length; i < ii; ++i) {
18721    const end = ends[i];
18722    area += linearRing(flatCoordinates, offset, end, stride);
18723    offset = end;
18724  }
18725  return area;
18726}
18727
18728/**
18729 * @param {Array<number>} flatCoordinates Flat coordinates.
18730 * @param {number} offset Offset.
18731 * @param {Array<Array<number>>} endss Endss.
18732 * @param {number} stride Stride.
18733 * @return {number} Area.
18734 */
18735function linearRingss(flatCoordinates, offset, endss, stride) {
18736  let area = 0;
18737  for (let i = 0, ii = endss.length; i < ii; ++i) {
18738    const ends = endss[i];
18739    area += linearRings(flatCoordinates, offset, ends, stride);
18740    offset = ends[ends.length - 1];
18741  }
18742  return area;
18743}
18744
18745;// CONCATENATED MODULE: ./node_modules/ol/geom/LinearRing.js
18746/**
18747 * @module ol/geom/LinearRing
18748 */
18749
18750
18751
18752
18753
18754
18755
18756
18757/**
18758 * @classdesc
18759 * Linear ring geometry. Only used as part of polygon; cannot be rendered
18760 * on its own.
18761 *
18762 * @api
18763 */
18764class LinearRing extends geom_SimpleGeometry {
18765  /**
18766   * @param {Array<import("../coordinate.js").Coordinate>|Array<number>} coordinates Coordinates.
18767   *     For internal use, flat coordinates in combination with `layout` are also accepted.
18768   * @param {import("./Geometry.js").GeometryLayout} [layout] Layout.
18769   */
18770  constructor(coordinates, layout) {
18771    super();
18772
18773    /**
18774     * @private
18775     * @type {number}
18776     */
18777    this.maxDelta_ = -1;
18778
18779    /**
18780     * @private
18781     * @type {number}
18782     */
18783    this.maxDeltaRevision_ = -1;
18784
18785    if (layout !== undefined && !Array.isArray(coordinates[0])) {
18786      this.setFlatCoordinates(
18787        layout,
18788        /** @type {Array<number>} */ (coordinates)
18789      );
18790    } else {
18791      this.setCoordinates(
18792        /** @type {Array<import("../coordinate.js").Coordinate>} */ (
18793          coordinates
18794        ),
18795        layout
18796      );
18797    }
18798  }
18799
18800  /**
18801   * Make a complete copy of the geometry.
18802   * @return {!LinearRing} Clone.
18803   * @api
18804   */
18805  clone() {
18806    return new LinearRing(this.flatCoordinates.slice(), this.layout);
18807  }
18808
18809  /**
18810   * @param {number} x X.
18811   * @param {number} y Y.
18812   * @param {import("../coordinate.js").Coordinate} closestPoint Closest point.
18813   * @param {number} minSquaredDistance Minimum squared distance.
18814   * @return {number} Minimum squared distance.
18815   */
18816  closestPointXY(x, y, closestPoint, minSquaredDistance) {
18817    if (minSquaredDistance < closestSquaredDistanceXY(this.getExtent(), x, y)) {
18818      return minSquaredDistance;
18819    }
18820    if (this.maxDeltaRevision_ != this.getRevision()) {
18821      this.maxDelta_ = Math.sqrt(
18822        maxSquaredDelta(
18823          this.flatCoordinates,
18824          0,
18825          this.flatCoordinates.length,
18826          this.stride,
18827          0
18828        )
18829      );
18830      this.maxDeltaRevision_ = this.getRevision();
18831    }
18832    return assignClosestPoint(
18833      this.flatCoordinates,
18834      0,
18835      this.flatCoordinates.length,
18836      this.stride,
18837      this.maxDelta_,
18838      true,
18839      x,
18840      y,
18841      closestPoint,
18842      minSquaredDistance
18843    );
18844  }
18845
18846  /**
18847   * Return the area of the linear ring on projected plane.
18848   * @return {number} Area (on projected plane).
18849   * @api
18850   */
18851  getArea() {
18852    return linearRing(
18853      this.flatCoordinates,
18854      0,
18855      this.flatCoordinates.length,
18856      this.stride
18857    );
18858  }
18859
18860  /**
18861   * Return the coordinates of the linear ring.
18862   * @return {Array<import("../coordinate.js").Coordinate>} Coordinates.
18863   * @api
18864   */
18865  getCoordinates() {
18866    return inflateCoordinates(
18867      this.flatCoordinates,
18868      0,
18869      this.flatCoordinates.length,
18870      this.stride
18871    );
18872  }
18873
18874  /**
18875   * @param {number} squaredTolerance Squared tolerance.
18876   * @return {LinearRing} Simplified LinearRing.
18877   * @protected
18878   */
18879  getSimplifiedGeometryInternal(squaredTolerance) {
18880    const simplifiedFlatCoordinates = [];
18881    simplifiedFlatCoordinates.length = douglasPeucker(
18882      this.flatCoordinates,
18883      0,
18884      this.flatCoordinates.length,
18885      this.stride,
18886      squaredTolerance,
18887      simplifiedFlatCoordinates,
18888      0
18889    );
18890    return new LinearRing(simplifiedFlatCoordinates, 'XY');
18891  }
18892
18893  /**
18894   * Get the type of this geometry.
18895   * @return {import("./Geometry.js").Type} Geometry type.
18896   * @api
18897   */
18898  getType() {
18899    return 'LinearRing';
18900  }
18901
18902  /**
18903   * Test if the geometry and the passed extent intersect.
18904   * @param {import("../extent.js").Extent} extent Extent.
18905   * @return {boolean} `true` if the geometry and the extent intersect.
18906   * @api
18907   */
18908  intersectsExtent(extent) {
18909    return false;
18910  }
18911
18912  /**
18913   * Set the coordinates of the linear ring.
18914   * @param {!Array<import("../coordinate.js").Coordinate>} coordinates Coordinates.
18915   * @param {import("./Geometry.js").GeometryLayout} [layout] Layout.
18916   * @api
18917   */
18918  setCoordinates(coordinates, layout) {
18919    this.setLayout(layout, coordinates, 1);
18920    if (!this.flatCoordinates) {
18921      this.flatCoordinates = [];
18922    }
18923    this.flatCoordinates.length = deflateCoordinates(
18924      this.flatCoordinates,
18925      0,
18926      coordinates,
18927      this.stride
18928    );
18929    this.changed();
18930  }
18931}
18932
18933/* harmony default export */ const geom_LinearRing = (LinearRing);
18934
18935;// CONCATENATED MODULE: ./node_modules/ol/geom/Point.js
18936/**
18937 * @module ol/geom/Point
18938 */
18939
18940
18941
18942
18943
18944/**
18945 * @classdesc
18946 * Point geometry.
18947 *
18948 * @api
18949 */
18950class Point extends geom_SimpleGeometry {
18951  /**
18952   * @param {import("../coordinate.js").Coordinate} coordinates Coordinates.
18953   * @param {import("./Geometry.js").GeometryLayout} [layout] Layout.
18954   */
18955  constructor(coordinates, layout) {
18956    super();
18957    this.setCoordinates(coordinates, layout);
18958  }
18959
18960  /**
18961   * Make a complete copy of the geometry.
18962   * @return {!Point} Clone.
18963   * @api
18964   */
18965  clone() {
18966    const point = new Point(this.flatCoordinates.slice(), this.layout);
18967    point.applyProperties(this);
18968    return point;
18969  }
18970
18971  /**
18972   * @param {number} x X.
18973   * @param {number} y Y.
18974   * @param {import("../coordinate.js").Coordinate} closestPoint Closest point.
18975   * @param {number} minSquaredDistance Minimum squared distance.
18976   * @return {number} Minimum squared distance.
18977   */
18978  closestPointXY(x, y, closestPoint, minSquaredDistance) {
18979    const flatCoordinates = this.flatCoordinates;
18980    const squaredDistance = math_squaredDistance(
18981      x,
18982      y,
18983      flatCoordinates[0],
18984      flatCoordinates[1]
18985    );
18986    if (squaredDistance < minSquaredDistance) {
18987      const stride = this.stride;
18988      for (let i = 0; i < stride; ++i) {
18989        closestPoint[i] = flatCoordinates[i];
18990      }
18991      closestPoint.length = stride;
18992      return squaredDistance;
18993    } else {
18994      return minSquaredDistance;
18995    }
18996  }
18997
18998  /**
18999   * Return the coordinate of the point.
19000   * @return {import("../coordinate.js").Coordinate} Coordinates.
19001   * @api
19002   */
19003  getCoordinates() {
19004    return !this.flatCoordinates ? [] : this.flatCoordinates.slice();
19005  }
19006
19007  /**
19008   * @param {import("../extent.js").Extent} extent Extent.
19009   * @protected
19010   * @return {import("../extent.js").Extent} extent Extent.
19011   */
19012  computeExtent(extent) {
19013    return createOrUpdateFromCoordinate(this.flatCoordinates, extent);
19014  }
19015
19016  /**
19017   * Get the type of this geometry.
19018   * @return {import("./Geometry.js").Type} Geometry type.
19019   * @api
19020   */
19021  getType() {
19022    return 'Point';
19023  }
19024
19025  /**
19026   * Test if the geometry and the passed extent intersect.
19027   * @param {import("../extent.js").Extent} extent Extent.
19028   * @return {boolean} `true` if the geometry and the extent intersect.
19029   * @api
19030   */
19031  intersectsExtent(extent) {
19032    return containsXY(extent, this.flatCoordinates[0], this.flatCoordinates[1]);
19033  }
19034
19035  /**
19036   * @param {!Array<*>} coordinates Coordinates.
19037   * @param {import("./Geometry.js").GeometryLayout} [layout] Layout.
19038   * @api
19039   */
19040  setCoordinates(coordinates, layout) {
19041    this.setLayout(layout, coordinates, 0);
19042    if (!this.flatCoordinates) {
19043      this.flatCoordinates = [];
19044    }
19045    this.flatCoordinates.length = deflateCoordinate(
19046      this.flatCoordinates,
19047      0,
19048      coordinates,
19049      this.stride
19050    );
19051    this.changed();
19052  }
19053}
19054
19055/* harmony default export */ const geom_Point = (Point);
19056
19057;// CONCATENATED MODULE: ./node_modules/ol/geom/flat/contains.js
19058/**
19059 * @module ol/geom/flat/contains
19060 */
19061
19062
19063/**
19064 * @param {Array<number>} flatCoordinates Flat coordinates.
19065 * @param {number} offset Offset.
19066 * @param {number} end End.
19067 * @param {number} stride Stride.
19068 * @param {import("../../extent.js").Extent} extent Extent.
19069 * @return {boolean} Contains extent.
19070 */
19071function linearRingContainsExtent(
19072  flatCoordinates,
19073  offset,
19074  end,
19075  stride,
19076  extent
19077) {
19078  const outside = forEachCorner(
19079    extent,
19080    /**
19081     * @param {import("../../coordinate.js").Coordinate} coordinate Coordinate.
19082     * @return {boolean} Contains (x, y).
19083     */
19084    function (coordinate) {
19085      return !linearRingContainsXY(
19086        flatCoordinates,
19087        offset,
19088        end,
vendor: 29,035 bytes, lines 19089-20222
19089        stride,
19090        coordinate[0],
19091        coordinate[1]
19092      );
19093    }
19094  );
19095  return !outside;
19096}
19097
19098/**
19099 * @param {Array<number>} flatCoordinates Flat coordinates.
19100 * @param {number} offset Offset.
19101 * @param {number} end End.
19102 * @param {number} stride Stride.
19103 * @param {number} x X.
19104 * @param {number} y Y.
19105 * @return {boolean} Contains (x, y).
19106 */
19107function linearRingContainsXY(
19108  flatCoordinates,
19109  offset,
19110  end,
19111  stride,
19112  x,
19113  y
19114) {
19115  // https://geomalgorithms.com/a03-_inclusion.html
19116  // Copyright 2000 softSurfer, 2012 Dan Sunday
19117  // This code may be freely used and modified for any purpose
19118  // providing that this copyright notice is included with it.
19119  // SoftSurfer makes no warranty for this code, and cannot be held
19120  // liable for any real or imagined damage resulting from its use.
19121  // Users of this code must verify correctness for their application.
19122  let wn = 0;
19123  let x1 = flatCoordinates[end - stride];
19124  let y1 = flatCoordinates[end - stride + 1];
19125  for (; offset < end; offset += stride) {
19126    const x2 = flatCoordinates[offset];
19127    const y2 = flatCoordinates[offset + 1];
19128    if (y1 <= y) {
19129      if (y2 > y && (x2 - x1) * (y - y1) - (x - x1) * (y2 - y1) > 0) {
19130        wn++;
19131      }
19132    } else if (y2 <= y && (x2 - x1) * (y - y1) - (x - x1) * (y2 - y1) < 0) {
19133      wn--;
19134    }
19135    x1 = x2;
19136    y1 = y2;
19137  }
19138  return wn !== 0;
19139}
19140
19141/**
19142 * @param {Array<number>} flatCoordinates Flat coordinates.
19143 * @param {number} offset Offset.
19144 * @param {Array<number>} ends Ends.
19145 * @param {number} stride Stride.
19146 * @param {number} x X.
19147 * @param {number} y Y.
19148 * @return {boolean} Contains (x, y).
19149 */
19150function linearRingsContainsXY(
19151  flatCoordinates,
19152  offset,
19153  ends,
19154  stride,
19155  x,
19156  y
19157) {
19158  if (ends.length === 0) {
19159    return false;
19160  }
19161  if (!linearRingContainsXY(flatCoordinates, offset, ends[0], stride, x, y)) {
19162    return false;
19163  }
19164  for (let i = 1, ii = ends.length; i < ii; ++i) {
19165    if (
19166      linearRingContainsXY(flatCoordinates, ends[i - 1], ends[i], stride, x, y)
19167    ) {
19168      return false;
19169    }
19170  }
19171  return true;
19172}
19173
19174/**
19175 * @param {Array<number>} flatCoordinates Flat coordinates.
19176 * @param {number} offset Offset.
19177 * @param {Array<Array<number>>} endss Endss.
19178 * @param {number} stride Stride.
19179 * @param {number} x X.
19180 * @param {number} y Y.
19181 * @return {boolean} Contains (x, y).
19182 */
19183function linearRingssContainsXY(
19184  flatCoordinates,
19185  offset,
19186  endss,
19187  stride,
19188  x,
19189  y
19190) {
19191  if (endss.length === 0) {
19192    return false;
19193  }
19194  for (let i = 0, ii = endss.length; i < ii; ++i) {
19195    const ends = endss[i];
19196    if (linearRingsContainsXY(flatCoordinates, offset, ends, stride, x, y)) {
19197      return true;
19198    }
19199    offset = ends[ends.length - 1];
19200  }
19201  return false;
19202}
19203
19204;// CONCATENATED MODULE: ./node_modules/ol/geom/flat/interiorpoint.js
19205/**
19206 * @module ol/geom/flat/interiorpoint
19207 */
19208
19209
19210
19211/**
19212 * Calculates a point that is likely to lie in the interior of the linear rings.
19213 * Inspired by JTS's com.vividsolutions.jts.geom.Geometry#getInteriorPoint.
19214 * @param {Array<number>} flatCoordinates Flat coordinates.
19215 * @param {number} offset Offset.
19216 * @param {Array<number>} ends Ends.
19217 * @param {number} stride Stride.
19218 * @param {Array<number>} flatCenters Flat centers.
19219 * @param {number} flatCentersOffset Flat center offset.
19220 * @param {Array<number>} [dest] Destination.
19221 * @return {Array<number>} Destination point as XYM coordinate, where M is the
19222 * length of the horizontal intersection that the point belongs to.
19223 */
19224function getInteriorPointOfArray(
19225  flatCoordinates,
19226  offset,
19227  ends,
19228  stride,
19229  flatCenters,
19230  flatCentersOffset,
19231  dest
19232) {
19233  let i, ii, x, x1, x2, y1, y2;
19234  const y = flatCenters[flatCentersOffset + 1];
19235  /** @type {Array<number>} */
19236  const intersections = [];
19237  // Calculate intersections with the horizontal line
19238  for (let r = 0, rr = ends.length; r < rr; ++r) {
19239    const end = ends[r];
19240    x1 = flatCoordinates[end - stride];
19241    y1 = flatCoordinates[end - stride + 1];
19242    for (i = offset; i < end; i += stride) {
19243      x2 = flatCoordinates[i];
19244      y2 = flatCoordinates[i + 1];
19245      if ((y <= y1 && y2 <= y) || (y1 <= y && y <= y2)) {
19246        x = ((y - y1) / (y2 - y1)) * (x2 - x1) + x1;
19247        intersections.push(x);
19248      }
19249      x1 = x2;
19250      y1 = y2;
19251    }
19252  }
19253  // Find the longest segment of the horizontal line that has its center point
19254  // inside the linear ring.
19255  let pointX = NaN;
19256  let maxSegmentLength = -Infinity;
19257  intersections.sort(numberSafeCompareFunction);
19258  x1 = intersections[0];
19259  for (i = 1, ii = intersections.length; i < ii; ++i) {
19260    x2 = intersections[i];
19261    const segmentLength = Math.abs(x2 - x1);
19262    if (segmentLength > maxSegmentLength) {
19263      x = (x1 + x2) / 2;
19264      if (linearRingsContainsXY(flatCoordinates, offset, ends, stride, x, y)) {
19265        pointX = x;
19266        maxSegmentLength = segmentLength;
19267      }
19268    }
19269    x1 = x2;
19270  }
19271  if (isNaN(pointX)) {
19272    // There is no horizontal line that has its center point inside the linear
19273    // ring.  Use the center of the the linear ring's extent.
19274    pointX = flatCenters[flatCentersOffset];
19275  }
19276  if (dest) {
19277    dest.push(pointX, y, maxSegmentLength);
19278    return dest;
19279  } else {
19280    return [pointX, y, maxSegmentLength];
19281  }
19282}
19283
19284/**
19285 * @param {Array<number>} flatCoordinates Flat coordinates.
19286 * @param {number} offset Offset.
19287 * @param {Array<Array<number>>} endss Endss.
19288 * @param {number} stride Stride.
19289 * @param {Array<number>} flatCenters Flat centers.
19290 * @return {Array<number>} Interior points as XYM coordinates, where M is the
19291 * length of the horizontal intersection that the point belongs to.
19292 */
19293function getInteriorPointsOfMultiArray(
19294  flatCoordinates,
19295  offset,
19296  endss,
19297  stride,
19298  flatCenters
19299) {
19300  let interiorPoints = [];
19301  for (let i = 0, ii = endss.length; i < ii; ++i) {
19302    const ends = endss[i];
19303    interiorPoints = getInteriorPointOfArray(
19304      flatCoordinates,
19305      offset,
19306      ends,
19307      stride,
19308      flatCenters,
19309      2 * i,
19310      interiorPoints
19311    );
19312    offset = ends[ends.length - 1];
19313  }
19314  return interiorPoints;
19315}
19316
19317;// CONCATENATED MODULE: ./node_modules/ol/geom/flat/segments.js
19318/**
19319 * @module ol/geom/flat/segments
19320 */
19321
19322/**
19323 * This function calls `callback` for each segment of the flat coordinates
19324 * array. If the callback returns a truthy value the function returns that
19325 * value immediately. Otherwise the function returns `false`.
19326 * @param {Array<number>} flatCoordinates Flat coordinates.
19327 * @param {number} offset Offset.
19328 * @param {number} end End.
19329 * @param {number} stride Stride.
19330 * @param {function(import("../../coordinate.js").Coordinate, import("../../coordinate.js").Coordinate): T} callback Function
19331 *     called for each segment.
19332 * @return {T|boolean} Value.
19333 * @template T
19334 */
19335function forEach(flatCoordinates, offset, end, stride, callback) {
19336  let ret;
19337  offset += stride;
19338  for (; offset < end; offset += stride) {
19339    ret = callback(
19340      flatCoordinates.slice(offset - stride, offset),
19341      flatCoordinates.slice(offset, offset + stride)
19342    );
19343    if (ret) {
19344      return ret;
19345    }
19346  }
19347  return false;
19348}
19349
19350;// CONCATENATED MODULE: ./node_modules/ol/geom/flat/intersectsextent.js
19351/**
19352 * @module ol/geom/flat/intersectsextent
19353 */
19354
19355
19356
19357
19358/**
19359 * @param {Array<number>} flatCoordinates Flat coordinates.
19360 * @param {number} offset Offset.
19361 * @param {number} end End.
19362 * @param {number} stride Stride.
19363 * @param {import("../../extent.js").Extent} extent Extent.
19364 * @return {boolean} True if the geometry and the extent intersect.
19365 */
19366function intersectsLineString(
19367  flatCoordinates,
19368  offset,
19369  end,
19370  stride,
19371  extent
19372) {
19373  const coordinatesExtent = extendFlatCoordinates(
19374    createEmpty(),
19375    flatCoordinates,
19376    offset,
19377    end,
19378    stride
19379  );
19380  if (!intersects(extent, coordinatesExtent)) {
19381    return false;
19382  }
19383  if (containsExtent(extent, coordinatesExtent)) {
19384    return true;
19385  }
19386  if (coordinatesExtent[0] >= extent[0] && coordinatesExtent[2] <= extent[2]) {
19387    return true;
19388  }
19389  if (coordinatesExtent[1] >= extent[1] && coordinatesExtent[3] <= extent[3]) {
19390    return true;
19391  }
19392  return forEach(
19393    flatCoordinates,
19394    offset,
19395    end,
19396    stride,
19397    /**
19398     * @param {import("../../coordinate.js").Coordinate} point1 Start point.
19399     * @param {import("../../coordinate.js").Coordinate} point2 End point.
19400     * @return {boolean} `true` if the segment and the extent intersect,
19401     *     `false` otherwise.
19402     */
19403    function (point1, point2) {
19404      return intersectsSegment(extent, point1, point2);
19405    }
19406  );
19407}
19408
19409/**
19410 * @param {Array<number>} flatCoordinates Flat coordinates.
19411 * @param {number} offset Offset.
19412 * @param {Array<number>} ends Ends.
19413 * @param {number} stride Stride.
19414 * @param {import("../../extent.js").Extent} extent Extent.
19415 * @return {boolean} True if the geometry and the extent intersect.
19416 */
19417function intersectsLineStringArray(
19418  flatCoordinates,
19419  offset,
19420  ends,
19421  stride,
19422  extent
19423) {
19424  for (let i = 0, ii = ends.length; i < ii; ++i) {
19425    if (
19426      intersectsLineString(flatCoordinates, offset, ends[i], stride, extent)
19427    ) {
19428      return true;
19429    }
19430    offset = ends[i];
19431  }
19432  return false;
19433}
19434
19435/**
19436 * @param {Array<number>} flatCoordinates Flat coordinates.
19437 * @param {number} offset Offset.
19438 * @param {number} end End.
19439 * @param {number} stride Stride.
19440 * @param {import("../../extent.js").Extent} extent Extent.
19441 * @return {boolean} True if the geometry and the extent intersect.
19442 */
19443function intersectsLinearRing(
19444  flatCoordinates,
19445  offset,
19446  end,
19447  stride,
19448  extent
19449) {
19450  if (intersectsLineString(flatCoordinates, offset, end, stride, extent)) {
19451    return true;
19452  }
19453  if (
19454    linearRingContainsXY(
19455      flatCoordinates,
19456      offset,
19457      end,
19458      stride,
19459      extent[0],
19460      extent[1]
19461    )
19462  ) {
19463    return true;
19464  }
19465  if (
19466    linearRingContainsXY(
19467      flatCoordinates,
19468      offset,
19469      end,
19470      stride,
19471      extent[0],
19472      extent[3]
19473    )
19474  ) {
19475    return true;
19476  }
19477  if (
19478    linearRingContainsXY(
19479      flatCoordinates,
19480      offset,
19481      end,
19482      stride,
19483      extent[2],
19484      extent[1]
19485    )
19486  ) {
19487    return true;
19488  }
19489  if (
19490    linearRingContainsXY(
19491      flatCoordinates,
19492      offset,
19493      end,
19494      stride,
19495      extent[2],
19496      extent[3]
19497    )
19498  ) {
19499    return true;
19500  }
19501  return false;
19502}
19503
19504/**
19505 * @param {Array<number>} flatCoordinates Flat coordinates.
19506 * @param {number} offset Offset.
19507 * @param {Array<number>} ends Ends.
19508 * @param {number} stride Stride.
19509 * @param {import("../../extent.js").Extent} extent Extent.
19510 * @return {boolean} True if the geometry and the extent intersect.
19511 */
19512function intersectsLinearRingArray(
19513  flatCoordinates,
19514  offset,
19515  ends,
19516  stride,
19517  extent
19518) {
19519  if (!intersectsLinearRing(flatCoordinates, offset, ends[0], stride, extent)) {
19520    return false;
19521  }
19522  if (ends.length === 1) {
19523    return true;
19524  }
19525  for (let i = 1, ii = ends.length; i < ii; ++i) {
19526    if (
19527      linearRingContainsExtent(
19528        flatCoordinates,
19529        ends[i - 1],
19530        ends[i],
19531        stride,
19532        extent
19533      )
19534    ) {
19535      if (
19536        !intersectsLineString(
19537          flatCoordinates,
19538          ends[i - 1],
19539          ends[i],
19540          stride,
19541          extent
19542        )
19543      ) {
19544        return false;
19545      }
19546    }
19547  }
19548  return true;
19549}
19550
19551/**
19552 * @param {Array<number>} flatCoordinates Flat coordinates.
19553 * @param {number} offset Offset.
19554 * @param {Array<Array<number>>} endss Endss.
19555 * @param {number} stride Stride.
19556 * @param {import("../../extent.js").Extent} extent Extent.
19557 * @return {boolean} True if the geometry and the extent intersect.
19558 */
19559function intersectsLinearRingMultiArray(
19560  flatCoordinates,
19561  offset,
19562  endss,
19563  stride,
19564  extent
19565) {
19566  for (let i = 0, ii = endss.length; i < ii; ++i) {
19567    const ends = endss[i];
19568    if (
19569      intersectsLinearRingArray(flatCoordinates, offset, ends, stride, extent)
19570    ) {
19571      return true;
19572    }
19573    offset = ends[ends.length - 1];
19574  }
19575  return false;
19576}
19577
19578;// CONCATENATED MODULE: ./node_modules/ol/geom/flat/reverse.js
19579/**
19580 * @module ol/geom/flat/reverse
19581 */
19582
19583/**
19584 * @param {Array<number>} flatCoordinates Flat coordinates.
19585 * @param {number} offset Offset.
19586 * @param {number} end End.
19587 * @param {number} stride Stride.
19588 */
19589function coordinates(flatCoordinates, offset, end, stride) {
19590  while (offset < end - stride) {
19591    for (let i = 0; i < stride; ++i) {
19592      const tmp = flatCoordinates[offset + i];
19593      flatCoordinates[offset + i] = flatCoordinates[end - stride + i];
19594      flatCoordinates[end - stride + i] = tmp;
19595    }
19596    offset += stride;
19597    end -= stride;
19598  }
19599}
19600
19601;// CONCATENATED MODULE: ./node_modules/ol/geom/flat/orient.js
19602/**
19603 * @module ol/geom/flat/orient
19604 */
19605
19606
19607/**
19608 * Is the linear ring oriented clockwise in a coordinate system with a bottom-left
19609 * coordinate origin? For a coordinate system with a top-left coordinate origin,
19610 * the ring's orientation is clockwise when this function returns false.
19611 * @param {Array<number>} flatCoordinates Flat coordinates.
19612 * @param {number} offset Offset.
19613 * @param {number} end End.
19614 * @param {number} stride Stride.
19615 * @return {boolean} Is clockwise.
19616 */
19617function linearRingIsClockwise(flatCoordinates, offset, end, stride) {
19618  // https://stackoverflow.com/q/1165647/clockwise-method#1165943
19619  // https://github.com/OSGeo/gdal/blob/master/gdal/ogr/ogrlinearring.cpp
19620  let edge = 0;
19621  let x1 = flatCoordinates[end - stride];
19622  let y1 = flatCoordinates[end - stride + 1];
19623  for (; offset < end; offset += stride) {
19624    const x2 = flatCoordinates[offset];
19625    const y2 = flatCoordinates[offset + 1];
19626    edge += (x2 - x1) * (y2 + y1);
19627    x1 = x2;
19628    y1 = y2;
19629  }
19630  return edge === 0 ? undefined : edge > 0;
19631}
19632
19633/**
19634 * Determines if linear rings are oriented.  By default, left-hand orientation
19635 * is tested (first ring must be clockwise, remaining rings counter-clockwise).
19636 * To test for right-hand orientation, use the `right` argument.
19637 *
19638 * @param {Array<number>} flatCoordinates Flat coordinates.
19639 * @param {number} offset Offset.
19640 * @param {Array<number>} ends Array of end indexes.
19641 * @param {number} stride Stride.
19642 * @param {boolean} [right] Test for right-hand orientation
19643 *     (counter-clockwise exterior ring and clockwise interior rings).
19644 * @return {boolean} Rings are correctly oriented.
19645 */
19646function linearRingsAreOriented(
19647  flatCoordinates,
19648  offset,
19649  ends,
19650  stride,
19651  right
19652) {
19653  right = right !== undefined ? right : false;
19654  for (let i = 0, ii = ends.length; i < ii; ++i) {
19655    const end = ends[i];
19656    const isClockwise = linearRingIsClockwise(
19657      flatCoordinates,
19658      offset,
19659      end,
19660      stride
19661    );
19662    if (i === 0) {
19663      if ((right && isClockwise) || (!right && !isClockwise)) {
19664        return false;
19665      }
19666    } else {
19667      if ((right && !isClockwise) || (!right && isClockwise)) {
19668        return false;
19669      }
19670    }
19671    offset = end;
19672  }
19673  return true;
19674}
19675
19676/**
19677 * Determines if linear rings are oriented.  By default, left-hand orientation
19678 * is tested (first ring must be clockwise, remaining rings counter-clockwise).
19679 * To test for right-hand orientation, use the `right` argument.
19680 *
19681 * @param {Array<number>} flatCoordinates Flat coordinates.
19682 * @param {number} offset Offset.
19683 * @param {Array<Array<number>>} endss Array of array of end indexes.
19684 * @param {number} stride Stride.
19685 * @param {boolean} [right] Test for right-hand orientation
19686 *     (counter-clockwise exterior ring and clockwise interior rings).
19687 * @return {boolean} Rings are correctly oriented.
19688 */
19689function linearRingssAreOriented(
19690  flatCoordinates,
19691  offset,
19692  endss,
19693  stride,
19694  right
19695) {
19696  for (let i = 0, ii = endss.length; i < ii; ++i) {
19697    const ends = endss[i];
19698    if (!linearRingsAreOriented(flatCoordinates, offset, ends, stride, right)) {
19699      return false;
19700    }
19701    if (ends.length) {
19702      offset = ends[ends.length - 1];
19703    }
19704  }
19705  return true;
19706}
19707
19708/**
19709 * Orient coordinates in a flat array of linear rings.  By default, rings
19710 * are oriented following the left-hand rule (clockwise for exterior and
19711 * counter-clockwise for interior rings).  To orient according to the
19712 * right-hand rule, use the `right` argument.
19713 *
19714 * @param {Array<number>} flatCoordinates Flat coordinates.
19715 * @param {number} offset Offset.
19716 * @param {Array<number>} ends Ends.
19717 * @param {number} stride Stride.
19718 * @param {boolean} [right] Follow the right-hand rule for orientation.
19719 * @return {number} End.
19720 */
19721function orientLinearRings(
19722  flatCoordinates,
19723  offset,
19724  ends,
19725  stride,
19726  right
19727) {
19728  right = right !== undefined ? right : false;
19729  for (let i = 0, ii = ends.length; i < ii; ++i) {
19730    const end = ends[i];
19731    const isClockwise = linearRingIsClockwise(
19732      flatCoordinates,
19733      offset,
19734      end,
19735      stride
19736    );
19737    const reverse =
19738      i === 0
19739        ? (right && isClockwise) || (!right && !isClockwise)
19740        : (right && !isClockwise) || (!right && isClockwise);
19741    if (reverse) {
19742      coordinates(flatCoordinates, offset, end, stride);
19743    }
19744    offset = end;
19745  }
19746  return offset;
19747}
19748
19749/**
19750 * Orient coordinates in a flat array of linear rings.  By default, rings
19751 * are oriented following the left-hand rule (clockwise for exterior and
19752 * counter-clockwise for interior rings).  To orient according to the
19753 * right-hand rule, use the `right` argument.
19754 *
19755 * @param {Array<number>} flatCoordinates Flat coordinates.
19756 * @param {number} offset Offset.
19757 * @param {Array<Array<number>>} endss Array of array of end indexes.
19758 * @param {number} stride Stride.
19759 * @param {boolean} [right] Follow the right-hand rule for orientation.
19760 * @return {number} End.
19761 */
19762function orientLinearRingsArray(
19763  flatCoordinates,
19764  offset,
19765  endss,
19766  stride,
19767  right
19768) {
19769  for (let i = 0, ii = endss.length; i < ii; ++i) {
19770    offset = orientLinearRings(
19771      flatCoordinates,
19772      offset,
19773      endss[i],
19774      stride,
19775      right
19776    );
19777  }
19778  return offset;
19779}
19780
19781/**
19782 * Return a two-dimensional endss
19783 * @param {Array<number>} flatCoordinates Flat coordinates
19784 * @param {Array<number>} ends Linear ring end indexes
19785 * @return {Array<Array<number>>} Two dimensional endss array that can
19786 * be used to contruct a MultiPolygon
19787 */
19788function inflateEnds(flatCoordinates, ends) {
19789  const endss = [];
19790  let offset = 0;
19791  let prevEndIndex = 0;
19792  for (let i = 0, ii = ends.length; i < ii; ++i) {
19793    const end = ends[i];
19794    // classifies an array of rings into polygons with outer rings and holes
19795    if (!linearRingIsClockwise(flatCoordinates, offset, end, 2)) {
19796      endss.push(ends.slice(prevEndIndex, i + 1));
19797    } else {
19798      if (endss.length === 0) {
19799        continue;
19800      }
19801      endss[endss.length - 1].push(ends[prevEndIndex]);
19802    }
19803    prevEndIndex = i + 1;
19804    offset = end;
19805  }
19806  return endss;
19807}
19808
19809;// CONCATENATED MODULE: ./node_modules/ol/geom/Polygon.js
19810/**
19811 * @module ol/geom/Polygon
19812 */
19813
19814
19815
19816
19817
19818
19819
19820
19821
19822
19823
19824
19825
19826
19827
19828
19829
19830/**
19831 * @classdesc
19832 * Polygon geometry.
19833 *
19834 * @api
19835 */
19836class Polygon extends geom_SimpleGeometry {
19837  /**
19838   * @param {!Array<Array<import("../coordinate.js").Coordinate>>|!Array<number>} coordinates
19839   *     Array of linear rings that define the polygon. The first linear ring of the
19840   *     array defines the outer-boundary or surface of the polygon. Each subsequent
19841   *     linear ring defines a hole in the surface of the polygon. A linear ring is
19842   *     an array of vertices' coordinates where the first coordinate and the last are
19843   *     equivalent. (For internal use, flat coordinates in combination with
19844   *     `layout` and `ends` are also accepted.)
19845   * @param {import("./Geometry.js").GeometryLayout} [layout] Layout.
19846   * @param {Array<number>} [ends] Ends (for internal use with flat coordinates).
19847   */
19848  constructor(coordinates, layout, ends) {
19849    super();
19850
19851    /**
19852     * @type {Array<number>}
19853     * @private
19854     */
19855    this.ends_ = [];
19856
19857    /**
19858     * @private
19859     * @type {number}
19860     */
19861    this.flatInteriorPointRevision_ = -1;
19862
19863    /**
19864     * @private
19865     * @type {import("../coordinate.js").Coordinate}
19866     */
19867    this.flatInteriorPoint_ = null;
19868
19869    /**
19870     * @private
19871     * @type {number}
19872     */
19873    this.maxDelta_ = -1;
19874
19875    /**
19876     * @private
19877     * @type {number}
19878     */
19879    this.maxDeltaRevision_ = -1;
19880
19881    /**
19882     * @private
19883     * @type {number}
19884     */
19885    this.orientedRevision_ = -1;
19886
19887    /**
19888     * @private
19889     * @type {Array<number>}
19890     */
19891    this.orientedFlatCoordinates_ = null;
19892
19893    if (layout !== undefined && ends) {
19894      this.setFlatCoordinates(
19895        layout,
19896        /** @type {Array<number>} */ (coordinates)
19897      );
19898      this.ends_ = ends;
19899    } else {
19900      this.setCoordinates(
19901        /** @type {Array<Array<import("../coordinate.js").Coordinate>>} */ (
19902          coordinates
19903        ),
19904        layout
19905      );
19906    }
19907  }
19908
19909  /**
19910   * Append the passed linear ring to this polygon.
19911   * @param {LinearRing} linearRing Linear ring.
19912   * @api
19913   */
19914  appendLinearRing(linearRing) {
19915    if (!this.flatCoordinates) {
19916      this.flatCoordinates = linearRing.getFlatCoordinates().slice();
19917    } else {
19918      array_extend(this.flatCoordinates, linearRing.getFlatCoordinates());
19919    }
19920    this.ends_.push(this.flatCoordinates.length);
19921    this.changed();
19922  }
19923
19924  /**
19925   * Make a complete copy of the geometry.
19926   * @return {!Polygon} Clone.
19927   * @api
19928   */
19929  clone() {
19930    const polygon = new Polygon(
19931      this.flatCoordinates.slice(),
19932      this.layout,
19933      this.ends_.slice()
19934    );
19935    polygon.applyProperties(this);
19936    return polygon;
19937  }
19938
19939  /**
19940   * @param {number} x X.
19941   * @param {number} y Y.
19942   * @param {import("../coordinate.js").Coordinate} closestPoint Closest point.
19943   * @param {number} minSquaredDistance Minimum squared distance.
19944   * @return {number} Minimum squared distance.
19945   */
19946  closestPointXY(x, y, closestPoint, minSquaredDistance) {
19947    if (minSquaredDistance < closestSquaredDistanceXY(this.getExtent(), x, y)) {
19948      return minSquaredDistance;
19949    }
19950    if (this.maxDeltaRevision_ != this.getRevision()) {
19951      this.maxDelta_ = Math.sqrt(
19952        arrayMaxSquaredDelta(
19953          this.flatCoordinates,
19954          0,
19955          this.ends_,
19956          this.stride,
19957          0
19958        )
19959      );
19960      this.maxDeltaRevision_ = this.getRevision();
19961    }
19962    return assignClosestArrayPoint(
19963      this.flatCoordinates,
19964      0,
19965      this.ends_,
19966      this.stride,
19967      this.maxDelta_,
19968      true,
19969      x,
19970      y,
19971      closestPoint,
19972      minSquaredDistance
19973    );
19974  }
19975
19976  /**
19977   * @param {number} x X.
19978   * @param {number} y Y.
19979   * @return {boolean} Contains (x, y).
19980   */
19981  containsXY(x, y) {
19982    return linearRingsContainsXY(
19983      this.getOrientedFlatCoordinates(),
19984      0,
19985      this.ends_,
19986      this.stride,
19987      x,
19988      y
19989    );
19990  }
19991
19992  /**
19993   * Return the area of the polygon on projected plane.
19994   * @return {number} Area (on projected plane).
19995   * @api
19996   */
19997  getArea() {
19998    return linearRings(
19999      this.getOrientedFlatCoordinates(),
20000      0,
20001      this.ends_,
20002      this.stride
20003    );
20004  }
20005
20006  /**
20007   * Get the coordinate array for this geometry.  This array has the structure
20008   * of a GeoJSON coordinate array for polygons.
20009   *
20010   * @param {boolean} [right] Orient coordinates according to the right-hand
20011   *     rule (counter-clockwise for exterior and clockwise for interior rings).
20012   *     If `false`, coordinates will be oriented according to the left-hand rule
20013   *     (clockwise for exterior and counter-clockwise for interior rings).
20014   *     By default, coordinate orientation will depend on how the geometry was
20015   *     constructed.
20016   * @return {Array<Array<import("../coordinate.js").Coordinate>>} Coordinates.
20017   * @api
20018   */
20019  getCoordinates(right) {
20020    let flatCoordinates;
20021    if (right !== undefined) {
20022      flatCoordinates = this.getOrientedFlatCoordinates().slice();
20023      orientLinearRings(flatCoordinates, 0, this.ends_, this.stride, right);
20024    } else {
20025      flatCoordinates = this.flatCoordinates;
20026    }
20027
20028    return inflateCoordinatesArray(flatCoordinates, 0, this.ends_, this.stride);
20029  }
20030
20031  /**
20032   * @return {Array<number>} Ends.
20033   */
20034  getEnds() {
20035    return this.ends_;
20036  }
20037
20038  /**
20039   * @return {Array<number>} Interior point.
20040   */
20041  getFlatInteriorPoint() {
20042    if (this.flatInteriorPointRevision_ != this.getRevision()) {
20043      const flatCenter = getCenter(this.getExtent());
20044      this.flatInteriorPoint_ = getInteriorPointOfArray(
20045        this.getOrientedFlatCoordinates(),
20046        0,
20047        this.ends_,
20048        this.stride,
20049        flatCenter,
20050        0
20051      );
20052      this.flatInteriorPointRevision_ = this.getRevision();
20053    }
20054    return this.flatInteriorPoint_;
20055  }
20056
20057  /**
20058   * Return an interior point of the polygon.
20059   * @return {Point} Interior point as XYM coordinate, where M is the
20060   * length of the horizontal intersection that the point belongs to.
20061   * @api
20062   */
20063  getInteriorPoint() {
20064    return new geom_Point(this.getFlatInteriorPoint(), 'XYM');
20065  }
20066
20067  /**
20068   * Return the number of rings of the polygon,  this includes the exterior
20069   * ring and any interior rings.
20070   *
20071   * @return {number} Number of rings.
20072   * @api
20073   */
20074  getLinearRingCount() {
20075    return this.ends_.length;
20076  }
20077
20078  /**
20079   * Return the Nth linear ring of the polygon geometry. Return `null` if the
20080   * given index is out of range.
20081   * The exterior linear ring is available at index `0` and the interior rings
20082   * at index `1` and beyond.
20083   *
20084   * @param {number} index Index.
20085   * @return {LinearRing|null} Linear ring.
20086   * @api
20087   */
20088  getLinearRing(index) {
20089    if (index < 0 || this.ends_.length <= index) {
20090      return null;
20091    }
20092    return new geom_LinearRing(
20093      this.flatCoordinates.slice(
20094        index === 0 ? 0 : this.ends_[index - 1],
20095        this.ends_[index]
20096      ),
20097      this.layout
20098    );
20099  }
20100
20101  /**
20102   * Return the linear rings of the polygon.
20103   * @return {Array<LinearRing>} Linear rings.
20104   * @api
20105   */
20106  getLinearRings() {
20107    const layout = this.layout;
20108    const flatCoordinates = this.flatCoordinates;
20109    const ends = this.ends_;
20110    const linearRings = [];
20111    let offset = 0;
20112    for (let i = 0, ii = ends.length; i < ii; ++i) {
20113      const end = ends[i];
20114      const linearRing = new geom_LinearRing(
20115        flatCoordinates.slice(offset, end),
20116        layout
20117      );
20118      linearRings.push(linearRing);
20119      offset = end;
20120    }
20121    return linearRings;
20122  }
20123
20124  /**
20125   * @return {Array<number>} Oriented flat coordinates.
20126   */
20127  getOrientedFlatCoordinates() {
20128    if (this.orientedRevision_ != this.getRevision()) {
20129      const flatCoordinates = this.flatCoordinates;
20130      if (linearRingsAreOriented(flatCoordinates, 0, this.ends_, this.stride)) {
20131        this.orientedFlatCoordinates_ = flatCoordinates;
20132      } else {
20133        this.orientedFlatCoordinates_ = flatCoordinates.slice();
20134        this.orientedFlatCoordinates_.length = orientLinearRings(
20135          this.orientedFlatCoordinates_,
20136          0,
20137          this.ends_,
20138          this.stride
20139        );
20140      }
20141      this.orientedRevision_ = this.getRevision();
20142    }
20143    return this.orientedFlatCoordinates_;
20144  }
20145
20146  /**
20147   * @param {number} squaredTolerance Squared tolerance.
20148   * @return {Polygon} Simplified Polygon.
20149   * @protected
20150   */
20151  getSimplifiedGeometryInternal(squaredTolerance) {
20152    const simplifiedFlatCoordinates = [];
20153    const simplifiedEnds = [];
20154    simplifiedFlatCoordinates.length = quantizeArray(
20155      this.flatCoordinates,
20156      0,
20157      this.ends_,
20158      this.stride,
20159      Math.sqrt(squaredTolerance),
20160      simplifiedFlatCoordinates,
20161      0,
20162      simplifiedEnds
20163    );
20164    return new Polygon(simplifiedFlatCoordinates, 'XY', simplifiedEnds);
20165  }
20166
20167  /**
20168   * Get the type of this geometry.
20169   * @return {import("./Geometry.js").Type} Geometry type.
20170   * @api
20171   */
20172  getType() {
20173    return 'Polygon';
20174  }
20175
20176  /**
20177   * Test if the geometry and the passed extent intersect.
20178   * @param {import("../extent.js").Extent} extent Extent.
20179   * @return {boolean} `true` if the geometry and the extent intersect.
20180   * @api
20181   */
20182  intersectsExtent(extent) {
20183    return intersectsLinearRingArray(
20184      this.getOrientedFlatCoordinates(),
20185      0,
20186      this.ends_,
20187      this.stride,
20188      extent
20189    );
20190  }
20191
20192  /**
20193   * Set the coordinates of the polygon.
20194   * @param {!Array<Array<import("../coordinate.js").Coordinate>>} coordinates Coordinates.
20195   * @param {import("./Geometry.js").GeometryLayout} [layout] Layout.
20196   * @api
20197   */
20198  setCoordinates(coordinates, layout) {
20199    this.setLayout(layout, coordinates, 2);
20200    if (!this.flatCoordinates) {
20201      this.flatCoordinates = [];
20202    }
20203    const ends = deflateCoordinatesArray(
20204      this.flatCoordinates,
20205      0,
20206      coordinates,
20207      this.stride,
20208      this.ends_
20209    );
20210    this.flatCoordinates.length = ends.length === 0 ? 0 : ends[ends.length - 1];
20211    this.changed();
20212  }
20213}
20214
20215/* harmony default export */ const geom_Polygon = (Polygon);
20216
20217/**
20218 * Create an approximation of a circle on the surface of a sphere.
20219 * @param {import("../coordinate.js").Coordinate} center Center (`[lon, lat]` in degrees).
20220 * @param {number} radius The great-circle distance from the center to
20221 *     the polygon vertices in meters.
20222 * @param {number} [n] Optional number of vertices for the resulting
20223 *     polygon. Default is `32`.
20224 * @param {number} [sphereRadius] Optional radius for the sphere (defaults to
20225 *     the Earth's mean radius using the WGS84 ellipsoid).
20226 * @return {Polygon} The "circular" polygon.
20227 * @api
20228 */
20229function circular(center, radius, n, sphereRadius) {
20230  n = n ? n : 32;
20231  /** @type {Array<number>} */
20232  const flatCoordinates = [];
20233  for (let i = 0; i < n; ++i) {
20234    extend(
20235      flatCoordinates,
20236      sphereOffset(center, radius, (2 * Math.PI * i) / n, sphereRadius)
20237    );
20238  }
20239  flatCoordinates.push(flatCoordinates[0], flatCoordinates[1]);
20240  return new Polygon(flatCoordinates, 'XY', [flatCoordinates.length]);
20241}
20242
20243/**
20244 * Create a polygon from an extent. The layout used is `XY`.
20245 * @param {import("../extent.js").Extent} extent The extent.
20246 * @return {Polygon} The polygon.
20247 * @api
20248 */
20249function fromExtent(extent) {
20250  const minX = extent[0];
20251  const minY = extent[1];
20252  const maxX = extent[2];
20253  const maxY = extent[3];
20254  const flatCoordinates = [
20255    minX,
20256    minY,
20257    minX,
20258    maxY,
20259    maxX,
20260    maxY,
20261    maxX,
20262    minY,
20263    minX,
20264    minY,
20265  ];
20266  return new Polygon(flatCoordinates, 'XY', [flatCoordinates.length]);
20267}
20268
20269/**
20270 * Create a regular polygon from a circle.
20271 * @param {import("./Circle.js").default} circle Circle geometry.
20272 * @param {number} [sides] Number of sides of the polygon. Default is 32.
20273 * @param {number} [angle] Start angle for the first vertex of the polygon in
20274 *     counter-clockwise radians. 0 means East. Default is 0.
20275 * @return {Polygon} Polygon geometry.
20276 * @api
20277 */
20278function fromCircle(circle, sides, angle) {
20279  sides = sides ? sides : 32;
20280  const stride = circle.getStride();
20281  const layout = circle.getLayout();
20282  const center = circle.getCenter();
20283  const arrayLength = stride * (sides + 1);
20284  const flatCoordinates = new Array(arrayLength);
20285  for (let i = 0; i < arrayLength; i += stride) {
20286    flatCoordinates[i] = 0;
20287    flatCoordinates[i + 1] = 0;
20288    for (let j = 2; j < stride; j++) {
20289      flatCoordinates[i + j] = center[j];
20290    }
20291  }
20292  const ends = [flatCoordinates.length];
20293  const polygon = new Polygon(flatCoordinates, layout, ends);
20294  makeRegular(polygon, center, circle.getRadius(), angle);
20295  return polygon;
20296}
20297
20298/**
20299 * Modify the coordinates of a polygon to make it a regular polygon.
20300 * @param {Polygon} polygon Polygon geometry.
20301 * @param {import("../coordinate.js").Coordinate} center Center of the regular polygon.
20302 * @param {number} radius Radius of the regular polygon.
20303 * @param {number} [angle] Start angle for the first vertex of the polygon in
20304 *     counter-clockwise radians. 0 means East. Default is 0.
20305 */
20306function makeRegular(polygon, center, radius, angle) {
20307  const flatCoordinates = polygon.getFlatCoordinates();
20308  const stride = polygon.getStride();
20309  const sides = flatCoordinates.length / stride - 1;
20310  const startAngle = angle ? angle : 0;
20311  for (let i = 0; i <= sides; ++i) {
20312    const offset = i * stride;
20313    const angle = startAngle + (modulo(i, sides) * 2 * Math.PI) / sides;
20314    flatCoordinates[offset] = center[0] + radius * Math.cos(angle);
20315    flatCoordinates[offset + 1] = center[1] + radius * Math.sin(angle);
20316  }
20317  polygon.changed();
20318}
20319
20320;// CONCATENATED MODULE: ./node_modules/ol/View.js
20321/**
20322 * @module ol/View
20323 */
20324
20325
20326
20327
20328
20329
20330
20331
20332
20333
20334
20335
20336
20337
20338
20339
20340
20341/**
20342 * An animation configuration
20343 *
20344 * @typedef {Object} Animation
20345 * @property {import("./coordinate.js").Coordinate} [sourceCenter] Source center.
20346 * @property {import("./coordinate.js").Coordinate} [targetCenter] Target center.
20347 * @property {number} [sourceResolution] Source resolution.
20348 * @property {number} [targetResolution] Target resolution.
20349 * @property {number} [sourceRotation] Source rotation.
20350 * @property {number} [targetRotation] Target rotation.
20351 * @property {import("./coordinate.js").Coordinate} [anchor] Anchor.
20352 * @property {number} start Start.
20353 * @property {number} duration Duration.
20354 * @property {boolean} complete Complete.
20355 * @property {function(number):number} easing Easing.
20356 * @property {function(boolean):void} callback Callback.
20357 */
20358
20359/**
20360 * @typedef {Object} Constraints
20361 * @property {import("./centerconstraint.js").Type} center Center.
20362 * @property {import("./resolutionconstraint.js").Type} resolution Resolution.
20363 * @property {import("./rotationconstraint.js").Type} rotation Rotation.
20364 */
20365
20366/**
20367 * @typedef {Object} FitOptions
20368 * @property {import("./size.js").Size} [size] The size in pixels of the box to fit
20369 * the extent into. Default is the current size of the first map in the DOM that
20370 * uses this view, or `[100, 100]` if no such map is found.
20371 * @property {!Array<number>} [padding=[0, 0, 0, 0]] Padding (in pixels) to be
20372 * cleared inside the view. Values in the array are top, right, bottom and left
20373 * padding.
20374 * @property {boolean} [nearest=false] If the view `constrainResolution` option is `true`,
20375 * get the nearest extent instead of the closest that actually fits the view.
20376 * @property {number} [minResolution=0] Minimum resolution that we zoom to.
20377 * @property {number} [maxZoom] Maximum zoom level that we zoom to. If
20378 * `minResolution` is given, this property is ignored.
20379 * @property {number} [duration] The duration of the animation in milliseconds.
20380 * By default, there is no animation to the target extent.
20381 * @property {function(number):number} [easing] The easing function used during
20382 * the animation (defaults to {@link module:ol/easing.inAndOut}).
20383 * The function will be called for each frame with a number representing a
20384 * fraction of the animation's duration.  The function should return a number
20385 * between 0 and 1 representing the progress toward the destination state.
20386 * @property {function(boolean):void} [callback] Function called when the view is in
20387 * its final position. The callback will be called with `true` if the animation
20388 * series completed on its own or `false` if it was cancelled.
20389 */
20390
20391/**
20392 * @typedef {Object} ViewOptions
20393 * @property {import("./coordinate.js").Coordinate} [center] The initial center for
20394 * the view. If a user projection is not set, the coordinate system for the center is
20395 * specified with the `projection` option. Layer sources will not be fetched if this
20396 * is not set, but the center can be set later with {@link #setCenter}.
20397 * @property {boolean|number} [constrainRotation=true] Rotation constraint.
20398 * `false` means no constraint. `true` means no constraint, but snap to zero
20399 * near zero. A number constrains the rotation to that number of values. For
20400 * example, `4` will constrain the rotation to 0, 90, 180, and 270 degrees.
20401 * @property {boolean} [enableRotation=true] Enable rotation.
20402 * If `false`, a rotation constraint that always sets the rotation to zero is
20403 * used. The `constrainRotation` option has no effect if `enableRotation` is
20404 * `false`.
20405 * @property {import("./extent.js").Extent} [extent] The extent that constrains the
20406 * view, in other words, nothing outside of this extent can be visible on the map.
20407 * @property {boolean} [constrainOnlyCenter=false] If true, the extent
20408 * constraint will only apply to the view center and not the whole extent.
20409 * @property {boolean} [smoothExtentConstraint=true] If true, the extent
20410 * constraint will be applied smoothly, i.e. allow the view to go slightly outside
20411 * of the given `extent`.
20412 * @property {number} [maxResolution] The maximum resolution used to determine
20413 * the resolution constraint. It is used together with `minResolution` (or
20414 * `maxZoom`) and `zoomFactor`. If unspecified it is calculated in such a way
20415 * that the projection's validity extent fits in a 256x256 px tile. If the
20416 * projection is Spherical Mercator (the default) then `maxResolution` defaults
20417 * to `40075016.68557849 / 256 = 156543.03392804097`.
20418 * @property {number} [minResolution] The minimum resolution used to determine
20419 * the resolution constraint.  It is used together with `maxResolution` (or
20420 * `minZoom`) and `zoomFactor`.  If unspecified it is calculated assuming 29
20421 * zoom levels (with a factor of 2). If the projection is Spherical Mercator
20422 * (the default) then `minResolution` defaults to
20423 * `40075016.68557849 / 256 / Math.pow(2, 28) = 0.0005831682455839253`.
20424 * @property {number} [maxZoom=28] The maximum zoom level used to determine the
20425 * resolution constraint. It is used together with `minZoom` (or
20426 * `maxResolution`) and `zoomFactor`.  Note that if `minResolution` is also
20427 * provided, it is given precedence over `maxZoom`.
20428 * @property {number} [minZoom=0] The minimum zoom level used to determine the
20429 * resolution constraint. It is used together with `maxZoom` (or
20430 * `minResolution`) and `zoomFactor`.  Note that if `maxResolution` is also
20431 * provided, it is given precedence over `minZoom`.
20432 * @property {boolean} [multiWorld=false] If `false` the view is constrained so
20433 * only one world is visible, and you cannot pan off the edge.  If `true` the map
20434 * may show multiple worlds at low zoom levels.  Only used if the `projection` is
20435 * global.  Note that if `extent` is also provided it is given precedence.
20436 * @property {boolean} [constrainResolution=false] If true, the view will always
20437 * animate to the closest zoom level after an interaction; false means
20438 * intermediary zoom levels are allowed.
20439 * @property {boolean} [smoothResolutionConstraint=true] If true, the resolution
20440 * min/max values will be applied smoothly, i. e. allow the view to exceed slightly
20441 * the given resolution or zoom bounds.
20442 * @property {boolean} [showFullExtent=false] Allow the view to be zoomed out to
20443 * show the full configured extent. By default, when a view is configured with an
20444 * extent, users will not be able to zoom out so the viewport exceeds the extent in
20445 * either dimension. This means the full extent may not be visible if the viewport
20446 * is taller or wider than the aspect ratio of the configured extent. If
20447 * showFullExtent is true, the user will be able to zoom out so that the viewport
20448 * exceeds the height or width of the configured extent, but not both, allowing the
20449 * full extent to be shown.
20450 * @property {import("./proj.js").ProjectionLike} [projection='EPSG:3857'] The
20451 * projection. The default is Spherical Mercator.
20452 * @property {number} [resolution] The initial resolution for the view. The
20453 * units are `projection` units per pixel (e.g. meters per pixel). An
20454 * alternative to setting this is to set `zoom`. Layer sources will not be
20455 * fetched if neither this nor `zoom` are defined, but they can be set later
20456 * with {@link #setZoom} or {@link #setResolution}.
20457 * @property {Array<number>} [resolutions] Resolutions that determine the
20458 * zoom levels if specified. The index in the array corresponds to the zoom level,
20459 * therefore the resolution values have to be in descending order. It also constrains
20460 * the resolution by the minimum and maximum value. If set the `maxResolution`,
20461 * `minResolution`, `minZoom`, `maxZoom`, and `zoomFactor` options are ignored.
20462 * @property {number} [rotation=0] The initial rotation for the view in radians
20463 * (positive rotation clockwise, 0 means North).
20464 * @property {number} [zoom] Only used if `resolution` is not defined. Zoom
20465 * level used to calculate the initial resolution for the view.
20466 * @property {number} [zoomFactor=2] The zoom factor used to compute the
20467 * corresponding resolution.
20468 * @property {!Array<number>} [padding=[0, 0, 0, 0]] Padding (in css pixels).
20469 * If the map viewport is partially covered with other content (overlays) along
20470 * its edges, this setting allows to shift the center of the viewport away from
20471 * that content. The order of the values is top, right, bottom, left.
20472 */
20473
20474/**
20475 * @typedef {Object} AnimationOptions
20476 * @property {import("./coordinate.js").Coordinate} [center] The center of the view at the end of
20477 * the animation.
20478 * @property {number} [zoom] The zoom level of the view at the end of the
20479 * animation. This takes precedence over `resolution`.
20480 * @property {number} [resolution] The resolution of the view at the end
20481 * of the animation.  If `zoom` is also provided, this option will be ignored.
20482 * @property {number} [rotation] The rotation of the view at the end of
20483 * the animation.
20484 * @property {import("./coordinate.js").Coordinate} [anchor] Optional anchor to remain fixed
20485 * during a rotation or resolution animation.
20486 * @property {number} [duration=1000] The duration of the animation in milliseconds.
20487 * @property {function(number):number} [easing] The easing function used
20488 * during the animation (defaults to {@link module:ol/easing.inAndOut}).
20489 * The function will be called for each frame with a number representing a
20490 * fraction of the animation's duration.  The function should return a number
20491 * between 0 and 1 representing the progress toward the destination state.
20492 */
20493
20494/**
20495 * @typedef {Object} State
20496 * @property {import("./coordinate.js").Coordinate} center Center.
20497 * @property {import("./proj/Projection.js").default} projection Projection.
20498 * @property {number} resolution Resolution.
20499 * @property {import("./coordinate.js").Coordinate} [nextCenter] The next center during an animation series.
20500 * @property {number} [nextResolution] The next resolution during an animation series.
20501 * @property {number} [nextRotation] The next rotation during an animation series.
20502 * @property {number} rotation Rotation.
20503 * @property {number} zoom Zoom.
20504 */
20505
20506/**
20507 * Default min zoom level for the map view.
20508 * @type {number}
20509 */
20510const DEFAULT_MIN_ZOOM = 0;
20511
20512/**
20513 * @typedef {import("./ObjectEventType").Types|'change:center'|'change:resolution'|'change:rotation'} ViewObjectEventTypes
20514 */
20515
20516/***
20517 * @template Return
20518 * @typedef {import("./Observable").OnSignature<import("./Observable").EventTypes, import("./events/Event.js").default, Return> &
20519 *   import("./Observable").OnSignature<ViewObjectEventTypes, import("./Object").ObjectEvent, Return> &
20520 *   import("./Observable").CombinedOnSignature<import("./Observable").EventTypes|ViewObjectEventTypes, Return>} ViewOnSignature
20521 */
20522
20523/**
20524 * @classdesc
20525 * A View object represents a simple 2D view of the map.
20526 *
20527 * This is the object to act upon to change the center, resolution,
20528 * and rotation of the map.
20529 *
20530 * A View has a `projection`. The projection determines the
20531 * coordinate system of the center, and its units determine the units of the
20532 * resolution (projection units per pixel). The default projection is
20533 * Web Mercator (EPSG:3857).
20534 *
20535 * ### The view states
20536 *
20537 * A View is determined by three states: `center`, `resolution`,
20538 * and `rotation`. Each state has a corresponding getter and setter, e.g.
20539 * `getCenter` and `setCenter` for the `center` state.
20540 *
20541 * The `zoom` state is actually not saved on the view: all computations
20542 * internally use the `resolution` state. Still, the `setZoom` and `getZoom`
20543 * methods are available, as well as `getResolutionForZoom` and
20544 * `getZoomForResolution` to switch from one system to the other.
20545 *
20546 * ### The constraints
20547 *
20548 * `setCenter`, `setResolution` and `setRotation` can be used to change the
20549 * states of the view, but any constraint defined in the constructor will
20550 * be applied along the way.
20551 *
20552 * A View object can have a *resolution constraint*, a *rotation constraint*
20553 * and a *center constraint*.
20554 *
20555 * The *resolution constraint* typically restricts min/max values and
20556 * snaps to specific resolutions. It is determined by the following
20557 * options: `resolutions`, `maxResolution`, `maxZoom` and `zoomFactor`.
20558 * If `resolutions` is set, the other three options are ignored. See
20559 * documentation for each option for more information. By default, the view
20560 * only has a min/max restriction and allow intermediary zoom levels when
20561 * pinch-zooming for example.
20562 *
20563 * The *rotation constraint* snaps to specific angles. It is determined
20564 * by the following options: `enableRotation` and `constrainRotation`.
20565 * By default rotation is allowed and its value is snapped to zero when approaching the
20566 * horizontal.
20567 *
20568 * The *center constraint* is determined by the `extent` option. By
20569 * default the view center is not constrained at all.
20570 *
20571 * ### Changing the view state
20572 *
20573 * It is important to note that `setZoom`, `setResolution`, `setCenter` and
20574 * `setRotation` are subject to the above mentioned constraints. As such, it
20575 * may sometimes not be possible to know in advance the resulting state of the
20576 * View. For example, calling `setResolution(10)` does not guarantee that
20577 * `getResolution()` will return `10`.
20578 *
20579 * A consequence of this is that, when applying a delta on the view state, one
20580 * should use `adjustCenter`, `adjustRotation`, `adjustZoom` and `adjustResolution`
20581 * rather than the corresponding setters. This will let view do its internal
20582 * computations. Besides, the `adjust*` methods also take an `anchor`
20583 * argument which allows specifying an origin for the transformation.
20584 *
20585 * ### Interacting with the view
20586 *
20587 * View constraints are usually only applied when the view is *at rest*, meaning that
20588 * no interaction or animation is ongoing. As such, if the user puts the view in a
20589 * state that is not equivalent to a constrained one (e.g. rotating the view when
20590 * the snap angle is 0), an animation will be triggered at the interaction end to
20591 * put back the view to a stable state;
20592 *
20593 * @api
20594 */
20595class View extends ol_Object {
20596  /**
20597   * @param {ViewOptions} [options] View options.
20598   */
20599  constructor(options) {
20600    super();
20601
20602    /***
20603     * @type {ViewOnSignature<import("./events").EventsKey>}
20604     */
20605    this.on;
20606
20607    /***
20608     * @type {ViewOnSignature<import("./events").EventsKey>}
20609     */
20610    this.once;
20611
20612    /***
20613     * @type {ViewOnSignature<void>}
20614     */
20615    this.un;
20616
20617    options = Object.assign({}, options);
20618
20619    /**
20620     * @private
20621     * @type {Array<number>}
20622     */
20623    this.hints_ = [0, 0];
20624
20625    /**
20626     * @private
20627     * @type {Array<Array<Animation>>}
20628     */
20629    this.animations_ = [];
20630
20631    /**
20632     * @private
20633     * @type {number|undefined}
20634     */
20635    this.updateAnimationKey_;
20636
20637    /**
20638     * @private
20639     * @const
20640     * @type {import("./proj/Projection.js").default}
20641     */
20642    this.projection_ = createProjection(options.projection, 'EPSG:3857');
20643
20644    /**
20645     * @private
20646     * @type {import("./size.js").Size}
20647     */
20648    this.viewportSize_ = [100, 100];
20649
20650    /**
20651     * @private
20652     * @type {import("./coordinate.js").Coordinate|undefined}
20653     */
20654    this.targetCenter_ = null;
20655
20656    /**
20657     * @private
20658     * @type {number|undefined}
20659     */
20660    this.targetResolution_;
20661
20662    /**
20663     * @private
20664     * @type {number|undefined}
20665     */
20666    this.targetRotation_;
20667
20668    /**
20669     * @private
20670     * @type {import("./coordinate.js").Coordinate}
20671     */
20672    this.nextCenter_ = null;
20673
20674    /**
20675     * @private
20676     * @type {number}
20677     */
20678    this.nextResolution_;
20679
20680    /**
20681     * @private
20682     * @type {number}
20683     */
20684    this.nextRotation_;
20685
20686    /**
20687     * @private
20688     * @type {import("./coordinate.js").Coordinate|undefined}
20689     */
20690    this.cancelAnchor_ = undefined;
20691
20692    if (options.projection) {
20693      disableCoordinateWarning();
20694    }
20695    if (options.center) {
20696      options.center = fromUserCoordinate(options.center, this.projection_);
20697    }
20698    if (options.extent) {
20699      options.extent = proj_fromUserExtent(options.extent, this.projection_);
20700    }
20701
20702    this.applyOptions_(options);
20703  }
20704
20705  /**
20706   * Set up the view with the given options.
20707   * @param {ViewOptions} options View options.
20708   */
20709  applyOptions_(options) {
20710    const properties = Object.assign({}, options);
20711    for (const key in ViewProperty) {
20712      delete properties[key];
20713    }
20714    this.setProperties(properties, true);
20715
20716    const resolutionConstraintInfo = createResolutionConstraint(options);
20717
20718    /**
20719     * @private
20720     * @type {number}
20721     */
20722    this.maxResolution_ = resolutionConstraintInfo.maxResolution;
20723
20724    /**
20725     * @private
20726     * @type {number}
20727     */
20728    this.minResolution_ = resolutionConstraintInfo.minResolution;
20729
20730    /**
20731     * @private
20732     * @type {number}
20733     */
20734    this.zoomFactor_ = resolutionConstraintInfo.zoomFactor;
20735
20736    /**
20737     * @private
20738     * @type {Array<number>|undefined}
20739     */
20740    this.resolutions_ = options.resolutions;
20741
20742    /**
20743     * @type {Array<number>|undefined}
20744     * @private
20745     */
20746    this.padding_ = options.padding;
20747
20748    /**
20749     * @private
20750     * @type {number}
20751     */
20752    this.minZoom_ = resolutionConstraintInfo.minZoom;
20753
20754    const centerConstraint = createCenterConstraint(options);
20755    const resolutionConstraint = resolutionConstraintInfo.constraint;
20756    const rotationConstraint = createRotationConstraint(options);
20757
20758    /**
20759     * @private
20760     * @type {Constraints}
20761     */
20762    this.constraints_ = {
20763      center: centerConstraint,
20764      resolution: resolutionConstraint,
20765      rotation: rotationConstraint,
20766    };
20767
20768    this.setRotation(options.rotation !== undefined ? options.rotation : 0);
20769    this.setCenterInternal(
20770      options.center !== undefined ? options.center : null
20771    );
20772    if (options.resolution !== undefined) {
20773      this.setResolution(options.resolution);
20774    } else if (options.zoom !== undefined) {
20775      this.setZoom(options.zoom);
20776    }
20777  }
20778
20779  /**
20780   * Padding (in css pixels).
20781   * If the map viewport is partially covered with other content (overlays) along
20782   * its edges, this setting allows to shift the center of the viewport away from that
20783   * content. The order of the values in the array is top, right, bottom, left.
20784   * The default is no padding, which is equivalent to `[0, 0, 0, 0]`.
20785   * @type {Array<number>|undefined}
20786   * @api
20787   */
20788  get padding() {
20789    return this.padding_;
20790  }
20791  set padding(padding) {
20792    let oldPadding = this.padding_;
20793    this.padding_ = padding;
20794    const center = this.getCenter();
20795    if (center) {
20796      const newPadding = padding || [0, 0, 0, 0];
20797      oldPadding = oldPadding || [0, 0, 0, 0];
20798      const resolution = this.getResolution();
20799      const offsetX =
20800        (resolution / 2) *
20801        (newPadding[3] - oldPadding[3] + oldPadding[1] - newPadding[1]);
20802      const offsetY =
20803        (resolution / 2) *
20804        (newPadding[0] - oldPadding[0] + oldPadding[2] - newPadding[2]);
20805      this.setCenterInternal([center[0] + offsetX, center[1] - offsetY]);
20806    }
20807  }
20808
20809  /**
20810   * Get an updated version of the view options used to construct the view.  The
20811   * current resolution (or zoom), center, and rotation are applied to any stored
20812   * options.  The provided options can be used to apply new min/max zoom or
20813   * resolution limits.
20814   * @param {ViewOptions} newOptions New options to be applied.
20815   * @return {ViewOptions} New options updated with the current view state.
20816   */
20817  getUpdatedOptions_(newOptions) {
20818    const options = this.getProperties();
20819
20820    // preserve resolution (or zoom)
20821    if (options.resolution !== undefined) {
20822      options.resolution = this.getResolution();
20823    } else {
20824      options.zoom = this.getZoom();
20825    }
20826
20827    // preserve center
20828    options.center = this.getCenterInternal();
20829
20830    // preserve rotation
20831    options.rotation = this.getRotation();
20832
20833    return Object.assign({}, options, newOptions);
20834  }
20835
20836  /**
20837   * Animate the view.  The view's center, zoom (or resolution), and rotation
20838   * can be animated for smooth transitions between view states.  For example,
20839   * to animate the view to a new zoom level:
20840   *
20841   *     view.animate({zoom: view.getZoom() + 1});
20842   *
20843   * By default, the animation lasts one second and uses in-and-out easing.  You
20844   * can customize this behavior by including `duration` (in milliseconds) and
20845   * `easing` options (see {@link module:ol/easing}).
20846   *
20847   * To chain together multiple animations, call the method with multiple
20848   * animation objects.  For example, to first zoom and then pan:
20849   *
20850   *     view.animate({zoom: 10}, {center: [0, 0]});
20851   *
20852   * If you provide a function as the last argument to the animate method, it
20853   * will get called at the end of an animation series.  The callback will be
20854   * called with `true` if the animation series completed on its own or `false`
20855   * if it was cancelled.
20856   *
20857   * Animations are cancelled by user interactions (e.g. dragging the map) or by
20858   * calling `view.setCenter()`, `view.setResolution()`, or `view.setRotation()`
20859   * (or another method that calls one of these).
20860   *
20861   * @param {...(AnimationOptions|function(boolean): void)} var_args Animation
20862   *     options.  Multiple animations can be run in series by passing multiple
20863   *     options objects.  To run multiple animations in parallel, call the method
20864   *     multiple times.  An optional callback can be provided as a final
20865   *     argument.  The callback will be called with a boolean indicating whether
20866   *     the animation completed without being cancelled.
20867   * @api
20868   */
20869  animate(var_args) {
20870    if (this.isDef() && !this.getAnimating()) {
20871      this.resolveConstraints(0);
20872    }
20873    const args = new Array(arguments.length);
20874    for (let i = 0; i < args.length; ++i) {
20875      let options = arguments[i];
20876      if (options.center) {
20877        options = Object.assign({}, options);
20878        options.center = fromUserCoordinate(
20879          options.center,
20880          this.getProjection()
20881        );
20882      }
20883      if (options.anchor) {
20884        options = Object.assign({}, options);
20885        options.anchor = fromUserCoordinate(
20886          options.anchor,
20887          this.getProjection()
20888        );
20889      }
20890      args[i] = options;
20891    }
20892    this.animateInternal.apply(this, args);
20893  }
20894
20895  /**
20896   * @param {...(AnimationOptions|function(boolean): void)} var_args Animation options.
20897   */
20898  animateInternal(var_args) {
20899    let animationCount = arguments.length;
20900    let callback;
20901    if (
20902      animationCount > 1 &&
20903      typeof arguments[animationCount - 1] === 'function'
20904    ) {
20905      callback = arguments[animationCount - 1];
20906      --animationCount;
20907    }
20908
20909    let i = 0;
20910    for (; i < animationCount && !this.isDef(); ++i) {
20911      // if view properties are not yet set, shortcut to the final state
20912      const state = arguments[i];
20913      if (state.center) {
20914        this.setCenterInternal(state.center);
20915      }
20916      if (state.zoom !== undefined) {
20917        this.setZoom(state.zoom);
20918      } else if (state.resolution) {
20919        this.setResolution(state.resolution);
20920      }
20921      if (state.rotation !== undefined) {
20922        this.setRotation(state.rotation);
20923      }
20924    }
20925    if (i === animationCount) {
20926      if (callback) {
20927        animationCallback(callback, true);
20928      }
20929      return;
20930    }
20931
20932    let start = Date.now();
20933    let center = this.targetCenter_.slice();
20934    let resolution = this.targetResolution_;
20935    let rotation = this.targetRotation_;
20936    const series = [];
20937    for (; i < animationCount; ++i) {
20938      const options = /** @type {AnimationOptions} */ (arguments[i]);
20939
20940      const animation = {
20941        start: start,
20942        complete: false,
20943        anchor: options.anchor,
20944        duration: options.duration !== undefined ? options.duration : 1000,
20945        easing: options.easing || inAndOut,
20946        callback: callback,
20947      };
20948
20949      if (options.center) {
20950        animation.sourceCenter = center;
20951        animation.targetCenter = options.center.slice();
20952        center = animation.targetCenter;
20953      }
20954
20955      if (options.zoom !== undefined) {
20956        animation.sourceResolution = resolution;
20957        animation.targetResolution = this.getResolutionForZoom(options.zoom);
20958        resolution = animation.targetResolution;
20959      } else if (options.resolution) {
20960        animation.sourceResolution = resolution;
20961        animation.targetResolution = options.resolution;
20962        resolution = animation.targetResolution;
20963      }
20964
20965      if (options.rotation !== undefined) {
20966        animation.sourceRotation = rotation;
20967        const delta =
20968          math_modulo(options.rotation - rotation + Math.PI, 2 * Math.PI) - Math.PI;
20969        animation.targetRotation = rotation + delta;
20970        rotation = animation.targetRotation;
20971      }
20972
20973      // check if animation is a no-op
20974      if (isNoopAnimation(animation)) {
20975        animation.complete = true;
20976        // we still push it onto the series for callback handling
20977      } else {
20978        start += animation.duration;
20979      }
20980      series.push(animation);
20981    }
vendor: 31,292 bytes, lines 20982-21982
20982    this.animations_.push(series);
20983    this.setHint(ViewHint.ANIMATING, 1);
20984    this.updateAnimations_();
20985  }
20986
20987  /**
20988   * Determine if the view is being animated.
20989   * @return {boolean} The view is being animated.
20990   * @api
20991   */
20992  getAnimating() {
20993    return this.hints_[ViewHint.ANIMATING] > 0;
20994  }
20995
20996  /**
20997   * Determine if the user is interacting with the view, such as panning or zooming.
20998   * @return {boolean} The view is being interacted with.
20999   * @api
21000   */
21001  getInteracting() {
21002    return this.hints_[ViewHint.INTERACTING] > 0;
21003  }
21004
21005  /**
21006   * Cancel any ongoing animations.
21007   * @api
21008   */
21009  cancelAnimations() {
21010    this.setHint(ViewHint.ANIMATING, -this.hints_[ViewHint.ANIMATING]);
21011    let anchor;
21012    for (let i = 0, ii = this.animations_.length; i < ii; ++i) {
21013      const series = this.animations_[i];
21014      if (series[0].callback) {
21015        animationCallback(series[0].callback, false);
21016      }
21017      if (!anchor) {
21018        for (let j = 0, jj = series.length; j < jj; ++j) {
21019          const animation = series[j];
21020          if (!animation.complete) {
21021            anchor = animation.anchor;
21022            break;
21023          }
21024        }
21025      }
21026    }
21027    this.animations_.length = 0;
21028    this.cancelAnchor_ = anchor;
21029    this.nextCenter_ = null;
21030    this.nextResolution_ = NaN;
21031    this.nextRotation_ = NaN;
21032  }
21033
21034  /**
21035   * Update all animations.
21036   */
21037  updateAnimations_() {
21038    if (this.updateAnimationKey_ !== undefined) {
21039      cancelAnimationFrame(this.updateAnimationKey_);
21040      this.updateAnimationKey_ = undefined;
21041    }
21042    if (!this.getAnimating()) {
21043      return;
21044    }
21045    const now = Date.now();
21046    let more = false;
21047    for (let i = this.animations_.length - 1; i >= 0; --i) {
21048      const series = this.animations_[i];
21049      let seriesComplete = true;
21050      for (let j = 0, jj = series.length; j < jj; ++j) {
21051        const animation = series[j];
21052        if (animation.complete) {
21053          continue;
21054        }
21055        const elapsed = now - animation.start;
21056        let fraction =
21057          animation.duration > 0 ? elapsed / animation.duration : 1;
21058        if (fraction >= 1) {
21059          animation.complete = true;
21060          fraction = 1;
21061        } else {
21062          seriesComplete = false;
21063        }
21064        const progress = animation.easing(fraction);
21065        if (animation.sourceCenter) {
21066          const x0 = animation.sourceCenter[0];
21067          const y0 = animation.sourceCenter[1];
21068          const x1 = animation.targetCenter[0];
21069          const y1 = animation.targetCenter[1];
21070          this.nextCenter_ = animation.targetCenter;
21071          const x = x0 + progress * (x1 - x0);
21072          const y = y0 + progress * (y1 - y0);
21073          this.targetCenter_ = [x, y];
21074        }
21075        if (animation.sourceResolution && animation.targetResolution) {
21076          const resolution =
21077            progress === 1
21078              ? animation.targetResolution
21079              : animation.sourceResolution +
21080                progress *
21081                  (animation.targetResolution - animation.sourceResolution);
21082          if (animation.anchor) {
21083            const size = this.getViewportSize_(this.getRotation());
21084            const constrainedResolution = this.constraints_.resolution(
21085              resolution,
21086              0,
21087              size,
21088              true
21089            );
21090            this.targetCenter_ = this.calculateCenterZoom(
21091              constrainedResolution,
21092              animation.anchor
21093            );
21094          }
21095          this.nextResolution_ = animation.targetResolution;
21096          this.targetResolution_ = resolution;
21097          this.applyTargetState_(true);
21098        }
21099        if (
21100          animation.sourceRotation !== undefined &&
21101          animation.targetRotation !== undefined
21102        ) {
21103          const rotation =
21104            progress === 1
21105              ? math_modulo(animation.targetRotation + Math.PI, 2 * Math.PI) -
21106                Math.PI
21107              : animation.sourceRotation +
21108                progress *
21109                  (animation.targetRotation - animation.sourceRotation);
21110          if (animation.anchor) {
21111            const constrainedRotation = this.constraints_.rotation(
21112              rotation,
21113              true
21114            );
21115            this.targetCenter_ = this.calculateCenterRotate(
21116              constrainedRotation,
21117              animation.anchor
21118            );
21119          }
21120          this.nextRotation_ = animation.targetRotation;
21121          this.targetRotation_ = rotation;
21122        }
21123        this.applyTargetState_(true);
21124        more = true;
21125        if (!animation.complete) {
21126          break;
21127        }
21128      }
21129      if (seriesComplete) {
21130        this.animations_[i] = null;
21131        this.setHint(ViewHint.ANIMATING, -1);
21132        this.nextCenter_ = null;
21133        this.nextResolution_ = NaN;
21134        this.nextRotation_ = NaN;
21135        const callback = series[0].callback;
21136        if (callback) {
21137          animationCallback(callback, true);
21138        }
21139      }
21140    }
21141    // prune completed series
21142    this.animations_ = this.animations_.filter(Boolean);
21143    if (more && this.updateAnimationKey_ === undefined) {
21144      this.updateAnimationKey_ = requestAnimationFrame(
21145        this.updateAnimations_.bind(this)
21146      );
21147    }
21148  }
21149
21150  /**
21151   * @param {number} rotation Target rotation.
21152   * @param {import("./coordinate.js").Coordinate} anchor Rotation anchor.
21153   * @return {import("./coordinate.js").Coordinate|undefined} Center for rotation and anchor.
21154   */
21155  calculateCenterRotate(rotation, anchor) {
21156    let center;
21157    const currentCenter = this.getCenterInternal();
21158    if (currentCenter !== undefined) {
21159      center = [currentCenter[0] - anchor[0], currentCenter[1] - anchor[1]];
21160      rotate(center, rotation - this.getRotation());
21161      coordinate_add(center, anchor);
21162    }
21163    return center;
21164  }
21165
21166  /**
21167   * @param {number} resolution Target resolution.
21168   * @param {import("./coordinate.js").Coordinate} anchor Zoom anchor.
21169   * @return {import("./coordinate.js").Coordinate|undefined} Center for resolution and anchor.
21170   */
21171  calculateCenterZoom(resolution, anchor) {
21172    let center;
21173    const currentCenter = this.getCenterInternal();
21174    const currentResolution = this.getResolution();
21175    if (currentCenter !== undefined && currentResolution !== undefined) {
21176      const x =
21177        anchor[0] -
21178        (resolution * (anchor[0] - currentCenter[0])) / currentResolution;
21179      const y =
21180        anchor[1] -
21181        (resolution * (anchor[1] - currentCenter[1])) / currentResolution;
21182      center = [x, y];
21183    }
21184    return center;
21185  }
21186
21187  /**
21188   * Returns the current viewport size.
21189   * @private
21190   * @param {number} [rotation] Take into account the rotation of the viewport when giving the size
21191   * @return {import("./size.js").Size} Viewport size or `[100, 100]` when no viewport is found.
21192   */
21193  getViewportSize_(rotation) {
21194    const size = this.viewportSize_;
21195    if (rotation) {
21196      const w = size[0];
21197      const h = size[1];
21198      return [
21199        Math.abs(w * Math.cos(rotation)) + Math.abs(h * Math.sin(rotation)),
21200        Math.abs(w * Math.sin(rotation)) + Math.abs(h * Math.cos(rotation)),
21201      ];
21202    } else {
21203      return size;
21204    }
21205  }
21206
21207  /**
21208   * Stores the viewport size on the view. The viewport size is not read every time from the DOM
21209   * to avoid performance hit and layout reflow.
21210   * This should be done on map size change.
21211   * Note: the constraints are not resolved during an animation to avoid stopping it
21212   * @param {import("./size.js").Size} [size] Viewport size; if undefined, [100, 100] is assumed
21213   */
21214  setViewportSize(size) {
21215    this.viewportSize_ = Array.isArray(size) ? size.slice() : [100, 100];
21216    if (!this.getAnimating()) {
21217      this.resolveConstraints(0);
21218    }
21219  }
21220
21221  /**
21222   * Get the view center.
21223   * @return {import("./coordinate.js").Coordinate|undefined} The center of the view.
21224   * @observable
21225   * @api
21226   */
21227  getCenter() {
21228    const center = this.getCenterInternal();
21229    if (!center) {
21230      return center;
21231    }
21232    return toUserCoordinate(center, this.getProjection());
21233  }
21234
21235  /**
21236   * Get the view center without transforming to user projection.
21237   * @return {import("./coordinate.js").Coordinate|undefined} The center of the view.
21238   */
21239  getCenterInternal() {
21240    return /** @type {import("./coordinate.js").Coordinate|undefined} */ (
21241      this.get(ViewProperty.CENTER)
21242    );
21243  }
21244
21245  /**
21246   * @return {Constraints} Constraints.
21247   */
21248  getConstraints() {
21249    return this.constraints_;
21250  }
21251
21252  /**
21253   * @return {boolean} Resolution constraint is set
21254   */
21255  getConstrainResolution() {
21256    return this.get('constrainResolution');
21257  }
21258
21259  /**
21260   * @param {Array<number>} [hints] Destination array.
21261   * @return {Array<number>} Hint.
21262   */
21263  getHints(hints) {
21264    if (hints !== undefined) {
21265      hints[0] = this.hints_[0];
21266      hints[1] = this.hints_[1];
21267      return hints;
21268    } else {
21269      return this.hints_.slice();
21270    }
21271  }
21272
21273  /**
21274   * Calculate the extent for the current view state and the passed size.
21275   * The size is the pixel dimensions of the box into which the calculated extent
21276   * should fit. In most cases you want to get the extent of the entire map,
21277   * that is `map.getSize()`.
21278   * @param {import("./size.js").Size} [size] Box pixel size. If not provided, the size
21279   * of the map that uses this view will be used.
21280   * @return {import("./extent.js").Extent} Extent.
21281   * @api
21282   */
21283  calculateExtent(size) {
21284    const extent = this.calculateExtentInternal(size);
21285    return proj_toUserExtent(extent, this.getProjection());
21286  }
21287
21288  /**
21289   * @param {import("./size.js").Size} [size] Box pixel size. If not provided,
21290   * the map's last known viewport size will be used.
21291   * @return {import("./extent.js").Extent} Extent.
21292   */
21293  calculateExtentInternal(size) {
21294    size = size || this.getViewportSizeMinusPadding_();
21295    const center = /** @type {!import("./coordinate.js").Coordinate} */ (
21296      this.getCenterInternal()
21297    );
21298    asserts_assert(center, 1); // The view center is not defined
21299    const resolution = /** @type {!number} */ (this.getResolution());
21300    asserts_assert(resolution !== undefined, 2); // The view resolution is not defined
21301    const rotation = /** @type {!number} */ (this.getRotation());
21302    asserts_assert(rotation !== undefined, 3); // The view rotation is not defined
21303
21304    return getForViewAndSize(center, resolution, rotation, size);
21305  }
21306
21307  /**
21308   * Get the maximum resolution of the view.
21309   * @return {number} The maximum resolution of the view.
21310   * @api
21311   */
21312  getMaxResolution() {
21313    return this.maxResolution_;
21314  }
21315
21316  /**
21317   * Get the minimum resolution of the view.
21318   * @return {number} The minimum resolution of the view.
21319   * @api
21320   */
21321  getMinResolution() {
21322    return this.minResolution_;
21323  }
21324
21325  /**
21326   * Get the maximum zoom level for the view.
21327   * @return {number} The maximum zoom level.
21328   * @api
21329   */
21330  getMaxZoom() {
21331    return /** @type {number} */ (
21332      this.getZoomForResolution(this.minResolution_)
21333    );
21334  }
21335
21336  /**
21337   * Set a new maximum zoom level for the view.
21338   * @param {number} zoom The maximum zoom level.
21339   * @api
21340   */
21341  setMaxZoom(zoom) {
21342    this.applyOptions_(this.getUpdatedOptions_({maxZoom: zoom}));
21343  }
21344
21345  /**
21346   * Get the minimum zoom level for the view.
21347   * @return {number} The minimum zoom level.
21348   * @api
21349   */
21350  getMinZoom() {
21351    return /** @type {number} */ (
21352      this.getZoomForResolution(this.maxResolution_)
21353    );
21354  }
21355
21356  /**
21357   * Set a new minimum zoom level for the view.
21358   * @param {number} zoom The minimum zoom level.
21359   * @api
21360   */
21361  setMinZoom(zoom) {
21362    this.applyOptions_(this.getUpdatedOptions_({minZoom: zoom}));
21363  }
21364
21365  /**
21366   * Set whether the view should allow intermediary zoom levels.
21367   * @param {boolean} enabled Whether the resolution is constrained.
21368   * @api
21369   */
21370  setConstrainResolution(enabled) {
21371    this.applyOptions_(this.getUpdatedOptions_({constrainResolution: enabled}));
21372  }
21373
21374  /**
21375   * Get the view projection.
21376   * @return {import("./proj/Projection.js").default} The projection of the view.
21377   * @api
21378   */
21379  getProjection() {
21380    return this.projection_;
21381  }
21382
21383  /**
21384   * Get the view resolution.
21385   * @return {number|undefined} The resolution of the view.
21386   * @observable
21387   * @api
21388   */
21389  getResolution() {
21390    return /** @type {number|undefined} */ (this.get(ViewProperty.RESOLUTION));
21391  }
21392
21393  /**
21394   * Get the resolutions for the view. This returns the array of resolutions
21395   * passed to the constructor of the View, or undefined if none were given.
21396   * @return {Array<number>|undefined} The resolutions of the view.
21397   * @api
21398   */
21399  getResolutions() {
21400    return this.resolutions_;
21401  }
21402
21403  /**
21404   * Get the resolution for a provided extent (in map units) and size (in pixels).
21405   * @param {import("./extent.js").Extent} extent Extent.
21406   * @param {import("./size.js").Size} [size] Box pixel size.
21407   * @return {number} The resolution at which the provided extent will render at
21408   *     the given size.
21409   * @api
21410   */
21411  getResolutionForExtent(extent, size) {
21412    return this.getResolutionForExtentInternal(
21413      proj_fromUserExtent(extent, this.getProjection()),
21414      size
21415    );
21416  }
21417
21418  /**
21419   * Get the resolution for a provided extent (in map units) and size (in pixels).
21420   * @param {import("./extent.js").Extent} extent Extent.
21421   * @param {import("./size.js").Size} [size] Box pixel size.
21422   * @return {number} The resolution at which the provided extent will render at
21423   *     the given size.
21424   */
21425  getResolutionForExtentInternal(extent, size) {
21426    size = size || this.getViewportSizeMinusPadding_();
21427    const xResolution = extent_getWidth(extent) / size[0];
21428    const yResolution = extent_getHeight(extent) / size[1];
21429    return Math.max(xResolution, yResolution);
21430  }
21431
21432  /**
21433   * Return a function that returns a value between 0 and 1 for a
21434   * resolution. Exponential scaling is assumed.
21435   * @param {number} [power] Power.
21436   * @return {function(number): number} Resolution for value function.
21437   */
21438  getResolutionForValueFunction(power) {
21439    power = power || 2;
21440    const maxResolution = this.getConstrainedResolution(this.maxResolution_);
21441    const minResolution = this.minResolution_;
21442    const max = Math.log(maxResolution / minResolution) / Math.log(power);
21443    return (
21444      /**
21445       * @param {number} value Value.
21446       * @return {number} Resolution.
21447       */
21448      function (value) {
21449        const resolution = maxResolution / Math.pow(power, value * max);
21450        return resolution;
21451      }
21452    );
21453  }
21454
21455  /**
21456   * Get the view rotation.
21457   * @return {number} The rotation of the view in radians.
21458   * @observable
21459   * @api
21460   */
21461  getRotation() {
21462    return /** @type {number} */ (this.get(ViewProperty.ROTATION));
21463  }
21464
21465  /**
21466   * Return a function that returns a resolution for a value between
21467   * 0 and 1. Exponential scaling is assumed.
21468   * @param {number} [power] Power.
21469   * @return {function(number): number} Value for resolution function.
21470   */
21471  getValueForResolutionFunction(power) {
21472    const logPower = Math.log(power || 2);
21473    const maxResolution = this.getConstrainedResolution(this.maxResolution_);
21474    const minResolution = this.minResolution_;
21475    const max = Math.log(maxResolution / minResolution) / logPower;
21476    return (
21477      /**
21478       * @param {number} resolution Resolution.
21479       * @return {number} Value.
21480       */
21481      function (resolution) {
21482        const value = Math.log(maxResolution / resolution) / logPower / max;
21483        return value;
21484      }
21485    );
21486  }
21487
21488  /**
21489   * Returns the size of the viewport minus padding.
21490   * @private
21491   * @param {number} [rotation] Take into account the rotation of the viewport when giving the size
21492   * @return {import("./size.js").Size} Viewport size reduced by the padding.
21493   */
21494  getViewportSizeMinusPadding_(rotation) {
21495    let size = this.getViewportSize_(rotation);
21496    const padding = this.padding_;
21497    if (padding) {
21498      size = [
21499        size[0] - padding[1] - padding[3],
21500        size[1] - padding[0] - padding[2],
21501      ];
21502    }
21503    return size;
21504  }
21505
21506  /**
21507   * @return {State} View state.
21508   */
21509  getState() {
21510    const projection = this.getProjection();
21511    const resolution = this.getResolution();
21512    const rotation = this.getRotation();
21513    let center = /** @type {import("./coordinate.js").Coordinate} */ (
21514      this.getCenterInternal()
21515    );
21516    const padding = this.padding_;
21517    if (padding) {
21518      const reducedSize = this.getViewportSizeMinusPadding_();
21519      center = calculateCenterOn(
21520        center,
21521        this.getViewportSize_(),
21522        [reducedSize[0] / 2 + padding[3], reducedSize[1] / 2 + padding[0]],
21523        resolution,
21524        rotation
21525      );
21526    }
21527    return {
21528      center: center.slice(0),
21529      projection: projection !== undefined ? projection : null,
21530      resolution: resolution,
21531      nextCenter: this.nextCenter_,
21532      nextResolution: this.nextResolution_,
21533      nextRotation: this.nextRotation_,
21534      rotation: rotation,
21535      zoom: this.getZoom(),
21536    };
21537  }
21538
21539  /**
21540   * Get the current zoom level. This method may return non-integer zoom levels
21541   * if the view does not constrain the resolution, or if an interaction or
21542   * animation is underway.
21543   * @return {number|undefined} Zoom.
21544   * @api
21545   */
21546  getZoom() {
21547    let zoom;
21548    const resolution = this.getResolution();
21549    if (resolution !== undefined) {
21550      zoom = this.getZoomForResolution(resolution);
21551    }
21552    return zoom;
21553  }
21554
21555  /**
21556   * Get the zoom level for a resolution.
21557   * @param {number} resolution The resolution.
21558   * @return {number|undefined} The zoom level for the provided resolution.
21559   * @api
21560   */
21561  getZoomForResolution(resolution) {
21562    let offset = this.minZoom_ || 0;
21563    let max, zoomFactor;
21564    if (this.resolutions_) {
21565      const nearest = linearFindNearest(this.resolutions_, resolution, 1);
21566      offset = nearest;
21567      max = this.resolutions_[nearest];
21568      if (nearest == this.resolutions_.length - 1) {
21569        zoomFactor = 2;
21570      } else {
21571        zoomFactor = max / this.resolutions_[nearest + 1];
21572      }
21573    } else {
21574      max = this.maxResolution_;
21575      zoomFactor = this.zoomFactor_;
21576    }
21577    return offset + Math.log(max / resolution) / Math.log(zoomFactor);
21578  }
21579
21580  /**
21581   * Get the resolution for a zoom level.
21582   * @param {number} zoom Zoom level.
21583   * @return {number} The view resolution for the provided zoom level.
21584   * @api
21585   */
21586  getResolutionForZoom(zoom) {
21587    if (this.resolutions_) {
21588      if (this.resolutions_.length <= 1) {
21589        return 0;
21590      }
21591      const baseLevel = math_clamp(
21592        Math.floor(zoom),
21593        0,
21594        this.resolutions_.length - 2
21595      );
21596      const zoomFactor =
21597        this.resolutions_[baseLevel] / this.resolutions_[baseLevel + 1];
21598      return (
21599        this.resolutions_[baseLevel] /
21600        Math.pow(zoomFactor, math_clamp(zoom - baseLevel, 0, 1))
21601      );
21602    } else {
21603      return (
21604        this.maxResolution_ / Math.pow(this.zoomFactor_, zoom - this.minZoom_)
21605      );
21606    }
21607  }
21608
21609  /**
21610   * Fit the given geometry or extent based on the given map size and border.
21611   * The size is pixel dimensions of the box to fit the extent into.
21612   * In most cases you will want to use the map size, that is `map.getSize()`.
21613   * Takes care of the map angle.
21614   * @param {import("./geom/SimpleGeometry.js").default|import("./extent.js").Extent} geometryOrExtent The geometry or
21615   *     extent to fit the view to.
21616   * @param {FitOptions} [options] Options.
21617   * @api
21618   */
21619  fit(geometryOrExtent, options) {
21620    /** @type {import("./geom/SimpleGeometry.js").default} */
21621    let geometry;
21622    asserts_assert(
21623      Array.isArray(geometryOrExtent) ||
21624        typeof (/** @type {?} */ (geometryOrExtent).getSimplifiedGeometry) ===
21625          'function',
21626      24
21627    ); // Invalid extent or geometry provided as `geometry`
21628    if (Array.isArray(geometryOrExtent)) {
21629      asserts_assert(!extent_isEmpty(geometryOrExtent), 25); // Cannot fit empty extent provided as `geometry`
21630      const extent = proj_fromUserExtent(geometryOrExtent, this.getProjection());
21631      geometry = fromExtent(extent);
21632    } else if (geometryOrExtent.getType() === 'Circle') {
21633      const extent = proj_fromUserExtent(
21634        geometryOrExtent.getExtent(),
21635        this.getProjection()
21636      );
21637      geometry = fromExtent(extent);
21638      geometry.rotate(this.getRotation(), getCenter(extent));
21639    } else {
21640      const userProjection = getUserProjection();
21641      if (userProjection) {
21642        geometry = /** @type {import("./geom/SimpleGeometry.js").default} */ (
21643          geometryOrExtent
21644            .clone()
21645            .transform(userProjection, this.getProjection())
21646        );
21647      } else {
21648        geometry = geometryOrExtent;
21649      }
21650    }
21651
21652    this.fitInternal(geometry, options);
21653  }
21654
21655  /**
21656   * Calculate rotated extent
21657   * @param {import("./geom/SimpleGeometry.js").default} geometry The geometry.
21658   * @return {import("./extent").Extent} The rotated extent for the geometry.
21659   */
21660  rotatedExtentForGeometry(geometry) {
21661    const rotation = this.getRotation();
21662    const cosAngle = Math.cos(rotation);
21663    const sinAngle = Math.sin(-rotation);
21664    const coords = geometry.getFlatCoordinates();
21665    const stride = geometry.getStride();
21666    let minRotX = +Infinity;
21667    let minRotY = +Infinity;
21668    let maxRotX = -Infinity;
21669    let maxRotY = -Infinity;
21670    for (let i = 0, ii = coords.length; i < ii; i += stride) {
21671      const rotX = coords[i] * cosAngle - coords[i + 1] * sinAngle;
21672      const rotY = coords[i] * sinAngle + coords[i + 1] * cosAngle;
21673      minRotX = Math.min(minRotX, rotX);
21674      minRotY = Math.min(minRotY, rotY);
21675      maxRotX = Math.max(maxRotX, rotX);
21676      maxRotY = Math.max(maxRotY, rotY);
21677    }
21678    return [minRotX, minRotY, maxRotX, maxRotY];
21679  }
21680
21681  /**
21682   * @param {import("./geom/SimpleGeometry.js").default} geometry The geometry.
21683   * @param {FitOptions} [options] Options.
21684   */
21685  fitInternal(geometry, options) {
21686    options = options || {};
21687    let size = options.size;
21688    if (!size) {
21689      size = this.getViewportSizeMinusPadding_();
21690    }
21691    const padding =
21692      options.padding !== undefined ? options.padding : [0, 0, 0, 0];
21693    const nearest = options.nearest !== undefined ? options.nearest : false;
21694    let minResolution;
21695    if (options.minResolution !== undefined) {
21696      minResolution = options.minResolution;
21697    } else if (options.maxZoom !== undefined) {
21698      minResolution = this.getResolutionForZoom(options.maxZoom);
21699    } else {
21700      minResolution = 0;
21701    }
21702
21703    const rotatedExtent = this.rotatedExtentForGeometry(geometry);
21704
21705    // calculate resolution
21706    let resolution = this.getResolutionForExtentInternal(rotatedExtent, [
21707      size[0] - padding[1] - padding[3],
21708      size[1] - padding[0] - padding[2],
21709    ]);
21710    resolution = isNaN(resolution)
21711      ? minResolution
21712      : Math.max(resolution, minResolution);
21713    resolution = this.getConstrainedResolution(resolution, nearest ? 0 : 1);
21714
21715    // calculate center
21716    const rotation = this.getRotation();
21717    const sinAngle = Math.sin(rotation);
21718    const cosAngle = Math.cos(rotation);
21719    const centerRot = getCenter(rotatedExtent);
21720    centerRot[0] += ((padding[1] - padding[3]) / 2) * resolution;
21721    centerRot[1] += ((padding[0] - padding[2]) / 2) * resolution;
21722    const centerX = centerRot[0] * cosAngle - centerRot[1] * sinAngle;
21723    const centerY = centerRot[1] * cosAngle + centerRot[0] * sinAngle;
21724    const center = this.getConstrainedCenter([centerX, centerY], resolution);
21725    const callback = options.callback ? options.callback : VOID;
21726
21727    if (options.duration !== undefined) {
21728      this.animateInternal(
21729        {
21730          resolution: resolution,
21731          center: center,
21732          duration: options.duration,
21733          easing: options.easing,
21734        },
21735        callback
21736      );
21737    } else {
21738      this.targetResolution_ = resolution;
21739      this.targetCenter_ = center;
21740      this.applyTargetState_(false, true);
21741      animationCallback(callback, true);
21742    }
21743  }
21744
21745  /**
21746   * Center on coordinate and view position.
21747   * @param {import("./coordinate.js").Coordinate} coordinate Coordinate.
21748   * @param {import("./size.js").Size} size Box pixel size.
21749   * @param {import("./pixel.js").Pixel} position Position on the view to center on.
21750   * @api
21751   */
21752  centerOn(coordinate, size, position) {
21753    this.centerOnInternal(
21754      fromUserCoordinate(coordinate, this.getProjection()),
21755      size,
21756      position
21757    );
21758  }
21759
21760  /**
21761   * @param {import("./coordinate.js").Coordinate} coordinate Coordinate.
21762   * @param {import("./size.js").Size} size Box pixel size.
21763   * @param {import("./pixel.js").Pixel} position Position on the view to center on.
21764   */
21765  centerOnInternal(coordinate, size, position) {
21766    this.setCenterInternal(
21767      calculateCenterOn(
21768        coordinate,
21769        size,
21770        position,
21771        this.getResolution(),
21772        this.getRotation()
21773      )
21774    );
21775  }
21776
21777  /**
21778   * Calculates the shift between map and viewport center.
21779   * @param {import("./coordinate.js").Coordinate} center Center.
21780   * @param {number} resolution Resolution.
21781   * @param {number} rotation Rotation.
21782   * @param {import("./size.js").Size} size Size.
21783   * @return {Array<number>|undefined} Center shift.
21784   */
21785  calculateCenterShift(center, resolution, rotation, size) {
21786    let centerShift;
21787    const padding = this.padding_;
21788    if (padding && center) {
21789      const reducedSize = this.getViewportSizeMinusPadding_(-rotation);
21790      const shiftedCenter = calculateCenterOn(
21791        center,
21792        size,
21793        [reducedSize[0] / 2 + padding[3], reducedSize[1] / 2 + padding[0]],
21794        resolution,
21795        rotation
21796      );
21797      centerShift = [
21798        center[0] - shiftedCenter[0],
21799        center[1] - shiftedCenter[1],
21800      ];
21801    }
21802    return centerShift;
21803  }
21804
21805  /**
21806   * @return {boolean} Is defined.
21807   */
21808  isDef() {
21809    return !!this.getCenterInternal() && this.getResolution() !== undefined;
21810  }
21811
21812  /**
21813   * Adds relative coordinates to the center of the view. Any extent constraint will apply.
21814   * @param {import("./coordinate.js").Coordinate} deltaCoordinates Relative value to add.
21815   * @api
21816   */
21817  adjustCenter(deltaCoordinates) {
21818    const center = toUserCoordinate(this.targetCenter_, this.getProjection());
21819    this.setCenter([
21820      center[0] + deltaCoordinates[0],
21821      center[1] + deltaCoordinates[1],
21822    ]);
21823  }
21824
21825  /**
21826   * Adds relative coordinates to the center of the view. Any extent constraint will apply.
21827   * @param {import("./coordinate.js").Coordinate} deltaCoordinates Relative value to add.
21828   */
21829  adjustCenterInternal(deltaCoordinates) {
21830    const center = this.targetCenter_;
21831    this.setCenterInternal([
21832      center[0] + deltaCoordinates[0],
21833      center[1] + deltaCoordinates[1],
21834    ]);
21835  }
21836
21837  /**
21838   * Multiply the view resolution by a ratio, optionally using an anchor. Any resolution
21839   * constraint will apply.
21840   * @param {number} ratio The ratio to apply on the view resolution.
21841   * @param {import("./coordinate.js").Coordinate} [anchor] The origin of the transformation.
21842   * @api
21843   */
21844  adjustResolution(ratio, anchor) {
21845    anchor = anchor && fromUserCoordinate(anchor, this.getProjection());
21846    this.adjustResolutionInternal(ratio, anchor);
21847  }
21848
21849  /**
21850   * Multiply the view resolution by a ratio, optionally using an anchor. Any resolution
21851   * constraint will apply.
21852   * @param {number} ratio The ratio to apply on the view resolution.
21853   * @param {import("./coordinate.js").Coordinate} [anchor] The origin of the transformation.
21854   */
21855  adjustResolutionInternal(ratio, anchor) {
21856    const isMoving = this.getAnimating() || this.getInteracting();
21857    const size = this.getViewportSize_(this.getRotation());
21858    const newResolution = this.constraints_.resolution(
21859      this.targetResolution_ * ratio,
21860      0,
21861      size,
21862      isMoving
21863    );
21864
21865    if (anchor) {
21866      this.targetCenter_ = this.calculateCenterZoom(newResolution, anchor);
21867    }
21868
21869    this.targetResolution_ *= ratio;
21870    this.applyTargetState_();
21871  }
21872
21873  /**
21874   * Adds a value to the view zoom level, optionally using an anchor. Any resolution
21875   * constraint will apply.
21876   * @param {number} delta Relative value to add to the zoom level.
21877   * @param {import("./coordinate.js").Coordinate} [anchor] The origin of the transformation.
21878   * @api
21879   */
21880  adjustZoom(delta, anchor) {
21881    this.adjustResolution(Math.pow(this.zoomFactor_, -delta), anchor);
21882  }
21883
21884  /**
21885   * Adds a value to the view rotation, optionally using an anchor. Any rotation
21886   * constraint will apply.
21887   * @param {number} delta Relative value to add to the zoom rotation, in radians.
21888   * @param {import("./coordinate.js").Coordinate} [anchor] The rotation center.
21889   * @api
21890   */
21891  adjustRotation(delta, anchor) {
21892    if (anchor) {
21893      anchor = fromUserCoordinate(anchor, this.getProjection());
21894    }
21895    this.adjustRotationInternal(delta, anchor);
21896  }
21897
21898  /**
21899   * @param {number} delta Relative value to add to the zoom rotation, in radians.
21900   * @param {import("./coordinate.js").Coordinate} [anchor] The rotation center.
21901   */
21902  adjustRotationInternal(delta, anchor) {
21903    const isMoving = this.getAnimating() || this.getInteracting();
21904    const newRotation = this.constraints_.rotation(
21905      this.targetRotation_ + delta,
21906      isMoving
21907    );
21908    if (anchor) {
21909      this.targetCenter_ = this.calculateCenterRotate(newRotation, anchor);
21910    }
21911    this.targetRotation_ += delta;
21912    this.applyTargetState_();
21913  }
21914
21915  /**
21916   * Set the center of the current view. Any extent constraint will apply.
21917   * @param {import("./coordinate.js").Coordinate|undefined} center The center of the view.
21918   * @observable
21919   * @api
21920   */
21921  setCenter(center) {
21922    this.setCenterInternal(
21923      center ? fromUserCoordinate(center, this.getProjection()) : center
21924    );
21925  }
21926
21927  /**
21928   * Set the center using the view projection (not the user projection).
21929   * @param {import("./coordinate.js").Coordinate|undefined} center The center of the view.
21930   */
21931  setCenterInternal(center) {
21932    this.targetCenter_ = center;
21933    this.applyTargetState_();
21934  }
21935
21936  /**
21937   * @param {import("./ViewHint.js").default} hint Hint.
21938   * @param {number} delta Delta.
21939   * @return {number} New value.
21940   */
21941  setHint(hint, delta) {
21942    this.hints_[hint] += delta;
21943    this.changed();
21944    return this.hints_[hint];
21945  }
21946
21947  /**
21948   * Set the resolution for this view. Any resolution constraint will apply.
21949   * @param {number|undefined} resolution The resolution of the view.
21950   * @observable
21951   * @api
21952   */
21953  setResolution(resolution) {
21954    this.targetResolution_ = resolution;
21955    this.applyTargetState_();
21956  }
21957
21958  /**
21959   * Set the rotation for this view. Any rotation constraint will apply.
21960   * @param {number} rotation The rotation of the view in radians.
21961   * @observable
21962   * @api
21963   */
21964  setRotation(rotation) {
21965    this.targetRotation_ = rotation;
21966    this.applyTargetState_();
21967  }
21968
21969  /**
21970   * Zoom to a specific zoom level. Any resolution constrain will apply.
21971   * @param {number} zoom Zoom level.
21972   * @api
21973   */
21974  setZoom(zoom) {
21975    this.setResolution(this.getResolutionForZoom(zoom));
21976  }
21977
21978  /**
21979   * Recompute rotation/resolution/center based on target values.
21980   * Note: we have to compute rotation first, then resolution and center considering that
21981   * parameters can influence one another in case a view extent constraint is present.
21982   * @param {boolean}
21982 [doNotCancelAnims] Do not cancel animations.
21983   * @param {boolean} [forceMoving] Apply constraints as if the view is moving.
21984   * @private
21985   */
21986  applyTargetState_(doNotCancelAnims, forceMoving) {
21987    const isMoving =
21988      this.getAnimating() || this.getInteracting() || forceMoving;
21989
21990    // compute rotation
21991    const newRotation = this.constraints_.rotation(
21992      this.targetRotation_,
21993      isMoving
21994    );
21995    const size = this.getViewportSize_(newRotation);
21996    const newResolution = this.constraints_.resolution(
21997      this.targetResolution_,
21998      0,
21999      size,
22000      isMoving
22001    );
22002    const newCenter = this.constraints_.center(
22003      this.targetCenter_,
22004      newResolution,
22005      size,
22006      isMoving,
22007      this.calculateCenterShift(
22008        this.targetCenter_,
22009        newResolution,
22010        newRotation,
22011        size
22012      )
22013    );
22014
22015    if (this.get(ViewProperty.ROTATION) !== newRotation) {
22016      this.set(ViewProperty.ROTATION, newRotation);
22017    }
22018    if (this.get(ViewProperty.RESOLUTION) !== newResolution) {
22019      this.set(ViewProperty.RESOLUTION, newResolution);
22020      this.set('zoom', this.getZoom(), true);
22021    }
22022    if (
22023      !newCenter ||
22024      !this.get(ViewProperty.CENTER) ||
22025      !coordinate_equals(this.get(ViewProperty.CENTER), newCenter)
22026    ) {
22027      this.set(ViewProperty.CENTER, newCenter);
22028    }
22029
22030    if (this.getAnimating() && !doNotCancelAnims) {
22031      this.cancelAnimations();
22032    }
22033    this.cancelAnchor_ = undefined;
22034  }
22035
22036  /**
22037   * If any constraints need to be applied, an animation will be triggered.
22038   * This is typically done on interaction end.
22039   * Note: calling this with a duration of 0 will apply the constrained values straight away,
22040   * without animation.
22041   * @param {number} [duration] The animation duration in ms.
22042   * @param {number} [resolutionDirection] Which direction to zoom.
22043   * @param {import("./coordinate.js").Coordinate} [anchor] The origin of the transformation.
22044   */
22045  resolveConstraints(duration, resolutionDirection, anchor) {
22046    duration = duration !== undefined ? duration : 200;
22047    const direction = resolutionDirection || 0;
22048
22049    const newRotation = this.constraints_.rotation(this.targetRotation_);
22050    const size = this.getViewportSize_(newRotation);
22051    const newResolution = this.constraints_.resolution(
22052      this.targetResolution_,
22053      direction,
22054      size
22055    );
22056    const newCenter = this.constraints_.center(
22057      this.targetCenter_,
22058      newResolution,
22059      size,
22060      false,
22061      this.calculateCenterShift(
22062        this.targetCenter_,
22063        newResolution,
22064        newRotation,
22065        size
22066      )
22067    );
22068
22069    if (duration === 0 && !this.cancelAnchor_) {
22070      this.targetResolution_ = newResolution;
22071      this.targetRotation_ = newRotation;
22072      this.targetCenter_ = newCenter;
22073      this.applyTargetState_();
22074      return;
22075    }
22076
22077    anchor = anchor || (duration === 0 ? this.cancelAnchor_ : undefined);
22078    this.cancelAnchor_ = undefined;
22079
22080    if (
22081      this.getResolution() !== newResolution ||
22082      this.getRotation() !== newRotation ||
22083      !this.getCenterInternal() ||
22084      !coordinate_equals(this.getCenterInternal(), newCenter)
22085    ) {
22086      if (this.getAnimating()) {
22087        this.cancelAnimations();
22088      }
22089
22090      this.animateInternal({
22091        rotation: newRotation,
22092        center: newCenter,
22093        resolution: newResolution,
22094        duration: duration,
22095        easing: easeOut,
22096        anchor: anchor,
22097      });
22098    }
22099  }
22100
22101  /**
22102   * Notify the View that an interaction has started.
22103   * The view state will be resolved to a stable one if needed
22104   * (depending on its constraints).
22105   * @api
22106   */
22107  beginInteraction() {
22108    this.resolveConstraints(0);
22109
22110    this.setHint(ViewHint.INTERACTING, 1);
22111  }
22112
22113  /**
22114   * Notify the View that an interaction has ended. The view state will be resolved
22115   * to a stable one if needed (depending on its constraints).
22116   * @param {number} [duration] Animation duration in ms.
22117   * @param {number} [resolutionDirection] Which direction to zoom.
22118   * @param {import("./coordinate.js").Coordinate} [anchor] The origin of the transformation.
22119   * @api
22120   */
22121  endInteraction(duration, resolutionDirection, anchor) {
22122    anchor = anchor && fromUserCoordinate(anchor, this.getProjection());
22123    this.endInteractionInternal(duration, resolutionDirection, anchor);
22124  }
22125
22126  /**
22127   * Notify the View that an interaction has ended. The view state will be resolved
22128   * to a stable one if needed (depending on its constraints).
22129   * @param {number} [duration] Animation duration in ms.
22130   * @param {number} [resolutionDirection] Which direction to zoom.
22131   * @param {import("./coordinate.js").Coordinate} [anchor] The origin of the transformation.
22132   */
22133  endInteractionInternal(duration, resolutionDirection, anchor) {
22134    this.setHint(ViewHint.INTERACTING, -1);
22135
22136    this.resolveConstraints(duration, resolutionDirection, anchor);
22137  }
22138
22139  /**
22140   * Get a valid position for the view center according to the current constraints.
22141   * @param {import("./coordinate.js").Coordinate|undefined} targetCenter Target center position.
22142   * @param {number} [targetResolution] Target resolution. If not supplied, the current one will be used.
22143   * This is useful to guess a valid center position at a different zoom level.
22144   * @return {import("./coordinate.js").Coordinate|undefined} Valid center position.
22145   */
22146  getConstrainedCenter(targetCenter, targetResolution) {
22147    const size = this.getViewportSize_(this.getRotation());
22148    return this.constraints_.center(
22149      targetCenter,
22150      targetResolution || this.getResolution(),
22151      size
22152    );
22153  }
22154
22155  /**
22156   * Get a valid zoom level according to the current view constraints.
22157   * @param {number|undefined} targetZoom Target zoom.
22158   * @param {number} [direction=0] Indicate which resolution should be used
22159   * by a renderer if the view resolution does not match any resolution of the tile source.
22160   * If 0, the nearest resolution will be used. If 1, the nearest lower resolution
22161   * will be used. If -1, the nearest higher resolution will be used.
22162   * @return {number|undefined} Valid zoom level.
22163   */
22164  getConstrainedZoom(targetZoom, direction) {
22165    const targetRes = this.getResolutionForZoom(targetZoom);
22166    return this.getZoomForResolution(
22167      this.getConstrainedResolution(targetRes, direction)
22168    );
22169  }
22170
22171  /**
22172   * Get a valid resolution according to the current view constraints.
22173   * @param {number|undefined} targetResolution Target resolution.
22174   * @param {number} [direction=0] Indicate which resolution should be used
22175   * by a renderer if the view resolution does not match any resolution of the tile source.
22176   * If 0, the nearest resolution will be used. If 1, the nearest lower resolution
22177   * will be used. If -1, the nearest higher resolution will be used.
22178   * @return {number|undefined} Valid resolution.
22179   */
22180  getConstrainedResolution(targetResolution, direction) {
22181    direction = direction || 0;
22182    const size = this.getViewportSize_(this.getRotation());
22183
22184    return this.constraints_.resolution(targetResolution, direction, size);
22185  }
22186}
22187
22188/**
22189 * @param {Function} callback Callback.
22190 * @param {*} returnValue Return value.
22191 */
22192function animationCallback(callback, returnValue) {
22193  setTimeout(function () {
22194    callback(returnValue);
22195  }, 0);
22196}
22197
22198/**
22199 * @param {ViewOptions} options View options.
22200 * @return {import("./centerconstraint.js").Type} The constraint.
22201 */
22202function createCenterConstraint(options) {
22203  if (options.extent !== undefined) {
22204    const smooth =
22205      options.smoothExtentConstraint !== undefined
22206        ? options.smoothExtentConstraint
22207        : true;
22208    return createExtent(options.extent, options.constrainOnlyCenter, smooth);
22209  }
22210
22211  const projection = createProjection(options.projection, 'EPSG:3857');
22212  if (options.multiWorld !== true && projection.isGlobal()) {
22213    const extent = projection.getExtent().slice();
22214    extent[0] = -Infinity;
22215    extent[2] = Infinity;
22216    return createExtent(extent, false, false);
22217  }
22218
22219  return none;
22220}
22221
22222/**
22223 * @param {ViewOptions} options View options.
22224 * @return {{constraint: import("./resolutionconstraint.js").Type, maxResolution: number,
22225 *     minResolution: number, minZoom: number, zoomFactor: number}} The constraint.
22226 */
22227function createResolutionConstraint(options) {
22228  let resolutionConstraint;
22229  let maxResolution;
22230  let minResolution;
22231
22232  // TODO: move these to be ol constants
22233  // see https://github.com/openlayers/openlayers/issues/2076
22234  const defaultMaxZoom = 28;
22235  const defaultZoomFactor = 2;
22236
22237  let minZoom =
22238    options.minZoom !== undefined ? options.minZoom : DEFAULT_MIN_ZOOM;
22239
22240  let maxZoom =
22241    options.maxZoom !== undefined ? options.maxZoom : defaultMaxZoom;
22242
22243  const zoomFactor =
22244    options.zoomFactor !== undefined ? options.zoomFactor : defaultZoomFactor;
22245
22246  const multiWorld =
22247    options.multiWorld !== undefined ? options.multiWorld : false;
22248
22249  const smooth =
22250    options.smoothResolutionConstraint !== undefined
22251      ? options.smoothResolutionConstraint
22252      : true;
22253
22254  const showFullExtent =
22255    options.showFullExtent !== undefined ? options.showFullExtent : false;
22256
22257  const projection = createProjection(options.projection, 'EPSG:3857');
22258  const projExtent = projection.getExtent();
22259  let constrainOnlyCenter = options.constrainOnlyCenter;
22260  let extent = options.extent;
22261  if (!multiWorld && !extent && projection.isGlobal()) {
22262    constrainOnlyCenter = false;
22263    extent = projExtent;
22264  }
22265
22266  if (options.resolutions !== undefined) {
22267    const resolutions = options.resolutions;
22268    maxResolution = resolutions[minZoom];
22269    minResolution =
22270      resolutions[maxZoom] !== undefined
22271        ? resolutions[maxZoom]
22272        : resolutions[resolutions.length - 1];
22273
22274    if (options.constrainResolution) {
22275      resolutionConstraint = createSnapToResolutions(
22276        resolutions,
22277        smooth,
22278        !constrainOnlyCenter && extent,
22279        showFullExtent
22280      );
22281    } else {
22282      resolutionConstraint = createMinMaxResolution(
22283        maxResolution,
22284        minResolution,
22285        smooth,
22286        !constrainOnlyCenter && extent,
22287        showFullExtent
22288      );
22289    }
22290  } else {
22291    // calculate the default min and max resolution
22292    const size = !projExtent
22293      ? // use an extent that can fit the whole world if need be
22294        (360 * Units_METERS_PER_UNIT.degrees) / projection.getMetersPerUnit()
22295      : Math.max(extent_getWidth(projExtent), extent_getHeight(projExtent));
22296
22297    const defaultMaxResolution =
22298      size / DEFAULT_TILE_SIZE / Math.pow(defaultZoomFactor, DEFAULT_MIN_ZOOM);
22299
22300    const defaultMinResolution =
22301      defaultMaxResolution /
22302      Math.pow(defaultZoomFactor, defaultMaxZoom - DEFAULT_MIN_ZOOM);
22303
22304    // user provided maxResolution takes precedence
22305    maxResolution = options.maxResolution;
22306    if (maxResolution !== undefined) {
22307      minZoom = 0;
22308    } else {
22309      maxResolution = defaultMaxResolution / Math.pow(zoomFactor, minZoom);
22310    }
22311
22312    // user provided minResolution takes precedence
22313    minResolution = options.minResolution;
22314    if (minResolution === undefined) {
22315      if (options.maxZoom !== undefined) {
22316        if (options.maxResolution !== undefined) {
22317          minResolution = maxResolution / Math.pow(zoomFactor, maxZoom);
22318        } else {
22319          minResolution = defaultMaxResolution / Math.pow(zoomFactor, maxZoom);
22320        }
22321      } else {
22322        minResolution = defaultMinResolution;
22323      }
22324    }
22325
22326    // given discrete zoom levels, minResolution may be different than provided
22327    maxZoom =
22328      minZoom +
22329      Math.floor(
22330        Math.log(maxResolution / minResolution) / Math.log(zoomFactor)
22331      );
22332    minResolution = maxResolution / Math.pow(zoomFactor, maxZoom - minZoom);
22333
22334    if (options.constrainResolution) {
22335      resolutionConstraint = createSnapToPower(
22336        zoomFactor,
22337        maxResolution,
22338        minResolution,
22339        smooth,
22340        !constrainOnlyCenter && extent,
22341        showFullExtent
22342      );
22343    } else {
22344      resolutionConstraint = createMinMaxResolution(
22345        maxResolution,
22346        minResolution,
22347        smooth,
22348        !constrainOnlyCenter && extent,
22349        showFullExtent
22350      );
22351    }
22352  }
22353  return {
22354    constraint: resolutionConstraint,
22355    maxResolution: maxResolution,
22356    minResolution: minResolution,
22357    minZoom: minZoom,
22358    zoomFactor: zoomFactor,
22359  };
22360}
22361
22362/**
22363 * @param {ViewOptions} options View options.
22364 * @return {import("./rotationconstraint.js").Type} Rotation constraint.
22365 */
22366function createRotationConstraint(options) {
22367  const enableRotation =
22368    options.enableRotation !== undefined ? options.enableRotation : true;
22369  if (enableRotation) {
22370    const constrainRotation = options.constrainRotation;
22371    if (constrainRotation === undefined || constrainRotation === true) {
22372      return createSnapToZero();
22373    } else if (constrainRotation === false) {
22374      return rotationconstraint_none;
22375    } else if (typeof constrainRotation === 'number') {
22376      return createSnapToN(constrainRotation);
22377    } else {
22378      return rotationconstraint_none;
22379    }
22380  } else {
22381    return disable;
22382  }
22383}
22384
22385/**
22386 * Determine if an animation involves no view change.
22387 * @param {Animation} animation The animation.
22388 * @return {boolean} The animation involves no view change.
22389 */
22390function isNoopAnimation(animation) {
22391  if (animation.sourceCenter && animation.targetCenter) {
22392    if (!coordinate_equals(animation.sourceCenter, animation.targetCenter)) {
22393      return false;
22394    }
22395  }
22396  if (animation.sourceResolution !== animation.targetResolution) {
22397    return false;
22398  }
22399  if (animation.sourceRotation !== animation.targetRotation) {
22400    return false;
22401  }
22402  return true;
22403}
22404
22405/**
22406 * @param {import("./coordinate.js").Coordinate} coordinate Coordinate.
22407 * @param {import("./size.js").Size} size Box pixel size.
22408 * @param {import("./pixel.js").Pixel} position Position on the view to center on.
22409 * @param {number} resolution Resolution.
22410 * @param {number} rotation Rotation.
22411 * @return {import("./coordinate.js").Coordinate} Shifted center.
22412 */
22413function calculateCenterOn(coordinate, size, position, resolution, rotation) {
22414  // calculate rotated position
22415  const cosAngle = Math.cos(-rotation);
22416  let sinAngle = Math.sin(-rotation);
22417  let rotX = coordinate[0] * cosAngle - coordinate[1] * sinAngle;
22418  let rotY = coordinate[1] * cosAngle + coordinate[0] * sinAngle;
22419  rotX += (size[0] / 2 - position[0]) * resolution;
22420  rotY += (position[1] - size[1] / 2) * resolution;
22421
22422  // go back to original angle
22423  sinAngle = -sinAngle; // go back to original rotation
22424  const centerX = rotX * cosAngle - rotY * sinAngle;
22425  const centerY = rotY * cosAngle + rotX * sinAngle;
22426
22427  return [centerX, centerY];
22428}
22429
22430/* harmony default export */ const ol_View = (View);
22431
22432;// CONCATENATED MODULE: ./node_modules/ol/CollectionEventType.js
22433/**
22434 * @module ol/CollectionEventType
22435 */
22436
22437/**
22438 * @enum {string}
22439 */
22440/* harmony default export */ const CollectionEventType = ({
22441  /**
22442   * Triggered when an item is added to the collection.
22443   * @event module:ol/Collection.CollectionEvent#add
22444   * @api
22445   */
22446  ADD: 'add',
22447  /**
22448   * Triggered when an item is removed from the collection.
22449   * @event module:ol/Collection.CollectionEvent#remove
22450   * @api
22451   */
22452  REMOVE: 'remove',
22453});
22454
22455;// CONCATENATED MODULE: ./node_modules/ol/Collection.js
22456/**
22457 * @module ol/Collection
22458 */
22459
22460
22461
22462
22463
22464/**
22465 * @enum {string}
22466 * @private
22467 */
22468const Property = {
22469  LENGTH: 'length',
22470};
22471
22472/**
22473 * @classdesc
22474 * Events emitted by {@link module:ol/Collection~Collection} instances are instances of this
22475 * type.
22476 * @template T
22477 */
22478class CollectionEvent extends Event {
22479  /**
22480   * @param {import("./CollectionEventType.js").default} type Type.
22481   * @param {T} element Element.
22482   * @param {number} index The index of the added or removed element.
22483   */
22484  constructor(type, element, index) {
22485    super(type);
22486
22487    /**
22488     * The element that is added to or removed from the collection.
22489     * @type {T}
22490     * @api
22491     */
22492    this.element = element;
22493
22494    /**
22495     * The index of the added or removed element.
22496     * @type {number}
22497     * @api
22498     */
22499    this.index = index;
22500  }
22501}
22502
22503/***
22504 * @template T
22505 * @template Return
22506 * @typedef {import("./Observable").OnSignature<import("./Observable").EventTypes, import("./events/Event.js").default, Return> &
22507 *   import("./Observable").OnSignature<import("./ObjectEventType").Types|'change:length', import("./Object").ObjectEvent, Return> &
22508 *   import("./Observable").OnSignature<'add'|'remove', CollectionEvent<T>, Return> &
22509 *   import("./Observable").CombinedOnSignature<import("./Observable").EventTypes|import("./ObjectEventType").Types|
22510 *     'change:length'|'add'|'remove',Return>} CollectionOnSignature
22511 */
22512
22513/**
22514 * @typedef {Object} Options
22515 * @property {boolean} [unique=false] Disallow the same item from being added to
22516 * the collection twice.
22517 */
22518
22519/**
22520 * @classdesc
22521 * An expanded version of standard JS Array, adding convenience methods for
22522 * manipulation. Add and remove changes to the Collection trigger a Collection
22523 * event. Note that this does not cover changes to the objects _within_ the
22524 * Collection; they trigger events on the appropriate object, not on the
22525 * Collection as a whole.
22526 *
22527 * @fires CollectionEvent
22528 *
22529 * @template T
22530 * @api
22531 */
22532class Collection extends ol_Object {
22533  /**
22534   * @param {Array<T>} [array] Array.
22535   * @param {Options} [options] Collection options.
22536   */
22537  constructor(array, options) {
22538    super();
22539
22540    /***
22541     * @type {CollectionOnSignature<T, import("./events").EventsKey>}
22542     */
22543    this.on;
22544
22545    /***
22546     * @type {CollectionOnSignature<T, import("./events").EventsKey>}
22547     */
22548    this.once;
22549
22550    /***
22551     * @type {CollectionOnSignature<T, void>}
22552     */
22553    this.un;
22554
22555    options = options || {};
22556
22557    /**
22558     * @private
22559     * @type {boolean}
22560     */
22561    this.unique_ = !!options.unique;
22562
22563    /**
22564     * @private
22565     * @type {!Array<T>}
22566     */
22567    this.array_ = array ? array : [];
22568
22569    if (this.unique_) {
22570      for (let i = 0, ii = this.array_.length; i < ii; ++i) {
22571        this.assertUnique_(this.array_[i], i);
22572      }
22573    }
22574
22575    this.updateLength_();
22576  }
22577
22578  /**
22579   * Remove all elements from the collection.
22580   * @api
22581   */
22582  clear() {
22583    while (this.getLength() > 0) {
22584      this.pop();
22585    }
22586  }
22587
22588  /**
22589   * Add elements to the collection.  This pushes each item in the provided array
22590   * to the end of the collection.
22591   * @param {!Array<T>} arr Array.
22592   * @return {Collection<T>} This collection.
22593   * @api
22594   */
22595  extend(arr) {
22596    for (let i = 0, ii = arr.length; i < ii; ++i) {
22597      this.push(arr[i]);
22598    }
22599    return this;
22600  }
22601
22602  /**
22603   * Iterate over each element, calling the provided callback.
22604   * @param {function(T, number, Array<T>): *} f The function to call
22605   *     for every element. This function takes 3 arguments (the element, the
22606   *     index and the array). The return value is ignored.
22607   * @api
22608   */
22609  forEach(f) {
22610    const array = this.array_;
22611    for (let i = 0, ii = array.length; i < ii; ++i) {
22612      f(array[i], i, array);
22613    }
22614  }
22615
22616  /**
22617   * Get a reference to the underlying Array object. Warning: if the array
22618   * is mutated, no events will be dispatched by the collection, and the
22619   * collection's "length" property won't be in sync with the actual length
22620   * of the array.
22621   * @return {!Array<T>} Array.
22622   * @api
22623   */
22624  getArray() {
22625    return this.array_;
22626  }
22627
22628  /**
22629   * Get the element at the provided index.
22630   * @param {number} index Index.
22631   * @return {T} Element.
22632   * @api
22633   */
22634  item(index) {
22635    return this.array_[index];
22636  }
22637
22638  /**
22639   * Get the length of this collection.
22640   * @return {number} The length of the array.
22641   * @observable
22642   * @api
22643   */
22644  getLength() {
22645    return this.get(Property.LENGTH);
22646  }
22647
22648  /**
22649   * Insert an element at the provided index.
22650   * @param {number} index Index.
22651   * @param {T} elem Element.
22652   * @api
22653   */
22654  insertAt(index, elem) {
22655    if (index < 0 || index > this.getLength()) {
22656      throw new Error('Index out of bounds: ' + index);
22657    }
22658    if (this.unique_) {
22659      this.assertUnique_(elem);
22660    }
22661    this.array_.splice(index, 0, elem);
22662    this.updateLength_();
22663    this.dispatchEvent(
22664      new CollectionEvent(CollectionEventType.ADD, elem, index)
22665    );
22666  }
22667
22668  /**
22669   * Remove the last element of the collection and return it.
22670   * Return `undefined` if the collection is empty.
22671   * @return {T|undefined} Element.
22672   * @api
22673   */
22674  pop() {
22675    return this.removeAt(this.getLength() - 1);
22676  }
22677
22678  /**
22679   * Insert the provided element at the end of the collection.
22680   * @param {T} elem Element.
22681   * @return {number} New length of the collection.
22682   * @api
22683   */
22684  push(elem) {
22685    if (this.unique_) {
22686      this.assertUnique_(elem);
22687    }
22688    const n = this.getLength();
22689    this.insertAt(n, elem);
22690    return this.getLength();
22691  }
22692
22693  /**
22694   * Remove the first occurrence of an element from the collection.
22695   * @param {T} elem Element.
22696   * @return {T|undefined} The removed element or undefined if none found.
22697   * @api
22698   */
22699  remove(elem) {
22700    const arr = this.array_;
22701    for (let i = 0, ii = arr.length; i < ii; ++i) {
22702      if (arr[i] === elem) {
22703        return this.removeAt(i);
22704      }
22705    }
22706    return undefined;
22707  }
22708
22709  /**
22710   * Remove the element at the provided index and return it.
22711   * Return `undefined` if the collection does not contain this index.
22712   * @param {number} index Index.
22713   * @return {T|undefined} Value.
22714   * @api
22715   */
22716  removeAt(index) {
22717    if (index < 0 || index >= this.getLength()) {
22718      return undefined;
22719    }
22720    const prev = this.array_[index];
22721    this.array_.splice(index, 1);
22722    this.updateLength_();
22723    this.dispatchEvent(
22724      /** @type {CollectionEvent<T>} */ (
22725        new CollectionEvent(CollectionEventType.REMOVE, prev, index)
22726      )
22727    );
22728    return prev;
22729  }
22730
22731  /**
22732   * Set the element at the provided index.
22733   * @param {number} index Index.
22734   * @param {T} elem Element.
22735   * @api
22736   */
22737  setAt(index, elem) {
22738    const n = this.getLength();
22739    if (index >= n) {
22740      this.insertAt(index, elem);
22741      return;
22742    }
22743    if (index < 0) {
22744      throw new Error('Index out of bounds: ' + index);
22745    }
22746    if (this.unique_) {
22747      this.assertUnique_(elem, index);
22748    }
22749    const prev = this.array_[index];
22750    this.array_[index] = elem;
22751    this.dispatchEvent(
22752      /** @type {CollectionEvent<T>} */ (
22753        new CollectionEvent(CollectionEventType.REMOVE, prev, index)
22754      )
22755    );
22756    this.dispatchEvent(
22757      /** @type {CollectionEvent<T>} */ (
22758        new CollectionEvent(CollectionEventType.ADD, elem, index)
22759      )
22760    );
22761  }
22762
22763  /**
22764   * @private
22765   */
22766  updateLength_() {
22767    this.set(Property.LENGTH, this.array_.length);
22768  }
22769
22770  /**
22771   * @private
22772   * @param {T} elem Element.
22773   * @param {number} [except] Optional index to ignore.
22774   */
22775  assertUnique_(elem, except) {
22776    for (let i = 0, ii = this.array_.length; i < ii; ++i) {
22777      if (this.array_[i] === elem && i !== except) {
22778        throw new ol_AssertionError(58);
22779      }
22780    }
22781  }
22782}
22783
22784/* harmony default export */ const ol_Collection = (Collection);
22785
22786;// CONCATENATED MODULE: ./node_modules/ol/color.js
22787/**
22788 * @module ol/color
22789 */
22790
22791
22792
22793/**
22794 * A color represented as a short array [red, green, blue, alpha].
22795 * red, green, and blue should be integers in the range 0..255 inclusive.
22796 * alpha should be a float in the range 0..1 inclusive. If no alpha value is
22797 * given then `1` will be used.
22798 * @typedef {Array<number>} Color
22799 * @api
22800 */
22801
22802/**
22803 * This RegExp matches # followed by 3, 4, 6, or 8 hex digits.
22804 * @const
22805 * @type {RegExp}
22806 * @private
22807 */
22808const HEX_COLOR_RE_ = /^#([a-f0-9]{3}|[a-f0-9]{4}(?:[a-f0-9]{2}){0,2})$/i;
22809
22810/**
22811 * Regular expression for matching potential named color style strings.
22812 * @const
22813 * @type {RegExp}
22814 * @private
22815 */
22816const NAMED_COLOR_RE_ = /^([a-z]*)$|^hsla?\(.*\)$/i;
22817
22818/**
22819 * Return the color as an rgba string.
22820 * @param {Color|string} color Color.
22821 * @return {string} Rgba string.
22822 * @api
22823 */
22824function asString(color) {
22825  if (typeof color === 'string') {
22826    return color;
22827  } else {
22828    return color_toString(color);
22829  }
22830}
22831
22832/**
22833 * Return named color as an rgba string.
22834 * @param {string} color Named color.
22835 * @return {string} Rgb string.
22836 */
22837function fromNamed(color) {
22838  const el = document.createElement('div');
22839  el.style.color = color;
22840  if (el.style.color !== '') {
22841    document.body.appendChild(el);
22842    const rgb = getComputedStyle(el).color;
22843    document.body.removeChild(el);
22844    return rgb;
22845  } else {
22846    return '';
22847  }
22848}
22849
22850/**
22851 * @param {string} s String.
22852 * @return {Color} Color.
22853 */
22854const fromString = (function () {
22855  // We maintain a small cache of parsed strings.  To provide cheap LRU-like
22856  // semantics, whenever the cache grows too large we simply delete an
22857  // arbitrary 25% of the entries.
22858
22859  /**
22860   * @const
22861   * @type {number}
22862   */
22863  const MAX_CACHE_SIZE = 1024;
22864
22865  /**
22866   * @type {Object<string, Color>}
22867   */
22868  const cache = {};
22869
22870  /**
22871   * @type {number}
22872   */
22873  let cacheSize = 0;
22874
22875  return (
22876    /**
22877     * @param {string} s String.
22878     * @return {Color} Color.
22879     */
22880    function (s) {
22881      let color;
22882      if (cache.hasOwnProperty(s)) {
22883        color = cache[s];
22884      } else {
22885        if (cacheSize >= MAX_CACHE_SIZE) {
22886          let i = 0;
22887          for (const key in cache) {
22888            if ((i++ & 3) === 0) {
22889              delete cache[key];
22890              --cacheSize;
22891            }
22892          }
22893        }
22894        color = fromStringInternal_(s);
22895        cache[s] = color;
22896        ++cacheSize;
22897      }
22898      return color;
22899    }
22900  );
22901})();
22902
22903/**
22904 * Return the color as an array. This function maintains a cache of calculated
22905 * arrays which means the result should not be modified.
22906 * @param {Color|string} color Color.
22907 * @return {Color} Color.
22908 * @api
22909 */
22910function asArray(color) {
22911  if (Array.isArray(color)) {
22912    return color;
22913  } else {
22914    return fromString(color);
22915  }
22916}
22917
22918/**
22919 * @param {string} s String.
22920 * @private
22921 * @return {Color} Color.
22922 */
22923function fromStringInternal_(s) {
22924  let r, g, b, a, color;
22925
22926  if (NAMED_COLOR_RE_.exec(s)) {
22927    s = fromNamed(s);
22928  }
22929
22930  if (HEX_COLOR_RE_.exec(s)) {
22931    // hex
22932    const n = s.length - 1; // number of hex digits
22933    let d; // number of digits per channel
22934    if (n <= 4) {
22935      d = 1;
22936    } else {
22937      d = 2;
22938    }
22939    const hasAlpha = n === 4 || n === 8;
22940    r = parseInt(s.substr(1 + 0 * d, d), 16);
22941    g = parseInt(s.substr(1 + 1 * d, d), 16);
22942    b = parseInt(s.substr(1 + 2 * d, d), 16);
22943    if (hasAlpha) {
22944      a = parseInt(s.substr(1 + 3 * d, d), 16);
22945    } else {
22946      a = 255;
22947    }
22948    if (d == 1) {
22949      r = (r << 4) + r;
22950      g = (g << 4) + g;
22951      b = (b << 4) + b;
22952      if (hasAlpha) {
22953        a = (a << 4) + a;
22954      }
22955    }
22956    color = [r, g, b, a / 255];
22957  } else if (s.startsWith('rgba(')) {
22958    // rgba()
22959    color = s.slice(5, -1).split(',').map(Number);
22960    normalize(color);
22961  } else if (s.startsWith('rgb(')) {
22962    // rgb()
22963    color = s.slice(4, -1).split(',').map(Number);
22964    color.push(1);
22965    normalize(color);
22966  } else {
22967    asserts_assert(false, 14); // Invalid color
22968  }
22969  return color;
22970}
22971
22972/**
22973 * TODO this function is only used in the test, we probably shouldn't export it
22974 * @param {Color} color Color.
22975 * @return {Color} Clamped color.
22976 */
22977function normalize(color) {
22978  color[0] = math_clamp((color[0] + 0.5) | 0, 0, 255);
22979  color[1] = math_clamp((color[1] + 0.5) | 0, 0, 255);
22980  color[2] = math_clamp((color[2] + 0.5) | 0, 0, 255);
22981  color[3] = math_clamp(color[3], 0, 1);
22982  return color;
22983}
22984
22985/**
22986 * @param {Color} color Color.
22987 * @return {string} String.
22988 */
22989function color_toString(color) {
22990  let r = color[0];
22991  if (r != (r | 0)) {
22992    r = (r + 0.5) | 0;
22993  }
22994  let g = color[1];
22995  if (g != (g | 0)) {
22996    g = (g + 0.5) | 0;
22997  }
22998  let b = color[2];
22999  if (b != (b | 0)) {
23000    b = (b + 0.5) | 0;
23001  }
23002  const a = color[3] === undefined ? 1 : Math.round(color[3] * 100) / 100;
23003  return 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')';
23004}
23005
23006/**
23007 * @param {string} s String.
23008 * @return {boolean} Whether the string is actually a valid color
23009 */
23010function isStringColor(s) {
23011  if (NAMED_COLOR_RE_.test(s)) {
23012    s = fromNamed(s);
23013  }
23014  return HEX_COLOR_RE_.test(s) || s.startsWith('rgba(') || s.startsWith('rgb(');
23015}
23016
23017;// CONCATENATED MODULE: ./node_modules/ol/style/IconImageCache.js
23018/**
23019 * @module ol/style/IconImageCache
23020 */
23021
23022
23023/**
23024 * @classdesc
23025 * Singleton class. Available through {@link module:ol/style/IconImageCache.shared}.
23026 */
23027class IconImageCache {
23028  constructor() {
23029    /**
23030     * @type {!Object<string, import("./IconImage.js").default>}
23031     * @private
23032     */
23033    this.cache_ = {};
23034
23035    /**
23036     * @type {number}
23037     * @private
23038     */
23039    this.cacheSize_ = 0;
23040
23041    /**
23042     * @type {number}
23043     * @private
23044     */
23045    this.maxCacheSize_ = 32;
23046  }
23047
23048  /**
23049   * FIXME empty description for jsdoc
23050   */
23051  clear() {
23052    this.cache_ = {};
23053    this.cacheSize_ = 0;
23054  }
23055
23056  /**
23057   * @return {boolean} Can expire cache.
23058   */
23059  canExpireCache() {
23060    return this.cacheSize_ > this.maxCacheSize_;
23061  }
23062
23063  /**
23064   * FIXME empty description for jsdoc
23065   */
23066  expire() {
23067    if (this.canExpireCache()) {
23068      let i = 0;
23069      for (const key in this.cache_) {
23070        const iconImage = this.cache_[key];
23071        if ((i++ & 3) === 0 && !iconImage.hasListener()) {
23072          delete this.cache_[key];
23073          --this.cacheSize_;
23074        }
23075      }
23076    }
23077  }
23078
23079  /**
23080   * @param {string} src Src.
23081   * @param {?string} crossOrigin Cross origin.
23082   * @param {import("../color.js").Color} color Color.
23083   * @return {import("./IconImage.js").default} Icon image.
23084   */
23085  get(src, crossOrigin, color) {
23086    const key = getKey(src, crossOrigin, color);
23087    return key in this.cache_ ? this.cache_[key] : null;
23088  }
23089
23090  /**
23091   * @param {string} src Src.
23092   * @param {?string} crossOrigin Cross origin.
23093   * @param {import("../color.js").Color} color Color.
23094   * @param {import("./IconImage.js").default} iconImage Icon image.
23095   */
23096  set(src, crossOrigin, color, iconImage) {
23097    const key = getKey(src, crossOrigin, color);
23098    this.cache_[key] = iconImage;
23099    ++this.cacheSize_;
23100  }
23101
23102  /**
23103   * Set the cache size of the icon cache. Default is `32`. Change this value when
23104   * your map uses more than 32 different icon images and you are not caching icon
23105   * styles on the application level.
23106   * @param {number} maxCacheSize Cache max size.
23107   * @api
23108   */
23109  setSize(maxCacheSize) {
23110    this.maxCacheSize_ = maxCacheSize;
23111    this.expire();
23112  }
23113}
23114
23115/**
23116 * @param {string} src Src.
23117 * @param {?string} crossOrigin Cross origin.
23118 * @param {import("../color.js").Color} color Color.
23119 * @return {string} Cache key.
23120 */
23121function getKey(src, crossOrigin, color) {
23122  const colorString = color ? asString(color) : 'null';
23123  return crossOrigin + ':' + src + ':' + colorString;
23124}
23125
23126/* harmony default export */ const style_IconImageCache = ((/* unused pure expression or super */ null && (IconImageCache)));
23127
23128/**
23129 * The {@link module:ol/style/IconImageCache~IconImageCache} for
23130 * {@link module:ol/style/Icon~Icon} images.
23131 * @api
23132 */
23133const shared = new IconImageCache();
23134
23135;// CONCATENATED MODULE: ./node_modules/ol/layer/Property.js
23136/**
23137 * @module ol/layer/Property
23138 */
23139
23140/**
23141 * @enum {string}
23142 */
23143/* harmony default export */ const layer_Property = ({
23144  OPACITY: 'opacity',
23145  VISIBLE: 'visible',
23146  EXTENT: 'extent',
23147  Z_INDEX: 'zIndex',
23148  MAX_RESOLUTION: 'maxResolution',
23149  MIN_RESOLUTION: 'minResolution',
23150  MAX_ZOOM: 'maxZoom',
23151  MIN_ZOOM: 'minZoom',
23152  SOURCE: 'source',
23153  MAP: 'map',
23154});
23155
23156;// CONCATENATED MODULE: ./node_modules/ol/layer/Base.js
23157/**
23158 * @module ol/layer/Base
23159 */
23160
23161
23162
23163
23164
23165
23166/**
23167 * A css color, or a function called with a view resolution returning a css color.
23168 *
23169 * @typedef {string|function(number):string}
23169 BackgroundColor
23170 * @api
23171 */
23172
23173/**
23174 * @typedef {import("../ObjectEventType").Types|'change:extent'|'change:maxResolution'|'change:maxZoom'|
23175 *    'change:minResolution'|'change:minZoom'|'change:opacity'|'change:visible'|'change:zIndex'} BaseLayerObjectEventTypes
23176 */
23177
23178/***
23179 * @template Return
23180 * @typedef {import("../Observable").OnSignature<import("../Observable").EventTypes, import("../events/Event.js").default, Return> &
23181 *   import("../Observable").OnSignature<BaseLayerObjectEventTypes, import("../Object").ObjectEvent, Return> &
23182 *   import("../Observable").CombinedOnSignature<import("../Observable").EventTypes|BaseLayerObjectEventTypes, Return>} BaseLayerOnSignature
23183 */
23184
23185/**
23186 * @typedef {Object} Options
23187 * @property {string} [className='ol-layer'] A CSS class name to set to the layer element.
23188 * @property {number} [opacity=1] Opacity (0, 1).
23189 * @property {boolean} [visible=true] Visibility.
23190 * @property {import("../extent.js").Extent} [extent] The bounding extent for layer rendering.  The layer will not be
23191 * rendered outside of this extent.
23192 * @property {number} [zIndex] The z-index for layer rendering.  At rendering time, the layers
23193 * will be ordered, first by Z-index and then by position. When `undefined`, a `zIndex` of 0 is assumed
23194 * for layers that are added to the map's `layers` collection, or `Infinity` when the layer's `setMap()`
23195 * method was used.
23196 * @property {number} [minResolution] The minimum resolution (inclusive) at which this layer will be
23197 * visible.
23198 * @property {number} [maxResolution] The maximum resolution (exclusive) below which this layer will
23199 * be visible.
23200 * @property {number} [minZoom] The minimum view zoom level (exclusive) above which this layer will be
23201 * visible.
23202 * @property {number} [maxZoom] The maximum view zoom level (inclusive) at which this layer will
23203 * be visible.
23204 * @property {BackgroundColor} [background] Background color for the layer. If not specified, no background
23205 * will be rendered.
23206 * @property {Object<string, *>} [properties] Arbitrary observable properties. Can be accessed with `#get()` and `#set()`.
23207 */
23208
23209/**
23210 * @classdesc
23211 * Abstract base class; normally only used for creating subclasses and not
23212 * instantiated in apps.
23213 * Note that with {@link module:ol/layer/Base~BaseLayer} and all its subclasses, any property set in
23214 * the options is set as a {@link module:ol/Object~BaseObject} property on the layer object, so
23215 * is observable, and has get/set accessors.
23216 *
23217 * @api
23218 */
23219class BaseLayer extends ol_Object {
23220  /**
23221   * @param {Options} options Layer options.
23222   */
23223  constructor(options) {
23224    super();
23225
23226    /***
23227     * @type {BaseLayerOnSignature<import("../events").EventsKey>}
23228     */
23229    this.on;
23230
23231    /***
23232     * @type {BaseLayerOnSignature<import("../events").EventsKey>}
23233     */
23234    this.once;
23235
23236    /***
23237     * @type {BaseLayerOnSignature<void>}
23238     */
23239    this.un;
23240
23241    /**
23242     * @type {BackgroundColor|false}
23243     * @private
23244     */
23245    this.background_ = options.background;
23246
23247    /**
23248     * @type {Object<string, *>}
23249     */
23250    const properties = Object.assign({}, options);
23251    if (typeof options.properties === 'object') {
23252      delete properties.properties;
23253      Object.assign(properties, options.properties);
23254    }
23255
23256    properties[layer_Property.OPACITY] =
23257      options.opacity !== undefined ? options.opacity : 1;
23258    asserts_assert(typeof properties[layer_Property.OPACITY] === 'number', 64); // Layer opacity must be a number
23259
23260    properties[layer_Property.VISIBLE] =
23261      options.visible !== undefined ? options.visible : true;
23262    properties[layer_Property.Z_INDEX] = options.zIndex;
23263    properties[layer_Property.MAX_RESOLUTION] =
23264      options.maxResolution !== undefined ? options.maxResolution : Infinity;
23265    properties[layer_Property.MIN_RESOLUTION] =
23266      options.minResolution !== undefined ? options.minResolution : 0;
23267    properties[layer_Property.MIN_ZOOM] =
23268      options.minZoom !== undefined ? options.minZoom : -Infinity;
23269    properties[layer_Property.MAX_ZOOM] =
23270      options.maxZoom !== undefined ? options.maxZoom : Infinity;
23271
23272    /**
23273     * @type {string}
23274     * @private
23275     */
23276    this.className_ =
23277      properties.className !== undefined ? properties.className : 'ol-layer';
23278    delete properties.className;
23279
23280    this.setProperties(properties);
23281
23282    /**
23283     * @type {import("./Layer.js").State}
23284     * @private
23285     */
23286    this.state_ = null;
23287  }
23288
23289  /**
23290   * Get the background for this layer.
23291   * @return {BackgroundColor|false} Layer background.
23292   */
23293  getBackground() {
23294    return this.background_;
23295  }
23296
23297  /**
23298   * @return {string} CSS class name.
23299   */
23300  getClassName() {
23301    return this.className_;
23302  }
23303
23304  /**
23305   * This method is not meant to be called by layers or layer renderers because the state
23306   * is incorrect if the layer is included in a layer group.
23307   *
23308   * @param {boolean} [managed] Layer is managed.
23309   * @return {import("./Layer.js").State} Layer state.
23310   */
23311  getLayerState(managed) {
23312    /** @type {import("./Layer.js").State} */
23313    const state =
23314      this.state_ ||
23315      /** @type {?} */ ({
23316        layer: this,
23317        managed: managed === undefined ? true : managed,
23318      });
23319    const zIndex = this.getZIndex();
23320    state.opacity = math_clamp(Math.round(this.getOpacity() * 100) / 100, 0, 1);
23321    state.visible = this.getVisible();
23322    state.extent = this.getExtent();
23323    state.zIndex = zIndex === undefined && !state.managed ? Infinity : zIndex;
23324    state.maxResolution = this.getMaxResolution();
23325    state.minResolution = Math.max(this.getMinResolution(), 0);
23326    state.minZoom = this.getMinZoom();
23327    state.maxZoom = this.getMaxZoom();
23328    this.state_ = state;
23329
23330    return state;
23331  }
23332
23333  /**
23334   * @abstract
23335   * @param {Array<import("./Layer.js").default>} [array] Array of layers (to be
23336   *     modified in place).
23337   * @return {Array<import("./Layer.js").default>} Array of layers.
23338   */
23339  getLayersArray(array) {
23340    return util_abstract();
23341  }
23342
23343  /**
23344   * @abstract
23345   * @param {Array<import("./Layer.js").State>} [states] Optional list of layer
23346   *     states (to be modified in place).
23347   * @return {Array<import("./Layer.js").State>} List of layer states.
23348   */
23349  getLayerStatesArray(states) {
23350    return util_abstract();
23351  }
23352
23353  /**
23354   * Return the {@link module:ol/extent~Extent extent} of the layer or `undefined` if it
23355   * will be visible regardless of extent.
23356   * @return {import("../extent.js").Extent|undefined} The layer extent.
23357   * @observable
23358   * @api
23359   */
23360  getExtent() {
23361    return /** @type {import("../extent.js").Extent|undefined} */ (
23362      this.get(layer_Property.EXTENT)
23363    );
23364  }
23365
23366  /**
23367   * Return the maximum resolution of the layer.
23368   * @return {number} The maximum resolution of the layer.
23369   * @observable
23370   * @api
23371   */
23372  getMaxResolution() {
23373    return /** @type {number} */ (this.get(layer_Property.MAX_RESOLUTION));
23374  }
23375
23376  /**
23377   * Return the minimum resolution of the layer.
23378   * @return {number} The minimum resolution of the layer.
23379   * @observable
23380   * @api
23381   */
23382  getMinResolution() {
23383    return /** @type {number} */ (this.get(layer_Property.MIN_RESOLUTION));
23384  }
23385
23386  /**
23387   * Return the minimum zoom level of the layer.
23388   * @return {number} The minimum zoom level of the layer.
23389   * @observable
23390   * @api
23391   */
23392  getMinZoom() {
23393    return /** @type {number} */ (this.get(layer_Property.MIN_ZOOM));
23394  }
23395
23396  /**
23397   * Return the maximum zoom level of the layer.
23398   * @return {number} The maximum zoom level of the layer.
23399   * @observable
23400   * @api
23401   */
23402  getMaxZoom() {
23403    return /** @type {number} */ (this.get(layer_Property.MAX_ZOOM));
23404  }
23405
23406  /**
23407   * Return the opacity of the layer (between 0 and 1).
23408   * @return {number} The opacity of the layer.
23409   * @observable
23410   * @api
23411   */
23412  getOpacity() {
23413    return /** @type {number} */ (this.get(layer_Property.OPACITY));
23414  }
23415
23416  /**
23417   * @abstract
23418   * @return {import("../source/Source.js").State} Source state.
23419   */
23420  getSourceState() {
23421    return util_abstract();
23422  }
23423
23424  /**
23425   * Return the visibility of the layer (`true` or `false`).
23426   * @return {boolean} The visibility of the layer.
23427   * @observable
23428   * @api
23429   */
23430  getVisible() {
23431    return /** @type {boolean} */ (this.get(layer_Property.VISIBLE));
23432  }
23433
23434  /**
23435   * Return the Z-index of the layer, which is used to order layers before
23436   * rendering. The default Z-index is 0.
23437   * @return {number} The Z-index of the layer.
23438   * @observable
23439   * @api
23440   */
23441  getZIndex() {
23442    return /** @type {number} */ (this.get(layer_Property.Z_INDEX));
23443  }
23444
23445  /**
23446   * Sets the background color.
23447   * @param {BackgroundColor} [background] Background color.
23448   */
23449  setBackground(background) {
23450    this.background_ = background;
23451    this.changed();
23452  }
23453
23454  /**
23455   * Set the extent at which the layer is visible.  If `undefined`, the layer
23456   * will be visible at all extents.
23457   * @param {import("../extent.js").Extent|undefined} extent The extent of the layer.
23458   * @observable
23459   * @api
23460   */
23461  setExtent(extent) {
23462    this.set(layer_Property.EXTENT, extent);
23463  }
23464
23465  /**
23466   * Set the maximum resolution at which the layer is visible.
23467   * @param {number} maxResolution The maximum resolution of the layer.
23468   * @observable
23469   * @api
23470   */
23471  setMaxResolution(maxResolution) {
23472    this.set(layer_Property.MAX_RESOLUTION, maxResolution);
23473  }
23474
23475  /**
23476   * Set the minimum resolution at which the layer is visible.
23477   * @param {number} minResolution The minimum resolution of the layer.
23478   * @observable
23479   * @api
23480   */
23481  setMinResolution(minResolution) {
23482    this.set(layer_Property.MIN_RESOLUTION, minResolution);
23483  }
23484
23485  /**
23486   * Set the maximum zoom (exclusive) at which the layer is visible.
23487   * Note that the zoom levels for layer visibility are based on the
23488   * view zoom level, which may be different from a tile source zoom level.
23489   * @param {number} maxZoom The maximum zoom of the layer.
23490   * @observable
23491   * @api
23492   */
23493  setMaxZoom(maxZoom) {
23494    this.set(layer_Property.MAX_ZOOM, maxZoom);
23495  }
23496
23497  /**
23498   * Set the minimum zoom (inclusive) at which the layer is visible.
23499   * Note that the zoom levels for layer visibility are based on the
23500   * view zoom level, which may be different from a tile source zoom level.
23501   * @param {number} minZoom The minimum zoom of the layer.
23502   * @observable
23503   * @api
23504   */
23505  setMinZoom(minZoom) {
23506    this.set(layer_Property.MIN_ZOOM, minZoom);
23507  }
23508
23509  /**
23510   * Set the opacity of the layer, allowed values range from 0 to 1.
23511   * @param {number} opacity The opacity of the layer.
23512   * @observable
23513   * @api
23514   */
23515  setOpacity(opacity) {
23516    asserts_assert(typeof opacity === 'number', 64); // Layer opacity must be a number
23517    this.set(layer_Property.OPACITY, opacity);
23518  }
23519
23520  /**
23521   * Set the visibility of the layer (`true` or `false`).
23522   * @param {boolean} visible The visibility of the layer.
23523   * @observable
23524   * @api
23525   */
23526  setVisible(visible) {
23527    this.set(layer_Property.VISIBLE, visible);
23528  }
23529
23530  /**
23531   * Set Z-index of the layer, which is used to order layers before rendering.
23532   * The default Z-index is 0.
23533   * @param {number} zindex The z-index of the layer.
23534   * @observable
23535   * @api
23536   */
23537  setZIndex(zindex) {
23538    this.set(layer_Property.Z_INDEX, zindex);
23539  }
23540
23541  /**
23542   * Clean up.
23543   */
23544  disposeInternal() {
23545    if (this.state_) {
23546      this.state_.layer = null;
23547      this.state_ = null;
23548    }
23549    super.disposeInternal();
23550  }
23551}
23552
23553/* harmony default export */ const Base = (BaseLayer);
23554
23555;// CONCATENATED MODULE: ./node_modules/ol/render/EventType.js
23556/**
23557 * @module ol/render/EventType
23558 */
23559
23560/**
23561 * @enum {string}
23562 */
23563/* harmony default export */ const render_EventType = ({
23564  /**
23565   * Triggered before a layer is rendered.
23566   * @event module:ol/render/Event~RenderEvent#prerender
23567   * @api
23568   */
23569  PRERENDER: 'prerender',
23570
23571  /**
23572   * Triggered after a layer is rendered.
23573   * @event module:ol/render/Event~RenderEvent#postrender
23574   * @api
23575   */
23576  POSTRENDER: 'postrender',
23577
23578  /**
23579   * Triggered before layers are composed.  When dispatched by the map, the event object will not have
23580   * a `context` set.  When dispatched by a layer, the event object will have a `context` set.  Only
23581   * WebGL layers currently dispatch this event.
23582   * @event module:ol/render/Event~RenderEvent#precompose
23583   * @api
23584   */
23585  PRECOMPOSE: 'precompose',
23586
23587  /**
23588   * Triggered after layers are composed.  When dispatched by the map, the event object will not have
23589   * a `context` set.  When dispatched by a layer, the event object will have a `context` set.  Only
23590   * WebGL layers currently dispatch this event.
23591   * @event module:ol/render/Event~RenderEvent#postcompose
23592   * @api
23593   */
23594  POSTCOMPOSE: 'postcompose',
23595
23596  /**
23597   * Triggered when rendering is complete, i.e. all sources and tiles have
23598   * finished loading for the current viewport, and all tiles are faded in.
23599   * The event object will not have a `context` set.
23600   * @event module:ol/render/Event~RenderEvent#rendercomplete
23601   * @api
23602   */
23603  RENDERCOMPLETE: 'rendercomplete',
23604});
23605
23606/**
23607 * @typedef {'postrender'|'precompose'|'postcompose'|'rendercomplete'} MapRenderEventTypes
23608 */
23609
23610/**
23611 * @typedef {'postrender'|'prerender'} LayerRenderEventTypes
23612 */
23613
23614;// CONCATENATED MODULE: ./node_modules/ol/layer/Layer.js
23615/**
23616 * @module ol/layer/Layer
23617 */
23618
23619
23620
23621
23622
23623
23624
23625/**
23626 * @typedef {function(import("../Map.js").FrameState):HTMLElement} RenderFunction
23627 */
23628
23629/***
23630 * @template Return
23631 * @typedef {import("../Observable").OnSignature<import("../Observable").EventTypes, import("../events/Event.js").default, Return> &
23632 *   import("../Observable").OnSignature<import("./Base").BaseLayerObjectEventTypes|
23633 *     'change:source', import("../Object").ObjectEvent, Return> &
23634 *   import("../Observable").OnSignature<import("../render/EventType").LayerRenderEventTypes, import("../render/Event").default, Return> &
23635 *   import("../Observable").CombinedOnSignature<import("../Observable").EventTypes|import("./Base").BaseLayerObjectEventTypes|'change:source'|
23636 *     import("../render/EventType").LayerRenderEventTypes, Return>} LayerOnSignature
23637 */
23638
23639/**
23640 * @template {import("../source/Source.js").default} [SourceType=import("../source/Source.js").default]
23641 * @typedef {Object} Options
23642 * @property {string} [className='ol-layer'] A CSS class name to set to the layer element.
23643 * @property {number} [opacity=1] Opacity (0, 1).
23644 * @property {boolean} [visible=true] Visibility.
23645 * @property {import("../extent.js").Extent} [extent] The bounding extent for layer rendering.  The layer will not be
23646 * rendered outside of this extent.
23647 * @property {number} [zIndex] The z-index for layer rendering.  At rendering time, the layers
23648 * will be ordered, first by Z-index and then by position. When `undefined`, a `zIndex` of 0 is assumed
23649 * for layers that are added to the map's `layers` collection, or `Infinity` when the layer's `setMap()`
23650 * method was used.
23651 * @property {number} [minResolution] The minimum resolution (inclusive) at which this layer will be
23652 * visible.
23653 * @property {number} [maxResolution] The maximum resolution (exclusive) below which this layer will
23654 * be visible.
23655 * @property {number} [minZoom] The minimum view zoom level (exclusive) above which this layer will be
23656 * visible.
23657 * @property {number} [maxZoom] The maximum view zoom level (inclusive) at which this layer will
23658 * be visible.
23659 * @property {SourceType} [source] Source for this layer.  If not provided to the constructor,
23660 * the source can be set by calling {@link module:ol/layer/Layer~Layer#setSource layer.setSource(source)} after
23661 * construction.
23662 * @property {import("../Map.js").default|null} [map] Map.
23663 * @property {RenderFunction} [render] Render function. Takes the frame state as input and is expected to return an
23664 * HTML element. Will overwrite the default rendering for the layer.
23665 * @property {Object<string, *>} [properties] Arbitrary observable properties. Can be accessed with `#get()` and `#set()`.
23666 */
23667
23668/**
23669 * @typedef {Object} State
23670 * @property {import("./Layer.js").default} layer Layer.
23671 * @property {number} opacity Opacity, the value is rounded to two digits to appear after the decimal point.
23672 * @property {boolean} visible Visible.
23673 * @property {boolean} managed Managed.
23674 * @property {import("../extent.js").Extent} [extent] Extent.
23675 * @property {number} zIndex ZIndex.
23676 * @property {number} maxResolution Maximum resolution.
23677 * @property {number} minResolution Minimum resolution.
23678 * @property {number} minZoom Minimum zoom.
23679 * @property {number} maxZoom Maximum zoom.
23680 */
23681
23682/**
23683 * @classdesc
23684 * Base class from which all layer types are derived. This should only be instantiated
23685 * in the case where a custom layer is added to the map with a custom `render` function.
23686 * Such a function can be specified in the `options` object, and is expected to return an HTML element.
23687 *
23688 * A visual representation of raster or vector map data.
23689 * Layers group together those properties that pertain to how the data is to be
23690 * displayed, irrespective of the source of that data.
23691 *
23692 * Layers are usually added to a map with [map.addLayer()]{@link import("../Map.js").default#addLayer}.
23693 * Components like {@link module:ol/interaction/Draw~Draw} use unmanaged layers
23694 * internally. These unmanaged layers are associated with the map using
23695 * [layer.setMap()]{@link module:ol/layer/Layer~Layer#setMap} instead.
23696 *
23697 * A generic `change` event is fired when the state of the source changes.
23698 *
23699 * @fires import("../render/Event.js").RenderEvent#prerender
23700 * @fires import("../render/Event.js").RenderEvent#postrender
23701 *
23702 * @template {import("../source/Source.js").default} [SourceType=import("../source/Source.js").default]
23703 * @template {import("../renderer/Layer.js").default} [RendererType=import("../renderer/Layer.js").default]
23704 * @api
23705 */
23706class Layer extends Base {
23707  /**
23708   * @param {Options<SourceType>} options Layer options.
23709   */
23710  constructor(options) {
23711    const baseOptions = Object.assign({}, options);
23712    delete baseOptions.source;
23713
23714    super(baseOptions);
23715
23716    /***
23717     * @type {LayerOnSignature<import("../events").EventsKey>}
23718     */
23719    this.on;
23720
23721    /***
23722     * @type {LayerOnSignature<import("../events").EventsKey>}
23723     */
23724    this.once;
23725
23726    /***
23727     * @type {LayerOnSignature<void>}
23728     */
23729    this.un;
23730
23731    /**
23732     * @private
23733     * @type {?import("../events.js").EventsKey}
23734     */
23735    this.mapPrecomposeKey_ = null;
23736
23737    /**
23738     * @private
23739     * @type {?import("../events.js").EventsKey}
23740     */
23741    this.mapRenderKey_ = null;
23742
23743    /**
23744     * @private
23745     * @type {?import("../events.js").EventsKey}
23746     */
23747    this.sourceChangeKey_ = null;
23748
23749    /**
23750     * @private
23751     * @type {RendererType}
23752     */
23753    this.renderer_ = null;
23754
23755    /**
23756     * @protected
23757     * @type {boolean}
23758     */
23759    this.rendered = false;
23760
23761    // Overwrite default render method with a custom one
23762    if (options.render) {
23763      this.render = options.render;
23764    }
23765
23766    if (options.map) {
23767      this.setMap(options.map);
23768    }
23769
23770    this.addChangeListener(
23771      layer_Property.SOURCE,
23772      this.handleSourcePropertyChange_
23773    );
23774
23775    const source = options.source
23776      ? /** @type {SourceType} */ (options.source)
23777      : null;
23778    this.setSource(source);
23779  }
23780
23781  /**
23782   * @param {Array<import("./Layer.js").default>} [array] Array of layers (to be modified in place).
23783   * @return {Array<import("./Layer.js").default>} Array of layers.
23784   */
23785  getLayersArray(array) {
23786    array = array ? array : [];
23787    array.push(this);
23788    return array;
23789  }
23790
23791  /**
23792   * @param {Array<import("./Layer.js").State>} [states] Optional list of layer states (to be modified in place).
23793   * @return {Array<import("./Layer.js").State>} List of layer states.
23794   */
23795  getLayerStatesArray(states) {
23796    states = states ? states : [];
23797    states.push(this.getLayerState());
23798    return states;
23799  }
23800
23801  /**
23802   * Get the layer source.
23803   * @return {SourceType|null} The layer source (or `null` if not yet set).
23804   * @observable
23805   * @api
23806   */
23807  getSource() {
23808    return /** @type {SourceType} */ (this.get(layer_Property.SOURCE)) || null;
23809  }
23810
23811  /**
23812   * @return {SourceType|null} The source being rendered.
23813   */
23814  getRenderSource() {
23815    return this.getSource();
23816  }
23817
23818  /**
23819   * @return {import("../source/Source.js").State} Source state.
23820   */
23821  getSourceState() {
23822    const source = this.getSource();
23823    return !source ? 'undefined' : source.getState();
23824  }
23825
23826  /**
23827   * @private
23828   */
23829  handleSourceChange_() {
23830    this.changed();
23831  }
23832
23833  /**
23834   * @private
23835   */
23836  handleSourcePropertyChange_() {
23837    if (this.sourceChangeKey_) {
23838      unlistenByKey(this.sourceChangeKey_);
23839      this.sourceChangeKey_ = null;
23840    }
23841    const source = this.getSource();
23842    if (source) {
23843      this.sourceChangeKey_ = listen(
23844        source,
23845        EventType.CHANGE,
23846        this.handleSourceChange_,
23847        this
23848      );
23849    }
23850    this.changed();
23851  }
23852
23853  /**
23854   * @param {import("../pixel").Pixel} pixel Pixel.
23855   * @return {Promise<Array<import("../Feature").default>>} Promise that resolves with
23856   * an array of features.
23857   */
23858  getFeatures(pixel) {
23859    if (!this.renderer_) {
23860      return new Promise((resolve) => resolve([]));
23861    }
23862    return this.renderer_.getFeatures(pixel);
23863  }
23864
23865  /**
23866   * @param {import("../pixel").Pixel} pixel Pixel.
23867   * @return {Uint8ClampedArray|Uint8Array|Float32Array|DataView|null} Pixel data.
23868   */
23869  getData(pixel) {
23870    if (!this.renderer_ || !this.rendered) {
23871      return null;
23872    }
23873    return this.renderer_.getData(pixel);
23874  }
23875
23876  /**
23877   * In charge to manage the rendering of the layer. One layer type is
23878   * bounded with one layer renderer.
23879   * @param {?import("../Map.js").FrameState} frameState Frame state.
23880   * @param {HTMLElement} target Target which the renderer may (but need not) use
23881   * for rendering its content.
23882   * @return {HTMLElement} The rendered element.
23883   */
23884  render(frameState, target) {
23885    const layerRenderer = this.getRenderer();
23886
23887    if (layerRenderer.prepareFrame(frameState)) {
23888      this.rendered = true;
23889      return layerRenderer.renderFrame(frameState, target);
23890    }
23891  }
23892
23893  /**
23894   * Called when a layer is not visible during a map render.
23895   */
23896  unrender() {
23897    this.rendered = false;
23898  }
23899
23900  /**
23901   * For use inside the library only.
23902   * @param {import("../Map.js").default|null} map Map.
23903   */
23904  setMapInternal(map) {
23905    if (!map) {
23906      this.unrender();
23907    }
23908    this.set(layer_Property.MAP, map);
23909  }
23910
23911  /**
23912   * For use inside the library only.
23913   * @return {import("../Map.js").default|null} Map.
23914   */
23915  getMapInternal() {
23916    return this.get(layer_Property.MAP);
23917  }
23918
23919  /**
23920   * Sets the layer to be rendered on top of other layers on a map. The map will
23921   * not manage this layer in its layers collection. This
23922   * is useful for temporary layers. To remove an unmanaged layer from the map,
23923   * use `#setMap(null)`.
23924   *
23925   * To add the layer to a map and have it managed by the map, use
23926   * {@link module:ol/Map~Map#addLayer} instead.
23927   * @param {import("../Map.js").default|null} map Map.
23928   * @api
23929   */
23930  setMap(map) {
23931    if (this.mapPrecomposeKey_) {
23932      unlistenByKey(this.mapPrecomposeKey_);
23933      this.mapPrecomposeKey_ = null;
23934    }
23935    if (!map) {
23936      this.changed();
23937    }
23938    if (this.mapRenderKey_) {
23939      unlistenByKey(this.mapRenderKey_);
23940      this.mapRenderKey_ = null;
23941    }
23942    if (map) {
23943      this.mapPrecomposeKey_ = listen(
23944        map,
23945        render_EventType.PRECOMPOSE,
23946        function (evt) {
23947          const renderEvent =
23948            /** @type {import("../render/Event.js").default} */ (evt);
23949          const layerStatesArray = renderEvent.frameState.layerStatesArray;
23950          const layerState = this.getLayerState(false);
23951          // A layer can only be added to the map once. Use either `layer.setMap()` or `map.addLayer()`, not both.
23952          asserts_assert(
23953            !layerStatesArray.some(function (arrayLayerState) {
23954              return arrayLayerState.layer === layerState.layer;
23955            }),
23956            67
23957          );
23958          layerStatesArray.push(layerState);
23959        },
23960        this
23961      );
23962      this.mapRenderKey_ = listen(this, EventType.CHANGE, map.render, map);
23963      this.changed();
23964    }
23965  }
23966
23967  /**
23968   * Set the layer source.
23969   * @param {SourceType|null} source The layer source.
23970   * @observable
23971   * @api
23972   */
23973  setSource(source) {
23974    this.set(layer_Property.SOURCE, source);
23975  }
23976
23977  /**
23978   * Get the renderer for this layer.
23979   * @return {RendererType|null} The layer renderer.
23980   */
23981  getRenderer() {
23982    if (!this.renderer_) {
23983      this.renderer_ = this.createRenderer();
23984    }
23985    return this.renderer_;
23986  }
23987
23988  /**
23989   * @return {boolean} The layer has a renderer.
23990   */
23991  hasRenderer() {
23992    return !!this.renderer_;
23993  }
23994
23995  /**
23996   * Create a renderer for this layer.
23997   * @return {RendererType} A layer renderer.
23998   * @protected
23999   */
24000  createRenderer() {
24001    return null;
24002  }
24003
24004  /**
24005   * Clean up.
24006   */
24007  disposeInternal() {
24008    if (this.renderer_) {
24009      this.renderer_.dispose();
24010      delete this.renderer_;
24011    }
24012
24013    this.setSource(null);
24014    super.disposeInternal();
24015  }
24016}
24017
24018/**
24019 * Return `true` if the layer is visible and if the provided view state
24020 * has resolution and zoom levels that are in range of the layer's min/max.
24021 * @param {State} layerState Layer state.
24022 * @param {import("../View.js").State} viewState View state.
24023 * @return {boolean} The layer is visible at the given view state.
24024 */
24025function inView(layerState, viewState) {
24026  if (!layerState.visible) {
24027    return false;
24028  }
24029  const resolution = viewState.resolution;
24030  if (
24031    resolution < layerState.minResolution ||
24032    resolution >= layerState.maxResolution
24033  ) {
24034    return false;
24035  }
24036  const zoom = viewState.zoom;
24037  return zoom > layerState.minZoom && zoom <= layerState.maxZoom;
24038}
24039
24040/* harmony default export */ const layer_Layer = (Layer);
24041
24042;// CONCATENATED MODULE: ./node_modules/ol/renderer/Map.js
24043/**
24044 * @module ol/renderer/Map
24045 */
24046
24047
24048
24049
24050
24051
24052
24053
24054
24055/**
24056 * @typedef HitMatch
24057 * @property {import("../Feature.js").FeatureLike} feature Feature.
24058 * @property {import("../layer/Layer.js").default} layer Layer.
24059 * @property {import("../geom/SimpleGeometry.js").default} geometry Geometry.
24060 * @property {number} distanceSq Squared distance.
24061 * @property {import("./vector.js").FeatureCallback<T>} callback Callback.
24062 * @template T
24063 */
24064
24065/**
24066 * @abstract
24067 */
24068class MapRenderer extends ol_Disposable {
24069  /**
24070   * @param {import("../Map.js").default} map Map.
24071   */
24072  constructor(map) {
24073    super();
24074
24075    /**
24076     * @private
24077     * @type {import("../Map.js").default}
24078     */
24079    this.map_ = map;
24080  }
24081
24082  /**
24083   * @abstract
24084   * @param {import("../render/EventType.js").default} type Event type.
24085   * @param {import("../Map.js").FrameState} frameState Frame state.
24086   */
24087  dispatchRenderEvent(type, frameState) {
24088    util_abstract();
24089  }
24090
24091  /**
24092   * @param {import("../Map.js").FrameState} frameState FrameState.
24093   * @protected
24094   */
24095  calculateMatrices2D(frameState) {
24096    const viewState = frameState.viewState;
24097    const coordinateToPixelTransform = frameState.coordinateToPixelTransform;
24098    const pixelToCoordinateTransform = frameState.pixelToCoordinateTransform;
24099
24100    compose(
24101      coordinateToPixelTransform,
24102      frameState.size[0] / 2,
24103      frameState.size[1] / 2,
24104      1 / viewState.resolution,
24105      -1 / viewState.resolution,
24106      -viewState.rotation,
24107      -viewState.center[0],
24108      -viewState.center[1]
24109    );
24110
24111    makeInverse(pixelToCoordinateTransform, coordinateToPixelTransform);
24112  }
24113
24114  /**
24115   * @param {import("../coordinate.js").Coordinate} coordinate Coordinate.
24116   * @param {import("../Map.js").FrameState} frameState FrameState.
24117   * @param {number} hitTolerance Hit tolerance in pixels.
24118   * @param {boolean} checkWrapped Check for wrapped geometries.
24119   * @param {import("./vector.js").FeatureCallback<T>}
24119 callback Feature callback.
24120   * @param {S} thisArg Value to use as `this` when executing `callback`.
24121   * @param {function(this: U, import("../layer/Layer.js").default): boolean} layerFilter Layer filter
24122   *     function, only layers which are visible and for which this function
24123   *     returns `true` will be tested for features.  By default, all visible
24124   *     layers will be tested.
24125   * @param {U} thisArg2 Value to use as `this` when executing `layerFilter`.
24126   * @return {T|undefined} Callback result.
24127   * @template S,T,U
24128   */
24129  forEachFeatureAtCoordinate(
24130    coordinate,
24131    frameState,
24132    hitTolerance,
24133    checkWrapped,
24134    callback,
24135    thisArg,
24136    layerFilter,
24137    thisArg2
24138  ) {
24139    let result;
24140    const viewState = frameState.viewState;
24141
24142    /**
24143     * @param {boolean} managed Managed layer.
24144     * @param {import("../Feature.js").FeatureLike} feature Feature.
24145     * @param {import("../layer/Layer.js").default} layer Layer.
24146     * @param {import("../geom/Geometry.js").default} geometry Geometry.
24147     * @return {T|undefined} Callback result.
24148     */
24149    function forEachFeatureAtCoordinate(managed, feature, layer, geometry) {
24150      return callback.call(thisArg, feature, managed ? layer : null, geometry);
24151    }
24152
24153    const projection = viewState.projection;
24154
24155    const translatedCoordinate = coordinate_wrapX(coordinate.slice(), projection);
24156    const offsets = [[0, 0]];
24157    if (projection.canWrapX() && checkWrapped) {
24158      const projectionExtent = projection.getExtent();
24159      const worldWidth = extent_getWidth(projectionExtent);
24160      offsets.push([-worldWidth, 0], [worldWidth, 0]);
24161    }
24162
24163    const layerStates = frameState.layerStatesArray;
24164    const numLayers = layerStates.length;
24165
24166    const matches = /** @type {Array<HitMatch<T>>} */ ([]);
24167    const tmpCoord = [];
24168    for (let i = 0; i < offsets.length; i++) {
24169      for (let j = numLayers - 1; j >= 0; --j) {
24170        const layerState = layerStates[j];
24171        const layer = layerState.layer;
24172        if (
24173          layer.hasRenderer() &&
24174          inView(layerState, viewState) &&
24175          layerFilter.call(thisArg2, layer)
24176        ) {
24177          const layerRenderer = layer.getRenderer();
24178          const source = layer.getSource();
24179          if (layerRenderer && source) {
24180            const coordinates = source.getWrapX()
24181              ? translatedCoordinate
24182              : coordinate;
24183            const callback = forEachFeatureAtCoordinate.bind(
24184              null,
24185              layerState.managed
24186            );
24187            tmpCoord[0] = coordinates[0] + offsets[i][0];
24188            tmpCoord[1] = coordinates[1] + offsets[i][1];
24189            result = layerRenderer.forEachFeatureAtCoordinate(
24190              tmpCoord,
24191              frameState,
24192              hitTolerance,
24193              callback,
24194              matches
24195            );
24196          }
24197          if (result) {
24198            return result;
24199          }
24200        }
24201      }
24202    }
24203    if (matches.length === 0) {
24204      return undefined;
24205    }
24206    const order = 1 / matches.length;
24207    matches.forEach((m, i) => (m.distanceSq += i * order));
24208    matches.sort((a, b) => a.distanceSq - b.distanceSq);
24209    matches.some((m) => {
24210      return (result = m.callback(m.feature, m.layer, m.geometry));
24211    });
24212    return result;
24213  }
24214
24215  /**
24216   * @param {import("../coordinate.js").Coordinate} coordinate Coordinate.
24217   * @param {import("../Map.js").FrameState} frameState FrameState.
24218   * @param {number} hitTolerance Hit tolerance in pixels.
24219   * @param {boolean} checkWrapped Check for wrapped geometries.
24220   * @param {function(this: U, import("../layer/Layer.js").default): boolean} layerFilter Layer filter
24221   *     function, only layers which are visible and for which this function
24222   *     returns `true` will be tested for features.  By default, all visible
24223   *     layers will be tested.
24224   * @param {U} thisArg Value to use as `this` when executing `layerFilter`.
24225   * @return {boolean} Is there a feature at the given coordinate?
24226   * @template U
24227   */
24228  hasFeatureAtCoordinate(
24229    coordinate,
24230    frameState,
24231    hitTolerance,
24232    checkWrapped,
24233    layerFilter,
24234    thisArg
24235  ) {
24236    const hasFeature = this.forEachFeatureAtCoordinate(
24237      coordinate,
24238      frameState,
24239      hitTolerance,
24240      checkWrapped,
24241      TRUE,
24242      this,
24243      layerFilter,
24244      thisArg
24245    );
24246
24247    return hasFeature !== undefined;
24248  }
24249
24250  /**
24251   * @return {import("../Map.js").default} Map.
24252   */
24253  getMap() {
24254    return this.map_;
24255  }
24256
24257  /**
24258   * Render.
24259   * @abstract
24260   * @param {?import("../Map.js").FrameState} frameState Frame state.
24261   */
24262  renderFrame(frameState) {
24263    util_abstract();
24264  }
24265
24266  /**
24267   * @param {import("../Map.js").FrameState} frameState Frame state.
24268   * @protected
24269   */
24270  scheduleExpireIconCache(frameState) {
24271    if (shared.canExpireCache()) {
24272      frameState.postRenderFunctions.push(expireIconCache);
24273    }
24274  }
24275}
24276
24277/**
24278 * @param {import("../Map.js").default} map Map.
24279 * @param {import("../Map.js").FrameState} frameState Frame state.
24280 */
24281function expireIconCache(map, frameState) {
24282  shared.expire();
24283}
24284
24285/* harmony default export */ const Map = (MapRenderer);
24286
24287;// CONCATENATED MODULE: ./node_modules/ol/render/Event.js
24288/**
24289 * @module ol/render/Event
24290 */
24291
24292
24293
24294class RenderEvent extends Event {
24295  /**
24296   * @param {import("./EventType.js").default} type Type.
24297   * @param {import("../transform.js").Transform} [inversePixelTransform] Transform for
24298   *     CSS pixels to rendered pixels.
24299   * @param {import("../Map.js").FrameState} [frameState] Frame state.
24300   * @param {?(CanvasRenderingContext2D|WebGLRenderingContext)} [context] Context.
24301   */
24302  constructor(type, inversePixelTransform, frameState, context) {
24303    super(type);
24304
24305    /**
24306     * Transform from CSS pixels (relative to the top-left corner of the map viewport)
24307     * to rendered pixels on this event's `context`. Only available when a Canvas renderer is used, null otherwise.
24308     * @type {import("../transform.js").Transform|undefined}
24309     * @api
24310     */
24311    this.inversePixelTransform = inversePixelTransform;
24312
24313    /**
24314     * An object representing the current render frame state.
24315     * @type {import("../Map.js").FrameState|undefined}
24316     * @api
24317     */
24318    this.frameState = frameState;
24319
24320    /**
24321     * Canvas context. Not available when the event is dispatched by the map. For Canvas 2D layers,
24322     * the context will be the 2D rendering context.  For WebGL layers, the context will be the WebGL
24323     * context.
24324     * @type {CanvasRenderingContext2D|WebGLRenderingContext|undefined}
24325     * @api
24326     */
24327    this.context = context;
24328  }
24329}
24330
24331/* harmony default export */ const render_Event = (RenderEvent);
24332
24333;// CONCATENATED MODULE: ./node_modules/ol/css.js
24334/**
24335 * @module ol/css
24336 */
24337
24338/**
24339 * @typedef {Object} FontParameters
24340 * @property {string} style Style.
24341 * @property {string} variant Variant.
24342 * @property {string} weight Weight.
24343 * @property {string} size Size.
24344 * @property {string} lineHeight LineHeight.
24345 * @property {string} family Family.
24346 * @property {Array<string>} families Families.
24347 */
24348
24349/**
24350 * The CSS class for hidden feature.
24351 *
24352 * @const
24353 * @type {string}
24354 */
24355const CLASS_HIDDEN = 'ol-hidden';
24356
24357/**
24358 * The CSS class that we'll give the DOM elements to have them selectable.
24359 *
24360 * @const
24361 * @type {string}
24362 */
24363const CLASS_SELECTABLE = 'ol-selectable';
24364
24365/**
24366 * The CSS class that we'll give the DOM elements to have them unselectable.
24367 *
24368 * @const
24369 * @type {string}
24370 */
24371const CLASS_UNSELECTABLE = 'ol-unselectable';
24372
24373/**
24374 * The CSS class for unsupported feature.
24375 *
24376 * @const
24377 * @type {string}
24378 */
24379const CLASS_UNSUPPORTED = 'ol-unsupported';
24380
24381/**
24382 * The CSS class for controls.
24383 *
24384 * @const
24385 * @type {string}
24386 */
24387const CLASS_CONTROL = 'ol-control';
24388
24389/**
24390 * The CSS class that we'll give the DOM elements that are collapsed, i.e.
24391 * to those elements which usually can be expanded.
24392 *
24393 * @const
24394 * @type {string}
24395 */
24396const CLASS_COLLAPSED = 'ol-collapsed';
24397
24398/**
24399 * From https://stackoverflow.com/questions/10135697/regex-to-parse-any-css-font
24400 * @type {RegExp}
24401 */
24402const fontRegEx = new RegExp(
24403  [
24404    '^\\s*(?=(?:(?:[-a-z]+\\s*){0,2}(italic|oblique))?)',
24405    '(?=(?:(?:[-a-z]+\\s*){0,2}(small-caps))?)',
24406    '(?=(?:(?:[-a-z]+\\s*){0,2}(bold(?:er)?|lighter|[1-9]00 ))?)',
24407    '(?:(?:normal|\\1|\\2|\\3)\\s*){0,3}((?:xx?-)?',
24408    '(?:small|large)|medium|smaller|larger|[\\.\\d]+(?:\\%|in|[cem]m|ex|p[ctx]))',
24409    '(?:\\s*\\/\\s*(normal|[\\.\\d]+(?:\\%|in|[cem]m|ex|p[ctx])?))',
24410    '?\\s*([-,\\"\\\'\\sa-z]+?)\\s*$',
24411  ].join(''),
24412  'i'
24413);
24414const fontRegExMatchIndex = [
24415  'style',
24416  'variant',
24417  'weight',
24418  'size',
24419  'lineHeight',
24420  'family',
24421];
24422
24423/**
24424 * Get the list of font families from a font spec.  Note that this doesn't work
24425 * for font families that have commas in them.
24426 * @param {string} fontSpec The CSS font property.
24427 * @return {FontParameters|null}
24427 The font parameters (or null if the input spec is invalid).
24428 */
24429const getFontParameters = function (fontSpec) {
24430  const match = fontSpec.match(fontRegEx);
24431  if (!match) {
24432    return null;
24433  }
24434  const style = /** @type {FontParameters} */ ({
24435    lineHeight: 'normal',
24436    size: '1.2em',
24437    style: 'normal',
24438    weight: 'normal',
24439    variant: 'normal',
24440  });
24441  for (let i = 0, ii = fontRegExMatchIndex.length; i < ii; ++i) {
24442    const value = match[i + 1];
24443    if (value !== undefined) {
24444      style[fontRegExMatchIndex[i]] = value;
24445    }
24446  }
24447  style.families = style.family.split(/,\s?/);
24448  return style;
24449};
24450
24451;// CONCATENATED MODULE: ./node_modules/ol/dom.js
24452
24453
24454/**
24455 * @module ol/dom
24456 */
24457
24458//FIXME Move this function to the canvas module
24459/**
24460 * Create an html canvas element and returns its 2d context.
24461 * @param {number} [width] Canvas width.
24462 * @param {number} [height] Canvas height.
24463 * @param {Array<HTMLCanvasElement>} [canvasPool] Canvas pool to take existing canvas from.
24464 * @param {CanvasRenderingContext2DSettings} [settings] CanvasRenderingContext2DSettings
24465 * @return {CanvasRenderingContext2D} The context.
24466 */
24467function createCanvasContext2D(width, height, canvasPool, settings) {
24468  /** @type {HTMLCanvasElement|OffscreenCanvas} */
24469  let canvas;
24470  if (canvasPool && canvasPool.length) {
24471    canvas = canvasPool.shift();
24472  } else if (WORKER_OFFSCREEN_CANVAS) {
24473    canvas = new OffscreenCanvas(width || 300, height || 300);
24474  } else {
24475    canvas = document.createElement('canvas');
24476  }
24477  if (width) {
24478    canvas.width = width;
24479  }
24480  if (height) {
24481    canvas.height = height;
24482  }
24483  //FIXME Allow OffscreenCanvasRenderingContext2D as return type
24484  return /** @type {CanvasRenderingContext2D} */ (
24485    canvas.getContext('2d', settings)
24486  );
24487}
24488
24489/**
24490 * Releases canvas memory to avoid exceeding memory limits in Safari.
24491 * See https://pqina.nl/blog/total-canvas-memory-use-exceeds-the-maximum-limit/
24492 * @param {CanvasRenderingContext2D} context Context.
24493 */
24494function releaseCanvas(context) {
24495  const canvas = context.canvas;
24496  canvas.width = 1;
24497  canvas.height = 1;
24498  context.clearRect(0, 0, 1, 1);
24499}
24500
24501/**
24502 * Get the current computed width for the given element including margin,
24503 * padding and border.
24504 * Equivalent to jQuery's `$(el).outerWidth(true)`.
24505 * @param {!HTMLElement} element Element.
24506 * @return {number} The width.
24507 */
24508function dom_outerWidth(element) {
24509  let width = element.offsetWidth;
24510  const style = getComputedStyle(element);
24511  width += parseInt(style.marginLeft, 10) + parseInt(style.marginRight, 10);
24512
24513  return width;
24514}
24515
24516/**
24517 * Get the current computed height for the given element including margin,
24518 * padding and border.
24519 * Equivalent to jQuery's `$(el).outerHeight(true)`.
24520 * @param {!HTMLElement} element Element.
24521 * @return {number} The height.
24522 */
24523function dom_outerHeight(element) {
24524  let height = element.offsetHeight;
24525  const style = getComputedStyle(element);
24526  height += parseInt(style.marginTop, 10) + parseInt(style.marginBottom, 10);
24527
24528  return height;
24529}
24530
24531/**
24532 * @param {Node} newNode Node to replace old node
24533 * @param {Node} oldNode The node to be replaced
24534 */
24535function replaceNode(newNode, oldNode) {
24536  const parent = oldNode.parentNode;
24537  if (parent) {
24538    parent.replaceChild(newNode, oldNode);
24539  }
24540}
24541
24542/**
24543 * @param {Node} node The node to remove.
24544 * @return {Node|null} The node that was removed or null.
24545 */
24546function removeNode(node) {
24547  return node && node.parentNode ? node.parentNode.removeChild(node) : null;
24548}
24549
24550/**
24551 * @param {Node} node The node to remove the children from.
24552 */
24553function removeChildren(node) {
24554  while (node.lastChild) {
24555    node.removeChild(node.lastChild);
24556  }
24557}
24558
24559/**
24560 * Transform the children of a parent node so they match the
24561 * provided list of children.  This function aims to efficiently
24562 * remove, add, and reorder child nodes while maintaining a simple
24563 * implementation (it is not guaranteed to minimize DOM operations).
24564 * @param {Node} node The parent node whose children need reworking.
24565 * @param {Array<Node>} children The desired children.
24566 */
24567function replaceChildren(node, children) {
24568  const oldChildren = node.childNodes;
24569
24570  for (let i = 0; true; ++i) {
24571    const oldChild = oldChildren[i];
24572    const newChild = children[i];
24573
24574    // check if our work is done
24575    if (!oldChild && !newChild) {
24576      break;
24577    }
24578
24579    // check if children match
24580    if (oldChild === newChild) {
24581      continue;
24582    }
24583
24584    // check if a new child needs to be added
24585    if (!oldChild) {
24586      node.appendChild(newChild);
24587      continue;
24588    }
24589
24590    // check if an old child needs to be removed
24591    if (!newChild) {
24592      node.removeChild(oldChild);
24593      --i;
24594      continue;
24595    }
24596
24597    // reorder
24598    node.insertBefore(newChild, oldChild);
24599  }
24600}
24601
24602;// CONCATENATED MODULE: ./node_modules/ol/render/canvas.js
24603/**
24604 * @module ol/render/canvas
24605 */
24606
24607
24608
24609
24610
24611
24612/**
24613 * @typedef {'Circle' | 'Image' | 'LineString' | 'Polygon' | 'Text' | 'Default'} BuilderType
24614 */
24615
24616/**
24617 * @typedef {Object} FillState
24618 * @property {import("../colorlike.js").ColorLike} fillStyle FillStyle.
24619 */
24620
24621/**
24622 * @typedef Label
24623 * @property {number} width Width.
24624 * @property {number} height Height.
24625 * @property {Array<string|number>} contextInstructions ContextInstructions.
24626 */
24627
24628/**
24629 * @typedef {Object} FillStrokeState
24630 * @property {import("../colorlike.js").ColorLike} [currentFillStyle] Current FillStyle.
24631 * @property {import("../colorlike.js").ColorLike} [currentStrokeStyle] Current StrokeStyle.
24632 * @property {CanvasLineCap} [currentLineCap] Current LineCap.
24633 * @property {Array<number>} currentLineDash Current LineDash.
24634 * @property {number} [currentLineDashOffset] Current LineDashOffset.
24635 * @property {CanvasLineJoin} [currentLineJoin] Current LineJoin.
24636 * @property {number} [currentLineWidth] Current LineWidth.
24637 * @property {number} [currentMiterLimit] Current MiterLimit.
24638 * @property {number} [lastStroke] Last stroke.
24639 * @property {import("../colorlike.js").ColorLike} [fillStyle] FillStyle.
24640 * @property {import("../colorlike.js").ColorLike} [strokeStyle] StrokeStyle.
24641 * @property {CanvasLineCap} [lineCap] LineCap.
24642 * @property {Array<number>} lineDash LineDash.
24643 * @property {number} [lineDashOffset] LineDashOffset.
24644 * @property {CanvasLineJoin} [lineJoin] LineJoin.
24645 * @property {number} [lineWidth] LineWidth.
24646 * @property {number} [miterLimit] MiterLimit.
24647 */
24648
24649/**
24650 * @typedef {Object} StrokeState
24651 * @property {CanvasLineCap} lineCap LineCap.
24652 * @property {Array<number>} lineDash LineDash.
24653 * @property {number} lineDashOffset LineDashOffset.
24654 * @property {CanvasLineJoin} lineJoin LineJoin.
24655 * @property {number} lineWidth LineWidth.
24656 * @property {number} miterLimit MiterLimit.
24657 * @property {import("../colorlike.js").ColorLike} strokeStyle StrokeStyle.
24658 */
24659
24660/**
24661 * @typedef {Object} TextState
24662 * @property {string} font Font.
24663 * @property {CanvasTextAlign} [textAlign] TextAlign.
24664 * @property {import("../style/Text.js").TextJustify} [justify] Justify.
24665 * @property {CanvasTextBaseline} textBaseline TextBaseline.
24666 * @property {import("../style/Text.js").TextPlacement} [placement] Placement.
24667 * @property {number} [maxAngle] MaxAngle.
24668 * @property {boolean} [overflow] Overflow.
24669 * @property {import("../style/Fill.js").default} [backgroundFill] BackgroundFill.
24670 * @property {import("../style/Stroke.js").default} [backgroundStroke] BackgroundStroke.
24671 * @property {import("../size.js").Size} [scale] Scale.
24672 * @property {Array<number>} [padding] Padding.
24673 */
24674
24675/**
24676 * @typedef {Object} SerializableInstructions
24677 * @property {Array<*>} instructions The rendering instructions.
24678 * @property {Array<*>} hitDetectionInstructions The rendering hit detection instructions.
24679 * @property {Array<number>} coordinates The array of all coordinates.
24680 * @property {!Object<string, TextState>} [textStates] The text states (decluttering).
24681 * @property {!Object<string, FillState>} [fillStates] The fill states (decluttering).
24682 * @property {!Object<string, StrokeState>} [strokeStates] The stroke states (decluttering).
24683 */
24684
24685/**
24686 * @typedef {Object<number, import("./canvas/Executor.js").ReplayImageOrLabelArgs>} DeclutterImageWithText
24687 */
24688
24689/**
24690 * @const
24691 * @type {string}
24692 */
24693const defaultFont = '10px sans-serif';
24694
24695/**
24696 * @const
24697 * @type {import("../colorlike.js").ColorLike}
24698 */
24699const defaultFillStyle = '#000';
24700
24701/**
24702 * @const
24703 * @type {CanvasLineCap}
24704 */
24705const defaultLineCap = 'round';
24706
24707/**
24708 * @const
24709 * @type {Array<number>}
24710 */
24711const defaultLineDash = [];
24712
24713/**
24714 * @const
24715 * @type {number}
24716 */
24717const defaultLineDashOffset = 0;
24718
24719/**
24720 * @const
24721 * @type {CanvasLineJoin}
24722 */
24723const defaultLineJoin = 'round';
24724
24725/**
24726 * @const
24727 * @type {number}
24728 */
24729const defaultMiterLimit = 10;
24730
24731/**
24732 * @const
24733 * @type {import("../colorlike.js").ColorLike}
24734 */
24735const defaultStrokeStyle = '#000';
24736
24737/**
24738 * @const
24739 * @type {CanvasTextAlign}
24740 */
24741const defaultTextAlign = 'center';
24742
24743/**
24744 * @const
24745 * @type {CanvasTextBaseline}
24746 */
24747const defaultTextBaseline = 'middle';
24748
24749/**
24750 * @const
24751 * @type {Array<number>}
24752 */
24753const defaultPadding = [0, 0, 0, 0];
24754
24755/**
24756 * @const
24757 * @type {number}
24758 */
24759const defaultLineWidth = 1;
24760
24761/**
24762 * @type {BaseObject}
24763 */
24764const checkedFonts = new ol_Object();
24765
24766/**
24767 * @type {CanvasRenderingContext2D}
24768 */
24769let measureContext = null;
24770
24771/**
24772 * @type {string}
24773 */
24774let measureFont;
24775
24776/**
24777 * @type {!Object<string, number>}
24778 */
24779const textHeights = {};
24780
24781/**
24782 * Clears the label cache when a font becomes available.
24783 * @param {string} fontSpec CSS font spec.
24784 */
24785const registerFont = (function () {
24786  const retries = 100;
24787  const size = '32px ';
24788  const referenceFonts = ['monospace', 'serif'];
24789  const len = referenceFonts.length;
24790  const text = 'wmytzilWMYTZIL@#/&?$%10\uF013';
24791  let interval, referenceWidth;
24792
24793  /**
24794   * @param {string} fontStyle Css font-style
24795   * @param {string} fontWeight Css font-weight
24796   * @param {*} fontFamily Css font-family
24797   * @return {boolean} Font with style and weight is available
24798   */
24799  function isAvailable(fontStyle, fontWeight, fontFamily) {
24800    let available = true;
24801    for (let i = 0; i < len; ++i) {
24802      const referenceFont = referenceFonts[i];
24803      referenceWidth = measureTextWidth(
24804        fontStyle + ' ' + fontWeight + ' ' + size + referenceFont,
24805        text
24806      );
24807      if (fontFamily != referenceFont) {
24808        const width = measureTextWidth(
24809          fontStyle +
24810            ' ' +
24811            fontWeight +
24812            ' ' +
24813            size +
24814            fontFamily +
24815            ',' +
24816            referenceFont,
24817          text
24818        );
24819        // If width and referenceWidth are the same, then the fallback was used
24820        // instead of the font we wanted, so the font is not available.
24821        available = available && width != referenceWidth;
24822      }
24823    }
24824    if (available) {
24825      return true;
24826    }
24827    return false;
24828  }
24829
24830  function check() {
24831    let done = true;
24832    const fonts = checkedFonts.getKeys();
24833    for (let i = 0, ii = fonts.length; i < ii; ++i) {
24834      const font = fonts[i];
24835      if (checkedFonts.get(font) < retries) {
24836        if (isAvailable.apply(this, font.split('\n'))) {
24837          clear(textHeights);
24838          // Make sure that loaded fonts are picked up by Safari
24839          measureContext = null;
24840          measureFont = undefined;
24841          checkedFonts.set(font, retries);
24842        } else {
24843          checkedFonts.set(font, checkedFonts.get(font) + 1, true);
24844          done = false;
24845        }
24846      }
24847    }
24848    if (done) {
24849      clearInterval(interval);
24850      interval = undefined;
24851    }
24852  }
24853
24854  return function (fontSpec) {
24855    const font = getFontParameters(fontSpec);
24856    if (!font) {
24857      return;
24858    }
24859    const families = font.families;
24860    for (let i = 0, ii = families.length; i < ii; ++i) {
24861      const family = families[i];
24862      const key = font.style + '\n' + font.weight + '\n' + family;
24863      if (checkedFonts.get(key) === undefined) {
24864        checkedFonts.set(key, retries, true);
24865        if (!isAvailable(font.style, font.weight, family)) {
24866          checkedFonts.set(key, 0, true);
24867          if (interval === undefined) {
24868            interval = setInterval(check, 32);
24869          }
24870        }
24871      }
24872    }
24873  };
24874})();
24875
24876/**
24877 * @param {string} font Font to use for measuring.
24878 * @return {import("../size.js").Size} Measurement.
24879 */
24880const measureTextHeight = (function () {
24881  /**
24882   * @type {HTMLDivElement}
24883   */
24884  let measureElement;
24885  return function (fontSpec) {
24886    let height = textHeights[fontSpec];
24887    if (height == undefined) {
24888      if (WORKER_OFFSCREEN_CANVAS) {
24889        const font = getFontParameters(fontSpec);
24890        const metrics = measureText(fontSpec, 'Žg');
24891        const lineHeight = isNaN(Number(font.lineHeight))
24892          ? 1.2
24893          : Number(font.lineHeight);
24894        height =
24895          lineHeight *
24896          (metrics.actualBoundingBoxAscent + metrics.actualBoundingBoxDescent);
24897      } else {
24898        if (!measureElement) {
24899          measureElement = document.createElement('div');
24900          measureElement.innerHTML = 'M';
24901          measureElement.style.minHeight = '0';
24902          measureElement.style.maxHeight = 'none';
24903          measureElement.style.height = 'auto';
24904          measureElement.style.padding = '0';
24905          measureElement.style.border = 'none';
24906          measureElement.style.position = 'absolute';
24907          measureElement.style.display = 'block';
24908          measureElement.style.left = '-99999px';
24909        }
24910        measureElement.style.font = fontSpec;
24911        document.body.appendChild(measureElement);
24912        height = measureElement.offsetHeight;
24913        document.body.removeChild(measureElement);
24914      }
24915      textHeights[fontSpec] = height;
24916    }
24917    return height;
24918  };
24919})();
24920
24921/**
24922 * @param {string} font Font.
24923 * @param {string} text Text.
24924 * @return {TextMetrics} Text metrics.
24925 */
24926function measureText(font, text) {
24927  if (!measureContext) {
24928    measureContext = createCanvasContext2D(1, 1);
24929  }
24930  if (font != measureFont) {
24931    measureContext.font = font;
24932    measureFont = measureContext.font;
24933  }
24934  return measureContext.measureText(text);
24935}
24936
24937/**
24938 * @param {string} font Font.
24939 * @param {string} text Text.
24940 * @return {number} Width.
24941 */
24942function measureTextWidth(font, text) {
24943  return measureText(font, text).width;
24944}
24945
24946/**
24947 * Measure text width using a cache.
24948 * @param {string} font The font.
24949 * @param {string} text The text to measure.
24950 * @param {Object<string, number>}
24950 cache A lookup of cached widths by text.
24951 * @return {number} The text width.
24952 */
24953function measureAndCacheTextWidth(font, text, cache) {
24954  if (text in cache) {
24955    return cache[text];
24956  }
24957  const width = text
24958    .split('\n')
24959    .reduce((prev, curr) => Math.max(prev, measureTextWidth(font, curr)), 0);
24960  cache[text] = width;
24961  return width;
24962}
24963
24964/**
24965 * @param {TextState} baseStyle Base style.
24966 * @param {Array<string>} chunks Text chunks to measure.
24967 * @return {{width: number, height: number, widths: Array<number>, heights: Array<number>, lineWidths: Array<number>}}} Text metrics.
24968 */
24969function getTextDimensions(baseStyle, chunks) {
24970  const widths = [];
24971  const heights = [];
24972  const lineWidths = [];
24973  let width = 0;
24974  let lineWidth = 0;
24975  let height = 0;
24976  let lineHeight = 0;
24977  for (let i = 0, ii = chunks.length; i <= ii; i += 2) {
24978    const text = chunks[i];
24979    if (text === '\n' || i === ii) {
24980      width = Math.max(width, lineWidth);
24981      lineWidths.push(lineWidth);
24982      lineWidth = 0;
24983      height += lineHeight;
24984      continue;
24985    }
24986    const font = chunks[i + 1] || baseStyle.font;
24987    const currentWidth = measureTextWidth(font, text);
24988    widths.push(currentWidth);
24989    lineWidth += currentWidth;
24990    const currentHeight = measureTextHeight(font);
24991    heights.push(currentHeight);
24992    lineHeight = Math.max(lineHeight, currentHeight);
24993  }
24994  return {width, height, widths, heights, lineWidths};
24995}
24996
24997/**
24998 * @param {CanvasRenderingContext2D} context Context.
24999 * @param {number} rotation Rotation.
25000 * @param {number} offsetX X offset.
25001 * @param {number} offsetY Y offset.
25002 */
25003function rotateAtOffset(context, rotation, offsetX, offsetY) {
25004  if (rotation !== 0) {
25005    context.translate(offsetX, offsetY);
25006    context.rotate(rotation);
25007    context.translate(-offsetX, -offsetY);
25008  }
25009}
25010
25011/**
25012 * @param {CanvasRenderingContext2D} context Context.
25013 * @param {import("../transform.js").Transform|null} transform Transform.
25014 * @param {number} opacity Opacity.
25015 * @param {Label|HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} labelOrImage Label.
25016 * @param {number} originX Origin X.
25017 * @param {number} originY Origin Y.
25018 * @param {number} w Width.
25019 * @param {number} h Height.
25020 * @param {number} x X.
25021 * @param {number} y Y.
25022 * @param {import("../size.js").Size} scale Scale.
25023 */
25024function drawImageOrLabel(
25025  context,
25026  transform,
25027  opacity,
25028  labelOrImage,
25029  originX,
25030  originY,
25031  w,
25032  h,
25033  x,
25034  y,
25035  scale
25036) {
25037  context.save();
25038
25039  if (opacity !== 1) {
25040    context.globalAlpha *= opacity;
25041  }
25042  if (transform) {
25043    context.setTransform.apply(context, transform);
25044  }
25045
25046  if (/** @type {*} */ (labelOrImage).contextInstructions) {
25047    // label
25048    context.translate(x, y);
25049    context.scale(scale[0], scale[1]);
25050    executeLabelInstructions(/** @type {Label} */ (labelOrImage), context);
25051  } else if (scale[0] < 0 || scale[1] < 0) {
25052    // flipped image
25053    context.translate(x, y);
25054    context.scale(scale[0], scale[1]);
25055    context.drawImage(
25056      /** @type {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} */ (
25057        labelOrImage
25058      ),
25059      originX,
25060      originY,
25061      w,
25062      h,
25063      0,
25064      0,
25065      w,
25066      h
25067    );
25068  } else {
25069    // if image not flipped translate and scale can be avoided
25070    context.drawImage(
25071      /** @type {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} */ (
25072        labelOrImage
25073      ),
25074      originX,
25075      originY,
25076      w,
25077      h,
25078      x,
25079      y,
25080      w * scale[0],
25081      h * scale[1]
25082    );
25083  }
25084
25085  context.restore();
25086}
25087
25088/**
25089 * @param {Label} label Label.
25090 * @param {CanvasRenderingContext2D} context Context.
25091 */
25092function executeLabelInstructions(label, context) {
25093  const contextInstructions = label.contextInstructions;
25094  for (let i = 0, ii = contextInstructions.length; i < ii; i += 2) {
25095    if (Array.isArray(contextInstructions[i + 1])) {
25096      context[contextInstructions[i]].apply(
25097        context,
25098        contextInstructions[i + 1]
25099      );
25100    } else {
25101      context[contextInstructions[i]] = contextInstructions[i + 1];
25102    }
25103  }
25104}
25105
25106;// CONCATENATED MODULE: ./node_modules/ol/renderer/Composite.js
25107/**
25108 * @module ol/renderer/Composite
25109 */
25110
25111
25112
25113
25114
25115
25116
25117
25118
25119
25120/**
25121 * @classdesc
25122 * Canvas map renderer.
25123 * @api
25124 */
25125class CompositeMapRenderer extends Map {
25126  /**
25127   * @param {import("../Map.js").default} map Map.
25128   */
25129  constructor(map) {
25130    super(map);
25131
25132    /**
25133     * @type {import("../events.js").EventsKey}
25134     */
25135    this.fontChangeListenerKey_ = listen(
25136      checkedFonts,
25137      ObjectEventType.PROPERTYCHANGE,
25138      map.redrawText.bind(map)
25139    );
25140
25141    /**
25142     * @private
25143     * @type {HTMLDivElement}
25144     */
25145    this.element_ = document.createElement('div');
25146    const style = this.element_.style;
25147    style.position = 'absolute';
25148    style.width = '100%';
25149    style.height = '100%';
25150    style.zIndex = '0';
25151
25152    this.element_.className = CLASS_UNSELECTABLE + ' ol-layers';
25153
25154    const container = map.getViewport();
25155    container.insertBefore(this.element_, container.firstChild || null);
25156
25157    /**
25158     * @private
25159     * @type {Array<HTMLElement>}
25160     */
25161    this.children_ = [];
25162
25163    /**
25164     * @private
25165     * @type {boolean}
25166     */
25167    this.renderedVisible_ = true;
25168  }
25169
25170  /**
25171   * @param {import("../render/EventType.js").default} type Event type.
25172   * @param {import("../Map.js").FrameState} frameState Frame state.
25173   */
25174  dispatchRenderEvent(type, frameState) {
25175    const map = this.getMap();
25176    if (map.hasListener(type)) {
25177      const event = new render_Event(type, undefined, frameState);
25178      map.dispatchEvent(event);
25179    }
25180  }
25181
25182  disposeInternal() {
25183    unlistenByKey(this.fontChangeListenerKey_);
25184    this.element_.parentNode.removeChild(this.element_);
25185    super.disposeInternal();
25186  }
25187
25188  /**
25189   * Render.
25190   * @param {?import("../Map.js").FrameState} frameState Frame state.
25191   */
25192  renderFrame(frameState) {
25193    if (!frameState) {
25194      if (this.renderedVisible_) {
25195        this.element_.style.display = 'none';
25196        this.renderedVisible_ = false;
25197      }
25198      return;
25199    }
25200
25201    this.calculateMatrices2D(frameState);
25202    this.dispatchRenderEvent(render_EventType.PRECOMPOSE, frameState);
25203
25204    const layerStatesArray = frameState.layerStatesArray.sort(function (a, b) {
25205      return a.zIndex - b.zIndex;
25206    });
25207    const viewState = frameState.viewState;
25208
25209    this.children_.length = 0;
25210    /**
25211     * @type {Array<import("../layer/BaseVector.js").default>}
25212     */
25213    const declutterLayers = [];
25214    let previousElement = null;
25215    for (let i = 0, ii = layerStatesArray.length; i < ii; ++i) {
25216      const layerState = layerStatesArray[i];
25217      frameState.layerIndex = i;
25218
25219      const layer = layerState.layer;
25220      const sourceState = layer.getSourceState();
25221      if (
25222        !inView(layerState, viewState) ||
25223        (sourceState != 'ready' && sourceState != 'undefined')
25224      ) {
25225        layer.unrender();
25226        continue;
25227      }
25228
25229      const element = layer.render(frameState, previousElement);
25230      if (!element) {
25231        continue;
25232      }
25233      if (element !== previousElement) {
25234        this.children_.push(element);
25235        previousElement = element;
25236      }
25237      if ('getDeclutter' in layer) {
25238        declutterLayers.push(
25239          /** @type {import("../layer/BaseVector.js").default} */ (layer)
25240        );
25241      }
25242    }
25243    for (let i = declutterLayers.length - 1; i >= 0; --i) {
25244      declutterLayers[i].renderDeclutter(frameState);
25245    }
25246
25247    replaceChildren(this.element_, this.children_);
25248
25249    this.dispatchRenderEvent(render_EventType.POSTCOMPOSE, frameState);
25250
25251    if (!this.renderedVisible_) {
25252      this.element_.style.display = '';
25253      this.renderedVisible_ = true;
25254    }
25255
25256    this.scheduleExpireIconCache(frameState);
25257  }
25258}
25259
25260/* harmony default export */ const Composite = (CompositeMapRenderer);
25261
25262;// CONCATENATED MODULE: ./node_modules/ol/layer/Group.js
25263/**
25264 * @module ol/layer/Group
25265 */
25266
25267
25268
25269
25270
25271
25272
25273
25274
25275
25276
25277
25278/**
25279 * @typedef {'addlayer'|'removelayer'} EventType
25280 */
25281
25282/**
25283 * @classdesc
25284 * A layer group triggers 'addlayer' and 'removelayer' events when layers are added to or removed from
25285 * the group or one of its child groups.  When a layer group is added to or removed from another layer group,
25286 * a single event will be triggered (instead of one per layer in the group added or removed).
25287 */
25288class GroupEvent extends Event {
25289  /**
25290   * @param {EventType} type The event type.
25291   * @param {BaseLayer} layer The layer.
25292   */
25293  constructor(type, layer) {
25294    super(type);
25295
25296    /**
25297     * The added or removed layer.
25298     * @type {BaseLayer}
25299     * @api
25300     */
25301    this.layer = layer;
25302  }
25303}
25304
25305/***
25306 * @template Return
25307 * @typedef {import("../Observable").OnSignature<import("../Observable").EventTypes, import("../events/Event.js").default, Return> &
25308 *   import("../Observable").OnSignature<import("./Base").BaseLayerObjectEventTypes|
25309 *     'change:layers', import("../Object").ObjectEvent, Return> &
25310 *   import("../Observable").CombinedOnSignature<import("../Observable").EventTypes|import("./Base").BaseLayerObjectEventTypes|'change:layers', Return>} GroupOnSignature
25311 */
25312
25313/**
25314 * @typedef {Object} Options
25315 * @property {number} [opacity=1] Opacity (0, 1).
25316 * @property {boolean} [visible=true] Visibility.
25317 * @property {import("../extent.js").Extent} [extent] The bounding extent for layer rendering.  The layer will not be
25318 * rendered outside of this extent.
25319 * @property {number} [zIndex] The z-index for layer rendering.  At rendering time, the layers
25320 * will be ordered, first by Z-index and then by position. When `undefined`, a `zIndex` of 0 is assumed
25321 * for layers that are added to the map's `layers` collection, or `Infinity` when the layer's `setMap()`
25322 * method was used.
25323 * @property {number} [minResolution] The minimum resolution (inclusive) at which this layer will be
25324 * visible.
25325 * @property {number} [maxResolution] The maximum resolution (exclusive) below which this layer will
25326 * be visible.
25327 * @property {number} [minZoom] The minimum view zoom level (exclusive) above which this layer will be
25328 * visible.
25329 * @property {number} [maxZoom] The maximum view zoom level (inclusive) at which this layer will
25330 * be visible.
25331 * @property {Array<import("./Base.js").default>|Collection<import("./Base.js").default>} [layers] Child layers.
25332 * @property {Object<string, *>} [properties] Arbitrary observable properties. Can be accessed with `#get()` and `#set()`.
25333 */
25334
25335/**
25336 * @enum {string}
25337 * @private
25338 */
25339const Group_Property = {
25340  LAYERS: 'layers',
25341};
25342
25343/**
25344 * @classdesc
25345 * A {@link module:ol/Collection~Collection} of layers that are handled together.
25346 *
25347 * A generic `change` event is triggered when the group/Collection changes.
25348 *
25349 * @api
25350 */
25351class LayerGroup extends Base {
25352  /**
25353   * @param {Options} [options] Layer options.
25354   */
25355  constructor(options) {
25356    options = options || {};
25357    const baseOptions = /** @type {Options} */ (Object.assign({}, options));
25358    delete baseOptions.layers;
25359
25360    let layers = options.layers;
25361
25362    super(baseOptions);
25363
25364    /***
25365     * @type {GroupOnSignature<import("../events").EventsKey>}
25366     */
25367    this.on;
25368
25369    /***
25370     * @type {GroupOnSignature<import("../events").EventsKey>}
25371     */
25372    this.once;
25373
25374    /***
25375     * @type {GroupOnSignature<void>}
25376     */
25377    this.un;
25378
25379    /**
25380     * @private
25381     * @type {Array<import("../events.js").EventsKey>}
25382     */
25383    this.layersListenerKeys_ = [];
25384
25385    /**
25386     * @private
25387     * @type {Object<string, Array<import("../events.js").EventsKey>>}
25388     */
25389    this.listenerKeys_ = {};
25390
25391    this.addChangeListener(Group_Property.LAYERS, this.handleLayersChanged_);
25392
25393    if (layers) {
25394      if (Array.isArray(layers)) {
25395        layers = new ol_Collection(layers.slice(), {unique: true});
25396      } else {
25397        asserts_assert(typeof (/** @type {?} */ (layers).getArray) === 'function', 43); // Expected `layers` to be an array or a `Collection`
25398      }
25399    } else {
25400      layers = new ol_Collection(undefined, {unique: true});
25401    }
25402
25403    this.setLayers(layers);
25404  }
25405
25406  /**
25407   * @private
25408   */
25409  handleLayerChange_() {
25410    this.changed();
25411  }
25412
25413  /**
25414   * @private
25415   */
25416  handleLayersChanged_() {
25417    this.layersListenerKeys_.forEach(unlistenByKey);
25418    this.layersListenerKeys_.length = 0;
25419
25420    const layers = this.getLayers();
25421    this.layersListenerKeys_.push(
25422      listen(layers, CollectionEventType.ADD, this.handleLayersAdd_, this),
25423      listen(layers, CollectionEventType.REMOVE, this.handleLayersRemove_, this)
25424    );
25425
25426    for (const id in this.listenerKeys_) {
25427      this.listenerKeys_[id].forEach(unlistenByKey);
25428    }
25429    clear(this.listenerKeys_);
25430
25431    const layersArray = layers.getArray();
25432    for (let i = 0, ii = layersArray.length; i < ii; i++) {
25433      const layer = layersArray[i];
25434      this.registerLayerListeners_(layer);
25435      this.dispatchEvent(new GroupEvent('addlayer', layer));
25436    }
25437    this.changed();
25438  }
25439
25440  /**
25441   * @param {BaseLayer} layer The layer.
25442   */
25443  registerLayerListeners_(layer) {
25444    const listenerKeys = [
25445      listen(
25446        layer,
25447        ObjectEventType.PROPERTYCHANGE,
25448        this.handleLayerChange_,
25449        this
25450      ),
25451      listen(layer, EventType.CHANGE, this.handleLayerChange_, this),
25452    ];
25453
25454    if (layer instanceof LayerGroup) {
25455      listenerKeys.push(
25456        listen(layer, 'addlayer', this.handleLayerGroupAdd_, this),
25457        listen(layer, 'removelayer', this.handleLayerGroupRemove_, this)
25458      );
25459    }
25460
25461    this.listenerKeys_[getUid(layer)] = listenerKeys;
25462  }
25463
25464  /**
25465   * @param {GroupEvent} event The layer group event.
25466   */
25467  handleLayerGroupAdd_(event) {
25468    this.dispatchEvent(new GroupEvent('addlayer', event.layer));
25469  }
25470
25471  /**
25472   * @param {GroupEvent} event The layer group event.
25473   */
25474  handleLayerGroupRemove_(event) {
25475    this.dispatchEvent(new GroupEvent('removelayer', event.layer));
25476  }
25477
25478  /**
25479   * @param {import("../Collection.js").CollectionEvent<import("./Base.js").default>} collectionEvent CollectionEvent.
25480   * @private
25481   */
25482  handleLayersAdd_(collectionEvent) {
25483    const layer = collectionEvent.element;
25484    this.registerLayerListeners_(layer);
25485    this.dispatchEvent(new GroupEvent('addlayer', layer));
25486    this.changed();
25487  }
25488
25489  /**
25490   * @param {import("../Collection.js").CollectionEvent<import("./Base.js").default>} collectionEvent CollectionEvent.
25491   * @private
25492   */
25493  handleLayersRemove_(collectionEvent) {
25494    const layer = collectionEvent.element;
25495    const key = getUid(layer);
25496    this.listenerKeys_[key].forEach(unlistenByKey);
25497    delete this.listenerKeys_[key];
25498    this.dispatchEvent(new GroupEvent('removelayer', layer));
25499    this.changed();
25500  }
25501
25502  /**
25503   * Returns the {@link module:ol/Collection~Collection collection} of {@link module:ol/layer/Layer~Layer layers}
25504   * in this group.
25505   * @return {!Collection<import("./Base.js").default>} Collection of
25506   *   {@link module:ol/layer/Base~BaseLayer layers} that are part of this group.
25507   * @observable
25508   * @api
25509   */
25510  getLayers() {
25511    return /** @type {!Collection<import("./Base.js").default>} */ (
25512      this.get(Group_Property.LAYERS)
25513    );
25514  }
25515
25516  /**
25517   * Set the {@link module:ol/Collection~Collection collection} of {@link module:ol/layer/Layer~Layer layers}
25518   * in this group.
25519   * @param {!Collection<import("./Base.js").default>} layers Collection of
25520   *   {@link module:ol/layer/Base~BaseLayer layers} that are part of this group.
25521   * @observable
25522   * @api
25523   */
25524  setLayers(layers) {
25525    const collection = this.getLayers();
25526    if (collection) {
25527      const currentLayers = collection.getArray();
25528      for (let i = 0, ii = currentLayers.length; i < ii; ++i) {
25529        this.dispatchEvent(new GroupEvent('removelayer', currentLayers[i]));
25530      }
25531    }
25532
25533    this.set(Group_Property.LAYERS, layers);
25534  }
25535
25536  /**
25537   * @param {Array<import("./Layer.js").default>} [array] Array of layers (to be modified in place).
25538   * @return {Array<import("./Layer.js").default>} Array of layers.
25539   */
25540  getLayersArray(array) {
25541    array = array !== undefined ? array : [];
25542    this.getLayers().forEach(function (layer) {
25543      layer.getLayersArray(array);
25544    });
25545    return array;
25546  }
25547
25548  /**
25549   * Get the layer states list and use this groups z-index as the default
25550   * for all layers in this and nested groups, if it is unset at this point.
25551   * If dest is not provided and this group's z-index is undefined
25552   * 0 is used a the default z-index.
25553   * @param {Array<import("./Layer.js").State>} [dest] Optional list
25554   * of layer states (to be modified in place).
25555   * @return {Array<import("./Layer.js").State>} List of layer states.
25556   */
25557  getLayerStatesArray(dest) {
25558    const states = dest !== undefined ? dest : [];
25559    const pos = states.length;
25560
25561    this.getLayers().forEach(function (layer) {
25562      layer.getLayerStatesArray(states);
25563    });
25564
25565    const ownLayerState = this.getLayerState();
25566    let defaultZIndex = ownLayerState.zIndex;
25567    if (!dest && ownLayerState.zIndex === undefined) {
25568      defaultZIndex = 0;
25569    }
25570    for (let i = pos, ii = states.length; i < ii; i++) {
25571      const layerState = states[i];
25572      layerState.opacity *= ownLayerState.opacity;
25573      layerState.visible = layerState.visible && ownLayerState.visible;
25574      layerState.maxResolution = Math.min(
25575        layerState.maxResolution,
25576        ownLayerState.maxResolution
25577      );
25578      layerState.minResolution = Math.max(
25579        layerState.minResolution,
25580        ownLayerState.minResolution
25581      );
25582      layerState.minZoom = Math.max(layerState.minZoom, ownLayerState.minZoom);
25583      layerState.maxZoom = Math.min(layerState.maxZoom, ownLayerState.maxZoom);
25584      if (ownLayerState.extent !== undefined) {
25585        if (layerState.extent !== undefined) {
25586          layerState.extent = getIntersection(
25587            layerState.extent,
25588            ownLayerState.extent
25589          );
25590        } else {
25591          layerState.extent = ownLayerState.extent;
25592        }
25593      }
25594      if (layerState.zIndex === undefined) {
25595        layerState.zIndex = defaultZIndex;
25596      }
25597    }
25598
25599    return states;
25600  }
25601
25602  /**
25603   * @return {import("../source/Source.js").State} Source state.
25604   */
25605  getSourceState() {
25606    return 'ready';
25607  }
25608}
25609
25610/* harmony default export */ const Group = (LayerGroup);
25611
25612;// CONCATENATED MODULE: ./node_modules/ol/MapEvent.js
25613/**
25614 * @module ol/MapEvent
25615 */
25616
25617
25618/**
25619 * @classdesc
25620 * Events emitted as map events are instances of this type.
25621 * See {@link module:ol/Map~Map} for which events trigger a map event.
25622 */
25623class MapEvent extends Event {
25624  /**
25625   * @param {string} type Event type.
25626   * @param {import("./Map.js").default} map Map.
25627   * @param {?import("./Map.js").FrameState} [frameState] Frame state.
25628   */
25629  constructor(type, map, frameState) {
25630    super(type);
25631
25632    /**
25633     * The map where the event occurred.
25634     * @type {import("./Map.js").default}
25635     * @api
25636     */
25637    this.map = map;
25638
25639    /**
25640     * The frame state at the time of the event.
25641     * @type {?import("./Map.js").FrameState}
25642     * @api
25643     */
25644    this.frameState = frameState !== undefined ? frameState : null;
25645  }
25646}
25647
25648/* harmony default export */ const ol_MapEvent = (MapEvent);
25649
25650;// CONCATENATED MODULE: ./node_modules/ol/MapBrowserEvent.js
25651/**
25652 * @module ol/MapBrowserEvent
25653 */
25654
25655
25656/**
25657 * @classdesc
25658 * Events emitted as map browser events are instances of this type.
25659 * See {@link module:ol/Map~Map} for which events trigger a map browser event.
25660 * @template {UIEvent} EVENT
25661 */
25662class MapBrowserEvent extends ol_MapEvent {
25663  /**
25664   * @param {string} type Event type.
25665   * @param {import("./Map.js").default} map Map.
25666   * @param {EVENT} originalEvent Original event.
25667   * @param {boolean} [dragging] Is the map currently being dragged?
25668   * @param {import("./Map.js").FrameState} [frameState] Frame state.
25669   * @param {Array<PointerEvent>} [activePointers] Active pointers.
25670   */
25671  constructor(type, map, originalEvent, dragging, frameState, activePointers) {
25672    super(type, map, frameState);
25673
25674    /**
25675     * The original browser event.
25676     * @const
25677     * @type {EVENT}
25678     * @api
25679     */
25680    this.originalEvent = originalEvent;
25681
25682    /**
25683     * The map pixel relative to the viewport corresponding to the original browser event.
25684     * @type {?import("./pixel.js").Pixel}
25685     */
25686    this.pixel_ = null;
25687
25688    /**
25689     * The coordinate in the user projection corresponding to the original browser event.
25690     * @type {?import("./coordinate.js").Coordinate}
25691     */
25692    this.coordinate_ = null;
25693
25694    /**
25695     * Indicates if the map is currently being dragged. Only set for
25696     * `POINTERDRAG` and `POINTERMOVE` events. Default is `false`.
25697     *
25698     * @type {boolean}
25699     * @api
25700     */
25701    this.dragging = dragging !== undefined ? dragging : false;
25702
25703    /**
25704     * @type {Array<PointerEvent>|undefined}
25705     */
25706    this.activePointers = activePointers;
25707  }
25708
25709  /**
25710   * The map pixel relative to the viewport corresponding to the original event.
25711   * @type {import("./pixel.js").Pixel}
25712   * @api
25713   */
25714  get pixel() {
25715    if (!this.pixel_) {
25716      this.pixel_ = this.map.getEventPixel(this.originalEvent);
25717    }
25718    return this.pixel_;
25719  }
25720  set pixel(pixel) {
25721    this.pixel_ = pixel;
25722  }
25723
25724  /**
25725   * The coordinate corresponding to the original browser event.  This will be in the user
25726   * projection if one is set.  Otherwise it will be in the view projection.
25727   * @type {import("./coordinate.js").Coordinate}
25728   * @api
25729   */
25730  get coordinate() {
25731    if (!this.coordinate_) {
25732      this.coordinate_ = this.map.getCoordinateFromPixel(this.pixel);
25733    }
25734    return this.coordinate_;
25735  }
25736  set coordinate(coordinate) {
25737    this.coordinate_ = coordinate;
25738  }
25739
25740  /**
25741   * Prevents the default browser action.
25742   * See https://developer.mozilla.org/en-US/docs/Web/API/event.preventDefault.
25743   * @api
25744   */
25745  preventDefault() {
25746    super.preventDefault();
25747    if ('preventDefault' in this.originalEvent) {
25748      /** @type {UIEvent} */ (this.originalEvent).preventDefault();
25749    }
25750  }
25751
25752  /**
25753   * Prevents further propagation of the current event.
25754   * See https://developer.mozilla.org/en-US/docs/Web/API/event.stopPropagation.
25755   * @api
25756   */
25757  stopPropagation() {
25758    super.stopPropagation();
25759    if ('stopPropagation' in this.originalEvent) {
25760      /** @type {UIEvent} */ (this.originalEvent).stopPropagation();
25761    }
25762  }
25763}
25764
25765/* harmony default export */ const ol_MapBrowserEvent = (MapBrowserEvent);
25766
25767;// CONCATENATED MODULE: ./node_modules/ol/MapBrowserEventType.js
25768/**
25769 * @module ol/MapBrowserEventType
25770 */
25771
25772
25773/**
25774 * Constants for event names.
25775 * @enum {string}
25776 */
25777/* harmony default export */ const ol_MapBrowserEventType = ({
25778  /**
25779   * A true single click with no dragging and no double click. Note that this
25780   * event is delayed by 250 ms to ensure that it is not a double click.
25781   * @event module:ol/MapBrowserEvent~MapBrowserEvent#singleclick
25782   * @api
25783   */
25784  SINGLECLICK: 'singleclick',
25785
25786  /**
25787   * A click with no dragging. A double click will fire two of this.
25788   * @event module:ol/MapBrowserEvent~MapBrowserEvent#click
25789   * @api
25790   */
25791  CLICK: EventType.CLICK,
25792
25793  /**
25794   * A true double click, with no dragging.
25795   * @event module:ol/MapBrowserEvent~MapBrowserEvent#dblclick
25796   * @api
25797   */
25798  DBLCLICK: EventType.DBLCLICK,
25799
25800  /**
25801   * Triggered when a pointer is dragged.
25802   * @event module:ol/MapBrowserEvent~MapBrowserEvent#pointerdrag
25803   * @api
25804   */
25805  POINTERDRAG: 'pointerdrag',
25806
25807  /**
25808   * Triggered when a pointer is moved. Note that on touch devices this is
25809   * triggered when the map is panned, so is not the same as mousemove.
25810   * @event module:ol/MapBrowserEvent~MapBrowserEvent#pointermove
25811   * @api
25812   */
25813  POINTERMOVE: 'pointermove',
25814
25815  POINTERDOWN: 'pointerdown',
25816  POINTERUP: 'pointerup',
25817  POINTEROVER: 'pointerover',
25818  POINTEROUT: 'pointerout',
25819  POINTERENTER: 'pointerenter',
25820  POINTERLEAVE: 'pointerleave',
25821  POINTERCANCEL: 'pointercancel',
25822});
25823
25824/***
25825 * @typedef {'singleclick'|'click'|'dblclick'|'pointerdrag'|'pointermove'} Types
25826 */
25827
25828;// CONCATENATED MODULE: ./node_modules/ol/pointer/EventType.js
25829/**
25830 * @module ol/pointer/EventType
25831 */
25832
25833/**
25834 * Constants for event names.
25835 * @enum {string}
25836 */
25837/* harmony default export */ const pointer_EventType = ({
25838  POINTERMOVE: 'pointermove',
25839  POINTERDOWN: 'pointerdown',
25840  POINTERUP: 'pointerup',
25841  POINTEROVER: 'pointerover',
25842  POINTEROUT: 'pointerout',
25843  POINTERENTER: 'pointerenter',
25844  POINTERLEAVE: 'pointerleave',
25845  POINTERCANCEL: 'pointercancel',
25846});
25847
25848;// CONCATENATED MODULE: ./node_modules/ol/MapBrowserEventHandler.js
25849/**
25850 * @module ol/MapBrowserEventHandler
25851 */
25852
25853
25854
25855
25856
25857
25858
25859
25860
25861
25862class MapBrowserEventHandler extends events_Target {
25863  /**
25864   * @param {import("./Map.js").default} map The map with the viewport to listen to events on.
25865   * @param {number} [moveTolerance] The minimal distance the pointer must travel to trigger a move.
25866   */
25867  constructor(map, moveTolerance) {
25868    super(map);
25869
25870    /**
25871     * This is the element that we will listen to the real events on.
25872     * @type {import("./Map.js").default}
25873     * @private
25874     */
25875    this.map_ = map;
25876
25877    /**
25878     * @type {any}
25879     * @private
25880     */
25881    this.clickTimeoutId_;
25882
25883    /**
25884     * Emulate dblclick and singleclick. Will be true when only one pointer is active.
25885     * @type {boolean}
25886     */
25887    this.emulateClicks_ = false;
25888
25889    /**
25890     * @type {boolean}
25891     * @private
25892     */
25893    this.dragging_ = false;
25894
25895    /**
25896     * @type {!Array<import("./events.js").EventsKey>}
25897     * @private
25898     */
25899    this.dragListenerKeys_ = [];
25900
25901    /**
25902     * @type {number}
25903     * @private
25904     */
25905    this.moveTolerance_ = moveTolerance === undefined ? 1 : moveTolerance;
25906
25907    /**
25908     * The most recent "down" type event (or null if none have occurred).
25909     * Set on pointerdown.
25910     * @type {PointerEvent|null}
25911     * @private
25912     */
25913    this.down_ = null;
25914
25915    const element = this.map_.getViewport();
25916
25917    /**
25918     * @type {Array<PointerEvent>}
25919     * @private
25920     */
25921    this.activePointers_ = [];
25922
25923    /**
25924     * @type {!Object<number, Event>}
25925     * @private
25926     */
25927    this.trackedTouches_ = {};
25928
25929    this.element_ = element;
25930
25931    /**
25932     * @type {?import("./events.js").EventsKey}
25933     * @private
25934     */
25935    this.pointerdownListenerKey_ = listen(
25936      element,
25937      pointer_EventType.POINTERDOWN,
25938      this.handlePointerDown_,
25939      this
25940    );
25941
25942    /**
25943     * @type {PointerEvent}
25944     * @private
25945     */
25946    this.originalPointerMoveEvent_;
25947
25948    /**
25949     * @type {?import("./events.js").EventsKey}
25950     * @private
25951     */
25952    this.relayedListenerKey_ = listen(
25953      element,
25954      pointer_EventType.POINTERMOVE,
25955      this.relayMoveEvent_,
25956      this
25957    );
25958
25959    /**
25960     * @private
25961     */
25962    this.boundHandleTouchMove_ = this.handleTouchMove_.bind(this);
25963
25964    this.element_.addEventListener(
25965      EventType.TOUCHMOVE,
25966      this.boundHandleTouchMove_,
25967      PASSIVE_EVENT_LISTENERS ? {passive: false} : false
25968    );
25969  }
25970
25971  /**
25972   * @param {PointerEvent} pointerEvent Pointer
25973   * event.
25974   * @private
25975   */
25976  emulateClick_(pointerEvent) {
25977    let newEvent = new ol_MapBrowserEvent(
25978      ol_MapBrowserEventType.CLICK,
25979      this.map_,
25980      pointerEvent
25981    );
25982    this.dispatchEvent(newEvent);
25983    if (this.clickTimeoutId_ !== undefined) {
25984      // double-click
25985      clearTimeout(this.clickTimeoutId_);
25986      this.clickTimeoutId_ = undefined;
25987      newEvent = new ol_MapBrowserEvent(
25988        ol_MapBrowserEventType.DBLCLICK,
25989        this.map_,
25990        pointerEvent
25991      );
25992      this.dispatchEvent(newEvent);
25993    } else {
25994      // click
25995      this.clickTimeoutId_ = setTimeout(
25996        /** @this {MapBrowserEventHandler} */
25997        function () {
25998          this.clickTimeoutId_ = undefined;
25999          const newEvent = new ol_MapBrowserEvent(
26000            ol_MapBrowserEventType.SINGLECLICK,
26001            this.map_,
26002            pointerEvent
26003          );
26004          this.dispatchEvent(newEvent);
26005        }.bind(this),
26006        250
26007      );
26008    }
26009  }
26010
26011  /**
26012   * Keeps track on how many pointers are currently active.
26013   *
26014   * @param {PointerEvent} pointerEvent Pointer
26015   * event.
26016   * @private
26017   */
26018  updateActivePointers_(pointerEvent) {
26019    const event = pointerEvent;
26020    const id = event.pointerId;
26021
26022    if (
26023      event.type == ol_MapBrowserEventType.POINTERUP ||
26024      event.type == ol_MapBrowserEventType.POINTERCANCEL
26025    ) {
26026      delete this.trackedTouches_[id];
26027      for (const pointerId in this.trackedTouches_) {
26028        if (this.trackedTouches_[pointerId].target !== event.target) {
26029          // Some platforms assign a new pointerId when the target changes.
26030          // If this happens, delete one tracked pointer. If there is more
26031          // than one tracked pointer for the old target, it will be cleared
26032          // by subsequent POINTERUP events from other pointers.
26033          delete this.trackedTouches_[pointerId];
26034          break;
26035        }
26036      }
26037    } else if (
26038      event.type == ol_MapBrowserEventType.POINTERDOWN ||
26039      event.type == ol_MapBrowserEventType.POINTERMOVE
26040    ) {
26041      this.trackedTouches_[id] = event;
26042    }
26043    this.activePointers_ = Object.values(this.trackedTouches_);
26044  }
26045
26046  /**
26047   * @param {PointerEvent} pointerEvent Pointer
26048   * event.
26049   * @private
26050   */
26051  handlePointerUp_(pointerEvent) {
26052    this.updateActivePointers_(pointerEvent);
26053    const newEvent = new ol_MapBrowserEvent(
26054      ol_MapBrowserEventType.POINTERUP,
26055      this.map_,
26056      pointerEvent,
26057      undefined,
26058      undefined,
26059      this.activePointers_
26060    );
26061    this.dispatchEvent(newEvent);
26062
26063    // We emulate click events on left mouse button click, touch contact, and pen
26064    // contact. isMouseActionButton returns true in these cases (evt.button is set
26065    // to 0).
26066    // See http://www.w3.org/TR/pointerevents/#button-states
26067    // We only fire click, singleclick, and doubleclick if nobody has called
26068    // event.preventDefault().
26069    if (
26070      this.emulateClicks_ &&
26071      !newEvent.defaultPrevented &&
26072      !this.dragging_ &&
26073      this.isMouseActionButton_(pointerEvent)
26074    ) {
26075      this.emulateClick_(this.down_);
26076    }
26077
26078    if (this.activePointers_.length === 0) {
26079      this.dragListenerKeys_.forEach(unlistenByKey);
26080      this.dragListenerKeys_.length = 0;
26081      this.dragging_ = false;
26082      this.down_ = null;
26083    }
26084  }
26085
26086  /**
26087   * @param {PointerEvent} pointerEvent Pointer
26088   * event.
26089   * @return {boolean} If the left mouse button was pressed.
26090   * @private
26091   */
26092  isMouseActionButton_(pointerEvent) {
26093    return pointerEvent.button === 0;
26094  }
26095
26096  /**
26097   * @param {PointerEvent} pointerEvent Pointer
26098   * event.
26099   * @private
26100   */
26101  handlePointerDown_(pointerEvent) {
26102    this.emulateClicks_ = this.activePointers_.length === 0;
26103    this.updateActivePointers_(pointerEvent);
26104    const newEvent = new ol_MapBrowserEvent(
26105      ol_MapBrowserEventType.POINTERDOWN,
26106      this.map_,
26107      pointerEvent,
26108      undefined,
26109      undefined,
26110      this.activePointers_
26111    );
26112    this.dispatchEvent(newEvent);
26113
26114    // Store a copy of the down event
26115    this.down_ = /** @type {PointerEvent} */ ({});
26116    for (const property in pointerEvent) {
26117      const value = pointerEvent[property];
26118      this.down_[property] = typeof value === 'function' ? VOID : value;
26119    }
26120
26121    if (this.dragListenerKeys_.length === 0) {
26122      const doc = this.map_.getOwnerDocument();
26123      this.dragListenerKeys_.push(
26124        listen(
26125          doc,
26126          ol_MapBrowserEventType.POINTERMOVE,
26127          this.handlePointerMove_,
26128          this
26129        ),
26130        listen(doc, ol_MapBrowserEventType.POINTERUP, this.handlePointerUp_, this),
26131        /* Note that the listener for `pointercancel is set up on
26132         * `pointerEventHandler_` and not `documentPointerEventHandler_` like
26133         * the `pointerup` and `pointermove` listeners.
26134         *
26135         * The reason for this is the following: `TouchSource.vacuumTouches_()`
26136         * issues `pointercancel` events, when there was no `touchend` for a
26137         * `touchstart`. Now, let's say a first `touchstart` is registered on
26138         * `pointerEventHandler_`. The `documentPointerEventHandler_` is set up.
26139         * But `documentPointerEventHandler_` doesn't know about the first
26140         * `touchstart`. If there is no `touchend` for the `touchstart`, we can
26141         * only receive a `touchcancel` from `pointerEventHandler_`, because it is
26142         * only registered there.
26143         */
26144        listen(
26145          this.element_,
26146          ol_MapBrowserEventType.POINTERCANCEL,
26147          this.handlePointerUp_,
26148          this
26149        )
26150      );
26151      if (this.element_.getRootNode && this.element_.getRootNode() !== doc) {
26152        this.dragListenerKeys_.push(
26153          listen(
26154            this.element_.getRootNode(),
26155            ol_MapBrowserEventType.POINTERUP,
26156            this.handlePointerUp_,
26157            this
26158          )
26159        );
26160      }
26161    }
26162  }
26163
26164  /**
26165   * @param {PointerEvent} pointerEvent Pointer
26166   * event.
26167   * @private
26168   */
26169  handlePointerMove_(pointerEvent) {
26170    // Between pointerdown and pointerup, pointermove events are triggered.
26171    // To avoid a 'false' touchmove event to be dispatched, we test if the pointer
26172    // moved a significant distance.
26173    if (this.isMoving_(pointerEvent)) {
26174      this.updateActivePointers_(pointerEvent);
26175      this.dragging_ = true;
26176      const newEvent = new ol_MapBrowserEvent(
26177        ol_MapBrowserEventType.POINTERDRAG,
26178        this.map_,
26179        pointerEvent,
26180        this.dragging_,
26181        undefined,
26182        this.activePointers_
26183      );
26184      this.dispatchEvent(newEvent);
26185    }
26186  }
26187
26188  /**
26189   * Wrap and relay a pointermove event.
26190   * @param {PointerEvent} pointerEvent Pointer
26191   * event.
26192   * @private
26193   */
26194  relayMoveEvent_(pointerEvent) {
26195    this.originalPointerMoveEvent_ = pointerEvent;
26196    const dragging = !!(this.down_ && this.isMoving_(pointerEvent));
26197    this.dispatchEvent(
26198      new ol_MapBrowserEvent(
26199        ol_MapBrowserEventType.POINTERMOVE,
26200        this.map_,
26201        pointerEvent,
26202        dragging
26203      )
26204    );
26205  }
26206
26207  /**
26208   * Flexible handling of a `touch-action: none` css equivalent: because calling
26209   * `preventDefault()` on a `pointermove` event does not stop native page scrolling
26210   * and zooming, we also listen for `touchmove` and call `preventDefault()` on it
26211   * when an interaction (currently `DragPan` handles the event.
26212   * @param {TouchEvent} event Event.
26213   * @private
26214   */
26215  handleTouchMove_(event) {
26216    // Due to https://github.com/mpizenberg/elm-pep/issues/2, `this.originalPointerMoveEvent_`
26217    // may not be initialized yet when we get here on a platform without native pointer events.
26218    const originalEvent = this.originalPointerMoveEvent_;
26219    if (
26220      (!originalEvent || originalEvent.defaultPrevented) &&
26221      (typeof event.cancelable !== 'boolean' || event.cancelable === true)
26222    ) {
26223      event.preventDefault();
26224    }
26225  }
26226
26227  /**
26228   * @param {PointerEvent} pointerEvent Pointer
26229   * event.
26230   * @return {boolean} Is moving.
26231   * @private
26232   */
26233  isMoving_(pointerEvent) {
26234    return (
26235      this.dragging_ ||
26236      Math.abs(pointerEvent.clientX - this.down_.clientX) >
26237        this.moveTolerance_ ||
26238      Math.abs(pointerEvent.clientY - this.down_.clientY) > this.moveTolerance_
26239    );
26240  }
26241
26242  /**
26243   * Clean up.
26244   */
26245  disposeInternal() {
26246    if (this.relayedListenerKey_) {
26247      unlistenByKey(this.relayedListenerKey_);
26248      this.relayedListenerKey_ = null;
26249    }
26250    this.element_.removeEventListener(
26251      EventType.TOUCHMOVE,
26252      this.boundHandleTouchMove_
26253    );
26254
26255    if (this.pointerdownListenerKey_) {
26256      unlistenByKey(this.pointerdownListenerKey_);
26257      this.pointerdownListenerKey_ = null;
26258    }
26259
26260    this.dragListenerKeys_.forEach(unlistenByKey);
26261    this.dragListenerKeys_.length = 0;
26262
26263    this.element_ = null;
26264    super.disposeInternal();
26265  }
26266}
26267
26268/* harmony default export */ const ol_MapBrowserEventHandler = (MapBrowserEventHandler);
26269
26270;// CONCATENATED MODULE: ./node_modules/ol/MapEventType.js
26271/**
26272 * @module ol/MapEventType
26273 */
26274
26275/**
26276 * @enum {string}
26277 */
26278/* harmony default export */ const MapEventType = ({
26279  /**
26280   * Triggered after a map frame is rendered.
26281   * @event module:ol/MapEvent~MapEvent#postrender
26282   * @api
26283   */
26284  POSTRENDER: 'postrender',
26285
26286  /**
26287   * Triggered when the map starts moving.
26288   * @event module:ol/MapEvent~MapEvent#movestart
26289   * @api
26290   */
26291  MOVESTART: 'movestart',
26292
26293  /**
26294   * Triggered after the map is moved.
26295   * @event module:ol/MapEvent~MapEvent#moveend
26296   * @api
26297   */
26298  MOVEEND: 'moveend',
26299
26300  /**
26301   * Triggered when loading of additional map data (tiles, images, features) starts.
26302   * @event module:ol/MapEvent~MapEvent#loadstart
26303   * @api
26304   */
26305  LOADSTART: 'loadstart',
26306
26307  /**
26308   * Triggered when loading of additional map data has completed.
26309   * @event module:ol/MapEvent~MapEvent#loadend
26310   * @api
26311   */
26312  LOADEND: 'loadend',
26313});
26314
26315/***
26316 * @typedef {'postrender'|'movestart'|'moveend'|'loadstart'|'loadend'} Types
26317 */
26318
26319;// CONCATENATED MODULE: ./node_modules/ol/MapProperty.js
26320/**
26321 * @module ol/MapProperty
26322 */
26323
26324/**
26325 * @enum {string}
26326 */
26327/* harmony default export */ const MapProperty = ({
26328  LAYERGROUP: 'layergroup',
26329  SIZE: 'size',
26330  TARGET: 'target',
26331  VIEW: 'view',
26332});
26333
26334;// CONCATENATED MODULE: ./node_modules/ol/structs/PriorityQueue.js
26335/**
26336 * @module ol/structs/PriorityQueue
26337 */
26338
26339
26340
26341/**
26342 * @type {number}
26343 */
26344const DROP = Infinity;
26345
26346/**
26347 * @classdesc
26348 * Priority queue.
26349 *
26350 * The implementation is inspired from the Closure Library's Heap class and
26351 * Python's heapq module.
26352 *
26353 * See https://github.com/google/closure-library/blob/master/closure/goog/structs/heap.js
26354 * and https://hg.python.org/cpython/file/2.7/Lib/heapq.py.
26355 *
26356 * @template T
26357 */
26358class PriorityQueue {
26359  /**
26360   * @param {function(T): number} priorityFunction Priority function.
26361   * @param {function(T): string} keyFunction Key function.
26362   */
26363  constructor(priorityFunction, keyFunction) {
26364    /**
26365     * @type {function(T): number}
26366     * @private
26367     */
26368    this.priorityFunction_ = priorityFunction;
26369
26370    /**
26371     * @type {function(T): string}
26372     * @private
26373     */
26374    this.keyFunction_ = keyFunction;
26375
26376    /**
26377     * @type {Array<T>}
26378     * @private
26379     */
26380    this.elements_ = [];
26381
26382    /**
26383     * @type {Array<number>}
26384     * @private
26385     */
26386    this.priorities_ = [];
26387
26388    /**
26389     * @type {!Object<string, boolean>}
26390     * @private
26391     */
26392    this.queuedElements_ = {};
26393  }
26394
26395  /**
26396   * FIXME empty description for jsdoc
26397   */
26398  clear() {
26399    this.elements_.length = 0;
26400    this.priorities_.length = 0;
26401    clear(this.queuedElements_);
26402  }
26403
26404  /**
26405   * Remove and return the highest-priority element. O(log N).
26406   * @return {T} Element.
26407   */
26408  dequeue() {
26409    const elements = this.elements_;
26410    const priorities = this.priorities_;
26411    const element = elements[0];
26412    if (elements.length == 1) {
26413      elements.length = 0;
26414      priorities.length = 0;
26415    } else {
26416      elements[0] = elements.pop();
26417      priorities[0] = priorities.pop();
26418      this.siftUp_(0);
26419    }
26420    const elementKey = this.keyFunction_(element);
26421    delete this.queuedElements_[elementKey];
26422    return element;
26423  }
26424
26425  /**
26426   * Enqueue an element. O(log N).
26427   * @param {T} element Element.
26428   * @return {boolean} The element was added to the queue.
26429   */
26430  enqueue(element) {
26431    asserts_assert(!(this.keyFunction_(element) in this.queuedElements_), 31); // Tried to enqueue an `element` that was already added to the queue
26432    const priority = this.priorityFunction_(element);
26433    if (priority != DROP) {
26434      this.elements_.push(element);
26435      this.priorities_.push(priority);
26436      this.queuedElements_[this.keyFunction_(element)] = true;
26437      this.siftDown_(0, this.elements_.length - 1);
26438      return true;
26439    }
26440    return false;
26441  }
26442
26443  /**
26444   * @return {number} Count.
26445   */
26446  getCount() {
26447    return this.elements_.length;
26448  }
26449
26450  /**
26451   * Gets the index of the left child of the node at the given index.
26452   * @param {number} index The index of the node to get the left child for.
26453   * @return {number} The index of the left child.
26454   * @private
26455   */
26456  getLeftChildIndex_(index) {
26457    return index * 2 + 1;
26458  }
26459
26460  /**
26461   * Gets the index of the right child of the node at the given index.
26462   * @param {number} index The index of the node to get the right child for.
26463   * @return {number} The index of the right child.
26464   * @private
26465   */
26466  getRightChildIndex_(index) {
26467    return index * 2 + 2;
26468  }
26469
26470  /**
26471   * Gets the index of the parent of the node at the given index.
26472   * @param {number} index The index of the node to get the parent for.
26473   * @return {number} The index of the parent.
26474   * @private
26475   */
26476  getParentIndex_(index) {
26477    return (index - 1) >> 1;
26478  }
26479
26480  /**
26481   * Make this a heap. O(N).
26482   * @private
26483   */
26484  heapify_() {
26485    let i;
26486    for (i = (this.elements_.length >> 1) - 1; i >= 0; i--) {
26487      this.siftUp_(i);
26488    }
26489  }
26490
26491  /**
26492   * @return {boolean} Is empty.
26493   */
26494  isEmpty() {
26495    return this.elements_.length === 0;
26496  }
26497
26498  /**
26499   * @param {string} key Key.
26500   * @return {boolean} Is key queued.
26501   */
26502  isKeyQueued(key) {
26503    return key in this.queuedElements_;
26504  }
26505
26506  /**
26507   * @param {T} element Element.
26508   * @return {boolean} Is queued.
26509   */
26510  isQueued(element) {
26511    return this.isKeyQueued(this.keyFunction_(element));
26512  }
26513
26514  /**
26515   * @param {number} index The index of the node to move down.
26516   * @private
26517   */
26518  siftUp_(index) {
26519    const elements = this.elements_;
26520    const priorities = this.priorities_;
26521    const count = elements.length;
26522    const element = elements[index];
26523    const priority = priorities[index];
26524    const startIndex = index;
26525
26526    while (index < count >> 1) {
26527      const lIndex = this.getLeftChildIndex_(index);
26528      const rIndex = this.getRightChildIndex_(index);
26529
26530      const smallerChildIndex =
26531        rIndex < count && priorities[rIndex] < priorities[lIndex]
26532          ? rIndex
26533          : lIndex;
26534
26535      elements[index] = elements[smallerChildIndex];
26536      priorities[index] = priorities[smallerChildIndex];
26537      index = smallerChildIndex;
26538    }
26539
26540    elements[index] = element;
26541    priorities[index] = priority;
26542    this.siftDown_(startIndex, index);
26543  }
26544
26545  /**
26546   * @param {number} startIndex The index of the root.
26547   * @param {number} index The index of the node to move up.
26548   * @private
26549   */
26550  siftDown_(startIndex, index) {
26551    const elements = this.elements_;
26552    const priorities = this.priorities_;
26553    const element = elements[index];
26554    const priority = priorities[index];
26555
26556    while (index > startIndex) {
26557      const parentIndex = this.getParentIndex_(index);
26558      if (priorities[parentIndex] > priority) {
26559        elements[index] = elements[parentIndex];
26560        priorities[index] = priorities[parentIndex];
26561        index = parentIndex;
26562      } else {
26563        break;
26564      }
26565    }
26566    elements[index] = element;
26567    priorities[index] = priority;
26568  }
26569
26570  /**
26571   * FIXME empty description for jsdoc
26572   */
26573  reprioritize() {
26574    const priorityFunction = this.priorityFunction_;
26575    const elements = this.elements_;
26576    const priorities = this.priorities_;
26577    let index = 0;
26578    const n = elements.length;
26579    let element, i, priority;
26580    for (i = 0; i < n; ++i) {
26581      element = elements[i];
26582      priority = priorityFunction(element);
26583      if (priority == DROP) {
26584        delete this.queuedElements_[this.keyFunction_(element)];
26585      } else {
26586        priorities[index] = priority;
26587        elements[index++] = element;
26588      }
26589    }
26590    elements.length = index;
26591    priorities.length = index;
26592    this.heapify_();
26593  }
26594}
26595
26596/* harmony default export */ const structs_PriorityQueue = (PriorityQueue);
26597
26598;// CONCATENATED MODULE: ./node_modules/ol/TileState.js
26599/**
26600 * @module ol/TileState
26601 */
26602
26603/**
26604 * @enum {number}
26605 */
26606/* harmony default export */ const TileState = ({
26607  IDLE: 0,
26608  LOADING: 1,
26609  LOADED: 2,
26610  /**
26611   * Indicates that tile loading failed
26612   * @type {number}
26613   */
26614  ERROR: 3,
26615  EMPTY: 4,
26616});
26617
26618;// CONCATENATED MODULE: ./node_modules/ol/TileQueue.js
26619/**
26620 * @module ol/TileQueue
26621 */
26622
26623
26624
26625
26626/**
26627 * @typedef {function(import("./Tile.js").default, string, import("./coordinate.js").Coordinate, number): number} PriorityFunction
26628 */
26629
26630class TileQueue extends structs_PriorityQueue {
26631  /**
26632   * @param {PriorityFunction} tilePriorityFunction Tile priority function.
26633   * @param {function(): ?} tileChangeCallback Function called on each tile change event.
26634   */
26635  constructor(tilePriorityFunction, tileChangeCallback) {
26636    super(
26637      /**
26638       * @param {Array} element Element.
26639       * @return {number} Priority.
26640       */
26641      function (element) {
26642        return tilePriorityFunction.apply(null, element);
26643      },
26644      /**
26645       * @param {Array} element Element.
26646       * @return {string} Key.
26647       */
26648      function (element) {
26649        return /** @type {import("./Tile.js").default} */ (element[0]).getKey();
26650      }
26651    );
26652
26653    /** @private */
26654    this.boundHandleTileChange_ = this.handleTileChange.bind(this);
26655
26656    /**
26657     * @private
26658     * @type {function(): ?}
26659     */
26660    this.tileChangeCallback_ = tileChangeCallback;
26661
26662    /**
26663     * @private
26664     * @type {number}
26665     */
26666    this.tilesLoading_ = 0;
26667
26668    /**
26669     * @private
26670     * @type {!Object<string,boolean>}
26671     */
26672    this.tilesLoadingKeys_ = {};
26673  }
26674
26675  /**
26676   * @param {Array} element Element.
26677   * @return {boolean} The element was added to the queue.
26678   */
26679  enqueue(element) {
26680    const added = super.enqueue(element);
26681    if (added) {
26682      const tile = element[0];
26683      tile.addEventListener(EventType.CHANGE, this.boundHandleTileChange_);
26684    }
26685    return added;
26686  }
26687
26688  /**
26689   * @return {number} Number of tiles loading.
26690   */
26691  getTilesLoading() {
26692    return this.tilesLoading_;
26693  }
26694
26695  /**
26696   * @param {import("./events/Event.js").default} event Event.
26697   * @protected
26698   */
26699  handleTileChange(event) {
26700    const tile = /** @type {import("./Tile.js").default} */ (event.target);
26701    const state = tile.getState();
26702    if (
26703      state === TileState.LOADED ||
26704      state === TileState.ERROR ||
26705      state === TileState.EMPTY
26706    ) {
26707      if (state !== TileState.ERROR) {
26708        tile.removeEventListener(EventType.CHANGE, this.boundHandleTileChange_);
26709      }
26710      const tileKey = tile.getKey();
26711      if (tileKey in this.tilesLoadingKeys_) {
26712        delete this.tilesLoadingKeys_[tileKey];
26713        --this.tilesLoading_;
26714      }
26715      this.tileChangeCallback_();
26716    }
26717  }
26718
26719  /**
26720   * @param {number} maxTotalLoading Maximum number tiles to load simultaneously.
26721   * @param {number} maxNewLoads Maximum number of new tiles to load.
26722   */
26723  loadMoreTiles(maxTotalLoading, maxNewLoads) {
26724    let newLoads = 0;
26725    let state, tile, tileKey;
26726    while (
26727      this.tilesLoading_ < maxTotalLoading &&
26728      newLoads < maxNewLoads &&
26729      this.getCount() > 0
26730    ) {
26731      tile = /** @type {import("./Tile.js").default} */ (this.dequeue()[0]);
26732      tileKey = tile.getKey();
26733      state = tile.getState();
26734      if (state === TileState.IDLE && !(tileKey in this.tilesLoadingKeys_)) {
26735        this.tilesLoadingKeys_[tileKey] = true;
26736        ++this.tilesLoading_;
26737        ++newLoads;
26738        tile.load();
26739      }
26740    }
26741  }
26742}
26743
26744/* harmony default export */ const ol_TileQueue = (TileQueue);
26745
26746/**
26747 * @param {import('./Map.js').FrameState} frameState Frame state.
26748 * @param {import("./Tile.js").default} tile Tile.
26749 * @param {string} tileSourceKey Tile source key.
26750 * @param {import("./coordinate.js").Coordinate} tileCenter Tile center.
26751 * @param {number} tileResolution Tile resolution.
26752 * @return {number} Tile priority.
26753 */
26754function getTilePriority(
26755  frameState,
26756  tile,
26757  tileSourceKey,
26758  tileCenter,
26759  tileResolution
26760) {
26761  // Filter out tiles at higher zoom levels than the current zoom level, or that
26762  // are outside the visible extent.
26763  if (!frameState || !(tileSourceKey in frameState.wantedTiles)) {
26764    return DROP;
26765  }
26766  if (!frameState.wantedTiles[tileSourceKey][tile.getKey()]) {
26767    return DROP;
26768  }
26769  // Prioritize the highest zoom level tiles closest to the focus.
26770  // Tiles at higher zoom levels are prioritized using Math.log(tileResolution).
26771  // Within a zoom level, tiles are prioritized by the distance in pixels between
26772  // the center of the tile and the center of the viewport.  The factor of 65536
26773  // means that the prioritization should behave as desired for tiles up to
26774  // 65536 * Math.log(2) = 45426 pixels from the focus.
26775  const center = frameState.viewState.center;
26776  const deltaX = tileCenter[0] - center[0];
26777  const deltaY = tileCenter[1] - center[1];
26778  return (
26779    65536 * Math.log(tileResolution) +
26780    Math.sqrt(deltaX * deltaX + deltaY * deltaY) / tileResolution
26781  );
26782}
26783
26784;// CONCATENATED MODULE: ./node_modules/ol/control/Control.js
26785/**
26786 * @module ol/control/Control
26787 */
26788
26789
26790
26791
26792
26793
26794/**
26795 * @typedef {Object} Options
26796 * @property {HTMLElement} [element] The element is the control's
26797 * container element. This only needs to be specified if you're developing
26798 * a custom control.
26799 * @property {function(import("../MapEvent.js").default):void} [render] Function called when
26800 * the control should be re-rendered. This is called in a `requestAnimationFrame`
26801 * callback.
26802 * @property {HTMLElement|string} [target] Specify a target if you want
26803 * the control to be rendered outside of the map's viewport.
26804 */
26805
26806/**
26807 * @classdesc
26808 * A control is a visible widget with a DOM element in a fixed position on the
26809 * screen. They can involve user input (buttons), or be informational only;
26810 * the position is determined using CSS. By default these are placed in the
26811 * container with CSS class name `ol-overlaycontainer-stopevent`, but can use
26812 * any outside DOM element.
26813 *
26814 * This is the base class for controls. You can use it for simple custom
26815 * controls by creating the element with listeners, creating an instance:
26816 * ```js
26817 * const myControl = new Control({element: myElement});
26818 * ```
26819 * and then adding this to the map.
26820 *
26821 * The main advantage of having this as a control rather than a simple separate
26822 * DOM element is that preventing propagation is handled for you. Controls
26823 * will also be objects in a {@link module:ol/Collection~Collection}, so you can use their methods.
26824 *
26825 * You can also extend this base for your own control class. See
26826 * examples/custom-controls for an example of how to do this.
26827 *
26828 * @api
26829 */
26830class Control extends ol_Object {
26831  /**
26832   * @param {Options} options Control options.
26833   */
26834  constructor(options) {
26835    super();
26836
26837    const element = options.element;
26838    if (element && !options.target && !element.style.pointerEvents) {
26839      element.style.pointerEvents = 'auto';
26840    }
26841
26842    /**
26843     * @protected
26844     * @type {HTMLElement}
26845     */
26846    this.element = element ? element : null;
26847
26848    /**
26849     * @private
26850     * @type {HTMLElement}
26851     */
26852    this.target_ = null;
26853
26854    /**
26855     * @private
26856     * @type {import("../Map.js").default|null}
26857     */
26858    this.map_ = null;
26859
26860    /**
26861     * @protected
26862     * @type {!Array<import("../events.js").EventsKey>}
26863     */
26864    this.listenerKeys = [];
26865
26866    if (options.render) {
26867      this.render = options.render;
26868    }
26869
26870    if (options.target) {
26871      this.setTarget(options.target);
26872    }
26873  }
26874
26875  /**
26876   * Clean up.
26877   */
26878  disposeInternal() {
26879    removeNode(this.element);
26880    super.disposeInternal();
26881  }
26882
26883  /**
26884   * Get the map associated with this control.
26885   * @return {import("../Map.js").default|null} Map.
26886   * @api
26887   */
26888  getMap() {
26889    return this.map_;
26890  }
26891
26892  /**
26893   * Remove the control from its current map and attach it to the new map.
26894   * Pass `null` to just remove the control from the current map.
26895   * Subclasses may set up event handlers to get notified about changes to
26896   * the map here.
26897   * @param {import("../Map.js").default|null} map Map.
26898   * @api
26899   */
26900  setMap(map) {
26901    if (this.map_) {
26902      removeNode(this.element);
26903    }
26904    for (let i = 0, ii = this.listenerKeys.length; i < ii; ++i) {
26905      unlistenByKey(this.listenerKeys[i]);
26906    }
26907    this.listenerKeys.length = 0;
26908    this.map_ = map;
26909    if (map) {
26910      const target = this.target_
26911        ? this.target_
26912        : map.getOverlayContainerStopEvent();
26913      target.appendChild(this.element);
26914      if (this.render !== VOID) {
26915        this.listenerKeys.push(
26916          listen(map, MapEventType.POSTRENDER, this.render, this)
26917        );
26918      }
26919      map.render();
26920    }
26921  }
26922
26923  /**
26924   * Renders the control.
26925   * @param {import("../MapEvent.js").default} mapEvent Map event.
26926   * @api
26927   */
26928  render(mapEvent) {}
26929
26930  /**
26931   * This function is used to set a target element for the control. It has no
26932   * effect if it is called after the control has been added to the map (i.e.
26933   * after `setMap` is called on the control). If no `target` is set in the
26934   * options passed to the control constructor and if `setTarget` is not called
26935   * then the control is added to the map's overlay container.
26936   * @param {HTMLElement|string} target Target.
26937   * @api
26938   */
26939  setTarget(target) {
26940    this.target_ =
26941      typeof target === 'string' ? document.getElementById(target) : target;
26942  }
26943}
26944
26945/* harmony default export */ const control_Control = (Control);
26946
26947;// CONCATENATED MODULE: ./node_modules/ol/control/Attribution.js
26948/**
26949 * @module ol/control/Attribution
26950 */
26951
26952
26953
26954
26955
26956
26957
26958/**
26959 * @typedef {Object} Options
26960 * @property {string} [className='ol-attribution'] CSS class name.
26961 * @property {HTMLElement|string} [target] Specify a target if you
26962 * want the control to be rendered outside of the map's
26963 * viewport.
26964 * @property {boolean} [collapsible] Specify if attributions can
26965 * be collapsed. If not specified, sources control this behavior with their
26966 * `attributionsCollapsible` setting.
26967 * @property {boolean} [collapsed=true] Specify if attributions should
26968 * be collapsed at startup.
26969 * @property {string} [tipLabel='Attributions'] Text label to use for the button tip.
26970 * @property {string|HTMLElement} [label='i'] Text label to use for the
26971 * collapsed attributions button.
26972 * Instead of text, also an element (e.g. a `span` element) can be used.
26973 * @property {string} [expandClassName=className + '-expand'] CSS class name for the
26974 * collapsed attributions button.
26975 * @property {string|HTMLElement} [collapseLabel='›'] Text label to use
26976 * for the expanded attributions button.
26977 * Instead of text, also an element (e.g. a `span` element) can be used.
26978 * @property {string} [collapseClassName=className + '-collapse'] CSS class name for the
26979 * expanded attributions button.
26980 * @property {function(import("../MapEvent.js").default):void} [render] Function called when
26981 * the control should be re-rendered. This is called in a `requestAnimationFrame`
26982 * callback.
26983 */
26984
26985/**
26986 * @classdesc
26987 * Control to show all the attributions associated with the layer sources
26988 * in the map. This control is one of the default controls included in maps.
26989 * By default it will show in the bottom right portion of the map, but this can
26990 * be changed by using a css selector for `.ol-attribution`.
26991 *
26992 * @api
26993 */
26994class Attribution extends control_Control {
26995  /**
26996   * @param {Options} [options] Attribution options.
26997   */
26998  constructor(options) {
26999    options = options ? options : {};
27000
27001    super({
27002      element: document.createElement('div'),
27003      render: options.render,
27004      target: options.target,
27005    });
27006
27007    /**
27008     * @private
27009     * @type {HTMLElement}
27010     */
27011    this.ulElement_ = document.createElement('ul');
27012
27013    /**
27014     * @private
27015     * @type {boolean}
27016     */
27017    this.collapsed_ =
27018      options.collapsed !== undefined ? options.collapsed : true;
27019
27020    /**
27021     * @private
27022     * @type {boolean}
27023     */
27024    this.userCollapsed_ = this.collapsed_;
27025
27026    /**
27027     * @private
27028     * @type {boolean}
27029     */
27030    this.overrideCollapsible_ = options.collapsible !== undefined;
27031
27032    /**
27033     * @private
27034     * @type {boolean}
27035     */
27036    this.collapsible_ =
27037      options.collapsible !== undefined ? options.collapsible : true;
27038
27039    if (!this.collapsible_) {
27040      this.collapsed_ = false;
27041    }
27042
27043    const className =
27044      options.className !== undefined ? options.className : 'ol-attribution';
27045
27046    const tipLabel =
27047      options.tipLabel !== undefined ? options.tipLabel : 'Attributions';
27048
27049    const expandClassName =
27050      options.expandClassName !== undefined
27051        ? options.expandClassName
27052        : className + '-expand';
27053
27054    const collapseLabel =
27055      options.collapseLabel !== undefined ? options.collapseLabel : '\u203A';
27056
27057    const collapseClassName =
27058      options.collapseClassName !== undefined
27059        ? options.collapseClassName
27060        : className + '-collapse';
27061
27062    if (typeof collapseLabel === 'string') {
27063      /**
27064       * @private
27065       * @type {HTMLElement}
27066       */
27067      this.collapseLabel_ = document.createElement('span');
27068      this.collapseLabel_.textContent = collapseLabel;
27069      this.collapseLabel_.className = collapseClassName;
27070    } else {
27071      this.collapseLabel_ = collapseLabel;
27072    }
27073
27074    const label = options.label !== undefined ? options.label : 'i';
27075
27076    if (typeof label === 'string') {
27077      /**
27078       * @private
27079       * @type {HTMLElement}
27080       */
27081      this.label_ = document.createElement('span');
27082      this.label_.textContent = label;
27083      this.label_.className = expandClassName;
27084    } else {
27085      this.label_ = label;
27086    }
27087
27088    const activeLabel =
27089      this.collapsible_ && !this.collapsed_ ? this.collapseLabel_ : this.label_;
27090
27091    /**
27092     * @private
27093     * @type {HTMLElement}
27094     */
27095    this.toggleButton_ = document.createElement('button');
27096    this.toggleButton_.setAttribute('type', 'button');
27097    this.toggleButton_.setAttribute('aria-expanded', String(!this.collapsed_));
27098    this.toggleButton_.title = tipLabel;
27099    this.toggleButton_.appendChild(activeLabel);
27100
27101    this.toggleButton_.addEventListener(
27102      EventType.CLICK,
27103      this.handleClick_.bind(this),
27104      false
27105    );
27106
27107    const cssClasses =
27108      className +
27109      ' ' +
27110      CLASS_UNSELECTABLE +
27111      ' ' +
27112      CLASS_CONTROL +
27113      (this.collapsed_ && this.collapsible_ ? ' ' + CLASS_COLLAPSED : '') +
27114      (this.collapsible_ ? '' : ' ol-uncollapsible');
27115    const element = this.element;
27116    element.className = cssClasses;
27117    element.appendChild(this.toggleButton_);
27118    element.appendChild(this.ulElement_);
27119
27120    /**
27121     * A list of currently rendered resolutions.
27122     * @type {Array<string>}
27123     * @private
27124     */
27125    this.renderedAttributions_ = [];
27126
27127    /**
27128     * @private
27129     * @type {boolean}
27130     */
27131    this.renderedVisible_ = true;
27132  }
27133
27134  /**
27135   * Collect a list of visible attributions and set the collapsible state.
27136   * @param {import("../Map.js").FrameState} frameState Frame state.
27137   * @return {Array<string>} Attributions.
27138   * @private
27139   */
27140  collectSourceAttributions_(frameState) {
27141    /**
27142     * Used to determine if an attribution already exists.
27143     * @type {!Object<string, boolean>}
27144     */
27145    const lookup = {};
27146
27147    /**
27148     * A list of visible attributions.
27149     * @type {Array<string>}
27150     */
27151    const visibleAttributions = [];
27152
27153    let collapsible = true;
27154    const layerStatesArray = frameState.layerStatesArray;
27155    for (let i = 0, ii = layerStatesArray.length; i < ii; ++i) {
27156      const layerState = layerStatesArray[i];
27157      if (!inView(layerState, frameState.viewState)) {
27158        continue;
27159      }
27160
27161      const source = /** @type {import("../layer/Layer.js").default} */ (
27162        layerState.layer
27163      ).getSource();
27164      if (!source) {
27165        continue;
27166      }
27167
27168      const attributionGetter = source.getAttributions();
27169      if (!attributionGetter) {
27170        continue;
27171      }
27172
27173      const attributions = attributionGetter(frameState);
27174      if (!attributions) {
27175        continue;
27176      }
27177
27178      collapsible =
27179        collapsible && source.getAttributionsCollapsible() !== false;
27180
27181      if (Array.isArray(attributions)) {
27182        for (let j = 0, jj = attributions.length; j < jj; ++j) {
27183          if (!(attributions[j] in lookup)) {
27184            visibleAttributions.push(attributions[j]);
27185            lookup[attributions[j]] = true;
27186          }
27187        }
27188      } else {
27189        if (!(attributions in lookup)) {
27190          visibleAttributions.push(attributions);
27191          lookup[attributions] = true;
27192        }
27193      }
27194    }
27195    if (!this.overrideCollapsible_) {
27196      this.setCollapsible(collapsible);
27197    }
27198    return visibleAttributions;
27199  }
27200
27201  /**
27202   * @private
27203   * @param {?import("../Map.js").FrameState} frameState Frame state.
27204   */
27205  updateElement_(frameState) {
27206    if (!frameState) {
27207      if (this.renderedVisible_) {
27208        this.element.style.display = 'none';
27209        this.renderedVisible_ = false;
27210      }
27211      return;
27212    }
27213
27214    const attributions = this.collectSourceAttributions_(frameState);
27215
27216    const visible = attributions.length > 0;
27217    if (this.renderedVisible_ != visible) {
27218      this.element.style.display = visible ? '' : 'none';
27219      this.renderedVisible_ = visible;
27220    }
27221
27222    if (equals(attributions, this.renderedAttributions_)) {
27223      return;
27224    }
27225
27226    removeChildren(this.ulElement_);
27227
27228    // append the attributions
27229    for (let i = 0, ii = attributions.length; i < ii; ++i) {
27230      const element = document.createElement('li');
27231      element.innerHTML = attributions[i];
27232      this.ulElement_.appendChild(element);
27233    }
27234
27235    this.renderedAttributions_ = attributions;
27236  }
27237
27238  /**
27239   * @param {MouseEvent} event The event to handle
27240   * @private
27241   */
27242  handleClick_(event) {
27243    event.preventDefault();
27244    this.handleToggle_();
27245    this.userCollapsed_ = this.collapsed_;
27246  }
27247
27248  /**
27249   * @private
27250   */
27251  handleToggle_() {
27252    this.element.classList.toggle(CLASS_COLLAPSED);
27253    if (this.collapsed_) {
27254      replaceNode(this.collapseLabel_, this.label_);
27255    } else {
27256      replaceNode(this.label_, this.collapseLabel_);
27257    }
27258    this.collapsed_ = !this.collapsed_;
27259    this.toggleButton_.setAttribute('aria-expanded', String(!this.collapsed_));
27260  }
27261
27262  /**
27263   * Return `true` if the attribution is collapsible, `false` otherwise.
27264   * @return {boolean} True if the widget is collapsible.
27265   * @api
27266   */
27267  getCollapsible() {
27268    return this.collapsible_;
27269  }
27270
27271  /**
27272   * Set whether the attribution should be collapsible.
27273   * @param {boolean} collapsible True if the widget is collapsible.
27274   * @api
27275   */
27276  setCollapsible(collapsible) {
27277    if (this.collapsible_ === collapsible) {
27278      return;
27279    }
27280    this.collapsible_ = collapsible;
27281    this.element.classList.toggle('ol-uncollapsible');
27282    if (this.userCollapsed_) {
27283      this.handleToggle_();
27284    }
27285  }
27286
27287  /**
27288   * Collapse or expand the attribution according to the passed parameter. Will
27289   * not do anything if the attribution isn't collapsible or if the current
27290   * collapsed state is already the one requested.
27291   * @param {boolean} collapsed True if the widget is collapsed.
27292   * @api
27293   */
27294  setCollapsed(collapsed) {
27295    this.userCollapsed_ = collapsed;
27296    if (!this.collapsible_ || this.collapsed_ === collapsed) {
27297      return;
27298    }
27299    this.handleToggle_();
27300  }
27301
27302  /**
27303   * Return `true` when the attribution is currently collapsed or `false`
27304   * otherwise.
27305   * @return {boolean} True if the widget is collapsed.
27306   * @api
27307   */
27308  getCollapsed() {
27309    return this.collapsed_;
27310  }
27311
27312  /**
27313   * Update the attribution element.
27314   * @param {import("../MapEvent.js").default} mapEvent Map event.
27315   * @override
27316   */
27317  render(mapEvent) {
27318    this.updateElement_(mapEvent.frameState);
27319  }
27320}
27321
27322/* harmony default export */ const control_Attribution = (Attribution);
27323
27324;// CONCATENATED MODULE: ./node_modules/ol/control/Rotate.js
27325/**
27326 * @module ol/control/Rotate
27327 */
27328
27329
27330
27331
27332
27333/**
27334 * @typedef {Object} Options
27335 * @property {string} [className='ol-rotate'] CSS class name.
27336 * @property {string|HTMLElement} [label='⇧'] Text label to use for the rotate button.
27337 * Instead of text, also an element (e.g. a `span` element) can be used.
27338 * @property {string} [tipLabel='Reset rotation'] Text label to use for the rotate tip.
27339 * @property {string} [compassClassName='ol-compass'] CSS class name for the compass.
27340 * @property {number} [duration=250] Animation duration in milliseconds.
27341 * @property {boolean} [autoHide=true] Hide the control when rotation is 0.
27342 * @property {function(import("../MapEvent.js").default):void} [render] Function called when the control should
27343 * be re-rendered. This is called in a `requestAnimationFrame` callback.
27344 * @property {function():void} [resetNorth] Function called when the control is clicked.
27345 * This will override the default `resetNorth`.
27346 * @property {HTMLElement|string} [target] Specify a target if you want the control to be
27347 * rendered outside of the map's viewport.
27348 */
27349
27350/**
27351 * @classdesc
27352 * A button control to reset rotation to 0.
27353 * To style this control use css selector `.ol-rotate`. A `.ol-hidden` css
27354 * selector is added to the button when the rotation is 0.
27355 *
27356 * @api
27357 */
27358class Rotate extends control_Control {
27359  /**
27360   * @param {Options} [options] Rotate options.
27361   */
27362  constructor(options) {
27363    options = options ? options : {};
27364
27365    super({
27366      element: document.createElement('div'),
27367      render: options.render,
27368      target: options.target,
27369    });
27370
27371    const className =
27372      options.className !== undefined ? options.className : 'ol-rotate';
27373
27374    const label = options.label !== undefined ? options.label : '\u21E7';
27375
27376    const compassClassName =
27377      options.compassClassName !== undefined
27378        ? options.compassClassName
27379        : 'ol-compass';
27380
27381    /**
27382     * @type {HTMLElement}
27383     * @private
27384     */
27385    this.label_ = null;
27386
27387    if (typeof label === 'string') {
27388      this.label_ = document.createElement('span');
27389      this.label_.className = compassClassName;
27390      this.label_.textContent = label;
27391    } else {
27392      this.label_ = label;
27393      this.label_.classList.add(compassClassName);
27394    }
27395
27396    const tipLabel = options.tipLabel ? options.tipLabel : 'Reset rotation';
27397
27398    const button = document.createElement('button');
27399    button.className = className + '-reset';
27400    button.setAttribute('type', 'button');
27401    button.title = tipLabel;
27402    button.appendChild(this.label_);
27403
27404    button.addEventListener(
27405      EventType.CLICK,
27406      this.handleClick_.bind(this),
27407      false
27408    );
27409
27410    const cssClasses =
27411      className + ' ' + CLASS_UNSELECTABLE + ' ' + CLASS_CONTROL;
27412    const element = this.element;
27413    element.className = cssClasses;
27414    element.appendChild(button);
27415
27416    this.callResetNorth_ = options.resetNorth ? options.resetNorth : undefined;
27417
27418    /**
27419     * @type {number}
27420     * @private
27421     */
27422    this.duration_ = options.duration !== undefined ? options.duration : 250;
27423
27424    /**
27425     * @type {boolean}
27426     * @private
27427     */
27428    this.autoHide_ = options.autoHide !== undefined ? options.autoHide : true;
27429
27430    /**
27431     * @private
27432     * @type {number|undefined}
27433     */
27434    this.rotation_ = undefined;
27435
27436    if (this.autoHide_) {
27437      this.element.classList.add(CLASS_HIDDEN);
27438    }
27439  }
27440
27441  /**
27442   * @param {MouseEvent} event The event to handle
27443   * @private
27444   */
27445  handleClick_(event) {
27446    event.preventDefault();
27447    if (this.callResetNorth_ !== undefined) {
27448      this.callResetNorth_();
27449    } else {
27450      this.resetNorth_();
27451    }
27452  }
27453
27454  /**
27455   * @private
27456   */
27457  resetNorth_() {
27458    const map = this.getMap();
27459    const view = map.getView();
27460    if (!view) {
27461      // the map does not have a view, so we can't act
27462      // upon it
27463      return;
27464    }
27465    const rotation = view.getRotation();
27466    if (rotation !== undefined) {
27467      if (this.duration_ > 0 && rotation % (2 * Math.PI) !== 0) {
27468        view.animate({
27469          rotation: 0,
27470          duration: this.duration_,
27471          easing: easeOut,
27472        });
27473      } else {
27474        view.setRotation(0);
27475      }
27476    }
27477  }
27478
27479  /**
27480   * Update the rotate control element.
27481   * @param {import("../MapEvent.js").default} mapEvent Map event.
27482   * @override
27483   */
27484  render(mapEvent) {
27485    const frameState = mapEvent.frameState;
27486    if (!frameState) {
27487      return;
27488    }
27489    const rotation = frameState.viewState.rotation;
27490    if (rotation != this.rotation_) {
27491      const transform = 'rotate(' + rotation + 'rad)';
27492      if (this.autoHide_) {
27493        const contains = this.element.classList.contains(CLASS_HIDDEN);
27494        if (!contains && rotation === 0) {
27495          this.element.classList.add(CLASS_HIDDEN);
27496        } else if (contains && rotation !== 0) {
27497          this.element.classList.remove(CLASS_HIDDEN);
27498        }
27499      }
27500      this.label_.style.transform = transform;
27501    }
27502    this.rotation_ = rotation;
27503  }
27504}
27505
27506/* harmony default export */ const control_Rotate = (Rotate);
27507
27508;// CONCATENATED MODULE: ./node_modules/ol/control/Zoom.js
27509/**
27510 * @module ol/control/Zoom
27511 */
27512
27513
27514
27515
27516
27517/**
27518 * @typedef {Object} Options
27519 * @property {number} [duration=250] Animation duration in milliseconds.
27520 * @property {string} [className='ol-zoom'] CSS class name.
27521 * @property {string} [zoomInClassName=className + '-in'] CSS class name for the zoom
27521-in button.
27522 * @property {string} [zoomOutClassName=className + '-out'] CSS class name for the zoom-out button.
27523 * @property {string|HTMLElement} [zoomInLabel='+'] Text label to use for the zoom-in
27524 * button. Instead of text, also an element (e.g. a `span` element) can be used.
27525 * @property {string|HTMLElement} [zoomOutLabel='–'] Text label to use for the zoom-out button.
27526 * Instead of text, also an element (e.g. a `span` element) can be used.
27527 * @property {string} [zoomInTipLabel='Zoom in'] Text label to use for the button tip.
27528 * @property {string} [zoomOutTipLabel='Zoom out'] Text label to use for the button tip.
27529 * @property {number} [delta=1] The zoom delta applied on each click.
27530 * @property {HTMLElement|string} [target] Specify a target if you want the control to be
27531 * rendered outside of the map's viewport.
27532 */
27533
27534/**
27535 * @classdesc
27536 * A control with 2 buttons, one for zoom in and one for zoom out.
27537 * This control is one of the default controls of a map. To style this control
27538 * use css selectors `.ol-zoom-in` and `.ol-zoom-out`.
27539 *
27540 * @api
27541 */
27542class Zoom extends control_Control {
27543  /**
27544   * @param {Options} [options] Zoom options.
27545   */
27546  constructor(options) {
27547    options = options ? options : {};
27548
27549    super({
27550      element: document.createElement('div'),
27551      target: options.target,
27552    });
27553
27554    const className =
27555      options.className !== undefined ? options.className : 'ol-zoom';
27556
27557    const delta = options.delta !== undefined ? options.delta : 1;
27558
27559    const zoomInClassName =
27560      options.zoomInClassName !== undefined
27561        ? options.zoomInClassName
27562        : className + '-in';
27563
27564    const zoomOutClassName =
27565      options.zoomOutClassName !== undefined
27566        ? options.zoomOutClassName
27567        : className + '-out';
27568
27569    const zoomInLabel =
27570      options.zoomInLabel !== undefined ? options.zoomInLabel : '+';
27571    const zoomOutLabel =
27572      options.zoomOutLabel !== undefined ? options.zoomOutLabel : '\u2013';
27573
27574    const zoomInTipLabel =
27575      options.zoomInTipLabel !== undefined ? options.zoomInTipLabel : 'Zoom in';
27576    const zoomOutTipLabel =
27577      options.zoomOutTipLabel !== undefined
27578        ? options.zoomOutTipLabel
27579        : 'Zoom out';
27580
27581    const inElement = document.createElement('button');
27582    inElement.className = zoomInClassName;
27583    inElement.setAttribute('type', 'button');
27584    inElement.title = zoomInTipLabel;
27585    inElement.appendChild(
27586      typeof zoomInLabel === 'string'
27587        ? document.createTextNode(zoomInLabel)
27588        : zoomInLabel
27589    );
27590
27591    inElement.addEventListener(
27592      EventType.CLICK,
27593      this.handleClick_.bind(this, delta),
27594      false
27595    );
27596
27597    const outElement = document.createElement('button');
27598    outElement.className = zoomOutClassName;
27599    outElement.setAttribute('type', 'button');
27600    outElement.title = zoomOutTipLabel;
27601    outElement.appendChild(
27602      typeof zoomOutLabel === 'string'
27603        ? document.createTextNode(zoomOutLabel)
27604        : zoomOutLabel
27605    );
27606
27607    outElement.addEventListener(
27608      EventType.CLICK,
27609      this.handleClick_.bind(this, -delta),
27610      false
27611    );
27612
27613    const cssClasses =
27614      className + ' ' + CLASS_UNSELECTABLE + ' ' + CLASS_CONTROL;
27615    const element = this.element;
27616    element.className = cssClasses;
27617    element.appendChild(inElement);
27618    element.appendChild(outElement);
27619
27620    /**
27621     * @type {number}
27622     * @private
27623     */
27624    this.duration_ = options.duration !== undefined ? options.duration : 250;
27625  }
27626
27627  /**
27628   * @param {number} delta Zoom delta.
27629   * @param {MouseEvent} event The event to handle
27630   * @private
27631   */
27632  handleClick_(delta, event) {
27633    event.preventDefault();
27634    this.zoomByDelta_(delta);
27635  }
27636
27637  /**
27638   * @param {number} delta Zoom delta.
27639   * @private
27640   */
27641  zoomByDelta_(delta) {
27642    const map = this.getMap();
27643    const view = map.getView();
27644    if (!view) {
27645      // the map does not have a view, so we can't act
27646      // upon it
27647      return;
27648    }
27649    const currentZoom = view.getZoom();
27650    if (currentZoom !== undefined) {
27651      const newZoom = view.getConstrainedZoom(currentZoom + delta);
27652      if (this.duration_ > 0) {
27653        if (view.getAnimating()) {
27654          view.cancelAnimations();
27655        }
27656        view.animate({
27657          zoom: newZoom,
27658          duration: this.duration_,
27659          easing: easeOut,
27660        });
27661      } else {
27662        view.setZoom(newZoom);
27663      }
27664    }
27665  }
27666}
27667
27668/* harmony default export */ const control_Zoom = (Zoom);
27669
27670;// CONCATENATED MODULE: ./node_modules/ol/control/defaults.js
27671/**
27672 * @module ol/control/defaults
27673 */
27674
27675
27676
27677
27678
27679/**
27680 * @typedef {Object} DefaultsOptions
27681 * @property {boolean} [attribution=true] Include
27682 * {@link module:ol/control/Attribution~Attribution}.
27683 * @property {import("./Attribution.js").Options} [attributionOptions]
27684 * Options for {@link module:ol/control/Attribution~Attribution}.
27685 * @property {boolean} [rotate=true] Include
27686 * {@link module:ol/control/Rotate~Rotate}.
27687 * @property {import("./Rotate.js").Options} [rotateOptions] Options
27688 * for {@link module:ol/control/Rotate~Rotate}.
27689 * @property {boolean} [zoom] Include {@link module:ol/control/Zoom~Zoom}.
27690 * @property {import("./Zoom.js").Options} [zoomOptions] Options for
27691 * {@link module:ol/control/Zoom~Zoom}.
27692 */
27693
27694/**
27695 * Set of controls included in maps by default. Unless configured otherwise,
27696 * this returns a collection containing an instance of each of the following
27697 * controls:
27698 * * {@link module:ol/control/Zoom~Zoom}
27699 * * {@link module:ol/control/Rotate~Rotate}
27700 * * {@link module:ol/control/Attribution~Attribution}
27701 *
27702 * @param {DefaultsOptions} [options] Options for the default controls.
27703 * @return {Collection<import("./Control.js").default>} A collection of controls
27704 * to be used with the {@link module:ol/Map~Map} constructor's `controls` option.
27705 * @api
27706 */
27707function defaults(options) {
27708  options = options ? options : {};
27709
27710  /** @type {Collection<import("./Control.js").default>} */
27711  const controls = new ol_Collection();
27712
27713  const zoomControl = options.zoom !== undefined ? options.zoom : true;
27714  if (zoomControl) {
27715    controls.push(new control_Zoom(options.zoomOptions));
27716  }
27717
27718  const rotateControl = options.rotate !== undefined ? options.rotate : true;
27719  if (rotateControl) {
27720    controls.push(new control_Rotate(options.rotateOptions));
27721  }
27722
27723  const attributionControl =
27724    options.attribution !== undefined ? options.attribution : true;
27725  if (attributionControl) {
27726    controls.push(new control_Attribution(options.attributionOptions));
27727  }
27728
27729  return controls;
27730}
27731
27732;// CONCATENATED MODULE: ./node_modules/ol/interaction/Property.js
27733/**
27734 * @module ol/interaction/Property
27735 */
27736
27737/**
27738 * @enum {string}
27739 */
27740/* harmony default export */ const interaction_Property = ({
27741  ACTIVE: 'active',
27742});
27743
27744;// CONCATENATED MODULE: ./node_modules/ol/interaction/Interaction.js
27745/**
27746 * @module ol/interaction/Interaction
27747 */
27748
27749
27750
27751
27752/***
27753 * @template Return
27754 * @typedef {import("../Observable").OnSignature<import("../Observable").EventTypes, import("../events/Event.js").default, Return> &
27755 *   import("../Observable").OnSignature<import("../ObjectEventType").Types|
27756 *     'change:active', import("../Object").ObjectEvent, Return> &
27757 *   import("../Observable").CombinedOnSignature<import("../Observable").EventTypes|import("../ObjectEventType").Types|
27758 *     'change:active', Return>} InteractionOnSignature
27759 */
27760
27761/**
27762 * Object literal with config options for interactions.
27763 * @typedef {Object} InteractionOptions
27764 * @property {function(import("../MapBrowserEvent.js").default):boolean} handleEvent
27765 * Method called by the map to notify the interaction that a browser event was
27766 * dispatched to the map. If the function returns a falsy value, propagation of
27767 * the event to other interactions in the map's interactions chain will be
27768 * prevented (this includes functions with no explicit return). The interactions
27769 * are traversed in reverse order of the interactions collection of the map.
27770 */
27771
27772/**
27773 * @classdesc
27774 * Abstract base class; normally only used for creating subclasses and not
27775 * instantiated in apps.
27776 * User actions that change the state of the map. Some are similar to controls,
27777 * but are not associated with a DOM element.
27778 * For example, {@link module:ol/interaction/KeyboardZoom~KeyboardZoom} is
27779 * functionally the same as {@link module:ol/control/Zoom~Zoom}, but triggered
27780 * by a keyboard event not a button element event.
27781 * Although interactions do not have a DOM element, some of them do render
27782 * vectors and so are visible on the screen.
27783 * @api
27784 */
27785class Interaction extends ol_Object {
27786  /**
27787   * @param {InteractionOptions} [options] Options.
27788   */
27789  constructor(options) {
27790    super();
27791
27792    /***
27793     * @type {InteractionOnSignature<import("../events").EventsKey>}
27794     */
27795    this.on;
27796
27797    /***
27798     * @type {InteractionOnSignature<import("../events").EventsKey>}
27799     */
27800    this.once;
27801
27802    /***
27803     * @type {InteractionOnSignature<void>}
27804     */
27805    this.un;
27806
27807    if (options && options.handleEvent) {
27808      this.handleEvent = options.handleEvent;
27809    }
27810
27811    /**
27812     * @private
27813     * @type {import("../Map.js").default|null}
27814     */
27815    this.map_ = null;
27816
27817    this.setActive(true);
27818  }
27819
27820  /**
27821   * Return whether the interaction is currently active.
27822   * @return {boolean} `true` if the interaction is active, `false` otherwise.
27823   * @observable
27824   * @api
27825   */
27826  getActive() {
27827    return /** @type {boolean} */ (this.get(interaction_Property.ACTIVE));
27828  }
27829
27830  /**
27831   * Get the map associated with this interaction.
27832   * @return {import("../Map.js").default|null} Map.
27833   * @api
27834   */
27835  getMap() {
27836    return this.map_;
27837  }
27838
27839  /**
27840   * Handles the {@link module:ol/MapBrowserEvent~MapBrowserEvent map browser event}.
27841   * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.
27842   * @return {boolean} `false` to stop event propagation.
27843   * @api
27844   */
27845  handleEvent(mapBrowserEvent) {
27846    return true;
27847  }
27848
27849  /**
27850   * Activate or deactivate the interaction.
27851   * @param {boolean} active Active.
27852   * @observable
27853   * @api
27854   */
27855  setActive(active) {
27856    this.set(interaction_Property.ACTIVE, active);
27857  }
27858
27859  /**
27860   * Remove the interaction from its current map and attach it to the new map.
27861   * Subclasses may set up event handlers to get notified about changes to
27862   * the map here.
27863   * @param {import("../Map.js").default|null} map Map.
27864   */
27865  setMap(map) {
27866    this.map_ = map;
27867  }
27868}
27869
27870/**
27871 * @param {import("../View.js").default} view View.
27872 * @param {import("../coordinate.js").Coordinate} delta Delta.
27873 * @param {number} [duration] Duration.
27874 */
27875function pan(view, delta, duration) {
27876  const currentCenter = view.getCenterInternal();
27877  if (currentCenter) {
27878    const center = [currentCenter[0] + delta[0], currentCenter[1] + delta[1]];
27879    view.animateInternal({
27880      duration: duration !== undefined ? duration : 250,
27881      easing: linear,
27882      center: view.getConstrainedCenter(center),
27883    });
27884  }
27885}
27886
27887/**
27888 * @param {import("../View.js").default} view View.
27889 * @param {number} delta Delta from previous zoom level.
27890 * @param {import("../coordinate.js").Coordinate} [anchor] Anchor coordinate in the user projection.
27891 * @param {number} [duration] Duration.
27892 */
27893function zoomByDelta(view, delta, anchor, duration) {
27894  const currentZoom = view.getZoom();
27895
27896  if (currentZoom === undefined) {
27897    return;
27898  }
27899
27900  const newZoom = view.getConstrainedZoom(currentZoom + delta);
27901  const newResolution = view.getResolutionForZoom(newZoom);
27902
27903  if (view.getAnimating()) {
27904    view.cancelAnimations();
27905  }
27906  view.animate({
27907    resolution: newResolution,
27908    anchor: anchor,
27909    duration: duration !== undefined ? duration : 250,
27910    easing: easeOut,
27911  });
27912}
27913
27914/* harmony default export */ const interaction_Interaction = (Interaction);
27915
27916;// CONCATENATED MODULE: ./node_modules/ol/interaction/DoubleClickZoom.js
27917/**
27918 * @module ol/interaction/DoubleClickZoom
27919 */
27920
27921
27922
27923/**
27924 * @typedef {Object} Options
27925 * @property {number} [duration=250] Animation duration in milliseconds.
27926 * @property {number} [delta=1] The zoom delta applied on each double click.
27927 */
27928
27929/**
27930 * @classdesc
27931 * Allows the user to zoom by double-clicking on the map.
27932 * @api
27933 */
27934class DoubleClickZoom extends interaction_Interaction {
27935  /**
27936   * @param {Options} [options] Options.
27937   */
27938  constructor(options) {
27939    super();
27940
27941    options = options ? options : {};
27942
27943    /**
27944     * @private
27945     * @type {number}
27946     */
27947    this.delta_ = options.delta ? options.delta : 1;
27948
27949    /**
27950     * @private
27951     * @type {number}
27952     */
27953    this.duration_ = options.duration !== undefined ? options.duration : 250;
27954  }
27955
27956  /**
27957   * Handles the {@link module:ol/MapBrowserEvent~MapBrowserEvent map browser event} (if it was a
27958   * doubleclick) and eventually zooms the map.
27959   * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.
27960   * @return {boolean} `false` to stop event propagation.
27961   */
27962  handleEvent(mapBrowserEvent) {
27963    let stopEvent = false;
27964    if (mapBrowserEvent.type == ol_MapBrowserEventType.DBLCLICK) {
27965      const browserEvent = /** @type {MouseEvent} */ (
27966        mapBrowserEvent.originalEvent
27967      );
27968      const map = mapBrowserEvent.map;
27969      const anchor = mapBrowserEvent.coordinate;
27970      const delta = browserEvent.shiftKey ? -this.delta_ : this.delta_;
27971      const view = map.getView();
27972      zoomByDelta(view, delta, anchor, this.duration_);
27973      browserEvent.preventDefault();
27974      stopEvent = true;
27975    }
27976    return !stopEvent;
27977  }
27978}
27979
27980/* harmony default export */ const interaction_DoubleClickZoom = (DoubleClickZoom);
27981
27982;// CONCATENATED MODULE: ./node_modules/ol/interaction/Pointer.js
27983/**
27984 * @module ol/interaction/Pointer
27985 */
27986
27987
27988
27989/**
27990 * @typedef {Object} Options
27991 * @property {function(import("../MapBrowserEvent.js").default):boolean} [handleDownEvent]
27992 * Function handling "down" events. If the function returns `true` then a drag
27993 * sequence is started.
27994 * @property {function(import("../MapBrowserEvent.js").default):void} [handleDragEvent]
27995 * Function handling "drag" events. This function is called on "move" events
27996 * during a drag sequence.
27997 * @property {function(import("../MapBrowserEvent.js").default):boolean} [handleEvent]
27998 * Method called by the map to notify the interaction that a browser event was
27999 * dispatched to the map. The function may return `false` to prevent the
28000 * propagation of the event to other interactions in the map's interactions
28001 * chain.
28002 * @property {function(import("../MapBrowserEvent.js").default):void} [handleMoveEvent]
28003 * Function handling "move" events. This function is called on "move" events.
28004 * This functions is also called during a drag sequence, so during a drag
28005 * sequence both the `handleDragEvent` function and this function are called.
28006 * If `handleDownEvent` is defined and it returns true this function will not
28007 * be called during a drag sequence.
28008 * @property {function(import("../MapBrowserEvent.js").default):boolean} [handleUpEvent]
28009 *  Function handling "up" events. If the function returns `false` then the
28010 * current drag sequence is stopped.
28011 * @property {function(boolean):boolean} [stopDown]
28012 * Should the down event be propagated to other interactions, or should be
28013 * stopped?
28014 */
28015
28016/**
28017 * @classdesc
28018 * Base class that calls user-defined functions on `down`, `move` and `up`
28019 * events. This class also manages "drag sequences".
28020 *
28021 * When the `handleDownEvent` user function returns `true` a drag sequence is
28022 * started. During a drag sequence the `handleDragEvent` user function is
28023 * called on `move` events. The drag sequence ends when the `handleUpEvent`
28024 * user function is called and returns `false`.
28025 * @api
28026 */
28027class PointerInteraction extends interaction_Interaction {
28028  /**
28029   * @param {Options} [options] Options.
28030   */
28031  constructor(options) {
28032    options = options ? options : {};
28033
28034    super(
28035      /** @type {import("./Interaction.js").InteractionOptions} */ (options)
28036    );
28037
28038    if (options.handleDownEvent) {
28039      this.handleDownEvent = options.handleDownEvent;
28040    }
28041
28042    if (options.handleDragEvent) {
28043      this.handleDragEvent = options.handleDragEvent;
28044    }
28045
28046    if (options.handleMoveEvent) {
28047      this.handleMoveEvent = options.handleMoveEvent;
28048    }
28049
28050    if (options.handleUpEvent) {
28051      this.handleUpEvent = options.handleUpEvent;
28052    }
28053
28054    if (options.stopDown) {
28055      this.stopDown = options.stopDown;
28056    }
28057
28058    /**
28059     * @type {boolean}
28060     * @protected
28061     */
28062    this.handlingDownUpSequence = false;
28063
28064    /**
28065     * @type {Array<PointerEvent>}
28066     * @protected
28067     */
28068    this.targetPointers = [];
28069  }
28070
28071  /**
28072   * Returns the current number of pointers involved in the interaction,
28073   * e.g. `2` when two fingers are used.
28074   * @return {number} The number of pointers.
28075   * @api
28076   */
28077  getPointerCount() {
28078    return this.targetPointers.length;
28079  }
28080
28081  /**
28082   * Handle pointer down events.
28083   * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.
28084   * @return {boolean} If the event was consumed.
28085   * @protected
28086   */
28087  handleDownEvent(mapBrowserEvent) {
28088    return false;
28089  }
28090
28091  /**
28092   * Handle pointer drag events.
28093   * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.
28094   * @protected
28095   */
28096  handleDragEvent(mapBrowserEvent) {}
28097
28098  /**
28099   * Handles the {@link module:ol/MapBrowserEvent~MapBrowserEvent map browser event} and may call into
28100   * other functions, if event sequences like e.g. 'drag' or 'down-up' etc. are
28101   * detected.
28102   * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.
28103   * @return {boolean} `false` to stop event propagation.
28104   * @api
28105   */
28106  handleEvent(mapBrowserEvent) {
28107    if (!mapBrowserEvent.originalEvent) {
28108      return true;
28109    }
28110
28111    let stopEvent = false;
28112    this.updateTrackedPointers_(mapBrowserEvent);
28113    if (this.handlingDownUpSequence) {
28114      if (mapBrowserEvent.type == ol_MapBrowserEventType.POINTERDRAG) {
28115        this.handleDragEvent(mapBrowserEvent);
28116        // prevent page scrolling during dragging
28117        mapBrowserEvent.originalEvent.preventDefault();
28118      } else if (mapBrowserEvent.type == ol_MapBrowserEventType.POINTERUP) {
28119        const handledUp = this.handleUpEvent(mapBrowserEvent);
28120        this.handlingDownUpSequence =
28121          handledUp && this.targetPointers.length > 0;
28122      }
28123    } else {
28124      if (mapBrowserEvent.type == ol_MapBrowserEventType.POINTERDOWN) {
28125        const handled = this.handleDownEvent(mapBrowserEvent);
28126        this.handlingDownUpSequence = handled;
28127        stopEvent = this.stopDown(handled);
28128      } else if (mapBrowserEvent.type == ol_MapBrowserEventType.POINTERMOVE) {
28129        this.handleMoveEvent(mapBrowserEvent);
28130      }
28131    }
28132    return !stopEvent;
28133  }
28134
28135  /**
28136   * Handle pointer move events.
28137   * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.
28138   * @protected
28139   */
28140  handleMoveEvent(mapBrowserEvent) {}
28141
28142  /**
28143   * Handle pointer up events.
28144   * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.
28145   * @return {boolean} If the event was consumed.
28146   * @protected
28147   */
28148  handleUpEvent(mapBrowserEvent) {
28149    return false;
28150  }
28151
28152  /**
28153   * This function is used to determine if "down" events should be propagated
28154   * to other interactions or should be stopped.
28155   * @param {boolean} handled Was the event handled by the interaction?
28156   * @return {boolean} Should the `down` event be stopped?
28157   */
28158  stopDown(handled) {
28159    return handled;
28160  }
28161
28162  /**
28163   * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.
28164   * @private
28165   */
28166  updateTrackedPointers_(mapBrowserEvent) {
28167    if (mapBrowserEvent.activePointers) {
28168      this.targetPointers = mapBrowserEvent.activePointers;
28169    }
28170  }
28171}
28172
28173/**
28174 * @param {Array<PointerEvent>} pointerEvents List of events.
28175 * @return {import("../pixel.js").Pixel} Centroid pixel.
28176 */
28177function Pointer_centroid(pointerEvents) {
28178  const length = pointerEvents.length;
28179  let clientX = 0;
28180  let clientY = 0;
28181  for (let i = 0; i < length; i++) {
28182    clientX += pointerEvents[i].clientX;
28183    clientY += pointerEvents[i].clientY;
28184  }
28185  return [clientX / length, clientY / length];
28186}
28187
28188/* harmony default export */ const Pointer = (PointerInteraction);
28189
28190;// CONCATENATED MODULE: ./node_modules/ol/events/condition.js
28191/**
28192 * @module ol/events/condition
28193 */
28194
28195
28196
28197
28198
28199/**
28200 * A function that takes an {@link module:ol/MapBrowserEvent~MapBrowserEvent} and returns a
28201 * `{boolean}`. If the condition is met, true should be returned.
28202 *
28203 * @typedef {function(this: ?, import("../MapBrowserEvent.js").default): boolean} Condition
28204 */
28205
28206/**
28207 * Creates a condition function that passes when all provided conditions pass.
28208 * @param {...Condition} var_args Conditions to check.
28209 * @return {Condition} Condition function.
28210 */
28211function condition_all(var_args) {
28212  const conditions = arguments;
28213  /**
28214   * @param {import("../MapBrowserEvent.js").default} event Event.
28215   * @return {boolean} All conditions passed.
28216   */
28217  return function (event) {
28218    let pass = true;
28219    for (let i = 0, ii = conditions.length; i < ii; ++i) {
28220      pass = pass && conditions[i](event);
28221      if (!pass) {
28222        break;
28223      }
28224    }
28225    return pass;
28226  };
28227}
28228
28229/**
28230 * Return `true` if only the alt-key is pressed, `false` otherwise (e.g. when
28231 * additionally the shift-key is pressed).
28232 *
28233 * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.
28234 * @return {boolean} True if only the alt key is pressed.
28235 * @api
28236 */
28237const altKeyOnly = function (mapBrowserEvent) {
28238  const originalEvent = /** @type {KeyboardEvent|MouseEvent|TouchEvent} */ (
28239    mapBrowserEvent.originalEvent
28240  );
28241  return (
28242    originalEvent.altKey &&
28243    !(originalEvent.metaKey || originalEvent.ctrlKey) &&
28244    !originalEvent.shiftKey
28245  );
28246};
28247
28248/**
28249 * Return `true` if only the alt-key and shift-key is pressed, `false` otherwise
28250 * (e.g. when additionally the platform-modifier-key is pressed).
28251 *
28252 * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.
28253 * @return {boolean} True if only the alt and shift keys are pressed.
28254 * @api
28255 */
28256const altShiftKeysOnly = function (mapBrowserEvent) {
28257  const originalEvent = /** @type {KeyboardEvent|MouseEvent|TouchEvent} */ (
28258    mapBrowserEvent.originalEvent
28259  );
28260  return (
28261    originalEvent.altKey &&
28262    !(originalEvent.metaKey || originalEvent.ctrlKey) &&
28263    originalEvent.shiftKey
28264  );
28265};
28266
28267/**
28268 * Return `true` if the map has the focus. This condition requires a map target
28269 * element with a `tabindex` attribute, e.g. `<div id="map" tabindex="1">`.
28270 *
28271 * @param {import("../MapBrowserEvent.js").default} event Map browser event.
28272 * @return {boolean} The map has the focus.
28273 * @api
28274 */
28275const condition_focus = function (event) {
28276  const targetElement = event.map.getTargetElement();
28277  const activeElement = event.map.getOwnerDocument().activeElement;
28278  return targetElement.contains(activeElement);
28279};
28280
28281/**
28282 * Return `true` if the map has the focus or no 'tabindex' attribute set.
28283 *
28284 * @param {import("../MapBrowserEvent.js").default} event Map browser event.
28285 * @return {boolean} The map container has the focus or no 'tabindex' attribute.
28286 */
28287const focusWithTabindex = function (event) {
28288  return event.map.getTargetElement().hasAttribute('tabindex')
28289    ? condition_focus(event)
28290    : true;
28291};
28292
28293/**
28294 * Return always true.
28295 *
28296 * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.
28297 * @return {boolean} True.
28298 * @api
28299 */
28300const always = TRUE;
28301
28302/**
28303 * Return `true` if the event is a `click` event, `false` otherwise.
28304 *
28305 * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.
28306 * @return {boolean} True if the event is a map `click` event.
28307 * @api
28308 */
28309const click = function (mapBrowserEvent) {
28310  return mapBrowserEvent.type == MapBrowserEventType.CLICK;
28311};
28312
28313/**
28314 * Return `true` if the event has an "action"-producing mouse button.
28315 *
28316 * By definition, this includes left-click on windows/linux, and left-click
28317 * without the ctrl key on Macs.
28318 *
28319 * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.
28320 * @return {boolean} The result.
28321 */
28322const mouseActionButton = function (mapBrowserEvent) {
28323  const originalEvent = /** @type {MouseEvent} */ (
28324    mapBrowserEvent.originalEvent
28325  );
28326  return originalEvent.button == 0 && !(WEBKIT && has_MAC && originalEvent.ctrlKey);
28327};
28328
28329/**
28330 * Return always false.
28331 *
28332 * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.
28333 * @return {boolean} False.
28334 * @api
28335 */
28336const never = (/* unused pure expression or super */ null && (FALSE));
28337
28338/**
28339 * Return `true` if the browser event is a `pointermove` event, `false`
28340 * otherwise.
28341 *
28342 * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.
28343 * @return {boolean} True if the browser event is a `pointermove` event.
28344 * @api
28345 */
28346const pointerMove = function (mapBrowserEvent) {
28347  return mapBrowserEvent.type == 'pointermove';
28348};
28349
28350/**
28351 * Return `true` if the event is a map `singleclick` event, `false` otherwise.
28352 *
28353 * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.
28354 * @return {boolean} True if the event is a map `singleclick` event.
28355 * @api
28356 */
28357const singleClick = function (mapBrowserEvent) {
28358  return mapBrowserEvent.type == MapBrowserEventType.SINGLECLICK;
28359};
28360
28361/**
28362 * Return `true` if the event is a map `dblclick` event, `false` otherwise.
28363 *
28364 * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.
28365 * @return {boolean} True if the event is a map `dblclick` event.
28366 * @api
28367 */
28368const doubleClick = function (mapBrowserEvent) {
28369  return mapBrowserEvent.type == MapBrowserEventType.DBLCLICK;
28370};
28371
28372/**
28373 * Return `true` if no modifier key (alt-, shift- or platform-modifier-key) is
28374 * pressed.
28375 *
28376 * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.
28377 * @return {boolean} True only if there no modifier keys are pressed.
28378 * @api
28379 */
28380const noModifierKeys = function (mapBrowserEvent) {
28381  const originalEvent = /** @type {KeyboardEvent|MouseEvent|TouchEvent} */ (
28382    mapBrowserEvent.originalEvent
28383  );
28384  return (
28385    !originalEvent.altKey &&
28386    !(originalEvent.metaKey || originalEvent.ctrlKey) &&
28387    !originalEvent.shiftKey
28388  );
28389};
28390
28391/**
28392 * Return `true` if only the platform-modifier-key (the meta-key on Mac,
28393 * ctrl-key otherwise) is pressed, `false` otherwise (e.g. when additionally
28394 * the shift-key is pressed).
28395 *
28396 * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.
28397 * @return {boolean} True if only the platform modifier key is pressed.
28398 * @api
28399 */
28400const platformModifierKeyOnly = function (mapBrowserEvent) {
28401  const originalEvent = /** @type {KeyboardEvent|MouseEvent|TouchEvent} */ (
28402    mapBrowserEvent.originalEvent
28403  );
28404  return (
28405    !originalEvent.altKey &&
28406    (MAC ? originalEvent.metaKey : originalEvent.ctrlKey) &&
28407    !originalEvent.shiftKey
28408  );
28409};
28410
28411/**
28412 * Return `true` if only the shift-key is pressed, `false` otherwise (e.g. when
28413 * additionally the alt-key is pressed).
28414 *
28415 * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.
28416 * @return {boolean} True if only the shift key is pressed.
28417 * @api
28418 */
28419const shiftKeyOnly = function (mapBrowserEvent) {
28420  const originalEvent = /** @type {KeyboardEvent|MouseEvent|TouchEvent} */ (
28421    mapBrowserEvent.originalEvent
28422  );
28423  return (
28424    !originalEvent.altKey &&
28425    !(originalEvent.metaKey || originalEvent.ctrlKey) &&
28426    originalEvent.shiftKey
28427  );
28428};
28429
28430/**
28431 * Return `true` if the target element is not editable, i.e. not an `input`,
28432 * `select`, or `textarea` element and no `contenteditable` attribute is
28433 * set or inherited, `false` otherwise.
28434 *
28435 * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.
28436 * @return {boolean} True only if the target element is not editable.
28437 * @api
28438 */
28439const targetNotEditable = function (mapBrowserEvent) {
28440  const originalEvent = /** @type {KeyboardEvent|MouseEvent|TouchEvent} */ (
28441    mapBrowserEvent.originalEvent
28442  );
28443  const tagName = /** @type {Element} */ (originalEvent.target).tagName;
28444  return (
28445    tagName !== 'INPUT' &&
28446    tagName !== 'SELECT' &&
28447    tagName !== 'TEXTAREA' &&
28448    // `isContentEditable` is only available on `HTMLElement`, but it may also be a
28449    // different type like `SVGElement`.
28450    // @ts-ignore
28451    !originalEvent.target.isContentEditable
28452  );
28453};
28454
28455/**
28456 * Return `true` if the event originates from a mouse device.
28457 *
28458 * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.
28459 * @return {boolean} True if the event originates from a mouse device.
28460 * @api
28461 */
28462const mouseOnly = function (mapBrowserEvent) {
28463  const pointerEvent = /** @type {import("../MapBrowserEvent").default} */ (
28464    mapBrowserEvent
28465  ).originalEvent;
28466  asserts_assert(pointerEvent !== undefined, 56); // mapBrowserEvent must originate from a pointer event
28467  // see https://www.w3.org/TR/pointerevents/#widl-PointerEvent-pointerType
28468  return pointerEvent.pointerType == 'mouse';
28469};
28470
28471/**
28472 * Return `true` if the event originates from a touchable device.
28473 *
28474 * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.
28475 * @return {boolean} True if the event originates from a touchable device.
28476 * @api
28477 */
28478const touchOnly = function (mapBrowserEvent) {
28479  const pointerEvt = /** @type {import("../MapBrowserEvent").default} */ (
28480    mapBrowserEvent
28481  ).originalEvent;
28482  assert(pointerEvt !== undefined, 56); // mapBrowserEvent must originate from a pointer event
28483  // see https://www.w3.org/TR/pointerevents/#widl-PointerEvent-pointerType
28484  return pointerEvt.pointerType === 'touch';
28485};
28486
28487/**
28488 * Return `true` if the event originates from a digital pen.
28489 *
28490 * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.
28491 * @return {boolean} True if the event originates from a digital pen.
28492 * @api
28493 */
28494const penOnly = function (mapBrowserEvent) {
28495  const pointerEvt = /** @type {import("../MapBrowserEvent").default} */ (
28496    mapBrowserEvent
28497  ).originalEvent;
28498  assert(pointerEvt !== undefined, 56); // mapBrowserEvent must originate from a pointer event
28499  // see https://www.w3.org/TR/pointerevents/#widl-PointerEvent-pointerType
28500  return pointerEvt.pointerType === 'pen';
28501};
28502
28503/**
28504 * Return `true` if the event originates from a primary pointer in
28505 * contact with the surface or if the left mouse button is pressed.
28506 * See https://www.w3.org/TR/pointerevents/#button-states.
28507 *
28508 * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.
28509 * @return {boolean} True if the event originates from a primary pointer.
28510 * @api
28511 */
28512const primaryAction = function (mapBrowserEvent) {
28513  const pointerEvent = /** @type {import("../MapBrowserEvent").default} */ (
28514    mapBrowserEvent
28515  ).originalEvent;
28516  asserts_assert(pointerEvent !== undefined, 56); // mapBrowserEvent must originate from a pointer event
28517  return pointerEvent.isPrimary && pointerEvent.button === 0;
28518};
28519
28520;// CONCATENATED MODULE: ./node_modules/ol/interaction/DragPan.js
28521/**
28522 * @module ol/interaction/DragPan
28523 */
28524
28525
28526
28527
28528
28529
28530/**
28531 * @typedef {Object} Options
28532 * @property {import("../events/condition.js").Condition} [condition] A function that takes an {@link module:ol/MapBrowserEvent~MapBrowserEvent} and returns a boolean
28533 * to indicate whether that event should be handled.
28534 * Default is {@link module:ol/events/condition.noModifierKeys}
28534 and {@link module:ol/events/condition.primaryAction}.
28535 * @property {boolean} [onFocusOnly=false] When the map's target has a `tabindex` attribute set,
28536 * the interaction will only handle events when the map has the focus.
28537 * @property {import("../Kinetic.js").default} [kinetic] Kinetic inertia to apply to the pan.
28538 */
28539
28540/**
28541 * @classdesc
28542 * Allows the user to pan the map by dragging the map.
28543 * @api
28544 */
28545class DragPan extends Pointer {
28546  /**
28547   * @param {Options} [options] Options.
28548   */
28549  constructor(options) {
28550    super({
28551      stopDown: functions_FALSE,
28552    });
28553
28554    options = options ? options : {};
28555
28556    /**
28557     * @private
28558     * @type {import("../Kinetic.js").default|undefined}
28559     */
28560    this.kinetic_ = options.kinetic;
28561
28562    /**
28563     * @type {import("../pixel.js").Pixel}
28564     */
28565    this.lastCentroid = null;
28566
28567    /**
28568     * @type {number}
28569     */
28570    this.lastPointersCount_;
28571
28572    /**
28573     * @type {boolean}
28574     */
28575    this.panning_ = false;
28576
28577    const condition = options.condition
28578      ? options.condition
28579      : condition_all(noModifierKeys, primaryAction);
28580
28581    /**
28582     * @private
28583     * @type {import("../events/condition.js").Condition}
28584     */
28585    this.condition_ = options.onFocusOnly
28586      ? condition_all(focusWithTabindex, condition)
28587      : condition;
28588
28589    /**
28590     * @private
28591     * @type {boolean}
28592     */
28593    this.noKinetic_ = false;
28594  }
28595
28596  /**
28597   * Handle pointer drag events.
28598   * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.
28599   */
28600  handleDragEvent(mapBrowserEvent) {
28601    if (!this.panning_) {
28602      this.panning_ = true;
28603      this.getMap().getView().beginInteraction();
28604    }
28605    const targetPointers = this.targetPointers;
28606    const centroid = Pointer_centroid(targetPointers);
28607    if (targetPointers.length == this.lastPointersCount_) {
28608      if (this.kinetic_) {
28609        this.kinetic_.update(centroid[0], centroid[1]);
28610      }
28611      if (this.lastCentroid) {
28612        const delta = [
28613          this.lastCentroid[0] - centroid[0],
28614          centroid[1] - this.lastCentroid[1],
28615        ];
28616        const map = mapBrowserEvent.map;
28617        const view = map.getView();
28618        scale(delta, view.getResolution());
28619        rotate(delta, view.getRotation());
28620        view.adjustCenterInternal(delta);
28621      }
28622    } else if (this.kinetic_) {
28623      // reset so we don't overestimate the kinetic energy after
28624      // after one finger down, tiny drag, second finger down
28625      this.kinetic_.begin();
28626    }
28627    this.lastCentroid = centroid;
28628    this.lastPointersCount_ = targetPointers.length;
28629    mapBrowserEvent.originalEvent.preventDefault();
28630  }
28631
28632  /**
28633   * Handle pointer up events.
28634   * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.
28635   * @return {boolean} If the event was consumed.
28636   */
28637  handleUpEvent(mapBrowserEvent) {
28638    const map = mapBrowserEvent.map;
28639    const view = map.getView();
28640    if (this.targetPointers.length === 0) {
28641      if (!this.noKinetic_ && this.kinetic_ && this.kinetic_.end()) {
28642        const distance = this.kinetic_.getDistance();
28643        const angle = this.kinetic_.getAngle();
28644        const center = view.getCenterInternal();
28645        const centerpx = map.getPixelFromCoordinateInternal(center);
28646        const dest = map.getCoordinateFromPixelInternal([
28647          centerpx[0] - distance * Math.cos(angle),
28648          centerpx[1] - distance * Math.sin(angle),
28649        ]);
28650        view.animateInternal({
28651          center: view.getConstrainedCenter(dest),
28652          duration: 500,
28653          easing: easeOut,
28654        });
28655      }
28656      if (this.panning_) {
28657        this.panning_ = false;
28658        view.endInteraction();
28659      }
28660      return false;
28661    } else {
28662      if (this.kinetic_) {
28663        // reset so we don't overestimate the kinetic energy after
28664        // after one finger up, tiny drag, second finger up
28665        this.kinetic_.begin();
28666      }
28667      this.lastCentroid = null;
28668      return true;
28669    }
28670  }
28671
28672  /**
28673   * Handle pointer down events.
28674   * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.
28675   * @return {boolean} If the event was consumed.
28676   */
28677  handleDownEvent(mapBrowserEvent) {
28678    if (this.targetPointers.length > 0 && this.condition_(mapBrowserEvent)) {
28679      const map = mapBrowserEvent.map;
28680      const view = map.getView();
28681      this.lastCentroid = null;
28682      // stop any current animation
28683      if (view.getAnimating()) {
28684        view.cancelAnimations();
28685      }
28686      if (this.kinetic_) {
28687        this.kinetic_.begin();
28688      }
28689      // No kinetic as soon as more than one pointer on the screen is
28690      // detected. This is to prevent nasty pans after pinch.
28691      this.noKinetic_ = this.targetPointers.length > 1;
28692      return true;
28693    } else {
28694      return false;
28695    }
28696  }
28697}
28698
28699/* harmony default export */ const interaction_DragPan = (DragPan);
28700
28701;// CONCATENATED MODULE: ./node_modules/ol/interaction/DragRotate.js
28702/**
28703 * @module ol/interaction/DragRotate
28704 */
28705
28706
28707
28708
28709
28710/**
28711 * @typedef {Object} Options
28712 * @property {import("../events/condition.js").Condition} [condition] A function that takes an
28713 * {@link module:ol/MapBrowserEvent~MapBrowserEvent} and returns a boolean
28714 * to indicate whether that event should be handled.
28715 * Default is {@link module:ol/events/condition.altShiftKeysOnly}.
28716 * @property {number} [duration=250] Animation duration in milliseconds.
28717 */
28718
28719/**
28720 * @classdesc
28721 * Allows the user to rotate the map by clicking and dragging on the map,
28722 * normally combined with an {@link module:ol/events/condition} that limits
28723 * it to when the alt and shift keys are held down.
28724 *
28725 * This interaction is only supported for mouse devices.
28726 * @api
28727 */
28728class DragRotate extends Pointer {
28729  /**
28730   * @param {Options} [options] Options.
28731   */
28732  constructor(options) {
28733    options = options ? options : {};
28734
28735    super({
28736      stopDown: functions_FALSE,
28737    });
28738
28739    /**
28740     * @private
28741     * @type {import("../events/condition.js").Condition}
28742     */
28743    this.condition_ = options.condition ? options.condition : altShiftKeysOnly;
28744
28745    /**
28746     * @private
28747     * @type {number|undefined}
28748     */
28749    this.lastAngle_ = undefined;
28750
28751    /**
28752     * @private
28753     * @type {number}
28754     */
28755    this.duration_ = options.duration !== undefined ? options.duration : 250;
28756  }
28757
28758  /**
28759   * Handle pointer drag events.
28760   * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.
28761   */
28762  handleDragEvent(mapBrowserEvent) {
28763    if (!mouseOnly(mapBrowserEvent)) {
28764      return;
28765    }
28766
28767    const map = mapBrowserEvent.map;
28768    const view = map.getView();
28769    if (view.getConstraints().rotation === disable) {
28770      return;
28771    }
28772    const size = map.getSize();
28773    const offset = mapBrowserEvent.pixel;
28774    const theta = Math.atan2(size[1] / 2 - offset[1], offset[0] - size[0] / 2);
28775    if (this.lastAngle_ !== undefined) {
28776      const delta = theta - this.lastAngle_;
28777      view.adjustRotationInternal(-delta);
28778    }
28779    this.lastAngle_ = theta;
28780  }
28781
28782  /**
28783   * Handle pointer up events.
28784   * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.
28785   * @return {boolean} If the event was consumed.
28786   */
28787  handleUpEvent(mapBrowserEvent) {
28788    if (!mouseOnly(mapBrowserEvent)) {
28789      return true;
28790    }
28791
28792    const map = mapBrowserEvent.map;
28793    const view = map.getView();
28794    view.endInteraction(this.duration_);
28795    return false;
28796  }
28797
28798  /**
28799   * Handle pointer down events.
28800   * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.
28801   * @return {boolean} If the event was consumed.
28802   */
28803  handleDownEvent(mapBrowserEvent) {
28804    if (!mouseOnly(mapBrowserEvent)) {
28805      return false;
28806    }
28807
28808    if (
28809      mouseActionButton(mapBrowserEvent) &&
28810      this.condition_(mapBrowserEvent)
28811    ) {
28812      const map = mapBrowserEvent.map;
28813      map.getView().beginInteraction();
28814      this.lastAngle_ = undefined;
28815      return true;
28816    } else {
28817      return false;
28818    }
28819  }
28820}
28821
28822/* harmony default export */ const interaction_DragRotate = (DragRotate);
28823
28824;// CONCATENATED MODULE: ./node_modules/ol/render/Box.js
28825/**
28826 * @module ol/render/Box
28827 */
28828
28829
28830
28831
28832class RenderBox extends ol_Disposable {
28833  /**
28834   * @param {string} className CSS class name.
28835   */
28836  constructor(className) {
28837    super();
28838
28839    /**
28840     * @type {import("../geom/Polygon.js").default}
28841     * @private
28842     */
28843    this.geometry_ = null;
28844
28845    /**
28846     * @type {HTMLDivElement}
28847     * @private
28848     */
28849    this.element_ = document.createElement('div');
28850    this.element_.style.position = 'absolute';
28851    this.element_.style.pointerEvents = 'auto';
28852    this.element_.className = 'ol-box ' + className;
28853
28854    /**
28855     * @private
28856     * @type {import("../Map.js").default|null}
28857     */
28858    this.map_ = null;
28859
28860    /**
28861     * @private
28862     * @type {import("../pixel.js").Pixel}
28863     */
28864    this.startPixel_ = null;
28865
28866    /**
28867     * @private
28868     * @type {import("../pixel.js").Pixel}
28869     */
28870    this.endPixel_ = null;
28871  }
28872
28873  /**
28874   * Clean up.
28875   */
28876  disposeInternal() {
28877    this.setMap(null);
28878  }
28879
28880  /**
28881   * @private
28882   */
28883  render_() {
28884    const startPixel = this.startPixel_;
28885    const endPixel = this.endPixel_;
28886    const px = 'px';
28887    const style = this.element_.style;
28888    style.left = Math.min(startPixel[0], endPixel[0]) + px;
28889    style.top = Math.min(startPixel[1], endPixel[1]) + px;
28890    style.width = Math.abs(endPixel[0] - startPixel[0]) + px;
28891    style.height = Math.abs(endPixel[1] - startPixel[1]) + px;
28892  }
28893
28894  /**
28895   * @param {import("../Map.js").default|null} map Map.
28896   */
28897  setMap(map) {
28898    if (this.map_) {
28899      this.map_.getOverlayContainer().removeChild(this.element_);
28900      const style = this.element_.style;
28901      style.left = 'inherit';
28902      style.top = 'inherit';
28903      style.width = 'inherit';
28904      style.height = 'inherit';
28905    }
28906    this.map_ = map;
28907    if (this.map_) {
28908      this.map_.getOverlayContainer().appendChild(this.element_);
28909    }
28910  }
28911
28912  /**
28913   * @param {import("../pixel.js").Pixel} startPixel Start pixel.
28914   * @param {import("../pixel.js").Pixel} endPixel End pixel.
28915   */
28916  setPixels(startPixel, endPixel) {
28917    this.startPixel_ = startPixel;
28918    this.endPixel_ = endPixel;
28919    this.createOrUpdateGeometry();
28920    this.render_();
28921  }
28922
28923  /**
28924   * Creates or updates the cached geometry.
28925   */
28926  createOrUpdateGeometry() {
28927    const startPixel = this.startPixel_;
28928    const endPixel = this.endPixel_;
28929    const pixels = [
28930      startPixel,
28931      [startPixel[0], endPixel[1]],
28932      endPixel,
28933      [endPixel[0], startPixel[1]],
28934    ];
28935    const coordinates = pixels.map(
28936      this.map_.getCoordinateFromPixelInternal,
28937      this.map_
28938    );
28939    // close the polygon
28940    coordinates[4] = coordinates[0].slice();
28941    if (!this.geometry_) {
28942      this.geometry_ = new geom_Polygon([coordinates]);
28943    } else {
28944      this.geometry_.setCoordinates([coordinates]);
28945    }
28946  }
28947
28948  /**
28949   * @return {import("../geom/Polygon.js").default} Geometry.
28950   */
28951  getGeometry() {
28952    return this.geometry_;
28953  }
28954}
28955
28956/* harmony default export */ const Box = (RenderBox);
28957
28958;// CONCATENATED MODULE: ./node_modules/ol/interaction/DragBox.js
28959/**
28960 * @module ol/interaction/DragBox
28961 */
28962// FIXME draw drag box
28963
28964
28965
28966
28967
28968/**
28969 * A function that takes a {@link module:ol/MapBrowserEvent~MapBrowserEvent} and two
28970 * {@link module:ol/pixel~Pixel}s and returns a `{boolean}`. If the condition is met,
28971 * true should be returned.
28972 * @typedef {function(this: ?, import("../MapBrowserEvent.js").default, import("../pixel.js").Pixel, import("../pixel.js").Pixel):boolean} EndCondition
28973 */
28974
28975/**
28976 * @typedef {Object} Options
28977 * @property {string} [className='ol-dragbox'] CSS class name for styling the box.
28978 * @property {import("../events/condition.js").Condition} [condition] A function that takes an {@link module:ol/MapBrowserEvent~MapBrowserEvent} and returns a boolean
28979 * to indicate whether that event should be handled.
28980 * Default is {@link ol/events/condition~mouseActionButton}.
28981 * @property {number} [minArea=64] The minimum area of the box in pixel, this value is used by the default
28982 * `boxEndCondition` function.
28983 * @property {EndCondition} [boxEndCondition] A function that takes a {@link module:ol/MapBrowserEvent~MapBrowserEvent} and two
28984 * {@link module:ol/pixel~Pixel}s to indicate whether a `boxend` event should be fired.
28985 * Default is `true` if the area of the box is bigger than the `minArea` option.
28986 * @property {function(this:DragBox, import("../MapBrowserEvent.js").default):void} [onBoxEnd] Code to execute just
28987 * before `boxend` is fired.
28988 */
28989
28990/**
28991 * @enum {string}
28992 */
28993const DragBoxEventType = {
28994  /**
28995   * Triggered upon drag box start.
28996   * @event DragBoxEvent#boxstart
28997   * @api
28998   */
28999  BOXSTART: 'boxstart',
29000
29001  /**
29002   * Triggered on drag when box is active.
29003   * @event DragBoxEvent#boxdrag
29004   * @api
29005   */
29006  BOXDRAG: 'boxdrag',
29007
29008  /**
29009   * Triggered upon drag box end.
29010   * @event DragBoxEvent#boxend
29011   * @api
29012   */
29013  BOXEND: 'boxend',
29014
29015  /**
29016   * Triggered upon drag box canceled.
29017   * @event DragBoxEvent#boxcancel
29018   * @api
29019   */
29020  BOXCANCEL: 'boxcancel',
29021};
29022
29023/**
29024 * @classdesc
29025 * Events emitted by {@link module:ol/interaction/DragBox~DragBox} instances are instances of
29026 * this type.
29027 */
29028class DragBoxEvent extends Event {
29029  /**
29030   * @param {string} type The event type.
29031   * @param {import("../coordinate.js").Coordinate} coordinate The event coordinate.
29032   * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Originating event.
29033   */
29034  constructor(type, coordinate, mapBrowserEvent) {
29035    super(type);
29036
29037    /**
29038     * The coordinate of the drag event.
29039     * @const
29040     * @type {import("../coordinate.js").Coordinate}
29041     * @api
29042     */
29043    this.coordinate = coordinate;
29044
29045    /**
29046     * @const
29047     * @type {import("../MapBrowserEvent.js").default}
29048     * @api
29049     */
29050    this.mapBrowserEvent = mapBrowserEvent;
29051  }
29052}
29053
29054/***
29055 * @template Return
29056 * @typedef {import("../Observable").OnSignature<import("../Observable").EventTypes, import("../events/Event.js").default, Return> &
29057 *   import("../Observable").OnSignature<import("../ObjectEventType").Types|
29058 *     'change:active', import("../Object").ObjectEvent, Return> &
29059 *   import("../Observable").OnSignature<'boxcancel'|'boxdrag'|'boxend'|'boxstart', DragBoxEvent, Return> &
29060 *   import("../Observable").CombinedOnSignature<import("../Observable").EventTypes|import("../ObjectEventType").Types|
29061 *     'change:active'|'boxcancel'|'boxdrag'|'boxend', Return>} DragBoxOnSignature
29062 */
29063
29064/**
29065 * @classdesc
29066 * Allows the user to draw a vector box by clicking and dragging on the map,
29067 * normally combined with an {@link module:ol/events/condition} that limits
29068 * it to when the shift or other key is held down. This is used, for example,
29069 * for zooming to a specific area of the map
29070 * (see {@link module:ol/interaction/DragZoom~DragZoom} and
29071 * {@link module:ol/interaction/DragRotateAndZoom~DragRotateAndZoom}).
29072 *
29073 * @fires DragBoxEvent
29074 * @api
29075 */
29076class DragBox extends Pointer {
29077  /**
29078   * @param {Options} [options] Options.
29079   */
29080  constructor(options) {
29081    super();
29082
29083    /***
29084     * @type {DragBoxOnSignature<import("../events").EventsKey>}
29085     */
29086    this.on;
29087
29088    /***
29089     * @type {DragBoxOnSignature<import("../events").EventsKey>}
29090     */
29091    this.once;
29092
29093    /***
29094     * @type {DragBoxOnSignature<void>}
29095     */
29096    this.un;
29097
29098    options = options ? options : {};
29099
29100    /**
29101     * @type {import("../render/Box.js").default}
29102     * @private
29103     */
29104    this.box_ = new Box(options.className || 'ol-dragbox');
29105
29106    /**
29107     * @type {number}
29108     * @private
29109     */
29110    this.minArea_ = options.minArea !== undefined ? options.minArea : 64;
29111
29112    if (options.onBoxEnd) {
29113      this.onBoxEnd = options.onBoxEnd;
29114    }
29115
29116    /**
29117     * @type {import("../pixel.js").Pixel}
29118     * @private
29119     */
29120    this.startPixel_ = null;
29121
29122    /**
29123     * @private
29124     * @type {import("../events/condition.js").Condition}
29125     */
29126    this.condition_ = options.condition ? options.condition : mouseActionButton;
29127
29128    /**
29129     * @private
29130     * @type {EndCondition}
29131     */
29132    this.boxEndCondition_ = options.boxEndCondition
29133      ? options.boxEndCondition
29134      : this.defaultBoxEndCondition;
29135  }
29136
29137  /**
29138   * The default condition for determining whether the boxend event
29139   * should fire.
29140   * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent The originating MapBrowserEvent
29141   *     leading to the box end.
29142   * @param {import("../pixel.js").Pixel} startPixel The starting pixel of the box.
29143   * @param {import("../pixel.js").Pixel} endPixel The end pixel of the box.
29144   * @return {boolean} Whether or not the boxend condition should be fired.
29145   */
29146  defaultBoxEndCondition(mapBrowserEvent, startPixel, endPixel) {
29147    const width = endPixel[0] - startPixel[0];
29148    const height = endPixel[1] - startPixel[1];
29149    return width * width + height * height >= this.minArea_;
29150  }
29151
29152  /**
29153   * Returns geometry of last drawn box.
29154   * @return {import("../geom/Polygon.js").default} Geometry.
29155   * @api
29156   */
29157  getGeometry() {
29158    return this.box_.getGeometry();
29159  }
29160
29161  /**
29162   * Handle pointer drag events.
29163   * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.
29164   */
29165  handleDragEvent(mapBrowserEvent) {
29166    this.box_.setPixels(this.startPixel_, mapBrowserEvent.pixel);
29167
29168    this.dispatchEvent(
29169      new DragBoxEvent(
29170        DragBoxEventType.BOXDRAG,
29171        mapBrowserEvent.coordinate,
29172        mapBrowserEvent
29173      )
29174    );
29175  }
29176
29177  /**
29178   * Handle pointer up events.
29179   * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.
29180   * @return {boolean} If the event was consumed.
29181   */
29182  handleUpEvent(mapBrowserEvent) {
29183    this.box_.setMap(null);
29184
29185    const completeBox = this.boxEndCondition_(
29186      mapBrowserEvent,
29187      this.startPixel_,
29188      mapBrowserEvent.pixel
29189    );
29190    if (completeBox) {
29191      this.onBoxEnd(mapBrowserEvent);
29192    }
29193    this.dispatchEvent(
29194      new DragBoxEvent(
29195        completeBox ? DragBoxEventType.BOXEND : DragBoxEventType.BOXCANCEL,
29196        mapBrowserEvent.coordinate,
29197        mapBrowserEvent
29198      )
29199    );
29200    return false;
29201  }
29202
29203  /**
29204   * Handle pointer down events.
29205   * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.
29206   * @return {boolean} If the event was consumed.
29207   */
29208  handleDownEvent(mapBrowserEvent) {
29209    if (this.condition_(mapBrowserEvent)) {
29210      this.startPixel_ = mapBrowserEvent.pixel;
29211      this.box_.setMap(mapBrowserEvent.map);
29212      this.box_.setPixels(this.startPixel_, this.startPixel_);
29213      this.dispatchEvent(
29214        new DragBoxEvent(
29215          DragBoxEventType.BOXSTART,
29216          mapBrowserEvent.coordinate,
29217          mapBrowserEvent
29218        )
29219      );
29220      return true;
29221    } else {
29222      return false;
29223    }
29224  }
29225
29226  /**
29227   * Function to execute just before `onboxend` is fired
29228   * @param {import("../MapBrowserEvent.js").default} event Event.
29229   */
29230  onBoxEnd(event) {}
29231}
29232
29233/* harmony default export */ const interaction_DragBox = (DragBox);
29234
29235;// CONCATENATED MODULE: ./node_modules/ol/interaction/DragZoom.js
29236/**
29237 * @module ol/interaction/DragZoom
29238 */
29239
29240
29241
29242
29243/**
29244 * @typedef {Object} Options
29245 * @property {string} [className='ol-dragzoom'] CSS class name for styling the
29246 * box.
29247 * @property {import("../events/condition.js").Condition} [condition] A function that
29248 * takes an {@link module:ol/MapBrowserEvent~MapBrowserEvent} and returns a
29249 * boolean to indicate whether that event should be handled.
29250 * Default is {@link module:ol/events/condition.shiftKeyOnly}.
29251 * @property {number} [duration=200] Animation duration in milliseconds.
29252 * @property {boolean} [out=false] Use interaction for zooming out.
29253 * @property {number} [minArea=64] The minimum area of the box in pixel, this value is used by the parent default
29254 * `boxEndCondition` function.
29255 */
29256
29257/**
29258 * @classdesc
29259 * Allows the user to zoom the map by clicking and dragging on the map,
29260 * normally combined with an {@link module:ol/events/condition} that limits
29261 * it to when a key, shift by default, is held down.
29262 *
29263 * To change the style of the box, use CSS and the `.ol-dragzoom` selector, or
29264 * your custom one configured with `className`.
29265 * @api
29266 */
29267class DragZoom extends interaction_DragBox {
29268  /**
29269   * @param {Options} [options] Options.
29270   */
29271  constructor(options) {
29272    options = options ? options : {};
29273
29274    const condition = options.condition ? options.condition : shiftKeyOnly;
29275
29276    super({
29277      condition: condition,
29278      className: options.className || 'ol-dragzoom',
29279      minArea: options.minArea,
29280    });
29281
29282    /**
29283     * @private
29284     * @type {number}
29285     */
29286    this.duration_ = options.duration !== undefined ? options.duration : 200;
29287
29288    /**
29289     * @private
29290     * @type {boolean}
29291     */
29292    this.out_ = options.out !== undefined ? options.out : false;
29293  }
29294
29295  /**
29296   * Function to execute just before `onboxend` is fired
29297   * @param {import("../MapBrowserEvent.js").default} event Event.
29298   */
29299  onBoxEnd(event) {
29300    const map = this.getMap();
29301    const view = /** @type {!import("../View.js").default} */ (map.getView());
29302    let geometry = this.getGeometry();
29303
29304    if (this.out_) {
29305      const rotatedExtent = view.rotatedExtentForGeometry(geometry);
29306      const resolution = view.getResolutionForExtentInternal(rotatedExtent);
29307      const factor = view.getResolution() / resolution;
29308      geometry = geometry.clone();
29309      geometry.scale(factor * factor);
29310    }
29311
29312    view.fitInternal(geometry, {
29313      duration: this.duration_,
29314      easing: easeOut,
29315    });
29316  }
29317}
29318
29319/* harmony default export */ const interaction_DragZoom = (DragZoom);
29320
29321;// CONCATENATED MODULE: ./node_modules/ol/events/KeyCode.js
29322/**
29323 * @module ol/events/KeyCode
29324 */
29325
29326/**
29327 * @enum {number}
29328 * @const
29329 */
29330/* harmony default export */ const KeyCode = ({
29331  LEFT: 37,
29332  UP: 38,
29333  RIGHT: 39,
29334  DOWN: 40,
29335});
29336
29337;// CONCATENATED MODULE: ./node_modules/ol/interaction/KeyboardPan.js
29338/**
29339 * @module ol/interaction/KeyboardPan
29340 */
29341
29342
29343
29344
29345
29346
29347/**
29348 * @typedef {Object} Options
29349 * @property {import("../events/condition.js").Condition} [condition] A function that
29350 * takes an {@link module:ol/MapBrowserEvent~MapBrowserEvent} and returns a
29351 * boolean to indicate whether that event should be handled. Default is
29352 * {@link module:ol/events/condition.noModifierKeys} and
29353 * {@link module:ol/events/condition.targetNotEditable}.
29354 * @property {number} [duration=100] Animation duration in milliseconds.
29355 * @property {number} [pixelDelta=128] The amount of pixels to pan on each key
29356 * press.
29357 */
29358
29359/**
29360 * @classdesc
29361 * Allows the user to pan the map using keyboard arrows.
29362 * Note that, although this interaction is by default included in maps,
29363 * the keys can only be used when browser focus is on the element to which
29364 * the keyboard events are attached. By default, this is the map div,
29365 * though you can change this with the `keyboardEventTarget` in
29366 * {@link module:ol/Map~Map}. `document` never loses focus but, for any other
29367 * element, focus will have to be on, and returned to, this element if the keys
29368 * are to function.
29369 * See also {@link module:ol/interaction/KeyboardZoom~KeyboardZoom}.
29370 * @api
29371 */
29372class KeyboardPan extends interaction_Interaction {
29373  /**
29374   * @param {Options} [options] Options.
29375   */
29376  constructor(options) {
29377    super();
29378
29379    options = options || {};
29380
29381    /**
29382     * @private
29383     * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Browser event.
29384     * @return {boolean} Combined condition result.
29385     */
29386    this.defaultCondition_ = function (mapBrowserEvent) {
29387      return (
29388        noModifierKeys(mapBrowserEvent) && targetNotEditable(mapBrowserEvent)
29389      );
29390    };
29391
29392    /**
29393     * @private
29394     * @type {import("../events/condition.js").Condition}
29395     */
29396    this.condition_ =
29397      options.condition !== undefined
29398        ? options.condition
29399        : this.defaultCondition_;
29400
29401    /**
29402     * @private
29403     * @type {number}
29404     */
29405    this.duration_ = options.duration !== undefined ? options.duration : 100;
29406
29407    /**
29408     * @private
29409     * @type {number}
29410     */
29411    this.pixelDelta_ =
29412      options.pixelDelta !== undefined ? options.pixelDelta : 128;
29413  }
29414
29415  /**
29416   * Handles the {@link module:ol/MapBrowserEvent~MapBrowserEvent map browser event} if it was a
29417   * `KeyEvent`, and decides the direction to pan to (if an arrow key was
29418   * pressed).
29419   * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.
29420   * @return {boolean} `false` to stop event propagation.
29421   * @this {KeyboardPan}
29422   */
29423  handleEvent(mapBrowserEvent) {
29424    let stopEvent = false;
29425    if (mapBrowserEvent.type == EventType.KEYDOWN) {
29426      const keyEvent = /** @type {KeyboardEvent} */ (
29427        mapBrowserEvent.originalEvent
29428      );
29429      const keyCode = keyEvent.keyCode;
29430      if (
29431        this.condition_(mapBrowserEvent) &&
29432        (keyCode == KeyCode.DOWN ||
29433          keyCode == KeyCode.LEFT ||
29434          keyCode == KeyCode.RIGHT ||
29435          keyCode == KeyCode.UP)
29436      ) {
29437        const map = mapBrowserEvent.map;
29438        const view = map.getView();
29439        const mapUnitsDelta = view.getResolution() * this.pixelDelta_;
29440        let deltaX = 0,
29441          deltaY = 0;
29442        if (keyCode == KeyCode.DOWN) {
29443          deltaY = -mapUnitsDelta;
29444        } else if (keyCode == KeyCode.LEFT) {
29445          deltaX = -mapUnitsDelta;
29446        } else if (keyCode == KeyCode.RIGHT) {
29447          deltaX = mapUnitsDelta;
29448        } else {
29449          deltaY = mapUnitsDelta;
29450        }
29451        const delta = [deltaX, deltaY];
29452        rotate(delta, view.getRotation());
29453        pan(view, delta, this.duration_);
29454        keyEvent.preventDefault();
29455        stopEvent = true;
29456      }
29457    }
29458    return !stopEvent;
29459  }
29460}
29461
29462/* harmony default export */ const interaction_KeyboardPan = (KeyboardPan);
29463
29464;// CONCATENATED MODULE: ./node_modules/ol/interaction/KeyboardZoom.js
29465/**
29466 * @module ol/interaction/KeyboardZoom
29467 */
29468
29469
29470
29471
29472/**
29473 * @typedef {Object} Options
29474 * @property {number} [duration=100] Animation duration in milliseconds.
29475 * @property {import("../events/condition.js").Condition} [condition] A function that
29476 * takes an {@link module:ol/MapBrowserEvent~MapBrowserEvent} and returns a
29477 * boolean to indicate whether that event should be handled. Default is
29478 * {@link module:ol/events/condition.targetNotEditable}.
29479 * @property {number} [delta=1] The zoom level delta on each key press.
29480 */
29481
29482/**
29483 * @classdesc
29484 * Allows the user to zoom the map using keyboard + and -.
29485 * Note that, although this interaction is by default included in maps,
29486 * the keys can only be used when browser focus is on the element to which
29487 * the keyboard events are attached. By default, this is the map div,
29488 * though you can change this with the `keyboardEventTarget` in
29489 * {@link module:ol/Map~Map}. `document` never loses focus but, for any other
29490 * element, focus will have to be on, and returned to, this element if the keys
29491 * are to function.
29492 * See also {@link module:ol/interaction/KeyboardPan~KeyboardPan}.
29493 * @api
29494 */
29495class KeyboardZoom extends interaction_Interaction {
29496  /**
29497   * @param {Options} [options] Options.
29498   */
29499  constructor(options) {
29500    super();
29501
29502    options = options ? options : {};
29503
29504    /**
29505     * @private
29506     * @type {import("../events/condition.js").Condition}
29507     */
29508    this.condition_ = options.condition ? options.condition : targetNotEditable;
29509
29510    /**
29511     * @private
29512     * @type {number}
29513     */
29514    this.delta_ = options.delta ? options.delta : 1;
29515
29516    /**
29517     * @private
29518     * @type {number}
29519     */
29520    this.duration_ = options.duration !== undefined ? options.duration : 100;
29521  }
29522
29523  /**
29524   * Handles the {@link module:ol/MapBrowserEvent~MapBrowserEvent map browser event} if it was a
29525   * `KeyEvent`, and decides whether to zoom in or out (depending on whether the
29526   * key pressed was '+' or '-').
29527   * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.
29528   * @return {boolean} `false` to stop event propagation.
29529   * @this {KeyboardZoom}
29530   */
29531  handleEvent(mapBrowserEvent) {
29532    let stopEvent = false;
29533    if (
29534      mapBrowserEvent.type == EventType.KEYDOWN ||
29535      mapBrowserEvent.type == EventType.KEYPRESS
29536    ) {
29537      const keyEvent = /** @type {KeyboardEvent} */ (
29538        mapBrowserEvent.originalEvent
29539      );
29540      const charCode = keyEvent.charCode;
29541      if (
29542        this.condition_(mapBrowserEvent) &&
29543        (charCode == '+'.charCodeAt(0) || charCode == '-'.charCodeAt(0))
29544      ) {
29545        const map = mapBrowserEvent.map;
29546        const delta =
29547          charCode == '+'.charCodeAt(0) ? this.delta_ : -this.delta_;
29548        const view = map.getView();
29549        zoomByDelta(view, delta, undefined, this.duration_);
29550        keyEvent.preventDefault();
29551        stopEvent = true;
29552      }
29553    }
29554    return !stopEvent;
29555  }
29556}
29557
29558/* harmony default export */ const interaction_KeyboardZoom = (KeyboardZoom);
29559
29560;// CONCATENATED MODULE: ./node_modules/ol/Kinetic.js
29561/**
29562 * @module ol/Kinetic
29563 */
29564
29565/**
29566 * @classdesc
29567 * Implementation of inertial deceleration for map movement.
29568 *
29569 * @api
29570 */
29571class Kinetic {
29572  /**
29573   * @param {number} decay Rate of decay (must be negative).
29574   * @param {number} minVelocity Minimum velocity (pixels/millisecond).
29575   * @param {number} delay Delay to consider to calculate the kinetic
29576   *     initial values (milliseconds).
29577   */
29578  constructor(decay, minVelocity, delay) {
29579    /**
29580     * @private
29581     * @type {number}
29582     */
29583    this.decay_ = decay;
29584
29585    /**
29586     * @private
29587     * @type {number}
29588     */
29589    this.minVelocity_ = minVelocity;
29590
29591    /**
29592     * @private
29593     * @type {number}
29594     */
29595    this.delay_ = delay;
29596
29597    /**
29598     * @private
29599     * @type {Array<number>}
29600     */
29601    this.points_ = [];
29602
29603    /**
29604     * @private
29605     * @type {number}
29606     */
29607    this.angle_ = 0;
29608
29609    /**
29610     * @private
29611     * @type {number}
29612     */
29613    this.initialVelocity_ = 0;
29614  }
29615
29616  /**
29617   * FIXME empty description for jsdoc
29618   */
29619  begin() {
29620    this.points_.length = 0;
29621    this.angle_ = 0;
29622    this.initialVelocity_ = 0;
29623  }
29624
29625  /**
29626   * @param {number} x X.
29627   * @param {number} y Y.
29628   */
29629  update(x, y) {
29630    this.points_.push(x, y, Date.now());
29631  }
29632
29633  /**
29634   * @return {boolean} Whether we should do kinetic animation.
29635   */
29636  end() {
29637    if (this.points_.length < 6) {
29638      // at least 2 points are required (i.e. there must be at least 6 elements
29639      // in the array)
29640      return false;
29641    }
29642    const delay = Date.now() - this.delay_;
29643    const lastIndex = this.points_.length - 3;
29644    if (this.points_[lastIndex + 2] < delay) {
29645      // the last tracked point is too old, which means that the user stopped
29646      // panning before releasing the map
29647      return false;
29648    }
29649
29650    // get the first point which still falls into the delay time
29651    let firstIndex = lastIndex - 3;
29652    while (firstIndex > 0 && this.points_[firstIndex + 2] > delay) {
29653      firstIndex -= 3;
29654    }
29655
29656    const duration = this.points_[lastIndex + 2] - this.points_[firstIndex + 2];
29657    // we don't want a duration of 0 (divide by zero)
29658    // we also make sure the user panned for a duration of at least one frame
29659    // (1/60s) to compute sane displacement values
29660    if (duration < 1000 / 60) {
29661      return false;
29662    }
29663
29664    const dx = this.points_[lastIndex] - this.points_[firstIndex];
29665    const dy = this.points_[lastIndex + 1] - this.points_[firstIndex + 1];
29666    this.angle_ = Math.atan2(dy, dx);
29667    this.initialVelocity_ = Math.sqrt(dx * dx + dy * dy) / duration;
29668    return this.initialVelocity_ > this.minVelocity_;
29669  }
29670
29671  /**
29672   * @return {number} Total distance travelled (pixels).
29673   */
29674  getDistance() {
29675    return (this.minVelocity_ - this.initialVelocity_) / this.decay_;
29676  }
29677
29678  /**
29679   * @return {number} Angle of the kinetic panning animation (radians).
29680   */
29681  getAngle() {
29682    return this.angle_;
29683  }
29684}
29685
29686/* harmony default export */ const ol_Kinetic = (Kinetic);
29687
29688;// CONCATENATED MODULE: ./node_modules/ol/interaction/MouseWheelZoom.js
29689/**
29690 * @module ol/interaction/MouseWheelZoom
29691 */
29692
29693
29694
29695
29696
29697
29698/**
29699 * @typedef {'trackpad' | 'wheel'} Mode
29700 */
29701
29702/**
29703 * @typedef {Object} Options
29704 * @property {import("../events/condition.js").Condition} [condition] A function that
29705 * takes an {@link module:ol/MapBrowserEvent~MapBrowserEvent} and returns a
29706 * boolean to indicate whether that event should be handled. Default is
29707 * {@link module:ol/events/condition.always}.
29708 * @property {boolean} [onFocusOnly=false] When the map's target has a `tabindex` attribute set,
29709 * the interaction will only handle events when the map has the focus.
29710 * @property {number} [maxDelta=1] Maximum mouse wheel delta.
29711 * @property {number} [duration=250] Animation duration in milliseconds.
29712 * @property {number} [timeout=80] Mouse wheel timeout duration in milliseconds.
29713 * @property {boolean} [useAnchor=true] Enable zooming using the mouse's
29714 * location as the anchor. When set to `false`, zooming in and out will zoom to
29715 * the center of the screen instead of zooming on the mouse's location.
29716 * @property {boolean} [constrainResolution=false] If true, the mouse wheel zoom
29717 * event will always animate to the closest zoom level after an interaction;
29718 * false means intermediary zoom levels are allowed.
29719 */
29720
29721/**
29722 * @classdesc
29723 * Allows the user to zoom the map by scrolling the mouse wheel.
29724 * @api
29725 */
29726class MouseWheelZoom extends interaction_Interaction {
29727  /**
29728   * @param {Options} [options] Options.
29729   */
29730  constructor(options) {
29731    options = options ? options : {};
29732
29733    super(
29734      /** @type {import("./Interaction.js").InteractionOptions} */ (options)
29735    );
29736
29737    /**
29738     * @private
29739     * @type {number}
29740     */
29741    this.totalDelta_ = 0;
29742
29743    /**
29744     * @private
29745     * @type {number}
29746     */
29747    this.lastDelta_ = 0;
29748
29749    /**
29750     * @private
29751     * @type {number}
29752     */
29753    this.maxDelta_ = options.maxDelta !== undefined ? options.maxDelta : 1;
29754
29755    /**
29756     * @private
29757     * @type {number}
29758     */
29759    this.duration_ = options.duration !== undefined ? options.duration : 250;
29760
29761    /**
29762     * @private
29763     * @type {number}
29764     */
29765    this.timeout_ = options.timeout !== undefined ? options.timeout : 80;
29766
29767    /**
29768     * @private
29769     * @type {boolean}
29770     */
29771    this.useAnchor_ =
29772      options.useAnchor !== undefined ? options.useAnchor : true;
29773
29774    /**
29775     * @private
29776     * @type {boolean}
29777     */
29778    this.constrainResolution_ =
29779      options.constrainResolution !== undefined
29780        ? options.constrainResolution
29781        : false;
29782
29783    const condition = options.condition ? options.condition : always;
29784
29785    /**
29786     * @private
29787     * @type {import("../events/condition.js").Condition}
29788     */
29789    this.condition_ = options.onFocusOnly
29790      ? condition_all(focusWithTabindex, condition)
29791      : condition;
29792
29793    /**
29794     * @private
29795     * @type {?import("../coordinate.js").Coordinate}
29796     */
29797    this.lastAnchor_ = null;
29798
29799    /**
29800     * @private
29801     * @type {number|undefined}
29802     */
29803    this.startTime_ = undefined;
29804
29805    /**
29806     * @private
29807     * @type {?}
29808     */
29809    this.timeoutId_;
29810
29811    /**
29812     * @private
29813     * @type {Mode|undefined}
29814     */
29815    this.mode_ = undefined;
29816
29817    /**
29818     * Trackpad events separated by this delay will be considered separate
29819     * interactions.
29820     * @type {number}
29821     */
29822    this.trackpadEventGap_ = 400;
29823
29824    /**
29825     * @type {?}
29826     */
29827    this.trackpadTimeoutId_;
29828
29829    /**
29830     * The number of delta values per zoom level
29831     * @private
29832     * @type {number}
29833     */
29834    this.deltaPerZoom_ = 300;
29835  }
29836
29837  /**
29838   * @private
29839   */
29840  endInteraction_() {
29841    this.trackpadTimeoutId_ = undefined;
29842    const map = this.getMap();
29843    if (!map) {
29844      return;
29845    }
29846    const view = map.getView();
29847    view.endInteraction(
29848      undefined,
29849      this.lastDelta_ ? (this.lastDelta_ > 0 ? 1 : -1) : 0,
29850      this.lastAnchor_
29851    );
29852  }
29853
29854  /**
29855   * Handles the {@link module:ol/MapBrowserEvent~MapBrowserEvent map browser event} (if it was a mousewheel-event) and eventually
29856   * zooms the map.
29857   * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.
29858   * @return {boolean} `false` to stop event propagation.
29859   */
29860  handleEvent(mapBrowserEvent) {
29861    if (!this.condition_(mapBrowserEvent)) {
29862      return true;
29863    }
29864    const type = mapBrowserEvent.type;
29865    if (type !== EventType.WHEEL) {
29866      return true;
29867    }
29868
29869    const map = mapBrowserEvent.map;
29870    const wheelEvent = /** @type {WheelEvent} */ (
29871      mapBrowserEvent.originalEvent
29872    );
29873    wheelEvent.preventDefault();
29874
29875    if (this.useAnchor_) {
29876      this.lastAnchor_ = mapBrowserEvent.coordinate;
29877    }
29878
29879    // Delta normalisation inspired by
29880    // https://github.com/mapbox/mapbox-gl-js/blob/001c7b9/js/ui/handler/scroll_zoom.js
29881    let delta;
29882    if (mapBrowserEvent.type == EventType.WHEEL) {
29883      delta = wheelEvent.deltaY;
29884      if (FIREFOX && wheelEvent.deltaMode === WheelEvent.DOM_DELTA_PIXEL) {
29885        delta /= DEVICE_PIXEL_RATIO;
29886      }
29887      if (wheelEvent.deltaMode === WheelEvent.DOM_DELTA_LINE) {
29888        delta *= 40;
29889      }
29890    }
29891
29892    if (delta === 0) {
29893      return false;
29894    } else {
29895      this.lastDelta_ = delta;
29896    }
29897
29898    const now = Date.now();
29899
29900    if (this.startTime_ === undefined) {
29901      this.startTime_ = now;
29902    }
29903
29904    if (!this.mode_ || now - this.startTime_ > this.trackpadEventGap_) {
29905      this.mode_ = Math.abs(delta) < 4 ? 'trackpad' : 'wheel';
29906    }
29907
29908    const view = map.getView();
29909    if (
29910      this.mode_ === 'trackpad' &&
29911      !(view.getConstrainResolution() || this.constrainResolution_)
29912    ) {
29913      if (this.trackpadTimeoutId_) {
29914        clearTimeout(this.trackpadTimeoutId_);
29915      } else {
29916        if (view.getAnimating()) {
29917          view.cancelAnimations();
29918        }
29919        view.beginInteraction();
29920      }
29921      this.trackpadTimeoutId_ = setTimeout(
29922        this.endInteraction_.bind(this),
29923        this.timeout_
29924      );
29925      view.adjustZoom(-delta / this.deltaPerZoom_, this.lastAnchor_);
29926      this.startTime_ = now;
29927      return false;
29928    }
29929
29930    this.totalDelta_ += delta;
29931
29932    const timeLeft = Math.max(this.timeout_ - (now - this.startTime_), 0);
29933
29934    clearTimeout(this.timeoutId_);
29935    this.timeoutId_ = setTimeout(
29936      this.handleWheelZoom_.bind(this, map),
29937      timeLeft
29938    );
29939
29940    return false;
29941  }
29942
29943  /**
29944   * @private
29945   * @param {import("../Map.js").default} map Map.
29946   */
29947  handleWheelZoom_(map) {
29948    const view = map.getView();
29949    if (view.getAnimating()) {
29950      view.cancelAnimations();
29951    }
29952    let delta =
29953      -math_clamp(
29954        this.totalDelta_,
29955        -this.maxDelta_ * this.deltaPerZoom_,
29956        this.maxDelta_ * this.deltaPerZoom_
29957      ) / this.deltaPerZoom_;
29958    if (view.getConstrainResolution() || this.constrainResolution_) {
29959      // view has a zoom constraint, zoom by 1
29960      delta = delta ? (delta > 0 ? 1 : -1) : 0;
29961    }
29962    zoomByDelta(view, delta, this.lastAnchor_, this.duration_);
29963
29964    this.mode_ = undefined;
29965    this.totalDelta_ = 0;
29966    this.lastAnchor_ = null;
29967    this.startTime_ = undefined;
29968    this.timeoutId_ = undefined;
29969  }
29970
29971  /**
29972   * Enable or disable using the mouse's location as an anchor when zooming
29973   * @param {boolean} useAnchor true to zoom to the mouse's location, false
29974   * to zoom to the center of the map
29975   * @api
29976   */
29977  setMouseAnchor(useAnchor) {
29978    this.useAnchor_ = useAnchor;
29979    if (!useAnchor) {
29980      this.lastAnchor_ = null;
29981    }
29982  }
29983}
29984
29985/* harmony default export */ const interaction_MouseWheelZoom = (MouseWheelZoom);
29986
29987;// CONCATENATED MODULE: ./node_modules/ol/interaction/PinchRotate.js
29988/**
29989 * @module ol/interaction/PinchRotate
29990 */
29991
29992
29993
29994
29995/**
29996 * @typedef {Object} Options
29997 * @property {number} [duration=250] The duration of the animation in
29998 * milliseconds.
29999 * @property {number} [threshold=0.3] Minimal angle in radians to start a rotation.
30000 */
30001
30002/**
30003 * @classdesc
30004 * Allows the user to rotate the map by twisting with two fingers
30005 * on a touch screen.
30006 * @api
30007 */
30008class PinchRotate extends Pointer {
30009  /**
30010   * @param {Options} [options] Options.
30011   */
30012  constructor(options) {
30013    options = options ? options : {};
30014
30015    const pointerOptions = /** @type {import("./Pointer.js").Options} */ (
30016      options
30017    );
30018
30019    if (!pointerOptions.stopDown) {
30020      pointerOptions.stopDown = functions_FALSE;
30021    }
30022
30023    super(pointerOptions);
30024
30025    /**
30026     * @private
30027     * @type {import("../coordinate.js").Coordinate}
30028     */
30029    this.anchor_ = null;
30030
30031    /**
30032     * @private
30033     * @type {number|undefined}
30034     */
30035    this.lastAngle_ = undefined;
30036
30037    /**
30038     * @private
30039     * @type {boolean}
30040     */
30041    this.rotating_ = false;
30042
30043    /**
30044     * @private
30045     * @type {number}
30046     */
30047    this.rotationDelta_ = 0.0;
30048
30049    /**
30050     * @private
30051     * @type {number}
30052     */
30053    this.threshold_ = options.threshold !== undefined ? options.threshold : 0.3;
30054
30055    /**
30056     * @private
30057     * @type {number}
30058     */
30059    this.duration_ = options.duration !== undefined ? options.duration : 250;
30060  }
30061
30062  /**
30063   * Handle pointer drag events.
30064   * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.
30065   */
30066  handleDragEvent(mapBrowserEvent) {
30067    let rotationDelta = 0.0;
30068
30069    const touch0 = this.targetPointers[0];
30070    const touch1 = this.targetPointers[1];
30071
30072    // angle between touches
30073    const angle = Math.atan2(
30074      touch1.clientY - touch0.clientY,
30075      touch1.clientX - touch0.clientX
30076    );
30077
30078    if (this.lastAngle_ !== undefined) {
30079      const delta = angle - this.lastAngle_;
30080      this.rotationDelta_ += delta;
30081      if (!this.rotating_ && Math.abs(this.rotationDelta_) > this.threshold_) {
30082        this.rotating_ = true;
30083      }
30084      rotationDelta = delta;
30085    }
30086    this.lastAngle_ = angle;
30087
30088    const map = mapBrowserEvent.map;
30089    const view = map.getView();
30090    if (view.getConstraints().rotation === disable) {
30091      return;
30092    }
30093
30094    // rotate anchor point.
30095    // FIXME: should be the intersection point between the lines:
30096    //     touch0,touch1 and previousTouch0,previousTouch1
30097    const viewportPosition = map.getViewport().getBoundingClientRect();
30098    const centroid = Pointer_centroid(this.targetPointers);
30099    centroid[0] -= viewportPosition.left;
30100    centroid[1] -= viewportPosition.top;
30101    this.anchor_ = map.getCoordinateFromPixelInternal(centroid);
30102
30103    // rotate
30104    if (this.rotating_) {
30105      map.render();
30106      view.adjustRotationInternal(rotationDelta, this.anchor_);
30107    }
30108  }
30109
30110  /**
30111   * Handle pointer up events.
30112   * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.
30113   * @return {boolean} If the event was consumed.
30114   */
30115  handleUpEvent(mapBrowserEvent) {
30116    if (this.targetPointers.length < 2) {
30117      const map = mapBrowserEvent.map;
30118      const view = map.getView();
30119      view.endInteraction(this.duration_);
30120      return false;
30121    } else {
30122      return true;
30123    }
30124  }
30125
30126  /**
30127   * Handle pointer down events.
30128   * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.
30129   * @return {boolean} If the event was consumed.
30130   */
30131  handleDownEvent(mapBrowserEvent) {
30132    if (this.targetPointers.length >= 2) {
30133      const map = mapBrowserEvent.map;
30134      this.anchor_ = null;
30135      this.lastAngle_ = undefined;
30136      this.rotating_ = false;
30137      this.rotationDelta_ = 0.0;
30138      if (!this.handlingDownUpSequence) {
30139        map.getView().beginInteraction();
30140      }
30141      return true;
30142    } else {
30143      return false;
30144    }
30145  }
30146}
30147
30148/* harmony default export */ const interaction_PinchRotate = (PinchRotate);
30149
30150;// CONCATENATED MODULE: ./node_modules/ol/interaction/PinchZoom.js
30151/**
30152 * @module ol/interaction/PinchZoom
30153 */
30154
30155
30156
30157/**
30158 * @typedef {Object} Options
30159 * @property {number} [duration=400] Animation duration in milliseconds.
30160 */
30161
30162/**
30163 * @classdesc
30164 * Allows the user to zoom the map by pinching with two fingers
30165 * on a touch screen.
30166 * @api
30167 */
30168class PinchZoom extends Pointer {
30169  /**
30170   * @param {Options} [options] Options.
30171   */
30172  constructor(options) {
30173    options = options ? options : {};
30174
30175    const pointerOptions = /** @type {import("./Pointer.js").Options} */ (
30176      options
30177    );
30178
30179    if (!pointerOptions.stopDown) {
30180      pointerOptions.stopDown = functions_FALSE;
30181    }
30182
30183    super(pointerOptions);
30184
30185    /**
30186     * @private
30187     * @type {import("../coordinate.js").Coordinate}
30188     */
30189    this.anchor_ = null;
30190
30191    /**
30192     * @private
30193     * @type {number}
30194     */
30195    this.duration_ = options.duration !== undefined ? options.duration : 400;
30196
30197    /**
30198     * @private
30199     * @type {number|undefined}
30200     */
30201    this.lastDistance_ = undefined;
30202
30203    /**
30204     * @private
30205     * @type {number}
30206     */
30207    this.lastScaleDelta_ = 1;
30208  }
30209
30210  /**
30211   * Handle pointer drag events.
30212   * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.
30213   */
30214  handleDragEvent(mapBrowserEvent) {
30215    let scaleDelta = 1.0;
30216
30217    const touch0 = this.targetPointers[0];
30218    const touch1 = this.targetPointers[1];
30219    const dx = touch0.clientX - touch1.clientX;
30220    const dy = touch0.clientY - touch1.clientY;
30221
30222    // distance between touches
30223    const distance = Math.sqrt(dx * dx + dy * dy);
30224
30225    if (this.lastDistance_ !== undefined) {
30226      scaleDelta = this.lastDistance_ / distance;
30227    }
30228    this.lastDistance_ = distance;
30229
30230    const map = mapBrowserEvent.map;
30231    const view = map.getView();
30232
30233    if (scaleDelta != 1.0) {
30234      this.lastScaleDelta_ = scaleDelta;
30235    }
30236
30237    // scale anchor point.
30238    const viewportPosition = map.getViewport().getBoundingClientRect();
30239    const centroid = Pointer_centroid(this.targetPointers);
30240    centroid[0] -= viewportPosition.left;
30241    centroid[1] -= viewportPosition.top;
30242    this.anchor_ = map.getCoordinateFromPixelInternal(centroid);
30243
30244    // scale, bypass the resolution constraint
30245    map.render();
30246    view.adjustResolutionInternal(scaleDelta, this.anchor_);
30247  }
30248
30249  /**
30250   * Handle pointer up events.
30251   * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.
30252   * @return {boolean} If the event was consumed.
30253   */
30254  handleUpEvent(mapBrowserEvent) {
30255    if (this.targetPointers.length < 2) {
30256      const map = mapBrowserEvent.map;
30257      const view = map.getView();
30258      const direction = this.lastScaleDelta_ > 1 ? 1 : -1;
30259      view.endInteraction(this.duration_, direction);
30260      return false;
30261    } else {
30262      return true;
30263    }
30264  }
30265
30266  /**
30267   * Handle pointer down events.
30268   * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.
30269   * @return {boolean} If the event was consumed.
30270   */
30271  handleDownEvent(mapBrowserEvent) {
30272    if (this.targetPointers.length >= 2) {
30273      const map = mapBrowserEvent.map;
30274      this.anchor_ = null;
30275      this.lastDistance_ = undefined;
30276      this.lastScaleDelta_ = 1;
30277      if (!this.handlingDownUpSequence) {
30278        map.getView().beginInteraction();
30279      }
30280      return true;
30281    } else {
30282      return false;
30283    }
30284  }
30285}
30286
30287/* harmony default export */ const interaction_PinchZoom = (PinchZo
30287om);
30288
30289;// CONCATENATED MODULE: ./node_modules/ol/interaction/defaults.js
30290/**
30291 * @module ol/interaction/defaults
30292 */
30293
30294
30295
30296
30297
30298
30299
30300
30301
30302
30303
30304
30305/**
30306 * @typedef {Object} DefaultsOptions
30307 * @property {boolean} [altShiftDragRotate=true] Whether Alt-Shift-drag rotate is
30308 * desired.
30309 * @property {boolean} [onFocusOnly=false] Interact only when the map has the
30310 * focus. This affects the `MouseWheelZoom` and `DragPan` interactions and is
30311 * useful when page scroll is desired for maps that do not have the browser's
30312 * focus.
30313 * @property {boolean} [doubleClickZoom=true] Whether double click zoom is
30314 * desired.
30315 * @property {boolean} [keyboard=true] Whether keyboard interaction is desired.
30316 * @property {boolean} [mouseWheelZoom=true] Whether mousewheel zoom is desired.
30317 * @property {boolean} [shiftDragZoom=true] Whether Shift-drag zoom is desired.
30318 * @property {boolean} [dragPan=true] Whether drag pan is desired.
30319 * @property {boolean} [pinchRotate=true] Whether pinch rotate is desired.
30320 * @property {boolean} [pinchZoom=true] Whether pinch zoom is desired.
30321 * @property {number} [zoomDelta] Zoom level delta when using keyboard or double click zoom.
30322 * @property {number} [zoomDuration] Duration of the zoom animation in
30323 * milliseconds.
30324 */
30325
30326/**
30327 * Set of interactions included in maps by default. Specific interactions can be
30328 * excluded by setting the appropriate option to false in the constructor
30329 * options, but the order of the interactions is fixed.  If you want to specify
30330 * a different order for interactions, you will need to create your own
30331 * {@link module:ol/interaction/Interaction~Interaction} instances and insert
30332 * them into a {@link module:ol/Collection~Collection} in the order you want
30333 * before creating your {@link module:ol/Map~Map} instance. Changing the order can
30334 * be of interest if the event propagation needs to be stopped at a point.
30335 * The default set of interactions, in sequence, is:
30336 * * {@link module:ol/interaction/DragRotate~DragRotate}
30337 * * {@link module:ol/interaction/DoubleClickZoom~DoubleClickZoom}
30338 * * {@link module:ol/interaction/DragPan~DragPan}
30339 * * {@link module:ol/interaction/PinchRotate~PinchRotate}
30340 * * {@link module:ol/interaction/PinchZoom~PinchZoom}
30341 * * {@link module:ol/interaction/KeyboardPan~KeyboardPan}
30342 * * {@link module:ol/interaction/KeyboardZoom~KeyboardZoom}
30343 * * {@link module:ol/interaction/MouseWheelZoom~MouseWheelZoom}
30344 * * {@link module:ol/interaction/DragZoom~DragZoom}
30345 *
30346 * @param {DefaultsOptions} [options] Defaults options.
30347 * @return {Collection<import("./Interaction.js").default>}
30348 * A collection of interactions to be used with the {@link module:ol/Map~Map}
30349 * constructor's `interactions` option.
30350 * @api
30351 */
30352function defaults_defaults(options) {
30353  options = options ? options : {};
30354
30355  /** @type {Collection<import("./Interaction.js").default>} */
30356  const interactions = new ol_Collection();
30357
30358  const kinetic = new ol_Kinetic(-0.005, 0.05, 100);
30359
30360  const altShiftDragRotate =
30361    options.altShiftDragRotate !== undefined
30362      ? options.altShiftDragRotate
30363      : true;
30364  if (altShiftDragRotate) {
30365    interactions.push(new interaction_DragRotate());
30366  }
30367
30368  const doubleClickZoom =
30369    options.doubleClickZoom !== undefined ? options.doubleClickZoom : true;
30370  if (doubleClickZoom) {
30371    interactions.push(
30372      new interaction_DoubleClickZoom({
30373        delta: options.zoomDelta,
30374        duration: options.zoomDuration,
30375      })
30376    );
30377  }
30378
30379  const dragPan = options.dragPan !== undefined ? options.dragPan : true;
30380  if (dragPan) {
30381    interactions.push(
30382      new interaction_DragPan({
30383        onFocusOnly: options.onFocusOnly,
30384        kinetic: kinetic,
30385      })
30386    );
30387  }
30388
30389  const pinchRotate =
30390    options.pinchRotate !== undefined ? options.pinchRotate : true;
30391  if (pinchRotate) {
30392    interactions.push(new interaction_PinchRotate());
30393  }
30394
30395  const pinchZoom = options.pinchZoom !== undefined ? options.pinchZoom : true;
30396  if (pinchZoom) {
30397    interactions.push(
30398      new interaction_PinchZoom({
30399        duration: options.zoomDuration,
30400      })
30401    );
30402  }
30403
30404  const keyboard = options.keyboard !== undefined ? options.keyboard : true;
30405  if (keyboard) {
30406    interactions.push(new interaction_KeyboardPan());
30407    interactions.push(
30408      new interaction_KeyboardZoom({
30409        delta: options.zoomDelta,
30410        duration: options.zoomDuration,
30411      })
30412    );
30413  }
30414
30415  const mouseWheelZoom =
30416    options.mouseWheelZoom !== undefined ? options.mouseWheelZoom : true;
30417  if (mouseWheelZoom) {
30418    interactions.push(
30419      new interaction_MouseWheelZoom({
30420        onFocusOnly: options.onFocusOnly,
30421        duration: options.zoomDuration,
30422      })
30423    );
30424  }
30425
30426  const shiftDragZoom =
30427    options.shiftDragZoom !== undefined ? options.shiftDragZoom : true;
30428  if (shiftDragZoom) {
30429    interactions.push(
30430      new interaction_DragZoom({
30431        duration: options.zoomDuration,
30432      })
30433    );
30434  }
30435
30436  return interactions;
30437}
30438
30439;// CONCATENATED MODULE: ./node_modules/ol/size.js
30440/**
30441 * @module ol/size
30442 */
30443
30444/**
30445 * An array of numbers representing a size: `[width, height]`.
30446 * @typedef {Array<number>} Size
30447 * @api
30448 */
30449
30450/**
30451 * Returns a buffered size.
30452 * @param {Size} size Size.
30453 * @param {number} num The amount by which to buffer.
30454 * @param {Size} [dest] Optional reusable size array.
30455 * @return {Size} The buffered size.
30456 */
30457function size_buffer(size, num, dest) {
30458  if (dest === undefined) {
30459    dest = [0, 0];
30460  }
30461  dest[0] = size[0] + 2 * num;
30462  dest[1] = size[1] + 2 * num;
30463  return dest;
30464}
30465
30466/**
30467 * Determines if a size has a positive area.
30468 * @param {Size} size The size to test.
30469 * @return {boolean} The size has a positive area.
30470 */
30471function hasArea(size) {
30472  return size[0] > 0 && size[1] > 0;
30473}
30474
30475/**
30476 * Returns a size scaled by a ratio. The result will be an array of integers.
30477 * @param {Size} size Size.
30478 * @param {number} ratio Ratio.
30479 * @param {Size} [dest] Optional reusable size array.
30480 * @return {Size} The scaled size.
30481 */
30482function size_scale(size, ratio, dest) {
30483  if (dest === undefined) {
30484    dest = [0, 0];
30485  }
30486  dest[0] = (size[0] * ratio + 0.5) | 0;
30487  dest[1] = (size[1] * ratio + 0.5) | 0;
30488  return dest;
30489}
30490
30491/**
30492 * Returns an `Size` array for the passed in number (meaning: square) or
30493 * `Size` array.
30494 * (meaning: non-square),
30495 * @param {number|Size} size Width and height.
30496 * @param {Size} [dest] Optional reusable size array.
30497 * @return {Size} Size.
30498 * @api
30499 */
30500function toSize(size, dest) {
30501  if (Array.isArray(size)) {
30502    return size;
30503  } else {
30504    if (dest === undefined) {
30505      dest = [size, size];
30506    } else {
30507      dest[0] = size;
30508      dest[1] = size;
30509    }
30510    return dest;
30511  }
30512}
30513
30514;// CONCATENATED MODULE: ./node_modules/ol/Map.js
30515/**
30516 * @module ol/Map
30517 */
30518
30519
30520
30521
30522
30523
30524
30525
30526
30527
30528
30529
30530
30531
30532
30533
30534
30535
30536
30537
30538
30539
30540
30541
30542
30543
30544
30545
30546
30547
30548
30549
30550/**
30551 * State of the current frame. Only `pixelRatio`, `time` and `viewState` should
30552 * be used in applications.
30553 * @typedef {Object} FrameState
30554 * @property {number} pixelRatio The pixel ratio of the frame.
30555 * @property {number} time The time when rendering of the frame was requested.
30556 * @property {import("./View.js").State} viewState The state of the current view.
30557 * @property {boolean} animate Animate.
30558 * @property {import("./transform.js").Transform} coordinateToPixelTransform CoordinateToPixelTransform.
30559 * @property {import("rbush").default} declutterTree DeclutterTree.
30560 * @property {null|import("./extent.js").Extent} extent Extent.
30561 * @property {import("./extent.js").Extent} [nextExtent] Next extent during an animation series.
30562 * @property {number} index Index.
30563 * @property {Array<import("./layer/Layer.js").State>} layerStatesArray LayerStatesArray.
30564 * @property {number} layerIndex LayerIndex.
30565 * @property {import("./transform.js").Transform} pixelToCoordinateTransform PixelToCoordinateTransform.
30566 * @property {Array<PostRenderFunction>} postRenderFunctions PostRenderFunctions.
30567 * @property {import("./size.js").Size} size Size.
30568 * @property {TileQueue} tileQueue TileQueue.
30569 * @property {!Object<string, Object<string, boolean>>} usedTiles UsedTiles.
30570 * @property {Array<number>} viewHints ViewHints.
30571 * @property {!Object<string, Object<string, boolean>>} wantedTiles WantedTiles.
30572 * @property {string} mapId The id of the map.
30573 * @property {Object<string, boolean>} renderTargets Identifiers of previously rendered elements.
30574 */
30575
30576/**
30577 * @typedef {function(Map, ?FrameState): any} PostRenderFunction
30578 */
30579
30580/**
30581 * @typedef {Object} AtPixelOptions
30582 * @property {undefined|function(import("./layer/Layer.js").default<import("./source/Source").default>): boolean} [layerFilter] Layer filter
30583 * function. The filter function will receive one argument, the
30584 * {@link module:ol/layer/Layer~Layer layer-candidate} and it should return a boolean value.
30585 * Only layers which are visible and for which this function returns `true`
30586 * will be tested for features. By default, all visible layers will be tested.
30587 * @property {number} [hitTolerance=0] Hit-detection tolerance in css pixels. Pixels
30588 * inside the radius around the given position will be checked for features.
30589 * @property {boolean} [checkWrapped=true] Check-Wrapped Will check for wrapped geometries inside the range of
30590 *   +/- 1 world width. Works only if a projection is used that can be wrapped.
30591 */
30592
30593/**
30594 * @typedef {Object} MapOptionsInternal
30595 * @property {Collection<import("./control/Control.js").default>} [controls] Controls.
30596 * @property {Collection<import("./interaction/Interaction.js").default>} [interactions] Interactions.
30597 * @property {HTMLElement|Document} keyboardEventTarget KeyboardEventTarget.
30598 * @property {Collection<import("./Overlay.js").default>} overlays Overlays.
30599 * @property {Object<string, *>} values Values.
30600 */
30601
30602/**
30603 * @typedef {import("./ObjectEventType").Types|'change:layergroup'|'change:size'|'change:target'|'change:view'} MapObjectEventTypes
30604 */
30605
vendor: 8,924 bytes, lines 30606-30864
30606/***
30607 * @template Return
30608 * @typedef {import("./Observable").OnSignature<import("./Observable").EventTypes, import("./events/Event.js").default, Return> &
30609 *    import("./Observable").OnSignature<MapObjectEventTypes, import("./Object").ObjectEvent, Return> &
30610 *    import("./Observable").OnSignature<import("./MapBrowserEventType").Types, import("./MapBrowserEvent").default, Return> &
30611 *    import("./Observable").OnSignature<import("./MapEventType").Types, import("./MapEvent").default, Return> &
30612 *    import("./Observable").OnSignature<import("./render/EventType").MapRenderEventTypes, import("./render/Event").default, Return> &
30613 *    import("./Observable").CombinedOnSignature<import("./Observable").EventTypes|MapObjectEventTypes|
30614 *      import("./MapBrowserEventType").Types|import("./MapEventType").Types|
30615 *      import("./render/EventType").MapRenderEventTypes, Return>} MapEventHandler
30616 */
30617
30618/**
30619 * Object literal with config options for the map.
30620 * @typedef {Object} MapOptions
30621 * @property {Collection<import("./control/Control.js").default>|Array<import("./control/Control.js").default>} [controls]
30622 * Controls initially added to the map. If not specified,
30623 * {@link module:ol/control/defaults.defaults} is used.
30624 * @property {number} [pixelRatio=window.devicePixelRatio] The ratio between
30625 * physical pixels and device-independent pixels (dips) on the device.
30626 * @property {Collection<import("./interaction/Interaction.js").default>|Array<import("./interaction/Interaction.js").default>} [interactions]
30627 * Interactions that are initially added to the map. If not specified,
30628 * {@link module:ol/interaction/defaults.defaults} is used.
30629 * @property {HTMLElement|Document|string} [keyboardEventTarget] The element to
30630 * listen to keyboard events on. This determines when the `KeyboardPan` and
30631 * `KeyboardZoom` interactions trigger. For example, if this option is set to
30632 * `document` the keyboard interactions will always trigger. If this option is
30633 * not specified, the element the library listens to keyboard events on is the
30634 * map target (i.e. the user-provided div for the map). If this is not
30635 * `document`, the target element needs to be focused for key events to be
30636 * emitted, requiring that the target element has a `tabindex` attribute.
30637 * @property {Array<import("./layer/Base.js").default>|Collection<import("./layer/Base.js").default>|LayerGroup} [layers]
30638 * Layers. If this is not defined, a map with no layers will be rendered. Note
30639 * that layers are rendered in the order supplied, so if you want, for example,
30640 * a vector layer to appear on top of a tile layer, it must come after the tile
30641 * layer.
30642 * @property {number} [maxTilesLoading=16] Maximum number tiles to load
30643 * simultaneously.
30644 * @property {number} [moveTolerance=1] The minimum distance in pixels the
30645 * cursor must move to be detected as a map move event instead of a click.
30646 * Increasing this value can make it easier to click on the map.
30647 * @property {Collection<import("./Overlay.js").default>|Array<import("./Overlay.js").default>} [overlays]
30648 * Overlays initially added to the map. By default, no overlays are added.
30649 * @property {HTMLElement|string} [target] The container for the map, either the
30650 * element itself or the `id` of the element. If not specified at construction
30651 * time, {@link module:ol/Map~Map#setTarget} must be called for the map to be
30652 * rendered. If passed by element, the container can be in a secondary document.
30653 * @property {View|Promise<import("./View.js").ViewOptions>} [view] The map's view.  No layer sources will be
30654 * fetched unless this is specified at construction time or through
30655 * {@link module:ol/Map~Map#setView}.
30656 */
30657
30658/**
30659 * @param {import("./layer/Base.js").default} layer Layer.
30660 */
30661function removeLayerMapProperty(layer) {
30662  if (layer instanceof layer_Layer) {
30663    layer.setMapInternal(null);
30664    return;
30665  }
30666  if (layer instanceof Group) {
30667    layer.getLayers().forEach(removeLayerMapProperty);
30668  }
30669}
30670
30671/**
30672 * @param {import("./layer/Base.js").default} layer Layer.
30673 * @param {Map} map Map.
30674 */
30675function setLayerMapProperty(layer, map) {
30676  if (layer instanceof layer_Layer) {
30677    layer.setMapInternal(map);
30678    return;
30679  }
30680  if (layer instanceof Group) {
30681    const layers = layer.getLayers().getArray();
30682    for (let i = 0, ii = layers.length; i < ii; ++i) {
30683      setLayerMapProperty(layers[i], map);
30684    }
30685  }
30686}
30687
30688/**
30689 * @classdesc
30690 * The map is the core component of OpenLayers. For a map to render, a view,
30691 * one or more layers, and a target container are needed:
30692 *
30693 *     import Map from 'ol/Map';
30694 *     import View from 'ol/View';
30695 *     import TileLayer from 'ol/layer/Tile';
30696 *     import OSM from 'ol/source/OSM';
30697 *
30698 *     const map = new Map({
30699 *       view: new View({
30700 *         center: [0, 0],
30701 *         zoom: 1,
30702 *       }),
30703 *       layers: [
30704 *         new TileLayer({
30705 *           source: new OSM(),
30706 *         }),
30707 *       ],
30708 *       target: 'map',
30709 *     });
30710 *
30711 * The above snippet creates a map using a {@link module:ol/layer/Tile~TileLayer} to
30712 * display {@link module:ol/source/OSM~OSM} OSM data and render it to a DOM
30713 * element with the id `map`.
30714 *
30715 * The constructor places a viewport container (with CSS class name
30716 * `ol-viewport`) in the target element (see `getViewport()`), and then two
30717 * further elements within the viewport: one with CSS class name
30718 * `ol-overlaycontainer-stopevent` for controls and some overlays, and one with
30719 * CSS class name `ol-overlaycontainer` for other overlays (see the `stopEvent`
30720 * option of {@link module:ol/Overlay~Overlay} for the difference). The map
30721 * itself is placed in a further element within the viewport.
30722 *
30723 * Layers are stored as a {@link module:ol/Collection~Collection} in
30724 * layerGroups. A top-level group is provided by the library. This is what is
30725 * accessed by `getLayerGroup` and `setLayerGroup`. Layers entered in the
30726 * options are added to this group, and `addLayer` and `removeLayer` change the
30727 * layer collection in the group. `getLayers` is a convenience function for
30728 * `getLayerGroup().getLayers()`. Note that {@link module:ol/layer/Group~LayerGroup}
30729 * is a subclass of {@link module:ol/layer/Base~BaseLayer}, so layers entered in the
30730 * options or added with `addLayer` can be groups, which can contain further
30731 * groups, and so on.
30732 *
30733 * @fires import("./MapBrowserEvent.js").MapBrowserEvent
30734 * @fires import("./MapEvent.js").MapEvent
30735 * @fires import("./render/Event.js").default#precompose
30736 * @fires import("./render/Event.js").default#postcompose
30737 * @fires import("./render/Event.js").default#rendercomplete
30738 * @api
30739 */
30740class Map_Map extends ol_Object {
30741  /**
30742   * @param {MapOptions} [options] Map options.
30743   */
30744  constructor(options) {
30745    super();
30746
30747    options = options || {};
30748
30749    /***
30750     * @type {MapEventHandler<import("./events").EventsKey>}
30751     */
30752    this.on;
30753
30754    /***
30755     * @type {MapEventHandler<import("./events").EventsKey>}
30756     */
30757    this.once;
30758
30759    /***
30760     * @type {MapEventHandler<void>}
30761     */
30762    this.un;
30763
30764    const optionsInternal = createOptionsInternal(options);
30765
30766    /**
30767     * @private
30768     * @type {boolean|undefined}
30769     */
30770    this.renderComplete_;
30771
30772    /**
30773     * @private
30774     * @type {boolean}
30775     */
30776    this.loaded_ = true;
30777
30778    /** @private */
30779    this.boundHandleBrowserEvent_ = this.handleBrowserEvent.bind(this);
30780
30781    /**
30782     * @type {number}
30783     * @private
30784     */
30785    this.maxTilesLoading_ =
30786      options.maxTilesLoading !== undefined ? options.maxTilesLoading : 16;
30787
30788    /**
30789     * @private
30790     * @type {number}
30791     */
30792    this.pixelRatio_ =
30793      options.pixelRatio !== undefined
30794        ? options.pixelRatio
30795        : DEVICE_PIXEL_RATIO;
30796
30797    /**
30798     * @private
30799     * @type {*}
30800     */
30801    this.postRenderTimeoutHandle_;
30802
30803    /**
30804     * @private
30805     * @type {number|undefined}
30806     */
30807    this.animationDelayKey_;
30808
30809    /**
30810     * @private
30811     */
30812    this.animationDelay_ = this.animationDelay_.bind(this);
30813
30814    /**
30815     * @private
30816     * @type {import("./transform.js").Transform}
30817     */
30818    this.coordinateToPixelTransform_ = create();
30819
30820    /**
30821     * @private
30822     * @type {import("./transform.js").Transform}
30823     */
30824    this.pixelToCoordinateTransform_ = create();
30825
30826    /**
30827     * @private
30828     * @type {number}
30829     */
30830    this.frameIndex_ = 0;
30831
30832    /**
30833     * @private
30834     * @type {?FrameState}
30835     */
30836    this.frameState_ = null;
30837
30838    /**
30839     * The extent at the previous 'moveend' event.
30840     * @private
30841     * @type {import("./extent.js").Extent}
30842     */
30843    this.previousExtent_ = null;
30844
30845    /**
30846     * @private
30847     * @type {?import("./events.js").EventsKey}
30848     */
30849    this.viewPropertyListenerKey_ = null;
30850
30851    /**
30852     * @private
30853     * @type {?import("./events.js").EventsKey}
30854     */
30855    this.viewChangeListenerKey_ = null;
30856
30857    /**
30858     * @private
30859     * @type {?Array<import("./events.js").EventsKey>}
30860     */
30861    this.layerGroupPropertyListenerKeys_ = null;
30862
30863    /**
30864     * @private
30865     * @type {!HTMLElement}
30866     */
30867    this.viewport_ = document.createElement('div');
30868    this.viewport_.className =
30869      'ol-viewport' + ('ontouchstart' in window ? ' ol-touch' : '');
30870    this.viewport_.style.position = 'relative';
30871    this.viewport_.style.overflow = 'hidden';
30872    this.viewport_.style.width = '100%';
30873    this.viewport_.style.height = '100%';
30874
30875    /**
30876     * @private
30877     * @type {!HTMLElement}
30878     */
30879    this.overlayContainer_ = document.createElement('div');
30880    this.overlayContainer_.style.position = 'absolute';
30881    this.overlayContainer_.style.zIndex = '0';
30882    this.overlayContainer_.style.width = '100%';
30883    this.overlayContainer_.style.height = '100%';
30884    this.overlayContainer_.style.pointerEvents = 'none';
30885    this.overlayContainer_.className = 'ol-overlaycontainer';
30886    this.viewport_.appendChild(this.overlayContainer_);
30887
30888    /**
30889     * @private
30890     * @type {!HTMLElement}
30891     */
30892    this.overlayContainerStopEvent_ = document.createElement('div');
30893    this.overlayContainerStopEvent_.style.position = 'absolute';
30894    this.overlayContainerStopEvent_.style.zIndex = '0';
30895    this.overlayContainerStopEvent_.style.width = '100%';
30896    this.overlayContainerStopEvent_.style.height = '100%';
30897    this.overlayContainerStopEvent_.style.pointerEvents = 'none';
30898    this.overlayContainerStopEvent_.className = 'ol-overlaycontainer-stopevent';
30899    this.viewport_.appendChild(this.overlayContainerStopEvent_);
30900
30901    /**
30902     * @private
30903     * @type {MapBrowserEventHandler}
30904     */
30905    this.mapBrowserEventHandler_ = null;
30906
30907    /**
30908     * @private
30909     * @type {number}
30910     */
30911    this.moveTolerance_ = options.moveTolerance;
30912
30913    /**
30914     * @private
30915     * @type {HTMLElement|Document}
30916     */
30917    this.keyboardEventTarget_ = optionsInternal.keyboardEventTarget;
30918
30919    /**
30920     * @private
30921     * @type {?Array<import("./events.js").EventsKey>}
30922     */
30923    this.targetChangeHandlerKeys_ = null;
30924
30925    /**
30926     * @type {Collection<import("./control/Control.js").default>}
30927     * @protected
30928     */
30929    this.controls = optionsInternal.controls || defaults();
30930
30931    /**
30932     * @type {Collection<import("./interaction/Interaction.js").default>}
30933     * @protected
30934     */
30935    this.interactions =
30936      optionsInternal.interactions ||
30937      defaults_defaults({
30938        onFocusOnly: true,
30939      });
30940
30941    /**
30942     * @type {Collection<import("./Overlay.js").default>}
30943     * @private
30944     */
30945    this.overlays_ = optionsInternal.overlays;
30946
30947    /**
30948     * A lookup of overlays by id.
30949     * @private
30950     * @type {Object<string, import("./Overlay.js").default>}
30951     */
30952    this.overlayIdIndex_ = {};
30953
30954    /**
30955     * @type {import("./renderer/Map.js").default|null}
30956     * @private
30957     */
30958    this.renderer_ = null;
30959
30960    /**
30961     * @private
30962     * @type {!Array<PostRenderFunction>}
30963     */
30964    this.postRenderFunctions_ = [];
30965
30966    /**
30967     * @private
30968     * @type {TileQueue}
30969     */
30970    this.tileQueue_ = new ol_TileQueue(
30971      this.getTilePriority.bind(this),
30972      this.handleTileChange_.bind(this)
30973    );
30974
30975    this.addChangeListener(
30976      MapProperty.LAYERGROUP,
30977      this.handleLayerGroupChanged_
30978    );
30979    this.addChangeListener(MapProperty.VIEW, this.handleViewChanged_);
30980    this.addChangeListener(MapProperty.SIZE, this.handleSizeChanged_);
30981    this.addChangeListener(MapProperty.TARGET, this.handleTargetChanged_);
30982
30983    // setProperties will trigger the rendering of the map if the map
30984    // is "defined" already.
30985    this.setProperties(optionsInternal.values);
30986
30987    const map = this;
30988    if (options.view && !(options.view instanceof ol_View)) {
30989      options.view.then(function (viewOptions) {
30990        map.setView(new ol_View(viewOptions));
30991      });
30992    }
30993
30994    this.controls.addEventListener(
30995      CollectionEventType.ADD,
30996      /**
30997       * @param {import("./Collection.js").CollectionEvent<import("./control/Control.js").default>} event CollectionEvent
30998       */
30999      function (event) {
31000        event.element.setMap(this);
31001      }.bind(this)
31002    );
31003
31004    this.controls.addEventListener(
31005      CollectionEventType.REMOVE,
31006      /**
31007       * @param {import("./Collection.js").CollectionEvent<import("./control/Control.js").default>} event CollectionEvent.
31008       */
31009      function (event) {
31010        event.element.setMap(null);
31011      }.bind(this)
31012    );
31013
31014    this.interactions.addEventListener(
31015      CollectionEventType.ADD,
31016      /**
31017       * @param {import("./Collection.js").CollectionEvent<import("./interaction/Interaction.js").default>} event CollectionEvent.
31018       */
31019      function (event) {
31020        event.element.setMap(this);
31021      }.bind(this)
31022    );
31023
31024    this.interactions.addEventListener(
31025      CollectionEventType.REMOVE,
31026      /**
31027       * @param {import("./Collection.js").CollectionEvent<import("./interaction/Interaction.js").default>} event CollectionEvent.
31028       */
31029      function (event) {
31030        event.element.setMap(null);
31031      }.bind(this)
31032    );
31033
31034    this.overlays_.addEventListener(
31035      CollectionEventType.ADD,
31036      /**
31037       * @param {import("./Collection.js").CollectionEvent<import("./Overlay.js").default>} event CollectionEvent.
31038       */
31039      function (event) {
31040        this.addOverlayInternal_(event.element);
31041      }.bind(this)
31042    );
31043
31044    this.overlays_.addEventListener(
31045      CollectionEventType.REMOVE,
31046      /**
31047       * @param {import("./Collection.js").CollectionEvent<import("./Overlay.js").default>} event CollectionEvent.
31048       */
31049      function (event) {
31050        const id = event.element.getId();
31051        if (id !== undefined) {
31052          delete this.overlayIdIndex_[id.toString()];
31053        }
31054        event.element.setMap(null);
31055      }.bind(this)
31056    );
31057
31058    this.controls.forEach(
31059      /**
31060       * @param {import("./control/Control.js").default} control Control.
31061       * @this {Map}
31062       */
31063      function (control) {
31064        control.setMap(this);
31065      }.bind(this)
31066    );
31067
31068    this.interactions.forEach(
31069      /**
31070       * @param {import("./interaction/Interaction.js").default} interaction Interaction.
31071       * @this {Map}
31072       */
31073      function (interaction) {
31074        interaction.setMap(this);
31075      }.bind(this)
31076    );
31077
31078    this.overlays_.forEach(this.addOverlayInternal_.bind(this));
31079  }
31080
31081  /**
31082   * Add the given control to the map.
31083   * @param {import("./control/Control.js").default} control Control.
31084   * @api
31085   */
31086  addControl(control) {
31087    this.getControls().push(control);
31088  }
31089
31090  /**
31091   * Add the given interaction to the map. If you want to add an interaction
31092   * at another point of the collection use `getInteractions()` and the methods
31093   * available on {@link module:ol/Collection~Collection}. This can be used to
31094   * stop the event propagation from the handleEvent function. The interactions
31095   * get to handle the events in the reverse order of this collection.
31096   * @param {import("./interaction/Interaction.js").default} interaction Interaction to add.
31097   * @api
31098   */
31099  addInteraction(interaction) {
31100    this.getInteractions().push(interaction);
31101  }
31102
31103  /**
31104   * Adds the given layer to the top of this map. If you want to add a layer
31105   * elsewhere in the stack, use `getLayers()` and the methods available on
31106   * {@link module:ol/Collection~Collection}.
31107   * @param {import("./layer/Base.js").default} layer Layer.
31108   * @api
31109   */
31110  addLayer(layer) {
31111    const layers = this.getLayerGroup().getLayers();
31112    layers.push(layer);
31113  }
31114
31115  /**
31116   * @param {import("./layer/Group.js").GroupEvent} event The layer add event.
31117   * @private
31118   */
31119  handleLayerAdd_(event) {
31120    setLayerMapProperty(event.layer, this);
31121  }
31122
31123  /**
31124   * Add the given overlay to the map.
31125   * @param {import("./Overlay.js").default} overlay Overlay.
31126   * @api
31127   */
31128  addOverlay(overlay) {
31129    this.getOverlays().push(overlay);
31130  }
31131
31132  /**
31133   * This deals with map's overlay collection changes.
31134   * @param {import("./Overlay.js").default} overlay Overlay.
31135   * @private
31136   */
31137  addOverlayInternal_(overlay) {
31138    const id = overlay.getId();
31139    if (id !== undefined) {
31140      this.overlayIdIndex_[id.toString()] = overlay;
31141    }
31142    overlay.setMap(this);
31143  }
31144
31145  /**
31146   *
31147   * Clean up.
31148   */
31149  disposeInternal() {
31150    this.controls.clear();
31151    this.interactions.clear();
31152    this.overlays_.clear();
31153    this.setTarget(null);
31154    super.disposeInternal();
31155  }
31156
31157  /**
31158   * Detect features that intersect a pixel on the viewport, and execute a
31159   * callback with each intersecting feature. Layers included in the detection can
31160   * be configured through the `layerFilter` option in `options`.
31161   * @param {import("./pixel.js").Pixel} pixel Pixel.
31162   * @param {function(import("./Feature.js").FeatureLike, import("./layer/Layer.js").default<import("./source/Source").default>, import("./geom/SimpleGeometry.js").default): T} callback Feature callback. The callback will be
31163   *     called with two arguments. The first argument is one
31164   *     {@link module:ol/Feature~Feature feature} or
31165   *     {@link module:ol/render/Feature~RenderFeature render feature} at the pixel, the second is
31166   *     the {@link module:ol/layer/Layer~Layer layer} of the feature and will be null for
31167   *     unmanaged layers. To stop detection, callback functions can return a
31168   *     truthy value.
31169   * @param {AtPixelOptions} [options] Optional options.
31170   * @return {T|undefined} Callback result, i.e. the return value of last
31171   * callback execution, or the first truthy callback return value.
31172   * @template T
31173   * @api
31174   */
31175  forEachFeatureAtPixel(pixel, callback, options) {
31176    if (!this.frameState_ || !this.renderer_) {
31177      return;
31178    }
31179    const coordinate = this.getCoordinateFromPixelInternal(pixel);
31180    options = options !== undefined ? options : {};
31181    const hitTolerance =
31182      options.hitTolerance !== undefined ? options.hitTolerance : 0;
31183    const layerFilter =
31184      options.layerFilter !== undefined ? options.layerFilter : TRUE;
31185    const checkWrapped = options.checkWrapped !== false;
31186    return this.renderer_.forEachFeatureAtCoordinate(
31187      coordinate,
31188      this.frameState_,
31189      hitTolerance,
31190      checkWrapped,
31191      callback,
31192      null,
31193      layerFilter,
31194      null
31195    );
31196  }
31197
31198  /**
31199   * Get all features that intersect a pixel on the viewport.
31200   * @param {import("./pixel.js").Pixel} pixel Pixel.
31201   * @param {AtPixelOptions} [options] Optional options.
31202   * @return {Array<import("./Feature.js").FeatureLike>} The detected features or
31203   * an empty array if none were found.
31204   * @api
31205   */
31206  getFeaturesAtPixel(pixel, options) {
31207    const features = [];
31208    this.forEachFeatureAtPixel(
31209      pixel,
31210      function (feature) {
31211        features.push(feature);
31212      },
31213      options
31214    );
31215    return features;
31216  }
31217
31218  /**
31219   * Get all layers from all layer groups.
31220   * @return {Array<import("./layer/Layer.js").default>} Layers.
31221   * @api
31222   */
31223  getAllLayers() {
31224    const layers = [];
31225    function addLayersFrom(layerGroup) {
31226      layerGroup.forEach(function (layer) {
31227        if (layer instanceof Group) {
31228          addLayersFrom(layer.getLayers());
31229        } else {
31230          layers.push(layer);
31231        }
31232      });
31233    }
31234    addLayersFrom(this.getLayers());
31235    return layers;
31236  }
31237
31238  /**
31239   * Detect if features intersect a pixel on the viewport. Layers included in the
31240   * detection can be configured through the `layerFilter` option.
31241   * @param {import("./pixel.js").Pixel} pixel Pixel.
31242   * @param {AtPixelOptions} [options] Optional options.
31243   * @return {boolean} Is there a feature at the given pixel?
31244   * @api
31245   */
31246  hasFeatureAtPixel(pixel, options) {
31247    if (!this.frameState_ || !this.renderer_) {
31248      return false;
31249    }
31250    const coordinate = this.getCoordinateFromPixelInternal(pixel);
31251    options = options !== undefined ? options : {};
31252    const layerFilter =
31253      options.layerFilter !== undefined ? options.layerFilter : TRUE;
31254    const hitTolerance =
31255      options.hitTolerance !== undefined ? options.hitTolerance : 0;
31256    const checkWrapped = options.checkWrapped !== false;
31257    return this.renderer_.hasFeatureAtCoordinate(
31258      coordinate,
31259      this.frameState_,
31260      hitTolerance,
31261      checkWrapped,
31262      layerFilter,
31263      null
31264    );
31265  }
31266
31267  /**
31268   * Returns the coordinate in user projection for a browser event.
31269   * @param {MouseEvent} event Event.
31270   * @return {import("./coordinate.js").Coordinate} Coordinate.
31271   * @api
31272   */
31273  getEventCoordinate(event) {
31274    return this.getCoordinateFromPixel(this.getEventPixel(event));
31275  }
31276
31277  /**
31278   * Returns the coordinate in view projection for a browser event.
31279   * @param {MouseEvent} event Event.
31280   * @return {import("./coordinate.js").Coordinate} Coordinate.
31281   */
31282  getEventCoordinateInternal(event) {
31283    return this.getCoordinateFromPixelInternal(this.getEventPixel(event));
31284  }
31285
31286  /**
31287   * Returns the map pixel position for a browser event relative to the viewport.
31288   * @param {UIEvent} event Event.
31289   * @return {import("./pixel.js").Pixel} Pixel.
31290   * @api
31291   */
31292  getEventPixel(event) {
31293    const viewportPosition = this.viewport_.getBoundingClientRect();
31294    const eventPosition =
31295      //FIXME Are we really calling this with a TouchEvent anywhere?
31296      'changedTouches' in event
31297        ? /** @type {TouchEvent} */ (event).changedTouches[0]
31298        : /** @type {MouseEvent} */ (event);
31299
31300    return [
31301      eventPosition.clientX - viewportPosition.left,
31302      eventPosition.clientY - viewportPosition.top,
31303    ];
31304  }
31305
31306  /**
31307   * Get the target in which this map is rendered.
31308   * Note that this returns what is entered as an option or in setTarget:
31309   * if that was an element, it returns an element; if a string, it returns that.
31310   * @return {HTMLElement|string|undefined} The Element or id of the Element that the
31311   *     map is rendered in.
31312   * @observable
31313   * @api
31314   */
31315  getTarget() {
31316    return /** @type {HTMLElement|string|undefined} */ (
31317      this.get(MapProperty.TARGET)
31318    );
31319  }
31320
31321  /**
31322   * Get the DOM element into which this map is rendered. In contrast to
31323   * `getTarget` this method always return an `Element`, or `null` if the
31324   * map has no target.
31325   * @return {HTMLElement} The element that the map is rendered in.
31326   * @api
31327   */
31328  getTargetElement() {
31329    const target = this.getTarget();
31330    if (target !== undefined) {
31331      return typeof target === 'string'
31332        ? document.getElementById(target)
31333        : target;
31334    } else {
31335      return null;
31336    }
31337  }
31338
31339  /**
31340   * Get the coordinate for a given pixel.  This returns a coordinate in the
31341   * user projection.
31342   * @param {import("./pixel.js").Pixel} pixel Pixel position in the map viewport.
31343   * @return {import("./coordinate.js").Coordinate} The coordinate for the pixel position.
31344   * @api
31345   */
31346  getCoordinateFromPixel(pixel) {
31347    return toUserCoordinate(
31348      this.getCoordinateFromPixelInternal(pixel),
31349      this.getView().getProjection()
31350    );
31351  }
31352
31353  /**
31354   * Get the coordinate for a given pixel.  This returns a coordinate in the
31355   * map view projection.
31356   * @param {import("./pixel.js").Pixel} pixel Pixel position in the map viewport.
31357   * @return {import("./coordinate.js").Coordinate} The coordinate for the pixel position.
31358   */
31359  getCoordinateFromPixelInternal(pixel) {
31360    const frameState = this.frameState_;
31361    if (!frameState) {
31362      return null;
31363    } else {
31364      return apply(
31365        frameState.pixelToCoordinateTransform,
31366        pixel.slice()
31367      );
31368    }
31369  }
31370
31371  /**
31372   * Get the map controls. Modifying this collection changes the controls
31373   * associated with the map.
31374   * @return {Collection<import("./control/Control.js").default>} Controls.
31375   * @api
31376   */
31377  getControls() {
31378    return this.controls;
31379  }
31380
31381  /**
31382   * Get the map overlays. Modifying this collection changes the overlays
31383   * associated with the map.
31384   * @return {Collection<import("./Overlay.js").default>} Overlays.
31385   * @api
31386   */
31387  getOverlays() {
31388    return this.overlays_;
31389  }
31390
31391  /**
31392   * Get an overlay by its identifier (the value returned by overlay.getId()).
31393   * Note that the index treats string and numeric identifiers as the same. So
31394   * `map.getOverlayById(2)` will return an overlay with id `'2'` or `2`.
31395   * @param {string|number} id Overlay identifier.
31396   * @return {import("./Overlay.js").default} Overlay.
31397   * @api
31398   */
31399  getOverlayById(id) {
31400    const overlay = this.overlayIdIndex_[id.toString()];
31401    return overlay !== undefined ? overlay : null;
31402  }
31403
31404  /**
31405   * Get the map interactions. Modifying this collection changes the interactions
31406   * associated with the map.
31407   *
31408   * Interactions are used for e.g. pan, zoom and rotate.
31409   * @return {Collection<import("./interaction/Interaction.js").default>} Interactions.
31410   * @api
31411   */
31412  getInteractions() {
31413    return this.interactions;
31414  }
31415
31416  /**
31417   * Get the layergroup associated with this map.
31418   * @return {LayerGroup} A layer group containing the layers in this map.
31419   * @observable
31420   * @api
31421   */
31422  getLayerGroup() {
31423    return /** @type {LayerGroup} */ (this.get(MapProperty.LAYERGROUP));
31424  }
31425
31426  /**
31427   * Clear any existing layers and add layers to the map.
31428   * @param {Array<import("./layer/Base.js").default>|Collection<import("./layer/Base.js").default>} layers The layers to be added to the map.
31429   * @api
31430   */
31431  setLayers(layers) {
31432    const group = this.getLayerGroup();
vendor: 5,084 bytes, lines 31433-31609
31433    if (layers instanceof ol_Collection) {
31434      group.setLayers(layers);
31435      return;
31436    }
31437
31438    const collection = group.getLayers();
31439    collection.clear();
31440    collection.extend(layers);
31441  }
31442
31443  /**
31444   * Get the collection of layers associated with this map.
31445   * @return {!Collection<import("./layer/Base.js").default>} Layers.
31446   * @api
31447   */
31448  getLayers() {
31449    const layers = this.getLayerGroup().getLayers();
31450    return layers;
31451  }
31452
31453  /**
31454   * @return {boolean} Layers have sources that are still loading.
31455   */
31456  getLoadingOrNotReady() {
31457    const layerStatesArray = this.getLayerGroup().getLayerStatesArray();
31458    for (let i = 0, ii = layerStatesArray.length; i < ii; ++i) {
31459      const state = layerStatesArray[i];
31460      if (!state.visible) {
31461        continue;
31462      }
31463      const renderer = state.layer.getRenderer();
31464      if (renderer && !renderer.ready) {
31465        return true;
31466      }
31467      const source = state.layer.getSource();
31468      if (source && source.loading) {
31469        return true;
31470      }
31471    }
31472    return false;
31473  }
31474
31475  /**
31476   * Get the pixel for a coordinate.  This takes a coordinate in the user
31477   * projection and returns the corresponding pixel.
31478   * @param {import("./coordinate.js").Coordinate} coordinate A map coordinate.
31479   * @return {import("./pixel.js").Pixel} A pixel position in the map viewport.
31480   * @api
31481   */
31482  getPixelFromCoordinate(coordinate) {
31483    const viewCoordinate = fromUserCoordinate(
31484      coordinate,
31485      this.getView().getProjection()
31486    );
31487    return this.getPixelFromCoordinateInternal(viewCoordinate);
31488  }
31489
31490  /**
31491   * Get the pixel for a coordinate.  This takes a coordinate in the map view
31492   * projection and returns the corresponding pixel.
31493   * @param {import("./coordinate.js").Coordinate} coordinate A map coordinate.
31494   * @return {import("./pixel.js").Pixel} A pixel position in the map viewport.
31495   */
31496  getPixelFromCoordinateInternal(coordinate) {
31497    const frameState = this.frameState_;
31498    if (!frameState) {
31499      return null;
31500    } else {
31501      return apply(
31502        frameState.coordinateToPixelTransform,
31503        coordinate.slice(0, 2)
31504      );
31505    }
31506  }
31507
31508  /**
31509   * Get the map renderer.
31510   * @return {import("./renderer/Map.js").default|null} Renderer
31511   */
31512  getRenderer() {
31513    return this.renderer_;
31514  }
31515
31516  /**
31517   * Get the size of this map.
31518   * @return {import("./size.js").Size|undefined} The size in pixels of the map in the DOM.
31519   * @observable
31520   * @api
31521   */
31522  getSize() {
31523    return /** @type {import("./size.js").Size|undefined} */ (
31524      this.get(MapProperty.SIZE)
31525    );
31526  }
31527
31528  /**
31529   * Get the view associated with this map. A view manages properties such as
31530   * center and resolution.
31531   * @return {View} The view that controls this map.
31532   * @observable
31533   * @api
31534   */
31535  getView() {
31536    return /** @type {View} */ (this.get(MapProperty.VIEW));
31537  }
31538
31539  /**
31540   * Get the element that serves as the map viewport.
31541   * @return {HTMLElement} Viewport.
31542   * @api
31543   */
31544  getViewport() {
31545    return this.viewport_;
31546  }
31547
31548  /**
31549   * Get the element that serves as the container for overlays.  Elements added to
31550   * this container will let mousedown and touchstart events through to the map,
31551   * so clicks and gestures on an overlay will trigger {@link module:ol/MapBrowserEvent~MapBrowserEvent}
31552   * events.
31553   * @return {!HTMLElement} The map's overlay container.
31554   */
31555  getOverlayContainer() {
31556    return this.overlayContainer_;
31557  }
31558
31559  /**
31560   * Get the element that serves as a container for overlays that don't allow
31561   * event propagation. Elements added to this container won't let mousedown and
31562   * touchstart events through to the map, so clicks and gestures on an overlay
31563   * don't trigger any {@link module:ol/MapBrowserEvent~MapBrowserEvent}.
31564   * @return {!HTMLElement} The map's overlay container that stops events.
31565   */
31566  getOverlayContainerStopEvent() {
31567    return this.overlayContainerStopEvent_;
31568  }
31569
31570  /**
31571   * @return {!Document} The document where the map is displayed.
31572   */
31573  getOwnerDocument() {
31574    const targetElement = this.getTargetElement();
31575    return targetElement ? targetElement.ownerDocument : document;
31576  }
31577
31578  /**
31579   * @param {import("./Tile.js").default} tile Tile.
31580   * @param {string} tileSourceKey Tile source key.
31581   * @param {import("./coordinate.js").Coordinate} tileCenter Tile center.
31582   * @param {number} tileResolution Tile resolution.
31583   * @return {number} Tile priority.
31584   */
31585  getTilePriority(tile, tileSourceKey, tileCenter, tileResolution) {
31586    return getTilePriority(
31587      this.frameState_,
31588      tile,
31589      tileSourceKey,
31590      tileCenter,
31591      tileResolution
31592    );
31593  }
31594
31595  /**
31596   * @param {UIEvent} browserEvent Browser event.
31597   * @param {string} [type] Type.
31598   */
31599  handleBrowserEvent(browserEvent, type) {
31600    type = type || browserEvent.type;
31601    const mapBrowserEvent = new ol_MapBrowserEvent(type, this, browserEvent);
31602    this.handleMapBrowserEvent(mapBrowserEvent);
31603  }
31604
31605  /**
31606   * @param {MapBrowserEvent} mapBrowserEvent The event to handle.
31607   */
31608  handleMapBrowserEvent(mapBrowserEvent) {
31609    if (!this.frameState_) {
31610      // With no view defined, we cannot translate pixels into geographical
31611      // coordinates so interactions cannot be used.
31612      return;
31613    }
31614    const originalEvent = /** @type {PointerEvent} */ (
31615      mapBrowserEvent.originalEvent
31616    );
31617    const eventType = originalEvent.type;
31618    if (
31619      eventType === pointer_EventType.POINTERDOWN ||
31620      eventType === EventType.WHEEL ||
31621      eventType === EventType.KEYDOWN
31622    ) {
31623      const doc = this.getOwnerDocument();
31624      const rootNode = this.viewport_.getRootNode
31625        ? this.viewport_.getRootNode()
31626        : doc;
31627      const target = /** @type {Node} */ (originalEvent.target);
31628      if (
31629        // Abort if the target is a child of the container for elements whose events are not meant
31630        // to be handled by map interactions.
31631        this.overlayContainerStopEvent_.contains(target) ||
31632        // Abort if the event target is a child of the container that is no longer in the page.
31633        // It's possible for the target to no longer be in the page if it has been removed in an
31634        // event listener, this might happen in a Control that recreates it's content based on
31635        // user interaction either manually or via a render in something like https://reactjs.org/
31636        !(rootNode === doc ? doc.documentElement : rootNode).contains(target)
31637      ) {
31638        return;
31639      }
31640    }
31641    mapBrowserEvent.frameState = this.frameState_;
31642    if (this.dispatchEvent(mapBrowserEvent) !== false) {
31643      const interactionsArray = this.getInteractions().getArray().slice();
31644      for (let i = interactionsArray.length - 1; i >= 0; i--) {
31645        const interaction = interactionsArray[i];
31646        if (
31647          interaction.getMap() !== this ||
31648          !interaction.getActive() ||
31649          !this.getTargetElement()
31650        ) {
31651          continue;
31652        }
31653        const cont = interaction.handleEvent(mapBrowserEvent);
31654        if (!cont || mapBrowserEvent.propagationStopped) {
31655          break;
31656        }
31657      }
31658    }
31659  }
31660
31661  /**
31662   * @protected
31663   */
31664  handlePostRender() {
31665    const frameState = this.frameState_;
31666
31667    // Manage the tile queue
31668    // Image loads are expensive and a limited resource, so try to use them
31669    // efficiently:
31670    // * When the view is static we allow a large number of parallel tile loads
31671    //   to complete the frame as quickly as possible.
31672    // * When animating or interacting, image loads can cause janks, so we reduce
31673    //   the maximum number of loads per frame and limit the number of parallel
31674    //   tile loads to remain reactive to view changes and to reduce the chance of
31675    //   loading tiles that will quickly disappear from view.
31676    const tileQueue = this.tileQueue_;
31677    if (!tileQueue.isEmpty()) {
31678      let maxTotalLoading = this.maxTilesLoading_;
31679      let maxNewLoads = maxTotalLoading;
31680      if (frameState) {
31681        const hints = frameState.viewHints;
31682        if (hints[ViewHint.ANIMATING] || hints[ViewHint.INTERACTING]) {
31683          const lowOnFrameBudget = Date.now() - frameState.time > 8;
31684          maxTotalLoading = lowOnFrameBudget ? 0 : 8;
31685          maxNewLoads = lowOnFrameBudget ? 0 : 2;
31686        }
31687      }
31688      if (tileQueue.getTilesLoading() < maxTotalLoading) {
31689        tileQueue.reprioritize(); // FIXME only call if view has changed
31690        tileQueue.loadMoreTiles(maxTotalLoading, maxNewLoads);
31691      }
31692    }
31693
31694    if (frameState && this.renderer_ && !frameState.animate) {
31695      if (this.renderComplete_ === true) {
31696        if (this.hasListener(render_EventType.RENDERCOMPLETE)) {
31697          this.renderer_.dispatchRenderEvent(
31698            render_EventType.RENDERCOMPLETE,
31699            frameState
31700          );
31701        }
31702        if (this.loaded_ === false) {
31703          this.loaded_ = true;
31704          this.dispatchEvent(
31705            new ol_MapEvent(MapEventType.LOADEND, this, frameState)
31706          );
31707        }
31708      } else if (this.loaded_ === true) {
31709        this.loaded_ = false;
31710        this.dispatchEvent(
31711          new ol_MapEvent(MapEventType.LOADSTART, this, frameState)
31712        );
31713      }
31714    }
31715
31716    const postRenderFunctions = this.postRenderFunctions_;
31717    for (let i = 0, ii = postRenderFunctions.length; i < ii; ++i) {
31718      postRenderFunctions[i](this, frameState);
31719    }
31720    postRenderFunctions.length = 0;
31721  }
31722
31723  /**
31724   * @private
31725   */
31726  handleSizeChanged_() {
31727    if (this.getView() && !this.getView().getAnimating()) {
31728      this.getView().resolveConstraints(0);
31729    }
31730
31731    this.render();
31732  }
31733
31734  /**
31735   * @private
31736   */
31737  handleTargetChanged_() {
31738    if (this.mapBrowserEventHandler_) {
31739      for (let i = 0, ii = this.targetChangeHandlerKeys_.length; i < ii; ++i) {
31740        unlistenByKey(this.targetChangeHandlerKeys_[i]);
31741      }
31742      this.targetChangeHandlerKeys_ = null;
31743      this.viewport_.removeEventListener(
31744        EventType.CONTEXTMENU,
31745        this.boundHandleBrowserEvent_
31746      );
31747      this.viewport_.removeEventListener(
31748        EventType.WHEEL,
31749        this.boundHandleBrowserEvent_
31750      );
31751      this.mapBrowserEventHandler_.dispose();
31752      this.mapBrowserEventHandler_ = null;
31753      removeNode(this.viewport_);
31754    }
31755
31756    // target may be undefined, null, a string or an Element.
31757    // If it's a string we convert it to an Element before proceeding.
31758    // If it's not now an Element we remove the viewport from the DOM.
31759    // If it's an Element we append the viewport element to it.
31760
31761    const targetElement = this.getTargetElement();
31762    if (!targetElement) {
31763      if (this.renderer_) {
31764        clearTimeout(this.postRenderTimeoutHandle_);
31765        this.postRenderTimeoutHandle_ = undefined;
31766        this.postRenderFunctions_.length = 0;
31767        this.renderer_.dispose();
31768        this.renderer_ = null;
31769      }
31770      if (this.animationDelayKey_) {
31771        cancelAnimationFrame(this.animationDelayKey_);
31772        this.animationDelayKey_ = undefined;
31773      }
31774    } else {
31775      targetElement.appendChild(this.viewport_);
31776      if (!this.renderer_) {
31777        this.renderer_ = new Composite(this);
31778      }
31779
31780      this.mapBrowserEventHandler_ = new ol_MapBrowserEventHandler(
31781        this,
31782        this.moveTolerance_
31783      );
31784      for (const key in ol_MapBrowserEventType) {
31785        this.mapBrowserEventHandler_.addEventListener(
31786          ol_MapBrowserEventType[key],
31787          this.handleMapBrowserEvent.bind(this)
31788        );
31789      }
31790      this.viewport_.addEventListener(
31791        EventType.CONTEXTMENU,
31792        this.boundHandleBrowserEvent_,
31793        false
31794      );
31795      this.viewport_.addEventListener(
31796        EventType.WHEEL,
31797        this.boundHandleBrowserEvent_,
31798        PASSIVE_EVENT_LISTENERS ? {passive: false} : false
31799      );
31800
31801      const defaultView = this.getOwnerDocument().defaultView;
vendor: 5,116 bytes, lines 31802-32002
31802      const keyboardEventTarget = !this.keyboardEventTarget_
31803        ? targetElement
31804        : this.keyboardEventTarget_;
31805      this.targetChangeHandlerKeys_ = [
31806        listen(
31807          keyboardEventTarget,
31808          EventType.KEYDOWN,
31809          this.handleBrowserEvent,
31810          this
31811        ),
31812        listen(
31813          keyboardEventTarget,
31814          EventType.KEYPRESS,
31815          this.handleBrowserEvent,
31816          this
31817        ),
31818        listen(defaultView, EventType.RESIZE, this.updateSize, this),
31819      ];
31820    }
31821
31822    this.updateSize();
31823    // updateSize calls setSize, so no need to call this.render
31824    // ourselves here.
31825  }
31826
31827  /**
31828   * @private
31829   */
31830  handleTileChange_() {
31831    this.render();
31832  }
31833
31834  /**
31835   * @private
31836   */
31837  handleViewPropertyChanged_() {
31838    this.render();
31839  }
31840
31841  /**
31842   * @private
31843   */
31844  handleViewChanged_() {
31845    if (this.viewPropertyListenerKey_) {
31846      unlistenByKey(this.viewPropertyListenerKey_);
31847      this.viewPropertyListenerKey_ = null;
31848    }
31849    if (this.viewChangeListenerKey_) {
31850      unlistenByKey(this.viewChangeListenerKey_);
31851      this.viewChangeListenerKey_ = null;
31852    }
31853    const view = this.getView();
31854    if (view) {
31855      this.updateViewportSize_();
31856
31857      this.viewPropertyListenerKey_ = listen(
31858        view,
31859        ObjectEventType.PROPERTYCHANGE,
31860        this.handleViewPropertyChanged_,
31861        this
31862      );
31863      this.viewChangeListenerKey_ = listen(
31864        view,
31865        EventType.CHANGE,
31866        this.handleViewPropertyChanged_,
31867        this
31868      );
31869
31870      view.resolveConstraints(0);
31871    }
31872    this.render();
31873  }
31874
31875  /**
31876   * @private
31877   */
31878  handleLayerGroupChanged_() {
31879    if (this.layerGroupPropertyListenerKeys_) {
31880      this.layerGroupPropertyListenerKeys_.forEach(unlistenByKey);
31881      this.layerGroupPropertyListenerKeys_ = null;
31882    }
31883    const layerGroup = this.getLayerGroup();
31884    if (layerGroup) {
31885      this.handleLayerAdd_(new GroupEvent('addlayer', layerGroup));
31886      this.layerGroupPropertyListenerKeys_ = [
31887        listen(layerGroup, ObjectEventType.PROPERTYCHANGE, this.render, this),
31888        listen(layerGroup, EventType.CHANGE, this.render, this),
31889        listen(layerGroup, 'addlayer', this.handleLayerAdd_, this),
31890        listen(layerGroup, 'removelayer', this.handleLayerRemove_, this),
31891      ];
31892    }
31893    this.render();
31894  }
31895
31896  /**
31897   * @return {boolean} Is rendered.
31898   */
31899  isRendered() {
31900    return !!this.frameState_;
31901  }
31902
31903  /**
31904   * @private
31905   */
31906  animationDelay_() {
31907    this.animationDelayKey_ = undefined;
31908    this.renderFrame_(Date.now());
31909  }
31910
31911  /**
31912   * Requests an immediate render in a synchronous manner.
31913   * @api
31914   */
31915  renderSync() {
31916    if (this.animationDelayKey_) {
31917      cancelAnimationFrame(this.animationDelayKey_);
31918    }
31919    this.animationDelay_();
31920  }
31921
31922  /**
31923   * Redraws all text after new fonts have loaded
31924   */
31925  redrawText() {
31926    const layerStates = this.getLayerGroup().getLayerStatesArray();
31927    for (let i = 0, ii = layerStates.length; i < ii; ++i) {
31928      const layer = layerStates[i].layer;
31929      if (layer.hasRenderer()) {
31930        layer.getRenderer().handleFontsChanged();
31931      }
31932    }
31933  }
31934
31935  /**
31936   * Request a map rendering (at the next animation frame).
31937   * @api
31938   */
31939  render() {
31940    if (this.renderer_ && this.animationDelayKey_ === undefined) {
31941      this.animationDelayKey_ = requestAnimationFrame(this.animationDelay_);
31942    }
31943  }
31944
31945  /**
31946   * Remove the given control from the map.
31947   * @param {import("./control/Control.js").default} control Control.
31948   * @return {import("./control/Control.js").default|undefined} The removed control (or undefined
31949   *     if the control was not found).
31950   * @api
31951   */
31952  removeControl(control) {
31953    return this.getControls().remove(control);
31954  }
31955
31956  /**
31957   * Remove the given interaction from the map.
31958   * @param {import("./interaction/Interaction.js").default} interaction Interaction to remove.
31959   * @return {import("./interaction/Interaction.js").default|undefined} The removed interaction (or
31960   *     undefined if the interaction was not found).
31961   * @api
31962   */
31963  removeInteraction(interaction) {
31964    return this.getInteractions().remove(interaction);
31965  }
31966
31967  /**
31968   * Removes the given layer from the map.
31969   * @param {import("./layer/Base.js").default} layer Layer.
31970   * @return {import("./layer/Base.js").default|undefined} The removed layer (or undefined if the
31971   *     layer was not found).
31972   * @api
31973   */
31974  removeLayer(layer) {
31975    const layers = this.getLayerGroup().getLayers();
31976    return layers.remove(layer);
31977  }
31978
31979  /**
31980   * @param {import("./layer/Group.js").GroupEvent} event The layer remove event.
31981   * @private
31982   */
31983  handleLayerRemove_(event) {
31984    removeLayerMapProperty(event.layer);
31985  }
31986
31987  /**
31988   * Remove the given overlay from the map.
31989   * @param {import("./Overlay.js").default} overlay Overlay.
31990   * @return {import("./Overlay.js").default|undefined} The removed overlay (or undefined
31991   *     if the overlay was not found).
31992   * @api
31993   */
31994  removeOverlay(overlay) {
31995    return this.getOverlays().remove(overlay);
31996  }
31997
31998  /**
31999   * @param {number} time Time.
32000   * @private
32001   */
32002  renderFrame_(time) {
32003    const size = this.getSize();
32004    const view = this.getView();
32005    const previousFrameState = this.frameState_;
32006    /** @type {?FrameState} */
32007    let frameState = null;
32008    if (size !== undefined && hasArea(size) && view && view.isDef()) {
32009      const viewHints = view.getHints(
32010        this.frameState_ ? this.frameState_.viewHints : undefined
32011      );
32012      const viewState = view.getState();
32013      frameState = {
32014        animate: false,
32015        coordinateToPixelTransform: this.coordinateToPixelTransform_,
32016        declutterTree: null,
32017        extent: getForViewAndSize(
32018          viewState.center,
32019          viewState.resolution,
32020          viewState.rotation,
32021          size
32022        ),
32023        index: this.frameIndex_++,
32024        layerIndex: 0,
32025        layerStatesArray: this.getLayerGroup().getLayerStatesArray(),
32026        pixelRatio: this.pixelRatio_,
32027        pixelToCoordinateTransform: this.pixelToCoordinateTransform_,
32028        postRenderFunctions: [],
32029        size: size,
32030        tileQueue: this.tileQueue_,
32031        time: time,
32032        usedTiles: {},
32033        viewState: viewState,
32034        viewHints: viewHints,
32035        wantedTiles: {},
32036        mapId: getUid(this),
32037        renderTargets: {},
32038      };
32039      if (viewState.nextCenter && viewState.nextResolution) {
32040        const rotation = isNaN(viewState.nextRotation)
32041          ? viewState.rotation
32042          : viewState.nextRotation;
32043
32044        frameState.nextExtent = getForViewAndSize(
32045          viewState.nextCenter,
32046          viewState.nextResolution,
32047          rotation,
32048          size
32049        );
32050      }
32051    }
32052
32053    this.frameState_ = frameState;
32054    this.renderer_.renderFrame(frameState);
32055
32056    if (frameState) {
32057      if (frameState.animate) {
32058        this.render();
32059      }
32060      Array.prototype.push.apply(
32061        this.postRenderFunctions_,
32062        frameState.postRenderFunctions
32063      );
32064
32065      if (previousFrameState) {
32066        const moveStart =
32067          !this.previousExtent_ ||
32068          (!extent_isEmpty(this.previousExtent_) &&
32069            !extent_equals(frameState.extent, this.previousExtent_));
32070        if (moveStart) {
32071          this.dispatchEvent(
32072            new ol_MapEvent(MapEventType.MOVESTART, this, previousFrameState)
32073          );
32074          this.previousExtent_ = createOrUpdateEmpty(this.previousExtent_);
32075        }
32076      }
32077
32078      const idle =
32079        this.previousExtent_ &&
32080        !frameState.viewHints[ViewHint.ANIMATING] &&
32081        !frameState.viewHints[ViewHint.INTERACTING] &&
32082        !extent_equals(frameState.extent, this.previousExtent_);
32083
32084      if (idle) {
32085        this.dispatchEvent(
32086          new ol_MapEvent(MapEventType.MOVEEND, this, frameState)
32087        );
32088        clone(frameState.extent, this.previousExtent_);
32089      }
32090    }
32091
32092    this.dispatchEvent(new ol_MapEvent(MapEventType.POSTRENDER, this, frameState));
32093
32094    this.renderComplete_ =
32095      this.hasListener(MapEventType.LOADSTART) ||
32096      this.hasListener(MapEventType.LOADEND) ||
32097      this.hasListener(render_EventType.RENDERCOMPLETE)
32098        ? !this.tileQueue_.getTilesLoading() &&
32099          !this.tileQueue_.getCount() &&
32100          !this.getLoadingOrNotReady()
32101        : undefined;
32102
32103    if (!this.postRenderTimeoutHandle_) {
32104      this.postRenderTimeoutHandle_ = setTimeout(() => {
32105        this.postRenderTimeoutHandle_ = undefined;
32106        this.handlePostRender();
32107      }, 0);
32108    }
32109  }
32110
32111  /**
32112   * Sets the layergroup of this map.
32113   * @param {LayerGroup} layerGroup A layer group containing the layers in this map.
32114   * @observable
32115   * @api
32116   */
32117  setLayerGroup(layerGroup) {
32118    const oldLayerGroup = this.getLayerGroup();
32119    if (oldLayerGroup) {
32120      this.handleLayerRemove_(new GroupEvent('removelayer', oldLayerGroup));
32121    }
32122    this.set(MapProperty.LAYERGROUP, layerGroup);
32123  }
32124
32125  /**
32126   * Set the size of this map.
32127   * @param {import("./size.js").Size|undefined} size The size in pixels of the map in the DOM.
32128   * @observable
32129   * @api
32130   */
32131  setSize(size) {
32132    this.set(MapProperty.SIZE, size);
32133  }
32134
32135  /**
32136   * Set the target element to render this map into.
32137   * @param {HTMLElement|string} [target] The Element or id of the Element
32138   *     that the map is rendered in.
32139   * @observable
32140   * @api
32141   */
32142  setTarget(target) {
32143    this.set(MapProperty.TARGET, target);
32144  }
32145
32146  /**
32147   * Set the view for this map.
32148   * @param {View|Promise<import("./View.js").ViewOptions>} view The view that controls this map.
32149   * It is also possible to pass a promise that resolves to options for c
32149onstructing a view.  This
32150   * alternative allows view properties to be resolved by sources or other components that load
32151   * view-related metadata.
32152   * @observable
32153   * @api
32154   */
32155  setView(view) {
32156    if (!view || view instanceof ol_View) {
32157      this.set(MapProperty.VIEW, view);
32158      return;
32159    }
32160    this.set(MapProperty.VIEW, new ol_View());
32161
32162    const map = this;
32163    view.then(function (viewOptions) {
32164      map.setView(new ol_View(viewOptions));
32165    });
32166  }
32167
32168  /**
32169   * Force a recalculation of the map viewport size.  This should be called when
32170   * third-party code changes the size of the map viewport.
32171   * @api
32172   */
32173  updateSize() {
32174    const targetElement = this.getTargetElement();
32175
32176    let size = undefined;
32177    if (targetElement) {
32178      const computedStyle = getComputedStyle(targetElement);
32179      const width =
32180        targetElement.offsetWidth -
32181        parseFloat(computedStyle['borderLeftWidth']) -
32182        parseFloat(computedStyle['paddingLeft']) -
32183        parseFloat(computedStyle['paddingRight']) -
32184        parseFloat(computedStyle['borderRightWidth']);
32185      const height =
32186        targetElement.offsetHeight -
32187        parseFloat(computedStyle['borderTopWidth']) -
32188        parseFloat(computedStyle['paddingTop']) -
32189        parseFloat(computedStyle['paddingBottom']) -
32190        parseFloat(computedStyle['borderBottomWidth']);
32191      if (!isNaN(width) && !isNaN(height)) {
32192        size = [width, height];
32193        if (
32194          !hasArea(size) &&
32195          !!(
32196            targetElement.offsetWidth ||
32197            targetElement.offsetHeight ||
32198            targetElement.getClientRects().length
32199          )
32200        ) {
32201          // eslint-disable-next-line
32202          console.warn(
32203            "No map visible because the map container's width or height are 0."
32204          );
32205        }
32206      }
32207    }
32208
32209    this.setSize(size);
32210    this.updateViewportSize_();
32211  }
32212
32213  /**
32214   * Recomputes the viewport size and save it on the view object (if any)
32215   * @private
32216   */
32217  updateViewportSize_() {
32218    const view = this.getView();
32219    if (view) {
32220      let size = undefined;
32221      const computedStyle = getComputedStyle(this.viewport_);
32222      if (computedStyle.width && computedStyle.height) {
32223        size = [
32224          parseInt(computedStyle.width, 10),
32225          parseInt(computedStyle.height, 10),
32226        ];
32227      }
32228      view.setViewportSize(size);
32229    }
32230  }
32231}
32232
32233/**
32234 * @param {MapOptions} options Map options.
32235 * @return {MapOptionsInternal} Internal map options.
32236 */
32237function createOptionsInternal(options) {
32238  /**
32239   * @type {HTMLElement|Document}
32240   */
32241  let keyboardEventTarget = null;
32242  if (options.keyboardEventTarget !== undefined) {
32243    keyboardEventTarget =
32244      typeof options.keyboardEventTarget === 'string'
32245        ? document.getElementById(options.keyboardEventTarget)
32246        : options.keyboardEventTarget;
32247  }
32248
32249  /**
32250   * @type {Object<string, *>}
32251   */
32252  const values = {};
32253
32254  const layerGroup =
32255    options.layers &&
32256    typeof (/** @type {?} */ (options.layers).getLayers) === 'function'
32257      ? /** @type {LayerGroup} */ (options.layers)
32258      : new Group({
32259          layers:
32260            /** @type {Collection<import("./layer/Base.js").default>|Array<import("./layer/Base.js").default>} */ (
32261              options.layers
32262            ),
32263        });
32264  values[MapProperty.LAYERGROUP] = layerGroup;
32265
32266  values[MapProperty.TARGET] = options.target;
32267
32268  values[MapProperty.VIEW] =
32269    options.view instanceof ol_View ? options.view : new ol_View();
32270
32271  /** @type {Collection<import("./control/Control.js").default>} */
32272  let controls;
32273  if (options.controls !== undefined) {
32274    if (Array.isArray(options.controls)) {
32275      controls = new ol_Collection(options.controls.slice());
32276    } else {
32277      asserts_assert(
32278        typeof (/** @type {?} */ (options.controls).getArray) === 'function',
32279        47
32280      ); // Expected `controls` to be an array or an `import("./Collection.js").Collection`
32281      controls = options.controls;
32282    }
32283  }
32284
32285  /** @type {Collection<import("./interaction/Interaction").default>} */
32286  let interactions;
32287  if (options.interactions !== undefined) {
32288    if (Array.isArray(options.interactions)) {
32289      interactions = new ol_Collection(options.interactions.slice());
32290    } else {
32291      asserts_assert(
32292        typeof (/** @type {?} */ (options.interactions).getArray) ===
32293          'function',
32294        48
32295      ); // Expected `interactions` to be an array or an `import("./Collection.js").Collection`
32296      interactions = options.interactions;
32297    }
32298  }
32299
32300  /** @type {Collection<import("./Overlay.js").default>} */
32301  let overlays;
32302  if (options.overlays !== undefined) {
32303    if (Array.isArray(options.overlays)) {
32304      overlays = new ol_Collection(options.overlays.slice());
32305    } else {
32306      asserts_assert(
32307        typeof (/** @type {?} */ (options.overlays).getArray) === 'function',
32308        49
32309      ); // Expected `overlays` to be an array or an `import("./Collection.js").Collection`
32310      overlays = options.overlays;
32311    }
32312  } else {
32313    overlays = new ol_Collection();
32314  }
32315
32316  return {
32317    controls: controls,
32318    interactions: interactions,
32319    keyboardEventTarget: keyboardEventTarget,
32320    overlays: overlays,
32321    values: values,
32322  };
32323}
32324/* harmony default export */ const ol_Map = (Map_Map);
32325
32326// EXTERNAL MODULE: ./node_modules/rbush/rbush.min.js
32327var rbush_min = __webpack_require__(582);
32328;// CONCATENATED MODULE: ./node_modules/ol/ImageState.js
32329/**
32330 * @module ol/ImageState
32331 */
32332
32333/**
32334 * @enum {number}
32335 */
32336/* harmony default export */ const ol_ImageState = ({
32337  IDLE: 0,
32338  LOADING: 1,
32339  LOADED: 2,
32340  ERROR: 3,
32341  EMPTY: 4,
32342});
32343
32344;// CONCATENATED MODULE: ./node_modules/ol/style/Image.js
32345/**
32346 * @module ol/style/Image
32347 */
32348
32349
32350
32351/**
32352 * @typedef {Object} Options
32353 * @property {number} opacity Opacity.
32354 * @property {boolean} rotateWithView If the image should get rotated with the view.
32355 * @property {number} rotation Rotation.
32356 * @property {number|import("../size.js").Size} scale Scale.
32357 * @property {Array<number>} displacement Displacement.
32358 * @property {"declutter"|"obstacle"|"none"|undefined} declutterMode Declutter mode: `declutter`, `obstacle`, 'none */
32359
32360/**
32361 * @classdesc
32362 * A base class used for creating subclasses and not instantiated in
32363 * apps. Base class for {@link module:ol/style/Icon~Icon}, {@link module:ol/style/Circle~CircleStyle} and
32364 * {@link module:ol/style/RegularShape~RegularShape}.
32365 * @abstract
32366 * @api
32367 */
32368class ImageStyle {
32369  /**
32370   * @param {Options} options Options.
32371   */
32372  constructor(options) {
32373    /**
32374     * @private
32375     * @type {number}
32376     */
32377    this.opacity_ = options.opacity;
32378
32379    /**
32380     * @private
32381     * @type {boolean}
32382     */
32383    this.rotateWithView_ = options.rotateWithView;
32384
32385    /**
32386     * @private
32387     * @type {number}
32388     */
32389    this.rotation_ = options.rotation;
32390
32391    /**
32392     * @private
32393     * @type {number|import("../size.js").Size}
32394     */
32395    this.scale_ = options.scale;
32396
32397    /**
32398     * @private
32399     * @type {import("../size.js").Size}
32400     */
32401    this.scaleArray_ = toSize(options.scale);
32402
32403    /**
32404     * @private
32405     * @type {Array<number>}
32406     */
32407    this.displacement_ = options.displacement;
32408
32409    /**
32410     * @private
32411     * @type {"declutter"|"obstacle"|"none"|undefined}
32412     */
32413    this.declutterMode_ = options.declutterMode;
32414  }
32415
32416  /**
32417   * Clones the style.
32418   * @return {ImageStyle} The cloned style.
32419   * @api
32420   */
32421  clone() {
32422    const scale = this.getScale();
32423    return new ImageStyle({
32424      opacity: this.getOpacity(),
32425      scale: Array.isArray(scale) ? scale.slice() : scale,
32426      rotation: this.getRotation(),
32427      rotateWithView: this.getRotateWithView(),
32428      displacement: this.getDisplacement().slice(),
32429      declutterMode: this.getDeclutterMode(),
32430    });
32431  }
32432
32433  /**
32434   * Get the symbolizer opacity.
32435   * @return {number} Opacity.
32436   * @api
32437   */
32438  getOpacity() {
32439    return this.opacity_;
32440  }
32441
32442  /**
32443   * Determine whether the symbolizer rotates with the map.
32444   * @return {boolean} Rotate with map.
32445   * @api
32446   */
32447  getRotateWithView() {
32448    return this.rotateWithView_;
32449  }
32450
32451  /**
32452   * Get the symoblizer rotation.
32453   * @return {number} Rotation.
32454   * @api
32455   */
32456  getRotation() {
32457    return this.rotation_;
32458  }
32459
32460  /**
32461   * Get the symbolizer scale.
32462   * @return {number|import("../size.js").Size} Scale.
32463   * @api
32464   */
32465  getScale() {
32466    return this.scale_;
32467  }
32468
32469  /**
32470   * Get the symbolizer scale array.
32471   * @return {import("../size.js").Size} Scale array.
32472   */
32473  getScaleArray() {
32474    return this.scaleArray_;
32475  }
32476
32477  /**
32478   * Get the displacement of the shape
32479   * @return {Array<number>} Shape's center displacement
32480   * @api
32481   */
32482  getDisplacement() {
32483    return this.displacement_;
32484  }
32485
32486  /**
32487   * Get the declutter mode of the shape
32488   * @return {"declutter"|"obstacle"|"none"|undefined} Shape's declutter mode
32489   * @api
32490   */
32491  getDeclutterMode() {
32492    return this.declutterMode_;
32493  }
32494
32495  /**
32496   * Get the anchor point in pixels. The anchor determines the center point for the
32497   * symbolizer.
32498   * @abstract
32499   * @return {Array<number>} Anchor.
32500   */
32501  getAnchor() {
32502    return util_abstract();
32503  }
32504
32505  /**
32506   * Get the image element for the symbolizer.
32507   * @abstract
32508   * @param {number} pixelRatio Pixel ratio.
32509   * @return {HTMLCanvasElement|HTMLVideoElement|HTMLImageElement} Image element.
32510   */
32511  getImage(pixelRatio) {
32512    return util_abstract();
32513  }
32514
32515  /**
32516   * @abstract
32517   * @return {HTMLCanvasElement|HTMLVideoElement|HTMLImageElement} Image element.
32518   */
32519  getHitDetectionImage() {
32520    return util_abstract();
32521  }
32522
32523  /**
32524   * Get the image pixel ratio.
32525   * @param {number} pixelRatio Pixel ratio.
32526   * @return {number} Pixel ratio.
32527   */
32528  getPixelRatio(pixelRatio) {
32529    return 1;
32530  }
32531
32532  /**
32533   * @abstract
32534   * @return {import("../ImageState.js").default} Image state.
32535   */
32536  getImageState() {
32537    return util_abstract();
32538  }
32539
32540  /**
32541   * @abstract
32542   * @return {import("../size.js").Size} Image size.
32543   */
32544  getImageSize() {
32545    return util_abstract();
32546  }
32547
32548  /**
32549   * Get the origin of the symbolizer.
32550   * @abstract
32551   * @return {Array<number>} Origin.
32552   */
32553  getOrigin() {
32554    return util_abstract();
32555  }
32556
32557  /**
32558   * Get the size of the symbolizer (in pixels).
32559   * @abstract
32560   * @return {import("../size.js").Size} Size.
32561   */
32562  getSize() {
32563    return util_abstract();
32564  }
32565
32566  /**
32567   * Set the displacement.
32568   *
32569   * @param {Array<number>} displacement Displacement.
32570   * @api
32571   */
32572  setDisplacement(displacement) {
32573    this.displacement_ = displacement;
32574  }
32575
32576  /**
32577   * Set the opacity.
32578   *
32579   * @param {number} opacity Opacity.
32580   * @api
32581   */
32582  setOpacity(opacity) {
32583    this.opacity_ = opacity;
32584  }
32585
32586  /**
32587   * Set whether to rotate the style with the view.
32588   *
32589   * @param {boolean} rotateWithView Rotate with map.
32590   * @api
32591   */
32592  setRotateWithView(rotateWithView) {
32593    this.rotateWithView_ = rotateWithView;
32594  }
32595
32596  /**
32597   * Set the rotation.
32598   *
32599   * @param {number} rotation Rotation.
32600   * @api
32601   */
32602  setRotation(rotation) {
32603    this.rotation_ = rotation;
32604  }
32605  /**
32606   * Set the scale.
32607   *
32608   * @param {number|import("../size.js").Size} scale Scale.
32609   * @api
32610   */
32611  setScale(scale) {
32612    this.scale_ = scale;
32613    this.scaleArray_ = toSize(scale);
32614  }
32615
32616  /**
32617   * @abstract
32618   * @param {function(import("../events/Event.js").default): void} listener Listener function.
32619   */
32620  listenImageChange(listener) {
32621    util_abstract();
32622  }
32623
32624  /**
32625   * Load not yet loaded URI.
32626   * @abstract
32627   */
32628  load() {
32629    util_abstract();
32630  }
32631
32632  /**
32633   * @abstract
32634   * @param {function(import("../events/Event.js").default): void} listener Listener function.
32635   */
32636  unlistenImageChange(listener) {
32637    util_abstract();
32638  }
32639}
32640
32641/* harmony default export */ const style_Image = (ImageStyle);
32642
32643;// CONCATENATED MODULE: ./node_modules/ol/colorlike.js
32644/**
32645 * @module ol/colorlike
32646 */
32647
32648
32649/**
32650 * A type accepted by CanvasRenderingContext2D.fillStyle
32651 * or CanvasRenderingContext2D.strokeStyle.
32652 * Represents a color, pattern, or gradient. The origin for patterns and
32653 * gradients as fill style is an increment of 512 css pixels from map coordinate
32654 * `[0, 0]`. For seamless repeat patterns, width and height of the pattern image
32655 * must be a factor of two (2, 4, 8, ..., 512).
32656 *
32657 * @typedef {string|CanvasPattern|CanvasGradient} ColorLike
32658 * @api
32659 */
32660
32661/**
32662 * @param {import("./color.js").Color|ColorLike} color Color.
32663 * @return {ColorLike} The color as an {@link ol/colorlike~ColorLike}.
32664 * @api
32665 */
32666function asColorLike(color) {
32667  if (Array.isArray(color)) {
32668    return color_toString(color);
32669  } else {
32670    return color;
32671  }
32672}
32673
32674;// CONCATENATED MODULE: ./node_modules/ol/style/RegularShape.js
32675/**
32676 * @module ol/style/RegularShape
32677 */
32678
32679
32680
32681
32682
32683
32684
32685
32686/**
32687 * Specify radius for regular polygons, or radius1 and radius2 for stars.
32688 * @typedef {Object} Options
32689 * @property {import("./Fill.js").default} [fill] Fill style.
32690 * @property {number} points Number of points for stars and regular polygons. In case of a polygon, the number of points
32691 * is the number of sides.
32692 * @property {number} [radius] Radius of a regular polygon.
32693 * @property {number} [radius1] First radius of a star. Ignored if radius is set.
32694 * @property {number} [radius2] Second radius of a star.
32695 * @property {number} [angle=0] Shape's angle in radians. A value of 0 will have one of the shape's points facing up.
32696 * @property {Array<number>} [displacement=[0, 0]] Displacement of the shape in pixels.
32697 * Positive values will shift the shape right and up.
32698 * @property {import("./Stroke.js").default} [stroke] Stroke style.
32699 * @property {number} [rotation=0] Rotation in radians (positive rotation clockwise).
32700 * @property {boolean} [rotateWithView=false] Whether to rotate the shape with the view.
32701 * @property {number|import("../size.js").Size} [scale=1] Scale. Unless two dimensional scaling is required a better
32702 * result may be obtained with appropriate settings for `radius`, `radius1` and `radius2`.
32703 * @property {"declutter"|"obstacle"|"none"|undefined} [declutterMode] Declutter mode.
32704 */
32705
32706/**
32707 * @typedef {Object} RenderOptions
32708 * @property {import("../colorlike.js").ColorLike} [strokeStyle] StrokeStyle.
32709 * @property {number} strokeWidth StrokeWidth.
32710 * @property {number} size Size.
32711 * @property {Array<number>|null} lineDash LineDash.
32712 * @property {number} lineDashOffset LineDashOffset.
32713 * @property {CanvasLineJoin}
32713 lineJoin LineJoin.
32714 * @property {number} miterLimit MiterLimit.
32715 */
32716
32717/**
32718 * @classdesc
32719 * Set regular shape style for vector features. The resulting shape will be
32720 * a regular polygon when `radius` is provided, or a star when `radius1` and
32721 * `radius2` are provided.
32722 * @api
32723 */
32724class RegularShape extends style_Image {
32725  /**
32726   * @param {Options} options Options.
32727   */
32728  constructor(options) {
32729    /**
32730     * @type {boolean}
32731     */
32732    const rotateWithView =
32733      options.rotateWithView !== undefined ? options.rotateWithView : false;
32734
32735    super({
32736      opacity: 1,
32737      rotateWithView: rotateWithView,
32738      rotation: options.rotation !== undefined ? options.rotation : 0,
32739      scale: options.scale !== undefined ? options.scale : 1,
32740      displacement:
32741        options.displacement !== undefined ? options.displacement : [0, 0],
32742      declutterMode: options.declutterMode,
32743    });
32744
32745    /**
32746     * @private
32747     * @type {Object<number, HTMLCanvasElement>}
32748     */
32749    this.canvas_ = undefined;
32750
32751    /**
32752     * @private
32753     * @type {HTMLCanvasElement}
32754     */
32755    this.hitDetectionCanvas_ = null;
32756
32757    /**
32758     * @private
32759     * @type {import("./Fill.js").default}
32760     */
32761    this.fill_ = options.fill !== undefined ? options.fill : null;
32762
32763    /**
32764     * @private
32765     * @type {Array<number>}
32766     */
32767    this.origin_ = [0, 0];
32768
32769    /**
32770     * @private
32771     * @type {number}
32772     */
32773    this.points_ = options.points;
32774
32775    /**
32776     * @protected
32777     * @type {number}
32778     */
32779    this.radius_ =
32780      options.radius !== undefined ? options.radius : options.radius1;
32781
32782    /**
32783     * @private
32784     * @type {number|undefined}
32785     */
32786    this.radius2_ = options.radius2;
32787
32788    /**
32789     * @private
32790     * @type {number}
32791     */
32792    this.angle_ = options.angle !== undefined ? options.angle : 0;
32793
32794    /**
32795     * @private
32796     * @type {import("./Stroke.js").default}
32797     */
32798    this.stroke_ = options.stroke !== undefined ? options.stroke : null;
32799
32800    /**
32801     * @private
32802     * @type {import("../size.js").Size}
32803     */
32804    this.size_ = null;
32805
32806    /**
32807     * @private
32808     * @type {RenderOptions}
32809     */
32810    this.renderOptions_ = null;
32811
32812    this.render();
32813  }
32814
32815  /**
32816   * Clones the style.
32817   * @return {RegularShape} The cloned style.
32818   * @api
32819   */
32820  clone() {
32821    const scale = this.getScale();
32822    const style = new RegularShape({
32823      fill: this.getFill() ? this.getFill().clone() : undefined,
32824      points: this.getPoints(),
32825      radius: this.getRadius(),
32826      radius2: this.getRadius2(),
32827      angle: this.getAngle(),
32828      stroke: this.getStroke() ? this.getStroke().clone() : undefined,
32829      rotation: this.getRotation(),
32830      rotateWithView: this.getRotateWithView(),
32831      scale: Array.isArray(scale) ? scale.slice() : scale,
32832      displacement: this.getDisplacement().slice(),
32833      declutterMode: this.getDeclutterMode(),
32834    });
32835    style.setOpacity(this.getOpacity());
32836    return style;
32837  }
32838
32839  /**
32840   * Get the anchor point in pixels. The anchor determines the center point for the
32841   * symbolizer.
32842   * @return {Array<number>} Anchor.
32843   * @api
32844   */
32845  getAnchor() {
32846    const size = this.size_;
32847    if (!size) {
32848      return null;
32849    }
32850    const displacement = this.getDisplacement();
32851    const scale = this.getScaleArray();
32852    // anchor is scaled by renderer but displacement should not be scaled
32853    // so divide by scale here
32854    return [
32855      size[0] / 2 - displacement[0] / scale[0],
32856      size[1] / 2 + displacement[1] / scale[1],
32857    ];
32858  }
32859
32860  /**
32861   * Get the angle used in generating the shape.
32862   * @return {number} Shape's rotation in radians.
32863   * @api
32864   */
32865  getAngle() {
32866    return this.angle_;
32867  }
32868
32869  /**
32870   * Get the fill style for the shape.
32871   * @return {import("./Fill.js").default} Fill style.
32872   * @api
32873   */
32874  getFill() {
32875    return this.fill_;
32876  }
32877
32878  /**
32879   * Set the fill style.
32880   * @param {import("./Fill.js").default} fill Fill style.
32881   * @api
32882   */
32883  setFill(fill) {
32884    this.fill_ = fill;
32885    this.render();
32886  }
32887
32888  /**
32889   * @return {HTMLCanvasElement} Image element.
32890   */
32891  getHitDetectionImage() {
32892    if (!this.hitDetectionCanvas_) {
32893      this.createHitDetectionCanvas_(this.renderOptions_);
32894    }
32895    return this.hitDetectionCanvas_;
32896  }
32897
32898  /**
32899   * Get the image icon.
32900   * @param {number} pixelRatio Pixel ratio.
32901   * @return {HTMLCanvasElement} Image or Canvas element.
32902   * @api
32903   */
32904  getImage(pixelRatio) {
32905    let image = this.canvas_[pixelRatio];
32906    if (!image) {
32907      const renderOptions = this.renderOptions_;
32908      const context = createCanvasContext2D(
32909        renderOptions.size * pixelRatio,
32910        renderOptions.size * pixelRatio
32911      );
32912      this.draw_(renderOptions, context, pixelRatio);
32913
32914      image = context.canvas;
32915      this.canvas_[pixelRatio] = image;
32916    }
32917    return image;
32918  }
32919
32920  /**
32921   * Get the image pixel ratio.
32922   * @param {number} pixelRatio Pixel ratio.
32923   * @return {number} Pixel ratio.
32924   */
32925  getPixelRatio(pixelRatio) {
32926    return pixelRatio;
32927  }
32928
32929  /**
32930   * @return {import("../size.js").Size} Image size.
32931   */
32932  getImageSize() {
32933    return this.size_;
32934  }
32935
32936  /**
32937   * @return {import("../ImageState.js").default} Image state.
32938   */
32939  getImageState() {
32940    return ol_ImageState.LOADED;
32941  }
32942
32943  /**
32944   * Get the origin of the symbolizer.
32945   * @return {Array<number>} Origin.
32946   * @api
32947   */
32948  getOrigin() {
32949    return this.origin_;
32950  }
32951
32952  /**
32953   * Get the number of points for generating the shape.
32954   * @return {number} Number of points for stars and regular polygons.
32955   * @api
32956   */
32957  getPoints() {
32958    return this.points_;
32959  }
32960
32961  /**
32962   * Get the (primary) radius for the shape.
32963   * @return {number} Radius.
32964   * @api
32965   */
32966  getRadius() {
32967    return this.radius_;
32968  }
32969
32970  /**
32971   * Get the secondary radius for the shape.
32972   * @return {number|undefined} Radius2.
32973   * @api
32974   */
32975  getRadius2() {
32976    return this.radius2_;
32977  }
32978
32979  /**
32980   * Get the size of the symbolizer (in pixels).
32981   * @return {import("../size.js").Size} Size.
32982   * @api
32983   */
32984  getSize() {
32985    return this.size_;
32986  }
32987
32988  /**
32989   * Get the stroke style for the shape.
32990   * @return {import("./Stroke.js").default} Stroke style.
32991   * @api
32992   */
32993  getStroke() {
32994    return this.stroke_;
32995  }
32996
32997  /**
32998   * Set the stroke style.
32999   * @param {import("./Stroke.js").default} stroke Stroke style.
33000   * @api
33001   */
33002  setStroke(stroke) {
33003    this.stroke_ = stroke;
33004    this.render();
33005  }
33006
33007  /**
33008   * @param {function(import("../events/Event.js").default): void} listener Listener function.
33009   */
33010  listenImageChange(listener) {}
33011
33012  /**
33013   * Load not yet loaded URI.
33014   */
33015  load() {}
33016
33017  /**
33018   * @param {function(import("../events/Event.js").default): void} listener Listener function.
33019   */
33020  unlistenImageChange(listener) {}
33021
33022  /**
33023   * Calculate additional canvas size needed for the miter.
33024   * @param {string}
33024 lineJoin Line join
33025   * @param {number} strokeWidth Stroke width
33026   * @param {number} miterLimit Miter limit
33027   * @return {number} Additional canvas size needed
33028   * @private
33029   */
33030  calculateLineJoinSize_(lineJoin, strokeWidth, miterLimit) {
33031    if (
33032      strokeWidth === 0 ||
33033      this.points_ === Infinity ||
33034      (lineJoin !== 'bevel' && lineJoin !== 'miter')
33035    ) {
33036      return strokeWidth;
33037    }
33038    // m  | ^
33039    // i  | |\                  .
33040    // t >|  #\
33041    // e  | |\ \              .
33042    // r      \s\
33043    //      |  \t\          .                 .
33044    //          \r\                      .   .
33045    //      |    \o\      .          .  . . .
33046    //          e \k\            .  .    . .
33047    //      |      \e\  .    .  .       . .
33048    //       d      \ \  .  .          . .
33049    //      | _ _a_ _\#  .            . .
33050    //   r1          / `             . .
33051    //      |                       . .
33052    //       b     /               . .
33053    //      |                     . .
33054    //           / r2            . .
33055    //      |                        .   .
33056    //         /                           .   .
33057    //      |α                                   .   .
33058    //       /                                         .   .
33059    //      ° center
33060    let r1 = this.radius_;
33061    let r2 = this.radius2_ === undefined ? r1 : this.radius2_;
33062    if (r1 < r2) {
33063      const tmp = r1;
33064      r1 = r2;
33065      r2 = tmp;
33066    }
33067    const points =
33068      this.radius2_ === undefined ? this.points_ : this.points_ * 2;
33069    const alpha = (2 * Math.PI) / points;
33070    const a = r2 * Math.sin(alpha);
33071    const b = Math.sqrt(r2 * r2 - a * a);
33072    const d = r1 - b;
33073    const e = Math.sqrt(a * a + d * d);
33074    const miterRatio = e / a;
33075    if (lineJoin === 'miter' && miterRatio <= miterLimit) {
33076      return miterRatio * strokeWidth;
33077    }
33078    // Calculate the distnce from center to the stroke corner where
33079    // it was cut short because of the miter limit.
33080    //              l
33081    //        ----+---- <= distance from center to here is maxr
33082    //       /####|k ##\
33083    //      /#####^#####\
33084    //     /#### /+\# s #\
33085    //    /### h/+++\# t #\
33086    //   /### t/+++++\# r #\
33087    //  /### a/+++++++\# o #\
33088    // /### p/++ fill +\# k #\
33089    ///#### /+++++^+++++\# e #\
33090    //#####/+++++/+\+++++\#####\
33091    const k = strokeWidth / 2 / miterRatio;
33092    const l = (strokeWidth / 2) * (d / e);
33093    const maxr = Math.sqrt((r1 + k) * (r1 + k) + l * l);
33094    const bevelAdd = maxr - r1;
33095    if (this.radius2_ === undefined || lineJoin === 'bevel') {
33096      return bevelAdd * 2;
33097    }
33098    // If outer miter is over the miter limit the inner miter may reach through the
33099    // center and be longer than the bevel, same calculation as above but swap r1 / r2.
33100    const aa = r1 * Math.sin(alpha);
33101    const bb = Math.sqrt(r1 * r1 - aa * aa);
33102    const dd = r2 - bb;
33103    const ee = Math.sqrt(aa * aa + dd * dd);
33104    const innerMiterRatio = ee / aa;
33105    if (innerMiterRatio <= miterLimit) {
33106      const innerLength = (innerMiterRatio * strokeWidth) / 2 - r2 - r1;
33107      return 2 * Math.max(bevelAdd, innerLength);
33108    }
33109    return bevelAdd * 2;
33110  }
33111
33112  /**
33113   * @return {RenderOptions}  The render options
33114   * @protected
33115   */
33116  createRenderOptions() {
33117    let lineJoin = defaultLineJoin;
33118    let miterLimit = 0;
33119    let lineDash = null;
33120    let lineDashOffset = 0;
33121    let strokeStyle;
33122    let strokeWidth = 0;
33123
33124    if (this.stroke_) {
33125      strokeStyle = this.stroke_.getColor();
33126      if (strokeStyle === null) {
33127        strokeStyle = defaultStrokeStyle;
33128      }
33129      strokeStyle = asColorLike(strokeStyle);
33130      strokeWidth = this.stroke_.getWidth();
33131      if (strokeWidth === undefined) {
33132        strokeWidth = defaultLineWidth;
33133      }
33134      lineDash = this.stroke_.getLineDash();
33135      lineDashOffset = this.stroke_.getLineDashOffset();
33136      lineJoin = this.stroke_.getLineJoin();
33137      if (lineJoin === undefined) {
33138        lineJoin = defaultLineJoin;
33139      }
33140      miterLimit = this.stroke_.getMiterLimit();
33141      if (miterLimit === undefined) {
33142        miterLimit = defaultMiterLimit;
33143      }
33144    }
33145
33146    const add = this.calculateLineJoinSize_(lineJoin, strokeWidth, miterLimit);
33147    const maxRadius = Math.max(this.radius_, this.radius2_ || 0);
33148    const size = Math.ceil(2 * maxRadius + add);
33149
33150    return {
33151      strokeStyle: strokeStyle,
33152      strokeWidth: strokeWidth,
33153      size: size,
33154      lineDash: lineDash,
33155      lineDashOffset: lineDashOffset,
33156      lineJoin: lineJoin,
33157      miterLimit: miterLimit,
33158    };
33159  }
33160
33161  /**
33162   * @protected
33163   */
33164  render() {
33165    this.renderOptions_ = this.createRenderOptions();
33166    const size = this.renderOptions_.size;
33167    this.canvas_ = {};
33168    this.size_ = [size, size];
33169  }
33170
33171  /**
33172   * @private
33173   * @param {RenderOptions} renderOptions Render options.
33174   * @param {CanvasRenderingContext2D} context The rendering context.
33175   * @param {number} pixelRatio The pixel ratio.
33176   */
33177  draw_(renderOptions, context, pixelRatio) {
33178    context.scale(pixelRatio, pixelRatio);
33179    // set origin to canvas center
33180    context.translate(renderOptions.size / 2, renderOptions.size / 2);
33181
33182    this.createPath_(context);
33183
33184    if (this.fill_) {
33185      let color = this.fill_.getColor();
33186      if (color === null) {
33187        color = defaultFillStyle;
33188      }
33189      context.fillStyle = asColorLike(color);
33190      context.fill();
33191    }
33192    if (this.stroke_) {
33193      context.strokeStyle = renderOptions.strokeStyle;
33194      context.lineWidth = renderOptions.strokeWidth;
33195      if (renderOptions.lineDash) {
33196        context.setLineDash(renderOptions.lineDash);
33197        context.lineDashOffset = renderOptions.lineDashOffset;
33198      }
33199      context.lineJoin = renderOptions.lineJoin;
33200      context.miterLimit = renderOptions.miterLimit;
33201      context.stroke();
33202    }
33203  }
33204
33205  /**
33206   * @private
33207   * @param {RenderOptions} renderOptions Render options.
33208   */
33209  createHitDetectionCanvas_(renderOptions) {
33210    if (this.fill_) {
33211      let color = this.fill_.getColor();
33212
33213      // determine if fill is transparent (or pattern or gradient)
33214      let opacity = 0;
33215      if (typeof color === 'string') {
33216        color = asArray(color);
33217      }
33218      if (color === null) {
33219        opacity = 1;
33220      } else if (Array.isArray(color)) {
33221        opacity = color.length === 4 ? color[3] : 1;
33222      }
33223      if (opacity === 0) {
33224        // if a transparent fill style is set, create an extra hit-detection image
33225        // with a default fill style
33226        const context = createCanvasContext2D(
33227          renderOptions.size,
33228          renderOptions.size
33229        );
33230        this.hitDetectionCanvas_ = context.canvas;
33231
33232        this.drawHitDetectionCanvas_(renderOptions, context);
33233      }
33234    }
33235    if (!this.hitDetectionCanvas_) {
33236      this.hitDetectionCanvas_ = this.getImage(1);
33237    }
33238  }
33239
33240  /**
33241   * @private
33242   * @param {CanvasRenderingContext2D} context The context to draw in.
33243   */
33244  createPath_(context) {
33245    let points = this.points_;
33246    const radius = this.radius_;
33247    if (points === Infinity) {
33248      context.arc(0, 0, radius, 0, 2 * Math.PI);
33249    } else {
33250      const radius2 = this.radius2_ === undefined ? radius : this.radius2_;
33251      if (this.radius2_ !== undefined) {
33252        points *= 2;
33253      }
33254      const startAngle = this.angle_ - Math.PI / 2;
33255      const step = (2 * Math.PI) / points;
33256      for (let i = 0; i < points; i++) {
33257        const angle0 = startAngle + i * step;
33258        const radiusC = i % 2 === 0 ? radius : radius2;
33259        context.lineTo(radiusC * Math.cos(angle0), radiusC * Math.sin(angle0));
33260      }
33261      context.closePath();
33262    }
33263  }
33264
33265  /**
33266   * @private
33267   * @param {RenderOptions} renderOptions Render options.
33268   * @param {CanvasRenderingContext2D} context The context.
33269   */
33270  drawHitDetectionCanvas_(renderOptions, context) {
33271    // set origin to canvas center
33272    context.translate(renderOptions.size / 2, renderOptions.size / 2);
33273
33274    this.createPath_(context);
33275
33276    context.fillStyle = defaultFillStyle;
33277    context.fill();
33278    if (this.stroke_) {
33279      context.strokeStyle = renderOptions.strokeStyle;
33280      context.lineWidth = renderOptions.strokeWidth;
33281      if (renderOptions.lineDash) {
33282        context.setLineDash(renderOptions.lineDash);
33283        context.lineDashOffset = renderOptions.lineDashOffset;
33284      }
33285      context.lineJoin = renderOptions.lineJoin;
33286      context.miterLimit = renderOptions.miterLimit;
33287      context.stroke();
33288    }
33289  }
33290}
33291
33292/* harmony default export */ const style_RegularShape = (RegularShape);
33293
33294;// CONCATENATED MODULE: ./node_modules/ol/style/Circle.js
33295/**
33296 * @module ol/style/Circle
33297 */
33298
33299
33300
33301/**
33302 * @typedef {Object} Options
33303 * @property {import("./Fill.js").default} [fill] Fill style.
33304 * @property {number} radius Circle radius.
33305 * @property {import("./Stroke.js").default} [stroke] Stroke style.
33306 * @property {Array<number>} [displacement=[0,0]] displacement
33307 * @property {number|import("../size.js").Size} [scale=1] Scale. A two dimensional scale will produce an ellipse.
33308 * Unless two dimensional scaling is required a better result may be obtained with an appropriate setting for `radius`.
33309 * @property {number} [rotation=0] Rotation in radians
33310 * (positive rotation clockwise, meaningful only when used in conjunction with a two dimensional scale).
33311 * @property {boolean} [rotateWithView=false] Whether to rotate the shape with the view
33312 * (meaningful only when used in conjunction with a two dimensional scale).
33313 * @property {"declutter"|"obstacle"|"none"|undefined} [declutterMode] Declutter mode
33314 */
33315
33316/**
33317 * @classdesc
33318 * Set circle style for vector features.
33319 * @api
33320 */
33321class Circle_CircleStyle extends style_RegularShape {
33322  /**
33323   * @param {Options} [options] Options.
33324   */
33325  constructor(options) {
33326    options = options ? options : {radius: 5};
33327
33328    super({
33329      points: Infinity,
33330      fill: options.fill,
33331      radius: options.radius,
33332      stroke: options.stroke,
33333      scale: options.scale !== undefined ? options.scale : 1,
33334      rotation: options.rotation !== undefined ? options.rotation : 0,
33335      rotateWithView:
33336        options.rotateWithView !== undefined ? options.rotateWithView : false,
33337      displacement:
33338        options.displacement !== undefined ? options.displacement : [0, 0],
33339      declutterMode: options.declutterMode,
33340    });
33341  }
33342
33343  /**
33344   * Clones the style.
33345   * @return {CircleStyle} The cloned style.
33346   * @api
33347   */
33348  clone() {
33349    const scale = this.getScale();
33350    const style = new Circle_CircleStyle({
33351      fill: this.getFill() ? this.getFill().clone() : undefined,
33352      stroke: this.getStroke() ? this.getStroke().clone() : undefined,
33353      radius: this.getRadius(),
33354      scale: Array.isArray(scale) ? scale.slice() : scale,
33355      rotation: this.getRotation(),
33356      rotateWithView: this.getRotateWithView(),
33357      displacement: this.getDisplacement().slice(),
33358      declutterMode: this.getDeclutterMode(),
33359    });
33360    style.setOpacity(this.getOpacity());
33361    return style;
33362  }
33363
33364  /**
33365   * Set the circle radius.
33366   *
33367   * @param {number} radius Circle radius.
33368   * @api
33369   */
33370  setRadius(radius) {
33371    this.radius_ = radius;
33372    this.render();
33373  }
33374}
33375
33376/* harmony default export */ const Circle = (Circle_CircleStyle);
33377
33378;// CONCATENATED MODULE: ./node_modules/ol/style/Fill.js
33379/**
33380 * @module ol/style/Fill
33381 */
33382
33383/**
33384 * @typedef {Object} Options
33385 * @property {import("../color.js").Color|import("../colorlike.js").ColorLike|null} [color=null] A color, gradient or pattern.
33386 * See {@link module:ol/color~Color} and {@link module:ol/colorlike~ColorLike} for possible formats.
33387 * Default null; if null, the Canvas/renderer default black will be used.
33388 */
33389
33390/**
33391 * @classdesc
33392 * Set fill style for vector features.
33393 * @api
33394 */
33395class Fill_Fill {
33396  /**
33397   * @param {Options} [options] Options.
33398   */
33399  constructor(options) {
33400    options = options || {};
33401
33402    /**
33403     * @private
33404     * @type {import("../color.js").Color|import("../colorlike.js").ColorLike|null}
33405     */
33406    this.color_ = options.color !== undefined ? options.color : null;
33407  }
33408
33409  /**
33410   * Clones the style. The color is not cloned if it is an {@link module:ol/colorlike~ColorLike}.
33411   * @return {Fill} The cloned style.
33412   * @api
33413   */
33414  clone() {
33415    const color = this.getColor();
33416    return new Fill_Fill({
33417      color: Array.isArray(color) ? color.slice() : color || undefined,
33418    });
33419  }
33420
33421  /**
33422   * Get the fill color.
33423   * @return {import("../color.js").Color|import("../colorlike.js").ColorLike|null} Color.
33424   * @api
33425   */
33426  getColor() {
33427    return this.color_;
33428  }
33429
33430  /**
33431   * Set the color.
33432   *
33433   * @param {import("../color.js").Color|import("../colorlike.js").ColorLike|null} color Color.
33434   * @api
33435   */
33436  setColor(color) {
33437    this.color_ = color;
33438  }
33439}
33440
33441/* harmony default export */ const style_Fill = (Fill_Fill);
33442
33443;// CONCATENATED MODULE: ./node_modules/ol/style/Stroke.js
33444/**
33445 * @module ol/style/Stroke
33446 */
33447
33448/**
33449 * @typedef {Object} Options
33450 * @property {import("../color.js").Color|import("../colorlike.js").ColorLike} [color] A color, gradient or pattern.
33451 * See {@link module:ol/color~Color} and {@link module:ol/colorlike~ColorLike} for possible formats.
33452 * Default null; if null, the Canvas/renderer default black will be used.
33453 * @property {CanvasLineCap} [lineCap='round'] Line cap style: `butt`, `round`, or `square`.
33454 * @property {CanvasLineJoin} [lineJoin='round'] Line join style: `bevel`, `round`, or `miter`.
33455 * @property {Array<number>} [lineDash] Line dash pattern. Default is `null` (no dash).
33456 * @property {number} [lineDashOffset=0] Line dash offset.
33457 * @property {number} [miterLimit=10] Miter limit.
33458 * @property {number} [width] Width.
33459 */
33460
33461/**
33462 * @classdesc
33463 * Set stroke style for vector features.
33464 * Note that the defaults given are the Canvas defaults, which will be used if
33465 * option is not defined. The `get` functions return whatever was entered in
33466 * the options; they will not return the default.
33467 * @api
33468 */
33469class Stroke_Stroke {
33470  /**
33471   * @param {Options} [options] Options.
33472   */
33473  constructor(options) {
33474    options = options || {};
33475
33476    /**
33477     * @private
33478     * @type {import("../color.js").Color|import("../colorlike.js").ColorLike}
33479     */
33480    this.color_ = options.color !== undefined ? options.color : null;
33481
33482    /**
33483     * @private
33484     * @type {CanvasLineCap|undefined}
33485     */
33486    this.lineCap_ = options.lineCap;
33487
33488    /**
33489     * @private
33490     * @type {Array<number>|null}
33491     */
33492    this.lineDash_ = options.lineDash !== undefined ? options.lineDash : null;
33493
33494    /**
33495     * @private
33496     * @type {number|undefined}
33497     */
33498    this.lineDashOffset_ = options.lineDashOffset;
33499
33500    /**
33501     * @private
33502     * @type {CanvasLineJoin|undefined}
33503     */
33504    this.lineJoin_ = options.lineJoin;
33505
33506    /**
33507     * @private
33508     * @type {number|undefined}
33509     */
33510    this.miterLimit_ = options.miterLimit;
33511
33512    /**
33513     * @private
33514     * @type {number|undefined}
33515     */
33516    this.width_ = options.width;
33517  }
33518
33519  /**
33520   * Clones the style.
33521   * @return {Stroke} The cloned style.
33522   * @api
33523   */
33524  clone() {
33525    const color = this.getColor();
33526    return new Stroke_Stroke({
33527      color: Array.isArray(color) ? color.slice() : color || undefined,
33528      lineCap: this.getLineCap(),
33529      lineDash: this.getLineDash() ? this.getLineDash().slice() : undefined,
33530      lineDashOffset: this.getLineDashOffset(),
33531      lineJoin: this.getLineJoin(),
33532      miterLimit: this.getMiterLimit(),
33533      width: this.getWidth(),
33534    });
33535  }
33536
33537  /**
33538   * Get the stroke color.
33539   * @return {import("../color.js").Color|import("../colorlike.js").ColorLike} Color.
33540   * @api
33541   */
33542  getColor() {
33543    return this.color_;
33544  }
33545
33546  /**
33547   * Get the line cap type for the stroke.
33548   * @return {CanvasLineCap|undefined} Line cap.
33549   * @api
33550   */
33551  getLineCap() {
33552    return this.lineCap_;
33553  }
33554
33555  /**
33556   * Get the line dash style for the stroke.
33557   * @return {Array<number>|null} Line dash.
33558   * @api
33559   */
33560  getLineDash() {
33561    return this.lineDash_;
33562  }
33563
33564  /**
33565   * Get the line dash offset for the stroke.
33566   * @return {number|undefined} Line dash offset.
33567   * @api
33568   */
33569  getLineDashOffset() {
33570    return this.lineDashOffset_;
33571  }
33572
33573  /**
33574   * Get the line join type for the stroke.
33575   * @return {CanvasLineJoin|undefined} Line join.
33576   * @api
33577   */
33578  getLineJoin() {
33579    return this.lineJoin_;
33580  }
33581
33582  /**
33583   * Get the miter limit for the stroke.
33584   * @return {number|undefined} Miter limit.
33585   * @api
33586   */
33587  getMiterLimit() {
33588    return this.miterLimit_;
33589  }
33590
33591  /**
33592   * Get the stroke width.
33593   * @return {number|undefined} Width.
33594   * @api
33595   */
33596  getWidth() {
33597    return this.width_;
33598  }
33599
33600  /**
33601   * Set the color.
33602   *
33603   * @param {import("../color.js").Color|import("../colorlike.js").ColorLike} color Color.
33604   * @api
33605   */
33606  setColor(color) {
33607    this.color_ = color;
33608  }
33609
33610  /**
33611   * Set the line cap.
33612   *
33613   * @param {CanvasLineCap|undefined} lineCap Line cap.
33614   * @api
33615   */
33616  setLineCap(lineCap) {
33617    this.lineCap_ = lineCap;
33618  }
33619
33620  /**
33621   * Set the line dash.
33622   *
33623   * @param {Array<number>|null} lineDash Line dash.
33624   * @api
33625   */
33626  setLineDash(lineDash) {
33627    this.lineDash_ = lineDash;
33628  }
33629
33630  /**
33631   * Set the line dash offset.
33632   *
33633   * @param {number|undefined} lineDashOffset Line dash offset.
33634   * @api
33635   */
33636  setLineDashOffset(lineDashOffset) {
33637    this.lineDashOffset_ = lineDashOffset;
33638  }
33639
33640  /**
33641   * Set the line join.
33642   *
33643   * @param {CanvasLineJoin|undefined} lineJoin Line join.
33644   * @api
33645   */
33646  setLineJoin(lineJoin) {
33647    this.lineJoin_ = lineJoin;
33648  }
33649
33650  /**
33651   * Set the miter limit.
33652   *
33653   * @param {number|undefined} miterLimit Miter limit.
33654   * @api
33655   */
33656  setMiterLimit(miterLimit) {
33657    this.miterLimit_ = miterLimit;
33658  }
33659
33660  /**
33661   * Set the width.
33662   *
33663   * @param {number|undefined} width Width.
33664   * @api
33665   */
33666  setWidth(width) {
33667    this.width_ = width;
33668  }
33669}
33670
33671/* harmony default export */ const style_Stroke = (Stroke_Stroke);
33672
33673;// CONCATENATED MODULE: ./node_modules/ol/style/Style.js
33674/**
33675 * @module ol/style/Style
33676 */
33677
33678
33679
33680
33681
33682
33683/**
33684 * A function that takes an {@link module:ol/Feature~Feature} and a `{number}`
33685 * representing the view's resolution. The function should return a
33686 * {@link module:ol/style/Style~Style} or an array of them. This way e.g. a
33687 * vector layer can be styled. If the function returns `undefined`, the
33688 * feature will not be rendered.
33689 *
33690 * @typedef {function(import("../Feature.js").FeatureLike, number):(Style|Array<Style>|void)} StyleFunction
33691 */
33692
33693/**
33694 * A {@link Style}, an array of {@link Style}, or a {@link StyleFunction}.
33695 * @typedef {Style|Array<Style>|StyleFunction} StyleLike
33696 */
33697
33698/**
33699 * A function that takes an {@link module:ol/Feature~Feature} as argument and returns an
33700 * {@link module:ol/geom/Geometry~Geometry} that will be rendered and styled for the feature.
33701 *
33702 * @typedef {function(import("../Feature.js").FeatureLike):
33703 *     (import("../geom/Geometry.js").default|import("../render/Feature.js").default|undefined)} GeometryFunction
33704 */
33705
33706/**
33707 * Custom renderer function. Takes two arguments:
33708 *
33709 * 1. The pixel coordinates of the geometry in GeoJSON notation.
33710 * 2. The {@link module:ol/render~State} of the layer renderer.
33711 *
33712 * @typedef {function((import("../coordinate.js").Coordinate|Array<import("../coordinate.js").Coordinate>|Array<Array<import("../coordinate.js").Coordinate>>),import("../render.js").State): void} RenderFunction
33713 */
33714
33715/**
33716 * @typedef {Object} Options
33717 * @property {string|import("../geom/Geometry.js").default|GeometryFunction} [geometry] Feature property or geometry
33718 * or function returning a geometry to render for this style.
33719 * @property {import("./Fill.js").default} [fill] Fill style.
33720 * @property {import("./Image.js").default} [image] Image style.
33721 * @property {RenderFunction} [renderer] Custom renderer. When configured, `fill`, `stroke` and `image` will be
33722 * ignored, and the provided function will be called with each render frame for each geometry.
33723 * @property {RenderFunction} [hitDetectionRenderer] Custom renderer for hit detection. If provided will be used
33724 * in hit detection rendering.
33725 * @property {import("./Stroke.js").default} [stroke] Stroke style.
33726 * @property {import("./Text.js").default} [text] Text style.
33727 * @property {number} [zIndex] Z index.
33728 */
33729
33730/**
33731 * @classdesc
33732 * Container for vector feature rendering styles. Any changes made to the style
33733 * or its children through `set*()` methods will not take effect until the
33734 * feature or layer that uses the style is re-rendered.
33735 *
33736 * ## Feature styles
33737 *
33738 * If no style is defined, the following default style is used:
33739 * ```js
33740 *  import {Circle, Fill, Stroke, Style} from 'ol/style';
33741 *
33742 *  const fill = new Fill({
33743 *    color: 'rgba(255,255,255,0.4)',
33744 *  });
33745 *  const stroke = new Stroke({
33746 *    color: '#3399CC',
33747 *    width: 1.25,
33748 *  });
33749 *  const styles = [
33750 *    new Style({
33751 *      image: new Circle({
33752 *        fill: fill,
33753 *        stroke: stroke,
33754 *        radius: 5,
33755 *      }),
33756 *      fill: fill,
33757 *      stroke: stroke,
33758 *    }),
33759 *  ];
33760 * ```
33761 *
33762 * A separate editing style has the following defaults:
33763 * ```js
33764 *  import {Circle, Fill, Stroke, Style} from 'ol/style';
33765 *
33766 *  const styles = {};
33767 *  const white = [255, 255, 255, 1];
33768 *  const blue = [0, 153, 255, 1];
33769 *  const width = 3;
33770 *  styles['Polygon'] = [
33771 *    new Style({
33772 *      fill: new Fill({
33773 *        color: [255, 255, 255, 0.5],
33774 *      }),
33775 *    }),
33776 *  ];
33777 *  styles['MultiPolygon'] =
33778 *      styles['Polygon'];
33779 *  styles['LineString'] = [
33780 *    new Style({
33781 *      stroke: new Stroke({
33782 *        color: white,
33783 *        width: width + 2,
33784 *      }),
33785 *    }),
33786 *    new Style({
33787 *      stroke: new Stroke({
33788 *        color: blue,
33789 *        width: width,
33790 *      }),
33791 *    }),
33792 *  ];
33793 *  styles['MultiLineString'] = styles['LineString'];
33794 *
33795 *  styles['Circle'] = styles['Polygon'].concat(
33796 *    styles['LineString']
33797 *  );
33798 *
33799 *  styles['Point'] = [
33800 *    new Style({
33801 *      image: new Circle({
33802 *        radius: width * 2,
33803 *        fill: new Fill({
33804 *          color: blue,
33805 *        }),
33806 *        stroke: new Stroke({
33807 *          color: white,
33808 *          width: width / 2,
33809 *        }),
33810 *      }),
33811 *      zIndex: Infinity,
33812 *    }),
33813 *  ];
33814 *  styles['MultiPoint'] =
33815 *      styles['Point'];
33816 *  styles['GeometryCollection'] =
33817 *      styles['Polygon'].concat(
33818 *          styles['LineString'],
33819 *          styles['Point']
33820 *      );
33821 * ```
33822 *
33823 * @api
33824 */
33825class Style {
33826  /**
33827   * @param {Options} [options] Style options.
33828   */
33829  constructor(options) {
33830    options = options || {};
33831
33832    /**
33833     * @private
33834     * @type {string|import("../geom/Geometry.js").default|GeometryFunction}
33835     */
33836    this.geometry_ = null;
33837
33838    /**
33839     * @private
33840     * @type {!GeometryFunction}
33841     */
33842    this.geometryFunction_ = defaultGeometryFunction;
33843
33844    if (options.geometry !== undefined) {
33845      this.setGeometry(options.geometry);
33846    }
33847
33848    /**
33849     * @private
33850     * @type {import("./Fill.js").default}
33851     */
33852    this.fill_ = options.fill !== undefined ? options.fill : null;
33853
33854    /**
33855     * @private
33856     * @type {import("./Image.js").default}
33857     */
33858    this.image_ = options.image !== undefined ? options.image : null;
33859
33860    /**
33861     * @private
33862     * @type {RenderFunction|null}
33863     */
33864    this.renderer_ = options.renderer !== undefined ? options.renderer : null;
33865
33866    /**
33867     * @private
33868     * @type {RenderFunction|null}
33869     */
33870    this.hitDetectionRenderer_ =
33871      options.hitDetectionRenderer !== undefined
33872        ? options.hitDetectionRenderer
33873        : null;
33874
33875    /**
33876     * @private
33877     * @type {import("./Stroke.js").default}
33878     */
33879    this.stroke_ = options.stroke !== undefined ? options.stroke : null;
33880
33881    /**
33882     * @private
33883     * @type {import("./Text.js").default}
33884     */
33885    this.text_ = options.text !== undefined ? options.text : null;
33886
33887    /**
33888     * @private
33889     * @type {number|undefined}
33890     */
33891    this.zIndex_ = options.zIndex;
33892  }
33893
33894  /**
33895   * Clones the style.
33896   * @return {Style} The cloned style.
33897   * @api
33898   */
33899  clone() {
33900    let geometry = this.getGeometry();
33901    if (geometry && typeof geometry === 'object') {
33902      geometry = /** @type {import("../geom/Geometry.js").default} */ (
33903        geometry
33904      ).clone();
33905    }
33906    return new Style({
33907      geometry: geometry,
33908      fill: this.getFill() ? this.getFill().clone() : undefined,
33909      image: this.getImage() ? this.getImage().clone() : undefined,
33910      renderer: this.getRenderer(),
33911      stroke: this.getStroke() ? this.getStroke().clone() : undefined,
33912      text: this.getText() ? this.getText().clone() : undefined,
33913      zIndex: this.getZIndex(),
33914    });
33915  }
33916
33917  /**
33918   * Get the custom renderer function that was configured with
33919   * {@link #setRenderer} or the `renderer` constructor option.
33920   * @return {RenderFunction|null} Custom renderer function.
33921   * @api
33922   */
33923  getRenderer() {
33924    return this.renderer_;
33925  }
33926
33927  /**
33928   * Sets a custom renderer function for this style. When set, `fill`, `stroke`
33929   * and `image` options of the style will be ignored.
33930   * @param {RenderFunction|null} renderer Custom renderer function.
33931   * @api
33932   */
33933  setRenderer(renderer) {
33934    this.renderer_ = renderer;
33935  }
33936
33937  /**
33938   * Sets a custom renderer function for this style used
33939   * in hit detection.
33940   * @param {RenderFunction|null} renderer Custom renderer function.
33941   * @api
33942   */
33943  setHitDetectionRenderer(renderer) {
33944    this.hitDetectionRenderer_ = renderer;
33945  }
33946
33947  /**
33948   * Get the custom renderer function that was configured with
33949   * {@link #setHitDetectionRenderer} or the `hitDetectionRenderer` constructor option.
33950   * @return {RenderFunction|null} Custom renderer function.
33951   * @api
33952   */
33953  getHitDetectionRenderer() {
33954    return this.hitDetectionRenderer_;
33955  }
33956
33957  /**
33958   * Get the geometry to be rendered.
33959   * @return {string|import("../geom/Geometry.js").default|GeometryFunction}
33960   * Feature property or geometry or function that returns the geometry that will
33961   * be rendered with this style.
33962   * @api
33963   */
33964  getGeometry() {
33965    return this.geometry_;
33966  }
33967
33968  /**
33969   * Get the function used to generate a geometry for rendering.
33970   * @return {!GeometryFunction} Function that is called with a feature
33971   * and returns the geometry to render instead of the feature's geometry.
33972   * @api
33973   */
33974  getGeometryFunction() {
33975    return this.geometryFunction_;
33976  }
33977
33978  /**
33979   * Get the fill style.
33980   * @return {import("./Fill.js").default} Fill style.
33981   * @api
33982   */
33983  getFill() {
33984    return this.fill_;
33985  }
33986
33987  /**
33988   * Set the fill style.
33989   * @param {import("./Fill.js").default} fill Fill style.
33990   * @api
33991   */
33992  setFill(fill) {
33993    this.fill_ = fill;
33994  }
33995
33996  /**
33997   * Get the image style.
33998   * @return {import("./Image.js").default} Image style.
33999   * @api
34000   */
34001  getImage() {
34002    return this.image_;
34003  }
34004
34005  /**
34006   * Set the image style.
34007   * @param {import("./Image.js").default} image Image style.
34008   * @api
34009   */
34010  setImage(image) {
34011    this.image_ = image;
34012  }
34013
34014  /**
34015   * Get the stroke style.
34016   * @return {import("./Stroke.js").default} Stroke style.
34017   * @api
34018   */
34019  getStroke() {
34020    return this.stroke_;
34021  }
34022
34023  /**
34024   * Set the stroke style.
34025   * @param {import("./Stroke.js").default} stroke Stroke style.
34026   * @api
34027   */
34028  setStroke(stroke) {
34029    this.stroke_ = stroke;
34030  }
34031
34032  /**
34033   * Get the text style.
34034   * @return {import("./Text.js").default} Text style.
34035   * @api
34036   */
34037  getText() {
34038    return this.text_;
34039  }
34040
34041  /**
34042   * Set the text style.
34043   * @param {import("./Text.js").default} text Text style.
34044   * @api
34045   */
34046  setText(text) {
34047    this.text_ = text;
34048  }
34049
34050  /**
34051   * Get the z-index for the style.
34052   * @return {number|undefined} ZIndex.
34053   * @api
34054   */
34055  getZIndex() {
34056    return this.zIndex_;
34057  }
34058
34059  /**
34060   * Set a geometry that is rendered instead of the feature's geometry.
34061   *
34062   * @param {string|import("../geom/Geometry.js").default|GeometryFunction} geometry
34063   *     Feature property or geometry or function returning a geometry to render
34064   *     for this style.
34065   * @api
34066   */
34067  setGeometry(geometry) {
34068    if (typeof geometry === 'function') {
34069      this.geometryFunction_ = geometry;
34070    } else if (typeof geometry === 'string') {
34071      this.geometryFunction_ = function (feature) {
34072        return /** @type {import("../geom/Geometry.js").default} */ (
34073          feature.get(geometry)
34074        );
34075      };
34076    } else if (!geometry) {
34077      this.geometryFunction_ = defaultGeometryFunction;
34078    } else if (geometry !== undefined) {
34079      this.geometryFunction_ = function () {
34080        return /** @type {import("../geom/Geometry.js").default} */ (geometry);
34081      };
34082    }
34083    this.geometry_ = geometry;
34084  }
34085
34086  /**
34087   * Set the z-index.
34088   *
34089   * @param {number|undefined} zIndex ZIndex.
34090   * @api
34091   */
34092  setZIndex(zIndex) {
34093    this.zIndex_ = zIndex;
34094  }
34095}
34096
34097/**
34098 * Convert the provided object into a style function.  Functions passed through
34099 * unchanged.  Arrays of Style or single style objects wrapped in a
34100 * new style function.
34101 * @param {StyleFunction|Array<Style>|Style} obj
34102 *     A style function, a single style, or an array of styles.
34103 * @return {StyleFunction} A style function.
34104 */
34105function toFunction(obj) {
34106  let styleFunction;
34107
34108  if (typeof obj === 'function') {
34109    styleFunction = obj;
34110  } else {
34111    /**
34112     * @type {Array<Style>}
34113     */
34114    let styles;
34115    if (Array.isArray(obj)) {
34116      styles = obj;
34117    } else {
34118      asserts_assert(typeof (/** @type {?} */ (obj).getZIndex) === 'function', 41); // Expected an `Style` or an array of `Style`
34119      const style = /** @type {Style} */ (obj);
34120      styles = [style];
34121    }
34122    styleFunction = function () {
34123      return styles;
34124    };
34125  }
34126  return styleFunction;
34127}
34128
34129/**
34130 * @type {Array<Style>|null}
34131 */
34132let defaultStyles = null;
34133
34134/**
34135 * @param {import("../Feature.js").FeatureLike} feature Feature.
34136 * @param {number} resolution Resolution.
34137 * @return {Array<Style>} Style.
34138 */
34139function createDefaultStyle(feature, resolution) {
34140  // We don't use an immediately-invoked function
34141  // and a closure so we don't get an error at script evaluation time in
34142  // browsers that do not support Canvas. (import("./Circle.js").CircleStyle does
34143  // canvas.getContext('2d') at construction time, which will cause an.error
34144  // in such browsers.)
34145  if (!defaultStyles) {
34146    const fill = new style_Fill({
34147      color: 'rgba(255,255,255,0.4)',
34148    });
34149    const stroke = new style_Stroke({
34150      color: '#3399CC',
34151      width: 1.25,
34152    });
34153    defaultStyles = [
34154      new Style({
34155        image: new Circle({
34156          fill: fill,
34157          stroke: stroke,
34158          radius: 5,
34159        }),
34160        fill: fill,
34161        stroke: stroke,
34162      }),
34163    ];
34164  }
34165  return defaultStyles;
34166}
34167
34168/**
34169 * Default styles for editing features.
34170 * @return {Object<import("../geom/Geometry.js").Type, Array<Style>>}
34170 Styles
34171 */
34172function createEditingStyle() {
34173  /** @type {Object<import("../geom/Geometry.js").Type, Array<Style>>} */
34174  const styles = {};
34175  const white = [255, 255, 255, 1];
34176  const blue = [0, 153, 255, 1];
34177  const width = 3;
34178  styles['Polygon'] = [
34179    new Style({
34180      fill: new Fill({
34181        color: [255, 255, 255, 0.5],
34182      }),
34183    }),
34184  ];
34185  styles['MultiPolygon'] = styles['Polygon'];
34186
34187  styles['LineString'] = [
34188    new Style({
34189      stroke: new Stroke({
34190        color: white,
34191        width: width + 2,
34192      }),
34193    }),
34194    new Style({
34195      stroke: new Stroke({
34196        color: blue,
34197        width: width,
34198      }),
34199    }),
34200  ];
34201  styles['MultiLineString'] = styles['LineString'];
34202
34203  styles['Circle'] = styles['Polygon'].concat(styles['LineString']);
34204
34205  styles['Point'] = [
34206    new Style({
34207      image: new CircleStyle({
34208        radius: width * 2,
34209        fill: new Fill({
34210          color: blue,
34211        }),
34212        stroke: new Stroke({
34213          color: white,
34214          width: width / 2,
34215        }),
34216      }),
34217      zIndex: Infinity,
34218    }),
34219  ];
34220  styles['MultiPoint'] = styles['Point'];
34221
34222  styles['GeometryCollection'] = styles['Polygon'].concat(
34223    styles['LineString'],
34224    styles['Point']
34225  );
34226
34227  return styles;
34228}
34229
34230/**
34231 * Function that is called with a feature and returns its default geometry.
34232 * @param {import("../Feature.js").FeatureLike} feature Feature to get the geometry for.
34233 * @return {import("../geom/Geometry.js").default|import("../render/Feature.js").default|undefined} Geometry to render.
34234 */
34235function defaultGeometryFunction(feature) {
34236  return feature.getGeometry();
34237}
34238
34239/* harmony default export */ const style_Style = (Style);
34240
34241;// CONCATENATED MODULE: ./node_modules/ol/Image.js
34242/**
34243 * @module ol/Image
34244 */
34245
34246
34247
34248
34249
34250
34251
34252/**
34253 * A function that takes an {@link module:ol/Image~ImageWrapper} for the image and a
34254 * `{string}` for the src as arguments. It is supposed to make it so the
34255 * underlying image {@link module:ol/Image~ImageWrapper#getImage} is assigned the
34256 * content specified by the src. If not specified, the default is
34257 *
34258 *     function(image, src) {
34259 *       image.getImage().src = src;
34260 *     }
34261 *
34262 * Providing a custom `imageLoadFunction` can be useful to load images with
34263 * post requests or - in general - through XHR requests, where the src of the
34264 * image element would be set to a data URI when the content is loaded.
34265 *
34266 * @typedef {function(ImageWrapper, string): void} LoadFunction
34267 * @api
34268 */
34269
34270class ImageWrapper extends (/* unused pure expression or super */ null && (ImageBase)) {
34271  /**
34272   * @param {import("./extent.js").Extent} extent Extent.
34273   * @param {number|undefined} resolution Resolution.
34274   * @param {number} pixelRatio Pixel ratio.
34275   * @param {string} src Image source URI.
34276   * @param {?string} crossOrigin Cross origin.
34277   * @param {LoadFunction} imageLoadFunction Image load function.
34278   */
34279  constructor(
34280    extent,
34281    resolution,
34282    pixelRatio,
34283    src,
34284    crossOrigin,
34285    imageLoadFunction
34286  ) {
34287    super(extent, resolution, pixelRatio, ImageState.IDLE);
34288
34289    /**
34290     * @private
34291     * @type {string}
34292     */
34293    this.src_ = src;
34294
34295    /**
34296     * @private
34297     * @type {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement}
34298     */
34299    this.image_ = new Image();
34300    if (crossOrigin !== null) {
34301      this.image_.crossOrigin = crossOrigin;
34302    }
34303
34304    /**
34305     * @private
34306     * @type {?function():void}
34307     */
34308    this.unlisten_ = null;
34309
34310    /**
34311     * @protected
34312     * @type {import("./ImageState.js").default}
34313     */
34314    this.state = ImageState.IDLE;
34315
34316    /**
34317     * @private
34318     * @type {LoadFunction}
34319     */
34320    this.imageLoadFunction_ = imageLoadFunction;
34321  }
34322
34323  /**
34324   * @return {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} Image.
34325   * @api
34326   */
34327  getImage() {
34328    return this.image_;
34329  }
34330
34331  /**
34332   * Tracks loading or read errors.
34333   *
34334   * @private
34335   */
34336  handleImageError_() {
34337    this.state = ImageState.ERROR;
34338    this.unlistenImage_();
34339    this.changed();
34340  }
34341
34342  /**
34343   * Tracks successful image load.
34344   *
34345   * @private
34346   */
34347  handleImageLoad_() {
34348    if (this.resolution === undefined) {
34349      this.resolution = getHeight(this.extent) / this.image_.height;
34350    }
34351    this.state = ImageState.LOADED;
34352    this.unlistenImage_();
34353    this.changed();
34354  }
34355
34356  /**
34357   * Load the image or retry if loading previously failed.
34358   * Loading is taken care of by the tile queue, and calling this method is
34359   * only needed for preloading or for reloading in case of an error.
34360   * @api
34361   */
34362  load() {
34363    if (this.state == ImageState.IDLE || this.state == ImageState.ERROR) {
34364      this.state = ImageState.LOADING;
34365      this.changed();
34366      this.imageLoadFunction_(this, this.src_);
34367      this.unlisten_ = listenImage(
34368        this.image_,
34369        this.handleImageLoad_.bind(this),
34370        this.handleImageError_.bind(this)
34371      );
34372    }
34373  }
34374
34375  /**
34376   * @param {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} image Image.
34377   */
34378  setImage(image) {
34379    this.image_ = image;
34380    this.resolution = getHeight(this.extent) / this.image_.height;
34381  }
34382
34383  /**
34384   * Discards event handlers which listen for load completion or errors.
34385   *
34386   * @private
34387   */
34388  unlistenImage_() {
34389    if (this.unlisten_) {
34390      this.unlisten_();
34391      this.unlisten_ = null;
34392    }
34393  }
34394}
34395
34396/**
34397 * @param {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} image Image element.
34398 * @param {function():any} loadHandler Load callback function.
34399 * @param {function():any} errorHandler Error callback function.
34400 * @return {function():void} Callback to stop listening.
34401 */
34402function listenImage(image, loadHandler, errorHandler) {
34403  const img = /** @type {HTMLImageElement} */ (image);
34404  let listening = true;
34405  let decoding = false;
34406  let loaded = false;
34407
34408  const listenerKeys = [
34409    listenOnce(img, EventType.LOAD, function () {
34410      loaded = true;
34411      if (!decoding) {
34412        loadHandler();
34413      }
34414    }),
34415  ];
34416
34417  if (img.src && IMAGE_DECODE) {
34418    decoding = true;
34419    img
34420      .decode()
34421      .then(function () {
34422        if (listening) {
34423          loadHandler();
34424        }
34425      })
34426      .catch(function (error) {
34427        if (listening) {
34428          if (loaded) {
34429            loadHandler();
34430          } else {
34431            errorHandler();
34432          }
34433        }
34434      });
34435  } else {
34436    listenerKeys.push(listenOnce(img, EventType.ERROR, errorHandler));
34437  }
34438
34439  return function unlisten() {
34440    listening = false;
34441    listenerKeys.forEach(unlistenByKey);
34442  };
34443}
34444
34445/* harmony default export */ const ol_Image = ((/* unused pure expression or super */ null && (ImageWrapper)));
34446
34447;// CONCATENATED MODULE: ./node_modules/ol/style/IconImage.js
34448/**
34449 * @module ol/style/IconImage
34450 */
34451
34452
34453
34454
34455
34456
34457
34458
34459
34460/**
34461 * @type {CanvasRenderingContext2D}
34462 */
34463let taintedTestContext = null;
34464
34465class IconImage extends events_Target {
34466  /**
34467   * @param {HTMLImageElement|HTMLCanvasElement} image Image.
34468   * @param {string|undefined} src Src.
34469   * @param {import("../size.js").Size} size Size.
34470   * @param {?string} crossOrigin Cross origin.
34471   * @param {import("../ImageState.js").default} imageState Image state.
34472   * @param {import("../color.js").Color} color Color.
34473   */
34474  constructor(image, src, size, crossOrigin, imageState, color) {
34475    super();
34476
34477    /**
34478     * @private
34479     * @type {HTMLImageElement|HTMLCanvasElement}
34480     */
34481    this.hitDetectionImage_ = null;
34482
34483    /**
34484     * @private
34485     * @type {HTMLImageElement|HTMLCanvasElement}
34486     */
34487    this.image_ = image;
34488
34489    /**
34490     * @private
34491     * @type {string|null}
34492     */
34493    this.crossOrigin_ = crossOrigin;
34494
34495    /**
34496     * @private
34497     * @type {Object<number, HTMLCanvasElement>}
34498     */
34499    this.canvas_ = {};
34500
34501    /**
34502     * @private
34503     * @type {import("../color.js").Color}
34504     */
34505    this.color_ = color;
34506
34507    /**
34508     * @private
34509     * @type {?function():void}
34510     */
34511    this.unlisten_ = null;
34512
34513    /**
34514     * @private
34515     * @type {import("../ImageState.js").default}
34516     */
34517    this.imageState_ = imageState;
34518
34519    /**
34520     * @private
34521     * @type {import("../size.js").Size}
34522     */
34523    this.size_ = size;
34524
34525    /**
34526     * @private
34527     * @type {string|undefined}
34528     */
34529    this.src_ = src;
34530
34531    /**
34532     * @private
34533     */
34534    this.tainted_;
34535  }
34536
34537  /**
34538   * @private
34539   */
34540  initializeImage_() {
34541    this.image_ = new Image();
34542    if (this.crossOrigin_ !== null) {
34543      this.image_.crossOrigin = this.crossOrigin_;
34544    }
34545  }
34546
34547  /**
34548   * @private
34549   * @return {boolean} The image canvas is tainted.
34550   */
34551  isTainted_() {
34552    if (this.tainted_ === undefined && this.imageState_ === ol_ImageState.LOADED) {
34553      if (!taintedTestContext) {
34554        taintedTestContext = createCanvasContext2D(1, 1);
34555      }
34556      taintedTestContext.drawImage(this.image_, 0, 0);
34557      try {
34558        taintedTestContext.getImageData(0, 0, 1, 1);
34559        this.tainted_ = false;
34560      } catch (e) {
34561        taintedTestContext = null;
34562        this.tainted_ = true;
34563      }
34564    }
34565    return this.tainted_ === true;
34566  }
34567
34568  /**
34569   * @private
34570   */
34571  dispatchChangeEvent_() {
34572    this.dispatchEvent(EventType.CHANGE);
34573  }
34574
34575  /**
34576   * @private
34577   */
34578  handleImageError_() {
34579    this.imageState_ = ol_ImageState.ERROR;
34580    this.unlistenImage_();
34581    this.dispatchChangeEvent_();
34582  }
34583
34584  /**
34585   * @private
34586   */
34587  handleImageLoad_() {
34588    this.imageState_ = ol_ImageState.LOADED;
34589    if (this.size_) {
34590      this.image_.width = this.size_[0];
34591      this.image_.height = this.size_[1];
34592    } else {
34593      this.size_ = [this.image_.width, this.image_.height];
34594    }
34595    this.unlistenImage_();
34596    this.dispatchChangeEvent_();
34597  }
34598
34599  /**
34600   * @param {number} pixelRatio Pixel ratio.
34601   * @return {HTMLImageElement|HTMLCanvasElement} Image or Canvas element.
34602   */
34603  getImage(pixelRatio) {
34604    if (!this.image_) {
34605      this.initializeImage_();
34606    }
34607    this.replaceColor_(pixelRatio);
34608    return this.canvas_[pixelRatio] ? this.canvas_[pixelRatio] : this.image_;
34609  }
34610
34611  /**
34612   * @param {number} pixelRatio Pixel ratio.
34613   * @return {number} Image or Canvas element.
34614   */
34615  getPixelRatio(pixelRatio) {
34616    this.replaceColor_(pixelRatio);
34617    return this.canvas_[pixelRatio] ? pixelRatio : 1;
34618  }
34619
34620  /**
34621   * @return {import("../ImageState.js").default} Image state.
34622   */
34623  getImageState() {
34624    return this.imageState_;
34625  }
34626
34627  /**
34628   * @return {HTMLImageElement|HTMLCanvasElement} Image element.
34629   */
34630  getHitDetectionImage() {
34631    if (!this.image_) {
34632      this.initializeImage_();
34633    }
34634    if (!this.hitDetectionImage_) {
34635      if (this.isTainted_()) {
34636        const width = this.size_[0];
34637        const height = this.size_[1];
34638        const context = createCanvasContext2D(width, height);
34639        context.fillRect(0, 0, width, height);
34640        this.hitDetectionImage_ = context.canvas;
34641      } else {
34642        this.hitDetectionImage_ = this.image_;
34643      }
34644    }
34645    return this.hitDetectionImage_;
34646  }
34647
34648  /**
34649   * Get the size of the icon (in pixels).
34650   * @return {import("../size.js").Size} Image size.
34651   */
34652  getSize() {
34653    return this.size_;
34654  }
34655
34656  /**
34657   * @return {string|undefined} Image src.
34658   */
34659  getSrc() {
34660    return this.src_;
34661  }
34662
34663  /**
34664   * Load not yet loaded URI.
34665   */
34666  load() {
34667    if (this.imageState_ !== ol_ImageState.IDLE) {
34668      return;
34669    }
34670    if (!this.image_) {
34671      this.initializeImage_();
34672    }
34673
34674    this.imageState_ = ol_ImageState.LOADING;
34675    try {
34676      /** @type {HTMLImageElement} */ (this.image_).src = this.src_;
34677    } catch (e) {
34678      this.handleImageError_();
34679    }
34680    this.unlisten_ = listenImage(
34681      this.image_,
34682      this.handleImageLoad_.bind(this),
34683      this.handleImageError_.bind(this)
34684    );
34685  }
34686
34687  /**
34688   * @param {number} pixelRatio Pixel ratio.
34689   * @private
34690   */
34691  replaceColor_(pixelRatio) {
34692    if (
34693      !this.color_ ||
34694      this.canvas_[pixelRatio] ||
34695      this.imageState_ !== ol_ImageState.LOADED
34696    ) {
34697      return;
34698    }
34699
34700    const image = this.image_;
34701    const canvas = document.createElement('canvas');
34702    canvas.width = Math.ceil(image.width * pixelRatio);
34703    canvas.height = Math.ceil(image.height * pixelRatio);
34704
34705    const ctx = canvas.getContext('2d');
34706    ctx.scale(pixelRatio, pixelRatio);
34707    ctx.drawImage(image, 0, 0);
34708
34709    ctx.globalCompositeOperation = 'multiply';
34710    ctx.fillStyle = asString(this.color_);
34711    ctx.fillRect(0, 0, canvas.width / pixelRatio, canvas.height / pixelRatio);
34712
34713    ctx.globalCompositeOperation = 'destination-in';
34714    ctx.drawImage(image, 0, 0);
34715
34716    this.canvas_[pixelRatio] = canvas;
34717  }
34718
34719  /**
34720   * Discards event handlers which listen for load completion or errors.
34721   *
34722   * @private
34723   */
34724  unlistenImage_() {
34725    if (this.unlisten_) {
34726      this.unlisten_();
34727      this.unlisten_ = null;
34728    }
34729  }
34730}
34731
34732/**
34733 * @param {HTMLImageElement|HTMLCanvasElement} image Image.
34734 * @param {string} src Src.
34735 * @param {import("../size.js").Size} size Size.
34736 * @param {?string} crossOrigin Cross origin.
34737 * @param {import("../ImageState.js").default} imageState Image state.
34738 * @param {import("../color.js").Color} color Color.
34739 * @return {IconImage} Icon image.
34740 */
34741function IconImage_get(image, src, size, crossOrigin, imageState, color) {
34742  let iconImage = shared.get(src, crossOrigin, color);
34743  if (!iconImage) {
34744    iconImage = new IconImage(image, src, size, crossOrigin, imageState, color);
34745    shared.set(src, crossOrigin, color, iconImage);
34746  }
34747  return iconImage;
34748}
34749
34750/* harmony default export */ const style_IconImage = ((/* unused pure expression or super */ null && (IconImage)));
34751
34752;// CONCATENATED MODULE: ./node_modules/ol/style/Icon.js
34753/**
34754 * @module ol/style/Icon
34755 */
34756
34757
34758
34759
34760
34761
34762
34763
34764/**
34765 * @typedef {'fraction' | 'pixels'} IconAnchorUnits
34766 * Anchor unit can be either a fraction of the icon size or in pixels.
34767 */
34768
34769/**
34770 * @typedef {'bottom-left' | 'bottom-right' | 'top-left' | 'top-right'} IconOrigin
34771 * Icon origin. One of 'bottom-left', 'bottom-right', 'top-left', 'top-right'.
34772 */
34773
34774/**
34775 * @typedef {Object} Options
34776 * @property {Array<number>} [anchor=[0.5, 0.5]] Anchor. Default value is the icon center.
34777 * @property {IconOrigin}
34777 [anchorOrigin='top-left'] Origin of the anchor: `bottom-left`, `bottom-right`,
34778 * `top-left` or `top-right`.
34779 * @property {IconAnchorUnits} [anchorXUnits='fraction'] Units in which the anchor x value is
34780 * specified. A value of `'fraction'` indicates the x value is a fraction of the icon. A value of `'pixels'` indicates
34781 * the x value in pixels.
34782 * @property {IconAnchorUnits} [anchorYUnits='fraction'] Units in which the anchor y value is
34783 * specified. A value of `'fraction'` indicates the y value is a fraction of the icon. A value of `'pixels'` indicates
34784 * the y value in pixels.
34785 * @property {import("../color.js").Color|string} [color] Color to tint the icon. If not specified,
34786 * the icon will be left as is.
34787 * @property {null|string} [crossOrigin] The `crossOrigin` attribute for loaded images. Note that you must provide a
34788 * `crossOrigin` value if you want to access pixel data with the Canvas renderer.
34789 * See https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image for more detail.
34790 * @property {HTMLImageElement|HTMLCanvasElement} [img] Image object for the icon. If the `src` option is not provided then the
34791 * provided image must already be loaded. And in that case, it is required
34792 * to provide the size of the image, with the `imgSize` option.
34793 * @property {import("../size.js").Size} [imgSize] Image size in pixels. Only required if `img` is set and `src` is not.
34794 * The provided `imgSize` needs to match the actual size of the image.
34795 * @property {Array<number>} [displacement=[0, 0]] Displacement of the icon in pixels.
34796 * Positive values will shift the icon right and up.
34797 * @property {number} [opacity=1] Opacity of the icon.
34798 * @property {number|import("../size.js").Size} [scale=1] Scale.
34799 * @property {boolean} [rotateWithView=false] Whether to rotate the icon with the view.
34800 * @property {number} [rotation=0] Rotation in radians (positive rotation clockwise).
34801 * @property {Array<number>} [offset=[0, 0]] Offset which, together with `size` and `offsetOrigin`, defines the
34802 * sub-rectangle to use from the original (sprite) image.
34803 * @property {IconOrigin} [offsetOrigin='top-left'] Origin of the offset: `bottom-left`, `bottom-right`,
34804 * `top-left` or `top-right`.
34805 * @property {import("../size.js").Size} [size] Icon size in pixels. Used together with `offset` to define the
34806 * sub-rectangle to use from the original (sprite) image.
34807 * @property {string} [src] Image source URI.
34808 * @property {"declutter"|"obstacle"|"none"|undefined} [declutterMode] Declutter mode.
34809 */
34810
34811/**
34812 * @classdesc
34813 * Set icon style for vector features.
34814 * @api
34815 */
34816class Icon extends style_Image {
34817  /**
34818   * @param {Options} [options] Options.
34819   */
34820  constructor(options) {
34821    options = options || {};
34822
34823    /**
34824     * @type {number}
34825     */
34826    const opacity = options.opacity !== undefined ? options.opacity : 1;
34827
34828    /**
34829     * @type {number}
34830     */
34831    const rotation = options.rotation !== undefined ? options.rotation : 0;
34832
34833    /**
34834     * @type {number|import("../size.js").Size}
34835     */
34836    const scale = options.scale !== undefined ? options.scale : 1;
34837
34838    /**
34839     * @type {boolean}
34840     */
34841    const rotateWithView =
34842      options.rotateWithView !== undefined ? options.rotateWithView : false;
34843
34844    super({
34845      opacity: opacity,
34846      rotation: rotation,
34847      scale: scale,
34848      displacement:
34849        options.displacement !== undefined ? options.displacement : [0, 0],
34850      rotateWithView: rotateWithView,
34851      declutterMode: options.declutterMode,
34852    });
34853
34854    /**
34855     * @private
34856     * @type {Array<number>}
34857     */
34858    this.anchor_ = options.anchor !== undefined ? options.anchor : [0.5, 0.5];
34859
34860    /**
34861     * @private
34862     * @type {Array<number>}
34863     */
34864    this.normalizedAnchor_ = null;
34865
34866    /**
34867     * @private
34868     * @type {IconOrigin}
34869     */
34870    this.anchorOrigin_ =
34871      options.anchorOrigin !== undefined ? options.anchorOrigin : 'top-left';
34872
34873    /**
34874     * @private
34875     * @type {IconAnchorUnits}
34876     */
34877    this.anchorXUnits_ =
34878      options.anchorXUnits !== undefined ? options.anchorXUnits : 'fraction';
34879
34880    /**
34881     * @private
34882     * @type {IconAnchorUnits}
34883     */
34884    this.anchorYUnits_ =
34885      options.anchorYUnits !== undefined ? options.anchorYUnits : 'fraction';
34886
34887    /**
34888     * @private
34889     * @type {?string}
34890     */
34891    this.crossOrigin_ =
34892      options.crossOrigin !== undefined ? options.crossOrigin : null;
34893
34894    /**
34895     * @type {HTMLImageElement|HTMLCanvasElement}
34896     */
34897    const image = options.img !== undefined ? options.img : null;
34898
34899    /**
34900     * @private
34901     * @type {import("../size.js").Size|undefined}
34902     */
34903    this.imgSize_ = options.imgSize;
34904
34905    /**
34906     * @type {string|undefined}
34907     */
34908    let src = options.src;
34909
34910    asserts_assert(!(src !== undefined && image), 4); // `image` and `src` cannot be provided at the same time
34911    asserts_assert(!image || (image && this.imgSize_), 5); // `imgSize` must be set when `image` is provided
34912
34913    if ((src === undefined || src.length === 0) && image) {
34914      src = /** @type {HTMLImageElement} */ (image).src || getUid(image);
34915    }
34916    asserts_assert(src !== undefined && src.length > 0, 6); // A defined and non-empty `src` or `image` must be provided
34917
34918    /**
34919     * @type {import("../ImageState.js").default}
34920     */
34921    const imageState =
34922      options.src !== undefined ? ol_ImageState.IDLE : ol_ImageState.LOADED;
34923
34924    /**
34925     * @private
34926     * @type {import("../color.js").Color}
34927     */
34928    this.color_ = options.color !== undefined ? asArray(options.color) : null;
34929
34930    /**
34931     * @private
34932     * @type {import("./IconImage.js").default}
34933     */
34934    this.iconImage_ = IconImage_get(
34935      image,
34936      /** @type {string} */ (src),
34937      this.imgSize_ !== undefined ? this.imgSize_ : null,
34938      this.crossOrigin_,
34939      imageState,
34940      this.color_
34941    );
34942
34943    /**
34944     * @private
34945     * @type {Array<number>}
34946     */
34947    this.offset_ = options.offset !== undefined ? options.offset : [0, 0];
34948    /**
34949     * @private
34950     * @type {IconOrigin}
34951     */
34952    this.offsetOrigin_ =
34953      options.offsetOrigin !== undefined ? options.offsetOrigin : 'top-left';
34954
34955    /**
34956     * @private
34957     * @type {Array<number>}
34958     */
34959    this.origin_ = null;
34960
34961    /**
34962     * @private
34963     * @type {import("../size.js").Size}
34964     */
34965    this.size_ = options.size !== undefined ? options.size : null;
34966  }
34967
34968  /**
34969   * Clones the style. The underlying Image/HTMLCanvasElement is not cloned.
34970   * @return {Icon} The cloned style.
34971   * @api
34972   */
34973  clone() {
34974    const scale = this.getScale();
34975    return new Icon({
34976      anchor: this.anchor_.slice(),
34977      anchorOrigin: this.anchorOrigin_,
34978      anchorXUnits: this.anchorXUnits_,
34979      anchorYUnits: this.anchorYUnits_,
34980      color:
34981        this.color_ && this.color_.slice
34982          ? this.color_.slice()
34983          : this.color_ || undefined,
34984      crossOrigin: this.crossOrigin_,
34985      imgSize: this.imgSize_,
34986      offset: this.offset_.slice(),
34987      offsetOrigin: this.offsetOrigin_,
34988      opacity: this.getOpacity(),
34989      rotateWithView: this.getRotateWithView(),
34990      rotation: this.getRotation(),
34991      scale: Array.isArray(scale) ? scale.slice() : scale,
34992      size: this.size_ !== null ? this.size_.slice() : undefined,
34993      src: this.getSrc(),
34994      displacement: this.getDisplacement().slice(),
34995      declutterMode: this.getDeclutterMode(),
34996    });
34997  }
34998
34999  /**
35000   * Get the anchor point in pixels. The anchor determines the center point for the
35001   * symbolizer.
35002   * @return {Array<number>} Anchor.
35003   * @api
35004   */
35005  getAnchor() {
35006    let anchor = this.normalizedAnchor_;
35007    if (!anchor) {
35008      anchor = this.anchor_;
35009      const size = this.getSize();
35010      if (
35011        this.anchorXUnits_ == 'fraction' ||
35012        this.anchorYUnits_ == 'fraction'
35013      ) {
35014        if (!size) {
35015          return null;
35016        }
35017        anchor = this.anchor_.slice();
35018        if (this.anchorXUnits_ == 'fraction') {
35019          anchor[0] *= size[0];
35020        }
35021        if (this.anchorYUnits_ == 'fraction') {
35022          anchor[1] *= size[1];
35023        }
35024      }
35025
35026      if (this.anchorOrigin_ != 'top-left') {
35027        if (!size) {
35028          return null;
35029        }
35030        if (anchor === this.anchor_) {
35031          anchor = this.anchor_.slice();
35032        }
35033        if (
35034          this.anchorOrigin_ == 'top-right' ||
35035          this.anchorOrigin_ == 'bottom-right'
35036        ) {
35037          anchor[0] = -anchor[0] + size[0];
35038        }
35039        if (
35040          this.anchorOrigin_ == 'bottom-left' ||
35041          this.anchorOrigin_ == 'bottom-right'
35042        ) {
35043          anchor[1] = -anchor[1] + size[1];
35044        }
35045      }
35046      this.normalizedAnchor_ = anchor;
35047    }
35048    const displacement = this.getDisplacement();
35049    const scale = this.getScaleArray();
35050    // anchor is scaled by renderer but displacement should not be scaled
35051    // so divide by scale here
35052    return [
35053      anchor[0] - displacement[0] / scale[0],
35054      anchor[1] + displacement[1] / scale[1],
35055    ];
35056  }
35057
35058  /**
35059   * Set the anchor point. The anchor determines the center point for the
35060   * symbolizer.
35061   *
35062   * @param {Array<number>} anchor Anchor.
35063   * @api
35064   */
35065  setAnchor(anchor) {
35066    this.anchor_ = anchor;
35067    this.normalizedAnchor_ = null;
35068  }
35069
35070  /**
35071   * Get the icon color.
35072   * @return {import("../color.js").Color} Color.
35073   * @api
35074   */
35075  getColor() {
35076    return this.color_;
35077  }
35078
35079  /**
35080   * Get the image icon.
35081   * @param {number} pixelRatio Pixel ratio.
35082   * @return {HTMLImageElement|HTMLCanvasElement} Image or Canvas element.
35083   * @api
35084   */
35085  getImage(pixelRatio) {
35086    return this.iconImage_.getImage(pixelRatio);
35087  }
35088
35089  /**
35090   * Get the pixel ratio.
35091   * @param {number} pixelRatio Pixel ratio.
35092   * @return {number} The pixel ratio of the image.
35093   * @api
35094   */
35095  getPixelRatio(pixelRatio) {
35096    return this.iconImage_.getPixelRatio(pixelRatio);
35097  }
35098
35099  /**
35100   * @return {import("../size.js").Size} Image size.
35101   */
35102  getImageSize() {
35103    return this.iconImage_.getSize();
35104  }
35105
35106  /**
35107   * @return {import("../ImageState.js").default} Image state.
35108   */
35109  getImageState() {
35110    return this.iconImage_.getImageState();
35111  }
35112
35113  /**
35114   * @return {HTMLImageElement|HTMLCanvasElement} Image element.
35115   */
35116  getHitDetectionImage() {
35117    return this.iconImage_.getHitDetectionImage();
35118  }
35119
35120  /**
35121   * Get the origin of the symbolizer.
35122   * @return {Array<number>} Origin.
35123   * @api
35124   */
35125  getOrigin() {
35126    if (this.origin_) {
35127      return this.origin_;
35128    }
35129    let offset = this.offset_;
35130
35131    if (this.offsetOrigin_ != 'top-left') {
35132      const size = this.getSize();
35133      const iconImageSize = this.iconImage_.getSize();
35134      if (!size || !iconImageSize) {
35135        return null;
35136      }
35137      offset = offset.slice();
35138      if (
35139        this.offsetOrigin_ == 'top-right' ||
35140        this.offsetOrigin_ == 'bottom-right'
35141      ) {
35142        offset[0] = iconImageSize[0] - size[0] - offset[0];
35143      }
35144      if (
35145        this.offsetOrigin_ == 'bottom-left' ||
35146        this.offsetOrigin_ == 'bottom-right'
35147      ) {
35148        offset[1] = iconImageSize[1] - size[1] - offset[1];
35149      }
35150    }
35151    this.origin_ = offset;
35152    return this.origin_;
35153  }
35154
35155  /**
35156   * Get the image URL.
35157   * @return {string|undefined} Image src.
35158   * @api
35159   */
35160  getSrc() {
35161    return this.iconImage_.getSrc();
35162  }
35163
35164  /**
35165   * Get the size of the icon (in pixels).
35166   * @return {import("../size.js").Size} Image size.
35167   * @api
35168   */
35169  getSize() {
35170    return !this.size_ ? this.iconImage_.getSize() : this.size_;
35171  }
35172
35173  /**
35174   * @param {function(import("../events/Event.js").default): void} listener Listener function.
35175   */
35176  listenImageChange(listener) {
35177    this.iconImage_.addEventListener(EventType.CHANGE, listener);
35178  }
35179
35180  /**
35181   * Load not yet loaded URI.
35182   * When rendering a feature with an icon style, the vector renderer will
35183   * automatically call this method. However, you might want to call this
35184   * method yourself for preloading or other purposes.
35185   * @api
35186   */
35187  load() {
35188    this.iconImage_.load();
35189  }
35190
35191  /**
35192   * @param {function(import("../events/Event.js").default): void} listener Listener function.
35193   */
35194  unlistenImageChange(listener) {
35195    this.iconImage_.removeEventListener(EventType.CHANGE, listener);
35196  }
35197}
35198
35199/* harmony default export */ const style_Icon = (Icon);
35200
35201;// CONCATENATED MODULE: ./node_modules/ol/style/Text.js
35202/**
35203 * @module ol/style/Text
35204 */
35205
35206
35207
35208/**
35209 * @typedef {'point' | 'line'} TextPlacement
35210 * Default text placement is `'point'`. Note that
35211 * `'line'` requires the underlying geometry to be a {@link module:ol/geom/LineString~LineString},
35212 * {@link module:ol/geom/Polygon~Polygon}, {@link module:ol/geom/MultiLineString~MultiLineString} or
35213 * {@link module:ol/geom/MultiPolygon~MultiPolygon}.
35214 */
35215
35216/**
35217 * @typedef {'left' | 'center' | 'right'} TextJustify
35218 */
35219
35220/**
35221 * The default fill color to use if no fill was set at construction time; a
35222 * blackish `#333`.
35223 *
35224 * @const {string}
35225 */
35226const DEFAULT_FILL_COLOR = '#333';
35227
35228/**
35229 * @typedef {Object} Options
35230 * @property {string} [font] Font style as CSS `font` value, see:
35231 * https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/font. Default is `'10px sans-serif'`
35232 * @property {number} [maxAngle=Math.PI/4] When `placement` is set to `'line'`, allow a maximum angle between adjacent characters.
35233 * The expected value is in radians, and the default is 45° (`Math.PI / 4`).
35234 * @property {number} [offsetX=0] Horizontal text offset in pixels. A positive will shift the text right.
35235 * @property {number} [offsetY=0] Vertical text offset in pixels. A positive will shift the text down.
35236 * @property {boolean} [overflow=false] For polygon labels or when `placement` is set to `'line'`, allow text to exceed
35237 * the width of the polygon at the label position or the length of the path that it follows.
35238 * @property {TextPlacement} [placement='point'] Text placement.
35239 * @property {number|import("../size.js").Size} [scale] Scale.
35240 * @property {boolean} [rotateWithView=false] Whether to rotate the text with the view.
35241 * @property {number} [rotation=0] Rotation in radians (positive rotation clockwise).
35242 * @property {string|Array<string>} [text] Text content or rich text content. For plain text provide a string, which can
35243 * contain line breaks (`\n`). For rich text provide an array of text/font tuples. A tuple consists of the text to
35244 * render and the font to use (or `''` to use the text style's font). A line break has to be a separate tuple (i.e. `'\n', ''`).
35245 * **Example:** `['foo', 'bold 10px sans-serif', ' bar', 'italic 10px sans-serif', ' baz', '']` will yield "**foo** *bar* baz".
35246 * **Note:** Rich text is not supported for the immediate rendering API.
35247 * @property {CanvasTextAlign} [textAlign] Text alignment. Possible values: `'left'`, `'right'`, `'center'`, `'end'` or `'start'`.
35248 * Default is `'center'` for `placement: 'point'`. For `placement: 'line'`, the default is to let the renderer choose a
35249 * placement where `maxAngle` is not exceeded.
35250 * @property {TextJustify} [justify] Text justification within the text box.
35251 * If not set, text is justified towards the `textAlign` anchor.
35252 * Otherwise, use options `'left'`, `'center'`, or `'right'` to justify the text within the text box.
35253 * **Note:** `justify` is ignored for immediate rendering and also for `placement: 'line'`.
35254 * @property {CanvasTextBaseline} [textBaseline='middle'] Text base line. Possible values: `'bottom'`, `'top'`, `'middle'`, `'alphabetic'`,
35255 * `'hanging'`, `'ideographic'`.
35256 * @property {import("./Fill.js").default}
35256 [fill] Fill style. If none is provided, we'll use a dark fill-style (#333).
35257 * @property {import("./Stroke.js").default} [stroke] Stroke style.
35258 * @property {import("./Fill.js").default} [backgroundFill] Fill style for the text background when `placement` is
35259 * `'point'`. Default is no fill.
35260 * @property {import("./Stroke.js").default} [backgroundStroke] Stroke style for the text background  when `placement`
35261 * is `'point'`. Default is no stroke.
35262 * @property {Array<number>} [padding=[0, 0, 0, 0]] Padding in pixels around the text for decluttering and background. The order of
35263 * values in the array is `[top, right, bottom, left]`.
35264 */
35265
35266/**
35267 * @classdesc
35268 * Set text style for vector features.
35269 * @api
35270 */
35271class Text {
35272  /**
35273   * @param {Options} [options] Options.
35274   */
35275  constructor(options) {
35276    options = options || {};
35277
35278    /**
35279     * @private
35280     * @type {string|undefined}
35281     */
35282    this.font_ = options.font;
35283
35284    /**
35285     * @private
35286     * @type {number|undefined}
35287     */
35288    this.rotation_ = options.rotation;
35289
35290    /**
35291     * @private
35292     * @type {boolean|undefined}
35293     */
35294    this.rotateWithView_ = options.rotateWithView;
35295
35296    /**
35297     * @private
35298     * @type {number|import("../size.js").Size|undefined}
35299     */
35300    this.scale_ = options.scale;
35301
35302    /**
35303     * @private
35304     * @type {import("../size.js").Size}
35305     */
35306    this.scaleArray_ = toSize(options.scale !== undefined ? options.scale : 1);
35307
35308    /**
35309     * @private
35310     * @type {string|Array<string>|undefined}
35311     */
35312    this.text_ = options.text;
35313
35314    /**
35315     * @private
35316     * @type {CanvasTextAlign|undefined}
35317     */
35318    this.textAlign_ = options.textAlign;
35319
35320    /**
35321     * @private
35322     * @type {TextJustify|undefined}
35323     */
35324    this.justify_ = options.justify;
35325
35326    /**
35327     * @private
35328     * @type {CanvasTextBaseline|undefined}
35329     */
35330    this.textBaseline_ = options.textBaseline;
35331
35332    /**
35333     * @private
35334     * @type {import("./Fill.js").default}
35335     */
35336    this.fill_ =
35337      options.fill !== undefined
35338        ? options.fill
35339        : new style_Fill({color: DEFAULT_FILL_COLOR});
35340
35341    /**
35342     * @private
35343     * @type {number}
35344     */
35345    this.maxAngle_ =
35346      options.maxAngle !== undefined ? options.maxAngle : Math.PI / 4;
35347
35348    /**
35349     * @private
35350     * @type {TextPlacement}
35351     */
35352    this.placement_ =
35353      options.placement !== undefined ? options.placement : 'point';
35354
35355    /**
35356     * @private
35357     * @type {boolean}
35358     */
35359    this.overflow_ = !!options.overflow;
35360
35361    /**
35362     * @private
35363     * @type {import("./Stroke.js").default}
35364     */
35365    this.stroke_ = options.stroke !== undefined ? options.stroke : null;
35366
35367    /**
35368     * @private
35369     * @type {number}
35370     */
35371    this.offsetX_ = options.offsetX !== undefined ? options.offsetX : 0;
35372
35373    /**
35374     * @private
35375     * @type {number}
35376     */
35377    this.offsetY_ = options.offsetY !== undefined ? options.offsetY : 0;
35378
35379    /**
35380     * @private
35381     * @type {import("./Fill.js").default}
35382     */
35383    this.backgroundFill_ = options.backgroundFill
35384      ? options.backgroundFill
35385      : null;
35386
35387    /**
35388     * @private
35389     * @type {import("./Stroke.js").default}
35390     */
35391    this.backgroundStroke_ = options.backgroundStroke
35392      ? options.backgroundStroke
35393      : null;
35394
35395    /**
35396     * @private
35397     * @type {Array<number>|null}
35398     */
35399    this.padding_ = options.padding === undefined ? null : options.padding;
35400  }
35401
35402  /**
35403   * Clones the style.
35404   * @return {Text} The cloned style.
35405   * @api
35406   */
35407  clone() {
35408    const scale = this.getScale();
35409    return new Text({
35410      font: this.getFont(),
35411      placement: this.getPlacement(),
35412      maxAngle: this.getMaxAngle(),
35413      overflow: this.getOverflow(),
35414      rotation: this.getRotation(),
35415      rotateWithView: this.getRotateWithView(),
35416      scale: Array.isArray(scale) ? scale.slice() : scale,
35417      text: this.getText(),
35418      textAlign: this.getTextAlign(),
35419      justify: this.getJustify(),
35420      textBaseline: this.getTextBaseline(),
35421      fill: this.getFill() ? this.getFill().clone() : undefined,
35422      stroke: this.getStroke() ? this.getStroke().clone() : undefined,
35423      offsetX: this.getOffsetX(),
35424      offsetY: this.getOffsetY(),
35425      backgroundFill: this.getBackgroundFill()
35426        ? this.getBackgroundFill().clone()
35427        : undefined,
35428      backgroundStroke: this.getBackgroundStroke()
35429        ? this.getBackgroundStroke().clone()
35430        : undefined,
35431      padding: this.getPadding() || undefined,
35432    });
35433  }
35434
35435  /**
35436   * Get the `overflow` configuration.
35437   * @return {boolean} Let text overflow the length of the path they follow.
35438   * @api
35439   */
35440  getOverflow() {
35441    return this.overflow_;
35442  }
35443
35444  /**
35445   * Get the font name.
35446   * @return {string|undefined} Font.
35447   * @api
35448   */
35449  getFont() {
35450    return this.font_;
35451  }
35452
35453  /**
35454   * Get the maximum angle between adjacent characters.
35455   * @return {number} Angle in radians.
35456   * @api
35457   */
35458  getMaxAngle() {
35459    return this.maxAngle_;
35460  }
35461
35462  /**
35463   * Get the label placement.
35464   * @return {TextPlacement} Text placement.
35465   * @api
35466   */
35467  getPlacement() {
35468    return this.placement_;
35469  }
35470
35471  /**
35472   * Get the x-offset for the text.
35473   * @return {number} Horizontal text offset.
35474   * @api
35475   */
35476  getOffsetX() {
35477    return this.offsetX_;
35478  }
35479
35480  /**
35481   * Get the y-offset for the text.
35482   * @return {number} Vertical text offset.
35483   * @api
35484   */
35485  getOffsetY() {
35486    return this.offsetY_;
35487  }
35488
35489  /**
35490   * Get the fill style for the text.
35491   * @return {import("./Fill.js").default} Fill style.
35492   * @api
35493   */
35494  getFill() {
35495    return this.fill_;
35496  }
35497
35498  /**
35499   * Determine whether the text rotates with the map.
35500   * @return {boolean|undefined} Rotate with map.
35501   * @api
35502   */
35503  getRotateWithView() {
35504    return this.rotateWithView_;
35505  }
35506
35507  /**
35508   * Get the text rotation.
35509   * @return {number|undefined} Rotation.
35510   * @api
35511   */
35512  getRotation() {
35513    return this.rotation_;
35514  }
35515
35516  /**
35517   * Get the text scale.
35518   * @return {number|import("../size.js").Size|undefined} Scale.
35519   * @api
35520   */
35521  getScale() {
35522    return this.scale_;
35523  }
35524
35525  /**
35526   * Get the symbolizer scale array.
35527   * @return {import("../size.js").Size} Scale array.
35528   */
35529  getScaleArray() {
35530    return this.scaleArray_;
35531  }
35532
35533  /**
35534   * Get the stroke style for the text.
35535   * @return {import("./Stroke.js").default} Stroke style.
35536   * @api
35537   */
35538  getStroke() {
35539    return this.stroke_;
35540  }
35541
35542  /**
35543   * Get the text to be rendered.
35544   * @return {string|Array<string>|undefined} Text.
35545   * @api
35546   */
35547  getText() {
35548    return this.text_;
35549  }
35550
35551  /**
35552   * Get the text alignment.
35553   * @return {CanvasTextAlign|undefined} Text align.
35554   * @api
35555   */
35556  getTextAlign() {
35557    return this.textAlign_;
35558  }
35559
35560  /**
35561   * Get the justification.
35562   * @return {TextJustify|undefined} Justification.
35563   * @api
35564   */
35565  getJustify() {
35566    return this.justify_;
35567  }
35568
35569  /**
35570   * Get the text baseline.
35571   * @return {CanvasTextBaseline|undefined} Text baseline.
35572   * @api
35573   */
35574  getTextBaseline() {
35575    return this.textBaseline_;
35576  }
35577
35578  /**
35579   * Get the background fill style for the text.
35580   * @return {import("./Fill.js").default} Fill style.
35581   * @api
35582   */
35583  getBackgroundFill() {
35584    return this.backgroundFill_;
35585  }
35586
35587  /**
35588   * Get the background stroke style for the text.
35589   * @return {import("./Stroke.js").default} Stroke style.
35590   * @api
35591   */
35592  getBackgroundStroke() {
35593    return this.backgroundStroke_;
35594  }
35595
35596  /**
35597   * Get the padding for the text.
35598   * @return {Array<number>|null} Padding.
35599   * @api
35600   */
35601  getPadding() {
35602    return this.padding_;
35603  }
35604
35605  /**
35606   * Set the `overflow` property.
35607   *
35608   * @param {boolean} overflow Let text overflow the path that it follows.
35609   * @api
35610   */
35611  setOverflow(overflow) {
35612    this.overflow_ = overflow;
35613  }
35614
35615  /**
35616   * Set the font.
35617   *
35618   * @param {string|undefined} font Font.
35619   * @api
35620   */
35621  setFont(font) {
35622    this.font_ = font;
35623  }
35624
35625  /**
35626   * Set the maximum angle between adjacent characters.
35627   *
35628   * @param {number} maxAngle Angle in radians.
35629   * @api
35630   */
35631  setMaxAngle(maxAngle) {
35632    this.maxAngle_ = maxAngle;
35633  }
35634
35635  /**
35636   * Set the x offset.
35637   *
35638   * @param {number} offsetX Horizontal text offset.
35639   * @api
35640   */
35641  setOffsetX(offsetX) {
35642    this.offsetX_ = offsetX;
35643  }
35644
35645  /**
35646   * Set the y offset.
35647   *
35648   * @param {number} offsetY Vertical text offset.
35649   * @api
35650   */
35651  setOffsetY(offsetY) {
35652    this.offsetY_ = offsetY;
35653  }
35654
35655  /**
35656   * Set the text placement.
35657   *
35658   * @param {TextPlacement} placement Placement.
35659   * @api
35660   */
35661  setPlacement(placement) {
35662    this.placement_ = placement;
35663  }
35664
35665  /**
35666   * Set whether to rotate the text with the view.
35667   *
35668   * @param {boolean} rotateWithView Rotate with map.
35669   * @api
35670   */
35671  setRotateWithView(rotateWithView) {
35672    this.rotateWithView_ = rotateWithView;
35673  }
35674
35675  /**
35676   * Set the fill.
35677   *
35678   * @param {import("./Fill.js").default} fill Fill style.
35679   * @api
35680   */
35681  setFill(fill) {
35682    this.fill_ = fill;
35683  }
35684
35685  /**
35686   * Set the rotation.
35687   *
35688   * @param {number|undefined} rotation Rotation.
35689   * @api
35690   */
35691  setRotation(rotation) {
35692    this.rotation_ = rotation;
35693  }
35694
35695  /**
35696   * Set the scale.
35697   *
35698   * @param {number|import("../size.js").Size|undefined} scale Scale.
35699   * @api
35700   */
35701  setScale(scale) {
35702    this.scale_ = scale;
35703    this.scaleArray_ = toSize(scale !== undefined ? scale : 1);
35704  }
35705
35706  /**
35707   * Set the stroke.
35708   *
35709   * @param {import("./Stroke.js").default} stroke Stroke style.
35710   * @api
35711   */
35712  setStroke(stroke) {
35713    this.stroke_ = stroke;
35714  }
35715
35716  /**
35717   * Set the text.
35718   *
35719   * @param {string|Array<string>|undefined} text Text.
35720   * @api
35721   */
35722  setText(text) {
35723    this.text_ = text;
35724  }
35725
35726  /**
35727   * Set the text alignment.
35728   *
35729   * @param {CanvasTextAlign|undefined} textAlign Text align.
35730   * @api
35731   */
35732  setTextAlign(textAlign) {
35733    this.textAlign_ = textAlign;
35734  }
35735
35736  /**
35737   * Set the justification.
35738   *
35739   * @param {TextJustify|undefined} justify Justification.
35740   * @api
35741   */
35742  setJustify(justify) {
35743    this.justify_ = justify;
35744  }
35745
35746  /**
35747   * Set the text baseline.
35748   *
35749   * @param {CanvasTextBaseline|undefined} textBaseline Text baseline.
35750   * @api
35751   */
35752  setTextBaseline(textBaseline) {
35753    this.textBaseline_ = textBaseline;
35754  }
35755
35756  /**
35757   * Set the background fill.
35758   *
35759   * @param {import("./Fill.js").default} fill Fill style.
35760   * @api
35761   */
35762  setBackgroundFill(fill) {
35763    this.backgroundFill_ = fill;
35764  }
35765
35766  /**
35767   * Set the background stroke.
35768   *
35769   * @param {import("./Stroke.js").default} stroke Stroke style.
35770   * @api
35771   */
35772  setBackgroundStroke(stroke) {
35773    this.backgroundStroke_ = stroke;
35774  }
35775
35776  /**
35777   * Set the padding (`[top, right, bottom, left]`).
35778   *
35779   * @param {Array<number>|null} padding Padding.
35780   * @api
35781   */
35782  setPadding(padding) {
35783    this.padding_ = padding;
35784  }
35785}
35786
35787/* harmony default export */ const style_Text = (Text);
35788
35789;// CONCATENATED MODULE: ./node_modules/ol/style/flat.js
35790/**
35791 * @module ol/style/flat
35792 */
35793
35794
35795
35796
35797
35798
35799
35800
35801
35802/**
35803 * For static styling, the [layer.setStyle()]{@link module:ol/layer/Vector~VectorLayer#setStyle} method
35804 * can be called with an object literal that has fill, stroke, text, icon, regular shape, and/or circle properties.
35805 * @api
35806 *
35807 * @typedef {FlatFill & FlatStroke & FlatText & FlatIcon & FlatShape & FlatCircle} FlatStyle
35808 */
35809
35810/**
35811 * A flat style literal or an array of the same.
35812 *
35813 * @typedef {FlatStyle|Array<FlatStyle>} FlatStyleLike
35814 */
35815
35816/**
35817 * Fill style properties applied to polygon features.
35818 *
35819 * @typedef {Object} FlatFill
35820 * @property {import("../color.js").Color|import("../colorlike.js").ColorLike} [fill-color] The fill color.
35821 */
35822
35823/**
35824 * Stroke style properties applied to line strings and polygon boundaries.  To apply a stroke, at least one of
35825 * `stroke-color` or `stroke-width` must be provided.
35826 *
35827 * @typedef {Object} FlatStroke
35828 * @property {import("../color.js").Color|import("../colorlike.js").ColorLike} [stroke-color] The stroke color.
35829 * @property {number} [stroke-width] Stroke pixel width.
35830 * @property {CanvasLineCap} [stroke-line-cap='round'] Line cap style: `butt`, `round`, or `square`.
35831 * @property {CanvasLineJoin} [stroke-line-join='round'] Line join style: `bevel`, `round`, or `miter`.
35832 * @property {Array<number>} [stroke-line-dash] Line dash pattern.
35833 * @property {number} [stroke-line-dash-offset=0] Line dash offset.
35834 * @property {number} [stroke-miter-limit=10] Miter limit.
35835 */
35836
35837/**
35838 * Label style properties applied to all features.  At a minimum, a `text-value` must be provided.
35839 *
35840 * @typedef {Object} FlatText
35841 * @property {string|Array<string>} [text-value] Text content or rich text content. For plain text provide a string, which can
35842 * contain line breaks (`\n`). For rich text provide an array of text/font tuples. A tuple consists of the text to
35843 * render and the font to use (or `''` to use the text style's font). A line break has to be a separate tuple (i.e. `'\n', ''`).
35844 * **Example:** `['foo', 'bold 10px sans-serif', ' bar', 'italic 10px sans-serif', ' baz', '']` will yield "**foo** *bar* baz".
35845 * **Note:** Rich text is not supported for the immediate rendering API.
35846 * @property {string} [text-font] Font style as CSS `font` value, see:
35847 * https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/font. Default is `'10px sans-serif'`
35848 * @property {number} [text-max-angle=Math.PI/4] When `text-placement` is set to `'line'`, allow a maximum angle between adjacent characters.
35849 * The expected value is in radians, and the default is 45° (`Math.PI / 4`).
35850 * @property {number} [text-offset-x=0] Horizontal text offset in pixels. A positive will shift the text right.
35851 * @property {number} [text-offset-y=0] Vertical text offset in pixels. A positive will shift the text down.
35852 * @property {boolean} [text-overflow=false] For polygon labels or when `placement` is set to `'line'`, allow text to exceed
35853 * the width of the polygon at the label position or the length of the path that it follows.
35854 * @property {import("./Text.js").TextPlacement} [text-placement='point'] Text placement.
35855 * @property {number|import("../size.js").Size} [text-scale] Scale.
35856 * @property {boolean} [text-rotate-with-view=false] Whether to rotate the text with the view.
35857 * @property {number} [text-rotation=0] Rotation in radians (positive rotation clockwise).
35858 * @property {CanvasTextAlign} [text-align] Text alignment. Possible values: `'left'`, `'right'`, `'center'`, `'end'` or `'start'`.
35859 * Default is `'center'` for `text-placement: 'point'`. For `text-placement: 'line'`, the default is to let the renderer choose a
35860 * placement where `text-max-angle` is not exceeded.
35861 * @property {import('./Text.js').TextJustify} [text-justify] Text justification within the text box.
35862 * If not set, text is justified towards the `textAlign` anchor.
35863 * Otherwise, use options `'left'`, `'center'`, or `'right'` to justify the text within the text box.
35864 * **Note:** `text-justify` is ignored for immediate rendering and also for `text-placement: 'line'`.
35865 * @property {CanvasTextBaseline} [text-baseline='middle'] Text base line. Possible values: `'bottom'`, `'top'`, `'middle'`, `'alphabetic'`,
35866 * `'hanging'`, `'ideographic'`.
35867 * @property {Array<number>} [text-padding=[0, 0, 0, 0]] Padding in pixels around the text for decluttering and background. The order of
35868 * values in the array is `[top, right, bottom, left]`.
35869 * @property {import("../color.js").Color|import("../colorlike.js").ColorLike} [text-fill-color] The fill color.
35870 * @property {import("../color.js").Color|import("../colorlike.js").ColorLike} [text-background-fill-color] The fill color.
35871 * @property {import("../color.js").Color|import("../colorlike.js").ColorLike} [text-stroke-color] The stroke color.
35872 * @property {CanvasLineCap} [text-stroke-line-cap='round'] Line cap style: `butt`, `round`, or `square`.
35873 * @property {CanvasLineJoin} [text-stroke-line-join='round'] Line join style: `bevel`, `round`, or `miter`.
35874 * @property {Array<number>} [text-stroke-line-dash] Line dash pattern.
35875 * @property {number} [text-stroke-line-dash-offset=0] Line dash offset.
35876 * @property {number} [text-stroke-miter-limit=10] Miter limit.
35877 * @property {number} [text-stroke-width] Stroke pixel width.
35878 * @property {import("../color.js").Color|import("../colorlike.js").ColorLike} [text-background-stroke-color] The stroke color.
35879 * @property {CanvasLineCap} [text-background-stroke-line-cap='round'] Line cap style: `butt`, `round`, or `square`.
35880 * @property {CanvasLineJoin} [text-background-stroke-line-join='round'] Line join style: `bevel`, `round`, or `miter`.
35881 * @property {Array<number>} [text-background-stroke-line-dash] Line dash pattern.
35882 * @property {number} [text-background-stroke-line-dash-offset=0] Line dash offset.
35883 * @property {number} [text-background-stroke-miter-limit=10] Miter limit.
35884 * @property {number} [text-background-stroke-width] Stroke pixel width.
35885 */
35886
35887/**
35888 * Icon style properties applied to point features.  One of `icon-src` or `icon-img` must be provided to render
35889 * points with an icon.
35890 *
35891 * @typedef {Object} FlatIcon
35892 * @property {string} [icon-src] Image source URI.
35893 * @property {HTMLImageElement|HTMLCanvasElement} [icon-img] Image object for the icon. If the `icon-src` option is not provided then the
35894 * provided image must already be loaded. And in that case, it is required
35895 * to provide the size of the image, with the `icon-img-size` option.
35896 * @property {import("../size.js").Size} [icon-img-size] Image size in pixels. Only required if `icon-img` is set and `icon-src` is not.
35897 * The provided size needs to match the actual size of the image.
35898 * @property {Array<number>} [icon-anchor=[0.5, 0.5]] Anchor. Default value is the icon center.
35899 * @property {import("./Icon.js").IconOrigin} [icon-anchor-origin='top-left'] Origin of the anchor: `bottom-left`, `bottom-right`,
35900 * `top-left` or `top-right`.
35901 * @property {import("./Icon.js").IconAnchorUnits} [icon-anchor-x-units='fraction'] Units in which the anchor x value is
35902 * specified. A value of `'fraction'` indicates the x value is a fraction of the icon. A value of `'pixels'` indicates
35903 * the x value in pixels.
35904 * @property {import("./Icon.js").IconAnchorUnits} [icon-anchor-y-units='fraction'] Units in which the anchor y value is
35905 * specified. A value of `'fraction'` indicates the y value is a fraction of the icon. A value of `'pixels'` indicates
35906 * the y value in pixels.
35907 * @property {import("../color.js").Color|string} [icon-color] Color to tint the icon. If not specified,
35908 * the icon will be left as is.
35909 * @property {null|string} [icon-cross-origin] The `crossOrigin` attribute for loaded images. Note that you must provide a
35910 * `icon-cross-origin` value if you want to access pixel data with the Canvas renderer.
35911 * See https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image for more detail.
35912 * @property {Array<number>} [icon-offset=[0, 0]] Offset, which, together with the size and the offset origin, define the
35913 * sub-rectangle to use from the original icon image.
35914 * @property {Array<number>} [icon-displacement=[0,0]] Displacement of the icon.
35915 * @property {import("./Icon.js").IconOrigin}
35915 [icon-offset-origin='top-left'] Origin of the offset: `bottom-left`, `bottom-right`,
35916 * `top-left` or `top-right`.
35917 * @property {number} [icon-opacity=1] Opacity of the icon.
35918 * @property {number|import("../size.js").Size} [icon-scale=1] Scale.
35919 * @property {number} [icon-rotation=0] Rotation in radians (positive rotation clockwise).
35920 * @property {boolean} [icon-rotate-with-view=false] Whether to rotate the icon with the view.
35921 * @property {import("../size.js").Size} [icon-size] Icon size in pixel. Can be used together with `icon-offset` to define the
35922 * sub-rectangle to use from the origin (sprite) icon image.
35923 * @property {"declutter"|"obstacle"|"none"|undefined} [icon-declutter-mode] Declutter mode
35924 */
35925
35926/**
35927 * Regular shape style properties for rendering point features.  At least `shape-points` must be provided.
35928 *
35929 * @typedef {Object} FlatShape
35930 * @property {number} [shape-points] Number of points for stars and regular polygons. In case of a polygon, the number of points
35931 * is the number of sides.
35932 * @property {import("../color.js").Color|import("../colorlike.js").ColorLike} [shape-fill-color] The fill color.
35933 * @property {import("../color.js").Color|import("../colorlike.js").ColorLike} [shape-stroke-color] The stroke color.
35934 * @property {number} [shape-stroke-width] Stroke pixel width.
35935 * @property {CanvasLineCap} [shape-stroke-line-cap='round'] Line cap style: `butt`, `round`, or `square`.
35936 * @property {CanvasLineJoin} [shape-stroke-line-join='round'] Line join style: `bevel`, `round`, or `miter`.
35937 * @property {Array<number>} [shape-stroke-line-dash] Line dash pattern.
35938 * @property {number} [shape-stroke-line-dash-offset=0] Line dash offset.
35939 * @property {number} [shape-stroke-miter-limit=10] Miter limit.
35940 * @property {number} [shape-radius] Radius of a regular polygon.
35941 * @property {number} [shape-radius1] First radius of a star. Ignored if radius is set.
35942 * @property {number} [shape-radius2] Second radius of a star.
35943 * @property {number} [shape-angle=0] Shape's angle in radians. A value of 0 will have one of the shape's point facing up.
35944 * @property {Array<number>} [shape-displacement=[0,0]] Displacement of the shape
35945 * @property {number} [shape-rotation=0] Rotation in radians (positive rotation clockwise).
35946 * @property {boolean} [shape-rotate-with-view=false] Whether to rotate the shape with the view.
35947 * @property {number|import("../size.js").Size} [shape-scale=1] Scale. Unless two dimensional scaling is required a better
35948 * result may be obtained with appropriate settings for `shape-radius`, `shape-radius1` and `shape-radius2`.
35949 * @property {"declutter"|"obstacle"|"none"|undefined} [shape-declutter-mode] Declutter mode.
35950 */
35951
35952/**
35953 * Circle style properties for rendering point features.  At least `circle-radius` must be provided.
35954 *
35955 * @typedef {Object} FlatCircle
35956 * @property {number} [circle-radius] Circle radius.
35957 * @property {import("../color.js").Color|import("../colorlike.js").ColorLike} [circle-fill-color] The fill color.
35958 * @property {import("../color.js").Color|import("../colorlike.js").ColorLike} [circle-stroke-color] The stroke color.
35959 * @property {number} [circle-stroke-width] Stroke pixel width.
35960 * @property {CanvasLineCap} [circle-stroke-line-cap='round'] Line cap style: `butt`, `round`, or `square`.
35961 * @property {CanvasLineJoin} [circle-stroke-line-join='round'] Line join style: `bevel`, `round`, or `miter`.
35962 * @property {Array<number>} [circle-stroke-line-dash] Line dash pattern.
35963 * @property {number} [circle-stroke-line-dash-offset=0] Line dash offset.
35964 * @property {number} [circle-stroke-miter-limit=10] Miter limit.
35965 * @property {Array<number>} [circle-displacement=[0,0]] displacement
35966 * @property {number|import("../size.js").Size} [circle-scale=1] Scale. A two dimensional scale will produce an ellipse.
35967 * Unless two dimensional scaling is required a better result may be obtained with an appropriate setting for `circle-radius`.
35968 * @property {number} [circle-rotation=0] Rotation in radians
35969 * (positive rotation clockwise, meaningful only when used in conjunction with a two dimensional scale).
35970 * @property {boolean} [circle-rotate-with-view=false] Whether to rotate the shape with the view
35971 * (meaningful only when used in conjunction with a two dimensional scale).
35972 * @property {"declutter"|"obstacle"|"none"|undefined} [circle-declutter-mode] Declutter mode
35973 */
35974
35975/**
35976 * @param {FlatStyle} flatStyle A flat style literal.
35977 * @return {import("./Style.js").default} A style instance.
35978 */
35979function toStyle(flatStyle) {
35980  const style = new style_Style({
35981    fill: getFill(flatStyle, ''),
35982    stroke: getStroke(flatStyle, ''),
35983    text: getText(flatStyle),
35984    image: getImage(flatStyle),
35985  });
35986
35987  return style;
35988}
35989
35990/**
35991 * @param {FlatStyle} flatStyle The flat style.
35992 * @param {string} prefix The property prefix.
35993 * @return {Fill|undefined} The fill (if any).
35994 */
35995function getFill(flatStyle, prefix) {
35996  const color = flatStyle[prefix + 'fill-color'];
35997  if (!color) {
35998    return;
35999  }
36000
36001  return new style_Fill({color: color});
36002}
36003
36004/**
36005 * @param {FlatStyle} flatStyle The flat style.
36006 * @param {string} prefix The property prefix.
36007 * @return {Stroke|undefined} The stroke (if any).
36008 */
36009function getStroke(flatStyle, prefix) {
36010  const width = flatStyle[prefix + 'stroke-width'];
36011  const color = flatStyle[prefix + 'stroke-color'];
36012  if (!width && !color) {
36013    return;
36014  }
36015
36016  return new style_Stroke({
36017    width: width,
36018    color: color,
36019    lineCap: flatStyle[prefix + 'stroke-line-cap'],
36020    lineJoin: flatStyle[prefix + 'stroke-line-join'],
36021    lineDash: flatStyle[prefix + 'stroke-line-dash'],
36022    lineDashOffset: flatStyle[prefix + 'stroke-line-dash-offset'],
36023    miterLimit: flatStyle[prefix + 'stroke-miter-limit'],
36024  });
36025}
36026
36027/**
36028 * @param {FlatStyle} flatStyle The flat style.
36029 * @return {Text|undefined} The text (if any).
36030 */
36031function getText(flatStyle) {
36032  const value = flatStyle['text-value'];
36033  if (!value) {
36034    return;
36035  }
36036
36037  const text = new style_Text({
36038    text: value,
36039    font: flatStyle['text-font'],
36040    maxAngle: flatStyle['text-max-angle'],
36041    offsetX: flatStyle['text-offset-x'],
36042    offsetY: flatStyle['text-offset-y'],
36043    overflow: flatStyle['text-overflow'],
36044    placement: flatStyle['text-placement'],
36045    scale: flatStyle['text-scale'],
36046    rotateWithView: flatStyle['text-rotate-with-view'],
36047    rotation: flatStyle['text-rotation'],
36048    textAlign: flatStyle['text-align'],
36049    justify: flatStyle['text-justify'],
36050    textBaseline: flatStyle['text-baseline'],
36051    padding: flatStyle['text-padding'],
36052    fill: getFill(flatStyle, 'text-'),
36053    backgroundFill: getFill(flatStyle, 'text-background-'),
36054    stroke: getStroke(flatStyle, 'text-'),
36055    backgroundStroke: getStroke(flatStyle, 'text-background-'),
36056  });
36057
36058  return text;
36059}
36060
36061/**
36062 * @param {FlatStyle} flatStyle The flat style.
36063 * @return {import("./Image.js").default|undefined} The image (if any).
36064 */
36065function getImage(flatStyle) {
36066  const iconSrc = flatStyle['icon-src'];
36067  const iconImg = flatStyle['icon-img'];
36068  if (iconSrc || iconImg) {
36069    const icon = new style_Icon({
36070      src: iconSrc,
36071      img: iconImg,
36072      imgSize: flatStyle['icon-img-size'],
36073      anchor: flatStyle['icon-anchor'],
36074      anchorOrigin: flatStyle['icon-anchor-origin'],
36075      anchorXUnits: flatStyle['icon-anchor-x-units'],
36076      anchorYUnits: flatStyle['icon-anchor-y-units'],
36077      color: flatStyle['icon-color'],
36078      crossOrigin: flatStyle['icon-cross-origin'],
36079      offset: flatStyle['icon-offset'],
36080      displacement: flatStyle['icon-displacement'],
36081      opacity: flatStyle['icon-opacity'],
36082      scale: flatStyle['icon-scale'],
36083      rotation: flatStyle['icon-rotation'],
36084      rotateWithView: flatStyle['icon-rotate-with-view'],
36085      size: flatStyle['icon-size'],
36086      declutterMode: flatStyle['icon-declutter-mode'],
36087    });
36088    return icon;
36089  }
36090
36091  const shapePoints = flatStyle['shape-points'];
36092  if (shapePoints) {
36093    const prefix = 'shape-';
36094    const shape = new style_RegularShape({
36095      points: shapePoints,
36096      fill: getFill(flatStyle, prefix),
36097      stroke: getStroke(flatStyle, prefix),
36098      radius: flatStyle['shape-radius'],
36099      radius1: flatStyle['shape-radius1'],
36100      radius2: flatStyle['shape-radius2'],
36101      angle: flatStyle['shape-angle'],
36102      displacement: flatStyle['shape-displacement'],
36103      rotation: flatStyle['shape-rotation'],
36104      rotateWithView: flatStyle['shape-rotate-with-view'],
36105      scale: flatStyle['shape-scale'],
36106      declutterMode: flatStyle['shape-declutter-mode'],
36107    });
36108
36109    return shape;
36110  }
36111
36112  const circleRadius = flatStyle['circle-radius'];
36113  if (circleRadius) {
36114    const prefix = 'circle-';
36115    const circle = new Circle({
36116      radius: circleRadius,
36117      fill: getFill(flatStyle, prefix),
36118      stroke: getStroke(flatStyle, prefix),
36119      displacement: flatStyle['circle-displacement'],
36120      scale: flatStyle['circle-scale'],
36121      rotation: flatStyle['circle-rotation'],
36122      rotateWithView: flatStyle['circle-rotate-with-view'],
36123      declutterMode: flatStyle['circle-declutter-mode'],
36124    });
36125
36126    return circle;
36127  }
36128
36129  return;
36130}
36131
36132;// CONCATENATED MODULE: ./node_modules/ol/layer/BaseVector.js
36133/**
36134 * @module ol/layer/BaseVector
36135 */
36136
36137
36138
36139
36140
36141/**
36142 * @template {import("../source/Vector.js").default|import("../source/VectorTile.js").default} VectorSourceType
36143 * @typedef {Object} Options
36144 * @property {string} [className='ol-layer'] A CSS class name to set to the layer element.
36145 * @property {number} [opacity=1] Opacity (0, 1).
36146 * @property {boolean} [visible=true] Visibility.
36147 * @property {import("../extent.js").Extent} [extent] The bounding extent for layer rendering.  The layer will not be
36148 * rendered outside of this extent.
36149 * @property {number} [zIndex] The z-index for layer rendering.  At rendering time, the layers
36150 * will be ordered, first by Z-index and then by position. When `undefined`, a `zIndex` of 0 is assumed
36151 * for layers that are added to the map's `layers` collection, or `Infinity` when the layer's `setMap()`
36152 * method was used.
36153 * @property {number} [minResolution] The minimum resolution (inclusive) at which this layer will be
36154 * visible.
36155 * @property {number} [maxResolution] The maximum resolution (exclusive) below which this layer will
36156 * be visible.
36157 * @property {number} [minZoom] The minimum view zoom level (exclusive) above which this layer will be
36158 * visible.
36159 * @property {number} [maxZoom] The maximum view zoom level (inclusive) at which this layer will
36160 * be visible.
36161 * @property {import("../render.js").OrderFunction} [renderOrder] Render order. Function to be used when sorting
36162 * features before rendering. By default features are drawn in the order that they are created. Use
36163 * `null` to avoid the sort, but get an undefined draw order.
36164 * @property {number} [renderBuffer=100] The buffer in pixels around the viewport extent used by the
36165 * renderer when getting features from the vector source for the rendering or hit-detection.
36166 * Recommended value: the size of the largest symbol, line width or label.
36167 * @property {VectorSourceType} [source] Source.
36168 * @property {import("../Map.js").default} [map] Sets the layer as overlay on a map. The map will not manage
36169 * this layer in its layers collection, and the layer will be rendered on top. This is useful for
36170 * temporary layers. The standard way to add a layer to a map and have it managed by the map is to
36171 * use [map.addLayer()]{@link import("../Map.js").default#addLayer}.
36172 * @property {boolean} [declutter=false] Declutter images and text. Decluttering is applied to all
36173 * image and text styles of all Vector and VectorTile layers that have set this to `true`. The priority
36174 * is defined by the z-index of the layer, the `zIndex` of the style and the render order of features.
36175 * Higher z-index means higher priority. Within the same z-index, a feature rendered before another has
36176 * higher priority.
36177 *
36178 * As an optimization decluttered features from layers with the same `className` are rendered above
36179 * the fill and stroke styles of all of those layers regardless of z-index.  To opt out of this
36180 * behavior and place declutterd features with their own layer configure the layer with a `className`
36181 * other than `ol-layer`.
36182 * @property {import("../style/Style.js").StyleLike|import("../style/flat.js").FlatStyleLike|null} [style] Layer style. When set to `null`, only
36183 * features that have their own style will be rendered. See {@link module:ol/style/Style~Style} for the default style
36184 * which will be used if this is not set.
36185 * @property {import("./Base.js").BackgroundColor} [background] Background color for the layer. If not specified, no background
36186 * will be rendered.
36187 * @property {boolean} [updateWhileAnimating=false] When set to `true`, feature batches will
36188 * be recreated during animations. This means that no vectors will be shown clipped, but the
36189 * setting will have a performance impact for large amounts of vector data. When set to `false`,
36190 * batches will be recreated when no animation is active.
36191 * @property {boolean} [updateWhileInteracting=false] When set to `true`, feature batches will
36192 * be recreated during interactions. See also `updateWhileAnimating`.
36193 * @property {Object<string, *>} [properties] Arbitrary observable properties. Can be accessed with `#get()` and `#set()`.
36194 */
36195
36196/**
36197 * @enum {string}
36198 * @private
36199 */
36200const BaseVector_Property = {
36201  RENDER_ORDER: 'renderOrder',
36202};
36203
36204/**
36205 * @classdesc
36206 * Vector data that is rendered client-side.
36207 * Note that any property set in the options is set as a {@link module:ol/Object~BaseObject}
36208 * property on the layer object; for example, setting `title: 'My Title'` in the
36209 * options means that `title` is observable, and has get/set accessors.
36210 *
36211 * @template {import("../source/Vector.js").default|import("../source/VectorTile.js").default} VectorSourceType
36212 * @template {import("../renderer/canvas/VectorLayer.js").default|import("../renderer/canvas/VectorTileLayer.js").default|import("../renderer/canvas/VectorImageLayer.js").default|import("../renderer/webgl/PointsLayer.js").default}
36212 RendererType
36213 * @extends {Layer<VectorSourceType, RendererType>}
36214 * @api
36215 */
36216class BaseVectorLayer extends layer_Layer {
36217  /**
36218   * @param {Options<VectorSourceType>} [options] Options.
36219   */
36220  constructor(options) {
36221    options = options ? options : {};
36222
36223    const baseOptions = Object.assign({}, options);
36224
36225    delete baseOptions.style;
36226    delete baseOptions.renderBuffer;
36227    delete baseOptions.updateWhileAnimating;
36228    delete baseOptions.updateWhileInteracting;
36229    super(baseOptions);
36230
36231    /**
36232     * @private
36233     * @type {boolean}
36234     */
36235    this.declutter_ =
36236      options.declutter !== undefined ? options.declutter : false;
36237
36238    /**
36239     * @type {number}
36240     * @private
36241     */
36242    this.renderBuffer_ =
36243      options.renderBuffer !== undefined ? options.renderBuffer : 100;
36244
36245    /**
36246     * User provided style.
36247     * @type {import("../style/Style.js").StyleLike}
36248     * @private
36249     */
36250    this.style_ = null;
36251
36252    /**
36253     * Style function for use within the library.
36254     * @type {import("../style/Style.js").StyleFunction|undefined}
36255     * @private
36256     */
36257    this.styleFunction_ = undefined;
36258
36259    this.setStyle(options.style);
36260
36261    /**
36262     * @type {boolean}
36263     * @private
36264     */
36265    this.updateWhileAnimating_ =
36266      options.updateWhileAnimating !== undefined
36267        ? options.updateWhileAnimating
36268        : false;
36269
36270    /**
36271     * @type {boolean}
36272     * @private
36273     */
36274    this.updateWhileInteracting_ =
36275      options.updateWhileInteracting !== undefined
36276        ? options.updateWhileInteracting
36277        : false;
36278  }
36279
36280  /**
36281   * @return {boolean} Declutter.
36282   */
36283  getDeclutter() {
36284    return this.declutter_;
36285  }
36286
36287  /**
36288   * Get the topmost feature that intersects the given pixel on the viewport. Returns a promise
36289   * that resolves with an array of features. The array will either contain the topmost feature
36290   * when a hit was detected, or it will be empty.
36291   *
36292   * The hit detection algorithm used for this method is optimized for performance, but is less
36293   * accurate than the one used in [map.getFeaturesAtPixel()]{@link import("../Map.js").default#getFeaturesAtPixel}.
36294   * Text is not considered, and icons are only represented by their bounding box instead of the exact
36295   * image.
36296   *
36297   * @param {import("../pixel.js").Pixel} pixel Pixel.
36298   * @return {Promise<Array<import("../Feature").default>>} Promise that resolves with an array of features.
36299   * @api
36300   */
36301  getFeatures(pixel) {
36302    return super.getFeatures(pixel);
36303  }
36304
36305  /**
36306   * @return {number|undefined} Render buffer.
36307   */
36308  getRenderBuffer() {
36309    return this.renderBuffer_;
36310  }
36311
36312  /**
36313   * @return {function(import("../Feature.js").default, import("../Feature.js").default): number|null|undefined} Render
36314   *     order.
36315   */
36316  getRenderOrder() {
36317    return /** @type {import("../render.js").OrderFunction|null|undefined} */ (
36318      this.get(BaseVector_Property.RENDER_ORDER)
36319    );
36320  }
36321
36322  /**
36323   * Get the style for features.  This returns whatever was passed to the `style`
36324   * option at construction or to the `setStyle` method.
36325   * @return {import("../style/Style.js").StyleLike|null|undefined} Layer style.
36326   * @api
36327   */
36328  getStyle() {
36329    return this.style_;
36330  }
36331
36332  /**
36333   * Get the style function.
36334   * @return {import("../style/Style.js").StyleFunction|undefined} Layer style function.
36335   * @api
36336   */
36337  getStyleFunction() {
36338    return this.styleFunction_;
36339  }
36340
36341  /**
36342   * @return {boolean} Whether the rendered layer should be updated while
36343   *     animating.
36344   */
36345  getUpdateWhileAnimating() {
36346    return this.updateWhileAnimating_;
36347  }
36348
36349  /**
36350   * @return {boolean} Whether the rendered layer should be updated while
36351   *     interacting.
36352   */
36353  getUpdateWhileInteracting() {
36354    return this.updateWhileInteracting_;
36355  }
36356
36357  /**
36358   * Render declutter items for this layer
36359   * @param {import("../Map.js").FrameState} frameState Frame state.
36360   */
36361  renderDeclutter(frameState) {
36362    if (!frameState.declutterTree) {
36363      frameState.declutterTree = new rbush_min(9);
36364    }
36365    /** @type {*} */ (this.getRenderer()).renderDeclutter(frameState);
36366  }
36367
36368  /**
36369   * @param {import("../render.js").OrderFunction|null|undefined} renderOrder
36370   *     Render order.
36371   */
36372  setRenderOrder(renderOrder) {
36373    this.set(BaseVector_Property.RENDER_ORDER, renderOrder);
36374  }
36375
36376  /**
36377   * Set the style for features.  This can be a single style object, an array
36378   * of styles, or a function that takes a feature and resolution and returns
36379   * an array of styles. If set to `null`, the layer has no style (a `null` style),
36380   * so only features that have their own styles will be rendered in the layer. C
36380all
36381   * `setStyle()` without arguments to reset to the default style. See
36382   * [the ol/style/Style module]{@link module:ol/style/Style~Style} for information on the default style.
36383   *
36384   * If your layer has a static style, you can use "flat" style object literals instead of
36385   * using the `Style` and symbolizer constructors (`Fill`, `Stroke`, etc.).  See the documentation
36386   * for the [flat style types]{@link module:ol/style/flat~FlatStyle} to see what properties are supported.
36387   *
36388   * @param {import("../style/Style.js").StyleLike|import("../style/flat.js").FlatStyleLike|null} [style] Layer style.
36389   * @api
36390   */
36391  setStyle(style) {
36392    /**
36393     * @type {import("../style/Style.js").StyleLike|null}
36394     */
36395    let styleLike;
36396
36397    if (style === undefined) {
36398      styleLike = createDefaultStyle;
36399    } else if (style === null) {
36400      styleLike = null;
36401    } else if (typeof style === 'function') {
36402      styleLike = style;
36403    } else if (style instanceof style_Style) {
36404      styleLike = style;
36405    } else if (Array.isArray(style)) {
36406      const len = style.length;
36407
36408      /**
36409       * @type {Array<Style>}
36410       */
36411      const styles = new Array(len);
36412
36413      for (let i = 0; i < len; ++i) {
36414        const s = style[i];
36415        if (s instanceof style_Style) {
36416          styles[i] = s;
36417        } else {
36418          styles[i] = toStyle(s);
36419        }
36420      }
36421      styleLike = styles;
36422    } else {
36423      styleLike = toStyle(style);
36424    }
36425
36426    this.style_ = styleLike;
36427    this.styleFunction_ =
36428      style === null ? undefined : toFunction(this.style_);
36429    this.changed();
36430  }
36431}
36432
36433/* harmony default export */ const BaseVector = (BaseVectorLayer);
36434
36435;// CONCATENATED MODULE: ./node_modules/ol/render/canvas/Instruction.js
36436/**
36437 * @module ol/render/canvas/Instruction
36438 */
36439
36440/**
36441 * @enum {number}
36442 */
36443const Instruction = {
36444  BEGIN_GEOMETRY: 0,
36445  BEGIN_PATH: 1,
36446  CIRCLE: 2,
36447  CLOSE_PATH: 3,
36448  CUSTOM: 4,
36449  DRAW_CHARS: 5,
36450  DRAW_IMAGE: 6,
36451  END_GEOMETRY: 7,
36452  FILL: 8,
36453  MOVE_TO_LINE_TO: 9,
36454  SET_FILL_STYLE: 10,
36455  SET_STROKE_STYLE: 11,
36456  STROKE: 12,
36457};
36458
36459/**
36460 * @type {Array<Instruction>}
36461 */
36462const fillInstruction = [Instruction.FILL];
36463
36464/**
36465 * @type {Array<Instruction>}
36466 */
36467const strokeInstruction = [Instruction.STROKE];
36468
36469/**
36470 * @type {Array<Instruction>}
36471 */
36472const beginPathInstruction = [Instruction.BEGIN_PATH];
36473
36474/**
36475 * @type {Array<Instruction>}
36476 */
36477const closePathInstruction = [Instruction.CLOSE_PATH];
36478
36479/* harmony default export */ const canvas_Instruction = (Instruction);
36480
36481;// CONCATENATED MODULE: ./node_modules/ol/render/VectorContext.js
36482/**
36483 * @module ol/render/VectorContext
36484 */
36485
36486/**
36487 * @classdesc
36488 * Context for drawing geometries.  A vector context is available on render
36489 * events and does not need to be constructed directly.
36490 * @api
36491 */
36492class VectorContext {
36493  /**
36494   * Render a geometry with a custom renderer.
36495   *
36496   * @param {import("../geom/SimpleGeometry.js").default} geometry Geometry.
36497   * @param {import("../Feature.js").FeatureLike} feature Feature.
36498   * @param {Function} renderer Renderer.
36499   * @param {Function} hitDetectionRenderer Renderer.
36500   */
36501  drawCustom(geometry, feature, renderer, hitDetectionRenderer) {}
36502
36503  /**
36504   * Render a geometry.
36505   *
36506   * @param {import("../geom/Geometry.js").default} geometry The geometry to render.
36507   */
36508  drawGeometry(geometry) {}
36509
36510  /**
36511   * Set the rendering style.
36512   *
36513   * @param {import("../style/Style.js").default} style The rendering style.
36514   */
36515  setStyle(style) {}
36516
36517  /**
36518   * @param {import("../geom/Circle.js").default} circleGeometry Circle geometry.
36519   * @param {import("../Feature.js").default} feature Feature.
36520   */
36521  drawCircle(circleGeometry, feature) {}
36522
36523  /**
36524   * @param {import("../Feature.js").default} feature Feature.
36525   * @param {import("../style/Style.js").default} style Style.
36526   */
36527  drawFeature(feature, style) {}
36528
36529  /**
36530   * @param {import("../geom/GeometryCollection.js").default} geometryCollectionGeometry Geometry collection.
36531   * @param {import("../Feature.js").default} feature Feature.
36532   */
36533  drawGeometryCollection(geometryCollectionGeometry, feature) {}
36534
36535  /**
36536   * @param {import("../geom/LineString.js").default|import("./Feature.js").default} lineStringGeometry Line string geometry.
36537   * @param {import("../Feature.js").FeatureLike} feature Feature.
36538   */
36539  drawLineString(lineStringGeometry, feature) {}
36540
36541  /**
36542   * @param {import("../geom/MultiLineString.js").default|import("./Feature.js").default} multiLineStringGeometry MultiLineString geometry.
36543   * @param {import("../Feature.js").FeatureLike} feature Feature.
36544   */
36545  drawMultiLineString(multiLineStringGeometry, feature) {}
36546
36547  /**
36548   * @param {import("../geom/MultiPoint.js").default|import("./Feature.js").default} multiPointGeometry MultiPoint geometry.
36549   * @param {import("../Feature.js").FeatureLike} feature Feature.
36550   */
36551  drawMultiPoint(multiPointGeometry, feature) {}
36552
36553  /**
36554   * @param {import("../geom/MultiPolygon.js").default} multiPolygonGeometry MultiPolygon geometry.
36555   * @param {import("../Feature.js").FeatureLike} feature Feature.
36556   */
36557  drawMultiPolygon(multiPolygonGeometry, feature) {}
36558
36559  /**
36560   * @param {import("../geom/Point.js").default|import("./Feature.js").default} pointGeometry Point geometry.
36561   * @param {import("../Feature.js").FeatureLike} feature Feature.
36562   */
36563  drawPoint(pointGeometry, feature) {}
36564
36565  /**
36566   * @param {import("../geom/Polygon.js").default|import("./Feature.js").default} polygonGeometry Polygon geometry.
36567   * @param {import("../Feature.js").FeatureLike} feature Feature.
36568   */
36569  drawPolygon(polygonGeometry, feature) {}
36570
36571  /**
36572   * @param {import("../geom/SimpleGeometry.js").default|import("./Feature.js").default} geometry Geometry.
36573   * @param {import("../Feature.js").FeatureLike} feature Feature.
36574   */
36575  drawText(geometry, feature) {}
36576
36577  /**
36578   * @param {import("../style/Fill.js").default} fillStyle Fill style.
36579   * @param {import("../style/Stroke.js").default} strokeStyle Stroke style.
36580   */
36581  setFillStrokeStyle(fillStyle, strokeStyle) {}
36582
36583  /**
36584   * @param {import("../style/Image.js").default} imageStyle Image style.
36585   * @param {import("../render/canvas.js").DeclutterImageWithText} [declutterImageWithText] Shared data for combined decluttering with a text style.
36586   */
36587  setImageStyle(imageStyle, declutterImageWithText) {}
36588
36589  /**
36590   * @param {import("../style/Text.js").default} textStyle Text style.
36591   * @param {import("../render/canvas.js").DeclutterImageWithText} [declutterImageWithText] Shared data for combined decluttering with an image style.
36592   */
36593  setTextStyle(textStyle, declutterImageWithText) {}
36594}
36595
36596/* harmony default export */ const render_VectorContext = (VectorContext);
36597
36598;// CONCATENATED MODULE: ./node_modules/ol/render/canvas/Builder.js
36599/**
36600 * @module ol/render/canvas/Builder
36601 */
36602
36603
36604
36605
36606
36607
36608
36609
36610
36611class CanvasBuilder extends render_VectorContext {
36612  /**
36613   * @param {number} tolerance Tolerance.
36614   * @param {import("../../extent.js").Extent} maxExtent Maximum extent.
36615   * @param {number} resolution Resolution.
36616   * @param {number} pixelRatio Pixel ratio.
36617   */
36618  constructor(tolerance, maxExtent, resolution, pixelRatio) {
36619    super();
36620
36621    /**
36622     * @protected
36623     * @type {number}
36624     */
36625    this.tolerance = tolerance;
36626
36627    /**
36628     * @protected
36629     * @const
36630     * @type {import("../../extent.js").Extent}
36631     */
36632    this.maxExtent = maxExtent;
36633
36634    /**
36635     * @protected
36636     * @type {number}
36637     */
36638    this.pixelRatio = pixelRatio;
36639
36640    /**
36641     * @protected
36642     * @type {number}
36643     */
36644    this.maxLineWidth = 0;
36645
36646    /**
36647     * @protected
36648     * @const
36649     * @type {number}
36650     */
36651    this.resolution = resolution;
36652
36653    /**
36654     * @private
36655     * @type {Array<*>}
36656     */
36657    this.beginGeometryInstruction1_ = null;
36658
36659    /**
36660     * @private
36661     * @type {Array<*>}
36662     */
36663    this.beginGeometryInstruction2_ = null;
36664
36665    /**
36666     * @private
36667     * @type {import("../../extent.js").Extent}
36668     */
36669    this.bufferedMaxExtent_ = null;
36670
36671    /**
36672     * @protected
36673     * @type {Array<*>}
36674     */
36675    this.instructions = [];
36676
36677    /**
36678     * @protected
36679     * @type {Array<number>}
36680     */
36681    this.coordinates = [];
36682
36683    /**
36684     * @private
36685     * @type {import("../../coordinate.js").Coordinate}
36686     */
36687    this.tmpCoordinate_ = [];
36688
36689    /**
36690     * @protected
36691     * @type {Array<*>}
36692     */
36693    this.hitDetectionInstructions = [];
36694
36695    /**
36696     * @protected
36697     * @type {import("../canvas.js").FillStrokeState}
36698     */
36699    this.state = /** @type {import("../canvas.js").FillStrokeState} */ ({});
36700  }
36701
36702  /**
36703   * @protected
36704   * @param {Array<number>} dashArray Dash array.
36705   * @return {Array<number>} Dash array with pixel ratio applied
36706   */
36707  applyPixelRatio(dashArray) {
36708    const pixelRatio = this.pixelRatio;
36709    return pixelRatio == 1
36710      ? dashArray
36711      : dashArray.map(function (dash) {
36712          return dash * pixelRatio;
36713        });
36714  }
36715
36716  /**
36717   * @param {Array<number>} flatCoordinates Flat coordinates.
36718   * @param {number} stride Stride.
36719   * @protected
36720   * @return {number} My end
36721   */
36722  appendFlatPointCoordinates(flatCoordinates, stride) {
36723    const extent = this.getBufferedMaxExtent();
36724    const tmpCoord = this.tmpCoordinate_;
36725    const coordinates = this.coordinates;
36726    let myEnd = coordinates.length;
36727    for (let i = 0, ii = flatCoordinates.length; i < ii; i += stride) {
36728      tmpCoord[0] = flatCoordinates[i];
36729      tmpCoord[1] = flatCoordinates[i + 1];
36730      if (containsCoordinate(extent, tmpCoord)) {
36731        coordinates[myEnd++] = tmpCoord[0];
36732        coordinates[myEnd++] = tmpCoord[1];
36733      }
36734    }
36735    return myEnd;
36736  }
36737
36738  /**
36739   * @param {Array<number>} flatCoordinates Flat coordinates.
36740   * @param {number} offset Offset.
36741   * @param {number} end End.
36742   * @param {number} stride Stride.
36743   * @param {boolean} closed Last input coordinate equals first.
36744   * @param {boolean} skipFirst Skip first coordinate.
36745   * @protected
36746   * @return {number} My end.
36747   */
36748  appendFlatLineCoordinates(
36749    flatCoordinates,
36750    offset,
36751    end,
36752    stride,
36753    closed,
36754    skipFirst
36755  ) {
36756    const coordinates = this.coordinates;
36757    let myEnd = coordinates.length;
36758    const extent = this.getBufferedMaxExtent();
36759    if (skipFirst) {
36760      offset += stride;
36761    }
36762    let lastXCoord = flatCoordinates[offset];
36763    let lastYCoord = flatCoordinates[offset + 1];
36764    const nextCoord = this.tmpCoordinate_;
36765    let skipped = true;
36766
36767    let i, lastRel, nextRel;
36768    for (i = offset + stride; i < end; i += stride) {
36769      nextCoord[0] = flatCoordinates[i];
36770      nextCoord[1] = flatCoordinates[i + 1];
36771      nextRel = coordinateRelationship(extent, nextCoord);
36772      if (nextRel !== lastRel) {
36773        if (skipped) {
36774          coordinates[myEnd++] = lastXCoord;
36775          coordinates[myEnd++] = lastYCoord;
36776          skipped = false;
36777        }
36778        coordinates[myEnd++] = nextCoord[0];
36779        coordinates[myEnd++] = nextCoord[1];
36780      } else if (nextRel === Relationship.INTERSECTING) {
36781        coordinates[myEnd++] = nextCoord[0];
36782        coordinates[myEnd++] = nextCoord[1];
36783        skipped = false;
36784      } else {
36785        skipped = true;
36786      }
36787      lastXCoord = nextCoord[0];
36788      lastYCoord = nextCoord[1];
36789      lastRel = nextRel;
36790    }
36791
36792    // Last coordinate equals first or only one point to append:
36793    if ((closed && skipped) || i === offset + stride) {
36794      coordinates[myEnd++] = lastXCoord;
36795      coordinates[myEnd++] = lastYCoord;
36796    }
36797    return myEnd;
36798  }
36799
36800  /**
36801   * @param {Array<number>} flatCoordinates Flat coordinates.
36802   * @param {number} offset Offset.
36803   * @param {Array<number>} ends Ends.
36804   * @param {number} stride Stride.
36805   * @param {Array<number>} builderEnds Builder ends.
36806   * @return {number} Offset.
36807   */
36808  drawCustomCoordinates_(flatCoordinates, offset, ends, stride, builderEnds) {
36809    for (let i = 0, ii = ends.length; i < ii; ++i) {
36810      const end = ends[i];
36811      const builderEnd = this.appendFlatLineCoordinates(
36812        flatCoordinates,
36813        offset,
36814        end,
36815        stride,
36816        false,
36817        false
36818      );
36819      builderEnds.push(builderEnd);
36820      offset = end;
36821    }
36822    return offset;
36823  }
36824
36825  /**
36826   * @param {import("../../geom/SimpleGeometry.js").default} geometry Geometry.
36827   * @param {import("../../Feature.js").FeatureLike} feature Feature.
36828   * @param {Function} renderer Renderer.
36829   * @param {Function} hitDetectionRenderer Renderer.
36830   */
36831  drawCustom(geometry, feature, renderer, hitDetectionRenderer) {
36832    this.beginGeometry(geometry, feature);
36833
36834    const type = geometry.getType();
36835    const stride = geometry.getStride();
36836    const builderBegin = this.coordinates.length;
36837
36838    let flatCoordinates, builderEnd, builderEnds, builderEndss;
36839    let offset;
36840
36841    switch (type) {
36842      case 'MultiPolygon':
36843        flatCoordinates =
36844          /** @type {import("../../geom/MultiPolygon.js").default} */ (
36845            geometry
36846          ).getOrientedFlatCoordinates();
36847        builderEndss = [];
36848        const endss =
36849          /** @type {import("../../geom/MultiPolygon.js").default} */ (
36850            geometry
36851          ).getEndss();
36852        offset = 0;
36853        for (let i = 0, ii = endss.length; i < ii; ++i) {
36854          const myEnds = [];
36855          offset = this.drawCustomCoordinates_(
36856            flatCoordinates,
36857            offset,
36858            endss[i],
36859            stride,
36860            myEnds
36861          );
36862          builderEndss.push(myEnds);
36863        }
36864        this.instructions.push([
36865          canvas_Instruction.CUSTOM,
36866          builderBegin,
36867          builderEndss,
36868          geometry,
36869          renderer,
36870          inflateMultiCoordinatesArray,
36871        ]);
36872        this.hitDetectionInstructions.push([
36873          canvas_Instruction.CUSTOM,
36874          builderBegin,
36875          builderEndss,
36876          geometry,
36877          hitDetectionRenderer || renderer,
36878          inflateMultiCoordinatesArray,
36879        ]);
36880        break;
36881      case 'Polygon':
36882      case 'MultiLineString':
36883        builderEnds = [];
36884        flatCoordinates =
36885          type == 'Polygon'
36886            ? /** @type {import("../../geom/Polygon.js").default} */ (
36887                geometry
36888              ).getOrientedFlatCoordinates()
36889            : geometry.getFlatCoordinates();
36890        offset = this.drawCustomCoordinates_(
36891          flatCoordinates,
36892          0,
36893          /** @type {import("../../geom/Polygon.js").default|import("../../geom/MultiLineString.js").default} */ (
36894            geometry
36895          ).getEnds(),
36896          stride,
36897          builderEnds
36898        );
36899        this.instructions.push([
36900          canvas_Instruction.CUSTOM,
36901          builderBegin,
36902          builderEnds,
36903          geometry,
36904          renderer,
36905          inflateCoordinatesArray,
36906        ]);
36907        this.hitDetectionInstructions.push([
36908          canvas_Instruction.CUSTOM,
36909          builderBegin,
36910          builderEnds,
36911          geometry,
36912          hitDetectionRenderer || renderer,
36913          inflateCoordinatesArray,
36914        ]);
36915        break;
36916      case 'LineString':
36917      case 'Circle':
36918        flatCoordinates = geometry.getFlatCoordinates();
36919        builderEnd = this.appendFlatLineCoordinates(
36920          flatCoordinates,
36921          0,
36922          flatCoordinates.length,
36923          stride,
36924          false,
36925          false
36926        );
36927        this.instructions.push([
36928          canvas_Instruction.CUSTOM,
36929          builderBegin,
36930          builderEnd,
36931          geometry,
36932          renderer,
36933          inflateCoordinates,
36934        ]);
36935        this.hitDetectionInstructions.push([
36936          canvas_Instruction.CUSTOM,
36937          builderBegin,
36938          builderEnd,
36939          geometry,
36940          hitDetectionRenderer || renderer,
36941          inflateCoordinates,
36942        ]);
36943        break;
36944      case 'MultiPoint':
36945        flatCoordinates = geometry.getFlatCoordinates();
36946        builderEnd = this.appendFlatPointCoordinates(flatCoordinates, stride);
36947
36948        if (builderEnd > builderBegin) {
36949          this.instructions.push([
36950            canvas_Instruction.CUSTOM,
36951            builderBegin,
36952            builderEnd,
36953            geometry,
36954            renderer,
36955            inflateCoordinates,
36956          ]);
36957          this.hitDetectionInstructions.push([
36958            canvas_Instruction.CUSTOM,
36959            builderBegin,
36960            builderEnd,
36961            geometry,
36962            hitDetectionRenderer || renderer,
36963            inflateCoordinates,
36964          ]);
36965        }
36966        break;
36967      case 'Point':
36968        flatCoordinates = geometry.getFlatCoordinates();
36969        this.coordinates.push(flatCoordinates[0], flatCoordinates[1]);
36970        builderEnd = this.coordinates.length;
36971
36972        this.instructions.push([
36973          canvas_Instruction.CUSTOM,
36974          builderBegin,
36975          builderEnd,
36976          geometry,
36977          renderer,
36978        ]);
36979        this.hitDetectionInstructions.push([
36980          canvas_Instruction.CUSTOM,
36981          builderBegin,
36982          builderEnd,
36983          geometry,
36984          hitDetectionRenderer || renderer,
36985        ]);
36986        break;
36987      default:
36988    }
36989    this.endGeometry(feature);
36990  }
36991
36992  /**
36993   * @protected
36994   * @param {import("../../geom/Geometry").default|import("../Feature.js").default} geometry The geometry.
36995   * @param {import("../../Feature.js").FeatureLike} feature Feature.
36996   */
36997  beginGeometry(geometry, feature) {
36998    this.beginGeometryInstruction1_ = [
36999      canvas_Instruction.BEGIN_GEOMETRY,
37000      feature,
37001      0,
37002      geometry,
37003    ];
37004    this.instructions.push(this.beginGeometryInstruction1_);
37005    this.beginGeometryInstruction2_ = [
37006      canvas_Instruction.BEGIN_GEOMETRY,
37007      feature,
37008      0,
37009      geometry,
37010    ];
37011    this.hitDetectionInstructions.push(this.beginGeometryInstruction2_);
37012  }
37013
37014  /**
37015   * @return {import("../canvas.js").SerializableInstructions} the serializable instructions.
37016   */
37017  finish() {
37018    return {
37019      instructions: this.instructions,
37020      hitDetectionInstructions: this.hitDetectionInstructions,
37021      coordinates: this.coordinates,
37022    };
37023  }
37024
37025  /**
37026   * Reverse the hit detection instructions.
37027   */
37028  reverseHitDetectionInstructions() {
37029    const hitDetectionInstructions = this.hitDetectionInstructions;
37030    // step 1 - reverse array
37031    hitDetectionInstructions.reverse();
37032    // step 2 - reverse instructions within geometry blocks
37033    let i;
37034    const n = hitDetectionInstructions.length;
37035    let instruction;
37036    let type;
37037    let begin = -1;
37038    for (i = 0; i < n; ++i) {
37039      instruction = hitDetectionInstructions[i];
37040      type = /** @type {import("./Instruction.js").default} */ (instruction[0]);
37041      if (type == canvas_Instruction.END_GEOMETRY) {
37042        begin = i;
37043      } else if (type == canvas_Instruction.BEGIN_GEOMETRY) {
37044        instruction[2] = i;
37045        reverseSubArray(this.hitDetectionInstructions, begin, i);
37046        begin = -1;
37047      }
37048    }
37049  }
37050
37051  /**
37052   * @param {import("../../style/Fill.js").default} fillStyle Fill style.
37053   * @param {import("../../style/Stroke.js").default} strokeStyle Stroke style.
37054   */
37055  setFillStrokeStyle(fillStyle, strokeStyle) {
37056    const state = this.state;
37057    if (fillStyle) {
37058      const fillStyleColor = fillStyle.getColor();
37059      state.fillStyle = asColorLike(
37060        fillStyleColor ? fillStyleColor : defaultFillStyle
37061      );
37062    } else {
37063      state.fillStyle = undefined;
37064    }
37065    if (strokeStyle) {
37066      const strokeStyleColor = strokeStyle.getColor();
37067      state.strokeStyle = asColorLike(
37068        strokeStyleColor ? strokeStyleColor : defaultStrokeStyle
37069      );
37070      const strokeStyleLineCap = strokeStyle.getLineCap();
37071      state.lineCap =
37072        strokeStyleLineCap !== undefined ? strokeStyleLineCap : defaultLineCap;
37073      const strokeStyleLineDash = strokeStyle.getLineDash();
37074      state.lineDash = strokeStyleLineDash
37075        ? strokeStyleLineDash.slice()
37076        : defaultLineDash;
37077      const strokeStyleLineDashOffset = strokeStyle.getLineDashOffset();
37078      state.lineDashOffset = strokeStyleLineDashOffset
37079        ? strokeStyleLineDashOffset
37080        : defaultLineDashOffset;
37081      const strokeStyleLineJoin = strokeStyle.getLineJoin();
37082      state.lineJoin =
37083        strokeStyleLineJoin !== undefined
37084          ? strokeStyleLineJoin
37085          : defaultLineJoin;
37086      const strokeStyleWidth = strokeStyle.getWidth();
37087      state.lineWidth =
37088        strokeStyleWidth !== undefined ? strokeStyleWidth : defaultLineWidth;
37089      const strokeStyleMiterLimit = strokeStyle.getMiterLimit();
37090      state.miterLimit =
37091        strokeStyleMiterLimit !== undefined
37092          ? strokeStyleMiterLimit
37093          : defaultMiterLimit;
37094
37095      if (state.lineWidth > this.maxLineWidth) {
37096        this.maxLineWidth = state.lineWidth;
37097        // invalidate the buffered max extent cache
37098        this.bufferedMaxExtent_ = null;
37099      }
37100    } else {
37101      state.strokeStyle = undefined;
37102      state.lineCap = undefined;
37103      state.lineDash = null;
37104      state.lineDashOffset = undefined;
37105      state.lineJoin = undefined;
37106      state.lineWidth = undefined;
37107      state.miterLimit = undefined;
37108    }
37109  }
37110
37111  /**
37112   * @param {import("../canvas.js").FillStrokeState} state State.
37113   * @return {Array<*>} Fill instruction.
37114   */
37115  createFill(state) {
37116    const fillStyle = state.fillStyle;
37117    /** @type {Array<*>} */
37118    const fillInstruction = [canvas_Instruction.SET_FILL_STYLE, fillStyle];
37119    if (typeof fillStyle !== 'string') {
37120      // Fill is a pattern or gradient - align it!
37121      fillInstruction.push(true);
37122    }
37123    return fillInstruction;
37124  }
37125
37126  /**
37127   * @param {import("../canvas.js").FillStrokeState} state State.
37128   */
37129  applyStroke(state) {
37130    this.instructions.push(this.createStroke(state));
37131  }
37132
37133  /**
37134   * @param {import("../canvas.js").FillStrokeState} state State.
37135   * @return {Array<*>} Stroke instruction.
37136   */
37137  createStroke(state) {
37138    return [
37139      canvas_Instruction.SET_STROKE_STYLE,
37140      state.strokeStyle,
37141      state.lineWidth * this.pixelRatio,
37142      state.lineCap,
37143      state.lineJoin,
37144      state.miterLimit,
37145      this.applyPixelRatio(state.lineDash),
37146      state.lineDashOffset * this.pixelRatio,
37147    ];
37148  }
37149
37150  /**
37151   * @param {import("../canvas.js").FillStrokeState} state State.
37152   * @param {function(this:CanvasBuilder, import("../canvas.js").FillStrokeState):Array<*>} createFill Create fill.
37153   */
37154  updateFillStyle(state, createFill) {
37155    const fillStyle = state.fillStyle;
37156    if (typeof fillStyle !== 'string' || state.currentFillStyle != fillStyle) {
37157      if (fillStyle !== undefined) {
37158        this.instructions.push(createFill.call(this, state));
37159      }
37160      state.currentFillStyle = fillStyle;
37161    }
37162  }
37163
37164  /**
37165   * @param {import("../canvas.js").FillStrokeState} state State.
37166   * @param {function(this:CanvasBuilder, import("../canvas.js").FillStrokeState): void} applyStroke Apply stroke.
37167   */
37168  updateStrokeStyle(state, applyStroke) {
37169    const strokeStyle = state.strokeStyle;
37170    const lineCap = state.lineCap;
37171    const lineDash = state.lineDash;
37172    const lineDashOffset = state.lineDashOffset;
37173    const lineJoin = state.lineJoin;
37174    const lineWidth = state.lineWidth;
37175    const miterLimit = state.miterLimit;
37176    if (
37177      state.currentStrokeStyle != strokeStyle ||
37178      state.currentLineCap != lineCap ||
37179      (lineDash != state.currentLineDash &&
37180        !equals(state.currentLineDash, lineDash)) ||
37181      state.currentLineDashOffset != lineDashOffset ||
37182      state.currentLineJoin != lineJoin ||
37183      state.currentLineWidth != lineWidth ||
37184      state.currentMiterLimit != miterLimit
37185    ) {
37186      if (strokeStyle !== undefined) {
37187        applyStroke.call(this, state);
37188      }
37189      state.currentStrokeStyle = strokeStyle;
37190      state.currentLineCap = lineCap;
37191      state.currentLineDash = lineDash;
37192      state.currentLineDashOffset = lineDashOffset;
37193      state.currentLineJoin = lineJoin;
37194      state.currentLineWidth = lineWidth;
37195      state.currentMiterLimit = miterLimit;
37196    }
37197  }
37198
37199  /**
37200   * @param {import("../../Feature.js").FeatureLike} feature Feature.
37201   */
37202  endGeometry(feature) {
37203    this.beginGeometryInstruction1_[2] = this.instructions.length;
37204    this.beginGeometryInstruction1_ = null;
37205    this.beginGeometryInstruction2_[2] = this.hitDetectionInstructions.length;
37206    this.beginGeometryInstruction2_ = null;
37207    const endGeometryInstruction = [canvas_Instruction.END_GEOMETRY, feature];
37208    this.instructions.push(endGeometryInstruction);
37209    this.hitDetectionInstructions.push(endGeometryInstruction);
37210  }
37211
37212  /**
37213   * Get the buffered rendering extent.  Rendering will be clipped to the extent
37214   * provided to the constructor.  To account for symbolizers that may intersect
37215   * this extent, we calculate a buffered extent (e.g. based on stroke width).
37216   * @return {import("../../extent.js").Extent} The buffered rendering extent.
37217   * @protected
37218   */
37219  getBufferedMaxExtent() {
37220    if (!this.bufferedMaxExtent_) {
37221      this.bufferedMaxExtent_ = clone(this.maxExtent);
37222      if (this.maxLineWidth > 0) {
37223        const width = (this.resolution * (this.maxLineWidth + 1)) / 2;
37224        buffer(this.bufferedMaxExtent_, width, this.bufferedMaxExtent_);
37225      }
37226    }
37227    return this.bufferedMaxExtent_;
37228  }
37229}
37230
37231/* harmony default export */ const Builder = (CanvasBuilder);
37232
37233;// CONCATENATED MODULE: ./node_modules/ol/render/canvas/ImageBuilder.js
37234/**
37235 * @module ol/render/canvas/ImageBuilder
37236 */
37237
37238
37239
37240class CanvasImageBuilder extends Builder {
37241  /**
37242   * @param {number} tolerance Tolerance.
37243   * @param {import("../../extent.js").Extent} maxExtent Maximum extent.
37244   * @param {number} resolution Resolution.
37245   * @param {number} pixelRatio Pixel ratio.
37246   */
37247  constructor(tolerance, maxExtent, resolution, pixelRatio) {
37248    super(tolerance, maxExtent, resolution, pixelRatio);
37249
37250    /**
37251     * @private
37252     * @type {HTMLCanvasElement|HTMLVideoElement|HTMLImageElement}
37253     */
37254    this.hitDetectionImage_ = null;
37255
37256    /**
37257     * @private
37258     * @type {HTMLCanvasElement|HTMLVideoElement|HTMLImageElement}
37259     */
37260    this.image_ = null;
37261
37262    /**
37263     * @private
37264     * @type {number|undefined}
37265     */
37266    this.imagePixelRatio_ = undefined;
37267
37268    /**
37269     * @private
37270     * @type {number|undefined}
37271     */
37272    this.anchorX_ = undefined;
37273
37274    /**
37275     * @private
37276     * @type {number|undefined}
37277     */
37278    this.anchorY_ = undefined;
37279
37280    /**
37281     * @private
37282     * @type {number|undefined}
37283     */
37284    this.height_ = undefined;
37285
37286    /**
37287     * @private
37288     * @type {number|undefined}
37289     */
37290    this.opacity_ = undefined;
37291
37292    /**
37293     * @private
37294     * @type {number|undefined}
37295     */
37296    this.originX_ = undefined;
37297
37298    /**
37299     * @private
37300     * @type {number|undefined}
37301     */
37302    this.originY_ = undefined;
37303
37304    /**
37305     * @private
37306     * @type {boolean|undefined}
37307     */
37308    this.rotateWithView_ = undefined;
37309
37310    /**
37311     * @private
37312     * @type {number|undefined}
37313     */
37314    this.rotation_ = undefined;
37315
37316    /**
37317     * @private
37318     * @type {import("../../size.js").Size|undefined}
37319     */
37320    this.scale_ = undefined;
37321
37322    /**
37323     * @private
37324     * @type {number|undefined}
37325     */
37326    this.width_ = undefined;
37327
37328    /**
37329     * @private
37330     * @type {"declutter"|"obstacle"|"none"|undefined}
37331     */
37332    this.declutterMode_ = undefined;
37333
37334    /**
37335     * Data shared with a text builder for combined decluttering.
37336     * @private
37337     * @type {import("../canvas.js").DeclutterImageWithText}
37338     */
37339    this.declutterImageWithText_ = undefined;
37340  }
37341
37342  /**
37343   * @param {import("../../geom/Point.js").default|import("../Feature.js").default} pointGeometry Point geometry.
37344   * @param {import("../../Feature.js").FeatureLike} feature Feature.
37345   */
37346  drawPoint(pointGeometry, feature) {
37347    if (!this.image_) {
37348      return;
37349    }
37350    this.beginGeometry(pointGeometry, feature);
37351    const flatCoordinates = pointGeometry.getFlatCoordinates();
37352    const stride = pointGeometry.getStride();
37353    const myBegin = this.coordinates.length;
37354    const myEnd = this.appendFlatPointCoordinates(flatCoordinates, stride);
37355    this.instructions.push([
37356      canvas_Instruction.DRAW_IMAGE,
37357      myBegin,
37358      myEnd,
37359      this.image_,
37360      // Remaining arguments to DRAW_IMAGE are in alphabetical order
37361      this.anchorX_ * this.imagePixelRatio_,
37362      this.anchorY_ * this.imagePixelRatio_,
37363      Math.ceil(this.height_ * this.imagePixelRatio_),
37364      this.opacity_,
37365      this.originX_ * this.imagePixelRatio_,
37366      this.originY_ * this.imagePixelRatio_,
37367      this.rotateWithView_,
37368      this.rotation_,
37369      [
37370        (this.scale_[0] * this.pixelRatio) / this.imagePixelRatio_,
37371        (this.scale_[1] * this.pixelRatio) / this.imagePixelRatio_,
37372      ],
37373      Math.ceil(this.width_ * this.imagePixelRatio_),
37374      this.declutterMode_,
37375      this.declutterImageWithText_,
37376    ]);
37377    this.hitDetectionInstructions.push([
37378      canvas_Instruction.DRAW_IMAGE,
37379      myBegin,
37380      myEnd,
37381      this.hitDetectionImage_,
37382      // Remaining arguments to DRAW_IMAGE are in alphabetical order
37383      this.anchorX_,
37384      this.anchorY_,
37385      this.height_,
37386      this.opacity_,
37387      this.originX_,
37388      this.originY_,
37389      this.rotateWithView_,
37390      this.rotation_,
37391      this.scale_,
37392      this.width_,
37393      this.declutterMode_,
37394      this.declutterImageWithText_,
37395    ]);
37396    this.endGeometry(feature);
37397  }
37398
37399  /**
37400   * @param {import("../../geom/MultiPoint.js").default|import("../Feature.js").default} multiPointGeometry MultiPoint geometry.
37401   * @param {import("../../Feature.js").FeatureLike} feature Feature.
37402   */
37403  drawMultiPoint(multiPointGeometry, feature) {
37404    if (!this.image_) {
37405      return;
37406    }
37407    this.beginGeometry(multiPointGeometry, feature);
37408    const flatCoordinates = multiPointGeometry.getFlatCoordinates();
37409    const stride = multiPointGeometry.getStride();
37410    const myBegin = this.coordinates.length;
37411    const myEnd = this.appendFlatPointCoordinates(flatCoordinates, stride);
37412    this.instructions.push([
37413      canvas_Instruction.DRAW_IMAGE,
37414      myBegin,
37415      myEnd,
37416      this.image_,
37417      // Remaining arguments to DRAW_IMAGE are in alphabetical order
37418      this.anchorX_ * this.imagePixelRatio_,
37419      this.anchorY_ * this.imagePixelRatio_,
37420      Math.ceil(this.height_ * this.imagePixelRatio_),
37421      this.opacity_,
37422      this.originX_ * this.imagePixelRatio_,
37423      this.originY_ * this.imagePixelRatio_,
37424      this.rotateWithView_,
37425      this.rotation_,
37426      [
37427        (this.scale_[0] * this.pixelRatio) / this.imagePixelRatio_,
37428        (this.scale_[1] * this.pixelRatio) / this.imagePixelRatio_,
37429      ],
37430      Math.ceil(this.width_ * this.imagePixelRatio_),
37431      this.declutterMode_,
37432      this.declutterImageWithText_,
37433    ]);
37434    this.hitDetectionInstructions.push([
37435      canvas_Instruction.DRAW_IMAGE,
37436      myBegin,
37437      myEnd,
37438      this.hitDetectionImage_,
37439      // Remaining arguments to DRAW_IMAGE are in alphabetical order
37440      this.anchorX_,
37441      this.anchorY_,
37442      this.height_,
37443      this.opacity_,
37444      this.originX_,
37445      this.originY_,
37446      this.rotateWithView_,
37447      this.rotation_,
37448      this.scale_,
37449      this.width_,
37450      this.declutterMode_,
37451      this.declutterImageWithText_,
37452    ]);
37453    this.endGeometry(feature);
37454  }
37455
37456  /**
37457   * @return {import("../canvas.js").SerializableInstructions} the serializable instructions.
37458   */
37459  finish() {
37460    this.reverseHitDetectionInstructions();
37461    // FIXME this doesn't really protect us against further calls to draw*Geometry
37462    this.anchorX_ = undefined;
37463    this.anchorY_ = undefined;
37464    this.hitDetectionImage_ = null;
37465    this.image_ = null;
37466    this.imagePixelRatio_ = undefined;
37467    this.height_ = undefined;
37468    this.scale_ = undefined;
37469    this.opacity_ = undefined;
37470    this.originX_ = undefined;
37471    this.originY_ = undefined;
37472    this.rotateWithView_ = undefined;
37473    this.rotation_ = undefined;
37474    this.width_ = undefined;
37475    return super.finish();
37476  }
37477
37478  /**
37479   * @param {import("../../style/Image.js").default} imageStyle Image style.
37480   * @param {Object} [sharedData] Shared data.
37481   */
37482  setImageStyle(imageStyle, sharedData) {
37483    const anchor = imageStyle.getAnchor();
37484    const size = imageStyle.getSize();
37485    const origin = imageStyle.getOrigin();
37486    this.imagePixelRatio_ = imageStyle.getPixelRatio(this.pixelRatio);
37487    this.anchorX_ = anchor[0];
37488    this.anchorY_ = anchor[1];
37489    this.hitDetectionImage_ = imageStyle.getHitDetectionImage();
37490    this.image_ = imageStyle.getImage(this.pixelRatio);
37491    this.height_ = size[1];
37492    this.opacity_ = imageStyle.getOpacity();
37493    this.originX_ = origin[0];
37494    this.originY_ = origin[1];
37495    this.rotateWithView_ = imageStyle.getRotateWithView();
37496    this.rotation_ = imageStyle.getRotation();
37497    this.scale_ = imageStyle.getScaleArray();
37498    this.width_ = size[0];
37499    this.declutterMode_ = imageStyle.getDeclutterMode();
37500    this.declutterImageWithText_ = sharedData;
37501  }
37502}
37503
37504/* harmony default export */ const ImageBuilder = (CanvasImageBuilder);
37505
37506;// CONCATENATED MODULE: ./node_modules/ol/render/canvas/LineStringBuilder.js
37507/**
37508 * @module ol/render/canvas/LineStringBuilder
37509 */
37510
37511
37512
37513
37514class CanvasLineStringBuilder extends Builder {
37515  /**
37516   * @param {number} tolerance Tolerance.
37517   * @param {import("../../extent.js").Extent} maxExtent Maximum extent.
37518   * @param {number} resolution Resolution.
37519   * @param {number} pixelRatio Pixel ratio.
37520   */
37521  constructor(tolerance, maxExtent, resolution, pixelRatio) {
37522    super(tolerance, maxExtent, resolution, pixelRatio);
37523  }
37524
37525  /**
37526   * @param {Array<number>} flatCoordinates Flat coordinates.
37527   * @param {number} offset Offset.
37528   * @param {number} end End.
37529   * @param {number} stride Stride.
37530   * @private
37531   * @return {number} end.
37532   */
37533  drawFlatCoordinates_(flatCoordinates, offset, end, stride) {
37534    const myBegin = this.coordinates.length;
37535    const myEnd = this.appendFlatLineCoordinates(
37536      flatCoordinates,
37537      offset,
37538      end,
37539      stride,
37540      false,
37541      false
37542    );
37543    const moveToLineToInstruction = [
37544      canvas_Instruction.MOVE_TO_LINE_TO,
37545      myBegin,
37546      myEnd,
37547    ];
37548    this.instructions.push(moveToLineToInstruction);
37549    this.hitDetectionInstructions.push(moveToLineToInstruction);
37550    return end;
37551  }
37552
37553  /**
37554   * @param {import("../../geom/LineString.js").default|import("../Feature.js").default} lineStringGeometry Line string geometry.
37555   * @param {import("../../Feature.js").FeatureLike} feature Feature.
37556   */
37557  drawLineString(lineStringGeometry, feature) {
37558    const state = this.state;
37559    const strokeStyle = state.strokeStyle;
37560    const lineWidth = state.lineWidth;
37561    if (strokeStyle === undefined || lineWidth === undefined) {
37562      return;
37563    }
37564    this.updateStrokeStyle(state, this.applyStroke);
37565    this.beginGeometry(lineStringGeometry, feature);
37566    this.hitDetectionInstructions.push(
37567      [
37568        canvas_Instruction.SET_STROKE_STYLE,
37569        state.strokeStyle,
37570        state.lineWidth,
37571        state.lineCap,
37572        state.lineJoin,
37573        state.miterLimit,
37574        defaultLineDash,
37575        defaultLineDashOffset,
37576      ],
37577      beginPathInstruction
37578    );
37579    const flatCoordinates = lineStringGeometry.getFlatCoordinates();
37580    const stride = lineStringGeometry.getStride();
37581    this.drawFlatCoordinates_(
37582      flatCoordinates,
37583      0,
37584      flatCoordinates.length,
37585      stride
37586    );
37587    this.hitDetectionInstructions.push(strokeInstruction);
37588    this.endGeometry(feature);
37589  }
37590
37591  /**
37592   * @param {import("../../geom/MultiLineString.js").default|import("../Feature.js").default} multiLineStringGeometry MultiLineString geometry.
37593   * @param {import("../../Feature.js").FeatureLike} feature Feature.
37594   */
37595  drawMultiLineString(multiLineStringGeometry, feature) {
37596    const state = this.state;
37597    const strokeStyle = state.strokeStyle;
37598    const lineWidth = state.lineWidth;
37599    if (strokeStyle === undefined || lineWidth === undefined) {
37600      return;
37601    }
37602    this.updateStrokeStyle(state, this.applyStroke);
37603    this.beginGeometry(multiLineStringGeometry, feature);
37604    this.hitDetectionInstructions.push(
37605      [
37606        canvas_Instruction.SET_STROKE_STYLE,
37607        state.strokeStyle,
37608        state.lineWidth,
37609        state.lineCap,
37610        state.lineJoin,
37611        state.miterLimit,
37612        state.lineDash,
37613        state.lineDashOffset,
37614      ],
37615      beginPathInstruction
37616    );
37617    const ends = multiLineStringGeometry.getEnds();
37618    const flatCoordinates = multiLineStringGeometry.getFlatCoordinates();
37619    const stride = multiLineStringGeometry.getStride();
37620    let offset = 0;
37621    for (let i = 0, ii = ends.length; i < ii; ++i) {
37622      offset = this.drawFlatCoordinates_(
37623        flatCoordinates,
37624        offset,
37625        /** @type {number} */ (ends[i]),
37626        stride
37627      );
37628    }
37629    this.hitDetectionInstructions.push(strokeInstruction);
37630    this.endGeometry(feature);
37631  }
37632
37633  /**
37634   * @return {import("../canvas.js").SerializableInstructions} the serializable instructions.
37635   */
37636  finish() {
37637    const state = this.state;
37638    if (
37639      state.lastStroke != undefined &&
37640      state.lastStroke != this.coordinates.length
37641    ) {
37642      this.instructions.push(strokeInstruction);
37643    }
37644    this.reverseHitDetectionInstructions();
37645    this.state = null;
37646    return super.finish();
37647  }
37648
37649  /**
37650   * @param {import("../canvas.js").FillStrokeState} state State.
37651   */
37652  applyStroke(state) {
37653    if (
37654      state.lastStroke != undefined &&
37655      state.lastStroke != this.coordinates.length
37656    ) {
37657      this.instructions.push(strokeInstruction);
37658      state.lastStroke = this.coordinates.length;
37659    }
37660    state.lastStroke = 0;
37661    super.applyStroke(state);
37662    this.instructions.push(beginPathInstruction);
37663  }
37664}
37665
37666/* harmony default export */ const LineStringBuilder = (CanvasLineStringBuilder);
37667
37668;// CONCATENATED MODULE: ./node_modules/ol/render/canvas/PolygonBuilder.js
37669/**
37670 * @module ol/render/canvas/PolygonBuilder
37671 */
37672
37673
37674
37675
37676
37677class CanvasPolygonBuilder extends Builder {
37678  /**
37679   * @param {number} tolerance Tolerance.
37680   * @param {import("../../extent.js").Extent} maxExtent Maximum extent.
37681   * @param {number} resolution Resolution.
37682   * @param {number} pixelRatio Pixel ratio.
37683   */
37684  constructor(tolerance, maxExtent, resolution, pixelRatio) {
37685    super(tolerance, maxExtent, resolution, pixelRatio);
37686  }
37687
37688  /**
37689   * @param {Array<number>} flatCoordinates Flat coordinates.
37690   * @param {number} offset Offset.
37691   * @param {Array<number>} ends Ends.
37692   * @param {number} stride Stride.
37693   * @private
37694   * @return {number} End.
37695   */
37696  drawFlatCoordinatess_(flatCoordinates, offset, ends, stride) {
37697    const state = this.state;
37698    const fill = state.fillStyle !== undefined;
37699    const stroke = state.strokeStyle !== undefined;
37700    const numEnds = ends.length;
37701    this.instructions.push(beginPathInstruction);
37702    this.hitDetectionInstructions.push(beginPathInstruction);
37703    for (let i = 0; i < numEnds; ++i) {
37704      const end = ends[i];
37705      const myBegin = this.coordinates.length;
37706      const myEnd = this.appendFlatLineCoordinates(
37707        flatCoordinates,
37708        offset,
37709        end,
37710        stride,
37711        true,
37712        !stroke
37713      );
37714      const moveToLineToInstruction = [
37715        canvas_Instruction.MOVE_TO_LINE_TO,
37716        myBegin,
37717        myEnd,
37718      ];
37719      this.instructions.push(moveToLineToInstruction);
37720      this.hitDetectionInstructions.push(moveToLineToInstruction);
37721      if (stroke) {
37722        // Performance optimization: only call closePath() when we have a stroke.
37723        // Otherwise the ring is closed already (see appendFlatLineCoordinates above).
37724        this.instructions.push(closePathInstruction);
37725        this.hitDetectionInstructions.push(closePathInstruction);
37726      }
37727      offset = end;
37728    }
37729    if (fill) {
37730      this.instructions.push(fillInstruction);
37731      this.hitDetectionInstructions.push(fillInstruction);
37732    }
37733    if (stroke) {
37734      this.instructions.push(strokeInstruction);
37735      this.hitDetectionInstructions.push(strokeInstruction);
37736    }
37737    return offset;
37738  }
37739
37740  /**
37741   * @param {import("../../geom/Circle.js").default} circleGeometry Circle geometry.
37742   * @param {import("../../Feature.js").default} feature Feature.
37743   */
37744  drawCircle(circleGeometry, feature) {
37745    const state = this.state;
37746    const fillStyle = state.fillStyle;
37747    const strokeStyle = state.strokeStyle;
37748    if (fillStyle === undefined && strokeStyle === undefined) {
37749      return;
37750    }
37751    this.setFillStrokeStyles_();
37752    this.beginGeometry(circleGeometry, feature);
37753    if (state.fillStyle !== undefined) {
37754      this.hitDetectionInstructions.push([
37755        canvas_Instruction.SET_FILL_STYLE,
37756        defaultFillStyle,
37757      ]);
37758    }
37759    if (state.strokeStyle !== undefined) {
37760      this.hitDetectionInstructions.push([
37761        canvas_Instruction.SET_STROKE_STYLE,
37762        state.strokeStyle,
37763        state.lineWidth,
37764        state.lineCap,
37765        state.lineJoin,
37766        state.miterLimit,
37767        state.lineDash,
37768        state.lineDashOffset,
37769      ]);
37770    }
37771    const flatCoordinates = circleGeometry.getFlatCoordinates();
37772    const stride = circleGeometry.getStride();
37773    const myBegin = this.coordinates.length;
37774    this.appendFlatLineCoordinates(
37775      flatCoordinates,
37776      0,
37777      flatCoordinates.length,
37778      stride,
37779      false,
37780      false
37781    );
37782    const circleInstruction = [canvas_Instruction.CIRCLE, myBegin];
37783    this.instructions.push(beginPathInstruction, circleInstruction);
37784    this.hitDetectionInstructions.push(beginPathInstruction, circleInstruction);
37785    if (state.fillStyle !== undefined) {
37786      this.instructions.push(fillInstruction);
37787      this.hitDetectionInstructions.push(fillInstruction);
37788    }
37789    if (state.strokeStyle !== undefined) {
37790      this.instructions.push(strokeInstruction);
37791      this.hitDetectionInstructions.push(strokeInstruction);
37792    }
37793    this.endGeometry(feature);
37794  }
37795
37796  /**
37797   * @param {import("../../geom/Polygon.js").default|import("../Feature.js").default} polygonGeometry Polygon geometry.
37798   * @param {import("../../Feature.js").FeatureLike} feature Feature.
37799   */
37800  drawPolygon(polygonGeometry, feature) {
37801    const state = this.state;
37802    const fillStyle = state.fillStyle;
37803    const strokeStyle = state.strokeStyle;
37804    if (fillStyle === undefined && strokeStyle === undefined) {
37805      return;
37806    }
37807    this.setFillStrokeStyles_();
37808    this.beginGeometry(polygonGeometry, feature);
37809    if (state.fillStyle !== undefined) {
37810      this.hitDetectionInstructions.push([
37811        canvas_Instruction.SET_FILL_STYLE,
37812        defaultFillStyle,
37813      ]);
37814    }
37815    if (state.strokeStyle !== undefined) {
37816      this.hitDetectionInstructions.push([
37817        canvas_Instruction.SET_STROKE_STYLE,
37818        state.strokeStyle,
37819        state.lineWidth,
37820        state.lineCap,
37821        state.lineJoin,
37822        state.miterLimit,
37823        state.lineDash,
37824        state.lineDashOffset,
37825      ]);
37826    }
37827    const ends = polygonGeometry.getEnds();
37828    const flatCoordinates = polygonGeometry.getOrientedFlatCoordinates();
37829    const stride = polygonGeometry.getStride();
37830    this.drawFlatCoordinatess_(
37831      flatCoordinates,
37832      0,
37833      /** @type {Array<number>} */ (ends),
37834      stride
37835    );
37836    this.endGeometry(feature);
37837  }
37838
37839  /**
37840   * @param {import("../../geom/MultiPolygon.js").default} multiPolygonGeometry MultiPolygon geometry.
37841   * @param {import("../../Feature.js").FeatureLike} feature Feature.
37842   */
37843  drawMultiPolygon(multiPolygonGeometry, feature) {
37844    const state = this.state;
37845    const fillStyle = state.fillStyle;
37846    const strokeStyle = state.strokeStyle;
37847    if (fillStyle === undefined && strokeStyle === undefined) {
37848      return;
37849    }
37850    this.setFillStrokeStyles_();
37851    this.beginGeometry(multiPolygonGeometry, feature);
37852    if (state.fillStyle !== undefined) {
37853      this.hitDetectionInstructions.push([
37854        canvas_Instruction.SET_FILL_STYLE,
37855        defaultFillStyle,
37856      ]);
37857    }
37858    if (state.strokeStyle !== undefined) {
37859      this.hitDetectionInstructions.push([
37860        canvas_Instruction.SET_STROKE_STYLE,
37861        state.strokeStyle,
37862        state.lineWidth,
37863        state.lineCap,
37864        state.lineJoin,
37865        state.miterLimit,
37866        state.lineDash,
37867        state.lineDashOffset,
37868      ]);
37869    }
37870    const endss = multiPolygonGeometry.getEndss();
37871    const flatCoordinates = multiPolygonGeometry.getOrientedFlatCoordinates();
37872    const stride = multiPolygonGeometry.getStride();
37873    let offset = 0;
37874    for (let i = 0, ii = endss.length; i < ii; ++i) {
37875      offset = this.drawFlatCoordinatess_(
37876        flatCoordinates,
37877        offset,
37878        endss[i],
37879        stride
37880      );
37881    }
37882    this.endGeometry(feature);
37883  }
37884
37885  /**
37886   * @return {import("../canvas.js").SerializableInstructions} the serializable instructions.
37887   */
37888  finish() {
37889    this.reverseHitDetectionInstructions();
37890    this.state = null;
37891    // We want to preserve topology when drawing polygons.  Polygons are
37892    // simplified using quantization and point elimination. However, we might
37893    // have received a mix of quantized and non-quantized geometries, so ensure
37894    // that all are quantized by quantizing all coordinates in the batch.
37895    const tolerance = this.tolerance;
37896    if (tolerance !== 0) {
37897      const coordinates = this.coordinates;
37898      for (let i = 0, ii = coordinates.length; i < ii; ++i) {
37899        coordinates[i] = snap(coordinates[i], tolerance);
37900      }
37901    }
37902    return super.finish();
37903  }
37904
37905  /**
37906   * @private
37907   */
37908  setFillStrokeStyles_() {
37909    const state = this.state;
37910    const fillStyle = state.fillStyle;
37911    if (fillStyle !== undefined) {
37912      this.updateFillStyle(state, this.createFill);
37913    }
37914    if (state.strokeStyle !== undefined) {
37915      this.updateStrokeStyle(state, this.applyStroke);
37916    }
37917  }
37918}
37919
37920/* harmony default export */ const PolygonBuilder = (CanvasPolygonBuilder);
37921
37922;// CONCATENATED MODULE: ./node_modules/ol/geom/flat/straightchunk.js
37923/**
37924 * @module ol/geom/flat/straightchunk
37925 */
37926
37927/**
37928 * @param {number} maxAngle Maximum acceptable angle delta between segments.
37929 * @param {Array<number>} flatCoordinates Flat coordinates.
37930 * @param {number} offset Offset.
37931 * @param {number} end End.
37932 * @param {number} stride Stride.
37933 * @return {Array<number>} Start and end of the first suitable chunk of the
37934 * given `flatCoordinates`.
37935 */
37936function matchingChunk(maxAngle, flatCoordinates, offset, end, stride) {
37937  let chunkStart = offset;
37938  let chunkEnd = offset;
37939  let chunkM = 0;
37940  let m = 0;
37941  let start = offset;
37942  let acos, i, m12, m23, x1, y1, x12, y12, x23, y23;
37943  for (i = offset; i < end; i += stride) {
37944    const x2 = flatCoordinates[i];
37945    const y2 = flatCoordinates[i + 1];
37946    if (x1 !== undefined) {
37947      x23 = x2 - x1;
37948      y23 = y2 - y1;
37949      m23 = Math.sqrt(x23 * x23 + y23 * y23);
37950      if (x12 !== undefined) {
37951        m += m12;
37952        acos = Math.acos((x12 * x23 + y12 * y23) / (m12 * m23));
37953        if (acos > maxAngle) {
37954          if (m > chunkM) {
37955            chunkM = m;
37956            chunkStart = start;
37957            chunkEnd = i;
37958          }
37959          m = 0;
37960          start = i - stride;
37961        }
37962      }
37963      m12 = m23;
37964      x12 = x23;
37965      y12 = y23;
37966    }
37967    x1 = x2;
37968    y1 = y2;
37969  }
37970  m += m23;
37971  return m > chunkM ? [start, i] : [chunkStart, chunkEnd];
37972}
37973
37974;// CONCATENATED MODULE: ./node_modules/ol/render/canvas/TextBuilder.js
37975/**
37976 * @module ol/render/canvas/TextBuilder
37977 */
37978
37979
37980
37981
37982
37983
37984
37985/**
37986 * @const
37987 * @enum {number}
37988 */
37989const TEXT_ALIGN = {
37990  'left': 0,
37991  'end': 0,
37992  'center': 0.5,
37993  'right': 1,
37994  'start': 1,
37995  'top': 0,
37996  'middle': 0.5,
37997  'hanging': 0.2,
37998  'alphabetic': 0.8,
37999  'ideographic': 0.8,
38000  'bottom': 1,
38001};
38002
38003class CanvasTextBuilder extends Builder {
38004  /**
38005   * @param {number} tolerance Tolerance.
38006   * @param {import("../../extent.js").Extent} maxExtent Maximum extent.
38007   * @param {number} resolution Resolution.
38008   * @param {number} pixelRatio Pixel ratio.
38009   */
38010  constructor(tolerance, maxExtent, resolution, pixelRatio) {
38011    super(tolerance, maxExtent, resolution, pixelRatio);
38012
38013    /**
38014     * @private
38015     * @type {Array<HTMLCanvasElement>}
38016     */
38017    this.labels_ = null;
38018
38019    /**
38020     * @private
38021     * @type {string|Array<string>}
38022     */
38023    this.text_ = '';
38024
38025    /**
38026     * @private
38027     * @type {number}
38028     */
38029    this.textOffsetX_ = 0;
38030
38031    /**
38032     * @private
38033     * @type {number}
38034     */
38035    this.textOffsetY_ = 0;
38036
38037    /**
38038     * @private
38039     * @type {boolean|undefined}
38040     */
38041    this.textRotateWithView_ = undefined;
38042
38043    /**
38044     * @private
38045     * @type {number}
38046     */
38047    this.textRotation_ = 0;
38048
38049    /**
38050     * @private
38051     * @type {?import("../canvas.js").FillState}
38052     */
38053    this.textFillState_ = null;
38054
38055    /**
38056     * @type {!Object<string, import("../canvas.js").FillState>}
38057     */
38058    this.fillStates = {};
38059
38060    /**
38061     * @private
38062     * @type {?import("../canvas.js").StrokeState}
38063     */
38064    this.textStrokeState_ = null;
38065
38066    /**
38067     * @type {!Object<string, import("../canvas.js").StrokeState>}
38068     */
38069    this.strokeStates = {};
38070
38071    /**
38072     * @private
38073     * @type {import("../canvas.js").TextState}
38074     */
38075    this.textState_ = /** @type {import("../canvas.js").TextState} */ ({});
38076
38077    /**
38078     * @type {!Object<string, import("../canvas.js").TextState>}
38079     */
38080    this.textStates = {};
38081
38082    /**
38083     * @private
38084     * @type {string}
38085     */
38086    this.textKey_ = '';
38087
38088    /**
38089     * @private
38090     * @type {string}
38091     */
38092    this.fillKey_ = '';
38093
38094    /**
38095     * @private
38096     * @type {string}
38097     */
38098    this.strokeKey_ = '';
38099
38100    /**
38101     * Data shared with an image builder for combined decluttering.
38102     * @private
38103     * @type {import("../canvas.js").DeclutterImageWithText}
38104     */
38105    this.declutterImageWithText_ = undefined;
38106  }
38107
38108  /**
38109   * @return {import("../canvas.js").SerializableInstructions} the serializable instructions.
38110   */
38111  finish() {
38112    const instructions = super.finish();
38113    instructions.textStates = this.textStates;
38114    instructions.fillStates = this.fillStates;
38115    instructions.strokeStates = this.strokeStates;
38116    return instructions;
38117  }
38118
38119  /**
38120   * @param {import("../../geom/SimpleGeometry.js").default|import("../Feature.js").default} geometry Geometry.
38121   * @param {import("../../Feature.js").FeatureLike} feature Feature.
38122   */
38123  drawText(geometry, feature) {
38124    const fillState = this.textFillState_;
38125    const strokeState = this.textStrokeState_;
38126    const textState = this.textState_;
38127    if (this.text_ === '' || !textState || (!fillState && !strokeState)) {
38128      return;
38129    }
38130
38131    const coordinates = this.coordinates;
38132    let begin = coordinates.length;
38133
38134    const geometryType = geometry.getType();
38135    let flatCoordinates = null;
38136    let stride = geometry.getStride();
38137
38138    if (
38139      textState.placement === 'line' &&
38140      (geometryType == 'LineString' ||
38141        geometryType == 'MultiLineString' ||
38142        geometryType == 'Polygon' ||
38143        geometryType == 'MultiPolygon')
38144    ) {
38145      if (!intersects(this.getBufferedMaxExtent(), geometry.getExtent())) {
38146        return;
38147      }
38148      let ends;
38149      flatCoordinates = geometry.getFlatCoordinates();
38150      if (geometryType == 'LineString') {
38151        ends = [flatCoordinates.length];
38152      } else if (geometryType == 'MultiLineString') {
38153        ends = /** @type {import("../../geom/MultiLineString.js").default} */ (
38154          geometry
38155        ).getEnds();
38156      } else if (geometryType == 'Polygon') {
38157        ends = /** @type {import("../../geom/Polygon.js").default} */ (geometry)
38158          .getEnds()
38159          .slice(0, 1);
38160      } else if (geometryType == 'MultiPolygon') {
38161        const endss =
38162          /** @type {import("../../geom/MultiPolygon.js").default} */ (
38163            geometry
38164          ).getEndss();
38165        ends = [];
38166        for (let i = 0, ii = endss.length; i < ii; ++i) {
38167          ends.push(endss[i][0]);
38168        }
38169      }
38170      this.beginGeometry(geometry, feature);
38171      const textAlign = textState.textAlign;
38172      // No `justify` support for line placement.
38173      let flatOffset = 0;
38174      let flatEnd;
38175      for (let o = 0, oo = ends.length; o < oo; ++o) {
38176        if (textAlign == undefined) {
38177          const range = matchingChunk(
38178            textState.maxAngle,
38179            flatCoordinates,
38180            flatOffset,
38181            ends[o],
38182            stride
38183          );
38184          flatOffset = range[0];
38185          flatEnd = range[1];
38186        } else {
38187          flatEnd = ends[o];
38188        }
38189        for (let i = flatOffset; i < flatEnd; i += stride) {
38190          coordinates.push(flatCoordinates[i], flatCoordinates[i + 1]);
38191        }
38192        const end = coordinates.length;
38193        flatOffset = ends[o];
38194        this.drawChars_(begin, end);
38195        begin = end;
38196      }
38197      this.endGeometry(feature);
38198    } else {
38199      let geometryWidths = textState.overflow ? null : [];
38200      switch (geometryType) {
38201        case 'Point':
38202        case 'MultiPoint':
38203          flatCoordinates =
38204            /** @type {import("../../geom/MultiPoint.js").default} */ (
38205              geometry
38206            ).getFlatCoordinates();
38207          break;
38208        case 'LineString':
38209          flatCoordinates =
38210            /** @type {import("../../geom/LineString.js").default} */ (
38211              geometry
38212            ).getFlatMidpoint();
38213          break;
38214        case 'Circle':
38215          flatCoordinates =
38216            /** @type {import("../../geom/Circle.js").default} */ (
38217              geometry
38218            ).getCenter();
38219          break;
38220        case 'MultiLineString':
38221          flatCoordinates =
38222            /** @type {import("../../geom/MultiLineString.js").default} */ (
38223              geometry
38224            ).getFlatMidpoints();
38225          stride = 2;
38226          break;
38227        case 'Polygon':
38228          flatCoordinates =
38229            /** @type {import("../../geom/Polygon.js").default} */ (
38230              geometry
38231            ).getFlatInteriorPoint();
38232          if (!textState.overflow) {
38233            geometryWidths.push(flatCoordinates[2] / this.resolution);
38234          }
38235          stride = 3;
38236          break;
38237        case 'MultiPolygon':
38238          const interiorPoints =
38239            /** @type {import("../../geom/MultiPolygon.js").default} */ (
38240              geometry
38241            ).getFlatInteriorPoints();
38242          flatCoordinates = [];
38243          for (let i = 0, ii = interiorPoints.length; i < ii; i += 3) {
38244            if (!textState.overflow) {
38245              geometryWidths.push(interiorPoints[i + 2] / this.resolution);
38246            }
38247            flatCoordinates.push(interiorPoints[i], interiorPoints[i + 1]);
38248          }
38249          if (flatCoordinates.length === 0) {
38250            return;
38251          }
38252          stride = 2;
38253          break;
38254        default:
38255      }
38256      const end = this.appendFlatPointCoordinates(flatCoordinates, stride);
38257      if (end === begin) {
38258        return;
38259      }
38260      if (
38261        geometryWidths &&
38262        (end - begin) / 2 !== flatCoordinates.length / stride
38263      ) {
38264        let beg = begin / 2;
38265        geometryWidths = geometryWidths.filter((w, i) => {
38266          const keep =
38267            coordinates[(beg + i) * 2] === flatCoordinates[i * stride] &&
38268            coordinates[(beg + i) * 2 + 1] === flatCoordinates[i * stride + 1];
38269          if (!keep) {
38270            --beg;
38271          }
38272          return keep;
38273        });
38274      }
38275
38276      this.saveTextStates_();
38277
38278      if (textState.backgroundFill || textState.backgroundStroke) {
38279        this.setFillStrokeStyle(
38280          textState.backgroundFill,
38281          textState.backgroundStroke
38282        );
38283        if (textState.backgroundFill) {
38284          this.updateFillStyle(this.state, this.createFill);
38285          this.hitDetectionInstructions.push(this.createFill(this.state));
38286        }
38287        if (textState.backgroundStroke) {
38288          this.updateStrokeStyle(this.state, this.applyStroke);
38289          this.hitDetectionInstructions.push(this.createStroke(this.state));
38290        }
38291      }
38292
38293      this.beginGeometry(geometry, feature);
38294
38295      // adjust padding for negative scale
38296      let padding = textState.padding;
38297      if (
38298        padding != defaultPadding &&
38299        (textState.scale[0] < 0 || textState.scale[1] < 0)
38300      ) {
38301        let p0 = textState.padding[0];
38302        let p1 = textState.padding[1];
38303        let p2 = textState.padding[2];
38304        let p3 = textState.padding[3];
38305        if (textState.scale[0] < 0) {
38306          p1 = -p1;
38307          p3 = -p3;
38308        }
38309        if (textState.scale[1] < 0) {
38310          p0 = -p0;
38311          p2 = -p2;
38312        }
38313        padding = [p0, p1, p2, p3];
38314      }
38315
38316      // The image is unknown at this stage so we pass null; it will be computed at render time.
38317      // For clarity, we pass NaN for offsetX, offsetY, width and height, which will be computed at
38318      // render time.
38319      const pixelRatio = this.pixelRatio;
38320      this.instructions.push([
38321        canvas_Instruction.DRAW_IMAGE,
38322        begin,
38323        end,
38324        null,
38325        NaN,
38326        NaN,
38327        NaN,
38328        1,
38329        0,
38330        0,
38331        this.textRotateWithView_,
38332        this.textRotation_,
38333        [1, 1],
38334        NaN,
38335        undefined,
38336        this.declutterImageWithText_,
38337        padding == defaultPadding
38338          ? defaultPadding
38339          : padding.map(function (p) {
38340              return p * pixelRatio;
38341            }),
38342        !!textState.backgroundFill,
38343        !!textState.backgroundStroke,
38344        this.text_,
38345        this.textKey_,
38346        this.strokeKey_,
38347        this.fillKey_,
38348        this.textOffsetX_,
38349        this.textOffsetY_,
38350        geometryWidths,
38351      ]);
38352      const scale = 1 / pixelRatio;
38353      this.hitDetectionInstructions.push([
38354        canvas_Instruction.DRAW_IMAGE,
38355        begin,
38356        end,
38357        null,
38358        NaN,
38359        NaN,
38360        NaN,
38361        1,
38362        0,
38363        0,
38364        this.textRotateWithView_,
38365        this.textRotation_,
38366        [scale, scale],
38367        NaN,
38368        undefined,
38369        this.declutterImageWithText_,
38370        padding,
38371        !!textState.backgroundFill,
38372        !!textState.backgroundStroke,
38373        this.text_,
38374        this.textKey_,
38375        this.strokeKey_,
38376        this.fillKey_,
38377        this.textOffsetX_,
38378        this.textOffsetY_,
38379        geometryWidths,
38380      ]);
38381
38382      this.endGeometry(feature);
38383    }
38384  }
38385
38386  /**
38387   * @private
38388   */
38389  saveTextStates_() {
38390    const strokeState = this.textStrokeState_;
38391    const textState = this.textState_;
38392    const fillState = this.textFillState_;
38393
38394    const strokeKey = this.strokeKey_;
38395    if (strokeState) {
38396      if (!(strokeKey in this.strokeStates)) {
38397        this.strokeStates[strokeKey] = {
38398          strokeStyle: strokeState.strokeStyle,
38399          lineCap: strokeState.lineCap,
38400          lineDashOffset: strokeState.lineDashOffset,
38401          lineWidth: strokeState.lineWidth,
38402          lineJoin: strokeState.lineJoin,
38403          miterLimit: strokeState.miterLimit,
38404          lineDash: strokeState.lineDash,
38405        };
38406      }
38407    }
38408    const textKey = this.textKey_;
38409    if (!(textKey in this.textStates)) {
38410      this.textStates[textKey] = {
38411        font: textState.font,
38412        textAlign: textState.textAlign || defaultTextAlign,
38413        justify: textState.justify,
38414        textBaseline: textState.textBaseline || defaultTextBaseline,
38415        scale: textState.scale,
38416      };
38417    }
38418    const fillKey = this.fillKey_;
38419    if (fillState) {
38420      if (!(fillKey in this.fillStates)) {
38421        this.fillStates[fillKey] = {
38422          fillStyle: fillState.fillStyle,
38423        };
38424      }
38425    }
38426  }
38427
38428  /**
38429   * @private
38430   * @param {number} begin Begin.
38431   * @param {number} end End.
38432   */
38433  drawChars_(begin, end) {
38434    const strokeState = this.textStrokeState_;
38435    const textState = this.textState_;
38436
38437    const strokeKey = this.strokeKey_;
38438    const textKey = this.textKey_;
38439    const fillKey = this.fillKey_;
38440    this.saveTextStates_();
38441
38442    const pixelRatio = this.pixelRatio;
38443    const baseline = TEXT_ALIGN[textState.textBaseline];
38444
38445    const offsetY = this.textOffsetY_ * pixelRatio;
38446    const text = this.text_;
38447    const strokeWidth = strokeState
38448      ? (strokeState.lineWidth * Math.abs(textState.scale[0])) / 2
38449      : 0;
38450
38451    this.instructions.push([
38452      canvas_Instruction.DRAW_CHARS,
38453      begin,
38454      end,
38455      baseline,
38456      textState.overflow,
38457      fillKey,
38458      textState.maxAngle,
38459      pixelRatio,
38460      offsetY,
38461      strokeKey,
38462      strokeWidth * pixelRatio,
38463      text,
38464      textKey,
38465      1,
38466    ]);
38467    this.hitDetectionInstructions.push([
38468      canvas_Instruction.DRAW_CHARS,
38469      begin,
38470      end,
38471      baseline,
38472      textState.overflow,
38473      fillKey,
38474      textState.maxAngle,
38475      1,
38476      offsetY,
38477      strokeKey,
38478      strokeWidth,
38479      text,
38480      textKey,
38481      1 / pixelRatio,
38482    ]);
38483  }
38484
38485  /**
38486   * @param {import("../../style/Text.js").default} textStyle Text style.
38487   * @param {Object} [sharedData] Shared data.
38488   */
38489  setTextStyle(textStyle, sharedData) {
38490    let textState, fillState, strokeState;
38491    if (!textStyle) {
38492      this.text_ = '';
38493    } else {
38494      const textFillStyle = textStyle.getFill();
38495      if (!textFillStyle) {
38496        fillState = null;
38497        this.textFillState_ = fillState;
38498      } else {
38499        fillState = this.textFillState_;
38500        if (!fillState) {
38501          fillState = /** @type {import("../canvas.js").FillState} */ ({});
38502          this.textFillState_ = fillState;
38503        }
38504        fillState.fillStyle = asColorLike(
38505          textFillStyle.getColor() || defaultFillStyle
38506        );
38507      }
38508
38509      const textStrokeStyle = textStyle.getStroke();
38510      if (!textStrokeStyle) {
38511        strokeState = null;
38512        this.textStrokeState_ = strokeState;
38513      } else {
38514        strokeState = this.textStrokeState_;
38515        if (!strokeState) {
38516          strokeState = /** @type {import("../canvas.js").StrokeState} */ ({});
38517          this.textStrokeState_ = strokeState;
38518        }
38519        const lineDash = textStrokeStyle.getLineDash();
38520        const lineDashOffset = textStrokeStyle.getLineDashOffset();
38521        const lineWidth = textStrokeStyle.getWidth();
38522        const miterLimit = textStrokeStyle.getMiterLimit();
38523        strokeState.lineCap = textStrokeStyle.getLineCap() || defaultLineCap;
38524        strokeState.lineDash = lineDash ? lineDash.slice() : defaultLineDash;
38525        strokeState.lineDashOffset =
38526          lineDashOffset === undefined ? defaultLineDashOffset : lineDashOffset;
38527        strokeState.lineJoin = textStrokeStyle.getLineJoin() || defaultLineJoin;
38528        strokeState.lineWidth =
38529          lineWidth === undefined ? defaultLineWidth : lineWidth;
38530        strokeState.miterLimit =
38531          miterLimit === undefined ? defaultMiterLimit : miterLimit;
38532        strokeState.strokeStyle = asColorLike(
38533          textStrokeStyle.getColor() || defaultStrokeStyle
38534        );
38535      }
38536
38537      textState = this.textState_;
38538      const font = textStyle.getFont() || defaultFont;
38539      registerFont(font);
38540      const textScale = textStyle.getScaleArray();
38541      textState.overflow = textStyle.getOverflow();
38542      textState.font = font;
38543      textState.maxAngle = textStyle.getMaxAngle();
38544      textState.placement = textStyle.getPlacement();
38545      textState.textAlign = textStyle.getTextAlign();
38546      textState.justify = textStyle.getJustify();
38547      textState.textBaseline =
38548        textStyle.getTextBaseline() || defaultTextBaseline;
38549      textState.backgroundFill = textStyle.getBackgroundFill();
38550      textState.backgroundStroke = textStyle.getBackgroundStroke();
38551      textState.padding = textStyle.getPadding() || defaultPadding;
38552      textState.scale = textScale === undefined ? [1, 1] : textScale;
38553
38554      const textOffsetX = textStyle.getOffsetX();
38555      const textOffsetY = textStyle.getOffsetY();
38556      const textRotateWithView = textStyle.getRotateWithView();
38557      const textRotation = textStyle.getRotation();
38558      this.text_ = textStyle.getText() || '';
38559      this.textOffsetX_ = textOffsetX === undefined ? 0 : textOffsetX;
38560      this.textOffsetY_ = textOffsetY === undefined ? 0 : textOffsetY;
38561      this.textRotateWithView_ =
38562        textRotateWithView === undefined ? false : textRotateWithView;
38563      this.textRotation_ = textRotation === undefined ? 0 : textRotation;
38564
38565      this.strokeKey_ = strokeState
38566        ? (typeof strokeState.strokeStyle == 'string'
38567            ? strokeState.strokeStyle
38568            : getUid(strokeState.strokeStyle)) +
38569          strokeState.lineCap +
38570          strokeState.lineDashOffset +
38571          '|' +
38572          strokeState.lineWidth +
38573          strokeState.lineJoin +
38574          strokeState.miterLimit +
38575          '[' +
38576          strokeState.lineDash.join() +
38577          ']'
38578        : '';
38579      this.textKey_ =
38580        textState.font +
38581        textState.scale +
38582        (textState.textAlign || '?') +
38583        (textState.justify || '?') +
38584        (textState.textBaseline || '?');
38585      this.fillKey_ = fillState
38586        ? typeof fillState.fillStyle == 'string'
38587          ? fillState.fillStyle
38588          : '|' + getUid(fillState.fillStyle)
38589        : '';
38590    }
38591    this.declutterImageWithText_ = sharedData;
38592  }
38593}
38594
38595/* harmony default export */ const TextBuilder = (CanvasTextBuilder);
38596
38597;// CONCATENATED MODULE: ./node_modules/ol/render/canvas/BuilderGroup.js
38598/**
38599 * @module ol/render/canvas/BuilderGroup
38600 */
38601
38602
38603
38604
38605
38606
38607
38608/**
38609 * @type {Object<import("../canvas.js").BuilderType, typeof Builder>}
38610 */
38611const BATCH_CONSTRUCTORS = {
38612  'Circle': PolygonBuilder,
38613  'Default': Builder,
38614  'Image': ImageBuilder,
38615  'LineString': LineStringBuilder,
38616  'Polygon': PolygonBuilder,
38617  'Text': TextBuilder,
38618};
38619
38620class BuilderGroup {
38621  /**
38622   * @param {number} tolerance Tolerance.
38623   * @param {import("../../extent.js").Extent} maxExtent Max extent.
38624   * @param {number} resolution Resolution.
38625   * @param {number} pixelRatio Pixel ratio.
38626   */
38627  constructor(tolerance, maxExtent, resolution, pixelRatio) {
38628    /**
38629     * @private
38630     * @type {number}
38631     */
38632    this.tolerance_ = tolerance;
38633
38634    /**
38635     * @private
38636     * @type {import("../../extent.js").Extent}
38637     */
38638    this.maxExtent_ = maxExtent;
38639
38640    /**
38641     * @private
38642     * @type {number}
38643     */
38644    this.pixelRatio_ = pixelRatio;
38645
38646    /**
38647     * @private
38648     * @type {number}
38649     */
38650    this.resolution_ = resolution;
38651
38652    /**
38653     * @private
38654     * @type {!Object<string, !Object<import("../canvas.js").BuilderType, Builder>>}
38655     */
38656    this.buildersByZIndex_ = {};
38657  }
38658
38659  /**
38660   * @return {!Object<string, !Object<import("../canvas.js").BuilderType, import("./Builder.js").SerializableInstructions>>} The serializable instructions
38661   */
38662  finish() {
38663    const builderInstructions = {};
38664    for (const zKey in this.buildersByZIndex_) {
38665      builderInstructions[zKey] = builderInstructions[zKey] || {};
38666      const builders = this.buildersByZIndex_[zKey];
38667      for (const builderKey in builders) {
38668        const builderInstruction = builders[builderKey].finish();
38669        builderInstructions[zKey][builderKey] = builderInstruction;
38670      }
38671    }
38672    return builderInstructions;
38673  }
38674
38675  /**
38676   * @param {number|undefined} zIndex Z index.
38677   * @param {import("../canvas.js").BuilderType} builderType Replay type.
38678   * @return {import("../VectorContext.js").default} Replay.
38679   */
38680  getBuilder(zIndex, builderType) {
38681    const zIndexKey = zIndex !== undefined ? zIndex.toString() : '0';
38682    let replays = this.buildersByZIndex_[zIndexKey];
38683    if (replays === undefined) {
38684      replays = {};
38685      this.buildersByZIndex_[zIndexKey] = replays;
38686    }
38687    let replay = replays[builderType];
38688    if (replay === undefined) {
38689      const Constructor = BATCH_CONSTRUCTORS[builderType];
38690      replay = new Constructor(
38691        this.tolerance_,
38692        this.maxExtent_,
38693        this.resolution_,
38694        this.pixelRatio_
38695      );
38696      replays[builderType] = replay;
38697    }
38698    return replay;
38699  }
38700}
38701
38702/* harmony default export */ const canvas_BuilderGroup = (BuilderGroup);
38703
38704;// CONCATENATED MODULE: ./node_modules/ol/renderer/Layer.js
38705/**
38706 * @module ol/renderer/Layer
38707 */
38708
38709
38710
38711
38712
38713/**
38714 * @template {import("../layer/Layer.js").default} LayerType
38715 */
38716class LayerRenderer extends ol_Observable {
38717  /**
38718   * @param {LayerType} layer Layer.
38719   */
38720  constructor(layer) {
38721    super();
38722
38723    /**
38724     * The renderer is initialized and ready to render.
38725     * @type {boolean}
38726     */
38727    this.ready = true;
38728
38729    /** @private */
38730    this.boundHandleImageChange_ = this.handleImageChange_.bind(this);
38731
38732    /**
38733     * @protected
38734     * @type {LayerType}
38735     */
38736    this.layer_ = layer;
38737
38738    /**
38739     * @type {import("../render/canvas/ExecutorGroup").default}
38740     */
38741    this.declutterExecutorGroup = null;
38742  }
38743
38744  /**
38745   * Asynchronous layer level hit detection.
38746   * @param {import("../pixel.js").Pixel} pixel Pixel.
38747   * @return {Promise<Array<import("../Feature").default>>} Promise that resolves with
38748   * an array of features.
38749   */
38750  getFeatures(pixel) {
38751    return util_abstract();
38752  }
38753
38754  /**
38755   * @param {import("../pixel.js").Pixel} pixel Pixel.
38756   * @return {Uint8ClampedArray|Uint8Array|Float32Array|DataView|null} Pixel data.
38757   */
38758  getData(pixel) {
38759    return null;
38760  }
38761
38762  /**
38763   * Determine whether render should be called.
38764   * @abstract
38765   * @param {import("../Map.js").FrameState} frameState Frame state.
38766   * @return {boolean} Layer is ready to be rendered.
38767   */
38768  prepareFrame(frameState) {
38769    return util_abstract();
38770  }
38771
38772  /**
38773   * Render the layer.
38774   * @abstract
38775   * @param {import("../Map.js").FrameState} frameState Frame state.
38776   * @param {HTMLElement} target Target that may be used to render content to.
38777   * @return {HTMLElement} The rendered element.
38778   */
38779  renderFrame(frameState, target) {
38780    return util_abstract();
38781  }
38782
38783  /**
38784   * @param {Object<number, Object<string, import("../Tile.js").default>>} tiles Lookup of loaded tiles by zoom level.
38785   * @param {number} zoom Zoom level.
38786   * @param {import("../Tile.js").default} tile Tile.
38787   * @return {boolean|void} If `false`, the tile will not be considered loaded.
38788   */
38789  loadedTileCallback(tiles, zoom, tile) {
38790    if (!tiles[zoom]) {
38791      tiles[zoom] = {};
38792    }
38793    tiles[zoom][tile.tileCoord.toString()] = tile;
38794    return undefined;
38795  }
38796
38797  /**
38798   * Create a function that adds loaded tiles to the tile lookup.
38799   * @param {import("../source/Tile.js").default} source Tile source.
38800   * @param {import("../proj/Projection.js").default} projection Projection of the tiles.
38801   * @param {Object<number, Object<string, import("../Tile.js").default>>} tiles Lookup of loaded tiles by zoom level.
38802   * @return {function(number, import("../TileRange.js").default):boolean} A function that can be
38803   *     called with a zoom level and a tile range to add loaded tiles to the lookup.
38804   * @protected
38805   */
38806  createLoadedTileFinder(source, projection, tiles) {
38807    return (
38808      /**
38809       * @param {number} zoom Zoom level.
38810       * @param {import("../TileRange.js").default} tileRange Tile range.
38811       * @return {boolean} The tile range is fully loaded.
38812       * @this {LayerRenderer}
38813       */
38814      function (zoom, tileRange) {
38815        const callback = this.loadedTileCallback.bind(this, tiles, zoom);
38816        return source.forEachLoadedTile(projection, zoom, tileRange, callback);
38817      }.bind(this)
38818    );
38819  }
38820  /**
38821   * @abstract
38822   * @param {import("../coordinate.js").Coordinate} coordinate Coordinate.
38823   * @param {import("../Map.js").FrameState} frameState Frame state.
38824   * @param {number} hitTolerance Hit tolerance in pixels.
38825   * @param {import("./vector.js").FeatureCallback<T>} callback Feature callback.
38826   * @param {Array<import("./Map.js").HitMatch<T>>} matches The hit detected matches with tolerance.
38827   * @return {T|undefined} Callback result.
38828   * @template T
38829   */
38830  forEachFeatureAtCoordinate(
38831    coordinate,
38832    frameState,
38833    hitTolerance,
38834    callback,
38835    matches
38836  ) {
38837    return undefined;
38838  }
38839
38840  /**
38841   * @return {LayerType} Layer.
38842   */
38843  getLayer() {
38844    return this.layer_;
38845  }
38846
38847  /**
38848   * Perform action necessary to get the layer rendered after new fonts have loaded
38849   * @abstract
38850   */
38851  handleFontsChanged() {}
38852
38853  /**
38854   * Handle changes in image state.
38855   * @param {import("../events/Event.js").default} event Image change event.
38856   * @private
38857   */
38858  handleImageChange_(event) {
38859    const image = /** @type {import("../Image.js").default} */ (event.target);
38860    if (image.getState() === ol_ImageState.LOADED) {
38861      this.renderIfReadyAndVisible();
38862    }
38863  }
38864
38865  /**
38866   * Load the image if not already loaded, and register the image change
38867   * listener if needed.
38868   * @param {import("../ImageBase.js").default} image Image.
38869   * @return {boolean} `true` if the image is already loaded, `false` otherwise.
38870   * @protected
38871   */
38872  loadImage(image) {
38873    let imageState = image.getState();
38874    if (imageState != ol_ImageState.LOADED && imageState != ol_ImageState.ERROR) {
38875      image.addEventListener(EventType.CHANGE, this.boundHandleImageChange_);
38876    }
38877    if (imageState == ol_ImageState.IDLE) {
38878      image.load();
38879      imageState = image.getState();
38880    }
38881    return imageState == ol_ImageState.LOADED;
38882  }
38883
38884  /**
38885   * @protected
38886   */
38887  renderIfReadyAndVisible() {
38888    const layer = this.getLayer();
38889    if (layer && layer.getVisible() && layer.getSourceState() === 'ready') {
38890      layer.changed();
38891    }
38892  }
38893
38894  /**
38895   * Clean up.
38896   */
38897  disposeInternal() {
38898    delete this.layer_;
38899    super.disposeInternal();
38900  }
38901}
38902
38903/* harmony default export */ const renderer_Layer = (LayerRenderer);
38904
38905;// CONCATENATED MODULE: ./node_modules/ol/renderer/canvas/Layer.js
38906/**
38907 * @module ol/renderer/canvas/Layer
38908 */
38909
38910
38911
38912
38913
38914
38915
38916
38917
38918/**
38919 * @type {Array<HTMLCanvasElement>}
38920 */
38921const canvasPool = [];
38922
38923/**
38924 * @type {CanvasRenderingContext2D}
38925 */
38926let pixelContext = null;
38927
38928function createPixelContext() {
38929  const canvas = document.createElement('canvas');
38930  canvas.width = 1;
38931  canvas.height = 1;
38932  pixelContext = canvas.getContext('2d');
38933}
38934
38935/**
38936 * @abstract
38937 * @template {import("../../layer/Layer.js").default} LayerType
38938 * @extends {LayerRenderer<LayerType>}
38939 */
38940class CanvasLayerRenderer extends renderer_Layer {
38941  /**
38942   * @param {LayerType} layer Layer.
38943   */
38944  constructor(layer) {
38945    super(layer);
38946
38947    /**
38948     * @protected
38949     * @type {HTMLElement}
38950     */
38951    this.container = null;
38952
38953    /**
38954     * @protected
38955     * @type {number}
38956     */
38957    this.renderedResolution;
38958
38959    /**
38960     * A temporary transform.  The values in this transform should only be used in a
38961     * function that sets the values.
38962     * @protected
38963     * @type {import("../../transform.js").Transform}
38964     */
38965    this.tempTransform = create();
38966
38967    /**
38968     * The transform for rendered pixels to viewport CSS pixels.  This transform must
38969     * be set when rendering a frame and may be used by other functions after rendering.
38970     * @protected
38971     * @type {import("../../transform.js").Transform}
38972     */
38973    this.pixelTransform = create();
38974
38975    /**
38976     * The transform for viewport CSS pixels to rendered pixels.  This transform must
38977     * be set when rendering a frame and may be used by other functions after rendering.
38978     * @protected
38979     * @type {import("../../transform.js").Transform}
38980     */
38981    this.inversePixelTransform = create();
38982
38983    /**
38984     * @type {CanvasRenderingContext2D}
38985     */
38986    this.context = null;
38987
38988    /**
38989     * @type {boolean}
38990     */
38991    this.containerReused = false;
38992
38993    /**
38994     * @private
38995     * @type {CanvasRenderingContext2D}
38996     */
38997    this.pixelContext_ = null;
38998
38999    /**
39000     * @protected
39001     * @type {import("../../Map.js").FrameState|null}
39002     */
39003    this.frameState = null;
39004  }
39005
39006  /**
39007   * @param {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} image Image.
39008   * @param {number} col The column index.
39009   * @param {number} row The row index.
39010   * @return {Uint8ClampedArray|null} The image data.
39011   */
39012  getImageData(image, col, row) {
39013    if (!pixelContext) {
39014      createPixelContext();
39015    }
39016    pixelContext.clearRect(0, 0, 1, 1);
39017
39018    let data;
39019    try {
39020      pixelContext.drawImage(image, col, row, 1, 1, 0, 0, 1, 1);
39021      data = pixelContext.getImageData(0, 0, 1, 1).data;
39022    } catch (err) {
39023      pixelContext = null;
39024      return null;
39025    }
39026    return data;
39027  }
39028
39029  /**
39030   * @param {import('../../Map.js').FrameState} frameState Frame state.
39031   * @return {string} Background color.
39032   */
39033  getBackground(frameState) {
39034    const layer = this.getLayer();
39035    let background = layer.getBackground();
39036    if (typeof background === 'function') {
39037      background = background(frameState.viewState.resolution);
39038    }
39039    return background || undefined;
39040  }
39041
39042  /**
39043   * Get a rendering container from an existing target, if compatible.
39044   * @param {HTMLElement} target Potential render target.
39045   * @param {string} transform CSS Transform.
39046   * @param {string} [backgroundColor] Background color.
39047   */
39048  useContainer(target, transform, backgroundColor) {
39049    const layerClassName = this.getLayer().getClassName();
39050    let container, context;
39051    if (
39052      target &&
39053      target.className === layerClassName &&
39054      (!backgroundColor ||
39055        (target &&
39056          target.style.backgroundColor &&
39057          equals(
39058            asArray(target.style.backgroundColor),
39059            asArray(backgroundColor)
39060          )))
39061    ) {
39062      const canvas = target.firstElementChild;
39063      if (canvas instanceof HTMLCanvasElement) {
39064        context = canvas.getContext('2d');
39065      }
39066    }
39067    if (context && context.canvas.style.transform === transform) {
39068      // Container of the previous layer renderer can be used.
39069      this.container = target;
39070      this.context = context;
39071      this.containerReused = true;
39072    } else if (this.containerReused) {
39073      // Previously reused container cannot be used any more.
39074      this.container = null;
39075      this.context = null;
39076      this.containerReused = false;
39077    }
39078    if (!this.container) {
39079      container = document.createElement('div');
39080      container.className = layerClassName;
39081      let style = container.style;
39082      style.position = 'absolute';
39083      style.width = '100%';
39084      style.height = '100%';
39085      context = createCanvasContext2D();
39086      const canvas = context.canvas;
39087      container.appendChild(canvas);
39088      style = canvas.style;
39089      style.position = 'absolute';
39090      style.left = '0';
39091      style.transformOrigin = 'top left';
39092      this.container = container;
39093      this.context = context;
39094    }
39095    if (
39096      !this.containerReused &&
39097      backgroundColor &&
39098      !this.container.style.backgroundColor
39099    ) {
39100      this.container.style.backgroundColor = backgroundColor;
39101    }
39102  }
39103
39104  /**
39105   * @param {CanvasRenderingContext2D} context Context.
39106   * @param {import("../../Map.js").FrameState} frameState Frame state.
39107   * @param {import("../../extent.js").Extent} extent Clip extent.
39108   * @protected
39109   */
39110  clipUnrotated(context, frameState, extent) {
39111    const topLeft = getTopLeft(extent);
39112    const topRight = getTopRight(extent);
39113    const bottomRight = getBottomRight(extent);
39114    const bottomLeft = getBottomLeft(extent);
39115
39116    apply(frameState.coordinateToPixelTransform, topLeft);
39117    apply(frameState.coordinateToPixelTransform, topRight);
39118    apply(frameState.coordinateToPixelTransform, bottomRight);
39119    apply(frameState.coordinateToPixelTransform, bottomLeft);
39120
39121    const inverted = this.inversePixelTransform;
39122    apply(inverted, topLeft);
39123    apply(inverted, topRight);
39124    apply(inverted, bottomRight);
39125    apply(inverted, bottomLeft);
39126
39127    context.save();
39128    context.beginPath();
39129    context.moveTo(Math.round(topLeft[0]), Math.round(topLeft[1]));
39130    context.lineTo(Math.round(topRight[0]), Math.round(topRight[1]));
39131    context.lineTo(Math.round(bottomRight[0]), Math.round(bottomRight[1]));
39132    context.lineTo(Math.round(bottomLeft[0]), Math.round(bottomLeft[1]));
39133    context.clip();
39134  }
39135
39136  /**
39137   * @param {import("../../render/EventType.js").default} type Event type.
39138   * @param {CanvasRenderingContext2D} context Context.
39139   * @param {import("../../Map.js").FrameState} frameState Frame state.
39140   * @private
39141   */
39142  dispatchRenderEvent_(type, context, frameState) {
39143    const layer = this.getLayer();
39144    if (layer.hasListener(type)) {
39145      const event = new render_Event(
39146        type,
39147        this.inversePixelTransform,
39148        frameState,
39149        context
39150      );
39151      layer.dispatchEvent(event);
39152    }
39153  }
39154
39155  /**
39156   * @param {CanvasRenderingContext2D} context Context.
39157   * @param {import("../../Map.js").FrameState} frameState Frame state.
39158   * @protected
39159   */
39160  preRender(context, frameState) {
39161    this.frameState = frameState;
39162    this.dispatchRenderEvent_(render_EventType.PRERENDER, context, frameState);
39163  }
39164
39165  /**
39166   * @param {CanvasRenderingContext2D} context Context.
39167   * @param {import("../../Map.js").FrameState} frameState Frame state.
39168   * @protected
39169   */
39170  postRender(context, frameState) {
39171    this.dispatchRenderEvent_(render_EventType.POSTRENDER, context, frameState);
39172  }
39173
39174  /**
39175   * Creates a transform for rendering to an element that will be rotated after rendering.
39176   * @param {import("../../coordinate.js").Coordinate} center Center.
39177   * @param {number} resolution Resolution.
39178   * @param {number} rotation Rotation.
39179   * @param {number} pixelRatio Pixel ratio.
39180   * @param {number} width Width of the rendered element (in pixels).
39181   * @param {number} height Height of the rendered element (in pixels).
39182   * @param {number} offsetX Offset on the x-axis in view coordinates.
39183   * @protected
39184   * @return {!import("../../transform.js").Transform} Transform.
39185   */
39186  getRenderTransform(
39187    center,
39188    resolution,
39189    rotation,
39190    pixelRatio,
39191    width,
39192    height,
39193    offsetX
39194  ) {
39195    const dx1 = width / 2;
39196    const dy1 = height / 2;
39197    const sx = pixelRatio / resolution;
39198    const sy = -sx;
39199    const dx2 = -center[0] + offsetX;
39200    const dy2 = -center[1];
39201    return compose(
39202      this.tempTransform,
39203      dx1,
39204      dy1,
39205      sx,
39206      sy,
39207      -rotation,
39208      dx2,
39209      dy2
39210    );
39211  }
39212
39213  /**
39214   * Clean up.
39215   */
39216  disposeInternal() {
39217    delete this.frameState;
39218    super.disposeInternal();
39219  }
39220}
39221
39222/* harmony default export */ const canvas_Layer = (CanvasLayerRenderer);
39223
39224;// CONCATENATED MODULE: ./node_modules/ol/geom/flat/textpath.js
39225/**
39226 * @module ol/geom/flat/textpath
39227 */
39228
39229
39230
39231/**
39232 * @param {Array<number>} flatCoordinates Path to put text on.
39233 * @param {number} offset Start offset of the `flatCoordinates`.
39234 * @param {number} end End offset of the `flatCoordinates`.
39235 * @param {number} stride Stride.
39236 * @param {string} text Text to place on the path.
39237 * @param {number} startM m along the path where the text starts.
39238 * @param {number} maxAngle Max angle between adjacent chars in radians.
39239 * @param {number} scale The product of the text scale and the device pixel ratio.
39240 * @param {function(string, string, Object<string, number>):number} measureAndCacheTextWidth Measure and cache text width.
39241 * @param {string} font The font.
39242 * @param {Object<string, number>} cache A cache of measured widths.
39243 * @param {number} rotation Rotation to apply to the flatCoordinates to determine whether text needs to be reversed.
39244 * @return {Array<Array<*>>|null} The result array (or null if `maxAngle` was
39245 * exceeded). Entries of the array are x, y, anchorX, angle, chunk.
39246 */
39247function drawTextOnPath(
39248  flatCoordinates,
39249  offset,
39250  end,
39251  stride,
39252  text,
39253  startM,
39254  maxAngle,
39255  scale,
39256  measureAndCacheTextWidth,
39257  font,
39258  cache,
39259  rotation
39260) {
39261  let x2 = flatCoordinates[offset];
39262  let y2 = flatCoordinates[offset + 1];
39263  let x1 = 0;
39264  let y1 = 0;
39265  let segmentLength = 0;
39266  let segmentM = 0;
39267
39268  function advance() {
39269    x1 = x2;
39270    y1 = y2;
39271    offset += stride;
39272    x2 = flatCoordinates[offset];
39273    y2 = flatCoordinates[offset + 1];
39274    segmentM += segmentLength;
39275    segmentLength = Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
39276  }
39277  do {
39278    advance();
39279  } while (offset < end - stride && segmentM + segmentLength < startM);
39280
39281  let interpolate =
39282    segmentLength === 0 ? 0 : (startM - segmentM) / segmentLength;
39283  const beginX = lerp(x1, x2, interpolate);
39284  const beginY = lerp(y1, y2, interpolate);
39285
39286  const startOffset = offset - stride;
39287  const startLength = segmentM;
39288  const endM = startM + scale * measureAndCacheTextWidth(font, text, cache);
39289  while (offset < end - stride && segmentM + segmentLength < endM) {
39290    advance();
39291  }
39292  interpolate = segmentLength === 0 ? 0 : (endM - segmentM) / segmentLength;
39293  const endX = lerp(x1, x2, interpolate);
39294  const endY = lerp(y1, y2, interpolate);
39295
39296  // Keep text upright
39297  let reverse;
39298  if (rotation) {
39299    const flat = [beginX, beginY, endX, endY];
39300    flat_transform_rotate(flat, 0, 4, 2, rotation, flat, flat);
39301    reverse = flat[0] > flat[2];
39302  } else {
39303    reverse = beginX > endX;
39304  }
39305
39306  const PI = Math.PI;
39307  const result = [];
39308  const singleSegment = startOffset + stride === offset;
39309
39310  offset = startOffset;
39311  segmentLength = 0;
39312  segmentM = startLength;
39313  x2 = flatCoordinates[offset];
39314  y2 = flatCoordinates[offset + 1];
39315
39316  let previousAngle;
39317  // All on the same segment
39318  if (singleSegment) {
39319    advance();
39320
39321    previousAngle = Math.atan2(y2 - y1, x2 - x1);
39322    if (reverse) {
39323      previousAngle += previousAngle > 0 ? -PI : PI;
39324    }
39325    const x = (endX + beginX) / 2;
39326    const y = (endY + beginY) / 2;
39327    result[0] = [x, y, (endM - startM) / 2, previousAngle, text];
39328    return result;
39329  }
39330
39331  // rendering across line segments
39332  text = text.replace(/\n/g, ' '); // ensure rendering in single-line as all calculations below don't handle multi-lines
39333
39334  for (let i = 0, ii = text.length; i < ii; ) {
39335    advance();
39336    let angle = Math.atan2(y2 - y1, x2 - x1);
39337    if (reverse) {
39338      angle += angle > 0 ? -PI : PI;
39339    }
39340    if (previousAngle !== undefined) {
39341      let delta = angle - previousAngle;
39342      delta += delta > PI ? -2 * PI : delta < -PI ? 2 * PI : 0;
39343      if (Math.abs(delta) > maxAngle) {
39344        return null;
39345      }
39346    }
39347    previousAngle = angle;
39348
39349    const iStart = i;
39350    let charLength = 0;
39351    for (; i < ii; ++i) {
39352      const index = reverse ? ii - i - 1 : i;
39353      const len = scale * measureAndCacheTextWidth(font, text[index], cache);
39354      if (
39355        offset + stride < end &&
39356        segmentM + segmentLength < startM + charLength + len / 2
39357      ) {
39358        break;
39359      }
39360      charLength += len;
39361    }
39362    if (i === iStart) {
39363      continue;
39364    }
39365    const chars = reverse
39366      ? text.substring(ii - iStart, ii - i)
39367      : text.substring(iStart, i);
39368    interpolate =
39369      segmentLength === 0
39370        ? 0
39371        : (startM + charLength / 2 - segmentM) / segmentLength;
39372    const x = lerp(x1, x2, interpolate);
39373    const y = lerp(y1, y2, interpolate);
39374    result.push([x, y, charLength / 2, angle, chars]);
39375    startM += charLength;
39376  }
39377  return result;
39378}
39379
39380;// CONCATENATED MODULE: ./node_modules/ol/geom/flat/length.js
39381/**
39382 * @module ol/geom/flat/length
39383 */
39384
39385/**
39386 * @param {Array<number>} flatCoordinates Flat coordinates.
39387 * @param {number} offset Offset.
39388 * @param {number} end End.
39389 * @param {number} stride Stride.
39390 * @return {number} Length.
39391 */
39392function lineStringLength(flatCoordinates, offset, end, stride) {
39393  let x1 = flatCoordinates[offset];
39394  let y1 = flatCoordinates[offset + 1];
39395  let length = 0;
39396  for (let i = offset + stride; i < end; i += stride) {
39397    const x2 = flatCoordinates[i];
39398    const y2 = flatCoordinates[i + 1];
39399    length += Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
39400    x1 = x2;
39401    y1 = y2;
39402  }
39403  return length;
39404}
39405
39406/**
39407 * @param {Array<number>} flatCoordinates Flat coordinates.
39408 * @param {number} offset Offset.
39409 * @param {number} end End.
39410 * @param {number} stride Stride.
39411 * @return {number} Perimeter.
39412 */
39413function linearRingLength(flatCoordinates, offset, end, stride) {
39414  let perimeter = lineStringLength(flatCoordinates, offset, end, stride);
39415  const dx = flatCoordinates[end - stride] - flatCoordinates[offset];
39416  const dy = flatCoordinates[end - stride + 1] - flatCoordinates[offset + 1];
39417  perimeter += Math.sqrt(dx * dx + dy * dy);
39418  return perimeter;
39419}
39420
39421;// CONCATENATED MODULE: ./node_modules/ol/render/canvas/Executor.js
39422/**
39423 * @module ol/render/canvas/Executor
39424 */
39425
39426
39427
39428
39429
39430
39431
39432
39433
39434
39435/**
39436 * @typedef {Object} BBox
39437 * @property {number} minX Minimal x.
39438 * @property {number} minY Minimal y.
39439 * @property {number} maxX Maximal x.
39440 * @property {number} maxY Maximal y
39441 * @property {*} value Value.
39442 */
39443
39444/**
39445 * @typedef {Object} ImageOrLabelDimensions
39446 * @property {number} drawImageX DrawImageX.
39447 * @property {number} drawImageY DrawImageY.
39448 * @property {number} drawImageW DrawImageW.
39449 * @property {number} drawImageH DrawImageH.
39450 * @property {number} originX OriginX.
39451 * @property {number} originY OriginY.
39452 * @property {Array<number>} scale Scale.
39453 * @property {BBox} declutterBox DeclutterBox.
39454 * @property {import("../../transform.js").Transform} canvasTransform CanvasTransform.
39455 */
39456
39457/**
39458 * @typedef {{0: CanvasRenderingContext2D, 1: number, 2: import("../canvas.js").Label|HTMLImageElement|HTMLCanvasElement|HTMLVideoElement, 3: ImageOrLabelDimensions, 4: number, 5: Array<*>, 6: Array<*>}} ReplayImageOrLabelArgs
39459 */
39460
39461/**
39462 * @template T
39463 * @typedef {function(import("../../Feature.js").FeatureLike, import("../../geom/SimpleGeometry.js").default): T} FeatureCallback
39464 */
39465
39466/**
39467 * @type {import("../../extent.js").Extent}
39468 */
39469const tmpExtent = createEmpty();
39470
39471/** @type {import("../../coordinate.js").Coordinate} */
39472const p1 = [];
39473/** @type {import("../../coordinate.js").Coordinate} */
39474const p2 = [];
39475/** @type {import("../../coordinate.js").Coordinate} */
39476const p3 = [];
39477/** @type {import("../../coordinate.js").Coordinate} */
39478const p4 = [];
39479
39480/**
39481 * @param {ReplayImageOrLabelArgs} replayImageOrLabelArgs Arguments to replayImageOrLabel
39482 * @return {BBox} Declutter bbox.
39483 */
39484function getDeclutterBox(replayImageOrLabelArgs) {
39485  return replayImageOrLabelArgs[3].declutterBox;
39486}
39487
39488const rtlRegEx = new RegExp(
39489  /* eslint-disable prettier/prettier */
39490  '[' +
39491    String.fromCharCode(0x00591) + '-' + String.fromCharCode(0x008ff) +
39492    String.fromCharCode(0x0fb1d) + '-' + String.fromCharCode(0x0fdff) +
39493    String.fromCharCode(0x0fe70) + '-' + String.fromCharCode(0x0fefc) +
39494    String.fromCharCode(0x10800) + '-' + String.fromCharCode(0x10fff) +
39495    String.fromCharCode(0x1e800) + '-' + String.fromCharCode(0x1efff) +
39496  ']'
39497  /* eslint-enable prettier/prettier */
39498);
39499
39500/**
39501 * @param {string} text Text.
39502 * @param {CanvasTextAlign} align Alignment.
39503 * @return {number} Text alignment.
39504 */
39505function horizontalTextAlign(text, align) {
39506  if ((align === 'start' || align === 'end') && !rtlRegEx.test(text)) {
39507    align = align === 'start' ? 'left' : 'right';
39508  }
39509  return TEXT_ALIGN[align];
39510}
39511
39512/**
39513 * @param {Array<string>} acc Accumulator.
39514 * @param {string} line Line of text.
39515 * @param {number} i Index
39516 * @return {Array<string>} Accumulator.
39517 */
39518function createTextChunks(acc, line, i) {
39519  if (i > 0) {
39520    acc.push('\n', '');
39521  }
39522  acc.push(line, '');
39523  return acc;
39524}
39525
39526class Executor {
39527  /**
39528   * @param {number} resolution Resolution.
39529   * @param {number} pixelRatio Pixel ratio.
39530   * @param {boolean} overlaps The replay can have overlapping geometries.
39531   * @param {import("../canvas.js").SerializableInstructions} instructions The serializable instructions
39532   */
39533  constructor(resolution, pixelRatio, overlaps, instructions) {
39534    /**
39535     * @protected
39536     * @type {boolean}
39537     */
39538    this.overlaps = overlaps;
39539
39540    /**
39541     * @protected
39542     * @type {number}
39543     */
39544    this.pixelRatio = pixelRatio;
39545
39546    /**
39547     * @protected
39548     * @const
39549     * @type {number}
39550     */
39551    this.resolution = resolution;
39552
39553    /**
39554     * @private
39555     * @type {boolean}
39556     */
39557    this.alignFill_;
39558
39559    /**
39560     * @protected
39561     * @type {Array<*>}
39562     */
39563    this.instructions = instructions.instructions;
39564
39565    /**
39566     * @protected
39567     * @type {Array<number>}
39568     */
39569    this.coordinates = instructions.coordinates;
39570
39571    /**
39572     * @private
39573     * @type {!Object<number,import("../../coordinate.js").Coordinate|Array<import("../../coordinate.js").Coordinate>|Array<Array<import("../../coordinate.js").Coordinate>>>}
39574     */
39575    this.coordinateCache_ = {};
39576
39577    /**
39578     * @private
39579     * @type {!import("../../transform.js").Transform}
39580     */
39581    this.renderedTransform_ = create();
39582
39583    /**
39584     * @protected
39585     * @type {Array<*>}
39586     */
39587    this.hitDetectionInstructions = instructions.hitDetectionInstructions;
39588
39589    /**
39590     * @private
39591     * @type {Array<number>}
39592     */
39593    this.pixelCoordinates_ = null;
39594
39595    /**
39596     * @private
39597     * @type {number}
39598     */
39599    this.viewRotation_ = 0;
39600
39601    /**
39602     * @type {!Object<string, import("../canvas.js").FillState>}
39603     */
39604    this.fillStates = instructions.fillStates || {};
39605
39606    /**
39607     * @type {!Object<string, import("../canvas.js").StrokeState>}
39608     */
39609    this.strokeStates = instructions.strokeStates || {};
39610
39611    /**
39612     * @type {!Object<string, import("../canvas.js").TextState>}
39613     */
39614    this.textStates = instructions.textStates || {};
39615
39616    /**
39617     * @private
39618     * @type {Object<string, Object<string, number>>}
39619     */
39620    this.widths_ = {};
39621
39622    /**
39623     * @private
39624     * @type {Object<string, import("../canvas.js").Label>}
39625     */
39626    this.labels_ = {};
39627  }
39628
39629  /**
39630   * @param {string|Array<string>} text Text.
39631   * @param {string} textKey Text style key.
39632   * @param {string} fillKey Fill style key.
39633   * @param {string} strokeKey Stroke style key.
39634   * @return {import("../canvas.js").Label} Label.
39635   */
39636  createLabel(text, textKey, fillKey, strokeKey) {
39637    const key = text + textKey + fillKey + strokeKey;
39638    if (this.labels_[key]) {
39639      return this.labels_[key];
39640    }
39641    const strokeState = strokeKey ? this.strokeStates[strokeKey] : null;
39642    const fillState = fillKey ? this.fillStates[fillKey] : null;
39643    const textState = this.textStates[textKey];
39644    const pixelRatio = this.pixelRatio;
39645    const scale = [
39646      textState.scale[0] * pixelRatio,
39647      textState.scale[1] * pixelRatio,
39648    ];
39649    const textIsArray = Array.isArray(text);
39650    const align = textState.justify
39651      ? TEXT_ALIGN[textState.justify]
39652      : horizontalTextAlign(
39653          Array.isArray(text) ? text[0] : text,
39654          textState.textAlign || defaultTextAlign
39655        );
39656    const strokeWidth =
39657      strokeKey && strokeState.lineWidth ? strokeState.lineWidth : 0;
39658
39659    const chunks = textIsArray
39660      ? text
39661      : text.split('\n').reduce(createTextChunks, []);
39662
39663    const {width, height, widths, heights, lineWidths} = getTextDimensions(
39664      textState,
39665      chunks
39666    );
39667    const renderWidth = width + strokeWidth;
39668    const contextInstructions = [];
39669    // make canvas 2 pixels wider to account for italic text width measurement errors
39670    const w = (renderWidth + 2) * scale[0];
39671    const h = (height + strokeWidth) * scale[1];
39672    /** @type {import("../canvas.js").Label} */
39673    const label = {
39674      width: w < 0 ? Math.floor(w) : Math.ceil(w),
39675      height: h < 0 ? Math.floor(h) : Math.ceil(h),
39676      contextInstructions: contextInstructions,
39677    };
39678    if (scale[0] != 1 || scale[1] != 1) {
39679      contextInstructions.push('scale', scale);
39680    }
39681    if (strokeKey) {
39682      contextInstructions.push('strokeStyle', strokeState.strokeStyle);
39683      contextInstructions.push('lineWidth', strokeWidth);
39684      contextInstructions.push('lineCap', strokeState.lineCap);
39685      contextInstructions.push('lineJoin', strokeState.lineJoin);
39686      contextInstructions.push('miterLimit', strokeState.miterLimit);
39687      contextInstructions.push('setLineDash', [strokeState.lineDash]);
39688      contextInstructions.push('lineDashOffset', strokeState.lineDashOffset);
39689    }
39690    if (fillKey) {
39691      contextInstructions.push('fillStyle', fillState.fillStyle);
39692    }
39693    contextInstructions.push('textBaseline', 'middle');
39694    contextInstructions.push('textAlign', 'center');
39695    const leftRight = 0.5 - align;
39696    let x = align * renderWidth + leftRight * strokeWidth;
39697    const strokeInstructions = [];
39698    const fillInstructions = [];
39699    let lineHeight = 0;
39700    let lineOffset = 0;
39701    let widthHeightIndex = 0;
39702    let lineWidthIndex = 0;
39703    let previousFont;
39704    for (let i = 0, ii = chunks.length; i < ii; i += 2) {
39705      const text = chunks[i];
39706      if (text === '\n') {
39707        lineOffset += lineHeight;
39708        lineHeight = 0;
39709        x = align * renderWidth + leftRight * strokeWidth;
39710        ++lineWidthIndex;
39711        continue;
39712      }
39713      const font = chunks[i + 1] || textState.font;
39714      if (font !== previousFont) {
39715        if (strokeKey) {
39716          strokeInstructions.push('font', font);
39717        }
39718        if (fillKey) {
39719          fillInstructions.push('font', font);
39720        }
39721        previousFont = font;
39722      }
39723      lineHeight = Math.max(lineHeight, heights[widthHeightIndex]);
39724      const fillStrokeArgs = [
39725        text,
39726        x +
39727          leftRight * widths[widthHeightIndex] +
39728          align * (widths[widthHeightIndex] - lineWidths[lineWidthIndex]),
39729        0.5 * (strokeWidth + lineHeight) + lineOffset,
39730      ];
39731      x += widths[widthHeightIndex];
39732      if (strokeKey) {
39733        strokeInstructions.push('strokeText', fillStrokeArgs);
39734      }
39735      if (fillKey) {
39736        fillInstructions.push('fillText', fillStrokeArgs);
39737      }
39738      ++widthHeightIndex;
39739    }
39740    Array.prototype.push.apply(contextInstructions, strokeInstructions);
39741    Array.prototype.push.apply(contextInstructions, fillInstructions);
39742    this.labels_[key] = label;
39743    return label;
39744  }
39745
39746  /**
39747   * @param {CanvasRenderingContext2D} context Context.
39748   * @param {import("../../coordinate.js").Coordinate} p1 1st point of the background box.
39749   * @param {import("../../coordinate.js").Coordinate} p2 2nd point of the background box.
39750   * @param {import("../../coordinate.js").Coordinate} p3 3rd point of the background box.
39751   * @param {import("../../coordinate.js").Coordinate} p4 4th point of the background box.
39752   * @param {Array<*>} fillInstruction Fill instruction.
39753   * @param {Array<*>} strokeInstruction Stroke instruction.
39754   */
39755  replayTextBackground_(
39756    context,
39757    p1,
39758    p2,
39759    p3,
39760    p4,
39761    fillInstruction,
39762    strokeInstruction
39763  ) {
39764    context.beginPath();
39765    context.moveTo.apply(context, p1);
39766    context.lineTo.apply(context, p2);
39767    context.lineTo.apply(context, p3);
39768    context.lineTo.apply(context, p4);
39769    context.lineTo.apply(context, p1);
39770    if (fillInstruction) {
39771      this.alignFill_ = /** @type {boolean} */ (fillInstruction[2]);
39772      this.fill_(context);
39773    }
39774    if (strokeInstruction) {
39775      this.setStrokeStyle_(
39776        context,
39777        /** @type {Array<*>} */ (strokeInstruction)
39778      );
39779      context.stroke();
39780    }
39781  }
39782
39783  /**
39784   * @private
39785   * @param {number} sheetWidth Width of the sprite sheet.
39786   * @param {number} sheetHeight Height of the sprite sheet.
39787   * @param {number} centerX X.
39788   * @param {number} centerY Y.
39789   * @param {number} width Width.
39790   * @param {number} height Height.
39791   * @param {number} anchorX Anchor X.
39792   * @param {number} anchorY Anchor Y.
39793   * @param {number} originX Origin X.
39794   * @param {number} originY Origin Y.
39795   * @param {number} rotation Rotation.
39796   * @param {import("../../size.js").Size} scale Scale.
39797   * @param {boolean} snapToPixel Snap to pixel.
39798   * @param {Array<number>} padding Padding.
39799   * @param {boolean} fillStroke Background fill or stroke.
39800   * @param {import("../../Feature.js").FeatureLike} feature Feature.
39801   * @return {ImageOrLabelDimensions} Dimensions for positioning and decluttering the image or label.
39802   */
39803  calculateImageOrLabelDimensions_(
39804    sheetWidth,
39805    sheetHeight,
39806    centerX,
39807    centerY,
39808    width,
39809    height,
39810    anchorX,
39811    anchorY,
39812    originX,
39813    originY,
39814    rotation,
39815    scale,
39816    snapToPixel,
39817    padding,
39818    fillStroke,
39819    feature
39820  ) {
39821    anchorX *= scale[0];
39822    anchorY *= scale[1];
39823    let x = centerX - anchorX;
39824    let y = centerY - anchorY;
39825
39826    const w = width + originX > sheetWidth ? sheetWidth - originX : width;
39827    const h = height + originY > sheetHeight ? sheetHeight - originY : height;
39828    const boxW = padding[3] + w * scale[0] + padding[1];
39829    const boxH = padding[0] + h * scale[1] + padding[2];
39830    const boxX = x - padding[3];
39831    const boxY = y - padding[0];
39832
39833    if (fillStroke || rotation !== 0) {
39834      p1[0] = boxX;
39835      p4[0] = boxX;
39836      p1[1] = boxY;
39837      p2[1] = boxY;
39838      p2[0] = boxX + boxW;
39839      p3[0] = p2[0];
39840      p3[1] = boxY + boxH;
39841      p4[1] = p3[1];
39842    }
39843
39844    let transform;
39845    if (rotation !== 0) {
39846      transform = compose(
39847        create(),
39848        centerX,
39849        centerY,
39850        1,
39851        1,
39852        rotation,
39853        -centerX,
39854        -centerY
39855      );
39856
39857      apply(transform, p1);
39858      apply(transform, p2);
39859      apply(transform, p3);
39860      apply(transform, p4);
39861      createOrUpdate(
39862        Math.min(p1[0], p2[0], p3[0], p4[0]),
39863        Math.min(p1[1], p2[1], p3[1], p4[1]),
39864        Math.max(p1[0], p2[0], p3[0], p4[0]),
39865        Math.max(p1[1], p2[1], p3[1], p4[1]),
39866        tmpExtent
39867      );
39868    } else {
39869      createOrUpdate(
39870        Math.min(boxX, boxX + boxW),
39871        Math.min(boxY, boxY + boxH),
39872        Math.max(boxX, boxX + boxW),
39873        Math.max(boxY, boxY + boxH),
39874        tmpExtent
39875      );
39876    }
39877    if (snapToPixel) {
39878      x = Math.round(x);
39879      y = Math.round(y);
39880    }
39881    return {
39882      drawImageX: x,
39883      drawImageY: y,
39884      drawImageW: w,
39885      drawImageH: h,
39886      originX: originX,
39887      originY: originY,
39888      declutterBox: {
39889        minX: tmpExtent[0],
39890        minY: tmpExtent[1],
39891        maxX: tmpExtent[2],
39892        maxY: tmpExtent[3],
39893        value: feature,
39894      },
39895      canvasTransform: transform,
39896      scale: scale,
39897    };
39898  }
39899
39900  /**
39901   * @private
39902   * @param {CanvasRenderingContext2D} context Context.
39903   * @param {number} contextScale Scale of the context.
39904   * @param {import("../canvas.js").Label|HTMLImageElement|HTMLCanvasElement|HTMLVideoElement} imageOrLabel Image.
39905   * @param {ImageOrLabelDimensions} dimensions Dimensions.
39906   * @param {number} opacity Opacity.
39907   * @param {Array<*>} fillInstruction Fill instruction.
39908   * @param {Array<*>}
39908 strokeInstruction Stroke instruction.
39909   * @return {boolean} The image or label was rendered.
39910   */
39911  replayImageOrLabel_(
39912    context,
39913    contextScale,
39914    imageOrLabel,
39915    dimensions,
39916    opacity,
39917    fillInstruction,
39918    strokeInstruction
39919  ) {
39920    const fillStroke = !!(fillInstruction || strokeInstruction);
39921
39922    const box = dimensions.declutterBox;
39923    const canvas = context.canvas;
39924    const strokePadding = strokeInstruction
39925      ? (strokeInstruction[2] * dimensions.scale[0]) / 2
39926      : 0;
39927    const intersects =
39928      box.minX - strokePadding <= canvas.width / contextScale &&
39929      box.maxX + strokePadding >= 0 &&
39930      box.minY - strokePadding <= canvas.height / contextScale &&
39931      box.maxY + strokePadding >= 0;
39932
39933    if (intersects) {
39934      if (fillStroke) {
39935        this.replayTextBackground_(
39936          context,
39937          p1,
39938          p2,
39939          p3,
39940          p4,
39941          /** @type {Array<*>} */ (fillInstruction),
39942          /** @type {Array<*>} */ (strokeInstruction)
39943        );
39944      }
39945      drawImageOrLabel(
39946        context,
39947        dimensions.canvasTransform,
39948        opacity,
39949        imageOrLabel,
39950        dimensions.originX,
39951        dimensions.originY,
39952        dimensions.drawImageW,
39953        dimensions.drawImageH,
39954        dimensions.drawImageX,
39955        dimensions.drawImageY,
39956        dimensions.scale
39957      );
39958    }
39959    return true;
39960  }
39961
39962  /**
39963   * @private
39964   * @param {CanvasRenderingContext2D} context Context.
39965   */
39966  fill_(context) {
39967    if (this.alignFill_) {
39968      const origin = apply(this.renderedTransform_, [0, 0]);
39969      const repeatSize = 512 * this.pixelRatio;
39970      context.save();
39971      context.translate(origin[0] % repeatSize, origin[1] % repeatSize);
39972      context.rotate(this.viewRotation_);
39973    }
39974    context.fill();
39975    if (this.alignFill_) {
39976      context.restore();
39977    }
39978  }
39979
39980  /**
39981   * @private
39982   * @param {CanvasRenderingContext2D} context Context.
39983   * @param {Array<*>} instruction Instruction.
39984   */
39985  setStrokeStyle_(context, instruction) {
39986    context['strokeStyle'] =
39987      /** @type {import("../../colorlike.js").ColorLike} */ (instruction[1]);
39988    context.lineWidth = /** @type {number} */ (instruction[2]);
39989    context.lineCap = /** @type {CanvasLineCap} */ (instruction[3]);
39990    context.lineJoin = /** @type {CanvasLineJoin} */ (instruction[4]);
39991    context.miterLimit = /** @type {number} */ (instruction[5]);
39992    context.lineDashOffset = /** @type {number} */ (instruction[7]);
39993    context.setLineDash(/** @type {Array<number>} */ (instruction[6]));
39994  }
39995
39996  /**
39997   * @private
39998   * @param {string|Array<string>} text The text to draw.
39999   * @param {string} textKey The key of the text state.
40000   * @param {string} strokeKey The key for the stroke state.
40001   * @param {string} fillKey The key for the fill state.
40002   * @return {{label: import("../canvas.js").Label, anchorX: number, anchorY: number}} The text image and its anchor.
40003   */
40004  drawLabelWithPointPlacement_(text, textKey, strokeKey, fillKey) {
40005    const textState = this.textStates[textKey];
40006
40007    const label = this.createLabel(text, textKey, fillKey, strokeKey);
40008
40009    const strokeState = this.strokeStates[strokeKey];
40010    const pixelRatio = this.pixelRatio;
40011    const align = horizontalTextAlign(
40012      Array.isArray(text) ? text[0] : text,
40013      textState.textAlign || defaultTextAlign
40014    );
40015    const baseline = TEXT_ALIGN[textState.textBaseline || defaultTextBaseline];
40016    const strokeWidth =
40017      strokeState && strokeState.lineWidth ? strokeState.lineWidth : 0;
40018
40019    // Remove the 2 pixels we added in createLabel() for the anchor
40020    const width = label.width / pixelRatio - 2 * textState.scale[0];
40021    const anchorX = align * width + 2 * (0.5 - align) * strokeWidth;
40022    const anchorY =
40023      (baseline * label.height) / pixelRatio +
40024      2 * (0.5 - baseline) * strokeWidth;
40025
40026    return {
40027      label: label,
40028      anchorX: anchorX,
40029      anchorY: anchorY,
40030    };
40031  }
40032
40033  /**
40034   * @private
40035   * @param {CanvasRenderingContext2D} context Context.
40036   * @param {number} contextScale Scale of the context.
40037   * @param {import("../../transform.js").Transform} transform Transform.
40038   * @param {Array<*>}
40038 instructions Instructions array.
40039   * @param {boolean} snapToPixel Snap point symbols and text to integer pixels.
40040   * @param {FeatureCallback<T>} [featureCallback] Feature callback.
40041   * @param {import("../../extent.js").Extent} [hitExtent] Only check
40042   *     features that intersect this extent.
40043   * @param {import("rbush").default} [declutterTree] Declutter tree.
40044   * @return {T|undefined} Callback result.
40045   * @template T
40046   */
40047  execute_(
40048    context,
40049    contextScale,
40050    transform,
40051    instructions,
40052    snapToPixel,
40053    featureCallback,
40054    hitExtent,
40055    declutterTree
40056  ) {
40057    /** @type {Array<number>} */
40058    let pixelCoordinates;
40059    if (this.pixelCoordinates_ && equals(transform, this.renderedTransform_)) {
40060      pixelCoordinates = this.pixelCoordinates_;
40061    } else {
40062      if (!this.pixelCoordinates_) {
40063        this.pixelCoordinates_ = [];
40064      }
40065      pixelCoordinates = transform2D(
40066        this.coordinates,
40067        0,
40068        this.coordinates.length,
40069        2,
40070        transform,
40071        this.pixelCoordinates_
40072      );
40073      setFromArray(this.renderedTransform_, transform);
40074    }
40075    let i = 0; // instruction index
40076    const ii = instructions.length; // end of instructions
40077    let d = 0; // data index
40078    let dd; // end of per-instruction data
40079    let anchorX,
40080      anchorY,
40081      prevX,
40082      prevY,
40083      roundX,
40084      roundY,
40085      image,
40086      text,
40087      textKey,
40088      strokeKey,
40089      fillKey;
40090    let pendingFill = 0;
40091    let pendingStroke = 0;
40092    let lastFillInstruction = null;
40093    let lastStrokeInstruction = null;
40094    const coordinateCache = this.coordinateCache_;
40095    const viewRotation = this.viewRotation_;
40096    const viewRotationFromTransform =
40097      Math.round(Math.atan2(-transform[1], transform[0]) * 1e12) / 1e12;
40098
40099    const state = /** @type {import("../../render.js").State} */ ({
40100      context: context,
40101      pixelRatio: this.pixelRatio,
40102      resolution: this.resolution,
40103      rotation: viewRotation,
40104    });
40105
40106    // When the batch size gets too big, performance decreases. 200 is a good
40107    // balance between batch size and number of fill/stroke instructions.
40108    const batchSize =
40109      this.instructions != instructions || this.overlaps ? 0 : 200;
40110    let /** @type {import("../../Feature.js").FeatureLike} */ feature;
40111    let x, y, currentGeometry;
40112    while (i < ii) {
40113      const instruction = instructions[i];
40114      const type = /** @type {import("./Instruction.js").default} */ (
40115        instruction[0]
40116      );
40117      switch (type) {
40118        case canvas_Instruction.BEGIN_GEOMETRY:
40119          feature = /** @type {import("../../Feature.js").FeatureLike} */ (
40120            instruction[1]
40121          );
40122          currentGeometry = instruction[3];
40123          if (!feature.getGeometry()) {
40124            i = /** @type {number} */ (instruction[2]);
40125          } else if (
40126            hitExtent !== undefined &&
40127            !intersects(hitExtent, currentGeometry.getExtent())
40128          ) {
40129            i = /** @type {number} */ (instruction[2]) + 1;
40130          } else {
40131            ++i;
40132          }
40133          break;
40134        case canvas_Instruction.BEGIN_PATH:
40135          if (pendingFill > batchSize) {
40136            this.fill_(context);
40137            pendingFill = 0;
40138          }
40139          if (pendingStroke > batchSize) {
40140            context.stroke();
40141            pendingStroke = 0;
40142          }
40143          if (!pendingFill && !pendingStroke) {
40144            context.beginPath();
40145            prevX = NaN;
40146            prevY = NaN;
40147          }
40148          ++i;
40149          break;
40150        case canvas_Instruction.CIRCLE:
40151          d = /** @type {number} */ (instruction[1]);
40152          const x1 = pixelCoordinates[d];
40153          const y1 = pixelCoordinates[d + 1];
40154          const x2 = pixelCoordinates[d + 2];
40155          const y2 = pixelCoordinates[d + 3];
40156          const dx = x2 - x1;
40157          const dy = y2 - y1;
40158          const r = Math.sqrt(dx * dx + dy * dy);
40159          context.moveTo(x1 + r, y1);
40160          context.arc(x1, y1, r, 0, 2 * Math.PI, true);
40161          ++i;
40162          break;
40163        case canvas_Instruction.CLOSE_PATH:
40164          context.closePath();
40165          ++i;
40166          break;
40167        case canvas_Instruction.CUSTOM:
40168          d = /** @type {number} */ (instruction[1]);
40169          dd = instruction[2];
40170          const geometry =
40171            /** @type {import("../../geom/SimpleGeometry.js").default} */ (
40172              instruction[3]
40173            );
40174          const renderer = instruction[4];
40175          const fn = instruction.length == 6 ? instruction[5] : undefined;
40176          state.geometry = geometry;
40177          state.feature = feature;
40178          if (!(i in coordinateCache)) {
40179            coordinateCache[i] = [];
40180          }
40181          const coords = coordinateCache[i];
40182          if (fn) {
40183            fn(pixelCoordinates, d, dd, 2, coords);
40184          } else {
40185            coords[0] = pixelCoordinates[d];
40186            coords[1] = pixelCoordinates[d + 1];
40187            coords.length = 2;
40188          }
40189          renderer(coords, state);
40190          ++i;
40191          break;
40192        case canvas_Instruction.DRAW_IMAGE:
40193          d = /** @type {number} */ (instruction[1]);
40194          dd = /** @type {number} */ (instruction[2]);
40195          image =
40196            /** @type {HTMLCanvasElement|HTMLVideoElement|HTMLImageElement} */ (
40197              instruction[3]
40198            );
40199
40200          // Remaining arguments in DRAW_IMAGE are in alphabetical order
40201          anchorX = /** @type {number} */ (instruction[4]);
40202          anchorY = /** @type {number} */ (instruction[5]);
40203          let height = /** @type {number} */ (instruction[6]);
40204          const opacity = /** @type {number} */ (instruction[7]);
40205          const originX = /** @type {number} */ (instruction[8]);
40206          const originY = /** @type {number} */ (instruction[9]);
40207          const rotateWithView = /** @type {boolean} */ (instruction[10]);
40208          let rotation = /** @type {number} */ (instruction[11]);
40209          const scale = /** @type {import("../../size.js").Size} */ (
40210            instruction[12]
40211          );
40212          let width = /** @type {number} */ (instruction[13]);
40213          const declutterMode =
40214            /** @type {"declutter"|"obstacle"|"none"|undefined} */ (
40215              instruction[14]
40216            );
40217          const declutterImageWithText =
40218            /** @type {import("../canvas.js").DeclutterImageWithText} */ (
40219              instruction[15]
40220            );
40221
40222          if (!image && instruction.length >= 20) {
40223            // create label images
40224            text = /** @type {string} */ (instruction[19]);
40225            textKey = /** @type {string} */ (instruction[20]);
40226            strokeKey = /** @type {string} */ (instruction[21]);
40227            fillKey = /** @type {string} */ (instruction[22]);
40228            const labelWithAnchor = this.drawLabelWithPointPlacement_(
40229              text,
40230              textKey,
40231              strokeKey,
40232              fillKey
40233            );
40234            image = labelWithAnchor.label;
40235            instruction[3] = image;
40236            const textOffsetX = /** @type {number} */ (instruction[23]);
40237            anchorX = (labelWithAnchor.anchorX - textOffsetX) * this.pixelRatio;
40238            instruction[4] = anchorX;
40239            const textOffsetY = /** @type {number} */ (instruction[24]);
40240            anchorY = (labelWithAnchor.anchorY - textOffsetY) * this.pixelRatio;
40241            instruction[5] = anchorY;
40242            height = image.height;
40243            instruction[6] = height;
40244            width = image.width;
40245            instruction[13] = width;
40246          }
40247
40248          let geometryWidths;
40249          if (instruction.length > 25) {
40250            geometryWidths = /** @type {number} */ (instruction[25]);
40251          }
40252
40253          let padding, backgroundFill, backgroundStroke;
40254          if (instruction.length > 17) {
40255            padding = /** @type {Array<number>} */ (instruction[16]);
40256            backgroundFill = /** @type {boolean} */ (instruction[17]);
40257            backgroundStroke = /** @type {boolean} */ (instruction[18]);
40258          } else {
40259            padding = defaultPadding;
40260            backgroundFill = false;
40261            backgroundStroke = false;
40262          }
40263
40264          if (rotateWithView && viewRotationFromTransform) {
40265            // Canvas is expected to be rotated to reverse view rotation.
40266            rotation += viewRotation;
40267          } else if (!rotateWithView && !viewRotationFromTransform) {
40268            // Canvas is not rotated, images need to be rotated back to be north-up.
40269            rotation -= viewRotation;
40270          }
40271          let widthIndex = 0;
40272          for (; d < dd; d += 2) {
40273            if (
40274              geometryWidths &&
40275              geometryWidths[widthIndex++] < width / this.pixelRatio
40276            ) {
40277              continue;
40278            }
40279            const dimensions = this.calculateImageOrLabelDimensions_(
40280              image.width,
40281              image.height,
40282              pixelCoordinates[d],
40283              pixelCoordinates[d + 1],
40284              width,
40285              height,
40286              anchorX,
40287              anchorY,
40288              originX,
40289              originY,
40290              rotation,
40291              scale,
40292              snapToPixel,
40293              padding,
40294              backgroundFill || backgroundStroke,
40295              feature
40296            );
40297            /** @type {ReplayImageOrLabelArgs} */
40298            const args = [
40299              context,
40300              contextScale,
40301              image,
40302              dimensions,
40303              opacity,
40304              backgroundFill
40305                ? /** @type {Array<*>} */ (lastFillInstruction)
40306                : null,
40307              backgroundStroke
40308                ? /** @type {Array<*>}
40308 */ (lastStrokeInstruction)
40309                : null,
40310            ];
40311            if (declutterTree) {
40312              if (declutterMode === 'none') {
40313                // not rendered in declutter group
40314                continue;
40315              } else if (declutterMode === 'obstacle') {
40316                // will always be drawn, thus no collision detection, but insert as obstacle
40317                declutterTree.insert(dimensions.declutterBox);
40318                continue;
40319              } else {
40320                let imageArgs;
40321                let imageDeclutterBox;
40322                if (declutterImageWithText) {
40323                  const index = dd - d;
40324                  if (!declutterImageWithText[index]) {
40325                    // We now have the image for an image+text combination.
40326                    declutterImageWithText[index] = args;
40327                    // Don't render anything for now, wait for the text.
40328                    continue;
40329                  }
40330                  imageArgs = declutterImageWithText[index];
40331                  delete declutterImageWithText[index];
40332                  imageDeclutterBox = getDeclutterBox(imageArgs);
40333                  if (declutterTree.collides(imageDeclutterBox)) {
40334                    continue;
40335                  }
40336                }
40337                if (declutterTree.collides(dimensions.declutterBox)) {
40338                  continue;
40339                }
40340                if (imageArgs) {
40341                  // We now have image and text for an image+text combination.
40342                  declutterTree.insert(imageDeclutterBox);
40343                  // Render the image before we render the text.
40344                  this.replayImageOrLabel_.apply(this, imageArgs);
40345                }
40346                declutterTree.insert(dimensions.declutterBox);
40347              }
40348            }
40349            this.replayImageOrLabel_.apply(this, args);
40350          }
40351          ++i;
40352          break;
40353        case canvas_Instruction.DRAW_CHARS:
40354          const begin = /** @type {number} */ (instruction[1]);
40355          const end = /** @type {number} */ (instruction[2]);
40356          const baseline = /** @type {number} */ (instruction[3]);
40357          const overflow = /** @type {number} */ (instruction[4]);
40358          fillKey = /** @type {string} */ (instruction[5]);
40359          const maxAngle = /** @type {number} */ (instruction[6]);
40360          const measurePixelRatio = /** @type {number} */ (instruction[7]);
40361          const offsetY = /** @type {number} */ (instruction[8]);
40362          strokeKey = /** @type {string} */ (instruction[9]);
40363          const strokeWidth = /** @type {number} */ (instruction[10]);
40364          text = /** @type {string} */ (instruction[11]);
40365          textKey = /** @type {string} */ (instruction[12]);
40366          const pixelRatioScale = [
40367            /** @type {number} */ (instruction[13]),
40368            /** @type {number} */ (instruction[13]),
40369          ];
40370
40371          const textState = this.textStates[textKey];
40372          const font = textState.font;
40373          const textScale = [
40374            textState.scale[0] * measurePixelRatio,
40375            textState.scale[1] * measurePixelRatio,
40376          ];
40377
40378          let cachedWidths;
40379          if (font in this.widths_) {
40380            cachedWidths = this.widths_[font];
40381          } else {
40382            cachedWidths = {};
40383            this.widths_[font] = cachedWidths;
40384          }
40385
40386          const pathLength = lineStringLength(pixelCoordinates, begin, end, 2);
40387          const textLength =
40388            Math.abs(textScale[0]) *
40389            measureAndCacheTextWidth(font, text, cachedWidths);
40390          if (overflow || textLength <= pathLength) {
40391            const textAlign = this.textStates[textKey].textAlign;
40392            const startM = (pathLength - textLength) * TEXT_ALIGN[textAlign];
40393            const parts = drawTextOnPath(
40394              pixelCoordinates,
40395              begin,
40396              end,
40397              2,
40398              text,
40399              startM,
40400              maxAngle,
40401              Math.abs(textScale[0]),
40402              measureAndCacheTextWidth,
40403              font,
40404              cachedWidths,
40405              viewRotationFromTransform ? 0 : this.viewRotation_
40406            );
40407            drawChars: if (parts) {
40408              /** @type {Array<ReplayImageOrLabelArgs>} */
40409              const replayImageOrLabelArgs = [];
40410              let c, cc, chars, label, part;
40411              if (strokeKey) {
40412                for (c = 0, cc = parts.length; c < cc; ++c) {
40413                  part = parts[c]; // x, y, anchorX, rotation, chunk
40414                  chars = /** @type {string} */ (part[4]);
40415                  label = this.createLabel(chars, textKey, '', strokeKey);
40416                  anchorX =
40417                    /** @type {number} */ (part[2]) +
40418                    (textScale[0] < 0 ? -strokeWidth : strokeWidth);
40419                  anchorY =
40420                    baseline * label.height +
40421                    ((0.5 - baseline) * 2 * strokeWidth * textScale[1]) /
40422                      textScale[0] -
40423                    offsetY;
40424                  const dimensions = this.calculateImageOrLabelDimensions_(
40425                    label.width,
40426                    label.height,
40427                    part[0],
40428                    part[1],
40429                    label.width,
40430                    label.height,
40431                    anchorX,
40432                    anchorY,
40433                    0,
40434                    0,
40435                    part[3],
40436                    pixelRatioScale,
40437                    false,
40438                    defaultPadding,
40439                    false,
40440                    feature
40441                  );
40442                  if (
40443                    declutterTree &&
40444                    declutterTree.collides(dimensions.declutterBox)
40445                  ) {
40446                    break drawChars;
40447                  }
40448                  replayImageOrLabelArgs.push([
40449                    context,
40450                    contextScale,
40451                    label,
40452                    dimensions,
40453                    1,
40454                    null,
40455                    null,
40456                  ]);
40457                }
40458              }
40459              if (fillKey) {
40460                for (c = 0, cc = parts.length; c < cc; ++c) {
40461                  part = parts[c]; // x, y, anchorX, rotation, chunk
40462                  chars = /** @type {string} */ (part[4]);
40463                  label = this.createLabel(chars, textKey, fillKey, '');
40464                  anchorX = /** @type {number} */ (part[2]);
40465                  anchorY = baseline * label.height - offsetY;
40466                  const dimensions = this.calculateImageOrLabelDimensions_(
40467                    label.width,
40468                    label.height,
40469                    part[0],
40470                    part[1],
40471                    label.width,
40472                    label.height,
40473                    anchorX,
40474                    anchorY,
40475                    0,
40476                    0,
40477                    part[3],
40478                    pixelRatioScale,
40479                    false,
40480                    defaultPadding,
40481                    false,
40482                    feature
40483                  );
40484                  if (
40485                    declutterTree &&
40486                    declutterTree.collides(dimensions.declutterBox)
40487                  ) {
40488                    break drawChars;
40489                  }
40490                  replayImageOrLabelArgs.push([
40491                    context,
40492                    contextScale,
40493                    label,
40494                    dimensions,
40495                    1,
40496                    null,
40497                    null,
40498                  ]);
40499                }
40500              }
40501              if (declutterTree) {
40502                declutterTree.load(replayImageOrLabelArgs.map(getDeclutterBox));
40503              }
40504              for (let i = 0, ii = replayImageOrLabelArgs.length; i < ii; ++i) {
40505                this.replayImageOrLabel_.apply(this, replayImageOrLabelArgs[i]);
40506              }
40507            }
40508          }
40509          ++i;
40510          break;
40511        case canvas_Instruction.END_GEOMETRY:
40512          if (featureCallback !== undefined) {
40513            feature = /** @type {import("../../Feature.js").FeatureLike} */ (
40514              instruction[1]
40515            );
40516            const result = featureCallback(feature, currentGeometry);
40517            if (result) {
40518              return result;
40519            }
40520          }
40521          ++i;
40522          break;
40523        case canvas_Instruction.FILL:
40524          if (batchSize) {
40525            pendingFill++;
40526          } else {
40527            this.fill_(context);
40528          }
40529          ++i;
40530          break;
40531        case canvas_Instruction.MOVE_TO_LINE_TO:
40532          d = /** @type {number} */ (instruction[1]);
40533          dd = /** @type {number} */ (instruction[2]);
40534          x = pixelCoordinates[d];
40535          y = pixelCoordinates[d + 1];
40536          roundX = (x + 0.5) | 0;
40537          roundY = (y + 0.5) | 0;
40538          if (roundX !== prevX || roundY !== prevY) {
40539            context.moveTo(x, y);
40540            prevX = roundX;
40541            prevY = roundY;
40542          }
40543          for (d += 2; d < dd; d += 2) {
40544            x = pixelCoordinates[d];
40545            y = pixelCoordinates[d + 1];
40546            roundX = (x + 0.5) | 0;
40547            roundY = (y + 0.5) | 0;
40548            if (d == dd - 2 || roundX !== prevX || roundY !== prevY) {
40549              context.lineTo(x, y);
40550              prevX = roundX;
40551              prevY = roundY;
40552            }
40553          }
40554          ++i;
40555          break;
40556        case canvas_Instruction.SET_FILL_STYLE:
40557          lastFillInstruction = instruction;
40558          this.alignFill_ = instruction[2];
40559
40560          if (pendingFill) {
40561            this.fill_(context);
40562            pendingFill = 0;
40563            if (pendingStroke) {
40564              context.stroke();
40565              pendingStroke = 0;
40566            }
40567          }
40568
40569          context.fillStyle =
40570            /** @type {import("../../colorlike.js").ColorLike} */ (
40571              instruction[1]
40572            );
40573          ++i;
40574          break;
40575        case canvas_Instruction.SET_STROKE_STYLE:
40576          lastStrokeInstruction = instruction;
40577          if (pendingStroke) {
40578            context.stroke();
40579            pendingStroke = 0;
40580          }
40581          this.setStrokeStyle_(context, /** @type {Array<*>} */ (instruction));
40582          ++i;
40583          break;
40584        case canvas_Instruction.STROKE:
40585          if (batchSize) {
40586            pendingStroke++;
40587          } else {
40588            context.stroke();
40589          }
40590          ++i;
40591          break;
40592        default: // consume the instruction anyway, to avoid an infinite loop
40593          ++i;
40594          break;
40595      }
40596    }
40597    if (pendingFill) {
40598      this.fill_(context);
40599    }
40600    if (pendingStroke) {
40601      context.stroke();
40602    }
40603    return undefined;
40604  }
40605
40606  /**
40607   * @param {CanvasRenderingContext2D} context Context.
40608   * @param {number} contextScale Scale of the context.
40609   * @param {import("../../transform.js").Transform} transform Transform.
40610   * @param {number} viewRotation View rotation.
40611   * @param {boolean} snapToPixel Snap point symbols and text to integer pixels.
40612   * @param {import("rbush").default} [declutterTree] Declutter tree.
40613   */
40614  execute(
40615    context,
40616    contextScale,
40617    transform,
40618    viewRotation,
40619    snapToPixel,
40620    declutterTree
40621  ) {
40622    this.viewRotation_ = viewRotation;
40623    this.execute_(
40624      context,
40625      contextScale,
40626      transform,
40627      this.instructions,
40628      snapToPixel,
40629      undefined,
40630      undefined,
40631      declutterTree
40632    );
40633  }
40634
40635  /**
40636   * @param {CanvasRenderingContext2D} context Context.
40637   * @param {import("../../transform.js").Transform} transform Transform.
40638   * @param {number} viewRotation View rotation.
40639   * @param {FeatureCallback<T>} [featureCallback] Feature callback.
40640   * @param {import("../../extent.js").Extent} [hitExtent] Only check
40641   *     features that intersect this extent.
40642   * @return {T|undefined} Callback result.
40643   * @template T
40644   */
40645  executeHitDetection(
40646    context,
40647    transform,
40648    viewRotation,
40649    featureCallback,
40650    hitExtent
40651  ) {
40652    this.viewRotation_ = viewRotation;
40653    return this.execute_(
40654      context,
40655      1,
40656      transform,
40657      this.hitDetectionInstructions,
40658      true,
40659      featureCallback,
40660      hitExtent
40661    );
40662  }
40663}
40664
40665/* harmony default export */ const canvas_Executor = (Executor);
40666
40667;// CONCATENATED MODULE: ./node_modules/ol/render/canvas/ExecutorGroup.js
40668/**
40669 * @module ol/render/canvas/ExecutorGroup
40670 */
40671
40672
40673
40674
40675
40676
40677
40678
40679
40680/**
40681 * @const
40682 * @type {Array<import("../canvas.js").BuilderType>}
40683 */
40684const ORDER = ['Polygon', 'Circle', 'LineString', 'Image', 'Text', 'Default'];
40685
40686class ExecutorGroup {
40687  /**
40688   * @param {import("../../extent.js").Extent} maxExtent Max extent for clipping. When a
40689   * `maxExtent` was set on the Builder for this executor group, the same `maxExtent`
40690   * should be set here, unless the target context does not exceed that extent (which
40691   * can be the case when rendering to tiles).
40692   * @param {number} resolution Resolution.
40693   * @param {number} pixelRatio Pixel ratio.
40694   * @param {boolean} overlaps The executor group can have overlapping geometries.
40695   * @param {!Object<string, !Object<import("../canvas.js").BuilderType, import("../canvas.js").SerializableInstructions>>} allInstructions
40696   * The serializable instructions.
40697   * @param {number} [renderBuffer] Optional rendering buffer.
40698   */
40699  constructor(
40700    maxExtent,
40701    resolution,
40702    pixelRatio,
40703    overlaps,
40704    allInstructions,
40705    renderBuffer
40706  ) {
40707    /**
40708     * @private
40709     * @type {import("../../extent.js").Extent}
40710     */
40711    this.maxExtent_ = maxExtent;
40712
40713    /**
40714     * @private
40715     * @type {boolean}
40716     */
40717    this.overlaps_ = overlaps;
40718
40719    /**
40720     * @private
40721     * @type {number}
40722     */
40723    this.pixelRatio_ = pixelRatio;
40724
40725    /**
40726     * @private
40727     * @type {number}
40728     */
40729    this.resolution_ = resolution;
40730
40731    /**
40732     * @private
40733     * @type {number|undefined}
40734     */
40735    this.renderBuffer_ = renderBuffer;
40736
40737    /**
40738     * @private
40739     * @type {!Object<string, !Object<import("../canvas.js").BuilderType, import("./Executor").default>>}
40740     */
40741    this.executorsByZIndex_ = {};
40742
40743    /**
40744     * @private
40745     * @type {CanvasRenderingContext2D}
40746     */
40747    this.hitDetectionContext_ = null;
40748
40749    /**
40750     * @private
40751     * @type {import("../../transform.js").Transform}
40752     */
40753    this.hitDetectionTransform_ = create();
40754
40755    this.createExecutors_(allInstructions);
40756  }
40757
40758  /**
40759   * @param {CanvasRenderingContext2D} context Context.
40760   * @param {import("../../transform.js").Transform} transform Transform.
40761   */
40762  clip(context, transform) {
40763    const flatClipCoords = this.getClipCoords(transform);
40764    context.beginPath();
40765    context.moveTo(flatClipCoords[0], flatClipCoords[1]);
40766    context.lineTo(flatClipCoords[2], flatClipCoords[3]);
40767    context.lineTo(flatClipCoords[4], flatClipCoords[5]);
40768    context.lineTo(flatClipCoords[6], flatClipCoords[7]);
40769    context.clip();
40770  }
40771
40772  /**
40773   * Create executors and populate them using the provided instructions.
40774   * @private
40775   * @param {!Object<string, !Object<import("../canvas.js").BuilderType, import("../canvas.js").SerializableInstructions>>} allInstructions The serializable instructions
40776   */
40777  createExecutors_(allInstructions) {
40778    for (const zIndex in allInstructions) {
40779      let executors = this.executorsByZIndex_[zIndex];
40780      if (executors === undefined) {
40781        executors = {};
40782        this.executorsByZIndex_[zIndex] = executors;
40783      }
40784      const instructionByZindex = allInstructions[zIndex];
40785      for (const builderType in instructionByZindex) {
40786        const instructions = instructionByZindex[builderType];
40787        executors[builderType] = new canvas_Executor(
40788          this.resolution_,
40789          this.pixelRatio_,
40790          this.overlaps_,
40791          instructions
40792        );
40793      }
40794    }
40795  }
40796
40797  /**
40798   * @param {Array<import("../canvas.js").BuilderType>} executors Executors.
40799   * @return {boolean} Has executors of the provided types.
40800   */
40801  hasExecutors(executors) {
40802    for (const zIndex in this.executorsByZIndex_) {
40803      const candidates = this.executorsByZIndex_[zIndex];
40804      for (let i = 0, ii = executors.length; i < ii; ++i) {
40805        if (executors[i] in candidates) {
40806          return true;
40807        }
40808      }
40809    }
40810    return false;
40811  }
40812
40813  /**
40814   * @param {import("../../coordinate.js").Coordinate} coordinate Coordinate.
40815   * @param {number} resolution Resolution.
40816   * @param {number} rotation Rotation.
40817   * @param {number} hitTolerance Hit tolerance in pixels.
40818   * @param {function(import("../../Feature.js").FeatureLike, import("../../geom/SimpleGeometry.js").default, number): T} callback Feature callback.
40819   * @param {Array<import("../../Feature.js").FeatureLike>} declutteredFeatures Decluttered features.
40820   * @return {T|undefined} Callback result.
40821   * @template T
40822   */
40823  forEachFeatureAtCoordinate(
40824    coordinate,
40825    resolution,
40826    rotation,
40827    hitTolerance,
40828    callback,
40829    declutteredFeatures
40830  ) {
40831    hitTolerance = Math.round(hitTolerance);
40832    const contextSize = hitTolerance * 2 + 1;
40833    const transform = compose(
40834      this.hitDetectionTransform_,
40835      hitTolerance + 0.5,
40836      hitTolerance + 0.5,
40837      1 / resolution,
40838      -1 / resolution,
40839      -rotation,
40840      -coordinate[0],
40841      -coordinate[1]
40842    );
40843
40844    const newContext = !this.hitDetectionContext_;
40845    if (newContext) {
40846      this.hitDetectionContext_ = createCanvasContext2D(
40847        contextSize,
40848        contextSize
40849      );
40850    }
40851    const context = this.hitDetectionContext_;
40852
40853    if (
40854      context.canvas.width !== contextSize ||
40855      context.canvas.height !== contextSize
40856    ) {
40857      context.canvas.width = contextSize;
40858      context.canvas.height = contextSize;
40859    } else if (!newContext) {
40860      context.clearRect(0, 0, contextSize, contextSize);
40861    }
40862
40863    /**
40864     * @type {import("../../extent.js").Extent}
40865     */
40866    let hitExtent;
40867    if (this.renderBuffer_ !== undefined) {
40868      hitExtent = createEmpty();
40869      extendCoordinate(hitExtent, coordinate);
40870      buffer(
40871        hitExtent,
40872        resolution * (this.renderBuffer_ + hitTolerance),
40873        hitExtent
40874      );
40875    }
40876
40877    const indexes = getPixelIndexArray(hitTolerance);
40878
40879    let builderType;
40880
40881    /**
40882     * @param {import("../../Feature.js").FeatureLike} feature Feature.
40883     * @param {import("../../geom/SimpleGeometry.js").default} geometry Geometry.
40884     * @return {T|undefined} Callback result.
40885     */
40886    function featureCallback(feature, geometry) {
40887      const imageData = context.getImageData(
40888        0,
40889        0,
40890        contextSize,
40891        contextSize
40892      ).data;
40893      for (let i = 0, ii = indexes.length; i < ii; i++) {
40894        if (imageData[indexes[i]] > 0) {
40895          if (
40896            !declutteredFeatures ||
40897            (builderType !== 'Image' && builderType !== 'Text') ||
40898            declutteredFeatures.includes(feature)
40899          ) {
40900            const idx = (indexes[i] - 3) / 4;
40901            const x = hitTolerance - (idx % contextSize);
40902            const y = hitTolerance - ((idx / contextSize) | 0);
40903            const result = callback(feature, geometry, x * x + y * y);
40904            if (result) {
40905              return result;
40906            }
40907          }
40908          context.clearRect(0, 0, contextSize, contextSize);
40909          break;
40910        }
40911      }
40912      return undefined;
40913    }
40914
40915    /** @type {Array<number>} */
40916    const zs = Object.keys(this.executorsByZIndex_).map(Number);
40917    zs.sort(numberSafeCompareFunction);
40918
40919    let i, j, executors, executor, result;
40920    for (i = zs.length - 1; i >= 0; --i) {
40921      const zIndexKey = zs[i].toString();
40922      executors = this.executorsByZIndex_[zIndexKey];
40923      for (j = ORDER.length - 1; j >= 0; --j) {
40924        builderType = ORDER[j];
40925        executor = executors[builderType];
40926        if (executor !== undefined) {
40927          result = executor.executeHitDetection(
40928            context,
40929            transform,
40930            rotation,
40931            featureCallback,
40932            hitExtent
40933          );
40934          if (result) {
40935            return result;
40936          }
40937        }
40938      }
40939    }
40940    return undefined;
40941  }
40942
40943  /**
40944   * @param {import("../../transform.js").Transform} transform Transform.
40945   * @return {Array<number>|null} Clip coordinates.
40946   */
40947  getClipCoords(transform) {
40948    const maxExtent = this.maxExtent_;
40949    if (!maxExtent) {
40950      return null;
40951    }
40952    const minX = maxExtent[0];
40953    const minY = maxExtent[1];
40954    const maxX = maxExtent[2];
40955    const maxY = maxExtent[3];
40956    const flatClipCoords = [minX, minY, minX, maxY, maxX, maxY, maxX, minY];
40957    transform2D(flatClipCoords, 0, 8, 2, transform, flatClipCoords);
40958    return flatClipCoords;
40959  }
40960
40961  /**
40962   * @return {boolean} Is empty.
40963   */
40964  isEmpty() {
40965    return obj_isEmpty(this.executorsByZIndex_);
40966  }
40967
40968  /**
40969   * @param {CanvasRenderingContext2D} context Context.
40970   * @param {number} contextScale Scale of the context.
40971   * @param {import("../../transform.js").Transform} transform Transform.
40972   * @param {number} viewRotation View rotation.
40973   * @param {boolean} snapToPixel Snap point symbols and test to integer pixel.
40974   * @param {Array<import("../canvas.js").BuilderType>} [builderTypes] Ordered replay types to replay.
40975   *     Default is {@link module:ol/render/replay~ORDER}
40976   * @param {import("rbush").default} [declutterTree] Declutter tree.
40977   */
40978  execute(
40979    context,
40980    contextScale,
40981    transform,
40982    viewRotation,
40983    snapToPixel,
40984    builderTypes,
40985    declutterTree
40986  ) {
40987    /** @type {Array<number>} */
40988    const zs = Object.keys(this.executorsByZIndex_).map(Number);
40989    zs.sort(numberSafeCompareFunction);
40990
40991    // setup clipping so that the parts of over-simplified geometries are not
40992    // visible outside the current extent when panning
40993    if (this.maxExtent_) {
40994      context.save();
40995      this.clip(context, transform);
40996    }
40997
40998    builderTypes = builderTypes ? builderTypes : ORDER;
40999    let i, ii, j, jj, replays, replay;
41000    if (declutterTree) {
41001      zs.reverse();
41002    }
41003    for (i = 0, ii = zs.length; i < ii; ++i) {
41004      const zIndexKey = zs[i].toString();
41005      replays = this.executorsByZIndex_[zIndexKey];
41006      for (j = 0, jj = builderTypes.length; j < jj; ++j) {
41007        const builderType = builderTypes[j];
41008        replay = replays[builderType];
41009        if (replay !== undefined) {
41010          replay.execute(
41011            context,
41012            contextScale,
41013            transform,
41014            viewRotation,
41015            snapToPixel,
41016            declutterTree
41017          );
41018        }
41019      }
41020    }
41021
41022    if (this.maxExtent_) {
41023      context.restore();
41024    }
41025  }
41026}
41027
41028/**
41029 * This cache is used to store arrays of indexes for calculated pixel circles
41030 * to increase performance.
41031 * It is a static property to allow each Replaygroup to access it.
41032 * @type {Object<number, Array<number>>}
41033 */
41034const circlePixelIndexArrayCache = {};
41035
41036/**
41037 * This methods creates an array with indexes of all pixels within a circle,
41038 * ordered by how close they are to the center.
41039 * A cache is used to increase performance.
41040 * @param {number} radius Radius.
41041 * @return {Array<number>} An array with indexes within a circle.
41042 */
41043function getPixelIndexArray(radius) {
41044  if (circlePixelIndexArrayCache[radius] !== undefined) {
41045    return circlePixelIndexArrayCache[radius];
41046  }
41047
41048  const size = radius * 2 + 1;
41049  const maxDistanceSq = radius * radius;
41050  const distances = new Array(maxDistanceSq + 1);
41051  for (let i = 0; i <= radius; ++i) {
41052    for (let j = 0; j <= radius; ++j) {
41053      const distanceSq = i * i + j * j;
41054      if (distanceSq > maxDistanceSq) {
41055        break;
41056      }
41057      let distance = distances[distanceSq];
41058      if (!distance) {
41059        distance = [];
41060        distances[distanceSq] = distance;
41061      }
41062      distance.push(((radius + i) * size + (radius + j)) * 4 + 3);
41063      if (i > 0) {
41064        distance.push(((radius - i) * size + (radius + j)) * 4 + 3);
41065      }
41066      if (j > 0) {
41067        distance.push(((radius + i) * size + (radius - j)) * 4 + 3);
41068        if (i > 0) {
41069          distance.push(((radius - i) * size + (radius - j)) * 4 + 3);
41070        }
41071      }
41072    }
41073  }
41074
41075  const pixelIndex = [];
41076  for (let i = 0, ii = distances.length; i < ii; ++i) {
41077    if (distances[i]) {
41078      pixelIndex.push(...distances[i]);
41079    }
41080  }
41081
41082  circlePixelIndexArrayCache[radius] = pixelIndex;
41083  return pixelIndex;
41084}
41085
41086/* harmony default export */ const canvas_ExecutorGroup = (ExecutorGroup);
41087
41088;// CONCATENATED MODULE: ./node_modules/ol/render/canvas/Immediate.js
41089/**
41090 * @module ol/render/canvas/Immediate
41091 */
41092// FIXME test, especially polygons with holes and multipolygons
41093// FIXME need to handle large thick features (where pixel size matters)
41094// FIXME add offset and end to ol/geom/flat/transform~transform2D?
41095
41096
41097
41098
41099
41100
41101
41102
41103
41104
41105/**
41106 * @classdesc
41107 * A concrete subclass of {@link module:ol/render/VectorContext~VectorContext} that implements
41108 * direct rendering of features and geometries to an HTML5 Canvas context.
41109 * Instances of this class are created internally by the library and
41110 * provided to application code as vectorContext member of the
41111 * {@link module:ol/render/Event~RenderEvent} object associated with postcompose, precompose and
41112 * render events emitted by layers and maps.
41113 */
41114class CanvasImmediateRenderer extends render_VectorContext {
41115  /**
41116   * @param {CanvasRenderingContext2D} context Context.
41117   * @param {number} pixelRatio Pixel ratio.
41118   * @param {import("../../extent.js").Extent} extent Extent.
41119   * @param {import("../../transform.js").Transform} transform Transform.
41120   * @param {number} viewRotation View rotation.
41121   * @param {number} [squaredTolerance] Optional squared tolerance for simplification.
41122   * @param {import("../../proj.js").TransformFunction} [userTransform] Transform from user to view projection.
41123   */
41124  constructor(
41125    context,
41126    pixelRatio,
41127    extent,
41128    transform,
41129    viewRotation,
41130    squaredTolerance,
41131    userTransform
41132  ) {
41133    super();
41134
41135    /**
41136     * @private
41137     * @type {CanvasRenderingContext2D}
41138     */
41139    this.context_ = context;
41140
41141    /**
41142     * @private
41143     * @type {number}
41144     */
41145    this.pixelRatio_ = pixelRatio;
41146
41147    /**
41148     * @private
41149     * @type {import("../../extent.js").Extent}
41150     */
41151    this.extent_ = extent;
41152
41153    /**
41154     * @private
41155     * @type {import("../../transform.js").Transform}
41156     */
41157    this.transform_ = transform;
41158
41159    /**
41160     * @private
41161     * @type {number}
41162     */
41163    this.viewRotation_ = viewRotation;
41164
41165    /**
41166     * @private
41167     * @type {number}
41168     */
41169    this.squaredTolerance_ = squaredTolerance;
41170
41171    /**
41172     * @private
41173     * @type {import("../../proj.js").TransformFunction}
41174     */
41175    this.userTransform_ = userTransform;
41176
41177    /**
41178     * @private
41179     * @type {?import("../canvas.js").FillState}
41180     */
41181    this.contextFillState_ = null;
41182
41183    /**
41184     * @private
41185     * @type {?import("../canvas.js").StrokeState}
41186     */
41187    this.contextStrokeState_ = null;
41188
41189    /**
41190     * @private
41191     * @type {?import("../canvas.js").TextState}
41192     */
41193    this.contextTextState_ = null;
41194
41195    /**
41196     * @private
41197     * @type {?import("../canvas.js").FillState}
41198     */
41199    this.fillState_ = null;
41200
41201    /**
41202     * @private
41203     * @type {?import("../canvas.js").StrokeState}
41204     */
41205    this.strokeState_ = null;
41206
41207    /**
41208     * @private
41209     * @type {HTMLCanvasElement|HTMLVideoElement|HTMLImageElement}
41210     */
41211    this.image_ = null;
41212
41213    /**
41214     * @private
41215     * @type {number}
41216     */
41217    this.imageAnchorX_ = 0;
41218
41219    /**
41220     * @private
41221     * @type {number}
41222     */
41223    this.imageAnchorY_ = 0;
41224
41225    /**
41226     * @private
41227     * @type {number}
41228     */
41229    this.imageHeight_ = 0;
41230
41231    /**
41232     * @private
41233     * @type {number}
41234     */
41235    this.imageOpacity_ = 0;
41236
41237    /**
41238     * @private
41239     * @type {number}
41240     */
41241    this.imageOriginX_ = 0;
41242
41243    /**
41244     * @private
41245     * @type {number}
41246     */
41247    this.imageOriginY_ = 0;
41248
41249    /**
41250     * @private
41251     * @type {boolean}
41252     */
41253    this.imageRotateWithView_ = false;
41254
41255    /**
41256     * @private
41257     * @type {number}
41258     */
41259    this.imageRotation_ = 0;
41260
41261    /**
41262     * @private
41263     * @type {import("../../size.js").Size}
41264     */
41265    this.imageScale_ = [0, 0];
41266
41267    /**
41268     * @private
41269     * @type {number}
41270     */
41271    this.imageWidth_ = 0;
41272
41273    /**
41274     * @private
41275     * @type {string}
41276     */
41277    this.text_ = '';
41278
41279    /**
41280     * @private
41281     * @type {number}
41282     */
41283    this.textOffsetX_ = 0;
41284
41285    /**
41286     * @private
41287     * @type {number}
41288     */
41289    this.textOffsetY_ = 0;
41290
41291    /**
41292     * @private
41293     * @type {boolean}
41294     */
41295    this.textRotateWithView_ = false;
41296
41297    /**
41298     * @private
41299     * @type {number}
41300     */
41301    this.textRotation_ = 0;
41302
41303    /**
41304     * @private
41305     * @type {import("../../size.js").Size}
41306     */
41307    this.textScale_ = [0, 0];
41308
41309    /**
41310     * @private
41311     * @type {?import("../canvas.js").FillState}
41312     */
41313    this.textFillState_ = null;
41314
41315    /**
41316     * @private
41317     * @type {?import("../canvas.js").StrokeState}
41318     */
41319    this.textStrokeState_ = null;
41320
41321    /**
41322     * @private
41323     * @type {?import("../canvas.js").TextState}
41324     */
41325    this.textState_ = null;
41326
41327    /**
41328     * @private
41329     * @type {Array<number>}
41330     */
41331    this.pixelCoordinates_ = [];
41332
41333    /**
41334     * @private
41335     * @type {import("../../transform.js").Transform}
41336     */
41337    this.tmpLocalTransform_ = create();
41338  }
41339
41340  /**
41341   * @param {Array<number>} flatCoordinates Flat coordinates.
41342   * @param {number} offset Offset.
41343   * @param {number} end End.
41344   * @param {number} stride Stride.
41345   * @private
41346   */
41347  drawImages_(flatCoordinates, offset, end, stride) {
41348    if (!this.image_) {
41349      return;
41350    }
41351    const pixelCoordinates = transform2D(
41352      flatCoordinates,
41353      offset,
41354      end,
41355      stride,
41356      this.transform_,
41357      this.pixelCoordinates_
41358    );
41359    const context = this.context_;
41360    const localTransform = this.tmpLocalTransform_;
41361    const alpha = context.globalAlpha;
41362    if (this.imageOpacity_ != 1) {
41363      context.globalAlpha = alpha * this.imageOpacity_;
41364    }
41365    let rotation = this.imageRotation_;
41366    if (this.imageRotateWithView_) {
41367      rotation += this.viewRotation_;
41368    }
41369    for (let i = 0, ii = pixelCoordinates.length; i < ii; i += 2) {
41370      const x = pixelCoordinates[i] - this.imageAnchorX_;
41371      const y = pixelCoordinates[i + 1] - this.imageAnchorY_;
41372      if (
41373        rotation !== 0 ||
41374        this.imageScale_[0] != 1 ||
41375        this.imageScale_[1] != 1
41376      ) {
41377        const centerX = x + this.imageAnchorX_;
41378        const centerY = y + this.imageAnchorY_;
41379        compose(
41380          localTransform,
41381          centerX,
41382          centerY,
41383          1,
41384          1,
41385          rotation,
41386          -centerX,
41387          -centerY
41388        );
41389        context.setTransform.apply(context, localTransform);
41390        context.translate(centerX, centerY);
41391        context.scale(this.imageScale_[0], this.imageScale_[1]);
41392        context.drawImage(
41393          this.image_,
41394          this.imageOriginX_,
41395          this.imageOriginY_,
41396          this.imageWidth_,
41397          this.imageHeight_,
41398          -this.imageAnchorX_,
41399          -this.imageAnchorY_,
41400          this.imageWidth_,
41401          this.imageHeight_
41402        );
41403        context.setTransform(1, 0, 0, 1, 0, 0);
41404      } else {
41405        context.drawImage(
41406          this.image_,
41407          this.imageOriginX_,
41408          this.imageOriginY_,
41409          this.imageWidth_,
41410          this.imageHeight_,
41411          x,
41412          y,
41413          this.imageWidth_,
41414          this.imageHeight_
41415        );
41416      }
41417    }
41418    if (this.imageOpacity_ != 1) {
41419      context.globalAlpha = alpha;
41420    }
41421  }
41422
41423  /**
41424   * @param {Array<number>} flatCoordinates Flat coordinates.
41425   * @param {number} offset Offset.
41426   * @param {number} end End.
41427   * @param {number} stride Stride.
41428   * @private
41429   */
41430  drawText_(flatCoordinates, offset, end, stride) {
41431    if (!this.textState_ || this.text_ === '') {
41432      return;
41433    }
41434    if (this.textFillState_) {
41435      this.setContextFillState_(this.textFillState_);
41436    }
41437    if (this.textStrokeState_) {
41438      this.setContextStrokeState_(this.textStrokeState_);
41439    }
41440    this.setContextTextState_(this.textState_);
41441    const pixelCoordinates = transform2D(
41442      flatCoordinates,
41443      offset,
41444      end,
41445      stride,
41446      this.transform_,
41447      this.pixelCoordinates_
41448    );
41449    const context = this.context_;
41450    let rotation = this.textRotation_;
41451    if (this.textRotateWithView_) {
41452      rotation += this.viewRotation_;
41453    }
41454    for (; offset < end; offset += stride) {
41455      const x = pixelCoordinates[offset] + this.textOffsetX_;
41456      const y = pixelCoordinates[offset + 1] + this.textOffsetY_;
41457      if (
41458        rotation !== 0 ||
41459        this.textScale_[0] != 1 ||
41460        this.textScale_[1] != 1
41461      ) {
41462        context.translate(x - this.textOffsetX_, y - this.textOffsetY_);
41463        context.rotate(rotation);
41464        context.translate(this.textOffsetX_, this.textOffsetY_);
41465        context.scale(this.textScale_[0], this.textScale_[1]);
41466        if (this.textStrokeState_) {
41467          context.strokeText(this.text_, 0, 0);
41468        }
41469        if (this.textFillState_) {
41470          context.fillText(this.text_, 0, 0);
41471        }
41472        context.setTransform(1, 0, 0, 1, 0, 0);
41473      } else {
41474        if (this.textStrokeState_) {
41475          context.strokeText(this.text_, x, y);
41476        }
41477        if (this.textFillState_) {
41478          context.fillText(this.text_, x, y);
41479        }
41480      }
41481    }
41482  }
41483
41484  /**
41485   * @param {Array<number>} flatCoordinates Flat coordinates.
41486   * @param {number} offset Offset.
41487   * @param {number} end End.
41488   * @param {number} stride Stride.
41489   * @param {boolean} close Close.
41490   * @private
41491   * @return {number} end End.
41492   */
41493  moveToLineTo_(flatCoordinates, offset, end, stride, close) {
41494    const context = this.context_;
41495    const pixelCoordinates = transform2D(
41496      flatCoordinates,
41497      offset,
41498      end,
41499      stride,
41500      this.transform_,
41501      this.pixelCoordinates_
41502    );
41503    context.moveTo(pixelCoordinates[0], pixelCoordinates[1]);
41504    let length = pixelCoordinates.length;
41505    if (close) {
41506      length -= 2;
41507    }
41508    for (let i = 2; i < length; i += 2) {
41509      context.lineTo(pixelCoordinates[i], pixelCoordinates[i + 1]);
41510    }
41511    if (close) {
41512      context.closePath();
41513    }
41514    return end;
41515  }
41516
41517  /**
41518   * @param {Array<number>} flatCoordinates Flat coordinates.
41519   * @param {number} offset Offset.
41520   * @param {Array<number>} ends Ends.
41521   * @param {number} stride Stride.
41522   * @private
41523   * @return {number} End.
41524   */
41525  drawRings_(flatCoordinates, offset, ends, stride) {
41526    for (let i = 0, ii = ends.length; i < ii; ++i) {
41527      offset = this.moveToLineTo_(
41528        flatCoordinates,
41529        offset,
41530        ends[i],
41531        stride,
41532        true
41533      );
41534    }
41535    return offset;
41536  }
41537
41538  /**
41539   * Render a circle geometry into the canvas.  Rendering is immediate and uses
41540   * the current fill and stroke styles.
41541   *
41542   * @param {import("../../geom/Circle.js").default} geometry Circle geometry.
41543   * @api
41544   */
41545  drawCircle(geometry) {
41546    if (!intersects(this.extent_, geometry.getExtent())) {
41547      return;
41548    }
41549    if (this.fillState_ || this.strokeState_) {
41550      if (this.fillState_) {
41551        this.setContextFillState_(this.fillState_);
41552      }
41553      if (this.strokeState_) {
41554        this.setContextStrokeState_(this.strokeState_);
41555      }
41556      const pixelCoordinates = transformGeom2D(
41557        geometry,
41558        this.transform_,
41559        this.pixelCoordinates_
41560      );
41561      const dx = pixelCoordinates[2] - pixelCoordinates[0];
41562      const dy = pixelCoordinates[3] - pixelCoordinates[1];
41563      const radius = Math.sqrt(dx * dx + dy * dy);
41564      const context = this.context_;
41565      context.beginPath();
41566      context.arc(
41567        pixelCoordinates[0],
41568        pixelCoordinates[1],
41569        radius,
41570        0,
41571        2 * Math.PI
41572      );
41573      if (this.fillState_) {
41574        context.fill();
41575      }
41576      if (this.strokeState_) {
41577        context.stroke();
41578      }
41579    }
41580    if (this.text_ !== '') {
41581      this.drawText_(geometry.getCenter(), 0, 2, 2);
41582    }
41583  }
41584
41585  /**
41586   * Set the rendering style.  Note that since this is an immediate rendering API,
41587   * any `zIndex` on the provided style will be ignored.
41588   *
41589   * @param {import("../../style/Style.js").default} style The rendering style.
41590   * @api
41591   */
41592  setStyle(style) {
41593    this.setFillStrokeStyle(style.getFill(), style.getStroke());
41594    this.setImageStyle(style.getImage());
41595    this.setTextStyle(style.getText());
41596  }
41597
41598  /**
41599   * @param {import("../../transform.js").Transform} transform Transform.
41600   */
41601  setTransform(transform) {
41602    this.transform_ = transform;
41603  }
41604
41605  /**
41606   * Render a geometry into the canvas.  Call
41607   * {@link module:ol/render/canvas/Immediate~CanvasImmediateRenderer#setStyle renderer.setStyle()} first to set the rendering style.
41608   *
41609   * @param {import("../../geom/Geometry.js").default|import("../Feature.js").default} geometry The geometry to render.
41610   * @api
41611   */
41612  drawGeometry(geometry) {
41613    const type = geometry.getType();
41614    switch (type) {
41615      case 'Point':
41616        this.drawPoint(
41617          /** @type {import("../../geom/Point.js").default} */ (geometry)
41618        );
41619        break;
41620      case 'LineString':
41621        this.drawLineString(
41622          /** @type {import("../../geom/LineString.js").default} */ (geometry)
41623        );
41624        break;
41625      case 'Polygon':
41626        this.drawPolygon(
41627          /** @type {import("../../geom/Polygon.js").default} */ (geometry)
41628        );
41629        break;
41630      case 'MultiPoint':
41631        this.drawMultiPoint(
41632          /** @type {import("../../geom/MultiPoint.js").default} */ (geometry)
41633        );
41634        break;
41635      case 'MultiLineString':
41636        this.drawMultiLineString(
41637          /** @type {import("../../geom/MultiLineString.js").default} */ (
41638            geometry
41639          )
41640        );
41641        break;
41642      case 'MultiPolygon':
41643        this.drawMultiPolygon(
41644          /** @type {import("../../geom/MultiPolygon.js").default} */ (geometry)
41645        );
41646        break;
41647      case 'GeometryCollection':
41648        this.drawGeometryCollection(
41649          /** @type {import("../../geom/GeometryCollection.js").default} */ (
41650            geometry
41651          )
41652        );
41653        break;
41654      case 'Circle':
41655        this.drawCircle(
41656          /** @type {import("../../geom/Circle.js").default} */ (geometry)
41657        );
41658        break;
41659      default:
41660    }
41661  }
41662
41663  /**
41664   * Render a feature into the canvas.  Note that any `zIndex` on the provided
41665   * style will be ignored - features are rendered immediately in the order that
41666   * this method is called.  If you need `zIndex` support, you should be using an
41667   * {@link module:ol/layer/Vector~VectorLayer} instead.
41668   *
41669   * @param {import("../../Feature.js").default} feature Feature.
41670   * @param {import("../../style/Style.js").default} style Style.
41671   * @api
41672   */
41673  drawFeature(feature, style) {
41674    const geometry = style.getGeometryFunction()(feature);
41675    if (!geometry || !intersects(this.extent_, geometry.getExtent())) {
41676      return;
41677    }
41678    this.setStyle(style);
41679    this.drawGeometry(geometry);
41680  }
41681
41682  /**
41683   * Render a GeometryCollection to the canvas.  Rendering is immediate and
41684   * uses the current styles appropriate for each geometry in the collection.
41685   *
41686   * @param {import("../../geom/GeometryCollection.js").default} geometry Geometry collection.
41687   */
41688  drawGeometryCollection(geometry) {
41689    const geometries = geometry.getGeometriesArray();
41690    for (let i = 0, ii = geometries.length; i < ii; ++i) {
41691      this.drawGeometry(geometries[i]);
41692    }
41693  }
41694
41695  /**
41696   * Render a Point geometry into the canvas.  Rendering is immediate and uses
41697   * the current style.
41698   *
41699   * @param {import("../../geom/Point.js").default|import("../Feature.js").default} geometry Point geometry.
41700   */
41701  drawPoint(geometry) {
41702    if (this.squaredTolerance_) {
41703      geometry = /** @type {import("../../geom/Point.js").default} */ (
41704        geometry.simplifyTransformed(
41705          this.squaredTolerance_,
41706          this.userTransform_
41707        )
41708      );
41709    }
41710    const flatCoordinates = geometry.getFlatCoordinates();
41711    const stride = geometry.getStride();
41712    if (this.image_) {
41713      this.drawImages_(flatCoordinates, 0, flatCoordinates.length, stride);
41714    }
41715    if (this.text_ !== '') {
41716      this.drawText_(flatCoordinates, 0, flatCoordinates.length, stride);
41717    }
41718  }
41719
41720  /**
41721   * Render a MultiPoint geometry  into the canvas.  Rendering is immediate and
41722   * uses the current style.
41723   *
41724   * @param {import("../../geom/MultiPoint.js").default|import("../Feature.js").default} geometry MultiPoint geometry.
41725   */
41726  drawMultiPoint(geometry) {
41727    if (this.squaredTolerance_) {
41728      geometry = /** @type {import("../../geom/MultiPoint.js").default} */ (
41729        geometry.simplifyTransformed(
41730          this.squaredTolerance_,
41731          this.userTransform_
41732        )
41733      );
41734    }
41735    const flatCoordinates = geometry.getFlatCoordinates();
41736    const stride = geometry.getStride();
41737    if (this.image_) {
41738      this.drawImages_(flatCoordinates, 0, flatCoordinates.length, stride);
41739    }
41740    if (this.text_ !== '') {
41741      this.drawText_(flatCoordinates, 0, flatCoordinates.length, stride);
41742    }
41743  }
41744
41745  /**
41746   * Render a LineString into the canvas.  Rendering is immediate and uses
41747   * the current style.
41748   *
41749   * @param {import("../../geom/LineString.js").default|import("../Feature.js").default} geometry LineString geometry.
41750   */
41751  drawLineString(geometry) {
41752    if (this.squaredTolerance_) {
41753      geometry = /** @type {import("../../geom/LineString.js").default} */ (
41754        geometry.simplifyTransformed(
41755          this.squaredTolerance_,
41756          this.userTransform_
41757        )
41758      );
41759    }
41760    if (!intersects(this.extent_, geometry.getExtent())) {
41761      return;
41762    }
41763    if (this.strokeState_) {
41764      this.setContextStrokeState_(this.strokeState_);
41765      const context = this.context_;
41766      const flatCoordinates = geometry.getFlatCoordinates();
41767      context.beginPath();
41768      this.moveToLineTo_(
41769        flatCoordinates,
41770        0,
41771        flatCoordinates.length,
41772        geometry.getStride(),
41773        false
41774      );
41775      context.stroke();
41776    }
41777    if (this.text_ !== '') {
41778      const flatMidpoint = geometry.getFlatMidpoint();
41779      this.drawText_(flatMidpoint, 0, 2, 2);
41780    }
41781  }
41782
41783  /**
41784   * Render a MultiLineString geometry into the canvas.  Rendering is immediate
41785   * and uses the current style.
41786   *
41787   * @param {import("../../geom/MultiLineString.js").default|import("../Feature.js").default} geometry MultiLineString geometry.
41788   */
41789  drawMultiLineString(geometry) {
41790    if (this.squaredTolerance_) {
41791      geometry =
41792        /** @type {import("../../geom/MultiLineString.js").default} */ (
41793          geometry.simplifyTransformed(
41794            this.squaredTolerance_,
41795            this.userTransform_
41796          )
41797        );
41798    }
41799    const geometryExtent = geometry.getExtent();
41800    if (!intersects(this.extent_, geometryExtent)) {
41801      return;
41802    }
41803    if (this.strokeState_) {
41804      this.setContextStrokeState_(this.strokeState_);
41805      const context = this.context_;
41806      const flatCoordinates = geometry.getFlatCoordinates();
41807      let offset = 0;
41808      const ends = /** @type {Array<number>} */ (geometry.getEnds());
41809      const stride = geometry.getStride();
41810      context.beginPath();
41811      for (let i = 0, ii = ends.length; i < ii; ++i) {
41812        offset = this.moveToLineTo_(
41813          flatCoordinates,
41814          offset,
41815          ends[i],
41816          stride,
41817          false
41818        );
41819      }
41820      context.stroke();
41821    }
41822    if (this.text_ !== '') {
41823      const flatMidpoints = geometry.getFlatMidpoints();
41824      this.drawText_(flatMidpoints, 0, flatMidpoints.length, 2);
41825    }
41826  }
41827
41828  /**
41829   * Render a Polygon geometry into the canvas.  Rendering is immediate and uses
41830   * the current style.
41831   *
41832   * @param {import("../../geom/Polygon.js").default|import("../Feature.js").default} geometry Polygon geometry.
41833   */
41834  drawPolygon(geometry) {
41835    if (this.squaredTolerance_) {
41836      geometry = /** @type {import("../../geom/Polygon.js").default} */ (
41837        geometry.simplifyTransformed(
41838          this.squaredTolerance_,
41839          this.userTransform_
41840        )
41841      );
41842    }
41843    if (!intersects(this.extent_, geometry.getExtent())) {
41844      return;
41845    }
41846    if (this.strokeState_ || this.fillState_) {
41847      if (this.fillState_) {
41848        this.setContextFillState_(this.fillState_);
41849      }
41850      if (this.strokeState_) {
41851        this.setContextStrokeState_(this.strokeState_);
41852      }
41853      const context = this.context_;
41854      context.beginPath();
41855      this.drawRings_(
41856        geometry.getOrientedFlatCoordinates(),
41857        0,
41858        /** @type {Array<number>} */ (geometry.getEnds()),
41859        geometry.getStride()
41860      );
41861      if (this.fillState_) {
41862        context.fill();
41863      }
41864      if (this.strokeState_) {
41865        context.stroke();
41866      }
41867    }
41868    if (this.text_ !== '') {
41869      const flatInteriorPoint = geometry.getFlatInteriorPoint();
41870      this.drawText_(flatInteriorPoint, 0, 2, 2);
41871    }
41872  }
41873
41874  /**
41875   * Render MultiPolygon geometry into the canvas.  Rendering is immediate and
41876   * uses the current style.
41877   * @param {import("../../geom/MultiPolygon.js").default} geometry MultiPolygon geometry.
41878   */
41879  drawMultiPolygon(geometry) {
41880    if (this.squaredTolerance_) {
41881      geometry = /** @type {import("../../geom/MultiPolygon.js").default} */ (
41882        geometry.simplifyTransformed(
41883          this.squaredTolerance_,
41884          this.userTransform_
41885        )
41886      );
41887    }
41888    if (!intersects(this.extent_, geometry.getExtent())) {
41889      return;
41890    }
41891    if (this.strokeState_ || this.fillState_) {
41892      if (this.fillState_) {
41893        this.setContextFillState_(this.fillState_);
41894      }
41895      if (this.strokeState_) {
41896        this.setContextStrokeState_(this.strokeState_);
41897      }
41898      const context = this.context_;
41899      const flatCoordinates = geometry.getOrientedFlatCoordinates();
41900      let offset = 0;
41901      const endss = geometry.getEndss();
41902      const stride = geometry.getStride();
41903      context.beginPath();
41904      for (let i = 0, ii = endss.length; i < ii; ++i) {
41905        const ends = endss[i];
41906        offset = this.drawRings_(flatCoordinates, offset, ends, stride);
41907      }
41908      if (this.fillState_) {
41909        context.fill();
41910      }
41911      if (this.strokeState_) {
41912        context.stroke();
41913      }
41914    }
41915    if (this.text_ !== '') {
41916      const flatInteriorPoints = geometry.getFlatInteriorPoints();
41917      this.drawText_(flatInteriorPoints, 0, flatInteriorPoints.length, 2);
41918    }
41919  }
41920
41921  /**
41922   * @param {import("../canvas.js").FillState} fillState Fill state.
41923   * @private
41924   */
41925  setContextFillState_(fillState) {
41926    const context = this.context_;
41927    const contextFillState = this.contextFillState_;
41928    if (!contextFillState) {
41929      context.fillStyle = fillState.fillStyle;
41930      this.contextFillState_ = {
41931        fillStyle: fillState.fillStyle,
41932      };
41933    } else {
41934      if (contextFillState.fillStyle != fillState.fillStyle) {
41935        contextFillState.fillStyle = fillState.fillStyle;
41936        context.fillStyle = fillState.fillStyle;
41937      }
41938    }
41939  }
41940
41941  /**
41942   * @param {import("../canvas.js").StrokeState} strokeState Stroke state.
41943   * @private
41944   */
41945  setContextStrokeState_(strokeState) {
41946    const context = this.context_;
41947    const contextStrokeState = this.contextStrokeState_;
41948    if (!contextStrokeState) {
41949      context.lineCap = strokeState.lineCap;
41950      context.setLineDash(strokeState.lineDash);
41951      context.lineDashOffset = strokeState.lineDashOffset;
41952      context.lineJoin = strokeState.lineJoin;
41953      context.lineWidth = strokeState.lineWidth;
41954      context.miterLimit = strokeState.miterLimit;
41955      context.strokeStyle = strokeState.strokeStyle;
41956      this.contextStrokeState_ = {
41957        lineCap: strokeState.lineCap,
41958        lineDash: strokeState.lineDash,
41959        lineDashOffset: strokeState.lineDashOffset,
41960        lineJoin: strokeState.lineJoin,
41961        lineWidth: strokeState.lineWidth,
41962        miterLimit: strokeState.miterLimit,
41963        strokeStyle: strokeState.strokeStyle,
41964      };
41965    } else {
41966      if (contextStrokeState.lineCap != strokeState.lineCap) {
41967        contextStrokeState.lineCap = strokeState.lineCap;
41968        context.lineCap = strokeState.lineCap;
41969      }
41970      if (!equals(contextStrokeState.lineDash, strokeState.lineDash)) {
41971        context.setLineDash(
41972          (contextStrokeState.lineDash = strokeState.lineDash)
41973        );
41974      }
41975      if (contextStrokeState.lineDashOffset != strokeState.lineDashOffset) {
41976        contextStrokeState.lineDashOffset = strokeState.lineDashOffset;
41977        context.lineDashOffset = strokeState.lineDashOffset;
41978      }
41979      if (contextStrokeState.lineJoin != strokeState.lineJoin) {
41980        contextStrokeState.lineJoin = strokeState.lineJoin;
41981        context.lineJoin = strokeState.lineJoin;
41982      }
41983      if (contextStrokeState.lineWidth != strokeState.lineWidth) {
41984        contextStrokeState.lineWidth = strokeState.lineWidth;
41985        context.lineWidth = strokeState.lineWidth;
41986      }
41987      if (contextStrokeState.miterLimit != strokeState.miterLimit) {
41988        contextStrokeState.miterLimit = strokeState.miterLimit;
41989        context.miterLimit = strokeState.miterLimit;
41990      }
41991      if (contextStrokeState.strokeStyle != strokeState.strokeStyle) {
41992        contextStrokeState.strokeStyle = strokeState.strokeStyle;
41993        context.strokeStyle = strokeState.strokeStyle;
41994      }
41995    }
41996  }
41997
41998  /**
41999   * @param {import("../canvas.js").TextState} textState Text state.
42000   * @private
42001   */
42002  setContextTextState_(textState) {
42003    const context = this.context_;
42004    const contextTextState = this.contextTextState_;
42005    const textAlign = textState.textAlign
42006      ? textState.textAlign
42007      : defaultTextAlign;
42008    if (!contextTextState) {
42009      context.font = textState.font;
42010      context.textAlign = textAlign;
42011      context.textBaseline = textState.textBaseline;
42012      this.contextTextState_ = {
42013        font: textState.font,
42014        textAlign: textAlign,
42015        textBaseline: textState.textBaseline,
42016      };
42017    } else {
42018      if (contextTextState.font != textState.font) {
42019        contextTextState.font = textState.font;
42020        context.font = textState.font;
42021      }
42022      if (contextTextState.textAlign != textAlign) {
42023        contextTextState.textAlign = textAlign;
42024        context.textAlign = textAlign;
42025      }
42026      if (contextTextState.textBaseline != textState.textBaseline) {
42027        contextTextState.textBaseline = textState.textBaseline;
42028        context.textBaseline = textState.textBaseline;
42029      }
42030    }
42031  }
42032
42033  /**
42034   * Set the fill and stroke style for subsequent draw operations.  To clear
42035   * either fill or stroke styles, pass null for the appropriate parameter.
42036   *
42037   * @param {import("../../style/Fill.js").default} fillStyle Fill style.
42038   * @param {import("../../style/Stroke.js").default} strokeStyle Stroke style.
42039   */
42040  setFillStrokeStyle(fillStyle, strokeStyle) {
42041    if (!fillStyle) {
42042      this.fillState_ = null;
42043    } else {
42044      const fillStyleColor = fillStyle.getColor();
42045      this.fillState_ = {
42046        fillStyle: asColorLike(
42047          fillStyleColor ? fillStyleColor : defaultFillStyle
42048        ),
42049      };
42050    }
42051    if (!strokeStyle) {
42052      this.strokeState_ = null;
42053    } else {
42054      const strokeStyleColor = strokeStyle.getColor();
42055      const strokeStyleLineCap = strokeStyle.getLineCap();
42056      const strokeStyleLineDash = strokeStyle.getLineDash();
42057      const strokeStyleLineDashOffset = strokeStyle.getLineDashOffset();
42058      const strokeStyleLineJoin = strokeStyle.getLineJoin();
42059      const strokeStyleWidth = strokeStyle.getWidth();
42060      const strokeStyleMiterLimit = strokeStyle.getMiterLimit();
42061      const lineDash = strokeStyleLineDash
42062        ? strokeStyleLineDash
42063        : defaultLineDash;
42064      this.strokeState_ = {
42065        lineCap:
42066          strokeStyleLineCap !== undefined
42067            ? strokeStyleLineCap
42068            : defaultLineCap,
42069        lineDash:
42070          this.pixelRatio_ === 1
42071            ? lineDash
42072            : lineDash.map((n) => n * this.pixelRatio_),
42073        lineDashOffset:
42074          (strokeStyleLineDashOffset
42075            ? strokeStyleLineDashOffset
42076            : defaultLineDashOffset) * this.pixelRatio_,
42077        lineJoin:
42078          strokeStyleLineJoin !== undefined
42079            ? strokeStyleLineJoin
42080            : defaultLineJoin,
42081        lineWidth:
42082          (strokeStyleWidth !== undefined
42083            ? strokeStyleWidth
42084            : defaultLineWidth) * this.pixelRatio_,
42085        miterLimit:
42086          strokeStyleMiterLimit !== undefined
42087            ? strokeStyleMiterLimit
42088            : defaultMiterLimit,
42089        strokeStyle: asColorLike(
42090          strokeStyleColor ? strokeStyleColor : defaultStrokeStyle
42091        ),
42092      };
42093    }
42094  }
42095
42096  /**
42097   * Set the image style for subsequent draw operations.  Pass null to remove
42098   * the image style.
42099   *
42100   * @param {import("../../style/Image.js").default} imageStyle Image style.
42101   */
42102  setImageStyle(imageStyle) {
42103    let imageSize;
42104    if (!imageStyle || !(imageSize = imageStyle.getSize())) {
42105      this.image_ = null;
42106      return;
42107    }
42108    const imagePixelRatio = imageStyle.getPixelRatio(this.pixelRatio_);
42109    const imageAnchor = imageStyle.getAnchor();
42110    const imageOrigin = imageStyle.getOrigin();
42111    this.image_ = imageStyle.getImage(this.pixelRatio_);
42112    this.imageAnchorX_ = imageAnchor[0] * imagePixelRatio;
42113    this.imageAnchorY_ = imageAnchor[1] * imagePixelRatio;
42114    this.imageHeight_ = imageSize[1] * imagePixelRatio;
42115    this.imageOpacity_ = imageStyle.getOpacity();
42116    this.imageOriginX_ = imageOrigin[0];
42117    this.imageOriginY_ = imageOrigin[1];
42118    this.imageRotateWithView_ = imageStyle.getRotateWithView();
42119    this.imageRotation_ = imageStyle.getRotation();
42120    const imageScale = imageStyle.getScaleArray();
42121    this.imageScale_ = [
42122      (imageScale[0] * this.pixelRatio_) / imagePixelRatio,
42123      (imageScale[1] * this.pixelRatio_) / imagePixelRatio,
42124    ];
42125    this.imageWidth_ = imageSize[0] * imagePixelRatio;
42126  }
42127
42128  /**
42129   * Set the text style for subsequent draw operations.  Pass null to
42130   * remove the text style.
42131   *
42132   * @param {import("../../style/Text.js").default} textStyle Text style.
42133   */
42134  setTextStyle(textStyle) {
42135    if (!textStyle) {
42136      this.text_ = '';
42137    } else {
42138      const textFillStyle = textStyle.getFill();
42139      if (!textFillStyle) {
42140        this.textFillState_ = null;
42141      } else {
42142        const textFillStyleColor = textFillStyle.getColor();
42143        this.textFillState_ = {
42144          fillStyle: asColorLike(
42145            textFillStyleColor ? textFillStyleColor : defaultFillStyle
42146          ),
42147        };
42148      }
42149      const textStrokeStyle = textStyle.getStroke();
42150      if (!textStrokeStyle) {
42151        this.textStrokeState_ = null;
42152      } else {
42153        const textStrokeStyleColor = textStrokeStyle.getColor();
42154        const textStrokeStyleLineCap = textStrokeStyle.getLineCap();
42155        const textStrokeStyleLineDash = textStrokeStyle.getLineDash();
42156        const textStrokeStyleLineDashOffset =
42157          textStrokeStyle.getLineDashOffset();
42158        const textStrokeStyleLineJoin = textStrokeStyle.getLineJoin();
42159        const textStrokeStyleWidth = textStrokeStyle.getWidth();
42160        const textStrokeStyleMiterLimit = textStrokeStyle.getMiterLimit();
42161        this.textStrokeState_ = {
42162          lineCap:
42163            textStrokeStyleLineCap !== undefined
42164              ? textStrokeStyleLineCap
42165              : defaultLineCap,
42166          lineDash: textStrokeStyleLineDash
42167            ? textStrokeStyleLineDash
42168            : defaultLineDash,
42169          lineDashOffset: textStrokeStyleLineDashOffset
42170            ? textStrokeStyleLineDashOffset
42171            : defaultLineDashOffset,
42172          lineJoin:
42173            textStrokeStyleLineJoin !== undefined
42174              ? textStrokeStyleLineJoin
42175              : defaultLineJoin,
42176          lineWidth:
42177            textStrokeStyleWidth !== undefined
42178              ? textStrokeStyleWidth
42179              : defaultLineWidth,
42180          miterLimit:
42181            textStrokeStyleMiterLimit !== undefined
42182              ? textStrokeStyleMiterLimit
42183              : defaultMiterLimit,
42184          strokeStyle: asColorLike(
42185            textStrokeStyleColor ? textStrokeStyleColor : defaultStrokeStyle
42186          ),
42187        };
42188      }
42189      const textFont = textStyle.getFont();
42190      const textOffsetX = textStyle.getOffsetX();
42191      const textOffsetY = textStyle.getOffsetY();
42192      const textRotateWithView = textStyle.getRotateWithView();
42193      const textRotation = textStyle.getRotation();
42194      const textScale = textStyle.getScaleArray();
42195      const textText = textStyle.getText();
42196      const textTextAlign = textStyle.getTextAlign();
42197      const textTextBaseline = textStyle.getTextBaseline();
42198      this.textState_ = {
42199        font: textFont !== undefined ? textFont : defaultFont,
42200        textAlign:
42201          textTextAlign !== undefined ? textTextAlign : defaultTextAlign,
42202        textBaseline:
42203          textTextBaseline !== undefined
42204            ? textTextBaseline
42205            : defaultTextBaseline,
42206      };
42207      this.text_ =
42208        textText !== undefined
42209          ? Array.isArray(textText)
42210            ? textText.reduce((acc, t, i) => (acc += i % 2 ? ' ' : t), '')
42211            : textText
42212          : '';
42213      this.textOffsetX_ =
42214        textOffsetX !== undefined ? this.pixelRatio_ * textOffsetX : 0;
42215      this.textOffsetY_ =
42216        textOffsetY !== undefined ? this.pixelRatio_ * textOffsetY : 0;
42217      this.textRotateWithView_ =
42218        textRotateWithView !== undefined ? textRotateWithView : false;
42219      this.textRotation_ = textRotation !== undefined ? textRotation : 0;
42220      this.textScale_ = [
42221        this.pixelRatio_ * textScale[0],
42222        this.pixelRatio_ * textScale[1],
42223      ];
42224    }
42225  }
42226}
42227
42228/* harmony default export */ const Immediate = (CanvasImmediateRenderer);
42229
42230;// CONCATENATED MODULE: ./node_modules/ol/render/canvas/hitdetect.js
42231/**
42232 * @module ol/render/canvas/hitdetect
42233 */
42234
42235
42236
42237
42238
42239
42240
42241
42242const HIT_DETECT_RESOLUTION = 0.5;
42243
42244/**
42245 * @param {import("../../size.js").Size} size Canvas size in css pixels.
42246 * @param {Array<import("../../transform.js").Transform>} transforms Transforms
42247 * for rendering features to all worlds of the viewport, from coordinates to css
42248 * pixels.
42249 * @param {Array<import("../../Feature.js").FeatureLike>} features
42250 * Features to consider for hit detection.
42251 * @param {import("../../style/Style.js").StyleFunction|undefined} styleFunction
42252 * Layer style function.
42253 * @param {import("../../extent.js").Extent} extent Extent.
42254 * @param {number} resolution Resolution.
42255 * @param {number} rotation Rotation.
42256 * @return {ImageData} Hit detection image data.
42257 */
42258function createHitDetectionImageData(
42259  size,
42260  transforms,
42261  features,
42262  styleFunction,
42263  extent,
42264  resolution,
42265  rotation
42266) {
42267  const width = size[0] * HIT_DETECT_RESOLUTION;
42268  const height = size[1] * HIT_DETECT_RESOLUTION;
42269  const context = createCanvasContext2D(width, height);
42270  context.imageSmoothingEnabled = false;
42271  const canvas = context.canvas;
42272  const renderer = new Immediate(
42273    context,
42274    HIT_DETECT_RESOLUTION,
42275    extent,
42276    null,
42277    rotation
42278  );
42279  const featureCount = features.length;
42280  // Stretch hit detection index to use the whole available color range
42281  const indexFactor = Math.floor((256 * 256 * 256 - 1) / featureCount);
42282  const featuresByZIndex = {};
42283  for (let i = 1; i <= featureCount; ++i) {
42284    const feature = features[i - 1];
42285    const featureStyleFunction = feature.getStyleFunction() || styleFunction;
42286    if (!styleFunction) {
42287      continue;
42288    }
42289    let styles = featureStyleFunction(feature, resolution);
42290    if (!styles) {
42291      continue;
42292    }
42293    if (!Array.isArray(styles)) {
42294      styles = [styles];
42295    }
42296    const index = i * indexFactor;
42297    const color = '#' + ('000000' + index.toString(16)).slice(-6);
42298    for (let j = 0, jj = styles.length; j < jj; ++j) {
42299      const originalStyle = styles[j];
42300      const geometry = originalStyle.getGeometryFunction()(feature);
42301      if (!geometry || !intersects(extent, geometry.getExtent())) {
42302        continue;
42303      }
42304      const style = originalStyle.clone();
42305      const fill = style.getFill();
42306      if (fill) {
42307        fill.setColor(color);
42308      }
42309      const stroke = style.getStroke();
42310      if (stroke) {
42311        stroke.setColor(color);
42312        stroke.setLineDash(null);
42313      }
42314      style.setText(undefined);
42315      const image = originalStyle.getImage();
42316      if (image && image.getOpacity() !== 0) {
42317        const imgSize = image.getImageSize();
42318        if (!imgSize) {
42319          continue;
42320        }
42321
42322        const imgContext = createCanvasContext2D(
42323          imgSize[0],
42324          imgSize[1],
42325          undefined,
42326          {alpha: false}
42327        );
42328        const img = imgContext.canvas;
42329        imgContext.fillStyle = color;
42330        imgContext.fillRect(0, 0, img.width, img.height);
42331        style.setImage(
42332          new style_Icon({
42333            img: img,
42334            imgSize: imgSize,
42335            anchor: image.getAnchor(),
42336            anchorXUnits: 'pixels',
42337            anchorYUnits: 'pixels',
42338            offset: image.getOrigin(),
42339            opacity: 1,
42340            size: image.getSize(),
42341            scale: image.getScale(),
42342            rotation: image.getRotation(),
42343            rotateWithView: image.getRotateWithView(),
42344          })
42345        );
42346      }
42347      const zIndex = style.getZIndex() || 0;
42348      let byGeometryType = featuresByZIndex[zIndex];
42349      if (!byGeometryType) {
42350        byGeometryType = {};
42351        featuresByZIndex[zIndex] = byGeometryType;
42352        byGeometryType['Polygon'] = [];
42353        byGeometryType['Circle'] = [];
42354        byGeometryType['LineString'] = [];
42355        byGeometryType['Point'] = [];
42356      }
42357      byGeometryType[geometry.getType().replace('Multi', '')].push(
42358        geometry,
42359        style
42360      );
42361    }
42362  }
42363
42364  const zIndexKeys = Object.keys(featuresByZIndex)
42365    .map(Number)
42366    .sort(numberSafeCompareFunction);
42367  for (let i = 0, ii = zIndexKeys.length; i < ii; ++i) {
42368    const byGeometryType = featuresByZIndex[zIndexKeys[i]];
42369    for (const type in byGeometryType) {
42370      const geomAndStyle = byGeometryType[type];
42371      for (let j = 0, jj = geomAndStyle.length; j < jj; j += 2) {
42372        renderer.setStyle(geomAndStyle[j + 1]);
42373        for (let k = 0, kk = transforms.length; k < kk; ++k) {
42374          renderer.setTransform(transforms[k]);
42375          renderer.drawGeometry(geomAndStyle[j]);
42376        }
42377      }
42378    }
42379  }
42380  return context.getImageData(0, 0, canvas.width, canvas.height);
42381}
42382
42383/**
42384 * @param {import("../../pixel").Pixel} pixel Pixel coordinate on the hit
42385 * detection canvas in css pixels.
42386 * @param {Array<import("../../Feature").FeatureLike>} features Features. Has to
42387 * match the `features` array that was passed to `createHitDetectionImageData()`.
42388 * @param {ImageData} imageData Hit detection image data generated by
42389 * `createHitDetectionImageData()`.
42390 * @return {Array<import("../../Feature").FeatureLike>} features Features.
42391 */
42392function hitDetect(pixel, features, imageData) {
42393  const resultFeatures = [];
42394  if (imageData) {
42395    const x = Math.floor(Math.round(pixel[0]) * HIT_DETECT_RESOLUTION);
42396    const y = Math.floor(Math.round(pixel[1]) * HIT_DETECT_RESOLUTION);
42397    // The pixel coordinate is clamped down to the hit-detect canvas' size to account
42398    // for browsers returning coordinates slightly larger than the actual canvas size
42399    // due to a non-integer pixel ratio.
42400    const index =
42401      (math_clamp(x, 0, imageData.width - 1) +
42402        math_clamp(y, 0, imageData.height - 1) * imageData.width) *
42403      4;
42404    const r = imageData.data[index];
42405    const g = imageData.data[index + 1];
42406    const b = imageData.data[index + 2];
42407    const i = b + 256 * (g + 256 * r);
42408    const indexFactor = Math.floor((256 * 256 * 256 - 1) / features.length);
42409    if (i && i % indexFactor === 0) {
42410      resultFeatures.push(features[i / indexFactor - 1]);
42411    }
42412  }
42413  return resultFeatures;
42414}
42415
42416;// CONCATENATED MODULE: ./node_modules/ol/renderer/vector.js
42417/**
42418 * @module ol/renderer/vector
42419 */
42420
42421
42422
42423/**
42424 * Feature callback. The callback will be called with three arguments. The first
42425 * argument is one {@link module:ol/Feature~Feature feature} or {@link module:ol/render/Feature~RenderFeature render feature}
42426 * at the pixel, the second is the {@link module:ol/layer/Layer~Layer layer} of the feature and will be null for
42427 * unmanaged layers. The third is the {@link module:ol/geom/SimpleGeometry~SimpleGeometry} of the feature. For features
42428 * with a GeometryCollection geometry, it will be the first detected geometry from the collection.
42429 * @template T
42430 * @typedef {function(import("../Feature.js").FeatureLike, import("../layer/Layer.js").default<import("../source/Source").default>, import("../geom/SimpleGeometry.js").default): T} FeatureCallback
42431 */
42432
42433/**
42434 * Tolerance for geometry simplification in device pixels.
42435 * @type {number}
42436 */
42437const SIMPLIFY_TOLERANCE = 0.5;
42438
42439/**
42440 * @const
42441 * @type {Object<import("../geom/Geometry.js").Type,
42442 *                function(import("../render/canvas/BuilderGroup.js").default, import("../geom/Geometry.js").default,
42443 *                         import("../style/Style.js").default, Object): void>}
42444 */
42445const GEOMETRY_RENDERERS = {
42446  'Point': renderPointGeometry,
42447  'LineString': renderLineStringGeometry,
42448  'Polygon': renderPolygonGeometry,
42449  'MultiPoint': renderMultiPointGeometry,
42450  'MultiLineString': renderMultiLineStringGeometry,
42451  'MultiPolygon': renderMultiPolygonGeometry,
42452  'GeometryCollection': renderGeometryCollectionGeometry,
42453  'Circle': renderCircleGeometry,
42454};
42455
42456/**
42457 * @param {import("../Feature.js").FeatureLike} feature1 Feature 1.
42458 * @param {import("../Feature.js").FeatureLike} feature2 Feature 2.
42459 * @return {number} Order.
42460 */
42461function defaultOrder(feature1, feature2) {
42462  return parseInt(getUid(feature1), 10) - parseInt(getUid(feature2), 10);
42463}
42464
42465/**
42466 * @param {number} resolution Resolution.
42467 * @param {number} pixelRatio Pixel ratio.
42468 * @return {number} Squared pixel tolerance.
42469 */
42470function getSquaredTolerance(resolution, pixelRatio) {
42471  const tolerance = getTolerance(resolution, pixelRatio);
42472  return tolerance * tolerance;
42473}
42474
42475/**
42476 * @param {number} resolution Resolution.
42477 * @param {number} pixelRatio Pixel ratio.
42478 * @return {number} Pixel tolerance.
42479 */
42480function getTolerance(resolution, pixelRatio) {
42481  return (SIMPLIFY_TOLERANCE * resolution) / pixelRatio;
42482}
42483
42484/**
42485 * @param {import("../render/canvas/BuilderGroup.js").default} builderGroup Builder group.
42486 * @param {import("../geom/Circle.js").default} geometry Geometry.
42487 * @param {import("../style/Style.js").default} style Style.
42488 * @param {import("../Feature.js").default} feature Feature.
42489 * @param {import("../render/canvas/BuilderGroup.js").default} [declutterBuilderGroup] Builder for decluttering.
42490 */
42491function renderCircleGeometry(
42492  builderGroup,
42493  geometry,
42494  style,
42495  feature,
42496  declutterBuilderGroup
42497) {
42498  const fillStyle = style.getFill();
42499  const strokeStyle = style.getStroke();
42500  if (fillStyle || strokeStyle) {
42501    const circleReplay = builderGroup.getBuilder(style.getZIndex(), 'Circle');
42502    circleReplay.setFillStrokeStyle(fillStyle, strokeStyle);
42503    circleReplay.drawCircle(geometry, feature);
42504  }
42505  const textStyle = style.getText();
42506  if (textStyle && textStyle.getText()) {
42507    const textReplay = (declutterBuilderGroup || builderGroup).getBuilder(
42508      style.getZIndex(),
42509      'Text'
42510    );
42511    textReplay.setTextStyle(textStyle);
42512    textReplay.drawText(geometry, feature);
42513  }
42514}
42515
42516/**
42517 * @param {import("../render/canvas/BuilderGroup.js").default} replayGroup Replay group.
42518 * @param {import("../Feature.js").FeatureLike} feature Feature.
42519 * @param {import("../style/Style.js").default} style Style.
42520 * @param {number} squaredTolerance Squared tolerance.
42521 * @param {function(import("../events/Event.js").default): void} listener Listener function.
42522 * @param {import("../proj.js").TransformFunction} [transform] Transform from user to view projection.
42523 * @param {import("../render/canvas/BuilderGroup.js").default} [declutterBuilderGroup] Builder for decluttering.
42524 * @return {boolean} `true` if style is loading.
42525 */
42526function renderFeature(
42527  replayGroup,
42528  feature,
42529  style,
42530  squaredTolerance,
42531  listener,
42532  transform,
42533  declutterBuilderGroup
42534) {
42535  let loading = false;
42536  const imageStyle = style.getImage();
42537  if (imageStyle) {
42538    const imageState = imageStyle.getImageState();
42539    if (imageState == ol_ImageState.LOADED || imageState == ol_ImageState.ERROR) {
42540      imageStyle.unlistenImageChange(listener);
42541    } else {
42542      if (imageState == ol_ImageState.IDLE) {
42543        imageStyle.load();
42544      }
42545      imageStyle.listenImageChange(listener);
42546      loading = true;
42547    }
42548  }
42549  renderFeatureInternal(
42550    replayGroup,
42551    feature,
42552    style,
42553    squaredTolerance,
42554    transform,
42555    declutterBuilderGroup
42556  );
42557
42558  return loading;
42559}
42560
42561/**
42562 * @param {import("../render/canvas/BuilderGroup.js").default} replayGroup Replay group.
42563 * @param {import("../Feature.js").FeatureLike} feature Feature.
42564 * @param {import("../style/Style.js").default} style Style.
42565 * @param {number} squaredTolerance Squared tolerance.
42566 * @param {import("../proj.js").TransformFunction} [transform] Optional transform function.
42567 * @param {import("../render/canvas/BuilderGroup.js").default} [declutterBuilderGroup] Builder for decluttering.
42568 */
42569function renderFeatureInternal(
42570  replayGroup,
42571  feature,
42572  style,
42573  squaredTolerance,
42574  transform,
42575  declutterBuilderGroup
42576) {
42577  const geometry = style.getGeometryFunction()(feature);
42578  if (!geometry) {
42579    return;
42580  }
42581  const simplifiedGeometry = geometry.simplifyTransformed(
42582    squaredTolerance,
42583    transform
42584  );
42585  const renderer = style.getRenderer();
42586  if (renderer) {
42587    renderGeometry(replayGroup, simplifiedGeometry, style, feature);
42588  } else {
42589    const geometryRenderer = GEOMETRY_RENDERERS[simplifiedGeometry.getType()];
42590    geometryRenderer(
42591      replayGroup,
42592      simplifiedGeometry,
42593      style,
42594      feature,
42595      declutterBuilderGroup
42596    );
42597  }
42598}
42599
42600/**
42601 * @param {import("../render/canvas/BuilderGroup.js").default} replayGroup Replay group.
42602 * @param {import("../geom/Geometry.js").default|import("../render/Feature.js").default} geometry Geometry.
42603 * @param {import("../style/Style.js").default} style Style.
42604 * @param {import("../Feature.js").FeatureLike} feature Feature.
42605 */
42606function renderGeometry(replayGroup, geometry, style, feature) {
42607  if (geometry.getType() == 'GeometryCollection') {
42608    const geometries =
42609      /** @type {import("../geom/GeometryCollection.js").default} */ (
42610        geometry
42611      ).getGeometries();
42612    for (let i = 0, ii = geometries.length; i < ii; ++i) {
42613      renderGeometry(replayGroup, geometries[i], style, feature);
42614    }
42615    return;
42616  }
42617  const replay = replayGroup.getBuilder(style.getZIndex(), 'Default');
42618  replay.drawCustom(
42619    /** @type {import("../geom/SimpleGeometry.js").default} */ (geometry),
42620    feature,
42621    style.getRenderer(),
42622    style.getHitDetectionRenderer()
42623  );
42624}
42625
42626/**
42627 * @param {import("../render/canvas/BuilderGroup.js").default} replayGroup Replay group.
42628 * @param {import("../geom/GeometryCollection.js").default} geometry Geometry.
42629 * @param {import("../style/Style.js").default} style Style.
42630 * @param {import("../Feature.js").default} feature Feature.
42631 * @param {import("../render/canvas/BuilderGroup.js").default} [declutterBuilderGroup] Builder for decluttering.
42632 */
42633function renderGeometryCollectionGeometry(
42634  replayGroup,
42635  geometry,
42636  style,
42637  feature,
42638  declutterBuilderGroup
42639) {
42640  const geometries = geometry.getGeometriesArray();
42641  let i, ii;
42642  for (i = 0, ii = geometries.length; i < ii; ++i) {
42643    const geometryRenderer = GEOMETRY_RENDERERS[geometries[i].getType()];
42644    geometryRenderer(
42645      replayGroup,
42646      geometries[i],
42647      style,
42648      feature,
42649      declutterBuilderGroup
42650    );
42651  }
42652}
42653
42654/**
42655 * @param {import("../render/canvas/BuilderGroup.js").default} builderGroup Replay group.
42656 * @param {import("../geom/LineString.js").default|import("../render/Feature.js").default} geometry Geometry.
42657 * @param {import("../style/Style.js").default} style Style.
42658 * @param {import("../Feature.js").FeatureLike} feature Feature.
42659 * @param {import("../render/canvas/BuilderGroup.js").default} [declutterBuilderGroup] Builder for decluttering.
42660 */
42661function renderLineStringGeometry(
42662  builderGroup,
42663  geometry,
42664  style,
42665  feature,
42666  declutterBuilderGroup
42667) {
42668  const strokeStyle = style.getStroke();
42669  if (strokeStyle) {
42670    const lineStringReplay = builderGroup.getBuilder(
42671      style.getZIndex(),
42672      'LineString'
42673    );
42674    lineStringReplay.setFillStrokeStyle(null, strokeStyle);
42675    lineStringReplay.drawLineString(geometry, feature);
42676  }
42677  const textStyle = style.getText();
42678  if (textStyle && textStyle.getText()) {
42679    const textReplay = (declutterBuilderGroup || builderGroup).getBuilder(
42680      style.getZIndex(),
42681      'Text'
42682    );
42683    textReplay.setTextStyle(textStyle);
42684    textReplay.drawText(geometry, feature);
42685  }
42686}
42687
42688/**
42689 * @param {import("../render/canvas/BuilderGroup.js").default} builderGroup Replay group.
42690 * @param {import("../geom/MultiLineString.js").default|import("../render/Feature.js").default} geometry Geometry.
42691 * @param {import("../style/Style.js").default} style Style.
42692 * @param {import("../Feature.js").FeatureLike} feature Feature.
42693 * @param {import("../render/canvas/BuilderGroup.js").default} [declutterBuilderGroup] Builder for decluttering.
42694 */
42695function renderMultiLineStringGeometry(
42696  builderGroup,
42697  geometry,
42698  style,
42699  feature,
42700  declutterBuilderGroup
42701) {
42702  const strokeStyle = style.getStroke();
42703  if (strokeStyle) {
42704    const lineStringReplay = builderGroup.getBuilder(
42705      style.getZIndex(),
42706      'LineString'
42707    );
42708    lineStringReplay.setFillStrokeStyle(null, strokeStyle);
42709    lineStringReplay.drawMultiLineString(geometry, feature);
42710  }
42711  const textStyle = style.getText();
42712  if (textStyle && textStyle.getText()) {
42713    const textReplay = (declutterBuilderGroup || builderGroup).getBuilder(
42714      style.getZIndex(),
42715      'Text'
42716    );
42717    textReplay.setTextStyle(textStyle);
42718    textReplay.drawText(geometry, feature);
42719  }
42720}
42721
42722/**
42723 * @param {import("../render/canvas/BuilderGroup.js").default} builderGroup Replay group.
42724 * @param {import("../geom/MultiPolygon.js").default} geometry Geometry.
42725 * @param {import("../style/Style.js").default} style Style.
42726 * @param {import("../Feature.js").default} feature Feature.
42727 * @param {import("../render/canvas/BuilderGroup.js").default} [declutterBuilderGroup] Builder for decluttering.
42728 */
42729function renderMultiPolygonGeometry(
42730  builderGroup,
42731  geometry,
42732  style,
42733  feature,
42734  declutterBuilderGroup
42735) {
42736  const fillStyle = style.getFill();
42737  const strokeStyle = style.getStroke();
42738  if (strokeStyle || fillStyle) {
42739    const polygonReplay = builderGroup.getBuilder(style.getZIndex(), 'Polygon');
42740    polygonReplay.setFillStrokeStyle(fillStyle, strokeStyle);
42741    polygonReplay.drawMultiPolygon(geometry, feature);
42742  }
42743  const textStyle = style.getText();
42744  if (textStyle && textStyle.getText()) {
42745    const textReplay = (declutterBuilderGroup || builderGroup).getBuilder(
42746      style.getZIndex(),
42747      'Text'
42748    );
42749    textReplay.setTextStyle(textStyle);
42750    textReplay.drawText(geometry, feature);
42751  }
42752}
42753
42754/**
42755 * @param {import("../render/canvas/BuilderGroup.js").default} builderGroup Replay group.
42756 * @param {import("../geom/Point.js").default|import("../render/Feature.js").default} geometry Geometry.
42757 * @param {import("../style/Style.js").default} style Style.
42758 * @param {import("../Feature.js").FeatureLike} feature Feature.
42759 * @param {import("../render/canvas/BuilderGroup.js").default} [declutterBuilderGroup] Builder for decluttering.
42760 */
42761function renderPointGeometry(
42762  builderGroup,
42763  geometry,
42764  style,
42765  feature,
42766  declutterBuilderGroup
42767) {
42768  const imageStyle = style.getImage();
42769  const textStyle = style.getText();
42770  /** @type {import("../render/canvas.js").DeclutterImageWithText} */
42771  let declutterImageWithText;
42772  if (imageStyle) {
42773    if (imageStyle.getImageState() != ol_ImageState.LOADED) {
42774      return;
42775    }
42776    let imageBuilderGroup = builderGroup;
42777    if (declutterBuilderGroup) {
42778      const declutterMode = imageStyle.getDeclutterMode();
42779      if (declutterMode !== 'none') {
42780        imageBuilderGroup = declutterBuilderGroup;
42781        if (declutterMode === 'obstacle') {
42782          // draw in non-declutter group:
42783          const imageReplay = builderGroup.getBuilder(
42784            style.getZIndex(),
42785            'Image'
42786          );
42787          imageReplay.setImageStyle(imageStyle, declutterImageWithText);
42788          imageReplay.drawPoint(geometry, feature);
42789        } else if (textStyle && textStyle.getText()) {
42790          declutterImageWithText = {};
42791        }
42792      }
42793    }
42794    const imageReplay = imageBuilderGroup.getBuilder(
42795      style.getZIndex(),
42796      'Image'
42797    );
42798    imageReplay.setImageStyle(imageStyle, declutterImageWithText);
42799    imageReplay.drawPoint(geometry, feature);
42800  }
42801  if (textStyle && textStyle.getText()) {
42802    let textBuilderGroup = builderGroup;
42803    if (declutterBuilderGroup) {
42804      textBuilderGroup = declutterBuilderGroup;
42805    }
42806    const textReplay = textBuilderGroup.getBuilder(style.getZIndex(), 'Text');
42807    textReplay.setTextStyle(textStyle, declutterImageWithText);
42808    textReplay.drawText(geometry, feature);
42809  }
42810}
42811
42812/**
42813 * @param {import("../render/canvas/BuilderGroup.js").default} builderGroup Replay group.
42814 * @param {import("../geom/MultiPoint.js").default|import("../render/Feature.js").default} geometry Geometry.
42815 * @param {import("../style/Style.js").default} style Style.
42816 * @param {import("../Feature.js").FeatureLike} feature Feature.
42817 * @param {import("../render/canvas/BuilderGroup.js").default} [declutterBuilderGroup] Builder for decluttering.
42818 */
42819function renderMultiPointGeometry(
42820  builderGroup,
42821  geometry,
42822  style,
42823  feature,
42824  declutterBuilderGroup
42825) {
42826  const imageStyle = style.getImage();
42827  const textStyle = style.getText();
42828  /** @type {import("../render/canvas.js").DeclutterImageWithText} */
42829  let declutterImageWithText;
42830  if (imageStyle) {
42831    if (imageStyle.getImageState() != ol_ImageState.LOADED) {
42832      return;
42833    }
42834    let imageBuilderGroup = builderGroup;
42835    if (declutterBuilderGroup) {
42836      const declutterMode = imageStyle.getDeclutterMode();
42837      if (declutterMode !== 'none') {
42838        imageBuilderGroup = declutterBuilderGroup;
42839        if (declutterMode === 'obstacle') {
42840          // draw in non-declutter group:
42841          const imageReplay = builderGroup.getBuilder(
42842            style.getZIndex(),
42843            'Image'
42844          );
42845          imageReplay.setImageStyle(imageStyle, declutterImageWithText);
42846          imageReplay.drawMultiPoint(geometry, feature);
42847        } else if (textStyle && textStyle.getText()) {
42848          declutterImageWithText = {};
42849        }
42850      }
42851    }
42852    const imageReplay = imageBuilderGroup.getBuilder(
42853      style.getZIndex(),
42854      'Image'
42855    );
42856    imageReplay.setImageStyle(imageStyle, declutterImageWithText);
42857    imageReplay.drawMultiPoint(geometry, feature);
42858  }
42859  if (textStyle && textStyle.getText()) {
42860    let textBuilderGroup = builderGroup;
42861    if (declutterBuilderGroup) {
42862      textBuilderGroup = declutterBuilderGroup;
42863    }
42864    const textReplay = textBuilderGroup.getBuilder(style.getZIndex(), 'Text');
42865    textReplay.setTextStyle(textStyle, declutterImageWithText);
42866    textReplay.drawText(geometry, feature);
42867  }
42868}
42869
42870/**
42871 * @param {import("../render/canvas/BuilderGroup.js").default} builderGroup Replay group.
42872 * @param {import("../geom/Polygon.js").default|import("../render/Feature.js").default} geometry Geometry.
42873 * @param {import("../style/Style.js").default} style Style.
42874 * @param {import("../Feature.js").FeatureLike} feature Feature.
42875 * @param {import("../render/canvas/BuilderGroup.js").default} [declutterBuilderGroup] Builder for decluttering.
42876 */
42877function renderPolygonGeometry(
42878  builderGroup,
42879  geometry,
42880  style,
42881  feature,
42882  declutterBuilderGroup
42883) {
42884  const fillStyle = style.getFill();
42885  const strokeStyle = style.getStroke();
42886  if (fillStyle || strokeStyle) {
42887    const polygonReplay = builderGroup.getBuilder(style.getZIndex(), 'Polygon');
42888    polygonReplay.setFillStrokeStyle(fillStyle, strokeStyle);
42889    polygonReplay.drawPolygon(geometry, feature);
42890  }
42891  const textStyle = style.getText();
42892  if (textStyle && textStyle.getText()) {
42893    const textReplay = (declutterBuilderGroup || builderGroup).getBuilder(
42894      style.getZIndex(),
42895      'Text'
42896    );
42897    textReplay.setTextStyle(textStyle);
42898    textReplay.drawText(geometry, feature);
42899  }
42900}
42901
42902;// CONCATENATED MODULE: ./node_modules/ol/renderer/canvas/VectorLayer.js
42903/**
42904 * @module ol/renderer/canvas/VectorLayer
42905 */
42906
42907
42908
42909
42910
42911
42912
42913
42914
42915
42916
42917
42918
42919
42920/**
42921 * @classdesc
42922 * Canvas renderer for vector layers.
42923 * @api
42924 */
42925class CanvasVectorLayerRenderer extends canvas_Layer {
42926  /**
42927   * @param {import("../../layer/BaseVector.js").default} vectorLayer Vector layer.
42928   */
42929  constructor(vectorLayer) {
42930    super(vectorLayer);
42931
42932    /** @private */
42933    this.boundHandleStyleImageChange_ = this.handleStyleImageChange_.bind(this);
42934
42935    /**
42936     * @type {boolean}
42937     */
42938    this.animatingOrInteracting_;
42939
42940    /**
42941     * @type {ImageData}
42942     */
42943    this.hitDetectionImageData_ = null;
42944
42945    /**
42946     * @type {Array<import("../../Feature.js").default>}
42947     */
42948    this.renderedFeatures_ = null;
42949
42950    /**
42951     * @private
42952     * @type {number}
42953     */
42954    this.renderedRevision_ = -1;
42955
42956    /**
42957     * @private
42958     * @type {number}
42959     */
42960    this.renderedResolution_ = NaN;
42961
42962    /**
42963     * @private
42964     * @type {import("../../extent.js").Extent}
42965     */
42966    this.renderedExtent_ = createEmpty();
42967
42968    /**
42969     * @private
42970     * @type {import("../../extent.js").Extent}
42971     */
42972    this.wrappedRenderedExtent_ = createEmpty();
42973
42974    /**
42975     * @private
42976     * @type {number}
42977     */
42978    this.renderedRotation_;
42979
42980    /**
42981     * @private
42982     * @type {import("../../coordinate").Coordinate}
42983     */
42984    this.renderedCenter_ = null;
42985
42986    /**
42987     * @private
42988     * @type {import("../../proj/Projection").default}
42989     */
42990    this.renderedProjection_ = null;
42991
42992    /**
42993     * @private
42994     * @type {function(import("../../Feature.js").default, import("../../Feature.js").default): number|null}
42995     */
42996    this.renderedRenderOrder_ = null;
42997
42998    /**
42999     * @private
43000     * @type {import("../../render/canvas/ExecutorGroup").default}
43001     */
43002    this.replayGroup_ = null;
43003
43004    /**
43005     * A new replay group had to be created by `prepareFrame()`
43006     * @type {boolean}
43007     */
43008    this.replayGroupChanged = true;
43009
43010    /**
43011     * @type {import("../../render/canvas/ExecutorGroup").default}
43012     */
43013    this.declutterExecutorGroup = null;
43014
43015    /**
43016     * Clipping to be performed by `renderFrame()`
43017     * @type {boolean}
43018     */
43019    this.clipping = true;
43020
43021    /**
43022     * @private
43023     * @type {CanvasRenderingContext2D}
43024     */
43025    this.compositionContext_ = null;
43026
43027    /**
43028     * @private
43029     * @type {number}
43030     */
43031    this.opacity_ = 1;
43032  }
43033
43034  /**
43035   * @param {ExecutorGroup} executorGroup Executor group.
43036   * @param {import("../../Map.js").FrameState} frameState Frame state.
43037   * @param {import("rbush").default} [declutterTree] Declutter tree.
43038   */
43039  renderWorlds(executorGroup, frameState, declutterTree) {
43040    const extent = frameState.extent;
43041    const viewState = frameState.viewState;
43042    const center = viewState.center;
43043    const resolution = viewState.resolution;
43044    const projection = viewState.projection;
43045    const rotation = viewState.rotation;
43046    const projectionExtent = projection.getExtent();
43047    const vectorSource = this.getLayer().getSource();
43048    const pixelRatio = frameState.pixelRatio;
43049    const viewHints = frameState.viewHints;
43050    const snapToPixel = !(
43051      viewHints[ViewHint.ANIMATING] || viewHints[ViewHint.INTERACTING]
43052    );
43053    const context = this.compositionContext_;
43054    const width = Math.round(frameState.size[0] * pixelRatio);
43055    const height = Math.round(frameState.size[1] * pixelRatio);
43056
43057    const multiWorld = vectorSource.getWrapX() && projection.canWrapX();
43058    const worldWidth = multiWorld ? extent_getWidth(projectionExtent) : null;
43059    const endWorld = multiWorld
43060      ? Math.ceil((extent[2] - projectionExtent[2]) / worldWidth) + 1
43061      : 1;
43062    let world = multiWorld
43063      ? Math.floor((extent[0] - projectionExtent[0]) / worldWidth)
43064      : 0;
43065    do {
43066      const transform = this.getRenderTransform(
43067        center,
43068        resolution,
43069        rotation,
43070        pixelRatio,
43071        width,
43072        height,
43073        world * worldWidth
43074      );
43075      executorGroup.execute(
43076        context,
43077        1,
43078        transform,
43079        rotation,
43080        snapToPixel,
43081        undefined,
43082        declutterTree
43083      );
43084    } while (++world < endWorld);
43085  }
43086
43087  setupCompositionContext_() {
43088    if (this.opacity_ !== 1) {
43089      const compositionContext = createCanvasContext2D(
43090        this.context.canvas.width,
43091        this.context.canvas.height,
43092        canvasPool
43093      );
43094      this.compositionContext_ = compositionContext;
43095    } else {
43096      this.compositionContext_ = this.context;
43097    }
43098  }
43099
43100  releaseCompositionContext_() {
43101    if (this.opacity_ !== 1) {
43102      const alpha = this.context.globalAlpha;
43103      this.context.globalAlpha = this.opacity_;
43104      this.context.drawImage(this.compositionContext_.canvas, 0, 0);
43105      this.context.globalAlpha = alpha;
43106      releaseCanvas(this.compositionContext_);
43107      canvasPool.push(this.compositionContext_.canvas);
43108      this.compositionContext_ = null;
43109    }
43110  }
43111
43112  /**
43113   * Render declutter items for this layer
43114   * @param {import("../../Map.js").FrameState} frameState Frame state.
43115   */
43116  renderDeclutter(frameState) {
43117    if (this.declutterExecutorGroup) {
43118      this.setupCompositionContext_();
43119      this.renderWorlds(
43120        this.declutterExecutorGroup,
43121        frameState,
43122        frameState.declutterTree
43123      );
43124      this.releaseCompositionContext_();
43125    }
43126  }
43127
43128  /**
43129   * Render the layer.
43130   * @param {import("../../Map.js").FrameState} frameState Frame state.
43131   * @param {HTMLElement} target Target that may be used to render content to.
43132   * @return {HTMLElement} The rendered element.
43133   */
43134  renderFrame(frameState, target) {
43135    const pixelRatio = frameState.pixelRatio;
43136    const layerState = frameState.layerStatesArray[frameState.layerIndex];
43137
43138    // set forward and inverse pixel transforms
43139    makeScale(this.pixelTransform, 1 / pixelRatio, 1 / pixelRatio);
43140    makeInverse(this.inversePixelTransform, this.pixelTransform);
43141
43142    const canvasTransform = transform_toString(this.pixelTransform);
43143
43144    this.useContainer(target, canvasTransform, this.getBackground(frameState));
43145    const context = this.context;
43146    const canvas = context.canvas;
43147
43148    const replayGroup = this.replayGroup_;
43149    const declutterExecutorGroup = this.declutterExecutorGroup;
43150    if (
43151      (!replayGroup || replayGroup.isEmpty()) &&
43152      (!declutterExecutorGroup || declutterExecutorGroup.isEmpty())
43153    ) {
43154      return null;
43155    }
43156
43157    // resize and clear
43158    const width = Math.round(frameState.size[0] * pixelRatio);
43159    const height = Math.round(frameState.size[1] * pixelRatio);
43160    if (canvas.width != width || canvas.height != height) {
43161      canvas.width = width;
43162      canvas.height = height;
43163      if (canvas.style.transform !== canvasTransform) {
43164        canvas.style.transform = canvasTransform;
43165      }
43166    } else if (!this.containerReused) {
43167      context.clearRect(0, 0, width, height);
43168    }
43169
43170    this.preRender(context, frameState);
43171
43172    const viewState = frameState.viewState;
43173    const projection = viewState.projection;
43174
43175    this.opacity_ = layerState.opacity;
43176    this.setupCompositionContext_();
43177
43178    // clipped rendering if layer extent is set
43179    let clipped = false;
43180    let render = true;
43181    if (layerState.extent && this.clipping) {
43182      const layerExtent = proj_fromUserExtent(layerState.extent, projection);
43183      render = intersects(layerExtent, frameState.extent);
43184      clipped = render && !containsExtent(layerExtent, frameState.extent);
43185      if (clipped) {
43186        this.clipUnrotated(this.compositionContext_, frameState, layerExtent);
43187      }
43188    }
43189
43190    if (render) {
43191      this.renderWorlds(replayGroup, frameState);
43192    }
43193
43194    if (clipped) {
43195      this.compositionContext_.restore();
43196    }
43197
43198    this.releaseCompositionContext_();
43199
43200    this.postRender(context, frameState);
43201
43202    if (this.renderedRotation_ !== viewState.rotation) {
43203      this.renderedRotation_ = viewState.rotation;
43204      this.hitDetectionImageData_ = null;
43205    }
43206    return this.container;
43207  }
43208
43209  /**
43210   * Asynchronous layer level hit detection.
43211   * @param {import("../../pixel.js").Pixel} pixel Pixel.
43212   * @return {Promise<Array<import("../../Feature").default>>} Promise that resolves with an array of features.
43213   */
43214  getFeatures(pixel) {
43215    return new Promise(
43216      /**
43217       * @param {function(Array<import("../../Feature").default|import("../../render/Feature").default>): void} resolve Resolver function.
43218       * @this {CanvasVectorLayerRenderer}
43219       */
43220      function (resolve) {
43221        if (!this.hitDetectionImageData_ && !this.animatingOrInteracting_) {
43222          const size = [this.context.canvas.width, this.context.canvas.height];
43223          apply(this.pixelTransform, size);
43224          const center = this.renderedCenter_;
43225          const resolution = this.renderedResolution_;
43226          const rotation = this.renderedRotation_;
43227          const projection = this.renderedProjection_;
43228          const extent = this.wrappedRenderedExtent_;
43229          const layer = this.getLayer();
43230          const transforms = [];
43231          const width = size[0] * HIT_DETECT_RESOLUTION;
43232          const height = size[1] * HIT_DETECT_RESOLUTION;
43233          transforms.push(
43234            this.getRenderTransform(
43235              center,
43236              resolution,
43237              rotation,
43238              HIT_DETECT_RESOLUTION,
43239              width,
43240              height,
43241              0
43242            ).slice()
43243          );
43244          const source = layer.getSource();
43245          const projectionExtent = projection.getExtent();
43246          if (
43247            source.getWrapX() &&
43248            projection.canWrapX() &&
43249            !containsExtent(projectionExtent, extent)
43250          ) {
43251            let startX = extent[0];
43252            const worldWidth = extent_getWidth(projectionExtent);
43253            let world = 0;
43254            let offsetX;
43255            while (startX < projectionExtent[0]) {
43256              --world;
43257              offsetX = worldWidth * world;
43258              transforms.push(
43259                this.getRenderTransform(
43260                  center,
43261                  resolution,
43262                  rotation,
43263                  HIT_DETECT_RESOLUTION,
43264                  width,
43265                  height,
43266                  offsetX
43267                ).slice()
43268              );
43269              startX += worldWidth;
43270            }
43271            world = 0;
43272            startX = extent[2];
43273            while (startX > projectionExtent[2]) {
43274              ++world;
43275              offsetX = worldWidth * world;
43276              transforms.push(
43277                this.getRenderTransform(
43278                  center,
43279                  resolution,
43280                  rotation,
43281                  HIT_DETECT_RESOLUTION,
43282                  width,
43283                  height,
43284                  offsetX
43285                ).slice()
43286              );
43287              startX -= worldWidth;
43288            }
43289          }
43290
43291          this.hitDetectionImageData_ = createHitDetectionImageData(
43292            size,
43293            transforms,
43294            this.renderedFeatures_,
43295            layer.getStyleFunction(),
43296            extent,
43297            resolution,
43298            rotation
43299          );
43300        }
43301        resolve(
43302          hitDetect(pixel, this.renderedFeatures_, this.hitDetectionImageData_)
43303        );
43304      }.bind(this)
43305    );
43306  }
43307
43308  /**
43309   * @param {import("../../coordinate.js").Coordinate} coordinate Coordinate.
43310   * @param {import("../../Map.js").FrameState} frameState Frame state.
43311   * @param {number} hitTolerance Hit tolerance in pixels.
43312   * @param {import("../vector.js").FeatureCallback<T>}
43312 callback Feature callback.
43313   * @param {Array<import("../Map.js").HitMatch<T>>} matches The hit detected matches with tolerance.
43314   * @return {T|undefined} Callback result.
43315   * @template T
43316   */
43317  forEachFeatureAtCoordinate(
43318    coordinate,
43319    frameState,
43320    hitTolerance,
43321    callback,
43322    matches
43323  ) {
43324    if (!this.replayGroup_) {
43325      return undefined;
43326    }
43327    const resolution = frameState.viewState.resolution;
43328    const rotation = frameState.viewState.rotation;
43329    const layer = this.getLayer();
43330
43331    /** @type {!Object<string, import("../Map.js").HitMatch<T>|true>} */
43332    const features = {};
43333
43334    /**
43335     * @param {import("../../Feature.js").FeatureLike} feature Feature.
43336     * @param {import("../../geom/SimpleGeometry.js").default} geometry Geometry.
43337     * @param {number} distanceSq The squared distance to the click position
43338     * @return {T|undefined} Callback result.
43339     */
43340    const featureCallback = function (feature, geometry, distanceSq) {
43341      const key = getUid(feature);
43342      const match = features[key];
43343      if (!match) {
43344        if (distanceSq === 0) {
43345          features[key] = true;
43346          return callback(feature, layer, geometry);
43347        }
43348        matches.push(
43349          (features[key] = {
43350            feature: feature,
43351            layer: layer,
43352            geometry: geometry,
43353            distanceSq: distanceSq,
43354            callback: callback,
43355          })
43356        );
43357      } else if (match !== true && distanceSq < match.distanceSq) {
43358        if (distanceSq === 0) {
43359          features[key] = true;
43360          matches.splice(matches.lastIndexOf(match), 1);
43361          return callback(feature, layer, geometry);
43362        }
43363        match.geometry = geometry;
43364        match.distanceSq = distanceSq;
43365      }
43366      return undefined;
43367    };
43368
43369    let result;
43370    const executorGroups = [this.replayGroup_];
43371    if (this.declutterExecutorGroup) {
43372      executorGroups.push(this.declutterExecutorGroup);
43373    }
43374    executorGroups.some((executorGroup) => {
43375      return (result = executorGroup.forEachFeatureAtCoordinate(
43376        coordinate,
43377        resolution,
43378        rotation,
43379        hitTolerance,
43380        featureCallback,
43381        executorGroup === this.declutterExecutorGroup &&
43382          frameState.declutterTree
43383          ? frameState.declutterTree.all().map((item) => item.value)
43384          : null
43385      ));
43386    });
43387
43388    return result;
43389  }
43390
43391  /**
43392   * Perform action necessary to get the layer rendered after new fonts have loaded
43393   */
43394  handleFontsChanged() {
43395    const layer = this.getLayer();
43396    if (layer.getVisible() && this.replayGroup_) {
43397      layer.changed();
43398    }
43399  }
43400
43401  /**
43402   * Handle changes in image style state.
43403   * @param {import("../../events/Event.js").default} event Image style change event.
43404   * @private
43405   */
43406  handleStyleImageChange_(event) {
43407    this.renderIfReadyAndVisible();
43408  }
43409
43410  /**
43411   * Determine whether render should be called.
43412   * @param {import("../../Map.js").FrameState} frameState Frame state.
43413   * @return {boolean} Layer is ready to be rendered.
43414   */
43415  prepareFrame(frameState) {
43416    const vectorLayer = this.getLayer();
43417    const vectorSource = vectorLayer.getSource();
43418    if (!vectorSource) {
43419      return false;
43420    }
43421
43422    const animating = frameState.viewHints[ViewHint.ANIMATING];
43423    const interacting = frameState.viewHints[ViewHint.INTERACTING];
43424    const updateWhileAnimating = vectorLayer.getUpdateWhileAnimating();
43425    const updateWhileInteracting = vectorLayer.getUpdateWhileInteracting();
43426
43427    if (
43428      (this.ready && !updateWhileAnimating && animating) ||
43429      (!updateWhileInteracting && interacting)
43430    ) {
43431      this.animatingOrInteracting_ = true;
43432      return true;
43433    }
43434    this.animatingOrInteracting_ = false;
43435
43436    const frameStateExtent = frameState.extent;
43437    const viewState = frameState.viewState;
43438    const projection = viewState.projection;
43439    const resolution = viewState.resolution;
43440    const pixelRatio = frameState.pixelRatio;
43441    const vectorLayerRevision = vectorLayer.getRevision();
43442    const vectorLayerRenderBuffer = vectorLayer.getRenderBuffer();
43443    let vectorLayerRenderOrder = vectorLayer.getRenderOrder();
43444
43445    if (vectorLayerRenderOrder === undefined) {
43446      vectorLayerRenderOrder = defaultOrder;
43447    }
43448
43449    const center = viewState.center.slice();
43450    const extent = buffer(
43451      frameStateExtent,
43452      vectorLayerRenderBuffer * resolution
43453    );
43454    const renderedExtent = extent.slice();
43455    const loadExtents = [extent.slice()];
43456    const projectionExtent = projection.getExtent();
43457
43458    if (
43459      vectorSource.getWrapX() &&
43460      projection.canWrapX() &&
43461      !containsExtent(projectionExtent, frameState.extent)
43462    ) {
43463      // For the replay group, we need an extent that intersects the real world
43464      // (-180° to +180°). To support geometries in a coordinate range from -540°
43465      // to +540°, we add at least 1 world width on each side of the projection
43466      // extent. If the viewport is wider than the world, we need to add half of
43467      // the viewport width to make sure we cover the whole viewport.
43468      const worldWidth = extent_getWidth(projectionExtent);
43469      const gutter = Math.max(extent_getWidth(extent) / 2, worldWidth);
43470      extent[0] = projectionExtent[0] - gutter;
43471      extent[2] = projectionExtent[2] + gutter;
43472      coordinate_wrapX(center, projection);
43473      const loadExtent = wrapX(loadExtents[0], projection);
43474      // If the extent crosses the date line, we load data for both edges of the worlds
43475      if (
43476        loadExtent[0] < projectionExtent[0] &&
43477        loadExtent[2] < projectionExtent[2]
43478      ) {
43479        loadExtents.push([
43480          loadExtent[0] + worldWidth,
43481          loadExtent[1],
43482          loadExtent[2] + worldWidth,
43483          loadExtent[3],
43484        ]);
43485      } else if (
43486        loadExtent[0] > projectionExtent[0] &&
43487        loadExtent[2] > projectionExtent[2]
43488      ) {
43489        loadExtents.push([
43490          loadExtent[0] - worldWidth,
43491          loadExtent[1],
43492          loadExtent[2] - worldWidth,
43493          loadExtent[3],
43494        ]);
43495      }
43496    }
43497
43498    if (
43499      this.ready &&
43500      this.renderedResolution_ == resolution &&
43501      this.renderedRevision_ == vectorLayerRevision &&
43502      this.renderedRenderOrder_ == vectorLayerRenderOrder &&
43503      containsExtent(this.wrappedRenderedExtent_, extent)
43504    ) {
43505      if (!equals(this.renderedExtent_, renderedExtent)) {
43506        this.hitDetectionImageData_ = null;
43507        this.renderedExtent_ = renderedExtent;
43508      }
43509      this.renderedCenter_ = center;
43510      this.replayGroupChanged = false;
43511      return true;
43512    }
43513
43514    this.replayGroup_ = null;
43515
43516    const replayGroup = new canvas_BuilderGroup(
43517      getTolerance(resolution, pixelRatio),
43518      extent,
43519      resolution,
43520      pixelRatio
43521    );
43522
43523    let declutterBuilderGroup;
43524    if (this.getLayer().getDeclutter()) {
43525      declutterBuilderGroup = new canvas_BuilderGroup(
43526        getTolerance(resolution, pixelRatio),
43527        extent,
43528        resolution,
43529        pixelRatio
43530      );
43531    }
43532
43533    const userProjection = getUserProjection();
43534    let userTransform;
43535    if (userProjection) {
43536      for (let i = 0, ii = loadExtents.length; i < ii; ++i) {
43537        const extent = loadExtents[i];
43538        const userExtent = proj_toUserExtent(extent, projection);
43539        vectorSource.loadFeatures(
43540          userExtent,
43541          toUserResolution(resolution, projection),
43542          userProjection
43543        );
43544      }
43545      userTransform = getTransformFromProjections(userProjection, projection);
43546    } else {
43547      for (let i = 0, ii = loadExtents.length; i < ii; ++i) {
43548        vectorSource.loadFeatures(loadExtents[i], resolution, projection);
43549      }
43550    }
43551
43552    const squaredTolerance = getSquaredTolerance(resolution, pixelRatio);
43553    let ready = true;
43554    const render =
43555      /**
43556       * @param {import("../../Feature.js").default} feature Feature.
43557       * @this {CanvasVectorLayerRenderer}
43558       */
43559      function (feature) {
43560        let styles;
43561        const styleFunction =
43562          feature.getStyleFunction() || vectorLayer.getStyleFunction();
43563        if (styleFunction) {
43564          styles = styleFunction(feature, resolution);
43565        }
43566        if (styles) {
43567          const dirty = this.renderFeature(
43568            feature,
43569            squaredTolerance,
43570            styles,
43571            replayGroup,
43572            userTransform,
43573            declutterBuilderGroup
43574          );
43575          ready = ready && !dirty;
43576        }
43577      }.bind(this);
43578
43579    const userExtent = proj_toUserExtent(extent, projection);
43580    /** @type {Array<import("../../Feature.js").default>} */
43581    const features = vectorSource.getFeaturesInExtent(userExtent);
43582    if (vectorLayerRenderOrder) {
43583      features.sort(vectorLayerRenderOrder);
43584    }
43585    for (let i = 0, ii = features.length; i < ii; ++i) {
43586      render(features[i]);
43587    }
43588    this.renderedFeatures_ = features;
43589    this.ready = ready;
43590
43591    const replayGroupInstructions = replayGroup.finish();
43592    const executorGroup = new canvas_ExecutorGroup(
43593      extent,
43594      resolution,
43595      pixelRatio,
43596      vectorSource.getOverlaps(),
43597      replayGroupInstructions,
43598      vectorLayer.getRenderBuffer()
43599    );
43600
43601    if (declutterBuilderGroup) {
43602      this.declutterExecutorGroup = new canvas_ExecutorGroup(
43603        extent,
43604        resolution,
43605        pixelRatio,
43606        vectorSource.getOverlaps(),
43607        declutterBuilderGroup.finish(),
43608        vectorLayer.getRenderBuffer()
43609      );
43610    }
43611
43612    this.renderedResolution_ = resolution;
43613    this.renderedRevision_ = vectorLayerRevision;
43614    this.renderedRenderOrder_ = vectorLayerRenderOrder;
43615    this.renderedExtent_ = renderedExtent;
43616    this.wrappedRenderedExtent_ = extent;
43617    this.renderedCenter_ = center;
43618    this.renderedProjection_ = projection;
43619    this.replayGroup_ = executorGroup;
43620    this.hitDetectionImageData_ = null;
43621
43622    this.replayGroupChanged = true;
43623    return true;
43624  }
43625
43626  /**
43627   * @param {import("../../Feature.js").default} feature Feature.
43628   * @param {number} squaredTolerance Squared render tolerance.
43629   * @param {import("../../style/Style.js").default|Array<import("../../style/Style.js").default>} styles The style or array of styles.
43630   * @param {import("../../render/canvas/BuilderGroup.js").default} builderGroup Builder group.
43631   * @param {import("../../proj.js").TransformFunction} [transform] Transform from user to view projection.
43632   * @param {import("../../render/canvas/BuilderGroup.js").default} [declutterBuilderGroup] Builder for decluttering.
43633   * @return {boolean} `true` if an image is loading.
43634   */
43635  renderFeature(
43636    feature,
43637    squaredTolerance,
43638    styles,
43639    builderGroup,
43640    transform,
43641    declutterBuilderGroup
43642  ) {
43643    if (!styles) {
43644      return false;
43645    }
43646    let loading = false;
43647    if (Array.isArray(styles)) {
43648      for (let i = 0, ii = styles.length; i < ii; ++i) {
43649        loading =
43650          renderFeature(
43651            builderGroup,
43652            feature,
43653            styles[i],
43654            squaredTolerance,
43655            this.boundHandleStyleImageChange_,
43656            transform,
43657            declutterBuilderGroup
43658          ) || loading;
43659      }
43660    } else {
43661      loading = renderFeature(
43662        builderGroup,
43663        feature,
43664        styles,
43665        squaredTolerance,
43666        this.boundHandleStyleImageChange_,
43667        transform,
43668        declutterBuilderGroup
43669      );
43670    }
43671    return loading;
43672  }
43673}
43674
43675/* harmony default export */ const canvas_VectorLayer = (CanvasVectorLayerRenderer);
43676
43677;// CONCATENATED MODULE: ./node_modules/ol/layer/Vector.js
43678/**
43679 * @module ol/layer/Vector
43680 */
43681
43682
43683
43684/**
43685 * @classdesc
43686 * Vector data is rendered client-side, as vectors. This layer type provides most accurate rendering
43687 * even during animations. Points and labels stay upright on rotated views. For very large
43688 * amounts of vector data, performance may suffer during pan and zoom animations. In this case,
43689 * try {@link module:ol/layer/VectorImage~VectorImageLayer}.
43690 *
43691 * Note that any property set in the options is set as a {@link module:ol/Object~BaseObject}
43692 * property on the layer object; for example, setting `title: 'My Title'` in the
43693 * options means that `title` is observable, and has get/set accessors.
43694 *
43695 * @template {import("../source/Vector.js").default} VectorSourceType
43696 * @extends {BaseVectorLayer<VectorSourceType, CanvasVectorLayerRenderer>}
43697 * @api
43698 */
43699class VectorLayer extends BaseVector {
43700  /**
43701   * @param {import("./BaseVector.js").Options<VectorSourceType>} [options] Options.
43702   */
43703  constructor(options) {
43704    super(options);
43705  }
43706
43707  createRenderer() {
43708    return new canvas_VectorLayer(this);
43709  }
43710}
43711
43712/* harmony default export */ const Vector = (VectorLayer);
43713
43714;// CONCATENATED MODULE: ./node_modules/ol/layer/TileProperty.js
43715/**
43716 * @module ol/layer/TileProperty
43717 */
43718
43719/**
43720 * @enum {string}
43721 */
43722/* harmony default export */ const TileProperty = ({
43723  PRELOAD: 'preload',
43724  USE_INTERIM_TILES_ON_ERROR: 'useInterimTilesOnError',
43725});
43726
43727;// CONCATENATED MODULE: ./node_modules/ol/layer/BaseTile.js
43728/**
43729 * @module ol/layer/BaseTile
43730 */
43731
43732
43733
43734/***
43735 * @template Return
43736 * @typedef {import("../Observable").OnSignature<import("../Observable").EventTypes, import("../events/Event.js").default, Return> &
43737 *   import("../Observable").OnSignature<import("./Base").BaseLayerObjectEventTypes|
43738 *     'change:source'|'change:preload'|'change:useInterimTilesOnError', import("../Object").ObjectEvent, Return> &
43739 *   import("../Observable").OnSignature<import("../render/EventType").LayerRenderEventTypes, import("../render/Event").default, Return> &
43740 *   import("../Observable").CombinedOnSignature<import("../Observable").EventTypes|import("./Base").BaseLayerObjectEventTypes|
43741 *   'change:source'|'change:preload'|'change:useInterimTilesOnError'|import("../render/EventType").LayerRenderEventTypes, Return>} BaseTileLayerOnSignature
43742 */
43743
43744/**
43745 * @template {import("../source/Tile.js").default} TileSourceType
43746 * @typedef {Object} Options
43747 * @property {string} [className='ol-layer'] A CSS class name to set to the layer element.
43748 * @property {number} [opacity=1] Opacity (0, 1).
43749 * @property {boolean} [visible=true] Visibility.
43750 * @property {import("../extent.js").Extent} [extent] The bounding extent for layer rendering.  The layer will not be
43751 * rendered outside of this extent.
43752 * @property {number} [zIndex] The z-index for layer rendering.  At rendering time, the layers
43753 * will be ordered, first by Z-index and then by position. When `undefined`, a `zIndex` of 0 is assumed
43754 * for layers that are added to the map's `layers` collection, or `Infinity` when the layer's `setMap()`
43755 * method was used.
43756 * @property {number} [minResolution] The minimum resolution (inclusive) at which this layer will be
43757 * visible.
43758 * @property {number} [maxResolution] The maximum resolution (exclusive) below which this layer will
43759 * be visible.
43760 * @property {number} [minZoom] The minimum view zoom level (exclusive) above which this layer will be
43761 * visible.
43762 * @property {number} [maxZoom] The maximum view zoom level (inclusive) at which this layer will
43763 * be visible.
43764 * @property {number} [preload=0] Preload. Load low-resolution tiles up to `preload` levels. `0`
43765 * means no preloading.
43766 * @property {TileSourceType} [source] Source for this layer.
43767 * @property {import("../Map.js").default} [map] Sets the layer as overlay on a map. The map will not manage
43768 * this layer in its layers collection, and the layer will be rendered on top. This is useful for
43769 * temporary layers. The standard way to add a layer to a map and have it managed by the map is to
43770 * use {@link import("../Map.js").default#addLayer map.addLayer()}.
43771 * @property {boolean} [useInterimTilesOnError=true] Use interim tiles on error.
43772 * @property {Object<string, *>} [properties] Arbitrary observable properties. Can be accessed with `#get()` and `#set()`.
43773 */
43774
43775/**
43776 * @classdesc
43777 * For layer sources that provide pre-rendered, tiled images in grids that are
43778 * organized by zoom levels for specific resolutions.
43779 * Note that any property set in the options is set as a {@link module:ol/Object~BaseObject}
43780 * property on the layer object; for example, setting `title: 'My Title'` in the
43781 * options means that `title` is observable, and has get/set accessors.
43782 *
43783 * @template {import("../source/Tile.js").default} TileSourceType
43784 * @template {import("../renderer/Layer.js").default} RendererType
43785 * @extends {Layer<TileSourceType, RendererType>}
43786 * @api
43787 */
43788class BaseTileLayer extends layer_Layer {
43789  /**
43790   * @param {Options<TileSourceType>} [options] Tile layer options.
43791   */
43792  constructor(options) {
43793    options = options ? options : {};
43794
43795    const baseOptions = Object.assign({}, options);
43796
43797    delete baseOptions.preload;
43798    delete baseOptions.useInterimTilesOnError;
43799    super(baseOptions);
43800
43801    /***
43802     * @type {BaseTileLayerOnSignature<import("../events").EventsKey>}
43803     */
43804    this.on;
43805
43806    /***
43807     * @type {BaseTileLayerOnSignature<import("../events").EventsKey>}
43808     */
43809    this.once;
43810
43811    /***
43812     * @type {BaseTileLayerOnSignature<void>}
43813     */
43814    this.un;
43815
43816    this.setPreload(options.preload !== undefined ? options.preload : 0);
43817    this.setUseInterimTilesOnError(
43818      options.useInterimTilesOnError !== undefined
43819        ? options.useInterimTilesOnError
43820        : true
43821    );
43822  }
43823
43824  /**
43825   * Return the level as number to which we will preload tiles up to.
43826   * @return {number} The level to preload tiles up to.
43827   * @observable
43828   * @api
43829   */
43830  getPreload() {
43831    return /** @type {number} */ (this.get(TileProperty.PRELOAD));
43832  }
43833
43834  /**
43835   * Set the level as number to which we will preload tiles up to.
43836   * @param {number} preload The level to preload tiles up to.
43837   * @observable
43838   * @api
43839   */
43840  setPreload(preload) {
43841    this.set(TileProperty.PRELOAD, preload);
43842  }
43843
43844  /**
43845   * Whether we use interim tiles on error.
43846   * @return {boolean} Use interim tiles on error.
43847   * @observable
43848   * @api
43849   */
43850  getUseInterimTilesOnError() {
43851    return /** @type {boolean} */ (
43852      this.get(TileProperty.USE_INTERIM_TILES_ON_ERROR)
43853    );
43854  }
43855
43856  /**
43857   * Set whether we use interim tiles on error.
43858   * @param {boolean} useInterimTilesOnError Use interim tiles on error.
43859   * @observable
43860   * @api
43861   */
43862  setUseInterimTilesOnError(useInterimTilesOnError) {
43863    this.set(TileProperty.USE_INTERIM_TILES_ON_ERROR, useInterimTilesOnError);
43864  }
43865
43866  /**
43867   * Get data for a pixel location.  The return type depends on the source data.  For image tiles,
43868   * a four element RGBA array will be returned.  For data tiles, the array length will match the
43869   * number of bands in the dataset.  For requests outside the layer extent, `null` will be returned.
43870   * Data for a image tiles can only be retrieved if the source's `crossOrigin` property is set.
43871   *
43872   * ```js
43873   * // display layer data on every pointer move
43874   * map.on('pointermove', (event) => {
43875   *   console.log(layer.getData(event.pixel));
43876   * });
43877   * ```
43878   * @param {import("../pixel").Pixel} pixel Pixel.
43879   * @return {Uint8ClampedArray|Uint8Array|Float32Array|DataView|null} Pixel data.
43880   * @api
43881   */
43882  getData(pixel) {
43883    return super.getData(pixel);
43884  }
43885}
43886
43887/* harmony default export */ const BaseTile = (BaseTileLayer);
43888
43889;// CONCATENATED MODULE: ./node_modules/ol/Tile.js
43890/**
43891 * @module ol/Tile
43892 */
43893
43894
43895
43896
43897
43898
43899/**
43900 * A function that takes an {@link module:ol/Tile~Tile} for the tile and a
43901 * `{string}` for the url as arguments. The default is
43902 * ```js
43903 * source.setTileLoadFunction(function(tile, src) {
43904 *   tile.getImage().src = src;
43905 * });
43906 * ```
43907 * For more fine grained control, the load function can use fetch or XMLHttpRequest and involve
43908 * error handling:
43909 *
43910 * ```js
43911 * import TileState from 'ol/TileState';
43912 *
43913 * source.setTileLoadFunction(function(tile, src) {
43914 *   const xhr = new XMLHttpRequest();
43915 *   xhr.responseType = 'blob';
43916 *   xhr.addEventListener('loadend', function (evt) {
43917 *     const data = this.response;
43918 *     if (data !== undefined) {
43919 *       tile.getImage().src = URL.createObjectURL(data);
43920 *     } else {
43921 *       tile.setState(TileState.ERROR);
43922 *     }
43923 *   });
43924 *   xhr.addEventListener('error', function () {
43925 *     tile.setState(TileState.ERROR);
43926 *   });
43927 *   xhr.open('GET', src);
43928 *   xhr.send();
43929 * });
43930 * ```
43931 *
43932 * @typedef {function(Tile, string): void} LoadFunction
43933 * @api
43934 */
43935
43936/**
43937 * {@link module:ol/source/Tile~TileSource} sources use a function of this type to get
43938 * the url that provides a tile for a given tile coordinate.
43939 *
43940 * This function takes an {@link module:ol/tilecoord~TileCoord} for the tile
43941 * coordinate, a `{number}` representing the pixel ratio and a
43942 * {@link module:ol/proj/Projection~Projection} for the projection  as arguments
43943 * and returns a `{string}` representing the tile URL, or undefined if no tile
43944 * should be requested for the passed tile coordinate.
43945 *
43946 * @typedef {function(import("./tilecoord.js").TileCoord, number,
43947 *           import("./proj/Projection.js").default): (string|undefined)} UrlFunction
43948 * @api
43949 */
43950
43951/**
43952 * @typedef {Object} Options
43953 * @property {number} [transition=250] A duration for tile opacity
43954 * transitions in milliseconds. A duration of 0 disables the opacity transition.
43955 * @property {boolean} [interpolate=false] Use interpolated values when resampling.  By default,
43956 * the nearest neighbor is used when resampling.
43957 * @api
43958 */
43959
43960/**
43961 * @classdesc
43962 * Base class for tiles.
43963 *
43964 * @abstract
43965 */
43966class Tile extends events_Target {
43967  /**
43968   * @param {import("./tilecoord.js").TileCoord} tileCoord Tile coordinate.
43969   * @param {import("./TileState.js").default} state State.
43970   * @param {Options} [options] Tile options.
43971   */
43972  constructor(tileCoord, state, options) {
43973    super();
43974
43975    options = options ? options : {};
43976
43977    /**
43978     * @type {import("./tilecoord.js").TileCoord}
43979     */
43980    this.tileCoord = tileCoord;
43981
43982    /**
43983     * @protected
43984     * @type {import("./TileState.js").default}
43985     */
43986    this.state = state;
43987
43988    /**
43989     * An "interim" tile for this tile. The interim tile may be used while this
43990     * one is loading, for "smooth" transitions when changing params/dimensions
43991     * on the source.
43992     * @type {Tile}
43993     */
43994    this.interimTile = null;
43995
43996    /**
43997     * A key assigned to the tile. This is used by the tile source to determine
43998     * if this tile can effectively be used, or if a new tile should be created
43999     * and this one be used as an interim tile for this new tile.
44000     * @type {string}
44001     */
44002    this.key = '';
44003
44004    /**
44005     * The duration for the opacity transition.
44006     * @type {number}
44007     */
44008    this.transition_ =
44009      options.transition === undefined ? 250 : options.transition;
44010
44011    /**
44012     * Lookup of start times for rendering transitions.  If the start time is
44013     * equal to -1, the transition is complete.
44014     * @type {Object<string, number>}
44015     */
44016    this.transitionStarts_ = {};
44017
44018    /**
44019     * @type {boolean}
44020     */
44021    this.interpolate = !!options.interpolate;
44022  }
44023
44024  /**
44025   * @protected
44026   */
44027  changed() {
44028    this.dispatchEvent(EventType.CHANGE);
44029  }
44030
44031  /**
44032   * Called by the tile cache when the tile is removed from the cache due to expiry
44033   */
44034  release() {
44035    if (this.state === TileState.ERROR) {
44036      // to remove the `change` listener on this tile in `ol/TileQueue#handleTileChange`
44037      this.setState(TileState.EMPTY);
44038    }
44039  }
44040
44041  /**
44042   * @return {string} Key.
44043   */
44044  getKey() {
44045    return this.key + '/' + this.tileCoord;
44046  }
44047
44048  /**
44049   * Get the interim tile most suitable for rendering using the chain of interim
44050   * tiles. This corresponds to the  most recent tile that has been loaded, if no
44051   * such tile exists, the original tile is returned.
44052   * @return {!Tile} Best tile for rendering.
44053   */
44054  getInterimTile() {
44055    if (!this.interimTile) {
44056      //empty chain
44057      return this;
44058    }
44059    let tile = this.interimTile;
44060
44061    // find the first loaded tile and return it. Since the chain is sorted in
44062    // decreasing order of creation time, there is no need to search the remainder
44063    // of the list (all those tiles correspond to older requests and will be
44064    // cleaned up by refreshInterimChain)
44065    do {
44066      if (tile.getState() == TileState.LOADED) {
44067        // Show tile immediately instead of fading it in after loading, because
44068        // the interim tile is in place already
44069        this.transition_ = 0;
44070        return tile;
44071      }
44072      tile = tile.interimTile;
44073    } while (tile);
44074
44075    // we can not find a better tile
44076    return this;
44077  }
44078
44079  /**
44080   * Goes through the chain of interim tiles and discards sections of the chain
44081   * that are no longer relevant.
44082   */
44083  refreshInterimChain() {
44084    if (!this.interimTile) {
44085      return;
44086    }
44087
44088    let tile = this.interimTile;
44089
44090    /**
44091     * @type {Tile}
44092     */
44093    let prev = this;
44094
44095    do {
44096      if (tile.getState() == TileState.LOADED) {
44097        //we have a loaded tile, we can discard the rest of the list
44098        //we would could abort any LOADING tile request
44099        //older than this tile (i.e. any LOADING tile following this entry in the chain)
44100        tile.interimTile = null;
44101        break;
44102      } else if (tile.getState() == TileState.LOADING) {
44103        //keep this LOADING tile any loaded tiles later in the chain are
44104        //older than this tile, so we're still interested in the request
44105        prev = tile;
44106      } else if (tile.getState() == TileState.IDLE) {
44107        //the head of the list is the most current tile, we don't need
44108        //to start any other requests for this chain
44109        prev.interimTile = tile.interimTile;
44110      } else {
44111        prev = tile;
44112      }
44113      tile = prev.interimTile;
44114    } while (tile);
44115  }
44116
44117  /**
44118   * Get the tile coordinate for this tile.
44119   * @return {import("./tilecoord.js").TileCoord} The tile coordinate.
44120   * @api
44121   */
44122  getTileCoord() {
44123    return this.tileCoord;
44124  }
44125
44126  /**
44127   * @return {import("./TileState.js").default} State.
44128   */
44129  getState() {
44130    return this.state;
44131  }
44132
44133  /**
44134   * Sets the state of this tile. If you write your own {@link module:ol/Tile~LoadFunction tileLoadFunction} ,
44135   * it is important to set the state correctly to {@link module:ol/TileState~ERROR}
44136   * when the tile cannot be loaded. Otherwise the tile cannot be removed from
44137   * the tile queue and will block other requests.
44138   * @param {import("./TileState.js").default} state State.
44139   * @api
44140   */
44141  setState(state) {
44142    if (this.state !== TileState.ERROR && this.state > state) {
44143      throw new Error('Tile load sequence violation');
44144    }
44145    this.state = state;
44146    this.changed();
44147  }
44148
44149  /**
44150   * Load the image or retry if loading previously failed.
44151   * Loading is taken care of by the tile queue, and calling this method is
44152   * only needed for preloading or for reloading in case of an error.
44153   * @abstract
44154   * @api
44155   */
44156  load() {
44157    util_abstract();
44158  }
44159
44160  /**
44161   * Get the alpha value for rendering.
44162   * @param {string} id An id for the renderer.
44163   * @param {number} time The render frame time.
44164   * @return {number} A number between 0 and 1.
44165   */
44166  getAlpha(id, time) {
44167    if (!this.transition_) {
44168      return 1;
44169    }
44170
44171    let start = this.transitionStarts_[id];
44172    if (!start) {
44173      start = time;
44174      this.transitionStarts_[id] = start;
44175    } else if (start === -1) {
44176      return 1;
44177    }
44178
44179    const delta = time - start + 1000 / 60; // avoid rendering at 0
44180    if (delta >= this.transition_) {
44181      return 1;
44182    }
44183    return easeIn(delta / this.transition_);
44184  }
44185
44186  /**
44187   * Determine if a tile is in an alpha transition.  A tile is considered in
44188   * transition if tile.getAlpha() has not yet been called or has been called
44189   * and returned 1.
44190   * @param {string} id An id for the renderer.
44191   * @return {boolean} The tile is in transition.
44192   */
44193  inTransition(id) {
44194    if (!this.transition_) {
44195      return false;
44196    }
44197    return this.transitionStarts_[id] !== -1;
44198  }
44199
44200  /**
44201   * Mark a transition as complete.
44202   * @param {string} id An id for the renderer.
44203   */
44204  endTransition(id) {
44205    if (this.transition_) {
44206      this.transitionStarts_[id] = -1;
44207    }
44208  }
44209}
44210
44211/* harmony default export */ const ol_Tile = (Tile);
44212
44213;// CONCATENATED MODULE: ./node_modules/ol/ImageTile.js
44214/**
44215 * @module ol/ImageTile
44216 */
44217
44218
44219
44220
44221
44222class ImageTile extends ol_Tile {
44223  /**
44224   * @param {import("./tilecoord.js").TileCoord} tileCoord Tile coordinate.
44225   * @param {import("./TileState.js").default} state State.
44226   * @param {string} src Image source URI.
44227   * @param {?string} crossOrigin Cross origin.
44228   * @param {import("./Tile.js").LoadFunction} tileLoadFunction Tile load function.
44229   * @param {import("./Tile.js").Options} [options] Tile options.
44230   */
44231  constructor(tileCoord, state, src, crossOrigin, tileLoadFunction, options) {
44232    super(tileCoord, state, options);
44233
44234    /**
44235     * @private
44236     * @type {?string}
44237     */
44238    this.crossOrigin_ = crossOrigin;
44239
44240    /**
44241     * Image URI
44242     *
44243     * @private
44244     * @type {string}
44245     */
44246    this.src_ = src;
44247
44248    this.key = src;
44249
44250    /**
44251     * @private
44252     * @type {HTMLImageElement|HTMLCanvasElement}
44253     */
44254    this.image_ = new Image();
44255    if (crossOrigin !== null) {
44256      this.image_.crossOrigin = crossOrigin;
44257    }
44258
44259    /**
44260     * @private
44261     * @type {?function():void}
44262     */
44263    this.unlisten_ = null;
44264
44265    /**
44266     * @private
44267     * @type {import("./Tile.js").LoadFunction}
44268     */
44269    this.tileLoadFunction_ = tileLoadFunction;
44270  }
44271
44272  /**
44273   * Get the HTML image element for this tile (may be a Canvas, Image, or Video).
44274   * @return {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} Image.
44275   * @api
44276   */
44277  getImage() {
44278    return this.image_;
44279  }
44280
44281  /**
44282   * Sets an HTML image element for this tile (may be a Canvas or preloaded Image).
44283   * @param {HTMLCanvasElement|HTMLImageElement} element Element.
44284   */
44285  setImage(element) {
44286    this.image_ = element;
44287    this.state = TileState.LOADED;
44288    this.unlistenImage_();
44289    this.changed();
44290  }
44291
44292  /**
44293   * Tracks loading or read errors.
44294   *
44295   * @private
44296   */
44297  handleImageError_() {
44298    this.state = TileState.ERROR;
44299    this.unlistenImage_();
44300    this.image_ = getBlankImage();
44301    this.changed();
44302  }
44303
44304  /**
44305   * Tracks successful image load.
44306   *
44307   * @private
44308   */
44309  handleImageLoad_() {
44310    const image = /** @type {HTMLImageElement} */ (this.image_);
44311    if (image.naturalWidth && image.naturalHeight) {
44312      this.state = TileState.LOADED;
44313    } else {
44314      this.state = TileState.EMPTY;
44315    }
44316    this.unlistenImage_();
44317    this.changed();
44318  }
44319
44320  /**
44321   * Load the image or retry if loading previously failed.
44322   * Loading is taken care of by the tile queue, and calling this method is
44323   * only needed for preloading or for reloading in case of an error.
44324   *
44325   * To retry loading tiles on failed requests, use a custom `tileLoadFunction`
44326   * that checks for error status codes and reloads only when the status code is
44327   * 408, 429, 500, 502, 503 and 504, and only when not too many retries have been
44328   * made already:
44329   *
44330   * ```js
44331   * const retryCodes = [408, 429, 500, 502, 503, 504];
44332   * const retries = {};
44333   * source.setTileLoadFunction((tile, src) => {
44334   *   const image = tile.getImage();
44335   *   fetch(src)
44336   *     .then((response) => {
44337   *       if (retryCodes.includes(response.status)) {
44338   *         retries[src] = (retries[src] || 0) + 1;
44339   *         if (retries[src] <= 3) {
44340   *           setTimeout(() => tile.load(), retries[src] * 1000);
44341   *         }
44342   *         return Promise.reject();
44343   *       }
44344   *       return response.blob();
44345   *     })
44346   *     .then((blob) => {
44347   *       const imageUrl = URL.createObjectURL(blob);
44348   *       image.src = imageUrl;
44349   *       setTimeout(() => URL.revokeObjectURL(imageUrl), 5000);
44350   *     })
44351   *     .catch(() => tile.setState(3)); // error
44352   * });
44353   * ```
44354   *
44355   * @api
44356   */
44357  load() {
44358    if (this.state == TileState.ERROR) {
44359      this.state = TileState.IDLE;
44360      this.image_ = new Image();
44361      if (this.crossOrigin_ !== null) {
44362        this.image_.crossOrigin = this.crossOrigin_;
44363      }
44364    }
44365    if (this.state == TileState.IDLE) {
44366      this.state = TileState.LOADING;
44367      this.changed();
44368      this.tileLoadFunction_(this, this.src_);
44369      this.unlisten_ = listenImage(
44370        this.image_,
44371        this.handleImageLoad_.bind(this),
44372        this.handleImageError_.bind(this)
44373      );
44374    }
44375  }
44376
44377  /**
44378   * Discards event handlers which listen for load completion or errors.
44379   *
44380   * @private
44381   */
44382  unlistenImage_() {
44383    if (this.unlisten_) {
44384      this.unlisten_();
44385      this.unlisten_ = null;
44386    }
44387  }
44388}
44389
44390/**
44391 * Get a 1-pixel blank image.
44392 * @return {HTMLCanvasElement} Blank image.
44393 */
44394function getBlankImage() {
44395  const ctx = createCanvasContext2D(1, 1);
44396  ctx.fillStyle = 'rgba(0,0,0,0)';
44397  ctx.fillRect(0, 0, 1, 1);
44398  return ctx.canvas;
44399}
44400
44401/* harmony default export */ const ol_ImageTile = (ImageTile);
44402
44403;// CONCATENATED MODULE: ./node_modules/ol/reproj/common.js
44404/**
44405 * @module ol/reproj/common
44406 */
44407
44408/**
44409 * Default maximum allowed threshold  (in pixels) for reprojection
44410 * triangulation.
44411 * @type {number}
44412 */
44413const ERROR_THRESHOLD = 0.5;
44414
44415;// CONCATENATED MODULE: ./node_modules/ol/reproj/Triangulation.js
44416/**
44417 * @module ol/reproj/Triangulation
44418 */
44419
44420
44421
44422
44423/**
44424 * Single triangle; consists of 3 source points and 3 target points.
44425 * @typedef {Object} Triangle
44426 * @property {Array<import("../coordinate.js").Coordinate>} source Source.
44427 * @property {Array<import("../coordinate.js").Coordinate>} target Target.
44428 */
44429
44430/**
44431 * Maximum number of subdivision steps during raster reprojection triangulation.
44432 * Prevents high memory usage and large number of proj4 calls (for certain
44433 * transformations and areas). At most `2*(2^this)` triangles are created for
44434 * each triangulated extent (tile/image).
44435 * @type {number}
44436 */
44437const MAX_SUBDIVISION = 10;
44438
44439/**
44440 * Maximum allowed size of triangle relative to world width. When transforming
44441 * corners of world extent between certain projections, the resulting
44442 * triangulation seems to have zero error and no subdivision is performed. If
44443 * the triangle width is more than this (relative to world width; 0-1),
44444 * subdivison is forced (up to `MAX_SUBDIVISION`). Default is `0.25`.
44445 * @type {number}
44446 */
44447const MAX_TRIANGLE_WIDTH = 0.25;
44448
44449/**
44450 * @classdesc
44451 * Class containing triangulation of the given target extent.
44452 * Used for determining source data and the reprojection itself.
44453 */
44454class Triangulation {
44455  /**
44456   * @param {import("../proj/Projection.js").default} sourceProj Source projection.
44457   * @param {import("../proj/Projection.js").default} targetProj Target projection.
44458   * @param {import("../extent.js").Extent} targetExtent Target extent to triangulate.
44459   * @param {import("../extent.js").Extent} maxSourceExtent Maximal source extent that can be used.
44460   * @param {number} errorThreshold Acceptable error (in source units).
44461   * @param {?number} destinationResolution The (optional) resolution of the destination.
44462   */
44463  constructor(
44464    sourceProj,
44465    targetProj,
44466    targetExtent,
44467    maxSourceExtent,
44468    errorThreshold,
44469    destinationResolution
44470  ) {
44471    /**
44472     * @type {import("../proj/Projection.js").default}
44473     * @private
44474     */
44475    this.sourceProj_ = sourceProj;
44476
44477    /**
44478     * @type {import("../proj/Projection.js").default}
44479     * @private
44480     */
44481    this.targetProj_ = targetProj;
44482
vendor: 11,012 bytes, lines 44483-44803
44483    /** @type {!Object<string, import("../coordinate.js").Coordinate>} */
44484    let transformInvCache = {};
44485    const transformInv = getTransform(this.targetProj_, this.sourceProj_);
44486
44487    /**
44488     * @param {import("../coordinate.js").Coordinate} c A coordinate.
44489     * @return {import("../coordinate.js").Coordinate} Transformed coordinate.
44490     * @private
44491     */
44492    this.transformInv_ = function (c) {
44493      const key = c[0] + '/' + c[1];
44494      if (!transformInvCache[key]) {
44495        transformInvCache[key] = transformInv(c);
44496      }
44497      return transformInvCache[key];
44498    };
44499
44500    /**
44501     * @type {import("../extent.js").Extent}
44502     * @private
44503     */
44504    this.maxSourceExtent_ = maxSourceExtent;
44505
44506    /**
44507     * @type {number}
44508     * @private
44509     */
44510    this.errorThresholdSquared_ = errorThreshold * errorThreshold;
44511
44512    /**
44513     * @type {Array<Triangle>}
44514     * @private
44515     */
44516    this.triangles_ = [];
44517
44518    /**
44519     * Indicates that the triangulation crosses edge of the source projection.
44520     * @type {boolean}
44521     * @private
44522     */
44523    this.wrapsXInSource_ = false;
44524
44525    /**
44526     * @type {boolean}
44527     * @private
44528     */
44529    this.canWrapXInSource_ =
44530      this.sourceProj_.canWrapX() &&
44531      !!maxSourceExtent &&
44532      !!this.sourceProj_.getExtent() &&
44533      extent_getWidth(maxSourceExtent) == extent_getWidth(this.sourceProj_.getExtent());
44534
44535    /**
44536     * @type {?number}
44537     * @private
44538     */
44539    this.sourceWorldWidth_ = this.sourceProj_.getExtent()
44540      ? extent_getWidth(this.sourceProj_.getExtent())
44541      : null;
44542
44543    /**
44544     * @type {?number}
44545     * @private
44546     */
44547    this.targetWorldWidth_ = this.targetProj_.getExtent()
44548      ? extent_getWidth(this.targetProj_.getExtent())
44549      : null;
44550
44551    const destinationTopLeft = getTopLeft(targetExtent);
44552    const destinationTopRight = getTopRight(targetExtent);
44553    const destinationBottomRight = getBottomRight(targetExtent);
44554    const destinationBottomLeft = getBottomLeft(targetExtent);
44555    const sourceTopLeft = this.transformInv_(destinationTopLeft);
44556    const sourceTopRight = this.transformInv_(destinationTopRight);
44557    const sourceBottomRight = this.transformInv_(destinationBottomRight);
44558    const sourceBottomLeft = this.transformInv_(destinationBottomLeft);
44559
44560    /*
44561     * The maxSubdivision controls how many splittings of the target area can
44562     * be done. The idea here is to do a linear mapping of the target areas
44563     * but the actual overal reprojection (can be) extremely non-linear. The
44564     * default value of MAX_SUBDIVISION was chosen based on mapping a 256x256
44565     * tile size. However this function is also called to remap canvas rendered
44566     * layers which can be much larger. This calculation increases the maxSubdivision
44567     * value by the right factor so that each 256x256 pixel area has
44568     * MAX_SUBDIVISION divisions.
44569     */
44570    const maxSubdivision =
44571      MAX_SUBDIVISION +
44572      (destinationResolution
44573        ? Math.max(
44574            0,
44575            Math.ceil(
44576              Math.log2(
44577                getArea(targetExtent) /
44578                  (destinationResolution * destinationResolution * 256 * 256)
44579              )
44580            )
44581          )
44582        : 0);
44583
44584    this.addQuad_(
44585      destinationTopLeft,
44586      destinationTopRight,
44587      destinationBottomRight,
44588      destinationBottomLeft,
44589      sourceTopLeft,
44590      sourceTopRight,
44591      sourceBottomRight,
44592      sourceBottomLeft,
44593      maxSubdivision
44594    );
44595
44596    if (this.wrapsXInSource_) {
44597      let leftBound = Infinity;
44598      this.triangles_.forEach(function (triangle, i, arr) {
44599        leftBound = Math.min(
44600          leftBound,
44601          triangle.source[0][0],
44602          triangle.source[1][0],
44603          triangle.source[2][0]
44604        );
44605      });
44606
44607      // Shift triangles to be as close to `leftBound` as possible
44608      // (if the distance is more than `worldWidth / 2` it can be closer.
44609      this.triangles_.forEach(
44610        function (triangle) {
44611          if (
44612            Math.max(
44613              triangle.source[0][0],
44614              triangle.source[1][0],
44615              triangle.source[2][0]
44616            ) -
44617              leftBound >
44618            this.sourceWorldWidth_ / 2
44619          ) {
44620            const newTriangle = [
44621              [triangle.source[0][0], triangle.source[0][1]],
44622              [triangle.source[1][0], triangle.source[1][1]],
44623              [triangle.source[2][0], triangle.source[2][1]],
44624            ];
44625            if (newTriangle[0][0] - leftBound > this.sourceWorldWidth_ / 2) {
44626              newTriangle[0][0] -= this.sourceWorldWidth_;
44627            }
44628            if (newTriangle[1][0] - leftBound > this.sourceWorldWidth_ / 2) {
44629              newTriangle[1][0] -= this.sourceWorldWidth_;
44630            }
44631            if (newTriangle[2][0] - leftBound > this.sourceWorldWidth_ / 2) {
44632              newTriangle[2][0] -= this.sourceWorldWidth_;
44633            }
44634
44635            // Rarely (if the extent contains both the dateline and prime meridian)
44636            // the shift can in turn break some triangles.
44637            // Detect this here and don't shift in such cases.
44638            const minX = Math.min(
44639              newTriangle[0][0],
44640              newTriangle[1][0],
44641              newTriangle[2][0]
44642            );
44643            const maxX = Math.max(
44644              newTriangle[0][0],
44645              newTriangle[1][0],
44646              newTriangle[2][0]
44647            );
44648            if (maxX - minX < this.sourceWorldWidth_ / 2) {
44649              triangle.source = newTriangle;
44650            }
44651          }
44652        }.bind(this)
44653      );
44654    }
44655
44656    transformInvCache = {};
44657  }
44658
44659  /**
44660   * Adds triangle to the triangulation.
44661   * @param {import("../coordinate.js").Coordinate} a The target a coordinate.
44662   * @param {import("../coordinate.js").Coordinate} b The target b coordinate.
44663   * @param {import("../coordinate.js").Coordinate} c The target c coordinate.
44664   * @param {import("../coordinate.js").Coordinate} aSrc The source a coordinate.
44665   * @param {import("../coordinate.js").Coordinate} bSrc The source b coordinate.
44666   * @param {import("../coordinate.js").Coordinate} cSrc The source c coordinate.
44667   * @private
44668   */
44669  addTriangle_(a, b, c, aSrc, bSrc, cSrc) {
44670    this.triangles_.push({
44671      source: [aSrc, bSrc, cSrc],
44672      target: [a, b, c],
44673    });
44674  }
44675
44676  /**
44677   * Adds quad (points in clock-wise order) to the triangulation
44678   * (and reprojects the vertices) if valid.
44679   * Performs quad subdivision if needed to increase precision.
44680   *
44681   * @param {import("../coordinate.js").Coordinate} a The target a coordinate.
44682   * @param {import("../coordinate.js").Coordinate} b The target b coordinate.
44683   * @param {import("../coordinate.js").Coordinate} c The target c coordinate.
44684   * @param {import("../coordinate.js").Coordinate} d The target d coordinate.
44685   * @param {import("../coordinate.js").Coordinate} aSrc The source a coordinate.
44686   * @param {import("../coordinate.js").Coordinate} bSrc The source b coordinate.
44687   * @param {import("../coordinate.js").Coordinate} cSrc The source c coordinate.
44688   * @param {import("../coordinate.js").Coordinate} dSrc The source d coordinate.
44689   * @param {number} maxSubdivision Maximal allowed subdivision of the quad.
44690   * @private
44691   */
44692  addQuad_(a, b, c, d, aSrc, bSrc, cSrc, dSrc, maxSubdivision) {
44693    const sourceQuadExtent = boundingExtent([aSrc, bSrc, cSrc, dSrc]);
44694    const sourceCoverageX = this.sourceWorldWidth_
44695      ? extent_getWidth(sourceQuadExtent) / this.sourceWorldWidth_
44696      : null;
44697    const sourceWorldWidth = /** @type {number} */ (this.sourceWorldWidth_);
44698
44699    // when the quad is wrapped in the source projection
44700    // it covers most of the projection extent, but not fully
44701    const wrapsX =
44702      this.sourceProj_.canWrapX() &&
44703      sourceCoverageX > 0.5 &&
44704      sourceCoverageX < 1;
44705
44706    let needsSubdivision = false;
44707
44708    if (maxSubdivision > 0) {
44709      if (this.targetProj_.isGlobal() && this.targetWorldWidth_) {
44710        const targetQuadExtent = boundingExtent([a, b, c, d]);
44711        const targetCoverageX =
44712          extent_getWidth(targetQuadExtent) / this.targetWorldWidth_;
44713        needsSubdivision =
44714          targetCoverageX > MAX_TRIANGLE_WIDTH || needsSubdivision;
44715      }
44716      if (!wrapsX && this.sourceProj_.isGlobal() && sourceCoverageX) {
44717        needsSubdivision =
44718          sourceCoverageX > MAX_TRIANGLE_WIDTH || needsSubdivision;
44719      }
44720    }
44721
44722    if (!needsSubdivision && this.maxSourceExtent_) {
44723      if (
44724        isFinite(sourceQuadExtent[0]) &&
44725        isFinite(sourceQuadExtent[1]) &&
44726        isFinite(sourceQuadExtent[2]) &&
44727        isFinite(sourceQuadExtent[3])
44728      ) {
44729        if (!intersects(sourceQuadExtent, this.maxSourceExtent_)) {
44730          // whole quad outside source projection extent -> ignore
44731          return;
44732        }
44733      }
44734    }
44735
44736    let isNotFinite = 0;
44737
44738    if (!needsSubdivision) {
44739      if (
44740        !isFinite(aSrc[0]) ||
44741        !isFinite(aSrc[1]) ||
44742        !isFinite(bSrc[0]) ||
44743        !isFinite(bSrc[1]) ||
44744        !isFinite(cSrc[0]) ||
44745        !isFinite(cSrc[1]) ||
44746        !isFinite(dSrc[0]) ||
44747        !isFinite(dSrc[1])
44748      ) {
44749        if (maxSubdivision > 0) {
44750          needsSubdivision = true;
44751        } else {
44752          // It might be the case that only 1 of the points is infinite. In this case
44753          // we can draw a single triangle with the other three points
44754          isNotFinite =
44755            (!isFinite(aSrc[0]) || !isFinite(aSrc[1]) ? 8 : 0) +
44756            (!isFinite(bSrc[0]) || !isFinite(bSrc[1]) ? 4 : 0) +
44757            (!isFinite(cSrc[0]) || !isFinite(cSrc[1]) ? 2 : 0) +
44758            (!isFinite(dSrc[0]) || !isFinite(dSrc[1]) ? 1 : 0);
44759          if (
44760            isNotFinite != 1 &&
44761            isNotFinite != 2 &&
44762            isNotFinite != 4 &&
44763            isNotFinite != 8
44764          ) {
44765            return;
44766          }
44767        }
44768      }
44769    }
44770
44771    if (maxSubdivision > 0) {
44772      if (!needsSubdivision) {
44773        const center = [(a[0] + c[0]) / 2, (a[1] + c[1]) / 2];
44774        const centerSrc = this.transformInv_(center);
44775
44776        let dx;
44777        if (wrapsX) {
44778          const centerSrcEstimX =
44779            (math_modulo(aSrc[0], sourceWorldWidth) +
44780              math_modulo(cSrc[0], sourceWorldWidth)) /
44781            2;
44782          dx = centerSrcEstimX - math_modulo(centerSrc[0], sourceWorldWidth);
44783        } else {
44784          dx = (aSrc[0] + cSrc[0]) / 2 - centerSrc[0];
44785        }
44786        const dy = (aSrc[1] + cSrc[1]) / 2 - centerSrc[1];
44787        const centerSrcErrorSquared = dx * dx + dy * dy;
44788        needsSubdivision = centerSrcErrorSquared > this.errorThresholdSquared_;
44789      }
44790      if (needsSubdivision) {
44791        if (Math.abs(a[0] - c[0]) <= Math.abs(a[1] - c[1])) {
44792          // split horizontally (top & bottom)
44793          const bc = [(b[0] + c[0]) / 2, (b[1] + c[1]) / 2];
44794          const bcSrc = this.transformInv_(bc);
44795          const da = [(d[0] + a[0]) / 2, (d[1] + a[1]) / 2];
44796          const daSrc = this.transformInv_(da);
44797
44798          this.addQuad_(
44799            a,
44800            b,
44801            bc,
44802            da,
44803            aSrc,
44804            bSrc,
44805            bcSrc,
44806            daSrc,
44807            maxSubdivision - 1
44808          );
44809          this.addQuad_(
44810            da,
44811            bc,
44812            c,
44813            d,
44814            daSrc,
44815            bcSrc,
44816            cSrc,
44817            dSrc,
44818            maxSubdivision - 1
44819          );
44820        } else {
44821          // split vertically (left & right)
44822          const ab = [(a[0] + b[0]) / 2, (a[1] + b[1]) / 2];
44823          const abSrc = this.transformInv_(ab);
44824          const cd = [(c[0] + d[0]) / 2, (c[1] + d[1]) / 2];
44825          const cdSrc = this.transformInv_(cd);
44826
44827          this.addQuad_(
44828            a,
44829            ab,
44830            cd,
44831            d,
44832            aSrc,
44833            abSrc,
44834            cdSrc,
44835            dSrc,
44836            maxSubdivision - 1
44837          );
44838          this.addQuad_(
44839            ab,
44840            b,
44841            c,
44842            cd,
44843            abSrc,
44844            bSrc,
44845            cSrc,
44846            cdSrc,
44847            maxSubdivision - 1
44848          );
44849        }
44850        return;
44851      }
44852    }
44853
44854    if (wrapsX) {
44855      if (!this.canWrapXInSource_) {
44856        return;
44857      }
44858      this.wrapsXInSource_ = true;
44859    }
44860
44861    // Exactly zero or one of *Src is not finite
44862    // The triangles must have the diagonal line as the first side
44863    // This is to allow easy code in reproj.s to make it straight for broken
44864    // browsers that can't handle diagonal clipping
44865    if ((isNotFinite & 0xb) == 0) {
44866      this.addTriangle_(a, c, d, aSrc, cSrc, dSrc);
44867    }
44868    if ((isNotFinite & 0xe) == 0) {
44869      this.addTriangle_(a, c, b, aSrc, cSrc, bSrc);
44870    }
44871    if (isNotFinite) {
44872      // Try the other two triangles
44873      if ((isNotFinite & 0xd) == 0) {
44874        this.addTriangle_(b, d, a, bSrc, dSrc, aSrc);
44875      }
44876      if ((isNotFinite & 0x7) == 0) {
44877        this.addTriangle_(b, d, c, bSrc, dSrc, cSrc);
44878      }
44879    }
44880  }
44881
44882  /**
44883   * Calculates extent of the `source` coordinates from all the triangles.
44884   *
44885   * @return {import("../extent.js").Extent} Calculated extent.
44886   */
44887  calculateSourceExtent() {
44888    const extent = createEmpty();
44889
44890    this.triangles_.forEach(function (triangle, i, arr) {
44891      const src = triangle.source;
44892      extendCoordinate(extent, src[0]);
44893      extendCoordinate(extent, src[1]);
44894      extendCoordinate(extent, src[2]);
44895    });
44896
44897    return extent;
44898  }
44899
44900  /**
44901   * @return {Array<Triangle>} Array of the calculated triangles.
44902   */
44903  getTriangles() {
44904    return this.triangles_;
44905  }
44906}
44907
44908/* harmony default export */ const reproj_Triangulation = (Triangulation);
44909
44910;// CONCATENATED MODULE: ./node_modules/ol/reproj.js
44911/**
44912 * @module ol/reproj
44913 */
44914
44915
44916
44917
44918
44919let brokenDiagonalRendering_;
44920
44921/**
44922 * @type {Array<HTMLCanvasElement>}
44923 */
44924const reproj_canvasPool = [];
44925
44926/**
44927 * This draws a small triangle into a canvas by setting the triangle as the clip region
44928 * and then drawing a (too large) rectangle
44929 *
44930 * @param {CanvasRenderingContext2D} ctx The context in which to draw the triangle
44931 * @param {number} u1 The x-coordinate of the second point. The first point is 0,0.
44932 * @param {number} v1 The y-coordinate of the second point.
44933 * @param {number} u2 The x-coordinate of the third point.
44934 * @param {number} v2 The y-coordinate of the third point.
44935 */
44936function drawTestTriangle(ctx, u1, v1, u2, v2) {
44937  ctx.beginPath();
44938  ctx.moveTo(0, 0);
44939  ctx.lineTo(u1, v1);
44940  ctx.lineTo(u2, v2);
44941  ctx.closePath();
44942  ctx.save();
44943  ctx.clip();
44944  ctx.fillRect(0, 0, Math.max(u1, u2) + 1, Math.max(v1, v2));
44945  ctx.restore();
44946}
44947
44948/**
44949 * Given the data from getImageData, see if the right values appear at the provided offset.
44950 * Returns true if either the color or transparency is off
44951 *
44952 * @param {Uint8ClampedArray} data The data returned from getImageData
44953 * @param {number} offset The pixel offset from the start of data.
44954 * @return {boolean} true if the diagonal rendering is broken
44955 */
44956function verifyBrokenDiagonalRendering(data, offset) {
44957  // the values ought to be close to the rgba(210, 0, 0, 0.75)
44958  return (
44959    Math.abs(data[offset * 4] - 210) > 2 ||
44960    Math.abs(data[offset * 4 + 3] - 0.75 * 255) > 2
44961  );
44962}
44963
44964/**
44965 * Determines if the current browser configuration can render triangular clip regions correctly.
44966 * This value is cached so the function is only expensive the first time called.
44967 * Firefox on Windows (as of now) does not if HWA is enabled. See https://bugzilla.mozilla.org/show_bug.cgi?id=1606976
44968 * Chrome works, and everything seems to work on OSX and Android. This function caches the
44969 * result. I suppose that it is conceivably possible that a browser might flip modes while the app is
44970 * running, but lets hope not.
44971 *
44972 * @return {boolean} true if the Diagonal Rendering is broken.
44973 */
44974function isBrokenDiagonalRendering() {
44975  if (brokenDiagonalRendering_ === undefined) {
44976    const ctx = document.createElement('canvas').getContext('2d');
44977    ctx.globalCompositeOperation = 'lighter';
44978    ctx.fillStyle = 'rgba(210, 0, 0, 0.75)';
44979    drawTestTriangle(ctx, 4, 5, 4, 0);
44980    drawTestTriangle(ctx, 4, 5, 0, 5);
44981    const data = ctx.getImageData(0, 0, 3, 3).data;
44982    brokenDiagonalRendering_ =
44983      verifyBrokenDiagonalRendering(data, 0) ||
44984      verifyBrokenDiagonalRendering(data, 4) ||
44985      verifyBrokenDiagonalRendering(data, 8);
44986  }
44987
44988  return brokenDiagonalRendering_;
44989}
44990
44991/**
44992 * Calculates ideal resolution to use from the source in order to achieve
44993 * pixel mapping as close as possible to 1:1 during reprojection.
44994 * The resolution is calculated regardless of what resolutions
44995 * are actually available in the dataset (TileGrid, Image, ...).
44996 *
44997 * @param {import("./proj/Projection.js").default} sourceProj Source projection.
44998 * @param {import("./proj/Projection.js").default} targetProj Target projection.
44999 * @param {import("./coordinate.js").Coordinate} targetCenter Target center.
45000 * @param {number} targetResolution Target resolution.
45001 * @return {number} The best resolution to use. Can be +-Infinity, NaN or 0.
45002 */
45003function calculateSourceResolution(
45004  sourceProj,
45005  targetProj,
45006  targetCenter,
45007  targetResolution
45008) {
45009  const sourceCenter = transform(targetCenter, targetProj, sourceProj);
45010
45011  // calculate the ideal resolution of the source data
45012  let sourceResolution = getPointResolution(
45013    targetProj,
45014    targetResolution,
45015    targetCenter
45016  );
45017
45018  const targetMetersPerUnit = targetProj.getMetersPerUnit();
45019  if (targetMetersPerUnit !== undefined) {
45020    sourceResolution *= targetMetersPerUnit;
45021  }
45022  const sourceMetersPerUnit = sourceProj.getMetersPerUnit();
45023  if (sourceMetersPerUnit !== undefined) {
45024    sourceResolution /= sourceMetersPerUnit;
45025  }
45026
45027  // Based on the projection properties, the point resolution at the specified
45028  // coordinates may be slightly different. We need to reverse-compensate this
45029  // in order to achieve optimal results.
45030
45031  const sourceExtent = sourceProj.getExtent();
45032  if (!sourceExtent || containsCoordinate(sourceExtent, sourceCenter)) {
45033    const compensationFactor =
45034      getPointResolution(sourceProj, sourceResolution, sourceCenter) /
45035      sourceResolution;
45036    if (isFinite(compensationFactor) && compensationFactor > 0) {
45037      sourceResolution /= compensationFactor;
45038    }
45039  }
45040
45041  return sourceResolution;
45042}
45043
45044/**
45045 * Calculates ideal resolution to use from the source in order to achieve
45046 * pixel mapping as close as possible to 1:1 during reprojection.
45047 * The resolution is calculated regardless of what resolutions
45048 * are actually available in the dataset (TileGrid, Image, ...).
45049 *
45050 * @param {import("./proj/Projection.js").default} sourceProj Source projection.
45051 * @param {import("./proj/Projection.js").default} targetProj Target projection.
45052 * @param {import("./extent.js").Extent} targetExtent Target extent
45053 * @param {number} targetResolution Target resolution.
45054 * @return {number} The best resolution to use. Can be +-Infinity, NaN or 0.
45055 */
45056function calculateSourceExtentResolution(
45057  sourceProj,
45058  targetProj,
45059  targetExtent,
45060  targetResolution
45061) {
45062  const targetCenter = getCenter(targetExtent);
45063  let sourceResolution = calculateSourceResolution(
45064    sourceProj,
45065    targetProj,
45066    targetCenter,
45067    targetResolution
45068  );
45069
45070  if (!isFinite(sourceResolution) || sourceResolution <= 0) {
45071    forEachCorner(targetExtent, function (corner) {
45072      sourceResolution = calculateSourceResolution(
45073        sourceProj,
45074        targetProj,
45075        corner,
45076        targetResolution
45077      );
45078      return isFinite(sourceResolution) && sourceResolution > 0;
45079    });
45080  }
45081
45082  return sourceResolution;
45083}
45084
45085/**
45086 * @typedef {Object} ImageExtent
45087 * @property {import("./extent.js").Extent} extent Extent.
45088 * @property {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} image Image.
45089 */
45090
45091/**
45092 * Renders the source data into new canvas based on the triangulation.
45093 *
45094 * @param {number} width Width of the canvas.
45095 * @param {number} height Height of the canvas.
45096 * @param {number} pixelRatio Pixel ratio.
45097 * @param {number} sourceResolution Source resolution.
45098 * @param {import("./extent.js").Extent} sourceExtent Extent of the data source.
45099 * @param {number} targetResolution Target resolution.
45100 * @param {import("./extent.js").Extent} targetExtent Target extent.
45101 * @param {import("./reproj/Triangulation.js").default} triangulation Calculated triangulation.
45102 * @param {Array<ImageExtent>} sources Array of sources.
45103 * @param {number} gutter Gutter of the sources.
45104 * @param {boolean} [renderEdges] Render reprojection edges.
45105 * @param {boolean} [interpolate] Use linear interpolation when resampling.
45106 * @return {HTMLCanvasElement} Canvas with reprojected data.
45107 */
45108function render(
45109  width,
45110  height,
45111  pixelRatio,
45112  sourceResolution,
45113  sourceExtent,
45114  targetResolution,
45115  targetExtent,
45116  triangulation,
45117  sources,
45118  gutter,
45119  renderEdges,
45120  interpolate
45121) {
45122  const context = createCanvasContext2D(
45123    Math.round(pixelRatio * width),
45124    Math.round(pixelRatio * height),
45125    reproj_canvasPool
45126  );
45127
45128  if (!interpolate) {
45129    context.imageSmoothingEnabled = false;
45130  }
45131
45132  if (sources.length === 0) {
45133    return context.canvas;
45134  }
45135
45136  context.scale(pixelRatio, pixelRatio);
45137
45138  function pixelRound(value) {
45139    return Math.round(value * pixelRatio) / pixelRatio;
45140  }
45141
45142  context.globalCompositeOperation = 'lighter';
45143
45144  const sourceDataExtent = createEmpty();
45145  sources.forEach(function (src, i, arr) {
45146    extent_extend(sourceDataExtent, src.extent);
45147  });
45148
45149  const canvasWidthInUnits = extent_getWidth(sourceDataExtent);
45150  const canvasHeightInUnits = extent_getHeight(sourceDataExtent);
45151  const stitchContext = createCanvasContext2D(
45152    Math.round((pixelRatio * canvasWidthInUnits) / sourceResolution),
45153    Math.round((pixelRatio * canvasHeightInUnits) / sourceResolution)
45154  );
45155
45156  if (!interpolate) {
45157    stitchContext.imageSmoothingEnabled = false;
45158  }
45159
45160  const stitchScale = pixelRatio / sourceResolution;
45161
45162  sources.forEach(function (src, i, arr) {
45163    const xPos = src.extent[0] - sourceDataExtent[0];
45164    const yPos = -(src.extent[3] - sourceDataExtent[3]);
45165    const srcWidth = extent_getWidth(src.extent);
45166    const srcHeight = extent_getHeight(src.extent);
45167
45168    // This test should never fail -- but it does. Need to find a fix the upstream condition
45169    if (src.image.width > 0 && src.image.height > 0) {
45170      stitchContext.drawImage(
45171        src.image,
45172        gutter,
45173        gutter,
45174        src.image.width - 2 * gutter,
45175        src.image.height - 2 * gutter,
45176        xPos * stitchScale,
45177        yPos * stitchScale,
45178        srcWidth * stitchScale,
45179        srcHeight * stitchScale
45180      );
45181    }
45182  });
45183
45184  const targetTopLeft = getTopLeft(targetExtent);
45185
vendor: 3,364 bytes, lines 45186-45286
45186  triangulation.getTriangles().forEach(function (triangle, i, arr) {
45187    /* Calculate affine transform (src -> dst)
45188     * Resulting matrix can be used to transform coordinate
45189     * from `sourceProjection` to destination pixels.
45190     *
45191     * To optimize number of context calls and increase numerical stability,
45192     * we also do the following operations:
45193     * trans(-topLeftExtentCorner), scale(1 / targetResolution), scale(1, -1)
45194     * here before solving the linear system so [ui, vi] are pixel coordinates.
45195     *
45196     * Src points: xi, yi
45197     * Dst points: ui, vi
45198     * Affine coefficients: aij
45199     *
45200     * | x0 y0 1  0  0 0 |   |a00|   |u0|
45201     * | x1 y1 1  0  0 0 |   |a01|   |u1|
45202     * | x2 y2 1  0  0 0 | x |a02| = |u2|
45203     * |  0  0 0 x0 y0 1 |   |a10|   |v0|
45204     * |  0  0 0 x1 y1 1 |   |a11|   |v1|
45205     * |  0  0 0 x2 y2 1 |   |a12|   |v2|
45206     */
45207    const source = triangle.source;
45208    const target = triangle.target;
45209    let x0 = source[0][0],
45210      y0 = source[0][1];
45211    let x1 = source[1][0],
45212      y1 = source[1][1];
45213    let x2 = source[2][0],
45214      y2 = source[2][1];
45215    // Make sure that everything is on pixel boundaries
45216    const u0 = pixelRound((target[0][0] - targetTopLeft[0]) / targetResolution);
45217    const v0 = pixelRound(
45218      -(target[0][1] - targetTopLeft[1]) / targetResolution
45219    );
45220    const u1 = pixelRound((target[1][0] - targetTopLeft[0]) / targetResolution);
45221    const v1 = pixelRound(
45222      -(target[1][1] - targetTopLeft[1]) / targetResolution
45223    );
45224    const u2 = pixelRound((target[2][0] - targetTopLeft[0]) / targetResolution);
45225    const v2 = pixelRound(
45226      -(target[2][1] - targetTopLeft[1]) / targetResolution
45227    );
45228
45229    // Shift all the source points to improve numerical stability
45230    // of all the subsequent calculations. The [x0, y0] is used here.
45231    // This is also used to simplify the linear system.
45232    const sourceNumericalShiftX = x0;
45233    const sourceNumericalShiftY = y0;
45234    x0 = 0;
45235    y0 = 0;
45236    x1 -= sourceNumericalShiftX;
45237    y1 -= sourceNumericalShiftY;
45238    x2 -= sourceNumericalShiftX;
45239    y2 -= sourceNumericalShiftY;
45240
45241    const augmentedMatrix = [
45242      [x1, y1, 0, 0, u1 - u0],
45243      [x2, y2, 0, 0, u2 - u0],
45244      [0, 0, x1, y1, v1 - v0],
45245      [0, 0, x2, y2, v2 - v0],
45246    ];
45247    const affineCoefs = solveLinearSystem(augmentedMatrix);
45248    if (!affineCoefs) {
45249      return;
45250    }
45251
45252    context.save();
45253    context.beginPath();
45254
45255    if (isBrokenDiagonalRendering() || !interpolate) {
45256      // Make sure that all lines are horizontal or vertical
45257      context.moveTo(u1, v1);
45258      // This is the diagonal line. Do it in 4 steps
45259      const steps = 4;
45260      const ud = u0 - u1;
45261      const vd = v0 - v1;
45262      for (let step = 0; step < steps; step++) {
45263        // Go horizontally
45264        context.lineTo(
45265          u1 + pixelRound(((step + 1) * ud) / steps),
45266          v1 + pixelRound((step * vd) / (steps - 1))
45267        );
45268        // Go vertically
45269        if (step != steps - 1) {
45270          context.lineTo(
45271            u1 + pixelRound(((step + 1) * ud) / steps),
45272            v1 + pixelRound(((step + 1) * vd) / (steps - 1))
45273          );
45274        }
45275      }
45276      // We are almost at u0r, v0r
45277      context.lineTo(u2, v2);
45278    } else {
45279      context.moveTo(u1, v1);
45280      context.lineTo(u0, v0);
45281      context.lineTo(u2, v2);
45282    }
45283
45284    context.clip();
45285
45286    context.transform(
45287      affineCoefs[0],
45288      affineCoefs[2],
45289      affineCoefs[1],
45290      affineCoefs[3],
45291      u0,
45292      v0
45293    );
45294
45295    context.translate(
45296      sourceDataExtent[0] - sourceNumericalShiftX,
45297      sourceDataExtent[3] - sourceNumericalShiftY
45298    );
45299
45300    context.scale(
45301      sourceResolution / pixelRatio,
45302      -sourceResolution / pixelRatio
45303    );
45304
45305    context.drawImage(stitchContext.canvas, 0, 0);
45306    context.restore();
45307  });
45308
45309  if (renderEdges) {
45310    context.save();
45311
45312    context.globalCompositeOperation = 'source-over';
45313    context.strokeStyle = 'black';
45314    context.lineWidth = 1;
45315
45316    triangulation.getTriangles().forEach(function (triangle, i, arr) {
45317      const target = triangle.target;
45318      const u0 = (target[0][0] - targetTopLeft[0]) / targetResolution;
45319      const v0 = -(target[0][1] - targetTopLeft[1]) / targetResolution;
45320      const u1 = (target[1][0] - targetTopLeft[0]) / targetResolution;
45321      const v1 = -(target[1][1] - targetTopLeft[1]) / targetResolution;
45322      const u2 = (target[2][0] - targetTopLeft[0]) / targetResolution;
45323      const v2 = -(target[2][1] - targetTopLeft[1]) / targetResolution;
45324
45325      context.beginPath();
45326      context.moveTo(u1, v1);
45327      context.lineTo(u0, v0);
45328      context.lineTo(u2, v2);
45329      context.closePath();
45330      context.stroke();
45331    });
45332
45333    context.restore();
45334  }
45335  return context.canvas;
45336}
45337
45338;// CONCATENATED MODULE: ./node_modules/ol/reproj/Tile.js
45339/**
45340 * @module ol/reproj/Tile
45341 */
45342
45343
45344
45345
45346
45347
45348
45349
45350
45351
45352
45353
45354/**
45355 * @typedef {function(number, number, number, number) : import("../Tile.js").default} FunctionType
45356 */
45357
45358/**
45359 * @classdesc
45360 * Class encapsulating single reprojected tile.
45361 * See {@link module:ol/source/TileImage~TileImage}.
45362 *
45363 */
45364class ReprojTile extends ol_Tile {
45365  /**
45366   * @param {import("../proj/Projection.js").default} sourceProj Source projection.
45367   * @param {import("../tilegrid/TileGrid.js").default} sourceTileGrid Source tile grid.
45368   * @param {import("../proj/Projection.js").default} targetProj Target projection.
45369   * @param {import("../tilegrid/TileGrid.js").default} targetTileGrid Target tile grid.
45370   * @param {import("../tilecoord.js").TileCoord} tileCoord Coordinate of the tile.
45371   * @param {import("../tilecoord.js").TileCoord} wrappedTileCoord Coordinate of the tile wrapped in X.
45372   * @param {number} pixelRatio Pixel ratio.
45373   * @param {number} gutter Gutter of the source tiles.
45374   * @param {FunctionType} getTileFunction
45375   *     Function returning source tiles (z, x, y, pixelRatio).
45376   * @param {number} [errorThreshold] Acceptable reprojection error (in px).
45377   * @param {boolean} [renderEdges] Render reprojection edges.
45378   * @param {boolean} [interpolate] Use linear interpolation when resampling.
45379   */
45380  constructor(
45381    sourceProj,
45382    sourceTileGrid,
45383    targetProj,
45384    targetTileGrid,
45385    tileCoord,
45386    wrappedTileCoord,
45387    pixelRatio,
45388    gutter,
45389    getTileFunction,
45390    errorThreshold,
45391    renderEdges,
45392    interpolate
45393  ) {
45394    super(tileCoord, TileState.IDLE, {interpolate: !!interpolate});
45395
45396    /**
45397     * @private
45398     * @type {boolean}
45399     */
45400    this.renderEdges_ = renderEdges !== undefined ? renderEdges : false;
45401
45402    /**
45403     * @private
45404     * @type {number}
45405     */
45406    this.pixelRatio_ = pixelRatio;
45407
45408    /**
45409     * @private
45410     * @type {number}
45411     */
45412    this.gutter_ = gutter;
45413
45414    /**
45415     * @private
45416     * @type {HTMLCanvasElement}
45417     */
45418    this.canvas_ = null;
45419
45420    /**
45421     * @private
45422     * @type {import("../tilegrid/TileGrid.js").default}
45423     */
45424    this.sourceTileGrid_ = sourceTileGrid;
45425
45426    /**
45427     * @private
45428     * @type {import("../tilegrid/TileGrid.js").default}
45429     */
45430    this.targetTileGrid_ = targetTileGrid;
45431
45432    /**
45433     * @private
45434     * @type {import("../tilecoord.js").TileCoord}
45435     */
45436    this.wrappedTileCoord_ = wrappedTileCoord ? wrappedTileCoord : tileCoord;
45437
45438    /**
45439     * @private
45440     * @type {!Array<import("../Tile.js").default>}
45441     */
45442    this.sourceTiles_ = [];
45443
45444    /**
45445     * @private
45446     * @type {?Array<import("../events.js").EventsKey>}
45447     */
45448    this.sourcesListenerKeys_ = null;
45449
45450    /**
45451     * @private
45452     * @type {number}
45453     */
45454    this.sourceZ_ = 0;
45455
45456    const targetExtent = targetTileGrid.getTileCoordExtent(
45457      this.wrappedTileCoord_
45458    );
45459    const maxTargetExtent = this.targetTileGrid_.getExtent();
45460    let maxSourceExtent = this.sourceTileGrid_.getExtent();
45461
45462    const limitedTargetExtent = maxTargetExtent
45463      ? getIntersection(targetExtent, maxTargetExtent)
45464      : targetExtent;
45465
45466    if (getArea(limitedTargetExtent) === 0) {
45467      // Tile is completely outside range -> EMPTY
45468      // TODO: is it actually correct that the source even creates the tile ?
45469      this.state = TileState.EMPTY;
45470      return;
45471    }
45472
45473    const sourceProjExtent = sourceProj.getExtent();
45474    if (sourceProjExtent) {
45475      if (!maxSourceExtent) {
45476        maxSourceExtent = sourceProjExtent;
45477      } else {
45478        maxSourceExtent = getIntersection(maxSourceExtent, sourceProjExtent);
45479      }
45480    }
45481
45482    const targetResolution = targetTileGrid.getResolution(
45483      this.wrappedTileCoord_[0]
45484    );
45485
45486    const sourceResolution = calculateSourceExtentResolution(
45487      sourceProj,
45488      targetProj,
45489      limitedTargetExtent,
45490      targetResolution
45491    );
45492
45493    if (!isFinite(sourceResolution) || sourceResolution <= 0) {
45494      // invalid sourceResolution -> EMPTY
45495      // probably edges of the projections when no extent is defined
45496      this.state = TileState.EMPTY;
45497      return;
45498    }
45499
45500    const errorThresholdInPixels =
45501      errorThreshold !== undefined ? errorThreshold : ERROR_THRESHOLD;
45502
45503    /**
45504     * @private
45505     * @type {!import("./Triangulation.js").default}
45506     */
45507    this.triangulation_ = new reproj_Triangulation(
45508      sourceProj,
45509      targetProj,
45510      limitedTargetExtent,
45511      maxSourceExtent,
45512      sourceResolution * errorThresholdInPixels,
45513      targetResolution
45514    );
45515
45516    if (this.triangulation_.getTriangles().length === 0) {
45517      // no valid triangles -> EMPTY
45518      this.state = TileState.EMPTY;
45519      return;
45520    }
45521
45522    this.sourceZ_ = sourceTileGrid.getZForResolution(sourceResolution);
45523    let sourceExtent = this.triangulation_.calculateSourceExtent();
45524
45525    if (maxSourceExtent) {
45526      if (sourceProj.canWrapX()) {
45527        sourceExtent[1] = math_clamp(
45528          sourceExtent[1],
45529          maxSourceExtent[1],
45530          maxSourceExtent[3]
45531        );
45532        sourceExtent[3] = math_clamp(
45533          sourceExtent[3],
45534          maxSourceExtent[1],
45535          maxSourceExtent[3]
45536        );
45537      } else {
45538        sourceExtent = getIntersection(sourceExtent, maxSourceExtent);
45539      }
45540    }
45541
45542    if (!getArea(sourceExtent)) {
45543      this.state = TileState.EMPTY;
45544    } else {
45545      const sourceRange = sourceTileGrid.getTileRangeForExtentAndZ(
45546        sourceExtent,
45547        this.sourceZ_
45548      );
45549
45550      for (let srcX = sourceRange.minX; srcX <= sourceRange.maxX; srcX++) {
45551        for (let srcY = sourceRange.minY; srcY <= sourceRange.maxY; srcY++) {
45552          const tile = getTileFunction(this.sourceZ_, srcX, srcY, pixelRatio);
45553          if (tile) {
45554            this.sourceTiles_.push(tile);
45555          }
45556        }
45557      }
45558
45559      if (this.sourceTiles_.length === 0) {
45560        this.state = TileState.EMPTY;
45561      }
45562    }
45563  }
45564
45565  /**
45566   * Get the HTML Canvas element for this tile.
45567   * @return {HTMLCanvasElement} Canvas.
45568   */
45569  getImage() {
45570    return this.canvas_;
45571  }
45572
45573  /**
45574   * @private
45575   */
45576  reproject_() {
45577    const sources = [];
45578    this.sourceTiles_.forEach(
45579      function (tile, i, arr) {
45580        if (tile && tile.getState() == TileState.LOADED) {
45581          sources.push({
45582            extent: this.sourceTileGrid_.getTileCoordExtent(tile.tileCoord),
45583            image: tile.getImage(),
45584          });
45585        }
45586      }.bind(this)
45587    );
45588    this.sourceTiles_.length = 0;
45589
45590    if (sources.length === 0) {
45591      this.state = TileState.ERROR;
45592    } else {
45593      const z = this.wrappedTileCoord_[0];
45594      const size = this.targetTileGrid_.getTileSize(z);
45595      const width = typeof size === 'number' ? size : size[0];
45596      const height = typeof size === 'number' ? size : size[1];
45597      const targetResolution = this.targetTileGrid_.getResolution(z);
45598      const sourceResolution = this.sourceTileGrid_.getResolution(
45599        this.sourceZ_
45600      );
45601
45602      const targetExtent = this.targetTileGrid_.getTileCoordExtent(
45603        this.wrappedTileCoord_
45604      );
45605
45606      this.canvas_ = render(
45607        width,
45608        height,
45609        this.pixelRatio_,
45610        sourceResolution,
45611        this.sourceTileGrid_.getExtent(),
45612        targetResolution,
45613        targetExtent,
45614        this.triangulation_,
45615        sources,
45616        this.gutter_,
45617        this.renderEdges_,
45618        this.interpolate
45619      );
45620
45621      this.state = TileState.LOADED;
45622    }
45623    this.changed();
45624  }
45625
45626  /**
45627   * Load not yet loaded URI.
45628   */
45629  load() {
45630    if (this.state == TileState.IDLE) {
45631      this.state = TileState.LOADING;
45632      this.changed();
45633
45634      let leftToLoad = 0;
45635
45636      this.sourcesListenerKeys_ = [];
45637      this.sourceTiles_.forEach(
45638        function (tile, i, arr) {
45639          const state = tile.getState();
45640          if (state == TileState.IDLE || state == TileState.LOADING) {
45641            leftToLoad++;
45642
45643            const sourceListenKey = listen(
45644              tile,
45645              EventType.CHANGE,
45646              function (e) {
45647                const state = tile.getState();
45648                if (
45649                  state == TileState.LOADED ||
45650                  state == TileState.ERROR ||
45651                  state == TileState.EMPTY
45652                ) {
45653                  unlistenByKey(sourceListenKey);
45654                  leftToLoad--;
45655                  if (leftToLoad === 0) {
45656                    this.unlistenSources_();
45657                    this.reproject_();
45658                  }
45659                }
45660              },
45661              this
45662            );
45663            this.sourcesListenerKeys_.push(sourceListenKey);
45664          }
45665        }.bind(this)
45666      );
45667
45668      if (leftToLoad === 0) {
45669        setTimeout(this.reproject_.bind(this), 0);
45670      } else {
45671        this.sourceTiles_.forEach(function (tile, i, arr) {
45672          const state = tile.getState();
45673          if (state == TileState.IDLE) {
45674            tile.load();
45675          }
45676        });
45677      }
45678    }
45679  }
45680
45681  /**
45682   * @private
45683   */
45684  unlistenSources_() {
45685    this.sourcesListenerKeys_.forEach(unlistenByKey);
45686    this.sourcesListenerKeys_ = null;
45687  }
45688
45689  /**
45690   * Remove from the cache due to expiry
45691   */
45692  release() {
45693    if (this.canvas_) {
45694      releaseCanvas(this.canvas_.getContext('2d'));
45695      reproj_canvasPool.push(this.canvas_);
45696      this.canvas_ = null;
45697    }
45698    super.release();
45699  }
45700}
45701
45702/* harmony default export */ const reproj_Tile = (ReprojTile);
45703
45704;// CONCATENATED MODULE: ./node_modules/ol/TileRange.js
45705/**
45706 * @module ol/TileRange
45707 */
45708
45709/**
45710 * A representation of a contiguous block of tiles.  A tile range is specified
45711 * by its min/max tile coordinates and is inclusive of coordinates.
45712 */
45713class TileRange {
45714  /**
45715   * @param {number} minX Minimum X.
45716   * @param {number} maxX Maximum X.
45717   * @param {number} minY Minimum Y.
45718   * @param {number} maxY Maximum Y.
45719   */
45720  constructor(minX, maxX, minY, maxY) {
45721    /**
45722     * @type {number}
45723     */
45724    this.minX = minX;
45725
45726    /**
45727     * @type {number}
45728     */
45729    this.maxX = maxX;
45730
45731    /**
45732     * @type {number}
45733     */
45734    this.minY = minY;
45735
45736    /**
45737     * @type {number}
45738     */
45739    this.maxY = maxY;
45740  }
45741
45742  /**
45743   * @param {import("./tilecoord.js").TileCoord} tileCoord Tile coordinate.
45744   * @return {boolean} Contains tile coordinate.
45745   */
45746  contains(tileCoord) {
45747    return this.containsXY(tileCoord[1], tileCoord[2]);
45748  }
45749
45750  /**
45751   * @param {TileRange} tileRange Tile range.
45752   * @return {boolean} Contains.
45753   */
45754  containsTileRange(tileRange) {
45755    return (
45756      this.minX <= tileRange.minX &&
45757      tileRange.maxX <= this.maxX &&
45758      this.minY <= tileRange.minY &&
45759      tileRange.maxY <= this.maxY
45760    );
45761  }
45762
45763  /**
45764   * @param {number} x Tile coordinate x.
45765   * @param {number} y Tile coordinate y.
45766   * @return {boolean} Contains coordinate.
45767   */
45768  containsXY(x, y) {
45769    return this.minX <= x && x <= this.maxX && this.minY <= y && y <= this.maxY;
45770  }
45771
45772  /**
45773   * @param {TileRange} tileRange Tile range.
45774   * @return {boolean} Equals.
45775   */
45776  equals(tileRange) {
45777    return (
45778      this.minX == tileRange.minX &&
45779      this.minY == tileRange.minY &&
45780      this.maxX == tileRange.maxX &&
45781      this.maxY == tileRange.maxY
45782    );
45783  }
45784
45785  /**
45786   * @param {TileRange} tileRange Tile range.
45787   */
45788  extend(tileRange) {
45789    if (tileRange.minX < this.minX) {
45790      this.minX = tileRange.minX;
45791    }
45792    if (tileRange.maxX > this.maxX) {
45793      this.maxX = tileRange.maxX;
45794    }
45795    if (tileRange.minY < this.minY) {
45796      this.minY = tileRange.minY;
45797    }
45798    if (tileRange.maxY > this.maxY) {
45799      this.maxY = tileRange.maxY;
45800    }
45801  }
45802
45803  /**
45804   * @return {number} Height.
45805   */
45806  getHeight() {
45807    return this.maxY - this.minY + 1;
45808  }
45809
45810  /**
45811   * @return {import("./size.js").Size} Size.
45812   */
45813  getSize() {
45814    return [this.getWidth(), this.getHeight()];
45815  }
45816
45817  /**
45818   * @return {number} Width.
45819   */
45820  getWidth() {
45821    return this.maxX - this.minX + 1;
45822  }
45823
45824  /**
45825   * @param {TileRange} tileRange Tile range.
45826   * @return {boolean} Intersects.
45827   */
45828  intersects(tileRange) {
45829    return (
45830      this.minX <= tileRange.maxX &&
45831      this.maxX >= tileRange.minX &&
45832      this.minY <= tileRange.maxY &&
45833      this.maxY >= tileRange.minY
45834    );
45835  }
45836}
45837
45838/**
45839 * @param {number} minX Minimum X.
45840 * @param {number} maxX Maximum X.
45841 * @param {number} minY Minimum Y.
45842 * @param {number} maxY Maximum Y.
45843 * @param {TileRange} [tileRange] TileRange.
45844 * @return {TileRange} Tile range.
45845 */
45846function TileRange_createOrUpdate(minX, maxX, minY, maxY, tileRange) {
45847  if (tileRange !== undefined) {
45848    tileRange.minX = minX;
45849    tileRange.maxX = maxX;
45850    tileRange.minY = minY;
45851    tileRange.maxY = maxY;
45852    return tileRange;
45853  } else {
45854    return new TileRange(minX, maxX, minY, maxY);
45855  }
45856}
45857
45858/* harmony default export */ const ol_TileRange = (TileRange);
45859
45860;// CONCATENATED MODULE: ./node_modules/ol/renderer/canvas/TileLayer.js
45861/**
45862 * @module ol/renderer/canvas/TileLayer
45863 */
45864
45865
45866
45867
45868
45869
45870
45871
45872
45873
45874
45875
45876/**
45877 * @classdesc
45878 * Canvas renderer for tile layers.
45879 * @api
45880 * @template {import("../../layer/Tile.js").default<import("../../source/Tile.js").default>|import("../../layer/VectorTile.js").default} [LayerType=import("../../layer/Tile.js").default<import("../../source/Tile.js").default>|import("../../layer/VectorTile.js").default]
45881 * @extends {CanvasLayerRenderer<LayerType>}
45882 */
45883class CanvasTileLayerRenderer extends canvas_Layer {
45884  /**
45885   * @param {LayerType} tileLayer Tile layer.
45886   */
45887  constructor(tileLayer) {
45888    super(tileLayer);
45889
45890    /**
45891     * Rendered extent has changed since the previous `renderFrame()` call
45892     * @type {boolean}
45893     */
45894    this.extentChanged = true;
45895
45896    /**
45897     * @private
45898     * @type {?import("../../extent.js").Extent}
45899     */
45900    this.renderedExtent_ = null;
45901
45902    /**
45903     * @protected
45904     * @type {number}
45905     */
45906    this.renderedPixelRatio;
45907
45908    /**
45909     * @protected
45910     * @type {import("../../proj/Projection.js").default}
45911     */
45912    this.renderedProjection = null;
45913
45914    /**
45915     * @protected
45916     * @type {number}
45917     */
45918    this.renderedRevision;
45919
45920    /**
45921     * @protected
45922     * @type {!Array<import("../../Tile.js").default>}
45923     */
45924    this.renderedTiles = [];
45925
45926    /**
45927     * @private
45928     * @type {boolean}
45929     */
45930    this.newTiles_ = false;
45931
45932    /**
45933     * @protected
45934     * @type {import("../../extent.js").Extent}
45935     */
45936    this.tmpExtent = createEmpty();
45937
45938    /**
45939     * @private
45940     * @type {import("../../TileRange.js").default}
45941     */
45942    this.tmpTileRange_ = new ol_TileRange(0, 0, 0, 0);
45943  }
45944
45945  /**
45946   * @protected
45947   * @param {import("../../Tile.js").default} tile Tile.
45948   * @return {boolean} Tile is drawable.
45949   */
45950  isDrawableTile(tile) {
45951    const tileLayer = this.getLayer();
45952    const tileState = tile.getState();
45953    const useInterimTilesOnError = tileLayer.getUseInterimTilesOnError();
45954    return (
45955      tileState == TileState.LOADED ||
45956      tileState == TileState.EMPTY ||
45957      (tileState == TileState.ERROR && !useInterimTilesOnError)
45958    );
45959  }
45960
45961  /**
45962   * @param {number} z Tile coordinate z.
45963   * @param {number} x Tile coordinate x.
45964   * @param {number} y Tile coordinate y.
45965   * @param {import("../../Map.js").FrameState} frameState Frame state.
45966   * @return {!import("../../Tile.js").default} Tile.
45967   */
45968  getTile(z, x, y, frameState) {
45969    const pixelRatio = frameState.pixelRatio;
45970    const projection = frameState.viewState.projection;
45971    const tileLayer = this.getLayer();
45972    const tileSource = tileLayer.getSource();
45973    let tile = tileSource.getTile(z, x, y, pixelRatio, projection);
45974    if (tile.getState() == TileState.ERROR) {
45975      if (tileLayer.getUseInterimTilesOnError() && tileLayer.getPreload() > 0) {
45976        // Preloaded tiles for lower resolutions might have finished loading.
45977        this.newTiles_ = true;
45978      }
45979    }
45980    if (!this.isDrawableTile(tile)) {
45981      tile = tile.getInterimTile();
45982    }
45983    return tile;
45984  }
45985
45986  /**
45987   * @param {import("../../pixel.js").Pixel} pixel Pixel.
45988   * @return {Uint8ClampedArray} Data at the pixel location.
45989   */
45990  getData(pixel) {
45991    const frameState = this.frameState;
45992    if (!frameState) {
45993      return null;
45994    }
45995
45996    const layer = this.getLayer();
45997    const coordinate = apply(
45998      frameState.pixelToCoordinateTransform,
45999      pixel.slice()
46000    );
46001
46002    const layerExtent = layer.getExtent();
46003    if (layerExtent) {
46004      if (!containsCoordinate(layerExtent, coordinate)) {
46005        return null;
46006      }
46007    }
46008
46009    const pixelRatio = frameState.pixelRatio;
46010    const projection = frameState.viewState.projection;
46011    const viewState = frameState.viewState;
46012    const source = layer.getRenderSource();
46013    const tileGrid = source.getTileGridForProjection(viewState.projection);
46014    const tilePixelRatio = source.getTilePixelRatio(frameState.pixelRatio);
46015
46016    for (
46017      let z = tileGrid.getZForResolution(viewState.resolution);
46018      z >= tileGrid.getMinZoom();
46019      --z
46020    ) {
46021      const tileCoord = tileGrid.getTileCoordForCoordAndZ(coordinate, z);
46022      const tile = source.getTile(
46023        z,
46024        tileCoord[1],
46025        tileCoord[2],
46026        pixelRatio,
46027        projection
46028      );
46029      if (!(tile instanceof ol_ImageTile || tile instanceof reproj_Tile)) {
46030        return null;
46031      }
46032
46033      if (tile.getState() !== TileState.LOADED) {
46034        continue;
46035      }
46036
46037      const tileOrigin = tileGrid.getOrigin(z);
46038      const tileSize = toSize(tileGrid.getTileSize(z));
46039      const tileResolution = tileGrid.getResolution(z);
46040
46041      const col = Math.floor(
46042        tilePixelRatio *
46043          ((coordinate[0] - tileOrigin[0]) / tileResolution -
46044            tileCoord[1] * tileSize[0])
46045      );
46046
46047      const row = Math.floor(
46048        tilePixelRatio *
46049          ((tileOrigin[1] - coordinate[1]) / tileResolution -
46050            tileCoord[2] * tileSize[1])
46051      );
46052
46053      const gutter = Math.round(
46054        tilePixelRatio * source.getGutterForProjection(viewState.projection)
46055      );
46056
46057      return this.getImageData(tile.getImage(), col + gutter, row + gutter);
46058    }
46059
46060    return null;
46061  }
46062
46063  /**
46064   * @param {Object<number, Object<string, import("../../Tile.js").default>>} tiles Lookup of loaded tiles by zoom level.
46065   * @param {number} zoom Zoom level.
46066   * @param {import("../../Tile.js").default} tile Tile.
46067   * @return {boolean|void} If `false`, the tile will not be considered loaded.
46068   */
46069  loadedTileCallback(tiles, zoom, tile) {
46070    if (this.isDrawableTile(tile)) {
46071      return super.loadedTileCallback(tiles, zoom, tile);
46072    }
46073    return false;
46074  }
46075
46076  /**
46077   * Determine whether render should be called.
46078   * @param {import("../../Map.js").FrameState} frameState Frame state.
46079   * @return {boolean} Layer is ready to be rendered.
46080   */
46081  prepareFrame(frameState) {
46082    return !!this.getLayer().getSource();
46083  }
46084
46085  /**
46086   * Render the layer.
46087   * @param {import("../../Map.js").FrameState} frameState Frame state.
46088   * @param {HTMLElement} target Target that may be used to render content to.
46089   * @return {HTMLElement} The rendered element.
46090   */
46091  renderFrame(frameState, target) {
46092    const layerState = frameState.layerStatesArray[frameState.layerIndex];
46093    const viewState = frameState.viewState;
46094    const projection = viewState.projection;
46095    const viewResolution = viewState.resolution;
46096    const viewCenter = viewState.center;
46097    const rotation = viewState.rotation;
46098    const pixelRatio = frameState.pixelRatio;
46099
46100    const tileLayer = this.getLayer();
46101    const tileSource = tileLayer.getSource();
46102    const sourceRevision = tileSource.getRevision();
46103    const tileGrid = tileSource.getTileGridForProjection(projection);
46104    const z = tileGrid.getZForResolution(viewResolution, tileSource.zDirection);
46105    const tileResolution = tileGrid.getResolution(z);
46106
46107    let extent = frameState.extent;
46108    const resolution = frameState.viewState.resolution;
46109    const tilePixelRatio = tileSource.getTilePixelRatio(pixelRatio);
46110    // desired dimensions of the canvas in pixels
46111    const width = Math.round((extent_getWidth(extent) / resolution) * pixelRatio);
46112    const height = Math.round((extent_getHeight(extent) / resolution) * pixelRatio);
46113
46114    const layerExtent =
46115      layerState.extent && proj_fromUserExtent(layerState.extent, projection);
46116    if (layerExtent) {
46117      extent = getIntersection(
46118        extent,
46119        proj_fromUserExtent(layerState.extent, projection)
46120      );
46121    }
46122
46123    const dx = (tileResolution * width) / 2 / tilePixelRatio;
46124    const dy = (tileResolution * height) / 2 / tilePixelRatio;
46125    const canvasExtent = [
46126      viewCenter[0] - dx,
46127      viewCenter[1] - dy,
46128      viewCenter[0] + dx,
46129      viewCenter[1] + dy,
46130    ];
46131
46132    const tileRange = tileGrid.getTileRangeForExtentAndZ(extent, z);
46133
46134    /**
46135     * @type {Object<number, Object<string, import("../../Tile.js").default>>}
46136     */
46137    const tilesToDrawByZ = {};
46138    tilesToDrawByZ[z] = {};
46139
46140    const findLoadedTiles = this.createLoadedTileFinder(
46141      tileSource,
46142      projection,
46143      tilesToDrawByZ
46144    );
46145
46146    const tmpExtent = this.tmpExtent;
46147    const tmpTileRange = this.tmpTileRange_;
46148    this.newTiles_ = false;
46149    const viewport = rotation
46150      ? getRotatedViewport(
46151          viewState.center,
46152          resolution,
46153          rotation,
46154          frameState.size
46155        )
46156      : undefined;
46157    for (let x = tileRange.minX; x <= tileRange.maxX; ++x) {
46158      for (let y = tileRange.minY; y <= tileRange.maxY; ++y) {
46159        if (
46160          rotation &&
46161          !tileGrid.tileCoordIntersectsViewport([z, x, y], viewport)
46162        ) {
46163          continue;
46164        }
46165        const tile = this.getTile(z, x, y, frameState);
46166        if (this.isDrawableTile(tile)) {
46167          const uid = getUid(this);
46168          if (tile.getState() == TileState.LOADED) {
46169            tilesToDrawByZ[z][tile.tileCoord.toString()] = tile;
46170            let inTransition = tile.inTransition(uid);
46171            if (inTransition && layerState.opacity !== 1) {
46172              // Skipping transition when layer is not fully opaque avoids visual artifacts.
46173              tile.endTransition(uid);
46174              inTransition = false;
46175            }
46176            if (
46177              !this.newTiles_ &&
46178              (inTransition || !this.renderedTiles.includes(tile))
46179            ) {
46180              this.newTiles_ = true;
46181            }
46182          }
46183          if (tile.getAlpha(uid, frameState.time) === 1) {
46184            // don't look for alt tiles if alpha is 1
46185            continue;
46186          }
46187        }
46188
46189        const childTileRange = tileGrid.getTileCoordChildTileRange(
46190          tile.tileCoord,
46191          tmpTileRange,
46192          tmpExtent
46193        );
46194
46195        let covered = false;
46196        if (childTileRange) {
46197          covered = findLoadedTiles(z + 1, childTileRange);
46198        }
46199        if (!covered) {
46200          tileGrid.forEachTileCoordParentTileRange(
46201            tile.tileCoord,
46202            findLoadedTiles,
46203            tmpTileRange,
46204            tmpExtent
46205          );
46206        }
46207      }
46208    }
46209
46210    const canvasScale =
46211      ((tileResolution / viewResolution) * pixelRatio) / tilePixelRatio;
46212
46213    // set forward and inverse pixel transforms
46214    compose(
46215      this.pixelTransform,
46216      frameState.size[0] / 2,
46217      frameState.size[1] / 2,
46218      1 / pixelRatio,
46219      1 / pixelRatio,
46220      rotation,
46221      -width / 2,
46222      -height / 2
46223    );
46224
46225    const canvasTransform = transform_toString(this.pixelTransform);
46226
46227    this.useContainer(target, canvasTransform, this.getBackground(frameState));
46228    const context = this.context;
46229    const canvas = context.canvas;
46230
46231    makeInverse(this.inversePixelTransform, this.pixelTransform);
46232
46233    // set scale transform for calculating tile positions on the canvas
46234    compose(
46235      this.tempTransform,
46236      width / 2,
46237      height / 2,
46238      canvasScale,
46239      canvasScale,
46240      0,
46241      -width / 2,
46242      -height / 2
46243    );
46244
46245    if (canvas.width != width || canvas.height != height) {
46246      canvas.width = width;
46247      canvas.height = height;
46248    } else if (!this.containerReused) {
46249      context.clearRect(0, 0, width, height);
46250    }
46251
46252    if (layerExtent) {
46253      this.clipUnrotated(context, frameState, layerExtent);
46254    }
46255
46256    if (!tileSource.getInterpolate()) {
46257      context.imageSmoothingEnabled = false;
46258    }
46259
46260    this.preRender(context, frameState);
46261
46262    this.renderedTiles.length = 0;
46263    /** @type {Array<number>} */
46264    let zs = Object.keys(tilesToDrawByZ).map(Number);
46265    zs.sort(numberSafeCompareFunction);
46266
46267    let clips, clipZs, currentClip;
46268    if (
46269      layerState.opacity === 1 &&
46270      (!this.containerReused ||
46271        tileSource.getOpaque(frameState.viewState.projection))
46272    ) {
46273      zs = zs.reverse();
46274    } else {
46275      clips = [];
46276      clipZs = [];
46277    }
46278    for (let i = zs.length - 1; i >= 0; --i) {
46279      const currentZ = zs[i];
46280      const currentTilePixelSize = tileSource.getTilePixelSize(
46281        currentZ,
46282        pixelRatio,
46283        projection
46284      );
46285      const currentResolution = tileGrid.getResolution(currentZ);
46286      const currentScale = currentResolution / tileResolution;
46287      const dx = currentTilePixelSize[0] * currentScale * canvasScale;
46288      const dy = currentTilePixelSize[1] * currentScale * canvasScale;
46289      const originTileCoord = tileGrid.getTileCoordForCoordAndZ(
46290        getTopLeft(canvasExtent),
46291        currentZ
46292      );
46293      const originTileExtent = tileGrid.getTileCoordExtent(originTileCoord);
46294      const origin = apply(this.tempTransform, [
46295        (tilePixelRatio * (originTileExtent[0] - canvasExtent[0])) /
46296          tileResolution,
46297        (tilePixelRatio * (canvasExtent[3] - originTileExtent[3])) /
46298          tileResolution,
46299      ]);
46300      const tileGutter =
46301        tilePixelRatio * tileSource.getGutterForProjection(projection);
46302      const tilesToDraw = tilesToDrawByZ[currentZ];
46303      for (const tileCoordKey in tilesToDraw) {
46304        const tile = /** @type {import("../../ImageTile.js").default} */ (
46305          tilesToDraw[tileCoordKey]
46306        );
46307        const tileCoord = tile.tileCoord;
46308
46309        // Calculate integer positions and sizes so that tiles align
46310        const xIndex = originTileCoord[1] - tileCoord[1];
46311        const nextX = Math.round(origin[0] - (xIndex - 1) * dx);
46312        const yIndex = originTileCoord[2] - tileCoord[2];
46313        const nextY = Math.round(origin[1] - (yIndex - 1) * dy);
46314        const x = Math.round(origin[0] - xIndex * dx);
46315        const y = Math.round(origin[1] - yIndex * dy);
46316        const w = nextX - x;
46317        const h = nextY - y;
46318        const transition = z === currentZ;
46319
46320        const inTransition =
46321          transition && tile.getAlpha(getUid(this), frameState.time) !== 1;
46322        let contextSaved = false;
46323        if (!inTransition) {
46324          if (clips) {
46325            // Clip mask for regions in this tile that already filled by a higher z tile
46326            currentClip = [x, y, x + w, y, x + w, y + h, x, y + h];
46327            for (let i = 0, ii = clips.length; i < ii; ++i) {
46328              if (z !== currentZ && currentZ < clipZs[i]) {
46329                const clip = clips[i];
46330                if (
46331                  intersects(
46332                    [x, y, x + w, y + h],
46333                    [clip[0], clip[3], clip[4], clip[7]]
46334                  )
46335                ) {
46336                  if (!contextSaved) {
46337                    context.save();
46338                    contextSaved = true;
46339                  }
46340                  context.beginPath();
46341                  // counter-clockwise (outer ring) for current tile
46342                  context.moveTo(currentClip[0], currentClip[1]);
46343                  context.lineTo(currentClip[2], currentClip[3]);
46344                  context.lineTo(currentClip[4], currentClip[5]);
46345                  context.lineTo(currentClip[6], currentClip[7]);
46346                  // clockwise (inner ring) for higher z tile
46347                  context.moveTo(clip[6], clip[7]);
46348                  context.lineTo(clip[4], clip[5]);
46349                  context.lineTo(clip[2], clip[3]);
46350                  context.lineTo(clip[0], clip[1]);
46351                  context.clip();
46352                }
46353              }
46354            }
46355            clips.push(currentClip);
46356            clipZs.push(currentZ);
46357          } else {
46358            context.clearRect(x, y, w, h);
46359          }
46360        }
46361        this.drawTileImage(
46362          tile,
46363          frameState,
46364          x,
46365          y,
46366          w,
46367          h,
46368          tileGutter,
46369          transition
46370        );
46371        if (clips && !inTransition) {
46372          if (contextSaved) {
46373            context.restore();
46374          }
46375          this.renderedTiles.unshift(tile);
46376        } else {
46377          this.renderedTiles.push(tile);
46378        }
46379        this.updateUsedTiles(frameState.usedTiles, tileSource, tile);
46380      }
46381    }
46382
46383    this.renderedRevision = sourceRevision;
46384    this.renderedResolution = tileResolution;
46385    this.extentChanged =
46386      !this.renderedExtent_ || !extent_equals(this.renderedExtent_, canvasExtent);
46387    this.renderedExtent_ = canvasExtent;
46388    this.renderedPixelRatio = pixelRatio;
46389    this.renderedProjection = projection;
46390
46391    this.manageTilePyramid(
46392      frameState,
46393      tileSource,
46394      tileGrid,
46395      pixelRatio,
46396      projection,
46397      extent,
46398      z,
46399      tileLayer.getPreload()
46400    );
46401    this.scheduleExpireCache(frameState, tileSource);
46402
46403    this.postRender(context, frameState);
46404
46405    if (layerState.extent) {
46406      context.restore();
46407    }
46408    context.imageSmoothingEnabled = true;
46409
46410    if (canvasTransform !== canvas.style.transform) {
46411      canvas.style.transform = canvasTransform;
46412    }
46413
46414    return this.container;
46415  }
46416
46417  /**
46418   * @param {import("../../ImageTile.js").default} tile Tile.
46419   * @param {import("../../Map.js").FrameState} frameState Frame state.
46420   * @param {number} x Left of the tile.
46421   * @param {number} y Top of the tile.
46422   * @param {number} w Width of the tile.
46423   * @param {number} h Height of the tile.
46424   * @param {number} gutter Tile gutter.
46425   * @param {boolean} transition Apply an alpha transition.
46426   */
46427  drawTileImage(tile, frameState, x, y, w, h, gutter, transition) {
46428    const image = this.getTileImage(tile);
46429    if (!image) {
46430      return;
46431    }
46432    const uid = getUid(this);
46433    const layerState = frameState.layerStatesArray[frameState.layerIndex];
46434    const alpha =
46435      layerState.opacity *
46436      (transition ? tile.getAlpha(uid, frameState.time) : 1);
46437    const alphaChanged = alpha !== this.context.globalAlpha;
46438    if (alphaChanged) {
46439      this.context.save();
46440      this.context.globalAlpha = alpha;
46441    }
46442    this.context.drawImage(
46443      image,
46444      gutter,
46445      gutter,
46446      image.width - 2 * gutter,
46447      image.height - 2 * gutter,
46448      x,
46449      y,
46450      w,
46451      h
46452    );
46453
46454    if (alphaChanged) {
46455      this.context.restore();
46456    }
46457    if (alpha !== layerState.opacity) {
46458      frameState.animate = true;
46459    } else if (transition) {
46460      tile.endTransition(uid);
46461    }
46462  }
46463
46464  /**
46465   * @return {HTMLCanvasElement} Image
46466   */
46467  getImage() {
46468    const context = this.context;
46469    return context ? context.canvas : null;
46470  }
46471
46472  /**
46473   * Get the image from a tile.
46474   * @param {import("../../ImageTile.js").default} tile Tile.
46475   * @return {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} Image.
46476   * @protected
46477   */
46478  getTileImage(tile) {
46479    return tile.getImage();
46480  }
46481
46482  /**
46483   * @param {import("../../Map.js").FrameState} frameState Frame state.
46484   * @param {import("../../source/Tile.js").default} tileSource Tile source.
46485   * @protected
46486   */
46487  scheduleExpireCache(frameState, tileSource) {
46488    if (tileSource.canExpireCache()) {
46489      /**
46490       * @param {import("../../source/Tile.js").default} tileSource Tile source.
46491       * @param {import("../../Map.js").default} map Map.
46492       * @param {import("../../Map.js").FrameState} frameState Frame state.
46493       */
46494      const postRenderFunction = function (tileSource, map, frameState) {
46495        const tileSourceKey = getUid(tileSource);
46496        if (tileSourceKey in frameState.usedTiles) {
46497          tileSource.expireCache(
46498            frameState.viewState.projection,
46499            frameState.usedTiles[tileSourceKey]
46500          );
46501        }
46502      }.bind(null, tileSource);
46503
46504      frameState.postRenderFunctions.push(
46505        /** @type {import("../../Map.js").PostRenderFunction} */ (
46506          postRenderFunction
46507        )
46508      );
46509    }
46510  }
46511
46512  /**
46513   * @param {!Object<string, !Object<string, boolean>>} usedTiles Used tiles.
46514   * @param {import("../../source/Tile.js").default} tileSource Tile source.
46515   * @param {import('../../Tile.js').default} tile Tile.
46516   * @protected
46517   */
46518  updateUsedTiles(usedTiles, tileSource, tile) {
46519    // FIXME should we use tilesToDrawByZ instead?
46520    const tileSourceKey = getUid(tileSource);
46521    if (!(tileSourceKey in usedTiles)) {
46522      usedTiles[tileSourceKey] = {};
46523    }
46524    usedTiles[tileSourceKey][tile.getKey()] = true;
46525  }
46526
46527  /**
46528   * Manage tile pyramid.
46529   * This function performs a number of functions related to the tiles at the
46530   * current zoom and lower zoom levels:
46531   * - registers idle tiles in frameState.wantedTiles so that they are not
46532   *   discarded by the tile queue
46533   * - enqueues missing tiles
46534   * @param {import("../../Map.js").FrameState} frameState Frame state.
46535   * @param {import("../../source/Tile.js").default} tileSource Tile source.
46536   * @param {import("../../tilegrid/TileGrid.js").default} tileGrid Tile grid.
46537   * @param {number} pixelRatio Pixel ratio.
46538   * @param {import("../../proj/Projection.js").default} projection Projection.
46539   * @param {import("../../extent.js").Extent} extent Extent.
46540   * @param {number} currentZ Current Z.
46541   * @param {number} preload Load low resolution tiles up to `preload` levels.
46542   * @param {function(import("../../Tile.js").default):void} [tileCallback] Tile callback.
46543   * @protected
46544   */
46545  manageTilePyramid(
46546    frameState,
46547    tileSource,
46548    tileGrid,
46549    pixelRatio,
46550    projection,
46551    extent,
46552    currentZ,
46553    preload,
46554    tileCallback
46555  ) {
46556    const tileSourceKey = getUid(tileSource);
46557    if (!(tileSourceKey in frameState.wantedTiles)) {
46558      frameState.wantedTiles[tileSourceKey] = {};
46559    }
46560    const wantedTiles = frameState.wantedTiles[tileSourceKey];
46561    const tileQueue = frameState.tileQueue;
46562    const minZoom = tileGrid.getMinZoom();
46563    const rotation = frameState.viewState.rotation;
46564    const viewport = rotation
46565      ? getRotatedViewport(
46566          frameState.viewState.center,
46567          frameState.viewState.resolution,
46568          rotation,
46569          frameState.size
46570        )
46571      : undefined;
46572    let tileCount = 0;
46573    let tile, tileRange, tileResolution, x, y, z;
46574    for (z = minZoom; z <= currentZ; ++z) {
46575      tileRange = tileGrid.getTileRangeForExtentAndZ(extent, z, tileRange);
46576      tileResolution = tileGrid.getResolution(z);
46577      for (x = tileRange.minX; x <= tileRange.maxX; ++x) {
46578        for (y = tileRange.minY; y <= tileRange.maxY; ++y) {
46579          if (
46580            rotation &&
46581            !tileGrid.tileCoordIntersectsViewport([z, x, y], viewport)
46582          ) {
46583            continue;
46584          }
46585          if (currentZ - z <= preload) {
46586            ++tileCount;
46587            tile = tileSource.getTile(z, x, y, pixelRatio, projection);
46588            if (tile.getState() == TileState.IDLE) {
46589              wantedTiles[tile.getKey()] = true;
46590              if (!tileQueue.isKeyQueued(tile.getKey())) {
46591                tileQueue.enqueue([
46592                  tile,
46593                  tileSourceKey,
46594                  tileGrid.getTileCoordCenter(tile.tileCoord),
46595                  tileResolution,
46596                ]);
46597              }
46598            }
46599            if (tileCallback !== undefined) {
46600              tileCallback(tile);
46601            }
46602          } else {
46603            tileSource.useTile(z, x, y, projection);
46604          }
46605        }
46606      }
46607    }
46608    tileSource.updateCacheSize(tileCount, projection);
46609  }
46610}
46611
46612/* harmony default export */ const canvas_TileLayer = (CanvasTileLayerRenderer);
46613
46614;// CONCATENATED MODULE: ./node_modules/ol/layer/Tile.js
46615/**
46616 * @module ol/layer/Tile
46617 */
46618
46619
46620
46621/**
46622 * @classdesc
46623 * For layer sources that provide pre-rendered, tiled images in grids that are
46624 * organized by zoom levels for specific resolutions.
46625 * Note that any property set in the options is set as a {@link module:ol/Object~BaseObject}
46626 * property on the layer object; for example, setting `title: 'My Title'` in the
46627 * options means that `title` is observable, and has get/set accessors.
46628 *
46629 * @template {import("../source/Tile.js").default} TileSourceType
46630 * @extends BaseTileLayer<TileSourceType, CanvasTileLayerRenderer>
46631 * @api
46632 */
46633class TileLayer extends BaseTile {
46634  /**
46635   * @param {import("./BaseTile.js").Options<TileSourceType>} [options] Tile layer options.
46636   */
46637  constructor(options) {
46638    super(options);
46639  }
46640
46641  createRenderer() {
46642    return new canvas_TileLayer(this);
46643  }
46644}
46645
46646/* harmony default export */ const layer_Tile = (TileLayer);
46647
46648;// CONCATENATED MODULE: ./node_modules/ol/structs/LRUCache.js
46649/**
46650 * @module ol/structs/LRUCache
46651 */
46652
46653
46654
46655/**
46656 * @typedef {Object} Entry
46657 * @property {string} key_ Key.
46658 * @property {Object} newer Newer.
46659 * @property {Object} older Older.
46660 * @property {*} value_ Value.
46661 */
46662
46663/**
46664 * @classdesc
46665 * Implements a Least-Recently-Used cache where the keys do not conflict with
46666 * Object's properties (e.g. 'hasOwnProperty' is not allowed as a key). Expiring
46667 * items from the cache is the responsibility of the user.
46668 *
46669 * @fires import("../events/Event.js").default
46670 * @template T
46671 */
46672class LRUCache {
46673  /**
46674   * @param {number} [highWaterMark] High water mark.
46675   */
46676  constructor(highWaterMark) {
46677    /**
46678     * Desired max cache size after expireCache(). If set to 0, no cache entries
46679     * will be pruned at all.
46680     * @type {number}
46681     */
46682    this.highWaterMark = highWaterMark !== undefined ? highWaterMark : 2048;
46683
46684    /**
46685     * @private
46686     * @type {number}
46687     */
46688    this.count_ = 0;
46689
46690    /**
46691     * @private
46692     * @type {!Object<string, Entry>}
46693     */
46694    this.entries_ = {};
46695
46696    /**
46697     * @private
46698     * @type {?Entry}
46699     */
46700    this.oldest_ = null;
46701
46702    /**
46703     * @private
46704     * @type {?Entry}
46705     */
46706    this.newest_ = null;
46707  }
46708
46709  /**
46710   * @return {boolean} Can expire cache.
46711   */
46712  canExpireCache() {
46713    return this.highWaterMark > 0 && this.getCount() > this.highWaterMark;
46714  }
46715
46716  /**
46717   * Expire the cache.
46718   * @param {!Object<string, boolean>} [keep] Keys to keep. To be implemented by subclasses.
46719   */
46720  expireCache(keep) {
46721    while (this.canExpireCache()) {
46722      this.pop();
46723    }
46724  }
46725
46726  /**
46727   * FIXME empty description for jsdoc
46728   */
46729  clear() {
46730    this.count_ = 0;
46731    this.entries_ = {};
46732    this.oldest_ = null;
46733    this.newest_ = null;
46734  }
46735
46736  /**
46737   * @param {string} key Key.
46738   * @return {boolean} Contains key.
46739   */
46740  containsKey(key) {
46741    return this.entries_.hasOwnProperty(key);
46742  }
46743
46744  /**
46745   * @param {function(T, string, LRUCache<T>): ?} f The function
46746   *     to call for every entry from the oldest to the newer. This function takes
46747   *     3 arguments (the entry value, the entry key and the LRUCache object).
46748   *     The return value is ignored.
46749   */
46750  forEach(f) {
46751    let entry = this.oldest_;
46752    while (entry) {
46753      f(entry.value_, entry.key_, this);
46754      entry = entry.newer;
46755    }
46756  }
46757
46758  /**
46759   * @param {string} key Key.
46760   * @param {*} [options] Options (reserved for subclasses).
46761   * @return {T} Value.
46762   */
46763  get(key, options) {
46764    const entry = this.entries_[key];
46765    asserts_assert(entry !== undefined, 15);
46765 // Tried to get a value for a key that does not exist in the cache
46766    if (entry === this.newest_) {
46767      return entry.value_;
46768    } else if (entry === this.oldest_) {
46769      this.oldest_ = /** @type {Entry} */ (this.oldest_.newer);
46770      this.oldest_.older = null;
46771    } else {
46772      entry.newer.older = entry.older;
46773      entry.older.newer = entry.newer;
46774    }
46775    entry.newer = null;
46776    entry.older = this.newest_;
46777    this.newest_.newer = entry;
46778    this.newest_ = entry;
46779    return entry.value_;
46780  }
46781
46782  /**
46783   * Remove an entry from the cache.
46784   * @param {string} key The entry key.
46785   * @return {T} The removed entry.
46786   */
46787  remove(key) {
46788    const entry = this.entries_[key];
46789    asserts_assert(entry !== undefined, 15); // Tried to get a value for a key that does not exist in the cache
46790    if (entry === this.newest_) {
46791      this.newest_ = /** @type {Entry} */ (entry.older);
46792      if (this.newest_) {
46793        this.newest_.newer = null;
46794      }
46795    } else if (entry === this.oldest_) {
46796      this.oldest_ = /** @type {Entry} */ (entry.newer);
46797      if (this.oldest_) {
46798        this.oldest_.older = null;
46799      }
46800    } else {
46801      entry.newer.older = entry.older;
46802      entry.older.newer = entry.newer;
46803    }
46804    delete this.entries_[key];
46805    --this.count_;
46806    return entry.value_;
46807  }
46808
46809  /**
46810   * @return {number} Count.
46811   */
46812  getCount() {
46813    return this.count_;
46814  }
46815
46816  /**
46817   * @return {Array<string>} Keys.
46818   */
46819  getKeys() {
46820    const keys = new Array(this.count_);
46821    let i = 0;
46822    let entry;
46823    for (entry = this.newest_; entry; entry = entry.older) {
46824      keys[i++] = entry.key_;
46825    }
46826    return keys;
46827  }
46828
46829  /**
46830   * @return {Array<T>} Values.
46831   */
46832  getValues() {
46833    const values = new Array(this.count_);
46834    let i = 0;
46835    let entry;
46836    for (entry = this.newest_; entry; entry = entry.older) {
46837      values[i++] = entry.value_;
46838    }
46839    return values;
46840  }
46841
46842  /**
46843   * @return {T} Last value.
46844   */
46845  peekLast() {
46846    return this.oldest_.value_;
46847  }
46848
46849  /**
46850   * @return {string} Last key.
46851   */
46852  peekLastKey() {
46853    return this.oldest_.key_;
46854  }
46855
46856  /**
46857   * Get the key of the newest item in the cache.  Throws if the cache is empty.
46858   * @return {string} The newest key.
46859   */
46860  peekFirstKey() {
46861    return this.newest_.key_;
46862  }
46863
46864  /**
46865   * Return an entry without updating least recently used time.
46866   * @param {string} key Key.
46867   * @return {T} Value.
46868   */
46869  peek(key) {
46870    if (!this.containsKey(key)) {
46871      return undefined;
46872    }
46873    return this.entries_[key].value_;
46874  }
46875
46876  /**
46877   * @return {T} value Value.
46878   */
46879  pop() {
46880    const entry = this.oldest_;
46881    delete this.entries_[entry.key_];
46882    if (entry.newer) {
46883      entry.newer.older = null;
46884    }
46885    this.oldest_ = /** @type {Entry} */ (entry.newer);
46886    if (!this.oldest_) {
46887      this.newest_ = null;
46888    }
46889    --this.count_;
46890    return entry.value_;
46891  }
46892
46893  /**
46894   * @param {string} key Key.
46895   * @param {T} value Value.
46896   */
46897  replace(key, value) {
46898    this.get(key); // update `newest_`
46899    this.entries_[key].value_ = value;
46900  }
46901
46902  /**
46903   * @param {string} key Key.
46904   * @param {T} value Value.
46905   */
46906  set(key, value) {
46907    asserts_assert(!(key in this.entries_), 16); // Tried to set a value for a key that is used already
46908    const entry = {
46909      key_: key,
46910      newer: null,
46911      older: this.newest_,
46912      value_: value,
46913    };
46914    if (!this.newest_) {
46915      this.oldest_ = entry;
46916    } else {
46917      this.newest_.newer = entry;
46918    }
46919    this.newest_ = entry;
46920    this.entries_[key] = entry;
46921    ++this.count_;
46922  }
46923
46924  /**
46925   * Set a maximum number of entries for the cache.
46926   * @param {number} size Cache size.
46927   * @api
46928   */
46929  setSize(size) {
46930    this.highWaterMark = size;
46931  }
46932}
46933
46934/* harmony default export */ const structs_LRUCache = (LRUCache);
46935
46936;// CONCATENATED MODULE: ./node_modules/ol/tilecoord.js
46937/**
46938 * @module ol/tilecoord
46939 */
46940
46941/**
46942 * An array of three numbers representing the location of a tile in a tile
46943 * grid. The order is `z` (zoom level), `x` (column), and `y` (row).
46944 * @typedef {Array<number>} TileCoord
46945 * @api
46946 */
46947
46948/**
46949 * @param {number} z Z.
46950 * @param {number} x X.
46951 * @param {number} y Y.
46952 * @param {TileCoord} [tileCoord] Tile coordinate.
46953 * @return {TileCoord} Tile coordinate.
46954 */
46955function tilecoord_createOrUpdate(z, x, y, tileCoord) {
46956  if (tileCoord !== undefined) {
46957    tileCoord[0] = z;
46958    tileCoord[1] = x;
46959    tileCoord[2] = y;
46960    return tileCoord;
46961  } else {
46962    return [z, x, y];
46963  }
46964}
46965
46966/**
46967 * @param {number} z Z.
46968 * @param {number} x X.
46969 * @param {number} y Y.
46970 * @return {string} Key.
46971 */
46972function getKeyZXY(z, x, y) {
46973  return z + '/' + x + '/' + y;
46974}
46975
46976/**
46977 * Get the key for a tile coord.
46978 * @param {TileCoord} tileCoord The tile coord.
46979 * @return {string} Key.
46980 */
46981function tilecoord_getKey(tileCoord) {
46982  return getKeyZXY(tileCoord[0], tileCoord[1], tileCoord[2]);
46983}
46984
46985/**
46986 * Get the tile cache key for a tile key obtained through `tile.getKey()`.
46987 * @param {string} tileKey The tile key.
46988 * @return {string} The cache key.
46989 */
46990function getCacheKeyForTileKey(tileKey) {
46991  const [z, x, y] = tileKey
46992    .substring(tileKey.lastIndexOf('/') + 1, tileKey.length)
46993    .split(',')
46994    .map(Number);
46995  return getKeyZXY(z, x, y);
46996}
46997
46998/**
46999 * Get a tile coord given a key.
47000 * @param {string} key The tile coord key.
47001 * @return {TileCoord} The tile coord.
47002 */
47003function fromKey(key) {
47004  return key.split('/').map(Number);
47005}
47006
47007/**
47008 * @param {TileCoord} tileCoord Tile coord.
47009 * @return {number} Hash.
47010 */
47011function hash(tileCoord) {
47012  return (tileCoord[1] << tileCoord[0]) + tileCoord[2];
47013}
47014
47015/**
47016 * @param {TileCoord} tileCoord Tile coordinate.
47017 * @param {!import("./tilegrid/TileGrid.js").default} tileGrid Tile grid.
47018 * @return {boolean} Tile coordinate is within extent and zoom level range.
47019 */
47020function withinExtentAndZ(tileCoord, tileGrid) {
47021  const z = tileCoord[0];
47022  const x = tileCoord[1];
47023  const y = tileCoord[2];
47024
47025  if (tileGrid.getMinZoom() > z || z > tileGrid.getMaxZoom()) {
47026    return false;
47027  }
47028  const tileRange = tileGrid.getFullTileRange(z);
47029  if (!tileRange) {
47030    return true;
47031  } else {
47032    return tileRange.containsXY(x, y);
47033  }
47034}
47035
47036;// CONCATENATED MODULE: ./node_modules/ol/TileCache.js
47037/**
47038 * @module ol/TileCache
47039 */
47040
47041
47042
47043class TileCache extends structs_LRUCache {
47044  clear() {
47045    while (this.getCount() > 0) {
47046      this.pop().release();
47047    }
47048    super.clear();
47049  }
47050
47051  /**
47052   * @param {!Object<string, boolean>} usedTiles Used tiles.
47053   */
47054  expireCache(usedTiles) {
47055    while (this.canExpireCache()) {
47056      const tile = this.peekLast();
47057      if (tile.getKey() in usedTiles) {
47058        break;
47059      } else {
47060        this.pop().release();
47061      }
47062    }
47063  }
47064
47065  /**
47066   * Prune all tiles from the cache that don't have the same z as the newest tile.
47067   */
47068  pruneExceptNewestZ() {
47069    if (this.getCount() === 0) {
47070      return;
47071    }
47072    const key = this.peekFirstKey();
47073    const tileCoord = fromKey(key);
47074    const z = tileCoord[0];
47075    this.forEach(
47076      function (tile) {
47077        if (tile.tileCoord[0] !== z) {
47078          this.remove(tilecoord_getKey(tile.tileCoord));
47079          tile.release();
47080        }
47081      }.bind(this)
47082    );
47083  }
47084}
47085
47086/* harmony default export */ const ol_TileCache = (TileCache);
47087
47088;// CONCATENATED MODULE: ./node_modules/ol/source/TileEventType.js
47089/**
47090 * @module ol/source/TileEventType
47091 */
47092
47093/**
47094 * @enum {string}
47095 */
47096/* harmony default export */ const TileEventType = ({
47097  /**
47098   * Triggered when a tile starts loading.
47099   * @event module:ol/source/Tile.TileSourceEvent#tileloadstart
47100   * @api
47101   */
47102  TILELOADSTART: 'tileloadstart',
47103
47104  /**
47105   * Triggered when a tile finishes loading, either when its data is loaded,
47106   * or when loading was aborted because the tile is no longer needed.
47107   * @event module:ol/source/Tile.TileSourceEvent#tileloadend
47108   * @api
47109   */
47110  TILELOADEND: 'tileloadend',
47111
47112  /**
47113   * Triggered if tile loading results in an error. Note that this is not the
47114   * right place to re-fetch tiles. See {@link module:ol/ImageTile~ImageTile#load}
47115   * for details.
47116   * @event module:ol/source/Tile.TileSourceEvent#tileloaderror
47117   * @api
47118   */
47119  TILELOADERROR: 'tileloaderror',
47120});
47121
47122/**
47123 * @typedef {'tileloadstart'|'tileloadend'|'tileloaderror'} TileSourceEventTypes
47124 */
47125
47126;// CONCATENATED MODULE: ./node_modules/ol/source/Source.js
47127/**
47128 * @module ol/source/Source
47129 */
47130
47131
47132
47133
47134/**
47135 * @typedef {'undefined' | 'loading' | 'ready' | 'error'} State
47136 * State of the source, one of 'undefined', 'loading', 'ready' or 'error'.
47137 */
47138
47139/**
47140 * A function that takes a {@link module:ol/Map~FrameState} and returns a string or
47141 * an array of strings representing source attributions.
47142 *
47143 * @typedef {function(import("../Map.js").FrameState): (string|Array<string>)} Attribution
47144 */
47145
47146/**
47147 * A type that can be used to provide attribution information for data sources.
47148 *
47149 * It represents either
47150 * * a simple string (e.g. `'© Acme Inc.'`)
47151 * * an array of simple strings (e.g. `['© Acme Inc.', '© Bacme Inc.']`)
47152 * * a function that returns a string or array of strings ({@link module:ol/source/Source~Attribution})
47153 *
47154 * @typedef {string|Array<string>|Attribution} AttributionLike
47155 */
47156
47157/**
47158 * @typedef {Object} Options
47159 * @property {AttributionLike} [attributions] Attributions.
47160 * @property {boolean} [attributionsCollapsible=true] Attributions are collapsible.
47161 * @property {import("../proj.js").ProjectionLike} [projection] Projection. Default is the view projection.
47162 * @property {import("./Source.js").State} [state='ready'] State.
47163 * @property {boolean} [wrapX=false] WrapX.
47164 * @property {boolean} [interpolate=false] Use interpolated values when resampling.  By default,
47165 * the nearest neighbor is used when resampling.
47166 */
47167
47168/**
47169 * @classdesc
47170 * Abstract base class; normally only used for creating subclasses and not
47171 * instantiated in apps.
47172 * Base class for {@link module:ol/layer/Layer~Layer} sources.
47173 *
47174 * A generic `change` event is triggered when the state of the source changes.
47175 * @abstract
47176 * @api
47177 */
47178class Source extends ol_Object {
47179  /**
47180   * @param {Options} options Source options.
47181   */
47182  constructor(options) {
47183    super();
47184
47185    /**
47186     * @protected
47187     * @type {import("../proj/Projection.js").default|null}
47188     */
47189    this.projection = proj_get(options.projection);
47190
47191    /**
47192     * @private
47193     * @type {?Attribution}
47194     */
47195    this.attributions_ = adaptAttributions(options.attributions);
47196
47197    /**
47198     * @private
47199     * @type {boolean}
47200     */
47201    this.attributionsCollapsible_ =
47202      options.attributionsCollapsible !== undefined
47203        ? options.attributionsCollapsible
47204        : true;
47205
47206    /**
47207     * This source is currently loading data. Sources that defer loading to the
47208     * map's tile queue never set this to `true`.
47209     * @type {boolean}
47210     */
47211    this.loading = false;
47212
47213    /**
47214     * @private
47215     * @type {import("./Source.js").State}
47216     */
47217    this.state_ = options.state !== undefined ? options.state : 'ready';
47218
47219    /**
47220     * @private
47221     * @type {boolean}
47222     */
47223    this.wrapX_ = options.wrapX !== undefined ? options.wrapX : false;
47224
47225    /**
47226     * @private
47227     * @type {boolean}
47228     */
47229    this.interpolate_ = !!options.interpolate;
47230
47231    /**
47232     * @protected
47233     * @type {function(import("../View.js").ViewOptions):void}
47234     */
47235    this.viewResolver = null;
47236
47237    /**
47238     * @protected
47239     * @type {function(Error):void}
47240     */
47241    this.viewRejector = null;
47242
47243    const self = this;
47244    /**
47245     * @private
47246     * @type {Promise<import("../View.js").ViewOptions>}
47247     */
47248    this.viewPromise_ = new Promise(function (resolve, reject) {
47249      self.viewResolver = resolve;
47250      self.viewRejector = reject;
47251    });
47252  }
47253
47254  /**
47255   * Get the attribution function for the source.
47256   * @return {?Attribution} Attribution function.
47257   * @api
47258   */
47259  getAttributions() {
47260    return this.attributions_;
47261  }
47262
47263  /**
47264   * @return {boolean} Attributions are collapsible.
47265   * @api
47266   */
47267  getAttributionsCollapsible() {
47268    return this.attributionsCollapsible_;
47269  }
47270
47271  /**
47272   * Get the projection of the source.
47273   * @return {import("../proj/Projection.js").default|null} Projection.
47274   * @api
47275   */
47276  getProjection() {
47277    return this.projection;
47278  }
47279
47280  /**
47281   * @abstract
47282   * @return {Array<number>|null} Resolutions.
47283   */
47284  getResolutions() {
47285    return util_abstract();
47286  }
47287
47288  /**
47289   * @return {Promise<import("../View.js").ViewOptions>} A promise for view-related properties.
47290   */
47291  getView() {
47292    return this.viewPromise_;
47293  }
47294
47295  /**
47296   * Get the state of the source, see {@link import("./Source.js").State} for possible states.
47297   * @return {import("./Source.js").State} State.
47298   * @api
47299   */
47300  getState() {
47301    return this.state_;
47302  }
47303
47304  /**
47305   * @return {boolean|undefined} Wrap X.
47306   */
47307  getWrapX() {
47308    return this.wrapX_;
47309  }
47310
47311  /**
47312   * @return {boolean} Use linear interpolation when resampling.
47313   */
47314  getInterpolate() {
47315    return this.interpolate_;
47316  }
47317
47318  /**
47319   * Refreshes the source. The source will be cleared, and data from the server will be reloaded.
47320   * @api
47321   */
47322  refresh() {
47323    this.changed();
47324  }
47325
47326  /**
47327   * Set the attributions of the source.
47328   * @param {AttributionLike|undefined} attributions Attributions.
47329   *     Can be passed as `string`, `Array<string>`, {@link module:ol/source/Source~Attribution},
47330   *     or `undefined`.
47331   * @api
47332   */
47333  setAttributions(attributions) {
47334    this.attributions_ = adaptAttributions(attributions);
47335    this.changed();
47336  }
47337
47338  /**
47339   * Set the state of the source.
47340   * @param {import("./Source.js").State} state State.
47341   */
47342  setState(state) {
47343    this.state_ = state;
47344    this.changed();
47345  }
47346}
47347
47348/**
47349 * Turns the attributions option into an attributions function.
47350 * @param {AttributionLike|undefined} attributionLike The attribution option.
47351 * @return {Attribution|null} An attribution function (or null).
47352 */
47353function adaptAttributions(attributionLike) {
47354  if (!attributionLike) {
47355    return null;
47356  }
47357  if (Array.isArray(attributionLike)) {
47358    return function (frameState) {
47359      return attributionLike;
47360    };
47361  }
47362
47363  if (typeof attributionLike === 'function') {
47364    return attributionLike;
47365  }
47366
47367  return function (frameState) {
47368    return [attributionLike];
47369  };
47370}
47371
47372/* harmony default export */ const source_Source = (Source);
47373
47374;// CONCATENATED MODULE: ./node_modules/ol/tilegrid/TileGrid.js
47375/**
47376 * @module ol/tilegrid/TileGrid
47377 */
47378
47379
47380
47381
47382
47383
47384
47385
47386
47387
47388/**
47389 * @private
47390 * @type {import("../tilecoord.js").TileCoord}
47391 */
47392const tmpTileCoord = [0, 0, 0];
47393
47394/**
47395 * Number of decimal digits to consider in integer values when rounding.
47396 * @type {number}
47397 */
47398const DECIMALS = 5;
47399
47400/**
47401 * @typedef {Object} Options
47402 * @property {import("../extent.js").Extent} [extent] Extent for the tile grid. No tiles outside this
47403 * extent will be requested by {@link module:ol/source/Tile~TileSource} sources. When no `origin` or
47404 * `origins` are configured, the `origin` will be set to the top-left corner of the extent.
47405 * @property {number} [minZoom=0] Minimum zoom.
47406 * @property {import("../coordinate.js").Coordinate} [origin] The tile grid origin, i.e. where the `x`
47407 * and `y` axes meet (`[z, 0, 0]`). Tile coordinates increase left to right and downwards. If not
47408 * specified, `extent` or `origins` must be provided.
47409 * @property {Array<import("../coordinate.js").Coordinate>} [origins] Tile grid origins, i.e. where
47410 * the `x` and `y` axes meet (`[z, 0, 0]`), for each zoom level. If given, the array length
47411 * should match the length of the `resolutions` array, i.e. each resolution can have a different
47412 * origin. Tile coordinates increase left to right and downwards. If not specified, `extent` or
47413 * `origin` must be provided.
47414 * @property {!Array<number>} resolutions Resolutions. The array index of each resolution needs
47415 * to match the zoom level. This means that even if a `minZoom` is configured, the resolutions
47416 * array will have a length of `maxZoom + 1`.
47417 * @property {Array<import("../size.js").Size>} [sizes] Number of tile rows and columns
47418 * of the grid for each zoom level. If specified the values
47419 * define each zoom level's extent together with the `origin` or `origins`.
47420 * A grid `extent` can be configured in addition, and will further limit the extent
47421 * for which tile requests are made by sources. If the bottom-left corner of
47422 * an extent is used as `origin` or `origins`, then the `y` value must be
47423 * negative because OpenLayers tile coordinates use the top left as the origin.
47424 * @property {number|import("../size.js").Size} [tileSize] Tile size.
47425 * Default is `[256, 256]`.
47426 * @property {Array<number|import("../size.js").Size>} [tileSizes] Tile sizes. If given, the array length
47427 * should match the length of the `resolutions` array, i.e. each resolution can have a different
47428 * tile size.
47429 */
47430
47431/**
47432 * @classdesc
47433 * Base class for setting the grid pattern for sources accessing tiled-image
47434 * servers.
47435 * @api
47436 */
47437class TileGrid {
47438  /**
47439   * @param {Options} options Tile grid options.
47440   */
47441  constructor(options) {
47442    /**
47443     * @protected
47444     * @type {number}
47445     */
47446    this.minZoom = options.minZoom !== undefined ? options.minZoom : 0;
47447
47448    /**
47449     * @private
47450     * @type {!Array<number>}
47451     */
47452    this.resolutions_ = options.resolutions;
47453    asserts_assert(
47454      isSorted(
47455        this.resolutions_,
47456        function (a, b) {
47457          return b - a;
47458        },
47459        true
47460      ),
47461      17
47462    ); // `resolutions` must be sorted in descending order
47463
47464    // check if we've got a consistent zoom factor and origin
47465    let zoomFactor;
47466    if (!options.origins) {
47467      for (let i = 0, ii = this.resolutions_.length - 1; i < ii; ++i) {
47468        if (!zoomFactor) {
47469          zoomFactor = this.resolutions_[i] / this.resolutions_[i + 1];
47470        } else {
47471          if (this.resolutions_[i] / this.resolutions_[i + 1] !== zoomFactor) {
47472            zoomFactor = undefined;
47473            break;
47474          }
47475        }
47476      }
47477    }
47478
47479    /**
47480     * @private
47481     * @type {number|undefined}
47482     */
47483    this.zoomFactor_ = zoomFactor;
47484
47485    /**
47486     * @protected
47487     * @type {number}
47488     */
47489    this.maxZoom = this.resolutions_.length - 1;
47490
47491    /**
47492     * @private
47493     * @type {import("../coordinate.js").Coordinate|null}
47494     */
47495    this.origin_ = options.origin !== undefined ? options.origin : null;
47496
47497    /**
47498     * @private
47499     * @type {Array<import("../coordinate.js").Coordinate>}
47500     */
47501    this.origins_ = null;
47502    if (options.origins !== undefined) {
47503      this.origins_ = options.origins;
47504      asserts_assert(this.origins_.length == this.resolutions_.length, 20); // Number of `origins` and `resolutions` must be equal
47505    }
47506
47507    const extent = options.extent;
47508
47509    if (extent !== undefined && !this.origin_ && !this.origins_) {
47510      this.origin_ = getTopLeft(extent);
47511    }
47512
47513    asserts_assert(
47514      (!this.origin_ && this.origins_) || (this.origin_ && !this.origins_),
47515      18
47516    ); // Either `origin` or `origins` must be configured, never both
47517
47518    /**
47519     * @private
47520     * @type {Array<number|import("../size.js").Size>}
47521     */
47522    this.tileSizes_ = null;
47523    if (options.tileSizes !== undefined) {
47524      this.tileSizes_ = options.tileSizes;
47525      asserts_assert(this.tileSizes_.length == this.resolutions_.length, 19); // Number of `tileSizes` and `resolutions` must be equal
47526    }
47527
47528    /**
47529     * @private
47530     * @type {number|import("../size.js").Size}
47531     */
47532    this.tileSize_ =
47533      options.tileSize !== undefined
47534        ? options.tileSize
47535        : !this.tileSizes_
47536        ? DEFAULT_TILE_SIZE
47537        : null;
47538    asserts_assert(
47539      (!this.tileSize_ && this.tileSizes_) ||
47540        (this.tileSize_ && !this.tileSizes_),
47541      22
47542    ); // Either `tileSize` or `tileSizes` must be configured, never both
47543
47544    /**
47545     * @private
47546     * @type {import("../extent.js").Extent}
47547     */
47548    this.extent_ = extent !== undefined ? extent : null;
47549
47550    /**
47551     * @private
47552     * @type {Array<import("../TileRange.js").default>}
47553     */
47554    this.fullTileRanges_ = null;
47555
47556    /**
47557     * @private
47558     * @type {import("../size.js").Size}
47559     */
47560    this.tmpSize_ = [0, 0];
47561
47562    /**
47563     * @private
47564     * @type {import("../extent.js").Extent}
47565     */
47566    this.tmpExtent_ = [0, 0, 0, 0];
47567
47568    if (options.sizes !== undefined) {
47569      this.fullTileRanges_ = options.sizes.map(function (size, z) {
47570        const tileRange = new ol_TileRange(
47571          Math.min(0, size[0]),
47572          Math.max(size[0] - 1, -1),
47573          Math.min(0, size[1]),
47574          Math.max(size[1] - 1, -1)
47575        );
47576        if (extent) {
47577          const restrictedTileRange = this.getTileRangeForExtentAndZ(extent, z);
47578          tileRange.minX = Math.max(restrictedTileRange.minX, tileRange.minX);
47579          tileRange.maxX = Math.min(restrictedTileRange.maxX, tileRange.maxX);
47580          tileRange.minY = Math.max(restrictedTileRange.minY, tileRange.minY);
47581          tileRange.maxY = Math.min(restrictedTileRange.maxY, tileRange.maxY);
47582        }
47583        return tileRange;
47584      }, this);
47585    } else if (extent) {
47586      this.calculateTileRanges_(extent);
47587    }
47588  }
47589
47590  /**
47591   * Call a function with each tile coordinate for a given extent and zoom level.
47592   *
47593   * @param {import("../extent.js").Extent} extent Extent.
47594   * @param {number} zoom Integer zoom level.
47595   * @param {function(import("../tilecoord.js").TileCoord): void} callback Function called with each tile coordinate.
47596   * @api
47597   */
47598  forEachTileCoord(extent, zoom, callback) {
47599    const tileRange = this.getTileRangeForExtentAndZ(extent, zoom);
47600    for (let i = tileRange.minX, ii = tileRange.maxX;
vendor: 16,384 bytes, lines 47600-48098
47600 i <= ii; ++i) {
47601      for (let j = tileRange.minY, jj = tileRange.maxY; j <= jj; ++j) {
47602        callback([zoom, i, j]);
47603      }
47604    }
47605  }
47606
47607  /**
47608   * @param {import("../tilecoord.js").TileCoord} tileCoord Tile coordinate.
47609   * @param {function(number, import("../TileRange.js").default): boolean} callback Callback.
47610   * @param {import("../TileRange.js").default} [tempTileRange] Temporary import("../TileRange.js").default object.
47611   * @param {import("../extent.js").Extent} [tempExtent] Temporary import("../extent.js").Extent object.
47612   * @return {boolean} Callback succeeded.
47613   */
47614  forEachTileCoordParentTileRange(
47615    tileCoord,
47616    callback,
47617    tempTileRange,
47618    tempExtent
47619  ) {
47620    let tileRange, x, y;
47621    let tileCoordExtent = null;
47622    let z = tileCoord[0] - 1;
47623    if (this.zoomFactor_ === 2) {
47624      x = tileCoord[1];
47625      y = tileCoord[2];
47626    } else {
47627      tileCoordExtent = this.getTileCoordExtent(tileCoord, tempExtent);
47628    }
47629    while (z >= this.minZoom) {
47630      if (this.zoomFactor_ === 2) {
47631        x = Math.floor(x / 2);
47632        y = Math.floor(y / 2);
47633        tileRange = TileRange_createOrUpdate(x, x, y, y, tempTileRange);
47634      } else {
47635        tileRange = this.getTileRangeForExtentAndZ(
47636          tileCoordExtent,
47637          z,
47638          tempTileRange
47639        );
47640      }
47641      if (callback(z, tileRange)) {
47642        return true;
47643      }
47644      --z;
47645    }
47646    return false;
47647  }
47648
47649  /**
47650   * Get the extent for this tile grid, if it was configured.
47651   * @return {import("../extent.js").Extent} Extent.
47652   * @api
47653   */
47654  getExtent() {
47655    return this.extent_;
47656  }
47657
47658  /**
47659   * Get the maximum zoom level for the grid.
47660   * @return {number} Max zoom.
47661   * @api
47662   */
47663  getMaxZoom() {
47664    return this.maxZoom;
47665  }
47666
47667  /**
47668   * Get the minimum zoom level for the grid.
47669   * @return {number} Min zoom.
47670   * @api
47671   */
47672  getMinZoom() {
47673    return this.minZoom;
47674  }
47675
47676  /**
47677   * Get the origin for the grid at the given zoom level.
47678   * @param {number} z Integer zoom level.
47679   * @return {import("../coordinate.js").Coordinate} Origin.
47680   * @api
47681   */
47682  getOrigin(z) {
47683    if (this.origin_) {
47684      return this.origin_;
47685    } else {
47686      return this.origins_[z];
47687    }
47688  }
47689
47690  /**
47691   * Get the resolution for the given zoom level.
47692   * @param {number} z Integer zoom level.
47693   * @return {number} Resolution.
47694   * @api
47695   */
47696  getResolution(z) {
47697    return this.resolutions_[z];
47698  }
47699
47700  /**
47701   * Get the list of resolutions for the tile grid.
47702   * @return {Array<number>} Resolutions.
47703   * @api
47704   */
47705  getResolutions() {
47706    return this.resolutions_;
47707  }
47708
47709  /**
47710   * @param {import("../tilecoord.js").TileCoord} tileCoord Tile coordinate.
47711   * @param {import("../TileRange.js").default} [tempTileRange] Temporary import("../TileRange.js").default object.
47712   * @param {import("../extent.js").Extent} [tempExtent] Temporary import("../extent.js").Extent object.
47713   * @return {import("../TileRange.js").default|null} Tile range.
47714   */
47715  getTileCoordChildTileRange(tileCoord, tempTileRange, tempExtent) {
47716    if (tileCoord[0] < this.maxZoom) {
47717      if (this.zoomFactor_ === 2) {
47718        const minX = tileCoord[1] * 2;
47719        const minY = tileCoord[2] * 2;
47720        return TileRange_createOrUpdate(
47721          minX,
47722          minX + 1,
47723          minY,
47724          minY + 1,
47725          tempTileRange
47726        );
47727      }
47728      const tileCoordExtent = this.getTileCoordExtent(
47729        tileCoord,
47730        tempExtent || this.tmpExtent_
47731      );
47732      return this.getTileRangeForExtentAndZ(
47733        tileCoordExtent,
47734        tileCoord[0] + 1,
47735        tempTileRange
47736      );
47737    }
47738    return null;
47739  }
47740
47741  /**
47742   * @param {import("../tilecoord.js").TileCoord} tileCoord Tile coordinate.
47743   * @param {number} z Integer zoom level.
47744   * @param {import("../TileRange.js").default} [tempTileRange] Temporary import("../TileRange.js").default object.
47745   * @return {import("../TileRange.js").default|null} Tile range.
47746   */
47747  getTileRangeForTileCoordAndZ(tileCoord, z, tempTileRange) {
47748    if (z > this.maxZoom || z < this.minZoom) {
47749      return null;
47750    }
47751
47752    const tileCoordZ = tileCoord[0];
47753    const tileCoordX = tileCoord[1];
47754    const tileCoordY = tileCoord[2];
47755
47756    if (z === tileCoordZ) {
47757      return TileRange_createOrUpdate(
47758        tileCoordX,
47759        tileCoordY,
47760        tileCoordX,
47761        tileCoordY,
47762        tempTileRange
47763      );
47764    }
47765
47766    if (this.zoomFactor_) {
47767      const factor = Math.pow(this.zoomFactor_, z - tileCoordZ);
47768      const minX = Math.floor(tileCoordX * factor);
47769      const minY = Math.floor(tileCoordY * factor);
47770      if (z < tileCoordZ) {
47771        return TileRange_createOrUpdate(minX, minX, minY, minY, tempTileRange);
47772      }
47773
47774      const maxX = Math.floor(factor * (tileCoordX + 1)) - 1;
47775      const maxY = Math.floor(factor * (tileCoordY + 1)) - 1;
47776      return TileRange_createOrUpdate(minX, maxX, minY, maxY, tempTileRange);
47777    }
47778
47779    const tileCoordExtent = this.getTileCoordExtent(tileCoord, this.tmpExtent_);
47780    return this.getTileRangeForExtentAndZ(tileCoordExtent, z, tempTileRange);
47781  }
47782
47783  /**
47784   * Get the extent for a tile range.
47785   * @param {number} z Integer zoom level.
47786   * @param {import("../TileRange.js").default} tileRange Tile range.
47787   * @param {import("../extent.js").Extent} [tempExtent] Temporary import("../extent.js").Extent object.
47788   * @return {import("../extent.js").Extent} Extent.
47789   */
47790  getTileRangeExtent(z, tileRange, tempExtent) {
47791    const origin = this.getOrigin(z);
47792    const resolution = this.getResolution(z);
47793    const tileSize = toSize(this.getTileSize(z), this.tmpSize_);
47794    const minX = origin[0] + tileRange.minX * tileSize[0] * resolution;
47795    const maxX = origin[0] + (tileRange.maxX + 1) * tileSize[0] * resolution;
47796    const minY = origin[1] + tileRange.minY * tileSize[1] * resolution;
47797    const maxY = origin[1] + (tileRange.maxY + 1) * tileSize[1] * resolution;
47798    return createOrUpdate(minX, minY, maxX, maxY, tempExtent);
47799  }
47800
47801  /**
47802   * Get a tile range for the given extent and integer zoom level.
47803   * @param {import("../extent.js").Extent} extent Extent.
47804   * @param {number} z Integer zoom level.
47805   * @param {import("../TileRange.js").default} [tempTileRange] Temporary tile range object.
47806   * @return {import("../TileRange.js").default} Tile range.
47807   */
47808  getTileRangeForExtentAndZ(extent, z, tempTileRange) {
47809    const tileCoord = tmpTileCoord;
47810    this.getTileCoordForXYAndZ_(extent[0], extent[3], z, false, tileCoord);
47811    const minX = tileCoord[1];
47812    const minY = tileCoord[2];
47813    this.getTileCoordForXYAndZ_(extent[2], extent[1], z, true, tileCoord);
47814    return TileRange_createOrUpdate(
47815      minX,
47816      tileCoord[1],
47817      minY,
47818      tileCoord[2],
47819      tempTileRange
47820    );
47821  }
47822
47823  /**
47824   * @param {import("../tilecoord.js").TileCoord} tileCoord Tile coordinate.
47825   * @return {import("../coordinate.js").Coordinate} Tile center.
47826   */
47827  getTileCoordCenter(tileCoord) {
47828    const origin = this.getOrigin(tileCoord[0]);
47829    const resolution = this.getResolution(tileCoord[0]);
47830    const tileSize = toSize(this.getTileSize(tileCoord[0]), this.tmpSize_);
47831    return [
47832      origin[0] + (tileCoord[1] + 0.5) * tileSize[0] * resolution,
47833      origin[1] - (tileCoord[2] + 0.5) * tileSize[1] * resolution,
47834    ];
47835  }
47836
47837  /**
47838   * Get the extent of a tile coordinate.
47839   *
47840   * @param {import("../tilecoord.js").TileCoord} tileCoord Tile coordinate.
47841   * @param {import("../extent.js").Extent} [tempExtent] Temporary extent object.
47842   * @return {import("../extent.js").Extent} Extent.
47843   * @api
47844   */
47845  getTileCoordExtent(tileCoord, tempExtent) {
47846    const origin = this.getOrigin(tileCoord[0]);
47847    const resolution = this.getResolution(tileCoord[0]);
47848    const tileSize = toSize(this.getTileSize(tileCoord[0]), this.tmpSize_);
47849    const minX = origin[0] + tileCoord[1] * tileSize[0] * resolution;
47850    const minY = origin[1] - (tileCoord[2] + 1) * tileSize[1] * resolution;
47851    const maxX = minX + tileSize[0] * resolution;
47852    const maxY = minY + tileSize[1] * resolution;
47853    return createOrUpdate(minX, minY, maxX, maxY, tempExtent);
47854  }
47855
47856  /**
47857   * Get the tile coordinate for the given map coordinate and resolution.  This
47858   * method considers that coordinates that intersect tile boundaries should be
47859   * assigned the higher tile coordinate.
47860   *
47861   * @param {import("../coordinate.js").Coordinate} coordinate Coordinate.
47862   * @param {number} resolution Resolution.
47863   * @param {import("../tilecoord.js").TileCoord} [opt_tileCoord] Destination import("../tilecoord.js").TileCoord object.
47864   * @return {import("../tilecoord.js").TileCoord} Tile coordinate.
47865   * @api
47866   */
47867  getTileCoordForCoordAndResolution(coordinate, resolution, opt_tileCoord) {
47868    return this.getTileCoordForXYAndResolution_(
47869      coordinate[0],
47870      coordinate[1],
47871      resolution,
47872      false,
47873      opt_tileCoord
47874    );
47875  }
47876
47877  /**
47878   * Note that this method should not be called for resolutions that correspond
47879   * to an integer zoom level.  Instead call the `getTileCoordForXYAndZ_` method.
47880   * @param {number} x X.
47881   * @param {number} y Y.
47882   * @param {number} resolution Resolution (for a non-integer zoom level).
47883   * @param {boolean} reverseIntersectionPolicy Instead of letting edge
47884   *     intersections go to the higher tile coordinate, let edge intersections
47885   *     go to the lower tile coordinate.
47886   * @param {import("../tilecoord.js").TileCoord} [opt_tileCoord] Temporary import("../tilecoord.js").TileCoord object.
47887   * @return {import("../tilecoord.js").TileCoord} Tile coordinate.
47888   * @private
47889   */
47890  getTileCoordForXYAndResolution_(
47891    x,
47892    y,
47893    resolution,
47894    reverseIntersectionPolicy,
47895    opt_tileCoord
47896  ) {
47897    const z = this.getZForResolution(resolution);
47898    const scale = resolution / this.getResolution(z);
47899    const origin = this.getOrigin(z);
47900    const tileSize = toSize(this.getTileSize(z), this.tmpSize_);
47901
47902    let tileCoordX = (scale * (x - origin[0])) / resolution / tileSize[0];
47903    let tileCoordY = (scale * (origin[1] - y)) / resolution / tileSize[1];
47904
47905    if (reverseIntersectionPolicy) {
47906      tileCoordX = ceil(tileCoordX, DECIMALS) - 1;
47907      tileCoordY = ceil(tileCoordY, DECIMALS) - 1;
47908    } else {
47909      tileCoordX = floor(tileCoordX, DECIMALS);
47910      tileCoordY = floor(tileCoordY, DECIMALS);
47911    }
47912
47913    return tilecoord_createOrUpdate(z, tileCoordX, tileCoordY, opt_tileCoord);
47914  }
47915
47916  /**
47917   * Although there is repetition between this method and `getTileCoordForXYAndResolution_`,
47918   * they should have separate implementations.  This method is for integer zoom
47919   * levels.  The other method should only be called for resolutions corresponding
47920   * to non-integer zoom levels.
47921   * @param {number} x Map x coordinate.
47922   * @param {number} y Map y coordinate.
47923   * @param {number} z Integer zoom level.
47924   * @param {boolean} reverseIntersectionPolicy Instead of letting edge
47925   *     intersections go to the higher tile coordinate, let edge intersections
47926   *     go to the lower tile coordinate.
47927   * @param {import("../tilecoord.js").TileCoord} [opt_tileCoord] Temporary import("../tilecoord.js").TileCoord object.
47928   * @return {import("../tilecoord.js").TileCoord} Tile coordinate.
47929   * @private
47930   */
47931  getTileCoordForXYAndZ_(x, y, z, reverseIntersectionPolicy, opt_tileCoord) {
47932    const origin = this.getOrigin(z);
47933    const resolution = this.getResolution(z);
47934    const tileSize = toSize(this.getTileSize(z), this.tmpSize_);
47935
47936    let tileCoordX = (x - origin[0]) / resolution / tileSize[0];
47937    let tileCoordY = (origin[1] - y) / resolution / tileSize[1];
47938
47939    if (reverseIntersectionPolicy) {
47940      tileCoordX = ceil(tileCoordX, DECIMALS) - 1;
47941      tileCoordY = ceil(tileCoordY, DECIMALS) - 1;
47942    } else {
47943      tileCoordX = floor(tileCoordX, DECIMALS);
47944      tileCoordY = floor(tileCoordY, DECIMALS);
47945    }
47946
47947    return tilecoord_createOrUpdate(z, tileCoordX, tileCoordY, opt_tileCoord);
47948  }
47949
47950  /**
47951   * Get a tile coordinate given a map coordinate and zoom level.
47952   * @param {import("../coordinate.js").Coordinate} coordinate Coordinate.
47953   * @param {number} z Zoom level.
47954   * @param {import("../tilecoord.js").TileCoord} [opt_tileCoord] Destination import("../tilecoord.js").TileCoord object.
47955   * @return {import("../tilecoord.js").TileCoord} Tile coordinate.
47956   * @api
47957   */
47958  getTileCoordForCoordAndZ(coordinate, z, opt_tileCoord) {
47959    return this.getTileCoordForXYAndZ_(
47960      coordinate[0],
47961      coordinate[1],
47962      z,
47963      false,
47964      opt_tileCoord
47965    );
47966  }
47967
47968  /**
47969   * @param {import("../tilecoord.js").TileCoord} tileCoord Tile coordinate.
47970   * @return {number} Tile resolution.
47971   */
47972  getTileCoordResolution(tileCoord) {
47973    return this.resolutions_[tileCoord[0]];
47974  }
47975
47976  /**
47977   * Get the tile size for a zoom level. The type of the return value matches the
47978   * `tileSize` or `tileSizes` that the tile grid was configured with. To always
47979   * get an {@link import("../size.js").Size}, run the result through {@link module:ol/size.toSize}.
47980   * @param {number} z Z.
47981   * @return {number|import("../size.js").Size} Tile size.
47982   * @api
47983   */
47984  getTileSize(z) {
47985    if (this.tileSize_) {
47986      return this.tileSize_;
47987    } else {
47988      return this.tileSizes_[z];
47989    }
47990  }
47991
47992  /**
47993   * @param {number} z Zoom level.
47994   * @return {import("../TileRange.js").default} Extent tile range for the specified zoom level.
47995   */
47996  getFullTileRange(z) {
47997    if (!this.fullTileRanges_) {
47998      return this.extent_
47999        ? this.getTileRangeForExtentAndZ(this.extent_, z)
48000        : null;
48001    } else {
48002      return this.fullTileRanges_[z];
48003    }
48004  }
48005
48006  /**
48007   * @param {number} resolution Resolution.
48008   * @param {number|import("../array.js").NearestDirectionFunction} [opt_direction]
48009   *     If 0, the nearest resolution will be used.
48010   *     If 1, the nearest higher resolution (lower Z) will be used. If -1, the
48011   *     nearest lower resolution (higher Z) will be used. Default is 0.
48012   *     Use a {@link module:ol/array~NearestDirectionFunction} for more precise control.
48013   *
48014   * For example to change tile Z at the midpoint of zoom levels
48015   * ```js
48016   * function(value, high, low) {
48017   *   return value - low * Math.sqrt(high / low);
48018   * }
48019   * ```
48020   * @return {number} Z.
48021   * @api
48022   */
48023  getZForResolution(resolution, opt_direction) {
48024    const z = linearFindNearest(
48025      this.resolutions_,
48026      resolution,
48027      opt_direction || 0
48028    );
48029    return math_clamp(z, this.minZoom, this.maxZoom);
48030  }
48031
48032  /**
48033   * The tile with the provided tile coordinate intersects the given viewport.
48034   * @param {import('../tilecoord.js').TileCoord} tileCoord Tile coordinate.
48035   * @param {Array<number>} viewport Viewport as returned from {@link module:ol/extent.getRotatedViewport}.
48036   * @return {boolean} The tile with the provided tile coordinate intersects the given viewport.
48037   */
48038  tileCoordIntersectsViewport(tileCoord, viewport) {
48039    return intersectsLinearRing(
48040      viewport,
48041      0,
48042      viewport.length,
48043      2,
48044      this.getTileCoordExtent(tileCoord)
48045    );
48046  }
48047
48048  /**
48049   * @param {!import("../extent.js").Extent} extent Extent for this tile grid.
48050   * @private
48051   */
48052  calculateTileRanges_(extent) {
48053    const length = this.resolutions_.length;
48054    const fullTileRanges = new Array(length);
48055    for (let z = this.minZoom; z < length; ++z) {
48056      fullTileRanges[z] = this.getTileRangeForExtentAndZ(extent, z);
48057    }
48058    this.fullTileRanges_ = fullTileRanges;
48059  }
48060}
48061
48062/* harmony default export */ const tilegrid_TileGrid = (TileGrid);
48063
48064;// CONCATENATED MODULE: ./node_modules/ol/tilegrid.js
48065/**
48066 * @module ol/tilegrid
48067 */
48068
48069
48070
48071
48072
48073
48074/**
48075 * @param {import("./proj/Projection.js").default} projection Projection.
48076 * @return {!TileGrid} Default tile grid for the
48077 * passed projection.
48078 */
48079function getForProjection(projection) {
48080  let tileGrid = projection.getDefaultTileGrid();
48081  if (!tileGrid) {
48082    tileGrid = createForProjection(projection);
48083    projection.setDefaultTileGrid(tileGrid);
48084  }
48085  return tileGrid;
48086}
48087
48088/**
48089 * @param {TileGrid} tileGrid Tile grid.
48090 * @param {import("./tilecoord.js").TileCoord} tileCoord Tile coordinate.
48091 * @param {import("./proj/Projection.js").default} projection Projection.
48092 * @return {import("./tilecoord.js").TileCoord} Tile coordinate.
48093 */
48094function tilegrid_wrapX(tileGrid, tileCoord, projection) {
48095  const z = tileCoord[0];
48096  const center = tileGrid.getTileCoordCenter(tileCoord);
48097  const projectionExtent = extentFromProjection(projection);
48098  if (!containsCoor
48098dinate(projectionExtent, center)) {
48099    const worldWidth = extent_getWidth(projectionExtent);
48100    const worldsAway = Math.ceil(
48101      (projectionExtent[0] - center[0]) / worldWidth
48102    );
48103    center[0] += worldWidth * worldsAway;
48104    return tileGrid.getTileCoordForCoordAndZ(center, z);
48105  } else {
48106    return tileCoord;
48107  }
48108}
48109
48110/**
48111 * @param {import("./extent.js").Extent} extent Extent.
48112 * @param {number} [maxZoom] Maximum zoom level (default is
48113 *     DEFAULT_MAX_ZOOM).
48114 * @param {number|import("./size.js").Size} [tileSize] Tile size (default uses
48115 *     DEFAULT_TILE_SIZE).
48116 * @param {import("./extent.js").Corner} [corner] Extent corner (default is `'top-left'`).
48117 * @return {!TileGrid} TileGrid instance.
48118 */
48119function createForExtent(extent, maxZoom, tileSize, corner) {
48120  corner = corner !== undefined ? corner : 'top-left';
48121
48122  const resolutions = resolutionsFromExtent(extent, maxZoom, tileSize);
48123
48124  return new tilegrid_TileGrid({
48125    extent: extent,
48126    origin: getCorner(extent, corner),
48127    resolutions: resolutions,
48128    tileSize: tileSize,
48129  });
48130}
48131
48132/**
48133 * @typedef {Object} XYZOptions
48134 * @property {import("./extent.js").Extent} [extent] Extent for the tile grid. The origin for an XYZ tile grid is the
48135 * top-left corner of the extent. If `maxResolution` is not provided the zero level of the grid is defined by the resolution
48136 * at which one tile fits in the provided extent. If not provided, the extent of the EPSG:3857 projection is used.
48137 * @property {number} [maxResolution] Resolution at level zero.
48138 * @property {number} [maxZoom] Maximum zoom. The default is `42`. This determines the number of levels
48139 * in the grid set. For example, a `maxZoom` of 21 means there are 22 levels in the grid set.
48140 * @property {number} [minZoom=0] Minimum zoom.
48141 * @property {number|import("./size.js").Size} [tileSize=[256, 256]] Tile size in pixels.
48142 */
48143
48144/**
48145 * Creates a tile grid with a standard XYZ tiling scheme.
48146 * @param {XYZOptions} [options] Tile grid options.
48147 * @return {!TileGrid} Tile grid instance.
48148 * @api
48149 */
48150function createXYZ(options) {
48151  const xyzOptions = options || {};
48152
48153  const extent = xyzOptions.extent || proj_get('EPSG:3857').getExtent();
48154
48155  const gridOptions = {
48156    extent: extent,
48157    minZoom: xyzOptions.minZoom,
48158    tileSize: xyzOptions.tileSize,
48159    resolutions: resolutionsFromExtent(
48160      extent,
48161      xyzOptions.maxZoom,
48162      xyzOptions.tileSize,
48163      xyzOptions.maxResolution
48164    ),
48165  };
48166  return new tilegrid_TileGrid(gridOptions);
48167}
48168
48169/**
48170 * Create a resolutions array from an extent.  A zoom factor of 2 is assumed.
48171 * @param {import("./extent.js").Extent} extent Extent.
48172 * @param {number} [maxZoom] Maximum zoom level (default is
48173 *     DEFAULT_MAX_ZOOM).
48174 * @param {number|import("./size.js").Size} [tileSize] Tile size (default uses
48175 *     DEFAULT_TILE_SIZE).
48176 * @param {number} [maxResolution] Resolution at level zero.
48177 * @return {!Array<number>} Resolutions array.
48178 */
48179function resolutionsFromExtent(extent, maxZoom, tileSize, maxResolution) {
48180  maxZoom = maxZoom !== undefined ? maxZoom : DEFAULT_MAX_ZOOM;
48181  tileSize = toSize(tileSize !== undefined ? tileSize : DEFAULT_TILE_SIZE);
48182
48183  const height = extent_getHeight(extent);
48184  const width = extent_getWidth(extent);
48185
48186  maxResolution =
48187    maxResolution > 0
48188      ? maxResolution
48189      : Math.max(width / tileSize[0], height / tileSize[1]);
48190
48191  const length = maxZoom + 1;
48192  const resolutions = new Array(length);
48193  for (let z = 0; z < length; ++z) {
48194    resolutions[z] = maxResolution / Math.pow(2, z);
48195  }
48196  return resolutions;
48197}
48198
48199/**
48200 * @param {import("./proj.js").ProjectionLike} projection Projection.
48201 * @param {number} [maxZoom] Maximum zoom level (default is
48202 *     DEFAULT_MAX_ZOOM).
48203 * @param {number|import("./size.js").Size} [tileSize] Tile size (default uses
48204 *     DEFAULT_TILE_SIZE).
48205 * @param {import("./extent.js").Corner} [corner] Extent corner (default is `'top-left'`).
48206 * @return {!TileGrid} TileGrid instance.
48207 */
48208function createForProjection(projection, maxZoom, tileSize, corner) {
48209  const extent = extentFromProjection(projection);
48210  return createForExtent(extent, maxZoom, tileSize, corner);
48211}
48212
48213/**
48214 * Generate a tile grid extent from a projection.  If the projection has an
48215 * extent, it is used.  If not, a global extent is assumed.
48216 * @param {import("./proj.js").ProjectionLike} projection Projection.
48217 * @return {import("./extent.js").Extent} Extent.
48218 */
48219function extentFromProjection(projection) {
48220  projection = proj_get(projection);
48221  let extent = projection.getExtent();
48222  if (!extent) {
48223    const half =
48224      (180 * Units_METERS_PER_UNIT.degrees) / projection.getMetersPerUnit();
48225    extent = createOrUpdate(-half, -half, half, half);
48226  }
48227  return extent;
48228}
48229
48230;// CONCATENATED MODULE: ./node_modules/ol/source/Tile.js
48231/**
48232 * @module ol/source/Tile
48233 */
48234
48235
48236
48237
48238
48239
48240
48241
48242
48243
48244
48245/***
48246 * @template Return
48247 * @typedef {import("../Observable").OnSignature<import("../Observable").EventTypes, import("../events/Event.js").default, Return> &
48248 *   import("../Observable").OnSignature<import("../ObjectEventType").Types, import("../Object").ObjectEvent, Return> &
48249 *   import("../Observable").OnSignature<import("./TileEventType").TileSourceEventTypes, TileSourceEvent, Return> &
48250 *   import("../Observable").CombinedOnSignature<import("../Observable").EventTypes|import("../ObjectEventType").Types|
48251 *     import("./TileEventType").TileSourceEventTypes, Return>} TileSourceOnSignature
48252 */
48253
48254/**
48255 * @typedef {Object} Options
48256 * @property {import("./Source.js").AttributionLike} [attributions] Attributions.
48257 * @property {boolean} [attributionsCollapsible=true] Attributions are collapsible.
48258 * @property {number} [cacheSize] CacheSize.
48259 * @property {boolean} [opaque=false] Whether the layer is opaque.
48260 * @property {number} [tilePixelRatio] TilePixelRatio.
48261 * @property {import("../proj.js").ProjectionLike} [projection] Projection.
48262 * @property {import("./Source.js").State} [state] State.
48263 * @property {import("../tilegrid/TileGrid.js").default} [tileGrid] TileGrid.
48264 * @property {boolean} [wrapX=false] WrapX.
48265 * @property {number} [transition] Transition.
48266 * @property {string} [key] Key.
48267 * @property {number|import("../array.js").NearestDirectionFunction} [zDirection=0] ZDirection.
48268 * @property {boolean} [interpolate=false] Use interpolated values when resampling.  By default,
48269 * the nearest neighbor is used when resampling.
48270 */
48271
48272/**
48273 * @classdesc
48274 * Abstract base class; normally only used for creating subclasses and not
48275 * instantiated in apps.
48276 * Base class for sources providing images divided into a tile grid.
48277 * @abstract
48278 * @api
48279 */
48280class TileSource extends source_Source {
48281  /**
48282   * @param {Options} options SourceTile source options.
48283   */
48284  constructor(options) {
48285    super({
48286      attributions: options.attributions,
48287      attributionsCollapsible: options.attributionsCollapsible,
48288      projection: options.projection,
48289      state: options.state,
48290      wrapX: options.wrapX,
48291      interpolate: options.interpolate,
48292    });
48293
48294    /***
48295     * @type {TileSourceOnSignature<import("../events").EventsKey>}
48296     */
48297    this.on;
48298
48299    /***
48300     * @type {TileSourceOnSignature<import("../events").EventsKey>}
48301     */
48302    this.once;
48303
48304    /***
48305     * @type {TileSourceOnSignature<void>}
48306     */
48307    this.un;
48308
48309    /**
48310     * @private
48311     * @type {boolean}
48312     */
48313    this.opaque_ = options.opaque !== undefined ? options.opaque : false;
48314
48315    /**
48316     * @private
48317     * @type {number}
48318     */
48319    this.tilePixelRatio_ =
48320      options.tilePixelRatio !== undefined ? options.tilePixelRatio : 1;
48321
48322    /**
48323     * @type {import("../tilegrid/TileGrid.js").default|null}
48324     */
48325    this.tileGrid = options.tileGrid !== undefined ? options.tileGrid : null;
48326
48327    const tileSize = [256, 256];
48328    if (this.tileGrid) {
48329      toSize(this.tileGrid.getTileSize(this.tileGrid.getMinZoom()), tileSize);
48330    }
48331
48332    /**
48333     * @protected
48334     * @type {import("../TileCache.js").default}
48335     */
48336    this.tileCache = new ol_TileCache(options.cacheSize || 0);
48337
48338    /**
48339     * @protected
48340     * @type {import("../size.js").Size}
48341     */
48342    this.tmpSize = [0, 0];
48343
48344    /**
48345     * @private
48346     * @type {string}
48347     */
48348    this.key_ = options.key || '';
48349
48350    /**
48351     * @protected
48352     * @type {import("../Tile.js").Options}
48353     */
48354    this.tileOptions = {
48355      transition: options.transition,
48356      interpolate: options.interpolate,
48357    };
48358
48359    /**
48360     * zDirection hint, read by the renderer. Indicates which resolution should be used
48361     * by a renderer if the views resolution does not match any resolution of the tile source.
48362     * If 0, the nearest resolution will be used. If 1, the nearest lower resolution
48363     * will be used. If -1, the nearest higher resolution will be used.
48364     * @type {number|import("../array.js").NearestDirectionFunction}
48365     */
48366    this.zDirection = options.zDirection ? options.zDirection : 0;
48367  }
48368
48369  /**
48370   * @return {boolean} Can expire cache.
48371   */
48372  canExpireCache() {
48373    return this.tileCache.canExpireCache();
48374  }
48375
48376  /**
48377   * @param {import("../proj/Projection.js").default} projection Projection.
48378   * @param {!Object<string, boolean>} usedTiles Used tiles.
48379   */
48380  expireCache(projection, usedTiles) {
48381    const tileCache = this.getTileCacheForProjection(projection);
48382    if (tileCache) {
48383      tileCache.expireCache(usedTiles);
48384    }
48385  }
48386
48387  /**
48388   * @param {import("../proj/Projection.js").default} projection Projection.
48389   * @param {number} z Zoom level.
48390   * @param {import("../TileRange.js").default} tileRange Tile range.
48391   * @param {function(import("../Tile.js").default):(boolean|void)} callback Called with each
48392   *     loaded tile.  If the callback returns `false`, the tile will not be
48393   *     considered loaded.
48394   * @return {boolean} The tile range is fully covered with loaded tiles.
48395   */
48396  forEachLoadedTile(projection, z, tileRange, callback) {
48397    const tileCache = this.getTileCacheForProjection(projection);
48398    if (!tileCache) {
48399      return false;
48400    }
48401
48402    let covered = true;
48403    let tile, tileCoordKey, loaded;
48404    for (let x = tileRange.minX; x <= tileRange.maxX; ++x) {
48405      for (let y = tileRange.minY; y <= tileRange.maxY; ++y) {
48406        tileCoordKey = getKeyZXY(z, x, y);
48407        loaded = false;
48408        if (tileCache.containsKey(tileCoordKey)) {
48409          tile = /** @type {!import("../Tile.js").default} */ (
48410            tileCache.get(tileCoordKey)
48411          );
48412          loaded = tile.getState() === TileState.LOADED;
48413          if (loaded) {
48414            loaded = callback(tile) !== false;
48415          }
48416        }
48417        if (!loaded) {
48418          covered = false;
48419        }
48420      }
48421    }
48422    return covered;
48423  }
48424
48425  /**
48426   * @param {import("../proj/Projection.js").default} projection Projection.
48427   * @return {number} Gutter.
48428   */
48429  getGutterForProjection(projection) {
48430    return 0;
48431  }
48432
48433  /**
48434   * Return the key to be used for all tiles in the source.
48435   * @return {string} The key for all tiles.
48436   */
48437  getKey() {
48438    return this.key_;
48439  }
48440
48441  /**
48442   * Set the value to be used as the key for all tiles in the source.
48443   * @param {string} key The key for tiles.
48444   * @protected
48445   */
48446  setKey(key) {
48447    if (this.key_ !== key) {
48448      this.key_ = key;
48449      this.changed();
48450    }
48451  }
48452
48453  /**
48454   * @param {import("../proj/Projection.js").default} projection Projection.
48455   * @return {boolean} Opaque.
48456   */
48457  getOpaque(projection) {
48458    return this.opaque_;
48459  }
48460
48461  /**
48462   * @return {Array<number>|null} Resolutions.
48463   */
48464  getResolutions() {
48465    if (!this.tileGrid) {
48466      return null;
48467    }
48468    return this.tileGrid.getResolutions();
48469  }
48470
48471  /**
48472   * @abstract
48473   * @param {number} z Tile coordinate z.
48474   * @param {number} x Tile coordinate x.
48475   * @param {number} y Tile coordinate y.
48476   * @param {number} pixelRatio Pixel ratio.
48477   * @param {import("../proj/Projection.js").default} projection Projection.
48478   * @return {!import("../Tile.js").default} Tile.
48479   */
48480  getTile(z, x, y, pixelRatio, projection) {
48481    return util_abstract();
48482  }
48483
48484  /**
48485   * Return the tile grid of the tile source.
48486   * @return {import("../tilegrid/TileGrid.js").default|null} Tile grid.
48487   * @api
48488   */
48489  getTileGrid() {
48490    return this.tileGrid;
48491  }
48492
48493  /**
48494   * @param {import("../proj/Projection.js").default} projection Projection.
48495   * @return {!import("../tilegrid/TileGrid.js").default} Tile grid.
48496   */
48497  getTileGridForProjection(projection) {
48498    if (!this.tileGrid) {
48499      return getForProjection(projection);
48500    } else {
48501      return this.tileGrid;
48502    }
48503  }
48504
48505  /**
48506   * @param {import("../proj/Projection.js").default} projection Projection.
48507   * @return {import("../TileCache.js").default} Tile cache.
48508   * @protected
48509   */
48510  getTileCacheForProjection(projection) {
48511    const sourceProjection = this.getProjection();
48512    asserts_assert(
48513      sourceProjection === null || equivalent(sourceProjection, projection),
48514      68 // A VectorTile source can only be rendered if it has a projection compatible with the view projection.
48515    );
48516    return this.tileCache;
48517  }
48518
48519  /**
48520   * Get the tile pixel ratio for this source. Subclasses may override this
48521   * method, which is meant to return a supported pixel ratio that matches the
48522   * provided `pixelRatio` as close as possible.
48523   * @param {number} pixelRatio Pixel ratio.
48524   * @return {number} Tile pixel ratio.
48525   */
48526  getTilePixelRatio(pixelRatio) {
48527    return this.tilePixelRatio_;
48528  }
48529
48530  /**
48531   * @param {number} z Z.
48532   * @param {number} pixelRatio Pixel ratio.
48533   * @param {import("../proj/Projection.js").default} projection Projection.
48534   * @return {import("../size.js").Size} Tile size.
48535   */
48536  getTilePixelSize(z, pixelRatio, projection) {
48537    const tileGrid = this.getTileGridForProjection(projection);
48538    const tilePixelRatio = this.getTilePixelRatio(pixelRatio);
48539    const tileSize = toSize(tileGrid.getTileSize(z), this.tmpSize);
48540    if (tilePixelRatio == 1) {
48541      return tileSize;
48542    } else {
48543      return size_scale(tileSize, tilePixelRatio, this.tmpSize);
48544    }
48545  }
48546
48547  /**
48548   * Returns a tile coordinate wrapped around the x-axis. When the tile coordinate
48549   * is outside the resolution and extent range of the tile grid, `null` will be
48550   * returned.
48551   * @param {import("../tilecoord.js").TileCoord} tileCoord Tile coordinate.
48552   * @param {import("../proj/Projection.js").default} [projection] Projection.
48553   * @return {import("../tilecoord.js").TileCoord} Tile coordinate to be passed to the tileUrlFunction or
48554   *     null if no tile URL should be created for the passed `tileCoord`.
48555   */
48556  getTileCoordForTileUrlFunction(tileCoord, projection) {
48557    projection = projection !== undefined ? projection : this.getProjection();
48558    const tileGrid = this.getTileGridForProjection(projection);
48559    if (this.getWrapX() && projection.isGlobal()) {
48560      tileCoord = tilegrid_wrapX(tileGrid, tileCoord, projection);
48561    }
48562    return withinExtentAndZ(tileCoord, tileGrid) ? tileCoord : null;
48563  }
48564
48565  /**
48566   * Remove all cached tiles from the source. The next render cycle will fetch new tiles.
48567   * @api
48568   */
48569  clear() {
48570    this.tileCache.clear();
48571  }
48572
48573  refresh() {
48574    this.clear();
48575    super.refresh();
48576  }
48577
48578  /**
48579   * Increases the cache size if needed
48580   * @param {number} tileCount Minimum number of tiles needed.
48581   * @param {import("../proj/Projection.js").default} projection Projection.
48582   */
48583  updateCacheSize(tileCount, projection) {
48584    const tileCache = this.getTileCacheForProjection(projection);
48585    if (tileCount > tileCache.highWaterMark) {
48586      tileCache.highWaterMark = tileCount;
48587    }
48588  }
48589
48590  /**
48591   * Marks a tile coord as being used, without triggering a load.
48592   * @abstract
48593   * @param {number} z Tile coordinate z.
48594   * @param {number} x Tile coordinate x.
48595   * @param {number} y Tile coordinate y.
48596   * @param {import("../proj/Projection.js").default} projection Projection.
48597   */
48598  useTile(z, x, y, projection) {}
48599}
48600
48601/**
48602 * @classdesc
48603 * Events emitted by {@link module:ol/source/Tile~TileSource} instances are instances of this
48604 * type.
48605 */
48606class TileSourceEvent extends Event {
48607  /**
48608   * @param {string} type Type.
48609   * @param {import("../Tile.js").default} tile The tile.
48610   */
48611  constructor(type, tile) {
48612    super(type);
48613
48614    /**
48615     * The tile related to the event.
48616     * @type {import("../Tile.js").default}
48617     * @api
48618     */
48619    this.tile = tile;
48620  }
48621}
48622
48623/* harmony default export */ const source_Tile = (TileSource);
48624
48625;// CONCATENATED MODULE: ./node_modules/ol/tileurlfunction.js
48626/**
48627 * @module ol/tileurlfunction
48628 */
48629
48630
48631
48632
48633/**
48634 * @param {string} template Template.
48635 * @param {import("./tilegrid/TileGrid.js").default} tileGrid Tile grid.
48636 * @return {import("./Tile.js").UrlFunction} Tile URL function.
48637 */
48638function createFromTemplate(template, tileGrid) {
48639  const zRegEx = /\{z\}/g;
48640  const xRegEx = /\{x\}/g;
48641  const yRegEx = /\{y\}/g;
48642  const dashYRegEx = /\{-y\}/g;
48643  return (
48644    /**
48645     * @param {import("./tilecoord.js").TileCoord} tileCoord Tile Coordinate.
48646     * @param {number} pixelRatio Pixel ratio.
48647     * @param {import("./proj/Projection.js").default} projection Projection.
48648     * @return {string|undefined} Tile URL.
48649     */
48650    function (tileCoord, pixelRatio, projection) {
48651      if (!tileCoord) {
48652        return undefined;
48653      } else {
48654        return template
48655          .replace(zRegEx, tileCoord[0].toString())
48656          .replace(xRegEx, tileCoord[1].toString())
48657          .replace(yRegEx, tileCoord[2].toString())
48658          .replace(dashYRegEx, function () {
48659            const z = tileCoord[0];
48660            const range = tileGrid.getFullTileRange(z);
48661            asserts_assert(range, 55); // The {-y} placeholder requires a tile grid with extent
48662            const y = range.getHeight() - tileCoord[2] - 1;
48663            return y.toString();
48664          });
48665      }
48666    }
48667  );
48668}
48669
48670/**
48671 * @param {Array<string>} templates Templates.
48672 * @param {import("./tilegrid/TileGrid.js").default} tileGrid Tile grid.
48673 * @return {import("./Tile.js").UrlFunction} Tile URL function.
48674 */
48675function createFromTemplates(templates, tileGrid) {
48676  const len = templates.length;
48677  const tileUrlFunctions = new Array(len);
48678  for (let i = 0; i < len; ++i) {
48679    tileUrlFunctions[i] = createFromTemplate(templates[i], tileGrid);
48680  }
48681  return createFromTileUrlFunctions(tileUrlFunctions);
48682}
48683
48684/**
48685 * @param {Array<import("./Tile.js").UrlFunction>} tileUrlFunctions Tile URL Functions.
48686 * @return {import("./Tile.js").UrlFunction} Tile URL function.
48687 */
48688function createFromTileUrlFunctions(tileUrlFunctions) {
48689  if (tileUrlFunctions.length === 1) {
48690    return tileUrlFunctions[0];
48691  }
48692  return (
48693    /**
48694     * @param {import("./tilecoord.js").TileCoord} tileCoord Tile Coordinate.
48695     * @param {number} pixelRatio Pixel ratio.
48696     * @param {import("./proj/Projection.js").default} projection Projection.
48697     * @return {string|undefined} Tile URL.
48698     */
48699    function (tileCoord, pixelRatio, projection) {
48700      if (!tileCoord) {
48701        return undefined;
48702      } else {
48703        const h = hash(tileCoord);
48704        const index = math_modulo(h, tileUrlFunctions.length);
48705        return tileUrlFunctions[index](tileCoord, pixelRatio, projection);
48706      }
48707    }
48708  );
48709}
48710
48711/**
48712 * @param {import("./tilecoord.js").TileCoord} tileCoord Tile coordinate.
48713 * @param {number} pixelRatio Pixel ratio.
48714 * @param {import("./proj/Projection.js").default} projection Projection.
48715 * @return {string|undefined} Tile URL.
48716 */
48717function nullTileUrlFunction(tileCoord, pixelRatio, projection) {
48718  return undefined;
48719}
48720
48721/**
48722 * @param {string} url URL.
48723 * @return {Array<string>} Array of urls.
48724 */
48725function expandUrl(url) {
48726  const urls = [];
48727  let match = /\{([a-z])-([a-z])\}/.exec(url);
48728  if (match) {
48729    // char range
vendor: 5,962 bytes, lines 48730-48945
48730    const startCharCode = match[1].charCodeAt(0);
48731    const stopCharCode = match[2].charCodeAt(0);
48732    let charCode;
48733    for (charCode = startCharCode; charCode <= stopCharCode; ++charCode) {
48734      urls.push(url.replace(match[0], String.fromCharCode(charCode)));
48735    }
48736    return urls;
48737  }
48738  match = /\{(\d+)-(\d+)\}/.exec(url);
48739  if (match) {
48740    // number range
48741    const stop = parseInt(match[2], 10);
48742    for (let i = parseInt(match[1], 10); i <= stop; i++) {
48743      urls.push(url.replace(match[0], i.toString()));
48744    }
48745    return urls;
48746  }
48747  urls.push(url);
48748  return urls;
48749}
48750
48751;// CONCATENATED MODULE: ./node_modules/ol/source/UrlTile.js
48752/**
48753 * @module ol/source/UrlTile
48754 */
48755
48756
48757
48758
48759
48760
48761
48762/**
48763 * @typedef {Object} Options
48764 * @property {import("./Source.js").AttributionLike} [attributions] Attributions.
48765 * @property {boolean} [attributionsCollapsible=true] Attributions are collapsible.
48766 * @property {number} [cacheSize] Cache size.
48767 * @property {boolean} [opaque=false] Whether the layer is opaque.
48768 * @property {import("../proj.js").ProjectionLike} [projection] Projection.
48769 * @property {import("./Source.js").State} [state] State.
48770 * @property {import("../tilegrid/TileGrid.js").default} [tileGrid] TileGrid.
48771 * @property {import("../Tile.js").LoadFunction} tileLoadFunction TileLoadFunction.
48772 * @property {number} [tilePixelRatio] TilePixelRatio.
48773 * @property {import("../Tile.js").UrlFunction} [tileUrlFunction] TileUrlFunction.
48774 * @property {string} [url] Url.
48775 * @property {Array<string>} [urls] Urls.
48776 * @property {boolean} [wrapX=true] WrapX.
48777 * @property {number} [transition] Transition.
48778 * @property {string} [key] Key.
48779 * @property {number|import("../array.js").NearestDirectionFunction} [zDirection=0] ZDirection.
48780 * @property {boolean} [interpolate=false] Use interpolated values when resampling.  By default,
48781 * the nearest neighbor is used when resampling.
48782 */
48783
48784/**
48785 * @classdesc
48786 * Base class for sources providing tiles divided into a tile grid over http.
48787 *
48788 * @fires import("./Tile.js").TileSourceEvent
48789 */
48790class UrlTile extends source_Tile {
48791  /**
48792   * @param {Options} options Image tile options.
48793   */
48794  constructor(options) {
48795    super({
48796      attributions: options.attributions,
48797      cacheSize: options.cacheSize,
48798      opaque: options.opaque,
48799      projection: options.projection,
48800      state: options.state,
48801      tileGrid: options.tileGrid,
48802      tilePixelRatio: options.tilePixelRatio,
48803      wrapX: options.wrapX,
48804      transition: options.transition,
48805      interpolate: options.interpolate,
48806      key: options.key,
48807      attributionsCollapsible: options.attributionsCollapsible,
48808      zDirection: options.zDirection,
48809    });
48810
48811    /**
48812     * @private
48813     * @type {boolean}
48814     */
48815    this.generateTileUrlFunction_ =
48816      this.tileUrlFunction === UrlTile.prototype.tileUrlFunction;
48817
48818    /**
48819     * @protected
48820     * @type {import("../Tile.js").LoadFunction}
48821     */
48822    this.tileLoadFunction = options.tileLoadFunction;
48823
48824    if (options.tileUrlFunction) {
48825      this.tileUrlFunction = options.tileUrlFunction;
48826    }
48827
48828    /**
48829     * @protected
48830     * @type {!Array<string>|null}
48831     */
48832    this.urls = null;
48833
48834    if (options.urls) {
48835      this.setUrls(options.urls);
48836    } else if (options.url) {
48837      this.setUrl(options.url);
48838    }
48839
48840    /**
48841     * @private
48842     * @type {!Object<string, boolean>}
48843     */
48844    this.tileLoadingKeys_ = {};
48845  }
48846
48847  /**
48848   * Return the tile load function of the source.
48849   * @return {import("../Tile.js").LoadFunction} TileLoadFunction
48850   * @api
48851   */
48852  getTileLoadFunction() {
48853    return this.tileLoadFunction;
48854  }
48855
48856  /**
48857   * Return the tile URL function of the source.
48858   * @return {import("../Tile.js").UrlFunction} TileUrlFunction
48859   * @api
48860   */
48861  getTileUrlFunction() {
48862    return Object.getPrototypeOf(this).tileUrlFunction === this.tileUrlFunction
48863      ? this.tileUrlFunction.bind(this)
48864      : this.tileUrlFunction;
48865  }
48866
48867  /**
48868   * Return the URLs used for this source.
48869   * When a tileUrlFunction is used instead of url or urls,
48870   * null will be returned.
48871   * @return {!Array<string>|null} URLs.
48872   * @api
48873   */
48874  getUrls() {
48875    return this.urls;
48876  }
48877
48878  /**
48879   * Handle tile change events.
48880   * @param {import("../events/Event.js").default} event Event.
48881   * @protected
48882   */
48883  handleTileChange(event) {
48884    const tile = /** @type {import("../Tile.js").default} */ (event.target);
48885    const uid = getUid(tile);
48886    const tileState = tile.getState();
48887    let type;
48888    if (tileState == TileState.LOADING) {
48889      this.tileLoadingKeys_[uid] = true;
48890      type = TileEventType.TILELOADSTART;
48891    } else if (uid in this.tileLoadingKeys_) {
48892      delete this.tileLoadingKeys_[uid];
48893      type =
48894        tileState == TileState.ERROR
48895          ? TileEventType.TILELOADERROR
48896          : tileState == TileState.LOADED
48897          ? TileEventType.TILELOADEND
48898          : undefined;
48899    }
48900    if (type != undefined) {
48901      this.dispatchEvent(new TileSourceEvent(type, tile));
48902    }
48903  }
48904
48905  /**
48906   * Set the tile load function of the source.
48907   * @param {import("../Tile.js").LoadFunction} tileLoadFunction Tile load function.
48908   * @api
48909   */
48910  setTileLoadFunction(tileLoadFunction) {
48911    this.tileCache.clear();
48912    this.tileLoadFunction = tileLoadFunction;
48913    this.changed();
48914  }
48915
48916  /**
48917   * Set the tile URL function of the source.
48918   * @param {import("../Tile.js").UrlFunction} tileUrlFunction Tile URL function.
48919   * @param {string} [key] Optional new tile key for the source.
48920   * @api
48921   */
48922  setTileUrlFunction(tileUrlFunction, key) {
48923    this.tileUrlFunction = tileUrlFunction;
48924    this.tileCache.pruneExceptNewestZ();
48925    if (typeof key !== 'undefined') {
48926      this.setKey(key);
48927    } else {
48928      this.changed();
48929    }
48930  }
48931
48932  /**
48933   * Set the URL to use for requests.
48934   * @param {string} url URL.
48935   * @api
48936   */
48937  setUrl(url) {
48938    const urls = expandUrl(url);
48939    this.urls = urls;
48940    this.setUrls(urls);
48941  }
48942
48943  /**
48944   * Set the URLs to use for requests.
48945   * @param {Array<string>}
48945 urls URLs.
48946   * @api
48947   */
48948  setUrls(urls) {
48949    this.urls = urls;
48950    const key = urls.join('\n');
48951    if (this.generateTileUrlFunction_) {
48952      this.setTileUrlFunction(createFromTemplates(urls, this.tileGrid), key);
48953    } else {
48954      this.setKey(key);
48955    }
48956  }
48957
48958  /**
48959   * @param {import("../tilecoord.js").TileCoord} tileCoord Tile coordinate.
48960   * @param {number} pixelRatio Pixel ratio.
48961   * @param {import("../proj/Projection.js").default} projection Projection.
48962   * @return {string|undefined} Tile URL.
48963   */
48964  tileUrlFunction(tileCoord, pixelRatio, projection) {
48965    return undefined;
48966  }
48967
48968  /**
48969   * Marks a tile coord as being used, without triggering a load.
48970   * @param {number} z Tile coordinate z.
48971   * @param {number} x Tile coordinate x.
48972   * @param {number} y Tile coordinate y.
48973   */
48974  useTile(z, x, y) {
48975    const tileCoordKey = getKeyZXY(z, x, y);
48976    if (this.tileCache.containsKey(tileCoordKey)) {
48977      this.tileCache.get(tileCoordKey);
48978    }
48979  }
48980}
48981
48982/* harmony default export */ const source_UrlTile = (UrlTile);
48983
48984;// CONCATENATED MODULE: ./node_modules/ol/source/TileImage.js
48985/**
48986 * @module ol/source/TileImage
48987 */
48988
48989
48990
48991
48992
48993
48994
48995
48996
48997
48998
48999/**
49000 * @typedef {Object} Options
49001 * @property {import("./Source.js").AttributionLike} [attributions] Attributions.
49002 * @property {boolean} [attributionsCollapsible=true] Attributions are collapsible.
49003 * @property {number} [cacheSize] Initial tile cache size. Will auto-grow to hold at least the number of tiles in the viewport.
49004 * @property {null|string} [crossOrigin] The `crossOrigin` attribute for loaded images.  Note that
49005 * you must provide a `crossOrigin` value if you want to access pixel data with the Canvas renderer.
49006 * See https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image for more detail.
49007 * @property {boolean} [interpolate=true] Use interpolated values when resampling.  By default,
49008 * linear interpolation is used when resampling.  Set to false to use the nearest neighbor instead.
49009 * @property {boolean} [opaque=false] Whether the layer is opaque.
49010 * @property {import("../proj.js").ProjectionLike} [projection] Projection. Default is the view projection.
49011 * @property {number} [reprojectionErrorThreshold=0.5] Maximum allowed reprojection error (in pixels).
49012 * Higher values can increase reprojection performance, but decrease precision.
49013 * @property {import("./Source.js").State} [state] Source state.
49014 * @property {typeof import("../ImageTile.js").default} [tileClass] Class used to instantiate image tiles.
49015 * Default is {@link module:ol/ImageTile~ImageTile}.
49016 * @property {import("../tilegrid/TileGrid.js").default} [tileGrid] Tile grid.
49017 * @property {import("../Tile.js").LoadFunction} [tileLoadFunction] Optional function to load a tile given a URL. The default is
49018 * ```js
49019 * function(imageTile, src) {
49020 *   imageTile.getImage().src = src;
49021 * };
49022 * ```
49023 * @property {number} [tilePixelRatio=1] The pixel ratio used by the tile service. For example, if the tile
49024 * service advertizes 256px by 256px tiles but actually sends 512px
49025 * by 512px images (for retina/hidpi devices) then `tilePixelRatio`
49026 * should be set to `2`.
49027 * @property {import("../Tile.js").UrlFunction} [tileUrlFunction] Optional function to get tile URL given a tile coordinate and the projection.
49028 * @property {string} [url] URL template. Must include `{x}`, `{y}` or `{-y}`, and `{z}` placeholders.
49029 * A `{?-?}` template pattern, for example `subdomain{a-f}.domain.com`, may be
49030 * used instead of defining each one separately in the `urls` option.
49031 * @property {Array<string>} [urls] An array of URL templates.
49032 * @property {boolean} [wrapX] Whether to wrap the world horizontally. The default, is to
49033 * request out-of-bounds tiles from the server. When set to `false`, only one
49034 * world will be rendered. When set to `true`, tiles will be requested for one
49035 * world only, but they will be wrapped horizontally to render multiple worlds.
49036 * @property {number} [transition] Duration of the opacity transition for rendering.
49037 * To disable the opacity transition, pass `transition: 0`.
49038 * @property {string} [key] Optional tile key for proper cache fetching
49039 * @property {number|import("../array.js").NearestDirectionFunction} [zDirection=0]
49040 * Choose whether to use tiles with a higher or lower zoom level when between integer
49041 * zoom levels. See {@link module:ol/tilegrid/TileGrid~TileGrid#getZForResolution}.
49042 */
49043
49044/**
49045 * @classdesc
49046 * Base class for sources providing images divided into a tile grid.
49047 *
49048 * @fires import("./Tile.js").TileSourceEvent
49049 * @api
49050 */
49051class TileImage extends source_UrlTile {
49052  /**
49053   * @param {!Options} options Image tile options.
49054   */
49055  constructor(options) {
49056    super({
49057      attributions: options.attributions,
49058      cacheSize: options.cacheSize,
49059      opaque: options.opaque,
49060      projection: options.projection,
49061      state: options.state,
49062      tileGrid: options.tileGrid,
49063      tileLoadFunction: options.tileLoadFunction
49064        ? options.tileLoadFunction
49065        : defaultTileLoadFunction,
49066      tilePixelRatio: options.tilePixelRatio,
49067      tileUrlFunction: options.tileUrlFunction,
49068      url: options.url,
49069      urls: options.urls,
49070      wrapX: options.wrapX,
49071      transition: options.transition,
49072      interpolate:
49073        options.interpolate !== undefined ? options.interpolate : true,
49074      key: options.key,
49075      attributionsCollapsible: options.attributionsCollapsible,
49076      zDirection: options.zDirection,
49077    });
49078
49079    /**
49080     * @protected
49081     * @type {?string}
49082     */
49083    this.crossOrigin =
49084      options.crossOrigin !== undefined ? options.crossOrigin : null;
49085
49086    /**
49087     * @protected
49088     * @type {typeof ImageTile}
49089     */
49090    this.tileClass =
49091      options.tileClass !== undefined ? options.tileClass : ol_ImageTile;
49092
49093    /**
49094     * @protected
49095     * @type {!Object<string, TileCache>}
49096     */
49097    this.tileCacheForProjection = {};
49098
49099    /**
49100     * @protected
49101     * @type {!Object<string, import("../tilegrid/TileGrid.js").default>}
49102     */
49103    this.tileGridForProjection = {};
49104
49105    /**
49106     * @private
49107     * @type {number|undefined}
49108     */
49109    this.reprojectionErrorThreshold_ = options.reprojectionErrorThreshold;
49110
49111    /**
49112     * @private
49113     * @type {boolean}
49114     */
49115    this.renderReprojectionEdges_ = false;
49116  }
49117
49118  /**
49119   * @return {boolean} Can expire cache.
49120   */
49121  canExpireCache() {
49122    if (this.tileCache.canExpireCache()) {
49123      return true;
49124    } else {
49125      for (const key in this.tileCacheForProjection) {
49126        if (this.tileCacheForProjection[key].canExpireCache()) {
49127          return true;
49128        }
49129      }
49130    }
49131    return false;
49132  }
49133
49134  /**
49135   * @param {import("../proj/Projection.js").default} projection Projection.
49136   * @param {!Object<string, boolean>} usedTiles Used tiles.
49137   */
49138  expireCache(projection, usedTiles) {
49139    const usedTileCache = this.getTileCacheForProjection(projection);
49140
49141    this.tileCache.expireCache(
49142      this.tileCache == usedTileCache ? usedTiles : {}
49143    );
49144    for (const id in this.tileCacheForProjection) {
49145      const tileCache = this.tileCacheForProjection[id];
49146      tileCache.expireCache(tileCache == usedTileCache ? usedTiles : {});
49147    }
49148  }
49149
49150  /**
49151   * @param {import("../proj/Projection.js").default} projection Projection.
49152   * @return {number} Gutter.
49153   */
49154  getGutterForProjection(projection) {
49155    if (
49156      this.getProjection() &&
49157      projection &&
49158      !equivalent(this.getProjection(), projection)
49159    ) {
49160      return 0;
49161    } else {
49162      return this.getGutter();
49163    }
49164  }
49165
49166  /**
49167   * @return {number} Gutter.
49168   */
49169  getGutter() {
49170    return 0;
49171  }
49172
49173  /**
49174   * Return the key to be used for all tiles in the source.
49175   * @return {string} The key for all tiles.
49176   */
49177  getKey() {
49178    let key = super.getKey();
49179    if (!this.getInterpolate()) {
49180      key += ':disable-interpolation';
49181    }
49182    return key;
49183  }
49184
49185  /**
49186   * @param {import("../proj/Projection.js").default} projection Projection.
49187   * @return {boolean} Opaque.
49188   */
49189  getOpaque(projection) {
49190    if (
49191      this.getProjection() &&
49192      projection &&
49193      !equivalent(this.getProjection(), projection)
49194    ) {
49195      return false;
49196    } else {
49197      return super.getOpaque(projection);
49198    }
49199  }
49200
49201  /**
49202   * @param {import("../proj/Projection.js").default} projection Projection.
49203   * @return {!import("../tilegrid/TileGrid.js").default} Tile grid.
49204   */
49205  getTileGridForProjection(projection) {
49206    const thisProj = this.getProjection();
49207    if (this.tileGrid && (!thisProj || equivalent(thisProj, projection))) {
49208      return this.tileGrid;
49209    } else {
49210      const projKey = getUid(projection);
49211      if (!(projKey in this.tileGridForProjection)) {
49212        this.tileGridForProjection[projKey] =
49213          getForProjection(projection);
49214      }
49215      return this.tileGridForProjection[projKey];
49216    }
49217  }
49218
49219  /**
49220   * @param {import("../proj/Projection.js").default} projection Projection.
49221   * @return {import("../TileCache.js").default} Tile cache.
49222   */
49223  getTileCacheForProjection(projection) {
49224    const thisProj = this.getProjection();
49225    if (!thisProj || equivalent(thisProj, projection)) {
49226      return this.tileCache;
49227    } else {
49228      const projKey = getUid(projection);
49229      if (!(projKey in this.tileCacheForProjection)) {
49230        this.tileCacheForProjection[projKey] = new ol_TileCache(
49231          this.tileCache.highWaterMark
49232        );
49233      }
49234      return this.tileCacheForProjection[projKey];
49235    }
49236  }
49237
49238  /**
49239   * @param {number} z Tile coordinate z.
49240   * @param {number} x Tile coordinate x.
49241   * @param {number} y Tile coordinate y.
49242   * @param {number} pixelRatio Pixel ratio.
49243   * @param {import("../proj/Projection.js").default} projection Projection.
49244   * @param {string} key The key set on the tile.
49245   * @return {!ImageTile} Tile.
49246   * @private
49247   */
49248  createTile_(z, x, y, pixelRatio, projection, key) {
49249    const tileCoord = [z, x, y];
49250    const urlTileCoord = this.getTileCoordForTileUrlFunction(
49251      tileCoord,
49252      projection
49253    );
49254    const tileUrl = urlTileCoord
49255      ? this.tileUrlFunction(urlTileCoord, pixelRatio, projection)
49256      : undefined;
49257    const tile = new this.tileClass(
49258      tileCoord,
49259      tileUrl !== undefined ? TileState.IDLE : TileState.EMPTY,
49260      tileUrl !== undefined ? tileUrl : '',
49261      this.crossOrigin,
49262      this.tileLoadFunction,
49263      this.tileOptions
49264    );
49265    tile.key = key;
49266    tile.addEventListener(EventType.CHANGE, this.handleTileChange.bind(this));
49267    return tile;
49268  }
49269
49270  /**
49271   * @param {number} z Tile coordinate z.
49272   * @param {number} x Tile coordinate x.
49273   * @param {number} y Tile coordinate y.
49274   * @param {number} pixelRatio Pixel ratio.
49275   * @param {import("../proj/Projection.js").default} projection Projection.
49276   * @return {!(ImageTile|ReprojTile)} Tile.
49277   */
49278  getTile(z, x, y, pixelRatio, projection) {
49279    const sourceProjection = this.getProjection();
49280    if (
49281      !sourceProjection ||
49282      !projection ||
49283      equivalent(sourceProjection, projection)
49284    ) {
49285      return this.getTileInternal(
49286        z,
49287        x,
49288        y,
49289        pixelRatio,
49290        sourceProjection || projection
49291      );
49292    } else {
49293      const cache = this.getTileCacheForProjection(projection);
49294      const tileCoord = [z, x, y];
49295      let tile;
49296      const tileCoordKey = tilecoord_getKey(tileCoord);
49297      if (cache.containsKey(tileCoordKey)) {
49298        tile = cache.get(tileCoordKey);
49299      }
49300      const key = this.getKey();
49301      if (tile && tile.key == key) {
49302        return tile;
49303      } else {
49304        const sourceTileGrid = this.getTileGridForProjection(sourceProjection);
49305        const targetTileGrid = this.getTileGridForProjection(projection);
49306        const wrappedTileCoord = this.getTileCoordForTileUrlFunction(
49307          tileCoord,
49308          projection
49309        );
49310        const newTile = new reproj_Tile(
49311          sourceProjection,
49312          sourceTileGrid,
49313          projection,
49314          targetTileGrid,
49315          tileCoord,
49316          wrappedTileCoord,
49317          this.getTilePixelRatio(pixelRatio),
49318          this.getGutter(),
49319          function (z, x, y, pixelRatio) {
49320            return this.getTileInternal(z, x, y, pixelRatio, sourceProjection);
49321          }.bind(this),
49322          this.reprojectionErrorThreshold_,
49323          this.renderReprojectionEdges_,
49324          this.getInterpolate()
49325        );
49326        newTile.key = key;
49327
49328        if (tile) {
49329          newTile.interimTile = tile;
49330          newTile.refreshInterimChain();
49331          cache.replace(tileCoordKey, newTile);
49332        } else {
49333          cache.set(tileCoordKey, newTile);
49334        }
49335        return newTile;
49336      }
49337    }
49338  }
49339
49340  /**
49341   * @param {number} z Tile coordinate z.
49342   * @param {number} x Tile coordinate x.
49343   * @param {number} y Tile coordinate y.
49344   * @param {number} pixelRatio Pixel ratio.
49345   * @param {!import("../proj/Projection.js").default} projection Projection.
49346   * @return {!(ImageTile|ReprojTile)} Tile.
49347   * @protected
49348   */
49349  getTileInternal(z, x, y, pixelRatio, projection) {
49350    let tile = null;
49351    const tileCoordKey = getKeyZXY(z, x, y);
49352    const key = this.getKey();
49353    if (!this.tileCache.containsKey(tileCoordKey)) {
49354      tile = this.createTile_(z, x, y, pixelRatio, projection, key);
49355      this.tileCache.set(tileCoordKey, tile);
49356    } else {
49357      tile = this.tileCache.get(tileCoordKey);
49358      if (tile.key != key) {
49359        // The source's params changed. If the tile has an interim tile and if we
49360        // can use it then we use it. Otherwise we create a new tile.  In both
49361        // cases we attempt to assign an interim tile to the new tile.
49362        const interimTile = tile;
49363        tile = this.createTile_(z, x, y, pixelRatio, projection, key);
49364
49365        //make the new tile the head of the list,
49366        if (interimTile.getState() == TileState.IDLE) {
49367          //the old tile hasn't begun loading yet, and is now outdated, so we can simply discard it
49368          tile.interimTile = interimTile.interimTile;
49369        } else {
49370          tile.interimTile = interimTile;
49371        }
49372        tile.refreshInterimChain();
49373        this.tileCache.replace(tileCoordKey, tile);
49374      }
49375    }
49376    return tile;
49377  }
49378
49379  /**
49380   * Sets whether to render reprojection edges or not (usually for debugging).
49381   * @param {boolean} render Render the edges.
49382   * @api
49383   */
49384  setRenderReprojectionEdges(render) {
49385    if (this.renderReprojectionEdges_ == render) {
49386      return;
49387    }
49388    this.renderReprojectionEdges_ = render;
49389    for (const id in this.tileCacheForProjection) {
49390      this.tileCacheForProjection[id].clear();
49391    }
49392    this.changed();
49393  }
49394
49395  /**
49396   * Sets the tile grid to use when reprojecting the tiles to the given
49397   * projection instead of the default tile grid for the projection.
49398   *
49399   * This can be useful when the default tile grid cannot be created
49400   * (e.g. projection has no extent defined) or
49401   * for optimization reasons (custom tile size, resolutions, ...).
49402   *
49403   * @param {import("../proj.js").ProjectionLike} projection Projection.
49404   * @param {import("../tilegrid/TileGrid.js").default} tilegrid Tile grid to use for the projection.
49405   * @api
49406   */
49407  setTileGridForProjection(projection, tilegrid) {
49408    const proj = proj_get(projection);
49409    if (proj) {
49410      const projKey = getUid(proj);
49411      if (!(projKey in this.tileGridForProjection)) {
49412        this.tileGridForProjection[projKey] = tilegrid;
49413      }
49414    }
49415  }
49416
49417  clear() {
49418    super.clear();
49419    for (const id in this.tileCacheForProjection) {
49420      this.tileCacheForProjection[id].clear();
49421    }
49422  }
49423}
49424
49425/**
49426 * @param {ImageTile} imageTile Image tile.
49427 * @param {string} src Source.
49428 */
49429function defaultTileLoadFunction(imageTile, src) {
49430  /** @type {HTMLImageElement|HTMLVideoElement} */ (imageTile.getImage()).src =
49431    src;
49432}
49433
49434/* harmony default export */ const source_TileImage = (TileImage);
49435
49436;// CONCATENATED MODULE: ./node_modules/ol/source/XYZ.js
49437/**
49438 * @module ol/source/XYZ
49439 */
49440
49441
49442
49443
49444/**
49445 * @typedef {Object} Options
49446 * @property {import("./Source.js").AttributionLike} [attributions] Attributions.
49447 * @property {boolean} [attributionsCollapsible=true] Attributions are collapsible.
49448 * @property {number} [cacheSize] Initial tile cache size. Will auto-grow to hold at least the number of tiles in the viewport.
49449 * @property {null|string} [crossOrigin] The `crossOrigin` attribute for loaded images.  Note that
49450 * you must provide a `crossOrigin` value if you want to access pixel data with the Canvas renderer.
49451 * See https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_
49451image for more detail.
49452 * @property {boolean} [interpolate=true] Use interpolated values when resampling.  By default,
49453 * linear interpolation is used when resampling.  Set to false to use the nearest neighbor instead.
49454 * @property {boolean} [opaque=false] Whether the layer is opaque.
49455 * @property {import("../proj.js").ProjectionLike} [projection='EPSG:3857'] Projection.
49456 * @property {number} [reprojectionErrorThreshold=0.5] Maximum allowed reprojection error (in pixels).
49457 * Higher values can increase reprojection performance, but decrease precision.
49458 * @property {number} [maxZoom=42] Optional max zoom level. Not used if `tileGrid` is provided.
49459 * @property {number} [minZoom=0] Optional min zoom level. Not used if `tileGrid` is provided.
49460 * @property {number} [maxResolution] Optional tile grid resolution at level zero. Not used if `tileGrid` is provided.
49461 * @property {import("../tilegrid/TileGrid.js").default} [tileGrid] Tile grid.
49462 * @property {import("../Tile.js").LoadFunction} [tileLoadFunction] Optional function to load a tile given a URL. The default is
49463 * ```js
49464 * function(imageTile, src) {
49465 *   imageTile.getImage().src = src;
49466 * };
49467 * ```
49468 * @property {number} [tilePixelRatio=1] The pixel ratio used by the tile service.
49469 * For example, if the tile service advertizes 256px by 256px tiles but actually sends 512px
49470 * by 512px images (for retina/hidpi devices) then `tilePixelRatio`
49471 * should be set to `2`.
49472 * @property {number|import("../size.js").Size} [tileSize=[256, 256]] The tile size used by the tile service.
49473 * Not used if `tileGrid` is provided.
49474 * @property {number} [gutter=0] The size in pixels of the gutter around image tiles to ignore.
49475 * This allows artifacts of rendering at tile edges to be ignored.
49476 * Supported images should be wider and taller than the tile size by a value of `2 x gutter`.
49477 * @property {import("../Tile.js").UrlFunction} [tileUrlFunction] Optional function to get
49478 * tile URL given a tile coordinate and the projection.
49479 * Required if `url` or `urls` are not provided.
49480 * @property {string} [url] URL template. Must include `{x}`, `{y}` or `{-y}`,
49481 * and `{z}` placeholders. A `{?-?}` template pattern, for example `subdomain{a-f}.domain.com`,
49482 * may be used instead of defining each one separately in the `urls` option.
49483 * @property {Array<string>} [urls] An array of URL templates.
49484 * @property {boolean} [wrapX=true] Whether to wrap the world horizontally.
49485 * @property {number} [transition=250] Duration of the opacity transition for rendering.
49486 * To disable the opacity transition, pass `transition: 0`.
49487 * @property {number|import("../array.js").NearestDirectionFunction} [zDirection=0]
49488 * Choose whether to use tiles with a higher or lower zoom level when between integer
49489 * zoom levels. See {@link module:ol/tilegrid/TileGrid~TileGrid#getZForResolution}.
49490 */
49491
49492/**
49493 * @classdesc
49494 * Layer source for tile data with URLs in a set XYZ format that are
49495 * defined in a URL template. By default, this follows the widely-used
49496 * Google grid where `x` 0 and `y` 0 are in the top left. Grids like
49497 * TMS where `x` 0 and `y` 0 are in the bottom left can be used by
49498 * using the `{-y}` placeholder in the URL template, so long as the
49499 * source does not have a custom tile grid. In this case
49500 * a `tileUrlFunction` can be used, such as:
49501 * ```js
49502 *  tileUrlFunction: function(coordinate) {
49503 *    return 'http://mapserver.com/' + coordinate[0] + '/' +
49504 *      coordinate[1] + '/' + (-coordinate[2] - 1) + '.png';
49505 *  }
49506 * ```
49507 * @api
49508 */
49509class XYZ_XYZ extends source_TileImage {
49510  /**
49511   * @param {Options} [options] XYZ options.
49512   */
49513  constructor(options) {
49514    options = options || {};
49515
49516    const projection =
49517      options.projection !== undefined ? options.projection : 'EPSG:3857';
49518
49519    const tileGrid =
49520      options.tileGrid !== undefined
49521        ? options.tileGrid
49522        : createXYZ({
49523            extent: extentFromProjection(projection),
49524            maxResolution: options.maxResolution,
49525            maxZoom: options.maxZoom,
49526            minZoom: options.minZoom,
49527            tileSize: options.tileSize,
49528          });
49529
49530    super({
49531      attributions: options.attributions,
49532      cacheSize: options.cacheSize,
49533      crossOrigin: options.crossOrigin,
49534      interpolate: options.interpolate,
49535      opaque: options.opaque,
49536      projection: projection,
49537      reprojectionErrorThreshold: options.reprojectionErrorThreshold,
49538      tileGrid: tileGrid,
49539      tileLoadFunction: options.tileLoadFunction,
49540      tilePixelRatio: options.tilePixelRatio,
49541      tileUrlFunction: options.tileUrlFunction,
49542      url: options.url,
49543      urls: options.urls,
49544      wrapX: options.wrapX !== undefined ? options.wrapX : true,
49545      transition: options.transition,
49546      attributionsCollapsible: options.attributionsCollapsible,
49547      zDirection: options.zDirection,
49548    });
49549
49550    /**
49551     * @private
49552     * @type {number}
49553     */
49554    this.gutter_ = options.gutter !== undefined ? options.gutter : 0;
49555  }
49556
49557  /**
49558   * @return {number} Gutter.
49559   */
49560  getGutter() {
49561    return this.gutter_;
49562  }
49563}
49564
49565/* harmony default export */ const source_XYZ = (XYZ_XYZ);
49566
49567;// CONCATENATED MODULE: ./node_modules/ol/structs/RBush.js
49568/**
49569 * @module ol/structs/RBush
49570 */
49571
49572
49573
49574
49575
49576/**
49577 * @typedef {Object} Entry
49578 * @property {number} minX MinX.
49579 * @property {number} minY MinY.
49580 * @property {number} maxX MaxX.
49581 * @property {number} maxY MaxY.
49582 * @property {Object} [value] Value.
49583 */
49584
49585/**
49586 * @classdesc
49587 * Wrapper around the RBush by Vladimir Agafonkin.
49588 * See https://github.com/mourner/rbush.
49589 *
49590 * @template T
49591 */
49592class RBush {
49593  /**
49594   * @param {number} [maxEntries] Max entries.
49595   */
49596  constructor(maxEntries) {
49597    /**
49598     * @private
49599     */
49600    this.rbush_ = new rbush_min(maxEntries);
49601
49602    /**
49603     * A mapping between the objects added to this rbush wrapper
49604     * and the objects that are actually added to the internal rbush.
49605     * @private
49606     * @type {Object<string, Entry>}
49607     */
49608    this.items_ = {};
49609  }
49610
49611  /**
49612   * Insert a value into the RBush.
49613   * @param {import("../extent.js").Extent} extent Extent.
49614   * @param {T} value Value.
49615   */
49616  insert(extent, value) {
49617    /** @type {Entry} */
49618    const item = {
49619      minX: extent[0],
49620      minY: extent[1],
49621      maxX: extent[2],
49622      maxY: extent[3],
49623      value: value,
49624    };
49625
49626    this.rbush_.insert(item);
49627    this.items_[getUid(value)] = item;
49628  }
49629
49630  /**
49631   * Bulk-insert values into the RBush.
49632   * @param {Array<import("../extent.js").Extent>} extents Extents.
49633   * @param {Array<T>} values Values.
49634   */
49635  load(extents, values) {
49636    const items = new Array(values.length);
49637    for (let i = 0, l = values.length; i < l; i++) {
49638      const extent = extents[i];
49639      const value = values[i];
49640
49641      /** @type {Entry} */
49642      const item = {
49643        minX: extent[0],
49644        minY: extent[1],
49645        maxX: extent[2],
49646        maxY: extent[3],
49647        value: value,
49648      };
49649      items[i] = item;
49650      this.items_[getUid(value)] = item;
49651    }
49652    this.rbush_.load(items);
49653  }
49654
49655  /**
49656   * Remove a value from the RBush.
49657   * @param {T} value Value.
49658   * @return {boolean} Removed.
49659   */
49660  remove(value) {
49661    const uid = getUid(value);
49662
49663    // get the object in which the value was wrapped when adding to the
49664    // internal rbush. then use that object to do the removal.
49665    const item = this.items_[uid];
49666    delete this.items_[uid];
49667    return this.rbush_.remove(item) !== null;
49668  }
49669
49670  /**
49671   * Update the extent of a value in the RBush.
49672   * @param {import("../extent.js").Extent} extent Extent.
49673   * @param {T} value Value.
49674   */
49675  update(extent, value) {
49676    const item = this.items_[getUid(value)];
49677    const bbox = [item.minX, item.minY, item.maxX, item.maxY];
49678    if (!extent_equals(bbox, extent)) {
49679      this.remove(value);
49680      this.insert(extent, value);
49681    }
49682  }
49683
49684  /**
49685   * Return all values in the RBush.
49686   * @return {Array<T>} All.
49687   */
49688  getAll() {
49689    const items = this.rbush_.all();
49690    return items.map(function (item) {
49691      return item.value;
49692    });
49693  }
49694
49695  /**
49696   * Return all values in the given extent.
49697   * @param {import("../extent.js").Extent} extent Extent.
49698   * @return {Array<T>} All in extent.
49699   */
49700  getInExtent(extent) {
49701    /** @type {Entry} */
49702    const bbox = {
49703      minX: extent[0],
49704      minY: extent[1],
49705      maxX: extent[2],
49706      maxY: extent[3],
49707    };
49708    const items = this.rbush_.search(bbox);
49709    return items.map(function (item) {
49710      return item.value;
49711    });
49712  }
49713
49714  /**
49715   * Calls a callback function with each value in the tree.
49716   * If the callback returns a truthy value, this value is returned without
49717   * checking the rest of the tree.
49718   * @param {function(T): *} callback Callback.
49719   * @return {*} Callback return value.
49720   */
49721  forEach(callback) {
49722    return this.forEach_(this.getAll(), callback);
49723  }
49724
49725  /**
49726   * Calls a callback function with each value in the provided extent.
49727   * @param {import("../extent.js").Extent} extent Extent.
49728   * @param {function(T): *} callback Callback.
49729   * @return {*} Callback return value.
49730   */
49731  forEachInExtent(extent, callback) {
49732    return this.forEach_(this.getInExtent(extent), callback);
49733  }
49734
49735  /**
49736   * @param {Array<T>} values Values.
49737   * @param {function(T): *} callback Callback.
49738   * @private
49739   * @return {*} Callback return value.
49740   */
49741  forEach_(values, callback) {
49742    let result;
49743    for (let i = 0, l = values.length; i < l; i++) {
49744      result = callback(values[i]);
49745      if (result) {
49746        return result;
49747      }
49748    }
49749    return result;
49750  }
49751
49752  /**
49753   * @return {boolean} Is empty.
49754   */
49755  isEmpty() {
49756    return obj_isEmpty(this.items_);
49757  }
49758
49759  /**
49760   * Remove all values from the RBush.
49761   */
49762  clear() {
49763    this.rbush_.clear();
49764    this.items_ = {};
49765  }
49766
49767  /**
49768   * @param {import("../extent.js").Extent} [extent] Extent.
49769   * @return {import("../extent.js").Extent} Extent.
49770   */
49771  getExtent(extent) {
49772    const data = this.rbush_.toJSON();
49773    return createOrUpdate(data.minX, data.minY, data.maxX, data.maxY, extent);
49774  }
49775
49776  /**
49777   * @param {RBush} rbush R-Tree.
49778   */
49779  concat(rbush) {
49780    this.rbush_.load(rbush.rbush_.all());
49781    for (const i in rbush.items_) {
49782      this.items_[i] = rbush.items_[i];
49783    }
49784  }
49785}
49786
49787/* harmony default export */ const structs_RBush = (RBush);
49788
49789;// CONCATENATED MODULE: ./node_modules/ol/source/VectorEventType.js
49790/**
49791 * @module ol/source/VectorEventType
49792 */
49793
49794/**
49795 * @enum {string}
49796 */
49797/* harmony default export */ const VectorEventType = ({
49798  /**
49799   * Triggered when a feature is added to the source.
49800   * @event module:ol/source/Vector.VectorSourceEvent#addfeature
49801   * @api
49802   */
49803  ADDFEATURE: 'addfeature',
49804
49805  /**
49806   * Triggered when a feature is updated.
49807   * @event module:ol/source/Vector.VectorSourceEvent#changefeature
49808   * @api
49809   */
49810  CHANGEFEATURE: 'changefeature',
49811
49812  /**
49813   * Triggered when the clear method is called on the source.
49814   * @event module:ol/source/Vector.VectorSourceEvent#clear
49815   * @api
49816   */
49817  CLEAR: 'clear',
49818
49819  /**
49820   * Triggered when a feature is removed from the source.
49821   * See {@link module:ol/source/Vector~VectorSource#clear source.clear()} for exceptions.
49822   * @event module:ol/source/Vector.VectorSourceEvent#removefeature
49823   * @api
49824   */
49825  REMOVEFEATURE: 'removefeature',
49826
49827  /**
49828   * Triggered when features starts loading.
49829   * @event module:ol/source/Vector.VectorSourceEvent#featuresloadstart
49830   * @api
49831   */
49832  FEATURESLOADSTART: 'featuresloadstart',
49833
49834  /**
49835   * Triggered when features finishes loading.
49836   * @event module:ol/source/Vector.VectorSourceEvent#featuresloadend
49837   * @api
49838   */
49839  FEATURESLOADEND: 'featuresloadend',
49840
49841  /**
49842   * Triggered if feature loading results in an error.
49843   * @event module:ol/source/Vector.VectorSourceEvent#featuresloaderror
49844   * @api
49845   */
49846  FEATURESLOADERROR: 'featuresloaderror',
49847});
49848
49849/**
49850 * @typedef {'addfeature'|'changefeature'|'clear'|'removefeature'|'featuresloadstart'|'featuresloadend'|'featuresloaderror'} VectorSourceEventTypes
49851 */
49852
49853;// CONCATENATED MODULE: ./node_modules/ol/loadingstrategy.js
49854/**
49855 * @module ol/loadingstrategy
49856 */
49857
49858
49859
49860/**
49861 * Strategy function for loading all features with a single request.
49862 * @param {import("./extent.js").Extent} extent Extent.
49863 * @param {number} resolution Resolution.
49864 * @return {Array<import("./extent.js").Extent>} Extents.
49865 * @api
49866 */
49867function loadingstrategy_all(extent, resolution) {
49868  return [[-Infinity, -Infinity, Infinity, Infinity]];
49869}
49870
49871/**
49872 * Strategy function for loading features based on the view's extent and
49873 * resolution.
49874 * @param {import("./extent.js").Extent} extent Extent.
49875 * @param {number} resolution Resolution.
49876 * @return {Array<import("./extent.js").Extent>} Extents.
49877 * @api
49878 */
49879function bbox(extent, resolution) {
49880  return [extent];
49881}
49882
49883/**
49884 * Creates a strategy function for loading features based on a tile grid.
49885 * @param {import("./tilegrid/TileGrid.js").default} tileGrid Tile grid.
49886 * @return {function(import("./extent.js").Extent, number, import("./proj.js").Projection): Array<import("./extent.js").Extent>} Loading strategy.
49887 * @api
49888 */
49889function tile(tileGrid) {
49890  return (
49891    /**
49892     * @param {import("./extent.js").Extent} extent Extent.
49893     * @param {number} resolution Resolution.
49894     * @param {import("./proj.js").Projection} projection Projection.
49895     * @return {Array<import("./extent.js").Extent>} Extents.
49896     */
49897    function (extent, resolution, projection) {
49898      const z = tileGrid.getZForResolution(
49899        fromUserResolution(resolution, projection)
49900      );
49901      const tileRange = tileGrid.getTileRangeForExtentAndZ(
49902        fromUserExtent(extent, projection),
49903        z
49904      );
49905      /** @type {Array<import("./extent.js").Extent>} */
49906      const extents = [];
49907      /** @type {import("./tilecoord.js").TileCoord} */
49908      const tileCoord = [z, 0, 0];
49909      for (
49910        tileCoord[1] = tileRange.minX;
49911        tileCoord[1] <= tileRange.maxX;
49912        ++tileCoord[1]
49913      ) {
49914        for (
49915          tileCoord[2] = tileRange.minY;
49916          tileCoord[2] <= tileRange.maxY;
49917          ++tileCoord[2]
49918        ) {
49919          extents.push(
49920            toUserExtent(tileGrid.getTileCoordExtent(tileCoord), projection)
49921          );
49922        }
49923      }
49924      return extents;
49925    }
49926  );
49927}
49928
49929;// CONCATENATED MODULE: ./node_modules/ol/featureloader.js
49930/**
49931 * @module ol/featureloader
49932 */
49933
49934
49935/**
49936 *
49937 * @type {boolean}
49938 * @private
49939 */
49940let withCredentials = false;
49941
49942/**
49943 * {@link module:ol/source/Vector~VectorSource} sources use a function of this type to
49944 * load features.
49945 *
49946 * This function takes up to 5 arguments. These are an {@link module:ol/extent~Extent} representing
49947 * the area to be loaded, a `{number}` representing the resolution (map units per pixel), an
49948 * {@link module:ol/proj/Projection~Projection} for the projection, an optional success callback that should get
49949 * the loaded features passed as an argument and an optional failure callback with no arguments. If
49950 * the callbacks are not used, the corresponding vector source will not fire `'featuresloadend'` and
49951 * `'featuresloaderror'` events. `this` within the function is bound to the
49952 * {@link module:ol/source/Vector~VectorSource} it's called from.
49953 *
49954 * The function is responsible for loading the features and adding them to the
49955 * source.
49956 * @typedef {function(this:(import("./source/Vector").default|import("./VectorTile.js").default),
49957 *           import("./extent.js").Extent,
49958 *           number,
49959 *           import("./proj/Projection.js").default,
49960 *           function(Array<import("./Feature.js").default>): void=,
49961 *           function(): void=): void} FeatureLoader
49962 * @api
49963 */
49964
49965/**
49966 * {@link module:ol/source/Vector~VectorSource} sources use a function of this type to
49967 * get the url to load features from.
49968 *
49969 * This function takes an {@link module:ol/extent~Extent} representing the area
49970 * to be loaded, a `{number}` representing the resolution (map units per pixel)
49971 * and an {@link module:ol/proj/Projection~Projection} for the projection  as
49972 * arguments and returns a `{string}` representing the URL.
49973 * @typedef {function(import("./extent.js").Extent, number, import("./proj/Projection.js").default): string} FeatureUrlFunction
49974 * @api
49975 */
49976
49977/**
49978 * @param {string|FeatureUrlFunction} url Feature URL service.
49979 * @param {import("./format/Feature.js").default} format Feature format.
49980 * @param {import("./extent.js").Extent} extent Extent.
49981 * @param {number} resolution Resolution.
49982 * @param {import("./proj/Projection.js").default} projection Projection.
49983 * @param {function(Array<import("./Feature.js").default>, import("./proj/Projection.js").default): void} success Success
49984 *      Function called with the loaded features and optionally with the data projection.
49985 * @param {function(): void} failure Failure
49986 *      Function called when loading failed.
49987 */
49988function loadFeaturesXhr(
49989  url,
49990  format,
49991  extent,
49992  resolution,
49993  projection,
49994  success,
49995  failure
49996) {
49997  const xhr = new XMLHttpRequest();
49998  xhr.open(
49999    'GET',
50000    typeof url === 'function' ? url(extent, resolution, projection) : url,
50001    true
50002  );
50003  if (format.getType() == 'arraybuffer') {
50004    xhr.responseType = 'arraybuffer';
50005  }
50006  xhr.withCredentials = withCredentials;
50007  /**
50008   * @param {Event} event Event.
50009   * @private
50010   */
50011  xhr.onload = function (event) {
50012    // status will be 0 for file:// urls
50013    if (!xhr.status || (xhr.status >= 200 && xhr.status < 300)) {
50014      const type = format.getType();
50015      /** @type {Document|Node|Object|string|undefined} */
50016      let source;
50017      if (type == 'json' || type == 'text') {
50018        source = xhr.responseText;
50019      } else if (type == 'xml') {
50020        source = xhr.responseXML;
50021        if (!source) {
50022          source = new DOMParser().parseFromString(
50023            xhr.responseText,
50024            'application/xml'
50025          );
50026        }
50027      } else if (type == 'arraybuffer') {
50028        source = /** @type {ArrayBuffer} */ (xhr.response);
50029      }
50030      if (source) {
50031        success(
50032          /** @type {Array<import("./Feature.js").default>} */
50033          (
50034            format.readFeatures(source, {
50035              extent: extent,
50036              featureProjection: projection,
50037            })
50038          ),
50039          format.readProjection(source)
50040        );
50041      } else {
50042        failure();
50043      }
50044    } else {
50045      failure();
50046    }
50047  };
50048  /**
50049   * @private
50050   */
50051  xhr.onerror = failure;
50052  xhr.send();
50053}
50054
50055/**
50056 * Create an XHR feature loader for a `url` and `format`. The feature loader
50057 * loads features (with XHR), parses the features, and adds them to the
50058 * vector source.
50059 * @param {string|FeatureUrlFunction} url Feature URL service.
50060 * @param {import("./format/Feature.js").default} format Feature format.
50061 * @return {FeatureLoader} The feature loader.
50062 * @api
50063 */
50064function xhr(url, format) {
50065  /**
50066   * @param {import("./extent.js").Extent} extent Extent.
50067   * @param {number} resolution Resolution.
50068   * @param {import("./proj/Projection.js").default} projection Projection.
50069   * @param {function(Array<import("./Feature.js").default>): void} [success] Success
50070   *      Function called when loading succeeded.
50071   * @param {function(): void} [failure] Failure
50072   *      Function called when loading failed.
50073   * @this {import("./source/Vector").default}
50074   */
50075  return function (extent, resolution, projection, success, failure) {
50076    const source = /** @type {import("./source/Vector").default} */ (this);
50077    loadFeaturesXhr(
50078      url,
50079      format,
50080      extent,
50081      resolution,
50082      projection,
50083      /**
50084       * @param {Array<import("./Feature.js").default>} features The loaded features.
50085       * @param {import("./proj/Projection.js").default} dataProjection Data
50086       * projection.
50087       */
50088      function (features, dataProjection) {
50089        source.addFeatures(features);
50090        if (success !== undefined) {
50091          success(features);
50092        }
50093      },
50094      /* FIXME handle error */ failure ? failure : VOID
50095    );
50096  };
50097}
50098
50099/**
50100 * Setter for the withCredentials configuration for the XHR.
50101 *
50102 * @param {boolean} xhrWithCredentials The value of withCredentials to set.
50103 * Compare https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/
50104 * @api
50105 */
50106function setWithCredentials(xhrWithCredentials) {
50107  withCredentials = xhrWithCredentials;
50108}
50109
50110;// CONCATENATED MODULE: ./node_modules/ol/source/Vector.js
50111/**
50112 * @module ol/source/Vector
50113 */
50114
50115
50116
50117
50118
50119
50120
50121
50122
50123
50124
50125
50126
50127
50128
50129
50130
50131
50132
50133/**
50134 * A function that takes an {@link module:ol/extent~Extent} and a resolution as arguments, and
50135 * returns an array of {@link module:ol/extent~Extent} with the extents to load. Usually this
50136 * is one of the standard {@link module:ol/loadingstrategy} strategies.
50137 *
50138 * @typedef {function(import("../extent.js").Extent, number, import("../proj/Projection.js").default): Array<import("../extent.js").Extent>} LoadingStrategy
50139 * @api
50140 */
50141
50142/**
50143 * @classdesc
50144 * Events emitted by {@link module:ol/source/Vector~VectorSource} instances are instances of this
50145 * type.
50146 * @template {import("../geom/Geometry.js").default} [Geometry=import("../geom/Geometry.js").default]
50147 */
50148class VectorSourceEvent extends Event {
50149  /**
50150   * @param {string} type Type.
50151   * @param {import("../Feature.js").default<Geometry>} [feature] Feature.
50152   * @param {Array<import("../Feature.js").default<Geometry>>} [features] Features.
50153   */
50154  constructor(type, feature, features) {
50155    super(type);
50156
50157    /**
50158     * The added or removed feature for the `ADDFEATURE` and `REMOVEFEATURE` events, `undefined` otherwise.
50159     * @type {import("../Feature.js").default<Geometry>|undefined}
50160     * @api
50161     */
50162    this.feature = feature;
50163
50164    /**
50165     * The loaded features for the `FEATURESLOADED` event, `undefined` otherwise.
50166     * @type {Array<import("../Feature.js").default<Geometry>>|undefined}
50167     * @api
50168     */
50169    this.features = features;
50170  }
50171}
50172
50173/***
50174 * @template Return
50175 * @typedef {import("../Observable").OnSignature<import("../Observable").EventTypes, import("../events/Event.js").default, Return> &
50176 *   import("../Observable").OnSignature<import("../ObjectEventType").Types, import("../Object").ObjectEvent, Return> &
50177 *   import("../Observable").OnSignature<import("./VectorEventType").VectorSourceEventTypes, VectorSourceEvent, Return> &
50178 *   import("../Observable").CombinedOnSignature<import("../Observable").EventTypes|import("../ObjectEventType").Types|
50179 *     import("./VectorEventType").VectorSourceEventTypes, Return>} VectorSourceOnSignature
50180 */
50181
50182/**
50183 * @typedef {Object} Options
50184 * @property {import("./Source.js").AttributionLike} [attributions] Attributions.
50185 * @property {Array<import("../Feature.js").default<Geometry>>|Collection<import("../Feature.js").default<Geometry>>} [features]
50186 * Features. If provided as {@link module:ol/Collection~Collection}, the features in the source
50187 * and the collection will stay in sync.
50188 * @property {import("../format/Feature.js").default} [format] The feature format used by the XHR
50189 * feature loader when `url` is set. Required if `url` is set, otherwise ignored.
50190 * @property {import("../featureloader.js").FeatureLoader} [loader]
50191 * The loader function used to load features, from a remote source for example.
50192 * If this is not set and `url` is set, the source will create and use an XHR
50193 * feature loader. The `'featuresloadend'` and `'featuresloaderror'` events
50194 * will only fire if the `success` and `failure` callbacks are used.
50195 *
50196 * Example:
50197 *
50198 * ```js
50199 * import {Vector} from 'ol/source';
50200 * import {GeoJSON} from 'ol/format';
50201 * import {bbox} from 'ol/loadingstrategy';
50202 *
50203 * const vectorSource = new Vector({
50204 *   format: new GeoJSON(),
50205 *   loader: function(extent, resolution, projection, success, failure) {
50206 *      const proj = projection.getCode();
50207 *      const url = 'https://ahocevar.com/geoserver/wfs?service=WFS&' +
50208 *          'version=1.1.0&request=GetFeature&typename=osm:water_areas&' +
50209 *          'outputFormat=application/json&srsname=' + proj + '&' +
50210 *          'bbox=' + extent.join(',') + ',' + proj;
50211 *      const xhr = new XMLHttpRequest();
50212 *      xhr.open('GET', url);
50213 *      const onError = function() {
50214 *        vectorSource.removeLoadedExtent(extent);
50215 *        failure();
50216 *      }
50217 *      xhr.onerror = onError;
50218 *      xhr.onload = function() {
50219 *        if (xhr.status == 200) {
50220 *          const features = vectorSource.getFormat().readFeatures(xhr.responseText);
50221 *          vectorSource.addFeatures(features);
50222 *          success(features);
50223 *        } else {
50224 *          onError();
50225 *        }
50226 *      }
50227 *      xhr.send();
50228 *    },
50229 *    strategy: bbox,
50230 *  });
50231 * ```
50232 * @property {boolean} [overlaps=true] This source may have overlapping geometries.
50233 * Setting this to `false` (e.g. for sources with polygons that represent administrative
50234 * boundaries or TopoJSON sources) allows the renderer to optimise fill and
50235 * stroke operations.
50236 * @property {LoadingStrategy} [strategy] The loading strategy to use.
50237 * By default an {@link module:ol/loadingstrategy.all}
50238 * strategy is used, a one-off strategy which loads all features at once.
50239 * @property {string|import("../featureloader.js").FeatureUrlFunction} [url]
50240 * Setting this option instructs the source to load features using an XHR loader
50241 * (see {@link module:ol/featureloader.xhr}). Use a `string` and an
50242 * {@link module:ol/loadingstrategy.all} for a one-off download of all features from
50243 * the given URL. Use a {@link module:ol/featureloader~FeatureUrlFunction} to generate the url with
50244 * other loading strategies.
50245 * Requires `format` to be set as well.
50246 * When default XHR feature loader is provided, the features will
50247 * be transformed from the data projection to the view projection
50248 * during parsing. If your remote data source does not advertise its projection
50249 * properly, this transformation will be incorrect. For some formats, the
50250 * default projection (usually EPSG:4326) can be overridden by setting the
50251 * dataProjection constructor option on the format.
50252 * Note that if a source contains non-feature data, such as a GeoJSON geometry
50253 * or a KML NetworkLink, these will be ignored. Use a custom loader to load these.
50254 * @property {boolean} [useSpatialIndex=true]
50255 * By default, an RTree is used as spatial index. When features are removed and
50256 * added frequently, and the total number of features is low, setting this to
50257 * `false` may improve performance.
50258 *
50259 * Note that
50260 * {@link module:ol/source/Vector~VectorSource#getFeaturesInExtent},
50261 * {@link module:ol/source/Vector~VectorSource#getClosestFeatureToCoordinate} and
50262 * {@link module:ol/source/Vector~VectorSource#getExtent} cannot be used when `useSpatialIndex` is
50263 * set to `false`, and {@link module:ol/source/Vector~VectorSource#forEachFeatureInExtent} will loop
50264 * through all features.
50265 *
50266 * When set to `false`, the features will be maintained in an
50267 * {@link module:ol/Collection~Collection}, which can be retrieved through
50268 * {@link module:ol/source/Vector~VectorSource#getFeaturesCollection}.
50269 * @property {boolean} [wrapX=true] Wrap the world horizontally. For vector editing across the
50270 * -180° and 180° meridians to work properly, this should be set to `false`. The
50271 * resulting geometry coordinates will then exceed the world bounds.
50272 * @template {import("../geom/Geometry.js").default} [Geometry=import("../geom/Geometry.js").default]
50273 */
50274
50275/**
50276 * @classdesc
50277 * Provides a source of features for vector layers. Vector features provided
50278 * by this source are suitable for editing. See {@link module:ol/source/VectorTile~VectorTile} for
50279 * vector data that is optimized for rendering.
50280 *
50281 * @fires VectorSourceEvent
50282 * @api
50283 * @template {import("../geom/Geometry.js").default} [Geometry=import("../geom/Geometry.js").default]
50284 */
50285class VectorSource extends source_Source {
50286  /**
50287   * @param {Options<Geometry>} [options] Vector source options.
50288   */
50289  constructor(options) {
50290    options = options || {};
50291
50292    super({
50293      attributions: options.attributions,
50294      interpolate: true,
50295      projection: undefined,
50296      state: 'ready',
50297      wrapX: options.wrapX !== undefined ? options.wrapX : true,
50298    });
50299
50300    /***
50301     * @type {VectorSourceOnSignature<import("../events").EventsKey>}
50302     */
50303    this.on;
50304
50305    /***
50306     * @type {VectorSourceOnSignature<import("../events").EventsKey>}
50307     */
50308    this.once;
50309
50310    /***
50311     * @type {VectorSourceOnSignature<void>}
50312     */
50313    this.un;
50314
50315    /**
50316     * @private
50317     * @type {import("../featureloader.js").FeatureLoader}
50318     */
50319    this.loader_ = VOID;
50320
50321    /**
50322     * @private
50323     * @type {import("../format/Feature.js").default|undefined}
50324     */
50325    this.format_ = options.format;
50326
50327    /**
50328     * @private
50329     * @type {boolean}
50330     */
50331    this.overlaps_ = options.overlaps === undefined ? true : options.overlaps;
50332
50333    /**
50334     * @private
50335     * @type {string|import("../featureloader.js").FeatureUrlFunction|undefined}
50336     */
50337    this.url_ = options.url;
50338
50339    if (options.loader !== undefined) {
50340      this.loader_ = options.loader;
50341    } else if (this.url_ !== undefined) {
50342      asserts_assert(this.format_, 7); // `format` must be set when `url` is set
50343      // create a XHR feature loader for "url" and "format"
50344      this.loader_ = xhr(
50345        this.url_,
50346        /** @type {import("../format/Feature.js").default} */ (this.format_)
50347      );
50348    }
50349
50350    /**
50351     * @private
50352     * @type {LoadingStrategy}
50353     */
50354    this.strategy_ =
50355      options.strategy !== undefined ? options.strategy : loadingstrategy_all;
50356
50357    const useSpatialIndex =
50358      options.useSpatialIndex !== undefined ? options.useSpatialIndex : true;
50359
50360    /**
50361     * @private
50362     * @type {RBush<import("../Feature.js").default<Geometry>>}
50363     */
50364    this.featuresRtree_ = useSpatialIndex ? new structs_RBush() : null;
50365
50366    /**
50367     * @private
50368     * @type {RBush<{extent: import("../extent.js").Extent}>}
50369     */
50370    this.loadedExtentsRtree_ = new structs_RBush();
50371
50372    /**
50373     * @type {number}
50374     * @private
50375     */
50376    this.loadingExtentsCount_ = 0;
50377
50378    /**
50379     * @private
50380     * @type {!Object<string, import("../Feature.js").default<Geometry>>}
50381     */
50382    this.nullGeometryFeatures_ = {};
50383
50384    /**
50385     * A lookup of features by id (the return from feature.getId()).
50386     * @private
50387     * @type {!Object<string, import("../Feature.js").default<Geometry>>}
50388     */
50389    this.idIndex_ = {};
50390
50391    /**
50392     * A lookup of features by uid (using getUid(feature)).
50393     * @private
50394     * @type {!Object<string, import("../Feature.js").default<Geometry>>}
50395     */
50396    this.uidIndex_ = {};
50397
50398    /**
50399     * @private
50400     * @type {Object<string, Array<import("../events.js").EventsKey>>}
50401     */
50402    this.featureChangeKeys_ = {};
50403
50404    /**
50405     * @private
50406     * @type {Collection<import("../Feature.js").default<Geometry>>|null}
50407     */
50408    this.featuresCollection_ = null;
50409
50410    /** @type {Collection<import("../Feature.js").default<Geometry>>} */
50411    let collection;
50412    /** @type {Array<import("../Feature.js").default<Geometry>>} */
50413    let features;
50414    if (Array.isArray(options.features)) {
50415      features = options.features;
50416    } else if (options.features) {
50417      collection = options.features;
50418      features = collection.getArray();
50419    }
50420    if (!useSpatialIndex && collection === undefined) {
50421      collection = new ol_Collection(features);
50422    }
50423    if (features !== undefined) {
50424      this.addFeaturesInternal(features);
50425    }
50426    if (collection !== undefined) {
50427      this.bindFeaturesCollection_(collection);
50428    }
50429  }
50430
50431  /**
50432   * Add a single feature to the source.  If you want to add a batch of features
50433   * at once, call {@link module:ol/source/Vector~VectorSource#addFeatures #addFeatures()}
50434   * instead. A feature will not be added to the source if feature with
50435   * the same id is already there. The reason for this behavior is to avoid
50436   * feature duplication when using bbox or tile loading strategies.
50437   * Note: this also applies if an {@link module:ol/Collection~Collection} is used for features,
50438   * meaning that if a feature with a duplicate id is added in the collection, it will
50439   * be removed from it right away.
50440   * @param {import("../Feature.js").default<Geometry>} feature Feature to add.
50441   * @api
50442   */
50443  addFeature(feature) {
50444    this.addFeatureInternal(feature);
50445    this.changed();
50446  }
50447
50448  /**
50449   * Add a feature without firing a `change` event.
50450   * @param {import("../Feature.js").default<Geometry>} feature Feature.
50451   * @protected
50452   */
50453  addFeatureInternal(feature) {
50454    const featureKey = getUid(feature);
50455
50456    if (!this.addToIndex_(featureKey, feature)) {
50457      if (this.featuresCollection_) {
50458        this.featuresCollection_.remove(feature);
50459      }
50460      return;
50461    }
50462
50463    this.setupChangeEvents_(featureKey, feature);
50464
50465    const geometry = feature.getGeometry();
50466    if (geometry) {
50467      const extent = geometry.getExtent();
50468      if (this.featuresRtree_) {
50469        this.featuresRtree_.insert(extent, feature);
50470      }
50471    } else {
50472      this.nullGeometryFeatures_[featureKey] = feature;
50473    }
50474
50475    this.dispatchEvent(
50476      new VectorSourceEvent(VectorEventType.ADDFEATURE, feature)
50477    );
50478  }
50479
50480  /**
50481   * @param {string} featureKey Unique identifier for the feature.
50482   * @param {import("../Feature.js").default<Geometry>} feature The feature.
50483   * @private
50484   */
50485  setupChangeEvents_(featureKey, feature) {
50486    this.featureChangeKeys_[featureKey] = [
50487      listen(feature, EventType.CHANGE, this.handleFeatureChange_, this),
50488      listen(
50489        feature,
50490        ObjectEventType.PROPERTYCHANGE,
50491        this.handleFeatureChange_,
50492        this
50493      ),
50494    ];
50495  }
50496
50497  /**
50498   * @param {string} featureKey Unique identifier for the feature.
50499   * @param {import("../Feature.js").default<Geometry>} feature The feature.
50500   * @return {boolean} The feature is "valid", in the sense that it is also a
50501   *     candidate for insertion into the Rtree.
50502   * @private
50503   */
50504  addToIndex_(featureKey, feature) {
50505    let valid = true;
50506    const id = feature.getId();
50507    if (id !== undefined) {
50508      if (!(id.toString() in this.idIndex_)) {
50509        this.idIndex_[id.toString()] = feature;
50510      } else {
50511        valid = false;
50512      }
50513    }
50514    if (valid) {
50515      asserts_assert(!(featureKey in this.uidIndex_), 30); // The passed `feature` was already added to the source
50516      this.uidIndex_[featureKey] = feature;
50517    }
50518    return valid;
50519  }
50520
50521  /**
50522   * Add a batch of features to the source.
50523   * @param {Array<import("../Feature.js").default<Geometry>>} features Features to add.
50524   * @api
50525   */
50526  addFeatures(features) {
50527    this.addFeaturesInternal(features);
50528    this.changed();
50529  }
50530
50531  /**
50532   * Add features without firing a `change` event.
50533   * @param {Array<import("../Feature.js").default<Geometry>>} features Features.
50534   * @protected
50535   */
50536  addFeaturesInternal(features) {
50537    const extents = [];
50538    const newFeatures = [];
50539    const geometryFeatures = [];
50540
50541    for (let i = 0, length = features.length; i < length; i++) {
50542      const feature = features[i];
50543      const featureKey = getUid(feature);
50544      if (this.addToIndex_(featureKey, feature)) {
50545        newFeatures.push(feature);
50546      }
50547    }
50548
50549    for (let i = 0, length = newFeatures.length; i < length; i++) {
50550      const feature = newFeatures[i];
50551      const featureKey = getUid(feature);
50552      this.setupChangeEvents_(featureKey, feature);
50553
50554      const geometry = feature.getGeometry();
50555      if (geometry) {
50556        const extent = geometry.getExtent();
50557        extents.push(extent);
50558        geometryFeatures.push(feature);
50559      } else {
50560        this.nullGeometryFeatures_[featureKey] = feature;
50561      }
50562    }
50563    if (this.featuresRtree_) {
50564      this.featuresRtree_.load(extents, geometryFeatures);
50565    }
50566
50567    if (this.hasListener(VectorEventType.ADDFEATURE)) {
50568      for (let i = 0, length = newFeatures.length; i < length; i++) {
50569        this.dispatchEvent(
50570          new VectorSourceEvent(VectorEventType.ADDFEATURE, newFeatures[i])
50571        );
50572      }
50573    }
50574  }
50575
50576  /**
50577   * @param {!Collection<import("../Feature.js").default<Geometry>>} collection Collection.
50578   * @private
50579   */
50580  bindFeaturesCollection_(collection) {
50581    let modifyingCollection = false;
50582    this.addEventListener(
50583      VectorEventType.ADDFEATURE,
50584      /**
50585       * @param {VectorSourceEvent<Geometry>} evt The vector source event
50586       */
50587      function (evt) {
50588        if (!modifyingCollection) {
50589          modifyingCollection = true;
50590          collection.push(evt.feature);
50591          modifyingCollection = false;
50592        }
50593      }
50594    );
50595    this.addEventListener(
50596      VectorEventType.REMOVEFEATURE,
50597      /**
50598       * @param {VectorSourceEvent<Geometry>} evt The vector source event
50599       */
50600      function (evt) {
50601        if (!modifyingCollection) {
50602          modifyingCollection = true;
50603          collection.remove(evt.feature);
50604          modifyingCollection = false;
50605        }
50606      }
50607    );
50608    collection.addEventListener(
50609      CollectionEventType.ADD,
50610      /**
50611       * @param {import("../Collection.js").CollectionEvent<import("../Feature.js").default<Geometry>>} evt The collection event
50612       */
50613      function (evt) {
50614        if (!modifyingCollection) {
50615          modifyingCollection = true;
50616          this.addFeature(evt.element);
50617          modifyingCollection = false;
50618        }
50619      }.bind(this)
50620    );
50621    collection.addEventListener(
50622      CollectionEventType.REMOVE,
50623      /**
50624       * @param {import("../Collection.js").CollectionEvent<import("../Feature.js").default<Geometry>>} evt The collection event
50625       */
50626      function (evt) {
50627        if (!modifyingCollection) {
50628          modifyingCollection = true;
50629          this.removeFeature(evt.element);
50630          modifyingCollection = false;
50631        }
50632      }.bind(this)
50633    );
50634    this.featuresCollection_ = collection;
50635  }
50636
50637  /**
50638   * Remove all features from the source.
50639   * @param {boolean} [fast] Skip dispatching of {@link module:ol/source/Vector.VectorSourceEvent#event:removefeature} events.
50640   * @api
50641   */
50642  clear(fast) {
50643    if (fast) {
50644      for (const featureId in this.featureChangeKeys_) {
50645        const keys = this.featureChangeKeys_[featureId];
50646        keys.forEach(unlistenByKey);
50647      }
50648      if (!this.featuresCollection_) {
50649        this.featureChangeKeys_ = {};
50650        this.idIndex_ = {};
50651        this.uidIndex_ = {};
50652      }
50653    } else {
50654      if (this.featuresRtree_) {
50655        const removeAndIgnoreReturn = function (feature) {
50656          this.removeFeatureInternal(feature);
50657        }.bind(this);
50658        this.featuresRtree_.forEach(removeAndIgnoreReturn);
50659        for (const id in this.nullGeometryFeatures_) {
50660          this.removeFeatureInternal(this.nullGeometryFeatures_[id]);
50661        }
50662      }
50663    }
50664    if (this.featuresCollection_) {
50665      this.featuresCollection_.clear();
50666    }
50667
50668    if (this.featuresRtree_) {
50669      this.featuresRtree_.clear();
50670    }
50671    this.nullGeometryFeatures_ = {};
50672
50673    const clearEvent = new VectorSourceEvent(VectorEventType.CLEAR);
50674    this.dispatchEvent(clearEvent);
50675    this.changed();
50676  }
50677
50678  /**
50679   * Iterate through all features on the source, calling the provided callback
50680   * with each one.  If the callback returns any "truthy" value, iteration will
50681   * stop and the function will return the same value.
50682   * Note: this function only iterate through the feature that have a defined geometry.
50683   *
50684   * @param {function(import("../Feature.js").default<Geometry>): T} callback Called with each feature
50685   *     on the source.  Return a truthy value to stop iteration.
50686   * @return {T|undefined} The return value from the last call to the callback.
50687   * @template T
50688   * @api
50689   */
50690  forEachFeature(callback) {
50691    if (this.featuresRtree_) {
50692      return this.featuresRtree_.forEach(callback);
50693    } else if (this.featuresCollection_) {
50694      this.featuresCollection_.forEach(callback);
50695    }
50696  }
50697
50698  /**
50699   * Iterate through all features whose geometries contain the provided
50700   * coordinate, calling the callback with each feature.  If the callback returns
50701   * a "truthy" value, iteration will stop and the function will return the same
50702   * value.
50703   *
50704   * @param {import("../coordinate.js").Coordinate} coordinate Coordinate.
50705   * @param {function(import("../Feature.js").default<Geometry>): T} callback Called with each feature
50706   *     whose goemetry contains the provided coordinate.
50707   * @return {T|undefined} The return value from the last call to the callback.
50708   * @template T
50709   */
50710  forEachFeatureAtCoordinateDirect(coordinate, callback) {
50711    const extent = [coordinate[0], coordinate[1], coordinate[0], coordinate[1]];
50712    return this.forEachFeatureInExtent(extent, function (feature) {
50713      const geometry = feature.getGeometry();
50714      if (geometry.intersectsCoordinate(coordinate)) {
50715        return callback(feature);
50716      } else {
50717        return undefined;
50718      }
50719    });
50720  }
50721
50722  /**
50723   * Iterate through all features whose bounding box intersects the provided
50724   * extent (note that the feature's geometry may not intersect the extent),
50725   * calling the callback with each feature.  If the callback returns a "truthy"
50726   * value, iteration will stop and the function will return the same value.
50727   *
50728   * If you are interested in features whose geometry intersects an extent, call
50729   * the {@link module:ol/source/Vector~VectorSource#forEachFeatureIntersectingExtent #forEachFeatureIntersectingExtent()} method instead.
50730   *
50731   * When `useSpatialIndex` is set to false, this method will loop through all
50732   * features, equivalent to {@link module:ol/source/Vector~VectorSource#forEachFeature #forEachFeature()}.
50733   *
50734   * @param {import("../extent.js").Extent} extent Extent.
50735   * @param {function(import("../Feature.js").default<Geometry>): T} callback Called with each feature
50736   *     whose bounding box intersects the provided extent.
50737   * @return {T|undefined} The return value from the last call to the callback.
50738   * @template T
50739   * @api
50740   */
50741  forEachFeatureInExtent(extent, callback) {
50742    if (this.featuresRtree_) {
50743      return this.featuresRtree_.forEachInExtent(extent, callback);
50744    } else if (this.featuresCollection_) {
50745      this.featuresCollection_.forEach(callback);
50746    }
50747  }
50748
50749  /**
50750   * Iterate through all features whose geometry intersects the provided extent,
50751   * calling the callback with each feature.  If the callback returns a "truthy"
50752   * value, iteration will stop and the function will return the same value.
50753   *
50754   * If you only want to test for bounding box intersection, call the
50755   * {@link module:ol/source/Vector~VectorSource#forEachFeatureInExtent #forEachFeatureInExtent()} method instead.
50756   *
50757   * @param {import("../extent.js").Extent} extent Extent.
50758   * @param {function(import("../Feature.js").default<Geometry>): T} callback Called with each feature
50759   *     whose geometry intersects the provided extent.
50760   * @return {T|undefined} The return value from the last call to the callback.
50761   * @template T
50762   * @api
50763   */
50764  forEachFeatureIntersectingExtent(extent, callback) {
50765    return this.forEachFeatureInExtent(
50766      extent,
50767      /**
50768       * @param {import("../Feature.js").default<Geometry>} feature Feature.
50769       * @return {T|undefined} The return value from the last call to the callback.
50770       */
50771      function (feature) {
50772        const geometry = feature.getGeometry();
50773        if (geometry.intersectsExtent(extent)) {
50774          const result = callback(feature);
50775          if (result) {
50776            return result;
50777          }
50778        }
50779      }
50780    );
50781  }
50782
50783  /**
50784   * Get the features collection associated with this source. Will be `null`
50785   * unless the source was configured with `useSpatialIndex` set to `false`, or
50786   * with an {@link module:ol/Collection~Collection} as `features`.
50787   * @return {Collection<import("../Feature.js").default<Geometry>>|null} The collection of features.
50788   * @api
50789   */
50790  getFeaturesCollection() {
50791    return this.featuresCollection_;
50792  }
50793
50794  /**
50795   * Get a snapshot of the features currently on the source in random order. The returned array
50796   * is a copy, the features are references to the features in the source.
50797   * @return {Array<import("../Feature.js").default<Geometry>>} Features.
50798   * @api
50799   */
50800  getFeatures() {
50801    let features;
50802    if (this.featuresCollection_) {
50803      features = this.featuresCollection_.getArray().slice(0);
50804    } else if (this.featuresRtree_) {
50805      features = this.featuresRtree_.getAll();
50806      if (!obj_isEmpty(this.nullGeometryFeatures_)) {
50807        array_extend(features, Object.values(this.nullGeometryFeatures_));
50808      }
50809    }
50810    return /** @type {Array<import("../Feature.js").default<Geometry>>} */ (
50811      features
50812    );
50813  }
50814
50815  /**
50816   * Get all features whose geometry intersects the provided coordinate.
50817   * @param {import("../coordinate.js").Coordinate} coordinate Coordinate.
50818   * @return {Array<import("../Feature.js").default<Geometry>>} Features.
50819   * @api
50820   */
50821  getFeaturesAtCoordinate(coordinate) {
50822    const features = [];
50823    this.forEachFeatureAtCoordinateDirect(coordinate, function (feature) {
50824      features.push(feature);
50825    });
50826    return features;
50827  }
50828
50829  /**
50830   * Get all features whose bounding box intersects the provided extent.  Note that this returns an array of
50831   * all features intersecting the given extent in random order (so it may include
50832   * features whose geometries do not intersect the extent).
50833   *
50834   * When `useSpatialIndex` is set to false, this method will return all
50835   * features.
50836   *
50837   * @param {import("../extent.js").Extent} extent Extent.
50838   * @param {import("../proj/Projection.js").default} [projection] Include features
50839   * where `extent` exceeds the x-axis bounds of `projection` and wraps around the world.
50840   * @return {Array<import("../Feature.js").default<Geometry>>} Features.
50841   * @api
50842   */
50843  getFeaturesInExtent(extent, projection) {
50844    if (this.featuresRtree_) {
50845      const multiWorld = projection && projection.canWrapX() && this.getWrapX();
50846
50847      if (!multiWorld) {
50848        return this.featuresRtree_.getInExtent(extent);
50849      }
50850
50851      const extents = wrapAndSliceX(extent, projection);
50852
50853      return [].concat(
50854        ...extents.map((anExtent) => this.featuresRtree_.getInExtent(anExtent))
50855      );
50856    } else if (this.featuresCollection_) {
50857      return this.featuresCollection_.getArray().slice(0);
50858    } else {
50859      return [];
50860    }
50861  }
50862
50863  /**
50864   * Get the closest feature to the provided coordinate.
50865   *
50866   * This method is not available when the source is configured with
50867   * `useSpatialIndex` set to `false`.
50868   * @param {import("../coordinate.js").Coordinate} coordinate Coordinate.
50869   * @param {function(import("../Feature.js").default<Geometry>):boolean} [filter] Feature filter function.
50870   *     The filter function will receive one argument, the {@link module:ol/Feature~Feature feature}
50871   *     and it should return a boolean value. By default, no filtering is made.
50872   * @return {import("../Feature.js").default<Geometry>} Closest feature.
50873   * @api
50874   */
50875  getClosestFeatureToCoordinate(coordinate, filter) {
50876    // Find the closest feature using branch and bound.  We start searching an
50877    // infinite extent, and find the distance from the first feature found.  This
50878    // becomes the closest feature.  We then compute a smaller extent which any
50879    // closer feature must intersect.  We continue searching with this smaller
50880    // extent, trying to find a closer feature.  Every time we find a closer
50881    // feature, we update the extent being searched so that any even closer
50882    // feature must intersect it.  We continue until we run out of features.
50883    const x = coordinate[0];
50884    const y = coordinate[1];
50885    let closestFeature = null;
50886    const closestPoint = [NaN, NaN];
50887    let minSquaredDistance = Infinity;
50888    const extent = [-Infinity, -Infinity, Infinity, Infinity];
50889    filter = filter ? filter : TRUE;
50890    this.featuresRtree_.forEachInExtent(
50891      extent,
50892      /**
50893       * @param {import("../Feature.js").default<Geometry>} feature Feature.
50894       */
50895      function (feature) {
50896        if (filter(feature)) {
50897          const geometry = feature.getGeometry();
50898          const previousMinSquaredDistance = minSquaredDistance;
50899          minSquaredDistance = geometry.closestPointXY(
50900            x,
50901            y,
50902            closestPoint,
50903            minSquaredDistance
50904          );
50905          if (minSquaredDistance < previousMinSquaredDistance) {
50906            closestFeature = feature;
50907            // This is sneaky.  Reduce the extent that it is currently being
50908            // searched while the R-Tree traversal using this same extent object
50909            // is still in progress.  This is safe because the new extent is
50910            // strictly contained by the old extent.
50911            const minDistance = Math.sqrt(minSquaredDistance);
50912            extent[0] = x - minDistance;
50913            extent[1] = y - minDistance;
50914            extent[2] = x + minDistance;
50915            extent[3] = y + minDistance;
50916          }
50917        }
50918      }
50919    );
50920    return closestFeature;
50921  }
50922
50923  /**
50924   * Get the extent of the features currently in the source.
50925   *
50926   * This method is not available when the source is configured with
50927   * `useSpatialIndex` set to `false`.
50928   * @param {import("../extent.js").Extent} [extent] Destination extent. If provided, no new extent
50929   *     will be created. Instead, that extent's coordinates will be overwritten.
50930   * @return {import("../extent.js").Extent} Extent.
50931   * @api
50932   */
50933  getExtent(extent) {
50934    return this.featuresRtree_.getExtent(extent);
50935  }
50936
50937  /**
50938   * Get a feature by its identifier (the value returned by feature.getId()).
50939   * Note that the index treats string and numeric identifiers as the same.  So
50940   * `source.getFeatureById(2)` will return a feature with id `'2'` or `2`.
50941   *
50942   * @param {string|number} id Feature identifier.
50943   * @return {import("../Feature.js").default<Geometry>|null} The feature (or `null` if not found).
50944   * @api
50945   */
50946  getFeatureById(id) {
50947    const feature = this.idIndex_[id.toString()];
50948    return feature !== undefined ? feature : null;
50949  }
50950
50951  /**
50952   * Get a feature by its internal unique identifier (using `getUid`).
50953   *
50954   * @param {string} uid Feature identifier.
50955   * @return {import("../Feature.js").default<Geometry>|null} The feature (or `null` if not found).
50956   */
50957  getFeatureByUid(uid) {
50958    const feature = this.uidIndex_[uid];
50959    return feature !== undefined ? feature : null;
50960  }
50961
50962  /**
50963   * Get the format associated with this source.
50964   *
50965   * @return {import("../format/Feature.js").default|undefined} The feature format.
50966   * @api
50967   */
50968  getFormat() {
50969    return this.format_;
50970  }
50971
50972  /**
50973   * @return {boolean} The source can have overlapping geometries.
50974   */
50975  getOverlaps() {
50976    return this.overlaps_;
50977  }
50978
50979  /**
50980   * Get the url associated with this source.
50981   *
50982   * @return {string|import("../featureloader.js").FeatureUrlFunction|undefined} The url.
50983   * @api
50984   */
50985  getUrl() {
50986    return this.url_;
50987  }
50988
50989  /**
50990   * @param {Event} event Event.
50991   * @private
50992   */
50993  handleFeatureChange_(event) {
50994    const feature = /** @type {import("../Feature.js").default<Geometry>} */ (
50995      event.target
50996    );
50997    const featureKey = getUid(feature);
50998    const geometry = feature.getGeometry();
50999    if (!geometry) {
51000      if (!(featureKey in this.nullGeometryFeatures_)) {
51001        if (this.featuresRtree_) {
51002          this.featuresRtree_.remove(feature);
51003        }
51004        this.nullGeometryFeatures_[featureKey] = feature;
51005      }
51006    } else {
51007      const extent = geometry.getExtent();
51008      if (featureKey in this.nullGeometryFeatures_) {
51009        delete this.nullGeometryFeatures_[featureKey];
51010        if (this.featuresRtree_) {
51011          this.featuresRtree_.insert(extent, feature);
51012        }
51013      } else {
51014        if (this.featuresRtree_) {
51015          this.featuresRtree_.update(extent, feature);
51016        }
51017      }
51018    }
51019    const id = feature.getId();
51020    if (id !== undefined) {
51021      const sid = id.toString();
51022      if (this.idIndex_[sid] !== feature) {
51023        this.removeFromIdIndex_(feature);
51024        this.idIndex_[sid] = feature;
51025      }
51026    } else {
51027      this.removeFromIdIndex_(feature);
51028      this.uidIndex_[featureKey] = feature;
51029    }
51030    this.changed();
51031    this.dispatchEvent(
51032      new VectorSourceEvent(VectorEventType.CHANGEFEATURE, feature)
51033    );
51034  }
51035
51036  /**
51037   * Returns true if the feature is contained within the source.
51038   * @param {import("../Feature.js").default<Geometry>} feature Feature.
51039   * @return {boolean} Has feature.
51040   * @api
51041   */
51042  hasFeature(feature) {
51043    const id = feature.getId();
51044    if (id !== undefined) {
51045      return id in this.idIndex_;
51046    } else {
51047      return getUid(feature) in this.uidIndex_;
51048    }
51049  }
51050
51051  /**
51052   * @return {boolean} Is empty.
51053   */
51054  isEmpty() {
51055    if (this.featuresRtree_) {
51056      return (
51057        this.featuresRtree_.isEmpty() && obj_isEmpty(this.nullGeometryFeatures_)
51058      );
51059    }
51060    if (this.featuresCollection_) {
51061      return this.featuresCollection_.getLength() === 0;
51062    }
51063    return true;
51064  }
51065
51066  /**
51067   * @param {import("../extent.js").Extent} extent Extent.
51068   * @param {number} resolution Resolution.
51069   * @param {import("../proj/Projection.js").default} projection Projection.
51070   */
51071  loadFeatures(extent, resolution, projection) {
51072    const loadedExtentsRtree = this.loadedExtentsRtree_;
51073    const extentsToLoad = this.strategy_(extent, resolution, projection);
51074    for (let i = 0, ii = extentsToLoad.length; i < ii; ++i) {
51075      const extentToLoad = extentsToLoad[i];
51076      const alreadyLoaded = loadedExtentsRtree.forEachInExtent(
51077        extentToLoad,
51078        /**
51079         * @param {{extent: import("../extent.js").Extent}} object Object.
51080         * @return {boolean} Contains.
51081         */
51082        function (object) {
51083          return containsExtent(object.extent, extentToLoad);
51084        }
51085      );
51086      if (!alreadyLoaded) {
51087        ++this.loadingExtentsCount_;
51088        this.dispatchEvent(
51089          new VectorSourceEvent(VectorEventType.FEATURESLOADSTART)
51090        );
51091        this.loader_.call(
51092          this,
51093          extentToLoad,
51094          resolution,
51095          projection,
51096          function (features) {
51097            --this.loadingExtentsCount_;
51098            this.dispatchEvent(
51099              new VectorSourceEvent(
51100                VectorEventType.FEATURESLOADEND,
51101                undefined,
51102                features
51103              )
51104            );
51105          }.bind(this),
51106          function () {
51107            --this.loadingExtentsCount_;
51108            this.dispatchEvent(
51109              new VectorSourceEvent(VectorEventType.FEATURESLOADERROR)
51110            );
51111          }.bind(this)
51112        );
51113        loadedExtentsRtree.insert(extentToLoad, {extent: extentToLoad.slice()});
51114      }
51115    }
51116    this.loading =
51117      this.loader_.length < 4 ? false : this.loadingExtentsCount_ > 0;
51118  }
51119
51120  refresh() {
51121    this.clear(true);
51122    this.loadedExtentsRtree_.clear();
51123    super.refresh();
51124  }
51125
51126  /**
51127   * Remove an extent from the list of loaded extents.
51128   * @param {import("../extent.js").Extent} extent Extent.
51129   * @api
51130   */
51131  removeLoadedExtent(extent) {
51132    const loadedExtentsRtree = this.loadedExtentsRtree_;
51133    let obj;
51134    loadedExtentsRtree.forEachInExtent(extent, function (object) {
51135      if (extent_equals(object.extent, extent)) {
51136        obj = object;
51137        return true;
51138      }
51139    });
51140    if (obj) {
51141      loadedExtentsRtree.remove(obj);
51142    }
51143  }
51144
51145  /**
51146   * Remove a single feature from the source.  If you want to remove all features
51147   * at once, use the {@link module:ol/source/Vector~VectorSource#clear #clear()} method
51148   * instead.
51149   * @param {import("../Feature.js").default<Geometry>} feature Feature to remove.
51150   * @api
51151   */
51152  removeFeature(feature) {
51153    if (!feature) {
51154      return;
51155    }
51156    const featureKey = getUid(feature);
51157    if (featureKey in this.nullGeometryFeatures_) {
51158      delete this.nullGeometryFeatures_[featureKey];
51159    } else {
51160      if (this.featuresRtree_) {
51161        this.featuresRtree_.remove(feature);
51162      }
51163    }
51164    const result = this.removeFeatureInternal(feature);
51165    if (result) {
51166      this.changed();
51167    }
51168  }
51169
51170  /**
51171   * Remove feature without firing a `change` event.
51172   * @param {import("../Feature.js").default<Geometry>} feature Feature.
51173   * @return {import("../Feature.js").default<Geometry>|undefined} The removed feature
51174   *     (or undefined if the feature was not found).
51175   * @protected
51176   */
51177  removeFeatureInternal(feature) {
51178    const featureKey = getUid(feature);
51179    const featureChangeKeys = this.featureChangeKeys_[featureKey];
51180    if (!featureChangeKeys) {
51181      return;
51182    }
51183    featureChangeKeys.forEach(unlistenByKey);
51184    delete this.featureChangeKeys_[featureKey];
51185    const id = feature.getId();
51186    if (id !== undefined) {
51187      delete this.idIndex_[id.toString()];
51188    }
51189    delete this.uidIndex_[featureKey];
51190    this.dispatchEvent(
51191      new VectorSourceEvent(VectorEventType.REMOVEFEATURE, feature)
51192    );
51193    return feature;
51194  }
51195
51196  /**
51197   * Remove a feature from the id index.  Called internally when the feature id
51198   * may have changed.
51199   * @param {import("../Feature.js").default<Geometry>} feature The feature.
51200   * @return {boolean} Removed the feature from the index.
51201   * @private
51202   */
51203  removeFromIdIndex_(feature) {
51204    let removed = false;
51205    for (const id in this.idIndex_) {
51206      if (this.idIndex_[id] === feature) {
51207        delete this.idIndex_[id];
51208        removed = true;
51209        break;
51210      }
51211    }
51212    return removed;
51213  }
51214
51215  /**
51216   * Set the new loader of the source. The next render cycle will use the
51217   * new loader.
51218   * @param {import("../featureloader.js").FeatureLoader} loader The loader to set.
51219   * @api
51220   */
51221  setLoader(loader) {
51222    this.loader_ = loader;
51223  }
51224
51225  /**
51226   * Points the source to a new url. The next render cycle will use the new url.
51227   * @param {string|import("../featureloader.js").FeatureUrlFunction} url Url.
51228   * @api
51229   */
51230  setUrl(url) {
51231    asserts_assert(this.format_, 7); // `format` must be set when `url` is set
51232    this.url_ = url;
51233    this.setLoader(xhr(url, this.format_));
51234  }
51235}
51236
51237/* harmony default export */ const source_Vector = (VectorSource);
51238
51239;// CONCATENATED MODULE: ./node_modules/ol/source/OSM.js
51240/**
51241 * @module ol/source/OSM
51242 */
51243
51244
51245
51246/**
51247 * The attribution containing a link to the OpenStreetMap Copyright and License
51248 * page.
51249 * @const
51250 * @type {string}
51251 * @api
51252 */
51253const ATTRIBUTION =
51254  '&#169; ' +
51255  '<a href="https://www.openstreetmap.org/copyright" target="_blank">OpenStreetMap</a> ' +
51256  'contributors.';
51257
51258/**
51259 * @typedef {Object} Options
51260 * @property {import("./Source.js").AttributionLike} [attributions] Attributions.
51261 * @property {number} [cacheSize] Initial tile cache size. Will auto-grow to hold at least the number of tiles in the viewport.
51262 * @property {null|string} [crossOrigin='anonymous'] The `crossOrigin` attribute for loaded images.  Note that
51263 * you must provide a `crossOrigin` value if you want to access pixel data with the Canvas renderer.
51264 * See https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image for more detail.
51265 * @property {boolean} [interpolate=true] Use interpolated values when resampling.  By default,
51266 * linear interpolation is used when resampling.  Set to false to use the nearest neighbor instead.
51267 * @property {number} [maxZoom=19] Max zoom.
51268 * @property {boolean} [opaque=true] Whether the layer is opaque.
51269 * @property {number} [reprojectionErrorThreshold=0.5] Maximum allowed reprojection error (in pixels).
51270 * Higher values can increase reprojection performance, but decrease precision.
51271 * @property {import("../Tile.js").LoadFunction} [tileLoadFunction] Optional function to load a tile given a URL. The default is
51272 * ```js
51273 * function(imageTile, src) {
51274 *   imageTile.getImage().src = src;
51275 * };
51276 * ```
51277 * @property {number} [transition=250] Duration of the opacity transition for rendering.
51278 * To disable the opacity transition, pass `transition: 0`.
51279 * @property {string} [url='https://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png'] URL template.
51280 * Must include `{x}`, `{y}` or `{-y}`, and `{z}` placeholders.
51281 * @property {boolean} [wrapX=true] Whether to wrap the world horizontally.
51282 * @property {number|import("../array.js").NearestDirectionFunction} [zDirection=0]
51283 * Choose whether to use tiles with a higher or lower zoom level when between integer
51284 * zoom levels. See {@link module:ol/tilegrid/TileGrid~TileGrid#getZForResolution}.
51285 */
51286
51287/**
51288 * @classdesc
51289 * Layer source for the OpenStreetMap tile server.
51290 * @api
51291 */
51292class OSM extends source_XYZ {
51293  /**
51294   * @param {Options} [options] Open Street Map options.
51295   */
51296  constructor(options) {
51297    options = options || {};
51298
51299    let attributions;
51300    if (options.attributions !== undefined) {
51301      attributions = options.attributions;
51302    } else {
51303      attributions = [ATTRIBUTION];
51304    }
51305
51306    const crossOrigin =
51307      options.crossOrigin !== undefined ? options.crossOrigin : 'anonymous';
51308
51309    const url =
51310      options.url !== undefined
51311        ? options.url
51312        : 'https://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png';
51313
51314    super({
51315      attributions: attributions,
51316      attributionsCollapsible: false,
51317      cacheSize: options.cacheSize,
51318      crossOrigin: crossOrigin,
51319      interpolate: options.interpolate,
51320      maxZoom: options.maxZoom !== undefined ? options.maxZoom : 19,
51321      opaque: options.opaque !== undefined ? options.opaque : true,
51322      reprojectionErrorThreshold: options.reprojectionErrorThreshold,
51323      tileLoadFunction: options.tileLoadFunction,
51324      transition: options.transition,
51325      url: url,
51326      wrapX: options.wrapX,
51327      zDirection: options.zDirection,
51328    });
51329  }
51330}
51331
51332/* harmony default export */ const source_OSM = (OSM);
51333
51334;// CONCATENATED MODULE: ./node_modules/ol/Overlay.js
51335/**
51336 * @module ol/Overlay
51337 */
51338
51339
51340
51341
51342
51343
51344
51345/**
51346 * @typedef {'bottom-left' | 'bottom-center' | 'bottom-right' | 'center-left' | 'center-center' | 'center-right' | 'top-left' | 'top-center' | 'top-right'} Positioning
51347 * The overlay position: `'bottom-left'`, `'bottom-center'`,  `'bottom-right'`,
51348 * `'center-left'`, `'center-center'`, `'center-right'`, `'top-left'`,
51349 * `'top-center'`, or `'top-right'`.
51350 */
51351
51352/**
51353 * @typedef {Object} Options
51354 * @property {number|string} [id] Set the overlay id. The overlay id can be used
51355 * with the {@link module:ol/Map~Map#getOverlayById} method.
51356 * @property {HTMLElement} [element] The overlay element.
51357 * @property {Array<number>} [offset=[0, 0]] Offsets in pixels used when positioning
51358 * the overlay. The first element in the
51359 * array is the horizontal offset. A positive value shifts the overlay right.
51360 * The second element in the array is the vertical offset. A positive value
51361 * shifts the overlay down.
51362 * @property {import("./coordinate.js").Coordinate} [position] The overlay position
51363 * in map projection.
51364 * @property {Positioning} [positioning='top-left'] Defines how
51365 * the overlay is actually positioned with respect to its `position` property.
51366 * Possible values are `'bottom-left'`, `'bottom-center'`, `'bottom-right'`,
51367 * `'center-left'`, `'center-center'`, `'center-right'`, `'top-left'`,
51368 * `'top-center'`, and `'top-right'`.
51369 * @property {boolean} [stopEvent=true] Whether event propagation to the map
51370 * viewport should be stopped. If `true` the overlay is placed in the same
51371 * container as that of the controls (CSS class name
51372 * `ol-overlaycontainer-stopevent`); if `false` it is placed in the container
51373 * with CSS class name specified by the `className` property.
51374 * @property {boolean} [insertFirst=true] Whether the overlay is inserted first
51375 * in the overlay container, or appended. If the overlay is placed in the same
51376 * container as that of the controls (see the `stopEvent` option) you will
51377 * probably set `insertFirst` to `true` so the overlay is displayed below the
51378 * controls.
51379 * @property {PanIntoViewOptions|boolean} [autoPan=false] Pan the map when calling
51380 * `setPosition`, so that the overlay is entirely visible in the current viewport.
51381 * @property {string} [className='ol-overlay-container ol-selectable'] CSS class
51382 * name.
51383 */
51384
51385/**
51386 * @typedef {Object} PanOptions
51387 * @property {number} [duration=1000] The duration of the animation in
51388 * milliseconds.
51389 * @property {function(number):number} [easing] The easing function to use. Can
51390 * be one from {@link module:ol/easing} or a custom function.
51391 * Default is {@link module:ol/easing.inAndOut}.
51392 */
51393
51394/**
51395 * @typedef {Object} PanIntoViewOptions
51396 * @property {PanOptions} [animation={}] The animation parameters for the pan
51397 * @property {number} [margin=20] The margin (in pixels) between the
51398 * overlay and the borders of the map when panning into view.
51399 */
51400
51401/**
51402 * @enum {string}
51403 * @protected
51404 */
51405const Overlay_Property = {
51406  ELEMENT: 'element',
51407  MAP: 'map',
51408  OFFSET: 'offset',
vendor: 11,579 bytes, lines 51409-51851
51409  POSITION: 'position',
51410  POSITIONING: 'positioning',
51411};
51412
51413/**
51414 * @typedef {import("./ObjectEventType").Types|'change:element'|'change:map'|'change:offset'|'change:position'|
51415 *   'change:positioning'} OverlayObjectEventTypes
51416 */
51417
51418/***
51419 * @template Return
51420 * @typedef {import("./Observable").OnSignature<import("./Observable").EventTypes, import("./events/Event.js").default, Return> &
51421 *   import("./Observable").OnSignature<OverlayObjectEventTypes, import("./Object").ObjectEvent, Return> &
51422 *   import("./Observable").CombinedOnSignature<import("./Observable").EventTypes|OverlayObjectEventTypes, Return>} OverlayOnSignature
51423 */
51424
51425/**
51426 * @classdesc
51427 * An element to be displayed over the map and attached to a single map
51428 * location.  Like {@link module:ol/control/Control~Control}, Overlays are
51429 * visible widgets. Unlike Controls, they are not in a fixed position on the
51430 * screen, but are tied to a geographical coordinate, so panning the map will
51431 * move an Overlay but not a Control.
51432 *
51433 * Example:
51434 *
51435 *     import Overlay from 'ol/Overlay';
51436 *
51437 *     // ...
51438 *     const popup = new Overlay({
51439 *       element: document.getElementById('popup'),
51440 *     });
51441 *     popup.setPosition(coordinate);
51442 *     map.addOverlay(popup);
51443 *
51444 * @api
51445 */
51446class Overlay extends ol_Object {
51447  /**
51448   * @param {Options} options Overlay options.
51449   */
51450  constructor(options) {
51451    super();
51452
51453    /***
51454     * @type {OverlayOnSignature<import("./events").EventsKey>}
51455     */
51456    this.on;
51457
51458    /***
51459     * @type {OverlayOnSignature<import("./events").EventsKey>}
51460     */
51461    this.once;
51462
51463    /***
51464     * @type {OverlayOnSignature<void>}
51465     */
51466    this.un;
51467
51468    /**
51469     * @protected
51470     * @type {Options}
51471     */
51472    this.options = options;
51473
51474    /**
51475     * @protected
51476     * @type {number|string|undefined}
51477     */
51478    this.id = options.id;
51479
51480    /**
51481     * @protected
51482     * @type {boolean}
51483     */
51484    this.insertFirst =
51485      options.insertFirst !== undefined ? options.insertFirst : true;
51486
51487    /**
51488     * @protected
51489     * @type {boolean}
51490     */
51491    this.stopEvent = options.stopEvent !== undefined ? options.stopEvent : true;
51492
51493    /**
51494     * @protected
51495     * @type {HTMLElement}
51496     */
51497    this.element = document.createElement('div');
51498    this.element.className =
51499      options.className !== undefined
51500        ? options.className
51501        : 'ol-overlay-container ' + CLASS_SELECTABLE;
51502    this.element.style.position = 'absolute';
51503    this.element.style.pointerEvents = 'auto';
51504
51505    /**
51506     * @protected
51507     * @type {PanIntoViewOptions|undefined}
51508     */
51509    this.autoPan = options.autoPan === true ? {} : options.autoPan || undefined;
51510
51511    /**
51512     * @protected
51513     * @type {{transform_: string,
51514     *         visible: boolean}}
51515     */
51516    this.rendered = {
51517      transform_: '',
51518      visible: true,
51519    };
51520
51521    /**
51522     * @protected
51523     * @type {?import("./events.js").EventsKey}
51524     */
51525    this.mapPostrenderListenerKey = null;
51526
51527    this.addChangeListener(Overlay_Property.ELEMENT, this.handleElementChanged);
51528    this.addChangeListener(Overlay_Property.MAP, this.handleMapChanged);
51529    this.addChangeListener(Overlay_Property.OFFSET, this.handleOffsetChanged);
51530    this.addChangeListener(Overlay_Property.POSITION, this.handlePositionChanged);
51531    this.addChangeListener(Overlay_Property.POSITIONING, this.handlePositioningChanged);
51532
51533    if (options.element !== undefined) {
51534      this.setElement(options.element);
51535    }
51536
51537    this.setOffset(options.offset !== undefined ? options.offset : [0, 0]);
51538
51539    this.setPositioning(options.positioning || 'top-left');
51540
51541    if (options.position !== undefined) {
51542      this.setPosition(options.position);
51543    }
51544  }
51545
51546  /**
51547   * Get the DOM element of this overlay.
51548   * @return {HTMLElement|undefined} The Element containing the overlay.
51549   * @observable
51550   * @api
51551   */
51552  getElement() {
51553    return /** @type {HTMLElement|undefined} */ (this.get(Overlay_Property.ELEMENT));
51554  }
51555
51556  /**
51557   * Get the overlay identifier which is set on constructor.
51558   * @return {number|string|undefined} Id.
51559   * @api
51560   */
51561  getId() {
51562    return this.id;
51563  }
51564
51565  /**
51566   * Get the map associated with this overlay.
51567   * @return {import("./Map.js").default|null} The map that the
51568   * overlay is part of.
51569   * @observable
51570   * @api
51571   */
51572  getMap() {
51573    return /** @type {import("./Map.js").default|null} */ (
51574      this.get(Overlay_Property.MAP) || null
51575    );
51576  }
51577
51578  /**
51579   * Get the offset of this overlay.
51580   * @return {Array<number>} The offset.
51581   * @observable
51582   * @api
51583   */
51584  getOffset() {
51585    return /** @type {Array<number>} */ (this.get(Overlay_Property.OFFSET));
51586  }
51587
51588  /**
51589   * Get the current position of this overlay.
51590   * @return {import("./coordinate.js").Coordinate|undefined} The spatial point that the overlay is
51591   *     anchored at.
51592   * @observable
51593   * @api
51594   */
51595  getPosition() {
51596    return /** @type {import("./coordinate.js").Coordinate|undefined} */ (
51597      this.get(Overlay_Property.POSITION)
51598    );
51599  }
51600
51601  /**
51602   * Get the current positioning of this overlay.
51603   * @return {Positioning} How the overlay is positioned
51604   *     relative to its point on the map.
51605   * @observable
51606   * @api
51607   */
51608  getPositioning() {
51609    return /** @type {Positioning} */ (this.get(Overlay_Property.POSITIONING));
51610  }
51611
51612  /**
51613   * @protected
51614   */
51615  handleElementChanged() {
51616    removeChildren(this.element);
51617    const element = this.getElement();
51618    if (element) {
51619      this.element.appendChild(element);
51620    }
51621  }
51622
51623  /**
51624   * @protected
51625   */
51626  handleMapChanged() {
51627    if (this.mapPostrenderListenerKey) {
51628      removeNode(this.element);
51629      unlistenByKey(this.mapPostrenderListenerKey);
51630      this.mapPostrenderListenerKey = null;
51631    }
51632    const map = this.getMap();
51633    if (map) {
51634      this.mapPostrenderListenerKey = listen(
51635        map,
51636        MapEventType.POSTRENDER,
51637        this.render,
51638        this
51639      );
51640      this.updatePixelPosition();
51641      const container = this.stopEvent
51642        ? map.getOverlayContainerStopEvent()
51643        : map.getOverlayContainer();
51644      if (this.insertFirst) {
51645        container.insertBefore(this.element, container.childNodes[0] || null);
51646      } else {
51647        container.appendChild(this.element);
51648      }
51649      this.performAutoPan();
51650    }
51651  }
51652
51653  /**
51654   * @protected
51655   */
51656  render() {
51657    this.updatePixelPosition();
51658  }
51659
51660  /**
51661   * @protected
51662   */
51663  handleOffsetChanged() {
51664    this.updatePixelPosition();
51665  }
51666
51667  /**
51668   * @protected
51669   */
51670  handlePositionChanged() {
51671    this.updatePixelPosition();
51672    this.performAutoPan();
51673  }
51674
51675  /**
51676   * @protected
51677   */
51678  handlePositioningChanged() {
51679    this.updatePixelPosition();
51680  }
51681
51682  /**
51683   * Set the DOM element to be associated with this overlay.
51684   * @param {HTMLElement|undefined} element The Element containing the overlay.
51685   * @observable
51686   * @api
51687   */
51688  setElement(element) {
51689    this.set(Overlay_Property.ELEMENT, element);
51690  }
51691
51692  /**
51693   * Set the map to be associated with this overlay.
51694   * @param {import("./Map.js").default|null} map The map that the
51695   * overlay is part of. Pass `null` to just remove the overlay from the current map.
51696   * @observable
51697   * @api
51698   */
51699  setMap(map) {
51700    this.set(Overlay_Property.MAP, map);
51701  }
51702
51703  /**
51704   * Set the offset for this overlay.
51705   * @param {Array<number>} offset Offset.
51706   * @observable
51707   * @api
51708   */
51709  setOffset(offset) {
51710    this.set(Overlay_Property.OFFSET, offset);
51711  }
51712
51713  /**
51714   * Set the position for this overlay. If the position is `undefined` the
51715   * overlay is hidden.
51716   * @param {import("./coordinate.js").Coordinate|undefined} position The spatial point that the overlay
51717   *     is anchored at.
51718   * @observable
51719   * @api
51720   */
51721  setPosition(position) {
51722    this.set(Overlay_Property.POSITION, position);
51723  }
51724
51725  /**
51726   * Pan the map so that the overlay is entirely visible in the current viewport
51727   * (if necessary) using the configured autoPan parameters
51728   * @protected
51729   */
51730  performAutoPan() {
51731    if (this.autoPan) {
51732      this.panIntoView(this.autoPan);
51733    }
51734  }
51735
51736  /**
51737   * Pan the map so that the overlay is entirely visible in the current viewport
51738   * (if necessary).
51739   * @param {PanIntoViewOptions} [panIntoViewOptions] Options for the pan action
51740   * @api
51741   */
51742  panIntoView(panIntoViewOptions) {
51743    const map = this.getMap();
51744
51745    if (!map || !map.getTargetElement() || !this.get(Overlay_Property.POSITION)) {
51746      return;
51747    }
51748
51749    const mapRect = this.getRect(map.getTargetElement(), map.getSize());
51750    const element = this.getElement();
51751    const overlayRect = this.getRect(element, [
51752      dom_outerWidth(element),
51753      dom_outerHeight(element),
51754    ]);
51755
51756    panIntoViewOptions = panIntoViewOptions || {};
51757
51758    const myMargin =
51759      panIntoViewOptions.margin === undefined ? 20 : panIntoViewOptions.margin;
51760    if (!containsExtent(mapRect, overlayRect)) {
51761      // the overlay is not completely inside the viewport, so pan the map
51762      const offsetLeft = overlayRect[0] - mapRect[0];
51763      const offsetRight = mapRect[2] - overlayRect[2];
51764      const offsetTop = overlayRect[1] - mapRect[1];
51765      const offsetBottom = mapRect[3] - overlayRect[3];
51766
51767      const delta = [0, 0];
51768      if (offsetLeft < 0) {
51769        // move map to the left
51770        delta[0] = offsetLeft - myMargin;
51771      } else if (offsetRight < 0) {
51772        // move map to the right
51773        delta[0] = Math.abs(offsetRight) + myMargin;
51774      }
51775      if (offsetTop < 0) {
51776        // move map up
51777        delta[1] = offsetTop - myMargin;
51778      } else if (offsetBottom < 0) {
51779        // move map down
51780        delta[1] = Math.abs(offsetBottom) + myMargin;
51781      }
51782
51783      if (delta[0] !== 0 || delta[1] !== 0) {
51784        const center = /** @type {import("./coordinate.js").Coordinate} */ (
51785          map.getView().getCenterInternal()
51786        );
51787        const centerPx = map.getPixelFromCoordinateInternal(center);
51788        if (!centerPx) {
51789          return;
51790        }
51791        const newCenterPx = [centerPx[0] + delta[0], centerPx[1] + delta[1]];
51792
51793        const panOptions = panIntoViewOptions.animation || {};
51794        map.getView().animateInternal({
51795          center: map.getCoordinateFromPixelInternal(newCenterPx),
51796          duration: panOptions.duration,
51797          easing: panOptions.easing,
51798        });
51799      }
51800    }
51801  }
51802
51803  /**
51804   * Get the extent of an element relative to the document
51805   * @param {HTMLElement} element The element.
51806   * @param {import("./size.js").Size} size The size of the element.
51807   * @return {import("./extent.js").Extent} The extent.
51808   * @protected
51809   */
51810  getRect(element, size) {
51811    const box = element.getBoundingClientRect();
51812    const offsetX = box.left + window.pageXOffset;
51813    const offsetY = box.top + window.pageYOffset;
51814    return [offsetX, offsetY, offsetX + size[0], offsetY + size[1]];
51815  }
51816
51817  /**
51818   * Set the positioning for this overlay.
51819   * @param {Positioning} positioning how the overlay is
51820   *     positioned relative to its point on the map.
51821   * @observable
51822   * @api
51823   */
51824  setPositioning(positioning) {
51825    this.set(Overlay_Property.POSITIONING, positioning);
51826  }
51827
51828  /**
51829   * Modify the visibility of the element.
51830   * @param {boolean} visible Element visibility.
51831   * @protected
51832   */
51833  setVisible(visible) {
51834    if (this.rendered.visible !== visible) {
51835      this.element.style.display = visible ? '' : 'none';
51836      this.rendered.visible = visible;
51837    }
51838  }
51839
51840  /**
51841   * Update pixel position.
51842   * @protected
51843   */
51844  updatePixelPosition() {
51845    const map = this.getMap();
51846    const position = this.getPosition();
51847    if (!map || !map.isRendered() || !position) {
51848      this.setVisible(false);
51849      return;
51850    }
51851
51852    const pixel = map.getPixelFromCoordinate(position);
51853    const mapSize = map.getSize();
51854    this.updateRenderedPosition(pixel, mapSize);
51855  }
51856
51857  /**
51858   * @param {import("./pixel.js").Pixel} pixel The pixel location.
51859   * @param {import("./size.js").Size|undefined} mapSize The map size.
51860   * @protected
51861   */
51862  updateRenderedPosition(pixel, mapSize) {
51863    const style = this.element.style;
51864    const offset = this.getOffset();
51865
51866    const positioning = this.getPositioning();
51867
51868    this.setVisible(true);
51869
51870    const x = Math.round(pixel[0] + offset[0]) + 'px';
51871    const y = Math.round(pixel[1] + offset[1]) + 'px';
51872    let posX = '0%';
51873    let posY = '0%';
51874    if (
51875      positioning == 'bottom-right' ||
51876      positioning == 'center-right' ||
51877      positioning == 'top-right'
51878    ) {
51879      posX = '-100%';
51880    } else if (
51881      positioning == 'bottom-center' ||
51882      positioning == 'center-center' ||
51883      positioning == 'top-center'
51884    ) {
51885      posX = '-50%';
51886    }
51887    if (
51888      positioning == 'bottom-left' ||
51889      positioning == 'bottom-center' ||
51890      positioning == 'bottom-right'
51891    ) {
51892      posY = '-100%';
51893    } else if (
51894      positioning == 'center-left' ||
51895      positioning == 'center-center' ||
51896      positioning == 'center-right'
51897    ) {
51898      posY = '-50%';
51899    }
51900    const transform = `translate(${posX}, ${posY}) translate(${x}, ${y})`;
51901    if (this.rendered.transform_ != transform) {
51902      this.rendered.transform_ = transform;
51903      style.transform = transform;
51904    }
51905  }
51906
51907  /**
51908   * returns the options this Overlay has been created with
51909   * @return {Options} overlay options
51910   */
51911  getOptions() {
51912    return this.options;
51913  }
51914}
51915
51916/* harmony default export */ const ol_Overlay = (Overlay);
51917
51918;// CONCATENATED MODULE: ./node_modules/ol/DataTile.js
51919/**
51920 * @module ol/DataTile
51921 */
51922
51923
51924
51925/**
51926 * Data that can be used with a DataTile.  For increased browser compatibility, use
51927 * Uint8Array instead of Uint8ClampedArray where possible.
51928 * @typedef {Uint8Array|Uint8ClampedArray|Float32Array|DataView} Data
51929 */
51930
51931/**
51932 * @typedef {Object} Options
51933 * @property {import("./tilecoord.js").TileCoord} tileCoord Tile coordinate.
51934 * @property {function(): Promise<Data>} loader Data loader.
51935 * @property {number} [transition=250] A duration for tile opacity
51936 * transitions in milliseconds. A duration of 0 disables the opacity transition.
51937 * @property {boolean} [interpolate=false] Use interpolated values when resampling.  By default,
51938 * the nearest neighbor is used when resampling.
51939 * @property {import('./size.js').Size} [size=[256, 256]] Tile size.
51940 * @api
51941 */
51942
51943class DataTile extends ol_Tile {
51944  /**
51945   * @param {Options} options Tile options.
51946   */
51947  constructor(options) {
51948    const state = TileState.IDLE;
51949
51950    super(options.tileCoord, state, {
51951      transition: options.transition,
51952      interpolate: options.interpolate,
51953    });
51954
51955    /**
51956     * @type {function(): Promise<Data>}
51957     * @private
51958     */
51959    this.loader_ = options.loader;
51960
51961    /**
51962     * @type {Data}
51963     * @private
51964     */
51965    this.data_ = null;
51966
51967    /**
51968     * @type {Error}
51969     * @private
51970     */
51971    this.error_ = null;
51972
51973    /**
51974     * @type {import('./size.js').Size}
51975     * @private
51976     */
51977    this.size_ = options.size || [256, 256];
51978  }
51979
51980  /**
51981   * Get the tile size.
51982   * @return {import('./size.js').Size} Tile size.
51983   */
51984  getSize() {
51985    return this.size_;
51986  }
51987
51988  /**
51989   * Get the data for the tile.
51990   * @return {Data} Tile data.
51991   * @api
51992   */
51993  getData() {
51994    return this.data_;
51995  }
51996
51997  /**
51998   * Get any loading error.
51999   * @return {Error} Loading error.
52000   * @api
52001   */
52002  getError() {
52003    return this.error_;
52004  }
52005
52006  /**
52007   * Load not yet loaded URI.
52008   * @api
52009   */
52010  load() {
52011    if (this.state !== TileState.IDLE && this.state !== TileState.ERROR) {
52012      return;
52013    }
52014    this.state = TileState.LOADING;
52015    this.changed();
52016
52017    const self = this;
52018    this.loader_()
52019      .then(function (data) {
52020        self.data_ = data;
52021        self.state = TileState.LOADED;
52022        self.changed();
52023      })
52024      .catch(function (error) {
52025        self.error_ = error;
52026        self.state = TileState.ERROR;
52027        self.changed();
52028      });
52029  }
52030}
52031
52032/* harmony default export */ const ol_DataTile = (DataTile);
52033
52034;
52034// CONCATENATED MODULE: ./node_modules/ol/webgl.js
52035/**
52036 * @module ol/webgl
52037 */
52038
52039
52040
52041/**
52042 * Constants taken from goog.webgl
52043 */
52044
52045/**
52046 * Used by {@link module:ol/webgl/Helper~WebGLHelper} for buffers containing vertices data, such as
52047 * position, color, texture coordinate, etc. These vertices are then referenced by an index buffer
52048 * to be drawn on screen (see {@link module:ol/webgl.ELEMENT_ARRAY_BUFFER}).
52049 * @const
52050 * @type {number}
52051 * @api
52052 */
52053const ARRAY_BUFFER = 0x8892;
52054
52055/**
52056 * Used by {@link module:ol/webgl/Helper~WebGLHelper} for buffers containing indices data.
52057 * Index buffers are essentially lists of references to vertices defined in a vertex buffer
52058 * (see {@link module:ol/webgl.ARRAY_BUFFER}), and define the primitives (triangles) to be drawn.
52059 * @const
52060 * @type {number}
52061 * @api
52062 */
52063const ELEMENT_ARRAY_BUFFER = 0x8893;
52064
52065/**
52066 * Used by {link module:ol/webgl/Buffer~WebGLArrayBuffer}.
52067 * @const
52068 * @type {number}
52069 * @api
52070 */
52071const STREAM_DRAW = 0x88e0;
52072
52073/**
52074 * Used by {link module:ol/webgl/Buffer~WebGLArrayBuffer}.
52075 * @const
52076 * @type {number}
52077 * @api
52078 */
52079const STATIC_DRAW = 0x88e4;
52080
52081/**
52082 * Used by {link module:ol/webgl/Buffer~WebGLArrayBuffer}.
52083 * @const
52084 * @type {number}
52085 * @api
52086 */
52087const DYNAMIC_DRAW = 0x88e8;
52088
52089/**
52090 * @const
52091 * @type {number}
52092 */
52093const UNSIGNED_BYTE = 0x1401;
52094
52095/**
52096 * @const
52097 * @type {number}
52098 */
52099const UNSIGNED_SHORT = 0x1403;
52100
52101/**
52102 * @const
52103 * @type {number}
52104 */
52105const UNSIGNED_INT = 0x1405;
52106
52107/**
52108 * @const
52109 * @type {number}
52110 */
52111const FLOAT = 0x1406;
52112
52113/** end of goog.webgl constants
52114 */
52115
52116/**
52117 * @const
52118 * @type {Array<string>}
52119 */
52120const CONTEXT_IDS = ['experimental-webgl', 'webgl', 'webkit-3d', 'moz-webgl'];
52121
52122/**
52123 * @param {HTMLCanvasElement} canvas Canvas.
52124 * @param {Object} [attributes] Attributes.
52125 * @return {WebGLRenderingContext} WebGL rendering context.
52126 */
52127function getContext(canvas, attributes) {
52128  attributes = Object.assign(
52129    {
52130      preserveDrawingBuffer: true,
52131      antialias: SAFARI_BUG_237906 ? false : true, // https://bugs.webkit.org/show_bug.cgi?id=237906
52132    },
52133    attributes
52134  );
52135  const ii = CONTEXT_IDS.length;
52136  for (let i = 0; i < ii; ++i) {
52137    try {
52138      const context = canvas.getContext(CONTEXT_IDS[i], attributes);
52139      if (context) {
52140        return /** @type {!WebGLRenderingContext} */ (context);
52141      }
52142    } catch (e) {
52143      // pass
52144    }
52145  }
52146  return null;
52147}
52148
52149/**
52150 * @type {Array<string>}
52151 */
52152let supportedExtensions;
52153
52154/**
52155 * @return {Array<string>} List of supported WebGL extensions.
52156 */
52157function getSupportedExtensions() {
52158  if (!supportedExtensions) {
52159    const canvas = document.createElement('canvas');
52160    const gl = getContext(canvas);
52161    if (gl) {
52162      supportedExtensions = gl.getSupportedExtensions();
52163    }
52164  }
52165  return supportedExtensions;
52166}
52167
52168;// CONCATENATED MODULE: ./node_modules/ol/webgl/Buffer.js
52169/**
52170 * @module ol/webgl/Buffer
52171 */
52172
52173
52174
52175/**
52176 * Used to describe the intended usage for the data: `STATIC_DRAW`, `STREAM_DRAW`
52177 * or `DYNAMIC_DRAW`.
52178 * @enum {number}
52179 */
52180const BufferUsage = {
52181  STATIC_DRAW: STATIC_DRAW,
52182  STREAM_DRAW: STREAM_DRAW,
52183  DYNAMIC_DRAW: DYNAMIC_DRAW,
52184};
52185
52186/**
52187 * @classdesc
52188 * Object used to store an array of data as well as usage information for that data.
52189 * Stores typed arrays internally, either Float32Array or Uint16/32Array depending on
52190 * the buffer type (ARRAY_BUFFER or ELEMENT_ARRAY_BUFFER) and available extensions.
52191 *
52192 * To populate the array, you can either use:
52193 * * A size using `#ofSize(buffer)`
52194 * * An `ArrayBuffer` object using `#fromArrayBuffer(buffer)`
52195 * * A plain array using `#fromArray(array)`
52196 *
52197 * Note:
52198 * See the documentation of [WebGLRenderingContext.bufferData](https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/bufferData)
52199 * for more info on buffer usage.
52200 * @api
52201 */
52202class WebGLArrayBuffer {
52203  /**
52204   * @param {number} type Buffer type, either ARRAY_BUFFER or ELEMENT_ARRAY_BUFFER.
52205   * @param {number} [usage] Intended usage, either `STATIC_DRAW`, `STREAM_DRAW` or `DYNAMIC_DRAW`.
52206   * Default is `DYNAMIC_DRAW`.
52207   */
52208  constructor(type, usage) {
52209    /**
52210     * @private
52211     * @type {Float32Array|Uint32Array}
52212     */
52213    this.array = null;
52214
52215    /**
52216     * @private
52217     * @type {number}
52218     */
52219    this.type = type;
52220
52221    asserts_assert(type === ARRAY_BUFFER || type === ELEMENT_ARRAY_BUFFER, 62);
52222
52223    /**
52224     * @private
52225     * @type {number}
52226     */
52227    this.usage = usage !== undefined ? usage : BufferUsage.STATIC_DRAW;
52228  }
52229
52230  /**
52231   * Populates the buffer with an array of the given size (all values will be zeroes).
52232   * @param {number} size Array size
52233   */
52234  ofSize(size) {
52235    this.array = new (getArrayClassForType(this.type))(size);
52236  }
52237
52238  /**
52239   * Populates the buffer with an array of the given size.
52240   * @param {Array<number>} array Numerical array
52241   */
52242  fromArray(array) {
52243    this.array = getArrayClassForType(this.type).from(array);
52244  }
52245
52246  /**
52247   * Populates the buffer with a raw binary array buffer.
52248   * @param {ArrayBuffer} buffer Raw binary buffer to populate the array with. Note that this buffer must have been
52249   * initialized for the same typed array class.
52250   */
52251  fromArrayBuffer(buffer) {
52252    this.array = new (getArrayClassForType(this.type))(buffer);
52253  }
52254
52255  /**
52256   * @return {number} Buffer type.
52257   */
52258  getType() {
52259    return this.type;
52260  }
52261
52262  /**
52263   * Will return null if the buffer was not initialized
52264   * @return {Float32Array|Uint32Array} Array.
52265   */
52266  getArray() {
52267    return this.array;
52268  }
52269
52270  /**
52271   * @return {number} Usage.
52272   */
52273  getUsage() {
52274    return this.usage;
52275  }
52276
52277  /**
52278   * Will return 0 if the buffer is not initialized
52279   * @return {number} Array size
52280   */
52281  getSize() {
52282    return this.array ? this.array.length : 0;
52283  }
52284}
52285
52286/**
52287 * Returns a typed array constructor based on the given buffer type
52288 * @param {number} type Buffer type, either ARRAY_BUFFER or ELEMENT_ARRAY_BUFFER.
52289 * @return {Float32ArrayConstructor|Uint32ArrayConstructor} The typed array class to use for this buffer.
52290 */
52291function getArrayClassForType(type) {
52292  switch (type) {
52293    case ARRAY_BUFFER:
52294      return Float32Array;
52295    case ELEMENT_ARRAY_BUFFER:
52296      return Uint32Array;
52297    default:
52298      return Float32Array;
52299  }
52300}
52301
52302/* harmony default export */ const Buffer = (WebGLArrayBuffer);
52303
52304;// CONCATENATED MODULE: ./node_modules/ol/webgl/TileTexture.js
52305/**
52306 * @module ol/webgl/TileTexture
52307 */
52308
52309
52310
52311
52312
52313
52314
52315
52316
52317
52318
52319/**
52320 * @param {WebGLRenderingContext} gl The WebGL context.
52321 * @param {WebGLTexture} texture The texture.
52322 * @param {boolean} interpolate Interpolate when resampling.
52323 */
52324function bindAndConfigure(gl, texture, interpolate) {
52325  const resampleFilter = interpolate ? gl.LINEAR : gl.NEAREST;
52326  gl.bindTexture(gl.TEXTURE_2D, texture);
52327  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
52328  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
52329  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, resampleFilter);
52330  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, resampleFilter);
52331}
52332
52333/**
52334 * @param {WebGLRenderingContext} gl The WebGL context.
52335 * @param {WebGLTexture} texture The texture.
52336 * @param {HTMLImageElement|HTMLCanvasElement|HTMLVideoElement} image The image.
52337 * @param {boolean} interpolate Interpolate when resampling.
52338 */
52339function uploadImageTexture(gl, texture, image, interpolate) {
52340  bindAndConfigure(gl, texture, interpolate);
52341
52342  gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
52343}
52344
52345/**
52346 * @param {import("./Helper.js").default} helper The WebGL helper.
52347 * @param {WebGLTexture} texture The texture.
52348 * @param {import("../DataTile.js").Data} data The pixel data.
52349 * @param {import("../size.js").Size} size The pixel size.
52350 * @param {number} bandCount The band count.
52351 * @param {boolean} interpolate Interpolate when resampling.
52352 */
52353function uploadDataTexture(
52354  helper,
52355  texture,
52356  data,
52357  size,
52358  bandCount,
52359  interpolate
52360) {
52361  const gl = helper.getGL();
52362  let textureType;
52363  let canInterpolate;
52364  if (data instanceof Float32Array) {
52365    textureType = gl.FLOAT;
52366    helper.getExtension('OES_texture_float');
52367    const extension = helper.getExtension('OES_texture_float_linear');
52368    canInterpolate = extension !== null;
52369  } else {
52370    textureType = gl.UNSIGNED_BYTE;
52371    canInterpolate = true;
52372  }
52373  bindAndConfigure(gl, texture, interpolate && canInterpolate);
52374
52375  const bytesPerRow = data.byteLength / size[1];
52376  let unpackAlignment = 1;
52377  if (bytesPerRow % 8 === 0) {
52378    unpackAlignment = 8;
52379  } else if (bytesPerRow % 4 === 0) {
52380    unpackAlignment = 4;
52381  } else if (bytesPerRow % 2 === 0) {
52382    unpackAlignment = 2;
52383  }
52384
52385  let format;
52386  switch (bandCount) {
52387    case 1: {
52388      format = gl.LUMINANCE;
52389      break;
52390    }
52391    case 2: {
52392      format = gl.LUMINANCE_ALPHA;
52393      break;
52394    }
52395    case 3: {
52396      format = gl.RGB;
52397      break;
52398    }
52399    case 4: {
52400      format = gl.RGBA;
52401      break;
52402    }
52403    default: {
52404      throw new Error(`Unsupported number of bands: ${bandCount}`);
52405    }
52406  }
52407
52408  const oldUnpackAlignment = gl.getParameter(gl.UNPACK_ALIGNMENT);
52409  gl.pixelStorei(gl.UNPACK_ALIGNMENT, unpackAlignment);
52410  gl.texImage2D(
52411    gl.TEXTURE_2D,
52412    0,
52413    format,
52414    size[0],
52415    size[1],
52416    0,
52417    format,
52418    textureType,
52419    data
52420  );
52421  gl.pixelStorei(gl.UNPACK_ALIGNMENT, oldUnpackAlignment);
52422}
52423
52424/**
52425 * @type {CanvasRenderingContext2D}
52426 */
52427let TileTexture_pixelContext = null;
52428
52429function TileTexture_createPixelContext() {
52430  const canvas = document.createElement('canvas');
52431  canvas.width = 1;
52432  canvas.height = 1;
52433  TileTexture_pixelContext = canvas.getContext('2d');
52434}
52435
52436/**
52437 * @typedef {import("../DataTile.js").default|ImageTile|ReprojTile} TileType
52438 */
52439
52440/**
52441 * @typedef {Object} Options
52442 * @property {TileType} tile The tile.
52443 * @property {import("../tilegrid/TileGrid.js").default} grid Tile grid.
52444 * @property {import("../webgl/Helper.js").default} helper WebGL helper.
52445 * @property {number} [gutter=0] The size in pixels of the gutter around image tiles to ignore.
52446 */
52447
52448class TileTexture extends events_Target {
52449  /**
52450   * @param {Options} options The tile texture options.
52451   */
52452  constructor(options) {
52453    super();
52454
52455    /**
52456     * @type {TileType}
52457     */
52458    this.tile;
52459
52460    /**
52461     * @type {Array<WebGLTexture>}
52462     */
52463    this.textures = [];
52464    this.handleTileChange_ = this.handleTileChange_.bind(this);
52465
52466    /**
52467     * @type {import("../size.js").Size}
52468     * @private
52469     */
52470    this.renderSize_ = toSize(
52471      options.grid.getTileSize(options.tile.tileCoord[0])
52472    );
52473
52474    /**
52475     * @type {number}
52476     * @private
52477     */
52478    this.gutter_ = options.gutter || 0;
52479
52480    /**
52481     * @type {number}
52482     */
52483    this.bandCount = NaN;
52484
52485    /**
52486     * @type {import("../webgl/Helper.js").default}
52487     * @private
52488     */
52489    this.helper_ = options.helper;
52490
52491    const coords = new Buffer(ARRAY_BUFFER, STATIC_DRAW);
52492    coords.fromArray([
52493      0, // P0
52494      1,
52495      1, // P1
52496      1,
52497      1, // P2
52498      0,
52499      0, // P3
52500      0,
52501    ]);
52502    this.helper_.flushBufferData(coords);
52503
52504    /**
52505     * @type {WebGLArrayBuffer}
52506     */
52507    this.coords = coords;
52508
52509    this.setTile(options.tile);
52510  }
52511
52512  /**
52513   * @param {TileType} tile Tile.
52514   */
52515  setTile(tile) {
52516    if (tile !== this.tile) {
52517      if (this.tile) {
52518        this.tile.removeEventListener(EventType.CHANGE, this.handleTileChange_);
52519      }
52520      this.tile = tile;
52521      this.textures.length = 0;
52522      this.loaded = tile.getState() === TileState.LOADED;
52523      if (this.loaded) {
52524        this.uploadTile_();
52525      } else {
52526        if (tile instanceof ol_ImageTile) {
52527          const image = tile.getImage();
52528          if (image instanceof Image && !image.crossOrigin) {
52529            image.crossOrigin = 'anonymous';
52530          }
52531        }
52532        tile.addEventListener(EventType.CHANGE, this.handleTileChange_);
52533      }
52534    }
52535  }
52536
52537  uploadTile_() {
52538    const helper = this.helper_;
52539    const gl = helper.getGL();
52540    const tile = this.tile;
52541
52542    if (tile instanceof ol_ImageTile || tile instanceof reproj_Tile) {
52543      const texture = gl.createTexture();
52544      this.textures.push(texture);
52545      this.bandCount = 4;
52546      uploadImageTexture(gl, texture, tile.getImage(), tile.interpolate);
52547      return;
52548    }
52549
52550    const sourceTileSize = tile.getSize();
52551    const pixelSize = [
52552      sourceTileSize[0] + 2 * this.gutter_,
52553      sourceTileSize[1] + 2 * this.gutter_,
52554    ];
52555    const data = tile.getData();
52556    const isFloat = data instanceof Float32Array;
52557    const pixelCount = pixelSize[0] * pixelSize[1];
52558    const DataType = isFloat ? Float32Array : Uint8Array;
52559    const bytesPerElement = DataType.BYTES_PER_ELEMENT;
52560    const bytesPerRow = data.byteLength / pixelSize[1];
52561
52562    this.bandCount = Math.floor(bytesPerRow / bytesPerElement / pixelSize[0]);
52563    const textureCount = Math.ceil(this.bandCount / 4);
52564
52565    if (textureCount === 1) {
52566      const texture = gl.createTexture();
52567      this.textures.push(texture);
52568      uploadDataTexture(
52569        helper,
52570        texture,
52571        data,
52572        pixelSize,
52573        this.bandCount,
52574        tile.interpolate
52575      );
52576      return;
52577    }
52578
52579    const textureDataArrays = new Array(textureCount);
52580    for (let textureIndex = 0; textureIndex < textureCount; ++textureIndex) {
52581      const texture = gl.createTexture();
52582      this.textures.push(texture);
52583
52584      const bandCount =
52585        textureIndex < textureCount - 1 ? 4 : ((this.bandCount - 1) % 4) + 1;
52586      textureDataArrays[textureIndex] = new DataType(pixelCount * bandCount);
52587    }
52588
52589    let dataIndex = 0;
52590    let rowOffset = 0;
52591    const colCount = pixelSize[0] * this.bandCount;
52592    for (let rowIndex = 0; rowIndex < pixelSize[1]; ++rowIndex) {
52593      for (let colIndex = 0; colIndex < colCount; ++colIndex) {
52594        const dataValue = data[rowOffset + colIndex];
52595
52596        const pixelIndex = Math.floor(dataIndex / this.bandCount);
52597        const bandIndex = colIndex % this.bandCount;
52598        const textureIndex = Math.floor(bandIndex / 4);
52599        const textureData = textureDataArrays[textureIndex];
52600        const bandCount = textureData.length / pixelCount;
52601        const textureBandIndex = bandIndex % 4;
52602        textureData[pixelIndex * bandCount + textureBandIndex] = dataValue;
52603
52604        ++dataIndex;
52605      }
52606      rowOffset += bytesPerRow / bytesPerElement;
52607    }
52608
52609    for (let textureIndex = 0; textureIndex < textureCount; ++textureIndex) {
52610      const texture = this.textures[textureIndex];
52611      const textureData = textureDataArrays[textureIndex];
52612      const bandCount = textureData.length / pixelCount;
52613      uploadDataTexture(
52614        helper,
52615        texture,
52616        textureData,
52617        pixelSize,
52618        bandCount,
52619        tile.interpolate
52620      );
52621    }
52622  }
52623
52624  handleTileChange_() {
52625    if (this.tile.getState() === TileState.LOADED) {
52626      this.loaded = true;
52627      this.uploadTile_();
52628      this.dispatchEvent(EventType.CHANGE);
52629    }
52630  }
52631
52632  disposeInternal() {
52633    const gl = this.helper_.getGL();
52634    this.helper_.deleteBuffer(this.coords);
52635    for (let i = 0; i < this.textures.length; ++i) {
52636      gl.deleteTexture(this.textures[i]);
52637    }
52638    this.tile.removeEventListener(EventType.CHANGE, this.handleTileChange_);
52639  }
52640
52641  /**
52642   * Get data for a pixel.  If the tile is not loaded, null is returned.
52643   * @param {number} renderCol The column index (in rendered tile space).
52644   * @param {number} renderRow The row index (in rendered tile space).
52645   * @return {import("../DataTile.js").Data|null} The data.
52646   */
52647  getPixelData(renderCol, renderRow) {
52648    if (!this.loaded) {
52649      return null;
52650    }
52651    const renderWidth = this.renderSize_[0];
52652    const renderHeight = this.renderSize_[1];
52653    const gutter = this.gutter_;
52654
52655    if (this.tile instanceof ol_DataTile) {
52656      const sourceSize = this.tile.getSize();
52657
52658      const sourceWidthWithoutGutter = sourceSize[0];
52659      const sourceHeightWithoutGutter = sourceSize[1];
52660      const sourceWidth = sourceWidthWithoutGutter + 2 * gutter;
52661      const sourceHeight = sourceHeightWithoutGutter + 2 * gutter;
52662
52663      const sourceCol =
52664        gutter +
52665        Math.floor(sourceWidthWithoutGutter * (renderCol / renderWidth));
52666
52667      const sourceRow =
52668        gutter +
52669        Math.floor(sourceHeightWithoutGutter * (renderRow / renderHeight));
52670
52671      const data = this.tile.getData();
52672      if (data instanceof DataView) {
52673        const bytesPerPixel = data.byteLength / (sourceWidth * sourceHeight);
52674        const offset = bytesPerPixel * (sourceRow * sourceWidth + sourceCol);
52675        const buffer = data.buffer.slice(offset, offset + bytesPerPixel);
52676        return new DataView(buffer);
52677      }
52678
52679      const offset = this.bandCount * (sourceRow * sourceWidth + sourceCol);
52680      return data.slice(offset, offset + this.bandCount);
52681    }
52682
52683    if (!TileTexture_pixelContext) {
52684      TileTexture_createPixelContext();
52685    }
52686    TileTexture_pixelContext.clearRect(0, 0, 1, 1);
52687
52688    const image = this.tile.getImage();
52689    const sourceWidth = image.width;
52690    const sourceHeight = image.height;
52691
52692    const sourceWidthWithoutGutter = sourceWidth - 2 * gutter;
52693    const sourceHeightWithoutGutter = sourceHeight - 2 * gutter;
52694
52695    const sourceCol =
52696      gutter + Math.floor(sourceWidthWithoutGutter * (renderCol / renderWidth));
52697
52698    const sourceRow =
52699      gutter +
52700      Math.floor(sourceHeightWithoutGutter * (renderRow / renderHeight));
52701
52702    let data;
52703    try {
52704      TileTexture_pixelContext.drawImage(image, sourceCol, sourceRow, 1, 1, 0, 0, 1, 1);
52705      data = TileTexture_pixelContext.getImageData(0, 0, 1, 1).data;
52706    } catch (err) {
52707      TileTexture_pixelContext = null;
52708      return null;
52709    }
52710    return data;
52711  }
52712}
52713
52714/* harmony default export */ const webgl_TileTexture = (TileTexture);
52715
52716;// CONCATENATED MODULE: ./node_modules/ol/webgl/ContextEventType.js
52717/**
52718 * @module ol/webgl/ContextEventType
52719 */
52720
52721/**
52722 * @enum {string}
52723 */
52724/* harmony default export */ const ContextEventType = ({
52725  LOST: 'webglcontextlost',
52726  RESTORED: 'webglcontextrestored',
52727});
52728
52729;// CONCATENATED MODULE: ./node_modules/ol/webgl/PostProcessingPass.js
52730/**
52731 * @module ol/webgl/PostProcessingPass
52732 */
52733
52734
52735
52736const DEFAULT_VERTEX_SHADER = `
52737  precision mediump float;
52738  
52739  attribute vec2 a_position;
52740  varying vec2 v_texCoord;
52741  varying vec2 v_screenCoord;
52742  
52743  uniform vec2 u_screenSize;
52744   
52745  void main() {
52746    v_texCoord = a_position * 0.5 + 0.5;
52747    v_screenCoord = v_texCoord * u_screenSize;
52748    gl_Position = vec4(a_position, 0.0, 1.0);
52749  }
52750`;
52751
52752const DEFAULT_FRAGMENT_SHADER = `
52753  precision mediump float;
52754   
52755  uniform sampler2D u_image;
52756  uniform float u_opacity;
52757   
52758  varying vec2 v_texCoord;
52759   
52760  void main() {
52761    gl_FragColor = texture2D(u_image, v_texCoord) * u_opacity;
52762  }
52763`;
52764
52765/**
52766 * @typedef {Object} Options
52767 * @property {WebGLRenderingContext} webGlContext WebGL context; mandatory.
52768 * @property {number} [scaleRatio] Scale ratio; if < 1, the post process will render to a texture smaller than
52769 * the main canvas that will then be sampled up (useful for saving resource on blur steps).
52770 * @property {string} [vertexShader] Vertex shader source
52771 * @property {string} [fragmentShader] Fragment shader source
52772 * @property {Object<string,import("./Helper").UniformValue>} [uniforms] Uniform definitions for the post process step
52773 */
52774
52775/**
52776 * @typedef {Object} UniformInternalDescription
52777 * @property {import("./Helper").UniformValue} value Value
52778 * @property {number} location Location
52779 * @property {WebGLTexture} [texture] Texture
52780 * @private
52781 */
52782
52783/**
52784 * @classdesc
52785 * This class is used to define Post Processing passes with custom shaders and uniforms.
52786 * This is used internally by {@link module:ol/webgl/Helper~WebGLHelper}.
52787 *
52788 * Please note that the final output on the DOM canvas is expected to have premultiplied alpha, which means that
52789 * a pixel which is 100% red with an opacity of 50% must have a color of (r=0.5, g=0, b=0, a=0.5).
52790 * Failing to provide pixel colors with premultiplied alpha will result in render anomalies.
52791 *
52792 * The default post-processing pass does *not* multiply color values with alpha value, it expects color values to be
52793 * premultiplied.
52794 *
52795 * Default shaders are shown hereafter:
52796 *
52797 * * Vertex shader:
52798 *
52799 *   ```
52800 *   precision mediump float;
52801 *
52802 *   attribute vec2 a_position;
52803 *   varying vec2 v_texCoord;
52804 *   varying vec2 v_screenCoord;
52805 *
52806 *   uniform vec2 u_screenSize;
52807 *
52808 *   void main() {
52809 *     v_texCoord = a_position * 0.5 + 0.5;
52810 *     v_screenCoord = v_texCoord * u_screenSize;
52811 *     gl_Position = vec4(a_position, 0.0, 1.0);
52812 *   }
52813 *   ```
52814 *
52815 * * Fragment shader:
52816 *
52817 *   ```
52818 *   precision mediump float;
52819 *
52820 *   uniform sampler2D u_image;
52821 *   uniform float u_opacity;
52822 *
52823 *   varying vec2 v_texCoord;
52824 *
52825 *   void main() {
52826 *     gl_FragColor = texture2D(u_image, v_texCoord) * u_opacity;
52827 *   }
52828 *   ```
52829 *
52830 * @api
52831 */
52832class WebGLPostProcessingPass {
52833  /**
52834   * @param {Options} options Options.
52835   */
52836  constructor(options) {
52837    this.gl_ = options.webGlContext;
52838    const gl = this.gl_;
52839
52840    this.scaleRatio_ = options.scaleRatio || 1;
52841
52842    this.renderTargetTexture_ = gl.createTexture();
52843    this.renderTargetTextureSize_ = null;
52844
52845    this.frameBuffer_ = gl.createFramebuffer();
52846
52847    // compile the program for the frame buffer
52848    // TODO: make compilation errors show up
52849    const vertexShader = gl.createShader(gl.VERTEX_SHADER);
52850    gl.shaderSource(
52851      vertexShader,
52852      options.vertexShader || DEFAULT_VERTEX_SHADER
52853    );
52854    gl.compileShader(vertexShader);
52855    const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
52856    gl.shaderSource(
52857      fragmentShader,
52858      options.fragmentShader || DEFAULT_FRAGMENT_SHADER
52859    );
52860    gl.compileShader(fragmentShader);
52861    this.renderTargetProgram_ = gl.createProgram();
52862    gl.attachShader(this.renderTargetProgram_, vertexShader);
52863    gl.attachShader(this.renderTargetProgram_, fragmentShader);
52864    gl.linkProgram(this.renderTargetProgram_);
52865
52866    // bind the vertices buffer for the frame buffer
52867    this.renderTargetVerticesBuffer_ = gl.createBuffer();
52868    const verticesArray = [-1, -1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1];
52869    gl.bindBuffer(gl.ARRAY_BUFFER, this.renderTargetVerticesBuffer_);
52870    gl.bufferData(
52871      gl.ARRAY_BUFFER,
52872      new Float32Array(verticesArray),
52873      gl.STATIC_DRAW
52874    );
52875
52876    this.renderTargetAttribLocation_ = gl.getAttribLocation(
52877      this.renderTargetProgram_,
52878      'a_position'
52879    );
52880    this.renderTargetUniformLocation_ = gl.getUniformLocation(
52881      this.renderTargetProgram_,
52882      'u_screenSize'
52883    );
52884    this.renderTargetOpacityLocation_ = gl.getUniformLocation(
52885      this.renderTargetProgram_,
52886      'u_opacity'
52887    );
52888    this.renderTargetTextureLocation_ = gl.getUniformLocation(
52889      this.renderTargetProgram_,
52890      'u_image'
52891    );
52892
52893    /**
52894     * Holds info about custom uniforms used in the post processing pass
52895     * @type {Array<UniformInternalDescription>}
52896     * @private
52897     */
52898    this.uniforms_ = [];
52899    options.uniforms &&
52900      Object.keys(options.uniforms).forEach(
52901        function (name) {
52902          this.uniforms_.push({
52903            value: options.uniforms[name],
52904            location: gl.getUniformLocation(this.renderTargetProgram_, name),
52905          });
52906        }.bind(this)
52907      );
52908  }
52909
52910  /**
52911   * Get the WebGL rendering context
52912   * @return {WebGLRenderingContext} The rendering context.
52913   * @api
52914   */
52915  getGL() {
52916    return this.gl_;
52917  }
52918
52919  /**
52920   * Initialize the render target texture of the post process, make sure it is at the
52921   * right size and bind it as a render target for the next draw calls.
52922   * The last step to be initialized will be the one where the primitives are rendered.
52923   * @param {import("../Map.js").FrameState} frameState current frame state
52924   * @api
52925   */
52926  init(frameState) {
52927    const gl = this.getGL();
52928    const textureSize = [
52929      gl.drawingBufferWidth * this.scaleRatio_,
52930      gl.drawingBufferHeight * this.scaleRatio_,
52931    ];
52932
52933    // rendering goes to my buffer
52934    gl.bindFramebuffer(gl.FRAMEBUFFER, this.getFrameBuffer());
52935    gl.viewport(0, 0, textureSize[0], textureSize[1]);
52936
52937    // if size has changed: adjust canvas & render target texture
52938    if (
52939      !this.renderTargetTextureSize_ ||
52940      this.renderTargetTextureSize_[0] !== textureSize[0] ||
52941      this.renderTargetTextureSize_[1] !== textureSize[1]
52942    ) {
52943      this.renderTargetTextureSize_ = textureSize;
52944
52945      // create a new texture
52946      const level = 0;
52947      const internalFormat = gl.RGBA;
52948      const border = 0;
52949      const format = gl.RGBA;
52950      const type = gl.UNSIGNED_BYTE;
52951      const data = null;
52952      gl.bindTexture(gl.TEXTURE_2D, this.renderTargetTexture_);
52953      gl.texImage2D(
52954        gl.TEXTURE_2D,
52955        level,
52956        internalFormat,
52957        textureSize[0],
52958        textureSize[1],
52959        border,
52960        format,
52961        type,
52962        data
52963      );
52964
52965      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
52966      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
52967      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
52968
52969      // bind the texture to the framebuffer
52970      gl.framebufferTexture2D(
52971        gl.FRAMEBUFFER,
52972        gl.COLOR_ATTACHMENT0,
52973        gl.TEXTURE_2D,
52974        this.renderTargetTexture_,
52975        0
52976      );
52977    }
52978  }
52979
52980  /**
52981   * Render to the next postprocessing pass (or to the canvas if final pass).
52982   * @param {import("../Map.js").FrameState} frameState current frame state
52983   * @param {WebGLPostProcessingPass} [nextPass] Next pass, optional
52984   * @param {function(WebGLRenderingContext, import("../Map.js").FrameState):void} [preCompose] Called before composing.
52985   * @param {function(WebGLRenderingContext, import("../Map.js").FrameState):void} [postCompose] Called before composing.
52986   * @api
52987   */
52988  apply(frameState, nextPass, preCompose, postCompose) {
52989    const gl = this.getGL();
52990    const size = frameState.size;
52991
52992    gl.bindFramebuffer(
52993      gl.FRAMEBUFFER,
52994      nextPass ? nextPass.getFrameBuffer() : null
52995    );
52996    gl.activeTexture(gl.TEXTURE0);
52997    gl.bindTexture(gl.TEXTURE_2D, this.renderTargetTexture_);
52998
52999    if (!nextPass) {
53000      // clear the canvas if we are the first to render to it
53001      // and preserveDrawingBuffer is true
53002      const canvasId = getUid(gl.canvas);
53003      if (!frameState.renderTargets[canvasId]) {
53004        const attributes = gl.getContextAttributes();
53005        if (attributes && attributes.preserveDrawingBuffer) {
53006          gl.clearColor(0.0, 0.0, 0.0, 0.0);
53007          gl.clear(gl.COLOR_BUFFER_BIT);
53008        }
53009
53010        frameState.renderTargets[canvasId] = true;
53011      }
53012    }
53013
53014    gl.enable(gl.BLEND);
53015    gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
53016    gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
53017
53018    gl.bindBuffer(gl.ARRAY_BUFFER, this.renderTargetVerticesBuffer_);
53019
53020    gl.useProgram(this.renderTargetProgram_);
53021    gl.enableVertexAttribArray(this.renderTargetAttribLocation_);
53022    gl.vertexAttribPointer(
53023      this.renderTargetAttribLocation_,
53024      2,
53025      gl.FLOAT,
53026      false,
53027      0,
53028      0
53029    );
53030    gl.uniform2f(this.renderTargetUniformLocation_, size[0], size[1]);
53031    gl.uniform1i(this.renderTargetTextureLocation_, 0);
53032
53033    const opacity = frameState.layerStatesArray[frameState.layerIndex].opacity;
53034    gl.uniform1f(this.renderTargetOpacityLocation_, opacity);
53035
53036    this.applyUniforms(frameState);
53037
53038    if (preCompose) {
53039      preCompose(gl, frameState);
53040    }
53041    gl.drawArrays(gl.TRIANGLES, 0, 6);
53042    if (postCompose) {
53043      postCompose(gl, frameState);
53044    }
53045  }
53046
53047  /**
53048   * @return {WebGLFramebuffer} Frame buffer
53049   * @api
53050   */
53051  getFrameBuffer() {
53052    return this.frameBuffer_;
53053  }
53054
53055  /**
53056   * Sets the custom uniforms based on what was given in the constructor.
53057   * @param {import("../Map.js").FrameState} frameState Frame state.
53058   * @private
53059   */
53060  applyUniforms(frameState) {
53061    const gl = this.getGL();
53062
53063    let value;
53064    let textureSlot = 1;
53065    this.uniforms_.forEach(function (uniform) {
53066      value =
53067        typeof uniform.value === 'function'
53068          ? uniform.value(frameState)
53069          : uniform.value;
53070
53071      // apply value based on type
53072      if (value instanceof HTMLCanvasElement || value instanceof ImageData) {
53073        // create a texture & put data
53074        if (!uniform.texture) {
53075          uniform.texture = gl.createTexture();
53076        }
53077        gl.activeTexture(gl[`TEXTURE${textureSlot}`]);
53078        gl.bindTexture(gl.TEXTURE_2D, uniform.texture);
53079        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
53080        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
53081        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
53082
53083        if (value instanceof ImageData) {
53084          gl.texImage2D(
53085            gl.TEXTURE_2D,
53086            0,
53087            gl.RGBA,
53088            gl.RGBA,
53089            value.width,
53090            value.height,
53091            0,
53092            gl.UNSIGNED_BYTE,
53093            new Uint8Array(value.data)
53094          );
53095        } else {
53096          gl.texImage2D(
53097            gl.TEXTURE_2D,
53098            0,
53099            gl.RGBA,
53100            gl.RGBA,
53101            gl.UNSIGNED_BYTE,
53102            value
53103          );
53104        }
53105
53106        // fill texture slots
53107        gl.uniform1i(uniform.location, textureSlot++);
53108      } else if (Array.isArray(value)) {
53109        switch (value.length) {
53110          case 2:
53111            gl.uniform2f(uniform.location, value[0], value[1]);
53112            return;
53113          case 3:
53114            gl.uniform3f(uniform.location, value[0], value[1], value[2]);
53115            return;
53116          case 4:
53117            gl.uniform4f(
53118              uniform.location,
53119              value[0],
53120              value[1],
53121              value[2],
53122              value[3]
53123            );
53124            return;
53125          default:
53126            return;
53127        }
53128      } else if (typeof value === 'number') {
53129        gl.uniform1f(uniform.location, value);
53130      }
53131    });
53132  }
53133}
53134
53135/* harmony default export */ const PostProcessingPass = (WebGLPostProcessingPass);
53136
53137;// CONCATENATED MODULE: ./node_modules/ol/vec/mat4.js
53138/**
53139 * @module ol/vec/mat4
53140 */
53141
53142/**
53143 * @return {Array<number>} "4x4 matrix representing a 3D identity transform."
53144 */
53145function mat4_create() {
53146  return [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
53147}
53148
53149/**
53150 * @param {Array<number>} mat4 Flattened 4x4 matrix receiving the result.
53151 * @param {import("../transform.js").Transform} transform Transformation matrix.
53152 * @return {Array<number>} "2D transformation matrix as flattened 4x4 matrix."
53153 */
53154function fromTransform(mat4, transform) {
53155  mat4[0] = transform[0];
53156  mat4[1] = transform[1];
53157  mat4[4] = transform[2];
53158  mat4[5] = transform[3];
53159  mat4[12] = transform[4];
53160  mat4[13] = transform[5];
53161  return mat4;
53162}
53163
53164;// CONCATENATED MODULE: ./node_modules/ol/webgl/Helper.js
53165/**
53166 * @module ol/webgl/Helper
53167 */
53168
53169
53170
53171
53172
53173
53174
53175
53176
53177/**
53178 * @typedef {Object} BufferCacheEntry
53179 * @property {import("./Buffer.js").default} buffer Buffer.
53180 * @property {WebGLBuffer} webGlBuffer WebGlBuffer.
53181 */
53182
53183/**
53184 * Shader types, either `FRAGMENT_SHADER` or `VERTEX_SHADER`.
53185 * @enum {number}
53186 */
53187const ShaderType = {
53188  FRAGMENT_SHADER: 0x8b30,
53189  VERTEX_SHADER: 0x8b31,
53190};
53191
53192/**
53193 * Names of uniforms made available to all shaders.
53194 * Please note: changing these *will* break custom shaders!
53195 * @enum {string}
53196 */
53197const DefaultUniform = {
53198  PROJECTION_MATRIX: 'u_projectionMatrix',
53199  OFFSET_SCALE_MATRIX: 'u_offsetScaleMatrix',
53200  OFFSET_ROTATION_MATRIX: 'u_offsetRotateMatrix',
53201  TIME: 'u_time',
53202  ZOOM: 'u_zoom',
53203  RESOLUTION: 'u_resolution',
53204  SIZE_PX: 'u_sizePx',
53205  PIXEL_RATIO: 'u_pixelRatio',
53206};
53207
53208/**
53209 * Attribute types, either `UNSIGNED_BYTE`, `UNSIGNED_SHORT`, `UNSIGNED_INT` or `FLOAT`
53210 * Note: an attribute stored in a `Float32Array` should be of type `FLOAT`.
53211 * @enum {number}
53212 */
53213const AttributeType = {
53214  UNSIGNED_BYTE: UNSIGNED_BYTE,
53215  UNSIGNED_SHORT: UNSIGNED_SHORT,
53216  UNSIGNED_INT: UNSIGNED_INT,
53217  FLOAT: FLOAT,
53218};
53219
53220/**
53221 * Description of an attribute in a buffer
53222 * @typedef {Object} AttributeDescription
53223 * @property {string} name Attribute name to use in shaders
53224 * @property {number} size Number of components per attributes
53225 * @property {AttributeType} [type] Attribute type, i.e. number of bytes used to store the value. This is
53226 * determined by the class of typed array which the buffer uses (eg. `Float32Array` for a `FLOAT` attribute).
53227 * Default is `FLOAT`.
53228 */
53229
53230/**
53231 * @typedef {number|Array<number>|HTMLCanvasElement|HTMLImageElement|ImageData|import("../transform").Transform} UniformLiteralValue
53232 */
53233
53234/**
53235 * Uniform value can be a number, array of numbers (2 to 4), canvas element or a callback returning
53236 * one of the previous types.
53237 * @typedef {UniformLiteralValue|function(import("../Map.js").FrameState):UniformLiteralValue} UniformValue
53238 */
53239
53240/**
53241 * @typedef {Object} PostProcessesOptions
53242 * @property {number} [scaleRatio] Scale ratio; if < 1, the post process will render to a texture smaller than
53243 * the main canvas which will then be sampled up (useful for saving resource on blur steps).
53244 * @property {string} [vertexShader] Vertex shader source
53245 * @property {string} [fragmentShader] Fragment shader source
53246 * @property {Object<string,UniformValue>} [uniforms] Uniform definitions for the post process step
53247 */
53248
53249/**
53250 * @typedef {Object} Options
53251 * @property {Object<string,UniformValue>} [uniforms] Uniform definitions; property names must match the uniform
53252 * names in the provided or default shaders.
53253 * @property {Array<PostProcessesOptions>} [postProcesses] Post-processes definitions
53254 * @property {string} [canvasCacheKey] The cache key for the canvas.
53255 */
53256
53257/**
53258 * @typedef {Object} UniformInternalDescription
53259 * @property {string} name Name
53260 * @property {UniformValue} [value] Value
53261 * @property {WebGLTexture} [texture] Texture
53262 * @private
53263 */
53264
53265/**
53266 * @typedef {Object} CanvasCacheItem
53267 * @property {HTMLCanvasElement} canvas Canvas element.
53268 * @property {number} users The count of users of this canvas.
53269 */
53270
53271/**
53272 * @type {Object<string,CanvasCacheItem>}
53273 */
53274const canvasCache = {};
53275
53276/**
53277 * @param {string} key The cache key for the canvas.
53278 * @return {string} The shared cache key.
53279 */
53280function getSharedCanvasCacheKey(key) {
53281  return 'shared/' + key;
53282}
53283
53284let uniqueCanvasCacheKeyCount = 0;
53285
53286/**
53287 * @return {string} The unique cache key.
53288 */
53289function getUniqueCanvasCacheKey() {
53290  const key = 'unique/' + uniqueCanvasCacheKeyCount;
53291  uniqueCanvasCacheKeyCount += 1;
53292  return key;
53293}
53294
53295/**
53296 * @param {string} key The cache key for the canvas.
53297 * @return {HTMLCanvasElement} The canvas.
53298 */
53299function getCanvas(key) {
53300  let cacheItem = canvasCache[key];
53301  if (!cacheItem) {
53302    const canvas = document.createElement('canvas');
53303    canvas.style.position = 'absolute';
53304    canvas.style.left = '0';
53305    cacheItem = {users: 0, canvas};
53306    canvasCache[key] = cacheItem;
53307  }
53308
53309  cacheItem.users += 1;
53310  return cacheItem.canvas;
53311}
53312
53313/**
53314 * @param {string} key The cache key for the canvas.
53315 */
53316function Helper_releaseCanvas(key) {
53317  const cacheItem = canvasCache[key];
53318  if (!cacheItem) {
53319    return;
53320  }
53321
53322  cacheItem.users -= 1;
53323  if (cacheItem.users > 0) {
53324    return;
53325  }
53326
53327  const canvas = cacheItem.canvas;
53328  const gl = getContext(canvas);
53329  const extension = gl.getExtension('WEBGL_lose_context');
53330  if (extension) {
53331    extension.loseContext();
53332  }
53333
53334  delete canvasCache[key];
53335}
53336
53337/**
53338 * @classdesc
53339 * This class is intended to provide low-level functions related to WebGL rendering, so that accessing
53340 * directly the WebGL API should not be required anymore.
53341 *
53342 * Several operations are handled by the `WebGLHelper` class:
53343 *
53344 * ### Define custom shaders and uniforms
53345 *
53346 *   *Shaders* are low-level programs executed on the GPU and written in GLSL. There are two types of shaders:
53347 *
53348 *   Vertex shaders are used to manipulate the position and attribute of *vertices* of rendered primitives (ie. corners of a square).
53349 *   Outputs are:
53350 *
53351 *   * `gl_Position`: position of the vertex in screen space
53352 *
53353 *   * Varyings usually prefixed with `v_` are passed on to the fragment shader
53354 *
53355 *   Fragment shaders are used to control the actual color of the pixels drawn on screen. Their only output is `gl_FragColor`.
53356 *
53357 *   Both shaders can take *uniforms* or *attributes* as input. Attributes are explained later. Uniforms are common, read-only values that
53358 *   can be changed at every frame and can be of type float, arrays of float or images.
53359 *
53360 *   Shaders must be compiled and assembled into a program like so:
53361 *   ```js
53362 *   // here we simply create two shaders and assemble them in a program which is then used
53363 *   // for subsequent rendering calls; note how a frameState is required to set up a program,
53364 *   // as several default uniforms are computed from it (projection matrix, zoom level, etc.)
53365 *   const vertexShader = new WebGLVertex(VERTEX_SHADER);
53366 *   const fragmentShader = new WebGLFragment(FRAGMENT_SHADER);
53367 *   const program = this.context.getProgram(fragmentShader, vertexShader);
53368 *   helper.useProgram(this.program, frameState);
53369 *   ```
53370 *
53371 *   Uniforms are defined using the `uniforms` option and can either be explicit values or callbacks taking the frame state as argument.
53372 *   You can also change their value along the way like so:
53373 *   ```js
53374 *   helper.setUniformFloatValue('u_value', valueAsNumber);
53375 *   ```
53376 *
53377 * ### Defining post processing passes
53378 *
53379 *   *Post processing* describes the act of rendering primitives to a texture, and then rendering this texture to the final canvas
53380 *   while applying special effects in screen space.
53381 *   Typical uses are: blurring, color manipulation, depth of field, filtering...
53382 *
53383 *   The `WebGLHelper` class offers the possibility to define post processes at creation time using the `postProcesses` option.
53384 *   A post process step accepts the following options:
53385 *
53386 *   * `fragmentShader` and `vertexShader`: text literals in GLSL language that will be compiled and used in the post processing step.
53387 *   * `uniforms`: uniforms can be defined for the post processing steps just like for the main render.
53388 *   * `scaleRatio`: allows using an intermediate texture smaller or higher than the final canvas in the post processing step.
53389 *     This is typically used in blur steps to reduce the performance overhead by using an already downsampled texture as input.
53390 *
53391 *   The {@link module:ol/webgl/PostProcessingPass~WebGLPostProcessingPass} class is used internally, refer to its documentation for more info.
53392 *
53393 * ### Binding WebGL buffers and flushing data into them
53394 *
53395 *   Data that must be passed to the GPU has to be transferred using {@link module:ol/webgl/Buffer~WebGLArrayBuffer} objects.
53396 *   A buffer has to be created only once, but must be bound every time the buffer content will be used for rendering.
53397 *   This is done using {@link bindBuffer}.
53398 *   When the buffer's array content has changed, the new data has to be flushed to the GPU memory; this is done using
53399 *   {@link flushBufferData}. Note: this operation is expensive and should be done as infrequently as possible.
53400 *
53401 *   When binding an array buffer, a `target` parameter must be given: it should be either {@link module:ol/webgl.ARRAY_BUFFER}
53402 *   (if the buffer contains vertices data) or {@link module:ol/webgl.ELEMENT_ARRAY_BUFFER} (if the buffer contains indices data).
53403 *
53404 *   Examples below:
53405 *   ```js
53406 *   // at initialization phase
53407 *   const verticesBuffer = new WebGLArrayBuffer([], DYNAMIC_DRAW);
53408 *   const indicesBuffer = new WebGLArrayBuffer([], DYNAMIC_DRAW);
53409 *
53410 *   // when array values have changed
53411 *   helper.flushBufferData(ARRAY_BUFFER, this.verticesBuffer);
53412 *   helper.flushBufferData(ELEMENT_ARRAY_BUFFER, this.indicesBuffer);
53413 *
53414 *   // at rendering phase
53415 *   helper.bindBuffer(ARRAY_BUFFER, this.verticesBuffer);
53416 *   helper.bindBuffer(ELEMENT_ARRAY_BUFFER, this.indicesBuffer);
53417 *   ```
53418 *
53419 * ### Specifying attributes
53420 *
53421 *   The GPU only receives the data as arrays of numbers. These numbers must be handled differently depending on what it describes (position, texture coordinate...).
53422 *   Attributes are used to specify these uses. Specify the attribute names with
53423 *   {@link module:ol/webgl/Helper~WebGLHelper#enableAttributes} (see code snippet below).
53424 *
53425 *   Please note that you will have to specify the type and offset of the attributes in the data array. You can refer to the documentation of [WebGLRenderingContext.vertexAttribPointer](https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/vertexAttribPointer) for more explanation.
53426 *   ```js
53427 *   // here we indicate that the data array has the following structure:
53428 *   // [posX, posY, offsetX, offsetY, texCoordU, texCoordV, posX, posY, ...]
53429 *   helper.enableAttributes([
53430 *     {
53431 *        name: 'a_position',
53432 *        size: 2
53433 *     },
53434 *     {
53435 *       name: 'a_offset',
53436 *       size: 2
53437 *     },
53438 *     {
53439 *       name: 'a_texCoord',
53440 *       size: 2
53441 *     }
53442 *   ])
53443 *   ```
53444 *
53445 * ### Rendering primitives
53446 *
53447 *   Once all the steps above have been achieved, rendering primitives to the screen is done using {@link prepareDraw}, {@link drawElements} and {@link finalizeDraw}.
53448 *   ```js
53449 *   // frame preparation step
53450 *   helper.prepareDraw(frameState);
53451 *
53452 *   // call this for every data array that has to be rendered on screen
53453 *   helper.drawElements(0, this.indicesBuffer.getArray().length);
53454 *
53455 *   // finalize the rendering by applying post processes
53456 *   helper.finalizeDraw(frameState);
53457 *   ```
53458 *
53459 * For an example usage of this class, refer to {@link module:ol/renderer/webgl/PointsLayer~WebGLPointsLayerRenderer}.
53460 */
53461class WebGLHelper extends ol_Disposable {
53462  /**
53463   * @param {Options} [options] Options.
53464   */
53465  constructor(options) {
53466    super();
53467    options = options || {};
53468
53469    /** @private */
53470    this.boundHandleWebGLContextLost_ = this.handleWebGLContextLost.bind(this);
53471
53472    /** @private */
53473    this.boundHandleWebGLContextRestored_ =
53474      this.handleWebGLContextRestored.bind(this);
53475
53476    /**
53477     * @private
53478     * @type {string}
53479     */
53480    this.canvasCacheKey_ = options.canvasCacheKey
53481      ? getSharedCanvasCacheKey(options.canvasCacheKey)
53482      : getUniqueCanvasCacheKey();
53483
53484    /**
53485     * @private
53486     * @type {HTMLCanvasElement}
53487     */
53488    this.canvas_ = getCanvas(this.canvasCacheKey_);
53489
53490    /**
53491     * @private
53492     * @type {WebGLRenderingContext}
53493     */
53494    this.gl_ = getContext(this.canvas_);
53495
53496    /**
53497     * @private
53498     * @type {!Object<string, BufferCacheEntry>}
53499     */
53500    this.bufferCache_ = {};
53501
53502    /**
53503     * @private
53504     * @type {Object<string, Object>}
53505     */
53506    this.extensionCache_ = {};
53507
53508    /**
53509     * @private
53510     * @type {WebGLProgram}
53511     */
53512    this.currentProgram_ = null;
53513
53514    this.canvas_.addEventListener(
53515      ContextEventType.LOST,
53516      this.boundHandleWebGLContextLost_
53517    );
53518    this.canvas_.addEventListener(
53519      ContextEventType.RESTORED,
53520      this.boundHandleWebGLContextRestored_
53521    );
53522
53523    /**
53524     * @private
53525     * @type {import("../transform.js").Transform}
53526     */
53527    this.offsetRotateMatrix_ = create();
53528
53529    /**
53530     * @private
53531     * @type {import("../transform.js").Transform}
53532     */
53533    this.offsetScaleMatrix_ = create();
53534
53535    /**
53536     * @private
53537     * @type {Array<number>}
53538     */
53539    this.tmpMat4_ = mat4_create();
53540
53541    /**
53542     * @private
53543     * @type {Object<string, WebGLUniformLocation>}
53544     */
53545    this.uniformLocations_ = {};
53546
53547    /**
53548     * @private
53549     * @type {Object<string, number>}
53550     */
53551    this.attribLocations_ = {};
53552
53553    /**
53554     * Holds info about custom uniforms used in the post processing pass.
53555     * If the uniform is a texture, the WebGL Texture object will be stored here.
53556     * @type {Array<UniformInternalDescription>}
53557     * @private
53558     */
53559    this.uniforms_ = [];
53560    if (options.uniforms) {
53561      this.setUniforms(options.uniforms);
53562    }
53563
53564    const gl = this.getGL();
53565
53566    /**
53567     * An array of PostProcessingPass objects is kept in this variable, built from the steps provided in the
53568     * options. If no post process was given, a default one is used (so as not to have to make an exception to
53569     * the frame buffer logic).
53570     * @type {Array<WebGLPostProcessingPass>}
53571     * @private
53572     */
53573    this.postProcessPasses_ = options.postProcesses
53574      ? options.postProcesses.map(function (options) {
53575          return new PostProcessingPass({
53576            webGlContext: gl,
53577            scaleRatio: options.scaleRatio,
53578            vertexShader: options.vertexShader,
53579            fragmentShader: options.fragmentShader,
53580            uniforms: options.uniforms,
53581          });
53582        })
53583      : [new PostProcessingPass({webGlContext: gl})];
53584
53585    /**
53586     * @type {string|null}
53587     * @private
53588     */
53589    this.shaderCompileErrors_ = null;
53590
53591    /**
53592     * @type {number}
53593     * @private
53594     */
53595    this.startTime_ = Date.now();
53596  }
53597
53598  /**
53599   * @param {Object<string, UniformValue>} uniforms Uniform definitions.
53600   */
53601  setUniforms(uniforms) {
53602    this.uniforms_ = [];
53603    for (const name in uniforms) {
53604      this.uniforms_.push({
53605        name: name,
53606        value: uniforms[name],
53607      });
53608    }
53609    this.uniformLocations_ = {};
53610  }
53611
53612  /**
53613   * @param {string} canvasCacheKey The canvas cache key.
53614   * @return {boolean} The provided key matches the one this helper was constructed with.
53615   */
53616  canvasCacheKeyMatches(canvasCacheKey) {
53617    return this.canvasCacheKey_ === getSharedCanvasCacheKey(canvasCacheKey);
53618  }
53619
53620  /**
53621   * Get a WebGL extension.  If the extension is not supported, null is returned.
53622   * Extensions are cached after they are enabled for the first time.
53623   * @param {string} name The extension name.
53624   * @return {Object|null} The extension or null if not supported.
53625   */
53626  getExtension(name) {
53627    if (name in this.extensionCache_) {
53628      return this.extensionCache_[name];
53629    }
53630    const extension = this.gl_.getExtension(name);
53631    this.extensionCache_[name] = extension;
53632    return extension;
53633  }
53634
53635  /**
53636   * Just bind the buffer if it's in the cache. Otherwise create
53637   * the WebGL buffer, bind it, populate it, and add an entry to
53638   * the cache.
53639   * @param {import("./Buffer").default} buffer Buffer.
53640   */
53641  bindBuffer(buffer) {
53642    const gl = this.getGL();
53643    const bufferKey = getUid(buffer);
53644    let bufferCache = this.bufferCache_[bufferKey];
53645    if (!bufferCache) {
53646      const webGlBuffer = gl.createBuffer();
53647      bufferCache = {
53648        buffer: buffer,
53649        webGlBuffer: webGlBuffer,
53650      };
53651      this.bufferCache_[bufferKey] = bufferCache;
53652    }
53653    gl.bindBuffer(buffer.getType(), bufferCache.webGlBuffer);
53654  }
53655
53656  /**
53657   * Update the data contained in the buffer array; this is required for the
53658   * new data to be rendered
53659   * @param {import("./Buffer").default} buffer Buffer.
53660   */
53661  flushBufferData(buffer) {
53662    const gl = this.getGL();
53663    this.bindBuffer(buffer);
53664    gl.bufferData(buffer.getType(), buffer.getArray(), buffer.getUsage());
53665  }
53666
53667  /**
53668   * @param {import("./Buffer.js").default} buf Buffer.
53669   */
53670  deleteBuffer(buf) {
53671    const gl = this.getGL();
53672    const bufferKey = getUid(buf);
53673    const bufferCacheEntry = this.bufferCache_[bufferKey];
53674    if (bufferCacheEntry && !gl.isContextLost()) {
53675      gl.deleteBuffer(bufferCacheEntry.webGlBuffer);
53676    }
53677    delete this.bufferCache_[bufferKey];
53678  }
53679
53680  /**
53681   * Clean up.
53682   */
53683  disposeInternal() {
53684    this.canvas_.removeEventListener(
53685      ContextEventType.LOST,
53686      this.boundHandleWebGLContextLost_
53687    );
53688    this.canvas_.removeEventListener(
53689      ContextEventType.RESTORED,
53690      this.boundHandleWebGLContextRestored_
53691    );
53692
53693    Helper_releaseCanvas(this.canvasCacheKey_);
53694
53695    delete this.gl_;
53696    delete this.canvas_;
53697  }
53698
53699  /**
53700   * Clear the buffer & set the viewport to draw.
53701   * Post process passes will be initialized here, the first one being bound as a render target for
53702   * subsequent draw calls.
53703   * @param {import("../Map.js").FrameState} frameState current frame state
53704   * @param {boolean} [disableAlphaBlend] If true, no alpha blending will happen.
53705   */
53706  prepareDraw(frameState, disableAlphaBlend) {
53707    const gl = this.getGL();
53708    const canvas = this.getCanvas();
53709    const size = frameState.size;
53710    const pixelRatio = frameState.pixelRatio;
53711
53712    canvas.width = size[0] * pixelRatio;
53713    canvas.height = size[1] * pixelRatio;
53714    canvas.style.width = size[0] + 'px';
53715    canvas.style.height = size[1] + 'px';
53716
53717    // loop backwards in post processes list
53718    for (let i = this.postProcessPasses_.length - 1; i >= 0; i--) {
53719      this.postProcessPasses_[i].init(frameState);
53720    }
53721
53722    gl.bindTexture(gl.TEXTURE_2D, null);
53723
53724    gl.clearColor(0.0, 0.0, 0.0, 0.0);
53725    gl.clear(gl.COLOR_BUFFER_BIT);
53726
53727    gl.enable(gl.BLEND);
53728    gl.blendFunc(gl.ONE, disableAlphaBlend ? gl.ZERO : gl.ONE_MINUS_SRC_ALPHA);
53729  }
53730
53731  /**
53732   * Clear the render target & bind it for future draw operations.
53733   * This is similar to `prepareDraw`, only post processes will not be applied.
53734   * Note: the whole viewport will be drawn to the render target, regardless of its size.
53735   * @param {import("../Map.js").FrameState} frameState current frame state
53736   * @param {import("./RenderTarget.js").default} renderTarget Render target to draw to
53737   * @param {boolean} [disableAlphaBlend] If true, no alpha blending will happen.
53738   */
53739  prepareDrawToRenderTarget(frameState, renderTarget, disableAlphaBlend) {
53740    const gl = this.getGL();
53741    const size = renderTarget.getSize();
53742
53743    gl.bindFramebuffer(gl.FRAMEBUFFER, renderTarget.getFramebuffer());
53744    gl.viewport(0, 0, size[0], size[1]);
53745    gl.bindTexture(gl.TEXTURE_2D, renderTarget.getTexture());
53746    gl.clearColor(0.0, 0.0, 0.0, 0.0);
53747    gl.clear(gl.COLOR_BUFFER_BIT);
53748    gl.enable(gl.BLEND);
53749    gl.blendFunc(gl.ONE, disableAlphaBlend ? gl.ZERO : gl.ONE_MINUS_SRC_ALPHA);
53750  }
53751
53752  /**
53753   * Execute a draw call based on the currently bound program, texture, buffers, attributes.
53754   * @param {number} start Start index.
53755   * @param {number} end End index.
53756   */
53757  drawElements(start, end) {
53758    const gl = this.getGL();
53759    this.getExtension('OES_element_index_uint');
53760
53761    const elementType = gl.UNSIGNED_INT;
53762    const elementSize = 4;
53763
53764    const numItems = end - start;
53765    const offsetInBytes = start * elementSize;
53766    gl.drawElements(gl.TRIANGLES, numItems, elementType, offsetInBytes);
53767  }
53768
53769  /**
53770   * Apply the successive post process passes which will eventually render to the actual canvas.
53771   * @param {import("../Map.js").FrameState} frameState current frame state
53772   * @param {function(WebGLRenderingContext, import("../Map.js").FrameState):void} [preCompose] Called before composing.
53773   * @param {function(WebGLRenderingContext, import("../Map.js").FrameState):void} [postCompose] Called before composing.
53774   */
53775  finalizeDraw(frameState, preCompose, postCompose) {
53776    // apply post processes using the next one as target
53777    for (let i = 0, ii = this.postProcessPasses_.length; i < ii; i++) {
53778      if (i === ii - 1) {
53779        this.postProcessPasses_[i].apply(
53780          frameState,
53781          null,
53782          preCompose,
53783          postCompose
53784        );
53785      } else {
53786        this.postProcessPasses_[i].apply(
53787          frameState,
53788          this.postProcessPasses_[i + 1]
53789        );
53790      }
53791    }
53792  }
53793
53794  /**
53795   * @return {HTMLCanvasElement} Canvas.
53796   */
53797  getCanvas() {
53798    return this.canvas_;
53799  }
53800
53801  /**
53802   * Get the WebGL rendering context
53803   * @return {WebGLRenderingContext} The rendering context.
53804   */
53805  getGL() {
53806    return this.gl_;
53807  }
53808
53809  /**
53810   * Sets the default matrix uniforms for a given frame state. This is called 
53810internally in `prepareDraw`.
53811   * @param {import("../Map.js").FrameState} frameState Frame state.
53812   */
53813  applyFrameState(frameState) {
53814    const size = frameState.size;
53815    const rotation = frameState.viewState.rotation;
53816    const pixelRatio = frameState.pixelRatio;
53817
53818    const offsetScaleMatrix = transform_reset(this.offsetScaleMatrix_);
53819    transform_scale(offsetScaleMatrix, 2 / size[0], 2 / size[1]);
53820
53821    const offsetRotateMatrix = transform_reset(this.offsetRotateMatrix_);
53822    if (rotation !== 0) {
53823      transform_rotate(offsetRotateMatrix, -rotation);
53824    }
53825
53826    this.setUniformMatrixValue(
53827      DefaultUniform.OFFSET_SCALE_MATRIX,
53828      fromTransform(this.tmpMat4_, offsetScaleMatrix)
53829    );
53830    this.setUniformMatrixValue(
53831      DefaultUniform.OFFSET_ROTATION_MATRIX,
53832      fromTransform(this.tmpMat4_, offsetRotateMatrix)
53833    );
53834
53835    this.setUniformFloatValue(
53836      DefaultUniform.TIME,
53837      (Date.now() - this.startTime_) * 0.001
53838    );
53839    this.setUniformFloatValue(DefaultUniform.ZOOM, frameState.viewState.zoom);
53840    this.setUniformFloatValue(
53841      DefaultUniform.RESOLUTION,
53842      frameState.viewState.resolution
53843    );
53844    this.setUniformFloatValue(DefaultUniform.PIXEL_RATIO, pixelRatio);
53845    this.setUniformFloatVec2(DefaultUniform.SIZE_PX, [size[0], size[1]]);
53846  }
53847
53848  /**
53849   * Sets the custom uniforms based on what was given in the constructor. This is called internally in `prepareDraw`.
53850   * @param {import("../Map.js").FrameState} frameState Frame state.
53851   */
53852  applyUniforms(frameState) {
53853    const gl = this.getGL();
53854
53855    let value;
53856    let textureSlot = 0;
53857    this.uniforms_.forEach(
53858      function (uniform) {
53859        value =
53860          typeof uniform.value === 'function'
53861            ? uniform.value(frameState)
53862            : uniform.value;
53863
53864        // apply value based on type
53865        if (
53866          value instanceof HTMLCanvasElement ||
53867          value instanceof HTMLImageElement ||
53868          value instanceof ImageData
53869        ) {
53870          // create a texture & put data
53871          if (!uniform.texture) {
53872            uniform.prevValue = undefined;
53873            uniform.texture = gl.createTexture();
53874          }
53875          gl.activeTexture(gl[`TEXTURE${textureSlot}`]);
53876          gl.bindTexture(gl.TEXTURE_2D, uniform.texture);
53877          gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
53878          gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
53879          gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
53880
53881          const imageReady =
53882            !(value instanceof HTMLImageElement) ||
53883            /** @type {HTMLImageElement} */ (value).complete;
53884          if (imageReady && uniform.prevValue !== value) {
53885            uniform.prevValue = value;
53886            gl.texImage2D(
53887              gl.TEXTURE_2D,
53888              0,
53889              gl.RGBA,
53890              gl.RGBA,
53891              gl.UNSIGNED_BYTE,
53892              value
53893            );
53894          }
53895
53896          // fill texture slots by increasing index
53897          gl.uniform1i(this.getUniformLocation(uniform.name), textureSlot++);
53898        } else if (Array.isArray(value) && value.length === 6) {
53899          this.setUniformMatrixValue(
53900            uniform.name,
53901            fromTransform(this.tmpMat4_, value)
53902          );
53903        } else if (Array.isArray(value) && value.length <= 4) {
53904          switch (value.length) {
53905            case 2:
53906              gl.uniform2f(
53907                this.getUniformLocation(uniform.name),
53908                value[0],
53909                value[1]
53910              );
53911              return;
53912            case 3:
53913              gl.uniform3f(
53914                this.getUniformLocation(uniform.name),
53915                value[0],
53916                value[1],
53917                value[2]
53918              );
53919              return;
53920            case 4:
53921              gl.uniform4f(
53922                this.getUniformLocation(uniform.name),
53923                value[0],
53924                value[1],
53925                value[2],
53926                value[3]
53927              );
53928              return;
53929            default:
53930              return;
53931          }
53932        } else if (typeof value === 'number') {
53933          gl.uniform1f(this.getUniformLocation(uniform.name), value);
53934        }
53935      }.bind(this)
53936    );
53937  }
53938
53939  /**
53940   * Set up a program for use. The program will be set as the current one. Then, the uniforms used
53941   * in the program will be set based on the current frame state and the helper configuration.
53942   * @param {WebGLProgram} program Program.
53943   * @param {import("../Map.js").FrameState} frameState Frame state.
53944   */
53945  useProgram(program, frameState) {
53946    const gl = this.getGL();
53947    gl.useProgram(program);
53948    this.currentProgram_ = program;
53949    this.uniformLocations_ = {};
53950    this.attribLocations_ = {};
53951    this.applyFrameState(frameState);
53952    this.applyUniforms(frameState);
53953  }
53954
53955  /**
53956   * Will attempt to compile a vertex or fragment shader based on source
53957   * On error, the shader will be returned but
53958   * `gl.getShaderParameter(shader, gl.COMPILE_STATUS)` will return `true`
53959   * Use `gl.getShaderInfoLog(shader)` to have details
53960   * @param {string} source Shader source
53961   * @param {ShaderType} type VERTEX_SHADER or FRAGMENT_SHADER
53962   * @return {WebGLShader} Shader object
53963   */
53964  compileShader(source, type) {
53965    const gl = this.getGL();
53966    const shader = gl.createShader(type);
53967    gl.shaderSource(shader, source);
53968    gl.compileShader(shader);
53969    return shader;
53970  }
53971
53972  /**
53973   * Create a program for a vertex and fragment shader.  Throws if shader compilation fails.
53974   * @param {string} fragmentShaderSource Fragment shader source.
53975   * @param {string} vertexShaderSource Vertex shader source.
53976   * @return {WebGLProgram} Program
53977   */
53978  getProgram(fragmentShaderSource, vertexShaderSource) {
53979    const gl = this.getGL();
53980
53981    const fragmentShader = this.compileShader(
53982      fragmentShaderSource,
53983      gl.FRAGMENT_SHADER
53984    );
53985
53986    const vertexShader = this.compileShader(
53987      vertexShaderSource,
53988      gl.VERTEX_SHADER
53989    );
53990
53991    const program = gl.createProgram();
53992    gl.attachShader(program, fragmentShader);
53993    gl.attachShader(program, vertexShader);
53994    gl.linkProgram(program);
53995
53996    if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {
53997      const message = `Fragment shader compliation failed: ${gl.getShaderInfoLog(
53998        fragmentShader
53999      )}`;
54000      throw new Error(message);
54001    }
54002    gl.deleteShader(fragmentShader);
54003
54004    if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {
54005      const message = `Vertex shader compilation failed: ${gl.getShaderInfoLog(
54006        vertexShader
54007      )}`;
54008      throw new Error(message);
54009    }
54010    gl.deleteShader(vertexShader);
54011
54012    if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
54013      const message = `GL program linking failed: ${gl.getShaderInfoLog(
54014        vertexShader
54015      )}`;
54016      throw new Error(message);
54017    }
54018
54019    return program;
54020  }
54021
54022  /**
54023   * Will get the location from the shader or the cache
54024   * @param {string} name Uniform name
54025   * @return {WebGLUniformLocation} uniformLocation
54026   */
54027  getUniformLocation(name) {
54028    if (this.uniformLocations_[name] === undefined) {
54029      this.uniformLocations_[name] = this.getGL().getUniformLocation(
54030        this.currentProgram_,
54031        name
54032      );
54033    }
54034    return this.uniformLocations_[name];
54035  }
54036
54037  /**
54038   * Will get the location from the shader or the cache
54039   * @param {string} name Attribute name
54040   * @return {number} attribLocation
54041   */
54042  getAttributeLocation(name) {
54043    if (this.attribLocations_[name] === undefined) {
54044      this.attribLocations_[name] = this.getGL().getAttribLocation(
54045        this.currentProgram_,
54046        name
54047      );
54048    }
54049    return this.attribLocations_[name];
54050  }
54051
54052  /**
54053   * Modifies the given transform to apply the rotation/translation/scaling of the given frame state.
54054   * The resulting transform can be used to convert world space coordinates to view coordinates.
54055   * @param {import("../Map.js").FrameState} frameState Frame state.
54056   * @param {import("../transform").Transform} transform Transform to update.
54057   * @return {import("../transform").Transform} The updated transform object.
54058   */
54059  makeProjectionTransform(frameState, transform) {
54060    const size = frameState.size;
54061    const rotation = frameState.viewState.rotation;
54062    const resolution = frameState.viewState.resolution;
54063    const center = frameState.viewState.center;
54064
54065    transform_reset(transform);
54066    compose(
54067      transform,
54068      0,
54069      0,
54070      2 / (resolution * size[0]),
54071      2 / (resolution * size[1]),
54072      -rotation,
54073      -center[0],
54074      -center[1]
54075    );
54076    return transform;
54077  }
54078
54079  /**
54080   * Give a value for a standard float uniform
54081   * @param {string} uniform Uniform name
54082   * @param {number} value Value
54083   */
54084  setUniformFloatValue(uniform, value) {
54085    this.getGL().uniform1f(this.getUniformLocation(uniform), value);
54086  }
54087
54088  /**
54089   * Give a value for a vec2 uniform
54090   * @param {string} uniform Uniform name
54091   * @param {Array<number>} value Array of length 4.
54092   */
54093  setUniformFloatVec2(uniform, value) {
54094    this.getGL().uniform2fv(this.getUniformLocation(uniform), value);
54095  }
54096
54097  /**
54098   * Give a value for a vec4 uniform
54099   * @param {string} uniform Uniform name
54100   * @param {Array<number>} value Array of length 4.
54101   */
54102  setUniformFloatVec4(uniform, value) {
54103    this.getGL().uniform4fv(this.getUniformLocation(uniform), value);
54104  }
54105
54106  /**
54107   * Give a value for a standard matrix4 uniform
54108   * @param {string} uniform Uniform name
54109   * @param {Array<number>} value Matrix value
54110   */
54111  setUniformMatrixValue(uniform, value) {
54112    this.getGL().uniformMatrix4fv(
54113      this.getUniformLocation(uniform),
54114      false,
54115      value
54116    );
54117  }
54118
54119  /**
54120   * Will set the currently bound buffer to an attribute of the shader program. Used by `#enableAttributes`
54121   * internally.
54122   * @param {string} attribName Attribute name
54123   * @param {number} size Number of components per attributes
54124   * @param {number} type UNSIGNED_INT, UNSIGNED_BYTE, UNSIGNED_SHORT or FLOAT
54125   * @param {number} stride Stride in bytes (0 means attribs are packed)
54126   * @param {number} offset Offset in bytes
54127   * @private
54128   */
54129  enableAttributeArray_(attribName, size, type, stride, offset) {
54130    const location = this.getAttributeLocation(attribName);
54131    // the attribute has not been found in the shaders; do not enable it
54132    if (location < 0) {
54133      return;
54134    }
54135    this.getGL().enableVertexAttribArray(location);
54136    this.getGL().vertexAttribPointer(
54137      location,
54138      size,
54139      type,
54140      false,
54141      stride,
54142      offset
54143    );
54144  }
54145
54146  /**
54147   * Will enable the following attributes to be read from the currently bound buffer,
54148   * i.e. tell the GPU where to read the different attributes in the buffer. An error in the
54149   * size/type/order of attributes will most likely break the rendering and throw a WebGL exception.
54150   * @param {Array<AttributeDescription>} attributes Ordered list of attributes to read from the buffer
54151   */
54152  enableAttributes(attributes) {
54153    const stride = computeAttributesStride(attributes);
54154    let offset = 0;
54155    for (let i = 0; i < attributes.length; i++) {
54156      const attr = attributes[i];
54157      this.enableAttributeArray_(
54158        attr.name,
54159        attr.size,
54160        attr.type || FLOAT,
54161        stride,
54162        offset
54163      );
54164      offset += attr.size * getByteSizeFromType(attr.type);
54165    }
54166  }
54167
54168  /**
54169   * WebGL context was lost
54170   * @private
54171   */
54172  handleWebGLContextLost() {
54173    clear(this.bufferCache_);
54174    this.currentProgram_ = null;
54175  }
54176
54177  /**
54178   * WebGL context was restored
54179   * @private
54180   */
54181  handleWebGLContextRestored() {}
54182
54183  /**
54184   * Will create or reuse a given webgl texture and apply the given size. If no image data
54185   * specified, the texture will be empty, otherwise image data will be used and the `size`
54186   * parameter will be ignored.
54187   * Note: wrap parameters are set to clamp to edge, min filter is set to linear.
54188   * @param {Array<number>} size Expected size of the texture
54189   * @param {ImageData|HTMLImageElement|HTMLCanvasElement} [data] Image data/object to bind to the texture
54190   * @param {WebGLTexture} [texture] Existing texture to reuse
54191   * @return {WebGLTexture} The generated texture
54192   */
54193  createTexture(size, data, texture) {
54194    const gl = this.getGL();
54195    texture = texture || gl.createTexture();
54196
54197    // set params & size
54198    const level = 0;
54199    const internalFormat = gl.RGBA;
54200    const border = 0;
54201    const format = gl.RGBA;
54202    const type = gl.UNSIGNED_BYTE;
54203    gl.bindTexture(gl.TEXTURE_2D, texture);
54204    if (data) {
54205      gl.texImage2D(gl.TEXTURE_2D, level, internalFormat, format, type, data);
54206    } else {
54207      gl.texImage2D(
54208        gl.TEXTURE_2D,
54209        level,
54210        internalFormat,
54211        size[0],
54212        size[1],
54213        border,
54214        format,
54215        type,
54216        null
54217      );
54218    }
54219    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
54220    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
54221    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
54222
54223    return texture;
54224  }
54225}
54226
54227/**
54228 * Compute a stride in bytes based on a list of attributes
54229 * @param {Array<AttributeDescription>} attributes Ordered list of attributes
54230 * @return {number} Stride, ie amount of values for each vertex in the vertex buffer
54231 */
54232function computeAttributesStride(attributes) {
54233  let stride = 0;
54234  for (let i = 0; i < attributes.length; i++) {
54235    const attr = attributes[i];
54236    stride += attr.size * getByteSizeFromType(attr.type);
54237  }
54238  return stride;
54239}
54240
54241/**
54242 * Computes the size in byte of an attribute type.
54243 * @param {AttributeType} type Attribute type
54244 * @return {number} The size in bytes
54245 */
54246function getByteSizeFromType(type) {
54247  switch (type) {
54248    case AttributeType.UNSIGNED_BYTE:
54249      return Uint8Array.BYTES_PER_ELEMENT;
54250    case AttributeType.UNSIGNED_SHORT:
54251      return Uint16Array.BYTES_PER_ELEMENT;
54252    case AttributeType.UNSIGNED_INT:
54253      return Uint32Array.BYTES_PER_ELEMENT;
54254    case AttributeType.FLOAT:
54255    default:
54256      return Float32Array.BYTES_PER_ELEMENT;
54257  }
54258}
54259
54260/* harmony default export */ const Helper = (WebGLHelper);
54261
54262;// CONCATENATED MODULE: ./node_modules/ol/renderer/webgl/Layer.js
54263/**
54264 * @module ol/renderer/webgl/Layer
54265 */
54266
54267
54268
54269
54270
54271
54272
54273/**
54274 * @typedef {Object} PostProcessesOptions
54275 * @property {number} [scaleRatio] Scale ratio; if < 1, the post process will render to a texture smaller than
54276 * the main canvas that will then be sampled up (useful for saving resource on blur steps).
54277 * @property {string} [vertexShader] Vertex shader source
54278 * @property {string} [fragmentShader] Fragment shader source
54279 * @property {Object<string,import("../../webgl/Helper").UniformValue>} [uniforms] Uniform definitions for the post process step
54280 */
54281
54282/**
54283 * @typedef {Object} Options
54284 * @property {Object<string,import("../../webgl/Helper").UniformValue>} [uniforms] Uniform definitions for the post process steps
54285 * @property {Array<PostProcessesOptions>} [postProcesses] Post-processes definitions
54286 */
54287
54288/**
54289 * @classdesc
54290 * Base WebGL renderer class.
54291 * Holds all logic related to data manipulation & some common rendering logic
54292 * @template {import("../../layer/Layer.js").default} LayerType
54293 * @extends {LayerRenderer<LayerType>}
54294 */
54295class WebGLLayerRenderer extends renderer_Layer {
54296  /**
54297   * @param {LayerType} layer Layer.
54298   * @param {Options} [options] Options.
54299   */
54300  constructor(layer, options) {
54301    super(layer);
54302
54303    options = options || {};
54304
54305    /**
54306     * The transform for viewport CSS pixels to rendered pixels.  This transform is only
54307     * set before dispatching rendering events.
54308     * @private
54309     * @type {import("../../transform.js").Transform}
54310     */
54311    this.inversePixelTransform_ = create();
54312
54313    /**
54314     * @private
54315     * @type {CanvasRenderingContext2D}
54316     */
54317    this.pixelContext_ = null;
54318
54319    /**
54320     * @private
54321     */
54322    this.postProcesses_ = options.postProcesses;
54323
54324    /**
54325     * @private
54326     */
54327    this.uniforms_ = options.uniforms;
54328
54329    /**
54330     * @type {WebGLHelper}
54331     * @protected
54332     */
54333    this.helper;
54334
54335    layer.addChangeListener(layer_Property.MAP, this.removeHelper.bind(this));
54336
54337    this.dispatchPreComposeEvent = this.dispatchPreComposeEvent.bind(this);
54338    this.dispatchPostComposeEvent = this.dispatchPostComposeEvent.bind(this);
54339  }
54340
54341  /**
54342   * @param {WebGLRenderingContext} context The WebGL rendering context.
54343   * @param {import("../../Map.js").FrameState} frameState Frame state.
54344   * @protected
54345   */
54346  dispatchPreComposeEvent(context, frameState) {
54347    const layer = this.getLayer();
54348    if (layer.hasListener(render_EventType.PRECOMPOSE)) {
54349      const event = new render_Event(
54350        render_EventType.PRECOMPOSE,
54351        undefined,
54352        frameState,
54353        context
54354      );
54355      layer.dispatchEvent(event);
54356    }
54357  }
54358
54359  /**
54360   * @param {WebGLRenderingContext} context The WebGL rendering context.
54361   * @param {import("../../Map.js").FrameState} frameState Frame state.
54362   * @protected
54363   */
54364  dispatchPostComposeEvent(context, frameState) {
54365    const layer = this.getLayer();
54366    if (layer.hasListener(render_EventType.POSTCOMPOSE)) {
54367      const event = new render_Event(
54368        render_EventType.POSTCOMPOSE,
54369        undefined,
54370        frameState,
54371        context
54372      );
54373      layer.dispatchEvent(event);
54374    }
54375  }
54376
54377  /**
54378   * Reset options (only handles uniforms).
54379   * @param {Options} options Options.
54380   */
54381  reset(options) {
54382    this.uniforms_ = options.uniforms;
54383    if (this.helper) {
54384      this.helper.setUniforms(this.uniforms_);
54385    }
54386  }
54387
54388  /**
54389   * @protected
54390   */
54391  removeHelper() {
54392    if (this.helper) {
54393      this.helper.dispose();
54394      delete this.helper;
54395    }
54396  }
54397
54398  /**
54399   * Determine whether renderFrame should be called.
54400   * @param {import("../../Map.js").FrameState} frameState Frame state.
54401   * @return {boolean} Layer is ready to be rendered.
54402   */
54403  prepareFrame(frameState) {
54404    if (this.getLayer().getRenderSource()) {
54405      let incrementGroup = true;
54406      let groupNumber = -1;
54407      let className;
54408      for (let i = 0, ii = frameState.layerStatesArray.length; i < ii; i++) {
54409        const layer = frameState.layerStatesArray[i].layer;
54410        const renderer = layer.getRenderer();
54411        if (!(renderer instanceof WebGLLayerRenderer)) {
54412          incrementGroup = true;
54413          continue;
54414        }
54415        const layerClassName = layer.getClassName();
54416        if (incrementGroup || layerClassName !== className) {
54417          groupNumber += 1;
54418          incrementGroup = false;
54419        }
54420        className = layerClassName;
54421        if (renderer === this) {
54422          break;
54423        }
54424      }
54425
54426      const canvasCacheKey =
54427        'map/' + frameState.mapId + '/group/' + groupNumber;
54428
54429      if (!this.helper || !this.helper.canvasCacheKeyMatches(canvasCacheKey)) {
54430        this.removeHelper();
54431
54432        this.helper = new Helper({
54433          postProcesses: this.postProcesses_,
54434          uniforms: this.uniforms_,
54435          canvasCacheKey: canvasCacheKey,
54436        });
54437
54438        if (className) {
54439          this.helper.getCanvas().className = className;
54440        }
54441
54442        this.afterHelperCreated();
54443      }
54444    }
54445
54446    return this.prepareFrameInternal(frameState);
54447  }
54448
54449  /**
54450   * @protected
54451   */
54452  afterHelperCreated() {}
54453
54454  /**
54455   * Determine whether renderFrame should be called.
54456   * @param {import("../../Map.js").FrameState} frameState Frame state.
54457   * @return {boolean} Layer is ready to be rendered.
54458   * @protected
54459   */
54460  prepareFrameInternal(frameState) {
54461    return true;
54462  }
54463
54464  /**
54465   * Clean up.
54466   */
54467  disposeInternal() {
54468    this.removeHelper();
54469    super.disposeInternal();
54470  }
54471
54472  /**
54473   * @param {import("../../render/EventType.js").default} type Event type.
54474   * @param {WebGLRenderingContext} context The rendering context.
54475   * @param {import("../../Map.js").FrameState} frameState Frame state.
54476   * @private
54477   */
54478  dispatchRenderEvent_(type, context, frameState) {
54479    const layer = this.getLayer();
54480    if (layer.hasListener(type)) {
54481      compose(
54482        this.inversePixelTransform_,
54483        0,
54484        0,
54485        frameState.pixelRatio,
54486        -frameState.pixelRatio,
54487        0,
54488        0,
54489        -frameState.size[1]
54490      );
54491
54492      const event = new render_Event(
54493        type,
54494        this.inversePixelTransform_,
54495        frameState,
54496        context
54497      );
54498      layer.dispatchEvent(event);
54499    }
54500  }
54501
54502  /**
54503   * @param {WebGLRenderingContext} context The rendering context.
54504   * @param {import("../../Map.js").FrameState} frameState Frame state.
54505   * @protected
54506   */
54507  preRender(context, frameState) {
54508    this.dispatchRenderEvent_(render_EventType.PRERENDER, context, frameState);
54509  }
54510
54511  /**
54512   * @param {WebGLRenderingContext} context The rendering context.
54513   * @param {import("../../Map.js").FrameState} frameState Frame state.
54514   * @protected
54515   */
54516  postRender(context, frameState) {
54517    this.dispatchRenderEvent_(render_EventType.POSTRENDER, context, frameState);
54518  }
54519}
54520
54521/* harmony default export */ const webgl_Layer = (WebGLLayerRenderer);
54522
54523;// CONCATENATED MODULE: ./node_modules/ol/renderer/webgl/TileLayer.js
54524/**
54525 * @module ol/renderer/webgl/TileLayer
54526 */
54527
54528
54529
54530
54531
54532
54533
54534
54535
54536
54537
54538
54539
54540
54541
54542
54543
54544const Uniforms = {
54545  TILE_TEXTURE_ARRAY: 'u_tileTextures',
54546  TILE_TRANSFORM: 'u_tileTransform',
54547  TRANSITION_ALPHA: 'u_transitionAlpha',
54548  DEPTH: 'u_depth',
54549  TEXTURE_PIXEL_WIDTH: 'u_texturePixelWidth',
54550  TEXTURE_PIXEL_HEIGHT: 'u_texturePixelHeight',
54551  TEXTURE_RESOLUTION: 'u_textureResolution', // map units per texture pixel
54552  TEXTURE_ORIGIN_X: 'u_textureOriginX', // map x coordinate of left edge of texture
54553  TEXTURE_ORIGIN_Y: 'u_textureOriginY', // map y coordinate of top edge of texture
54554  RENDER_EXTENT: 'u_renderExtent', // intersection of layer, source, and view extent
54555  RESOLUTION: 'u_resolution',
54556  ZOOM: 'u_zoom',
54557};
54558
54559const Attributes = {
54560  TEXTURE_COORD: 'a_textureCoord',
54561};
54562
54563/**
54564 * @type {Array<import('../../webgl/Helper.js').AttributeDescription>}
54565 */
54566const attributeDescriptions = [
54567  {
54568    name: Attributes.TEXTURE_COORD,
54569    size: 2,
54570    type: AttributeType.FLOAT,
54571  },
54572];
54573
54574/**
54575 * @type {Object<string, boolean>}
54576 */
54577const empty = {};
54578
54579/**
54580 * Transform a zoom level into a depth value ranging from -1 to 1.
54581 * @param {number} z A zoom level.
54582 * @return {number} A depth value.
54583 */
54584function depthForZ(z) {
54585  return 2 * (1 - 1 / (z + 1)) - 1;
54586}
54587
54588/**
54589 * Add a tile texture to the lookup.
54590 * @param {Object<number, Array<import("../../webgl/TileTexture.js").default>>} tileTexturesByZ Lookup of
54591 * tile textures by zoom level.
54592 * @param {import("../../webgl/TileTexture.js").default} tileTexture A tile texture.
54593 * @param {number} z The zoom level.
54594 */
54595function addTileTextureToLookup(tileTexturesByZ, tileTexture, z) {
54596  if (!(z in tileTexturesByZ)) {
54597    tileTexturesByZ[z] = [];
54598  }
54599  tileTexturesByZ[z].push(tileTexture);
54600}
54601
54602/**
54603 * @param {import("../../Map.js").FrameState} frameState Frame state.
54604 * @param {import("../../extent.js").Extent} extent The frame extent.
54605 * @return {import("../../extent.js").Extent} Frame extent intersected with layer extents.
54606 */
54607function getRenderExtent(frameState, extent) {
54608  const layerState = frameState.layerStatesArray[frameState.layerIndex];
54609  if (layerState.extent) {
54610    extent = getIntersection(
54611      extent,
54612      proj_fromUserExtent(layerState.extent, frameState.viewState.projection)
54613    );
54614  }
54615  const source = /** @type {import("../../source/Tile.js").default} */ (
54616    layerState.layer.getRenderSource()
54617  );
54618  if (!source.getWrapX()) {
54619    const gridExtent = source
54620      .getTileGridForProjection(frameState.viewState.projection)
54621      .getExtent();
54622    if (gridExtent) {
54623      extent = getIntersection(extent, gridExtent);
54624    }
54625  }
54626  return extent;
54627}
54628
54629function getCacheKey(source, tileCoord) {
54630  return `${source.getKey()},${tilecoord_getKey(tileCoord)}`;
54631}
54632
54633/**
54634 * @typedef {Object} Options
54635 * @property {string} vertexShader Vertex shader source.
54636 * @property {string} fragmentShader Fragment shader source.
54637 * @property {Object<string, import("../../webgl/Helper").UniformValue>} [uniforms] Additional uniforms
54638 * made available to shaders.
54639 * @property {Array<import("../../webgl/PaletteTexture.js").default>} [paletteTextures] Palette textures.
54640 * @property {number} [cacheSize=512] The texture cache size.
54641 */
54642
54643/**
54644 * @typedef {import("../../layer/WebGLTile.js").default} LayerType
54645 */
54646
54647/**
54648 * @classdesc
54649 * WebGL renderer for tile layers.
54650 * @extends {WebGLLayerRenderer<LayerType>}
54651 * @api
54652 */
54653class WebGLTileLayerRenderer extends webgl_Layer {
54654  /**
54655   * @param {LayerType} tileLayer Tile layer.
54656   * @param {Options} options Options.
54657   */
54658  constructor(tileLayer, options) {
54659    super(tileLayer, {
54660      uniforms: options.uniforms,
54661    });
54662
54663    /**
54664     * The last call to `renderFrame` was completed with all tiles loaded
54665     * @type {boolean}
54666     */
54667    this.renderComplete = false;
54668
54669    /**
54670     * This transform converts texture coordinates to screen coordinates.
54671     * @type {import("../../transform.js").Transform}
54672     * @private
54673     */
54674    this.tileTransform_ = create();
54675
54676    /**
54677     * @type {Array<number>}
54678     * @private
54679     */
54680    this.tempMat4_ = mat4_create();
54681
54682    /**
54683     * @type {import("../../TileRange.js").default}
54684     * @private
54685     */
54686    this.tempTileRange_ = new ol_TileRange(0, 0, 0, 0);
54687
54688    /**
54689     * @type {import("../../tilecoord.js").TileCoord}
54690     * @private
54691     */
54692    this.tempTileCoord_ = tilecoord_createOrUpdate(0, 0, 0);
54693
54694    /**
54695     * @type {import("../../size.js").Size}
54696     * @private
54697     */
54698    this.tempSize_ = [0, 0];
54699
54700    /**
54701     * @type {WebGLProgram}
54702     * @private
54703     */
54704    this.program_;
54705
54706    /**
54707     * @private
54708     */
54709    this.vertexShader_ = options.vertexShader;
54710
54711    /**
54712     * @private
54713     */
54714    this.fragmentShader_ = options.fragmentShader;
54715
54716    /**
54717     * Tiles are rendered as a quad with the following structure:
54718     *
54719     *  [P3]---------[P2]
54720     *   |`           |
54721     *   |  `     B   |
54722     *   |    `       |
54723     *   |      `     |
54724     *   |   A    `   |
54725     *   |          ` |
54726     *  [P0]---------[P1]
54727     *
54728     * Triangle A: P0, P1, P3
54729     * Triangle B: P1, P2, P3
54730     *
54731     * @private
54732     */
54733    this.indices_ = new Buffer(ELEMENT_ARRAY_BUFFER, STATIC_DRAW);
54734    this.indices_.fromArray([0, 1, 3, 1, 2, 3]);
54735
54736    const cacheSize = options.cacheSize !== undefined ? options.cacheSize : 512;
54737
54738    /**
54739     * @type {import("../../structs/LRUCache.js").default<import("../../webgl/TileTexture.js").default>}
54740     * @private
54741     */
54742    this.tileTextureCache_ = new structs_LRUCache(cacheSize);
54743
54744    /**
54745     * @type {Array<import("../../webgl/PaletteTexture.js").default>}
54746     * @private
54747     */
54748    this.paletteTextures_ = options.paletteTextures || [];
54749
54750    /**
54751     * @private
54752     * @type {import("../../Map.js").FrameState|null}
54753     */
54754    this.frameState_ = null;
54755  }
54756
54757  /**
54758   * @param {Options} options Options.
54759   */
54760  reset(options) {
54761    super.reset({
54762      uniforms: options.uniforms,
54763    });
54764    this.vertexShader_ = options.vertexShader;
54765    this.fragmentShader_ = options.fragmentShader;
54766    this.paletteTextures_ = options.paletteTextures || [];
54767
54768    if (this.helper) {
54769      this.program_ = this.helper.getProgram(
54770        this.fragmentShader_,
54771        this.vertexShader_
54772      );
54773    }
54774  }
54775
54776  afterHelperCreated() {
54777    this.program_ = this.helper.getProgram(
54778      this.fragmentShader_,
54779      this.vertexShader_
54780    );
54781
54782    this.helper.flushBufferData(this.indices_);
54783  }
54784
54785  /**
54786   * @param {import("../../webgl/TileTexture").TileType} tile Tile.
54787   * @return {boolean} Tile is drawable.
54788   * @private
54789   */
54790  isDrawableTile_(tile) {
54791    const tileLayer = this.getLayer();
54792    const tileState = tile.getState();
54793    const useInterimTilesOnError = tileLayer.getUseInterimTilesOnError();
54794    return (
54795      tileState == TileState.LOADED ||
54796      tileState == TileState.EMPTY ||
54797      (tileState == TileState.ERROR && !useInterimTilesOnError)
54798    );
54799  }
54800
54801  /**
54802   * Determine whether renderFrame should be called.
54803   * @param {import("../../Map.js").FrameState} frameState Frame state.
54804   * @return {boolean} Layer is ready to be rendered.
54805   */
54806  prepareFrameInternal(frameState) {
54807    const layer = this.getLayer();
54808    const source = layer.getRenderSource();
54809    if (!source) {
54810      return false;
54811    }
54812
54813    if (extent_isEmpty(getRenderExtent(frameState, frameState.extent))) {
54814      return false;
54815    }
54816    return source.getState() === 'ready';
54817  }
54818
54819  /**
54820   * @param {import("../../Map.js").FrameState} frameState Frame state.
54821   * @param {import("../../extent.js").Extent} extent The extent to be rendered.
54822   * @param {number} initialZ The zoom level.
54823   * @param {Object<number, Array<TileTexture>>} tileTexturesByZ The zoom level.
54824   */
54825  enqueueTiles(frameState, extent, initialZ, tileTexturesByZ) {
54826    const viewState = frameState.viewState;
54827    const tileLayer = this.getLayer();
54828    const tileSource = tileLayer.getRenderSource();
54829    const tileGrid = tileSource.getTileGridForProjection(viewState.projection);
54830    const gutter = tileSource.getGutterForProjection(viewState.projection);
54831
54832    const tileSourceKey = getUid(tileSource);
54833    if (!(tileSourceKey in frameState.wantedTiles)) {
54834      frameState.wantedTiles[tileSourceKey] = {};
54835    }
54836
54837    const wantedTiles = frameState.wantedTiles[tileSourceKey];
54838
54839    const tileTextureCache = this.tileTextureCache_;
54840    const minZ = Math.max(
54841      initialZ - tileLayer.getPreload(),
54842      tileGrid.getMinZoom(),
54843      tileLayer.getMinZoom()
54844    );
54845    for (let z = initialZ; z >= minZ; --z) {
54846      const tileRange = tileGrid.getTileRangeForExtentAndZ(
54847        extent,
54848        z,
54849        this.tempTileRange_
54850      );
54851
54852      const tileResolution = tileGrid.getResolution(z);
54853
54854      for (let x = tileRange.minX; x <= tileRange.maxX; ++x) {
54855        for (let y = tileRange.minY; y <= tileRange.maxY; ++y) {
54856          const tileCoord = tilecoord_createOrUpdate(z, x, y, this.tempTileCoord_);
54857          const cacheKey = getCacheKey(tileSource, tileCoord);
54858
54859          /** @type {TileTexture} */
54860          let tileTexture;
54861
54862          /** @type {import("../../webgl/TileTexture").TileType} */
54863          let tile;
54864
54865          if (tileTextureCache.containsKey(cacheKey)) {
54866            tileTexture = tileTextureCache.get(cacheKey);
54867            tile = tileTexture.tile;
54868          }
54869          if (!tileTexture || tileTexture.tile.key !== tileSource.getKey()) {
54870            tile = tileSource.getTile(
54871              z,
54872              x,
54873              y,
54874              frameState.pixelRatio,
54875              viewState.projection
54876            );
54877            if (!tileTexture) {
54878              tileTexture = new webgl_TileTexture({
54879                tile: tile,
54880                grid: tileGrid,
54881                helper: this.helper,
54882                gutter: gutter,
54883              });
54884              tileTextureCache.set(cacheKey, tileTexture);
54885            } else {
54886              if (this.isDrawableTile_(tile)) {
54887                tileTexture.setTile(tile);
54888              } else {
54889                const interimTile =
54890                  /** @type {import("../../webgl/TileTexture").TileType} */ (
54891                    tile.getInterimTile()
54892                  );
54893                tileTexture.setTile(interimTile);
54894              }
54895            }
54896          }
54897
54898          addTileTextureToLookup(tileTexturesByZ, tileTexture, z);
54899
54900          const tileQueueKey = tile.getKey();
54901          wantedTiles[tileQueueKey] = true;
54902
54903          if (tile.getState() === TileState.IDLE) {
54904            if (!frameState.tileQueue.isKeyQueued(tileQueueKey)) {
54905              frameState.tileQueue.enqueue([
54906                tile,
54907                tileSourceKey,
54908                tileGrid.getTileCoordCenter(tileCoord),
54909                tileResolution,
54910              ]);
54911            }
54912          }
54913        }
54914      }
54915    }
54916  }
54917
54918  /**
54919   * Render the layer.
54920   * @param {import("../../Map.js").FrameState} frameState Frame state.
54921   * @return {HTMLElement} The rendered element.
54922   */
54923  renderFrame(frameState) {
54924    this.frameState_ = frameState;
54925    this.renderComplete = true;
54926    const gl = this.helper.getGL();
54927    this.preRender(gl, frameState);
54928
54929    const viewState = frameState.viewState;
54930    const tileLayer = this.getLayer();
54931    const tileSource = tileLayer.getRenderSource();
54932    const tileGrid = tileSource.getTileGridForProjection(viewState.projection);
54933    const gutter = tileSource.getGutterForProjection(viewState.projection);
54934    const extent = getRenderExtent(frameState, frameState.extent);
54935    const z = tileGrid.getZForResolution(
54936      viewState.resolution,
54937      tileSource.zDirection
54938    );
54939
54940    /**
54941     * @type {Object<number, Array<import("../../webgl/TileTexture.js").default>>}
54942     */
54943    const tileTexturesByZ = {};
54944
54945    if (frameState.nextExtent) {
54946      const targetZ = tileGrid.getZForResolution(
54947        viewState.nextResolution,
54948        tileSource.zDirection
54949      );
54950      const nextExtent = getRenderExtent(frameState, frameState.nextExtent);
54951      this.enqueueTiles(frameState, nextExtent, targetZ, tileTexturesByZ);
54952    }
54953
54954    this.enqueueTiles(frameState, extent, z, tileTexturesByZ);
54955
54956    /**
54957     * A lookup of alpha values for tiles at the target rendering resolution
54958     * for tiles that are in transition.  If a tile coord key is absent from
54959     * this lookup, the tile should be rendered at alpha 1.
54960     * @type {Object<string, number>}
54961     */
54962    const alphaLookup = {};
54963
54964    const uid = getUid(this);
54965    const time = frameState.time;
54966    let blend = false;
54967
54968    // look for cached tiles to use if a target tile is not ready
54969    const tileTextures = tileTexturesByZ[z];
54970    for (let i = 0, ii = tileTextures.length; i < ii; ++i) {
54971      const tileTexture = tileTextures[i];
54972      const tile = tileTexture.tile;
54973      const tileCoord = tile.tileCoord;
54974
54975      if (tileTexture.loaded) {
54976        const alpha = tile.getAlpha(uid, time);
54977        if (alpha === 1) {
54978          // no need to look for alt tiles
54979          tile.endTransition(uid);
54980          continue;
54981        }
54982        blend = true;
54983        const tileCoordKey = tilecoord_getKey(tileCoord);
54984        alphaLookup[tileCoordKey] = alpha;
54985      }
54986      this.renderComplete = false;
54987
54988      // first look for child tiles (at z + 1)
54989      const coveredByChildren = this.findAltTiles_(
54990        tileGrid,
54991        tileCoord,
54992        z + 1,
54993        tileTexturesByZ
54994      );
54995
54996      if (coveredByChildren) {
54997        continue;
54998      }
54999
55000      // next look for parent tiles
55001      const minZoom = tileGrid.getMinZoom();
55002      for (let parentZ = z - 1; parentZ >= minZoom; --parentZ) {
55003        const coveredByParent = this.findAltTiles_(
55004          tileGrid,
55005          tileCoord,
55006          parentZ,
55007          tileTexturesByZ
55008        );
55009
55010        if (coveredByParent) {
55011          break;
55012        }
55013      }
55014    }
55015
55016    this.helper.useProgram(this.program_, frameState);
55017    this.helper.prepareDraw(frameState, !blend);
55018
55019    const zs = Object.keys(tileTexturesByZ)
55020      .map(Number)
55021      .sort(numberSafeCompareFunction);
55022
55023    const centerX = viewState.center[0];
55024    const centerY = viewState.center[1];
55025
55026    for (let j = 0, jj = zs.length; j < jj; ++j) {
55027      const tileZ = zs[j];
55028      const tileResolution = tileGrid.getResolution(tileZ);
55029      const tileSize = toSize(tileGrid.getTileSize(tileZ), this.tempSize_);
55030      const tileOrigin = tileGrid.getOrigin(tileZ);
55031
55032      const tileWidthWithGutter = tileSize[0] + 2 * gutter;
55033      const tileHeightWithGutter = tileSize[1] + 2 * gutter;
55034      const aspectRatio = tileWidthWithGutter / tileHeightWithGutter;
55035
55036      const centerI =
55037        (centerX - tileOrigin[0]) / (tileSize[0] * tileResolution);
55038      const centerJ =
55039        (tileOrigin[1] - centerY) / (tileSize[1] * tileResolution);
55040
55041      const tileScale = viewState.resolution / tileResolution;
55042
55043      const depth = depthForZ(tileZ);
55044      const tileTextures = tileTexturesByZ[tileZ];
55045      for (let i = 0, ii = tileTextures.length; i < ii; ++i) {
55046        const tileTexture = tileTextures[i];
55047        if (!tileTexture.loaded) {
55048          continue;
55049        }
55050        const tile = tileTexture.tile;
55051        const tileCoord = tile.tileCoord;
55052        const tileCoordKey = tilecoord_getKey(tileCoord);
55053
55054        const tileCenterI = tileCoord[1];
55055        const tileCenterJ = tileCoord[2];
55056
55057        transform_reset(this.tileTransform_);
55058        transform_scale(
55059          this.tileTransform_,
55060          2 / ((frameState.size[0] * tileScale) / tileWidthWithGutter),
55061          -2 / ((frameState.size[1] * tileScale) / tileWidthWithGutter)
55062        );
55063        transform_rotate(this.tileTransform_, viewState.rotation);
55064        transform_scale(this.tileTransform_, 1, 1 / aspectRatio);
55065        translate(
55066          this.tileTransform_,
55067          (tileSize[0] * (tileCenterI - centerI) - gutter) /
55068            tileWidthWithGutter,
55069          (tileSize[1] * (tileCenterJ - centerJ) - gutter) /
55070            tileHeightWithGutter
55071        );
55072
55073        this.helper.setUniformMatrixValue(
55074          Uniforms.TILE_TRANSFORM,
55075          fromTransform(this.tempMat4_, this.tileTransform_)
55076        );
55077
55078        this.helper.bindBuffer(tileTexture.coords);
55079        this.helper.bindBuffer(this.indices_);
55080        this.helper.enableAttributes(attributeDescriptions);
55081
55082        let textureSlot = 0;
55083        while (textureSlot < tileTexture.textures.length) {
55084          const textureProperty = 'TEXTURE' + textureSlot;
55085          const uniformName = `${Uniforms.TILE_TEXTURE_ARRAY}[${textureSlot}]`;
55086          gl.activeTexture(gl[textureProperty]);
55087          gl.bindTexture(gl.TEXTURE_2D, tileTexture.textures[textureSlot]);
55088          gl.uniform1i(
55089            this.helper.getUniformLocation(uniformName),
55090            textureSlot
55091          );
55092          ++textureSlot;
55093        }
55094
55095        for (
55096          let paletteIndex = 0;
55097          paletteIndex < this.paletteTextures_.length;
55098          ++paletteIndex
55099        ) {
55100          const paletteTexture = this.paletteTextures_[paletteIndex];
55101          gl.activeTexture(gl['TEXTURE' + textureSlot]);
55102          const texture = paletteTexture.getTexture(gl);
55103          gl.bindTexture(gl.TEXTURE_2D, texture);
55104          gl.uniform1i(
55105            this.helper.getUniformLocation(paletteTexture.name),
55106            textureSlot
55107          );
55108          ++textureSlot;
55109        }
55110
55111        const alpha =
55112          tileCoordKey in alphaLookup ? alphaLookup[tileCoordKey] : 1;
55113
55114        if (alpha < 1) {
55115          frameState.animate = true;
55116        }
55117
55118        this.helper.setUniformFloatValue(Uniforms.TRANSITION_ALPHA, alpha);
55119        this.helper.setUniformFloatValue(Uniforms.DEPTH, depth);
55120        this.helper.setUniformFloatValue(
55121          Uniforms.TEXTURE_PIXEL_WIDTH,
55122          tileWidthWithGutter
55123        );
55124        this.helper.setUniformFloatValue(
55125          Uniforms.TEXTURE_PIXEL_HEIGHT,
55126          tileHeightWithGutter
55127        );
55128        this.helper.setUniformFloatValue(
55129          Uniforms.TEXTURE_RESOLUTION,
55130          tileResolution
55131        );
55132        this.helper.setUniformFloatValue(
55133          Uniforms.TEXTURE_ORIGIN_X,
55134          tileOrigin[0] +
55135            tileCenterI * tileSize[0] * tileResolution -
55136            gutter * tileResolution
55137        );
55138        this.helper.setUniformFloatValue(
55139          Uniforms.TEXTURE_ORIGIN_Y,
55140          tileOrigin[1] -
55141            tileCenterJ * tileSize[1] * tileResolution +
55142            gutter * tileResolution
55143        );
55144        let gutterExtent = extent;
55145        if (gutter > 0) {
55146          gutterExtent = tileGrid.getTileCoordExtent(tileCoord);
55147          getIntersection(gutterExtent, extent, gutterExtent);
55148        }
55149        this.helper.setUniformFloatVec4(Uniforms.RENDER_EXTENT, gutterExtent);
55150        this.helper.setUniformFloatValue(
55151          Uniforms.RESOLUTION,
55152          viewState.resolution
55153        );
55154        this.helper.setUniformFloatValue(Uniforms.ZOOM, viewState.zoom);
55155
55156        this.helper.drawElements(0, this.indices_.getSize());
55157      }
55158    }
55159
55160    this.helper.finalizeDraw(
55161      frameState,
55162      this.dispatchPreComposeEvent,
55163      this.dispatchPostComposeEvent
55164    );
55165
55166    const canvas = this.helper.getCanvas();
55167
55168    const tileTextureCache = this.tileTextureCache_;
55169    while (tileTextureCache.canExpireCache()) {
55170      const tileTexture = tileTextureCache.pop();
55171      tileTexture.dispose();
55172    }
55173
55174    // TODO: let the renderers manage their own cache instead of managing the source cache
55175    /**
55176     * Here we unconditionally expire the source cache since the renderer maintains
55177     * its own cache.
55178     * @param {import("../../Map.js").default} map Map.
55179     * @param {import("../../Map.js").FrameState} frameState Frame state.
55180     */
55181    const postRenderFunction = function (map, frameState) {
55182      tileSource.updateCacheSize(0.1, frameState.viewState.projection);
55183      tileSource.expireCache(frameState.viewState.projection, empty);
55184    };
55185
55186    frameState.postRenderFunctions.push(postRenderFunction);
55187
55188    this.postRender(gl, frameState);
55189    return canvas;
55190  }
55191
55192  /**
55193   * @param {import("../../pixel.js").Pixel} pixel Pixel.
55194   * @return {Uint8ClampedArray|Uint8Array|Float32Array|DataView} Data at the pixel location.
55195   */
55196  getData(pixel) {
55197    const gl = this.helper.getGL();
55198    if (!gl) {
55199      return null;
55200    }
55201
55202    const frameState = this.frameState_;
55203    if (!frameState) {
55204      return null;
55205    }
55206
55207    const layer = this.getLayer();
55208    const coordinate = apply(
55209      frameState.pixelToCoordinateTransform,
55210      pixel.slice()
55211    );
55212
55213    const viewState = frameState.viewState;
55214    const layerExtent = layer.getExtent();
55215    if (layerExtent) {
55216      if (
55217        !containsCoordinate(
55218          proj_fromUserExtent(layerExtent, viewState.projection),
55219          coordinate
55220        )
55221      ) {
55222        return null;
55223      }
55224    }
55225
55226    // determine last source suitable for rendering at coordinate
55227    const sources = layer.getSources(
55228      boundingExtent([coordinate]),
55229      viewState.resolution
55230    );
55231    let i, source, tileGrid;
55232    for (i = sources.length - 1; i >= 0; --i) {
55233      source = sources[i];
55234      if (source.getState() === 'ready') {
55235        tileGrid = source.getTileGridForProjection(viewState.projection);
55236        if (source.getWrapX()) {
55237          break;
55238        }
55239        const gridExtent = tileGrid.getExtent();
55240        if (!gridExtent || containsCoordinate(gridExtent, coordinate)) {
55241          break;
55242        }
55243      }
55244    }
55245    if (i < 0) {
55246      return null;
55247    }
55248
55249    const tileTextureCache = this.tileTextureCache_;
55250    for (
55251      let z = tileGrid.getZForResolution(viewState.resolution);
55252      z >= tileGrid.getMinZoom();
55253      --z
55254    ) {
55255      const tileCoord = tileGrid.getTileCoordForCoordAndZ(coordinate, z);
55256      const cacheKey = getCacheKey(source, tileCoord);
55257      if (!tileTextureCache.containsKey(cacheKey)) {
55258        continue;
55259      }
55260      const tileTexture = tileTextureCache.get(cacheKey);
55261      if (!tileTexture.loaded) {
55262        continue;
55263      }
55264      const tileOrigin = tileGrid.getOrigin(z);
55265      const tileSize = toSize(tileGrid.getTileSize(z));
55266      const tileResolution = tileGrid.getResolution(z);
55267
55268      const col =
55269        (coordinate[0] - tileOrigin[0]) / tileResolution -
55270        tileCoord[1] * tileSize[0];
55271
55272      const row =
55273        (tileOrigin[1] - coordinate[1]) / tileResolution -
55274        tileCoord[2] * tileSize[1];
55275
55276      return tileTexture.getPixelData(col, row);
55277    }
55278    return null;
55279  }
55280
55281  /**
55282   * Look for tiles covering the provided tile coordinate at an alternate
55283   * zoom level.  Loaded tiles will be added to the provided tile texture lookup.
55284   * @param {import("../../tilegrid/TileGrid.js").default} tileGrid The tile grid.
55285   * @param {import("../../tilecoord.js").TileCoord} tileCoord The target tile coordinate.
55286   * @param {number} altZ The alternate zoom level.
55287   * @param {Object<number, Array<import("../../webgl/TileTexture.js").default>>} tileTexturesByZ Lookup of
55288   * tile textures by zoom level.
55289   * @return {boolean} The tile coordinate is covered by loaded tiles at the alternate zoom level.
55290   * @private
55291   */
55292  findAltTiles_(tileGrid, tileCoord, altZ, tileTexturesByZ) {
55293    const tileRange = tileGrid.getTileRangeForTileCoordAndZ(
55294      tileCoord,
55295      altZ,
55296      this.tempTileRange_
55297    );
55298
55299    if (!tileRange) {
55300      return false;
55301    }
55302
55303    let covered = true;
55304    const tileTextureCache = this.tileTextureCache_;
55305    const source = this.getLayer().getRenderSource();
55306    for (let x = tileRange.minX; x <= tileRange.maxX; ++x) {
55307      for (let y = tileRange.minY; y <= tileRange.maxY; ++y) {
55308        const cacheKey = getCacheKey(source, [altZ, x, y]);
55309        let loaded = false;
55310        if (tileTextureCache.containsKey(cacheKey)) {
55311          const tileTexture = tileTextureCache.get(cacheKey);
55312          if (tileTexture.loaded) {
55313            addTileTextureToLookup(tileTexturesByZ, tileTexture, altZ);
55314            loaded = true;
55315          }
55316        }
55317        if (!loaded) {
55318          covered = false;
55319        }
55320      }
55321    }
55322    return covered;
55323  }
55324
55325  removeHelper() {
55326    if (this.helper) {
55327      const tileTextureCache = this.tileTextureCache_;
55328      tileTextureCache.forEach((tileTexture) => tileTexture.dispose());
55329      tileTextureCache.clear();
55330    }
55331
55332    super.removeHelper();
55333  }
55334
55335  /**
55336   * Clean up.
55337   */
55338  disposeInternal() {
55339    const helper = this.helper;
55340    if (helper) {
55341      const gl = helper.getGL();
55342      gl.deleteProgram(this.program_);
55343      delete this.program_;
55344
55345      helper.deleteBuffer(this.indices_);
55346    }
55347
55348    super.disposeInternal();
55349
55350    delete this.indices_;
55351    delete this.tileTextureCache_;
55352    delete this.frameState_;
55353  }
55354}
55355
55356/* harmony default export */ const webgl_TileLayer = (WebGLTileLayerRenderer);
55357
55358;// CONCATENATED MODULE: ./node_modules/ol/webgl/PaletteTexture.js
55359/**
55360 * @module ol/webgl/PaletteTexture
55361 */
55362
55363class PaletteTexture {
55364  /**
55365   * @param {string} name The name of the texture.
55366   * @param {Uint8Array} data The texture data.
55367   */
55368  constructor(name, data) {
55369    this.name = name;
55370    this.data = data;
55371
55372    /**
55373     * @type {WebGLTexture}
55374     * @private
55375     */
55376    this.texture_ = null;
55377  }
55378
55379  /**
55380   * @param {WebGLRenderingContext} gl Rendering context.
55381   * @return {WebGLTexture} The texture.
55382   */
55383  getTexture(gl) {
55384    if (!this.texture_) {
55385      const texture = gl.createTexture();
55386      gl.bindTexture(gl.TEXTURE_2D, texture);
55387      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
55388      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
55389      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
55390      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
55391      gl.texImage2D(
55392        gl.TEXTURE_2D,
55393        0,
55394        gl.RGBA,
55395        this.data.length / 4,
55396        1,
55397        0,
55398        gl.RGBA,
55399        gl.UNSIGNED_BYTE,
55400        this.data
55401      );
55402      this.texture_ = texture;
55403    }
55404    return this.texture_;
55405  }
55406}
55407
55408/* harmony default export */ const webgl_PaletteTexture = (PaletteTexture);
55409
55410;// CONCATENATED MODULE: ./node_modules/ol/style/expressions.js
55411/**
55412 * Operators and utilities used for style expressions
55413 * @module ol/style/expressions
55414 */
55415
55416
55417
55418
55419
55420/**
55421 * Base type used for literal style parameters; can be a number literal or the output of an operator,
55422 * which in turns takes {@link import("./expressions.js").ExpressionValue} arguments.
55423 *
55424 * The following operators can be used:
55425 *
55426 * * Reading operators:
55427 *   * `['band', bandIndex, xOffset, yOffset]` For tile layers only. Fetches pixel values from band
55428 *     `bandIndex` of the source's data. The first `bandIndex` of the source data is `1`. Fetched values
55429 *     are in the 0..1 range. {@link import("../source/TileImage.js").default} sources have 4 bands: red,
55430 *     green, blue and alpha. {@link import("../source/DataTile.js").default} sources can have any number
55431 *     of bands, depending on the underlying data source and
55432 *     {@link import("../source/GeoTIFF.js").Options configuration}. `xOffset` and `yOffset` are optional
55433 *     and allow specifying pixel offsets for x and y. This is used for sampling data from neighboring pixels.
55434 *   * `['get', 'attributeName']` fetches a feature attribute (it will be prefixed by `a_` in the shader)
55435 *     Note: those will be taken from the attributes provided to the renderer
55436 *   * `['resolution']` returns the current resolution
55437 *   * `['time']` returns the time in seconds since the creation of the layer
55438 *   * `['var', 'varName']` fetches a value from the style variables, or 0 if undefined
55439 *   * `['zoom']` returns the current zoom level
55440 *
55441 * * Math operators:
55442 *   * `['*', value1, value2]` multiplies `value1` by `value2`
55443 *   * `['/', value1, value2]` divides `value1` by `value2`
55444 *   * `['+', value1, value2]` adds `value1` and `value2`
55445 *   * `['-', value1, value2]` subtracts `value2` from `value1`
55446 *   * `['clamp', value, low, high]` clamps `value` between `low` and `high`
55447 *   * `['%', value1, value2]` returns the result of `value1 % value2` (modulo)
55448 *   * `['^', value1, value2]` returns the value of `value1` raised to the `value2` power
55449 *   * `['abs', value1]` returns the absolute value of `value1`
55450 *   * `['floor', value1]` returns the nearest integer less than or equal to `value1`
55451 *   * `['round', value1]` returns the nearest integer to `value1`
55452 *   * `['ceil', value1]` returns the nearest integer greater than or equal to `value1`
55453 *   * `['sin', value1]` returns the sine of `value1`
55454 *   * `['cos', value1]` returns the cosine of `value1`
55455 *   * `['atan', value1, value2]` returns `atan2(value1, value2)`. If `value2` is not provided, returns `atan(value1)`
55456 *
55457 * * Transform operators:
55458 *   * `['case', condition1, output1, ...conditionN, outputN, fallback]` selects the first output whose corresponding
55459 *     condition evaluates to `true`. If no match is found, returns the `fallback` value.
55460 *     All conditions should be `boolean`, output and fallback can be any kind.
55461 *   * `['match', input, match1, output1, ...matchN, outputN, fallback]` compares the `input` value against all
55462 *     provided `matchX` values, returning the output associated with the first valid match. If no match is found,
55463 *     returns the `fallback` value.
55464 *     `input` and `matchX` values must all be of the same type, and can be `number` or `str
55464ing`. `outputX` and
55465 *     `fallback` values must be of the same type, and can be of any kind.
55466 *   * `['interpolate', interpolation, input, stop1, output1, ...stopN, outputN]` returns a value by interpolating between
55467 *     pairs of inputs and outputs; `interpolation` can either be `['linear']` or `['exponential', base]` where `base` is
55468 *     the rate of increase from stop A to stop B (i.e. power to which the interpolation ratio is raised); a value
55469 *     of 1 is equivalent to `['linear']`.
55470 *     `input` and `stopX` values must all be of type `number`. `outputX` values can be `number` or `color` values.
55471 *     Note: `input` will be clamped between `stop1` and `stopN`, meaning that all output values will be comprised
55472 *     between `output1` and `outputN`.
55473 *
55474 * * Logical operators:
55475 *   * `['<', value1, value2]` returns `true` if `value1` is strictly lower than `value2`, or `false` otherwise.
55476 *   * `['<=', value1, value2]` returns `true` if `value1` is lower than or equals `value2`, or `false` otherwise.
55477 *   * `['>', value1, value2]` returns `true` if `value1` is strictly greater than `value2`, or `false` otherwise.
55478 *   * `['>=', value1, value2]` returns `true` if `value1` is greater than or equals `value2`, or `false` otherwise.
55479 *   * `['==', value1, value2]` returns `true` if `value1` equals `value2`, or `false` otherwise.
55480 *   * `['!=', value1, value2]` returns `true` if `value1` does not equal `value2`, or `false` otherwise.
55481 *   * `['!', value1]` returns `false` if `value1` is `true` or greater than `0`, or `true` otherwise.
55482 *   * `['all', value1, value2, ...]` returns `true` if all the inputs are `true`, `false` otherwise.
55483 *   * `['any', value1, value2, ...]` returns `true` if any of the inputs are `true`, `false` otherwise.
55484 *   * `['between', value1, value2, value3]` returns `true` if `value1` is contained between `value2` and `value3`
55485 *     (inclusively), or `false` otherwise.
55486 *
55487 * * Conversion operators:
55488 *   * `['array', value1, ...valueN]` creates a numerical array from `number` values; please note that the amount of
55489 *     values can currently only be 2, 3 or 4.
55490 *   * `['color', red, green, blue, alpha]` creates a `color` value from `number` values; the `alpha` parameter is
55491 *     optional; if not specified, it will be set to 1.
55492 *     Note: `red`, `green` and `blue` components must be values between 0 and 255; `alpha` between 0 and 1.
55493 *   * `['palette', index, colors]` picks a `color` value from an array of colors using the given index; the `index`
55494 *     expression must evaluate to a number; the items in the `colors` array must be strings with hex colors
55495 *     (e.g. `'#86A136'`), colors using the rgba[a] functional notation (e.g. `'rgb(134, 161, 54)'` or `'rgba(134, 161, 54, 1)'`),
55496 *     named colors (e.g. `'red'`), or array literals with 3 ([r, g, b]) or 4 ([r, g, b, a]) values (with r, g, and b
55497 *     in the 0-255 range and a in the 0-1 range).
55498 *
55499 * Values can either be literals or another operator, as they will be evaluated recursively.
55500 * Literal values can be of the following types:
55501 * * `boolean`
55502 * * `number`
55503 * * `string`
55504 * * {@link module:ol/color~Color}
55505 *
55506 * @typedef {Array<*>|import("../color.js").Color|string|number|boolean} ExpressionValue
55507 * @api
55508 */
55509
55510/**
55511 * Possible inferred types from a given value or expression.
55512 * Note: these are binary flags.
55513 * @enum {number}
55514 */
55515const ValueTypes = {
55516  NUMBER: 0b00001,
55517  STRING: 0b00010,
55518  COLOR: 0b00100,
55519  BOOLEAN: 0b01000,
55520  NUMBER_ARRAY: 0b10000,
55521  ANY: 0b11111,
55522  NONE: 0,
55523};
55524
55525/**
55526 * An operator declaration must contain two methods: `getReturnType` which returns a type based on
55527 * the operator arguments, and `toGlsl` which returns a GLSL-compatible string.
55528 * Note: both methods can process arguments recursively.
55529 * @typedef {Object} Operator
55530 * @property {function(Array<ExpressionValue>): ValueTypes|number} getReturnType Returns one or several types
55531 * @property {function(ParsingContext, Array<ExpressionValue>, ValueTypes=): string} toGlsl Returns a GLSL-compatible string
55532 * Note: takes in an optional type hint as 3rd parameter
55533 */
55534
55535/**
55536 * Operator declarations
55537 * @type {Object<string, Operator>}
55538 */
55539const Operators = {};
55540
55541/**
55542 * Returns the possible types for a given value (each type being a binary flag)
55543 * To test a value use e.g. `getValueType(v) & ValueTypes.BOOLEAN`
55544 * @param {ExpressionValue} value Value
55545 * @return {ValueTypes|number} Type or types inferred from the value
55546 */
55547function getValueType(value) {
55548  if (typeof value === 'number') {
55549    return ValueTypes.NUMBER;
55550  }
55551  if (typeof value === 'boolean') {
55552    return ValueTypes.BOOLEAN;
55553  }
55554  if (typeof value === 'string') {
55555    if (isStringColor(value)) {
55556      return ValueTypes.COLOR | ValueTypes.STRING;
55557    }
55558    return ValueTypes.STRING;
55559  }
55560  if (!Array.isArray(value)) {
55561    throw new Error(`Unhandled value type: ${JSON.stringify(value)}`);
55562  }
55563  const valueArr = /** @type {Array<*>} */ (value);
55564  const onlyNumbers = valueArr.every(function (v) {
55565    return typeof v === 'number';
55566  });
55567  if (onlyNumbers) {
55568    if (valueArr.length === 3 || valueArr.length === 4) {
55569      return ValueTypes.COLOR | ValueTypes.NUMBER_ARRAY;
55570    }
55571    return ValueTypes.NUMBER_ARRAY;
55572  }
55573  if (typeof valueArr[0] !== 'string') {
55574    throw new Error(
55575      `Expected an expression operator but received: ${JSON.stringify(
55576        valueArr
55577      )}`
55578    );
55579  }
55580  const operator = Operators[valueArr[0]];
55581  if (operator === undefined) {
55582    throw new Error(
55583      `Unrecognized expression operator: ${JSON.stringify(valueArr)}`
55584    );
55585  }
55586  return operator.getReturnType(valueArr.slice(1));
55587}
55588
55589/**
55590 * Checks if only one value type is enabled in the input number.
55591 * @param {ValueTypes|number} valueType Number containing value type binary flags
55592 * @return {boolean} True if only one type flag is enabled, false if zero or multiple
55593 */
55594function isTypeUnique(valueType) {
55595  return Math.log2(valueType) % 1 === 0;
55596}
55597
55598/**
55599 * Context available during the parsing of an expression.
55600 * @typedef {Object} ParsingContext
55601 * @property {boolean} [inFragmentShader] If false, means the expression output should be made for a vertex shader
55602 * @property {Array<string>} variables List of variables used in the expression; contains **unprefixed names**
55603 * @property {Array<string>} attributes List of attributes used in the expression; contains **unprefixed names**
55604 * @property {Object<string, number>} stringLiteralsMap This object maps all encountered string values to a number
55605 * @property {Object<string, string>} functions Lookup of functions used by the style.
55606 * @property {number} [bandCount] Number of bands per pixel.
55607 * @property {Array<PaletteTexture>} [paletteTextures] List of palettes used by the style.
55608 */
55609
55610/**
55611 * Will return the number as a float with a dot separator, which is required by GLSL.
55612 * @param {number} v Numerical value.
55613 * @return {string} The value as string.
55614 */
55615function numberToGlsl(v) {
55616  const s = v.toString();
55617  return s.includes('.') ? s : s + '.0';
55618}
55619
55620/**
55621 * Will return the number array as a float with a dot separator, concatenated with ', '.
55622 * @param {Array<number>} array Numerical values array.
55623 * @return {string} The array as a vector, e. g.: `vec3(1.0, 2.0, 3.0)`.
55624 */
55625function arrayToGlsl(array) {
55626  if (array.length < 2 || array.length > 4) {
55627    throw new Error(
55628      '`formatArray` can only output `vec2`, `vec3` or `vec4` arrays.'
55629    );
55630  }
55631  return `vec${array.length}(${array.map(numberToGlsl).join(', ')})`;
55632}
55633
55634/**
55635 * Will normalize and converts to string a `vec4` color array compatible with GLSL.
55636 * @param {string|import("../color.js").Color} color Color either in string format or [r, g, b, a] array format,
55637 * with RGB components in the 0..255 range and the alpha component in the 0..1 range.
55638 * Note that the final array will always have 4 components.
55639 * @return {string} The color expressed in the `vec4(1.0, 1.0, 1.0, 1.0)` form.
55640 */
55641function colorToGlsl(color) {
55642  const array = asArray(color).slice();
55643  if (array.length < 4) {
55644    array.push(1);
55645  }
55646  return arrayToGlsl(
55647    array.map(function (c, i) {
55648      return i < 3 ? c / 255 : c;
55649    })
55650  );
55651}
55652
55653/**
55654 * Returns a stable equivalent number for the string literal.
55655 * @param {ParsingContext} context Parsing context
55656 * @param {string} string String literal value
55657 * @return {number} Number equivalent
55658 */
55659function getStringNumberEquivalent(context, string) {
55660  if (context.stringLiteralsMap[string] === undefined) {
55661    context.stringLiteralsMap[string] = Object.keys(
55662      context.stringLiteralsMap
55663    ).length;
55664  }
55665  return context.stringLiteralsMap[string];
55666}
55667
55668/**
55669 * Returns a stable equivalent number for the string literal, for use in shaders. This number is then
55670 * converted to be a GLSL-compatible string.
55671 * @param {ParsingContext} context Parsing context
55672 * @param {string} string String literal value
55673 * @return {string} GLSL-compatible string containing a number
55674 */
55675function stringToGlsl(context, string) {
55676  return numberToGlsl(getStringNumberEquivalent(context, string));
55677}
55678
55679/**
55680 * Recursively parses a style expression and outputs a GLSL-compatible string. Takes in a parsing context that
55681 * will be read and modified during the parsing operation.
55682 * @param {ParsingContext} context Parsing context
55683 * @param {ExpressionValue} value Value
55684 * @param {ValueTypes|number} [typeHint] Hint for the expected final type (can be several types combined)
55685 * @return {string} GLSL-compatible output
55686 */
55687function expressionToGlsl(context, value, typeHint) {
55688  // operator
55689  if (Array.isArray(value) && typeof value[0] === 'string') {
55690    const operator = Operators[value[0]];
55691    if (operator === undefined) {
55692      throw new Error(
55693        `Unrecognized expression operator: ${JSON.stringify(value)}`
55694      );
55695    }
55696    return operator.toGlsl(context, value.slice(1), typeHint);
55697  }
55698
55699  const valueType = getValueType(value);
55700  if ((valueType & ValueTypes.NUMBER) > 0) {
55701    return numberToGlsl(/** @type {number} */ (value));
55702  }
55703
55704  if ((valueType & ValueTypes.BOOLEAN) > 0) {
55705    return value.toString();
55706  }
55707
55708  if (
55709    (valueType & ValueTypes.STRING) > 0 &&
55710    (typeHint === undefined || typeHint == ValueTypes.STRING)
55711  ) {
55712    return stringToGlsl(context, value.toString());
55713  }
55714
55715  if (
55716    (valueType & ValueTypes.COLOR) > 0 &&
55717    (typeHint === undefined || typeHint == ValueTypes.COLOR)
55718  ) {
55719    return colorToGlsl(/** @type {Array<number> | string} */ (value));
55720  }
55721
55722  if ((valueType & ValueTypes.NUMBER_ARRAY) > 0) {
55723    return arrayToGlsl(/** @type {Array<number>} */ (value));
55724  }
55725
55726  throw new Error(`Unexpected expression ${value} (expected type ${typeHint})`);
55727}
55728
55729function assertNumber(value) {
55730  if (!(getValueType(value) & ValueTypes.NUMBER)) {
55731    throw new Error(
55732      `A numeric value was expected, got ${JSON.stringify(value)} instead`
55733    );
55734  }
55735}
55736function assertNumbers(values) {
55737  for (let i = 0; i < values.length; i++) {
55738    assertNumber(values[i]);
55739  }
55740}
55741function assertString(value) {
55742  if (!(getValueType(value) & ValueTypes.STRING)) {
55743    throw new Error(
55744      `A string value was expected, got ${JSON.stringify(value)} instead`
55745    );
55746  }
55747}
55748function assertBoolean(value) {
55749  if (!(getValueType(value) & ValueTypes.BOOLEAN)) {
55750    throw new Error(
55751      `A boolean value was expected, got ${JSON.stringify(value)} instead`
55752    );
55753  }
55754}
55755function assertArgsCount(args, count) {
55756  if (args.length !== count) {
55757    throw new Error(
55758      `Exactly ${count} arguments were expected, got ${args.length} instead`
55759    );
55760  }
55761}
55762function assertArgsMinCount(args, count) {
55763  if (args.length < count) {
55764    throw new Error(
55765      `At least ${count} arguments were expected, got ${args.length} instead`
55766    );
55767  }
55768}
55769function assertArgsMaxCount(args, count) {
55770  if (args.length > count) {
55771    throw new Error(
55772      `At most ${count} arguments were expected, got ${args.length} instead`
55773    );
55774  }
55775}
55776function assertArgsEven(args) {
55777  if (args.length % 2 !== 0) {
55778    throw new Error(
55779      `An even amount of arguments was expected, got ${args} instead`
55780    );
55781  }
55782}
55783function assertArgsOdd(args) {
55784  if (args.length % 2 === 0) {
55785    throw new Error(
55786      `An odd amount of arguments was expected, got ${args} instead`
55787    );
55788  }
55789}
55790function assertUniqueInferredType(args, types) {
55791  if (!isTypeUnique(types)) {
55792    throw new Error(
55793      `Could not infer only one type from the following expression: ${JSON.stringify(
55794        args
55795      )}`
55796    );
55797  }
55798}
55799
55800Operators['get'] = {
55801  getReturnType: function (args) {
55802    return ValueTypes.ANY;
55803  },
55804  toGlsl: function (context, args) {
55805    assertArgsCount(args, 1);
55806    assertString(args[0]);
55807    const value = args[0].toString();
55808    if (!context.attributes.includes(value)) {
55809      context.attributes.push(value);
55810    }
55811    const prefix = context.inFragmentShader ? 'v_' : 'a_';
55812    return prefix + value;
55813  },
55814};
55815
55816/**
55817 * Get the uniform name given a variable name.
55818 * @param {string} variableName The variable name.
55819 * @return {string} The uniform name.
55820 */
55821function uniformNameForVariable(variableName) {
55822  return 'u_var_' + variableName;
55823}
55824
55825Operators['var'] = {
55826  getReturnType: function (args) {
55827    return ValueTypes.ANY;
55828  },
55829  toGlsl: function (context, args) {
55830    assertArgsCount(args, 1);
55831    assertString(args[0]);
55832    const value = args[0].toString();
55833    if (!context.variables.includes(value)) {
55834      context.variables.push(value);
55835    }
55836    return uniformNameForVariable(value);
55837  },
55838};
55839
55840const PALETTE_TEXTURE_ARRAY = 'u_paletteTextures';
55841
55842// ['palette', index, colors]
55843Operators['palette'] = {
55844  getReturnType: function (args) {
55845    return ValueTypes.COLOR;
55846  },
55847  toGlsl: function (context, args) {
55848    assertArgsCount(args, 2);
55849    assertNumber(args[0]);
55850    const index = expressionToGlsl(context, args[0]);
55851    const colors = args[1];
55852    if (!Array.isArray(colors)) {
55853      throw new Error('The second argument of palette must be an array');
55854    }
55855    const numColors = colors.length;
55856    const palette = new Uint8Array(numColors * 4);
55857    for (let i = 0; i < numColors; i++) {
55858      const candidate = colors[i];
55859      /**
55860       * @type {import('../color.js').Color}
55861       */
55862      let color;
55863      if (typeof candidate === 'string') {
55864        color = fromString(candidate);
55865      } else {
55866        if (!Array.isArray(candidate)) {
55867          throw new Error(
55868            'The second argument of palette must be an array of strings or colors'
55869          );
55870        }
55871        const length = candidate.length;
55872        if (length === 4) {
55873          color = candidate;
55874        } else {
55875          if (length !== 3) {
55876            throw new Error(
55877              `Expected palette color to have 3 or 4 values, got ${length}`
55878            );
55879          }
55880          color = [candidate[0], candidate[1], candidate[2], 1];
55881        }
55882      }
55883      const offset = i * 4;
55884      palette[offset] = color[0];
55885      palette[offset + 1] = color[1];
55886      palette[offset + 2] = color[2];
55887      palette[offset + 3] = color[3] * 255;
55888    }
55889    if (!context.paletteTextures) {
55890      context.paletteTextures = [];
55891    }
55892    const paletteName = `${PALETTE_TEXTURE_ARRAY}[${context.paletteTextures.length}]`;
55893    const paletteTexture = new webgl_PaletteTexture(paletteName, palette);
55894    context.paletteTextures.push(paletteTexture);
55895    return `texture2D(${paletteName}, vec2((${index} + 0.5) / ${numColors}.0, 0.5))`;
55896  },
55897};
55898
55899const GET_BAND_VALUE_FUNC = 'getBandValue';
55900
55901Operators['band'] = {
55902  getReturnType: function (args) {
55903    return ValueTypes.NUMBER;
55904  },
55905  toGlsl: function (context, args) {
55906    assertArgsMinCount(args, 1);
55907    assertArgsMaxCount(args, 3);
55908    const band = args[0];
55909
55910    if (!(GET_BAND_VALUE_FUNC in context.functions)) {
55911      let ifBlocks = '';
55912      const bandCount = context.bandCount || 1;
55913      for (let i = 0; i < bandCount; i++) {
55914        const colorIndex = Math.floor(i / 4);
55915        let bandIndex = i % 4;
55916        if (i === bandCount - 1 && bandIndex === 1) {
55917          // LUMINANCE_ALPHA - band 1 assigned to rgb and band 2 assigned to alpha
55918          bandIndex = 3;
55919        }
55920        const textureName = `${Uniforms.TILE_TEXTURE_ARRAY}[${colorIndex}]`;
55921        ifBlocks += `
55922          if (band == ${i + 1}.0) {
55923            return texture2D(${textureName}, v_textureCoord + vec2(dx, dy))[${bandIndex}];
55924          }
55925        `;
55926      }
55927
55928      context.functions[GET_BAND_VALUE_FUNC] = `
55929        float getBandValue(float band, float xOffset, float yOffset) {
55930          float dx = xOffset / ${Uniforms.TEXTURE_PIXEL_WIDTH};
55931          float dy = yOffset / ${Uniforms.TEXTURE_PIXEL_HEIGHT};
55932          ${ifBlocks}
55933        }
55934      `;
55935    }
55936
55937    const bandExpression = expressionToGlsl(context, band);
55938    const xOffsetExpression = expressionToGlsl(context, args[1] || 0);
55939    const yOffsetExpression = expressionToGlsl(context, args[2] || 0);
55940    return `${GET_BAND_VALUE_FUNC}(${bandExpression}, ${xOffsetExpression}, ${yOffsetExpression})`;
55941  },
55942};
55943
55944Operators['time'] = {
55945  getReturnType: function (args) {
55946    return ValueTypes.NUMBER;
55947  },
55948  toGlsl: function (context, args) {
55949    assertArgsCount(args, 0);
55950    return 'u_time';
55951  },
55952};
55953
55954Operators['zoom'] = {
55955  getReturnType: function (args) {
55956    return ValueTypes.NUMBER;
55957  },
55958  toGlsl: function (context, args) {
55959    assertArgsCount(args, 0);
55960    return 'u_zoom';
55961  },
55962};
55963
55964Operators['resolution'] = {
55965  getReturnType: function (args) {
55966    return ValueTypes.NUMBER;
55967  },
55968  toGlsl: function (context, args) {
55969    assertArgsCount(args, 0);
55970    return 'u_resolution';
55971  },
55972};
55973
55974Operators['*'] = {
55975  getReturnType: function (args) {
55976    return ValueTypes.NUMBER;
55977  },
55978  toGlsl: function (context, args) {
55979    assertArgsCount(args, 2);
55980    assertNumbers(args);
55981    return `(${expressionToGlsl(context, args[0])} * ${expressionToGlsl(
55982      context,
55983      args[1]
55984    )})`;
55985  },
55986};
55987
55988Operators['/'] = {
55989  getReturnType: function (args) {
55990    return ValueTypes.NUMBER;
55991  },
55992  toGlsl: function (context, args) {
55993    assertArgsCount(args, 2);
55994    assertNumbers(args);
55995    return `(${expressionToGlsl(context, args[0])} / ${expressionToGlsl(
55996      context,
55997      args[1]
55998    )})`;
55999  },
56000};
56001
56002Operators['+'] = {
56003  getReturnType: function (args) {
56004    return ValueTypes.NUMBER;
56005  },
56006  toGlsl: function (context, args) {
56007    assertArgsCount(args, 2);
56008    assertNumbers(args);
56009    return `(${expressionToGlsl(context, args[0])} + ${expressionToGlsl(
56010      context,
56011      args[1]
56012    )})`;
56013  },
56014};
56015
56016Operators['-'] = {
56017  getReturnType: function (args) {
56018    return ValueTypes.NUMBER;
56019  },
56020  toGlsl: function (context, args) {
56021    assertArgsCount(args, 2);
56022    assertNumbers(args);
56023    return `(${expressionToGlsl(context, args[0])} - ${expressionToGlsl(
56024      context,
56025      args[1]
56026    )})`;
56027  },
56028};
56029
56030Operators['clamp'] = {
56031  getReturnType: function (args) {
56032    return ValueTypes.NUMBER;
56033  },
56034  toGlsl: function (context, args) {
56035    assertArgsCount(args, 3);
56036    assertNumbers(args);
56037    const min = expressionToGlsl(context, args[1]);
56038    const max = expressionToGlsl(context, args[2]);
56039    return `clamp(${expressionToGlsl(context, args[0])}, ${min}, ${max})`;
56040  },
56041};
56042
56043Operators['%'] = {
56044  getReturnType: function (args) {
56045    return ValueTypes.NUMBER;
56046  },
56047  toGlsl: function (context, args) {
56048    assertArgsCount(args, 2);
56049    assertNumbers(args);
56050    return `mod(${expressionToGlsl(context, args[0])}, ${expressionToGlsl(
56051      context,
56052      args[1]
56053    )})`;
56054  },
56055};
56056
56057Operators['^'] = {
56058  getReturnType: function (args) {
56059    return ValueTypes.NUMBER;
56060  },
56061  toGlsl: function (context, args) {
56062    assertArgsCount(args, 2);
56063    assertNumbers(args);
56064    return `pow(${expressionToGlsl(context, args[0])}, ${expressionToGlsl(
56065      context,
56066      args[1]
56067    )})`;
56068  },
56069};
56070
56071Operators['abs'] = {
56072  getReturnType: function (args) {
56073    return ValueTypes.NUMBER;
56074  },
56075  toGlsl: function (context, args) {
56076    assertArgsCount(args, 1);
56077    assertNumbers(args);
56078    return `abs(${expressionToGlsl(context, args[0])})`;
56079  },
56080};
56081
56082Operators['floor'] = {
56083  getReturnType: function (args) {
56084    return ValueTypes.NUMBER;
56085  },
56086  toGlsl: function (context, args) {
56087    assertArgsCount(args, 1);
56088    assertNumbers(args);
56089    return `floor(${expressionToGlsl(context, args[0])})`;
56090  },
56091};
56092
56093Operators['round'] = {
56094  getReturnType: function (args) {
56095    return ValueTypes.NUMBER;
56096  },
56097  toGlsl: function (context, args) {
56098    assertArgsCount(args, 1);
56099    assertNumbers(args);
56100    return `floor(${expressionToGlsl(context, args[0])} + 0.5)`;
56101  },
56102};
56103
56104Operators['ceil'] = {
56105  getReturnType: function (args) {
56106    return ValueTypes.NUMBER;
56107  },
56108  toGlsl: function (context, args) {
56109    assertArgsCount(args, 1);
56110    assertNumbers(args);
56111    return `ceil(${expressionToGlsl(context, args[0])})`;
56112  },
56113};
56114
56115Operators['sin'] = {
56116  getReturnType: function (args) {
56117    return ValueTypes.NUMBER;
56118  },
56119  toGlsl: function (context, args) {
56120    assertArgsCount(args, 1);
56121    assertNumbers(args);
56122    return `sin(${expressionToGlsl(context, args[0])})`;
56123  },
56124};
56125
56126Operators['cos'] = {
56127  getReturnType: function (args) {
56128    return ValueTypes.NUMBER;
56129  },
56130  toGlsl: function (context, args) {
56131    assertArgsCount(args, 1);
56132    assertNumbers(args);
56133    return `cos(${expressionToGlsl(context, args[0])})`;
56134  },
56135};
56136
56137Operators['atan'] = {
56138  getReturnType: function (args) {
56139    return ValueTypes.NUMBER;
56140  },
56141  toGlsl: function (context, args) {
56142    assertArgsMinCount(args, 1);
56143    assertArgsMaxCount(args, 2);
56144    assertNumbers(args);
56145    return args.length === 2
56146      ? `atan(${expressionToGlsl(context, args[0])}, ${expressionToGlsl(
56147          context,
56148          args[1]
56149        )})`
56150      : `atan(${expressionToGlsl(context, args[0])})`;
56151  },
56152};
56153
56154Operators['>'] = {
56155  getReturnType: function (args) {
56156    return ValueTypes.BOOLEAN;
56157  },
56158  toGlsl: function (context, args) {
56159    assertArgsCount(args, 2);
56160    assertNumbers(args);
56161    return `(${expressionToGlsl(context, args[0])} > ${expressionToGlsl(
56162      context,
56163      args[1]
56164    )})`;
56165  },
56166};
56167
56168Operators['>='] = {
56169  getReturnType: function (args) {
56170    return ValueTypes.BOOLEAN;
56171  },
56172  toGlsl: function (context, args) {
56173    assertArgsCount(args, 2);
56174    assertNumbers(args);
56175    return `(${expressionToGlsl(context, args[0])} >= ${expressionToGlsl(
56176      context,
56177      args[1]
56178    )})`;
56179  },
56180};
56181
56182Operators['<'] = {
56183  getReturnType: function (args) {
56184    return ValueTypes.BOOLEAN;
56185  },
56186  toGlsl: function (context, args) {
56187    assertArgsCount(args, 2);
56188    assertNumbers(args);
56189    return `(${expressionToGlsl(context, args[0])} < ${expressionToGlsl(
56190      context,
56191      args[1]
56192    )})`;
56193  },
56194};
56195
56196Operators['<='] = {
56197  getReturnType: function (args) {
56198    return ValueTypes.BOOLEAN;
56199  },
56200  toGlsl: function (context, args) {
56201    assertArgsCount(args, 2);
56202    assertNumbers(args);
56203    return `(${expressionToGlsl(context, args[0])} <= ${expressionToGlsl(
56204      context,
56205      args[1]
56206    )})`;
56207  },
56208};
56209
56210function getEqualOperator(operator) {
56211  return {
56212    getReturnType: function (args) {
56213      return ValueTypes.BOOLEAN;
56214    },
56215    toGlsl: function (context, args) {
56216      assertArgsCount(args, 2);
56217
56218      // find common type
56219      let type = ValueTypes.ANY;
56220      for (let i = 0; i < args.length; i++) {
56221        type &= getValueType(args[i]);
56222      }
56223      if (type === ValueTypes.NONE) {
56224        throw new Error(
56225          `All arguments should be of compatible type, got ${JSON.stringify(
56226            args
56227          )} instead`
56228        );
56229      }
56230
56231      // Since it's not possible to have color types here, we can leave it out
56232      // This fixes issues in case the value type is ambiguously detected as a color (e.g. the string 'red')
56233      type &= ~ValueTypes.COLOR;
56234
56235      return `(${expressionToGlsl(
56236        context,
56237        args[0],
56238        type
56239      )} ${operator} ${expressionToGlsl(context, args[1], type)})`;
56240    },
56241  };
56242}
56243
56244Operators['=='] = getEqualOperator('==');
56245
56246Operators['!='] = getEqualOperator('!=');
56247
56248Operators['!'] = {
56249  getReturnType: function (args) {
56250    return ValueTypes.BOOLEAN;
56251  },
56252  toGlsl: function (context, args) {
56253    assertArgsCount(args, 1);
56254    assertBoolean(args[0]);
56255    return `(!${expressionToGlsl(context, args[0])})`;
56256  },
56257};
56258
56259function getDecisionOperator(operator) {
56260  return {
56261    getReturnType: function (args) {
56262      return ValueTypes.BOOLEAN;
56263    },
56264    toGlsl: function (context, args) {
56265      assertArgsMinCount(args, 2);
56266      for (let i = 0; i < args.length; i++) {
56267        assertBoolean(args[i]);
56268      }
56269      let result = '';
56270      result = args
56271        .map((arg) => expressionToGlsl(context, arg))
56272        .join(` ${operator} `);
56273      result = `(${result})`;
56274      return result;
56275    },
56276  };
56277}
56278
56279Operators['all'] = getDecisionOperator('&&');
56280
56281Operators['any'] = getDecisionOperator('||');
56282
56283Operators['between'] = {
56284  getReturnType: function (args) {
56285    return ValueTypes.BOOLEAN;
56286  },
56287  toGlsl: function (context, args) {
56288    assertArgsCount(args, 3);
56289    assertNumbers(args);
56290    const min = expressionToGlsl(context, args[1]);
56291    const max = expressionToGlsl(context, args[2]);
56292    const value = expressionToGlsl(context, args[0]);
56293    return `(${value} >= ${min} && ${value} <= ${max})`;
56294  },
56295};
56296
56297Operators['array'] = {
56298  getReturnType: function (args) {
56299    return ValueTypes.NUMBER_ARRAY;
56300  },
56301  toGlsl: function (context, args) {
56302    assertArgsMinCount(args, 2);
56303    assertArgsMaxCount(args, 4);
56304    assertNumbers(args);
56305    const parsedArgs = args.map(function (val) {
56306      return expressionToGlsl(context, val, ValueTypes.NUMBER);
56307    });
56308    return `vec${args.length}(${parsedArgs.join(', ')})`;
56309  },
56310};
56311
56312Operators['color'] = {
56313  getReturnType: function (args) {
56314    return ValueTypes.COLOR;
56315  },
56316  toGlsl: function (context, args) {
56317    assertArgsMinCount(args, 3);
56318    assertArgsMaxCount(args, 4);
56319    assertNumbers(args);
56320    const array = /** @type {Array<number>} */ (args);
56321    if (args.length === 3) {
56322      array.push(1);
56323    }
56324    const parsedArgs = args.map(function (val, i) {
56325      return (
56326        expressionToGlsl(context, val, ValueTypes.NUMBER) +
56327        (i < 3 ? ' / 255.0' : '')
56328      );
56329    });
56330    return `vec${args.length}(${parsedArgs.join(', ')})`;
56331  },
56332};
56333
56334Operators['interpolate'] = {
56335  getReturnType: function (args) {
56336    let type = ValueTypes.COLOR | ValueTypes.NUMBER;
56337    for (let i = 3; i < args.length; i += 2) {
56338      type = type & getValueType(args[i]);
56339    }
56340    return type;
56341  },
56342  toGlsl: function (context, args, typeHint) {
56343    assertArgsEven(args);
56344    assertArgsMinCount(args, 6);
56345
56346    // validate interpolation type
56347    const type = args[0];
56348    let interpolation;
56349    switch (type[0]) {
56350      case 'linear':
56351        interpolation = 1;
56352        break;
56353      case 'exponential':
56354        interpolation = type[1];
56355        break;
56356      default:
56357        interpolation = null;
56358    }
56359    if (!interpolation) {
56360      throw new Error(
56361        `Invalid interpolation type for "interpolate" operator, received: ${JSON.stringify(
56362          type
56363        )}`
56364      );
56365    }
56366
56367    // compute input/output types
56368    typeHint = typeHint !== undefined ? typeHint : ValueTypes.ANY;
56369    const outputType = Operators['interpolate'].getReturnType(args) & typeHint;
56370    assertUniqueInferredType(args, outputType);
56371
56372    const input = expressionToGlsl(context, args[1]);
56373    const exponent = numberToGlsl(interpolation);
56374
56375    let result = '';
56376    for (let i = 2; i < args.length - 2; i += 2) {
56377      const stop1 = expressionToGlsl(context, args[i]);
56378      const output1 =
56379        result || expressionToGlsl(context, args[i + 1], outputType);
56380      const stop2 = expressionToGlsl(context, args[i + 2]);
56381      const output2 = expressionToGlsl(context, args[i + 3], outputType);
56382      result = `mix(${output1}, ${output2}, pow(clamp((${input} - ${stop1}) / (${stop2} - ${stop1}), 0.0, 1.0), ${exponent}))`;
56383    }
56384    return result;
56385  },
56386};
56387
56388Operators['match'] = {
56389  getReturnType: function (args) {
56390    let type = ValueTypes.ANY;
56391    for (let i = 2; i < args.length; i += 2) {
56392      type = type & getValueType(args[i]);
56393    }
56394    type = type & getValueType(args[args.length - 1]);
56395    return type;
56396  },
56397  toGlsl: function (context, args, typeHint) {
56398    assertArgsEven(args);
56399    assertArgsMinCount(args, 4);
56400
56401    typeHint = typeHint !== undefined ? typeHint : ValueTypes.ANY;
56402    const outputType = Operators['match'].getReturnType(args) & typeHint;
56403    assertUniqueInferredType(args, outputType);
56404
56405    const input = expressionToGlsl(context, args[0]);
56406    const fallback = expressionToGlsl(
56407      context,
56408      args[args.length - 1],
56409      outputType
56410    );
56411    let result = null;
56412    for (let i = args.length - 3; i >= 1; i -= 2) {
56413      const match = expressionToGlsl(context, args[i]);
56414      const output = expressionToGlsl(context, args[i + 1], outputType);
56415      result = `(${input} == ${match} ? ${output} : ${result || fallback})`;
56416    }
56417    return result;
56418  },
56419};
56420
56421Operators['case'] = {
56422  getReturnType: function (args) {
56423    let type = ValueTypes.ANY;
56424    for (let i = 1; i < args.length; i += 2) {
56425      type = type & getValueType(args[i]);
56426    }
56427    type = type & getValueType(args[args.length - 1]);
56428    return type;
56429  },
56430  toGlsl: function (context, args, typeHint) {
56431    assertArgsOdd(args);
56432    assertArgsMinCount(args, 3);
56433
56434    typeHint = typeHint !== undefined ? typeHint : ValueTypes.ANY;
56435    const outputType = Operators['case'].getReturnType(args) & typeHint;
56436    assertUniqueInferredType(args, outputType);
56437    for (let i = 0; i < args.length - 1; i += 2) {
56438      assertBoolean(args[i]);
56439    }
56440
56441    const fallback = expressionToGlsl(
56442      context,
56443      args[args.length - 1],
56444      outputType
56445    );
56446    let result = null;
56447    for (let i = args.length - 3; i >= 0; i -= 2) {
56448      const condition = expressionToGlsl(context, args[i]);
56449      const output = expressionToGlsl(context, args[i + 1], outputType);
56450      result = `(${condition} ? ${output} : ${result || fallback})`;
56451    }
56452    return result;
56453  },
56454};
56455
56456;// CONCATENATED MODULE: ./node_modules/ol/layer/WebGLTile.js
56457/**
56458 * @module ol/layer/WebGLTile
56459 */
56460
56461
56462
56463
56464
56465/**
56466 * @typedef {import("../source/DataTile.js").default|import("../source/TileImage.js").default} SourceType
56467 */
56468
56469/**
56470 * @typedef {Object} Style
56471 * Translates tile data to rendered pixels.
56472 *
56473 * @property {Object<string, (string|number)>} [variables] Style variables.  Each variable must hold a number or string.  These
56474 * variables can be used in the `color`, `brightness`, `contrast`, `exposure`, `saturation` and `gamma`
56475 * {@link import("../style/expressions.js").ExpressionValue expressions}, using the `['var', 'varName']` operator.
56476 * To update style variables, use the {@link import("./WebGLTile.js").default#updateStyleVariables} method.
56477 * @property {import("../style/expressions.js").ExpressionValue} [color] An expression applied to color values.
56478 * @property {import("../style/expressions.js").ExpressionValue} [brightness=0] Value used to decrease or increase
56479 * the layer brightness.  Values range from -1 to 1.
56480 * @property {import("../style/expressions.js").ExpressionValue} [contrast=0] Value used to decrease or increase
56481 * the layer contrast.  Values range from -1 to 1.
56482 * @property {import("../style/expressions.js").ExpressionValue} [exposure=0] Value used to decrease or increase
56483 * the layer exposure.  Values range from -1 to 1.
56484 * @property {import("../style/expressions.js").ExpressionValue} [saturation=0] Value used to decrease or increase
56485 * the layer saturation.  Values range from -1 to 1.
56486 * @property {import("../style/expressions.js").ExpressionValue} [gamma=1] Apply a gamma correction to the layer.
56487 * Values range from 0 to infinity.
56488 */
56489
56490/**
56491 * @typedef {Object} Options
56492 * @property {Style} [style] Style to apply to the layer.
56493 * @property {string} [className='ol-layer'] A CSS class name to set to the layer element.
56494 * @property {number} [opacity=1] Opacity (0, 1).
56495 * @property {boolean} [visible=true] Visibility.
56496 * @property {import("../extent.js").Extent} [extent] The bounding extent for layer rendering.  The layer will not be
56497 * rendered outside of this extent.
56498 * @property {number} [zIndex] The z-index for layer rendering.  At rendering time, the layers
56499 * will be ordered, first by Z-index and then by position. When `undefined`, a `zIndex` of 0 is assumed
56500 * for layers that are added to the map's `layers` collection, or `Infinity` when the layer's `setMap()`
56501 * method was used.
56502 * @property {number} [minResolution] The minimum resolution (inclusive) at which this layer will be
56503 * visible.
56504 * @property {number} [maxResolution] The maximum resolution (exclusive) below which this layer will
56505 * be visible.
56506 * @property {number} [minZoom] The minimum view zoom level (exclusive) above which this layer will be
56507 * visible.
56508 * @property {number} [maxZoom] The maximum view zoom level (inclusive) at which this layer will
56509 * be visible.
56510 * @property {number} [preload=0] Preload. Load low-resolution tiles up to `preload` levels. `0`
56511 * means no preloading.
56512 * @property {SourceType} [source] Source for this layer.
56513 * @property {Array<SourceType>|function(import("../extent.js").Extent, number):Array<SourceType>} [sources] Array
56514 * of sources for this layer. Takes precedence over `source`. Can either be an array of sources, or a function that
56515 * expects an extent and a resolution (in view projection units per pixel) and returns an array of sources. See
56516 * {@link module:ol/source.sourcesFromTileGrid} for a helper function to generate sources that are organized in a
56517 * pyramid following the same pattern as a tile grid. **Note:** All sources must have the same band count and content.
56518 * @property {import("../Map.js").default} [map] Sets the layer as overlay on a map. The map will not manage
56519 * this layer in its layers collection, and the layer will be rendered on top. This is useful for
56520 * temporary layers. The standard way to add a layer to a map and have it managed by the map is to
56521 * use {@link module:ol/Map~Map#addLayer}.
56522 * @property {boolean} [useInterimTilesOnError=true] Use interim tiles on error.
56523 * @property {number} [cacheSize=512] The internal texture cache size.  This needs to be large enough to render
56524 * two zoom levels worth of tiles.
56525 */
56526
56527/**
56528 * @typedef {Object} ParsedStyle
56529 * @property {string} vertexShader The vertex shader.
56530 * @property {string} fragmentShader The fragment shader.
56531 * @property {Object<string,import("../webgl/Helper.js").UniformValue>} uniforms Uniform definitions.
56532 * @property {Array<import("../webgl/PaletteTexture.js").default>} paletteTextures Palette textures.
56533 */
56534
56535/**
56536 * @param {Style} style The layer style.
56537 * @param {number} [bandCount] The number of bands.
56538 * @return {ParsedStyle} Shaders and uniforms generated from the style.
56539 */
56540function parseStyle(style, bandCount) {
56541  const vertexShader = `
56542    attribute vec2 ${Attributes.TEXTURE_COORD};
56543    uniform mat4 ${Uniforms.TILE_TRANSFORM};
56544    uniform float ${Uniforms.TEXTURE_PIXEL_WIDTH};
56545    uniform float ${Uniforms.TEXTURE_PIXEL_HEIGHT};
56546    uniform float ${Uniforms.TEXTURE_RESOLUTION};
56547    uniform float ${Uniforms.TEXTURE_ORIGIN_X};
56548    uniform float ${Uniforms.TEXTURE_ORIGIN_Y};
56549    uniform float ${Uniforms.DEPTH};
56550
56551    varying vec2 v_textureCoord;
56552    varying vec2 v_mapCoord;
56553
56554    void main() {
56555      v_textureCoord = ${Attributes.TEXTURE_COORD};
56556      v_mapCoord = vec2(
56557        ${Uniforms.TEXTURE_ORIGIN_X} + ${Uniforms.TEXTURE_RESOLUTION} * ${Uniforms.TEXTURE_PIXEL_WIDTH} * v_textureCoord[0],
56558        ${Uniforms.TEXTURE_ORIGIN_Y} - ${Uniforms.TEXTURE_RESOLUTION} * ${Uniforms.TEXTURE_PIXEL_HEIGHT} * v_textureCoord[1]
56559      );
56560      gl_Position = ${Uniforms.TILE_TRANSFORM} * vec4(${Attributes.TEXTURE_COORD}, ${Uniforms.DEPTH}, 1.0);
56561    }
56562  `;
56563
56564  /**
56565   * @type {import("../style/expressions.js").ParsingContext}
56566   */
56567  const context = {
56568    inFragmentShader: true,
56569    variables: [],
56570    attributes: [],
56571    stringLiteralsMap: {},
56572    functions: {},
56573    bandCount: bandCount,
56574  };
56575
56576  const pipeline = [];
56577
56578  if (style.color !== undefined) {
56579    const color = expressionToGlsl(context, style.color, ValueTypes.COLOR);
56580    pipeline.push(`color = ${color};`);
56581  }
56582
56583  if (style.contrast !== undefined) {
56584    const contrast = expressionToGlsl(
56585      context,
56586      style.contrast,
56587      ValueTypes.NUMBER
56588    );
56589    pipeline.push(
56590      `color.rgb = clamp((${contrast} + 1.0) * color.rgb - (${contrast} / 2.0), vec3(0.0, 0.0, 0.0), vec3(1.0, 1.0, 1.0));`
56591    );
56592  }
56593
56594  if (style.exposure !== undefined) {
56595    const exposure = expressionToGlsl(
56596      context,
56597      style.exposure,
56598      ValueTypes.NUMBER
56599    );
56600    pipeline.push(
56601      `color.rgb = clamp((${exposure} + 1.0) * color.rgb, vec3(0.0, 0.0, 0.0), vec3(1.0, 1.0, 1.0));`
56602    );
56603  }
56604
56605  if (style.saturation !== undefined) {
56606    const saturation = expressionToGlsl(
56607      context,
56608      style.saturation,
56609      ValueTypes.NUMBER
56610    );
56611    pipeline.push(`
56612      float saturation = ${saturation} + 1.0;
56613      float sr = (1.0 - saturation) * 0.2126;
56614      float sg = (1.0 - saturation) * 0.7152;
56615      float sb = (1.0 - saturation) * 0.0722;
56616      mat3 saturationMatrix = mat3(
56617        sr + saturation, sr, sr,
56618        sg, sg + saturation, sg,
56619        sb, sb, sb + saturation
56620      );
56621      color.rgb = clamp(saturationMatrix * color.rgb, vec3(0.0, 0.0, 0.0), vec3(1.0, 1.0, 1.0));
56622    `);
56623  }
56624
56625  if (style.gamma !== undefined) {
56626    const gamma = expressionToGlsl(context, style.gamma, ValueTypes.NUMBER);
56627    pipeline.push(`color.rgb = pow(color.rgb, vec3(1.0 / ${gamma}));`);
56628  }
56629
56630  if (style.brightness !== undefined) {
56631    const brightness = expressionToGlsl(
56632      context,
56633      style.brightness,
56634      ValueTypes.NUMBER
56635    );
56636    pipeline.push(
56637      `color.rgb = clamp(color.rgb + ${brightness}, vec3(0.0, 0.0, 0.0), vec3(1.0, 1.0, 1.0));`
56638    );
56639  }
56640
56641  /** @type {Object<string,import("../webgl/Helper").UniformValue>} */
56642  const uniforms = {};
56643
56644  const numVariables = context.variables.length;
56645  if (numVariables > 1 && !style.variables) {
56646    throw new Error(
56647      `Missing variables in style (expected ${context.variables})`
56648    );
56649  }
56650
56651  for (let i = 0; i < numVariables; ++i) {
56652    const variableName = context.variables[i];
56653    if (!(variableName in style.variables)) {
56654      throw new Error(`Missing '${variableName}' in style variables`);
56655    }
56656    const uniformName = uniformNameForVariable(variableName);
56657    uniforms[uniformName] = function () {
56658      let value = style.variables[variableName];
56659      if (typeof value === 'string') {
56660        value = getStringNumberEquivalent(context, value);
56661      }
56662      return value !== undefined ? value : -9999999; // to avoid matching with the first string literal
56663    };
56664  }
56665
56666  const uniformDeclarations = Object.keys(uniforms).map(function (name) {
56667    return `uniform float ${name};`;
56668  });
56669
56670  const textureCount = Math.ceil(bandCount / 4);
56671  uniformDeclarations.push(
56672    `uniform sampler2D ${Uniforms.TILE_TEXTURE_ARRAY}[${textureCount}];`
56673  );
56674
56675  if (context.paletteTextures) {
56676    uniformDeclarations.push(
56677      `uniform sampler2D ${PALETTE_TEXTURE_ARRAY}[${context.paletteTextures.length}];`
56678    );
56679  }
56680
56681  const functionDefintions = Object.keys(context.functions).map(function (
56682    name
56683  ) {
56684    return context.functions[name];
56685  });
56686
56687  const fragmentShader = `
56688    #ifdef GL_FRAGMENT_PRECISION_HIGH
56689    precision highp float;
56690    #else
56691    precision mediump float;
56692    #endif
56693
56694    varying vec2 v_textureCoord;
56695    varying vec2 v_mapCoord;
56696    uniform vec4 ${Uniforms.RENDER_EXTENT};
56697    uniform float ${Uniforms.TRANSITION_ALPHA};
56698    uniform float ${Uniforms.TEXTURE_PIXEL_WIDTH};
56699    uniform float ${Uniforms.TEXTURE_PIXEL_HEIGHT};
56700    uniform float ${Uniforms.RESOLUTION};
56701    uniform float ${Uniforms.ZOOM};
56702
56703    ${uniformDeclarations.join('\n')}
56704
56705    ${functionDefintions.join('\n')}
56706
56707    void main() {
56708      if (
56709        v_mapCoord[0] < ${Uniforms.RENDER_EXTENT}[0] ||
56710        v_mapCoord[1] < ${Uniforms.RENDER_EXTENT}[1] ||
56711        v_mapCoord[0] > ${Uniforms.RENDER_EXTENT}[2] ||
56712        v_mapCoord[1] > ${Uniforms.RENDER_EXTENT}[3]
56713      ) {
56714        discard;
56715      }
56716
56717      vec4 color = texture2D(${
56718        Uniforms.TILE_TEXTURE_ARRAY
56719      }[0],  v_textureCoord);
56720
56721      ${pipeline.join('\n')}
56722
56723      if (color.a == 0.0) {
56724        discard;
56725      }
56726
56727      gl_FragColor = color;
56728      gl_FragColor.rgb *= gl_FragColor.a;
56729      gl_FragColor *= ${Uniforms.TRANSITION_ALPHA};
56730    }`;
56731
56732  return {
56733    vertexShader: vertexShader,
56734    fragmentShader: fragmentShader,
56735    uniforms: uniforms,
56736    paletteTextures: context.paletteTextures,
56737  };
56738}
56739
56740/**
56741 * @classdesc
56742 * For layer sources that provide pre-rendered, tiled images in grids that are
56743 * organized by zoom levels for specific resolutions.
56744 * Note that any property set in the options is set as a {@link module:ol/Object~BaseObject}
56745 * property on the layer object; for example, setting `title: 'My Title'` in the
56746 * options means that `title` is observable, and has get/set accessors.
56747 *
56748 * @extends BaseTileLayer<SourceType, WebGLTileLayerRenderer>
56749 * @fires import("../render/Event.js").RenderEvent
56750 * @api
56751 */
56752class WebGLTileLayer extends BaseTile {
56753  /**
56754   * @param {Options} options Tile layer options.
56755   */
56756  constructor(options) {
56757    options = options ? Object.assign({}, options) : {};
56758
56759    const style = options.style || {};
56760    delete options.style;
56761
56762    const cacheSize = options.cacheSize;
56763    delete options.cacheSize;
56764
56765    super(options);
56766
56767    /**
56768     * @type {Array<SourceType>|function(import("../extent.js").Extent, number):Array<SourceType>}
56769     * @private
56770     */
56771    this.sources_ = options.sources;
56772
56773    /**
56774     * @type {SourceType|null}
56775     * @private
56776     */
56777    this.renderedSource_ = null;
56778
56779    /**
56780     * @type {number}
56781     * @private
56782     */
56783    this.renderedResolution_ = NaN;
56784
56785    /**
56786     * @type {Style}
56787     * @private
56788     */
56789    this.style_ = style;
56790
56791    /**
56792     * @type {number}
56793     * @private
56794     */
56795    this.cacheSize_ = cacheSize;
56796
56797    /**
56798     * @type {Object<string, (string|number)>}
56799     * @private
56800     */
56801    this.styleVariables_ = this.style_.variables || {};
56802
56803    this.addChangeListener(layer_Property.SOURCE, this.handleSourceUpdate_);
56804  }
56805
56806  /**
56807   * Gets the sources for this layer, for a given extent and resolution.
56808   * @param {import("../extent.js").Extent} extent Extent.
56809   * @param {number} resolution Resolution.
56810   * @return {Array<SourceType>} Sources.
56811   */
56812  getSources(extent, resolution) {
56813    const source = this.getSource();
56814    return this.sources_
56815      ? typeof this.sources_ === 'function'
56816        ? this.sources_(extent, resolution)
56817        : this.sources_
56818      : source
56819      ? [source]
56820      : [];
56821  }
56822
56823  /**
56824   * @return {SourceType} The source being rendered.
56825   */
56826  getRenderSource() {
56827    return this.renderedSource_ || this.getSource();
56828  }
56829
56830  /**
56831   * @return {import("../source/Source.js").State} Source state.
56832   */
56833  getSourceState() {
56834    const source = this.getRenderSource();
56835    return source ? source.getState() : 'undefined';
56836  }
56837
56838  /**
56839   * @private
56840   */
56841  handleSourceUpdate_() {
56842    if (this.getSource()) {
56843      this.setStyle(this.style_);
56844    }
56845  }
56846
56847  /**
56848   * @private
56849   * @return {number} The number of source bands.
56850   */
56851  getSourceBandCount_() {
56852    const max = Number.MAX_SAFE_INTEGER;
56853    const sources = this.getSources([-max, -max, max, max], max);
56854    return sources && sources.length && 'bandCount' in sources[0]
56855      ? sources[0].bandCount
56856      : 4;
56857  }
56858
56859  createRenderer() {
56860    const parsedStyle = parseStyle(this.style_, this.getSourceBandCount_());
56861
56862    return new webgl_TileLayer(this, {
56863      vertexShader: parsedStyle.vertexShader,
56864      fragmentShader: parsedStyle.fragmentShader,
56865      uniforms: parsedStyle.uniforms,
56866      cacheSize: this.cacheSize_,
56867      paletteTextures: parsedStyle.paletteTextures,
56868    });
56869  }
56870
56871  /**
56872   * @param {import("../Map").FrameState} frameState Frame state.
56873   * @param {Array<SourceType>} sources Sources.
56874   * @return {HTMLElement} Canvas.
56875   */
56876  renderSources(frameState, sources) {
56877    const layerRenderer = this.getRenderer();
56878    let canvas;
56879    for (let i = 0, ii = sources.length; i < ii; ++i) {
56880      this.renderedSource_ = sources[i];
56881      if (layerRenderer.prepareFrame(frameState)) {
56882        canvas = layerRenderer.renderFrame(frameState);
56883      }
56884    }
56885    return canvas;
56886  }
56887
56888  /**
56889   * @param {?import("../Map.js").FrameState} frameState Frame state.
56890   * @param {HTMLElement} target Target which the renderer may (but need not) use
56891   * for rendering its content.
56892   * @return {HTMLElement} The rendered element.
56893   */
56894  render(frameState, target) {
56895    this.rendered = true;
56896    const viewState = frameState.viewState;
56897    const sources = this.getSources(frameState.extent, viewState.resolution);
56898    let ready = true;
56899    for (let i = 0, ii = sources.length; i < ii; ++i) {
56900      const source = sources[i];
56901      const sourceState = source.getState();
56902      if (sourceState == 'loading') {
56903        const onChange = () => {
56904          if (source.getState() == 'ready') {
56905            source.removeEventListener('change', onChange);
56906            this.changed();
56907          }
56908        };
56909        source.addEventListener('change', onChange);
56910      }
56911      ready = ready && sourceState == 'ready';
56912    }
56913    const canvas = this.renderSources(frameState, sources);
56914    if (this.getRenderer().renderComplete && ready) {
56915      // Fully rendered, done.
56916      this.renderedResolution_ = viewState.resolution;
56917      return canvas;
56918    }
56919    // Render sources from previously fully rendered frames
56920    if (this.renderedResolution_ > 0.5 * viewState.resolution) {
56921      const altSources = this.getSources(
56922        frameState.extent,
56923        this.renderedResolution_
56924      ).filter((source) => !sources.includes(source));
56925      if (altSources.length > 0) {
56926        return this.renderSources(frameState, altSources);
56927      }
56928    }
56929    return canvas;
56930  }
56931
56932  /**
56933   * Update the layer style.  The `updateStyleVariables` function is a more efficient
56934   * way to update layer rendering.  In cases where the whole style needs to be updated,
56935   * this method may be called instead.  Note that calling this method will also replace
56936   * any previously set variables, so the new style also needs to include new variables,
56937   * if needed.
56938   * @param {Style} style The new style.
56939   */
56940  setStyle(style) {
56941    this.styleVariables_ = style.variables || {};
56942    this.style_ = style;
56943    const parsedStyle = parseStyle(this.style_, this.getSourceBandCount_());
56944    const renderer = this.getRenderer();
56945    renderer.reset({
56946      vertexShader: parsedStyle.vertexShader,
56947      fragmentShader: parsedStyle.fragmentShader,
56948      uniforms: parsedStyle.uniforms,
56949      paletteTextures: parsedStyle.paletteTextures,
56950    });
56951    this.changed();
56952  }
56953
56954  /**
56955   * Update any variables used by the layer style and trigger a re-render.
56956   * @param {Object<string, number>} variables Variables to update.
56957   * @api
56958   */
56959  updateStyleVariables(variables) {
56960    Object.assign(this.styleVariables_, variables);
56961    this.changed();
56962  }
56963}
56964
56965/**
56966 * Clean up underlying WebGL resources.
56967 * @function
56968 * @api
56969 */
56970WebGLTileLayer.prototype.dispose;
56971
56972/* harmony default export */ const WebGLTile = (WebGLTileLayer);
56973
56974;// CONCATENATED MODULE: ./node_modules/ol/geom/GeometryCollection.js
56975/**
56976 * @module ol/geom/GeometryCollection
56977 */
56978
56979
56980
56981
56982
56983/**
56984 * @classdesc
56985 * An array of {@link module:ol/geom/Geometry~Geometry} objects.
56986 *
56987 * @api
56988 */
56989class GeometryCollection extends geom_Geometry {
56990  /**
56991   * @param {Array<Geometry>} [geometries] Geometries.
56992   */
56993  constructor(geometries) {
56994    super();
56995
56996    /**
56997     * @private
56998     * @type {Array<Geometry>}
56999     */
57000    this.geometries_ = geometries ? geometries : null;
57001
57002    /**
57003     * @type {Array<import("../events.js").EventsKey>}
57004     */
57005    this.changeEventsKeys_ = [];
57006
57007    this.listenGeometriesChange_();
57008  }
57009
57010  /**
57011   * @private
57012   */
57013  unlistenGeometriesChange_() {
57014    this.changeEventsKeys_.forEach(unlistenByKey);
57015    this.changeEventsKeys_.length = 0;
57016  }
57017
57018  /**
57019   * @private
57020   */
57021  listenGeometriesChange_() {
57022    if (!this.geometries_) {
57023      return;
57024    }
57025    for (let i = 0, ii = this.geometries_.length; i < ii; ++i) {
57026      this.changeEventsKeys_.push(
57027        listen(this.geometries_[i], EventType.CHANGE, this.changed, this)
57028      );
57029    }
57030  }
57031
57032  /**
57033   * Make a complete copy of the geometry.
57034   * @return {!GeometryCollection} Clone.
57035   * @api
57036   */
57037  clone() {
57038    const geometryCollection = new GeometryCollection(null);
57039    geometryCollection.setGeometries(this.geometries_);
57040    geometryCollection.applyProperties(this);
57041    return geometryCollection;
57042  }
57043
57044  /**
57045   * @param {number} x X.
57046   * @param {number} y Y.
57047   * @param {import("../coordinate.js").Coordinate} closestPoint Closest point.
57048   * @param {number} minSquaredDistance Minimum squared distance.
57049   * @return {number} Minimum squared distance.
57050   */
57051  closestPointXY(x, y, closestPoint, minSquaredDistance) {
57052    if (minSquaredDistance < closestSquaredDistanceXY(this.getExtent(), x, y)) {
57053      return minSquaredDistance;
57054    }
57055    const geometries = this.geometries_;
57056    for (let i = 0, ii = geometries.length; i < ii; ++i) {
57057      minSquaredDistance = geometries[i].closestPointXY(
57058        x,
57059        y,
57060        closestPoint,
57061        minSquaredDistance
57062      );
57063    }
57064    return minSquaredDistance;
57065  }
57066
57067  /**
57068   * @param {number} x X.
57069   * @param {number} y Y.
57070   * @return {boolean} Contains (x, y).
57071   */
57072  containsXY(x, y) {
57073    const geometries = this.geometries_;
57074    for (let i = 0, ii = geometries.length; i < ii; ++i) {
57075      if (geometries[i].containsXY(x, y)) {
57076        return true;
57077      }
57078    }
57079    return false;
57080  }
57081
57082  /**
57083   * @param {import("../extent.js").Extent} extent Extent.
57084   * @protected
57085   * @return {import("../extent.js").Extent} extent Extent.
57086   */
57087  computeExtent(extent) {
57088    createOrUpdateEmpty(extent);
57089    const geometries = this.geometries_;
57090    for (let i = 0, ii = geometries.length; i < ii; ++i) {
57091      extent_extend(extent, geometries[i].getExtent());
57092    }
57093    return extent;
57094  }
57095
57096  /**
57097   * Return the geometries that make up this geometry collection.
57098   * @return {Array<Geometry>} Geometries.
57099   * @api
57100   */
57101  getGeometries() {
57102    return cloneGeometries(this.geometries_);
57103  }
57104
57105  /**
57106   * @return {Array<Geometry>} Geometries.
57107   */
57108  getGeometriesArray() {
57109    return this.geometries_;
57110  }
57111
57112  /**
57113   * @return {Array<Geometry>} Geometries.
57114   */
57115  getGeometriesArrayRecursive() {
57116    /** @type {Array<Geometry>} */
57117    let geometriesArray = [];
57118    const geometries = this.geometries_;
57119    for (let i = 0, ii = geometries.length; i < ii; ++i) {
57120      if (geometries[i].getType() === this.getType()) {
57121        geometriesArray = geometriesArray.concat(
57122          /** @type {GeometryCollection} */ (
57123            geometries[i]
57124          ).getGeometriesArrayRecursive()
57125        );
57126      } else {
57127        geometriesArray.push(geometries[i]);
57128      }
57129    }
57130    return geometriesArray;
57131  }
57132
57133  /**
57134   * Create a simplified version of this geometry using the Douglas Peucker algorithm.
57135   * @param {number} squaredTolerance Squared tolerance.
57136   * @return {GeometryCollection} Simplified GeometryCollection.
57137   */
57138  getSimplifiedGeometry(squaredTolerance) {
57139    if (this.simplifiedGeometryRevision !== this.getRevision()) {
57140      this.simplifiedGeometryMaxMinSquaredTolerance = 0;
57141      this.simplifiedGeometryRevision = this.getRevision();
57142    }
57143    if (
57144      squaredTolerance < 0 ||
57145      (this.simplifiedGeometryMaxMinSquaredTolerance !== 0 &&
57146        squaredTolerance < this.simplifiedGeometryMaxMinSquaredTolerance)
57147    ) {
57148      return this;
57149    }
57150
57151    const simplifiedGeometries = [];
57152    const geometries = this.geometries_;
57153    let simplified = false;
57154    for (let i = 0, ii = geometries.length; i < ii; ++i) {
57155      const geometry = geometries[i];
57156      const simplifiedGeometry =
57157        geometry.getSimplifiedGeometry(squaredTolerance);
57158      simplifiedGeometries.push(simplifiedGeometry);
57159      if (simplifiedGeometry !== geometry) {
57160        simplified = true;
57161      }
57162    }
57163    if (simplified) {
57164      const simplifiedGeometryCollection = new GeometryCollection(null);
57165      simplifiedGeometryCollection.setGeometriesArray(simplifiedGeometries);
57166      return simplifiedGeometryCollection;
57167    } else {
57168      this.simplifiedGeometryMaxMinSquaredTolerance = squaredTolerance;
57169      return this;
57170    }
57171  }
57172
57173  /**
57174   * Get the type of this geometry.
57175   * @return {import("./Geometry.js").Type} Geometry type.
57176   * @api
57177   */
57178  getType() {
57179    return 'GeometryCollection';
57180  }
57181
57182  /**
57183   * Test if the geometry and the passed extent intersect.
57184   * @param {import("../extent.js").Extent} extent Extent.
57185   * @return {boolean} `true` if the geometry and the extent intersect.
57186   * @api
57187   */
57188  intersectsExtent(extent) {
57189    const geometries = this.geometries_;
57190    for (let i = 0, ii = geometries.length; i < ii; ++i) {
57191      if (geometries[i].intersectsExtent(extent)) {
57192        return true;
57193      }
57194    }
57195    return false;
57196  }
57197
57198  /**
57199   * @return {boolean} Is empty.
57200   */
57201  isEmpty() {
57202    return this.geometries_.length === 0;
57203  }
57204
57205  /**
57206   * Rotate the geometry around a given coordinate. This modifies the geometry
57207   * coordinates in place.
57208   * @param {number} angle Rotation angle in radians.
57209   * @param {import("../coordinate.js").Coordinate} anchor The rotation center.
57210   * @api
57211   */
57212  rotate(angle, anchor) {
57213    const geometries = this.geometries_;
57214    for (let i = 0, ii = geometries.length; i < ii; ++i) {
57215      geometries[i].rotate(angle, anchor);
57216    }
57217    this.changed();
57218  }
57219
57220  /**
57221   * Scale the geometry (with an optional origin).  This modifies the geometry
57222   * coordinates in place.
57223   * @abstract
57224   * @param {number} sx The scaling factor in the x-direction.
57225   * @param {number} [sy] The scaling factor in the y-direction (defaults to sx).
57226   * @param {import("../coordinate.js").Coordinate} [anchor] The scale origin (defaults to the center
57227   *     of the geometry extent).
57228   * @api
57229   */
57230  scale(sx, sy, anchor) {
57231    if (!anchor) {
57232      anchor = getCenter(this.getExtent());
57233    }
57234    const geometries = this.geometries_;
57235    for (let i = 0, ii = geometries.length; i < ii; ++i) {
57236      geometries[i].scale(sx, sy, anchor);
57237    }
57238    this.changed();
57239  }
57240
57241  /**
57242   * Set the geometries that make up this geometry collection.
57243   * @param {Array<Geometry>} geometries Geometries.
57244   * @api
57245   */
57246  setGeometries(geometries) {
57247    this.setGeometriesArray(cloneGeometries(geometries));
57248  }
57249
57250  /**
57251   * @param {Array<Geometry>} geometries Geometries.
57252   */
57253  setGeometriesArray(geometries) {
57254    this.unlistenGeometriesChange_();
57255    this.geometries_ = geometries;
57256    this.listenGeometriesChange_();
57257    this.changed();
57258  }
57259
57260  /**
57261   * Apply a transform function to the coordinates of the geometry.
57262   * The geometry is modified in place.
57263   * If you do not want the geometry modified in place, first `clone()` it and
57264   * then use this function on the clone.
57265   * @param {import("../proj.js").TransformFunction} transformFn Transform function.
57266   * Called with a flat array of geometry coordinates.
57267   * @api
57268   */
57269  applyTransform(transformFn) {
57270    const geometries = this.geometries_;
57271    for (let i = 0, ii = geometries.length; i < ii; ++i) {
57272      geometries[i].applyTransform(transformFn);
57273    }
57274    this.changed();
57275  }
57276
57277  /**
57278   * Translate the geometry.  This modifies the geometry coordinates in place.  If
57279   * instead you want a new geometry, first `clone()` this geometry.
57280   * @param {number} deltaX Delta X.
57281   * @param {number} deltaY Delta Y.
57282   * @api
57283   */
57284  translate(deltaX, deltaY) {
57285    const geometries = this.geometries_;
57286    for (let i = 0, ii = geometries.length; i < ii; ++i) {
57287      geometries[i].translate(deltaX, deltaY);
57288    }
57289    this.changed();
57290  }
57291
57292  /**
57293   * Clean up.
57294   */
57295  disposeInternal() {
57296    this.unlistenGeometriesChange_();
57297    super.disposeInternal();
57298  }
57299}
57300
57301/**
57302 * @param {Array<Geometry>} geometries Geometries.
57303 * @return {Array<Geometry>} Cloned geometries.
57304 */
57305function cloneGeometries(geometries) {
57306  const clonedGeometries = [];
57307  for (let i = 0, ii = geometries.length; i < ii; ++i) {
57308    clonedGeometries.push(geometries[i].clone());
57309  }
57310  return clonedGeometries;
57311}
57312
57313/* harmony default export */ const geom_GeometryCollection = (GeometryCollection);
57314
57315;// CONCATENATED MODULE: ./node_modules/ol/format/Feature.js
57316/**
57317 * @module ol/format/Feature
57318 */
57319
57320
57321
57322/**
57323 * @typedef {Object} ReadOptions
57324 * @property {import("../proj.js").ProjectionLike} [dataProjection] Projection of the data we are reading.
57325 * If not provided, the projection will be derived from the data (where possible) or
57326 * the `dataProjection` of the format is assigned (where set). If the projection
57327 * can not be derived from the data and if no `dataProjection` is set for a format,
57328 * the features will not be reprojected.
57329 * @property {import("../extent.js").Extent} [extent] Tile extent in map units of the tile being read.
57330 * This is only required when reading data with tile pixels as geometry units. When configured,
57331 * a `dataProjection` with `TILE_PIXELS` as `units` and the tile's pixel extent as `extent` needs to be
57332 * provided.
57333 * @property {import("../proj.js").ProjectionLike} [featureProjection] Projection of the feature geometries
57334 * created by the format reader. If not provided, features will be returned in the
57335 * `dataProjection`.
57336 */
57337
57338/**
57339 * @typedef {Object} WriteOptions
57340 * @property {import("../proj.js").ProjectionLike} [dataProjection] Projection of the data we are writing.
57341 * If not provided, the `dataProjection` of the format is assigned (where set).
57342 * If no `dataProjection` is set for a format, the features will be returned
57343 * in the `featureProjection`.
57344 * @property {import("../proj.js").ProjectionLike} [featureProjection] Projection of the feature geometries
57345 * that will be serialized by the format writer. If not provided, geometries are assumed
57346 * to be in the `dataProjection` if that is set; in other words, they are not transformed.
57347 * @property {boolean} [rightHanded] When writing geometries, follow the right-hand
57348 * rule for linear ring orientation.  This means that polygons will have counter-clockwise
57349 * exterior rings and clockwise interior rings.  By default, coordinates are serialized
57350 * as they are provided at construction.  If `true`, the right-hand rule will
57351 * be applied.  If `false`, the left-hand rule will be applied (clockwise for
57352 * exterior and counter-clockwise for interior rings).  Note that not all
57353 * formats support this.  The GeoJSON format does use this property when writing
57354 * geometries.
57355 * @property {number} [decimals] Maximum number of decimal places for coordinates.
57356 * Coordinates are stored internally as floats, but floating-point arithmetic can create
57357 * coordinates with a large number of decimal places, not generally wanted on output.
57358 * Set a number here to round coordinates. Can also be used to ensure that
57359 * coordinates read in can be written back out with the same number of decimals.
57360 * Default is no rounding.
57361 */
57362
57363/**
57364 * @typedef {'arraybuffer' | 'json' | 'text' | 'xml'} Type
57365 */
57366
57367/**
57368 * @classdesc
57369 * Abstract base class; normally only used for creating subclasses and not
57370 * instantiated in apps.
57371 * Base class for feature formats.
57372 * {@link module:ol/format/Feature~FeatureFormat} subclasses provide the ability to decode and encode
57373 * {@link module:ol/Feature~Feature} objects from a variety of commonly used geospatial
57374 * file formats.  See the documentation for each format for more details.
57375 *
57376 * @abstract
57377 * @api
57378 */
57379class FeatureFormat {
57380  constructor() {
57381    /**
57382     * @protected
57383     * @type {import("../proj/Projection.js").default|undefined}
57384     */
57385    this.dataProjection = undefined;
57386
57387    /**
57388     * @protected
57389     * @type {import("../proj/Projection.js").default|undefined}
57390     */
57391    this.defaultFeatureProjection = undefined;
57392
57393    /**
57394     * A list media types supported by the format in descending order of preference.
57395     * @type {Array<string>}
57396     */
57397    this.supportedMediaTypes = null;
57398  }
57399
57400  /**
57401   * Adds the data projection to the read options.
57402   * @param {Document|Element|Object|string} source Source.
57403   * @param {ReadOptions} [options] Options.
57404   * @return {ReadOptions|undefined} Options.
57405   * @protected
57406   */
57407  getReadOptions(source, options) {
57408    if (options) {
57409      let dataProjection = options.dataProjection
57410        ? proj_get(options.dataProjection)
57411        : this.readProjection(source);
57412      if (
57413        options.extent &&
57414        dataProjection &&
57415        dataProjection.getUnits() === 'tile-pixels'
57416      ) {
57417        dataProjection = proj_get(dataProjection);
57418        dataProjection.setWorldExtent(options.extent);
57419      }
57420      options = {
57421        dataProjection: dataProjection,
57422        featureProjection: options.featureProjection,
57423      };
57424    }
57425    return this.adaptOptions(options);
57426  }
57427
57428  /**
57429   * Sets the `dataProjection` on the options, if no `dataProjection`
57430   * is set.
57431   * @param {WriteOptions|ReadOptions|undefined} options
57432   *     Options.
57433   * @protected
57434   * @return {WriteOptions|ReadOptions|undefined}
57435   *     Updated options.
57436   */
57437  adaptOptions(options) {
57438    return Object.assign(
57439      {
57440        dataProjection: this.dataProjection,
57441        featureProjection: this.defaultFeatureProjection,
57442      },
57443      options
57444    );
57445  }
57446
57447  /**
57448   * @abstract
57449   * @return {Type} The format type.
57450   */
57451  getType() {
57452    return util_abstract();
57453  }
57454
57455  /**
57456   * Read a single feature from a source.
57457   *
57458   * @abstract
57459   * @param {Document|Element|Object|string} source Source.
57460   * @param {ReadOptions} [options] Read options.
57461   * @return {import("../Feature.js").FeatureLike} Feature.
57462   */
57463  readFeature(source, options) {
57464    return util_abstract();
57465  }
57466
57467  /**
57468   * Read all features from a source.
57469   *
57470   * @abstract
57471   * @param {Document|Element|ArrayBuffer|Object|string} source Source.
57472   * @param {ReadOptions} [options] Read options.
57473   * @return {Array<import("../Feature.js").FeatureLike>} Features.
57474   */
57475  readFeatures(source, options) {
57476    return util_abstract();
57477  }
57478
57479  /**
57480   * Read a single geometry from a source.
57481   *
57482   * @abstract
57483   * @param {Document|Element|Object|string} source Source.
57484   * @param {ReadOptions} [options] Read options.
57485   * @return {import("../geom/Geometry.js").default} Geometry.
57486   */
57487  readGeometry(source, options) {
57488    return util_abstract();
57489  }
57490
57491  /**
57492   * Read the projection from a source.
57493   *
57494   * @abstract
57495   * @param {Document|Element|Object|string} source Source.
57496   * @return {import("../proj/Projection.js").default|undefined} Projection.
57497   */
57498  readProjection(source) {
57499    return util_abstract();
57500  }
57501
57502  /**
57503   * Encode a feature in this format.
57504   *
57505   * @abstract
57506   * @param {import("../Feature.js").default} feature Feature.
57507   * @param {WriteOptions} [options] Write options.
57508   * @return {string|ArrayBuffer} Result.
57509   */
57510  writeFeature(feature, options) {
57511    return util_abstract();
57512  }
57513
57514  /**
57515   * Encode an array of features in this format.
57516   *
57517   * @abstract
57518   * @param {Array<import("../Feature.js").default>} features Features.
57519   * @param {WriteOptions} [options] Write options.
57520   * @return {string|ArrayBuffer} Result.
57521   */
57522  writeFeatures(features, options) {
57523    return util_abstract();
57524  }
57525
57526  /**
57527   * Write a single geometry in this format.
57528   *
57529   * @abstract
57530   * @param {import("../geom/Geometry.js").default} geometry Geometry.
57531   * @param {WriteOptions} [options] Write options.
57532   * @return {string|ArrayBuffer} Result.
57533   */
57534  writeGeometry(geometry, options) {
57535    return util_abstract();
57536  }
57537}
57538
57539/* harmony default export */ const format_Feature = (FeatureFormat);
57540
57541/**
57542 * @param {import("../geom/Geometry.js").default} geometry Geometry.
57543 * @param {boolean} write Set to true for writing, false for reading.
57544 * @param {WriteOptions|ReadOptions} [options] Options.
57545 * @return {import("../geom/Geometry.js").default} Transformed geometry.
57546 */
57547function transformGeometryWithOptions(geometry, write, options) {
57548  const featureProjection = options
57549    ? proj_get(options.featureProjection)
57550    : null;
57551  const dataProjection = options ? proj_get(options.dataProjection) : null;
57552
57553  let transformed;
57554  if (
57555    featureProjection &&
57556    dataProjection &&
57557    !equivalent(featureProjection, dataProjection)
57558  ) {
57559    transformed = (write ? geometry.clone() : geometry).transform(
57560      write ? featureProjection : dataProjection,
57561      write ? dataProjection : featureProjection
57562    );
57563  } else {
57564    transformed = geometry;
57565  }
57566  if (
57567    write &&
57568    options &&
57569    /** @type {WriteOptions} */ (options).decimals !== undefined
57570  ) {
57571    const power = Math.pow(10, /** @type {WriteOptions} */ (options).decimals);
57572    // if decimals option on write, round each coordinate appropriately
57573    /**
57574     * @param {Array<number>} coordinates Coordinates.
57575     * @return {Array<number>} Transformed coordinates.
57576     */
57577    const transform = function (coordinates) {
57578      for (let i = 0, ii = coordinates.length; i < ii; ++i) {
57579        coordinates[i] = Math.round(coordinates[i] * power) / power;
57580      }
57581      return coordinates;
57582    };
57583    if (transformed === geometry) {
57584      transformed = geometry.clone();
57585    }
57586    transformed.applyTransform(transform);
57587  }
57588  return transformed;
57589}
57590
57591/**
57592 * @param {import("../extent.js").Extent} extent Extent.
57593 * @param {ReadOptions} [options] Read options.
57594 * @return {import("../extent.js").Extent} Transformed extent.
57595 */
57596function transformExtentWithOptions(extent, options) {
57597  const featureProjection = options
57598    ? getProjection(options.featureProjection)
57599    : null;
57600  const dataProjection = options ? getProjection(options.dataProjection) : null;
57601
57602  if (
57603    featureProjection &&
57604    dataProjection &&
57605    !equivalentProjection(featureProjection, dataProjection)
57606  ) {
57607    return transformExtent(extent, dataProjection, featureProjection);
57608  } else {
57609    return extent;
57610  }
57611}
57612
57613;// CONCATENATED MODULE: ./node_modules/ol/format/JSONFeature.js
57614/**
57615 * @module ol/format/JSONFeature
57616 */
57617
57618
57619
57620/**
57621 * @classdesc
57622 * Abstract base class; normally only used for creating subclasses and not
57623 * instantiated in apps.
57624 * Base class for JSON feature formats.
57625 *
57626 * @abstract
57627 */
57628class JSONFeature extends format_Feature {
57629  constructor() {
57630    super();
57631  }
57632
57633  /**
57634   * @return {import("./Feature.js").Type} Format.
57635   */
57636  getType() {
57637    return 'json';
57638  }
57639
57640  /**
57641   * Read a feature.  Only works for a single feature. Use `readFeatures` to
57642   * read a feature collection.
57643   *
57644   * @param {ArrayBuffer|Document|Element|Object|string} source Source.
57645   * @param {import("./Feature.js").ReadOptions} [options] Read options.
57646   * @return {import("../Feature.js").default} Feature.
57647   * @api
57648   */
57649  readFeature(source, options) {
57650    return this.readFeatureFromObject(
57651      getObject(source),
57652      this.getReadOptions(source, options)
57653    );
57654  }
57655
57656  /**
57657   * Read all features.  Works with both a single feature and a feature
57658   * collection.
57659   *
57660   * @param {ArrayBuffer|Document|Element|Object|string} source Source.
57661   * @param {import("./Feature.js").ReadOptions} [options] Read options.
57662   * @return {Array<import("../Feature.js").default>} Features.
57663   * @api
57664   */
57665  readFeatures(source, options) {
57666    return this.readFeaturesFromObject(
57667      getObject(source),
57668      this.getReadOptions(source, options)
57669    );
57670  }
57671
57672  /**
57673   * @abstract
57674   * @param {Object} object Object.
57675   * @param {import("./Feature.js").ReadOptions} [options] Read options.
57676   * @protected
57677   * @return {import("../Feature.js").default} Feature.
57678   */
57679  readFeatureFromObject(object, options) {
57680    return util_abstract();
57681  }
57682
57683  /**
57684   * @abstract
57685   * @param {Object} object Object.
57686   * @param {import("./Feature.js").ReadOptions} [options] Read options.
57687   * @protected
57688   * @return {Array<import("../Feature.js").default>} Features.
57689   */
57690  readFeaturesFromObject(object, options) {
57691    return util_abstract();
57692  }
57693
57694  /**
57695   * Read a geometry.
57696   *
57697   * @param {ArrayBuffer|Document|Element|Object|string} source Source.
57698   * @param {import("./Feature.js").ReadOptions} [options] Read options.
57699   * @return {import("../geom/Geometry.js").default} Geometry.
57700   * @api
57701   */
57702  readGeometry(source, options) {
57703    return this.readGeometryFromObject(
57704      getObject(source),
57705      this.getReadOptions(source, options)
57706    );
57707  }
57708
57709  /**
57710   * @abstract
57711   * @param {Object} object Object.
57712   * @param {import("./Feature.js").ReadOptions} [options] Read options.
57713   * @protected
57714   * @return {import("../geom/Geometry.js").default} Geometry.
57715   */
57716  readGeometryFromObject(object, options) {
57717    return util_abstract();
57718  }
57719
57720  /**
57721   * Read the projection.
57722   *
57723   * @param {ArrayBuffer|Document|Element|Object|string} source Source.
57724   * @return {import("../proj/Projection.js").default} Projection.
57725   * @api
57726   */
57727  readProjection(source) {
57728    return this.readProjectionFromObject(getObject(source));
57729  }
57730
57731  /**
57732   * @abstract
57733   * @param {Object} object Object.
57734   * @protected
57735   * @return {import("../proj/Projection.js").default} Projection.
57736   */
57737  readProjectionFromObject(object) {
57738    return util_abstract();
57739  }
57740
57741  /**
57742   * Encode a feature as string.
57743   *
57744   * @param {import("../Feature.js").default} feature Feature.
57745   * @param {import("./Feature.js").WriteOptions} [options] Write options.
57746   * @return {string} Encoded feature.
57747   * @api
57748   */
57749  writeFeature(feature, options) {
57750    return JSON.stringify(this.writeFeatureObject(feature, options));
57751  }
57752
57753  /**
57754   * @abstract
57755   * @param {import("../Feature.js").default} feature Feature.
57756   * @param {import("./Feature.js").WriteOptions} [options] Write options.
57757   * @return {Object} Object.
57758   */
57759  writeFeatureObject(feature, options) {
57760    return util_abstract();
57761  }
57762
57763  /**
57764   * Encode an array of features as string.
57765   *
57766   * @param {Array<import("../Feature.js").default>} features Features.
57767   * @param {import("./Feature.js").WriteOptions} [options] Write options.
57768   * @return {string} Encoded features.
57769   * @api
57770   */
57771  writeFeatures(features, options) {
57772    return JSON.stringify(this.writeFeaturesObject(features, options));
57773  }
57774
57775  /**
57776   * @abstract
57777   * @param {Array<import("../Feature.js").default>} features Features.
57778   * @param {import("./Feature.js").WriteOptions} [options] Write options.
57779   * @return {Object} Object.
57780   */
57781  writeFeaturesObject(features, options) {
57782    return util_abstract();
57783  }
57784
57785  /**
57786   * Encode a geometry as string.
57787   *
57788   * @param {import("../geom/Geometry.js").default} geometry Geometry.
57789   * @param {import("./Feature.js").WriteOptions} [options] Write options.
57790   * @return {string} Encoded geometry.
57791   * @api
57792   */
57793  writeGeometry(geometry, options) {
57794    return JSON.stringify(this.writeGeometryObject(geometry, options));
57795  }
57796
57797  /**
57798   * @abstract
57799   * @param {import("../geom/Geometry.js").default} geometry Geometry.
57800   * @param {import("./Feature.js").WriteOptions} [options] Write options.
57801   * @return {Object} Object.
57802   */
57803  writeGeometryObject(geometry, options) {
57804    return util_abstract();
57805  }
57806}
57807
57808/**
57809 * @param {Document|Element|Object|string} source Source.
57810 * @return {Object} Object.
57811 */
57812function getObject(source) {
57813  if (typeof source === 'string') {
57814    const object = JSON.parse(source);
57815    return object ? /** @type {Object} */ (object) : null;
57816  } else if (source !== null) {
57817    return source;
57818  } else {
57819    return null;
57820  }
57821}
57822
57823/* harmony default export */ const format_JSONFeature = (JSONFeature);
57824
57825;// CONCATENATED MODULE: ./node_modules/ol/geom/flat/interpolate.js
57826/**
57827 * @module ol/geom/flat/interpolate
57828 */
57829
57830
57831
57832/**
57833 * @param {Array<number>} flatCoordinates Flat coordinates.
57834 * @param {number} offset Offset.
57835 * @param {number} end End.
57836 * @param {number} stride Stride.
57837 * @param {number} fraction Fraction.
57838 * @param {Array<number>} [dest] Destination.
57839 * @param {number} [dimension] Destination dimension (default is `2`)
57840 * @return {Array<number>} Destination.
57841 */
57842function interpolatePoint(
57843  flatCoordinates,
57844  offset,
57845  end,
57846  stride,
57847  fraction,
57848  dest,
57849  dimension
57850) {
57851  let o, t;
57852  const n = (end - offset) / stride;
57853  if (n === 1) {
57854    o = offset;
57855  } else if (n === 2) {
57856    o = offset;
57857    t = fraction;
57858  } else if (n !== 0) {
57859    let x1 = flatCoordinates[offset];
57860    let y1 = flatCoordinates[offset + 1];
57861    let length = 0;
57862    const cumulativeLengths = [0];
57863    for (let i = offset + stride; i < end; i += stride) {
57864      const x2 = flatCoordinates[i];
57865      const y2 = flatCoordinates[i + 1];
57866      length += Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
57867      cumulativeLengths.push(length);
57868      x1 = x2;
57869      y1 = y2;
57870    }
57871    const target = fraction * length;
57872    const index = binarySearch(cumulativeLengths, target);
57873    if (index < 0) {
57874      t =
57875        (target - cumulativeLengths[-index - 2]) /
57876        (cumulativeLengths[-index - 1] - cumulativeLengths[-index - 2]);
57877      o = offset + (-index - 2) * stride;
57878    } else {
57879      o = offset + index * stride;
57880    }
57881  }
57882  dimension = dimension > 1 ? dimension : 2;
57883  dest = dest ? dest : new Array(dimension);
57884  for (let i = 0; i < dimension; ++i) {
57885    dest[i] =
57886      o === undefined
57887        ? NaN
57888        : t === undefined
57889        ? flatCoordinates[o + i]
57890        : lerp(flatCoordinates[o + i], flatCoordinates[o + stride + i], t);
57891  }
57892  return dest;
57893}
57894
57895/**
57896 * @param {Array<number>} flatCoordinates Flat coordinates.
57897 * @param {number} offset Offset.
57898 * @param {number} end End.
57899 * @param {number} stride Stride.
57900 * @param {number} m M.
57901 * @param {boolean} extrapolate Extrapolate.
57902 * @return {import("../../coordinate.js").Coordinate|null} Coordinate.
57903 */
57904function lineStringCoordinateAtM(
57905  flatCoordinates,
57906  offset,
57907  end,
57908  stride,
57909  m,
57910  extrapolate
57911) {
57912  if (end == offset) {
57913    return null;
57914  }
57915  let coordinate;
57916  if (m < flatCoordinates[offset + stride - 1]) {
57917    if (extrapolate) {
57918      coordinate = flatCoordinates.slice(offset, offset + stride);
57919      coordinate[stride - 1] = m;
57920      return coordinate;
57921    } else {
57922      return null;
57923    }
57924  } else if (flatCoordinates[end - 1] < m) {
57925    if (extrapolate) {
57926      coordinate = flatCoordinates.slice(end - stride, end);
57927      coordinate[stride - 1] = m;
57928      return coordinate;
57929    } else {
57930      return null;
57931    }
57932  }
57933  // FIXME use O(1) search
57934  if (m == flatCoordinates[offset + stride - 1]) {
57935    return flatCoordinates.slice(offset, offset + stride);
57936  }
57937  let lo = offset / stride;
57938  let hi = end / stride;
57939  while (lo < hi) {
57940    const mid = (lo + hi) >> 1;
57941    if (m < flatCoordinates[(mid + 1) * stride - 1]) {
57942      hi = mid;
57943    } else {
57944      lo = mid + 1;
57945    }
57946  }
57947  const m0 = flatCoordinates[lo * stride - 1];
57948  if (m == m0) {
57949    return flatCoordinates.slice((lo - 1) * stride, (lo - 1) * stride + stride);
57950  }
57951  const m1 = flatCoordinates[(lo + 1) * stride - 1];
57952  const t = (m - m0) / (m1 - m0);
57953  coordinate = [];
57954  for (let i = 0; i < stride - 1; ++i) {
57955    coordinate.push(
57956      lerp(
57957        flatCoordinates[(lo - 1) * stride + i],
57958        flatCoordinates[lo * stride + i],
57959        t
57960      )
57961    );
57962  }
57963  coordinate.push(m);
57964  return coordinate;
57965}
57966
57967/**
57968 * @param {Array<number>} flatCoordinates Flat coordinates.
57969 * @param {number} offset Offset.
57970 * @param {Array<number>} ends Ends.
57971 * @param {number} stride Stride.
57972 * @param {number} m M.
57973 * @param {boolean} extrapolate Extrapolate.
57974 * @param {boolean} interpolate Interpolate.
57975 * @return {import("../../coordinate.js").Coordinate|null} Coordinate.
57976 */
57977function lineStringsCoordinateAtM(
57978  flatCoordinates,
57979  offset,
57980  ends,
57981  stride,
57982  m,
57983  extrapolate,
57984  interpolate
57985) {
57986  if (interpolate) {
57987    return lineStringCoordinateAtM(
57988      flatCoordinates,
57989      offset,
57990      ends[ends.length - 1],
57991      stride,
57992      m,
57993      extrapolate
57994    );
57995  }
57996  let coordinate;
57997  if (m < flatCoordinates[stride - 1]) {
57998    if (extrapolate) {
57999      coordinate = flatCoordinates.slice(0, stride);
58000      coordinate[stride - 1] = m;
58001      return coordinate;
58002    } else {
58003      return null;
58004    }
58005  }
58006  if (flatCoordinates[flatCoordinates.length - 1] < m) {
58007    if (extrapolate) {
58008      coordinate = flatCoordinates.slice(flatCoordinates.length - stride);
58009      coordinate[stride - 1] = m;
58010      return coordinate;
58011    } else {
58012      return null;
58013    }
58014  }
58015  for (let i = 0, ii = ends.length; i < ii; ++i) {
58016    const end = ends[i];
58017    if (offset == end) {
58018      continue;
58019    }
58020    if (m < flatCoordinates[offset + stride - 1]) {
58021      return null;
58022    } else if (m <= flatCoordinates[end - 1]) {
58023      return lineStringCoordinateAtM(
58024        flatCoordinates,
58025        offset,
58026        end,
58027        stride,
58028        m,
58029        false
58030      );
58031    }
58032    offset = end;
58033  }
58034  return null;
58035}
58036
58037;// CONCATENATED MODULE: ./node_modules/ol/geom/LineString.js
58038/**
58039 * @module ol/geom/LineString
58040 */
58041
58042
58043
58044
58045
58046
58047
58048
58049
58050
58051
58052
58053/**
58054 * @classdesc
58055 * Linestring geometry.
58056 *
58057 * @api
58058 */
58059class LineString extends geom_SimpleGeometry {
58060  /**
58061   * @param {Array<import("../coordinate.js").Coordinate>|Array<number>} coordinates Coordinates.
58062   *     For internal use, flat coordinates in combination with `layout` are also accepted.
58063   * @param {import("./Geometry.js").GeometryLayout} [layout] Layout.
58064   */
58065  constructor(coordinates, layout) {
58066    super();
58067
58068    /**
58069     * @private
58070     * @type {import("../coordinate.js").Coordinate}
58071     */
58072    this.flatMidpoint_ = null;
58073
58074    /**
58075     * @private
58076     * @type {number}
58077     */
58078    this.flatMidpointRevision_ = -1;
58079
58080    /**
58081     * @private
58082     * @type {number}
58083     */
58084    this.maxDelta_ = -1;
58085
58086    /**
58087     * @private
58088     * @type {number}
58089     */
58090    this.maxDeltaRevision_ = -1;
58091
58092    if (layout !== undefined && !Array.isArray(coordinates[0])) {
58093      this.setFlatCoordinates(
58094        layout,
58095        /** @type {Array<number>} */ (coordinates)
58096      );
58097    } else {
58098      this.setCoordinates(
58099        /** @type {Array<import("../coordinate.js").Coordinate>} */ (
58100          coordinates
58101        ),
58102        layout
58103      );
58104    }
58105  }
58106
58107  /**
58108   * Append the passed coordinate to the coordinates of the linestring.
58109   * @param {import("../coordinate.js").Coordinate} coordinate Coordinate.
58110   * @api
58111   */
58112  appendCoordinate(coordinate) {
58113    if (!this.flatCoordinates) {
58114      this.flatCoordinates = coordinate.slice();
58115    } else {
58116      array_extend(this.flatCoordinates, coordinate);
58117    }
58118    this.changed();
58119  }
58120
58121  /**
58122   * Make a complete copy of the geometry.
58123   * @return {!LineString} Clone.
58124   * @api
58125   */
58126  clone() {
58127    const lineString = new LineString(
58128      this.flatCoordinates.slice(),
58129      this.layout
58130    );
58131    lineString.applyProperties(this);
58132    return lineString;
58133  }
58134
58135  /**
58136   * @param {number} x X.
58137   * @param {number} y Y.
58138   * @param {import("../coordinate.js").Coordinate} closestPoint Closest point.
58139   * @param {number} minSquaredDistance Minimum squared distance.
58140   * @return {number} Minimum squared distance.
58141   */
58142  closestPointXY(x, y, closestPoint, minSquaredDistance) {
58143    if (minSquaredDistance < closestSquaredDistanceXY(this.getExtent(), x, y)) {
58144      return minSquaredDistance;
58145    }
58146    if (this.maxDeltaRevision_ != this.getRevision()) {
58147      this.maxDelta_ = Math.sqrt(
58148        maxSquaredDelta(
58149          this.flatCoordinates,
58150          0,
58151          this.flatCoordinates.length,
58152          this.stride,
58153          0
58154        )
58155      );
58156      this.maxDeltaRevision_ = this.getRevision();
58157    }
58158    return assignClosestPoint(
58159      this.flatCoordinates,
58160      0,
58161      this.flatCoordinates.length,
58162      this.stride,
58163      this.maxDelta_,
58164      false,
58165      x,
58166      y,
58167      closestPoint,
58168      minSquaredDistance
58169    );
58170  }
58171
58172  /**
58173   * Iterate over each segment, calling the provided callback.
58174   * If the callback returns a truthy value the function returns that
58175   * value immediately. Otherwise the function returns `false`.
58176   *
58177   * @param {function(this: S, import("../coordinate.js").Coordinate, import("../coordinate.js").Coordinate): T} callback Function
58178   *     called for each segment. The function will receive two arguments, the start and end coordinates of the segment.
58179   * @return {T|boolean} Value.
58180   * @template T,S
58181   * @api
58182   */
58183  forEachSegment(callback) {
58184    return forEach(
58185      this.flatCoordinates,
58186      0,
58187      this.flatCoordinates.length,
58188      this.stride,
58189      callback
58190    );
58191  }
58192
58193  /**
58194   * Returns the coordinate at `m` using linear interpolation, or `null` if no
58195   * such coordinate exists.
58196   *
58197   * `extrapolate` controls extrapolation beyond the range of Ms in the
58198   * MultiLineString. If `extrapolate` is `true` then Ms less than the first
58199   * M will return the first coordinate and Ms greater than the last M will
58200   * return the last coordinate.
58201   *
58202   * @param {number} m M.
58203   * @param {boolean} [extrapolate] Extrapolate. Default is `false`.
58204   * @return {import("../coordinate.js").Coordinate|null} Coordinate.
58205   * @api
58206   */
58207  getCoordinateAtM(m, extrapolate) {
58208    if (this.layout != 'XYM' && this.layout != 'XYZM') {
58209      return null;
58210    }
58211    extrapolate = extrapolate !== undefined ? extrapolate : false;
58212    return lineStringCoordinateAtM(
58213      this.flatCoordinates,
58214      0,
58215      this.flatCoordinates.length,
58216      this.stride,
58217      m,
58218      extrapolate
58219    );
58220  }
58221
58222  /**
58223   * Return the coordinates of the linestring.
58224   * @return {Array<import("../coordinate.js").Coordinate>} Coordinates.
58225   * @api
58226   */
58227  getCoordinates() {
58228    return inflateCoordinates(
58229      this.flatCoordinates,
58230      0,
58231      this.flatCoordinates.length,
58232      this.stride
58233    );
58234  }
58235
58236  /**
58237   * Return the coordinate at the provided fraction along the linestring.
58238   * The `fraction` is a number between 0 and 1, where 0 is the start of the
58239   * linestring and 1 is the end.
58240   * @param {number} fraction Fraction.
58241   * @param {import("../coordinate.js").Coordinate} [dest] Optional coordinate whose values will
58242   *     be modified. If not provided, a new coordinate will be returned.
58243   * @return {import("../coordinate.js").Coordinate} Coordinate of the interpolated point.
58244   * @api
58245   */
58246  getCoordinateAt(fraction, dest) {
58247    return interpolatePoint(
58248      this.flatCoordinates,
58249      0,
58250      this.flatCoordinates.length,
58251      this.stride,
58252      fraction,
58253      dest,
58254      this.stride
58255    );
58256  }
58257
58258  /**
58259   * Return the length of the linestring on projected plane.
58260   * @return {number} Length (on projected plane).
58261   * @api
58262   */
58263  getLength() {
58264    return lineStringLength(
58265      this.flatCoordinates,
58266      0,
58267      this.flatCoordinates.length,
58268      this.stride
58269    );
58270  }
58271
58272  /**
58273   * @return {Array<number>} Flat midpoint.
58274   */
58275  getFlatMidpoint() {
58276    if (this.flatMidpointRevision_ != this.getRevision()) {
58277      this.flatMidpoint_ = this.getCoordinateAt(0.5, this.flatMidpoint_);
58278      this.flatMidpointRevision_ = this.getRevision();
58279    }
58280    return this.flatMidpoint_;
58281  }
58282
58283  /**
58284   * @param {number} squaredTolerance Squared tolerance.
58285   * @return {LineString} Simplified LineString.
58286   * @protected
58287   */
58288  getSimplifiedGeometryInternal(squaredTolerance) {
58289    const simplifiedFlatCoordinates = [];
58290    simplifiedFlatCoordinates.length = douglasPeucker(
58291      this.flatCoordinates,
58292      0,
58293      this.flatCoordinates.length,
58294      this.stride,
58295      squaredTolerance,
58296      simplifiedFlatCoordinates,
58297      0
58298    );
58299    return new LineString(simplifiedFlatCoordinates, 'XY');
58300  }
58301
58302  /**
58303   * Get the type of this geometry.
58304   * @return {import("./Geometry.js").Type} Geometry type.
58305   * @api
58306   */
58307  getType() {
58308    return 'LineString';
58309  }
58310
58311  /**
58312   * Test if the geometry and the passed extent intersect.
58313   * @param {import("../extent.js").Extent} extent Extent.
58314   * @return {boolean} `true` if the geometry and the extent intersect.
58315   * @api
58316   */
58317  intersectsExtent(extent) {
58318    return intersectsLineString(
58319      this.flatCoordinates,
58320      0,
58321      this.flatCoordinates.length,
58322      this.stride,
58323      extent
58324    );
58325  }
58326
58327  /**
58328   * Set the coordinates of the linestring.
58329   * @param {!Array<import("../coordinate.js").Coordinate>} coordinates Coordinates.
58330   * @param {import("./Geometry.js").GeometryLayout} [layout] Layout.
58331   * @api
58332   */
58333  setCoordinates(coordinates, layout) {
58334    this.setLayout(layout, coordinates, 1);
58335    if (!this.flatCoordinates) {
58336      this.flatCoordinates = [];
58337    }
58338    this.flatCoordinates.length = deflateCoordinates(
58339      this.flatCoordinates,
58340      0,
58341      coordinates,
58342      this.stride
58343    );
58344    this.changed();
58345  }
58346}
58347
58348/* harmony default export */ const geom_LineString = (LineString);
58349
58350;// CONCATENATED MODULE: ./node_modules/ol/geom/MultiLineString.js
58351/**
58352 * @module ol/geom/MultiLineString
58353 */
58354
58355
58356
58357
58358
58359
58360
58361
58362
58363
58364
58365/**
58366 * @classdesc
58367 * Multi-linestring geometry.
58368 *
58369 * @api
58370 */
58371class MultiLineString extends geom_SimpleGeometry {
58372  /**
58373   * @param {Array<Array<import("../coordinate.js").Coordinate>|LineString>|Array<number>} coordinates
58374   *     Coordinates or LineString geometries. (For internal use, flat coordinates in
58375   *     combination with `layout` and `ends` are also accepted.)
58376   * @param {import("./Geometry.js").GeometryLayout} [layout] Layout.
58377   * @param {Array<number>} [ends] Flat coordinate ends for internal use.
58378   */
58379  constructor(coordinates, layout, ends) {
58380    super();
58381
58382    /**
58383     * @type {Array<number>}
58384     * @private
58385     */
58386    this.ends_ = [];
58387
58388    /**
58389     * @private
58390     * @type {number}
58391     */
58392    this.maxDelta_ = -1;
58393
58394    /**
58395     * @private
58396     * @type {number}
58397     */
58398    this.maxDeltaRevision_ = -1;
58399
58400    if (Array.isArray(coordinates[0])) {
58401      this.setCoordinates(
58402        /** @type {Array<Array<import("../coordinate.js").Coordinate>>} */ (
58403          coordinates
58404        ),
58405        layout
58406      );
58407    } else if (layout !== undefined && ends) {
58408      this.setFlatCoordinates(
58409        layout,
58410        /** @type {Array<number>} */ (coordinates)
58411      );
58412      this.ends_ = ends;
58413    } else {
58414      let layout = this.getLayout();
58415      const lineStrings = /** @type {Array<LineString>} */ (coordinates);
58416      const flatCoordinates = [];
58417      const ends = [];
58418      for (let i = 0, ii = lineStrings.length; i < ii; ++i) {
58419        const lineString = lineStrings[i];
58420        if (i === 0) {
58421          layout = lineString.getLayout();
58422        }
58423        array_extend(flatCoordinates, lineString.getFlatCoordinates());
58424        ends.push(flatCoordinates.length);
58425      }
58426      this.setFlatCoordinates(layout, flatCoordinates);
58427      this.ends_ = ends;
58428    }
58429  }
58430
58431  /**
58432   * Append the passed linestring to the multilinestring.
58433   * @param {LineString} lineString LineString.
58434   * @api
58435   */
58436  appendLineString(lineString) {
58437    if (!this.flatCoordinates) {
58438      this.flatCoordinates = lineString.getFlatCoordinates().slice();
58439    } else {
58440      array_extend(this.flatCoordinates, lineString.getFlatCoordinates().slice());
58441    }
58442    this.ends_.push(this.flatCoordinates.length);
58443    this.changed();
58444  }
58445
58446  /**
58447   * Make a complete copy of the geometry.
58448   * @return {!MultiLineString} Clone.
58449   * @api
58450   */
58451  clone() {
58452    const multiLineString = new MultiLineString(
58453      this.flatCoordinates.slice(),
58454      this.layout,
58455      this.ends_.slice()
58456    );
58457    multiLineString.applyProperties(this);
58458    return multiLineString;
58459  }
58460
58461  /**
58462   * @param {number} x X.
58463   * @param {number} y Y.
58464   * @param {import("../coordinate.js").Coordinate} closestPoint Closest point.
58465   * @param {number} minSquaredDistance Minimum squared distance.
58466   * @return {number} Minimum squared distance.
58467   */
58468  closestPointXY(x, y, closestPoint, minSquaredDistance) {
58469    if (minSquaredDistance < closestSquaredDistanceXY(this.getExtent(), x, y)) {
58470      return minSquaredDistance;
58471    }
58472    if (this.maxDeltaRevision_ != this.getRevision()) {
58473      this.maxDelta_ = Math.sqrt(
58474        arrayMaxSquaredDelta(
58475          this.flatCoordinates,
58476          0,
58477          this.ends_,
58478          this.stride,
58479          0
58480        )
58481      );
58482      this.maxDeltaRevision_ = this.getRevision();
58483    }
58484    return assignClosestArrayPoint(
58485      this.flatCoordinates,
58486      0,
58487      this.ends_,
58488      this.stride,
58489      this.maxDelta_,
58490      false,
58491      x,
58492      y,
58493      closestPoint,
58494      minSquaredDistance
58495    );
58496  }
58497
58498  /**
58499   * Returns the coordinate at `m` using linear interpolation, or `null` if no
58500   * such coordinate exists.
58501   *
58502   * `extrapolate` controls extrapolation beyond the range of Ms in the
58503   * MultiLineString. If `extrapolate` is `true` then Ms less than the first
58504   * M will return the first coordinate and Ms greater than the last M will
58505   * return the last coordinate.
58506   *
58507   * `interpolate` controls interpolation between consecutive LineStrings
58508   * within the MultiLineString. If `interpolate` is `true` the coordinates
58509   * will be linearly interpolated between the last coordinate of one LineString
58510   * and the first coordinate of the next LineString.  If `interpolate` is
58511   * `false` then the function will return `null` for Ms falling between
58512   * LineStrings.
58513   *
58514   * @param {number} m M.
58515   * @param {boolean} [extrapolate] Extrapolate. Default is `false`.
58516   * @param {boolean} [interpolate] Interpolate. Default is `false`.
58517   * @return {import("../coordinate.js").Coordinate|null} Coordinate.
58518   * @api
58519   */
58520  getCoordinateAtM(m, extrapolate, interpolate) {
58521    if (
58522      (this.layout != 'XYM' && this.layout != 'XYZM') ||
58523      this.flatCoordinates.length === 0
58524    ) {
58525      return null;
58526    }
58527    extrapolate = extrapolate !== undefined ? extrapolate : false;
vendor: 6,135 bytes, lines 58528-58781
58528    interpolate = interpolate !== undefined ? interpolate : false;
58529    return lineStringsCoordinateAtM(
58530      this.flatCoordinates,
58531      0,
58532      this.ends_,
58533      this.stride,
58534      m,
58535      extrapolate,
58536      interpolate
58537    );
58538  }
58539
58540  /**
58541   * Return the coordinates of the multilinestring.
58542   * @return {Array<Array<import("../coordinate.js").Coordinate>>} Coordinates.
58543   * @api
58544   */
58545  getCoordinates() {
58546    return inflateCoordinatesArray(
58547      this.flatCoordinates,
58548      0,
58549      this.ends_,
58550      this.stride
58551    );
58552  }
58553
58554  /**
58555   * @return {Array<number>} Ends.
58556   */
58557  getEnds() {
58558    return this.ends_;
58559  }
58560
58561  /**
58562   * Return the linestring at the specified index.
58563   * @param {number} index Index.
58564   * @return {LineString} LineString.
58565   * @api
58566   */
58567  getLineString(index) {
58568    if (index < 0 || this.ends_.length <= index) {
58569      return null;
58570    }
58571    return new geom_LineString(
58572      this.flatCoordinates.slice(
58573        index === 0 ? 0 : this.ends_[index - 1],
58574        this.ends_[index]
58575      ),
58576      this.layout
58577    );
58578  }
58579
58580  /**
58581   * Return the linestrings of this multilinestring.
58582   * @return {Array<LineString>} LineStrings.
58583   * @api
58584   */
58585  getLineStrings() {
58586    const flatCoordinates = this.flatCoordinates;
58587    const ends = this.ends_;
58588    const layout = this.layout;
58589    /** @type {Array<LineString>} */
58590    const lineStrings = [];
58591    let offset = 0;
58592    for (let i = 0, ii = ends.length; i < ii; ++i) {
58593      const end = ends[i];
58594      const lineString = new geom_LineString(
58595        flatCoordinates.slice(offset, end),
58596        layout
58597      );
58598      lineStrings.push(lineString);
58599      offset = end;
58600    }
58601    return lineStrings;
58602  }
58603
58604  /**
58605   * @return {Array<number>} Flat midpoints.
58606   */
58607  getFlatMidpoints() {
58608    const midpoints = [];
58609    const flatCoordinates = this.flatCoordinates;
58610    let offset = 0;
58611    const ends = this.ends_;
58612    const stride = this.stride;
58613    for (let i = 0, ii = ends.length; i < ii; ++i) {
58614      const end = ends[i];
58615      const midpoint = interpolatePoint(
58616        flatCoordinates,
58617        offset,
58618        end,
58619        stride,
58620        0.5
58621      );
58622      array_extend(midpoints, midpoint);
58623      offset = end;
58624    }
58625    return midpoints;
58626  }
58627
58628  /**
58629   * @param {number} squaredTolerance Squared tolerance.
58630   * @return {MultiLineString} Simplified MultiLineString.
58631   * @protected
58632   */
58633  getSimplifiedGeometryInternal(squaredTolerance) {
58634    const simplifiedFlatCoordinates = [];
58635    const simplifiedEnds = [];
58636    simplifiedFlatCoordinates.length = douglasPeuckerArray(
58637      this.flatCoordinates,
58638      0,
58639      this.ends_,
58640      this.stride,
58641      squaredTolerance,
58642      simplifiedFlatCoordinates,
58643      0,
58644      simplifiedEnds
58645    );
58646    return new MultiLineString(simplifiedFlatCoordinates, 'XY', simplifiedEnds);
58647  }
58648
58649  /**
58650   * Get the type of this geometry.
58651   * @return {import("./Geometry.js").Type} Geometry type.
58652   * @api
58653   */
58654  getType() {
58655    return 'MultiLineString';
58656  }
58657
58658  /**
58659   * Test if the geometry and the passed extent intersect.
58660   * @param {import("../extent.js").Extent} extent Extent.
58661   * @return {boolean} `true` if the geometry and the extent intersect.
58662   * @api
58663   */
58664  intersectsExtent(extent) {
58665    return intersectsLineStringArray(
58666      this.flatCoordinates,
58667      0,
58668      this.ends_,
58669      this.stride,
58670      extent
58671    );
58672  }
58673
58674  /**
58675   * Set the coordinates of the multilinestring.
58676   * @param {!Array<Array<import("../coordinate.js").Coordinate>>} coordinates Coordinates.
58677   * @param {import("./Geometry.js").GeometryLayout} [layout] Layout.
58678   * @api
58679   */
58680  setCoordinates(coordinates, layout) {
58681    this.setLayout(layout, coordinates, 2);
58682    if (!this.flatCoordinates) {
58683      this.flatCoordinates = [];
58684    }
58685    const ends = deflateCoordinatesArray(
58686      this.flatCoordinates,
58687      0,
58688      coordinates,
58689      this.stride,
58690      this.ends_
58691    );
58692    this.flatCoordinates.length = ends.length === 0 ? 0 : ends[ends.length - 1];
58693    this.changed();
58694  }
58695}
58696
58697/* harmony default export */ const geom_MultiLineString = (MultiLineString);
58698
58699;// CONCATENATED MODULE: ./node_modules/ol/geom/MultiPoint.js
58700/**
58701 * @module ol/geom/MultiPoint
58702 */
58703
58704
58705
58706
58707
58708
58709
58710
58711/**
58712 * @classdesc
58713 * Multi-point geometry.
58714 *
58715 * @api
58716 */
58717class MultiPoint extends geom_SimpleGeometry {
58718  /**
58719   * @param {Array<import("../coordinate.js").Coordinate>|Array<number>} coordinates Coordinates.
58720   *     For internal use, flat coordinates in combination with `layout` are also accepted.
58721   * @param {import("./Geometry.js").GeometryLayout} [layout] Layout.
58722   */
58723  constructor(coordinates, layout) {
58724    super();
58725    if (layout && !Array.isArray(coordinates[0])) {
58726      this.setFlatCoordinates(
58727        layout,
58728        /** @type {Array<number>} */ (coordinates)
58729      );
58730    } else {
58731      this.setCoordinates(
58732        /** @type {Array<import("../coordinate.js").Coordinate>} */ (
58733          coordinates
58734        ),
58735        layout
58736      );
58737    }
58738  }
58739
58740  /**
58741   * Append the passed point to this multipoint.
58742   * @param {Point} point Point.
58743   * @api
58744   */
58745  appendPoint(point) {
58746    if (!this.flatCoordinates) {
58747      this.flatCoordinates = point.getFlatCoordinates().slice();
58748    } else {
58749      array_extend(this.flatCoordinates, point.getFlatCoordinates());
58750    }
58751    this.changed();
58752  }
58753
58754  /**
58755   * Make a complete copy of the geometry.
58756   * @return {!MultiPoint} Clone.
58757   * @api
58758   */
58759  clone() {
58760    const multiPoint = new MultiPoint(
58761      this.flatCoordinates.slice(),
58762      this.layout
58763    );
58764    multiPoint.applyProperties(this);
58765    return multiPoint;
58766  }
58767
58768  /**
58769   * @param {number} x X.
58770   * @param {number} y Y.
58771   * @param {import("../coordinate.js").Coordinate} closestPoint Closest point.
58772   * @param {number} minSquaredDistance Minimum squared distance.
58773   * @return {number} Minimum squared distance.
58774   */
58775  closestPointXY(x, y, closestPoint, minSquaredDistance) {
58776    if (minSquaredDistance < closestSquaredDistanceXY(this.getExtent(), x, y)) {
58777      return minSquaredDistance;
58778    }
58779    const flatCoordinates = this.flatCoordinates;
58780    const stride = this.stride;
58781    for (let i = 0, ii = flatCoordinates.length; i < ii; i += stride) {
58782      const squaredDistance = math_squaredDistance(
58783        x,
58784        y,
58785        flatCoordinates[i],
58786        flatCoordinates[i + 1]
58787      );
58788      if (squaredDistance < minSquaredDistance) {
58789        minSquaredDistance = squaredDistance;
58790        for (let j = 0; j < stride; ++j) {
58791          closestPoint[j] = flatCoordinates[i + j];
58792        }
58793        closestPoint.length = stride;
58794      }
58795    }
58796    return minSquaredDistance;
58797  }
58798
58799  /**
58800   * Return the coordinates of the multipoint.
58801   * @return {Array<import("../coordinate.js").Coordinate>} Coordinates.
58802   * @api
58803   */
58804  getCoordinates() {
58805    return inflateCoordinates(
58806      this.flatCoordinates,
58807      0,
58808      this.flatCoordinates.length,
58809      this.stride
58810    );
58811  }
58812
58813  /**
58814   * Return the point at the specified index.
58815   * @param {number} index Index.
58816   * @return {Point} Point.
58817   * @api
58818   */
58819  getPoint(index) {
58820    const n = !this.flatCoordinates
58821      ? 0
58822      : this.flatCoordinates.length / this.stride;
58823    if (index < 0 || n <= index) {
58824      return null;
58825    }
58826    return new geom_Point(
58827      this.flatCoordinates.slice(
58828        index * this.stride,
58829        (index + 1) * this.stride
58830      ),
58831      this.layout
58832    );
58833  }
58834
58835  /**
58836   * Return the points of this multipoint.
58837   * @return {Array<Point>} Points.
58838   * @api
58839   */
58840  getPoints() {
58841    const flatCoordinates = this.flatCoordinates;
58842    const layout = this.layout;
58843    const stride = this.stride;
58844    /** @type {Array<Point>} */
58845    const points = [];
58846    for (let i = 0, ii = flatCoordinates.length; i < ii; i += stride) {
58847      const point = new geom_Point(flatCoordinates.slice(i, i + stride), layout);
58848      points.push(point);
58849    }
58850    return points;
58851  }
58852
58853  /**
58854   * Get the type of this geometry.
58855   * @return {import("./Geometry.js").Type} Geometry type.
58856   * @api
58857   */
58858  getType() {
58859    return 'MultiPoint';
58860  }
58861
58862  /**
58863   * Test if the geometry and the passed extent intersect.
58864   * @param {import("../extent.js").Extent} extent Extent.
58865   * @return {boolean} `true` if the geometry and the extent intersect.
58866   * @api
58867   */
58868  intersectsExtent(extent) {
58869    const flatCoordinates = this.flatCoordinates;
58870    const stride = this.stride;
58871    for (let i = 0, ii = flatCoordinates.length; i < ii; i += stride) {
58872      const x = flatCoordinates[i];
58873      const y = flatCoordinates[i + 1];
58874      if (containsXY(extent, x, y)) {
58875        return true;
58876      }
58877    }
58878    return false;
58879  }
58880
58881  /**
58882   * Set the coordinates of the multipoint.
58883   * @param {!Array<import("../coordinate.js").Coordinate>} coordinates Coordinates.
58884   * @param {import("./Geometry.js").GeometryLayout} [layout] Layout.
58885   * @api
58886   */
58887  setCoordinates(coordinates, layout) {
58888    this.setLayout(layout, coordinates, 1);
58889    if (!this.flatCoordinates) {
58890      this.flatCoordinates = [];
58891    }
58892    this.flatCoordinates.length = deflateCoordinates(
58893      this.flatCoordinates,
58894      0,
58895      coordinates,
58896      this.stride
58897    );
58898    this.changed();
58899  }
58900}
58901
58902/* harmony default export */ const geom_MultiPoint = (MultiPoint);
58903
58904;// CONCATENATED MODULE: ./node_modules/ol/geom/flat/center.js
58905/**
58906 * @module ol/geom/flat/center
58907 */
58908
58909
58910/**
58911 * @param {Array<number>} flatCoordinates Flat coordinates.
58912 * @param {number} offset Offset.
58913 * @param {Array<Array<number>>} endss Endss.
58914 * @param {number} stride Stride.
58915 * @return {Array<number>} Flat centers.
58916 */
58917function center_linearRingss(flatCoordinates, offset, endss, stride) {
58918  const flatCenters = [];
58919  let extent = createEmpty();
58920  for (let i = 0, ii = endss.length; i < ii; ++i) {
58921    const ends = endss[i];
58922    extent = createOrUpdateFromFlatCoordinates(
58923      flatCoordinates,
58924      offset,
58925      ends[0],
58926      stride
58927    );
58928    flatCenters.push((extent[0] + extent[2]) / 2, (extent[1] + extent[3]) / 2);
58929    offset = ends[ends.length - 1];
58930  }
58931  return flatCenters;
58932}
58933
58934;// CONCATENATED MODULE: ./node_modules/ol/geom/MultiPolygon.js
58935/**
58936 * @module ol/geom/MultiPolygon
58937 */
58938
58939
58940
58941
58942
58943
58944
58945
58946
58947
58948
58949
58950
58951
58952
58953
58954/**
58955 * @classdesc
58956 * Multi-polygon geometry.
58957 *
58958 * @api
58959 */
58960class MultiPolygon extends geom_SimpleGeometry {
58961  /**
58962   * @param {Array<Array<Array<import("../coordinate.js").Coordinate>>|Polygon>|Array<number>} coordinates Coordinates.
58963   *     For internal use, flat coordinates in combination with `layout` and `endss` are also accepted.
58964   * @param {import("./Geometry.js").GeometryLayout} [layout] Layout.
58965   * @param {Array<Array<number>>} [endss] Array of ends for internal use with flat coordinates.
58966   */
58967  constructor(coordinates, layout, endss) {
58968    super();
58969
58970    /**
58971     * @type {Array<Array<number>>}
58972     * @private
58973     */
58974    this.endss_ = [];
58975
58976    /**
58977     * @private
58978     * @type {number}
58979     */
58980    this.flatInteriorPointsRevision_ = -1;
58981
58982    /**
58983     * @private
58984     * @type {Array<number>}
58985     */
58986    this.flatInteriorPoints_ = null;
58987
58988    /**
58989     * @private
58990     * @type {number}
58991     */
58992    this.maxDelta_ = -1;
58993
58994    /**
58995     * @private
58996     * @type {number}
58997     */
58998    this.maxDeltaRevision_ = -1;
58999
59000    /**
59001     * @private
59002     * @type {number}
59003     */
59004    this.orientedRevision_ = -1;
59005
59006    /**
59007     * @private
59008     * @type {Array<number>}
59009     */
59010    this.orientedFlatCoordinates_ = null;
59011
59012    if (!endss && !Array.isArray(coordinates[0])) {
59013      let thisLayout = this.getLayout();
59014      const polygons = /** @type {Array<Polygon>} */ (coordinates);
59015      const flatCoordinates = [];
59016      const thisEndss = [];
59017      for (let i = 0, ii = polygons.length; i < ii; ++i) {
59018        const polygon = polygons[i];
59019        if (i === 0) {
59020          thisLayout = polygon.getLayout();
59021        }
59022        const offset = flatCoordinates.length;
59023        const ends = polygon.getEnds();
59024        for (let j = 0, jj = ends.length; j < jj; ++j) {
59025          ends[j] += offset;
59026        }
vendor: 13,004 bytes, lines 59027-59516
59027        array_extend(flatCoordinates, polygon.getFlatCoordinates());
59028        thisEndss.push(ends);
59029      }
59030      layout = thisLayout;
59031      coordinates = flatCoordinates;
59032      endss = thisEndss;
59033    }
59034    if (layout !== undefined && endss) {
59035      this.setFlatCoordinates(
59036        layout,
59037        /** @type {Array<number>} */ (coordinates)
59038      );
59039      this.endss_ = endss;
59040    } else {
59041      this.setCoordinates(
59042        /** @type {Array<Array<Array<import("../coordinate.js").Coordinate>>>} */ (
59043          coordinates
59044        ),
59045        layout
59046      );
59047    }
59048  }
59049
59050  /**
59051   * Append the passed polygon to this multipolygon.
59052   * @param {Polygon} polygon Polygon.
59053   * @api
59054   */
59055  appendPolygon(polygon) {
59056    /** @type {Array<number>} */
59057    let ends;
59058    if (!this.flatCoordinates) {
59059      this.flatCoordinates = polygon.getFlatCoordinates().slice();
59060      ends = polygon.getEnds().slice();
59061      this.endss_.push();
59062    } else {
59063      const offset = this.flatCoordinates.length;
59064      array_extend(this.flatCoordinates, polygon.getFlatCoordinates());
59065      ends = polygon.getEnds().slice();
59066      for (let i = 0, ii = ends.length; i < ii; ++i) {
59067        ends[i] += offset;
59068      }
59069    }
59070    this.endss_.push(ends);
59071    this.changed();
59072  }
59073
59074  /**
59075   * Make a complete copy of the geometry.
59076   * @return {!MultiPolygon} Clone.
59077   * @api
59078   */
59079  clone() {
59080    const len = this.endss_.length;
59081    const newEndss = new Array(len);
59082    for (let i = 0; i < len; ++i) {
59083      newEndss[i] = this.endss_[i].slice();
59084    }
59085
59086    const multiPolygon = new MultiPolygon(
59087      this.flatCoordinates.slice(),
59088      this.layout,
59089      newEndss
59090    );
59091    multiPolygon.applyProperties(this);
59092
59093    return multiPolygon;
59094  }
59095
59096  /**
59097   * @param {number} x X.
59098   * @param {number} y Y.
59099   * @param {import("../coordinate.js").Coordinate} closestPoint Closest point.
59100   * @param {number} minSquaredDistance Minimum squared distance.
59101   * @return {number} Minimum squared distance.
59102   */
59103  closestPointXY(x, y, closestPoint, minSquaredDistance) {
59104    if (minSquaredDistance < closestSquaredDistanceXY(this.getExtent(), x, y)) {
59105      return minSquaredDistance;
59106    }
59107    if (this.maxDeltaRevision_ != this.getRevision()) {
59108      this.maxDelta_ = Math.sqrt(
59109        multiArrayMaxSquaredDelta(
59110          this.flatCoordinates,
59111          0,
59112          this.endss_,
59113          this.stride,
59114          0
59115        )
59116      );
59117      this.maxDeltaRevision_ = this.getRevision();
59118    }
59119    return assignClosestMultiArrayPoint(
59120      this.getOrientedFlatCoordinates(),
59121      0,
59122      this.endss_,
59123      this.stride,
59124      this.maxDelta_,
59125      true,
59126      x,
59127      y,
59128      closestPoint,
59129      minSquaredDistance
59130    );
59131  }
59132
59133  /**
59134   * @param {number} x X.
59135   * @param {number} y Y.
59136   * @return {boolean} Contains (x, y).
59137   */
59138  containsXY(x, y) {
59139    return linearRingssContainsXY(
59140      this.getOrientedFlatCoordinates(),
59141      0,
59142      this.endss_,
59143      this.stride,
59144      x,
59145      y
59146    );
59147  }
59148
59149  /**
59150   * Return the area of the multipolygon on projected plane.
59151   * @return {number} Area (on projected plane).
59152   * @api
59153   */
59154  getArea() {
59155    return linearRingss(
59156      this.getOrientedFlatCoordinates(),
59157      0,
59158      this.endss_,
59159      this.stride
59160    );
59161  }
59162
59163  /**
59164   * Get the coordinate array for this geometry.  This array has the structure
59165   * of a GeoJSON coordinate array for multi-polygons.
59166   *
59167   * @param {boolean} [right] Orient coordinates according to the right-hand
59168   *     rule (counter-clockwise for exterior and clockwise for interior rings).
59169   *     If `false`, coordinates will be oriented according to the left-hand rule
59170   *     (clockwise for exterior and counter-clockwise for interior rings).
59171   *     By default, coordinate orientation will depend on how the geometry was
59172   *     constructed.
59173   * @return {Array<Array<Array<import("../coordinate.js").Coordinate>>>} Coordinates.
59174   * @api
59175   */
59176  getCoordinates(right) {
59177    let flatCoordinates;
59178    if (right !== undefined) {
59179      flatCoordinates = this.getOrientedFlatCoordinates().slice();
59180      orientLinearRingsArray(
59181        flatCoordinates,
59182        0,
59183        this.endss_,
59184        this.stride,
59185        right
59186      );
59187    } else {
59188      flatCoordinates = this.flatCoordinates;
59189    }
59190
59191    return inflateMultiCoordinatesArray(
59192      flatCoordinates,
59193      0,
59194      this.endss_,
59195      this.stride
59196    );
59197  }
59198
59199  /**
59200   * @return {Array<Array<number>>} Endss.
59201   */
59202  getEndss() {
59203    return this.endss_;
59204  }
59205
59206  /**
59207   * @return {Array<number>} Flat interior points.
59208   */
59209  getFlatInteriorPoints() {
59210    if (this.flatInteriorPointsRevision_ != this.getRevision()) {
59211      const flatCenters = center_linearRingss(
59212        this.flatCoordinates,
59213        0,
59214        this.endss_,
59215        this.stride
59216      );
59217      this.flatInteriorPoints_ = getInteriorPointsOfMultiArray(
59218        this.getOrientedFlatCoordinates(),
59219        0,
59220        this.endss_,
59221        this.stride,
59222        flatCenters
59223      );
59224      this.flatInteriorPointsRevision_ = this.getRevision();
59225    }
59226    return this.flatInteriorPoints_;
59227  }
59228
59229  /**
59230   * Return the interior points as {@link module:ol/geom/MultiPoint~MultiPoint multipoint}.
59231   * @return {MultiPoint} Interior points as XYM coordinates, where M is
59232   * the length of the horizontal intersection that the point belongs to.
59233   * @api
59234   */
59235  getInteriorPoints() {
59236    return new geom_MultiPoint(this.getFlatInteriorPoints().slice(), 'XYM');
59237  }
59238
59239  /**
59240   * @return {Array<number>} Oriented flat coordinates.
59241   */
59242  getOrientedFlatCoordinates() {
59243    if (this.orientedRevision_ != this.getRevision()) {
59244      const flatCoordinates = this.flatCoordinates;
59245      if (
59246        linearRingssAreOriented(flatCoordinates, 0, this.endss_, this.stride)
59247      ) {
59248        this.orientedFlatCoordinates_ = flatCoordinates;
59249      } else {
59250        this.orientedFlatCoordinates_ = flatCoordinates.slice();
59251        this.orientedFlatCoordinates_.length = orientLinearRingsArray(
59252          this.orientedFlatCoordinates_,
59253          0,
59254          this.endss_,
59255          this.stride
59256        );
59257      }
59258      this.orientedRevision_ = this.getRevision();
59259    }
59260    return this.orientedFlatCoordinates_;
59261  }
59262
59263  /**
59264   * @param {number} squaredTolerance Squared tolerance.
59265   * @return {MultiPolygon} Simplified MultiPolygon.
59266   * @protected
59267   */
59268  getSimplifiedGeometryInternal(squaredTolerance) {
59269    const simplifiedFlatCoordinates = [];
59270    const simplifiedEndss = [];
59271    simplifiedFlatCoordinates.length = quantizeMultiArray(
59272      this.flatCoordinates,
59273      0,
59274      this.endss_,
59275      this.stride,
59276      Math.sqrt(squaredTolerance),
59277      simplifiedFlatCoordinates,
59278      0,
59279      simplifiedEndss
59280    );
59281    return new MultiPolygon(simplifiedFlatCoordinates, 'XY', simplifiedEndss);
59282  }
59283
59284  /**
59285   * Return the polygon at the specified index.
59286   * @param {number} index Index.
59287   * @return {Polygon} Polygon.
59288   * @api
59289   */
59290  getPolygon(index) {
59291    if (index < 0 || this.endss_.length <= index) {
59292      return null;
59293    }
59294    let offset;
59295    if (index === 0) {
59296      offset = 0;
59297    } else {
59298      const prevEnds = this.endss_[index - 1];
59299      offset = prevEnds[prevEnds.length - 1];
59300    }
59301    const ends = this.endss_[index].slice();
59302    const end = ends[ends.length - 1];
59303    if (offset !== 0) {
59304      for (let i = 0, ii = ends.length; i < ii; ++i) {
59305        ends[i] -= offset;
59306      }
59307    }
59308    return new geom_Polygon(
59309      this.flatCoordinates.slice(offset, end),
59310      this.layout,
59311      ends
59312    );
59313  }
59314
59315  /**
59316   * Return the polygons of this multipolygon.
59317   * @return {Array<Polygon>} Polygons.
59318   * @api
59319   */
59320  getPolygons() {
59321    const layout = this.layout;
59322    const flatCoordinates = this.flatCoordinates;
59323    const endss = this.endss_;
59324    const polygons = [];
59325    let offset = 0;
59326    for (let i = 0, ii = endss.length; i < ii; ++i) {
59327      const ends = endss[i].slice();
59328      const end = ends[ends.length - 1];
59329      if (offset !== 0) {
59330        for (let j = 0, jj = ends.length; j < jj; ++j) {
59331          ends[j] -= offset;
59332        }
59333      }
59334      const polygon = new geom_Polygon(
59335        flatCoordinates.slice(offset, end),
59336        layout,
59337        ends
59338      );
59339      polygons.push(polygon);
59340      offset = end;
59341    }
59342    return polygons;
59343  }
59344
59345  /**
59346   * Get the type of this geometry.
59347   * @return {import("./Geometry.js").Type} Geometry type.
59348   * @api
59349   */
59350  getType() {
59351    return 'MultiPolygon';
59352  }
59353
59354  /**
59355   * Test if the geometry and the passed extent intersect.
59356   * @param {import("../extent.js").Extent} extent Extent.
59357   * @return {boolean} `true` if the geometry and the extent intersect.
59358   * @api
59359   */
59360  intersectsExtent(extent) {
59361    return intersectsLinearRingMultiArray(
59362      this.getOrientedFlatCoordinates(),
59363      0,
59364      this.endss_,
59365      this.stride,
59366      extent
59367    );
59368  }
59369
59370  /**
59371   * Set the coordinates of the multipolygon.
59372   * @param {!Array<Array<Array<import("../coordinate.js").Coordinate>>>} coordinates Coordinates.
59373   * @param {import("./Geometry.js").GeometryLayout} [layout] Layout.
59374   * @api
59375   */
59376  setCoordinates(coordinates, layout) {
59377    this.setLayout(layout, coordinates, 3);
59378    if (!this.flatCoordinates) {
59379      this.flatCoordinates = [];
59380    }
59381    const endss = deflateMultiCoordinatesArray(
59382      this.flatCoordinates,
59383      0,
59384      coordinates,
59385      this.stride,
59386      this.endss_
59387    );
59388    if (endss.length === 0) {
59389      this.flatCoordinates.length = 0;
59390    } else {
59391      const lastEnds = endss[endss.length - 1];
59392      this.flatCoordinates.length =
59393        lastEnds.length === 0 ? 0 : lastEnds[lastEnds.length - 1];
59394    }
59395    this.changed();
59396  }
59397}
59398
59399/* harmony default export */ const geom_MultiPolygon = (MultiPolygon);
59400
59401;// CONCATENATED MODULE: ./node_modules/ol/format/GeoJSON.js
59402/**
59403 * @module ol/format/GeoJSON
59404 */
59405
59406
59407
59408
59409
59410
59411
59412
59413
59414
59415
59416
59417
59418
59419
59420/**
59421 * @typedef {import("geojson").GeoJSON} GeoJSONObject
59422 * @typedef {import("geojson").Feature} GeoJSONFeature
59423 * @typedef {import("geojson").FeatureCollection} GeoJSONFeatureCollection
59424 * @typedef {import("geojson").Geometry} GeoJSONGeometry
59425 * @typedef {import("geojson").Point} GeoJSONPoint
59426 * @typedef {import("geojson").LineString} GeoJSONLineString
59427 * @typedef {import("geojson").Polygon} GeoJSONPolygon
59428 * @typedef {import("geojson").MultiPoint} GeoJSONMultiPoint
59429 * @typedef {import("geojson").MultiLineString} GeoJSONMultiLineString
59430 * @typedef {import("geojson").MultiPolygon} GeoJSONMultiPolygon
59431 * @typedef {import("geojson").GeometryCollection} GeoJSONGeometryCollection
59432 */
59433
59434/**
59435 * @typedef {Object} Options
59436 * @property {import("../proj.js").ProjectionLike} [dataProjection='EPSG:4326'] Default data projection.
59437 * @property {import("../proj.js").ProjectionLike} [featureProjection] Projection for features read or
59438 * written by the format.  Options passed to read or write methods will take precedence.
59439 * @property {string} [geometryName] Geometry name to use when creating features.
59440 * @property {boolean} [extractGeometryName=false] Certain GeoJSON providers include
59441 * the geometry_name field in the feature GeoJSON. If set to `true` the GeoJSON reader
59442 * will look for that field to set the geometry name. If both this field is set to `true`
59443 * and a `geometryName` is provided, the `geometryName` will take precedence.
59444 */
59445
59446/**
59447 * @classdesc
59448 * Feature format for reading and writing data in the GeoJSON format.
59449 *
59450 * @api
59451 */
59452class GeoJSON extends format_JSONFeature {
59453  /**
59454   * @param {Options} [options] Options.
59455   */
59456  constructor(options) {
59457    options = options ? options : {};
59458
59459    super();
59460
59461    /**
59462     * @type {import("../proj/Projection.js").default}
59463     */
59464    this.dataProjection = proj_get(
59465      options.dataProjection ? options.dataProjection : 'EPSG:4326'
59466    );
59467
59468    if (options.featureProjection) {
59469      /**
59470       * @type {import("../proj/Projection.js").default}
59471       */
59472      this.defaultFeatureProjection = proj_get(options.featureProjection);
59473    }
59474
59475    /**
59476     * Name of the geometry attribute for features.
59477     * @type {string|undefined}
59478     * @private
59479     */
59480    this.geometryName_ = options.geometryName;
59481
59482    /**
59483     * Look for the geometry name in the feature GeoJSON
59484     * @type {boolean|undefined}
59485     * @private
59486     */
59487    this.extractGeometryName_ = options.extractGeometryName;
59488
59489    this.supportedMediaTypes = [
59490      'application/geo+json',
59491      'application/vnd.geo+json',
59492    ];
59493  }
59494
59495  /**
59496   * @param {Object} object Object.
59497   * @param {import("./Feature.js").ReadOptions} [options] Read options.
59498   * @protected
59499   * @return {import("../Feature.js").default} Feature.
59500   */
59501  readFeatureFromObject(object, options) {
59502    /**
59503     * @type {GeoJSONFeature}
59504     */
59505    let geoJSONFeature = null;
59506    if (object['type'] === 'Feature') {
59507      geoJSONFeature = /** @type {GeoJSONFeature} */ (object);
59508    } else {
59509      geoJSONFeature = {
59510        'type': 'Feature',
59511        'geometry': /** @type {GeoJSONGeometry} */ (object),
59512        'properties': null,
59513      };
59514    }
59515
59516    const geometry = readGeometry(geoJSONFeature['geometry'], options);
59517    const feature = new ol_Feature();
59518    if (this.geometryName_) {
59519      feature.setGeometryName(this.geometryName_);
59520    } else if (
59521      this.extractGeometryName_ &&
59522      'geometry_name' in geoJSONFeature !== undefined
59523    ) {
59524      feature.setGeometryName(geoJSONFeature['geometry_name']);
59525    }
59526    feature.setGeometry(geometry);
59527
59528    if ('id' in geoJSONFeature) {
59529      feature.setId(geoJSONFeature['id']);
59530    }
59531
59532    if (geoJSONFeature['properties']) {
59533      feature.setProperties(geoJSONFeature['properties'], true);
59534    }
59535    return feature;
59536  }
59537
59538  /**
59539   * @param {Object} object Object.
59540   * @param {import("./Feature.js").ReadOptions} [options] Read options.
59541   * @protected
59542   * @return {Array<Feature>} Features.
59543   */
59544  readFeaturesFromObject(object, options) {
59545    const geoJSONObject = /** @type {GeoJSONObject} */ (object);
59546    /** @type {Array<import("../Feature.js").default>} */
59547    let features = null;
59548    if (geoJSONObject['type'] === 'FeatureCollection') {
59549      const geoJSONFeatureCollection = /** @type {GeoJSONFeatureCollection} */ (
59550        object
59551      );
59552      features = [];
59553      const geoJSONFeatures = geoJSONFeatureCollection['features'];
59554      for (let i = 0, ii = geoJSONFeatures.length; i < ii; ++i) {
59555        features.push(this.readFeatureFromObject(geoJSONFeatures[i], options));
59556      }
59557    } else {
59558      features = [this.readFeatureFromObject(object, options)];
59559    }
59560    return features;
59561  }
59562
59563  /**
59564   * @param {GeoJSONGeometry} object Object.
59565   * @param {import("./Feature.js").ReadOptions} [options] Read options.
59566   * @protected
59567   * @return {import("../geom/Geometry.js").default} Geometry.
59568   */
59569  readGeometryFromObject(object, options) {
59570    return readGeometry(object, options);
59571  }
59572
59573  /**
59574   * @param {Object} object Object.
59575   * @protected
59576   * @return {import("../proj/Projection.js").default} Projection.
59577   */
59578  readProjectionFromObject(object) {
59579    const crs = object['crs'];
59580    let projection;
59581    if (crs) {
59582      if (crs['type'] == 'name') {
59583        projection = proj_get(crs['properties']['name']);
59584      } else if (crs['type'] === 'EPSG') {
59585        projection = proj_get('EPSG:' + crs['properties']['code']);
59586      } else {
59587        asserts_assert(false, 36); // Unknown SRS type
59588      }
59589    } else {
59590      projection = this.dataProjection;
59591    }
59592    return /** @type {import("../proj/Projection.js").default} */ (projection);
59593  }
59594
59595  /**
59596   * Encode a feature as a GeoJSON Feature object.
59597   *
59598   * @param {import("../Feature.js").default} feature Feature.
59599   * @param {import("./Feature.js").WriteOptions} [options] Write options.
59600   * @return {GeoJSONFeature} Object.
59601   * @api
59602   */
59603  writeFeatureObject(feature, options) {
59604    options = this.adaptOptions(options);
59605
59606    /** @type {GeoJSONFeature} */
59607    const object = {
59608      'type': 'Feature',
59609      geometry: null,
59610      properties: null,
59611    };
59612
59613    const id = feature.getId();
59614    if (id !== undefined) {
59615      object.id = id;
59616    }
59617
59618    if (!feature.hasProperties()) {
59619      return object;
59620    }
59621
59622    const properties = feature.getProperties();
59623    const geometry = feature.getGeometry();
59624    if (geometry) {
59625      object.geometry = writeGeometry(geometry, options);
59626
59627      delete properties[feature.getGeometryName()];
59628    }
59629
59630    if (!obj_isEmpty(properties)) {
59631      object.properties = properties;
59632    }
59633
59634    return object;
59635  }
59636
59637  /**
59638   * Encode an array of features as a GeoJSON object.
59639   *
59640   * @param {Array<import("../Feature.js").default>} features Features.
59641   * @param {import("./Feature.js").WriteOptions} [options] Write options.
59642   * @return {GeoJSONFeatureCollection} GeoJSON Object.
59643   * @api
59644   */
59645  writeFeaturesObject(features, options) {
59646    options = this.adaptOptions(options);
59647    const objects = [];
59648    for (let i = 0, ii = features.length; i < ii; ++i) {
59649      objects.push(this.writeFeatureObject(features[i], options));
59650    }
59651    return {
59652      type: 'FeatureCollection',
59653      features: objects,
59654    };
59655  }
59656
59657  /**
59658   * Encode a geometry as a GeoJSON object.
59659   *
59660   * @param {import("../geom/Geometry.js").default} geometry Geometry.
59661   * @param {import("./Feature.js").WriteOptions} [options] Write options.
59662   * @return {GeoJSONGeometry|GeoJSONGeometryCollection} Object.
59663   * @api
59664   */
59665  writeGeometryObject(geometry, options) {
59666    return writeGeometry(geometry, this.adaptOptions(options));
59667  }
59668}
59669
59670/**
59671 * @param {GeoJSONGeometry|GeoJSONGeometryCollection} object Object.
59672 * @param {import("./Feature.js").ReadOptions} [options] Read options.
59673 * @return {import("../geom/Geometry.js").default} Geometry.
59674 */
59675function readGeometry(object, options) {
59676  if (!object) {
59677    return null;
59678  }
59679
59680  /**
59681   * @type {import("../geom/Geometry.js").default}
59682   */
59683  let geometry;
59684  switch (object['type']) {
59685    case 'Point': {
59686      geometry = readPointGeometry(/** @type {GeoJSONPoint} */ (object));
59687      break;
59688    }
59689    case 'LineString': {
59690      geometry = readLineStringGeometry(
59691        /** @type {GeoJSONLineString} */ (object)
59692      );
59693      break;
59694    }
59695    case 'Polygon': {
59696      geometry = readPolygonGeometry(/** @type {GeoJSONPolygon} */ (object));
59697      break;
59698    }
59699    case 'MultiPoint': {
59700      geometry = readMultiPointGeometry(
59701        /** @type {GeoJSONMultiPoint} */ (object)
59702      );
59703      break;
59704    }
59705    case 'MultiLineString': {
59706      geometry = readMultiLineStringGeometry(
59707        /** @type {GeoJSONMultiLineString} */ (object)
59708      );
59709      break;
59710    }
59711    case 'MultiPolygon': {
59712      geometry = readMultiPolygonGeometry(
59713        /** @type {GeoJSONMultiPolygon} */ (object)
59714      );
59715      break;
59716    }
59717    case 'GeometryCollection': {
59718      geometry = readGeometryCollectionGeometry(
59719        /** @type {GeoJSONGeometryCollection} */ (object)
59720      );
59721      break;
59722    }
59723    default: {
59724      throw new Error('Unsupported GeoJSON type: ' + object['type']);
59725    }
59726  }
59727  return transformGeometryWithOptions(geometry, false, options);
59728}
59729
59730/**
59731 * @param {GeoJSONGeometryCollection} object Object.
59732 * @param {import("./Feature.js").ReadOptions} [options] Read options.
59733 * @return {GeometryCollection} Geometry collection.
59734 */
59735function readGeometryCollectionGeometry(object, options) {
59736  const geometries = object['geometries'].map(
59737    /**
59738     * @param {GeoJSONGeometry} geometry Geometry.
59739     * @return {import("../geom/Geometry.js").default} geometry Geometry.
59740     */
59741    function (geometry) {
59742      return readGeometry(geometry, options);
59743    }
59744  );
59745  return new geom_GeometryCollection(geometries);
59746}
59747
59748/**
59749 * @param {GeoJSONPoint} object Object.
59750 * @return {Point} Point.
59751 */
59752function readPointGeometry(object) {
59753  return new geom_Point(object['coordinates']);
59754}
59755
59756/**
59757 * @param {GeoJSONLineString} object Object.
59758 * @return {LineString} LineString.
59759 */
59760function readLineStringGeometry(object) {
59761  return new geom_LineString(object['coordinates']);
59762}
59763
59764/**
59765 * @param {GeoJSONMultiLineString} object Object.
59766 * @return {MultiLineString} MultiLineString.
59767 */
59768function readMultiLineStringGeometry(object) {
59769  return new geom_MultiLineString(object['coordinates']);
59770}
59771
59772/**
59773 * @param {GeoJSONMultiPoint} object Object.
59774 * @return {MultiPoint} MultiPoint.
59775 */
59776function readMultiPointGeometry(object) {
59777  return new geom_MultiPoint(object['coordinates']);
59778}
59779
59780/**
59781 * @param {GeoJSONMultiPolygon} object Object.
59782 * @return {MultiPolygon} MultiPolygon.
59783 */
59784function readMultiPolygonGeometry(object) {
59785  return new geom_MultiPolygon(object['coordinates']);
59786}
59787
59788/**
59789 * @param {GeoJSONPolygon} object Object.
59790 * @return {Polygon} Polygon.
59791 */
59792function readPolygonGeometry(object) {
59793  return new geom_Polygon(object['coordinates']);
59794}
59795
59796/**
59797 * @param {import("../geom/Geometry.js").default} geometry Geometry.
59798 * @param {import("./Feature.js").WriteOptions} [options] Write options.
59799 * @return {GeoJSONGeometry} GeoJSON geometry.
59800 */
59801function writeGeometry(geometry, options) {
59802  geometry = transformGeometryWithOptions(geometry, true, options);
59803  const type = geometry.getType();
59804
59805  /** @type {GeoJSONGeometry} */
59806  let geoJSON;
59807  switch (type) {
59808    case 'Point': {
59809      geoJSON = writePointGeometry(/** @type {Point} */ (geometry), options);
59810      break;
59811    }
59812    case 'LineString': {
59813      geoJSON = writeLineStringGeometry(
59814        /** @type {LineString} */ (geometry),
59815        options
59816      );
59817      break;
59818    }
59819    case 'Polygon': {
59820      geoJSON = writePolygonGeometry(
59821        /** @type {Polygon} */ (geometry),
59822        options
59823      );
59824      break;
59825    }
59826    case 'MultiPoint': {
59827      geoJSON = writeMultiPointGeometry(
59828        /** @type {MultiPoint} */ (geometry),
59829        options
59830      );
59831      break;
59832    }
59833    case 'MultiLineString': {
59834      geoJSON = writeMultiLineStringGeometry(
59835        /** @type {MultiLineString} */ (geometry),
59836        options
59837      );
59838      break;
59839    }
59840    case 'MultiPolygon': {
59841      geoJSON = writeMultiPolygonGeometry(
59842        /** @type {MultiPolygon} */ (geometry),
59843        options
59844      );
59845      break;
59846    }
59847    case 'GeometryCollection': {
59848      geoJSON = writeGeometryCollectionGeometry(
59849        /** @type {GeometryCollection} */ (geometry),
59850        options
59851      );
59852      break;
59853    }
59854    case 'Circle': {
59855      geoJSON = {
59856        type: 'GeometryCollection',
59857        geometries: [],
59858      };
59859      break;
59860    }
59861    default: {
59862      throw new Error('Unsupported geometry type: ' + type);
59863    }
59864  }
59865  return geoJSON;
59866}
59867
59868/**
59869 * @param {GeometryCollection} geometry Geometry.
59870 * @param {import("./Feature.js").WriteOptions} [options] Write options.
59871 * @return {GeoJSONGeometryCollection} GeoJSON geometry collection.
59872 */
59873function writeGeometryCollectionGeometry(geometry, options) {
59874  options = Object.assign({}, options);
59875  delete options.featureProjection;
59876  const geometries = geometry.getGeometriesArray().map(function (geometry) {
59877    return writeGeometry(geometry, options);
59878  });
59879  return {
59880    type: 'GeometryCollection',
59881    geometries: geometries,
59882  };
59883}
59884
59885/**
59886 * @param {LineString} geometry Geometry.
59887 * @param {import("./Feature.js").WriteOptions} [options] Write options.
59888 * @return {GeoJSONGeometry} GeoJSON geometry.
59889 */
59890function writeLineStringGeometry(geometry, options) {
59891  return {
59892    type: 'LineString',
59893    coordinates: geometry.getCoordinates(),
59894  };
59895}
59896
59897/**
59898 * @param {MultiLineString} geometry Geometry.
59899 * @param {import("./Feature.js").WriteOptions} [options] Write options.
59900 * @return {GeoJSONGeometry} GeoJSON geometry.
59901 */
59902function writeMultiLineStringGeometry(geometry, options) {
59903  return {
59904    type: 'MultiLineString',
59905    coordinates: geometry.getCoordinates(),
59906  };
59907}
59908
59909/**
59910 * @param {MultiPoint} geometry Geometry.
59911 * @param {import("./Feature.js").WriteOptions} [options] Write options.
59912 * @return {GeoJSONGeometry} GeoJSON geometry.
59913 */
59914function writeMultiPointGeometry(geometry, options) {
59915  return {
59916    type: 'MultiPoint',
59917    coordinates: geometry.getCoordinates(),
59918  };
59919}
59920
59921/**
59922 * @param {MultiPolygon} geometry Geometry.
59923 * @param {import("./Feature.js").WriteOptions} [options] Write options.
59924 * @return {GeoJSONGeometry} GeoJSON geometry.
59925 */
59926function writeMultiPolygonGeometry(geometry, options) {
59927  let right;
59928  if (options) {
59929    right = options.rightHanded;
59930  }
59931  return {
59932    type: 'MultiPolygon',
59933    coordinates: geometry.getCoordinates(right),
59934  };
59935}
59936
59937/**
59938 * @param {Point} geometry Geometry.
59939 * @param {import("./Feature.js").WriteOptions} [options] Write options.
59940 * @return {GeoJSONGeometry} GeoJSON geometry.
59941 */
59942function writePointGeometry(geometry, options) {
59943  return {
59944    type: 'Point',
59945    coordinates: geometry.getCoordinates(),
59946  };
59947}
59948
59949/**
59950 * @param {Polygon} geometry Geometry.
59951 * @param {import("./Feature.js").WriteOptions} [options] Write options.
59952 * @return {GeoJSONGeometry} GeoJSON geometry.
59953 */
59954function writePolygonGeometry(geometry, options) {
59955  let right;
59956  if (options) {
59957    right = options.rightHanded;
59958  }
59959  return {
59960    type: 'Polygon',
59961    coordinates: geometry.getCoordinates(right),
59962  };
59963}
59964
59965/* harmony default export */ const format_GeoJSON = (GeoJSON);
59966
59967;// CONCATENATED MODULE: ./wwwroot/js/event-emitter.js
59968class EventEmitter { constructor() { this.events = {} } on(e, t) { return "object" != typeof this.events[e] && (this.events[e] = []), this.events[e].push(t), () => this.removeListener(e, t) } removeListener(e, t) { "object" != typeof this.events[e] || -1 < (t = this.events[e].indexOf(t)) && this.events[e].splice(t, 1) } emit(e, ...t) { "object" == typeof this.events[e] && this.events[e].forEach(e => e.apply(this, t)) } once(e, t) { const s = this.on(e, (...e) => { s(), t.apply(this, e) }) } }
59968 class EventManager extends EventEmitter { constructor() { super() } trigger_copter_selecting(e) { this.emit("copterselecting", { copter: e }) } trigger_copter_selected(e) { this.emit("copterselected", e) } trigger_waypoint_added(e) { this.emit("waypoint_added", e) } }
59969;// CONCATENATED MODULE: ./wwwroot/js/domain-map-openlayers.js
59970/* provided dependency */ var $ = __webpack_require__(755);
59971//import jQuery from "./bundle.min.js";
59972//import "https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.14.1/build/ol.js";
59973
59974
59975
59976
59977
59978
59979
59980
59981
59982
59983
59984
59985
59986
59987
59988
59989
59990
59991
59992
59993
59994//const $ = jQuery;
59995
59996class ControlOverlay extends control_Control {
59997    constructor(opt_options) {
59998        const options = opt_options || {};
59999
60000        super({
60001            element: options.element,
60002            target: options.target,
60003        });
60004    }
60005}
60006
60007Number.prototype.toDegrees = function () {
60008    return this * 180 / Math.PI;
60009}
60010
60011Number.prototype.toRadians = function () {
60012    return this * Math.PI / 180;
60013}
60014
60015class LonLat {
60016    constructor(lon, lat) {
60017        this.lat = Number(lat);
60018        this.lon = Number(lon);
60019    }
60020
60021    destinationPoint(distance, bearing, radius) {
60022        radius = (radius === undefined) ? 6371e3 : Number(radius);
60023
60024        var delta = Number(distance) / radius;
60025        var Theta = Number(bearing).toRadians();
60026
60027        var Phi1 = this.lat.toRadians();
60028        var Lambda1 = this.lon.toRadians();
60029
60030        var sinPhi1 = Math.sin(Phi1), cosPhi1 = Math.cos(Phi1);
60031        var sindelta = Math.sin(delta), cosdelta = Math.cos(delta);
60032        var sinTheta = Math.sin(Theta), cosTheta = Math.cos(Theta);
60033
60034        var sinPhi2 = sinPhi1 * cosdelta + cosPhi1 * sindelta * cosTheta;
60035        var Phi2 = Math.asin(sinPhi2);
60036        var y = sinTheta * sindelta * cosPhi1;
60037        var x = cosdelta - sinPhi1 * sinPhi2;
60038        var Lambda2 = Lambda1 + Math.atan2(y, x);
60039
60040        return new LonLat((Lambda2.toDegrees() + 540) % 360 - 180, Phi2.toDegrees());
60041        // normalise to −180..+180°
60042    }
60043}
60044 
60045const container = document.getElementById('popup');
60046const content = document.getElementById('popup-content');
60047const closer = document.getElementById('popup-closer');
60048
60049const overlay = new ol_Overlay({
60050    element: container,
60051    autoPan: {
60052        animation: {
60053            duration: 250,
60054        },
60055    },
60056});
60057
60058const nexradLayer = new WebGLTile({
60059    source: new source_XYZ({
60060        attributions: '',
60061        url: 'http://mesonet.agron.iastate.edu/cache/tile.py/1.0.0/nexrad-n0q-900913/{z}/{x}/{y}.png',
60062        maxZoom: 16,
60063    }),
60064});
60065
60066
60067function refresher() {
60068    $.getJSON('https://mesonet.agron.iastate.edu/json/tms.json', function (data) {
60069        $.each(data.services, function (key, val) {
60070            if (val.id == 'ridge_uscomp_n0q') {
60071                var dt = new Date(val.utc_valid);
60072                nexradLayer.set('title', "NEXRAD N0Q @"
60073                    + ("0" + dt.getUTCHours()).slice(-2)
60074                    + ("0" + dt.getUTCMinutes()).slice(-2)
60075                    + " UTC");
60076                nexradLayer.setSource(new XYZ({
60077                    url: 'https://mesonet.agron.iastate.edu/cache/tile.py/1.0.0/' + val.layername + '/{z}/{x}/{y}.png'
60078                }));
60079            }
60080        })
60081    });
60082
60083}
60084
60085closer.onclick = function () {
60086    overlay.setPosition(undefined);
60087    closer.blur();
60088    return false;
60089};
60090
60091function colorWithAlpha(color, alpha) {
60092    const [r, g, b] = Array.from(asArray(color));
60093    return asString([r, g, b, alpha]);
60094}
60095
60096function DomainMap(centralLatInput, centralLongInput, mapId, showControls) {
60097
60098
60099    var wofs_map = {
60100        domainSize: 900000, // meters
60101        map: {},
60102        overlay_urls: {
60103            "tornado": "https://www.spc.noaa.gov/products/outlook/day1otlk_torn.nolyr.geojson",
60104            "hail": "https://www.spc.noaa.gov/products/outlook/day1otlk_hail.nolyr.geojson",
60105            "wind": "https://www.spc.noaa.gov/products/outlook/day1otlk_wind.nolyr.geojson",
60106            "radars": "../json/radars.geojson"
60107        },
60108        domain: new Vector(),
60109        tornado: new Vector(),
60110        wind: new Vector(),
60111        hail: new Vector(),
60112        radars: new Vector(),
60113        lat: 0,
60114        lon: 0,
60115        selected_copter: '',
60116        eventManager: new EventManager(),
60117        controlOverlay: {},
60118        waypoints: [],
60119        update_copter_location: function (id, lat, lon) {
60120            var f = wofs_map.domain.getSource().getFeatures().filter(a => a.get('name') === id);
60121
60122            if (f && f.length > 0) {
60123                f[0].setGeometry(new geom_Point(fromLonLat([lon, lat])));
60124            }
60125        },
60126        loadControlOverlay: function () {
60127            $('.overlay input').on('change', function () {
60128                var cat = $(this).attr('data-category');
60129                if ($(this).prop('checked')) {
60130                    if (wofs_map.overlay_urls[cat]) {
60131                        const vectorSource = new source_Vector({
60132                            format: new format_GeoJSON(),
60133                            url: wofs_map.overlay_urls[cat]
60134                        });
60135                        wofs_map[cat].setSource(vectorSource);
60136
60137                    }
60138
60139                    wofs_map[cat].setVisible(true);
60140                }
60141                else {
60142                    wofs_map[cat].setVisible(false);
60143                }
60144            });
60145
60146            wofs_map.controlOverlay = $('.overlay').show();
60147        },
60148        initDomain: function () {
60149            //wofs_map.domain.setStyle(new Style({
60150            //    fill: new Fill({
60151            //        color: colorWithAlpha('#000', 0.15)
60152            //    }),
60153            //    stroke: new Stroke({
60154            //        color: colorWithAlpha('#000', 0.5)
60155            //    })
60156            //}));
60157
60158            wofs_map.lat = centralLatInput.val();
60159            wofs_map.lon = centralLongInput.val();
60160
60161            wofs_map.drawCopters(wofs_map.lon, wofs_map.lat);
60162
60163            $(`#${centralLatInput.attr('id')}, #${centralLongInput.attr('id')}`).on('change', function () {
60164                wofs_map.drawDomain(centralLongInput.val(), centralLatInput.val());
60165            });
60166        },
60167        drawCopters: function (lng, lat) {
60168            fetch('GetRecent').then(function (response) {
60169                return response.json();
60170            }).then(function (data) {
60171                var features = [];
60172
60173                for (const copter of data) {
60174                    var feature = new ol_Feature({
60175                        geometry: new geom_Point(fromLonLat([copter.longitude, copter.latitude])),
60176                        name: copter.id,
60177                        last_seen: copter.last_seen,
60178                        live_url: copter.live_url
60179                    });
60180                    features.push(feature);
60181                }
60182
60183                wofs_map.domain.setSource(new source_Vector({
60184                    features: features
60185                }));
60186
60187                wofs_map.map.getView().fit(wofs_map.domain.getSource().getExtent(), { maxZoom: 16 });
60188
60189            });
60190        },
60191        get_copter_color: function(last_seen) {
60192            if (last_seen <= 15) return 'rgba(6, 127, 0,1)';
60193            else if (last_seen <= 30) return 'rgba(234, 0, 0,1)';
60194            else return 'rgba(128,128,128,0.8)';
60195        },
60196        init: function () {
60197            var mapOptions = {
60198                controls: defaults().extend([new ControlOverlay({ element: $('.overlay')[0] }), new ControlOverlay({ element: $('.overlay-copter')[0] })]),
60199                interactions: defaults_defaults({ doubleClickZoom: false }),
60200                target: mapId,
60201                units: 'm',
60202                layers: [
60203                    new layer_Tile({
60204                        source: new source_OSM()
60205                    }),
60206                    //nexradLayer,
60207                    wofs_map.tornado,
60208                    wofs_map.hail,
60209                    wofs_map.wind,
60210                    wofs_map.domain
60211                ],
60212                overlays: [overlay],
60213                view: new ol_View({
60214                    center: fromLonLat([centralLongInput.val(), centralLatInput.val()]),
60215                    zoom: 7
60216                })
60217            };
60218
60219            wofs_map.map = new ol_Map(mapOptions);
60220
60221            //wofs_map.map.on('dblclick', function (event) {
60222            //    event.preventDefault();
60223            //    if (event.coordinate) {
60224            //        const [lon, lat] = transform(event.coordinate, 'EPSG:3857', 'EPSG:4326');
60225            //        centralLongInput.val(lon);
60226            //        centralLatInput.val(lat);
60227            //        centralLatInput.change();
60228            //    }
60229            //});
60230
60231            wofs_map.map.on('singleclick', function (e) {
60232                const coordinate = e.coordinate;
60233                //const hdms = toStringHDMS(toLonLat(coordinate));
60234
60235                var selected = null;
60236
60237                wofs_map.map.forEachFeatureAtPixel(e.pixel, function (f) {
60238                    selected = f;
60239                    return true;
60240                });
60241
60242                if (selected && selected.get('name')) {
60243                    wofs_map.eventManager.trigger_copter_selecting(wofs_map.selected_copter);
60244
60245                    wofs_map.selected_copter = selected.get('name');
60246                    wofs_map.waypoints = [];
60247
60248                    wofs_map.domain.getSource().getFeatures().forEach(a => a.set('selected', false));
60249
60250                    selected.set('selected', true);
60251
60252                    wofs_map.eventManager.trigger_copter_selected({
60253                        copter: wofs_map.selected_copter,
60254                        live_url: selected.get('live_url'),
60255                        last_seen: selected.get('last_seen')
60256                    });
60257
60258                    $('.overlay-copter').show();
60259                }
60260            });
60261
60262            if (showControls) {
60263                wofs_map.map.on('dblclick', function (e) {
60264                    $('#popup').removeClass('d-none');
60265
60266                    if (wofs_map.selected_copter.length > 0) {
60267                        const coordinate = e.coordinate;
60268                        const lonLat = toLonLat(coordinate);
60269
60270                        // for now, clear it out... maybe a future feature
60271                        wofs_map.waypoints = [];
60272                        wofs_map.waypoints.push({
60273                            latitude: lonLat[1],
60274                            longitude: lonLat[0]
60275                        });
60276                        overlay.setPosition(coordinate);
60277                        wofs_map.eventManager.trigger_waypoint_added(wofs_map.waypoints[wofs_map.waypoints.length - 1]);
60278                    }
60279                });
60280            }
60281
60282            wofs_map.map.on('pointermove', function (e) {
60283                var selected = null;
60284
60285                wofs_map.map.forEachFeatureAtPixel(e.pixel, function (f) {
60286                    selected = f;
60287                    return true;
60288                });
60289
60290                if (selected) {
60291                    $(`#${mapId}`).attr('title', selected.get('LABEL2') || selected.get('name'));
60292                } else {
60293                    $(`#${mapId}`).removeAttr('title');
60294                }
60295            });
60296
60297            wofs_map.loadControlOverlay();
60298
60299            wofs_map.initDomain();
60300
60301            function setDataStyles(data) {
60302                data.setStyle(function (feature, resolution) {
60303                    var props = feature.getProperties();
60304                    return new style_Style({
60305                        fill: new style_Fill({
60306                            color: colorWithAlpha(props['fill'], 0.15)
60307                        }),
60308                        stroke: new style_Stroke({
60309                            color: props['stroke']
60310                        })
60311                    });
60312                });
60313            }
60314
60315            setDataStyles(wofs_map.tornado);
60316            setDataStyles(wofs_map.hail);
60317            setDataStyles(wofs_map.wind);
60318
60319            wofs_map.domain.setStyle(function (feature, resolution) {
60320                var geo = feature.getGeometry();
60321
60322                //when it's a point
60323                if (geo.getType().toLowerCase() === 'point') {
60324                    var style = [
60325                        new style_Style({
60326                            image: new Circle({
60327                                radius: 7,
60328                                fill: new style_Fill({
60329                                    color: wofs_map.get_copter_color(feature.get('last_seen'))
60330                                })
60331                            })
60332                        })
60333                    ];
60334
60335                    if (feature.get('selected') === true)
60336                        style.push(new style_Style({
60337                            image: new Circle({
60338                                radius: 15,
60339                                stroke: new style_Stroke({
60340                                    color: 'rgba(0,191,255,0.5)',
60341                                    width: 5,
60342                                })
60343                            })
60344                        }));
60345
60346                    return style;
60347                }
60348            });
60349
60350            //refresher();
60351
60352            //window.setInterval(function () {
60353            //    refresher();
60354            //}, 5 * 60000);
60355
60356            $('#btnSampleColumn').on('click', async function () {
60357                if (wofs_map.selected_copter.length > 0 && wofs_map.waypoints.length > 0) {
60358                    const height = $('#txtHeight').val();
60359                    const response = await fetch("UpdateFlightPlan", {
60360                        method: 'POST',
60361                        headers: {
60362                            'Accept': 'application/json',
60363                            'Content-Type': 'application/json'
60364                        },
60365                        body: `{
60366                           "copter": "${wofs_map.selected_copter}",
60367                           "height": "${height}",
60368                           "lat": ${wofs_map.waypoints[0].latitude},
60369                           "lon": ${wofs_map.waypoints[0].longitude}
60370                        }`,
60371                    });
60372
60373                    if (response.ok) {
60374                        closer.onclick();
60375                        //console.log(data);
60376                    }
60377                }
60378            });
60379        }
60380    };
60381
60382    wofs_map.init();
60383
60384    return wofs_map;
60385}
60386;// CONCATENATED MODULE: ./node_modules/@microsoft/signalr/dist/esm/DefaultReconnectPolicy.js
60387// Licensed to the .NET Foundation under one or more agreements.
60388// The .NET Foundation licenses this file to you under the MIT license.
60389// 0, 2, 10, 30 second delays before reconnect attempts.
60390const DEFAULT_RETRY_DELAYS_IN_MILLISECONDS = [0, 2000, 10000, 30000, null];
60391/** @private */
60392class DefaultReconnectPolicy {
60393    constructor(retryDelays) {
60394        this._retryDelays = retryDelays !== undefined ? [...retryDelays, null] : DEFAULT_RETRY_DELAYS_IN_MILLISECONDS;
60395    }
60396    nextRetryDelayInMilliseconds(retryContext) {
60397        return this._retryDelays[retryContext.previousRetryCount];
60398    }
60399}
60400//# sourceMappingURL=DefaultReconnectPolicy.js.map
60401;// CONCATENATED MODULE: ./node_modules/@microsoft/signalr/dist/esm/Errors.js
60402// Licensed to the .NET Foundation under one or more agreements.
60403// The .NET Foundation licenses this file to you under the MIT license.
60404/** Error thrown when an HTTP request fails. */
60405class HttpError extends Error {
60406    /** Constructs a new instance of {@link @microsoft/signalr.HttpError}.
60407     *
60408     * @param {string} errorMessage A descriptive error message.
60409     * @param {number} statusCode The HTTP status code represented by this error.
60410     */
60411    constructor(errorMessage, statusCode) {
60412        const trueProto = new.target.prototype;
60413        super(`${errorMessage}: Status code '${statusCode}'`);
60414        this.statusCode = statusCode;
60415        // Workaround issue in Typescript compiler
60416        // https://github.com/Microsoft/TypeScript/issues/13965#issuecomment-278570200
60417        this.__proto__ = trueProto;
60418    }
60419}
60420/** Error thrown when a timeout elapses. */
60421class TimeoutError extends Error {
60422    /** Constructs a new instance of {@link @microsoft/signalr.TimeoutError}.
60423     *
60424     * @param {string} errorMessage A descriptive error message.
60425     */
60426    constructor(errorMessage = "A timeout occurred.") {
60427        const trueProto = new.target.prototype;
60428        super(errorMessage);
60429        // Workaround issue in Typescript compiler
60430        // https://github.com/Microsoft/TypeScript/issues/13965#issuecomment-278570200
60431        this.__proto__ = trueProto;
60432    }
60433}
60434/** Error thrown when an action is aborted. */
60435class AbortError extends Error {
60436    /** Constructs a new instance of {@link AbortError}.
60437     *
60438     * @param {string} errorMessage A descriptive error message.
60439     */
60440    constructor(errorMessage = "An abort occurred.") {
60441        const trueProto = new.target.prototype;
60442        super(errorMessage);
60443        // Workaround issue in Typescript compiler
60444        // https://github.com/Microsoft/TypeScript/issues/13965#issuecomment-278570200
60445        this.__proto__ = trueProto;
60446    }
60447}
60448/** Error thrown when the selected transport is unsupported by the browser. */
60449/** @private */
60450class UnsupportedTransportError extends Error {
60451    /** Constructs a new instance of {@link @microsoft/signalr.UnsupportedTransportError}.
60452     *
60453     * @param {string} message A descriptive error message.
60454     * @param {HttpTransportType} transport The {@link @microsoft/signalr.HttpTransportType} this error occured on.
60455     */
60456    constructor(message, transport) {
60457        const trueProto = new.target.prototype;
60458        super(message);
60459        this.transport = transport;
60460        this.errorType = 'UnsupportedTransportError';
60461        // Workaround issue in Typescript compiler
60462        // https://github.com/Microsoft/TypeScript/issues/13965#issuecomment-278570200
60463        this.__proto__ = trueProto;
60464    }
60465}
60466/** Error thrown when the selected transport is disabled by the browser. */
60467/** @private */
60468class DisabledTransportError extends Error {
60469    /** Constructs a new instance of {@link @microsoft/signalr.DisabledTransportError}.
60470     *
60471     * @param {string} message A descriptive error message.
60472     * @param {HttpTransportType} transport The {@link @microsoft/signalr.HttpTransportType} this error occured on.
60473     */
60474    constructor(message, transport) {
60475        const trueProto = new.target.prototype;
60476        super(message);
60477        this.transport = transport;
60478        this.errorType = 'DisabledTransportError';
60479        // Workaround issue in Typescript compiler
60480        // https://github.com/Microsoft/TypeScript/issues/13965#issuecomment-278570200
60481        this.__proto__ = trueProto;
60482    }
60483}
60484/** Error thrown when the selected transport cannot be started. */
60485/** @private */
60486class FailedToStartTransportError extends Error {
60487    /** Constructs a new instance of {@link @microsoft/signalr.FailedToStartTransportError}.
60488     *
60489     * @param {string} message A descriptive error message.
60490     * @param {HttpTransportType} transport The {@link @microsoft/signalr.HttpTransportType} this error occured on.
60491     */
60492    constructor(message, transport) {
60493        const trueProto = new.target.prototype;
60494        super(message);
60495        this.transport = transport;
60496        this.errorType = 'FailedToStartTransportError';
60497        // Workaround issue in Typescript compiler
60498        // https://github.com/Microsoft/TypeScript/issues/13965#issuecomment-278570200
60499        this.__proto__ = trueProto;
60500    }
60501}
60502/** Error thrown when the negotiation with the server failed to complete. */
60503/** @private */
vendor: 28,056 bytes, lines 60504-61235
60504class FailedToNegotiateWithServerError extends Error {
60505    /** Constructs a new instance of {@link @microsoft/signalr.FailedToNegotiateWithServerError}.
60506     *
60507     * @param {string} message A descriptive error message.
60508     */
60509    constructor(message) {
60510        const trueProto = new.target.prototype;
60511        super(message);
60512        this.errorType = 'FailedToNegotiateWithServerError';
60513        // Workaround issue in Typescript compiler
60514        // https://github.com/Microsoft/TypeScript/issues/13965#issuecomment-278570200
60515        this.__proto__ = trueProto;
60516    }
60517}
60518/** Error thrown when multiple errors have occured. */
60519/** @private */
60520class AggregateErrors extends Error {
60521    /** Constructs a new instance of {@link @microsoft/signalr.AggregateErrors}.
60522     *
60523     * @param {string} message A descriptive error message.
60524     * @param {Error[]} innerErrors The collection of errors this error is aggregating.
60525     */
60526    constructor(message, innerErrors) {
60527        const trueProto = new.target.prototype;
60528        super(message);
60529        this.innerErrors = innerErrors;
60530        // Workaround issue in Typescript compiler
60531        // https://github.com/Microsoft/TypeScript/issues/13965#issuecomment-278570200
60532        this.__proto__ = trueProto;
60533    }
60534}
60535//# sourceMappingURL=Errors.js.map
60536;// CONCATENATED MODULE: ./node_modules/@microsoft/signalr/dist/esm/HttpClient.js
60537// Licensed to the .NET Foundation under one or more agreements.
60538// The .NET Foundation licenses this file to you under the MIT license.
60539/** Represents an HTTP response. */
60540class HttpResponse {
60541    constructor(statusCode, statusText, content) {
60542        this.statusCode = statusCode;
60543        this.statusText = statusText;
60544        this.content = content;
60545    }
60546}
60547/** Abstraction over an HTTP client.
60548 *
60549 * This class provides an abstraction over an HTTP client so that a different implementation can be provided on different platforms.
60550 */
60551class HttpClient {
60552    get(url, options) {
60553        return this.send({
60554            ...options,
60555            method: "GET",
60556            url,
60557        });
60558    }
60559    post(url, options) {
60560        return this.send({
60561            ...options,
60562            method: "POST",
60563            url,
60564        });
60565    }
60566    delete(url, options) {
60567        return this.send({
60568            ...options,
60569            method: "DELETE",
60570            url,
60571        });
60572    }
60573    /** Gets all cookies that apply to the specified URL.
60574     *
60575     * @param url The URL that the cookies are valid for.
60576     * @returns {string} A string containing all the key-value cookie pairs for the specified URL.
60577     */
60578    // @ts-ignore
60579    getCookieString(url) {
60580        return "";
60581    }
60582}
60583//# sourceMappingURL=HttpClient.js.map
60584;// CONCATENATED MODULE: ./node_modules/@microsoft/signalr/dist/esm/ILogger.js
60585// Licensed to the .NET Foundation under one or more agreements.
60586// The .NET Foundation licenses this file to you under the MIT license.
60587// These values are designed to match the ASP.NET Log Levels since that's the pattern we're emulating here.
60588/** Indicates the severity of a log message.
60589 *
60590 * Log Levels are ordered in increasing severity. So `Debug` is more severe than `Trace`, etc.
60591 */
60592var LogLevel;
60593(function (LogLevel) {
60594    /** Log level for very low severity diagnostic messages. */
60595    LogLevel[LogLevel["Trace"] = 0] = "Trace";
60596    /** Log level for low severity diagnostic messages. */
60597    LogLevel[LogLevel["Debug"] = 1] = "Debug";
60598    /** Log level for informational diagnostic messages. */
60599    LogLevel[LogLevel["Information"] = 2] = "Information";
60600    /** Log level for diagnostic messages that indicate a non-fatal problem. */
60601    LogLevel[LogLevel["Warning"] = 3] = "Warning";
60602    /** Log level for diagnostic messages that indicate a failure in the current operation. */
60603    LogLevel[LogLevel["Error"] = 4] = "Error";
60604    /** Log level for diagnostic messages that indicate a failure that will terminate the entire application. */
60605    LogLevel[LogLevel["Critical"] = 5] = "Critical";
60606    /** The highest possible log level. Used when configuring logging to indicate that no log messages should be emitted. */
60607    LogLevel[LogLevel["None"] = 6] = "None";
60608})(LogLevel || (LogLevel = {}));
60609//# sourceMappingURL=ILogger.js.map
60610;// CONCATENATED MODULE: ./node_modules/@microsoft/signalr/dist/esm/Loggers.js
60611// Licensed to the .NET Foundation under one or more agreements.
60612// The .NET Foundation licenses this file to you under the MIT license.
60613/** A logger that does nothing when log messages are sent to it. */
60614class NullLogger {
60615    constructor() { }
60616    /** @inheritDoc */
60617    // eslint-disable-next-line
60618    log(_logLevel, _message) {
60619    }
60620}
60621/** The singleton instance of the {@link @microsoft/signalr.NullLogger}. */
60622NullLogger.instance = new NullLogger();
60623//# sourceMappingURL=Loggers.js.map
60624;// CONCATENATED MODULE: ./node_modules/@microsoft/signalr/dist/esm/Utils.js
60625// Licensed to the .NET Foundation under one or more agreements.
60626// The .NET Foundation licenses this file to you under the MIT license.
60627
60628
60629// Version token that will be replaced by the prepack command
60630/** The version of the SignalR client. */
60631const Utils_VERSION = "6.0.9";
60632/** @private */
60633class Arg {
60634    static isRequired(val, name) {
60635        if (val === null || val === undefined) {
60636            throw new Error(`The '${name}' argument is required.`);
60637        }
60638    }
60639    static isNotEmpty(val, name) {
60640        if (!val || val.match(/^\s*$/)) {
60641            throw new Error(`The '${name}' argument should not be empty.`);
60642        }
60643    }
60644    static isIn(val, values, name) {
60645        // TypeScript enums have keys for **both** the name and the value of each enum member on the type itself.
60646        if (!(val in values)) {
60647            throw new Error(`Unknown ${name} value: ${val}.`);
60648        }
60649    }
60650}
60651/** @private */
60652class Platform {
60653    // react-native has a window but no document so we should check both
60654    static get isBrowser() {
60655        return typeof window === "object" && typeof window.document === "object";
60656    }
60657    // WebWorkers don't have a window object so the isBrowser check would fail
60658    static get isWebWorker() {
60659        return typeof self === "object" && "importScripts" in self;
60660    }
60661    // react-native has a window but no document
60662    static get isReactNative() {
60663        return typeof window === "object" && typeof window.document === "undefined";
60664    }
60665    // Node apps shouldn't have a window object, but WebWorkers don't either
60666    // so we need to check for both WebWorker and window
60667    static get isNode() {
60668        return !this.isBrowser && !this.isWebWorker && !this.isReactNative;
60669    }
60670}
60671/** @private */
60672function getDataDetail(data, includeContent) {
60673    let detail = "";
60674    if (isArrayBuffer(data)) {
60675        detail = `Binary data of length ${data.byteLength}`;
60676        if (includeContent) {
60677            detail += `. Content: '${formatArrayBuffer(data)}'`;
60678        }
60679    }
60680    else if (typeof data === "string") {
60681        detail = `String data of length ${data.length}`;
60682        if (includeContent) {
60683            detail += `. Content: '${data}'`;
60684        }
60685    }
60686    return detail;
60687}
60688/** @private */
60689function formatArrayBuffer(data) {
60690    const view = new Uint8Array(data);
60691    // Uint8Array.map only supports returning another Uint8Array?
60692    let str = "";
60693    view.forEach((num) => {
60694        const pad = num < 16 ? "0" : "";
60695        str += `0x${pad}${num.toString(16)} `;
60696    });
60697    // Trim of trailing space.
60698    return str.substr(0, str.length - 1);
60699}
60700// Also in signalr-protocol-msgpack/Utils.ts
60701/** @private */
60702function isArrayBuffer(val) {
60703    return val && typeof ArrayBuffer !== "undefined" &&
60704        (val instanceof ArrayBuffer ||
60705            // Sometimes we get an ArrayBuffer that doesn't satisfy instanceof
60706            (val.constructor && val.constructor.name === "ArrayBuffer"));
60707}
60708/** @private */
60709async function sendMessage(logger, transportName, httpClient, url, accessTokenFactory, content, options) {
60710    let headers = {};
60711    if (accessTokenFactory) {
60712        const token = await accessTokenFactory();
60713        if (token) {
60714            headers = {
60715                ["Authorization"]: `Bearer ${token}`,
60716            };
60717        }
60718    }
60719    const [name, value] = getUserAgentHeader();
60720    headers[name] = value;
60721    logger.log(LogLevel.Trace, `(${transportName} transport) sending data. ${getDataDetail(content, options.logMessageContent)}.`);
60722    const responseType = isArrayBuffer(content) ? "arraybuffer" : "text";
60723    const response = await httpClient.post(url, {
60724        content,
60725        headers: { ...headers, ...options.headers },
60726        responseType,
60727        timeout: options.timeout,
60728        withCredentials: options.withCredentials,
60729    });
60730    logger.log(LogLevel.Trace, `(${transportName} transport) request complete. Response status: ${response.statusCode}.`);
60731}
60732/** @private */
60733function createLogger(logger) {
60734    if (logger === undefined) {
60735        return new ConsoleLogger(LogLevel.Information);
60736    }
60737    if (logger === null) {
60738        return NullLogger.instance;
60739    }
60740    if (logger.log !== undefined) {
60741        return logger;
60742    }
60743    return new ConsoleLogger(logger);
60744}
60745/** @private */
60746class SubjectSubscription {
60747    constructor(subject, observer) {
60748        this._subject = subject;
60749        this._observer = observer;
60750    }
60751    dispose() {
60752        const index = this._subject.observers.indexOf(this._observer);
60753        if (index > -1) {
60754            this._subject.observers.splice(index, 1);
60755        }
60756        if (this._subject.observers.length === 0 && this._subject.cancelCallback) {
60757            this._subject.cancelCallback().catch((_) => { });
60758        }
60759    }
60760}
60761/** @private */
60762class ConsoleLogger {
60763    constructor(minimumLogLevel) {
60764        this._minLevel = minimumLogLevel;
60765        this.out = console;
60766    }
60767    log(logLevel, message) {
60768        if (logLevel >= this._minLevel) {
60769            const msg = `[${new Date().toISOString()}] ${LogLevel[logLevel]}: ${message}`;
60770            switch (logLevel) {
60771                case LogLevel.Critical:
60772                case LogLevel.Error:
60773                    this.out.error(msg);
60774                    break;
60775                case LogLevel.Warning:
60776                    this.out.warn(msg);
60777                    break;
60778                case LogLevel.Information:
60779                    this.out.info(msg);
60780                    break;
60781                default:
60782                    // console.debug only goes to attached debuggers in Node, so we use console.log for Trace and Debug
60783                    this.out.log(msg);
60784                    break;
60785            }
60786        }
60787    }
60788}
60789/** @private */
60790function getUserAgentHeader() {
60791    let userAgentHeaderName = "X-SignalR-User-Agent";
60792    if (Platform.isNode) {
60793        userAgentHeaderName = "User-Agent";
60794    }
60795    return [userAgentHeaderName, constructUserAgent(Utils_VERSION, getOsName(), getRuntime(), getRuntimeVersion())];
60796}
60797/** @private */
60798function constructUserAgent(version, os, runtime, runtimeVersion) {
60799    // Microsoft SignalR/[Version] ([Detailed Version]; [Operating System]; [Runtime]; [Runtime Version])
60800    let userAgent = "Microsoft SignalR/";
60801    const majorAndMinor = version.split(".");
60802    userAgent += `${majorAndMinor[0]}.${majorAndMinor[1]}`;
60803    userAgent += ` (${version}; `;
60804    if (os && os !== "") {
60805        userAgent += `${os}; `;
60806    }
60807    else {
60808        userAgent += "Unknown OS; ";
60809    }
60810    userAgent += `${runtime}`;
60811    if (runtimeVersion) {
60812        userAgent += `; ${runtimeVersion}`;
60813    }
60814    else {
60815        userAgent += "; Unknown Runtime Version";
60816    }
60817    userAgent += ")";
60818    return userAgent;
60819}
60820// eslint-disable-next-line spaced-comment
60821/*#__PURE__*/ function getOsName() {
60822    if (Platform.isNode) {
60823        switch (process.platform) {
60824            case "win32":
60825                return "Windows NT";
60826            case "darwin":
60827                return "macOS";
60828            case "linux":
60829                return "Linux";
60830            default:
60831                return process.platform;
60832        }
60833    }
60834    else {
60835        return "";
60836    }
60837}
60838// eslint-disable-next-line spaced-comment
60839/*#__PURE__*/ function getRuntimeVersion() {
60840    if (Platform.isNode) {
60841        return process.versions.node;
60842    }
60843    return undefined;
60844}
60845function getRuntime() {
60846    if (Platform.isNode) {
60847        return "NodeJS";
60848    }
60849    else {
60850        return "Browser";
60851    }
60852}
60853/** @private */
60854function getErrorString(e) {
60855    if (e.stack) {
60856        return e.stack;
60857    }
60858    else if (e.message) {
60859        return e.message;
60860    }
60861    return `${e}`;
60862}
60863/** @private */
60864function getGlobalThis() {
60865    // globalThis is semi-new and not available in Node until v12
60866    if (typeof globalThis !== "undefined") {
60867        return globalThis;
60868    }
60869    if (typeof self !== "undefined") {
60870        return self;
60871    }
60872    if (typeof window !== "undefined") {
60873        return window;
60874    }
60875    if (typeof __webpack_require__.g !== "undefined") {
60876        return __webpack_require__.g;
60877    }
60878    throw new Error("could not find global");
60879}
60880//# sourceMappingURL=Utils.js.map
60881;// CONCATENATED MODULE: ./node_modules/@microsoft/signalr/dist/esm/FetchHttpClient.js
60882// Licensed to the .NET Foundation under one or more agreements.
60883// The .NET Foundation licenses this file to you under the MIT license.
60884
60885
60886
60887
60888class FetchHttpClient extends HttpClient {
60889    constructor(logger) {
60890        super();
60891        this._logger = logger;
60892        if (typeof fetch === "undefined") {
60893            // In order to ignore the dynamic require in webpack builds we need to do this magic
60894            // @ts-ignore: TS doesn't know about these names
60895            const requireFunc =  true ? require : 0;
60896            // Cookies aren't automatically handled in Node so we need to add a CookieJar to preserve cookies across requests
60897            this._jar = new (requireFunc("tough-cookie")).CookieJar();
60898            this._fetchType = requireFunc("node-fetch");
60899            // node-fetch doesn't have a nice API for getting and setting cookies
60900            // fetch-cookie will wrap a fetch implementation with a default CookieJar or a provided one
60901            this._fetchType = requireFunc("fetch-cookie")(this._fetchType, this._jar);
60902        }
60903        else {
60904            this._fetchType = fetch.bind(getGlobalThis());
60905        }
60906        if (typeof AbortController === "undefined") {
60907            // In order to ignore the dynamic require in webpack builds we need to do this magic
60908            // @ts-ignore: TS doesn't know about these names
60909            const requireFunc =  true ? require : 0;
60910            // Node needs EventListener methods on AbortController which our custom polyfill doesn't provide
60911            this._abortControllerType = requireFunc("abort-controller");
60912        }
60913        else {
60914            this._abortControllerType = AbortController;
60915        }
60916    }
60917    /** @inheritDoc */
60918    async send(request) {
60919        // Check that abort was not signaled before calling send
60920        if (request.abortSignal && request.abortSignal.aborted) {
60921            throw new AbortError();
60922        }
60923        if (!request.method) {
60924            throw new Error("No method defined.");
60925        }
60926        if (!request.url) {
60927            throw new Error("No url defined.");
60928        }
60929        const abortController = new this._abortControllerType();
60930        let error;
60931        // Hook our abortSignal into the abort controller
60932        if (request.abortSignal) {
60933            request.abortSignal.onabort = () => {
60934                abortController.abort();
60935                error = new AbortError();
60936            };
60937        }
60938        // If a timeout has been passed in, setup a timeout to call abort
60939        // Type needs to be any to fit window.setTimeout and NodeJS.setTimeout
60940        let timeoutId = null;
60941        if (request.timeout) {
60942            const msTimeout = request.timeout;
60943            timeoutId = setTimeout(() => {
60944                abortController.abort();
60945                this._logger.log(LogLevel.Warning, `Timeout from HTTP request.`);
60946                error = new TimeoutError();
60947            }, msTimeout);
60948        }
60949        let response;
60950        try {
60951            response = await this._fetchType(request.url, {
60952                body: request.content,
60953                cache: "no-cache",
60954                credentials: request.withCredentials === true ? "include" : "same-origin",
60955                headers: {
60956                    "Content-Type": "text/plain;charset=UTF-8",
60957                    "X-Requested-With": "XMLHttpRequest",
60958                    ...request.headers,
60959                },
60960                method: request.method,
60961                mode: "cors",
60962                redirect: "follow",
60963                signal: abortController.signal,
60964            });
60965        }
60966        catch (e) {
60967            if (error) {
60968                throw error;
60969            }
60970            this._logger.log(LogLevel.Warning, `Error from HTTP request. ${e}.`);
60971            throw e;
60972        }
60973        finally {
60974            if (timeoutId) {
60975                clearTimeout(timeoutId);
60976            }
60977            if (request.abortSignal) {
60978                request.abortSignal.onabort = null;
60979            }
60980        }
60981        if (!response.ok) {
60982            const errorMessage = await deserializeContent(response, "text");
60983            throw new HttpError(errorMessage || response.statusText, response.status);
60984        }
60985        const content = deserializeContent(response, request.responseType);
60986        const payload = await content;
60987        return new HttpResponse(response.status, response.statusText, payload);
60988    }
60989    getCookieString(url) {
60990        let cookies = "";
60991        if (Platform.isNode && this._jar) {
60992            // @ts-ignore: unused variable
60993            this._jar.getCookies(url, (e, c) => cookies = c.join("; "));
60994        }
60995        return cookies;
60996    }
60997}
60998function deserializeContent(response, responseType) {
60999    let content;
61000    switch (responseType) {
61001        case "arraybuffer":
61002            content = response.arrayBuffer();
61003            break;
61004        case "text":
61005            content = response.text();
61006            break;
61007        case "blob":
61008        case "document":
61009        case "json":
61010            throw new Error(`${responseType} is not supported.`);
61011        default:
61012            content = response.text();
61013            break;
61014    }
61015    return content;
61016}
61017//# sourceMappingURL=FetchHttpClient.js.map
61018;// CONCATENATED MODULE: ./node_modules/@microsoft/signalr/dist/esm/XhrHttpClient.js
61019// Licensed to the .NET Foundation under one or more agreements.
61020// The .NET Foundation licenses this file to you under the MIT license.
61021
61022
61023
61024class XhrHttpClient extends HttpClient {
61025    constructor(logger) {
61026        super();
61027        this._logger = logger;
61028    }
61029    /** @inheritDoc */
61030    send(request) {
61031        // Check that abort was not signaled before calling send
61032        if (request.abortSignal && request.abortSignal.aborted) {
61033            return Promise.reject(new AbortError());
61034        }
61035        if (!request.method) {
61036            return Promise.reject(new Error("No method defined."));
61037        }
61038        if (!request.url) {
61039            return Promise.reject(new Error("No url defined."));
61040        }
61041        return new Promise((resolve, reject) => {
61042            const xhr = new XMLHttpRequest();
61043            xhr.open(request.method, request.url, true);
61044            xhr.withCredentials = request.withCredentials === undefined ? true : request.withCredentials;
61045            xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
61046            // Explicitly setting the Content-Type header for React Native on Android platform.
61047            xhr.setRequestHeader("Content-Type", "text/plain;charset=UTF-8");
61048            const headers = request.headers;
61049            if (headers) {
61050                Object.keys(headers)
61051                    .forEach((header) => {
61052                    xhr.setRequestHeader(header, headers[header]);
61053                });
61054            }
61055            if (request.responseType) {
61056                xhr.responseType = request.responseType;
61057            }
61058            if (request.abortSignal) {
61059                request.abortSignal.onabort = () => {
61060                    xhr.abort();
61061                    reject(new AbortError());
61062                };
61063            }
61064            if (request.timeout) {
61065                xhr.timeout = request.timeout;
61066            }
61067            xhr.onload = () => {
61068                if (request.abortSignal) {
61069                    request.abortSignal.onabort = null;
61070                }
61071                if (xhr.status >= 200 && xhr.status < 300) {
61072                    resolve(new HttpResponse(xhr.status, xhr.statusText, xhr.response || xhr.responseText));
61073                }
61074                else {
61075                    reject(new HttpError(xhr.response || xhr.responseText || xhr.statusText, xhr.status));
61076                }
61077            };
61078            xhr.onerror = () => {
61079                this._logger.log(LogLevel.Warning, `Error from HTTP request. ${xhr.status}: ${xhr.statusText}.`);
61080                reject(new HttpError(xhr.statusText, xhr.status));
61081            };
61082            xhr.ontimeout = () => {
61083                this._logger.log(LogLevel.Warning, `Timeout from HTTP request.`);
61084                reject(new TimeoutError());
61085            };
61086            xhr.send(request.content || "");
61087        });
61088    }
61089}
61090//# sourceMappingURL=XhrHttpClient.js.map
61091;// CONCATENATED MODULE: ./node_modules/@microsoft/signalr/dist/esm/DefaultHttpClient.js
61092// Licensed to the .NET Foundation under one or more agreements.
61093// The .NET Foundation licenses this file to you under the MIT license.
61094
61095
61096
61097
61098
61099/** Default implementation of {@link @microsoft/signalr.HttpClient}. */
61100class DefaultHttpClient extends HttpClient {
61101    /** Creates a new instance of the {@link @microsoft/signalr.DefaultHttpClient}, using the provided {@link @microsoft/signalr.ILogger} to log messages. */
61102    constructor(logger) {
61103        super();
61104        if (typeof fetch !== "undefined" || Platform.isNode) {
61105            this._httpClient = new FetchHttpClient(logger);
61106        }
61107        else if (typeof XMLHttpRequest !== "undefined") {
61108            this._httpClient = new XhrHttpClient(logger);
61109        }
61110        else {
61111            throw new Error("No usable HttpClient found.");
61112        }
61113    }
61114    /** @inheritDoc */
61115    send(request) {
61116        // Check that abort was not signaled before calling send
61117        if (request.abortSignal && request.abortSignal.aborted) {
61118            return Promise.reject(new AbortError());
61119        }
61120        if (!request.method) {
61121            return Promise.reject(new Error("No method defined."));
61122        }
61123        if (!request.url) {
61124            return Promise.reject(new Error("No url defined."));
61125        }
61126        return this._httpClient.send(request);
61127    }
61128    getCookieString(url) {
61129        return this._httpClient.getCookieString(url);
61130    }
61131}
61132//# sourceMappingURL=DefaultHttpClient.js.map
61133;// CONCATENATED MODULE: ./node_modules/@microsoft/signalr/dist/esm/HeaderNames.js
61134// Licensed to the .NET Foundation under one or more agreements.
61135// The .NET Foundation licenses this file to you under the MIT license.
61136class HeaderNames {
61137}
61138HeaderNames.Authorization = "Authorization";
61139HeaderNames.Cookie = "Cookie";
61140//# sourceMappingURL=HeaderNames.js.map
61141;// CONCATENATED MODULE: ./node_modules/@microsoft/signalr/dist/esm/ITransport.js
61142// Licensed to the .NET Foundation under one or more agreements.
61143// The .NET Foundation licenses this file to you under the MIT license.
61144// This will be treated as a bit flag in the future, so we keep it using power-of-two values.
61145/** Specifies a specific HTTP transport type. */
61146var HttpTransportType;
61147(function (HttpTransportType) {
61148    /** Specifies no transport preference. */
61149    HttpTransportType[HttpTransportType["None"] = 0] = "None";
61150    /** Specifies the WebSockets transport. */
61151    HttpTransportType[HttpTransportType["WebSockets"] = 1] = "WebSockets";
61152    /** Specifies the Server-Sent Events transport. */
61153    HttpTransportType[HttpTransportType["ServerSentEvents"] = 2] = "ServerSentEvents";
61154    /** Specifies the Long Polling transport. */
61155    HttpTransportType[HttpTransportType["LongPolling"] = 4] = "LongPolling";
61156})(HttpTransportType || (HttpTransportType = {}));
61157/** Specifies the transfer format for a connection. */
61158var TransferFormat;
61159(function (TransferFormat) {
61160    /** Specifies that only text data will be transmitted over the connection. */
61161    TransferFormat[TransferFormat["Text"] = 1] = "Text";
61162    /** Specifies that binary data will be transmitted over the connection. */
61163    TransferFormat[TransferFormat["Binary"] = 2] = "Binary";
61164})(TransferFormat || (TransferFormat = {}));
61165//# sourceMappingURL=ITransport.js.map
61166;// CONCATENATED MODULE: ./node_modules/@microsoft/signalr/dist/esm/AbortController.js
61167// Licensed to the .NET Foundation under one or more agreements.
61168// The .NET Foundation licenses this file to you under the MIT license.
61169// Rough polyfill of https://developer.mozilla.org/en-US/docs/Web/API/AbortController
61170// We don't actually ever use the API being polyfilled, we always use the polyfill because
61171// it's a very new API right now.
61172// Not exported from index.
61173/** @private */
61174class AbortController_AbortController {
61175    constructor() {
61176        this._isAborted = false;
61177        this.onabort = null;
61178    }
61179    abort() {
61180        if (!this._isAborted) {
61181            this._isAborted = true;
61182            if (this.onabort) {
61183                this.onabort();
61184            }
61185        }
61186    }
61187    get signal() {
61188        return this;
61189    }
61190    get aborted() {
61191        return this._isAborted;
61192    }
61193}
61194//# sourceMappingURL=AbortController.js.map
61195;// CONCATENATED MODULE: ./node_modules/@microsoft/signalr/dist/esm/LongPollingTransport.js
61196// Licensed to the .NET Foundation under one or more agreements.
61197// The .NET Foundation licenses this file to you under the MIT license.
61198
61199
61200
61201
61202
61203
61204// Not exported from 'index', this type is internal.
61205/** @private */
61206class LongPollingTransport {
61207    constructor(httpClient, accessTokenFactory, logger, options) {
61208        this._httpClient = httpClient;
61209        this._accessTokenFactory = accessTokenFactory;
61210        this._logger = logger;
61211        this._pollAbort = new AbortController_AbortController();
61212        this._options = options;
61213        this._running = false;
61214        this.onreceive = null;
61215        this.onclose = null;
61216    }
61217    // This is an internal type, not exported from 'index' so this is really just internal.
61218    get pollAborted() {
61219        return this._pollAbort.aborted;
61220    }
61221    async connect(url, transferFormat) {
61222        Arg.isRequired(url, "url");
61223        Arg.isRequired(transferFormat, "transferFormat");
61224        Arg.isIn(transferFormat, TransferFormat, "transferFormat");
61225        this._url = url;
61226        this._logger.log(LogLevel.Trace, "(LongPolling transport) Connecting.");
61227        // Allow binary format on Node and Browsers that support binary content (indicated by the presence of responseType property)
61228        if (transferFormat === TransferFormat.Binary &&
61229            (typeof XMLHttpRequest !== "undefined" && typeof new XMLHttpRequest().responseType !== "string")) {
61230            throw new Error("Binary protocols over XmlHttpRequest not implementing advanced features are not supported.");
61231        }
61232        const [name, value] = getUserAgentHeader();
61233        const headers = { [name]: value, ...this._options.headers };
61234        const pollOptions = {
61235            abortSignal: this._pollAbort.signal,
61236            headers,
61237            timeout: 100000,
61238            withCredentials: this._options.withCredentials,
61239        };
61240        if (transferFormat === TransferFormat.Binary) {
61241            pollOptions.responseType = "arraybuffer";
61242        }
61243        const token = await this._getAccessToken();
61244        this._updateHeaderToken(pollOptions, token);
61245        // Make initial long polling request
61246        // Server uses first long polling request to finish initializing connection and it returns without data
61247        const pollUrl = `${url}&_=${Date.now()}`;
61248        this._logger.log(LogLevel.Trace, `(LongPolling transport) polling: ${pollUrl}.`);
61249        const response = await this._httpClient.get(pollUrl, pollOptions);
61250        if (response.statusCode !== 200) {
61251            this._logger.log(LogLevel.Error, `(LongPolling transport) Unexpected response code: ${response.statusCode}.`);
61252            // Mark running as false so that the poll immediately ends and runs the close logic
61253            this._closeError = new HttpError(response.statusText || "", response.statusCode);
61254            this._running = false;
61255        }
61256        else {
61257            this._running = true;
61258        }
61259        this._receiving = this._poll(this._url, pollOptions);
61260    }
61261    async _getAccessToken() {
61262        if (this._accessTokenFactory) {
61263            return await this._accessTokenFactory();
61264        }
61265        return null;
61266    }
61267    _updateHeaderToken(request, token) {
61268        if (!request.headers) {
61269            request.headers = {};
61270        }
61271        if (token) {
61272            request.headers[HeaderNames.Authorization] = `Bearer ${token}`;
61273            return;
61274        }
61275        if (request.headers[HeaderNames.Authorization]) {
61276            delete request.headers[HeaderNames.Authorization];
61277        }
61278    }
61279    async _poll(url, pollOptions) {
61280        try {
61281            while (this._running) {
61282                // We have to get the access token on each poll, in case it changes
61283                const token = await this._getAccessToken();
61284                this._updateHeaderToken(pollOptions, token);
61285                try {
61286                    const pollUrl = `${url}&_=${Date.now()}`;
61287                    this._logger.log(LogLevel.Trace, `(LongPolling transport) polling: ${pollUrl}.`);
61288                    const response = await this._httpClient.get(pollUrl, pollOptions);
61289                    if (response.statusCode === 204) {
61290                        this._logger.log(LogLevel.Information, "(LongPolling transport) Poll terminated by server.");
61291                        this._running = false;
61292                    }
61293                    else if (response.statusCode !== 200) {
61294                        this._logger.log(LogLevel.Error, `(LongPolling transport) Unexpected response code: ${response.statusCode}.`);
61295                        // Unexpected status code
61296                        this._closeError = new HttpError(response.statusText || "", response.statusCode);
61297                        this._running = false;
61298                    }
61299                    else {
61300                        // Process the response
61301                        if (response.content) {
61302                            this._logger.log(LogLevel.Trace, `(LongPolling transport) data received. ${getDataDetail(response.content, this._options.logMessageContent)}.`);
61303                            if (this.onreceive) {
61304                                this.onreceive(response.content);
61305                            }
61306                        }
61307                        else {
61308                            // This is another way timeout manifest.
61309                            this._logger.log(LogLevel.Trace, "(LongPolling transport) Poll timed out, reissuing.");
61310                        }
61311                    }
61312                }
61313                catch (e) {
61314                    if (!this._running) {
61315                        // Log but disregard errors that occur after stopping
61316                        this._logger.log(LogLevel.Trace, `(LongPolling transport) Poll errored after shutdown: ${e.message}`);
61317                    }
61318                    else {
61319                        if (e instanceof TimeoutError) {
61320                            // Ignore timeouts and reissue the poll.
61321                            this._logger.log(LogLevel.Trace, "(LongPolling transport) Poll timed out, reissuing.");
61322                        }
61323                        else {
61324                            // Close the connection with the error as the result.
61325                            this._closeError = e;
61326                            this._running = false;
61327                        }
61328                    }
61329                }
61330            }
61331        }
61332        finally {
61333            this._logger.log(LogLevel.Trace, "(LongPolling transport) Polling complete.");
61334            // We will reach here with pollAborted==false when the server returned a response causing the transport to stop.
61335            // If pollAborted==true then client initiated the stop and the stop method will raise the close event after DELETE is sent.
61336            if (!this.pollAborted) {
61337                this._raiseOnClose();
61338            }
61339        }
61340    }
61341    async send(data) {
61342        if (!this._running) {
61343            return Promise.reject(new Error("Cannot send until the transport is connected"));
61344        }
61345        return sendMessage(this._logger, "LongPolling", this._httpClient, this._url, this._accessTokenFactory, data, this._options);
61346    }
61347    async stop() {
61348        this._logger.log(LogLevel.Trace, "(LongPolling transport) Stopping polling.");
61349        // Tell receiving loop to stop, abort any current request, and then wait for it to finish
61350        this._running = false;
61351        this._pollAbort.abort();
61352        try {
61353            await this._receiving;
61354            // Send DELETE to clean up long polling on the server
61355            this._logger.log(LogLevel.Trace, `(LongPolling transport) sending DELETE request to ${this._url}.`);
61356            const headers = {};
61357            const [name, value] = getUserAgentHeader();
61358            headers[name] = value;
61359            const deleteOptions = {
61360                headers: { ...headers, ...this._options.headers },
61361                timeout: this._options.timeout,
61362                withCredentials: this._options.withCredentials,
61363            };
61364            const token = await this._getAccessToken();
61365            this._updateHeaderToken(deleteOptions, token);
61366            await this._httpClient.delete(this._url, deleteOptions);
61367            this._logger.log(LogLevel.Trace, "(LongPolling transport) DELETE request sent.");
61368        }
61369        finally {
61370            this._logger.log(LogLevel.Trace, "(LongPolling transport) Stop finished.");
61371            // Raise close event here instead of in polling
61372            // It needs to happen after the DELETE request is sent
61373            this._raiseOnClose();
61374        }
61375    }
61376    _raiseOnClose() {
61377        if (this.onclose) {
61378            let logMessage = "(LongPolling transport) Firing onclose event.";
61379            if (this._closeError) {
61380                logMessage += " Error: " + this._closeError;
61381            }
61382            this._logger.log(LogLevel.Trace, logMessage);
61383            this.onclose(this._closeError);
61384        }
61385    }
61386}
61387//# sourceMappingURL=LongPollingTransport.js.map
61388;// CONCATENATED MODULE: ./node_modules/@microsoft/signalr/dist/esm/ServerSentEventsTransport.js
61389// Licensed to the .NET Foundation under one or more agreements.
61390// The .NET Foundation licenses this file to you under the MIT license.
61391
61392
61393
61394/** @private */
61395class ServerSentEventsTransport {
61396    constructor(httpClient, accessTokenFactory, logger, options) {
61397        this._httpClient = httpClient;
61398        this._accessTokenFactory = accessTokenFactory;
vendor: 69,724 bytes, lines 61399-62809
61399        this._logger = logger;
61400        this._options = options;
61401        this.onreceive = null;
61402        this.onclose = null;
61403    }
61404    async connect(url, transferFormat) {
61405        Arg.isRequired(url, "url");
61406        Arg.isRequired(transferFormat, "transferFormat");
61407        Arg.isIn(transferFormat, TransferFormat, "transferFormat");
61408        this._logger.log(LogLevel.Trace, "(SSE transport) Connecting.");
61409        // set url before accessTokenFactory because this.url is only for send and we set the auth header instead of the query string for send
61410        this._url = url;
61411        if (this._accessTokenFactory) {
61412            const token = await this._accessTokenFactory();
61413            if (token) {
61414                url += (url.indexOf("?") < 0 ? "?" : "&") + `access_token=${encodeURIComponent(token)}`;
61415            }
61416        }
61417        return new Promise((resolve, reject) => {
61418            let opened = false;
61419            if (transferFormat !== TransferFormat.Text) {
61420                reject(new Error("The Server-Sent Events transport only supports the 'Text' transfer format"));
61421                return;
61422            }
61423            let eventSource;
61424            if (Platform.isBrowser || Platform.isWebWorker) {
61425                eventSource = new this._options.EventSource(url, { withCredentials: this._options.withCredentials });
61426            }
61427            else {
61428                // Non-browser passes cookies via the dictionary
61429                const cookies = this._httpClient.getCookieString(url);
61430                const headers = {};
61431                headers.Cookie = cookies;
61432                const [name, value] = getUserAgentHeader();
61433                headers[name] = value;
61434                eventSource = new this._options.EventSource(url, { withCredentials: this._options.withCredentials, headers: { ...headers, ...this._options.headers } });
61435            }
61436            try {
61437                eventSource.onmessage = (e) => {
61438                    if (this.onreceive) {
61439                        try {
61440                            this._logger.log(LogLevel.Trace, `(SSE transport) data received. ${getDataDetail(e.data, this._options.logMessageContent)}.`);
61441                            this.onreceive(e.data);
61442                        }
61443                        catch (error) {
61444                            this._close(error);
61445                            return;
61446                        }
61447                    }
61448                };
61449                // @ts-ignore: not using event on purpose
61450                eventSource.onerror = (e) => {
61451                    // EventSource doesn't give any useful information about server side closes.
61452                    if (opened) {
61453                        this._close();
61454                    }
61455                    else {
61456                        reject(new Error("EventSource failed to connect. The connection could not be found on the server,"
61457                            + " either the connection ID is not present on the server, or a proxy is refusing/buffering the connection."
61458                            + " If you have multiple servers check that sticky sessions are enabled."));
61459                    }
61460                };
61461                eventSource.onopen = () => {
61462                    this._logger.log(LogLevel.Information, `SSE connected to ${this._url}`);
61463                    this._eventSource = eventSource;
61464                    opened = true;
61465                    resolve();
61466                };
61467            }
61468            catch (e) {
61469                reject(e);
61470                return;
61471            }
61472        });
61473    }
61474    async send(data) {
61475        if (!this._eventSource) {
61476            return Promise.reject(new Error("Cannot send until the transport is connected"));
61477        }
61478        return sendMessage(this._logger, "SSE", this._httpClient, this._url, this._accessTokenFactory, data, this._options);
61479    }
61480    stop() {
61481        this._close();
61482        return Promise.resolve();
61483    }
61484    _close(e) {
61485        if (this._eventSource) {
61486            this._eventSource.close();
61487            this._eventSource = undefined;
61488            if (this.onclose) {
61489                this.onclose(e);
61490            }
61491        }
61492    }
61493}
61494//# sourceMappingURL=ServerSentEventsTransport.js.map
61495;// CONCATENATED MODULE: ./node_modules/@microsoft/signalr/dist/esm/WebSocketTransport.js
61496// Licensed to the .NET Foundation under one or more agreements.
61497// The .NET Foundation licenses this file to you under the MIT license.
61498
61499
61500
61501
61502/** @private */
61503class WebSocketTransport {
61504    constructor(httpClient, accessTokenFactory, logger, logMessageContent, webSocketConstructor, headers) {
61505        this._logger = logger;
61506        this._accessTokenFactory = accessTokenFactory;
61507        this._logMessageContent = logMessageContent;
61508        this._webSocketConstructor = webSocketConstructor;
61509        this._httpClient = httpClient;
61510        this.onreceive = null;
61511        this.onclose = null;
61512        this._headers = headers;
61513    }
61514    async connect(url, transferFormat) {
61515        Arg.isRequired(url, "url");
61516        Arg.isRequired(transferFormat, "transferFormat");
61517        Arg.isIn(transferFormat, TransferFormat, "transferFormat");
61518        this._logger.log(LogLevel.Trace, "(WebSockets transport) Connecting.");
61519        if (this._accessTokenFactory) {
61520            const token = await this._accessTokenFactory();
61521            if (token) {
61522                url += (url.indexOf("?") < 0 ? "?" : "&") + `access_token=${encodeURIComponent(token)}`;
61523            }
61524        }
61525        return new Promise((resolve, reject) => {
61526            url = url.replace(/^http/, "ws");
61527            let webSocket;
61528            const cookies = this._httpClient.getCookieString(url);
61529            let opened = false;
61530            if (Platform.isNode) {
61531                const headers = {};
61532                const [name, value] = getUserAgentHeader();
61533                headers[name] = value;
61534                if (cookies) {
61535                    headers[HeaderNames.Cookie] = `${cookies}`;
61536                }
61537                // Only pass headers when in non-browser environments
61538                webSocket = new this._webSocketConstructor(url, undefined, {
61539                    headers: { ...headers, ...this._headers },
61540                });
61541            }
61542            if (!webSocket) {
61543                // Chrome is not happy with passing 'undefined' as protocol
61544                webSocket = new this._webSocketConstructor(url);
61545            }
61546            if (transferFormat === TransferFormat.Binary) {
61547                webSocket.binaryType = "arraybuffer";
61548            }
61549            webSocket.onopen = (_event) => {
61550                this._logger.log(LogLevel.Information, `WebSocket connected to ${url}.`);
61551                this._webSocket = webSocket;
61552                opened = true;
61553                resolve();
61554            };
61555            webSocket.onerror = (event) => {
61556                let error = null;
61557                // ErrorEvent is a browser only type we need to check if the type exists before using it
61558                if (typeof ErrorEvent !== "undefined" && event instanceof ErrorEvent) {
61559                    error = event.error;
61560                }
61561                else {
61562                    error = "There was an error with the transport";
61563                }
61564                this._logger.log(LogLevel.Information, `(WebSockets transport) ${error}.`);
61565            };
61566            webSocket.onmessage = (message) => {
61567                this._logger.log(LogLevel.Trace, `(WebSockets transport) data received. ${getDataDetail(message.data, this._logMessageContent)}.`);
61568                if (this.onreceive) {
61569                    try {
61570                        this.onreceive(message.data);
61571                    }
61572                    catch (error) {
61573                        this._close(error);
61574                        return;
61575                    }
61576                }
61577            };
61578            webSocket.onclose = (event) => {
61579                // Don't call close handler if connection was never established
61580                // We'll reject the connect call instead
61581                if (opened) {
61582                    this._close(event);
61583                }
61584                else {
61585                    let error = null;
61586                    // ErrorEvent is a browser only type we need to check if the type exists before using it
61587                    if (typeof ErrorEvent !== "undefined" && event instanceof ErrorEvent) {
61588                        error = event.error;
61589                    }
61590                    else {
61591                        error = "WebSocket failed to connect. The connection could not be found on the server,"
61592                            + " either the endpoint may not be a SignalR endpoint,"
61593                            + " the connection ID is not present on the server, or there is a proxy blocking WebSockets."
61594                            + " If you have multiple servers check that sticky sessions are enabled.";
61595                    }
61596                    reject(new Error(error));
61597                }
61598            };
61599        });
61600    }
61601    send(data) {
61602        if (this._webSocket && this._webSocket.readyState === this._webSocketConstructor.OPEN) {
61603            this._logger.log(LogLevel.Trace, `(WebSockets transport) sending data. ${getDataDetail(data, this._logMessageContent)}.`);
61604            this._webSocket.send(data);
61605            return Promise.resolve();
61606        }
61607        return Promise.reject("WebSocket is not in the OPEN state");
61608    }
61609    stop() {
61610        if (this._webSocket) {
61611            // Manually invoke onclose callback inline so we know the HttpConnection was closed properly before returning
61612            // This also solves an issue where websocket.onclose could take 18+ seconds to trigger during network disconnects
61613            this._close(undefined);
61614        }
61615        return Promise.resolve();
61616    }
61617    _close(event) {
61618        // webSocket will be null if the transport did not start successfully
61619        if (this._webSocket) {
61620            // Clear websocket handlers because we are considering the socket closed now
61621            this._webSocket.onclose = () => { };
61622            this._webSocket.onmessage = () => { };
61623            this._webSocket.onerror = () => { };
61624            this._webSocket.close();
61625            this._webSocket = undefined;
61626        }
61627        this._logger.log(LogLevel.Trace, "(WebSockets transport) socket closed.");
61628        if (this.onclose) {
61629            if (this._isCloseEvent(event) && (event.wasClean === false || event.code !== 1000)) {
61630                this.onclose(new Error(`WebSocket closed with status code: ${event.code} (${event.reason || "no reason given"}).`));
61631            }
61632            else if (event instanceof Error) {
61633                this.onclose(event);
61634            }
61635            else {
61636                this.onclose();
61637            }
61638        }
61639    }
61640    _isCloseEvent(event) {
61641        return event && typeof event.wasClean === "boolean" && typeof event.code === "number";
61642    }
61643}
61644//# sourceMappingURL=WebSocketTransport.js.map
61645;// CONCATENATED MODULE: ./node_modules/@microsoft/signalr/dist/esm/HttpConnection.js
61646// Licensed to the .NET Foundation under one or more agreements.
61647// The .NET Foundation licenses this file to you under the MIT license.
61648
61649
61650
61651
61652
61653
61654
61655
61656
61657const MAX_REDIRECTS = 100;
61658/** @private */
61659class HttpConnection {
61660    constructor(url, options = {}) {
61661        this._stopPromiseResolver = () => { };
61662        this.features = {};
61663        this._negotiateVersion = 1;
61664        Arg.isRequired(url, "url");
61665        this._logger = createLogger(options.logger);
61666        this.baseUrl = this._resolveUrl(url);
61667        options = options || {};
61668        options.logMessageContent = options.logMessageContent === undefined ? false : options.logMessageContent;
61669        if (typeof options.withCredentials === "boolean" || options.withCredentials === undefined) {
61670            options.withCredentials = options.withCredentials === undefined ? true : options.withCredentials;
61671        }
61672        else {
61673            throw new Error("withCredentials option was not a 'boolean' or 'undefined' value");
61674        }
61675        options.timeout = options.timeout === undefined ? 100 * 1000 : options.timeout;
61676        let webSocketModule = null;
61677        let eventSourceModule = null;
61678        if (Platform.isNode && "function" !== "undefined") {
61679            // In order to ignore the dynamic require in webpack builds we need to do this magic
61680            // @ts-ignore: TS doesn't know about these names
61681            const requireFunc =  true ? require : 0;
61682            webSocketModule = requireFunc("ws");
61683            eventSourceModule = requireFunc("eventsource");
61684        }
61685        if (!Platform.isNode && typeof WebSocket !== "undefined" && !options.WebSocket) {
61686            options.WebSocket = WebSocket;
61687        }
61688        else if (Platform.isNode && !options.WebSocket) {
61689            if (webSocketModule) {
61690                options.WebSocket = webSocketModule;
61691            }
61692        }
61693        if (!Platform.isNode && typeof EventSource !== "undefined" && !options.EventSource) {
61694            options.EventSource = EventSource;
61695        }
61696        else if (Platform.isNode && !options.EventSource) {
61697            if (typeof eventSourceModule !== "undefined") {
61698                options.EventSource = eventSourceModule;
61699            }
61700        }
61701        this._httpClient = options.httpClient || new DefaultHttpClient(this._logger);
61702        this._connectionState = "Disconnected" /* Disconnected */;
61703        this._connectionStarted = false;
61704        this._options = options;
61705        this.onreceive = null;
61706        this.onclose = null;
61707    }
61708    async start(transferFormat) {
61709        transferFormat = transferFormat || TransferFormat.Binary;
61710        Arg.isIn(transferFormat, TransferFormat, "transferFormat");
61711        this._logger.log(LogLevel.Debug, `Starting connection with transfer format '${TransferFormat[transferFormat]}'.`);
61712        if (this._connectionState !== "Disconnected" /* Disconnected */) {
61713            return Promise.reject(new Error("Cannot start an HttpConnection that is not in the 'Disconnected' state."));
61714        }
61715        this._connectionState = "Connecting" /* Connecting */;
61716        this._startInternalPromise = this._startInternal(transferFormat);
61717        await this._startInternalPromise;
61718        // The TypeScript compiler thinks that connectionState must be Connecting here. The TypeScript compiler is wrong.
61719        if (this._connectionState === "Disconnecting" /* Disconnecting */) {
61720            // stop() was called and transitioned the client into the Disconnecting state.
61721            const message = "Failed to start the HttpConnection before stop() was called.";
61722            this._logger.log(LogLevel.Error, message);
61723            // We cannot await stopPromise inside startInternal since stopInternal awaits the startInternalPromise.
61724            await this._stopPromise;
61725            return Promise.reject(new Error(message));
61726        }
61727        else if (this._connectionState !== "Connected" /* Connected */) {
61728            // stop() was called and transitioned the client into the Disconnecting state.
61729            const message = "HttpConnection.startInternal completed gracefully but didn't enter the connection into the connected state!";
61730            this._logger.log(LogLevel.Error, message);
61731            return Promise.reject(new Error(message));
61732        }
61733        this._connectionStarted = true;
61734    }
61735    send(data) {
61736        if (this._connectionState !== "Connected" /* Connected */) {
61737            return Promise.reject(new Error("Cannot send data if the connection is not in the 'Connected' State."));
61738        }
61739        if (!this._sendQueue) {
61740            this._sendQueue = new TransportSendQueue(this.transport);
61741        }
61742        // Transport will not be null if state is connected
61743        return this._sendQueue.send(data);
61744    }
61745    async stop(error) {
61746        if (this._connectionState === "Disconnected" /* Disconnected */) {
61747            this._logger.log(LogLevel.Debug, `Call to HttpConnection.stop(${error}) ignored because the connection is already in the disconnected state.`);
61748            return Promise.resolve();
61749        }
61750        if (this._connectionState === "Disconnecting" /* Disconnecting */) {
61751            this._logger.log(LogLevel.Debug, `Call to HttpConnection.stop(${error}) ignored because the connection is already in the disconnecting state.`);
61752            return this._stopPromise;
61753        }
61754        this._connectionState = "Disconnecting" /* Disconnecting */;
61755        this._stopPromise = new Promise((resolve) => {
61756            // Don't complete stop() until stopConnection() completes.
61757            this._stopPromiseResolver = resolve;
61758        });
61759        // stopInternal should never throw so just observe it.
61760        await this._stopInternal(error);
61761        await this._stopPromise;
61762    }
61763    async _stopInternal(error) {
61764        // Set error as soon as possible otherwise there is a race between
61765        // the transport closing and providing an error and the error from a close message
61766        // We would prefer the close message error.
61767        this._stopError = error;
61768        try {
61769            await this._startInternalPromise;
61770        }
61771        catch (e) {
61772            // This exception is returned to the user as a rejected Promise from the start method.
61773        }
61774        // The transport's onclose will trigger stopConnection which will run our onclose event.
61775        // The transport should always be set if currently connected. If it wasn't set, it's likely because
61776        // stop was called during start() and start() failed.
61777        if (this.transport) {
61778            try {
61779                await this.transport.stop();
61780            }
61781            catch (e) {
61782                this._logger.log(LogLevel.Error, `HttpConnection.transport.stop() threw error '${e}'.`);
61783                this._stopConnection();
61784            }
61785            this.transport = undefined;
61786        }
61787        else {
61788            this._logger.log(LogLevel.Debug, "HttpConnection.transport is undefined in HttpConnection.stop() because start() failed.");
61789        }
61790    }
61791    async _startInternal(transferFormat) {
61792        // Store the original base url and the access token factory since they may change
61793        // as part of negotiating
61794        let url = this.baseUrl;
61795        this._accessTokenFactory = this._options.accessTokenFactory;
61796        try {
61797            if (this._options.skipNegotiation) {
61798                if (this._options.transport === HttpTransportType.WebSockets) {
61799                    // No need to add a connection ID in this case
61800                    this.transport = this._constructTransport(HttpTransportType.WebSockets);
61801                    // We should just call connect directly in this case.
61802                    // No fallback or negotiate in this case.
61803                    await this._startTransport(url, transferFormat);
61804                }
61805                else {
61806                    throw new Error("Negotiation can only be skipped when using the WebSocket transport directly.");
61807                }
61808            }
61809            else {
61810                let negotiateResponse = null;
61811                let redirects = 0;
61812                do {
61813                    negotiateResponse = await this._getNegotiationResponse(url);
61814                    // the user tries to stop the connection when it is being started
61815                    if (this._connectionState === "Disconnecting" /* Disconnecting */ || this._connectionState === "Disconnected" /* Disconnected */) {
61816                        throw new Error("The connection was stopped during negotiation.");
61817                    }
61818                    if (negotiateResponse.error) {
61819                        throw new Error(negotiateResponse.error);
61820                    }
61821                    if (negotiateResponse.ProtocolVersion) {
61822                        throw new Error("Detected a connection attempt to an ASP.NET SignalR Server. This client only supports connecting to an ASP.NET Core SignalR Server. See https://aka.ms/signalr-core-differences for details.");
61823                    }
61824                    if (negotiateResponse.url) {
61825                        url = negotiateResponse.url;
61826                    }
61827                    if (negotiateResponse.accessToken) {
61828                        // Replace the current access token factory with one that uses
61829                        // the returned access token
61830                        const accessToken = negotiateResponse.accessToken;
61831                        this._accessTokenFactory = () => accessToken;
61832                    }
61833                    redirects++;
61834                } while (negotiateResponse.url && redirects < MAX_REDIRECTS);
61835                if (redirects === MAX_REDIRECTS && negotiateResponse.url) {
61836                    throw new Error("Negotiate redirection limit exceeded.");
61837                }
61838                await this._createTransport(url, this._options.transport, negotiateResponse, transferFormat);
61839            }
61840            if (this.transport instanceof LongPollingTransport) {
61841                this.features.inherentKeepAlive = true;
61842            }
61843            if (this._connectionState === "Connecting" /* Connecting */) {
61844                // Ensure the connection transitions to the connected state prior to completing this.startInternalPromise.
61845                // start() will handle the case when stop was called and startInternal exits still in the disconnecting state.
61846                this._logger.log(LogLevel.Debug, "The HttpConnection connected successfully.");
61847                this._connectionState = "Connected" /* Connected */;
61848            }
61849            // stop() is waiting on us via this.startInternalPromise so keep this.transport around so it can clean up.
61850            // This is the only case startInternal can exit in neither the connected nor disconnected state because stopConnection()
61851            // will transition to the disconnected state. start() will wait for the transition using the stopPromise.
61852        }
61853        catch (e) {
61854            this._logger.log(LogLevel.Error, "Failed to start the connection: " + e);
61855            this._connectionState = "Disconnected" /* Disconnected */;
61856            this.transport = undefined;
61857            // if start fails, any active calls to stop assume that start will complete the stop promise
61858            this._stopPromiseResolver();
61859            return Promise.reject(e);
61860        }
61861    }
61862    async _getNegotiationResponse(url) {
61863        const headers = {};
61864        if (this._accessTokenFactory) {
61865            const token = await this._accessTokenFactory();
61866            if (token) {
61867                headers[HeaderNames.Authorization] = `Bearer ${token}`;
61868            }
61869        }
61870        const [name, value] = getUserAgentHeader();
61871        headers[name] = value;
61872        const negotiateUrl = this._resolveNegotiateUrl(url);
61873        this._logger.log(LogLevel.Debug, `Sending negotiation request: ${negotiateUrl}.`);
61874        try {
61875            const response = await this._httpClient.post(negotiateUrl, {
61876                content: "",
61877                headers: { ...headers, ...this._options.headers },
61878                timeout: this._options.timeout,
61879                withCredentials: this._options.withCredentials,
61880            });
61881            if (response.statusCode !== 200) {
61882                return Promise.reject(new Error(`Unexpected status code returned from negotiate '${response.statusCode}'`));
61883            }
61884            const negotiateResponse = JSON.parse(response.content);
61885            if (!negotiateResponse.negotiateVersion || negotiateResponse.negotiateVersion < 1) {
61886                // Negotiate version 0 doesn't use connectionToken
61887                // So we set it equal to connectionId so all our logic can use connectionToken without being aware of the negotiate version
61888                negotiateResponse.connectionToken = negotiateResponse.connectionId;
61889            }
61890            return negotiateResponse;
61891        }
61892        catch (e) {
61893            let errorMessage = "Failed to complete negotiation with the server: " + e;
61894            if (e instanceof HttpError) {
61895                if (e.statusCode === 404) {
61896                    errorMessage = errorMessage + " Either this is not a SignalR endpoint or there is a proxy blocking the connection.";
61897                }
61898            }
61899            this._logger.log(LogLevel.Error, errorMessage);
61900            return Promise.reject(new FailedToNegotiateWithServerError(errorMessage));
61901        }
61902    }
61903    _createConnectUrl(url, connectionToken) {
61904        if (!connectionToken) {
61905            return url;
61906        }
61907        return url + (url.indexOf("?") === -1 ? "?" : "&") + `id=${connectionToken}`;
61908    }
61909    async _createTransport(url, requestedTransport, negotiateResponse, requestedTransferFormat) {
61910        let connectUrl = this._createConnectUrl(url, negotiateResponse.connectionToken);
61911        if (this._isITransport(requestedTransport)) {
61912            this._logger.log(LogLevel.Debug, "Connection was provided an instance of ITransport, using that directly.");
61913            this.transport = requestedTransport;
61914            await this._startTransport(connectUrl, requestedTransferFormat);
61915            this.connectionId = negotiateResponse.connectionId;
61916            return;
61917        }
61918        const transportExceptions = [];
61919        const transports = negotiateResponse.availableTransports || [];
61920        let negotiate = negotiateResponse;
61921        for (const endpoint of transports) {
61922            const transportOrError = this._resolveTransportOrError(endpoint, requestedTransport, requestedTransferFormat);
61923            if (transportOrError instanceof Error) {
61924                // Store the error and continue, we don't want to cause a re-negotiate in these cases
61925                transportExceptions.push(`${endpoint.transport} failed:`);
61926                transportExceptions.push(transportOrError);
61927            }
61928            else if (this._isITransport(transportOrError)) {
61929                this.transport = transportOrError;
61930                if (!negotiate) {
61931                    try {
61932                        negotiate = await this._getNegotiationResponse(url);
61933                    }
61934                    catch (ex) {
61935                        return Promise.reject(ex);
61936                    }
61937                    connectUrl = this._createConnectUrl(url, negotiate.connectionToken);
61938                }
61939                try {
61940                    await this._startTransport(connectUrl, requestedTransferFormat);
61941                    this.connectionId = negotiate.connectionId;
61942                    return;
61943                }
61944                catch (ex) {
61945                    this._logger.log(LogLevel.Error, `Failed to start the transport '${endpoint.transport}': ${ex}`);
61946                    negotiate = undefined;
61947                    transportExceptions.push(new FailedToStartTransportError(`${endpoint.transport} failed: ${ex}`, HttpTransportType[endpoint.transport]));
61948                    if (this._connectionState !== "Connecting" /* Connecting */) {
61949                        const message = "Failed to select transport before stop() was called.";
61950                        this._logger.log(LogLevel.Debug, message);
61951                        return Promise.reject(new Error(message));
61952                    }
61953                }
61954            }
61955        }
61956        if (transportExceptions.length > 0) {
61957            return Promise.reject(new AggregateErrors(`Unable to connect to the server with any of the available transports. ${transportExceptions.join(" ")}`, transportExceptions));
61958        }
61959        return Promise.reject(new Error("None of the transports supported by the client are supported by the server."));
61960    }
61961    _constructTransport(transport) {
61962        switch (transport) {
61963            case HttpTransportType.WebSockets:
61964                if (!this._options.WebSocket) {
61965                    throw new Error("'WebSocket' is not supported in your environment.");
61966                }
61967                return new WebSocketTransport(this._httpClient, this._accessTokenFactory, this._logger, this._options.logMessageContent, this._options.WebSocket, this._options.headers || {});
61968            case HttpTransportType.ServerSentEvents:
61969                if (!this._options.EventSource) {
61970                    throw new Error("'EventSource' is not supported in your environment.");
61971                }
61972                return new ServerSentEventsTransport(this._httpClient, this._accessTokenFactory, this._logger, this._options);
61973            case HttpTransportType.LongPolling:
61974                return new LongPollingTransport(this._httpClient, this._accessTokenFactory, this._logger, this._options);
61975            default:
61976                throw new Error(`Unknown transport: ${transport}.`);
61977        }
61978    }
61979    _startTransport(url, transferFormat) {
61980        this.transport.onreceive = this.onreceive;
61981        this.transport.onclose = (e) => this._stopConnection(e);
61982        return this.transport.connect(url, transferFormat);
61983    }
61984    _resolveTransportOrError(endpoint, requestedTransport, requestedTransferFormat) {
61985        const transport = HttpTransportType[endpoint.transport];
61986        if (transport === null || transport === undefined) {
61987            this._logger.log(LogLevel.Debug, `Skipping transport '${endpoint.transport}' because it is not supported by this client.`);
61988            return new Error(`Skipping transport '${endpoint.transport}' because it is not supported by this client.`);
61989        }
61990        else {
61991            if (transportMatches(requestedTransport, transport)) {
61992                const transferFormats = endpoint.transferFormats.map((s) => TransferFormat[s]);
61993                if (transferFormats.indexOf(requestedTransferFormat) >= 0) {
61994                    if ((transport === HttpTransportType.WebSockets && !this._options.WebSocket) ||
61995                        (transport === HttpTransportType.ServerSentEvents && !this._options.EventSource)) {
61996                        this._logger.log(LogLevel.Debug, `Skipping transport '${HttpTransportType[transport]}' because it is not supported in your environment.'`);
61997                        return new UnsupportedTransportError(`'${HttpTransportType[transport]}' is not supported in your environment.`, transport);
61998                    }
61999                    else {
62000                        this._logger.log(LogLevel.Debug, `Selecting transport '${HttpTransportType[transport]}'.`);
62001                        try {
62002                            return this._constructTransport(transport);
62003                        }
62004                        catch (ex) {
62005                            return ex;
62006                        }
62007                    }
62008                }
62009                else {
62010                    this._logger.log(LogLevel.Debug, `Skipping transport '${HttpTransportType[transport]}' because it does not support the requested transfer format '${TransferFormat[requestedTransferFormat]}'.`);
62011                    return new Error(`'${HttpTransportType[transport]}' does not support ${TransferFormat[requestedTransferFormat]}.`);
62012                }
62013            }
62014            else {
62015                this._logger.log(LogLevel.Debug, `Skipping transport '${HttpTransportType[transport]}' because it was disabled by the client.`);
62016                return new DisabledTransportError(`'${HttpTransportType[transport]}' is disabled by the client.`, transport);
62017            }
62018        }
62019    }
62020    _isITransport(transport) {
62021        return transport && typeof (transport) === "object" && "connect" in transport;
62022    }
62023    _stopConnection(error) {
62024        this._logger.log(LogLevel.Debug, `HttpConnection.stopConnection(${error}) called while in state ${this._connectionState}.`);
62025        this.transport = undefined;
62026        // If we have a stopError, it takes precedence over the error from the transport
62027        error = this._stopError || error;
62028        this._stopError = undefined;
62029        if (this._connectionState === "Disconnected" /* Disconnected */) {
62030            this._logger.log(LogLevel.Debug, `Call to HttpConnection.stopConnection(${error}) was ignored because the connection is already in the disconnected state.`);
62031            return;
62032        }
62033        if (this._connectionState === "Connecting" /* Connecting */) {
62034            this._logger.log(LogLevel.Warning, `Call to HttpConnection.stopConnection(${error}) was ignored because the connection is still in the connecting state.`);
62035            throw new Error(`HttpConnection.stopConnection(${error}) was called while the connection is still in the connecting state.`);
62036        }
62037        if (this._connectionState === "Disconnecting" /* Disconnecting */) {
62038            // A call to stop() induced this call to stopConnection and needs to be completed.
62039            // Any stop() awaiters will be scheduled to continue after the onclose callback fires.
62040            this._stopPromiseResolver();
62041        }
62042        if (error) {
62043            this._logger.log(LogLevel.Error, `Connection disconnected with error '${error}'.`);
62044        }
62045        else {
62046            this._logger.log(LogLevel.Information, "Connection disconnected.");
62047        }
62048        if (this._sendQueue) {
62049            this._sendQueue.stop().catch((e) => {
62050                this._logger.log(LogLevel.Error, `TransportSendQueue.stop() threw error '${e}'.`);
62051            });
62052            this._sendQueue = undefined;
62053        }
62054        this.connectionId = undefined;
62055        this._connectionState = "Disconnected" /* Disconnected */;
62056        if (this._connectionStarted) {
62057            this._connectionStarted = false;
62058            try {
62059                if (this.onclose) {
62060                    this.onclose(error);
62061                }
62062            }
62063            catch (e) {
62064                this._logger.log(LogLevel.Error, `HttpConnection.onclose(${error}) threw error '${e}'.`);
62065            }
62066        }
62067    }
62068    _resolveUrl(url) {
62069        // startsWith is not supported in IE
62070        if (url.lastIndexOf("https://", 0) === 0 || url.lastIndexOf("http://", 0) === 0) {
62071            return url;
62072        }
62073        if (!Platform.isBrowser) {
62074            throw new Error(`Cannot resolve '${url}'.`);
62075        }
62076        // Setting the url to the href propery of an anchor tag handles normalization
62077        // for us. There are 3 main cases.
62078        // 1. Relative path normalization e.g "b" -> "http://localhost:5000/a/b"
62079        // 2. Absolute path normalization e.g "/a/b" -> "http://localhost:5000/a/b"
62080        // 3. Networkpath reference normalization e.g "//localhost:5000/a/b" -> "http://localhost:5000/a/b"
62081        const aTag = window.document.createElement("a");
62082        aTag.href = url;
62083        this._logger.log(LogLevel.Information, `Normalizing '${url}' to '${aTag.href}'.`);
62084        return aTag.href;
62085    }
62086    _resolveNegotiateUrl(url) {
62087        const index = url.indexOf("?");
62088        let negotiateUrl = url.substring(0, index === -1 ? url.length : index);
62089        if (negotiateUrl[negotiateUrl.length - 1] !== "/") {
62090            negotiateUrl += "/";
62091        }
62092        negotiateUrl += "negotiate";
62093        negotiateUrl += index === -1 ? "" : url.substring(index);
62094        if (negotiateUrl.indexOf("negotiateVersion") === -1) {
62095            negotiateUrl += index === -1 ? "?" : "&";
62096            negotiateUrl += "negotiateVersion=" + this._negotiateVersion;
62097        }
62098        return negotiateUrl;
62099    }
62100}
62101function transportMatches(requestedTransport, actualTransport) {
62102    return !requestedTransport || ((actualTransport & requestedTransport) !== 0);
62103}
62104/** @private */
62105class TransportSendQueue {
62106    constructor(_transport) {
62107        this._transport = _transport;
62108        this._buffer = [];
62109        this._executing = true;
62110        this._sendBufferedData = new PromiseSource();
62111        this._transportResult = new PromiseSource();
62112        this._sendLoopPromise = this._sendLoop();
62113    }
62114    send(data) {
62115        this._bufferData(data);
62116        if (!this._transportResult) {
62117            this._transportResult = new PromiseSource();
62118        }
62119        return this._transportResult.promise;
62120    }
62121    stop() {
62122        this._executing = false;
62123        this._sendBufferedData.resolve();
62124        return this._sendLoopPromise;
62125    }
62126    _bufferData(data) {
62127        if (this._buffer.length && typeof (this._buffer[0]) !== typeof (data)) {
62128            throw new Error(`Expected data to be of type ${typeof (this._buffer)} but was of type ${typeof (data)}`);
62129        }
62130        this._buffer.push(data);
62131        this._sendBufferedData.resolve();
62132    }
62133    async _sendLoop() {
62134        while (true) {
62135            await this._sendBufferedData.promise;
62136            if (!this._executing) {
62137                if (this._transportResult) {
62138                    this._transportResult.reject("Connection stopped.");
62139                }
62140                break;
62141            }
62142            this._sendBufferedData = new PromiseSource();
62143            const transportResult = this._transportResult;
62144            this._transportResult = undefined;
62145            const data = typeof (this._buffer[0]) === "string" ?
62146                this._buffer.join("") :
62147                TransportSendQueue._concatBuffers(this._buffer);
62148            this._buffer.length = 0;
62149            try {
62150                await this._transport.send(data);
62151                transportResult.resolve();
62152            }
62153            catch (error) {
62154                transportResult.reject(error);
62155            }
62156        }
62157    }
62158    static _concatBuffers(arrayBuffers) {
62159        const totalLength = arrayBuffers.map((b) => b.byteLength).reduce((a, b) => a + b);
62160        const result = new Uint8Array(totalLength);
62161        let offset = 0;
62162        for (const item of arrayBuffers) {
62163            result.set(new Uint8Array(item), offset);
62164            offset += item.byteLength;
62165        }
62166        return result.buffer;
62167    }
62168}
62169class PromiseSource {
62170    constructor() {
62171        this.promise = new Promise((resolve, reject) => [this._resolver, this._rejecter] = [resolve, reject]);
62172    }
62173    resolve() {
62174        this._resolver();
62175    }
62176    reject(reason) {
62177        this._rejecter(reason);
62178    }
62179}
62180//# sourceMappingURL=HttpConnection.js.map
62181;// CONCATENATED MODULE: ./node_modules/@microsoft/signalr/dist/esm/TextMessageFormat.js
62182// Licensed to the .NET Foundation under one or more agreements.
62183// The .NET Foundation licenses this file to you under the MIT license.
62184// Not exported from index
62185/** @private */
62186class TextMessageFormat {
62187    static write(output) {
62188        return `${output}${TextMessageFormat.RecordSeparator}`;
62189    }
62190    static parse(input) {
62191        if (input[input.length - 1] !== TextMessageFormat.RecordSeparator) {
62192            throw new Error("Message is incomplete.");
62193        }
62194        const messages = input.split(TextMessageFormat.RecordSeparator);
62195        messages.pop();
62196        return messages;
62197    }
62198}
62199TextMessageFormat.RecordSeparatorCode = 0x1e;
62200TextMessageFormat.RecordSeparator = String.fromCharCode(TextMessageFormat.RecordSeparatorCode);
62201//# sourceMappingURL=TextMessageFormat.js.map
62202;// CONCATENATED MODULE: ./node_modules/@microsoft/signalr/dist/esm/HandshakeProtocol.js
62203// Licensed to the .NET Foundation under one or more agreements.
62204// The .NET Foundation licenses this file to you under the MIT license.
62205
62206
62207/** @private */
62208class HandshakeProtocol {
62209    // Handshake request is always JSON
62210    writeHandshakeRequest(handshakeRequest) {
62211        return TextMessageFormat.write(JSON.stringify(handshakeRequest));
62212    }
62213    parseHandshakeResponse(data) {
62214        let messageData;
62215        let remainingData;
62216        if (isArrayBuffer(data)) {
62217            // Format is binary but still need to read JSON text from handshake response
62218            const binaryData = new Uint8Array(data);
62219            const separatorIndex = binaryData.indexOf(TextMessageFormat.RecordSeparatorCode);
62220            if (separatorIndex === -1) {
62221                throw new Error("Message is incomplete.");
62222            }
62223            // content before separator is handshake response
62224            // optional content after is additional messages
62225            const responseLength = separatorIndex + 1;
62226            messageData = String.fromCharCode.apply(null, Array.prototype.slice.call(binaryData.slice(0, responseLength)));
62227            remainingData = (binaryData.byteLength > responseLength) ? binaryData.slice(responseLength).buffer : null;
62228        }
62229        else {
62230            const textData = data;
62231            const separatorIndex = textData.indexOf(TextMessageFormat.RecordSeparator);
62232            if (separatorIndex === -1) {
62233                throw new Error("Message is incomplete.");
62234            }
62235            // content before separator is handshake response
62236            // optional content after is additional messages
62237            const responseLength = separatorIndex + 1;
62238            messageData = textData.substring(0, responseLength);
62239            remainingData = (textData.length > responseLength) ? textData.substring(responseLength) : null;
62240        }
62241        // At this point we should have just the single handshake message
62242        const messages = TextMessageFormat.parse(messageData);
62243        const response = JSON.parse(messages[0]);
62244        if (response.type) {
62245            throw new Error("Expected a handshake response from the server.");
62246        }
62247        const responseMessage = response;
62248        // multiple messages could have arrived with handshake
62249        // return additional data to be parsed as usual, or null if all parsed
62250        return [remainingData, responseMessage];
62251    }
62252}
62253//# sourceMappingURL=HandshakeProtocol.js.map
62254;// CONCATENATED MODULE: ./node_modules/@microsoft/signalr/dist/esm/IHubProtocol.js
62255// Licensed to the .NET Foundation under one or more agreements.
62256// The .NET Foundation licenses this file to you under the MIT license.
62257/** Defines the type of a Hub Message. */
62258var MessageType;
62259(function (MessageType) {
62260    /** Indicates the message is an Invocation message and implements the {@link @microsoft/signalr.InvocationMessage} interface. */
62261    MessageType[MessageType["Invocation"] = 1] = "Invocation";
62262    /** Indicates the message is a StreamItem message and implements the {@link @microsoft/signalr.StreamItemMessage} interface. */
62263    MessageType[MessageType["StreamItem"] = 2] = "StreamItem";
62264    /** Indicates the message is a Completion message and implements the {@link @microsoft/signalr.CompletionMessage} interface. */
62265    MessageType[MessageType["Completion"] = 3] = "Completion";
62266    /** Indicates the message is a Stream Invocation message and implements the {@link @microsoft/signalr.StreamInvocationMessage} interface. */
62267    MessageType[MessageType["StreamInvocation"] = 4] = "StreamInvocation";
62268    /** Indicates the message is a Cancel Invocation message and implements the {@link @microsoft/signalr.CancelInvocationMessage} interface. */
62269    MessageType[MessageType["CancelInvocation"] = 5] = "CancelInvocation";
62270    /** Indicates the message is a Ping message and implements the {@link @microsoft/signalr.PingMessage} interface. */
62271    MessageType[MessageType["Ping"] = 6] = "Ping";
62272    /** Indicates the message is a Close message and implements the {@link @microsoft/signalr.CloseMessage} interface. */
62273    MessageType[MessageType["Close"] = 7] = "Close";
62274})(MessageType || (MessageType = {}));
62275//# sourceMappingURL=IHubProtocol.js.map
62276;// CONCATENATED MODULE: ./node_modules/@microsoft/signalr/dist/esm/Subject.js
62277// Licensed to the .NET Foundation under one or more agreements.
62278// The .NET Foundation licenses this file to you under the MIT license.
62279
62280/** Stream implementation to stream items to the server. */
62281class Subject {
62282    constructor() {
62283        this.observers = [];
62284    }
62285    next(item) {
62286        for (const observer of this.observers) {
62287            observer.next(item);
62288        }
62289    }
62290    error(err) {
62291        for (const observer of this.observers) {
62292            if (observer.error) {
62293                observer.error(err);
62294            }
62295        }
62296    }
62297    complete() {
62298        for (const observer of this.observers) {
62299            if (observer.complete) {
62300                observer.complete();
62301            }
62302        }
62303    }
62304    subscribe(observer) {
62305        this.observers.push(observer);
62306        return new SubjectSubscription(this, observer);
62307    }
62308}
62309//# sourceMappingURL=Subject.js.map
62310;// CONCATENATED MODULE: ./node_modules/@microsoft/signalr/dist/esm/HubConnection.js
62311// Licensed to the .NET Foundation under one or more agreements.
62312// The .NET Foundation licenses this file to you under the MIT license.
62313
62314
62315
62316
62317
62318const DEFAULT_TIMEOUT_IN_MS = 30 * 1000;
62319const DEFAULT_PING_INTERVAL_IN_MS = 15 * 1000;
62320/** Describes the current state of the {@link HubConnection} to the server. */
62321var HubConnectionState;
62322(function (HubConnectionState) {
62323    /** The hub connection is disconnected. */
62324    HubConnectionState["Disconnected"] = "Disconnected";
62325    /** The hub connection is connecting. */
62326    HubConnectionState["Connecting"] = "Connecting";
62327    /** The hub connection is connected. */
62328    HubConnectionState["Connected"] = "Connected";
62329    /** The hub connection is disconnecting. */
62330    HubConnectionState["Disconnecting"] = "Disconnecting";
62331    /** The hub connection is reconnecting. */
62332    HubConnectionState["Reconnecting"] = "Reconnecting";
62333})(HubConnectionState || (HubConnectionState = {}));
62334/** Represents a connection to a SignalR Hub. */
62335class HubConnection {
62336    constructor(connection, logger, protocol, reconnectPolicy) {
62337        this._nextKeepAlive = 0;
62338        this._freezeEventListener = () => {
62339            this._logger.log(LogLevel.Warning, "The page is being frozen, this will likely lead to the connection being closed and messages being lost. For more information see the docs at https://docs.microsoft.com/aspnet/core/signalr/javascript-client#bsleep");
62340        };
62341        Arg.isRequired(connection, "connection");
62342        Arg.isRequired(logger, "logger");
62343        Arg.isRequired(protocol, "protocol");
62344        this.serverTimeoutInMilliseconds = DEFAULT_TIMEOUT_IN_MS;
62345        this.keepAliveIntervalInMilliseconds = DEFAULT_PING_INTERVAL_IN_MS;
62346        this._logger = logger;
62347        this._protocol = protocol;
62348        this.connection = connection;
62349        this._reconnectPolicy = reconnectPolicy;
62350        this._handshakeProtocol = new HandshakeProtocol();
62351        this.connection.onreceive = (data) => this._processIncomingData(data);
62352        this.connection.onclose = (error) => this._connectionClosed(error);
62353        this._callbacks = {};
62354        this._methods = {};
62355        this._closedCallbacks = [];
62356        this._reconnectingCallbacks = [];
62357        this._reconnectedCallbacks = [];
62358        this._invocationId = 0;
62359        this._receivedHandshakeResponse = false;
62360        this._connectionState = HubConnectionState.Disconnected;
62361        this._connectionStarted = false;
62362        this._cachedPingMessage = this._protocol.writeMessage({ type: MessageType.Ping });
62363    }
62364    /** @internal */
62365    // Using a public static factory method means we can have a private constructor and an _internal_
62366    // create method that can be used by HubConnectionBuilder. An "internal" constructor would just
62367    // be stripped away and the '.d.ts' file would have no constructor, which is interpreted as a
62368    // public parameter-less constructor.
62369    static create(connection, logger, protocol, reconnectPolicy) {
62370        return new HubConnection(connection, logger, protocol, reconnectPolicy);
62371    }
62372    /** Indicates the state of the {@link HubConnection} to the server. */
62373    get state() {
62374        return this._connectionState;
62375    }
62376    /** Represents the connection id of the {@link HubConnection} on the server. The connection id will be null when the connection is either
62377     *  in the disconnected state or if the negotiation step was skipped.
62378     */
62379    get connectionId() {
62380        return this.connection ? (this.connection.connectionId || null) : null;
62381    }
62382    /** Indicates the url of the {@link HubConnection} to the server. */
62383    get baseUrl() {
62384        return this.connection.baseUrl || "";
62385    }
62386    /**
62387     * Sets a new url for the HubConnection. Note that the url can only be changed when the connection is in either the Disconnected or
62388     * Reconnecting states.
62389     * @param {string} url The url to connect to.
62390     */
62391    set baseUrl(url) {
62392        if (this._connectionState !== HubConnectionState.Disconnected && this._connectionState !== HubConnectionState.Reconnecting) {
62393            throw new Error("The HubConnection must be in the Disconnected or Reconnecting state to change the url.");
62394        }
62395        if (!url) {
62396            throw new Error("The HubConnection url must be a valid url.");
62397        }
62398        this.connection.baseUrl = url;
62399    }
62400    /** Starts the connection.
62401     *
62402     * @returns {Promise<void>} A Promise that resolves when the connection has been successfully established, or rejects with an error.
62403     */
62404    start() {
62405        this._startPromise = this._startWithStateTransitions();
62406        return this._startPromise;
62407    }
62408    async _startWithStateTransitions() {
62409        if (this._connectionState !== HubConnectionState.Disconnected) {
62410            return Promise.reject(new Error("Cannot start a HubConnection that is not in the 'Disconnected' state."));
62411        }
62412        this._connectionState = HubConnectionState.Connecting;
62413        this._logger.log(LogLevel.Debug, "Starting HubConnection.");
62414        try {
62415            await this._startInternal();
62416            if (Platform.isBrowser) {
62417                // Log when the browser freezes the tab so users know why their connection unexpectedly stopped working
62418                window.document.addEventListener("freeze", this._freezeEventListener);
62419            }
62420            this._connectionState = HubConnectionState.Connected;
62421            this._connectionStarted = true;
62422            this._logger.log(LogLevel.Debug, "HubConnection connected successfully.");
62423        }
62424        catch (e) {
62425            this._connectionState = HubConnectionState.Disconnected;
62426            this._logger.log(LogLevel.Debug, `HubConnection failed to start successfully because of error '${e}'.`);
62427            return Promise.reject(e);
62428        }
62429    }
62430    async _startInternal() {
62431        this._stopDuringStartError = undefined;
62432        this._receivedHandshakeResponse = false;
62433        // Set up the promise before any connection is (re)started otherwise it could race with received messages
62434        const handshakePromise = new Promise((resolve, reject) => {
62435            this._handshakeResolver = resolve;
62436            this._handshakeRejecter = reject;
62437        });
62438        await this.connection.start(this._protocol.transferFormat);
62439        try {
62440            const handshakeRequest = {
62441                protocol: this._protocol.name,
62442                version: this._protocol.version,
62443            };
62444            this._logger.log(LogLevel.Debug, "Sending handshake request.");
62445            await this._sendMessage(this._handshakeProtocol.writeHandshakeRequest(handshakeRequest));
62446            this._logger.log(LogLevel.Information, `Using HubProtocol '${this._protocol.name}'.`);
62447            // defensively cleanup timeout in case we receive a message from the server before we finish start
62448            this._cleanupTimeout();
62449            this._resetTimeoutPeriod();
62450            this._resetKeepAliveInterval();
62451            await handshakePromise;
62452            // It's important to check the stopDuringStartError instead of just relying on the handshakePromise
62453            // being rejected on close, because this continuation can run after both the handshake completed successfully
62454            // and the connection was closed.
62455            if (this._stopDuringStartError) {
62456                // It's important to throw instead of returning a rejected promise, because we don't want to allow any state
62457                // transitions to occur between now and the calling code observing the exceptions. Returning a rejected promise
62458                // will cause the calling continuation to get scheduled to run later.
62459                // eslint-disable-next-line @typescript-eslint/no-throw-literal
62460                throw this._stopDuringStartError;
62461            }
62462        }
62463        catch (e) {
62464            this._logger.log(LogLevel.Debug, `Hub handshake failed with error '${e}' during start(). Stopping HubConnection.`);
62465            this._cleanupTimeout();
62466            this._cleanupPingTimer();
62467            // HttpConnection.stop() should not complete until after the onclose callback is invoked.
62468            // This will transition the HubConnection to the disconnected state before HttpConnection.stop() completes.
62469            await this.connection.stop(e);
62470            throw e;
62471        }
62472    }
62473    /** Stops the connection.
62474     *
62475     * @returns {Promise<void>} A Promise that resolves when the connection has been successfully terminated, or rejects with an error.
62476     */
62477    async stop() {
62478        // Capture the start promise before the connection might be restarted in an onclose callback.
62479        const startPromise = this._startPromise;
62480        this._stopPromise = this._stopInternal();
62481        await this._stopPromise;
62482        try {
62483            // Awaiting undefined continues immediately
62484            await startPromise;
62485        }
62486        catch (e) {
62487            // This exception is returned to the user as a rejected Promise from the start method.
62488        }
62489    }
62490    _stopInternal(error) {
62491        if (this._connectionState === HubConnectionState.Disconnected) {
62492            this._logger.log(LogLevel.Debug, `Call to HubConnection.stop(${error}) ignored because it is already in the disconnected state.`);
62493            return Promise.resolve();
62494        }
62495        if (this._connectionState === HubConnectionState.Disconnecting) {
62496            this._logger.log(LogLevel.Debug, `Call to HttpConnection.stop(${error}) ignored because the connection is already in the disconnecting state.`);
62497            return this._stopPromise;
62498        }
62499        this._connectionState = HubConnectionState.Disconnecting;
62500        this._logger.log(LogLevel.Debug, "Stopping HubConnection.");
62501        if (this._reconnectDelayHandle) {
62502            // We're in a reconnect delay which means the underlying connection is currently already stopped.
62503            // Just clear the handle to stop the reconnect loop (which no one is waiting on thankfully) and
62504            // fire the onclose callbacks.
62505            this._logger.log(LogLevel.Debug, "Connection stopped during reconnect delay. Done reconnecting.");
62506            clearTimeout(this._reconnectDelayHandle);
62507            this._reconnectDelayHandle = undefined;
62508            this._completeClose();
62509            return Promise.resolve();
62510        }
62511        this._cleanupTimeout();
62512        this._cleanupPingTimer();
62513        this._stopDuringStartError = error || new Error("The connection was stopped before the hub handshake could complete.");
62514        // HttpConnection.stop() should not complete until after either HttpConnection.start() fails
62515        // or the onclose callback is invoked. The onclose callback will transition the HubConnection
62516        // to the disconnected state if need be before HttpConnection.stop() completes.
62517        return this.connection.stop(error);
62518    }
62519    /** Invokes a streaming hub method on the server using the specified name and arguments.
62520     *
62521     * @typeparam T The type of the items returned by the server.
62522     * @param {string} methodName The name of the server method to invoke.
62523     * @param {any[]} args The arguments used to invoke the server method.
62524     * @returns {IStreamResult<T>} An object that yields results from the server as they are received.
62525     */
62526    stream(methodName, ...args) {
62527        const [streams, streamIds] = this._replaceStreamingParams(args);
62528        const invocationDescriptor = this._createStreamInvocation(methodName, args, streamIds);
62529        // eslint-disable-next-line prefer-const
62530        let promiseQueue;
62531        const subject = new Subject();
62532        subject.cancelCallback = () => {
62533            const cancelInvocation = this._createCancelInvocation(invocationDescriptor.invocationId);
62534            delete this._callbacks[invocationDescriptor.invocationId];
62535            return promiseQueue.then(() => {
62536                return this._sendWithProtocol(cancelInvocation);
62537            });
62538        };
62539        this._callbacks[invocationDescriptor.invocationId] = (invocationEvent, error) => {
62540            if (error) {
62541                subject.error(error);
62542                return;
62543            }
62544            else if (invocationEvent) {
62545                // invocationEvent will not be null when an error is not passed to the callback
62546                if (invocationEvent.type === MessageType.Completion) {
62547                    if (invocationEvent.error) {
62548                        subject.error(new Error(invocationEvent.error));
62549                    }
62550                    else {
62551                        subject.complete();
62552                    }
62553                }
62554                else {
62555                    subject.next((invocationEvent.item));
62556                }
62557            }
62558        };
62559        promiseQueue = this._sendWithProtocol(invocationDescriptor)
62560            .catch((e) => {
62561            subject.error(e);
62562            delete this._callbacks[invocationDescriptor.invocationId];
62563        });
62564        this._launchStreams(streams, promiseQueue);
62565        return subject;
62566    }
62567    _sendMessage(message) {
62568        this._resetKeepAliveInterval();
62569        return this.connection.send(message);
62570    }
62571    /**
62572     * Sends a js object to the server.
62573     * @param message The js object to serialize and send.
62574     */
62575    _sendWithProtocol(message) {
62576        return this._sendMessage(this._protocol.writeMessage(message));
62577    }
62578    /** Invokes a hub method on the server using the specified name and arguments. Does not wait for a response from the receiver.
62579     *
62580     * The Promise returned by this method resolves when the client has sent the invocation to the server. The server may still
62581     * be processing the invocation.
62582     *
62583     * @param {string} methodName The name of the server method to invoke.
62584     * @param {any[]} args The arguments used to invoke the server method.
62585     * @returns {Promise<void>} A Promise that resolves when the invocation has been successfully sent, or rejects with an error.
62586     */
62587    send(methodName, ...args) {
62588        const [streams, streamIds] = this._replaceStreamingParams(args);
62589        const sendPromise = this._sendWithProtocol(this._createInvocation(methodName, args, true, streamIds));
62590        this._launchStreams(streams, sendPromise);
62591        return sendPromise;
62592    }
62593    /** Invokes a hub method on the server using the specified name and arguments.
62594     *
62595     * The Promise returned by this method resolves when the server indicates it has finished invoking the method. When the promise
62596     * resolves, the server has finished invoking the method. If the server method returns a result, it is produced as the result of
62597     * resolving the Promise.
62598     *
62599     * @typeparam T The expected return type.
62600     * @param {string} methodName The name of the server method to invoke.
62601     * @param {any[]} args The arguments used to invoke the server method.
62602     * @returns {Promise<T>} A Promise that resolves with the result of the server method (if any), or rejects with an error.
62603     */
62604    invoke(methodName, ...args) {
62605        const [streams, streamIds] = this._replaceStreamingParams(args);
62606        const invocationDescriptor = this._createInvocation(methodName, args, false, streamIds);
62607        const p = new Promise((resolve, reject) => {
62608            // invocationId will always have a value for a non-blocking invocation
62609            this._callbacks[invocationDescriptor.invocationId] = (invocationEvent, error) => {
62610                if (error) {
62611                    reject(error);
62612                    return;
62613                }
62614                else if (invocationEvent) {
62615                    // invocationEvent will not be null when an error is not passed to the callback
62616                    if (invocationEvent.type === MessageType.Completion) {
62617                        if (invocationEvent.error) {
62618                            reject(new Error(invocationEvent.error));
62619                        }
62620                        else {
62621                            resolve(invocationEvent.result);
62622                        }
62623                    }
62624                    else {
62625                        reject(new Error(`Unexpected message type: ${invocationEvent.type}`));
62626                    }
62627                }
62628            };
62629            const promiseQueue = this._sendWithProtocol(invocationDescriptor)
62630                .catch((e) => {
62631                reject(e);
62632                // invocationId will always have a value for a non-blocking invocation
62633                delete this._callbacks[invocationDescriptor.invocationId];
62634            });
62635            this._launchStreams(streams, promiseQueue);
62636        });
62637        return p;
62638    }
62639    /** Registers a handler that will be invoked when the hub method with the specified method name is invoked.
62640     *
62641     * @param {string} methodName The name of the hub method to define.
62642     * @param {Function} newMethod The handler that will be raised when the hub method is invoked.
62643     */
62644    on(methodName, newMethod) {
62645        if (!methodName || !newMethod) {
62646            return;
62647        }
62648        methodName = methodName.toLowerCase();
62649        if (!this._methods[methodName]) {
62650            this._methods[methodName] = [];
62651        }
62652        // Preventing adding the same handler multiple times.
62653        if (this._methods[methodName].indexOf(newMethod) !== -1) {
62654            return;
62655        }
62656        this._methods[methodName].push(newMethod);
62657    }
62658    off(methodName, method) {
62659        if (!methodName) {
62660            return;
62661        }
62662        methodName = methodName.toLowerCase();
62663        const handlers = this._methods[methodName];
62664        if (!handlers) {
62665            return;
62666        }
62667        if (method) {
62668            const removeIdx = handlers.indexOf(method);
62669            if (removeIdx !== -1) {
62670                handlers.splice(removeIdx, 1);
62671                if (handlers.length === 0) {
62672                    delete this._methods[methodName];
62673                }
62674            }
62675        }
62676        else {
62677            delete this._methods[methodName];
62678        }
62679    }
62680    /** Registers a handler that will be invoked when the connection is closed.
62681     *
62682     * @param {Function} callback The handler that will be invoked when the connection is closed. Optionally receives a single argument containing the error that caused the connection to close (if any).
62683     */
62684    onclose(callback) {
62685        if (callback) {
62686            this._closedCallbacks.push(callback);
62687        }
62688    }
62689    /** Registers a handler that will be invoked when the connection starts reconnecting.
62690     *
62691     * @param {Function} callback The handler that will be invoked when the connection starts reconnecting. Optionally receives a single argument containing the error that caused the connection to start reconnecting (if any).
62692     */
62693    onreconnecting(callback) {
62694        if (callback) {
62695            this._reconnectingCallbacks.push(callback);
62696        }
62697    }
62698    /** Registers a handler that will be invoked when the connection successfully reconnects.
62699     *
62700     * @param {Function} callback The handler that will be invoked when the connection successfully reconnects.
62701     */
62702    onreconnected(callback) {
62703        if (callback) {
62704            this._reconnectedCallbacks.push(callback);
62705        }
62706    }
62707    _processIncomingData(data) {
62708        this._cleanupTimeout();
62709        if (!this._receivedHandshakeResponse) {
62710            data = this._processHandshakeResponse(data);
62711            this._receivedHandshakeResponse = true;
62712        }
62713        // Data may have all been read when processing handshake response
62714        if (data) {
62715            // Parse the messages
62716            const messages = this._protocol.parseMessages(data, this._logger);
62717            for (const message of messages) {
62718                switch (message.type) {
62719                    case MessageType.Invocation:
62720                        this._invokeClientMethod(message);
62721                        break;
62722                    case MessageType.StreamItem:
62723                    case MessageType.Completion: {
62724                        const callback = this._callbacks[message.invocationId];
62725                        if (callback) {
62726                            if (message.type === MessageType.Completion) {
62727                                delete this._callbacks[message.invocationId];
62728                            }
62729                            try {
62730                                callback(message);
62731                            }
62732                            catch (e) {
62733                                this._logger.log(LogLevel.Error, `Stream callback threw error: ${getErrorString(e)}`);
62734                            }
62735                        }
62736                        break;
62737                    }
62738                    case MessageType.Ping:
62739                        // Don't care about pings
62740                        break;
62741                    case MessageType.Close: {
62742                        this._logger.log(LogLevel.Information, "Close message received from server.");
62743                        const error = message.error ? new Error("Server returned an error on close: " + message.error) : undefined;
62744                        if (message.allowReconnect === true) {
62745                            // It feels wrong not to await connection.stop() here, but processIncomingData is called as part of an onreceive callback which is not async,
62746                            // this is already the behavior for serverTimeout(), and HttpConnection.Stop() should catch and log all possible exceptions.
62747                            // eslint-disable-next-line @typescript-eslint/no-floating-promises
62748                            this.connection.stop(error);
62749                        }
62750                        else {
62751                            // We cannot await stopInternal() here, but subsequent calls to stop() will await this if stopInternal() is still ongoing.
62752                            this._stopPromise = this._stopInternal(error);
62753                        }
62754                        break;
62755                    }
62756                    default:
62757                        this._logger.log(LogLevel.Warning, `Invalid message type: ${message.type}.`);
62758                        break;
62759                }
62760            }
62761        }
62762        this._resetTimeoutPeriod();
62763    }
62764    _processHandshakeResponse(data) {
62765        let responseMessage;
62766        let remainingData;
62767        try {
62768            [remainingData, responseMessage] = this._handshakeProtocol.parseHandshakeResponse(data);
62769        }
62770        catch (e) {
62771            const message = "Error parsing handshake response: " + e;
62772            this._logger.log(LogLevel.Error, message);
62773            const error = new Error(message);
62774            this._handshakeRejecter(error);
62775            throw error;
62776        }
62777        if (responseMessage.error) {
62778            const message = "Server returned handshake error: " + responseMessage.error;
62779            this._logger.log(LogLevel.Error, message);
62780            const error = new Error(message);
62781            this._handshakeRejecter(error);
62782            throw error;
62783        }
62784        else {
62785            this._logger.log(LogLevel.Debug, "Server handshake complete.");
62786        }
62787        this._handshakeResolver();
62788        return remainingData;
62789    }
62790    _resetKeepAliveInterval() {
62791        if (this.connection.features.inherentKeepAlive) {
62792            return;
62793        }
62794        // Set the time we want the next keep alive to be sent
62795        // Timer will be setup on next message receive
62796        this._nextKeepAlive = new Date().getTime() + this.keepAliveIntervalInMilliseconds;
62797        this._cleanupPingTimer();
62798    }
62799    _resetTimeoutPeriod() {
62800        if (!this.connection.features || !this.connection.features.inherentKeepAlive) {
62801            // Set the timeout timer
62802            this._timeoutHandle = setTimeout(() => this.serverTimeout(), this.serverTimeoutInMilliseconds);
62803            // Set keepAlive timer if there isn't one
62804            if (this._pingServerHandle === undefined) {
62805                let nextPing = this._nextKeepAlive - new Date().getTime();
62806                if (nextPing < 0) {
62807                    nextPing = 0;
62808                }
62809                // The timer needs to be set from a networking c
62809allback to avoid Chrome timer throttling from causing timers to run once a minute
62810                this._pingServerHandle = setTimeout(async () => {
62811                    if (this._connectionState === HubConnectionState.Connected) {
62812                        try {
62813                            await this._sendMessage(this._cachedPingMessage);
62814                        }
62815                        catch {
62816                            // We don't care about the error. It should be seen elsewhere in the client.
62817                            // The connection is probably in a bad or closed state now, cleanup the timer so it stops triggering
62818                            this._cleanupPingTimer();
62819                        }
62820                    }
62821                }, nextPing);
62822            }
62823        }
62824    }
62825    // eslint-disable-next-line @typescript-eslint/naming-convention
62826    serverTimeout() {
62827        // The server hasn't talked to us in a while. It doesn't like us anymore ... :(
62828        // Terminate the connection, but we don't need to wait on the promise. This could trigger reconnecting.
62829        // eslint-disable-next-line @typescript-eslint/no-floating-promises
62830        this.connection.stop(new Error("Server timeout elapsed without receiving a message from the server."));
62831    }
62832    _invokeClientMethod(invocationMessage) {
62833        const methods = this._methods[invocationMessage.target.toLowerCase()];
62834        if (methods) {
62835            try {
62836                methods.forEach((m) => m.apply(this, invocationMessage.arguments));
62837            }
62838            catch (e) {
62839                this._logger.log(LogLevel.Error, `A callback for the method ${invocationMessage.target.toLowerCase()} threw error '${e}'.`);
62840            }
62841            if (invocationMessage.invocationId) {
62842                // This is not supported in v1. So we return an error to avoid blocking the server waiting for the response.
62843                const message = "Server requested a response, which is not supported in this version of the client.";
62844                this._logger.log(LogLevel.Error, message);
62845                // We don't want to wait on the stop itself.
62846                this._stopPromise = this._stopInternal(new Error(message));
62847            }
62848        }
62849        else {
62850            this._logger.log(LogLevel.Warning, `No client method with the name '${invocationMessage.target}' found.`);
62851        }
62852    }
62853    _connectionClosed(error) {
62854        this._logger.log(LogLevel.Debug, `HubConnection.connectionClosed(${error}) called while in state ${this._connectionState}.`);
62855        // Triggering this.handshakeRejecter is insufficient because it could already be resolved without the continuation having run yet.
62856        this._stopDuringStartError = this._stopDuringStartError || error || new Error("The underlying connection was closed before the hub handshake could complete.");
62857        // If the handshake is in progress, start will be waiting for the handshake promise, so we complete it.
62858        // If it has already completed, this should just noop.
62859        if (this._handshakeResolver) {
62860            this._handshakeResolver();
62861        }
62862        this._cancelCallbacksWithError(error || new Error("Invocation canceled due to the underlying connection being closed."));
62863        this._cleanupTimeout();
62864        this._cleanupPingTimer();
62865        if (this._connectionState === HubConnectionState.Disconnecting) {
62866            this._completeClose(error);
62867        }
62868        else if (this._connectionState === HubConnectionState.Connected && this._reconnectPolicy) {
62869            // eslint-disable-next-line @typescript-eslint/no-floating-promises
62870            this._reconnect(error);
62871        }
62872        else if (this._connectionState === HubConnectionState.Connected) {
62873            this._completeClose(error);
62874        }
62875        // If none of the above if conditions were true were called the HubConnection must be in either:
62876        // 1. The Connecting state in which case the handshakeResolver will c
vendor: 17,747 bytes, lines 62876-63307
62876omplete it and stopDuringStartError will fail it.
62877        // 2. The Reconnecting state in which case the handshakeResolver will complete it and stopDuringStartError will fail the current reconnect attempt
62878        //    and potentially continue the reconnect() loop.
62879        // 3. The Disconnected state in which case we're already done.
62880    }
62881    _completeClose(error) {
62882        if (this._connectionStarted) {
62883            this._connectionState = HubConnectionState.Disconnected;
62884            this._connectionStarted = false;
62885            if (Platform.isBrowser) {
62886                window.document.removeEventListener("freeze", this._freezeEventListener);
62887            }
62888            try {
62889                this._closedCallbacks.forEach((c) => c.apply(this, [error]));
62890            }
62891            catch (e) {
62892                this._logger.log(LogLevel.Error, `An onclose callback called with error '${error}' threw error '${e}'.`);
62893            }
62894        }
62895    }
62896    async _reconnect(error) {
62897        const reconnectStartTime = Date.now();
62898        let previousReconnectAttempts = 0;
62899        let retryError = error !== undefined ? error : new Error("Attempting to reconnect due to a unknown error.");
62900        let nextRetryDelay = this._getNextRetryDelay(previousReconnectAttempts++, 0, retryError);
62901        if (nextRetryDelay === null) {
62902            this._logger.log(LogLevel.Debug, "Connection not reconnecting because the IRetryPolicy returned null on the first reconnect attempt.");
62903            this._completeClose(error);
62904            return;
62905        }
62906        this._connectionState = HubConnectionState.Reconnecting;
62907        if (error) {
62908            this._logger.log(LogLevel.Information, `Connection reconnecting because of error '${error}'.`);
62909        }
62910        else {
62911            this._logger.log(LogLevel.Information, "Connection reconnecting.");
62912        }
62913        if (this._reconnectingCallbacks.length !== 0) {
62914            try {
62915                this._reconnectingCallbacks.forEach((c) => c.apply(this, [error]));
62916            }
62917            catch (e) {
62918                this._logger.log(LogLevel.Error, `An onreconnecting callback called with error '${error}' threw error '${e}'.`);
62919            }
62920            // Exit early if an onreconnecting callback called connection.stop().
62921            if (this._connectionState !== HubConnectionState.Reconnecting) {
62922                this._logger.log(LogLevel.Debug, "Connection left the reconnecting state in onreconnecting callback. Done reconnecting.");
62923                return;
62924            }
62925        }
62926        while (nextRetryDelay !== null) {
62927            this._logger.log(LogLevel.Information, `Reconnect attempt number ${previousReconnectAttempts} will start in ${nextRetryDelay} ms.`);
62928            await new Promise((resolve) => {
62929                this._reconnectDelayHandle = setTimeout(resolve, nextRetryDelay);
62930            });
62931            this._reconnectDelayHandle = undefined;
62932            if (this._connectionState !== HubConnectionState.Reconnecting) {
62933                this._logger.log(LogLevel.Debug, "Connection left the reconnecting state during reconnect delay. Done reconnecting.");
62934                return;
62935            }
62936            try {
62937                await this._startInternal();
62938                this._connectionState = HubConnectionState.Connected;
62939                this._logger.log(LogLevel.Information, "HubConnection reconnected successfully.");
62940                if (this._reconnectedCallbacks.length !== 0) {
62941                    try {
62942                        this._reconnectedCallbacks.forEach((c) => c.apply(this, [this.connection.connectionId]));
62943                    }
62944                    catch (e) {
62945                        this._logger.log(LogLevel.Error, `An onreconnected callback called with connectionId '${this.connection.connectionId}; threw error '${e}'.`);
62946                    }
62947                }
62948                return;
62949            }
62950            catch (e) {
62951                this._logger.log(LogLevel.Information, `Reconnect attempt failed because of error '${e}'.`);
62952                if (this._connectionState !== HubConnectionState.Reconnecting) {
62953                    this._logger.log(LogLevel.Debug, `Connection moved to the '${this._connectionState}' from the reconnecting state during reconnect attempt. Done reconnecting.`);
62954                    // The TypeScript compiler thinks that connectionState must be Connected here. The TypeScript compiler is wrong.
62955                    if (this._connectionState === HubConnectionState.Disconnecting) {
62956                        this._completeClose();
62957                    }
62958                    return;
62959                }
62960                retryError = e instanceof Error ? e : new Error(e.toString());
62961                nextRetryDelay = this._getNextRetryDelay(previousReconnectAttempts++, Date.now() - reconnectStartTime, retryError);
62962            }
62963        }
62964        this._logger.log(LogLevel.Information, `Reconnect retries have been exhausted after ${Date.now() - reconnectStartTime} ms and ${previousReconnectAttempts} failed attempts. Connection disconnecting.`);
62965        this._completeClose();
62966    }
62967    _getNextRetryDelay(previousRetryCount, elapsedMilliseconds, retryReason) {
62968        try {
62969            return this._reconnectPolicy.nextRetryDelayInMilliseconds({
62970                elapsedMilliseconds,
62971                previousRetryCount,
62972                retryReason,
62973            });
62974        }
62975        catch (e) {
62976            this._logger.log(LogLevel.Error, `IRetryPolicy.nextRetryDelayInMilliseconds(${previousRetryCount}, ${elapsedMilliseconds}) threw error '${e}'.`);
62977            return null;
62978        }
62979    }
62980    _cancelCallbacksWithError(error) {
62981        const callbacks = this._callbacks;
62982        this._callbacks = {};
62983        Object.keys(callbacks)
62984            .forEach((key) => {
62985            const callback = callbacks[key];
62986            try {
62987                callback(null, error);
62988            }
62989            catch (e) {
62990                this._logger.log(LogLevel.Error, `Stream 'error' callback called with '${error}' threw error: ${getErrorString(e)}`);
62991            }
62992        });
62993    }
62994    _cleanupPingTimer() {
62995        if (this._pingServerHandle) {
62996            clearTimeout(this._pingServerHandle);
62997            this._pingServerHandle = undefined;
62998        }
62999    }
63000    _cleanupTimeout() {
63001        if (this._timeoutHandle) {
63002            clearTimeout(this._timeoutHandle);
63003        }
63004    }
63005    _createInvocation(methodName, args, nonblocking, streamIds) {
63006        if (nonblocking) {
63007            if (streamIds.length !== 0) {
63008                return {
63009                    arguments: args,
63010                    streamIds,
63011                    target: methodName,
63012                    type: MessageType.Invocation,
63013                };
63014            }
63015            else {
63016                return {
63017                    arguments: args,
63018                    target: methodName,
63019                    type: MessageType.Invocation,
63020                };
63021            }
63022        }
63023        else {
63024            const invocationId = this._invocationId;
63025            this._invocationId++;
63026            if (streamIds.length !== 0) {
63027                return {
63028                    arguments: args,
63029                    invocationId: invocationId.toString(),
63030                    streamIds,
63031                    target: methodName,
63032                    type: MessageType.Invocation,
63033                };
63034            }
63035            else {
63036                return {
63037                    arguments: args,
63038                    invocationId: invocationId.toString(),
63039                    target: methodName,
63040                    type: MessageType.Invocation,
63041                };
63042            }
63043        }
63044    }
63045    _launchStreams(streams, promiseQueue) {
63046        if (streams.length === 0) {
63047            return;
63048        }
63049        // Synchronize stream data so they arrive in-order on the server
63050        if (!promiseQueue) {
63051            promiseQueue = Promise.resolve();
63052        }
63053        // We want to iterate over the keys, since the keys are the stream ids
63054        // eslint-disable-next-line guard-for-in
63055        for (const streamId in streams) {
63056            streams[streamId].subscribe({
63057                complete: () => {
63058                    promiseQueue = promiseQueue.then(() => this._sendWithProtocol(this._createCompletionMessage(streamId)));
63059                },
63060                error: (err) => {
63061                    let message;
63062                    if (err instanceof Error) {
63063                        message = err.message;
63064                    }
63065                    else if (err && err.toString) {
63066                        message = err.toString();
63067                    }
63068                    else {
63069                        message = "Unknown error";
63070                    }
63071                    promiseQueue = promiseQueue.then(() => this._sendWithProtocol(this._createCompletionMessage(streamId, message)));
63072                },
63073                next: (item) => {
63074                    promiseQueue = promiseQueue.then(() => this._sendWithProtocol(this._createStreamItemMessage(streamId, item)));
63075                },
63076            });
63077        }
63078    }
63079    _replaceStreamingParams(args) {
63080        const streams = [];
63081        const streamIds = [];
63082        for (let i = 0; i < args.length; i++) {
63083            const argument = args[i];
63084            if (this._isObservable(argument)) {
63085                const streamId = this._invocationId;
63086                this._invocationId++;
63087                // Store the stream for later use
63088                streams[streamId] = argument;
63089                streamIds.push(streamId.toString());
63090                // remove stream from args
63091                args.splice(i, 1);
63092            }
63093        }
63094        return [streams, streamIds];
63095    }
63096    _isObservable(arg) {
63097        // This allows other stream implementations to just work (like rxjs)
63098        return arg && arg.subscribe && typeof arg.subscribe === "function";
63099    }
63100    _createStreamInvocation(methodName, args, streamIds) {
63101        const invocationId = this._invocationId;
63102        this._invocationId++;
63103        if (streamIds.length !== 0) {
63104            return {
63105                arguments: args,
63106                invocationId: invocationId.toString(),
63107                streamIds,
63108                target: methodName,
63109                type: MessageType.StreamInvocation,
63110            };
63111        }
63112        else {
63113            return {
63114                arguments: args,
63115                invocationId: invocationId.toString(),
63116                target: methodName,
63117                type: MessageType.StreamInvocation,
63118            };
63119        }
63120    }
63121    _createCancelInvocation(id) {
63122        return {
63123            invocationId: id,
63124            type: MessageType.CancelInvocation,
63125        };
63126    }
63127    _createStreamItemMessage(id, item) {
63128        return {
63129            invocationId: id,
63130            item,
63131            type: MessageType.StreamItem,
63132        };
63133    }
63134    _createCompletionMessage(id, error, result) {
63135        if (error) {
63136            return {
63137                error,
63138                invocationId: id,
63139                type: MessageType.Completion,
63140            };
63141        }
63142        return {
63143            invocationId: id,
63144            result,
63145            type: MessageType.Completion,
63146        };
63147    }
63148}
63149//# sourceMappingURL=HubConnection.js.map
63150;// CONCATENATED MODULE: ./node_modules/@microsoft/signalr/dist/esm/JsonHubProtocol.js
63151// Licensed to the .NET Foundation under one or more agreements.
63152// The .NET Foundation licenses this file to you under the MIT license.
63153
63154
63155
63156
63157
63158const JSON_HUB_PROTOCOL_NAME = "json";
63159/** Implements the JSON Hub Protocol. */
63160class JsonHubProtocol {
63161    constructor() {
63162        /** @inheritDoc */
63163        this.name = JSON_HUB_PROTOCOL_NAME;
63164        /** @inheritDoc */
63165        this.version = 1;
63166        /** @inheritDoc */
63167        this.transferFormat = TransferFormat.Text;
63168    }
63169    /** Creates an array of {@link @microsoft/signalr.HubMessage} objects from the specified serialized representation.
63170     *
63171     * @param {string} input A string containing the serialized representation.
63172     * @param {ILogger} logger A logger that will be used to log messages that occur during parsing.
63173     */
63174    parseMessages(input, logger) {
63175        // The interface does allow "ArrayBuffer" to be passed in, but this implementation does not. So let's throw a useful error.
63176        if (typeof input !== "string") {
63177            throw new Error("Invalid input for JSON hub protocol. Expected a string.");
63178        }
63179        if (!input) {
63180            return [];
63181        }
63182        if (logger === null) {
63183            logger = NullLogger.instance;
63184        }
63185        // Parse the messages
63186        const messages = TextMessageFormat.parse(input);
63187        const hubMessages = [];
63188        for (const message of messages) {
63189            const parsedMessage = JSON.parse(message);
63190            if (typeof parsedMessage.type !== "number") {
63191                throw new Error("Invalid payload.");
63192            }
63193            switch (parsedMessage.type) {
63194                case MessageType.Invocation:
63195                    this._isInvocationMessage(parsedMessage);
63196                    break;
63197                case MessageType.StreamItem:
63198                    this._isStreamItemMessage(parsedMessage);
63199                    break;
63200                case MessageType.Completion:
63201                    this._isCompletionMessage(parsedMessage);
63202                    break;
63203                case MessageType.Ping:
63204                    // Single value, no need to validate
63205                    break;
63206                case MessageType.Close:
63207                    // All optional values, no need to validate
63208                    break;
63209                default:
63210                    // Future protocol changes can add message types, old clients can ignore them
63211                    logger.log(LogLevel.Information, "Unknown message type '" + parsedMessage.type + "' ignored.");
63212                    continue;
63213            }
63214            hubMessages.push(parsedMessage);
63215        }
63216        return hubMessages;
63217    }
63218    /** Writes the specified {@link @microsoft/signalr.HubMessage} to a string and returns it.
63219     *
63220     * @param {HubMessage} message The message to write.
63221     * @returns {string} A string containing the serialized representation of the message.
63222     */
63223    writeMessage(message) {
63224        return TextMessageFormat.write(JSON.stringify(message));
63225    }
63226    _isInvocationMessage(message) {
63227        this._assertNotEmptyString(message.target, "Invalid payload for Invocation message.");
63228        if (message.invocationId !== undefined) {
63229            this._assertNotEmptyString(message.invocationId, "Invalid payload for Invocation message.");
63230        }
63231    }
63232    _isStreamItemMessage(message) {
63233        this._assertNotEmptyString(message.invocationId, "Invalid payload for StreamItem message.");
63234        if (message.item === undefined) {
63235            throw new Error("Invalid payload for StreamItem message.");
63236        }
63237    }
63238    _isCompletionMessage(message) {
63239        if (message.result && message.error) {
63240            throw new Error("Invalid payload for Completion message.");
63241        }
63242        if (!message.result && message.error) {
63243            this._assertNotEmptyString(message.error, "Invalid payload for Completion message.");
63244        }
63245        this._assertNotEmptyString(message.invocationId, "Invalid payload for Completion message.");
63246    }
63247    _assertNotEmptyString(value, errorMessage) {
63248        if (typeof value !== "string" || value === "") {
63249            throw new Error(errorMessage);
63250        }
63251    }
63252}
63253//# sourceMappingURL=JsonHubProtocol.js.map
63254;// CONCATENATED MODULE: ./node_modules/@microsoft/signalr/dist/esm/HubConnectionBuilder.js
63255// Licensed to the .NET Foundation under one or more agreements.
63256// The .NET Foundation licenses this file to you under the MIT license.
63257
63258
63259
63260
63261
63262
63263
63264const LogLevelNameMapping = {
63265    trace: LogLevel.Trace,
63266    debug: LogLevel.Debug,
63267    info: LogLevel.Information,
63268    information: LogLevel.Information,
63269    warn: LogLevel.Warning,
63270    warning: LogLevel.Warning,
63271    error: LogLevel.Error,
63272    critical: LogLevel.Critical,
63273    none: LogLevel.None,
63274};
63275function parseLogLevel(name) {
63276    // Case-insensitive matching via lower-casing
63277    // Yes, I know case-folding is a complicated problem in Unicode, but we only support
63278    // the ASCII strings defined in LogLevelNameMapping anyway, so it's fine -anurse.
63279    const mapping = LogLevelNameMapping[name.toLowerCase()];
63280    if (typeof mapping !== "undefined") {
63281        return mapping;
63282    }
63283    else {
63284        throw new Error(`Unknown log level: ${name}`);
63285    }
63286}
63287/** A builder for configuring {@link @microsoft/signalr.HubConnection} instances. */
63288class HubConnectionBuilder {
63289    configureLogging(logging) {
63290        Arg.isRequired(logging, "logging");
63291        if (isLogger(logging)) {
63292            this.logger = logging;
63293        }
63294        else if (typeof logging === "string") {
63295            const logLevel = parseLogLevel(logging);
63296            this.logger = new ConsoleLogger(logLevel);
63297        }
63298        else {
63299            this.logger = new ConsoleLogger(logging);
63300        }
63301        return this;
63302    }
63303    withUrl(url, transportTypeOrOptions) {
63304        Arg.isRequired(url, "url");
63305        Arg.isNotEmpty(url, "url");
63306        this.url = url;
63307        // Flow-typing knows where it's at. Since HttpTransportType is a 
63307number and IHttpConnectionOptions is guaranteed
63308        // to be an object, we know (as does TypeScript) this comparison is all we need to figure out which overload was called.
63309        if (typeof transportTypeOrOptions === "object") {
63310            this.httpConnectionOptions = { ...this.httpConnectionOptions, ...transportTypeOrOptions };
63311        }
63312        else {
63313            this.httpConnectionOptions = {
63314                ...this.httpConnectionOptions,
63315                transport: transportTypeOrOptions,
63316            };
63317        }
63318        return this;
63319    }
63320    /** Configures the {@link @microsoft/signalr.HubConnection} to use the specified Hub Protocol.
63321     *
63322     * @param {IHubProtocol} protocol The {@link @microsoft/signalr.IHubProtocol} implementation to use.
63323     */
63324    withHubProtocol(protocol) {
63325        Arg.isRequired(protocol, "protocol");
63326        this.protocol = protocol;
63327        return this;
63328    }
63329    withAutomaticReconnect(retryDelaysOrReconnectPolicy) {
63330        if (this.reconnectPolicy) {
63331            throw new Error("A reconnectPolicy has already been set.");
63332        }
63333        if (!retryDelaysOrReconnectPolicy) {
63334            this.reconnectPolicy = new DefaultReconnectPolicy();
63335        }
63336        else if (Array.isArray(retryDelaysOrReconnectPolicy)) {
63337            this.reconnectPolicy = new DefaultReconnectPolicy(retryDelaysOrReconnectPolicy);
63338        }
63339        else {
63340            this.reconnectPolicy = retryDelaysOrReconnectPolicy;
63341        }
63342        return this;
63343    }
63344    /** Creates a {@link @microsoft/signalr.HubConnection} from the configuration options specified in this builder.
63345     *
63346     * @returns {HubConnection} The configured {@link @microsoft/signalr.HubConnection}.
63347     */
63348    build() {
63349        // If httpConnectionOptions has a logger, use it. Otherwise, override it with the one
63350        // provided to configureLogger
63351        const httpConnectionOptions = this.httpConnectionOptions || {};
63352        // If it's 'null', the user **explicitly** asked for null, don't mess with it.
63353        if (httpConnectionOptions.logger === undefined) {
63354            // If our logger is undefined or null, that's OK, the HttpConnection constructor will handle it.
63355            httpConnectionOptions.logger = this.logger;
63356        }
63357        // Now create the connection
63358        if (!this.url) {
63359            throw new Error("The 'HubConnectionBuilder.withUrl' method must be called before building the connection.");
63360        }
63361        const connection = new HttpConnection(this.url, httpConnectionOptions);
63362        return HubConnection.create(connection, this.logger || NullLogger.instance, this.protocol || new JsonHubProtocol(), this.reconnectPolicy);
63363    }
63364}
63365function isLogger(logger) {
63366    return logger.log !== undefined;
63367}
63368//# sourceMappingURL=HubConnectionBuilder.js.map
63369;// CONCATENATED MODULE: ./wwwroot/js/domain-map.js
63370/* provided dependency */ var domain_map_$ = __webpack_require__(755);
63371
63372
63373
63374
63375window.domainMap = DomainMap(domain_map_$('#Domain_CentralLatitude'), domain_map_$('#Domain_CentralLongitude'), 'map_canvas', domain_map_$('#Domain_ShowControls').val() === 'true');
63376
63377const connection = new HubConnectionBuilder()
63378    .withUrl("/copterhub")
63379    .configureLogging(signalR.LogLevel.Information)
63380    .build();
63381
63382function set_last_seen(mins) {
63383    document.getElementById('txtSeen').innerText = mins >= 60 ? 'over an hour ago' : Math.round(mins) + ' minutes ago';
63384}
63385
63386window.domainMap.eventManager.on('copterselecting', a => {
63387    if (a && a.copter) {
63388        console.log(`Leaving group ${a.copter}`);
63389        connection.invoke('leaveGroup', a.copter);
63390    }
63391
63392    domain_map_$('.overlay-copter .container-fluid').addClass('visually-hidden');
63393});
63394
63395
63396window.domainMap.eventManager.on('copterselected', a => {
63397    if (a && a.copter) {
63398        console.log(`Joining group ${a.copter}`);
63399        connection.invoke('joinGroup', a.copter);
63400
63401        document.getElementById('txtSelected').textContent = a.copter;
63402        document.getElementById('lnkLive').href = a.live_url;
63403        set_last_seen(a.last_seen);
63404    }
63405});
63406
63407//window.domainMap.eventManager.on('waypoint_added', a => {
63408//    if (a) {
63409//        document.getElementById('txtLat').value = a.latitude;
63410//        document.getElementById('txtLon').value = a.longitude;
63411//    }
63412//});
63413
63414connection.on('LocationUpdate', d => {
63415    if (d) {
63416        //console.log(d);
63417        window.domainMap.update_copter_location(d.copter, d.latitude, d.longitude);
63418    }
63419});
63420
63421let toC = K => (K - 273.15).toFixed(2);
63422let humidity = v => (v * 100).toFixed(2);
63423
63424connection.on('ReceiveData', d => {
63425    if (d) {
63426        domain_map_$('.overlay-copter .container-fluid').removeClass('visually-hidden');
63427
63428        let diff = new Date() - Date.parse(d.last_seen);
63429        let mins = Math.round(((diff % 86400000) % 3600000) / 60000);
63430
63431        if (!domain_map_$('#copterStatusIcon').hasClass(d.control_mode.toLowerCase())) {
63432            domain_map_$('#copterStatusIcon').removeClass().addClass(['copter-status', d.control_mode.toLowerCase()]);
63433        }
63434
63435        set_last_seen(mins);
63436        document.getElementById('copterTemp').innerText = toC(d.filteredT);
63437        document.getElementById('copterHum').innerText = humidity(d.filteredRH);
63438        document.getElementById('copterPress').innerText = (d.pressure.value / 100).toFixed(2);
63439        document.getElementById('copterAlt').innerText = d.location.altitude.toFixed(2);
63440        document.getElementById('copterDir').innerText = d.wind.direction.toFixed(2);
63441        document.getElementById('copterSpd').innerText = d.wind.speed.toFixed(2);
63442        // console.log(d);
63443    }
63444});
63445
63446connection.start()
63447    .then(() => connection.invoke('joinGroup', 'CopterMap'))
63448    .catch(err => console.error(err.toString()));
63449})();
63450
63451/******/ })()
63452;

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.