PageSourceSearch

https://letniysad.pro/bitrix/js/main/core/core.js?1787824881334249

js letniysad.pro collected 2026-09-30 02:33:34 UTC 334,249 bytes, 13,472 lines download raw bytes

1/* eslint-disable */
2;(function() {
3
4	if (typeof window.BX === 'function')
5	{
6		return;
7	}
8
9/**
10 * Babel external helpers
11 * (c) 2018 Babel
12 * @license MIT
13 */
14(function (global) {
15	var babelHelpers = global.babelHelpers = {};
16
17	function _typeof(obj) {
18		if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
19			babelHelpers.typeof = _typeof = function (obj) {
20				return typeof obj;
21			};
22		} else {
23			babelHelpers.typeof = _typeof = function (obj) {
24				return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
25			};
26		}
27
28		return _typeof(obj);
29	}
30
31	babelHelpers.typeof = _typeof;
32	var REACT_ELEMENT_TYPE;
33
34	function _createRawReactElement(type, props, key, children) {
35		if (!REACT_ELEMENT_TYPE) {
36			REACT_ELEMENT_TYPE = typeof Symbol === "function" && Symbol.for && Symbol.for("react.element") || 0xeac7;
37		}
38
39		var defaultProps = type && type.defaultProps;
40		var childrenLength = arguments.length - 3;
41
42		if (!props && childrenLength !== 0) {
43			props = {
44				children: void 0
45			};
46		}
47
48		if (props && defaultProps) {
49			for (var propName in defaultProps) {
50				if (props[propName] === void 0) {
51					props[propName] = defaultProps[propName];
52				}
53			}
54		} else if (!props) {
55			props = defaultProps || {};
56		}
57
58		if (childrenLength === 1) {
59			props.children = children;
60		} else if (childrenLength > 1) {
61			var childArray = new Array(childrenLength);
62
63			for (var i = 0; i < childrenLength; i++) {
64				childArray[i] = arguments[i + 3];
65			}
66
67			props.children = childArray;
68		}
69
70		return {
71			$$typeof: REACT_ELEMENT_TYPE,
72			type: type,
73			key: key === undefined ? null : '' + key,
74			ref: null,
75			props: props,
76			_owner: null
77		};
78	}
79
80	babelHelpers.jsx = _createRawReactElement;
81
82	function _asyncIterator(iterable) {
83		var method;
84
85		if (typeof Symbol === "function") {
86			if (Symbol.asyncIterator) {
87				method = iterable[Symbol.asyncIterator];
88				if (method != null) return method.call(iterable);
89			}
90
91			if (Symbol.iterator) {
92				method = iterable[Symbol.iterator];
93				if (method != null) return method.call(iterable);
94			}
95		}
96
97		throw new TypeError("Object is not async iterable");
98	}
99
100	babelHelpers.asyncIterator = _asyncIterator;
101
102	function _AwaitValue(value) {
103		this.wrapped = value;
104	}
105
106	babelHelpers.AwaitValue = _AwaitValue;
107
108	function AsyncGenerator(gen) {
109		var front, back;
110
111		function send(key, arg) {
112			return new Promise(function (resolve, reject) {
113				var request = {
114					key: key,
115					arg: arg,
116					resolve: resolve,
117					reject: reject,
118					next: null
119				};
120
121				if (back) {
122					back = back.next = request;
123				} else {
124					front = back = request;
125					resume(key, arg);
126				}
127			});
128		}
129
130		function resume(key, arg) {
131			try {
132				var result = gen[key](arg);
133				var value = result.value;
134				var wrappedAwait = value instanceof babelHelpers.AwaitValue;
135				Promise.resolve(wrappedAwait ? value.wrapped : value).then(function (arg) {
136					if (wrappedAwait) {
137						resume("next", arg);
138						return;
139					}
140
141					settle(result.done ? "return" : "normal", arg);
142				}, function (err) {
143					resume("throw", err);
144				});
145			} catch (err) {
146				settle("throw", err);
147			}
148		}
149
150		function settle(type, value) {
151			switch (type) {
152				case "return":
153					front.resolve({
154						value: value,
155						done: true
156					});
157					break;
158
159				case "throw":
160					front.reject(value);
161					break;
162
163				default:
164					front.resolve({
165						value: value,
166						done: false
167					});
168					break;
169			}
170
171			front = front.next;
172
173			if (front) {
174				resume(front.key, front.arg);
175			} else {
176				back = null;
177			}
178		}
179
180		this._invoke = send;
181
182		if (typeof gen.return !== "function") {
183			this.return = undefined;
184		}
185	}
186
187	if (typeof Symbol === "function" && Symbol.asyncIterator) {
188		AsyncGenerator.prototype[Symbol.asyncIterator] = function () {
189			return this;
190		};
191	}
192
193	AsyncGenerator.prototype.next = function (arg) {
194		return this._invoke("next", arg);
195	};
196
197	AsyncGenerator.prototype.throw = function (arg) {
198		return this._invoke("throw", arg);
199	};
200
201	AsyncGenerator.prototype.return = function (arg) {
202		return this._invoke("return", arg);
203	};
204
205	babelHelpers.AsyncGenerator = AsyncGenerator;
206
207	function _wrapAsyncGenerator(fn) {
208		return function () {
209			return new babelHelpers.AsyncGenerator(fn.apply(this, arguments));
210		};
211	}
212
213	babelHelpers.wrapAsyncGenerator = _wrapAsyncGenerator;
214
215	function _awaitAsyncGenerator(value) {
216		return new babelHelpers.AwaitValue(value);
217	}
218
219	babelHelpers.awaitAsyncGenerator = _awaitAsyncGenerator;
220
221	function _asyncGeneratorDelegate(inner, awaitWrap) {
222		var iter = {},
223				waiting = false;
224
225		function pump(key, value) {
226			waiting = true;
227			value = new Promise(function (resolve) {
228				resolve(inner[key](value));
229			});
230			return {
231				done: false,
232				value: awaitWrap(value)
233			};
234		}
235
236		;
237
238		if (typeof Symbol === "function" && Symbol.iterator) {
239			iter[Symbol.iterator] = function () {
240				return this;
241			};
242		}
243
244		iter.next = function (value) {
245			if (waiting) {
246				waiting = false;
247				return value;
248			}
249
250			return pump("next", value);
251		};
252
253		if (typeof inner.throw === "function") {
254			iter.throw = function (value) {
255				if (waiting) {
256					waiting = false;
257					throw value;
258				}
259
260				return pump("throw", value);
261			};
262		}
263
264		if (typeof inner.return === "function") {
265			iter.return = function (value) {
266				return pump("return", value);
267			};
268		}
269
270		return iter;
271	}
272
273	babelHelpers.asyncGeneratorDelegate = _asyncGeneratorDelegate;
274
275	function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
276		try {
277			var info = gen[key](arg);
278			var value = info.value;
279		} catch (error) {
280			reject(error);
281			return;
282		}
283
284		if (info.done) {
285			resolve(value);
286		} else {
287			Promise.resolve(value).then(_next, _throw);
288		}
289	}
290
291	function _asyncToGenerator(fn) {
292		return function () {
293			var self = this,
294					args = arguments;
295			return new Promise(function (resolve, reject) {
296				var gen = fn.apply(self, args);
297
298				function _next(value) {
299					asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
300				}
301
302				function _throw(err) {
303					asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
304				}
305
306				_next(undefined);
307			});
308		};
309	}
310
311	babelHelpers.asyncToGenerator = _asyncToGenerator;
312
313	function _classCallCheck(instance, Constructor) {
314		if (!(instance instanceof Constructor)) {
315			throw new TypeError("Cannot call a class as a function");
316		}
317	}
318
319	babelHelpers.classCallCheck = _classCallCheck;
320
321	function _defineProperties(target, props) {
322		for (var i = 0; i < props.length; i++) {
323			var descriptor = props[i];
324			descriptor.enumerable = descriptor.enumerable || false;
325			descriptor.configurable = true;
326			if ("value" in descriptor) descriptor.writable = true;
327			Object.defineProperty(target, descriptor.key, descriptor);
328		}
329	}
330
331	function _createClass(Constructor, protoProps, staticProps) {
332		if (protoProps) _defineProperties(Constructor.prototype, protoProps);
333		if (staticProps) _defineProperties(Constructor, staticProps);
334		return Constructor;
335	}
336
337	babelHelpers.createClass = _createClass;
338
339	function _defineEnumerableProperties(obj, descs) {
340		for (var key in descs) {
341			var desc = descs[key];
342			desc.configurable = desc.enumerable = true;
343			if ("value" in desc) desc.writable = true;
344			Object.defineProperty(obj, key, desc);
345		}
346
347		if (Object.getOwnPropertySymbols) {
348			var objectSymbols = Object.getOwnPropertySymbols(descs);
349
350			for (var i = 0; i < objectSymbols.length; i++) {
351				var sym = objectSymbols[i];
352				var desc = descs[sym];
353				desc.configurable = desc.enumerable = true;
354				if ("value" in desc) desc.writable = true;
355				Object.defineProperty(obj, sym, desc);
356			}
357		}
358
359		return obj;
360	}
361
362	babelHelpers.defineEnumerableProperties = _defineEnumerableProperties;
363
364	function _defaults(obj, defaults) {
365		var keys = Object.getOwnPropertyNames(defaults);
366
367		for (var i = 0; i < keys.length; i++) {
368			var key = keys[i];
369			var value = Object.getOwnPropertyDescriptor(defaults, key);
370
371			if (value && value.configurable && obj[key] === undefined) {
372				Object.defineProperty(obj, key, value);
373			}
374		}
375
376		return obj;
377	}
378
379	babelHelpers.defaults = _defaults;
380
381	function _defineProperty(obj, key, value) {
382		if (key in obj) {
383			Object.defineProperty(obj, key, {
384				value: value,
385				enumerable: true,
386				configurable: true,
387				writable: true
388			});
389		} else {
390			obj[key] = value;
391		}
392
393		return obj;
394	}
395
396	babelHelpers.defineProperty = _defineProperty;
397
398	function _extends() {
399		babelHelpers.extends = _extends = Object.assign || function (target) {
400			for (var i = 1; i < arguments.length; i++) {
401				var source = arguments[i];
402
403				for (var key in source) {
404					if (Object.prototype.hasOwnProperty.call(source, key)) {
405						target[key] = source[key];
406					}
407				}
408			}
409
410			return target;
411		};
412
413		return _extends.apply(this, arguments);
414	}
415
416	babelHelpers.extends = _extends;
417
418	function _objectSpread(target) {
419		for (var i = 1; i < arguments.length; i++) {
420			var source = arguments[i] != null ? arguments[i] : {};
421			var ownKeys = Object.keys(source);
422
423			if (typeof Object.getOwnPropertySymbols === 'function') {
424				ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) {
425					return Object.getOwnPropertyDescriptor(source, sym).enumerable;
426				}));
427			}
428
429			ownKeys.forEach(function (key) {
430				babelHelpers.defineProperty(target, key, source[key]);
431			});
432		}
433
434		return target;
435	}
436
437	babelHelpers.objectSpread = _objectSpread;
438
439	function _inherits(subClass, superClass) {
440		if (typeof superClass !== "function" && superClass !== null) {
441			throw new TypeError("Super expression must either be null or a function");
442		}
443
444		subClass.prototype = Object.create(superClass && superClass.prototype, {
445			constructor: {
446				value: subClass,
447				writable: true,
448				configurable: true
449			}
450		});
451		if (superClass) babelHelpers.setPrototypeOf(subClass, superClass);
452	}
453
454	babelHelpers.inherits = _inherits;
455
456	function _inheritsLoose(subClass, superClass) {
457		subClass.prototype = Object.create(superClass.prototype);
458		subClass.prototype.constructor = subClass;
459		subClass.__proto__ = superClass;
460	}
461
462	babelHelpers.inheritsLoose = _inheritsLoose;
463
464	function _getPrototypeOf(o) {
465		babelHelpers.getPrototypeOf = _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
466			return o.__proto__ || Object.getPrototypeOf(o);
467		};
468		return _getPrototypeOf(o);
469	}
470
471	babelHelpers.getPrototypeOf = _getPrototypeOf;
472
473	function _setPrototypeOf(o, p) {
474		babelHelpers.setPrototypeOf = _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
475			o.__proto__ = p;
476			return o;
477		};
478
479		return _setPrototypeOf(o, p);
480	}
481
482	babelHelpers.setPrototypeOf = _setPrototypeOf;
483
484	function isNativeReflectConstruct() {
485		if (typeof Reflect === "undefined" || !Reflect.construct) return false;
486		if (Reflect.construct.sham) return false;
487		if (typeof Proxy === "function") return true;
488
489		try {
490			Date.prototype.toString.call(Reflect.construct(Date, [], function () {}));
491			return true;
492		} catch (e) {
493			return false;
494		}
495	}
496
497	function _construct(Parent, args, Class) {
498		if (isNativeReflectConstruct()) {
499			babelHelpers.construct = _construct = Reflect.construct;
500		} else {
501			babelHelpers.construct = _construct = function _construct(Parent, args, Class) {
502				var a = [null];
503				a.push.apply(a, args);
504				var Constructor = Function.bind.apply(Parent, a);
505				var instance = new Constructor();
506				if (Class) babelHelpers.setPrototypeOf(instance, Class.prototype);
507				return instance;
508			};
509		}
510
511		return _construct.apply(null, arguments);
512	}
513
514	babelHelpers.construct = _construct;
515
516	function _isNativeFunction(fn) {
517		return Function.toString.call(fn).indexOf("[native code]") !== -1;
518	}
519
520	babelHelpers.isNativeFunction = _isNativeFunction;
521
522	function _wrapNativeSuper(Class) {
523		var _cache = typeof Map === "function" ? new Map() : undefined;
524
525		babelHelpers.wrapNativeSuper = _wrapNativeSuper = function _wrapNativeSuper(Class) {
526			if (Class === null || !babelHelpers.isNativeFunction(Class)) return Class;
527
528			if (typeof Class !== "function") {
529				throw new TypeError("Super expression must either be null or a function");
530			}
531
532			if (typeof _cache !== "undefined") {
533				if (_cache.has(Class)) return _cache.get(Class);
534
535				_cache.set(Class, Wrapper);
536			}
537
538			function Wrapper() {
539				return babelHelpers.construct(Class, arguments, babelHelpers.getPrototypeOf(this).constructor);
540			}
541
542			Wrapper.prototype = Object.create(Class.prototype, {
543				constructor: {
544					value: Wrapper,
545					enumerable: false,
546					writable: true,
547					configurable: true
548				}
549			});
550			return babelHelpers.setPrototypeOf(Wrapper, Class);
551		};
552
553		return _wrapNativeSuper(Class);
554	}
555
556	babelHelpers.wrapNativeSuper = _wrapNativeSuper;
557
558	function _instanceof(left, right) {
559		if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
560			return right[Symbol.hasInstance](left);
561		} else {
562			return left instanceof right;
563		}
564	}
565
566	babelHelpers.instanceof = _instanceof;
567
568	function _interopRequireDefault(obj) {
569		return obj && obj.__esModule ? obj : {
570			default: obj
571		};
572	}
573
574	babelHelpers.interopRequireDefault = _interopRequireDefault;
575
576	function _interopRequireWildcard(obj) {
577		if (obj && obj.__esModule) {
578			return obj;
579		} else {
580			var newObj = {};
581
582			if (obj != null) {
583				for (var key in obj) {
584					if (Object.prototype.hasOwnProperty.call(obj, key)) {
585						var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {};
586
587						if (desc.get || desc.set) {
588							Object.defineProperty(newObj, key, desc);
589						} else {
590							newObj[key] = obj[key];
591						}
592					}
593				}
594			}
595
596			newObj.default = obj;
597			return newObj;
598		}
599	}
600
601	babelHelpers.interopRequireWildcard = _interopRequireWildcard;
602
603	function _newArrowCheck(innerThis, boundThis) {
604		if (innerThis !== boundThis) {
605			throw new TypeError("Cannot instantiate an arrow function");
606		}
607	}
608
609	babelHelpers.newArrowCheck = _newArrowCheck;
610
611	function _objectDestructuringEmpty(obj) {
612		if (obj == null) throw new TypeError("Cannot destructure undefined");
613	}
614
615	babelHelpers.objectDestructuringEmpty = _objectDestructuringEmpty;
616
617	function _objectWithoutPropertiesLoose(source, excluded) {
618		if (source == null) return {};
619		var target = {};
620		var sourceKeys = Object.keys(source);
621		var key, i;
622
623		for (i = 0; i < sourceKeys.length; i++) {
624			key = sourceKeys[i];
625			if (excluded.indexOf(key) >= 0) continue;
626			target[key] = source[key];
627		}
628
629		return target;
630	}
631
632	babelHelpers.objectWithoutPropertiesLoose = _objectWithoutPropertiesLoose;
633
634	function _objectWithoutProperties(source, excluded) {
635		if (source == null) return {};
636		var target = babelHelpers.objectWithoutPropertiesLoose(source, excluded);
637		var key, i;
638
639		if (Object.getOwnPropertySymbols) {
640			var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
641
642			for (i = 0; i < sourceSymbolKeys.length; i++) {
643				key = sourceSymbolKeys[i];
644				if (excluded.indexOf(key) >= 0) continue;
645				if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
646				target[key] = source[key];
647			}
648		}
649
650		return target;
651	}
652
653	babelHelpers.objectWithoutProperties = _objectWithoutProperties;
654
655	function _assertThisInitialized(self) {
656		if (self === void 0) {
657			throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
658		}
659
660		return self;
661	}
662
663	babelHelpers.assertThisInitialized = _assertThisInitialized;
664
665	function _possibleConstructorReturn(self, call) {
666		if (call && (typeof call === "object" || typeof call === "function")) {
667			return call;
668		}
669
670		return babelHelpers.assertThisInitialized(self);
671	}
672
673	babelHelpers.possibleConstructorReturn = _possibleConstructorReturn;
674
675	function _superPropBase(object, property) {
676		while (!Object.prototype.hasOwnProperty.call(object, property)) {
677			object = babelHelpers.getPrototypeOf(object);
678			if (object === null) break;
679		}
680
681		return object;
682	}
683
684	babelHelpers.superPropBase = _superPropBase;
685
686	function _get(target, property, receiver) {
687		if (typeof Reflect !== "undefined" && Reflect.get) {
688			babelHelpers.get = _get = Reflect.get;
689		} else {
690			babelHelpers.get = _get = function _get(target, property, receiver) {
691				var base = babelHelpers.superPropBase(target, property);
692				if (!base) return;
693				var desc = Object.getOwnPropertyDescriptor(base, property);
694
695				if (desc.get) {
696					return desc.get.call(receiver);
697				}
698
699				return desc.value;
700			};
701		}
702
703		return _get(target, property, receiver || target);
704	}
705
706	babelHelpers.get = _get;
707
708	function set(target, property, value, receiver) {
709		if (typeof Reflect !== "undefined" && Reflect.set) {
710			set = Reflect.set;
711		} else {
712			set = function set(target, property, value, receiver) {
713				var base = babelHelpers.superPropBase(target, property);
714				var desc;
715
716				if (base) {
717					desc = Object.getOwnPropertyDescriptor(base, property);
718
719					if (desc.set) {
720						desc.set.call(receiver, value);
721						return true;
722					} else if (!desc.writable) {
723						return false;
724					}
725				}
726
727				desc = Object.getOwnPropertyDescriptor(receiver, property);
728
729				if (desc) {
730					if (!desc.writable) {
731						return false;
732					}
733
734					desc.value = value;
735					Object.defineProperty(receiver, property, desc);
736				} else {
737					babelHelpers.defineProperty(receiver, property, value);
738				}
739
740				return true;
741			};
742		}
743
744		return set(target, property, value, receiver);
745	}
746
747	function _set(target, property, value, receiver, isStrict) {
748		var s = set(target, property, value, receiver || target);
749
750		if (!s && isStrict) {
751			throw new Error('failed to set property');
752		}
753
754		return value;
755	}
756
757	babelHelpers.set = _set;
758
759	function _taggedTemplateLiteral(strings, raw) {
760		if (!raw) {
761			raw = strings.slice(0);
762		}
763
764		return Object.freeze(Object.defineProperties(strings, {
765			raw: {
766				value: Object.freeze(raw)
767			}
768		}));
769	}
770
771	babelHelpers.taggedTemplateLiteral = _taggedTemplateLiteral;
772
773	function _taggedTemplateLiteralLoose(strings, raw) {
774		if (!raw) {
775			raw = strings.slice(0);
776		}
777
778		strings.raw = raw;
779		return strings;
780	}
781
782	babelHelpers.taggedTemplateLiteralLoose = _taggedTemplateLiteralLoose;
783
784	function _temporalRef(val, name) {
785		if (val === babelHelpers.temporalUndefined) {
786			throw new ReferenceError(name + " is not defined - temporal dead zone");
787		} else {
788			return val;
789		}
790	}
791
792	babelHelpers.temporalRef = _temporalRef;
793
794	function _readOnlyError(name) {
795		throw new Error("\"" + name + "\" is read-only");
796	}
797
798	babelHelpers.readOnlyError = _readOnlyError;
799
800	function _classNameTDZError(name) {
801		throw new Error("Class \"" + name + "\" cannot be referenced in computed property keys.");
802	}
803
804	babelHelpers.classNameTDZError = _classNameTDZError;
805	babelHelpers.temporalUndefined = {};
806
807	function _slicedToArray(arr, i) {
808		return babelHelpers.arrayWithHoles(arr) || babelHelpers.iterableToArrayLimit(arr, i) || babelHelpers.nonIterableRest();
809	}
810
811	babelHelpers.slicedToArray = _slicedToArray;
812
813	function _slicedToArrayLoose(arr, i) {
814		return babelHelpers.arrayWithHoles(arr) || babelHelpers.iterableToArrayLimitLoose(arr, i) || babelHelpers.nonIterableRest();
815	}
816
817	babelHelpers.slicedToArrayLoose = _slicedToArrayLoose;
818
819	function _toArray(arr) {
820		return babelHelpers.arrayWithHoles(arr) || babelHelpers.iterableToArray(arr) || babelHelpers.nonIterableRest();
821	}
822
823	babelHelpers.toArray = _toArray;
824
825	function _toConsumableArray(arr) {
826		return babelHelpers.arrayWithoutHoles(arr) || babelHelpers.iterableToArray(arr) || babelHelpers.nonIterableSpread();
827	}
828
829	babelHelpers.toConsumableArray = _toConsumableArray;
830
831	function _arrayWithoutHoles(arr) {
832		if (Array.isArray(arr)) {
833			for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];
834
835			return arr2;
836		}
837	}
838
839	babelHelpers.arrayWithoutHoles = _arrayWithoutHoles;
840
841	function _arrayWithHoles(arr) {
842		if (Array.isArray(arr)) return arr;
843	}
844
845	babelHelpers.arrayWithHoles = _arrayWithHoles;
846
847	function _iterableToArray(iter) {
848		if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter);
849	}
850
851	babelHelpers.iterableToArray = _iterableToArray;
852
853	function _iterableToArrayLimit(arr, i) {
854		var _arr = [];
855		var _n = true;
856		var _d = false;
857		var _e = undefined;
858
859		try {
860			for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
861				_arr.push(_s.value);
862
863				if (i && _arr.length === i) break;
864			}
865		} catch (err) {
866			_d = true;
867			_e = err;
868		} finally {
869			try {
870				if (!_n && _i["return"] != null) _i["return"]();
871			} finally {
872				if (_d) throw _e;
873			}
874		}
875
876		return _arr;
877	}
878
879	babelHelpers.iterableToArrayLimit = _iterableToArrayLimit;
880
881	function _iterableToArrayLimitLoose(arr, i) {
882		var _arr = [];
883
884		for (var _iterator = arr[Symbol.iterator](), _step; !(_step = _iterator.next()).done;) {
885			_arr.push(_step.value);
886
887			if (i && _arr.length === i) break;
888		}
889
890		return _arr;
891	}
892
893	babelHelpers.iterableToArrayLimitLoose = _iterableToArrayLimitLoose;
894
895	function _nonIterableSpread() {
896		throw new TypeError("Invalid attempt to spread non-iterable instance");
897	}
898
899	babelHelpers.nonIterableSpread = _nonIterableSpread;
900
901	function _nonIterableRest() {
902		throw new TypeError("Invalid attempt to destructure non-iterable instance");
903	}
904
905	babelHelpers.nonIterableRest = _nonIterableRest;
906
907	function _skipFirstGeneratorNext(fn) {
908		return function () {
909			var it = fn.apply(this, arguments);
910			it.next();
911			return it;
912		};
913	}
914
915	babelHelpers.skipFirstGeneratorNext = _skipFirstGeneratorNext;
916
917	function _toPropertyKey(key) {
918		if (typeof key === "symbol") {
919			return key;
920		} else {
921			return String(key);
922		}
923	}
924
925	babelHelpers.toPropertyKey = _toPropertyKey;
926
927	function _initializerWarningHelper(descriptor, context) {
928		throw new Error('Decorating class property failed. Please ensure that ' + 'proposal-class-properties is enabled and set to use loose mode. ' + 'To use proposal-class-properties in spec mode with decorators, wait for ' + 'the next major version of decorators in stage 2.');
929	}
930
931	babelHelpers.initializerWarningHelper = _initializerWarningHelper;
932
933	function _initializerDefineProperty(target, property, descriptor, context) {
934		if (!descriptor) return;
935		Object.defineProperty(target, property, {
936			enumerable: descriptor.enumerable,
937			configurable: descriptor.configurable,
938			writable: descriptor.writable,
939			value: descriptor.initializer ? descriptor.initializer.call(context) : void 0
940		});
941	}
942
943	babelHelpers.initializerDefineProperty = _initializerDefineProperty;
944
945	function _applyDecoratedDescriptor(target, property, decorators, descriptor, context) {
946		var desc = {};
947		Object['ke' + 'ys'](descriptor).forEach(function (key) {
948			desc[key] = descriptor[key];
949		});
950		desc.enumerable = !!desc.enumerable;
951		desc.configurable = !!desc.configurable;
952
953		if ('value' in desc || desc.initializer) {
954			desc.writable = true;
955		}
956
957		desc = decorators.slice().reverse().reduce(function (desc, decorator) {
958			return decorator(target, property, desc) || desc;
959		}, desc);
960
961		if (context && desc.initializer !== void 0) {
962			desc.value = desc.initializer ? desc.initializer.call(context) : void 0;
963			desc.initializer = undefined;
964		}
965
966		if (desc.initializer === void 0) {
967			Object['define' + 'Property'](target, property, desc);
968			desc = null;
969		}
970
971		return desc;
972	}
973
974	babelHelpers.applyDecoratedDescriptor = _applyDecoratedDescriptor;
975	var id = 0;
976
977	function _classPrivateFieldKey(name) {
978		return "__private_" + id++ + "_" + name;
979	}
980
981	babelHelpers.classPrivateFieldLooseKey = _classPrivateFieldKey;
982
983	function _classPrivateFieldBase(receiver, privateKey) {
984		if (!Object.prototype.hasOwnProperty.call(receiver, privateKey)) {
985			throw new TypeError("attempted to use private field on non-instance");
986		}
987
988		return receiver;
989	}
990
991	babelHelpers.classPrivateFieldLooseBase = _classPrivateFieldBase;
992
993	function _classPrivateFieldGet(receiver, privateMap) {
994		if (!privateMap.has(receiver)) {
995			throw new TypeError("attempted to get private field on non-instance");
996		}
997
998		return privateMap.get(receiver).value;
999	}
1000
1001	babelHelpers.classPrivateFieldGet = _classPrivateFieldGet;
1002
1003	function _classPrivateFieldSet(receiver, privateMap, value) {
1004		if (!privateMap.has(receiver)) {
1005			throw new TypeError("attempted to set private field on non-instance");
1006		}
1007
1008		var descriptor = privateMap.get(receiver);
1009
1010		if (!descriptor.writable) {
1011			throw new TypeError("attempted to set read only private field");
1012		}
1013
1014		descriptor.value = value;
1015		return value;
1016	}
1017
1018	babelHelpers.classPrivateFieldSet = _classPrivateFieldSet;
1019})(typeof global === "undefined" ? window : global);
1020
1021/**
1022 * Copyright (c) 2014-present, Facebook, Inc.
1023 *
1024 * This source code is licensed under the MIT license found in the
1025 * LICENSE file in the root directory of this source tree.
1026 */
1027
1028!(function(global) {
1029	"use strict";
1030
1031	var Op = Object.prototype;
1032	var hasOwn = Op.hasOwnProperty;
1033	var undefined; // More compressible than void 0.
1034	var $Symbol = typeof Symbol === "function" ? Symbol : {};
1035	var iteratorSymbol = $Symbol.iterator || "@@iterator";
1036	var asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator";
1037	var toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag";
1038
1039	// Define the runtime globally (as expected by generated code) as either
1040	// module.exports (if we're in a module) or a new, empty object.
1041	var runtime = global.regeneratorRuntime = {};
1042
1043	function wrap(innerFn, outerFn, self, tryLocsList) {
1044		// If outerFn provided and outerFn.prototype is a Generator, then outerFn.prototype instanceof Generator.
1045		var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator;
1046		var generator = Object.create(protoGenerator.prototype);
1047		var context = new Context(tryLocsList || []);
1048
1049		// The ._invoke method unifies the implementations of the .next,
1050		// .throw, and .return methods.
1051		generator._invoke = makeInvokeMethod(innerFn, self, context);
1052
1053		return generator;
1054	}
1055	runtime.wrap = wrap;
1056
1057	// Try/catch helper to minimize deoptimizations. Returns a completion
1058	// record like context.tryEntries[i].completion. This interface could
vendor: 10,591 bytes, lines 1059-1352
1059	// have been (and was previously) designed to take a closure to be
1060	// invoked without arguments, but in all the cases we care about we
1061	// already have an existing method we want to call, so there's no need
1062	// to create a new function object. We can even get away with assuming
1063	// the method takes exactly one argument, since that happens to be true
1064	// in every case, so we don't have to touch the arguments object. The
1065	// only additional allocation required is the completion record, which
1066	// has a stable shape and so hopefully should be cheap to allocate.
1067	function tryCatch(fn, obj, arg) {
1068		try {
1069			return { type: "normal", arg: fn.call(obj, arg) };
1070		} catch (err) {
1071			return { type: "throw", arg: err };
1072		}
1073	}
1074
1075	var GenStateSuspendedStart = "suspendedStart";
1076	var GenStateSuspendedYield = "suspendedYield";
1077	var GenStateExecuting = "executing";
1078	var GenStateCompleted = "completed";
1079
1080	// Returning this object from the innerFn has the same effect as
1081	// breaking out of the dispatch switch statement.
1082	var ContinueSentinel = {};
1083
1084	// Dummy constructor functions that we use as the .constructor and
1085	// .constructor.prototype properties for functions that return Generator
1086	// objects. For full spec compliance, you may wish to configure your
1087	// minifier not to mangle the names of these two functions.
1088	function Generator() {}
1089	function GeneratorFunction() {}
1090	function GeneratorFunctionPrototype() {}
1091
1092	// This is a polyfill for %IteratorPrototype% for environments that
1093	// don't natively support it.
1094	var IteratorPrototype = {};
1095	IteratorPrototype[iteratorSymbol] = function () {
1096		return this;
1097	};
1098
1099	var getProto = Object.getPrototypeOf;
1100	var NativeIteratorPrototype = getProto && getProto(getProto(values([])));
1101	if (NativeIteratorPrototype &&
1102		NativeIteratorPrototype !== Op &&
1103		hasOwn.call(NativeIteratorPrototype, iteratorSymbol)) {
1104		// This environment has a native %IteratorPrototype%; use it instead
1105		// of the polyfill.
1106		IteratorPrototype = NativeIteratorPrototype;
1107	}
1108
1109	var Gp = GeneratorFunctionPrototype.prototype =
1110		Generator.prototype = Object.create(IteratorPrototype);
1111	GeneratorFunction.prototype = Gp.constructor = GeneratorFunctionPrototype;
1112	GeneratorFunctionPrototype.constructor = GeneratorFunction;
1113	GeneratorFunctionPrototype[toStringTagSymbol] =
1114		GeneratorFunction.displayName = "GeneratorFunction";
1115
1116	// Helper for defining the .next, .throw, and .return methods of the
1117	// Iterator interface in terms of a single ._invoke method.
1118	function defineIteratorMethods(prototype) {
1119		["next", "throw", "return"].forEach(function(method) {
1120			prototype[method] = function(arg) {
1121				return this._invoke(method, arg);
1122			};
1123		});
1124	}
1125
1126	runtime.isGeneratorFunction = function(genFun) {
1127		var ctor = typeof genFun === "function" && genFun.constructor;
1128		return ctor
1129			? ctor === GeneratorFunction ||
1130			// For the native GeneratorFunction constructor, the best we can
1131			// do is to check its .name property.
1132			(ctor.displayName || ctor.name) === "GeneratorFunction"
1133			: false;
1134	};
1135
1136	runtime.mark = function(genFun) {
1137		if (Object.setPrototypeOf) {
1138			Object.setPrototypeOf(genFun, GeneratorFunctionPrototype);
1139		} else {
1140			genFun.__proto__ = GeneratorFunctionPrototype;
1141			if (!(toStringTagSymbol in genFun)) {
1142				genFun[toStringTagSymbol] = "GeneratorFunction";
1143			}
1144		}
1145		genFun.prototype = Object.create(Gp);
1146		return genFun;
1147	};
1148
1149	// Within the body of any async function, `await x` is transformed to
1150	// `yield regeneratorRuntime.awrap(x)`, so that the runtime can test
1151	// `hasOwn.call(value, "__await")` to determine if the yielded value is
1152	// meant to be awaited.
1153	runtime.awrap = function(arg) {
1154		return { __await: arg };
1155	};
1156
1157	function AsyncIterator(generator) {
1158		function invoke(method, arg, resolve, reject) {
1159			var record = tryCatch(generator[method], generator, arg);
1160			if (record.type === "throw") {
1161				reject(record.arg);
1162			} else {
1163				var result = record.arg;
1164				var value = result.value;
1165				if (value &&
1166					typeof value === "object" &&
1167					hasOwn.call(value, "__await")) {
1168					return Promise.resolve(value.__await).then(function(value) {
1169						invoke("next", value, resolve, reject);
1170					}, function(err) {
1171						invoke("throw", err, resolve, reject);
1172					});
1173				}
1174
1175				return Promise.resolve(value).then(function(unwrapped) {
1176					// When a yielded Promise is resolved, its final value becomes
1177					// the .value of the Promise<{value,done}> result for the
1178					// current iteration. If the Promise is rejected, however, the
1179					// result for this iteration will be rejected with the same
1180					// reason. Note that rejections of yielded Promises are not
1181					// thrown back into the generator function, as is the case
1182					// when an awaited Promise is rejected. This difference in
1183					// behavior between yield and await is important, because it
1184					// allows the consumer to decide what to do with the yielded
1185					// rejection (swallow it and continue, manually .throw it back
1186					// into the generator, abandon iteration, whatever). With
1187					// await, by contrast, there is no opportunity to examine the
1188					// rejection reason outside the generator function, so the
1189					// only option is to throw it from the await expression, and
1190					// let the generator function handle the exception.
1191					result.value = unwrapped;
1192					resolve(result);
1193				}, reject);
1194			}
1195		}
1196
1197		var previousPromise;
1198
1199		function enqueue(method, arg) {
1200			function callInvokeWithMethodAndArg() {
1201				return new Promise(function(resolve, reject) {
1202					invoke(method, arg, resolve, reject);
1203				});
1204			}
1205
1206			return previousPromise =
1207				// If enqueue has been called before, then we want to wait until
1208				// all previous Promises have been resolved before calling invoke,
1209				// so that results are always delivered in the correct order. If
1210				// enqueue has not been called before, then it is important to
1211				// call invoke immediately, without waiting on a callback to fire,
1212				// so that the async generator function has the opportunity to do
1213				// any necessary setup in a predictable way. This predictability
1214				// is why the Promise constructor synchronously invokes its
1215				// executor callback, and why async functions synchronously
1216				// execute code before the first await. Since we implement simple
1217				// async functions in terms of async generators, it is especially
1218				// important to get this right, even though it requires care.
1219				previousPromise ? previousPromise.then(
1220					callInvokeWithMethodAndArg,
1221					// Avoid propagating failures to Promises returned by later
1222					// invocations of the iterator.
1223					callInvokeWithMethodAndArg
1224				) : callInvokeWithMethodAndArg();
1225		}
1226
1227		// Define the unified helper method that is used to implement .next,
1228		// .throw, and .return (see defineIteratorMethods).
1229		this._invoke = enqueue;
1230	}
1231
1232	defineIteratorMethods(AsyncIterator.prototype);
1233	AsyncIterator.prototype[asyncIteratorSymbol] = function () {
1234		return this;
1235	};
1236	runtime.AsyncIterator = AsyncIterator;
1237
1238	// Note that simple async functions are implemented on top of
1239	// AsyncIterator objects; they just return a Promise for the value of
1240	// the final result produced by the iterator.
1241	runtime.async = function(innerFn, outerFn, self, tryLocsList) {
1242		var iter = new AsyncIterator(
1243			wrap(innerFn, outerFn, self, tryLocsList)
1244		);
1245
1246		return runtime.isGeneratorFunction(outerFn)
1247			? iter // If outerFn is a generator, return the full iterator.
1248			: iter.next().then(function(result) {
1249				return result.done ? result.value : iter.next();
1250			});
1251	};
1252
1253	function makeInvokeMethod(innerFn, self, context) {
1254		var state = GenStateSuspendedStart;
1255
1256		return function invoke(method, arg) {
1257			if (state === GenStateExecuting) {
1258				throw new Error("Generator is already running");
1259			}
1260
1261			if (state === GenStateCompleted) {
1262				if (method === "throw") {
1263					throw arg;
1264				}
1265
1266				// Be forgiving, per 25.3.3.3.3 of the spec:
1267				// https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume
1268				return doneResult();
1269			}
1270
1271			context.method = method;
1272			context.arg = arg;
1273
1274			while (true) {
1275				var delegate = context.delegate;
1276				if (delegate) {
1277					var delegateResult = maybeInvokeDelegate(delegate, context);
1278					if (delegateResult) {
1279						if (delegateResult === ContinueSentinel) continue;
1280						return delegateResult;
1281					}
1282				}
1283
1284				if (context.method === "next") {
1285					// Setting context._sent for legacy support of Babel's
1286					// function.sent implementation.
1287					context.sent = context._sent = context.arg;
1288
1289				} else if (context.method === "throw") {
1290					if (state === GenStateSuspendedStart) {
1291						state = GenStateCompleted;
1292						throw context.arg;
1293					}
1294
1295					context.dispatchException(context.arg);
1296
1297				} else if (context.method === "return") {
1298					context.abrupt("return", context.arg);
1299				}
1300
1301				state = GenStateExecuting;
1302
1303				var record = tryCatch(innerFn, self, context);
1304				if (record.type === "normal") {
1305					// If an exception is thrown from innerFn, we leave state ===
1306					// GenStateExecuting and loop back for another invocation.
1307					state = context.done
1308						? GenStateCompleted
1309						: GenStateSuspendedYield;
1310
1311					if (record.arg === ContinueSentinel) {
1312						continue;
1313					}
1314
1315					return {
1316						value: record.arg,
1317						done: context.done
1318					};
1319
1320				} else if (record.type === "throw") {
1321					state = GenStateCompleted;
1322					// Dispatch the exception by looping back around to the
1323					// context.dispatchException(context.arg) call above.
1324					context.method = "throw";
1325					context.arg = record.arg;
1326				}
1327			}
1328		};
1329	}
1330
1331	// Call delegate.iterator[context.method](context.arg) and handle the
1332	// result, either by returning a { value, done } result from the
1333	// delegate iterator, or by modifying context.method and context.arg,
1334	// setting context.delegate to null, and returning the ContinueSentinel.
1335	function maybeInvokeDelegate(delegate, context) {
1336		var method = delegate.iterator[context.method];
1337		if (method === undefined) {
1338			// A .throw or .return when the delegate iterator has no .throw
1339			// method always terminates the yield* loop.
1340			context.delegate = null;
1341
1342			if (context.method === "throw") {
1343				if (delegate.iterator.return) {
1344					// If the delegate iterator has a return method, give it a
1345					// chance to clean up.
1346					context.method = "return";
1347					context.arg = undefined;
1348					maybeInvokeDelegate(delegate, context);
1349
1350					if (context.method === "throw") {
1351						// If maybeInvokeDelegate(context) changed context.method from
1352						// "return" to "throw", let that override the TypeError below.
vendor: 4,172 bytes, lines 1353-1506
1353						return ContinueSentinel;
1354					}
1355				}
1356
1357				context.method = "throw";
1358				context.arg = new TypeError(
1359					"The iterator does not provide a 'throw' method");
1360			}
1361
1362			return ContinueSentinel;
1363		}
1364
1365		var record = tryCatch(method, delegate.iterator, context.arg);
1366
1367		if (record.type === "throw") {
1368			context.method = "throw";
1369			context.arg = record.arg;
1370			context.delegate = null;
1371			return ContinueSentinel;
1372		}
1373
1374		var info = record.arg;
1375
1376		if (! info) {
1377			context.method = "throw";
1378			context.arg = new TypeError("iterator result is not an object");
1379			context.delegate = null;
1380			return ContinueSentinel;
1381		}
1382
1383		if (info.done) {
1384			// Assign the result of the finished delegate to the temporary
1385			// variable specified by delegate.resultName (see delegateYield).
1386			context[delegate.resultName] = info.value;
1387
1388			// Resume execution at the desired location (see delegateYield).
1389			context.next = delegate.nextLoc;
1390
1391			// If context.method was "throw" but the delegate handled the
1392			// exception, let the outer generator proceed normally. If
1393			// context.method was "next", forget context.arg since it has been
1394			// "consumed" by the delegate iterator. If context.method was
1395			// "return", allow the original .return call to continue in the
1396			// outer generator.
1397			if (context.method !== "return") {
1398				context.method = "next";
1399				context.arg = undefined;
1400			}
1401
1402		} else {
1403			// Re-yield the result returned by the delegate method.
1404			return info;
1405		}
1406
1407		// The delegate iterator is finished, so forget it and continue with
1408		// the outer generator.
1409		context.delegate = null;
1410		return ContinueSentinel;
1411	}
1412
1413	// Define Generator.prototype.{next,throw,return} in terms of the
1414	// unified ._invoke helper method.
1415	defineIteratorMethods(Gp);
1416
1417	Gp[toStringTagSymbol] = "Generator";
1418
1419	// A Generator should always return itself as the iterator object when the
1420	// @@iterator function is called on it. Some browsers' implementations of the
1421	// iterator prototype chain incorrectly implement this, causing the Generator
1422	// object to not be returned from this call. This ensures that doesn't happen.
1423	// See https://github.com/facebook/regenerator/issues/274 for more details.
1424	Gp[iteratorSymbol] = function() {
1425		return this;
1426	};
1427
1428	Gp.toString = function() {
1429		return "[object Generator]";
1430	};
1431
1432	function pushTryEntry(locs) {
1433		var entry = { tryLoc: locs[0] };
1434
1435		if (1 in locs) {
1436			entry.catchLoc = locs[1];
1437		}
1438
1439		if (2 in locs) {
1440			entry.finallyLoc = locs[2];
1441			entry.afterLoc = locs[3];
1442		}
1443
1444		this.tryEntries.push(entry);
1445	}
1446
1447	function resetTryEntry(entry) {
1448		var record = entry.completion || {};
1449		record.type = "normal";
1450		delete record.arg;
1451		entry.completion = record;
1452	}
1453
1454	function Context(tryLocsList) {
1455		// The root entry object (effectively a try statement without a catch
1456		// or a finally block) gives us a place to store values thrown from
1457		// locations where there is no enclosing try statement.
1458		this.tryEntries = [{ tryLoc: "root" }];
1459		tryLocsList.forEach(pushTryEntry, this);
1460		this.reset(true);
1461	}
1462
1463	runtime.keys = function(object) {
1464		var keys = [];
1465		for (var key in object) {
1466			keys.push(key);
1467		}
1468		keys.reverse();
1469
1470		// Rather than returning an object with a next method, we keep
1471		// things simple and return the next function itself.
1472		return function next() {
1473			while (keys.length) {
1474				var key = keys.pop();
1475				if (key in object) {
1476					next.value = key;
1477					next.done = false;
1478					return next;
1479				}
1480			}
1481
1482			// To avoid creating an additional object, we just hang the .value
1483			// and .done properties off the next function object itself. This
1484			// also ensures that the minifier will not anonymize the function.
1485			next.done = true;
1486			return next;
1487		};
1488	};
1489
1490	function values(iterable) {
1491		if (iterable) {
1492			var iteratorMethod = iterable[iteratorSymbol];
1493			if (iteratorMethod) {
1494				return iteratorMethod.call(iterable);
1495			}
1496
1497			if (typeof iterable.next === "function") {
1498				return iterable;
1499			}
1500
1501			if (!isNaN(iterable.length)) {
1502				var i = -1, next = function next() {
1503					while (++i < iterable.length) {
1504						if (hasOwn.call(iterable, i)) {
1505							next.value = iterable[i];
1506							next.done = false;
vendor: 6,037 bytes, lines 1507-1760
1507							return next;
1508						}
1509					}
1510
1511					next.value = undefined;
1512					next.done = true;
1513
1514					return next;
1515				};
1516
1517				return next.next = next;
1518			}
1519		}
1520
1521		// Return an iterator with no values.
1522		return { next: doneResult };
1523	}
1524	runtime.values = values;
1525
1526	function doneResult() {
1527		return { value: undefined, done: true };
1528	}
1529
1530	Context.prototype = {
1531		constructor: Context,
1532
1533		reset: function(skipTempReset) {
1534			this.prev = 0;
1535			this.next = 0;
1536			// Resetting context._sent for legacy support of Babel's
1537			// function.sent implementation.
1538			this.sent = this._sent = undefined;
1539			this.done = false;
1540			this.delegate = null;
1541
1542			this.method = "next";
1543			this.arg = undefined;
1544
1545			this.tryEntries.forEach(resetTryEntry);
1546
1547			if (!skipTempReset) {
1548				for (var name in this) {
1549					// Not sure about the optimal order of these conditions:
1550					if (name.charAt(0) === "t" &&
1551						hasOwn.call(this, name) &&
1552						!isNaN(+name.slice(1))) {
1553						this[name] = undefined;
1554					}
1555				}
1556			}
1557		},
1558
1559		stop: function() {
1560			this.done = true;
1561
1562			var rootEntry = this.tryEntries[0];
1563			var rootRecord = rootEntry.completion;
1564			if (rootRecord.type === "throw") {
1565				throw rootRecord.arg;
1566			}
1567
1568			return this.rval;
1569		},
1570
1571		dispatchException: function(exception) {
1572			if (this.done) {
1573				throw exception;
1574			}
1575
1576			var context = this;
1577			function handle(loc, caught) {
1578				record.type = "throw";
1579				record.arg = exception;
1580				context.next = loc;
1581
1582				if (caught) {
1583					// If the dispatched exception was caught by a catch block,
1584					// then let that catch block handle the exception normally.
1585					context.method = "next";
1586					context.arg = undefined;
1587				}
1588
1589				return !! caught;
1590			}
1591
1592			for (var i = this.tryEntries.length - 1; i >= 0; --i) {
1593				var entry = this.tryEntries[i];
1594				var record = entry.completion;
1595
1596				if (entry.tryLoc === "root") {
1597					// Exception thrown outside of any try block that could handle
1598					// it, so set the completion value of the entire function to
1599					// throw the exception.
1600					return handle("end");
1601				}
1602
1603				if (entry.tryLoc <= this.prev) {
1604					var hasCatch = hasOwn.call(entry, "catchLoc");
1605					var hasFinally = hasOwn.call(entry, "finallyLoc");
1606
1607					if (hasCatch && hasFinally) {
1608						if (this.prev < entry.catchLoc) {
1609							return handle(entry.catchLoc, true);
1610						} else if (this.prev < entry.finallyLoc) {
1611							return handle(entry.finallyLoc);
1612						}
1613
1614					} else if (hasCatch) {
1615						if (this.prev < entry.catchLoc) {
1616							return handle(entry.catchLoc, true);
1617						}
1618
1619					} else if (hasFinally) {
1620						if (this.prev < entry.finallyLoc) {
1621							return handle(entry.finallyLoc);
1622						}
1623
1624					} else {
1625						throw new Error("try statement without catch or finally");
1626					}
1627				}
1628			}
1629		},
1630
1631		abrupt: function(type, arg) {
1632			for (var i = this.tryEntries.length - 1; i >= 0; --i) {
1633				var entry = this.tryEntries[i];
1634				if (entry.tryLoc <= this.prev &&
1635					hasOwn.call(entry, "finallyLoc") &&
1636					this.prev < entry.finallyLoc) {
1637					var finallyEntry = entry;
1638					break;
1639				}
1640			}
1641
1642			if (finallyEntry &&
1643				(type === "break" ||
1644					type === "continue") &&
1645				finallyEntry.tryLoc <= arg &&
1646				arg <= finallyEntry.finallyLoc) {
1647				// Ignore the finally entry if control is not jumping to a
1648				// location outside the try/catch block.
1649				finallyEntry = null;
1650			}
1651
1652			var record = finallyEntry ? finallyEntry.completion : {};
1653			record.type = type;
1654			record.arg = arg;
1655
1656			if (finallyEntry) {
1657				this.method = "next";
1658				this.next = finallyEntry.finallyLoc;
1659				return ContinueSentinel;
1660			}
1661
1662			return this.complete(record);
1663		},
1664
1665		complete: function(record, afterLoc) {
1666			if (record.type === "throw") {
1667				throw record.arg;
1668			}
1669
1670			if (record.type === "break" ||
1671				record.type === "continue") {
1672				this.next = record.arg;
1673			} else if (record.type === "return") {
1674				this.rval = this.arg = record.arg;
1675				this.method = "return";
1676				this.next = "end";
1677			} else if (record.type === "normal" && afterLoc) {
1678				this.next = afterLoc;
1679			}
1680
1681			return ContinueSentinel;
1682		},
1683
1684		finish: function(finallyLoc) {
1685			for (var i = this.tryEntries.length - 1; i >= 0; --i) {
1686				var entry = this.tryEntries[i];
1687				if (entry.finallyLoc === finallyLoc) {
1688					this.complete(entry.completion, entry.afterLoc);
1689					resetTryEntry(entry);
1690					return ContinueSentinel;
1691				}
1692			}
1693		},
1694
1695		"catch": function(tryLoc) {
1696			for (var i = this.tryEntries.length - 1; i >= 0; --i) {
1697				var entry = this.tryEntries[i];
1698				if (entry.tryLoc === tryLoc) {
1699					var record = entry.completion;
1700					if (record.type === "throw") {
1701						var thrown = record.arg;
1702						resetTryEntry(entry);
1703					}
1704					return thrown;
1705				}
1706			}
1707
1708			// The context.catch method must only be called with a location
1709			// argument that corresponds to a known catch block.
1710			throw new Error("illegal catch attempt");
1711		},
1712
1713		delegateYield: function(iterable, resultName, nextLoc) {
1714			this.delegate = {
1715				iterator: values(iterable),
1716				resultName: resultName,
1717				nextLoc: nextLoc
1718			};
1719
1720			if (this.method === "next") {
1721				// Deliberately forget the last sent value so that we don't
1722				// accidentally pass it on to the delegate.
1723				this.arg = undefined;
1724			}
1725
1726			return ContinueSentinel;
1727		}
1728	};
1729})(
1730	// In sloppy mode, unbound `this` refers to the global object, fallback to
1731	// Function constructor if we're in global strict mode. That is sadly a form
1732	// of indirect eval which violates Content Security Policy.
1733	(function() { return this })() || Function("return this")()
1734);
1735
1736if (window._main_polyfill_core)
1737{
1738	console.warn('main.polyfill.core is loaded more than once on this page');
1739}
1740
1741window._main_polyfill_core = true;
1742
1743
1744(function (exports) {
1745	'use strict';
1746
1747	const bxTmp = window.BX;
1748	window.BX = function (node) {
1749		if (window.BX.type.isNotEmptyString(node)) {
1750			return document.getElementById(node);
1751		}
1752		if (window.BX.type.isDomNode(node)) {
1753			return node;
1754		}
1755		if (window.BX.type.isFunction(node)) {
1756			return window.BX.ready(node);
1757		}
1758		return null;
1759	};
1760	if (bxTmp) {
1761		Object.keys(bxTmp).forEach(key => {
1762			window.BX[key] = bxTmp[key];
1763		});
1764	}
1765	exports = window.BX;
1766
1767	function getTag(value) {
1768		return Object.prototype.toString.call(value);
1769	}
1770
1771	const objectCtorString = Function.prototype.toString.call(Object);
1772	class Type {
1773		static isString(value) {
1774			return typeof value === 'string';
1775		}
1776		static isStringFilled(value) {
1777			return Type.isString(value) && value !== '';
1778		}
1779		static isFunction(value) {
1780			return typeof value === 'function';
1781		}
1782		static isObject(value) {
1783			return Boolean(value) && (typeof value === 'object' || typeof value === 'function');
1784		}
1785		static isObjectLike(value) {
1786			return Boolean(value) && typeof value === 'object';
1787		}
1788		static isPlainObject(value) {
1789			if (!Type.isObjectLike(value) || getTag(value) !== '[object Object]') {
1790				return false;
1791			}
1792			const proto = Object.getPrototypeOf(value);
1793			if (proto === null) {
1794				return true;
1795			}
1796			const ctor = proto.hasOwnProperty('constructor') && proto.constructor;
1797			return typeof ctor === 'function' && Function.prototype.toString.call(ctor) === objectCtorString;
1798		}
1799		static isBoolean(value) {
1800			return value === true || value === false;
1801		}
1802		static isNumber(value) {
1803			return !Number.isNaN(value) && typeof value === 'number';
1804		}
1805		static isInteger(value) {
1806			return Type.isNumber(value) && value % 1 === 0;
1807		}
1808		static isFloat(value) {
1809			return Type.isNumber(value) && !Type.isInteger(value);
1810		}
1811		static isNil(value) {
1812			return value === null || value === undefined;
1813		}
1814		static isArray(value) {
1815			return !Type.isNil(value) && Array.isArray(value);
1816		}
1817		static isArrayFilled(value) {
1818			return Type.isArray(value) && value.length > 0;
1819		}
1820		static isArrayLike(value) {
1821			if (Type.isNil(value) || Type.isFunction(value) || !('length' in value)) {
1822				return false;
1823			}
1824			const {
1825				length
1826			} = value;
1827			return Type.isNumber(length) && length > -1 && length <= Number.MAX_SAFE_INTEGER;
1828		}
1829		static isDate(value) {
1830			return Type.isObjectLike(value) && getTag(value) === '[object Date]';
1831		}
1832		static isDomNode(value) {
1833			return Type.isObjectLike(value) && !Type.isPlainObject(value) && 'nodeType' in value;
1834		}
1835		static isElementNode(value) {
1836			return Type.isDomNode(value) && value.nodeType === Node.ELEMENT_NODE;
1837		}
1838		static isEventTargetLike(value) {
1839			return Type.isObjectLike(value) && Type.isFunction(value.addEventListener) && Type.isFunction(value.removeEventListener) && Type.isFunction(value.dispatchEvent);
1840		}
1841		static isTextNode(value) {
1842			return Type.isDomNode(value) && value.nodeType === Node.TEXT_NODE;
1843		}
1844		static isMap(value) {
1845			return Type.isObjectLike(value) && getTag(value) === '[object Map]';
1846		}
1847		static isSet(value) {
1848			return Type.isObjectLike(value) && getTag(value) === '[object Set]';
1849		}
1850		static isWeakMap(value) {
1851			return Type.isObjectLike(value) && getTag(value) === '[object WeakMap]';
1852		}
1853		static isWeakSet(value) {
1854			return Type.isObjectLike(value) && getTag(value) === '[object WeakSet]';
1855		}
1856		static isPrototype(value) {
1857			if (!Type.isObjectLike(value)) {
1858				return false;
1859			}
1860			const ctor = value.constructor;
1861			const proto = Type.isFunction(ctor) ? ctor.prototype : Object.prototype;
1862			return proto === value;
1863		}
1864		static isRegExp(value) {
1865			return Type.isObjectLike(value) && getTag(value) === '[object RegExp]';
1866		}
1867		static isNull(value) {
1868			return value === null;
1869		}
1870		static isUndefined(value) {
1871			return typeof value === 'undefined';
1872		}
1873		static isArrayBuffer(value) {
1874			return Type.isObjectLike(value) && getTag(value) === '[object ArrayBuffer]';
1875		}
1876		static isTypedArray(value) {
1877			const regExpTypedTag = /^\[object (?:Float(?:32|64)|(?:Int|Uint)(?:8|16|32)|Uint8Clamped)]$/;
1878			return Type.isObjectLike(value) && regExpTypedTag.test(getTag(value));
1879		}
1880		static isBlob(value) {
1881			return Type.isObjectLike(value) && Type.isNumber(value.size) && Type.isString(value.type) && Type.isFunction(value.slice);
1882		}
1883		static isFile(value) {
1884			if (!Type.isBlob(value) || !('name' in value) || !Type.isString(value.name)) {
1885				return false;
1886			}
1887			if ('lastModified' in value && Type.isNumber(value.lastModified)) {
1888				return true;
1889			}
1890			return 'lastModifiedDate' in value && Type.isObjectLike(value.lastModifiedDate);
1891		}
1892		static isFormData(value) {
1893			return value instanceof FormData;
1894		}
1895		static isJsonValue(value) {
1896			return Type.isPlainObject(value) || Type.isString(value) || Type.isNumber(value) || Type.isBoolean(value) || Type.isNull(value) || Type.isArray(value);
1897		}
1898	}
1899
1900	class Reflection {
1901		static getClass(className) {
1902			if (Type.isString(className) && Boolean(className)) {
1903				let classFn = null;
1904				let currentNamespace = window;
1905				const namespaces = className.split('.');
1906				for (const namespace of namespaces) {
1907					if (!currentNamespace[namespace]) {
1908						return null;
1909					}
1910					currentNamespace = currentNamespace[namespace];
1911					classFn = currentNamespace;
1912				}
1913				return classFn;
1914			}
1915			if (Type.isFunction(className)) {
1916				return className;
1917			}
1918			return null;
1919		}
1920		static namespace(namespaceName) {
1921			let parts = namespaceName.split('.');
1922			let parent = window.BX;
1923			if (parts[0] === 'BX') {
1924				parts = parts.slice(1);
1925			}
1926			for (const part of parts) {
1927				if (Type.isUndefined(parent[part])) {
1928					parent[part] = {};
1929				}
1930				parent = parent[part];
1931			}
1932			return parent;
1933		}
1934	}
1935
1936	const reEscape = /["&'<>]/g;
1937	const reUnescape = /&(?:amp|#38|lt|#60|gt|#62|apos|#39|quot|#34);/g;
1938	const escapeEntities = {
1939		'&': '&amp;',
1940		'<': '&lt;',
1941		'>': '&gt;',
1942		"'": '&#39;',
1943		'"': '&quot;'
1944	};
1945	const unescapeEntities = {
1946		'&amp;': '&',
1947		'&#38;': '&',
1948		'&lt;': '<',
1949		'&#60;': '<',
1950		'&gt;': '>',
1951		'&#62;': '>',
1952		'&apos;': "'",
1953		'&#39;': "'",
1954		'&quot;': '"',
1955		'&#34;': '"'
1956	};
1957	class Text {
1958		static encode(value) {
1959			if (Type.isString(value)) {
1960				return value.replaceAll(reEscape, item => escapeEntities[item]);
1961			}
1962			return value;
1963		}
1964		static decode(value) {
1965			if (Type.isString(value)) {
1966				return value.replaceAll(reUnescape, item => unescapeEntities[item]);
1967			}
1968			return value;
1969		}
1970		static getRandom(length = 8) {
1971			return Array.from({
1972				length
1973			}, () => Math.trunc(Math.random() * 36).toString(36)).join('');
1974		}
1975		static toNumber(value) {
1976			const parsedValue = Number.parseFloat(String(value));
1977			if (Type.isNumber(parsedValue)) {
1978				return parsedValue;
1979			}
1980			return 0;
1981		}
1982		static toInteger(value) {
1983			return Text.toNumber(Number.parseInt(String(value), 10));
1984		}
1985		static toBoolean(value, trueValues = []) {
1986			const transformedValue = Type.isString(value) ? value.toLowerCase() : value;
1987			const truthyValues = ['true', 'y', '1', 1, true, ...trueValues];
1988			return truthyValues.includes(transformedValue);
1989		}
1990		static toCamelCase(str) {
1991			if (!Type.isStringFilled(str)) {
1992				return str;
1993			}
1994			const regex = /[\s_-]+(.)?/g;
1995			if (!regex.test(str)) {
1996				return /^[A-Z]+$/.test(str) ? str.toLowerCase() : str[0].toLowerCase() + str.slice(1);
1997			}
1998			const result = str.toLowerCase().replaceAll(regex, (match, letter) => {
1999				return letter ? letter.toUpperCase() : '';
2000			});
2001			return result[0].toLowerCase() + result.slice(1);
2002		}
2003		static toPascalCase(str) {
2004			if (!Type.isStringFilled(str)) {
2005				return str;
2006			}
2007			return this.capitalize(this.toCamelCase(str));
2008		}
2009		static toKebabCase(str) {
2010			if (!Type.isStringFilled(str)) {
2011				return str;
2012			}
2013			const matches = str.match(/[A-Z]{2,}(?=[A-Z][a-z]+\d*|\b)|[A-Z]?[a-z]+\d*|[A-Z]|\d+/g);
2014			if (!matches) {
2015				return str;
2016			}
2017			return matches.map(x => x.toLowerCase()).join('-');
2018		}
2019		static capitalize(str) {
2020			if (!Type.isStringFilled(str)) {
2021				return str;
2022			}
2023			return str[0].toUpperCase() + str.slice(1);
2024		}
2025	}
2026
2027	const aliases = {
2028		mousewheel: ['DOMMouseScroll'],
2029		bxchange: ['change', 'cut', 'paste', 'drop', 'keyup'],
2030		animationend: ['animationend', 'oAnimationEnd', 'webkitAnimationEnd', 'MSAnimationEnd'],
2031		transitionend: ['webkitTransitionEnd', 'otransitionend', 'oTransitionEnd', 'msTransitionEnd', 'transitionend'],
2032		fullscreenchange: ['fullscreenchange', 'webkitfullscreenchange', 'mozfullscreenchange', 'MSFullscreenChange'],
2033		fullscreenerror: ['fullscreenerror', 'webkitfullscreenerror', 'mozfullscreenerror', 'MSFullscreenError']
2034	};
2035
2036	class Registry {
2037		registry = new WeakMap();
2038		set(target, event, listener) {
2039			if (!Type.isEventTargetLike(target)) {
2040				return;
2041			}
2042			const events = this.get(target);
2043			if (!Type.isSet(events[event])) {
2044				events[event] = new Set();
2045			}
2046			events[event].add(listener);
2047			this.registry.set(target, events);
2048		}
2049		get(target) {
2050			return this.registry.get(target) || {};
2051		}
2052		has(target, event, listener) {
2053			if (event && listener) {
2054				const events = this.registry.get(target);
2055				return this.registry.has(target) && Boolean(events && events[event]?.has(listener));
2056			}
2057			return this.registry.has(target);
2058		}
2059		delete(target, event, listener) {
2060			if (!Type.isEventTargetLike(target)) {
2061				return;
2062			}
2063			if (Type.isString(event) && Type.isFunction(listener)) {
2064				const events = this.registry.get(target);
2065				if (Type.isPlainObject(events) && Type.isSet(events[event])) {
2066					events[event].delete(listener);
2067				}
2068				return;
2069			}
2070			if (Type.isString(event)) {
2071				const events = this.registry.get(target);
2072				if (Type.isPlainObject(events) && Type.isSet(events[event])) {
2073					events[event] = new Set();
2074				}
2075				return;
2076			}
2077			this.registry.delete(target);
2078		}
2079	}
2080	var registry = new Registry();
2081
2082	function isOptionSupported(name) {
2083		let isSupported = false;
2084		try {
2085			const options = Object.defineProperty({}, name, {
2086				get() {
2087					isSupported = true;
2088				}
2089			});
2090			window.addEventListener('test', null, options);
2091		} catch {
2092		}
2093		return isSupported;
2094	}
2095	function fetchSupportedListenerOptions(options) {
2096		if (!Type.isPlainObject(options)) {
2097			return options;
2098		}
2099		return Object.keys(options).reduce((acc, name) => {
2100			if (isOptionSupported(name)) {
2101				acc[name] = options[name];
2102			}
2103			return acc;
2104		}, {});
2105	}
2106
2107	function bind$1(target, eventName, handler, options) {
2108		if (!Type.isEventTargetLike(target) || handler === null) {
2109			return;
2110		}
2111		const listenerOptions = fetchSupportedListenerOptions(options);
2112		if (eventName in aliases) {
2113			aliases[eventName].forEach(key => {
2114				target.addEventListener(key, handler, listenerOptions);
2115				registry.set(target, eventName, handler);
2116			});
2117			return;
2118		}
2119		target.addEventListener(eventName, handler, listenerOptions);
2120		registry.set(target, eventName, handler);
2121	}
2122
2123	function unbind$1(target, eventName, handler, options) {
2124		if (!Type.isEventTargetLike(target) || handler === null) {
2125			return;
2126		}
2127		const listenerOptions = fetchSupportedListenerOptions(options);
2128		if (eventName in aliases) {
2129			aliases[eventName].forEach(key => {
2130				target.removeEventListener(key, handler, listenerOptions);
2131				registry.delete(target, key, handler);
2132			});
2133			return;
2134		}
2135		target.removeEventListener(eventName, handler, listenerOptions);
2136		registry.delete(target, eventName, handler);
2137	}
2138
2139	function unbindAll$1(target, eventName) {
2140		const events = registry.get(target);
2141		Object.keys(events).forEach(currentEvent => {
2142			events[currentEvent].forEach(handler => {
2143				if (!Type.isString(eventName) || eventName === currentEvent) {
2144					unbind$1(target, currentEvent, handler);
2145				}
2146			});
2147		});
2148	}
2149
2150	function bindOnce$1(target, eventName, handler, options) {
2151		if (handler === null) {
2152			return;
2153		}
2154		const once = function once(event) {
2155			unbind$1(target, eventName, once, options);
2156			if (Type.isFunction(handler)) {
2157				handler(event);
2158			} else if (Type.isObject(handler) && Type.isFunction(handler.handleEvent)) {
2159				handler.handleEvent(event);
2160			}
2161		};
2162		bind$1(target, eventName, once, options);
2163	}
2164
2165	let debugState = true;
2166	function enableDebug() {
2167		debugState = true;
2168	}
2169	function disableDebug() {
2170		debugState = false;
2171	}
2172	function isDebugEnabled() {
2173		return debugState;
2174	}
2175	function debug$1(...args) {
2176		if (!isDebugEnabled() || !Type.isObject(window.console)) {
2177			return;
2178		}
2179		let limit = 5;
2180		if (typeof args[args.length - 1] === 'number') {
2181			limit = args.pop();
2182		}
2183		if (Type.isFunction(window.console.log)) {
2184			window.console.log('BX.debug:', ...args);
2185			if (args[0] instanceof Error && args[0].stack) {
2186				const errorStack = args[0].stack.split('\n').slice(0, limit).join('\n');
2187				window.console.log(`BX.debug error stack trace:\n${errorStack}`);
2188			}
2189		}
2190		const stack = new Error('debug').stack;
2191		if (stack && Type.isFunction(window.console.log)) {
2192			const formattedStack = stack.split('\n').slice(1, limit + 1).join('\n');
2193			window.console.log(`BX.debug trace:\n${formattedStack}`);
2194		}
2195	}
2196
2197	var debugNs = Object.freeze({
2198		__proto__: null,
2199		get debugState () { return debugState; },
2200		default: debug$1,
2201		disableDebug: disableDebug,
2202		enableDebug: enableDebug,
2203		isDebugEnabled: isDebugEnabled
2204	});
2205
2206	const extensionsStorage = new Map();
2207
2208	const ajaxController = 'main.bitrix.main.controller.loadext.getextensions';
2209	function loadAssets(options) {
2210		return new Promise((resolve, reject) => {
2211			const getParameters = {
2212				e: (options?.extension || []).join(',')
2213			};
2214			BX.ajax.runAction(ajaxController, {
2215				data: options,
2216				getParameters
2217			}).then(result => {
2218				resolve(result?.data);
2219			}).catch(err => {
2220				reject(err);
2221			});
2222		});
2223	}
2224
2225	function fetchInlineScripts(acc, item) {
2226		if (item.isInternal) {
2227			acc.push(item.JS);
2228		}
2229		return acc;
2230	}
2231	function fetchExternalScripts(acc, item) {
2232		if (!item.isInternal) {
2233			acc.push(item.JS);
2234		}
2235		return acc;
2236	}
2237	function fetchExternalStyles(acc, item) {
2238		if (Type.isString(item) && item !== '') {
2239			acc.push(item);
2240		}
2241		return acc;
2242	}
2243	function fetchExtensionSettings(html) {
2244		if (Type.isStringFilled(html)) {
2245			const scripts = html.match(/<script type="extension\/settings" \b[^>]*>([\S\s]*?)<\/script>/g);
2246			if (Type.isArrayFilled(scripts)) {
2247				return scripts.map(script => {
2248					const [, extension] = script.match(/data-extension="(.[\d._a-z-]+)"/);
2249					return {
2250						extension,
2251						script
2252					};
2253				});
2254			}
2255		}
2256		return [];
2257	}
2258	function loadAll(items) {
2259		const itemsList = Type.isArray(items) ? items : [items];
2260		if (itemsList.length === 0) {
2261			return Promise.resolve();
2262		}
2263		return new Promise((resolve, reject) => {
2264			BX.load(itemsList, resolve, document, reject);
2265		});
2266	}
2267
2268	function parseExtensionHtml(html) {
2269		const result = window.BX.processHTML(html);
2270		const inlinePreScripts = [];
2271		const inlineAfterScripts = [];
2272		result.SCRIPT.reduce((accumulator, element) => {
2273			return fetchInlineScripts(accumulator, element);
2274		}
2274, []).forEach(script => {
2275			if (script.startsWith('BX.Runtime.registerExtension')) {
2276				inlineAfterScripts.push(script);
2277			} else {
2278				inlinePreScripts.push(script);
2279			}
2280		});
2281		return {
2282			inlinePreScripts,
2283			inlineAfterScripts,
2284			externalScripts: result.SCRIPT.reduce((accumulator, element) => {
2285				return fetchExternalScripts(accumulator, element);
2286			}, []),
2287			externalStyles: result.STYLE.reduce((accumulator, element) => {
2288				return fetchExternalStyles(accumulator, element);
2289			}, []),
2290			settingsScripts: fetchExtensionSettings(result.HTML)
2291		};
2292	}
2293
2294	function waitOnline() {
2295		return new Promise(resolve => {
2296			Event.bindOnce(window, 'online', () => resolve());
2297		});
2298	}
2299
2300	const TIMEOUTS = [1000, 3000, 5000];
2301	async function tryLoad(extensions, callback) {
2302		for (let i = 0; i <= TIMEOUTS.length; i++) {
2303			try {
2304				return await callback();
2305			} catch {
2306				if (navigator.onLine === false) {
2307					console.warn(`Wait online for load ${extensions.join(', ')}`);
2308					await waitOnline();
2309					i--;
2310					continue;
2311				}
2312				if (i === TIMEOUTS.length) {
2313					throw new Error(`${extensions.join(', ')} loading failed...`);
2314				}
2315				const delay = TIMEOUTS[i];
2316				const displayRetryCount = i + 1;
2317				console.warn(`Retry load #${displayRetryCount}: ${extensions.join(', ')}`);
2318				await new Promise(resolve => {
2319					setTimeout(resolve, delay);
2320				});
2321			}
2322		}
2323		throw new Error('Unexpected end of retry loop');
2324	}
2325
2326	async function processExtensions(map) {
2327		const loadableExtensions = [...map.keys()];
2328		const rawAssets = (await tryLoad(loadableExtensions, () => loadAssets({
2329			extension: loadableExtensions
2330		}))) ?? [];
2331		rawAssets.forEach(rawAsset => {
2332			const preparedHtml = rawAsset.html ?? '';
2333			const extensionAssets = parseExtensionHtml(preparedHtml);
2334			extensionAssets.settingsScripts.forEach(({
2335				script
2336			}) => {
2337				document.body.insertAdjacentHTML('beforeend', script);
2338			});
2339			extensionAssets.inlinePreScripts.forEach(script => {
2340				window.BX.evalGlobal(script);
2341			});
2342			const loadableExtensionEntry = map.get(rawAsset.extension);
2343			void Promise.all([tryLoad(loadableExtensions, () => loadAll(extensionAssets.externalScripts)), tryLoad(loadableExtensions, () => loadAll(extensionAssets.externalStyles))]).then(() => {
2344				extensionAssets.inlineAfterScripts.forEach(script => {
2345					window.BX.evalGlobal(script);
2346				});
2347				const namespace = rawAsset?.config?.namespace ?? 'window';
2348				loadableExtensionEntry.resolve(namespace);
2349			}).catch(error => {
2350				loadableExtensionEntry.reject(error);
2351			});
2352		});
2353	}
2354
2355	const queue = new Map();
2356	let timerId = null;
2357	async function loadExtension(...name) {
2358		if (Type.isNumber(timerId)) {
2359			clearTimeout(timerId);
2360		}
2361		const requestedNames = name.flat();
2362		const extensionsToLoad = requestedNames.filter(extensionName => {
2363			return !extensionsStorage.has(extensionName);
2364		});
2365		extensionsToLoad.forEach(extensionName => {
2366			let resolve = null;
2367			let reject = null;
2368			const loadableExtensionEntry = {
2369				promise: new Promise((sourceResolve, sourceReject) => {
2370					resolve = sourceResolve;
2371					reject = sourceReject;
2372				}),
2373				resolve,
2374				reject
2375			};
2376			extensionsStorage.set(extensionName, loadableExtensionEntry.promise);
2377			queue.set(extensionName, loadableExtensionEntry);
2378		});
2379		timerId = setTimeout(() => {
2380			if (queue.size > 0) {
2381				void processExtensions(new Map(queue.entries()));
2382				queue.clear();
2383			}
2384		});
2385		const namespaces = await Promise.all(requestedNames.map(extensionName => {
2386			return extensionsStorage.get(extensionName);
2387		}));
2388		return namespaces.reduce((acc, namespace) => {
2389			return {
2390				...acc,
2391				...Reflection.getClass(namespace)
2392			};
2393		}, {});
2394	}
2395
2396	const cloneableTags = new Set(['[object Object]', '[object Array]', '[object RegExp]', '[object Arguments]', '[object Date]', '[object Error]', '[object Map]', '[object Set]', '[object ArrayBuffer]', '[object DataView]', '[object Float32Array]', '[object Float64Array]', '[object Int8Array]', '[object Int16Array]', '[object Int32Array]', '[object Uint8Array]', '[object Uint16Array]', '[object Uint32Array]', '[object Uint8ClampedArray]']);
2397	function isCloneable(value) {
2398		const isCloneableValue = Type.isObjectLike(value) && cloneableTags.has(getTag(value));
2399		return isCloneableValue || Type.isDomNode(value);
2400	}
2401	function internalClone(value, map) {
2402		if (map.has(value)) {
2403			return map.get(value);
2404		}
2405		if (isCloneable(value)) {
2406			if (Type.isArray(value)) {
2407				const cloned = [...value];
2408				map.set(value, cloned);
2409				value.forEach((item, index) => {
2410					cloned[index] = internalClone(item, map);
2411				});
2412				return map.get(value);
2413			}
2414			if (Type.isDomNode(value)) {
2415				return value.cloneNode(true);
2416			}
2417			if (Type.isMap(value)) {
2418				const result = new Map();
2419				map.set(value, result);
2420				value.forEach((item, key) => {
2421					result.set(internalClone(key, map), internalClone(item, map));
2422				});
2423				return result;
2424			}
2425			if (Type.isSet(value)) {
2426				const result = new Set();
2427				map.set(value, result);
2428				value.forEach(item => {
2429					result.add(internalClone(item, map));
2430				});
2431				return result;
2432			}
2433			if (Type.isDate(value)) {
2434				return new Date(value);
2435			}
2436			if (Type.isRegExp(value)) {
2437				const regExpFlags = /\w*$/;
2438				const flags = regExpFlags.exec(value);
2439				let result = new RegExp(value.source);
2440				if (flags && Type.isArray(flags)) {
2441					result = new RegExp(value.source, flags[0]);
2442				}
2443				result.lastIndex = value.lastIndex;
2444				return result;
2445			}
2446			const proto = Object.getPrototypeOf(value);
2447			const result = Object.assign(Object.create(proto), value);
2448			map.set(value, result);
2449			Object.keys(value).forEach(key => {
2450				result[key] = internalClone(value[key], map);
2451			});
2452			return result;
2453		}
2454		return value;
2455	}
2456	function clone$1(value) {
2457		return internalClone(value, new WeakMap());
2458	}
2459
2460	function merge(current, target) {
2461		return Object.entries(target).reduce((acc, [key, value]) => {
2462			if (!Type.isDomNode(acc[key]) && Type.isObjectLike(acc[key]) && Type.isObjectLike(value)) {
2463				acc[key] = merge(acc[key], value);
2464				return acc;
2465			}
2466			acc[key] = value;
2467			return acc;
2468		}, current);
2469	}
2470
2471	function createComparator(fields, orders = []) {
2472		return (a, b) => {
2473			const field = fields[0];
2474			const order = orders[0] || 'asc';
2475			if (Type.isUndefined(field)) {
2476				return 0;
2477			}
2478			let valueA = a[field];
2479			let valueB = b[field];
2480			if (Type.isString(valueA) && Type.isString(valueB)) {
2481				valueA = valueA.toLowerCase();
2482				valueB = valueB.toLowerCase();
2483			}
2484			if (valueA < valueB) {
2485				return order === 'asc' ? -1 : 1;
2486			}
2487			if (valueA > valueB) {
2488				return order === 'asc' ? 1 : -1;
2489			}
2490			return createComparator(fields.slice(1), orders.slice(1))(a, b);
2491		};
2492	}
2493
2494	function registerExtension(options) {
2495		if (!extensionsStorage.has(options.name)) {
2496			const namespace = options?.namespace ?? 'window';
2497			extensionsStorage.set(options.name, Promise.resolve(namespace));
2498		}
2499	}
2500
2501	class Runtime {
2502		static debug = debug$1;
2503		static loadExtension = loadExtension;
2504		static registerExtension = registerExtension;
2505		static clone = clone$1;
2506		static debounce(func, wait = 0, context = null) {
2507			let timeoutId = null;
2508			return function debounced(...args) {
2509				if (Type.isNumber(timeoutId)) {
2510					clearTimeout(timeoutId);
2511				}
2512				timeoutId = setTimeout(() => {
2513					func.apply(context || this, args);
2514				}, wait);
2515			};
2516		}
2517		static throttle(func, wait = 0, context = null) {
2518			let timer = null;
2519			let invoke = false;
2520			return function wrapper(...args) {
2521				invoke = true;
2522				if (!timer) {
2523					const q = function q() {
2524						if (invoke) {
2525							func.apply(context || this, args);
2526							invoke = false;
2527							timer = setTimeout(q, wait);
2528						} else {
2529							timer = null;
2530						}
2531					};
2532					q();
2533				}
2534			};
2535		}
2536		static html(node, html, params = {}) {
2537			if (Type.isNil(html) && Type.isDomNode(node)) {
2538				return node.innerHTML;
2539			}
2540			const parsedHtml = BX.processHTML(html);
2541			const externalCss = parsedHtml.STYLE.reduce((acc, item) => fetchExternalStyles(acc, item), []);
2542			const externalJs = parsedHtml.SCRIPT.reduce((acc, item) => fetchExternalScripts(acc, item), []);
2543			const inlineJs = parsedHtml.SCRIPT.reduce((acc, item) => fetchInlineScripts(acc, item), []);
2544			if (Type.isDomNode(node) && (params.htmlFirst || externalJs.length === 0 && externalCss.length === 0)) {
2545				if (params.useAdjacentHTML) {
2546					node.insertAdjacentHTML('beforeend', parsedHtml.HTML);
2547				} else {
2548					node.innerHTML = parsedHtml.HTML;
2549				}
2550			}
2551			return Promise.all([loadAll(externalJs), loadAll(externalCss)]).then(() => {
2552				if (Type.isDomNode(node) && (externalJs.length > 0 || externalCss.length > 0)) {
2553					if (params.useAdjacentHTML) {
2554						node.insertAdjacentHTML('beforeend', parsedHtml.HTML);
2555					} else {
2556						node.innerHTML = parsedHtml.HTML;
2557					}
2558				}
2559				inlineJs.forEach(script => BX.evalGlobal(script));
2560				if (Type.isFunction(params.callback)) {
2561					params.callback();
2562				}
2563			});
2564		}
2565		static merge(...targets) {
2566			if (Type.isArray(targets[0])) {
2567				targets.unshift([]);
2568			} else if (Type.isObject(targets[0])) {
2569				targets.unshift({});
2570			}
2571			return targets.reduce((acc, item) => {
2572				return merge(acc, item);
2573			}, targets[0]);
2574		}
2575		static orderBy(collection, fields = [], orders = []) {
2576			const comparator = createComparator(fields, orders);
2577			return Object.values(collection).sort(comparator);
2578		}
2579		static destroy(target, errorMessage = 'Object is destroyed') {
2580			if (Type.isObject(target)) {
2581				const onPropertyAccess = () => {
2582					throw new Error(errorMessage);
2583				};
2584				const ownProperties = Object.keys(target);
2585				const prototypeProperties = (() => {
2586					const targetPrototype = Object.getPrototypeOf(target);
2587					if (Type.isObject(targetPrototype)) {
2588						return Object.getOwnPropertyNames(targetPrototype);
2589					}
2590					return [];
2591				})();
2592				const uniquePropertiesList = [...new Set([...ownProperties, ...prototypeProperties])];
2593				uniquePropertiesList.filter(name => {
2594					const descriptor = Object.getOwnPropertyDescriptor(target, name);
2595					return !/__(.+)__/.test(name) && (!Type.isObject(descriptor) || descriptor.configurable === true);
2596				}
2596).forEach(name => {
2597					Object.defineProperty(target, name, {
2598						get: onPropertyAccess,
2599						set: onPropertyAccess,
2600						configurable: false
2601					});
2602				});
2603				Object.setPrototypeOf(target, null);
2604			}
2605		}
2606	}
2607
2608	const isError = Symbol.for('BX.BaseError.isError');
2609	class BaseError {
2610		[isError];
2611		message;
2612		code;
2613		customData;
2614		constructor(message, code, customData) {
2615			this[isError] = true;
2616			this.message = '';
2617			this.code = null;
2618			this.customData = null;
2619			this.setMessage(message);
2620			this.setCode(code);
2621			this.setCustomData(customData);
2622		}
2623		getMessage() {
2624			return this.message;
2625		}
2626		setMessage(message) {
2627			if (Type.isString(message)) {
2628				this.message = message;
2629			}
2630			return this;
2631		}
2632		getCode() {
2633			return this.code;
2634		}
2635		setCode(code) {
2636			if (Type.isStringFilled(code) || code === null) {
2637				this.code = code;
2638			}
2639			return this;
2640		}
2641		getCustomData() {
2642			return this.customData;
2643		}
2644		setCustomData(customData) {
2645			if (!Type.isUndefined(customData)) {
2646				this.customData = customData;
2647			}
2648			return this;
2649		}
2650		toString() {
2651			const code = this.getCode();
2652			const message = this.getMessage();
2653			if (!Type.isStringFilled(code) && !Type.isStringFilled(message)) {
2654				return '';
2655			}
2656			if (!Type.isStringFilled(code)) {
2657				return `Error: ${message}`;
2658			}
2659			if (!Type.isStringFilled(message)) {
2660				return code;
2661			}
2662			return `${code}: ${message}`;
2663		}
2664		static isError(error) {
2665			return Type.isObject(error) && error[isError] === true;
2666		}
2667	}
2668
2669	let BaseEvent = function () {
2670		function BaseEvent(options = {
2671			data: {}
2672		}) {
2673			babelHelpers.classCallCheck(this, BaseEvent);
2674			babelHelpers.defineProperty(this, "type", '');
2675			babelHelpers.defineProperty(this, "data", null);
2676			babelHelpers.defineProperty(this, "target", null);
2677			babelHelpers.defineProperty(this, "compatData", null);
2678			babelHelpers.defineProperty(this, "defaultPrevented", false);
2679			babelHelpers.defineProperty(this, "immediatePropagationStopped", false);
2680			babelHelpers.defineProperty(this, "errors", []);
2681			this.setData(options.data);
2682			this.setCompatData(options.compatData);
2683		}
2684		return babelHelpers.createClass(BaseEvent, [{
2685			key: "getType",
2686			value:
2687			function getType() {
2688				return this.type;
2689			}
2690		}, {
2691			key: "setType",
2692			value: function setType(type) {
2693				if (Type.isStringFilled(type)) {
2694					this.type = type;
2695				}
2696				return this;
2697			}
2698		}, {
2699			key: "getData",
2700			value: function getData() {
2701				return this.data;
2702			}
2703		}, {
2704			key: "setData",
2705			value: function setData(data) {
2706				if (!Type.isUndefined(data)) {
2707					this.data = data;
2708				}
2709				return this;
2710			}
2711		}, {
2712			key: "getCompatData",
2713			value: function getCompatData() {
2714				return this.compatData;
2715			}
2716		}, {
2717			key: "setCompatData",
2718			value: function setCompatData(data) {
2719				if (Type.isArrayLike(data)) {
2720					this.compatData = data;
2721				}
2722				return this;
2723			}
2724		}, {
2725			key: "setTarget",
2726			value: function setTarget(target) {
2727				this.target = target;
2728				return this;
2729			}
2730		}, {
2731			key: "getTarget",
2732			value: function getTarget() {
2733				return this.target;
2734			}
2735		}, {
2736			key: "getErrors",
2737			value: function getErrors() {
2738				return this.errors;
2739			}
2740		}, {
2741			key: "setError",
2742			value: function setError(error) {
2743				if (BaseError.isError(error)) {
2744					this.errors.push(error);
2745				}
2746			}
2747		}, {
2748			key: "preventDefault",
2749			value: function preventDefault() {
2750				this.defaultPrevented = true;
2751			}
2752		}, {
2753			key: "isDefaultPrevented",
2754			value: function isDefaultPrevented() {
2755				return this.defaultPrevented;
2756			}
2757		}, {
2758			key: "stopImmediatePropagation",
2759			value: function stopImmediatePropagation() {
2760				this.immediatePropagationStopped = true;
2761			}
2762		}, {
2763			key: "isImmediatePropagationStopped",
2764			value: function isImmediatePropagationStopped() {
2765				return this.immediatePropagationStopped;
2766			}
2767		}], [{
2768			key: "create",
2769			value: function create(options) {
2770				return new this(options);
2771			}
2772		}]);
2773	}();
2774
2775	class EventStore {
2776		defaultMaxListeners;
2777		eventStore = new WeakMap();
2778		constructor(options = {}) {
2779			this.defaultMaxListeners = Type.isNumber(options.defaultMaxListeners) ? options.defaultMaxListeners : 10;
2780		}
2781		add(target, options = {}) {
2782			const record = this.getRecordScheme();
2783			if (Type.isNumber(options.maxListeners)) {
2784				record.maxListeners = options.maxListeners;
2785			}
2786			this.eventStore.set(target, record);
2787			return record;
2788		}
2789		get(target) {
2790			return this.eventStore.get(target);
2791		}
2792		getOrAdd(target, options = {}) {
2793			return this.get(target) || this.add(target, options);
2794		}
2795		delete(context) {
2796			this.eventStore.delete(context);
2797		}
2798		getRecordScheme() {
2799			return {
2800				eventsMap: new Map(),
2801				onceMap: new Map(),
2802				maxListeners: this.getDefaultMaxListeners(),
2803				eventsMaxListeners: new Map()
2804			};
2805		}
2806		getDefaultMaxListeners() {
2807			return this.defaultMaxListeners;
2808		}
2809	}
2810
2811	class WarningStore {
2812		warnings = new Map();
2813		printDelayed;
2814		constructor() {
2815			this.printDelayed = Runtime.debounce(this.print.bind(this), 500);
2816		}
2817		add(target, eventName, listeners) {
2818			let contextWarnings = this.warnings.get(target);
2819			if (!contextWarnings) {
2820				contextWarnings = Object.create(null);
2821				this.warnings.set(target, contextWarnings);
2822			}
2823			if (!contextWarnings[eventName]) {
2824				contextWarnings[eventName] = {};
2825			}
2826			contextWarnings[eventName].size = listeners.size;
2827			if (!Type.isArray(contextWarnings[eventName].errors)) {
2828				contextWarnings[eventName].errors = [];
2829			}
2830			contextWarnings[eventName].errors.push(new Error('EventEmitter warning'));
2831		}
2832		print() {
2833			this.warnings.forEach(warnings => {
2834				for (const eventName of Object.keys(warnings)) {
2835					console.groupCollapsed('Possible BX.Event.EventEmitter memory leak detected. ' + `${warnings[eventName].size} "${eventName}" listeners added. ` + 'Use emitter.setMaxListeners() to increase limit.');
2836					console.dir(warnings[eventName].errors);
2837					console.groupEnd();
2838				}
2839			});
2840			this.clear();
2841		}
2842		clear() {
2843			this.warnings.clear();
2844		}
2845	}
2846
2847	const eventStore = new EventStore({
2848		defaultMaxListeners: 10
2849	});
2850	const warningStore = new WarningStore();
2851	const aliasStore = new Map();
2852	const globalTarget = {
2853		GLOBAL_TARGET: 'GLOBAL_TARGET'
2854	};
2855	eventStore.add(globalTarget, {
2856		maxListeners: 25
2857	});
2858	const isEmitterProperty = Symbol.for('BX.Event.EventEmitter.isEmitter');
2859	const namespaceProperty = Symbol('namespaceProperty');
2860	const targetProperty = Symbol('targetProperty');
2861	let EventEmitter = function () {
2862		function EventEmitter(...args) {
2863			babelHelpers.classCallCheck(this, EventEmitter);
2864			this[targetProperty] = null;
2865			this[namespaceProperty] = null;
2866			this[isEmitterProperty] = true;
2867			let target = this;
2868			if (Object.getPrototypeOf(this) === EventEmitter.prototype && args.length > 0) {
2869				if (!Type.isObject(args[0])) {
2870					throw new TypeError('The "target" argument must be an object.');
2871				}
2872				target = args[0];
2873				this.setEventNamespace(args[1]);
2874			}
2875			this[targetProperty] = target;
2876		}
2877		return babelHelpers.createClass(EventEmitter, [{
2878			key: "setEventNamespace",
2879			value: function setEventNamespace(namespace) {
2880				if (Type.isStringFilled(namespace)) {
2881					this[namespaceProperty] = namespace;
2882				}
2883			}
2884		}, {
2885			key: "getEventNamespace",
2886			value: function getEventNamespace() {
2887				return this[namespaceProperty];
2888			}
2889		}, {
2890			key: "subscribe",
2891			value:
2892			function subscribe(eventName, listener) {
2893				EventEmitter.subscribe(this, eventName, listener);
2894				return this;
2895			}
2896		}, {
2897			key: "subscribeFromOptions",
2898			value: function subscribeFromOptions(options, aliases, compatMode) {
2899				if (Type.isArrayFilled(options)) {
2900					options.forEach(events => {
2901						this.subscribeFromOptions(events);
2902					});
2903					return;
2904				}
2905				if (!Type.isPlainObject(options)) {
2906					return;
2907				}
2908				const normalizedAliases = Type.isPlainObject(aliases) ? EventEmitter.normalizeAliases(aliases) : {};
2909				const optionsRecord = options;
2910				Object.keys(optionsRecord).forEach(eventName => {
2911					const listener = EventEmitter.normalizeListener(optionsRecord[eventName]);
2912					eventName = EventEmitter.normalizeEventName(eventName);
2913					if (normalizedAliases[eventName]) {
2914						const {
2915							eventName: actualName
2916						} = normalizedAliases[eventName];
2917						EventEmitter.subscribe(this, actualName, listener, {
2918							compatMode: compatMode !== false
2919						});
2920					} else {
2921						EventEmitter.subscribe(this, eventName, listener, {
2922							compatMode: compatMode === true
2923						});
2924					}
2925				});
2926			}
2927		}, {
2928			key: "subscribeOnce",
2929			value:
2930			function subscribeOnce(eventName, listener) {
2931				EventEmitter.subscribeOnce(this, eventName, listener);
2932				return this;
2933			}
2934		}, {
2935			key: "unsubscribe",
2936			value:
2937			function unsubscribe(eventName, listener) {
2938				EventEmitter.unsubscribe(this, eventName, listener);
2939				return this;
2940			}
2941		}, {
2942			key: "unsubscribeAll",
2943			value:
2944			function unsubscribeAll(eventName) {
2945				EventEmitter.unsubscribeAll(this, eventName);
2946			}
2947		}, {
2948			key: "emit",
2949			value:
2950			function emit(eventName, event) {
2951				if (this.getEventNamespace() === null) {
2952					console.warn('The instance of BX.Event.EventEmitter is supposed to have an event namespace. ' + 'Use emitter.setEventNamespace() to make events more unique.');
2953				}
2954				EventEmitter.emit(this, eventName, event);
2955				return this;
2956			}
2957		}, {
2958			key: "emitAsync",
2959			value:
2960			function emitAsync(eventName, event) {
2961				if (this.getEventNamespace() === null) {
2962					console.warn('The instance of BX.Event.EventEmitter is supposed to have an event namespace. ' + 'Use emitter.setEventNamespace() to make events more unique.');
2963				}
2964				return EventEmitter.emitAsync(this, eventName, event);
2965			}
2966		}, {
2967			key: "setMaxListeners",
2968			value:
2969			function setMaxListeners(...args) {
2970				EventEmitter.setMaxListeners(this, ...args);
2971				return this;
2972			}
2973		}, {
2974			key: "getMaxListeners",
2975			value:
2976			function getMaxListeners(eventName) {
2977				return EventEmitter.getMaxListeners(this, eventName);
2978			}
2979		}, {
2980			key: "incrementMaxListeners",
2981			value:
2982			function incrementMaxListeners(...args) {
2983				return EventEmitter.incrementMaxListeners(this, ...args);
2984			}
2985		}, {
2986			key: "decrementMaxListeners",
2987			value:
2988			function decrementMaxListeners(...args) {
2989				return EventEmitter.decrementMaxListeners(this, ...args);
2990			}
2991		}, {
2992			key: "getListeners",
2993			value:
2994			function getListeners(eventName) {
2995				return EventEmitter.getListeners(this, eventName);
2996			}
2997		}, {
2998			key: "getFullEventName",
2999			value: function getFullEventName(eventName) {
3000				if (!Type.isStringFilled(eventName)) {
3001					throw new TypeError('The "eventName" argument must be a string.');
3002				}
3003				return EventEmitter.makeFullEventName(this.getEventNamespace(), eventName);
3004			}
3005		}], [{
3006			key: "makeObservable",
3007			value: function makeObservable(target, namespace) {
3008				if (!Type.isObject(target)) {
3009					throw new TypeError('The "target" argument must be an object.');
3010				}
3011				if (!Type.isStringFilled(namespace)) {
3012					throw new TypeError('The "namespace" must be an non-empty string.');
3013				}
3014				if (EventEmitter.isEventEmitter(target)) {
3015					throw new TypeError('The "target" is an event emitter already.');
3016				}
3017				const targetProto = Object.getPrototypeOf(target);
3018				const emitter = new EventEmitter();
3019				emitter.setEventNamespace(namespace);
3020				Object.setPrototypeOf(emitter, targetProto);
3021				Object.setPrototypeOf(target, emitter);
3022				Object.getOwnPropertyNames(EventEmitter.prototype).forEach(method => {
3023					if (['constructor'].includes(method)) {
3024						return;
3025					}
3026					emitter[method] = function (...args) {
3027						return EventEmitter.prototype[method].apply(target, args);
3028					};
3029				});
3030			}
3031		}, {
3032			key: "subscribe",
3033			value: function subscribe(target, eventName, listener, options) {
3034				if (Type.isString(target)) {
3035					options = listener;
3036					listener = eventName;
3037					eventName = target;
3038					target = this.GLOBAL_TARGET;
3039				}
3040				if (!Type.isObject(target)) {
3041					throw new TypeError('The "target" argument must be an object.');
3042				}
3043				eventName = this.normalizeEventName(eventName);
3044				if (!Type.isStringFilled(eventName)) {
3045					throw new TypeError('The "eventName" argument must be a string.');
3046				}
3047				listener = this.normalizeListener(listener);
3048				options = Type.isPlainObject(options) ? options : {};
3049				const fullEventName = this.resolveEventName(eventName, target, options.useGlobalNaming === true);
3050				const {
3051					eventsMap,
3052					onceMap
3053				} = eventStore.getOrAdd(target);
3054				const onceListeners = onceMap.get(fullEventName);
3055				let listeners = eventsMap.get(fullEventName);
3056				if (listeners && listeners.has(listener) || onceListeners && onceListeners.has(listener)) {
3057					console.error(`You cannot subscribe the same "${fullEventName}" event listener twice.`);
3058				} else if (listeners) {
3059					listeners.set(listener, {
3060						listener,
3061						options,
3062						sort: this.getNextSequenceValue()
3063					});
3064				} else {
3065					listeners = new Map([[listener, {
3066						listener,
3067						options,
3068						sort: this.getNextSequenceValue()
3069					}]]);
3070					eventsMap.set(fullEventName, listeners);
3071				}
3072				const maxListeners = this.getMaxListeners(target, eventName);
3073				if (listeners.size > maxListeners) {
3074					warningStore.add(target, fullEventName, listeners);
3075					warningStore.printDelayed();
3076				}
3077			}
3078		}, {
3079			key: "subscribeOnce",
3080			value: function subscribeOnce(target, eventName, listener) {
3081				if (Type.isString(target)) {
3082					listener = eventName;
3083					eventName = target;
3084					target = this.GLOBAL_TARGET;
3085				}
3086				if (!Type.isObject(target)) {
3087					throw new TypeError('The "target" argument must be an object.');
3088				}
3089				eventName = this.normalizeEventName(eventName);
3090				if (!Type.isStringFilled(eventName)) {
3091					throw new TypeError('The "eventName" argument must be a string.');
3092				}
3093				listener = this.normalizeListener(listener);
3094				const fullEventName = this.resolveEventName(eventName, target);
3095				const {
3096					eventsMap,
3097					onceMap
3098				} = eventStore.getOrAdd(target);
3099				const listeners = eventsMap.get(fullEventName);
3100				let onceListeners = onceMap.get(fullEventName);
3101				if (listeners && listeners.has(listener) || onceListeners && onceListeners.has(listener)) {
3102					console.error(`You cannot subscribe the same "${fullEventName}" event listener twice.`);
3103				} else {
3104					const once = (...args) => {
3105						this.unsubscribe(target, eventName, once);
3106						onceListeners.delete(listener);
3107						listener(...args);
3108					};
3109					if (onceListeners) {
3110						onceListeners.set(listener, once);
3111					} else {
3112						onceListeners = new Map([[listener, once]]);
3113						onceMap.set(fullEventName, onceListeners);
3114					}
3115					this.subscribe(target, eventName, once);
3116				}
3117			}
3118		}, {
3119			key: "unsubscribe",
3120			value: function unsubscribe(target, eventName, listener, options) {
3121				if (Type.isString(target)) {
3122					listener = eventName;
3123					eventName = target;
3124					target = this.GLOBAL_TARGET;
3125				}
3126				eventName = this.normalizeEventName(eventName);
3127				if (!Type.isStringFilled(eventName)) {
3128					throw new TypeError('The "eventName" argument must be a string.');
3129				}
3130				listener = this.normalizeListener(listener);
3131				options = Type.isPlainObject(options) ? options : {};
3132				const fullEventName = this.resolveEventName(eventName, target, options.useGlobalNaming === true);
3133				const targetInfo = eventStore.get(target);
3134				const listeners = targetInfo && targetInfo.eventsMap.get(fullEventName);
3135				const onceListeners = targetInfo && targetInfo.onceMap.get(fullEventName);
3136				if (listeners) {
3137					listeners.delete(listener);
3138				}
3139				if (onceListeners) {
3140					const once = onceListeners.get(listener);
3141					if (once) {
3142						onceListeners.delete(listener);
3143						listeners.delete(once);
3144					}
3145				}
3146			}
3147		}, {
3148			key: "unsubscribeAll",
3149			value: function unsubscribeAll(target, eventName, options) {
3150				if (Type.isString(target)) {
3151					eventName = target;
3152					target = this.GLOBAL_TARGET;
3153				}
3154				if (Type.isStringFilled(eventName)) {
3155					const targetInfo = eventStore.get(target);
3156					if (targetInfo) {
3157						options = Type.isPlainObject(options) ? options : {};
3158						const fullEventName = this.resolveEventName(eventName, target, options.useGlobalNaming === true);
3159						targetInfo.eventsMap.delete(fullEventName);
3160						targetInfo.onceMap.delete(fullEventName);
3161					}
3162				} else if (Type.isNil(eventName)) {
3163					if (target === this.GLOBAL_TARGET) {
3164						console.error('You cannot unsubscribe all global listeners.');
3165					} else {
3166						eventStore.delete(target);
3167					}
3168				}
3169			}
3170		}, {
3171			key: "emit",
3172			value: function emit(target, eventName, event, options) {
3173				if (Type.isString(target)) {
3174					options = event;
3175					event = eventName;
3176					eventName = target;
3177					target = this.GLOBAL_TARGET;
3178				}
3179				if (!Type.isObject(target)) {
3180					throw new TypeError('The "target" argument must be an object.');
3181				}
3182				eventName = this.normalizeEventName(eventName);
3183				if (!Type.isStringFilled(eventName)) {
3184					throw new TypeError('The "eventName" argument must be a string.');
3185				}
3186				options = Type.isPlainObject(options) ? options : {};
3187				const fullEventName = this.resolveEventName(eventName, target, options.useGlobalNaming === true);
3188				const globalEvents = eventStore.get(this.GLOBAL_TARGET);
3189				const globalListeners = globalEvents && globalEvents.eventsMap.get(fullEventName) || new Map();
3190				let targetListeners = new Set();
3191				if (target !== this.GLOBAL_TARGET) {
3192					const targetEvents = eventStore.get(target);
3193					targetListeners = targetEvents && targetEvents.eventsMap.get(fullEventName) || new Map();
3194				}
3195				const listeners = [...globalListeners.values(), ...targetListeners.values()];
3196				listeners.sort((a, b) => {
3197					return a.sort - b.sort;
3198				});
3199				const preparedEvent = this.prepareEvent(target, fullEventName, event);
3200				const result = [];
3201				for (const {
3202					listener,
3203					options: listenerOptions
3204				} of listeners) {
3205					if (preparedEvent.isImmediatePropagationStopped()) {
3206						break;
3207					}
3208					if (globalListeners.has(listener) || targetListeners.has(listener)) {
3209						let listenerResult = null;
3210						if (listenerOptions.compatMode) {
3211							const compatData = preparedEvent.getCompatData();
3212							const params = compatData === null ? [preparedEvent] : options.cloneData === true ? Runtime.clone(compatData) : compatData;
3213							const context = Type.isUndefined(options.thisArg) ? target : options.thisArg;
3214							listenerResult = listener.apply(context, params);
3215						} else {
3216							listenerResult = Type.isUndefined(options.thisArg) ? listener(preparedEvent) : listener.call(options.thisArg, preparedEvent);
3217						}
3218						result.push(listenerResult);
3219					}
3220				}
3221				return result;
3222			}
3223		}, {
3224			key: "emitAsync",
3225			value: function emitAsync(target, eventName, event) {
3226				if (Type.isString(target)) {
3227					event = eventName;
3228					eventName = target;
3229					target = this.GLOBAL_TARGET;
3230				}
3231				return Promise.all(this.emit(target, eventName, event));
3232			}
3233		}, {
3234			key: "prepareEvent",
3235			value: function prepareEvent(target, eventName, event) {
3236				const preparedEvent = event instanceof BaseEvent ? event : new BaseEvent();
3237				if (!(event instanceof BaseEvent)) {
3238					preparedEvent.setData(event);
3239				}
3240				preparedEvent.setTarget(this.isEventEmitter(target) ? target[targetProperty] : target);
3241				preparedEvent.setType(eventName);
3242				return preparedEvent;
3243			}
3244		}, {
3245			key: "getNextSequenceValue",
3246			value: function getNextSequenceValue() {
3247				return this.sequenceValue++;
3248			}
3249		}, {
3250			key: "setMaxListeners",
3251			value: function setMaxListeners(...args) {
3252				let target = this.GLOBAL_TARGET;
3253				let eventName = null;
3254				let count = null;
3255				if (args.length === 1) {
3256					count = args[0];
3257				} else if (args.length === 2) {
3258					if (Type.isString(args[0])) {
3259						[eventName, count] = args;
3260					} else {
3261						[target, count] = args;
3262					}
3263				} else if (args.length >= 3) {
3264					[target, eventName, count] = args;
3265				}
3266				if (!Type.isObject(target)) {
3267					throw new TypeError('The "target" argument must be an object.');
3268				}
3269				if (eventName !== null && !Type.isStringFilled(eventName)) {
3270					throw new TypeError('The "eventName" argument must be a string.');
3271				}
3272				if (!Type.isNumber(count) || count < 0) {
3273					throw new TypeError(`The value of "count" is out of range. It must be a non-negative number. Received ${count}.`);
3274				}
3275				const targetInfo = eventStore.getOrAdd(target);
3276				if (Type.isStringFilled(eventName)) {
3277					const fullEventName = this.resolveEventName(eventName, target);
3278					targetInfo.eventsMaxListeners.set(fullEventName, count);
3279				} else {
3280					targetInfo.maxListeners = count;
3281				}
3282			}
3283		}, {
3284			key: "getMaxListeners",
3285			value: function getMaxListeners(target, eventName) {
3286				if (Type.isString(target)) {
3287					eventName = target;
3288					target = this.GLOBAL_TARGET;
3289				} else if (Type.isNil(target)) {
3290					target = this.GLOBAL_TARGET;
3291				}
3292				if (!Type.isObject(target)) {
3293					throw new TypeError('The "target" argument must be an object.');
3294				}
3295				const targetInfo = eventStore.get(target);
3296				if (targetInfo) {
3297					let maxListeners = targetInfo.maxListeners;
3298					if (Type.isStringFilled(eventName)) {
3299						const fullEventName = this.resolveEventName(eventName, target);
3300						maxListeners = targetInfo.eventsMaxListeners.get(fullEventName) || maxListeners;
3301					}
3302					return maxListeners;
3303				}
3304				return this.DEFAULT_MAX_LISTENERS;
3305			}
3306		}, {
3307			key: "addMaxListeners",
3308			value: function addMaxListeners(...args) {
3309				const [target, eventName, increment] = this.destructMaxListenersArgs(...args);
3310				const maxListeners = Math.max(this.getMaxListeners(target, eventName) + increment, 0);
3311				if (Type.isStringFilled(eventName)) {
3312					EventEmitter.setMaxListeners(target, eventName, maxListeners);
3313				} else {
3314					EventEmitter.setMaxListeners(target, maxListeners);
3315				}
3316				return maxListeners;
3317			}
3318		}, {
3319			key: "incrementMaxListeners",
3320			value: function incrementMaxListeners(...args) {
3321				const [target, eventName, increment] = this.destructMaxListenersArgs(...args);
3322				return this.addMaxListeners(target, eventName, Math.abs(increment));
3323			}
3324		}, {
3325			key: "decrementMaxListeners",
3326			value: function decrementMaxListeners(...args) {
3327				const [target, eventName, increment] = this.destructMaxListenersArgs(...args);
3328				return this.addMaxListeners(target, eventName, -Math.abs(increment));
3329			}
3330		}, {
3331			key: "destructMaxListenersArgs",
3332			value: function destructMaxListenersArgs(...args) {
3333				let eventName = null;
3334				let increment = 1;
3335				let target = this.GLOBAL_TARGET;
3336				if (args.length === 1) {
3337					if (Type.isNumber(args[0])) {
3338						increment = args[0];
3339					} else if (Type.isString(args[0])) {
3340						eventName = args[0];
3341					} else {
3342						target = args[0];
3343					}
3344				} else if (args.length === 2) {
3345					if (Type.isString(args[0])) {
3346						[eventName, increment] = args;
3347					} else if (Type.isString(args[1])) {
3348						[target, eventName] = args;
3349					} else {
3350						[target, increment] = args;
3351					}
3352				} else if (args.length >= 3) {
3353					[target, eventName, increment] = args;
3354				}
3355				if (!Type.isObject(target)) {
3356					throw new TypeError('The "target" argument must be an object.');
3357				}
3358				if (eventName !== null && !Type.isStringFilled(eventName)) {
3359					throw new TypeError('The "eventName" argument must be a string.');
3360				}
3361				if (!Type.isNumber(increment)) {
3362					throw new TypeError('The value of "increment" must be a number.');
3363				}
3364				return [target, eventName, increment];
3365			}
3366		}, {
3367			key: "getListeners",
3368			value: function getListeners(target, eventName) {
3369				if (Type.isString(target)) {
3370					eventName = target;
3371					target = this.GLOBAL_TARGET;
3372				}
3373				if (!Type.isObject(target)) {
3374					throw new TypeError('The "target" argument must be an object.');
3375				}
3376				eventName = this.normalizeEventName(eventName);
3377				if (!Type.isStringFilled(eventName)) {
3378					throw new TypeError('The "eventName" argument must be a string.');
3379				}
3380				const targetInfo = eventStore.get(target);
3381				if (!targetInfo) {
3382					return new Map();
3383				}
3384				const fullEventName = this.resolveEventName(eventName, target);
3385				return targetInfo.eventsMap.get(fullEventName) || new Map();
3386			}
3387		}, {
3388			key: "registerAliases",
3389			value: function registerAliases(aliases) {
3390				const normalizedAliases = this.normalizeAliases(aliases);
3391				Object.keys(normalizedAliases).forEach(alias => {
3392					aliasStore.set(alias, {
3393						eventName: normalizedAliases[alias].eventName,
3394						namespace: normalizedAliases[alias].namespace
3395					});
3396				});
3397				EventEmitter.mergeEventAliases(normalizedAliases);
3398			}
3399		}, {
3400			key: "normalizeAliases",
3401			value: function normalizeAliases(aliases) {
3402				if (!Type.isPlainObject(aliases)) {
3403					throw new TypeError('The "aliases" argument must be an object.');
3404				}
3405				const aliasesRecord = aliases;
3406				const result = Object.create(null);
3407				for (const key of Object.keys(aliasesRecord)) {
3408					if (!Type.isStringFilled(key)) {
3409						throw new TypeError('The alias must be an non-empty string.');
3410					}
3411					const options = aliasesRecord[key];
3412					if (!options || !Type.isStringFilled(options.eventName) || !Type.isStringFilled(options.namespace)) {
3413						throw new TypeError('The alias options must set the "eventName" and the "namespace".');
3414					}
3415					const normalizedAlias = this.normalizeEventName(key);
3416					result[normalizedAlias] = {
3417						eventName: options.eventName,
3418						namespace: options.namespace
3419					};
3420				}
3421				return result;
3422			}
3423		}, {
3424			key: "mergeEventAliases",
3425			value: function mergeEventAliases(aliases) {
3426				const globalEvents = eventStore.get(this.GLOBAL_TARGET);
3427				if (!globalEvents) {
3428					return;
3429				}
3430				Object.keys(aliases).forEach(alias => {
3431					const options = aliases[alias];
3432					alias = this.normalizeEventName(alias);
3433					const fullEventName = this.makeFullEventName(options.namespace, options.eventName);
3434					const aliasListeners = globalEvents.eventsMap.get(alias);
3435					if (aliasListeners) {
3436						const listeners = globalEvents.eventsMap.get(fullEventName) || new Map();
3437						globalEvents.eventsMap.set(fullEventName, new Map([...listeners, ...aliasListeners]));
3438						globalEvents.eventsMap.delete(alias);
3439					}
3440					const aliasOnceListeners = globalEvents.onceMap.get(alias);
3441					if (aliasOnceListeners) {
3442						const onceListeners = globalEvents.onceMap.get(fullEventName) || new Map();
3443						globalEvents.onceMap.set(fullEventName, new Map([...onceListeners, ...aliasOnceListeners]));
3444						globalEvents.onceMap.delete(alias);
3445					}
3446					const aliasMaxListeners = globalEvents.eventsMaxListeners.get(alias);
3447					if (aliasMaxListeners) {
3448						const eventMaxListeners = globalEvents.eventsMaxListeners.get(fullEventName) || 0;
3449						globalEvents.eventsMaxListeners.set(fullEventName, Math.max(eventMaxListeners, aliasMaxListeners));
3450						globalEvents.eventsMaxListeners.delete(alias);
3451					}
3452				});
3453			}
3454		}, {
3455			key: "isEventEmitter",
3456			value: function isEventEmitter(target) {
3457				return Type.isObject(target) && target[isEmitterProperty] === true;
3458			}
3459		}, {
3460			key: "normalizeEventName",
3461			value: function normalizeEventName(eventName) {
3462				if (!Type.isStringFilled(eventName)) {
3463					return '';
3464				}
3465				return eventName.toLowerCase();
3466			}
3467		}, {
3468			key: "normalizeListener",
3469			value: function normalizeListener(listener) {
3470				if (Type.isString(listener)) {
3471					listener = Reflection.getClass(listener);
3472				}
3473				if (!Type.isFunction(listener)) {
3474					throw new TypeError(`The "listener" argument must be of type Function. Received type ${typeof listener}.`);
3475				}
3476				return listener;
3477			}
3478		}, {
3479			key: "resolveEventName",
3480			value: function resolveEventName(eventName, target, useGlobalNaming = false) {
3481				eventName = this.normalizeEventName(eventName);
3482				if (!Type.isStringFilled(eventName)) {
3483					return '';
3484				}
3485				if (this.isEventEmitter(target) && useGlobalNaming !== true) {
3486					if (target.getEventNamespace() !== null && eventName.includes('.')) {
3487						console.warn(`Possible the wrong event name "${eventName}".`);
3488					}
3489					eventName = target.getFullEventName(eventName);
3490				} else if (aliasStore.has(eventName)) {
3491					const {
3492						namespace,
3493						eventName: actualEventName
3494					} = aliasStore.get(eventName);
3495					eventName = this.makeFullEventName(namespace, actualEventName);
3496				}
3497				return eventName;
3498			}
3499		}, {
3500			key: "makeFullEventName",
3501			value: function makeFullEventName(namespace, eventName) {
3502				const fullName = Type.isStringFilled(namespace) ? `${namespace}:${eventName}` : eventName;
3503				return Type.isStringFilled(fullName) ? fullName.toLowerCase() : '';
3504			}
3505		}]);
3506	}();
3507	babelHelpers.defineProperty(EventEmitter, "GLOBAL_TARGET", globalTarget);
3508	babelHelpers.defineProperty(EventEmitter, "DEFAULT_MAX_LISTENERS", eventStore.getDefaultMaxListeners());
3509	babelHelpers.defineProperty(EventEmitter, "sequenceValue", 1);
3510
3511	let stack = [];
3512	exports.isReady = false;
3513	function ready$1(handler) {
3514		if (!Type.isFunction(handler)) {
3515			return;
3516		}
3517		if (exports.isReady) {
3518			handler();
3519		} else {
3520			stack.push(handler);
3521		}
3522	}
3523	bindOnce$1(document, 'DOMContentLoaded', () => {
3524		exports.isReady = true;
3525		stack.forEach(handler => {
3526			handler();
3527		});
3528		stack = [];
3529	});
3530
3531	function getEventListeners(target, eventName) {
3532		const listeners = [];
3533		if (Type.isEventTargetLike(target)) {
3534			const events = registry.get(target);
3535			if (events[eventName]) {
3536				events[eventName].forEach(listener => {
3537					listeners.push({
3538						type: eventName,
3539						listener
3540					});
3541				});
3542			}
3543		}
3544		return listeners;
3545	}
3546
3547	class Event {
3548		static bind = bind$1;
3549		static bindOnce = bindOnce$1;
3550		static unbind = unbind$1;
3551		static unbindAll = unbindAll$1;
3552		static ready = ready$1;
3553		static getEventListeners = getEventListeners;
3554		static EventEmitter = EventEmitter;
3555		static BaseEvent = BaseEvent;
3556	}
3557
3558	function encodeAttributeValue(value) {
3559		if (Type.isPlainObject(value) || Type.isArray(value)) {
3560			return JSON.stringify(value);
3561		}
3562		return Text.encode(Text.decode(value));
3563	}
3564
3565	function decodeAttributeValue(value) {
3566		if (Type.isString(value)) {
3567			const decodedValue = Text.decode(value);
3568			let result = null;
3569			try {
3570				result = JSON.parse(decodedValue);
3571			} catch {
3572				result = decodedValue;
3573			}
3574			if (result === decodedValue && /^[\d.]+[.]?\d+$/.test(result)) {
3575				return Number(result);
3576			}
3577			if (result === 'true' || result === 'false') {
3578				return Boolean(result);
3579			}
3580			return result;
3581		}
3582		return value;
3583	}
3584
3585	function getPageScroll() {
3586		const {
3587			documentElement,
3588			body
3589		} = document;
3590		const scrollTop = Math.max(window.pageYOffset || 0, documentElement ? documentElement.scrollTop : 0, body ? body.scrollTop : 0);
3591		const scrollLeft = Math.max(window.pageXOffset || 0, documentElement ? documentElement.scrollLeft : 0, body ? body.scrollLeft : 0);
3592		return {
3593			scrollTop,
3594			scrollLeft
3595		};
3596	}
3597
3598	class Dom {
3599		static replace(oldElement, newElement) {
3600			if (Type.isDomNode(oldElement) && Type.isDomNode(newElement) && Type.isDomNode(oldElement.parentNode)) {
3601				oldElement.parentNode.replaceChild(newElement, oldElement);
3602			}
3603		}
3604		static remove(element) {
3605			if (Type.isDomNode(element) && Type.isDomNode(element.parentNode)) {
3606				element.parentNode.removeChild(element);
3607			}
3608		}
3609		static clean(element) {
3610			if (Type.isDomNode(element)) {
3611				while (element.firstChild) {
3612					element.removeChild(element.firstChild);
3613				}
3614				return;
3615			}
3616			if (Type.isString(element)) {
3617				Dom.clean(document.getElementById(element));
3618			}
3619		}
3620		static insertBefore(current, target) {
3621			if (Type.isDomNode(current) && Type.isDomNode(target) && Type.isDomNode(target.parentNode)) {
3622				target.parentNode.insertBefore(current, target);
3623			}
3624		}
3625		static insertAfter(current, target) {
3626			if (Type.isDomNode(current) && Type.isDomNode(target) && Type.isDomNode(target.parentNode)) {
3627				const parent = target.parentNode;
3628				if (Type.isDomNode(target.nextSibling)) {
3629					parent.insertBefore(current, target.nextSibling);
3630					return;
3631				}
3632				parent.appendChild(current);
3633			}
3634		}
3635		static append(current, target) {
3636			if (Type.isDomNode(current) && Type.isDomNode(target)) {
3637				target.appendChild(current);
3638			}
3639		}
3640		static prepend(current, target) {
3641			if (Type.isDomNode(current) && Type.isDomNode(target)) {
3642				if (Type.isDomNode(target.firstChild)) {
3643					target.insertBefore(current, target.firstChild);
3644					return;
3645				}
3646				Dom.append(current, target);
3647			}
3648		}
3649		static hasClass(element, className) {
3650			if (Type.isElementNode(element)) {
3651				if (Type.isString(className)) {
3652					const preparedClassName = className.trim();
3653					if (preparedClassName.length > 0) {
3654						if (preparedClassName.includes(' ')) {
3655							return preparedClassName.split(' ').every(name => Dom.hasClass(element, name));
3656						}
3657						return element.classList.contains(preparedClassName);
3658					}
3659				}
3660				if (Type.isArray(className) && className.length > 0) {
3661					return className.every(name => Dom.hasClass(element, name));
3662				}
3663			}
3664			return false;
3665		}
3666		static addClass(element, className) {
3667			if (Type.isElementNode(element)) {
3668				if (Type.isString(className)) {
3669					const preparedClassName = className.trim();
3670					if (preparedClassName.length > 0) {
3671						if (preparedClassName.includes(' ')) {
3672							Dom.addClass(element, preparedClassName.split(' '));
3673							return;
3674						}
3675						element.classList.add(preparedClassName);
3676						return;
3677					}
3678				}
3679				if (Type.isArray(className)) {
3680					className.forEach(name => Dom.addClass(element, name));
3681				}
3682			}
3683		}
3684		static removeClass(element, className) {
3685			if (Type.isElementNode(element)) {
3686				if (Type.isString(className)) {
3687					const preparedClassName = className.trim();
3688					if (preparedClassName.length > 0) {
3689						if (preparedClassName.includes(' ')) {
3690							Dom.removeClass(element, preparedClassName.split(' '));
3691							return;
3692						}
3693						element.classList.remove(preparedClassName);
3694						return;
3695					}
3696				}
3697				if (Type.isArray(className)) {
3698					className.forEach(name => Dom.removeClass(element, name));
3699				}
3700			}
3701		}
3702		static toggleClass(element, className, force) {
3703			if (!Type.isElementNode(element) || !Type.isStringFilled(className) && !Type.isArrayFilled(className)) {
3704				return;
3705			}
3706			[className].flat().flatMap(it =>
3706 it?.trim?.().split(' ')).forEach(token => {
3707				if (Type.isStringFilled(token)) {
3708					element.classList.toggle(token, Type.isBoolean(force) ? force : undefined);
3709				}
3710			});
3711		}
3712		static style(element, prop, value) {
3713			if (Type.isElementNode(element)) {
3714				if (Type.isNull(prop)) {
3715					element.removeAttribute('style');
3716					return element;
3717				}
3718				if (Type.isPlainObject(prop)) {
3719					Object.entries(prop).forEach(([currentKey, currentValue]) => {
3720						Dom.style(element, currentKey, currentValue);
3721					});
3722					return element;
3723				}
3724				if (Type.isString(prop)) {
3725					if (Type.isUndefined(value) && element.nodeType !== Node.DOCUMENT_NODE) {
3726						const computedStyle = getComputedStyle(element);
3727						if (prop in computedStyle) {
3728							return computedStyle[prop];
3729						}
3730						return computedStyle.getPropertyValue(prop);
3731					}
3732					if (Type.isNull(value) || value === '' || value === 'null') {
3733						if (String(prop).startsWith('--')) {
3734							element.style.removeProperty(prop);
3735							return element;
3736						}
3737						element.style[prop] = '';
3738						return element;
3739					}
3740					if (Type.isString(value) || Type.isNumber(value)) {
3741						if (String(prop).startsWith('--')) {
3742							element.style.setProperty(prop, String(value));
3743							return element;
3744						}
3745						element.style[prop] = value;
3746						return element;
3747					}
3748				}
3749			}
3750			return null;
3751		}
3752		static adjust(target, data = {}) {
3753			if (!target.nodeType) {
3754				return null;
3755			}
3756			let element = target;
3757			if (target.nodeType === Node.DOCUMENT_NODE) {
3758				element = target.body;
3759			}
3760			if (Type.isPlainObject(data)) {
3761				if (Type.isPlainObject(data.attrs)) {
3762					const attrs = data.attrs;
3763					Object.keys(attrs).forEach(key => {
3764						if (key === 'class' || key.toLowerCase() === 'classname') {
3765							element.className = attrs[key];
3766							return;
3767						}
3768						if (attrs[key] == '') {
3769							element.removeAttribute(key);
3770							return;
3771						}
3772						element.setAttribute(key, attrs[key]);
3773					});
3774				}
3775				if (Type.isPlainObject(data.style)) {
3776					Dom.style(element, data.style);
3777				}
3778				if (Type.isPlainObject(data.props)) {
3779					const props = data.props;
3780					Object.keys(props).forEach(key => {
3781						element[key] = props[key];
3782					});
3783				}
3784				if (Type.isPlainObject(data.events)) {
3785					const events = data.events;
3786					Object.keys(events).forEach(key => {
3787						Event.bind(element, key, events[key]);
3788					});
3789				}
3790				if (Type.isPlainObject(data.dataset)) {
3791					const dataset = data.dataset;
3792					Object.keys(dataset).forEach(key => {
3793						element.dataset[key] = dataset[key];
3794					});
3795				}
3796				const children = Type.isString(data.children) ? [data.children] : data.children;
3797				if (Type.isArray(children) && children.length > 0) {
3798					children.forEach(item => {
3799						if (Type.isDomNode(item)) {
3800							Dom.append(item, element);
3801						}
3802						if (Type.isString(item)) {
3803							element.insertAdjacentHTML('beforeend', item);
3804						}
3805					});
3806					return element;
3807				}
3808				if ('text' in data && !Type.isNil(data.text)) {
3809					element.textContent = data.text;
3810					return element;
3811				}
3812				if ('html' in data && !Type.isNil(data.html)) {
3813					element.innerHTML = data.html;
3814				}
3815			}
3816			return element;
3817		}
3818		static create(tag, data = {}, context = document) {
3819			let tagName = tag;
3820			let options = data;
3821			if (Type.isObjectLike(tag)) {
3822				const tagOptions = tag;
3823				options = tagOptions;
3824				tagName = tagOptions.tag;
3825			}
3826			return Dom.adjust(context.createElement(tagName), options);
3827		}
3828		static show(element) {
3829			if (Type.isDomNode(element)) {
3830				element.hidden = false;
3831			}
3832		}
3833		static hide(element) {
3834			if (Type.isDomNode(element)) {
3835				element.hidden = true;
3836			}
3837		}
3838		static isShown(element) {
3839			return Type.isDomNode(element) && !element.hidden && element.style.getPropertyValue('display') !== 'none';
3840		}
3841		static isShownRecursive(element) {
3842			if (!Type.isDomNode(element)) {
3843				return false;
3844			}
3845			if (element === document.body) {
3846				return Dom.isShown(element);
3847			}
3848			return Dom.isShown(element) && Dom.isShownRecursive(element.parentElement);
3849		}
3850		static toggle(element) {
3851			if (Type.isDomNode(element)) {
3852				if (Dom.isShown(element)) {
3853					Dom.hide(element);
3854				} else {
3855					Dom.show(element);
3856				}
3857			}
3858		}
3859		static getPosition(element) {
3860			if (Type.isDomNode(element)) {
3861				const elementRect = element.getBoundingClientRect();
3862				const {
3863					scrollLeft,
3864					scrollTop
3865				} = getPageScroll();
3866				return new DOMRect(elementRect.left + scrollLeft, elementRect.top + scrollTop, elementRect.width, elementRect.height);
3867			}
3868			return new DOMRect();
3869		}
3870		static getRelativePosition(element, relationElement) {
3871			if (Type.isDomNode(element) && Type.isDomNode(relationElement)) {
3872				const elementPosition = Dom.getPosition(element);
3873				const relationElementPosition = Dom.getPosition(relationElement);
3874				return new DOMRect(elementPosition.left - relationElementPosition.left, elementPosition.top - relationElementPosition.top, elementPosition.width, elementPosition.height);
3875			}
3876			return new DOMRect();
3877		}
3878		static attr(element, attr, value) {
3879			if (Type.isElementNode(element)) {
3880				if (Type.isString(attr)) {
3881					if (!Type.isNil(value)) {
3882						if (Type.isObjectLike(value)) {
3883							element.setAttribute(attr, encodeAttributeValue(value));
3884						} else {
3885							element.setAttribute(attr, String(value));
3886						}
3887					} else if (Type.isNull(value)) {
3888						element.removeAttribute(attr);
3889					} else {
3890						return decodeAttributeValue(element.getAttribute(attr));
3891					}
3892				}
3893				if (Type.isPlainObject(attr)) {
3894					Object.entries(attr).forEach(([attrKey, attrValue]) => {
3895						Dom.attr(element, attrKey, attrValue);
3896					});
3897				}
3898			}
3899			return null;
3900		}
3901	}
3902
3903	const UA = navigator.userAgent.toLowerCase();
3904	class Browser {
3905		static isOpera() {
3906			return UA.includes('opera');
3907		}
3908		static isIE() {
3909			return false;
3910		}
3911		static isIE6() {
3912			return false;
3913		}
3914		static isIE7() {
3915			return false;
3916		}
3917		static isIE8() {
3918			return false;
3919		}
3920		static isIE9() {
3921			return false;
3922		}
3923		static isIE10() {
3924			return false;
3925		}
3926		static isSafari() {
3927			return UA.includes('safari') && !UA.includes('chrome');
3928		}
3929		static isFirefox() {
3930			return UA.includes('firefox');
3931		}
3932		static isChrome() {
3933			return UA.includes('chrome');
3934		}
3935		static detectIEVersion() {
3936			return -1;
3937		}
3938		static isIE11() {
3939			return false;
3940		}
3941		static isMac() {
3942			return UA.includes('macintosh');
3943		}
3944		static isWin() {
3945			return UA.includes('windows');
3946		}
3947		static isLinux() {
3948			return UA.includes('linux') && !Browser.isAndroid();
3949		}
3950		static isAndroid() {
3951			return UA.includes('android');
3952		}
3953		static isIPad() {
3954			return UA.includes('ipad;') || this.isMac() && this.isTouchDevice();
3955		}
3956		static isIPhone() {
3957			return UA.includes('iphone;');
3958		}
3959		static isIOS() {
3960			return Browser.isIPad() || Browser.isIPhone();
3961		}
3962		static isMobile() {
3963			return Browser.isIPhone() || Browser.isIPad() || Browser.isAndroid() || UA.includes('mobile') || UA.includes('touch');
3964		}
3965		static isRetina() {
3966			return window.devicePixelRatio >= 2;
3967		}
3968		static isTouchDevice() {
3969			return 'ontouchstart' in window || navigator.maxTouchPoints > 0 || navigator.msMaxTouchPoints > 0;
3970		}
3971		static isDoctype(target) {
3972			const doc = target || document;
3973			if (doc.compatMode) {
3974				return doc.compatMode === 'CSS1Compat';
3975			}
3976			return Boolean(doc.documentElement && doc.documentElement.clientHeight);
3977		}
3978		static isLocalStorageSupported() {
3979			return true;
3980		}
3981		static addGlobalClass(target) {
3982			const element = Type.isElementNode(target) ? target : document.documentElement;
3983			let globalClass = 'bx-core';
3984			if (Dom.hasClass(element, globalClass)) {
3985				return;
3986			}
3987			if (Browser.isIOS()) {
3988				globalClass += ' bx-ios';
3989			} else if (Browser.isWin()) {
3990				globalClass += ' bx-win';
3991			} else if (Browser.isMac()) {
3992				globalClass += ' bx-mac';
3993			} else if (Browser.isLinux()) {
3994				globalClass += ' bx-linux';
3995			} else if (Browser.isAndroid()) {
3996				globalClass += ' bx-android';
3997			}
3998			globalClass += Browser.isMobile() ? ' bx-touch' : ' bx-no-touch';
3999			globalClass += Browser.isRetina() ? ' bx-retina' : ' bx-no-retina';
4000			if (Browser.isSafari()) {
4001				globalClass += ' bx-safari';
4002			} else if (/AppleWebKit/.test(navigator.userAgent)) {
4003				globalClass += ' bx-chrome';
4004			} else if (/Opera/.test(navigator.userAgent)) {
4005				globalClass += ' bx-opera';
4006			} else if (Browser.isFirefox()) {
4007				globalClass += ' bx-firefox';
4008			}
4009			Dom.addClass(element, globalClass);
4010		}
4011		static detectAndroidVersion() {
4012			const re = /Android ([\d.]+)/;
4013			if (re.exec(navigator.userAgent) !== null) {
4014				const res = navigator.userAgent.match(re);
4015				if (Type.isArrayLike(res) && res.length > 0) {
4016					return parseFloat(res[1]);
4017				}
4018			}
4019			return 0;
4020		}
4021		static isPropertySupported(jsProperty, returnCSSName) {
4022			if (jsProperty === '') {
4023				return false;
4024			}
4025			function getCssName(propertyName) {
4026				return propertyName.replaceAll(/[A-Z]/g, match => `-${match.toLowerCase()}`);
4027			}
4028			function getJsName(cssName) {
4029				const reg = /(\\-([a-z]))/g;
4030				if (reg.test(cssName)) {
4031					return cssName.replaceAll(reg, (...args) => args[2].toUpperCase());
4032				}
4033				return cssName;
4034			}
4035			const property = jsProperty.includes('-') ? getJsName(jsProperty) : jsProperty;
4036			const bReturnCSSName = Boolean(returnCSSName);
4037			const ucProperty = property.charAt(0).toUpperCase() + property.slice(1);
4038			const props = ['Webkit', 'Moz', 'O', 'ms'].join(`${ucProperty} `);
4039			const properties = `${property} ${props} ${ucProperty}`.split(' ');
4040			const obj = document.body || document.documentElement;
4041			for (const prop of properties) {
4042				if (obj && 'style' in obj && prop in obj.style) {
4043					const lowerProp = prop.slice(0, prop.length - property.length).toLowerCase();
4044					const prefix = prop === property ? '' : `-${lowerProp}-`;
4045					return bReturnCSSName ? prefix + getCssName(property) : prop;
4046				}
4047			}
4048			return false;
4049		}
4050		static addGlobalFeatures(features) {
4051			if (!Type.isArray(features)) {
4052				return;
4053			}
4054			const classNames = [];
4055			for (const feature of features) {
4056				const support = Boolean(Browser.isPropertySupported(feature));
4057				classNames.push(`bx-${support ? '' : 'no-'}${feature.toLowerCase()}`);
4058			}
4059			Dom.addClass(document.documentElement, classNames.join(' '));
4060		}
4061	}
4062
4063	class Cookie {
4064		static getList() {
4065			return document.cookie.split(';').map(item => item.split('=')).map(item => item.map(subItem => subItem.trim())).reduce((acc, item) => {
4066				const [key, value] = item;
4067				acc[decodeURIComponent(key)] = decodeURIComponent(value);
4068				return acc;
4069			}, {});
4070		}
4071		static get(name) {
4072			const cookiesList = Cookie.getList();
4073			if (name in cookiesList) {
4074				return cookiesList[name];
4075			}
4076			return undefined;
4077		}
4078		static set(name, value, options = {}) {
4079			const attributes = {
4080				expires: '',
4081				...options
4082			};
4083			if (Type.isNumber(attributes.expires)) {
4084				const now = Date.now();
4085				const days = attributes.expires;
4086				const dayInMs = 864e5;
4087				attributes.expires = new Date(now + days * dayInMs);
4088			}
4089			if (Type.isDate(attributes.expires)) {
4090				attributes.expires = attributes.expires.toUTCString();
4091			}
4092			const safeName = decodeURIComponent(String(name)).replaceAll(/%(23|24|26|2B|5E|60|7C)/g, decodeURIComponent).replaceAll(/[()]/g, escape);
4093			const safeValue = encodeURIComponent(String(value)).replaceAll(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g, decodeURIComponent);
4094			const stringifiedAttributes = Object.keys(attributes).reduce((acc, key) => {
4095				const attributeValue = attributes[key];
4096				if (!attributeValue) {
4097					return acc;
4098				}
4099				if (attributeValue === true) {
4100					return `${acc}; ${key}`;
4101				}
4102				return `${acc}; ${key}=${attributeValue.split(';')[0]}`;
4103			}, '');
4104			document.cookie = `${safeName}=${safeValue}${stringifiedAttributes}`;
4105		}
4106		static remove(name, options = {}) {
4107			Cookie.set(name, '', {
4108				...options,
4109				expires: -1
4110			});
4111		}
4112	}
4113
4114	function objectToFormData(source, formData = new FormData(), pre = null) {
4115		if (Type.isUndefined(source)) {
4116			return formData;
4117		}
4118		if (Type.isNull(source)) {
4119			formData.append(pre, '');
4120		} else if (Type.isArray(source)) {
4121			if (source.length > 0) {
4122				source.forEach((value, index) => {
4123					const key = `${pre}[${index}]`;
4124					objectToFormData(value, formData, key);
4125				});
4126			} else {
4127				const key = `${pre}[]`;
4128				formData.append(key, '');
4129			}
4130		} else if (Type.isDate(source)) {
4131			formData.append(pre, source.toISOString());
4132		} else if (Type.isObject(source) && !Type.isFile(source) && !Type.isBlob(source)) {
4133			Object.keys(source).forEach(property => {
4134				const value = source[property];
4135				let preparedProperty = property;
4136				if (Type.isArray(value)) {
4137					while (preparedProperty.length > 2 && preparedProperty.lastIndexOf('[]') === preparedProperty.length - 2) {
4138						preparedProperty = preparedProperty.slice(0, -2);
4139					}
4140				}
4141				const key = pre ? `${pre}[${preparedProperty}]` : preparedProperty;
4142				objectToFormData(value, formData, key);
4143			});
4144		} else {
4145			formData.append(pre, source);
4146		}
4147		return formData;
4148	}
4149
4150	class Data {
4151		static convertObjectToFormData(source) {
4152			return objectToFormData(source);
4153		}
4154	}
4155
4156	class Http {
4157		static Cookie = Cookie;
4158		static Data = Data;
4159	}
4160
4161	const message$1 = function (value) {
4162		if (Type.isString(value)) {
4163			if (Type.isNil(message$1[value])) {
4164				EventEmitter.emit('onBXMessageNotFound', new BaseEvent({
4165					compatData: [value]
4166				}));
4167				if (Type.isNil(message$1[value])) {
4168					Runtime.debug(`message undefined: ${value}`);
4169					message$1[value] = '';
4170				}
4171			}
4172			return message$1[value];
4173		}
4174		if (Type.isPlainObject(value)) {
4175			Object.keys(value).forEach(key => {
4176				message$1[key] = value[key];
4177			});
4178		}
4179		return undefined;
4180	};
4181	if (!Type.isNil(window.BX) && Type.isFunction(window.BX.message)) {
4182		Object.keys(window.BX.message).forEach(key => {
4183			message$1({
4184				[key]: window.BX.message[key]
4185			});
4186		});
4187	}
4188
4189	class Loc {
4190		static getMessage(messageId, replacements = null) {
4191			let mess = message$1(messageId);
4192			if (Type.isString(mess) && Type.isPlainObject(replacements)) {
4193				const escape = str => String(str).replaceAll(/[$()*+.?[\\\]^{|}]/g, '\\$&');
4194				Object.keys(replacements).forEach(replacement => {
4195					const globalRegexp = new RegExp(escape(replacement), 'gi');
4196					mess = mess.replaceAll(globalRegexp, () => {
4197						return Type.isNil(replacements[replacement]) ? '' : String(replacements[replacement]);
4198					});
4199				});
4200			}
4201			return mess;
4202		}
4203		static hasMessage(messageId) {
4204			return Type.isString(messageId) && !Type.isNil(message$1[messageId]);
4205		}
4206		static setMessage(id, value) {
4207			if (Type.isString(id) && Type.isString(value)) {
4208				message$1({
4209					[id]: value
4210				});
4211			}
4212			if (Type.isObject(id)) {
4213				message$1(id);
4214			}
4215		}
4216		static getMessagePlural(messageId, value, replacements = null) {
4217			let result = '';
4218			if (Type.isNumber(value)) {
4219				if (this.hasMessage(`${messageId}_PLURAL_${this.getPluralForm(value)}`)) {
4220					result = this.getMessage(`${messageId}_PLURAL_${this.getPluralForm(value)}`, replacements);
4221				} else {
4222					result = this.getMessage(`${messageId}_PLURAL_1`, replacements);
4223				}
4224			} else {
4225				result = this.getMessage(messageId, replacements);
4226			}
4227			return result;
4228		}
4229		static getPluralForm(value, languageId) {
4230			let pluralForm = 1;
4231			let lang = languageId;
4232			if (!Type.isStringFilled(lang)) {
4233				lang = message$1('LANGUAGE_ID');
4234			}
4235			const absValue = Math.abs(value);
4236			switch (lang) {
4237				case 'ar':
4238					pluralForm = absValue === 1 ? 0 : 1;
4239					break;
4240				case 'br':
4241				case 'fr':
4242				case 'tr':
4243					pluralForm = absValue > 1 ? 1 : 0;
4244					break;
4245				case 'de':
4246				case 'en':
4247				case 'hi':
4248				case 'it':
4249				case 'la':
4250					pluralForm = absValue === 1 ? 0 : 1;
4251					break;
4252				case 'ru':
4253				case 'ua':
4254					if (absValue % 10 === 1 && absValue % 100 !== 11) {
4255						pluralForm = 0;
4256					} else if (absValue % 10 >= 2 && absValue % 10 <= 4 && (absValue % 100 < 10 || absValue % 100 >= 20)) {
4257						pluralForm = 1;
4258					} else {
4259						pluralForm = 2;
4260					}
4261					break;
4262				case 'pl':
4263					if (absValue === 1) {
4264						pluralForm = 0;
4265					} else if (absValue % 10 >= 2 && absValue % 10 <= 4 && (absValue % 100 < 10 || absValue % 100 >= 20)) {
4266						pluralForm = 1;
4267					} else {
4268						pluralForm = 2;
4269					}
4270					break;
4271				case 'id':
4272				case 'ja':
4273				case 'ms':
4274				case 'sc':
4275				case 'tc':
4276				case 'th':
4277				case 'vn':
4278					pluralForm = 0;
4279					break;
4280				default:
4281					pluralForm = 1;
4282					break;
4283			}
4284			return pluralForm;
4285		}
4286	}
4287
4288	const voidElements = new Set(['area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'param', 'source', 'track', 'wbr']);
4289	function isVoidElement(element) {
4290		return voidElements.has(element);
4291	}
4292
4293	const matchers = {
4294		tag: /<[\d!/A-Za-z-](?:"[^"]*"|'[^']*'|[^"'>])*>|{{uid\d+}}/g,
4295		comment: /<!--(?!<!)[^>[].*?-->/g,
4296		tagName: /<\/?(\S+?)[\s/>]/,
4297		attributes: /\s([\w.:-]+)\s?\n?=\s?\n?"([^"]+)?"|\s([\w.:-]+)\s?\n?=\s?\n?'([^']+)?'|\s([\w.:-]+)/gs,
4298		placeholder: /{{uid\d+}}/g
4299	};
4300
4301	function parseTag(tag) {
4302		const tagResult = {
4303			type: 'tag',
4304			name: '',
4305			svg: false,
4306			attrs: {},
4307			children: [],
4308			voidElement: false
4309		};
4310		if (tag.startsWith('<!--')) {
4311			const endIndex = tag.indexOf('-->');
4312			const openTagLength = '<!--'.length;
4313			return {
4314				type: 'comment',
4315				content: endIndex === -1 ? '' : tag.slice(openTagLength, endIndex)
4316			};
4317		}
4318		const tagNameMatch = tag.match(matchers.tagName);
4319		if (Type.isArrayFilled(tagNameMatch)) {
4320			const [, tagName] = tagNameMatch;
4321			tagResult.name = tagName;
4322			tagResult.svg = tagName === 'svg';
4323			tagResult.voidElement = isVoidElement(tagName) || tag.trim().endsWith('/>');
4324		}
4325		const reg = new RegExp(matchers.attributes);
4326		for (;;) {
4327			const result = reg.exec(tag);
4328			if (Type.isNil(result)) {
4329				break;
4330			}
4331			const [, doubleQuoteName, doubleQuoteValue] = result;
4332			if (Type.isNil(doubleQuoteName)) {
4333				const singleQuoteName = result[3];
4334				const singleQuoteValue = result[4];
4335				if (Type.isNil(singleQuoteName)) {
4336					const booleanAttrName = result[5];
4337					tagResult.attrs[booleanAttrName] = '';
4338				} else {
4339					tagResult.attrs[singleQuoteName] = Type.isStringFilled(singleQuoteValue) ? singleQuoteValue : '';
4340				}
4341			} else {
4342				tagResult.attrs[doubleQuoteName] = Type.isStringFilled(doubleQuoteValue) ? doubleQuoteValue : '';
4343			}
4344		}
4345		return tagResult;
4346	}
4347
4348	function parseText(input) {
4349		const preparedText = input.replace(/[\t\n\r]$/, '');
4350		const placeholders = preparedText.match(matchers.placeholder);
4351		return preparedText.split(matchers.placeholder).reduce((acc, item, index) => {
4352			if (Type.isStringFilled(item)) {
4353				acc.push(...item.split(/\n/).reduce((textAcc, text) => {
4354					const preparedItemText = text.replaceAll(/[\t\r]/g, '');
4355					if (Type.isStringFilled(preparedItemText)) {
4356						textAcc.push({
4357							type: 'text',
4358							content: preparedItemText
4359						});
4360					}
4361					return textAcc;
4362				}, []));
4363			}
4364			if (placeholders && placeholders[index]) {
4365				acc.push({
4366					type: 'placeholder',
4367					uid: parseInt(placeholders[index].replace(/{{uid|}}/, ''), 10)
4368				});
4369			}
4370			return acc;
4371		}, []);
4372	}
4373
4374	function parse(html, substitutions) {
4375		const result = [];
4376		if (html.indexOf('<') !== 0 && !html.startsWith('{{')) {
4377			const end = html.indexOf('<');
4378			result.push(...parseText(end === -1 ? html : html.slice(0, end)));
4379		}
4380		const commentsContent = [];
4381		let commentIndex = -1;
4382		html = html.replace(matchers.comment, tag => {
4383			commentIndex += 1;
4384			commentsContent.push(tag.replaceAll(/^<!--|-->$/g, ''));
4385			return `<!--{{cUid${commentIndex}}}-->`;
4386		});
4387		const arr = [];
4388		let level = -1;
4389		let current = null;
4390		html.replace(matchers.tag, (tag, index) => {
4391			const start = index + tag.length;
4392			const nextChar = html.charAt(start);
4393			let parent = null;
4394			if (tag.startsWith('<!--')) {
4395				const comment = parseTag(tag);
4396				comment.content = commentsContent[tag.replaceAll(/<!--{{cUid|}}-->/g, '')];
4397				if (level < 0) {
4398					result.push(comment);
4399					return result;
4400				}
4401				parent = arr[level];
4402				parent.children.push(comment);
4403				return result;
4404			}
4405			if (tag.startsWith('{{')) {
4406				const [placeholder] = parseText(tag);
4407				if (level < 0) {
4408					result.push(placeholder);
4409					return result;
4410				}
4411				parent = arr[level];
4412				parent.children.push(placeholder);
4413				return result;
4414			}
4415			if (!tag.startsWith('</')) {
4416				level++;
4417				current = parseTag(tag);
4418				if (!current.voidElement && nextChar && nextChar !== '<') {
4419					current.children.push(...parseText(html.slice(start, html.indexOf('<', start))));
4420				}
4421				if (level === 0) {
4422					result.push(current);
4423				}
4424				parent = arr[level - 1];
4425				if (parent) {
4426					if (!current.svg) {
4427						current.svg = parent.svg;
4428					}
4429					parent.children.push(current);
4430				}
4431				arr[level] = current;
4432			}
4433			if (tag.startsWith('</') || current.voidElement) {
4434				if (level > -1 && (current.voidElement || current.name === tag.slice(2, -1))) {
4435					level--;
4436					current = level === -1 ? result : arr[level];
4437				}
4438				if (nextChar && nextChar !== '<') {
4439					parent = level === -1 ? result : arr[level].children;
4440					const end = html.indexOf('<', start);
4441					const content = html.slice(start, end === -1 ? undefined : end);
4442					if (end >
4442 -1 && level + parent.length >= 0 || content !== ' ') {
4443						parent.push(...parseText(content));
4444					}
4445				}
4446			}
4447			return result;
4448		});
4449		return result;
4450	}
4451
4452	const appendElement = (current, target) => {
4453		if (Type.isDomNode(current) && Type.isDomNode(target)) {
4454			if (target.nodeName === 'TEMPLATE') {
4455				target.content.append(current);
4456			} else {
4457				Dom.append(current, target);
4458			}
4459		}
4460	};
4461	function renderNode(options) {
4462		const {
4463			node,
4464			parentElement,
4465			substitutions,
4466			refs = []
4467		} = options;
4468		if (node.type === 'tag') {
4469			const element = (() => {
4470				if (node.svg) {
4471					return document.createElementNS('http://www.w3.org/2000/svg', node.name);
4472				}
4473				return document.createElement(node.name);
4474			})();
4475			if (Object.hasOwn(node.attrs, 'ref')) {
4476				refs.push([node.attrs.ref, element]);
4477				delete node.attrs.ref;
4478			}
4479			Object.entries(node.attrs).forEach(([key, value]) => {
4480				if (key.startsWith('on') && new RegExp(`^${matchers.placeholder.source}$`).test(String(value).trim())) {
4481					const substitution = substitutions[parseInt(String(value).trim().replace('{{uid', ''), 10) - 1];
4482					if (Type.isFunction(substitution)) {
4483						const bindFunctionName = key.endsWith('once') ? 'bindOnce' : 'bind';
4484						Event[bindFunctionName](element, key.replaceAll(/^on|once$/g, ''), substitution);
4485					} else {
4486						element.setAttribute(key, substitution);
4487					}
4488				} else if (new RegExp(matchers.placeholder).test(value)) {
4489					const preparedValue = value.split(/{{|}}/).reduce((acc, item) => {
4490						if (item.startsWith('uid')) {
4491							const substitution = substitutions[parseInt(item.replace('uid', ''), 10) - 1];
4492							return `${acc}${Text.decode(String(substitution))}`;
4493						}
4494						return `${acc}${Text.decode(item)}`;
4495					}, '');
4496					element.setAttribute(key, preparedValue);
4497				} else {
4498					element.setAttribute(key, Text.decode(value));
4499				}
4500			});
4501			node.children.forEach(childNode => {
4502				const result = renderNode({
4503					node: childNode,
4504					parentElement: element,
4505					substitutions,
4506					refs
4507				});
4508				if (Type.isArray(result)) {
4509					result.forEach(subChildElement => {
4510						appendElement(subChildElement, element);
4511					});
4512				} else {
4513					appendElement(result, element);
4514				}
4515			});
4516			return element;
4517		}
4518		if (node.type === 'comment') {
4519			return document.createComment(node.content);
4520		}
4521		if (node.type === 'text') {
4522			if (parentElement) {
4523				if (parentElement.nodeName === 'TEMPLATE') {
4524					parentElement.content.append(node.content);
4525				} else {
4526					parentElement.insertAdjacentHTML('beforeend', node.content);
4527				}
4528				return undefined;
4529			}
4530			return document.createTextNode(node.content);
4531		}
4532		if (node.type === 'placeholder') {
4533			return substitutions[node.uid - 1];
4534		}
4535		return undefined;
4536	}
4537
4538	const SECTION_STATE_OUTSIDE_TAG = 0;
4539	const SECTION_STATE_IN_TAG = 1;
4540	const SECTION_STATE_IN_ATTR_VALUE_DOUBLE = 2;
4541	const SECTION_STATE_IN_ATTR_VALUE_SINGLE = 3;
4542	const tagNameStart = /[A-Za-z]/;
4543	function transitionFromOutsideTag(section, position) {
4544		if (section.charAt(position) === '<') {
4545			const next = section.charAt(position + 1);
4546			if (next === '!' || next === '/' || tagNameStart.test(next)) {
4547				return SECTION_STATE_IN_TAG;
4548			}
4549		}
4550		return SECTION_STATE_OUTSIDE_TAG;
4551	}
4552	function transitionFromInTag(char) {
4553		if (char === '"') {
4554			return SECTION_STATE_IN_ATTR_VALUE_DOUBLE;
4555		}
4556		if (char === '\'') {
4557			return SECTION_STATE_IN_ATTR_VALUE_SINGLE;
4558		}
4559		if (char === '>') {
4560			return SECTION_STATE_OUTSIDE_TAG;
4561		}
4562		return SECTION_STATE_IN_TAG;
4563	}
4564	function advanceState(state, section, position) {
4565		const char = section.charAt(position);
4566		switch (state) {
4567			case SECTION_STATE_OUTSIDE_TAG:
4568				return transitionFromOutsideTag(section, position);
4569			case SECTION_STATE_IN_TAG:
4570				return transitionFromInTag(char);
4571			case SECTION_STATE_IN_ATTR_VALUE_DOUBLE:
4572				return char === '"' ? SECTION_STATE_IN_TAG : state;
4573			case SECTION_STATE_IN_ATTR_VALUE_SINGLE:
4574				return char === '\'' ? SECTION_STATE_IN_TAG : state;
4575			default:
4576				return state;
4577		}
4578	}
4579	function computeSectionStates(sections) {
4580		const states = [];
4581		let state = SECTION_STATE_OUTSIDE_TAG;
4582		for (const section of sections) {
4583			for (let position = 0; position < section.length; position++) {
4584				state = advanceState(state, section, position);
4585			}
4586			states.push(state);
4587		}
4588		return states;
4589	}
4590	function render(sections, ...substitutions) {
4591		const sectionStates = computeSectionStates(sections);
4592		const html = sections.reduce((acc, item, index) => {
4593			if (index > 0) {
4594				const substitution = substitutions[index - 1];
4595				const previousSectionState = sectionStates[index - 1];
4596				const isInsideAttributeValue = previousSectionState === SECTION_STATE_IN_ATTR_VALUE_DOUBLE || previousSectionState === SECTION_STATE_IN_ATTR_VALUE_SINGLE;
4597				if (!isInsideAttributeValue && (Type.isString(substitution) || Type.isNumber(substitution))) {
4598					return `${acc}${substitution}${item}`;
4599				}
4600				return `${acc}{{uid${index}}}${item}`;
4601			}
4602			return acc;
4603		}, sections[0]).replaceAll(/^\s+/gm, '').replaceAll(/>\n+/g, '>').replaceAll(/}\n+/g, '}');
4604		const ast = parse(html);
4605		if (ast.length === 1) {
4606			const refs = [];
4607			const renderedNode = renderNode({
4608				node: ast[0],
4609				substitutions,
4610				refs
4611			});
4612			if (Type.isArrayFilled(refs)) {
4613				return Object.fromEntries([['root', renderedNode], ...refs]);
4614			}
4615			return renderedNode;
4616		}
4617		if (ast.length > 1) {
4618			const refs = [];
4619			const renderedNodes = ast.map(node => {
4620				return renderNode({
4621					node,
4622					substitutions,
4623					refs
4624				});
4625			});
4626			if (Type.isArrayFilled(refs)) {
4627				return Object.fromEntries([['root', renderedNodes], ...refs]);
4628			}
4629			return renderedNodes;
4630		}
4631		return false;
4632	}
4633
4634	function parseProps(...args) {
4635		const [sections, ...substitutions] = args;
4636		return substitutions.reduce((acc, item, index) => {
4637			const nextSectionIndex = index + 1;
4638			if (!Type.isPlainObject(item) && !Type.isArray(item)) {
4639				return acc + item + sections[nextSectionIndex];
4640			}
4641			return `${acc}__s${index}${sections[nextSectionIndex]}`;
4642		}, sections[0]).replaceAll(/[\t\r]/gm, '').split(';\n').map(item => item.replace(/\n/, '')).reduce((acc, item) => {
4643			if (item !== '') {
4644				const matches = item.match(/^[\w-. ]+:/);
4645				const splitted = item.split(/^[\w-. ]+:/);
4646				const key = matches[0].replace(':', '').trim();
4647				const value = splitted[1].trim();
4648				const substitutionPlaceholderExp = /^__s\d+/;
4649				if (substitutionPlaceholderExp.test(value)) {
4650					acc[key] = substitutions[value.replace('__s', '')];
4651					return acc;
4652				}
4653				acc[key] = value;
4654			}
4655			return acc;
4656		}, {});
4657	}
4658	class Tag {
4659		static safe(sections, ...substitutions) {
4660			return substitutions.reduce((acc, item, index) => acc + Text.encode(item) + sections[index + 1], sections[0]);
4661		}
4662		static unsafe(sections, ...substitutions) {
4663			return substitutions.reduce((acc, item, index) => acc + Text.decode(item) + sections[index + 1], sections[0]);
4664		}
4665		static style(element) {
4666			if (!Type.isDomNode(element)) {
4667				throw new Error('element is not HTMLElement');
4668			}
4669			return function styleTagHandler(...args) {
4670				Dom.style(element, parseProps(...args));
4671			};
4672		}
4673		static message(sections, ...substitutions) {
4674			return substitutions.reduce((acc, item, index) => acc + Loc.getMessage(item) + sections[index + 1], sections[0]);
4675		}
4676		static render = render;
4677		static attrs(element) {
4678			if (!Type.isDomNode(element)) {
4679				throw new Error('element is not HTMLElement');
4680			}
4681			return function attrsTagHandler(...args) {
4682				Dom.attr(element, parseProps(...args));
4683			};
4684		}
4685		static attr = Tag.attrs;
4686	}
4687
4688	function getParser(format) {
4689		switch (format) {
4690			case 'index':
4691				return (sourceKey, value, accumulator) => {
4692					const result = /\[(\w*)]$/.exec(sourceKey);
4693					const key = sourceKey.replace(/\[\w*]$/, '');
4694					if (Type.isNil(result)) {
4695						accumulator[key] = value;
4696						return;
4697					}
4698					if (Type.isUndefined(accumulator[key])) {
4699						accumulator[key] = {};
4700					}
4701					accumulator[key][result[1]] = value;
4702				};
4703			case 'bracket':
4704				return (sourceKey, value, accumulator) => {
4705					const result = /(\[])$/.exec(sourceKey);
4706					const key = sourceKey.replace(/\[]$/, '');
4707					if (Type.isNil(result)) {
4708						accumulator[key] = value;
4709						return;
4710					}
4711					if (Type.isUndefined(accumulator[key])) {
4712						accumulator[key] = Type.isNil(value) ? [] : [value];
4713						return;
4714					}
4715					accumulator[key] = [].concat(accumulator[key], value);
4716				};
4717			default:
4718				return (sourceKey, value, accumulator) => {
4719					const key = sourceKey.replace(/\[]$/, '');
4720					accumulator[key] = value;
4721				};
4722		}
4723	}
4724	function getKeyFormat(key) {
4725		if (/^\w+\[(\w+)]$/.test(key)) {
4726			return 'index';
4727		}
4728		if (/^\w+\[]$/.test(key)) {
4729			return 'bracket';
4730		}
4731		return 'default';
4732	}
4733	function isAllowedKey(key) {
4734		return !String(key).startsWith('__proto__');
4735	}
4736	function parseQuery(input) {
4737		if (!Type.isString(input)) {
4738			return {};
4739		}
4740		const url = input.trim().replace(/^[#&?]/, '');
4741		if (!url) {
4742			return {};
4743		}
4744		return {
4745			...url.split('&').reduce((acc, param) => {
4746				const [key, value] = param.replaceAll('+', ' ').split('=');
4747				if (isAllowedKey(key)) {
4748					const keyFormat = getKeyFormat(key);
4749					const formatter = getParser(keyFormat);
4750					formatter(key, value, acc);
4751				}
4752				return acc;
4753			}, Object.create(null))
4754		};
4755	}
4756	const urlExp = /^((\w+):)?(\/\/((\w+)?(:(\w+))?@)?([^/:?]+)(:(\d+))?)?(\/?([^#/?][^#?]*)?)?(\?([^#]+))?(#((?:[\w-?/:@.~!$&'()*+,;=]|%\w{2})*))?/;
4757	function prepareParams(params) {
4758		const paramsEntries = Object.entries(params);
4759		return paramsEntries.reduce((acc, [key, value]) => {
4760			if (Type.isNil(value)) {
4761				acc[key] = '';
4762			} else if (Type.isPlainObject(value)) {
4763				acc[key] = prepareParams(value);
4764			} else {
4765				acc[key] = value;
4766			}
4767			return acc;
4768		}, {});
4769	}
4770	function parseUrl(url) {
4771		const result = url.match(urlExp);
4772		if (Type.isArray(result)) {
4773			const sourceParams = parseQuery(result[14]);
4774			const preparedParams = prepareParams(sourceParams);
4775			return {
4776				useShort: /^\/\//.test(url),
4777				href: result[0] || '',
4778				schema: result[2] || '',
4779				host: result[8] || '',
4780				port: result[10] || '',
4781				path: result[11] || '',
4782				query: result[14] || '',
4783				sourceQueryParams: sourceParams,
4784				queryParams: preparedParams,
4785				hash: result[16] || '',
4786				username: result[5] || '',
4787				password: result[7] || '',
4788				origin: result[8] || ''
4789			};
4790		}
4791		return {};
4792	}
4793
4794	function renderParam(param, value) {
4795		if (Type.isNil(value)) {
4796			return param;
4797		}
4798		return `${param}=${value}`;
4799	}
4800
4801	function buildQueryString(params = {}) {
4802		const queryString = Object.keys(params).reduce((acc, key) => {
4803			if (Type.isArray(params[key])) {
4804				if (Type.isArrayFilled(params[key])) {
4805					params[key].forEach(paramValue => {
4806						acc.push(renderParam(`${key}[]`, paramValue));
4807					});
4808				} else {
4809					acc.push(renderParam(`${key}[]`, null));
4810				}
4811			}
4812			if (Type.isPlainObject(params[key])) {
4813				Object.keys(params[key]).forEach(paramIndex => {
4814					acc.push(renderParam(`${key}[${paramIndex}]`, params[key][paramIndex]));
4815				});
4816			}
4817			if (!Type.isObject(params[key]) && !Type.isArray(params[key])) {
4818				acc.push(renderParam(key, params[key]));
4819			}
4820			return acc;
4821		}, []).join('&');
4822		if (queryString.length > 0) {
4823			return `?${queryString}`;
4824		}
4825		return queryString;
4826	}
4827
4828	function prepareParamValue(value) {
4829		if (Type.isArray(value)) {
4830			return value.map(item => String(item));
4831		}
4832		if (Type.isPlainObject(value)) {
4833			return {
4834				...value
4835			};
4836		}
4837		return String(value);
4838	}
4839
4840	const map = new WeakMap();
4841	class Uri {
4842		static addParam(url, params = {}) {
4843			return new Uri(url).setQueryParams(params).toString();
4844		}
4845		static removeParam(url, params) {
4846			const removableParams = Type.isArray(params) ? params : [params];
4847			return new Uri(url).removeQueryParam(...removableParams).toString();
4848		}
4849		constructor(url = '') {
4850			map.set(this, parseUrl(url));
4851		}
4852		getSchema() {
4853			return map.get(this).schema;
4854		}
4855		setSchema(schema) {
4856			map.get(this).schema = String(schema);
4857			return this;
4858		}
4859		getHost() {
4860			return map.get(this).host;
4861		}
4862		setHost(host) {
4863			map.get(this).host = String(host);
4864			return this;
4865		}
4866		getPort() {
4867			return map.get(this).port;
4868		}
4869		setPort(port) {
4870			map.get(this).port = String(port);
4871			return this;
4872		}
4873		getPath() {
4874			return map.get(this).path;
4875		}
4876		setPath(path) {
4877			if (!/^\//.test(path)) {
4878				map.get(this).path = `/${String(path)}`;
4879				return this;
4880			}
4881			map.get(this).path = String(path);
4882			return this;
4883		}
4884		getQuery() {
4885			return buildQueryString(map.get(this).queryParams);
4886		}
4887		getQueryParam(key) {
4888			const params = this.getQueryParams();
4889			if (Object.hasOwn(params, key)) {
4890				return params[key];
4891			}
4892			return null;
4893		}
4894		setQueryParam(key, value = '') {
4895			map.get(this).queryParams[key] = prepareParamValue(value);
4896			map.get(this).sourceQueryParams[key] = prepareParamValue(value);
4897			return this;
4898		}
4899		getQueryParams() {
4900			return {
4901				...map.get(this).queryParams
4902			};
4903		}
4904		setQueryParams(params = {}) {
4905			if (Type.isPlainObject(params)) {
4906				const {
4907					queryParams,
4908					sourceQueryParams
4909				} = map.get(this);
4910				Object.entries(params).forEach(([key, value]) => {
4911					const preparedValue = prepareParamValue(value);
4912					queryParams[key] = preparedValue;
4913					sourceQueryParams[key] = preparedValue;
4914				});
4915			}
4916			return this;
4917		}
4918		removeQueryParam(...keys) {
4919			const {
4920				queryParams,
4921				sourceQueryParams
4922			} = map.get(this);
4923			keys.forEach(key => {
4924				delete queryParams[key];
4925				delete sourceQueryParams[key];
4926			});
4927			return this;
4928		}
4929		getFragment() {
4930			return map.get(this).hash;
4931		}
4932		setFragment(hash) {
4933			map.get(this).hash = String(hash);
4934			return this;
4935		}
4936		serialize() {
4937			const serialized = {
4938				...map.get(this)
4939			};
4940			delete serialized.sourceQueryParams;
4941			serialized.href = this.toString();
4942			return serialized;
4943		}
4944		toString() {
4945			const data = {
4946				...map.get(this)
4947			};
4948			let protocol = data.schema ? `${data.schema}://` : '';
4949			if (data.useShort) {
4950				protocol = '//';
4951			}
4952			const port = (() => {
4953				if (Type.isString(data.port) && !['', '80'].includes(data.port)) {
4954					return `:${data.port}`;
4955				}
4956				return '';
4957			})();
4958			const host = this.getHost();
4959			const path = this.getPath();
4960			const query = buildQueryString(data.sourceQueryParams);
4961			const hash = data.hash ? `#${data.hash}` : '';
4962			return `${host ? protocol : ''}${host}${host ? port : ''}${path}${query}${hash}`;
4963		}
4964	}
4965
4966	class Validation {
4967		static MAX_EMAIL_LENGTH = 254;
4968		static MAX_LOCAL_LENGTH = 64;
4969		static LOCAL_ALLOWED_CHARS = /^[\w%+.ЁА-яё-]+$/;
4970		static DOMAIN_LABEL_CHARS = /^[\w.ЁА-яё-]+$/;
4971		static isEmail(email) {
4972			if (!Type.isStringFilled(email)) {
4973				return false;
4974			}
4975			if (email.length > Validation.MAX_EMAIL_LENGTH) {
4976				return false;
4977			}
4978			const atPos = email.indexOf('@');
4979			if (atPos <= 0 || atPos === email.length - 1 || email.includes('@', atPos + 1)) {
4980				return false;
4981			}
4982			const local = email.slice(0, atPos);
4983			const domain = email.slice(atPos + 1);
4984			if (!Validation.LOCAL_ALLOWED_CHARS.test(local)) {
4985				return false;
4986			}
4987			if (local.startsWith('.') || local.endsWith('.') || local.startsWith('-') || local.endsWith('-') || local.includes('..') || local.length > Validation.MAX_LOCAL_LENGTH) {
4988				return false;
4989			}
4990			if (!Validation.DOMAIN_LABEL_CHARS.test(domain)) {
4991				return false;
4992			}
4993			if (domain.startsWith('.') || domain.endsWith('.') || domain.includes('..')) {
4994				return false;
4995			}
4996			const labels = domain.split('.');
4997			if (labels.length < 2) {
4998				return false;
4999			}
5000			const tld = labels[labels.length - 1];
5001			if (tld.length < 2 || tld.length > 24) {
5002				return false;
5003			}
5004			for (const label of labels) {
5005				if (label.startsWith('-') || label.endsWith('-')) {
5006					return false;
5007				}
5008				const startsWithLetterOrDigit = /^[\dA-Za-zЁА-яё]/.test(label);
5009				const endsWithLetterOrDigit = /[\dA-Za-zЁА-яё]$/.test(label);
5010				if (!startsWithLetterOrDigit || !endsWithLetterOrDigit) {
5011					return false;
5012				}
5013			}
5014			return true;
5015		}
5016	}
5017
5018	class MemoryStorage {
5019		#map = new Map();
5020		get(key) {
5021			return this.#map.get(key);
5022		}
5023		set(key, value) {
5024			this.#map.set(key, value);
5025		}
5026		has(key) {
5027			return this.#map.has(key);
5028		}
5029		delete(key) {
5030			this.#map.delete(key);
5031		}
5032		get size() {
5033			return this.#map.size;
5034		}
5035		keys() {
5036			return [...this.#map.keys()];
5037		}
5038		values() {
5039			return [...this.#map.values()];
5040		}
5041	}
5042
5043	class BaseCache {
5044		storage = new MemoryStorage();
5045		get(key, defaultValue) {
5046			if (!this.storage.has(key)) {
5047				if (Type.isFunction(defaultValue)) {
5048					return defaultValue();
5049				}
5050				if (!Type.isUndefined(defaultValue)) {
5051					return defaultValue;
5052				}
5053			}
5054			return this.storage.get(key);
5055		}
5056		set(key, value) {
5057			this.storage.set(key, value);
5058		}
5059		delete(key) {
5060			this.storage.delete(key);
5061		}
5062		has(key) {
5063			return this.storage.has(key);
5064		}
5065		remember(key, defaultValue) {
5066			if (!this.storage.has(key)) {
5067				if (Type.isFunction(defaultValue)) {
5068					this.storage.set(key, defaultValue());
5069				} else if (!Type.isUndefined(defaultValue)) {
5070					this.storage.set(key, defaultValue);
5071				}
5072			}
5073			return this.storage.get(key);
5074		}
5075		size() {
5076			return this.storage.size;
5077		}
5078		keys() {
5079			return this.storage.keys();
5080		}
5081		values() {
5082			return this.storage.values();
5083		}
5084	}
5085
5086	class MemoryCache extends BaseCache {}
5087
5088	class LsStorage {
5089		stackKey = 'BX.Cache.Storage.LsStorage.stack';
5090		stack = null;
5091		getStack() {
5092			if (Type.isPlainObject(this.stack)) {
5093				return this.stack;
5094			}
5095			const stack = localStorage.getItem(this.stackKey);
5096			if (Type.isString(stack) && stack !== '') {
5097				const parsedStack = JSON.parse(stack);
5098				if (Type.isPlainObject(parsedStack)) {
5099					this.stack = parsedStack;
5100					return this.stack;
5101				}
5102			}
5103			this.stack = {};
5104			return this.stack;
5105		}
5106		saveStack() {
5107			if (Type.isPlainObject(this.stack)) {
5108				const preparedStack = JSON.stringify(this.stack);
5109				localStorage.setItem(this.stackKey, preparedStack);
5110			}
5111		}
5112		get(key) {
5113			const stack = this.getStack();
5114			return stack[key];
5115		}
5116		set(key, value) {
5117			const stack = this.getStack();
5118			stack[key] = value;
5119			this.saveStack();
5120		}
5121		delete(key) {
5122			const stack = this.getStack();
5123			if (key in stack) {
5124				delete stack[key];
5125			}
5126		}
5127		has(key) {
5128			const stack = this.getStack();
5129			return key in stack;
5130		}
5131		get size() {
5132			const stack = this.getStack();
5133			return Object.keys(stack).length;
5134		}
5135		keys() {
5136			const stack = this.getStack();
5137			return Object.keys(stack);
5138		}
5139		values() {
5140			const stack = this.getStack();
5141			return Object.values(stack);
5142		}
5143	}
5144
5145	class LocalStorageCache extends BaseCache {
5146		storage = new LsStorage();
5147	}
5148
5149	class Cache {
5150		static BaseCache = BaseCache;
5151		static MemoryCache = MemoryCache;
5152		static LocalStorageCache = LocalStorageCache;
5153	}
5154
5155	function convertPath(path) {
5156		if (Type.isStringFilled(path)) {
5157			return path.split('.').reduce((acc, item) => {
5158				item.split(/\[["']?(.+?)["']?]/g).forEach(key => {
5159					if (Type.isStringFilled(key)) {
5160						acc.push(key);
5161					}
5162				});
5163				return acc;
5164			}, []);
5165		}
5166		return [];
5167	}
5168
5169	class SettingsCollection {
5170		constructor(options = {}) {
5171			if (Type.isPlainObject(options)) {
5172				Object.assign(this, options);
5173			}
5174		}
5175		get(path, defaultValue = null) {
5176			const convertedPath = convertPath(path);
5177			return convertedPath.reduce((acc, key) => {
5178				if (!Type.isNil(acc) && acc !== defaultValue) {
5179					if (!Type.isUndefined(acc[key])) {
5180						return acc[key];
5181					}
5182					return defaultValue;
5183				}
5184				return acc;
5185			}, this);
5186		}
5187	}
5188
5189	function deepFreeze(target) {
5190		if (Type.isObject(target)) {
5191			Object.values(target).forEach(value => {
5192				deepFreeze(value);
5193			});
5194			return Object.freeze(target);
5195		}
5196		return target;
5197	}
5198
5199	const settingsStorage = new Map();
5200	class Extension {
5201		static getSettings(extensionName) {
5202			if (Type.isStringFilled(extensionName)) {
5203				if (settingsStorage.has(extensionName)) {
5204					return settingsStorage.get(extensionName);
5205				}
5206				const settingsScriptNode = document.querySelector(`script[data-extension="${extensionName}"]`);
5207				if (Type.isDomNode(settingsScriptNode)) {
5208					const decodedSettings = (() => {
5209						try {
5210							return new SettingsCollection(JSON.parse(settingsScriptNode.innerHTML));
5211						} catch {
5212							return new SettingsCollection();
5213						}
5214					})();
5215					const frozenSettings = deepFreeze(decodedSettings);
5216					settingsStorage.set(extensionName, frozenSettings);
5217					return frozenSettings;
5218				}
5219			}
5220			return deepFreeze(new SettingsCollection());
5221		}
5222	}
5223
5224	function _classPrivateMethodInitSpec(e, a) { _checkPrivateRedeclaration(e, a), a.add(e); }
5225	function _checkPrivateRedeclaration(e, t) { if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object"); }
5226	function _assertClassBrand(e, t, n) { if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n; throw new TypeError("Private element is not present on this object"); }
5227	var _OrderedArray_brand = new WeakSet();
5228	let OrderedArray = function () {
5229		function OrderedArray(comparator = null) {
5230			babelHelpers.classCallCheck(this, OrderedArray);
5231			_classPrivateMethodInitSpec(this, _OrderedArray_brand);
5232			babelHelpers.defineProperty(this, "comparator", null);
5233			babelHelpers.defineProperty(this, "items", []);
5234			this.comparator = Type.isFunction(comparator) ? comparator : null;
5235		}
5236		return babelHelpers.createClass(OrderedArray, [{
5237			key: "add",
5238			value: function add(item) {
5239				let index = -1;
5240				if (this.comparator) {
5241					index = _assertClassBrand(_OrderedArray_brand, this, _searchIndexToInsert).call(this, item);
5242					this.items.splice(index, 0, item);
5243				} else {
5244					this.items.push(item);
5245				}
5246				return index;
5247			}
5248		}, {
5249			key: "has",
5250			value: function has(item) {
5251				return this.items.includes(item);
5252			}
5253		}, {
5254			key: "getIndex",
5255			value: function getIndex(item) {
5256				return this.items.indexOf(item);
5257			}
5258		}, {
5259			key: "getByIndex",
5260			value: function getByIndex(index) {
5261				if (Type.isNumber(index) && index >= 0) {
5262					const item = this.items[index];
5263					return Type.isUndefined(item) ? null : item;
5264				}
5265				return null;
5266			}
5267		}, {
5268			key: "getFirst",
5269			value: function getFirst() {
5270				const first = this.items[0];
5271				return Type.isUndefined(first) ? null : first;
5272			}
5273		}, {
5274			key: "getLast",
5275			value: function getLast() {
5276				const last = this.items[this.count() - 1];
5277				return Type.isUndefined(last) ? null : last;
5278			}
5279		}, {
5280			key: "count",
5281			value: function count() {
5282				return this.items.length;
5283			}
5284		}, {
5285			key: "delete",
5286			value: function _delete(item) {
5287				const index = this.getIndex(item);
5288				if (index !== -1) {
5289					this.items.splice(index, 1);
5290					return true;
5291				}
5292				return false;
5293			}
5294		}, {
5295			key: "clear",
5296			value: function clear() {
5297				this.items = [];
5298			}
5299		}, {
5300			key: Symbol.iterator,
5301			value: function () {
5302				return this.items[Symbol.iterator]();
5303			}
5304		}, {
5305			key: "forEach",
5306			value: function forEach(callbackfn, thisArg) {
5307				const callback = thisArg ? callbackfn.bind(thisArg) : callbackfn;
5308				this.items.forEach((value, index, array) => {
5309					callback(value, index, array);
5310				});
5311			}
5312		}, {
5313			key: "getAll",
5314			value: function getAll() {
5315				return this.items;
5316			}
5317		}, {
5318			key: "getComparator",
5319			value: function getComparator() {
5320				return this.comparator;
5321			}
5322		}, {
5323			key: "sort",
5324			value: function sort() {
5325				const comparator = this.getComparator();
5326				if (comparator === null) {
5327					return;
5328				}
5329				const length = this.items.length;
5330				const indexes = Array.from({
5331					length
5332				}, (_, i) => i);
5333				indexes.sort((index1, index2) => {
5334					return comparator(this.items[index1], this.items[index2]) || index1 - index2;
5335				});
5336				for (let i = 0; i < length; i++) {
5337					indexes[i] = this.items[indexes[i]];
5338				}
5339				for (let i = 0; i < length; i++) {
5340					this.items[i] = indexes[i];
5341				}
5342			}
5343		}]);
5344	}();
5345	function _searchIndexToInsert(value) {
5346		let low = 0;
5347		let high = this.items.length;
5348		while (low < high) {
5349			const mid = Math.floor((low + high) / 2);
5350			if (this.comparator(this.items[mid], value) >= 0) {
5351				high = mid;
5352			} else {
5353				low = mid + 1;
5354			}
5355		}
5356		return low;
5357	}
5358
5359	class ZIndexComponent extends EventEmitter {
5360		sort = 0;
5361		alwaysOnTop = false;
5362		zIndex = 0;
5363		element = null;
5364		overlay = null;
5365		overlayGap = -5;
5366		stack = null;
5367		constructor(element, componentOptions = {}) {
5368			super();
5369			this.setEventNamespace('BX.Main.ZIndexManager.Component');
5370			if (!Type.isElementNode(element)) {
5371				throw new Error("ZIndexManager.Component: The argument 'element' must be a DOM element.");
5372			}
5373			this.element = element;
5374			const options = Type.isPlainObject(componentOptions) ? componentOptions : {};
5375			this.setAlwaysOnTop(options.alwaysOnTop);
5376			this.setOverlay(options.overlay);
5377			this.setOverlayGap(options.overlayGap);
5378			this.subscribeFromOptions(options.events);
5379		}
5380		getSort() {
5381			return this.sort;
5382		}
5383		setSort(sort) {
5384			if (Type.isNumber(sort)) {
5385				this.sort = sort;
5386			}
5387		}
5388		setStack(stack) {
5389			this.stack = stack;
5390		}
5391		getStack() {
5392			return this.stack;
5393		}
5394		getZIndex() {
5395			return this.zIndex;
5396		}
5397		setZIndex(zIndex) {
5398			const changed = this.getZIndex() !== zIndex;
5399			this.getElement().style.setProperty('z-index', String(zIndex), 'important');
5400			this.zIndex = zIndex;
5401			if (this.getOverlay() !== null) {
5402				this.getOverlay().style.setProperty('z-index', String(zIndex + this.getOverlayGap()), 'important');
5403			}
5404			if (changed) {
5405				this.emit('onZIndexChange', {
5406					component: this
5407				});
5408			}
5409		}
5410		getAlwaysOnTop() {
5411			return this.alwaysOnTop;
5412		}
5413		setAlwaysOnTop(value) {
5414			if (Type.isNumber(value) || Type.isBoolean(value)) {
5415				this.alwaysOnTop = value;
5416			}
5417		}
5418		getElement() {
5419			return this.element;
5420		}
5421		setOverlay(overlay, gap) {
5422			if (Type.isElementNode(overlay) || overlay === null) {
5423				this.overlay = overlay;
5424				this.setOverlayGap(gap);
5425				if (this.getStack()) {
5426					this.getStack().sort();
5427				}
5428			}
5429		}
5430		getOverlay() {
5431			return this.overlay;
5432		}
5433		setOverlayGap(gap) {
5434			if (Type.isNumber(gap)) {
5435				this.overlayGap = gap;
5436			}
5437		}
5438		getOverlayGap() {
5439			return this.overlayGap;
5440		}
5441	}
5442
5443	class ZIndexStack {
5444		container;
5445		components;
5446		elements = new WeakMap();
5447		baseIndex = 1000;
5448		baseStep = 50;
5449		sortCount = 0;
5450		constructor(container) {
5451			if (!Type.isDomNode(container)) {
5452				throw new Error("ZIndexManager.Stack: The 'container' argument must be a DOM element.");
5453			}
5454			this.container = container;
5455			const comparator = (componentA, componentB) => {
5456				let result = (Number(componentA.getAlwaysOnTop()) || 0) - (Number(componentB.getAlwaysOnTop()) || 0);
5457				if (!result) {
5458					result = componentA.getSort() - componentB.getSort();
5459				}
5460				return result;
5461			};
5462			this.components = new OrderedArray(comparator);
5463		}
5464		getBaseIndex() {
5465			return this.baseIndex;
5466		}
5467		setBaseIndex(index) {
5468			if (Type.isNumber(index) && index >= 0) {
5469				this.baseIndex = index;
5470				this.sort();
5471			}
5472		}
5473		setBaseStep(step) {
5474			if (Type.isNumber(step) && step > 0) {
5475				this.baseStep = step;
5476				this.sort();
5477			}
5478		}
5479		getBaseStep() {
5480			return this.baseStep;
5481		}
5482		register(element, options = {}) {
5483			if (this.getComponent(element)) {
5484				console.warn('ZIndexManager: You cannot register the element twice.', element);
5485				return this.getComponent(element);
5486			}
5487			const component = new ZIndexComponent(element, options);
5488			component.setStack(this);
5489			component.setSort(++this.sortCount);
5490			this.elements.set(element, component);
5491			this.components.add(component);
5492			this.sort();
5493			return component;
5494		}
5495		unregister(element) {
5496			const component = this.elements.get(element);
5497			this.components.delete(component);
5498			this.elements.delete(element);
5499			this.sort();
5500		}
5501		getComponent(element) {
5502			return this.elements.get(element) || null;
5503		}
5504		getComponents() {
5505			return this.components.getAll();
5506		}
5507		getMaxZIndex() {
5508			const last = this.components.getLast();
5509			return last ? last.getZIndex() : this.baseIndex;
5510		}
5511		sort() {
5512			this.components.sort();
5513			let zIndex = this.baseIndex;
5514			this.components.forEach(component => {
5515				component.setZIndex(zIndex);
5516				zIndex += this.baseStep;
5517			});
5518		}
5519		bringToFront(element) {
5520			const component = this.getComponent(element);
5521			if (!component) {
5522				console.error('ZIndexManager: element was not found in the stack.', element);
5523				return null;
5524			}
5525			component.setSort(++this.sortCount);
5526			this.sort();
5527			return component;
5528		}
5529	}
5530
5531	class ZIndexManager {
5532		static stacks = new WeakMap();
5533		static register(element, options = {}) {
5534			const parentNode = this.#getParentNode(element);
5535			if (!parentNode) {
5536				return null;
5537			}
5538			const stack = this.getOrAddStack(parentNode);
5539			return stack.register(element, options);
5540		}
5541		static unregister(element) {
5542			const parentNode = this.#getParentNode(element);
5543			const stack = this.getStack(parentNode);
5544			if (stack) {
5545				stack.unregister(element);
5546			}
5547		}
5548		static addStack(container) {
5549			const stack = new ZIndexStack(container);
5550			this.stacks.set(container, stack);
5551			return stack;
5552		}
5553		static getStack(container) {
5554			return this.stacks.get(container) || null;
5555		}
5556		static getOrAddStack(container) {
5557			return this.getStack(container) || this.addStack(container);
5558		}
5559		static getComponent(element) {
5560			const parentNode = this.#getParentNode(element, true);
5561			if (!parentNode) {
5562				return null;
5563			}
5564			const stack = this.getStack(parentNode);
5565			return stack ? stack.getComponent(element) : null;
5566		}
5567		static bringToFront(element) {
5568			const parentNode = this.#getParentNode(element);
5569			const stack = this.getStack(parentNode);
5570			if (stack) {
5571				return stack.bringToFront(element);
5572			}
5573			return null;
5574		}
5575		static #getParentNode(element, suppressWarnings = false) {
5576			if (!Type.isElementNode(element)) {
5577				if (!suppressWarnings) {
5578					console.error("ZIndexManager: The argument 'element' must be a DOM element.", element);
5579				}
5580				return null;
5581			}
5582			if (!Type.isElementNode(element.parentNode)) {
5583				if (!suppressWarnings) {
5584					console.error("ZIndexManager: The 'element' doesn't have a parent node.", element);
5585				}
5586				return null;
5587			}
5588			return element.parentNode;
5589		}
5590	}
5591
5592	const IS_WEAK_REF_SUPPORTED = typeof WeakRef !== 'undefined';
5593	class WeakRefMap {
5594		#refs = new Map();
5595		#registry = null;
5596		constructor() {
5597			if (IS_WEAK_REF_SUPPORTED) {
5598				this.#registry = new FinalizationRegistry(this.#cleanupCallback.bind(this));
5599			}
5600		}
5601		clear() {
5602			if (!IS_WEAK_REF_SUPPORTED) {
5603				this.#refs.clear();
5604				return;
5605			}
5606			this.#refs.forEach(ref => {
5607				const value = ref.deref();
5608				if (!Type.isUndefined(value)) {
5609					this.#registry.unregister(value);
5610				}
5611			});
5612			this.#refs.clear();
5613		}
5614		delete(key) {
5615			if (!IS_WEAK_REF_SUPPORTED) {
5616				return this.#refs.delete(key);
5617			}
5618			const value = this.get(key);
5619			if (!Type.isUndefined(value)) {
5620				this.#registry.unregister(value);
5621			}
5622			return this.#refs.delete(key);
5623		}
5624		get(key) {
5625			if (!IS_WEAK_REF_SUPPORTED) {
5626				return this.#refs.get(key);
5627			}
5628			return this.#refs.get(key)?.deref();
5629		}
5630		has(key) {
5631			if (!IS_WEAK_REF_SUPPORTED) {
5632				return this.#refs.has(key);
5633			}
5634			return !Type.isUndefined(this.#refs.get(key)?.deref());
5635		}
5636		set(key, value) {
5637			if (!IS_WEAK_REF_SUPPORTED) {
5638				this.#refs.set(key, value);
5639				return this;
5640			}
5641			this.#refs.set(key, new WeakRef(value));
5642			this.#registry.register(value, key, value);
5643			return this;
5644		}
5645		#cleanupCallback(key) {
5646			const ref = this.#refs.get(key);
5647			if (ref && !ref.deref()) {
5648				this.#refs.delete(key);
5649			}
5650		}
5651	}
5652
5653	var collections = {
5654		OrderedArray,
5655		SettingsCollection,
5656		WeakRefMap
5657	};
5658
5659	class Transition {
5660		static linear(progress) {
5661			return progress;
5662		}
5663		static quad(progress) {
5664			return progress ** 2;
5665		}
5666		static cubic(progress) {
5667			return progress ** 3;
5668		}
5669		static quart(progress) {
5670			return progress ** 4;
5671		}
5672		static quint(progress) {
5673			return progress ** 5;
5674		}
5675		static circ(progress) {
5676			return 1 - Math.sin(Math.acos(progress));
5677		}
5678		static back(progress) {
5679			return progress ** 2 * ((1.5 + 1) * progress - 1.5);
5680		}
5681		static elasti(progress) {
5682			return 2 ** (10 * (progress - 1)) * Math.cos(20 * Math.PI * 1.5 / 3 * progress);
5683		}
5684		static bounce(progress) {
5685			for (let a = 0, b = 1;; a += b, b /= 2) {
5686				if (progress >= (7 - 4 * a) / 11) {
5687					return -(((11 - 6 * a - 11 * progress) / 4) ** 2) + b ** 2;
5688				}
5689			}
5690		}
5691	}
5692
5693	class Easing {
5694		#duration = 1000;
5695		#transition = Transition.linear;
5696		#begin = null;
5697		#step = null;
5698		#complete = null;
5699		#start = {};
5700		#finish = {};
5701		#currentState = {};
5702		#progress = null;
5703		#timer = null;
5704		#options = null;
5705		constructor(easingOptions) {
5706			this.setOptions(easingOptions);
5707		}
5708		setOptions(easingOptions) {
5709			const options = Type.isPlainObject(easingOptions) ? easingOptions : {};
5710			this.#duration = Type.isNumber(options.duration) && options.duration > 0 ? options.duration : this.#duration;
5711			this.#begin = Type.isFunction(options.begin) || options.begin === null ? options.begin : this.#begin;
5712			this.#step = Type.isFunction(options.step) || options.step === null ? options.step : this.#step;
5713			this.#complete = Type.isFunction(options.complete) || options.complete === null ? options.complete : this.#complete;
5714			this.#progress = Type.isFunction(options.progress) || options.progress === null ? options.progress : this.#progress;
5715			this.#start = Type.isPlainObject(options.start) ? {
5716				...options.start
5717			} : this.#start;
5718			this.#finish = Type.isPlainObject(options.finish) ? {
5719				...options.finish
5720			} : this.#finish;
5721		}
5722		setTransition(transition) {
5723			if (Type.isFunction(transition)) {
5724				this.#transition = transition;
5725			} else if (Type.isStringFilled(transition)) {
5726				let funcName = transition;
5727				let decorator = null;
5728				if (transition.startsWith('ease-out-')) {
5729					funcName = funcName.replace('ease-out-', '');
5730					decorator = Easing.makeEaseOut;
5731				} else if (transition.startsWith('ease-in-out-')) {
5732					funcName = funcName.replace('ease-in-out-', '');
5733					decorator = Easing.makeEaseInOut;
5734				}
5735				if (Type.isFunction(Transition[funcName])) {
5736					this.#transition = decorator === null ? Transition[funcName] : decorator(Transition[funcName]);
5737				}
5738			}
5739		}
5740		animateProgress() {
5741			this.#animate();
5742		}
5743		animate() {
5744			this.#progress = progress => {
5745				this.#currentState = {};
5746				for (const propName of Object.keys(this.#start)) {
5747					this.#currentState[propName] = Math.round(this.#start[propName] + (this.#finish[propName] - this.#start[propName]) * progress);
5748				}
5749				if (this.#step !== null) {
5750					this.#step(this.#currentState);
5751				}
5752			};
5753			this.#animate();
5754		}
5755		#animate() {
5756			for (const propName of Object.keys(this.#start)) {
5757				if (Type.isUndefined(this.#finish[propName])) {
5758					delete this.#start[propName];
5759				}
5760			}
5761			let start = null;
5762			const animation = time => {
5763				if (start === null) {
5764					start = time;
5765				}
5766				let progress = (time - start) / this.#duration;
5767				if (progress > 1) {
5768					progress = 1;
5769				}
5770				const delta = this.#transition(progress);
5771				this.#progress(delta);
5772				if (progress === 1) {
5773					this.stop(true);
5774				} else {
5775					this.#timer = requestAnimationFrame(animation);
5776				}
5777			};
5778			if (this.#begin !== null) {
5779				this.#begin(this.#currentState);
5780			}
5781			this.#timer = requestAnimationFrame(animation);
5782		}
5783		get options() {
5784			if (this.#options === null) {
5785				this.#options = new Proxy(this, {
5786					get(target, property, receiver) {
5787						switch (property) {
5788							case 'transition':
5789								return target.#transition;
5790							case 'start':
5791								return target.#start;
5792							case 'finish':
5793								return target.#finish;
5794							case 'duration':
5795								return target.#duration;
5796							default:
5797								return null;
5798						}
5799					},
5800					set(target, property, value, receiver) {
5801						target.setOptions({
5802							[property]: value
5803						});
5804						return true;
5805					}
5806				});
5807			}
5808			return this.#options;
5809		}
5810		stop(completed = false) {
5811			if (this.#timer !== null) {
5812				cancelAnimationFrame(this.#timer);
5813				this.#timer = null;
5814				if (completed && this.#complete !== null) {
5815					this.#complete(this.#currentState);
5816				}
5817			}
5818		}
5819		static makeEaseInOut(delta) {
5820			return progress => {
5821				if (progress < 0.5) {
5822					return delta(2 * progress) / 2;
5823				}
5824				return (2 - delta(2 * (1 - progress))) / 2;
5825			};
5826		}
5827		static makeEaseOut(delta) {
5828			return progress => {
5829				return 1 - delta(1 - progress);
5830			};
5831		}
5832		static get transitions() {
5833			return Transition;
5834		}
5835	}
5836
5837	class LocalStorage {
5838		#prefix = null;
5839		constructor(storageOptions = {}) {
5840			const options = Type.isPlainObject(storageOptions) ? storageOptions : {};
5841			this.#setPrefix(options.prefix);
5842			Event.bind(window, 'storage', this.#handleStorageChange.bind(this));
5843			setInterval(this.#clear.bind(this), 5000);
5844		}
5845		set(key, value, ttl = 60) {
5846			if (!Type.isStringFilled(key) || Type.isNil(value)) {
5847				return false;
5848			}
5849			try {
5850				window.localStorage.setItem(this.getPrefix() + key, `${Math.round(Date.now() / 1000) + ttl}:${this.#encode(value)}`);
5851			} catch {
5852				console.error('LocalStorage error', key, ttl);
5853				return false;
5854			}
5855			return true;
5856		}
5857		get(key) {
5858			const storageValue = window.localStorage.getItem(this.getPrefix() + key);
5859			if (storageValue) {
5860				const valueParts = this.#parseValue(storageValue);
5861				if (valueParts === null) {
5862					return null;
5863				}
5864				const [ttl, value] = valueParts;
5865				if (Date.now() <= ttl) {
5866					return this.#decode(value);
5867				}
5868				this.remove(key);
5869			}
5870			return null;
5871		}
5872		remove(key) {
5873			window.localStorage.removeItem(this.getPrefix() + key);
5874		}
5875		getPrefix() {
5876			if (this.#prefix === null) {
5877				const userId = Loc.hasMessage('USER_ID') ? Loc.getMessage('USER_ID') : '';
5878				const siteId = Loc.hasMessage('SITE_ID') ? Loc.getMessage('SITE_ID') : 'admin';
5879				this.#prefix = `${this.getBasePrefix()}${userId}-${siteId}-`;
5880			}
5881			return this.#prefix;
5882		}
5883		getBasePrefix() {
5884			return 'bx';
5885		}
5886		#setPrefix(prefix) {
5887			if (Type.isString(prefix)) {
5888				this.#prefix = `${this.getBasePrefix()}-${prefix}`;
5889			}
5890		}
5891		#handleStorageChange(event) {
5892			if (!Type.isStringFilled(event.key) || !event.key.startsWith(this.getPrefix())) {
5893				return;
5894			}
5895			const key = event.key.slice(this.getPrefix().length);
5896			const value = this.#getRealValue(event.newValue);
5897			const oldValue = this.#getRealValue(event.oldValue);
5898			const data = {
5899				key,
5900				value,
5901				oldValue
5902			};
5903			if (key === 'BXGCE') {
5904				if (value) {
5905					const val = data.value;
5906					EventEmitter.emit(val.e, new BaseEvent({
5907						data: val.p,
5908						compatData: val.p
5909					}));
5910				}
5911			} else {
5912				if (event.newValue) {
5913					EventEmitter.emit('onLocalStorageSet', new BaseEvent({
5914						data: [data],
5915						compatData: [data]
5916					}));
5917				}
5918				if (event.oldValue && !event.newValue) {
5919					EventEmitter.emit('onLocalStorageRemove', new BaseEvent({
5920						data: [data],
5921						compatData: [data]
5922					}));
5923				}
5924				EventEmitter.emit('onLocalStorageChange', new BaseEvent({
5925					data: [data],
5926					compatData: [data]
5927				}));
5928			}
5929		}
5930		#clear() {
5931			const curDate = Date.now();
5932			for (let i = 0; i < window.localStorage.length; i++) {
5933				const key = window.localStorage.key(i);
5934				if (key !== null && key.startsWith(this.getBasePrefix())) {
5935					const value = window.localStorage.getItem(key);
5936					const valueParts = this.#parseValue(value);
5937					if (valueParts === null) {
5938						continue;
5939					}
5940					const [ttl] = valueParts;
5941					if (curDate >= ttl) {
5942						window.localStorage.removeItem(key);
5943					}
5944				}
5945			}
5946		}
5947		#encode(value) {
5948			if (Type.isJsonValue(value)) {
5949				return JSON.stringify(value);
5950			}
5951			return value.toString();
5952		}
5953		#decode(value) {
5954			let result = null;
5955			if (Type.isStringFilled(value)) {
5956				try {
5957					result = JSON.parse(value);
5958				} catch {
5959					result = value;
5960				}
5961			}
5962			return result;
5963		}
5964		#getRealValue(value) {
5965			const valueParts = this.#parseValue(value);
5966			if (valueParts === null) {
5967				return null;
5968			}
5969			return this.#decode(valueParts[1]);
5970		}
5971		#parseValue(value) {
5972			if (!this.#isValueValid(value)) {
5973				return null;
5974			}
5975			const [ttl] = value.split(':', 1);
5976			const realValue = value.slice(ttl.length + 1);
5977			return [parseInt(ttl, 10) * 1000, realValue];
5978		}
5979		#isValueValid(value) {
5980			return Type.isStringFilled(value) && /^\d{10}:/.test(value);
5981		}
5982	}
5983	const localStorage$1 = new LocalStorage();
5984
5985	class Page {
5986		static getRootWindow() {
5987			return this.getTopWindowOfCurrentHost(window);
5988		}
5989		static isCrossOriginObject(currentWindow) {
5990			try {
5991				void currentWindow.location.host;
5992			} catch {
5993				return true;
5994			}
5995			return false;
5996		}
5997		static getTopWindowOfCurrentHost(currentWindow) {
5998			if (!this.isCrossOriginObject(currentWindow.parent) && currentWindow.parent !== currentWindow && currentWindow.parent.location.host === currentWindow.location.host) {
5999				return this.getTopWindowOfCurrentHost(currentWindow.parent);
6000			}
6001			return currentWindow;
6002		}
6003		static getParentWindowOfCurrentHost(currentWindow) {
6004			if (this.isCrossOriginObject(currentWindow.parent)) {
6005				return currentWindow;
6006			}
6007			return currentWindow.parent;
6008		}
6009		static redirect(redirectUrl, redirectOptions = {}) {
6010			if (!Type.isStringFilled(redirectUrl)) {
6011				throw new Error('Redirect: "url" must be a non-empty string.');
6012			}
6013			const rootWindow = this.getRootWindow();
6014			let url = null;
6015			try {
6016				url = new URL(redirectUrl, rootWindow.location.origin);
6017			} catch {
6018				throw new Error(`Redirect: invalid URL: ${redirectUrl}`);
6019			}
6020			const options = Type.isPlainObject(redirectOptions) ? redirectOptions : {};
6021			if (!this.#isSafeUrl(url, options.allowedOrigins)) {
6022				console.error(`Redirect: blocked potentially unsafe URL: ${url}`);
6023				return;
6024			}
6025			const wholeUrl = url.toString();
6026			if (options.newTab === true) {
6027				const win = rootWindow.open(wholeUrl, '_blank', 'noopener,noreferrer');
6028				if (win) {
6029					win.opener = null;
6030				}
6031				return;
6032			}
6033			if (options.replaceHistory === true) {
6034				rootWindow.location.replace(wholeUrl);
6035			} else {
6036				rootWindow.location.assign(wholeUrl);
6037			}
6038		}
6039		static reload() {
6040			const rootWindow = this.getRootWindow();
6041			rootWindow.location.reload();
6042		}
6043		static #isSafeUrl(url, allowedOrigins = []) {
6044			if (!(url instanceof URL)) {
6045				return false;
6046			}
6047			const allowedProtocols = ['http:', 'https:'];
6048			if (!allowedProtocols.includes(url.protocol)) {
6049				return false;
6050			}
6051			const rootWindow = this.getRootWindow();
6052			if (url.origin === rootWindow.location.origin) {
6053				return true;
6054			}
6055			if (Type.isArray(allowedOrigins) && allowedOrigins.length > 0) {
6056				return allowedOrigins.includes(url.origin);
6057			}
6058			return false;
6059		}
6060	}
6061
6062	function getElement(element) {
6063		if (Type.isString(element)) {
6064			return document.getElementById(element);
6065		}
6066		return element;
6067	}
6068
6069	function getWindow(element) {
6070		if (Type.isElementNode(element)) {
6071			return element.ownerDocument.parentWindow || element.ownerDocument.defaultView || window;
6072		}
6073		if (Type.isDomNode(element)) {
6074			return element.parentWindow || element.defaultView || window;
6075		}
6076		return window;
6077	}
6078
6079	class FX {
6080		#easing = null;
6081		constructor(options) {
6082			const fxOptions = Type.isPlainObject(options) ? options : {};
6083			const callback = Type.isFunction(fxOptions.callback) ? fxOptions.callback : null;
6084			const callbackStart = Type.isFunction(fxOptions.callback_start) ? fxOptions.callback_start : null;
6085			const callbackComplete = Type.isFunction(fxOptions.callback_complete) ? fxOptions.callback_complete : null;
6086			const easingOptions = {
6087				transition: 'linear',
6088				duration: Type.isNumber(fxOptions.time) && fxOptions.time > 0 ? fxOptions.time * 1000 : 1000,
6089				begin: state => {
6090					if (callbackStart !== null) {
6091						callbackStart(Type.isUndefined(state._param) ? state : state._param);
6092					}
6093				},
6094				step: state => {
6095					if (callback !== null) {
6096						callback(Type.isUndefined(state._param) ? state : state._param);
6097					}
6098				},
6099				complete: state => {
6100					if (callbackComplete !== null) {
6101						callbackComplete(Type.isUndefined(state._param) ? state : state._param);
6102					}
6103				}
6104			};
6105			if (Type.isPlainObject(fxOptions.start)) {
6106				easingOptions.start = fxOptions.start;
6107				easingOptions.finish = fxOptions.finish;
6108			} else {
6109				easingOptions.start = {
6110					_param: fxOptions.start
6111				};
6112				easingOptions.finish = {
6113					_param: fxOptions.finish
6114				};
6115			}
6116			if (fxOptions.type === 'accelerated') {
6117				easingOptions.transition = 'quint';
6118			} else if (fxOptions.type === 'decelerated') {
6119				fxOptions.transition = 'ease-out-quint';
6120			}
6121			this.#easing = new Easing(easingOptions);
6122		}
6123		start() {
6124			this.#easing.animate();
6125			return this;
6126		}
6127		stop(silent = false) {
6128			this.#easing.stop(silent);
6129		}
6130		pause() {
6131		}
6132		static hide(el, type, opts) {
6133			return this.#toggle('hide', el, type, opts);
6134		}
6135		static show(el, type, opts) {
6136			return this.#toggle('show', el, type, opts);
6137		}
6138		static #toggle(mode, el, type, opts) {
6139			let options = {};
6140			let effect = null;
6141			const element = Type.isStringFilled(el) ? document.getElementById(el) : el;
6142			if (Type.isPlainObject(type) && Type.isNil(opts)) {
6143				options = type;
6144				effect = options.type;
6145			} else if (Type.isPlainObject(opts)) {
6146				options = opts;
6147				effect = type;
6148			}
6149			if (!Type.isStringFilled(effect)) {
6150				Dom.style(element, 'display', mode === 'show' ? 'block' : 'none');
6151				return undefined;
6152			}
6153			const fxOptions = effect === 'scroll' ? this.#scroll(element, options, mode) : this.#fade(element, options, mode);
6154			fxOptions.callback_complete = () => {
6155				if (options.show !== false && options.hide !== false) {
6156					Dom.style(element, 'display', mode === 'show' ? 'block' : 'none');
6157				}
6158				if (options.callback_complete) {
6159					options.callback_complete();
6160				}
6161			};
6162			return new FX(fxOptions).start();
6163		}
6164		static #scroll(el, opts, mode) {
6165			const param = opts.direction === 'horizontal' ? 'width' : 'height';
6166			let currentValue = parseInt(String(Dom.style(el, param)), 10);
6167			if (Number.isNaN(currentValue)) {
6168				currentValue = Dom.getPosition(el)[param];
6169			}
6170			const start = currentValue;
6171			const finish = opts.min_height ? parseInt(opts.min_height, 10) : 0;
6172			return {
6173				start,
6174				finish,
6175				time: opts.time || 1,
6176				type: 'linear',
6177				callback_start: () => {
6178					if (Dom.style(el, 'position') === 'static') {
6179						Dom.style(el, 'position', 'relative');
6180					}
6181					Dom.style(el, 'overflow', 'hidden');
6182					Dom.style(el, param, `${start}px`);
6183					Dom.style(el, 'display', 'block');
6184				},
6185				callback: value => {
6186					Dom.style(el, param, `${value}px`);
6187				}
6188			};
6189		}
6190		static #fade(element, opts, mode) {
6191			return {
6192				time: opts.time || 1,
6193				type: mode === 'show' ? 'linear' : 'decelerated',
6194				start: mode === 'show' ? 0 : 100,
6195				finish: mode === 'show' ? 100 : 0,
6196				callback_start: () => {
6197					Dom.style(element, 'display', 'block');
6198				},
6199				callback: val => {
6200					Dom.style(element, 'opacity', val / 100);
6201				}
6202			};
6203		}
6204	}
6205
6206	const {
6207		getClass,
6208		namespace
6209	} = Reflection;
6210	const message = message$1;
6211	const easing = Easing;
6212	const fx = FX;
6213	const PageObject = Page;
6214	const {
6215		replace,
6216		remove,
6217		clean,
6218		insertBefore,
6219		insertAfter,
6220		append,
6221		prepend,
6222		style,
6223		adjust,
6224		create,
6225		isShown
6226	} = Dom;
6227	const addClass = function addClass() {
6228		Dom.addClass(...Runtime.merge([], Array.from(arguments), [getElement(arguments[0])]));
6229	};
6230	const removeClass = function removeClass() {
6231		Dom.removeClass(...Runtime.merge(Array.from(arguments), [getElement(arguments[0])]));
6232	};
6233	const hasClass = function hasClass() {
6234		return Dom.hasClass(...Runtime.merge(Array.from(arguments), [getElement(arguments[0])]));
6235	};
6236	const toggleClass = function toggleClass() {
6237		Dom.toggleClass(...Runtime.merge(Array.from(arguments), [getElement(arguments[0])]));
6238	};
6239	const cleanNode = (element, removeElement = false) => {
6240		const currentElement = getElement(element);
6241		if (Type.isDomNode(currentElement)) {
6242			Dom.clean(currentElement);
6243			if (removeElement) {
6244				Dom.remove(currentElement);
6245				return currentElement;
6246			}
6247		}
6248		return currentElement;
6249	};
6250	const getCookie = Http.Cookie.get;
6251	const setCookie = (name, value, options = {}) => {
6252		const attributes = {
6253			...options
6254		};
6255		if (Type.isNumber(attributes.expires)) {
6256			attributes.expires /= 3600 * 24;
6257		}
6258		Http.Cookie.set(name, value, attributes);
6259	};
6260	const {
6261		bind,
6262		unbind,
6263		unbindAll,
6264		bindOnce,
6265		ready
6266	} = Event;
6267	const {
6268		debugState: debugEnableFlag,
6269		isDebugEnabled: debugStatus,
6270		default: debug
6271	} = debugNs;
6272	const debugEnable = value => {
6273		if (value) {
6274			enableDebug();
6275		} else {
6276			disableDebug();
6277		}
6278	};
6279	const {
6280		clone,
6281		loadExtension: loadExt,
6282		debounce,
6283		throttle,
6284		html
6285	} = Runtime;
6286	const type = {
6287		...Object.getOwnPropertyNames(Type).filter(key => !['name', 'length', 'prototype', 'caller', 'arguments'].includes(key)).reduce((acc, key) => {
6288			acc[key] = Type[key];
6289			return acc;
6290		}, {}),
6291		isNotEmptyString: value => Type.isString(value) && value !== '',
6292		isNotEmptyObject: value => Type.isObjectLike(value) && Object.keys(value).length > 0,
6293		isMapKey: Type.isObject,
6294		stringToInt: value => {
6295			const parsed = parseInt(value);
6296			return !Number.isNaN(parsed) ? parsed : 0;
6297		}
6298	};
6299	const browser = {
6300		IsOpera: Browser.isOpera,
6301		IsIE: Browser.isIE,
6302		IsIE6: Browser.isIE6,
6303		IsIE7: Browser.isIE7,
6304		IsIE8: Browser.isIE8,
6305		IsIE9: Browser.isIE9,
6306		IsIE10: Browser.isIE10,
6307		IsIE11: Browser.isIE11,
6308		IsSafari: Browser.isSafari,
6309		IsFirefox: Browser.isFirefox,
6310		IsChrome: Browser.isChrome,
6311		DetectIeVersion: Browser.detectIEVersion,
6312		IsMac: Browser.isMac,
6313		IsAndroid: Browser.isAndroid,
6314		isIPad: Browser.isIPad,
6315		isIPhone: Browser.isIPhone,
6316		IsIOS: Browser.isIOS,
6317		IsMobile: Browser.isMobile,
6318		isRetina: Browser.isRetina,
6319		IsDoctype: Browser.isDoctype,
6320		SupportLocalStorage: Browser.isLocalStorageSupported,
6321		addGlobalClass: Browser.addGlobalClass,
6322		DetectAndroidVersion: Browser.detectAndroidVersion,
6323		isPropertySupported: Browser.isPropertySupported,
6324		addGlobalFeatures: Browser.addGlobalFeatures
6325	};
6326	const ajax = window.BX ? window.BX.ajax : () => {};
6327	function GetWindowScrollSize(doc = document) {
6328		return {
6329			scrollWidth: doc.documentElement.scrollWidth,
6330			scrollHeight: doc.documentElement.scrollHeight
6331		};
6332	}
6333	function GetWindowScrollPos(doc = document) {
6334		const win = getWindow(doc);
6335		return {
6336			scrollLeft: win.pageXOffset,
6337			scrollTop: win.pageYOffset
6338		};
6339	}
6340	function GetWindowInnerSize(doc = document) {
6341		const win = getWindow(doc);
6342		return {
6343			innerWidth: win.innerWidth,
6344			innerHeight: win.innerHeight
6345		};
6346	}
6347	function GetWindowSize(doc = document) {
6348		return {
6349			...GetWindowInnerSize(doc),
6350			...GetWindowScrollPos(doc),
6351			...GetWindowScrollSize(doc)
6352		};
6353	}
6354	function GetContext(node) {
6355		return getWindow(node);
6356	}
6357	function pos(element, relative = false) {
6358		if (!element) {
6359			return new DOMRect().toJSON();
6360		}
6361		if (element.ownerDocument === document && !relative) {
6362			const clientRect = element.getBoundingClientRect();
6363			const root = document.documentElement;
6364			const {
6365				body
6366			} = document;
6367			return {
6368				top: Math.round(clientRect.top + (root.scrollTop || body.scrollTop)),
6369				left: Math.round(clientRect.left + (root.scrollLeft || body.scrollLeft)),
6370				width: Math.round(clientRect.right - clientRect.left),
6371				height: Math.round(clientRect.bottom - clientRect.top),
6372				right: Math.round(clientRect.right + (root.scrollLeft || body.scrollLeft)),
6373				bottom: Math.round(clientRect.bottom + (root.scrollTop || body.scrollTop))
6374			};
6375		}
6376		let x = 0;
6377		let y = 0;
6378		const w = element.offsetWidth;
6379		const h = element.offsetHeight;
6380		let first = true;
6381		for (; element != null; element = element.offsetParent) {
6382			if (!first && relative && window.BX.is_relative(element)) {
6383				break;
6384			}
6385			x += element.offsetLeft;
6386			y += element.offsetTop;
6387			if (first) {
6388				first = false;
6389				continue;
6390			}
6391			x += Text.toNumber(Dom.style(element, 'border-left-width'));
6392			y += Text.toNumber(Dom.style(element, 'border-top-width'));
6393		}
6394		return new DOMRect(x, y, w, h).toJSON();
6395	}
6396	function addCustomEvent(eventObject, eventName, eventHandler) {
6397		if (Type.isString(eventObject)) {
6398			eventHandler = eventName;
6399			eventName = eventObject;
6400			eventObject = EventEmitter.GLOBAL_TARGET;
6401		}
6402		if (eventObject === window) {
6403			eventObject = EventEmitter.GLOBAL_TARGET;
6404		}
6405		if (!Type.isObject(eventObject)) {
6406			console.error('The "eventObject" argument must be an object. Received type ' + typeof eventObject + '.');
6407			return;
6408		}
6409		if (!Type.isStringFilled(eventName)) {
6410			console.error('The "eventName" argument must be a string.');
6411			return;
6412		}
6413		if (!Type.isFunction(eventHandler)) {
6414			console.error('The "eventHandler" argument must be a function. Received type ' + typeof eventHandler + '.');
6415			return;
6416		}
6417		eventName = eventName.toLowerCase();
6418		EventEmitter.subscribe(eventObject, eventName, eventHandler, {
6419			compatMode: true,
6420			useGlobalNaming: true
6421		});
6422	}
6423	function onCustomEvent(eventObject, eventName, eventParams, secureParams) {
6424		if (Type.isString(eventObject)) {
6425			secureParams = eventParams;
6426			eventParams = eventName;
6427			eventName = eventObject;
6428			eventObject = EventEmitter.GLOBAL_TARGET;
6429		}
6430		if (!Type.isObject(eventObject) || eventObject === window) {
6431			eventObject = EventEmitter.GLOBAL_TARGET;
6432		}
6433		if (!eventParams) {
6434			eventParams = [];
6435		}
6436		eventName = eventName.toLowerCase();
6437		const event = new BaseEvent();
6438		event.setData(eventParams);
6439		event.setCompatData(eventParams);
6440		EventEmitter.emit(eventObject, eventName, event, {
6441			cloneData: secureParams === true,
6442			useGlobalNaming: true
6443		});
6444	}
6445	function removeCustomEvent(eventObject, eventName, eventHandler) {
6446		if (Type.isString(eventObject)) {
6447			eventHandler = eventName;
6448			eventName = eventObject;
6449			eventObject = EventEmitter.GLOBAL_TARGET;
6450		}
6451		if (!Type.isFunction(eventHandler)) {
6452			console.error('The "eventHandler" argument must be a function. Received type ' + typeof eventHandler + '.');
6453			return;
6454		}
6455		if (eventObject === window) {
6456			eventObject = EventEmitter.GLOBAL_TARGET;
6457		}
6458		eventName = eventName.toLowerCase();
6459		EventEmitter.unsubscribe(eventObject, eventName, eventHandler, {
6460			useGlobalNaming: true
6461		});
6462	}
6463	function removeAllCustomEvents(eventObject, eventName) {
6464		if (Type.isString(eventObject)) {
6465			eventName = eventObject;
6466			eventObject = EventEmitter.GLOBAL_TARGET;
6467		}
6468		if (eventObject === window) {
6469			eventObject = EventEmitter.GLOBAL_TARGET;
6470		}
6471		eventName = eventName.toLowerCase();
6472		EventEmitter.unsubscribeAll(eventObject, eventName, {
6473			useGlobalNaming: true
6474		});
6475	}
6476	function onGlobalCustomEvent(eventName, arEventParams, bSkipSelf) {
6477		localStorage$1.set('BXGCE', {
6478			e: eventName,
6479			p: arEventParams
6480		}, 1);
6481		if (!bSkipSelf) {
6482			onCustomEvent(eventName, arEventParams);
6483		}
6484	}
6485
6486	exports.BaseError = BaseError;
6487	exports.Browser = Browser;
6488	exports.Cache = Cache;
6489	exports.Collections = collections;
6490	exports.Dom = Dom;
6491	exports.Easing = Easing;
6492	exports.Event = Event;
6493	exports.Extension = Extension;
6494	exports.GetContext = GetContext;
6495	exports.GetWindowInnerSize = GetWindowInnerSize;
6496	exports.GetWindowScrollPos = GetWindowScrollPos;
6497	exports.GetWindowScrollSize = GetWindowScrollSize;
6498	exports.GetWindowSize = GetWindowSize;
6499	exports.Http = Http;
6500	exports.Loc = Loc;
6501	exports.LocalStorage = LocalStorage;
6502	exports.Page = Page;
6503	exports.PageObject = PageObject;
6504	exports.Reflection = Reflection;
6505	exports.Runtime = Runtime;
6506	exports.Tag = Tag;
6507	exports.Text = Text;
6508	exports.Type = Type;
6509	exports.Uri = Uri;
6510	exports.Validation = Validation;
6511	exports.ZIndexManager = ZIndexManager;
6512	exports.addClass = addClass;
6513	exports.addCustomEvent = addCustomEvent;
6514	exports.adjust = adjust;
6515	exports.ajax = ajax;
6516	exports.append = append;
6517	exports.bind = bind;
6518	exports.bindOnce = bindOnce;
6519	exports.browser = browser;
6520	exports.clean = clean;
6521	exports.cleanNode = cleanNode;
6522	exports.clone = clone;
6523	exports.create = create;
6524	exports.debounce = debounce;
6525	exports.debug = debug;
6526	exports.debugEnable = debugEnable;
6527	exports.debugEnableFlag = debugEnableFlag;
6528	exports.debugStatus = debugStatus;
6529	exports.easing = easing;
6530	exports.fx = fx;
6531	exports.getClass = getClass;
6532	exports.getCookie = getCookie;
6533	exports.hasClass = hasClass;
6534	exports.html = html;
6535	exports.insertAfter = insertAfter;
6536	exports.insertBefore = insertBefore;
6537	exports.isShown = isShown;
6538	exports.loadExt = loadExt;
6539	exports.localStorage = localStorage$1;
6540	exports.message = message;
6541	exports.namespace = namespace;
6542	exports.onCustomEvent = onCustomEvent;
6543	exports.onGlobalCustomEvent = onGlobalCustomEvent;
6544	exports.pos = pos;
6545	exports.prepend = prepend;
6546	exports.ready = ready;
6547	exports.remove = remove;
6548	exports.removeAllCustomEvents = removeAllCustomEvents;
6549	exports.removeClass = removeClass;
6550	exports.removeCustomEvent = removeCustomEvent;
6551	exports.replace = replace;
6552	exports.setCookie = setCookie;
6553	exports.style = style;
6554	exports.throttle = throttle;
6555	exports.toggleClass = toggleClass;
6556	exports.type = type;
6557	exports.unbind = unbind;
6558	exports.unbindAll = unbindAll;
6559
6560})(this.BX = this.BX || {});
6561
6562
6563
6564(function(BX) {
6565	/* list of registered proxy functions */
6566	var proxyList = new WeakMap();
6567	var deferList = new WeakMap();
6568
6569	/* List of denied event handlers */
6570	var deniedEvents = [];
6571
6572	/* list of registered custom events */
6573	var customEvents = new WeakMap();
6574	var customEventsCnt = 0;
6575
6576	/* list of external garbage collectors */
6577	var garbageCollectors = [];
6578
6579	/* list of loaded CSS files */
6580	var cssList = [];
6581	var cssInit = false;
6582
6583	/* list of loaded JS files */
6584	var jsList = [];
6585	var jsInit = false;
6586
6587	var eventTypes = {
6588		click: 'MouseEvent',
6589		dblclick: 'MouseEvent',
6590		mousedown: 'MouseEvent',
6591		mousemove: 'MouseEvent',
6592		mouseout: 'MouseEvent',
6593		mouseover: 'MouseEvent',
6594		mouseup: 'MouseEvent',
6595		focus: 'MouseEvent',
6596		blur: 'MouseEvent'
6597	};
6598
6599	var lastWait = [];
6600
6601	var CHECK_FORM_ELEMENTS = {tagName: /^INPUT|SELECT|TEXTAREA|BUTTON$/i};
6602
6603	BX.MSLEFT = 1;
6604	BX.MSMIDDLE = 2;
6605	BX.MSRIGHT = 4;
6606
6607	BX.AM_PM_UPPER = 1;
6608	BX.AM_PM_LOWER = 2;
6609	BX.AM_PM_NONE = false;
6610
6611	BX.ext = function(ob)
6612	{
6613		for (var i in ob)
6614		{
6615			if(ob.hasOwnProperty(i))
6616			{
6617				this[i] = ob[i];
6618			}
6619		}
6620	};
6621
6622	var r = {
6623		script: /<script([^>]*)>/ig,
6624		script_end: /<\/script>/ig,
6625		script_src: /src=["\']([^"\']+)["\']/i,
6626		script_type: /type=["\']([^"\']+)["\']/i,
6627		space: /\s+/,
6628		ltrim: /^[\s\r\n]+/g,
6629		rtrim: /[\s\r\n]+$/g,
6630		style: /<link[^>]*?(rel="stylesheet"|type="text\/css")[^>]*>/i,
6631		style_href: /href=["\']([^"\']+)["\']/i
6632	};
6633
6634	BX.processHTML = function(data, scriptsRunFirst)
6635	{
6636		var matchScript, matchStyle, matchSrc, matchHref, matchType, scripts = [], styles = [];
6637		var textIndexes = [];
6638		var lastIndex = r.script.lastIndex = r.script_end.lastIndex = 0;
6639
6640		while ((matchScript = r.script.exec(data)) !== null)
6641		{
6642			r.script_end.lastIndex = r.script.lastIndex;
6643			var matchScriptEnd = r.script_end.exec(data);
6644			if (matchScriptEnd === null)
6645			{
6646				break;
6647			}
6648
6649			// skip script tags of special types
6650			var skipTag = false;
6651			if ((matchType = matchScript[1].match(r.script_type)) !== null)
6652			{
6653				if(
6654					matchType[1] == 'text/html'
6655					|| matchType[1] == 'text/template'
6656					|| matchType[1] == 'extension/settings'
6657				)
6658				{
6659					skipTag = true;
6660				}
6661			}
6662
6663			if(skipTag)
6664			{
6665				textIndexes.push([lastIndex, r.script_end.lastIndex - lastIndex]);
6666			}
6667			else
6668			{
6669				textIndexes.push([lastIndex, matchScript.index - lastIndex]);
6670
6671				var bRunFirst = scriptsRunFirst || (matchScript[1].indexOf('bxrunfirst') != '-1');
6672
6673				if ((matchSrc = matchScript[1].match(r.script_src)) !== null)
6674				{
6675					scripts.push({"bRunFirst": bRunFirst, "isInternal": false, "JS": matchSrc[1]});
6676				}
6677				else
6678				{
6679					var start = matchScript.index + matchScript[0].length;
6680					var js = data.substr(start, matchScriptEnd.index-start);
6681
6682					scripts.push({"bRunFirst": bRunFirst, "isInternal": true, "JS": js});
6683				}
6684			}
6685
6686			lastIndex = matchScriptEnd.index + 9;
6687			r.script.lastIndex = lastIndex;
6688		}
6689
6690		textIndexes.push([lastIndex, lastIndex === 0 ? data.length : data.length - lastIndex]);
6691		var pureData = "";
6692		for (var i = 0, length = textIndexes.length; i < length; i++)
6693		{
6694			if (BX.type.isString(data) && BX.type.isFunction(data.substr))
6695			{
6696				pureData += data.substr(textIndexes[i][0], textIndexes[i][1]);
6697			}
6698		}
6699
6700		while ((matchStyle = pureData.match(r.style)) !== null)
6701		{
6702			if ((matchHref = matchStyle[0].match(r.style_href)) !== null && matchStyle[0].indexOf('media="') < 0)
6703			{
6704				styles.push(matchHref[1]);
6705			}
6706
6707			pureData = pureData.replace(matchStyle[0], '');
6708		}
6709
6710		return {'HTML': pureData, 'SCRIPT': scripts, 'STYLE': styles};
6711	};
6712
6713	/* OO emulation utility */
6714	BX.extend = function(child, parent)
6715	{
6716		var f = function() {};
6717		f.prototype = parent.prototype;
6718
6719		child.prototype = new f();
6720		child.prototype.constructor = child;
6721
6722		child.superclass = parent.prototype;
6723		child.prototype.superclass = parent.prototype;
6724		if(parent.prototype.constructor == Object.prototype.constructor)
6725		{
6726			parent.prototype.constructor = parent;
6727		}
6728	};
6729
6730	BX.is_subclass_of = function(ob, parent_class)
6731	{
6732		if (ob instanceof parent_class)
6733			return true;
6734
6735		if (parent_class.superclass)
6736			return BX.is_subclass_of(ob, parent_class.superclass);
6737
6738		return false;
6739	};
6740
6741	BX.clearNodeCache = function()
6742	{
6743		return false;
6744	};
6745
6746	BX.bitrix_sessid = function() {return BX.message("bitrix_sessid"); };
6747
6748	/**
6749	 * Creates document fragment with child nodes.
6750	 *
6751	 * @param {Node[]} nodes
6752	 * @return {DocumentFragment}
6753	 */
6754	BX.createFragment = function(nodes)
6755	{
6756		var fragment = document.createDocumentFragment();
6757
6758		if(!BX.type.isArray(nodes))
6759		{
6760			return fragment;
6761		}
6762		for(var i = 0; i < nodes.length; i++)
6763		{
6764			fragment.appendChild(nodes[i]);
6765		}
6766
6767		return fragment;
6768	};
6769
6770	/**
6771	 * @deprecated
6772	 * @use BX.style
6773	 * @param element
6774	 * @param opacity
6775	 */
6776	BX.setOpacity = function(element, opacity)
6777	{
6778		var opacityValue = parseFloat(opacity);
6779
6780		if (!isNaN(opacityValue) && BX.type.isDomNode(element))
6781		{
6782			opacityValue = opacityValue < 1 ? opacityValue : opacityValue / 100;
6783			BX.style(element, 'opacity', opacityValue);
6784		}
6785	};
6786
6787	/**
6788	 * @deprecated
6789	 * @param el
6790	 * @return {*}
6791	 */
6792	BX.hoverEvents = function(el)
6793	{
6794		if (el)
6795			return BX.adjust(el, {events: BX.hoverEvents()});
6796		else
6797			return {mouseover: BX.hoverEventsHover, mouseout: BX.hoverEventsHout};
6798	};
6799
6800	/**
6801	 * @deprecated
6802	 */
6803	BX.hoverEventsHover = function(){BX.addClass(this,'bx-hover');this.BXHOVER=true;};
6804	/**
6805	 * @deprecated
6806	 */
6807	BX.hoverEventsHout = function(){BX.removeClass(this,'bx-hover');this.BXHOVER=false;};
6808
6809	/**
6810	 * @deprecated
6811	 */
6812	BX.focusEvents = function(el)
6813	{
6814		if (el)
6815			return BX.adjust(el, {events: BX.focusEvents()});
6816		else
6817			return {mouseover: BX.focusEventsFocus, mouseout: BX.focusEventsBlur};
6818	};
6819
6820	/**
6821	 * @deprecated
6822	 */
6823	BX.focusEventsFocus = function(){BX.addClass(this,'bx-focus');this.BXFOCUS=true;};
6824	/**
6825	 * @deprecated
6826	 */
6827	BX.focusEventsBlur = function(){BX.removeClass(this,'bx-focus');this.BXFOCUS=false;};
6828
6829	BX.setUnselectable = function(node)
6830	{
6831		BX.style(node, {
6832			'userSelect': 'none',
6833			'MozUserSelect': 'none',
6834			'WebkitUserSelect': 'none',
6835			'KhtmlUserSelect': 'none',
6836		});
6837		node.setAttribute('unSelectable', 'on');
6838	};
6839
6840	BX.setSelectable = function(node)
6841	{
6842		BX.style(node, {
6843			'userSelect': null,
6844			'MozUserSelect': null,
6845			'WebkitUserSelect': null,
6846			'KhtmlUserSelect': null,
6847		});
6848		node.removeAttribute('unSelectable');
6849	};
6850
6851	BX.styleIEPropertyName = function(name)
6852	{
6853		if (name == 'float')
6854			name = BX.browser.IsIE() ? 'styleFloat' : 'cssFloat';
6855		else
6856		{
6857			var res = BX.browser.isPropertySupported(name);
6858			if (res)
6859			{
6860				name = res;
6861			}
6862			else
6863			{
6864				var reg = /(\-([a-z]){1})/g;
6865				if (reg.test(name))
6866				{
6867					name = name.replace(reg, function () {return arguments[2].toUpperCase();});
6868				}
6869			}
6870		}
6871		return name;
6872	};
6873
6874	BX.focus = function(el)
6875	{
6876		try
6877		{
6878			el.focus();
6879			return true;
6880		}
6881		catch (e)
6882		{
6883			return false;
6884		}
6885	};
6886
6887	BX.firstChild = function(el)
6888	{
6889		return BX.type.isDomNode(el) ? el.firstElementChild : null;
6890	};
6891
6892	BX.lastChild = function(el)
6893	{
6894		return BX.type.isDomNode(el) ? el.lastElementChild : null;
6895	};
6896
6897	BX.previousSibling = function(el)
6898	{
6899		return BX.type.isDomNode(el) ? el.previousElementSibling : null;
6900	};
6901
6902	BX.nextSibling = function(el)
6903	{
6904		return BX.type.isDomNode(el) ? el.nextElementSibling : null;
6905	};
6906
6907	/*
6908		params: {
6909			obj : html node
6910			className : className value
6911			recursive : used only for older browsers to optimize the tree traversal, in new browsers the search is always recursively, default - true
6912		}
6913
6914		Search all nodes with className
6915	*/
6916	/**
6917	 * @deprecated
6918	 * @use .querySelectorAll
6919	 * @param obj
6920	 * @param className
6921	 * @param recursive
6922	 * @return {*}
6923	 */
6924	BX.findChildrenByClassName = function(obj, className, recursive)
6925	{
6926		if(!obj || !obj.childNodes) return null;
6927
6928		var result = [];
6929		if (typeof(obj.getElementsByClassName) == 'undefined')
6930		{
6931			recursive = recursive !== false;
6932			result = BX.findChildren(obj, {className : className}, recursive);
6933		}
6934		else
6935		{
6936			var col = obj.getElementsByClassName(className);
6937			for (i=0,l=col.length;i<l;i++)
6938			{
6939				result[i] = col[i];
6940			}
6941		}
6942		return result;
6943	};
6944
6945	/*
6946		params: {
6947			obj : html node
6948			className : className value
6949			recursive : used only for older browsers to optimize the tree traversal, in new browsers the search is always recursively, default - true
6950		}
6951
6952		Search first node with className
6953	*/
6954	/**
6955	 * @deprecated
6956	 * @use .querySelector
6957	 * @param obj
6958	 * @param className
6959	 * @param recursive
6960	 * @return {*}
6961	 */
6962	BX.findChildByClassName = function(obj, className, recursive)
6963	{
6964		if(!obj || !obj.childNodes) return null;
6965
6966		var result = null;
6967		if (typeof(obj.getElementsByClassName) == 'undefined')
6968		{
6969			recursive = recursive !== false;
6970			result = BX.findChild(obj, {className : className}, recursive);
6971		}
6972		else
6973		{
6974			var col = obj.getElementsByClassName(className);
6975			if (col && typeof(col[0]) != 'undefined')
6976			{
6977				result = col[0];
6978			}
6979			else
6980			{
6981				result = null;
6982			}
6983		}
6984		return result;
6985	};
6986
6987	/*
6988		params: {
6989			tagName|tag : 'tagName',
6990			className|class : 'className',
6991			attribute : {attribute : value, attribute : value} | attribute | [attribute, attribute....],
6992			property : {prop: value, prop: value} | prop | [prop, prop]
6993		}
6994
6995		all values can be RegExps or strings
6996	*/
6997	/**
6998	 * @deprecated
6999	 * @use .querySelectorAll
7000	 * @param obj
7001	 * @param params
7002	 * @param recursive
7003	 * @return {*|Node}
7004	 */
7005	BX.findChildren = function(obj, params, recursive)
7006	{
7007		return BX.findChild(obj, params, recursive, true);
7008	};
7009
7010	/**
7011	 * @deprecated
7012	 * @use .querySelectorAll
7013	 * @param obj
7014	 * @param params
7015	 * @param recursive
7016	 * @param get_all
7017	 * @return {*}
7018	 */
7019	BX.findChild = function(obj, params, recursive, get_all)
7020	{
7021		if(!obj || !obj.childNodes) return null;
7022
7023		recursive = !!recursive; get_all = !!get_all;
7024
7025		var n = obj.childNodes.length, result = [];
7026
7027		for (var j=0; j<n; j++)
7028		{
7029			var child = obj.childNodes[j];
7030
7031			if (_checkNode(child, params))
7032			{
7033				if (get_all)
7034					result.push(child);
7035				else
7036					return child;
7037			}
7038
7039			if(recursive == true)
7040			{
7041				var res = BX.findChild(child, params, recursive, get_all);
7042				if (res)
7043				{
7044					if (get_all)
7045						result = BX.util.array_merge(result, res);
7046					else
7047						return res;
7048				}
7049			}
7050		}
7051
7052		if (get_all || result.length > 0)
7053			return result;
7054		else
7055			return null;
7056	};
7057
7058	/**
7059	 * @deprecated
7060	 * @use .closest()
7061	 * @param obj
7062	 * @param params
7063	 * @param maxParent
7064	 * @return {*}
7065	 */
7066	BX.findParent = function(obj, params, maxParent)
7067	{
7068		if(!obj)
7069			return null;
7070
7071		var o = obj;
7072		while(o.parentNode)
7073		{
7074			var parent = o.parentNode;
7075
7076			if (_checkNode(parent, params))
7077				return parent;
7078
7079			o = parent;
7080
7081			if (!!maxParent &&
7082				(BX.type.isFunction(maxParent)
7083					|| typeof maxParent == 'object'))
7084			{
7085				if (BX.type.isElementNode(maxParent))
7086				{
7087					if (o == maxParent)
7088						break;
7089				}
7090				else
7091				{
7092					if (_checkNode(o, maxParent))
7093						break;
7094				}
7095			}
7096		}
7097		return null;
7098	};
7099
7100	/**
7101	 * @deprecated
7102	 * @use .querySelector
7103	 * @param obj
7104	 * @param params
7105	 * @return {*}
7106	 */
7107	BX.findNextSibling = function(obj, params)
7108	{
7109		if(!obj)
7110			return null;
7111		var o = obj;
7112		while(o.nextSibling)
7113		{
7114			var sibling = o.nextSibling;
7115			if (_checkNode(sibling, params))
7116				return sibling;
7117			o = sibling;
7118		}
7119		return null;
7120	};
7121
7122	/**
7123	 * @deprecated
7124	 * @use .querySelector
7125	 * @param obj
7126	 * @param params
7127	 * @return {*}
7128	 */
7129	BX.findPreviousSibling = function(obj, params)
7130	{
7131		if(!obj)
7132			return null;
7133
7134		var o = obj;
7135		while(o.previousSibling)
7136		{
7137			var sibling = o.previousSibling;
7138			if(_checkNode(sibling, params))
7139				return sibling;
7140			o = sibling;
7141		}
7142		return null;
7143	};
7144
7145	BX.checkNode = function(obj, params)
7146	{
7147		return _checkNode(obj, params);
7148	};
7149
7150	/**
7151	 * @deprecated
7152	 * @use .querySelectorAll
7153	 * @param form
7154	 * @return {Array}
7155	 */
7156	BX.findFormElements = function(form)
7157	{
7158		if (BX.type.isString(form))
7159			form = document.forms[form]||BX(form);
7160
7161		var res = [];
7162
7163		if (BX.type.isElementNode(form))
7164		{
7165			if (form.tagName.toUpperCase() == 'FORM')
7166			{
7167				res = form.elements;
7168			}
7169			else
7170			{
7171				res = BX.findChildren(form, CHECK_FORM_ELEMENTS, true);
7172			}
7173		}
7174
7175		return res;
7176	};
7177
7178	/**
7179	 * @deprecated
7180	 * @use .contains()
7181	 * @param whichNode
7182	 * @param forNode
7183	 * @return {boolean}
7184	 */
7185	BX.isParentForNode = function(whichNode, forNode)
7186	{
7187		if (BX.type.isDomNode(whichNode) && BX.type.isDomNode(forNode))
7188		{
7189			return whichNode.contains(forNode);
7190		}
7191
7192		return false;
7193	};
7194
7195	BX.getCaretPosition = function(node)
7196	{
7197		var pos = 0;
7198
7199		if(node.selectionStart || node.selectionStart == 0)
7200		{
7201			pos = node.selectionStart;
7202		}
7203		else if(document.selection)
7204		{
7205			node.focus();
7206			var selection = document.selection.createRange();
7207			selection.moveStart('character', -node.value.length);
7208			pos = selection.text.length;
7209		}
7210
7211		return (pos);
7212	};
7213
7214	BX.setCaretPosition = function(node, pos)
7215	{
7216		if(!BX.isNodeInDom(node) || BX.isNodeHidden(node) || node.disabled)
7217		{
7218			return;
7219		}
7220
7221		if(node.setSelectionRange)
7222		{
7223			node.focus();
7224			node.setSelectionRange(pos, pos);
7225		}
7226		else if(node.createTextRange)
7227		{
7228			var range = node.createTextRange();
7229			range.collapse(true);
7230			range.moveEnd('character', pos);
7231			range.moveStart('character', pos);
7232			range.select();
7233		}
7234	};
7235
7236	// access private. use BX.mergeEx instead.
7237	// todo: refactor BX.merge, make it work through BX.mergeEx
7238	BX.merge = function(){
7239		var arg = Array.prototype.slice.call(arguments);
7240
7241		if(arg.length < 2)
7242			return {};
7243
7244		var result = arg.shift();
7245
7246		for(var i = 0; i < arg.length; i++)
7247		{
7248			for(var k in arg[i]){
7249
7250				if(typeof arg[i] == 'undefined' || arg[i] == null)
7251					continue;
7252
7253				if(arg[i].hasOwnProperty(k)){
7254
7255					if(typeof arg[i][k] == 'undefined' || arg[i][k] == null)
7256						continue;
7257
7258					if(typeof arg[i][k] == 'object' && !BX.type.isDomNode(arg[i][k]) && (typeof arg[i][k]['isUIWidget'] == 'undefined')){
7259
7260						// go deeper
7261
7262						var isArray = 'length' in arg[i][k];
7263
7264						if(typeof result[k] != 'object')
7265							result[k] = isArray ? [] : {};
7266
7267						if(isArray)
7268							BX.util.array_merge(result[k], arg[i][k]);
7269						else
7270							BX.merge(result[k], arg[i][k]);
7271
7272					}else
7273						result[k] = arg[i][k];
7274				}
7275			}
7276		}
7277
7278		return result;
7279	};
7280
7281	BX.mergeEx = function()
7282	{
7283		var arg = Array.prototype.slice.call(arguments);
7284		if(arg.length < 2)
7285		{
7286			return {};
7287		}
7288
7289		var result = arg.shift();
7290		for (var i = 0; i < arg.length; i++)
7291		{
7292			for (var k in arg[i])
7293			{
7294				if (typeof arg[i] == "undefined" || arg[i] == null || !arg[i].hasOwnProperty(k))
7295				{
7296					continue;
7297				}
7298
7299				if (BX.type.isPlainObject(arg[i][k]) && BX.type.isPlainObject(result[k]))
7300				{
7301					BX.mergeEx(result[k], arg[i][k]);
7302				}
7303				else
7304				{
7305					result[k] = BX.type.isPlainObject(arg[i][k]) ? BX.clone(arg[i][k]) : arg[i][k];
7306				}
7307			}
7308		}
7309
7310		return result;
7311	};
7312
7313	BX.getEventButton = function(e)
7314	{
7315		e = e || window.event;
7316
7317		var flags = 0;
7318
7319		if (typeof e.which != 'undefined')
7320		{
7321			switch (e.which)
7322			{
7323				case 1: flags = flags|BX.MSLEFT; break;
7324				case 2: flags = flags|BX.MSMIDDLE; break;
7325				case 3: flags = flags|BX.MSRIGHT; break;
7326			}
7327		}
7328		else if (typeof e.button != 'undefined')
7329		{
7330			flags = event.button;
7331		}
7332
7333		return flags || BX.MSLEFT;
7334	};
7335
7336	var captured_events = null, _bind = null;
7337	BX.CaptureEvents = function(el_c, evname_c)
7338	{
7339		if (_bind)
7340			return;
7341
7342		_bind = BX.bind;
7343		captured_events = [];
7344
7345		BX.bind = function(el, evname, func)
7346		{
7347			if (el === el_c && evname === evname_c)
7348				captured_events.push(func);
7349
7350			_bind.apply(this, arguments);
7351		}
7352	};
7353
7354	BX.CaptureEventsGet = function()
7355	{
7356		if (_bind)
7357		{
7358			BX.bind = _bind;
7359
7360			var captured = captured_events;
7361
7362			_bind = null;
7363			captured_events = null;
7364			return captured;
7365		}
7366		return null;
7367	};
7368
7369	// Don't even try to use it for submit event!
7370	BX.fireEvent = function(ob,ev)
7371	{
7372		var result = false, e = null;
7373		if (BX.type.isDomNode(ob))
7374		{
7375			result = true;
7376			if (document.createEventObject)
7377			{
7378				// IE
7379				if (eventTypes[ev] != 'MouseEvent')
7380				{
7381					e = document.createEventObject();
7382					e.type = ev;
7383					result = ob.fireEvent('on' + ev, e);
7384				}
7385
7386				if (ob[ev])
7387				{
7388					ob[ev]();
7389				}
7390			}
7391			else
7392			{
7393				// non-IE
7394				e = null;
7395
7396				switch (eventTypes[ev])
7397				{
7398					case 'MouseEvent':
7399						e = document.createEvent('MouseEvent');
7400						try
7401						{
7402							e.initMouseEvent(ev, true, true, top, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, null);
7403						}
7404						catch (initException)
7405						{
7406							e.initMouseEvent(ev, true, true, window, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, null);
7407						}
7408
7409					break;
7410					default:
7411						e = document.createEvent('Event');
7412						e.initEvent(ev, true, true);
7413				}
7414
7415				result = ob.dispatchEvent(e);
7416			}
7417		}
7418
7419		return result;
7420	};
7421
7422	BX.getWheelData = function(e)
7423	{
7424		e = e || window.event;
7425		e.wheelData = e.detail ? e.detail * -1 : e.wheelDelta / 40;
7426		return e.wheelData;
7427	};
7428
7429	BX.proxy_context = null;
7430
7431	BX.delegate = function (func, thisObject)
7432	{
7433		if (!func || !thisObject)
7434			return func;
7435
7436		return function() {
7437			var cur = BX.proxy_context;
7438			BX.proxy_context = this;
7439			var res = func.apply(thisObject, arguments);
7440			BX.proxy_context = cur;
7441			return res;
7442		}
7443	};
7444
7445	BX.delegateLater = function (func_name, thisObject, contextObject)
7446	{
7447		return function()
7448		{
7449			if (thisObject[func_name])
7450			{
7451				var cur = BX.proxy_context;
7452				BX.proxy_context = this;
7453				var res = thisObject[func_name].apply(contextObject||thisObject, arguments);
7454				BX.proxy_context = cur;
7455				return res;
7456			}
7457			return null;
7458		}
7459	};
7460
7461	BX.proxy = function(func, thisObject)
7462	{
7463		return getObjectDelegate(func, thisObject, proxyList);
7464	};
7465
7466	BX.defer = function(func, thisObject)
7467	{
7468		if (!!thisObject)
7469			return BX.defer_proxy(func, thisObject);
7470		else
7471			return function() {
7472				var arg = arguments;
7473				setTimeout(function(){func.apply(this,arg)}, 10);
7474			};
7475	};
7476
7477	BX.defer_proxy = function(func, thisObject)
7478	{
7479		return getObjectDelegate(func, thisObject, deferList, BX.defer);
7480	};
7481
7482	/**
7483	 *
7484	 * @private
7485	 */
7486	function getObjectDelegate(func, thisObject, collection, decorator)
7487	{
7488		if (!BX.type.isFunction(func) || !BX.type.isMapKey(thisObject))
7489		{
7490			return func;
7491		}
7492
7493		var objectDelegates = collection.get(thisObject);
7494		if (!objectDelegates)
7495		{
7496			objectDelegates = new WeakMap();
7497			collection.set(thisObject, objectDelegates);
7498		}
7499
7500		var delegate = objectDelegates.get(func);
7501		if (!delegate)
7502		{
7503			delegate = decorator ? decorator(BX.delegate(func, thisObject)) : BX.delegate(func, thisObject);
7504			objectDelegates.set(func, delegate);
7505		}
7506
7507		return delegate;
7508	}
7509
7510	BX.once = function(el, evname, func)
7511	{
7512		var fn = function()
7513		{
7514			BX.unbind(el, evname, fn);
7515			func.apply(this, arguments);
7516		};
7517
7518		return fn;
7519	};
7520
7521	BX.bindDelegate = function (elem, eventName, isTarget, handler)
7522	{
7523		var h = BX.delegateEvent(isTarget, handler);
7524		BX.bind(elem, eventName, h);
7525		return h;
7526	};
7527
7528	BX.delegateEvent = function(isTarget, handler)
7529	{
7530		return function(e)
7531		{
7532			e = e || window.event;
7533			var target = e.target || e.srcElement;
7534
7535			while (target != this)
7536			{
7537				if (_checkNode(target, isTarget))
7538				{
7539					return handler.call(target, e);
7540				}
7541				if (target && target.parentNode)
7542					target = target.parentNode;
7543				else
7544					break;
7545			}
7546			return null;
7547		}
7548	};
7549
7550	BX.False = function() {return false;};
7551	BX.DoNothing = function() {};
7552
7553	// TODO: also check event handlers set via BX.bind()
7554	BX.denyEvent = function(el, ev)
7555	{
7556		deniedEvents.push([el, ev, el['on' + ev]]);
7557		el['on' + ev] = BX.DoNothing;
7558	};
7559
7560	BX.allowEvent = function(el, ev)
7561	{
7562		for(var i=0, len=deniedEvents.length; i<len; i++)
7563		{
7564			if (deniedEvents[i][0] == el && deniedEvents[i][1] == ev)
7565			{
7566				el['on' + ev] = deniedEvents[i][2];
7567				BX.util.deleteFromArray(deniedEvents, i);
7568				return;
7569			}
7570		}
7571	};
7572
7573	BX.fixEventPageXY = function(event)
7574	{
7575		BX.fixEventPageX(event);
7576		BX.fixEventPageY(event);
7577		return event;
7578	};
7579
7580	BX.fixEventPageX = function(event)
7581	{
7582		if (event.pageX == null && event.clientX != null)
7583		{
7584			event.pageX =
7585				event.clientX +
7586				(document.documentElement && document.documentElement.scrollLeft || document.body && document.body.scrollLeft || 0) -
7587				(document.documentElement.clientLeft || 0);
7588		}
7589
7590		return event;
7591	};
7592
7593	BX.fixEventPageY = function(event)
7594	{
7595		if (event.pageY == null && event.clientY != null)
7596		{
7597			event.pageY =
7598				event.clientY +
7599				(document.documentElement && document.documentElement.scrollTop || document.body && document.body.scrollTop || 0) -
7600				(document.documentElement.clientTop || 0);
7601		}
7602
7603		return event;
7604	};
7605
7606	/**
7607	 * @deprecated
7608	 * @see e.preventDefault()
7609	 */
7610	BX.PreventDefault = function(e)
7611	{
7612		if(!e) e = window.event;
7613		if(e.stopPropagation)
7614		{
7615			e.preventDefault();
7616			e.stopPropagation();
7617		}
7618		else
7619		{
7620			e.cancelBubble = true;
7621			e.returnValue = false;
7622		}
7623		return false;
7624	};
7625
7626	/**
7627	 * @deprecated
7628	 * @see e.preventDefault();
7629	 *
7630	 * @param e
7631	 * @return {boolean}
7632	 */
7633	BX.eventReturnFalse = function(e)
7634	{
7635		e=e||window.event;
7636		if (e && e.preventDefault) e.preventDefault();
7637		else e.returnValue = false;
7638		return false;
7639	};
7640
7641	/**
7642	 * @deprecated
7643	 * @see e.stopPropagation()
7644	 * @param e
7645	 */
7646	BX.eventCancelBubble = function(e)
7647	{
7648		e=e||window.event;
7649		if(e && e.stopPropagation)
7650			e.stopPropagation();
7651		else
7652			e.cancelBubble = true;
7653	};
7654
7655	BX.bindDebouncedChange = function(node, fn, fnInstant, timeout, ctx)
7656	{
7657		ctx = ctx || window;
7658		timeout = timeout || 300;
7659
7660		var dataTag = 'bx-dc-previous-value';
7661		BX.data(node, dataTag, node.value);
7662
7663		var act = function(fn, val){
7664
7665			var pVal = BX.data(node, dataTag);
7666
7667			if(typeof pVal == 'undefined' || pVal != val){
7668				if(typeof ctx != 'object')
7669					fn(val);
7670				else
7671					fn.apply(ctx, [val]);
7672			}
7673		};
7674
7675		var actD = BX.debounce(function(){
7676			var val = node.value;
7677			act(fn, val);
7678			BX.data(node, dataTag, val);
7679		}, timeout);
7680
7681		BX.bind(node, 'keyup', actD);
7682		BX.bind(node, 'change', actD);
7683		BX.bind(node, 'input', actD);
7684
7685		if(BX.type.isFunction(fnInstant)){
7686
7687			var actI = function(){
7688				act(fnInstant, node.value);
7689			};
7690
7691			BX.bind(node, 'keyup', actI);
7692			BX.bind(node, 'change', actI);
7693			BX.bind(node, 'input', actI);
7694		}
7695	};
7696
7697	BX.parseJSON = function(data, context)
7698	{
7699		var result = null;
7700		if (BX.type.isNotEmptyString(data))
7701		{
7702			try {
7703				if (data.indexOf("\n") >= 0)
7704					eval('result = ' + data);
7705				else
7706					result = (new Function("return " + data))();
7707			} catch(e) {
7708				BX.onCustomEvent(context, 'onParseJSONFailure', [data, context])
7709			}
7710		}
7711		else if(BX.type.isPlainObject(data))
7712		{
7713			return data;
7714		}
7715
7716		return result;
7717	};
7718
7719	BX.submit = function(obForm, action_name, action_value, onAfterSubmit)
7720	{
7721		action_name = action_name || 'save';
7722		if (!obForm['BXFormSubmit_' + action_name])
7723		{
7724			obForm['BXFormSubmit_' + action_name] = obForm.appendChild(BX.create('INPUT', {
7725				'props': {
7726					'type': 'submit',
7727					'name': action_name,
7728					'value': action_value || 'Y'
7729				},
7730				'style': {
7731					'display': 'none'
7732				}
7733			}));
7734		}
7735
7736		if (obForm.sessid)
7737			obForm.sessid.value = BX.bitrix_sessid();
7738
7739		setTimeout(BX.delegate(function() {BX.fireEvent(this, 'click'); if (onAfterSubmit) onAfterSubmit();}, obForm['BXFormSubmit_' + action_name]), 10);
7740	};
7741
7742	BX.show = function(ob, displayType)
7743	{
7744		if (ob.BXDISPLAY || !_checkDisplay(ob, displayType))
7745		{
7746			ob.style.display = ob.BXDISPLAY;
7747		}
7748	};
7749
7750	BX.hide = function(ob, displayType)
7751	{
7752		if (!ob.BXDISPLAY)
7753			_checkDisplay(ob, displayType);
7754
7755		ob.style.display = 'none';
7756	};
7757
7758	BX.toggle = function(ob, values)
7759	{
7760		if (!values && BX.type.isElementNode(ob))
7761		{
7762			var bShow = true;
7763			if (ob.BXDISPLAY)
7764				bShow = !_checkDisplay(ob);
7765			else
7766				bShow = ob.style.display == 'none';
7767
7768			if (bShow)
7769				BX.show(ob);
7770			else
7771				BX.hide(ob);
7772		}
7773		else if (BX.type.isArray(values))
7774		{
7775			for (var i=0,len=values.length; i<len; i++)
7776			{
7777				if (ob == values[i])
7778				{
7779					ob = values[i==len-1 ? 0 : i+1];
7780					break;
7781				}
7782			}
7783			if (i==len)
7784				ob = values[0];
7785		}
7786
7787		return ob;
7788	};
7789
7790	function _checkDisplay(ob, displayType)
7791	{
7792		if (typeof displayType != 'undefined')
7793			ob.BXDISPLAY = displayType;
7794
7795		var d = ob.style.display || BX.style(ob, 'display');
7796		if (d != 'none')
7797		{
7798			ob.BXDISPLAY = ob.BXDISPLAY || d;
7799			return true;
7800		}
7801		else
7802		{
7803			ob.BXDISPLAY = ob.BXDISPLAY || 'block';
7804			return false;
7805		}
7806	}
7807
7808	/* some useful util functions */
7809
7810	BX.util = {
7811		/**
7812		 * @deprecated
7813		 * @use [].filter(value => !BX.Type.isNil(value))
7814		 * @param ar
7815		 * @return {*}
7816		 */
7817		array_values: function(ar)
7818		{
7819			if (!BX.type.isArray(ar))
7820				return BX.util._array_values_ob(ar);
7821			var arv = [];
7822			for(var i=0,l=ar.length;i<l;i++)
7823				if (ar[i] !== null && typeof ar[i] != 'undefined')
7824					arv.push(ar[i]);
7825			return arv;
7826		},
7827
7828		/**
7829		 * @deprecated
7830		 * @use Object.values([]).filter(value => !BX.Type.isNil(value))
7831		 * @param ar
7832		 * @return {Array}
7833		 * @private
7834		 */
7835		_array_values_ob: function(ar)
7836		{
7837			var arv = [];
7838			for(var i in ar)
7839				if (ar[i] !== null && typeof ar[i] != 'undefined')
7840					arv.push(ar[i]);
7841			return arv;
7842		},
7843
7844		/**
7845		 * @deprecated
7846		 * @use
7847		 * @param ar
7848		 * @return {*}
7849		 */
7850		array_keys: function(ar)
7851		{
7852			if (!BX.type.isArray(ar))
7853				return BX.util._array_keys_ob(ar);
7854			var arv = [];
7855			for(var i=0,l=ar.length;i<l;i++)
7856				if (ar[i] !== null && typeof ar[i] != 'undefined')
7857					arv.push(i);
7858			return arv;
7859		},
7860
7861		_array_keys_ob: function(ar)
7862		{
7863			var arv = [];
7864			for(var i in ar)
7865				if (ar[i] !== null && typeof ar[i] != 'undefined')
7866					arv.push(i);
7867			return arv;
7868		},
7869
7870		object_keys: function(obj)
7871		{
7872			var arv = [];
7873			for(var k in obj)
7874			{
7875				if(obj.hasOwnProperty(k))
7876				{
7877					arv.push(k);
7878				}
7879			}
7880			return arv;
7881		},
7882
7883		/**
7884		 * @deprecated
7885		 * @use firstArr.concat(secondArr);
7886		 * @param first
7887		 * @param second
7888		 * @return {*[]}
7889		 */
7890		array_merge: function(first, second)
7891		{
7892			if (!BX.type.isArray(first)) first = [];
7893			if (!BX.type.isArray(second)) second = [];
7894
7895			var i = first.length, j = 0;
7896
7897			if (typeof second.length === "number")
7898			{
7899				for (var l = second.length; j < l; j++)
7900				{
7901					first[i++] = second[j];
7902				}
7903			}
7904			else
7905			{
7906				while (second[j] !== undefined)
7907				{
7908					first[i++] = second[j++];
7909				}
7910			}
7911
7912			first.length = i;
7913
7914			return first;
7915		},
7916
7917		array_flip: function (object)
7918		{
7919			var newObject = {};
7920
7921			for (var key in object)
7922			{
7923				newObject[object[key]] = key;
7924			}
7925
7926			return newObject;
7927		},
7928
7929		array_diff: function(ar1, ar2, hash)
7930		{
7931			hash = BX.type.isFunction(hash) ? hash : null;
7932			var i, length, v, h, map = {}, result = [];
7933			for(i = 0, length = ar2.length; i < length; i++)
7934			{
7935				v = ar2[i];
7936				h = hash ? hash(v) : v;
7937				map[h] = true;
7938			}
7939
7940			for(i = 0, length = ar1.length; i < length; i++)
7941			{
7942				v = ar1[i];
7943				h = hash ? hash(v) : v;
7944				if(typeof(map[h]) === "undefined")
7945				{
7946					result.push(v);
7947				}
7948			}
7949			return result;
7950		},
7951
7952		/**
7953		 * @deprecated
7954		 * @use Set
7955		 */
7956		array_unique: function(ar)
7957		{
7958			var i=0,j,len=ar.length;
7959			if(len<2) return ar;
7960
7961			for (; i<len-1;i++)
7962			{
7963				for (j=i+1; j<len;j++)
7964				{
7965					if (ar[i]==ar[j])
7966					{
7967						ar.splice(j--,1); len--;
7968					}
7969				}
7970			}
7971
7972			return ar;
7973		},
7974
7975		/**
7976		 * @deprecated
7977		 * @use myArr.includes(needle)
7978		 */
7979		in_array: function(needle, haystack)
7980		{
7981			for(var i=0; i<haystack.length; i++)
7982			{
7983				if(haystack[i] == needle)
7984					return true;
7985			}
7986			return false;
7987		},
7988
7989		/**
7990		 * @deprecated
7991		 * @use myArr.findIndex(item => item === needle);
7992		 */
7993		array_search: function(needle, haystack)
7994		{
7995			for(var i=0; i<haystack.length; i++)
7996			{
7997				if(haystack[i] == needle)
7998					return i;
7999			}
8000			return -1;
8001		},
8002
8003		object_search_key: function(needle, haystack)
8004		{
8005			if (typeof haystack[needle] != 'undefined')
8006				return haystack[needle];
8007
8008			for(var i in haystack)
8009			{
8010				if (typeof haystack[i] == "object")
8011				{
8012					var result = BX.util.object_search_key(needle, haystack[i]);
8013					if (result !== false)
8014						return result;
8015				}
8016			}
8017			return false;
8018		},
8019
8020		trim: function(s)
8021		{
8022			if (BX.type.isString(s))
8023			{
8024				return s.trim();
8025			}
8026
8027			return s;
8028		},
8029
8030		urlencode: function(s){return encodeURIComponent(s);},
8031
8032		// it may also be useful. via sVD.
8033		deleteFromArray: function(ar, ind) {return ar.slice(0, ind).concat(ar.slice(ind + 1));},
8034		insertIntoArray: function(ar, ind, el) {return ar.slice(0, ind).concat([el]).concat(ar.slice(ind));},
8035
8036		htmlspecialchars: function(str)
8037		{
8038			return BX.Text.encode(str);
8039		},
8040
8041		htmlspecialcharsback: function(str)
8042		{
8043			return BX.Text.decode(str);
8044		},
8045
8046		// Quote regular expression characters plus an optional character
8047		preg_quote: function(str, delimiter)
8048		{
8049			if(!str.replace)
8050				return str;
8051			return str.replace(new RegExp('[.\\\\+*?\\[\\^\\]$(){}=!<>|:\\' + (delimiter || '') + '-]', 'g'), '\\$&');
8052		},
8053
8054		jsencode: function(str)
8055		{
8056			if (!str || !str.replace)
8057				return str;
8058
8059			var escapes =
8060				[
8061					{ c: "\\\\", r: "\\\\" }, // should be first
8062					{ c: "\\t", r: "\\t" },
8063					{ c: "\\n", r: "\\n" },
8064					{ c: "\\r", r: "\\r" },
8065					{ c: "\"", r: "\\\"" },
8066					{ c: "'", r: "\\'" },
8067					{ c: "<", r: "\\x3C" },
8068					{ c: ">", r: "\\x3E" },
8069					{ c: "\\u2028", r: "\\u2028" },
8070					{ c: "\\u2029", r: "\\u2029" }
8071				];
8072			for (var i = 0; i < escapes.length; i++)
8073				str = str.replace(new RegExp(escapes[i].c, 'g'), escapes[i].r);
8074			return str;
8075		},
8076
8077		getCssName: function(jsName)
8078		{
8079			if (!BX.type.isNotEmptyString(jsName))
8080			{
8081				return "";
8082			}
8083
8084			return jsName.replace(/[A-Z]/g, function(match) {
8085				return "-" + match.toLowerCase();
8086			});
8087		},
8088
8089		getJsName: function(cssName)
8090		{
8091			var regex = /\-([a-z]){1}/g;
8092			if (regex.test(cssName))
8093			{
8094				return cssName.replace(regex, function(match, letter) {
8095					return letter.toUpperCase();
8096				});
8097			}
8098
8099			return cssName;
8100		},
8101
8102		nl2br: function(str)
8103		{
8104			if (!str || !str.replace)
8105				return str;
8106
8107			return str.replace(/([^>])\n/g, '$1<br/>');
8108		},
8109
8110		/**
8111		 * @deprecated
8112		 * @use .padStart() / .padEnd()
8113		 * @param input
8114		 * @param pad_length
8115		 * @param pad_string
8116		 * @param pad_type
8117		 * @return {*}
8118		 */
8119		str_pad: function(input, pad_length, pad_string, pad_type)
8120		{
8121			pad_string = pad_string || ' ';
8122			pad_type = pad_type || 'right';
8123			input = input.toString();
8124
8125			if (pad_type === 'left')
8126			{
8127				return BX.util.str_pad_left(input, pad_length, pad_string);
8128			}
8129
8130			return BX.util.str_pad_right(input, pad_length, pad_string);
8131		},
8132
8133		str_pad_left: function(input, pad_length, pad_string)
8134		{
8135			return input.toString().padStart(pad_length, pad_string);
8136		},
8137
8138		str_pad_right: function(input, pad_length, pad_string)
8139		{
8140			return input.toString().padEnd(pad_length, pad_string);
8141		},
8142
8143		strip_tags: function(str)
8144		{
8145			return str.split(/<[^>]+>/g).join('');
8146		},
8147
8148		strip_php_tags: function(str)
8149		{
8150			return str.replace(/<\?(.|[\r\n])*?\?>/g, '');
8151		},
8152
8153		popup: function(url, width, height)
8154		{
8155			var w, h;
8156			if(BX.browser.IsOpera())
8157			{
8158				w = document.body.offsetWidth;
8159				h = document.body.offsetHeight;
8160			}
8161			else
8162			{
8163				w = screen.width;
8164				h = screen.height;
8165			}
8166			return window.open(url, '', 'status=no,scrollbars=yes,resizable=yes,width='+width+',height='+height+',top='+Math.floor((h - height)/2-14)+',left='+Math.floor((w - width)/2-5));
8167		},
8168
8169		shuffle: function(array)
8170		{
8171			var temporaryValue, randomIndex;
8172			var currentIndex = array.length;
8173
8174			while (0 !== currentIndex)
8175			{
8176				randomIndex = Math.floor(Math.random() * currentIndex);
8177				currentIndex -= 1;
8178
8179				temporaryValue = array[currentIndex];
8180				array[currentIndex] = array[randomIndex];
8181				array[randomIndex] = temporaryValue;
8182			}
8183
8184			return array;
8185		},
8186
8187		// BX.util.objectSort(object, sortBy, sortDir) - Sort object by property
8188		// function params: 1 - object for sort, 2 - sort by property, 3 - sort direction (asc/desc)
8189		// return: sort array [[objectElement], [objectElement]] in sortDir direction
8190
8191		// example: BX.util.objectSort({'L1': {'name': 'Last'}, 'F1': {'name': 'First'}}, 'name', 'asc');
8192		// return: [{'name' : 'First'}, {'name' : 'Last'}]
8193		objectSort: function(object, sortBy, sortDir)
8194		{
8195			sortDir = sortDir == 'asc'? 'asc': 'desc';
8196
8197			var arItems = [], i;
8198			for (i in object)
8199			{
8200				if (object.hasOwnProperty(i) && object[i][sortBy])
8201				{
8202					arItems.push([i, object[i][sortBy]]);
8203				}
8204			}
8205
8206			if (sortDir == 'asc')
8207			{
8208				arItems.sort(function(i, ii) {
8209					var s1, s2;
8210					if (BX.type.isDate(i[1]))
8211					{
8212						s1 = i[1].getTime();
8213					}
8214					else if (!isNaN(i[1]))
8215					{
8216						s1 = parseInt(i[1]);
8217					}
8218					else
8219					{
8220						s1 = i[1].toString().toLowerCase();
8221					}
8222
8223					if (BX.type.isDate(ii[1]))
8224					{
8225						s2 = ii[1].getTime();
8226					}
8227					else if (!isNaN(ii[1]))
8228					{
8229						s2 = parseInt(ii[1]);
8230					}
8231					else
8232					{
8233						s2 = ii[1].toString().toLowerCase();
8234					}
8235
8236					if (s1 > s2)
8237						return 1;
8238					else if (s1 < s2)
8239						return -1;
8240					else
8241						return 0;
8242				});
8243			}
8244			else
8245			{
8246				arItems.sort(function(i, ii) {
8247					var s1, s2;
8248					if (BX.type.isDate(i[1]))
8249					{
8250						s1 = i[1].getTime();
8251					}
8252					else if (!isNaN(i[1]))
8253					{
8254						s1 = parseInt(i[1]);
8255					}
8256					else
8257					{
8258						s1 = i[1].toString().toLowerCase();
8259					}
8260
8261					if (BX.type.isDate(ii[1]))
8262					{
8263						s2 = ii[1].getTime();
8264					}
8265					else if (!isNaN(ii[1]))
8266					{
8267						s2 = parseInt(ii[1]);
8268					}
8269					else
8270					{
8271						s2 = ii[1].toString().toLowerCase();
8272					}
8273
8274					if (s1 < s2)
8275						return 1;
8276					else if (s1 > s2)
8277						return -1;
8278					else
8279						return 0;
8280				});
8281			}
8282
8283			var arReturnArray = Array();
8284			for (i = 0; i < arItems.length; i++)
8285			{
8286				arReturnArray.push(object[arItems[i][0]]);
8287			}
8288
8289			return arReturnArray;
8290		},
8291
8292		objectMerge: function()
8293		{
8294			return BX.mergeEx.apply(window, arguments);
8295		},
8296
8297		objectClone : function(object)
8298		{
8299			return BX.clone(object, true);
8300		},
8301
8302		// #fdf9e5 => {r=253, g=249, b=229}
8303		hex2rgb: function(color)
8304		{
8305			var rgb = color.replace(/[# ]/g,"").replace(/^(.)(.)(.)$/,'$1$1$2$2$3$3').match(/.{2}/g);
8306			for (var i=0;  i<3; i++)
8307			{
8308				rgb[i] = parseInt(rgb[i], 16);
8309			}
8310			return {'r':rgb[0],'g':rgb[1],'b':rgb[2]};
8311		},
8312
8313		/**
8314		 * @deprecated
8315		 * @use BX.Uri
8316		 * @param url
8317		 * @param param
8318		 * @return {string}
8319		 */
8320		remove_url_param: function(url, param)
8321		{
8322			return BX.Uri.removeParam(url, param);
8323		},
8324
8325		/*
8326		{'param1': 'value1', 'param2': 'value2'}
8327		 */
8328		/**
8329		 * @deprecated
8330		 * @use BX.Uri
8331		 * @param url
8332		 * @param params
8333		 * @return {string}
8334		 */
8335		add_url_param: function(url, params)
8336		{
8337			var preparedParams = Object.entries(params).reduce(function(acc, item) {
8338				acc[item[0]] = BX.type.isArray(item[1]) ? item[1].join() : item[1];
8339				return acc;
8340			}, {});
8341
8342			return BX.Uri.addParam(url, preparedParams);
8343		},
8344
8345		/*
8346	{'param1': 'value1', 'param2': 'value2'}
8347	 */
8348		buildQueryString: function(params)
8349		{
8350			var result = '';
8351			for (var key in params)
8352			{
8353				var value = params[key];
8354				if(BX.type.isArray(value))
8355				{
8356					value.forEach(function(valueElement, index)
8357					{
8358						result += encodeURIComponent(key + "[" + index + "]") + "=" + encodeURIComponent(valueElement) + "&";
8359					});
8360				}
8361				else
8362				{
8363					result += encodeURIComponent(key) + "=" + encodeURIComponent(value) + "&";
8364				}
8365			}
8366
8367			if(result.length > 0)
8368			{
8369				result = result.substr(0, result.length - 1);
8370			}
8371			return result;
8372		},
8373
8374		even: function(digit)
8375		{
8376			return (parseInt(digit) % 2 == 0);
8377		},
8378
8379		hashCode: function(str)
8380		{
8381			if(!BX.type.isNotEmptyString(str))
8382			{
8383				return 0;
8384			}
8385
8386			var hash = 0;
8387			for (var i = 0; i < str.length; i++)
8388			{
8389				var c = str.charCodeAt(i);
8390				hash = ((hash << 5) - hash) + c;
8391				hash = hash & hash;
8392			}
8393			return hash;
8394		},
8395
8396		getRandomString: function (length)
8397		{
8398			return BX.Text.getRandom(length);
8399		},
8400
8401		number_format: function(number, decimals, dec_point, thousands_sep)
8402		{
8403			var i, j, kw, kd, km, sign = '';
8404			decimals = Math.abs(decimals);
8405			if (isNaN(decimals) || decimals < 0)
8406			{
8407				decimals = 2;
8408			}
8409			dec_point = dec_point || ',';
8410			if (typeof thousands_sep === 'undefined')
8411				thousands_sep = '.';
8412
8413			number = (+number || 0).toFixed(decimals);
8414			if (number < 0)
8415			{
8416				sign = '-';
8417				number = -number;
8418			}
8419
8420			i = parseInt(number, 10) + '';
8421			j = (i.length > 3 ? i.length % 3 : 0);
8422
8423			km = (j ? i.substr(0, j) + thousands_sep : '');
8424			kw = i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + thousands_sep);
8425			kd = (decimals ? dec_point + Math.abs(number - i).toFixed(decimals).replace(/-/, '0').slice(2) : '');
8426
8427			return sign + km + kw + kd;
8428		},
8429
8430		getExtension: function (url)
8431		{
8432			url = url || "";
8433			var items = url.split("?")[0].split(".");
8434			return items[items.length-1].toLowerCase();
8435		},
8436		addObjectToForm: function(object, form, prefix)
8437		{
8438			if(!BX.type.isString(prefix))
8439			{
8440				prefix = "";
8441			}
8442
8443			for(var key in object)
8444			{
8445				if(!object.hasOwnProperty(key))
8446				{
8447					continue;
8448				}
8449
8450				var value = object[key];
8451				var name = prefix !== "" ? (prefix + "[" + key + "]") : key;
8452				if(BX.type.isArray(value))
8453				{
8454					var obj = {};
8455					for(var i = 0; i < value.length; i++)
8456					{
8457						obj[i] = value[i];
8458					}
8459
8460					BX.util.addObjectToForm(obj, form, name);
8461				}
8462				else if(BX.type.isPlainObject(value))
8463				{
8464					BX.util.addObjectToForm(value, form, name);
8465				}
8466				else
8467				{
8468					value = BX.type.isFunction(value.toString) ? value.toString() : "";
8469					if(value !== "")
8470					{
8471						form.appendChild(BX.create("INPUT", { attrs: { type: "hidden", name: name, value: value } }));
8472					}
8473				}
8474			}
8475		},
8476
8477		observe: function(object, enable)
8478		{
8479			console.error('BX.util.observe: function is no longer supported by browser.');
8480			return false;
8481		},
8482
8483		escapeRegExp: function(str)
8484		{
8485			return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
8486		}
8487	};
8488
8489	BX.validation = {
8490		checkIfEmail: function(s)
8491		{
8492			var atom = "[=a-z0-9_+~'!$&*^`|#%/?{}-]";
8493			return (new RegExp('^\\s*'+atom+'+(\\.'+atom+'+)*@([a-z0-9-]+\\.)+[a-z0-9-]{2,20}\\s*$', 'i')).test(s);
8494		},
8495		checkIfPhone: function(s)
8496		{
8497			var regexp = new RegExp(
8498				typeof(BX.PhoneNumber) === "undefined"
8499					? BX.PhoneNumber.getValidNumberPattern()
8500					: '^\\s*\\+?\s*[0-9(-)\\s]+\\s*$',
8501				'i'
8502			);
8503			return regexp.test(s);
8504		}
8505	};
8506
8507	BX.prop =
8508		{
8509			get: function(object, key, defaultValue)
8510			{
8511				return object && object.hasOwnProperty(key) ? object[key] : defaultValue;
8512			},
8513			getObject: function(object, key, defaultValue)
8514			{
8515				return object && BX.type.isPlainObject(object[key]) ? object[key] : defaultValue;
8516			},
8517			getElementNode: function(object, key, defaultValue)
8518			{
8519				return object && BX.type.isElementNode(object[key]) ? object[key] : defaultValue;
8520			},
8521			getArray: function(object, key, defaultValue)
8522			{
8523				return object && BX.type.isArray(object[key]) ? object[key] : defaultValue;
8524			},
8525			getFunction: function(object, key, defaultValue)
8526			{
8527				return object && BX.type.isFunction(object[key]) ? object[key] : defaultValue;
8528			},
8529			getNumber: function(object, key, defaultValue)
8530			{
8531				if(!(object && object.hasOwnProperty(key)))
8532				{
8533					return defaultValue;
8534				}
8535
8536				var value = object[key];
8537				if(BX.type.isNumber(value))
8538				{
8539					return value;
8540				}
8541
8542				value = parseFloat(value);
8543				return !isNaN(value) ? value : defaultValue;
8544			},
8545			getInteger: function(object, key, defaultValue)
8546			{
8547				if(!(object && object.hasOwnProperty(key)))
8548				{
8549					return defaultValue;
8550				}
8551
8552				var value = object[key];
8553				if(BX.type.isNumber(value))
8554				{
8555					return value;
8556				}
8557
8558				value = parseInt(value);
8559				return !isNaN(value) ? value : defaultValue;
8560			},
8561			getBoolean: function(object, key, defaultValue)
8562			{
8563				if(!(object && object.hasOwnProperty(key)))
8564				{
8565					return defaultValue;
8566				}
8567
8568				var value = object[key];
8569				return (BX.type.isBoolean(value)
8570						? value
8571						: (BX.type.isString(value) ? (value.toLowerCase() === "true") : !!value)
8572				);
8573			},
8574			getString: function(object, key, defaultValue)
8575			{
8576				if(!(object && object.hasOwnProperty(key)))
8577				{
8578					return defaultValue;
8579				}
8580
8581				var value = object[key];
8582				return BX.type.isString(value) ? value : (value ? value.toString() : '');
8583			},
8584			extractDate: function(datetime)
8585			{
8586				if(!BX.type.isDate(datetime))
8587				{
8588					datetime = new Date();
8589				}
8590
8591				datetime.setHours(0);
8592				datetime.setMinutes(0);
8593				datetime.setSeconds(0);
8594				datetime.setMilliseconds(0);
8595
8596				return datetime;
8597			}
8598		};
8599
8600	BX.isNodeInDom = function(node, doc)
8601	{
8602		return node === (doc || document) ? true :
8603			(node.parentNode ? BX.isNodeInDom(node.parentNode) : false);
8604	};
8605
8606	BX.isNodeHidden = function(node)
8607	{
8608		if (node === document)
8609			return false;
8610		else if (BX.style(node, 'display') == 'none')
8611			return true;
8612		else
8613			return (node.parentNode ? BX.isNodeHidden(node.parentNode) : true);
8614	};
8615
8616	BX.evalPack = function(code)
8617	{
8618		while (code.length > 0)
8619		{
8620			var c = code.shift();
8621
8622			if (c.TYPE == 'SCRIPT_EXT' || c.TYPE == 'SCRIPT_SRC')
8623			{
8624				BX.loadScript(c.DATA, function() {BX.evalPack(code)});
8625				return;
8626			}
8627			else if (c.TYPE == 'SCRIPT')
8628			{
8629				BX.evalGlobal(c.DATA);
8630			}
8631		}
8632	};
8633
8634	BX.evalGlobal = function(data)
8635	{
8636		if (data)
8637		{
8638			var head = document.getElementsByTagName("head")[0] || document.documentElement,
8639				script = document.createElement("script");
8640
8641			script.type = "text/javascript";
8642
8643			if (!BX.browser.IsIE())
8644			{
8645				script.appendChild(document.createTextNode(data));
8646			}
8647			else
8648			{
8649				script.text = data;
8650			}
8651
8652			head.insertBefore(script, head.firstChild);
8653			head.removeChild(script);
8654		}
8655	};
8656
8657	BX.garbage = function(call, thisObject)
8658	{
8659		garbageCollectors.push({callback: call, context: thisObject});
8660	};
8661
8662	BX.GetDocElement = function (pDoc)
8663	{
8664		pDoc = pDoc || document;
8665		return (BX.browser.IsDoctype(pDoc) ? pDoc.documentElement : pDoc.body);
8666	};
8667
8668	BX.scrollTop = function(node, val){
8669		if(typeof val != 'undefined'){
8670
8671			if(node == window){
8672				throw new Error('scrollTop() for window is not implemented');
8673			}else
8674				node.scrollTop = parseInt(val);
8675
8676		}else{
8677
8678			if(node == window)
8679				return BX.GetWindowScrollPos().scrollTop;
8680
8681			return node.scrollTop;
8682		}
8683	};
8684
8685	BX.scrollLeft = function(node, val){
8686		if(typeof val != 'undefined'){
8687
8688			if(node == window){
8689				throw new Error('scrollLeft() for window is not implemented');
8690			}else
8691				node.scrollLeft = parseInt(val);
8692
8693		}else{
8694
8695			if(node == window)
8696				return BX.GetWindowScrollPos().scrollLeft;
8697
8698			return node.scrollLeft;
8699		}
8700	};
8701
8702	BX.hide_object = function(ob)
8703	{
8704		ob = BX(ob);
8705		ob.style.position = 'absolute';
8706		ob.style.top = '-1000px';
8707		ob.style.left = '-1000px';
8708		ob.style.height = '10px';
8709		ob.style.width = '10px';
8710	};
8711
8712	BX.is_relative = function(el)
8713	{
8714		var p = BX.style(el, 'position');
8715		return p == 'relative' || p == 'absolute';
8716	};
8717
8718	BX.is_float = function(el)
8719	{
8720		var p = BX.style(el, 'float');
8721		return p == 'right' || p == 'left';
8722	};
8723
8724	BX.is_fixed = function(el)
8725	{
8726		var p = BX.style(el, 'position');
8727		return p == 'fixed';
8728	};
8729
8730	BX.width = function(node, val){
8731		if(typeof val != 'undefined')
8732			BX.style(node, 'width', parseInt(val)+'px');
8733		else{
8734
8735			if(node == window)
8736				return window.innerWidth;
8737
8738			//return parseInt(BX.style(node, 'width'));
8739			return BX.pos(node).width;
8740		}
8741	};
8742
8743	BX.height = function(node, val){
8744		if(typeof val != 'undefined')
8745			BX.style(node, 'height', parseInt(val)+'px');
8746		else{
8747
8748			if(node == window)
8749				return window.innerHeight;
8750
8751			//return parseInt(BX.style(node, 'height'));
8752			return BX.pos(node).height;
8753		}
8754	};
8755
8756	BX.align = function(pos, w, h, type)
8757	{
8758		if (type)
8759			type = type.toLowerCase();
8760		else
8761			type = '';
8762
8763		var pDoc = document;
8764		if (BX.type.isElementNode(pos))
8765		{
8766			pDoc = pos.ownerDocument;
8767			pos = BX.pos(pos);
8768		}
8769
8770		var x = pos["left"], y = pos["bottom"];
8771
8772		var scroll = BX.GetWindowScrollPos(pDoc);
8773		var size = BX.GetWindowInnerSize(pDoc);
8774
8775		if((size.innerWidth + scroll.scrollLeft) - (pos["left"] + w) < 0)
8776		{
8777			if(pos["right"] - w >= 0 )
8778				x = pos["right"] - w;
8779			else
8780				x = scroll.scrollLeft;
8781		}
8782
8783		if(((size.innerHeight + scroll.scrollTop) - (pos["bottom"] + h) < 0) || ~type.indexOf('top'))
8784		{
8785			if(pos["top"] - h >= 0 || ~type.indexOf('top'))
8786				y = pos["top"] - h;
8787			else
8788				y = scroll.scrollTop;
8789		}
8790
8791		return {'left':x, 'top':y};
8792	};
8793
8794	BX.scrollToNode = function(node)
8795	{
8796		var obNode = BX(node);
8797
8798		if (obNode.scrollIntoView)
8799			obNode.scrollIntoView(true);
8800		else
8801		{
8802			var arNodePos = BX.pos(obNode);
8803			window.scrollTo(arNodePos.left, arNodePos.top);
8804		}
8805	};
8806
8807	/* non-xhr loadings */
8808	BX.showWait = function(node, msg)
8809	{
8810		node = BX(node) || document.body || document.documentElement;
8811		msg = msg || BX.message('JS_CORE_LOADING');
8812
8813		var container_id = node.id || Math.random();
8814
8815		var obMsg = node.bxmsg = document.body.appendChild(BX.create('DIV', {
8816			props: {
8817				id: 'wait_' + container_id
8818			},
8819			style: {
8820				background: 'url("/bitrix/js/main/core/images/wait.gif") no-repeat scroll 10px center #fcf7d1',
8821				border: '1px solid #E1B52D',
8822				color: 'black',
8823				fontFamily: 'Verdana,Arial,sans-serif',
8824				fontSize: '11px',
8825				padding: '10px 30px 10px 37px',
8826				position: 'absolute',
8827				textAlign:'center'
8828			},
8829			text: msg
8830		}));
8831
8832		BX.ZIndexManager.register(obMsg);
8833		BX.ZIndexManager.bringToFront(obMsg);
8834
8835		setTimeout(BX.delegate(_adjustWait, node), 10);
8836
8837		lastWait[lastWait.length] = obMsg;
8838		return obMsg;
8839	};
8840
8841	BX.closeWait = function(node, obMsg)
8842	{
8843		if(node && !obMsg)
8844			obMsg = node.bxmsg;
8845		if(node && !obMsg && BX.hasClass(node, 'bx-core-waitwindow'))
8846			obMsg = node;
8847		if(node && !obMsg)
8848			obMsg = BX('wait_' + node.id);
8849		if(!obMsg)
8850			obMsg = lastWait.pop();
8851
8852		if (obMsg && obMsg.parentNode)
8853		{
8854			for (var i=0,len=lastWait.length;i<len;i++)
8855			{
8856				if (obMsg == lastWait[i])
8857				{
8858					lastWait = BX.util.deleteFromArray(lastWait, i);
8859					break;
8860				}
8861			}
8862
8863			BX.ZIndexManager.unregister(obMsg);
8864			obMsg.parentNode.removeChild(obMsg);
8865			if (node) node.bxmsg = null;
8866			BX.cleanNode(obMsg, true);
8867		}
8868	};
8869
8870	BX.setJSList = function(scripts)
8871	{
8872		if (BX.type.isArray(scripts))
8873		{
8874			scripts = scripts.map(function(script) {
8875				return normalizeUrl(script)
8876			});
8877
8878			jsList = jsList.concat(scripts);
8879		}
8880	};
8881
8882	BX.getJSList = function()
8883	{
8884		initJsList();
8885		return jsList;
8886	};
8887
8888	BX.setCSSList = function(cssFiles)
8889	{
8890		if (BX.type.isArray(cssFiles))
8891		{
8892			cssFiles = cssFiles.map(function(cssFile) {
8893				return normalizeUrl(cssFile);
8894			});
8895
8896			cssList = cssList.concat(cssFiles);
8897		}
8898	};
8899
8900	BX.getCSSList = function()
8901	{
8902		initCssList();
8903		return cssList;
8904	};
8905
8906	BX.getJSPath = function(js)
8907	{
8908		return js.replace(/^(http[s]*:)*\/\/[^\/]+/i, '');
8909	};
8910
8911	BX.getCSSPath = function(css)
8912	{
8913		return css.replace(/^(http[s]*:)*\/\/[^\/]+/i, '');
8914	};
8915
8916	BX.getCDNPath = function(path)
8917	{
8918		return path;
8919	};
8920
8921	BX.loadScript = function(script, callback, doc)
8922	{
8923		if (BX.type.isString(script))
8924		{
8925			script = [script];
8926		}
8927
8928		return BX.load(script, callback, doc);
8929	};
8930
8931	BX.loadCSS = function(css, doc, win)
8932	{
8933		if (BX.type.isString(css))
8934		{
8935			css = [css];
8936		}
8937
8938		if (BX.type.isArray(css))
8939		{
8940			css = css.map(function(url) {
8941				return { url: url, ext: "css" }
8942			});
8943
8944			BX.load(css, null, doc);
8945		}
8946	};
8947
8948	const LOADING = 3;
8949	const LOADED = 4;
8950	const assets = {};
8951	const loadingAssetCallbacks = {};
8952
8953	BX.load = function(items, callback, doc, reject)
8954	{
8955		if (!BX.isReady)
8956		{
8957			var _args = arguments;
8958			BX.ready(function() {
8959				BX.load.apply(this, _args);
8960			});
8961
8962			return null;
8963		}
8964
8965		doc = doc || document;
8966
8967		callback = BX.Type.isFunction(callback) ? callback : () => {};
8968
8969		return loadAsync(items, callback, doc, reject);
8970	};
8971
8972	function loadAsync(items, callback, doc, reject)
8973	{
8974		if (!BX.type.isArray(items))
8975		{
8976			callback();
8977
8978			return;
8979		}
8980
8981		function onLoad()
8982		{
8983			const nextAsset = queue.shift();
8984			if (nextAsset)
8985			{
8986				load(nextAsset, onLoad, doc, reject);
8987			}
8988			else if (allLoaded())
8989			{
8990				callback();
8991			}
8992		}
8993
8994		function allLoaded()
8995		{
8996			for (const name in assetMap)
8997			{
8998				if (assetMap[name].state !== LOADED)
8999				{
9000					return false;
9001				}
9002			}
9003
9004			return true;
9005		}
9006
9007		const queue = [];
9008		const assetMap = {};
9009		items.forEach(item => {
9010			const asset = getAsset(item);
9011			if (asset && asset.state !== LOADED)
9012			{
9013				queue.push(asset);
9014				assetMap[asset.name] = asset;
9015			}
9016		});
9017
9018		if (queue.length > 0)
9019		{
9020			const maxParallelLoads = 6;
9021			const parallelLoads = Math.min(queue.length, maxParallelLoads);
9022			const firstPackage = queue.splice(0, parallelLoads);
9023			firstPackage.forEach(asset => {
9024				load(asset, onLoad, doc, reject);
9025			});
9026		}
9027		else
9028		{
9029			callback();
9030		}
9031	}
9032
9033	function load(asset, callback, doc, reject)
9034	{
9035		callback = callback || BX.DoNothing;
9036
9037		if (asset.state === LOADED)
9038		{
9039			callback();
9040			return;
9041		}
9042
9043		if (asset.state === LOADING)
9044		{
9045			if (!BX.Type.isArray(loadingAssetCallbacks[asset.name]))
9046			{
9047				loadingAssetCallbacks[asset.name] = [];
9048			}
9049
9050			loadingAssetCallbacks[asset.name].push(callback);
9051
9052			return;
9053		}
9054
9055		asset.state = LOADING;
9056
9057		const onReject = () => {
9058			delete assets[asset.name];
9059			delete loadingAssetCallbacks[asset.name];
9060			reject();
9061		};
9062
9063		loadAsset(
9064			asset,
9065			function () {
9066				asset.state = LOADED;
9067				callback();
9068				if (BX.Type.isArrayFilled(loadingAssetCallbacks[asset.name]))
9069				{
9070					for (const cb of loadingAssetCallbacks[asset.name])
9071					{
9072						cb();
9073					}
9074				}
9075
9076				delete loadingAssetCallbacks[asset.name];
9077			},
9078			doc,
9079			BX.Type.isFunction(reject) ? onReject : null,
9080		);
9081	}
9082
9083	function loadAsset(asset, callback, doc, reject)
9084	{
9085		callback = callback || BX.DoNothing;
9086
9087		function error(event)
9088		{
9089			window.clearTimeout(asset.errorTimeout);
9090			window.clearTimeout(asset.cssTimeout);
9091			ele.onload = ele.onreadystatechange = ele.onerror = null;
9092			if (BX.Type.isFunction(reject))
9093			{
9094				reject();
9095			}
9096			else
9097			{
9098				callback();
9099			}
9100		}
9101
9102		function process(event)
9103		{
9104			if (ext === "css")
9105			{
9106				cssList.push(normalizeMinUrl(normalizeUrl(asset.url)));
9107			}
9108			else
9109			{
9110				jsList.push(normalizeMinUrl(normalizeUrl(asset.url)));
9111			}
9112
9113			event = event || window.event;
9114			if (event.type === "load" || (/loaded|complete/.test(ele.readyState) && (!doc.documentMode || doc.documentMode < 9)))
9115			{
9116				window.clearTimeout(asset.errorTimeout);
9117				window.clearTimeout(asset.cssTimeout);
9118				ele.onload = ele.onreadystatechange = ele.onerror = null;
9119				callback();
9120			}
9121		}
9122
9123		function isCssLoaded()
9124		{
9125			if (asset.state !== LOADED && asset.cssRetries <= 20)
9126			{
9127				for (var i = 0, l = doc.styleSheets.length; i < l; i++)
9128				{
9129					if (doc.styleSheets[i].href === ele.href)
9130					{
9131						process({"type": "load"});
9132						return;
9133					}
9134				}
9135
9136				asset.cssRetries++;
9137				asset.cssTimeout = window.setTimeout(isCssLoaded, 250);
9138			}
9139		}
9140
9141		let ele = null;
9142		const ext = BX.type.isNotEmptyString(asset.ext) ? asset.ext : BX.util.getExtension(asset.url);
9143
9144		if (ext === "css")
9145		{
9146			ele = doc.createElement("link");
9147			ele.type = "text/" + (asset.type || "css");
9148			ele.rel = "stylesheet";
9149			ele.href = asset.url;
9150
9151			asset.cssRetries = 0;
9152			asset.cssTimeout = window.setTimeout(isCssLoaded, 500);
9153		}
9154		else
9155		{
9156			ele = doc.createElement("script");
9157			ele.type = "text/" + (asset.type || "javascript");
9158			ele.src = asset.url;
9159		}
9160
9161		ele.onload = ele.onreadystatechange = process;
9162		ele.onerror = error;
9163
9164		ele.async = asset.async === true;
9165		ele.defer = false;
9166
9167		asset.errorTimeout = window.setTimeout(function () {
9168			error({type: "timeout"});
9169		}, 7000);
9170
9171		let templateLink = null;
9172		const head = doc.head || doc.getElementsByTagName("head")[0];
9173		if (ext === "css" && (templateLink = getTemplateLink(head)) !== null)
9174		{
9175			templateLink.parentNode.insertBefore(ele, templateLink);
9176		}
9177		else
9178		{
9179			head.insertBefore(ele, head.lastChild);
9180		}
9181	}
9182
9183	function getAsset(item)
9184	{
9185		var asset = {};
9186		if (typeof item === "object")
9187		{
9188			asset = item;
9189			asset.name = asset.name ? asset.name : BX.util.hashCode(item.url);
9190		}
9191		else
9192		{
9193			asset = { name: BX.util.hashCode(item), url : item };
9194		}
9195
9196		var ext = BX.type.isNotEmptyString(asset.ext) ? asset.ext : BX.util.getExtension(asset.url);
9197		if ((ext === "css" && isCssLoaded(asset.url)) || isScriptLoaded(asset.url))
9198		{
9199			asset.state = LOADED;
9200		}
9201
9202		var existing = assets[asset.name];
9203		if (existing && existing.url === asset.url)
9204		{
9205			return existing;
9206		}
9207
9208		assets[asset.name] = asset;
9209
9210		return asset;
9211	}
9212
9213	function normalizeUrl(url)
9214	{
9215		if (!BX.type.isNotEmptyString(url))
9216		{
9217			return "";
9218		}
9219
9220		url = BX.getJSPath(url);
9221		url = url.replace(/\?[0-9]*$/, "");
9222
9223		return url;
9224	}
9225
9226	function normalizeMinUrl(url)
9227	{
9228		if (!BX.type.isNotEmptyString(url))
9229		{
9230			return "";
9231		}
9232
9233		var minPos = url.indexOf(".min");
9234		return minPos >= 0 ? url.substr(0, minPos) + url.substr(minPos + 4) : url;
9235	}
9236
9237	function isCssLoaded(fileSrc)
9238	{
9239		initCssList();
9240
9241		fileSrc = normalizeUrl(fileSrc);
9242		var fileSrcMin = normalizeMinUrl(fileSrc);
9243
9244		return (fileSrc !== fileSrcMin && BX.util.in_array(fileSrcMin, cssList)) || BX.util.in_array(fileSrc, cssList);
9245	}
9246
9247	function initCssList()
9248	{
9249		if(!cssInit)
9250		{
9251			var linksCol = document.getElementsByTagName('link');
9252
9253			if(!!linksCol && linksCol.length > 0)
9254			{
9255				for(var i = 0; i < linksCol.length; i++)
9256				{
9257					var href = linksCol[i].getAttribute('href');
9258					if (BX.type.isNotEmptyString(href))
9259					{
9260						href = normalizeMinUrl(normalizeUrl(href));
9261						cssList.push(href);
9262					}
9263				}
9264			}
9265			cssInit = true;
9266		}
9267	}
9268
9269	function getTemplateLink(head)
9270	{
9271		var findLink = function(tag)
9272		{
9273			var links = head.getElementsByTagName(tag);
9274			for (var i = 0, length = links.length; i < length; i++)
9275			{
9276				var templateStyle = links[i].getAttribute("data-template-style");
9277				if (BX.type.isNotEmptyString(templateStyle) && templateStyle == "true")
9278				{
9279					return links[i];
9280				}
9281			}
9282
9283			return null;
9284		};
9285
9286		var link = findLink("link");
9287		if (link === null)
9288		{
9289			link = findLink("style");
9290		}
9291
9292		return link;
9293	}
9294
9295	function isScriptLoaded(fileSrc)
9296	{
9297		initJsList();
9298
9299		fileSrc = normalizeUrl(fileSrc);
9300		var fileSrcMin = normalizeMinUrl(fileSrc);
9301
9302		return (fileSrc !== fileSrcMin && BX.util.in_array(fileSrcMin, jsList)) || BX.util.in_array(fileSrc, jsList);
9303	}
9304
9305	function initJsList()
9306	{
9307		if(!jsInit)
9308		{
9309			var scriptCol = document.getElementsByTagName('script');
9310
9311			if(!!scriptCol && scriptCol.length > 0)
9312			{
9313				for(var i=0; i<scriptCol.length; i++)
9314				{
9315					var src = scriptCol[i].getAttribute('src');
9316
9317					if (BX.type.isNotEmptyString(src))
9318					{
9319						src = normalizeMinUrl(normalizeUrl(src));
9320						jsList.push(src);
9321					}
9322				}
9323			}
9324			jsInit = true;
9325		}
9326	}
9327
9328	function reloadInternal(back_url, bAddClearCache)
9329	{
9330		if (back_url === true)
9331		{
9332			bAddClearCache = true;
9333			back_url = null;
9334		}
9335
9336		var topWindow = (function() {
9337			if (BX.PageObject && BX.PageObject.getRootWindow)
9338			{
9339				return BX.PageObject.getRootWindow();
9340			}
9341
9342			return window.top;
9343		})();
9344		var new_href = back_url || topWindow.location.href;
9345
9346		var hashpos = new_href.indexOf('#'), hash = '';
9347
9348		if (hashpos != -1)
9349		{
9350			hash = new_href.substr(hashpos);
9351			new_href = new_href.substr(0, hashpos);
9352		}
9353
9354		if (bAddClearCache && new_href.indexOf('clear_cache=Y') < 0)
9355			new_href += (new_href.indexOf('?') == -1 ? '?' : '&') + 'clear_cache=Y';
9356
9357		if (hash)
9358		{
9359			// hack for clearing cache in ajax mode components with history emulation
9360			if (bAddClearCache && (hash.substr(0, 5) == 'view/' || hash.substr(0, 6) == '#view/') && hash.indexOf('clear_cache%3DY') < 0)
9361				hash += (hash.indexOf('%3F') == -1 ? '%3F' : '%26') + 'clear_cache%3DY';
9362
9363			new_href = new_href.replace(/(\?|\&)_r=[\d]*/, '');
9364			new_href += (new_href.indexOf('?') == -1 ? '?' : '&') + '_r='+Math.round(Math.random()*10000) + hash;
9365		}
9366
9367		topWindow.location.href = new_href;
9368	}
9369
9370	BX.reload = function(back_url, bAddClearCache)
9371	{
9372		reloadInternal(back_url, bAddClearCache);
9373	};
9374
9375	BX.clearCache = function()
9376	{
9377		BX.showWait();
9378		BX.reload(true);
9379	};
9380
9381	BX.template = function(tpl, callback, bKillTpl)
9382	{
9383		BX.ready(function() {
9384			_processTpl(BX(tpl), callback, bKillTpl);
9385		});
9386	};
9387
9388	BX.isAmPmMode = function(returnConst)
9389	{
9390		if (returnConst === true)
9391		{
9392			return BX.message.AMPM_MODE;
9393		}
9394		return BX.message.AMPM_MODE !== false;
9395	};
9396
9397	BX.formatDate = function(date, format)
9398	{
9399		date = date || new Date();
9400
9401		var bTime = date.getHours() || date.getMinutes() || date.getSeconds(),
9402			str = !!format
9403				? format :
9404				(bTime ? BX.message('FORMAT_DATETIME') : BX.message('FORMAT_DATE')
9405				);
9406
9407		return str.replace(/YYYY/ig, date.getFullYear())
9408			.replace(/MMMM/ig, BX.util.str_pad_left((date.getMonth()+1).toString(), 2, '0'))
9409			.replace(/MM/ig, BX.util.str_pad_left((date.getMonth()+1).toString(), 2, '0'))
9410			.replace(/DD/ig, BX.util.str_pad_left(date.getDate().toString(), 2, '0'))
9411			.replace(/HH/ig, BX.util.str_pad_left(date.getHours().toString(), 2, '0'))
9412			.replace(/MI/ig, BX.util.str_pad_left(date.getMinutes().toString(), 2, '0'))
9413			.replace(/SS/ig, BX.util.str_pad_left(date.getSeconds().toString(), 2, '0'));
9414	};
9415	BX.formatName = function(user, template, login)
9416	{
9417		user = user || {};
9418		template = (template || '');
9419		var replacement = {
9420			TITLE : (user["TITLE"] || ''),
9421			NAME : (user["NAME"] || ''),
9422			LAST_NAME : (user["LAST_NAME"] || ''),
9423			SECOND_NAME : (user["SECOND_NAME"] || ''),
9424			LOGIN : (user["LOGIN"] || ''),
9425			NAME_SHORT : user["NAME"] ? user["NAME"].substr(0, 1) + '.' : '',
9426			LAST_NAME_SHORT : user["LAST_NAME"] ? user["LAST_NAME"].substr(0, 1) + '.' : '',
9427			SECOND_NAME_SHORT : user["SECOND_NAME"] ? user["SECOND_NAME"].substr(0, 1) + '.' : '',
9428			EMAIL : (user["EMAIL"] || ''),
9429			ID : (user["ID"] || ''),
9430			NOBR : "",
9431			'/NOBR' : ""
9432		}, result = template;
9433		for (var ii in replacement)
9434		{
9435			if (replacement.hasOwnProperty(ii))
9436			{
9437				result = result.replace("#" + ii+ "#", replacement[ii])
9438			}
9439		}
9440		result = result.replace(/([\s]+)/gi, " ").trim();
9441		if (result == "")
9442		{
9443			result = (login == "Y" ? replacement["LOGIN"] : "");
9444			result = (result == "" ? "Noname" : result);
9445		}
9446		return result;
9447	};
9448
9449	BX.getNumMonth = function(month)
9450	{
9451		var wordMonthCut = ['jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep', 'oct', 'nov', 'dec'];
9452		var wordMonth = ['january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december'];
9453
9454		var q = month.toUpperCase();
9455		for (i = 1; i <= 12; i++)
9456		{
9457			if (q == BX.message('MON_'+i).toUpperCase() || q == BX.message('MONTH_'+i).toUpperCase() || q == wordMonthCut[i-1].toUpperCase() || q == wordMonth[i-1].toUpperCase())
9458			{
9459				return i;
9460			}
9461		}
9462		return month;
9463	};
9464
9465	BX.parseDate = function(str, bUTC, formatDate, formatDatetime)
9466	{
9467		if (BX.type.isNotEmptyString(str))
9468		{
9469			if (!formatDate)
9470				formatDate = BX.message('FORMAT_DATE');
9471			if (!formatDatetime)
9472				formatDatetime = BX.message('FORMAT_DATETIME');
9473
9474			var regMonths = '';
9475			for (i = 1; i <= 12; i++)
9476			{
9477				regMonths = regMonths + '|' + BX.message('MON_'+i);
9478			}
9479
9480			var expr = new RegExp('([0-9]+|[a-z]+' + regMonths + ')', 'ig');
9481			var aDate = str.match(expr),
9482				aFormat = formatDate.match(/(DD|MI|MMMM|MM|M|YYYY)/ig),
9483				i, cnt,
9484				aDateArgs=[], aFormatArgs=[],
9485				aResult={};
9486
9487			if (!aDate)
9488				return null;
9489
9490			if(aDate.length > aFormat.length)
9491			{
9492				aFormat = formatDatetime.match(/(DD|MI|MMMM|MM|M|YYYY|HH|H|SS|TT|T|GG|G)/ig);
9493			}
9494
9495			for(i = 0, cnt = aDate.length; i < cnt; i++)
9496			{
9497				if(BX.util.trim(aDate[i]) != '')
9498				{
9499					aDateArgs[aDateArgs.length] = aDate[i];
9500				}
9501			}
9502
9503			for(i = 0, cnt = aFormat.length; i < cnt; i++)
9504			{
9505				if(BX.util.trim(aFormat[i]) != '')
9506				{
9507					aFormatArgs[aFormatArgs.length] = aFormat[i];
9508				}
9509			}
9510
9511
9512			var m = BX.util.array_search('MMMM', aFormatArgs);
9513			if (m > 0)
9514			{
9515				aDateArgs[m] = BX.getNumMonth(aDateArgs[m]);
9516				aFormatArgs[m] = "MM";
9517			}
9518			else
9519			{
9520				m = BX.util.array_search('M', aFormatArgs);
9521				if (m > 0)
9522				{
9523					aDateArgs[m] = BX.getNumMonth(aDateArgs[m]);
9524					aFormatArgs[m] = "MM";
9525				}
9526			}
9527
9528			for(i = 0, cnt = aFormatArgs.length; i < cnt; i++)
9529			{
9530				var k = aFormatArgs[i].toUpperCase();
9531				aResult[k] = k == 'T' || k == 'TT' ? aDateArgs[i] : parseInt(aDateArgs[i], 10);
9532			}
9533
9534			if(aResult['DD'] > 0 && aResult['MM'] > 0 && aResult['YYYY'] > 0)
9535			{
9536				var d = new Date();
9537
9538				if(bUTC)
9539				{
9540					d.setUTCDate(1);
9541					d.setUTCFullYear(aResult['YYYY']);
9542					d.setUTCMonth(aResult['MM'] - 1);
9543					d.setUTCDate(aResult['DD']);
9544					d.setUTCHours(0, 0, 0, 0);
9545				}
9546				else
9547				{
9548					d.setDate(1);
9549					d.setFullYear(aResult['YYYY']);
9550					d.setMonth(aResult['MM'] - 1);
9551					d.setDate(aResult['DD']);
9552					d.setHours(0, 0, 0, 0);
9553				}
9554
9555				if(
9556					(!isNaN(aResult['HH']) || !isNaN(aResult['GG']) || !isNaN(aResult['H']) || !isNaN(aResult['G']))
9557					&& !isNaN(aResult['MI'])
9558				)
9559				{
9560					if (!isNaN(aResult['H']) || !isNaN(aResult['G']))
9561					{
9562						var bPM = (aResult['T']||aResult['TT']||'am').toUpperCase()=='PM';
9563						var h = parseInt(aResult['H']||aResult['G']||0, 10);
9564						if(bPM)
9565						{
9566							aResult['HH'] = h + (h == 12 ? 0 : 12);
9567						}
9568						else
9569						{
9570							aResult['HH'] = h < 12 ? h : 0;
9571						}
9572					}
9573					else
9574					{
9575						aResult['HH'] = parseInt(aResult['HH']||aResult['GG']||0, 10);
9576					}
9577
9578					if (isNaN(aResult['SS']))
9579						aResult['SS'] = 0;
9580
9581					if(bUTC)
9582					{
9583						d.setUTCHours(aResult['HH'], aResult['MI'], aResult['SS']);
9584					}
9585					else
9586					{
9587						d.setHours(aResult['HH'], aResult['MI'], aResult['SS']);
9588					}
9589				}
9590
9591				return d;
9592			}
9593		}
9594
9595		return null;
9596	};
9597
9598	BX.selectUtils =
9599		{
9600			addNewOption: function(oSelect, opt_value, opt_name, do_sort, check_unique)
9601			{
9602				oSelect = BX(oSelect);
9603				if(oSelect)
9604				{
9605					var n = oSelect.length;
9606					if(check_unique !== false)
9607					{
9608						for(var i=0;i<n;i++)
9609						{
9610							if(oSelect[i].value==opt_value)
9611							{
9612								return;
9613							}
9614						}
9615					}
9616
9617					oSelect.options[n] = new Option(opt_name, opt_value, false, false);
9618				}
9619
9620				if(do_sort === true)
9621				{
9622					this.sortSelect(oSelect);
9623				}
9624			},
9625
9626			deleteOption: function(oSelect, opt_value)
9627			{
9628				oSelect = BX(oSelect);
9629				if(oSelect)
9630				{
9631					for(var i=0;i<oSelect.length;i++)
9632					{
9633						if(oSelect[i].value==opt_value)
9634						{
9635							oSelect.remove(i);
9636							break;
9637						}
9638					}
9639				}
9640			},
9641
9642			deleteSelectedOptions: function(oSelect)
9643			{
9644				oSelect = BX(oSelect);
9645				if(oSelect)
9646				{
9647					var i=0;
9648					while(i<oSelect.length)
9649					{
9650						if(oSelect[i].selected)
9651						{
9652							oSelect[i].selected=false;
9653							oSelect.remove(i);
9654						}
9655						else
9656						{
9657							i++;
9658						}
9659					}
9660				}
9661			},
9662
9663			deleteAllOptions: function(oSelect)
9664			{
9665				oSelect = BX(oSelect);
9666				if(oSelect)
9667				{
9668					for(var i=oSelect.length-1; i>=0; i--)
9669					{
9670						oSelect.remove(i);
9671					}
9672				}
9673			},
9674
9675			optionCompare: function(record1, record2)
9676			{
9677				var value1 = record1.optText.toLowerCase();
9678				var value2 = record2.optText.toLowerCase();
9679				if (value1 > value2) return(1);
9680				if (value1 < value2) return(-1);
9681				return(0);
9682			},
9683
9684			sortSelect: function(oSelect)
9685			{
9686				oSelect = BX(oSelect);
9687				if(oSelect)
9688				{
9689					var myOptions = [];
9690					var n = oSelect.options.length;
9691					var i;
9692					for (i=0;i<n;i++)
9693					{
9694						myOptions[i] = {
9695							optText:oSelect[i].text,
9696							optValue:oSelect[i].value
9697						};
9698					}
9699					myOptions.sort(this.optionCompare);
9700					oSelect.length=0;
9701					n = myOptions.length;
9702					for(i=0;i<n;i++)
9703					{
9704						oSelect[i] = new Option(myOptions[i].optText, myOptions[i].optValue, false, false);
9705					}
9706				}
9707			},
9708
9709			selectAllOptions: function(oSelect)
9710			{
9711				oSelect = BX(oSelect);
9712				if(oSelect)
9713				{
9714					var n = oSelect.length;
9715					for(var i=0;i<n;i++)
9716					{
9717						oSelect[i].selected=true;
9718					}
9719				}
9720			},
9721
9722			selectOption: function(oSelect, opt_value)
9723			{
9724				oSelect = BX(oSelect);
9725				if(oSelect)
9726				{
9727					var n = oSelect.length;
9728					for(var i=0;i<n;i++)
9729					{
9730						oSelect[i].selected = (oSelect[i].value == opt_value);
9731					}
9732				}
9733			},
9734
9735			addSelectedOptions: function(oSelect, to_select_id, check_unique, do_sort)
9736			{
9737				oSelect = BX(oSelect);
9738				if(!oSelect)
9739					return;
9740				var n = oSelect.length;
9741				for(var i=0; i<n; i++)
9742					if(oSelect[i].selected)
9743						this.addNewOption(to_select_id, oSelect[i].value, oSelect[i].text, do_sort, check_unique);
9744			},
9745
9746			moveOptionsUp: function(oSelect)
9747			{
9748				oSelect = BX(oSelect);
9749				if(!oSelect)
9750					return;
9751				var n = oSelect.length;
9752				for(var i=0; i<n; i++)
9753				{
9754					if(oSelect[i].selected && i>0 && oSelect[i-1].selected == false)
9755					{
9756						var option = new Option(oSelect[i].text, oSelect[i].value);
9757						oSelect[i] = new Option(oSelect[i-1].text, oSelect[i-1].value);
9758						oSelect[i].selected = false;
9759						oSelect[i-1] = option;
9760						oSelect[i-1].selected = true;
9761					}
9762				}
9763			},
9764
9765			moveOptionsDown: function(oSelect)
9766			{
9767				oSelect = BX(oSelect);
9768				if(!oSelect)
9769					return;
9770				var n = oSelect.length;
9771				for(var i=n-1; i>=0; i--)
9772				{
9773					if(oSelect[i].selected && i<n-1 && oSelect[i+1].selected == false)
9774					{
9775						var option = new Option(oSelect[i].text, oSelect[i].value);
9776						oSelect[i] = new Option(oSelect[i+1].text, oSelect[i+1].value);
9777						oSelect[i].selected = false;
9778						oSelect[i+1] = option;
9779						oSelect[i+1].selected = true;
9780					}
9781				}
9782			}
9783		};
9784
9785	BX.getEventTarget = function(e)
9786	{
9787		if(e.target)
9788		{
9789			return e.target;
9790		}
9791		else if(e.srcElement)
9792		{
9793			return e.srcElement;
9794		}
9795		return null;
9796	};
9797
9798	BX.convert = {
9799		toNumber: function(value)
9800		{
9801			if(BX.type.isNumber(value))
9802			{
9803				return value;
9804			}
9805
9806			value = Number(value);
9807			return !isNaN(value) ? value : 0;
9808		},
9809		nodeListToArray: function(nodes)
9810		{
9811			try
9812			{
9813				return (Array.prototype.slice.call(nodes, 0));
9814			}
9815			catch (ex)
9816			{
9817				var ary = [];
9818				for(var i = 0, l = nodes.length; i < l; i++)
9819				{
9820					ary.push(nodes[i]);
9821				}
9822				return ary;
9823			}
9824		}
9825	};
9826
9827	/******* HINT ***************/
9828// if function has 2 params - the 2nd one is hint html. otherwise hint_html is third and hint_title - 2nd;
9829// '<div onmouseover="BX.hint(this, 'This is &lt;b&gt;Hint&lt;/b&gt;')"'>;
9830// BX.hint(el, 'This is <b>Hint</b>') - this won't work, use constructor
9831	BX.hint = function(el, hint_title, hint_html, hint_id)
9832	{
9833		if (null == hint_html)
9834		{
9835			hint_html = hint_title;
9836			hint_title = '';
9837		}
9838
9839		if (null == el.BXHINT)
9840		{
9841			el.BXHINT = new BX.CHint({
9842				parent: el, hint: hint_html, title: hint_title, id: hint_id
9843			});
9844			el.BXHINT.Show();
9845		}
9846	};
9847
9848	BX.hint_replace = function(el, hint_title, hint_html)
9849	{
9850		if (null == hint_html)
9851		{
9852			hint_html = hint_title;
9853			hint_title = '';
9854		}
9855
9856		if (!el || !el.parentNode || !hint_html)
9857			return null;
9858
9859		var obHint = new BX.CHint({
9860			hint: hint_html,
9861			title: hint_title
9862		});
9863
9864		obHint.CreateParent();
9865
9866		el.parentNode.insertBefore(obHint.PARENT, el);
9867		el.parentNode.removeChild(el);
9868
9869		obHint.PARENT.style.marginLeft = '5px';
9870
9871		return el;
9872	};
9873
9874	BX.CHint = function(params)
9875	{
9876		if (BX.CHint.cssLoaded === false)
9877		{
9878			BX.load(['/bitrix/js/main/core/css/core_hint.css']);
9879			BX.CHint.cssLoaded = true;
9880		}
9881
9882		this.PARENT = BX(params.parent);
9883
9884		this.HINT = params.hint;
9885		this.HINT_TITLE = params.title;
9886
9887		this.PARAMS = {};
9888		for (var i in this.defaultSettings)
9889		{
9890			if (null == params[i])
9891				this.PARAMS[i] = this.defaultSettings[i];
9892			else
9893				this.PARAMS[i] = params[i];
9894		}
9895
9896		if (null != params.id)
9897			this.ID = params.id;
9898
9899		this.timer = null;
9900		this.bInited = false;
9901		this.msover = true;
9902
9903		if (this.PARAMS.showOnce)
9904		{
9905			this.__show();
9906			this.msover = false;
9907			this.timer = setTimeout(BX.proxy(this.__hide, this), this.PARAMS.hide_timeout);
9908		}
9909		else if (this.PARENT)
9910		{
9911			BX.bind(this.PARENT, 'mouseover', BX.proxy(this.Show, this));
9912			BX.bind(this.PARENT, 'mouseout', BX.proxy(this.Hide, this));
9913		}
9914	};
9915
9916	BX.CHint.cssLoaded = false;
9917
9918	BX.CHint.openHints = new Set();
9919
9920	BX.CHint.globalDisabled = false;
9921
9922	BX.CHint.handleMenuOpen = function() {
9923		BX.CHint.globalDisabled = true;
9924
9925		BX.CHint.openHints.forEach(function(hint) {
9926			hint.__hide_immediately();
9927		});
9928	};
9929
9930	BX.CHint.handleMenuClose = function() {
9931		BX.CHint.globalDisabled = false;
9932	};
9933
9934	BX.addCustomEvent('onMenuOpen', BX.CHint.handleMenuOpen);
9935	BX.addCustomEvent('onMenuClose', BX.CHint.handleMenuClose);
9936
9937	BX.CHint.prototype.defaultSettings = {
9938		show_timeout: 1000,
9939		hide_timeout: 500,
9940		dx: 2,
9941		showOnce: false,
9942		preventHide: true,
9943		min_width: 250
9944	};
9945
9946	BX.CHint.prototype.CreateParent = function(element, params)
9947	{
9948		if (this.PARENT)
9949		{
9950			BX.unbind(this.PARENT, 'mouseover', BX.proxy(this.Show, this));
9951			BX.unbind(this.PARENT, 'mouseout', BX.proxy(this.Hide, this));
9952		}
9953
9954		if (!params) params = {};
9955		var type = 'icon';
9956
9957		if (params.type && (params.type == "link" || params.type == "icon"))
9958			type = params.type;
9959
9960		if (element)
9961			type = "element";
9962
9963		if (type == "icon")
9964		{
9965			element = BX.create('IMG', {
9966				props: {
9967					src: params.iconSrc
9968						? params.iconSrc
9969						: "/bitrix/js/main/core/images/hint.gif"
9970				}
9971			});
9972		}
9973		else if (type == "link")
9974		{
9975			element = BX.create("A", {
9976				props: {href: 'javascript:void(0)'},
9977				html: '[?]'
9978			});
9979		}
9980
9981		this.PARENT = element;
9982
9983		BX.bind(this.PARENT, 'mouseover', BX.proxy(this.Show, this));
9984		BX.bind(this.PARENT, 'mouseout', BX.proxy(this.Hide, this));
9985
9986		return this.PARENT;
9987	};
9988
9989	BX.CHint.prototype.Show = function()
9990	{
9991		this.msover = true;
9992
9993		if (null != this.timer)
9994			clearTimeout(this.timer);
9995
9996		this.timer = setTimeout(BX.proxy(this.__show, this), this.PARAMS.show_timeout);
9997	};
9998
9999	BX.CHint.prototype.Hide = function()
10000	{
10001		this.msover = false;
10002
10003		if (null != this.timer)
10004			clearTimeout(this.timer);
10005
10006		this.timer = setTimeout(BX.proxy(this.__hide, this), this.PARAMS.hide_timeout);
10007	};
10008
10009	BX.CHint.prototype.__show = function()
10010	{
10011		if (!this.msover || this.disabled || BX.CHint.globalDisabled) return;
10012		if (!this.bInited) this.Init();
10013
10014		if (this.prepareAdjustPos())
10015		{
10016			this.DIV.style.display = 'block';
10017			BX.ZIndexManager.bringToFront(this.DIV);
10018
10019			this.adjustPos();
10020
10021			BX.CHint.openHints.add(this);
10022
10023			BX.bind(window, 'scroll', BX.proxy(this.__onscroll, this));
10024
10025			if (this.PARAMS.showOnce)
10026			{
10027				this.timer = setTimeout(BX.proxy(this.__hide, this), this.PARAMS.hide_timeout);
10028			}
10029		}
10030	};
10031
10032	BX.CHint.prototype.__onscroll = function()
10033	{
10034		if (!BX.admin || !BX.admin.panel || !BX.admin.panel.isFixed()) return;
10035
10036		if (this.scrollTimer) clearTimeout(this.scrollTimer);
10037
10038		this.DIV.style.display = 'none';
10039		this.scrollTimer = setTimeout(BX.proxy(this.Reopen, this), this.PARAMS.show_timeout);
10040	};
10041
10042	BX.CHint.prototype.Reopen = function()
10043	{
10044		if (null != this.timer) clearTimeout(this.timer);
10045		this.timer = setTimeout(BX.proxy(this.__show, this), 50);
10046	};
10047
10048	BX.CHint.prototype.__hide = function()
10049	{
10050		if (this.msover) return;
10051		if (!this.bInited) return;
10052
10053		BX.unbind(window, 'scroll', BX.proxy(this.Reopen, this));
10054
10055		BX.CHint.openHints.delete(this);
10056
10057		if (this.PARAMS.showOnce)
10058		{
10059			this.Destroy();
10060		}
10061		else
10062		{
10063			this.DIV.style.display = 'none';
10064		}
10065	};
10066
10067	BX.CHint.prototype.__hide_immediately = function()
10068	{
10069		this.msover = false;
10070		this.__hide();
10071	};
10072
10073	BX.CHint.prototype.Init = function()
10074	{
10075		this.DIV = document.body.appendChild(BX.create('DIV', {
10076			props: {className: 'bx-panel-tooltip'},
10077			style: {
10078				display: 'none',
10079				position: 'absolute',
10080				visibility: 'hidden'
10081			},
10082			children: [
10083				(this.CONTENT = BX.create('DIV', {
10084					props: {className: 'bx-panel-tooltip-content'},
10085					children: [
10086						BX.create('DIV', {
10087							props: {className: 'bx-panel-tooltip-underlay'},
10088							children: [
10089								BX.create('DIV', {props: {className: 'bx-panel-tooltip-underlay-bg'}})
10090							]
10091						})
10092					]
10093				}))
10094			]
10095		}));
10096
10097		BX.ZIndexManager.register(this.DIV);
10098
10099		if (this.ID)
10100		{
10101			this.CONTENT.insertBefore(BX.create('A', {
10102				attrs: {href: 'javascript:void(0)'},
10103				props: {className: 'bx-panel-tooltip-close'},
10104				events: {click: BX.delegate(this.Close, this)}
10105			}), this.CONTENT.firstChild);
10106		}
10107
10108		if (this.HINT_TITLE)
10109		{
10110			this.CONTENT.appendChild(
10111				BX.create('DIV', {
10112					props: {className: 'bx-panel-tooltip-title'},
10113					text: this.HINT_TITLE
10114				})
10115			);
10116		}
10117
10118		if (this.HINT)
10119		{
10120			this.CONTENT_TEXT = this.CONTENT.appendChild(BX.create('DIV', {props: {className: 'bx-panel-tooltip-text'}})).appendChild(BX.create('SPAN', {html: this.HINT}));
10121		}
10122
10123		if (this.PARAMS.preventHide)
10124		{
10125			BX.bind(this.DIV, 'mouseout', BX.proxy(this.Hide, this));
10126			BX.bind(this.DIV, 'mouseover', BX.proxy(this.Show, this));
10127		}
10128
10129		this.bInited = true;
10130	};
10131
10132	BX.CHint.prototype.setContent = function(content)
10133	{
10134		this.HINT = content;
10135
10136		if (this.CONTENT_TEXT)
10137			this.CONTENT_TEXT.innerHTML = this.HINT;
10138		else
10139			this.CONTENT_TEXT = this.CONTENT.appendChild(BX.create('DIV', {props: {className: 'bx-panel-tooltip-text'}})).appendChild(BX.create('SPAN', {html: this.HINT}));
10140	};
10141
10142	BX.CHint.prototype.prepareAdjustPos = function()
10143	{
10144		this._wnd = {scrollPos: BX.GetWindowScrollPos(),scrollSize:BX.GetWindowScrollSize()};
10145		return BX.style(this.PARENT, 'display') != 'none';
10146	};
10147
10148	BX.CHint.prototype.getAdjustPos = function()
10149	{
10150		var res = {}, pos = BX.pos(this.PARENT), min_top = 0;
10151
10152		res.top = pos.bottom + this.PARAMS.dx;
10153
10154		if (BX.admin && BX.admin.panel.DIV)
10155		{
10156			min_top = BX.admin.panel.DIV.offsetHeight + this.PARAMS.dx;
10157
10158			if (BX.admin.panel.isFixed())
10159			{
10160				min_top += this._wnd.scrollPos.scrollTop;
10161			}
10162		}
10163
10164		if (res.top < min_top)
10165			res.top = min_top;
10166		else
10167		{
10168			if (res.top + this.DIV.offsetHeight > this._wnd.scrollSize.scrollHeight)
10169				res.top = pos.top - this.PARAMS.dx - this.DIV.offsetHeight;
10170		}
10171
10172		res.left = pos.left;
10173		if (pos.left < this.PARAMS.dx)
10174			pos.left = this.PARAMS.dx;
10175		else
10176		{
10177			var floatWidth = this.DIV.offsetWidth;
10178
10179			var max_left = this._wnd.scrollSize.scrollWidth - floatWidth - this.PARAMS.dx;
10180
10181			if (res.left > max_left)
10182				res.left = max_left;
10183		}
10184
10185		return res;
10186	};
10187
10188	BX.CHint.prototype.adjustWidth = function()
10189	{
10190		if (this.bWidthAdjusted) return;
10191
10192		var w = this.DIV.offsetWidth, h = this.DIV.offsetHeight;
10193
10194		if (w > this.PARAMS.min_width)
10195			w = Math.round(Math.sqrt(1.618*w*h));
10196
10197		if (w < this.PARAMS.min_width)
10198			w = this.PARAMS.min_width;
10199
10200		this.DIV.style.width = w + "px";
10201
10202		if (this._adjustWidthInt)
10203			clearInterval(this._adjustWidthInt);
10204		this._adjustWidthInt = setInterval(BX.delegate(this._adjustWidthInterval, this), 5);
10205
10206		this.bWidthAdjusted = true;
10207	};
10208
10209	BX.CHint.prototype._adjustWidthInterval = function()
10210	{
10211		if (!this.DIV || this.DIV.style.display == 'none')
10212			clearInterval(this._adjustWidthInt);
10213
10214		var
10215			dW = 20,
10216			maxWidth = 1500,
10217			w = this.DIV.offsetWidth,
10218			w1 = this.CONTENT_TEXT.offsetWidth;
10219
10220		if (w > 0 && w1 > 0 && w - w1 < dW && w < maxWidth)
10221		{
10222			this.DIV.style.width = (w + dW) + "px";
10223			return;
10224		}
10225
10226		clearInterval(this._adjustWidthInt);
10227	};
10228
10229	BX.CHint.prototype.adjustPos = function()
10230	{
10231		this.adjustWidth();
10232
10233		var pos = this.getAdjustPos();
10234
10235		this.DIV.style.top = pos.top + 'px';
10236		this.DIV.style.left = pos.left + 'px';
10237	};
10238
10239	BX.CHint.prototype.Close = function()
10240	{
10241		if (this.ID && BX.WindowManager)
10242			BX.WindowManager.saveWindowOptions(this.ID, {display: 'off'});
10243		this.__hide_immediately();
10244		this.Destroy();
10245	};
10246
10247	BX.CHint.prototype.Destroy = function()
10248	{
10249		if (this.PARENT)
10250		{
10251			BX.unbind(this.PARENT, 'mouseover', BX.proxy(this.Show, this));
10252			BX.unbind(this.PARENT, 'mouseout', BX.proxy(this.Hide, this));
10253		}
10254
10255		if (this.DIV)
10256		{
10257			BX.unbind(this.DIV, 'mouseover', BX.proxy(this.Show, this));
10258			BX.unbind(this.DIV, 'mouseout', BX.proxy(this.Hide, this));
10259
10260			BX.ZIndexManager.unregister(this.DIV);
10261
10262			BX.cleanNode(this.DIV, true);
10263		}
10264	};
10265
10266	BX.CHint.prototype.enable = function(){this.disabled = false;};
10267	BX.CHint.prototype.disable = function(){this.__hide_immediately(); this.disabled = true;};
10268
10269
10270	function _adjustWait()
10271	{
10272		if (!this.bxmsg) return;
10273
10274		var arContainerPos = BX.pos(this),
10275			div_top = arContainerPos.top;
10276
10277		if (div_top < BX.GetDocElement().scrollTop)
10278			div_top = BX.GetDocElement().scrollTop + 5;
10279
10280		this.bxmsg.style.top = (div_top + 5) + 'px';
10281
10282		if (this == BX.GetDocElement())
10283		{
10284			this.bxmsg.style.right = '5px';
10285		}
10286		else
10287		{
10288			this.bxmsg.style.left = (arContainerPos.right - this.bxmsg.offsetWidth - 5) + 'px';
10289		}
10290	}
10291
10292	function _processTpl(tplNode, cb, bKillTpl)
10293	{
10294		if (tplNode)
10295		{
10296			if (bKillTpl)
10297				tplNode.parentNode.removeChild(tplNode);
10298
10299			var res = {}, nodes = BX.findChildren(tplNode, {attribute: 'data-role'}, true);
10300
10301			for (var i = 0, l = nodes.length; i < l; i++)
10302			{
10303				res[nodes[i].getAttribute('data-role')] = nodes[i];
10304			}
10305
10306			cb.apply(tplNode, [res]);
10307		}
10308	}
10309
10310	function _checkNode(obj, params)
10311	{
10312		params = params || {};
10313
10314		if (BX.type.isFunction(params))
10315			return params.call(window, obj);
10316
10317		if (!params.allowTextNodes && !BX.type.isElementNode(obj))
10318			return false;
10319		var i,j,len;
10320		for (i in params)
10321		{
10322			if(params.hasOwnProperty(i))
10323			{
10324				switch(i)
10325				{
10326					case 'tag':
10327					case 'tagName':
10328						if (BX.type.isString(params[i]))
10329						{
10330							if (obj.tagName.toUpperCase() != params[i].toUpperCase())
10331								return false;
10332						}
10333						else if (params[i] instanceof RegExp)
10334						{
10335							if (!params[i].test(obj.tagName))
10336								return false;
10337						}
10338						break;
10339
10340					case 'class':
10341					case 'className':
10342						if (BX.type.isString(params[i]))
10343						{
10344							if (!BX.hasClass(obj, params[i]))
10345								return false;
10346						}
10347						else if (params[i] instanceof RegExp)
10348						{
10349							if (!BX.type.isString(obj.className) || !params[i].test(obj.className))
10350								return false;
10351						}
10352						break;
10353
10354					case 'attr':
10355					case 'attrs':
10356					case 'attribute':
10357						if (BX.type.isString(params[i]))
10358						{
10359							if (!obj.getAttribute(params[i]))
10360								return false;
10361						}
10362						else if (BX.type.isArray(params[i]))
10363						{
10364							for (j = 0, len = params[i].length; j < len; j++)
10365							{
10366								if (params[i] && !obj.getAttribute(params[i]))
10367									return false;
10368							}
10369						}
10370						else
10371						{
10372							for (j in params[i])
10373							{
10374								if(params[i].hasOwnProperty(j))
10375								{
10376									var q = obj.getAttribute(j);
10377									if (params[i][j] instanceof RegExp)
10378									{
10379										if (!BX.type.isString(q) || !params[i][j].test(q))
10380										{
10381											return false;
10382										}
10383									}
10384									else
10385									{
10386										if (q != '' + params[i][j])
10387										{
10388											return false;
10389										}
10390									}
10391								}
10392							}
10393						}
10394						break;
10395
10396					case 'property':
10397					case 'props':
10398						if (BX.type.isString(params[i]))
10399						{
10400							if (!obj[params[i]])
10401								return false;
10402						}
10403						else if (BX.type.isArray(params[i]))
10404						{
10405							for (j = 0, len = params[i].length; j < len; j++)
10406							{
10407								if (params[i] && !obj[params[i]])
10408									return false;
10409							}
10410						}
10411						else
10412						{
10413							for (j in params[i])
10414							{
10415								if (BX.type.isString(params[i][j]))
10416								{
10417									if (obj[j] != params[i][j])
10418										return false;
10419								}
10420								else if (params[i][j] instanceof RegExp)
10421								{
10422									if (!BX.type.isString(obj[j]) || !params[i][j].test(obj[j]))
10423										return false;
10424								}
10425							}
10426						}
10427						break;
10428
10429					case 'callback':
10430						return params[i](obj);
10431				}
10432			}
10433		}
10434
10435		return true;
10436	}
10437
10438	window.addEventListener('pagehide', () => {
10439		garbageCollectors.forEach(({ callback, context = window }) => {
10440			try
10441			{
10442				callback.apply(context);
10443			} catch (err) {}
10444		});
10445	});
10446
10447	// set empty ready handler
10448	BX(BX.DoNothing);
10449	window.BX = BX;
10450
10451	BX.browser.addGlobalClass();
10452
10453	/* data storage */
10454	BX.data = function(node, key, value)
10455	{
10456		if(typeof node == 'undefined')
10457			return undefined;
10458
10459		if(typeof key == 'undefined')
10460			return undefined;
10461
10462		if(typeof value != 'undefined')
10463		{
10464			// write to manager
10465			dataStorage.set(node, key, value);
10466		}
10467		else
10468		{
10469			var data;
10470
10471			// from manager
10472			if((data = dataStorage.get(node, key)) != undefined)
10473			{
10474				return data;
10475			}
10476			else
10477			{
10478				// from attribute data-*
10479				if('getAttribute' in node)
10480				{
10481					data = node.getAttribute('data-'+key.toString());
10482					if(data === null)
10483					{
10484						return undefined;
10485					}
10486					return data;
10487				}
10488			}
10489
10490			return undefined;
10491		}
10492	};
10493
10494	BX.DataStorage = function()
10495	{
10496
10497		this.keyOffset = 1;
10498		this.data = {};
10499		this.uniqueTag = 'BX-'+Math.random();
10500
10501		this.resolve = function(owner, create){
10502			if(typeof owner[this.uniqueTag] == 'undefined')
10503				if(create)
10504				{
10505					try
10506					{
10507						Object.defineProperty(owner, this.uniqueTag, {
10508							value: this.keyOffset++
10509						});
10510					}
10511					catch(e)
10512					{
10513						owner[this.uniqueTag] = this.keyOffset++;
10514					}
10515				}
10516				else
10517					return undefined;
10518
10519			return owner[this.uniqueTag];
10520		};
10521		this.get = function(owner, key){
10522			if((owner != document && !BX.type.isElementNode(owner)) || typeof key == 'undefined')
10523				return undefined;
10524
10525			owner = this.resolve(owner, false);
10526
10527			if(typeof owner == 'undefined' || typeof this.data[owner] == 'undefined')
10528				return undefined;
10529
10530			return this.data[owner][key];
10531		};
10532		this.set = function(owner, key, value){
10533
10534			if((owner != document && !BX.type.isElementNode(owner)) || typeof value == 'undefined')
10535				return;
10536
10537			var o = this.resolve(owner, true);
10538
10539			if(typeof this.data[o] == 'undefined')
10540				this.data[o] = {};
10541
10542			this.data[o][key] = value;
10543		};
10544	};
10545
10546// some internal variables for new logic
10547	var dataStorage = new BX.DataStorage();	// manager which BX.data() uses to keep data
10548})(window.BX);
10549
10550
10551;(function(window)
10552{
10553	/****************** ATTENTION *******************************
10554	 * Please do not use Bitrix CoreJS in this class.
10555	 * This class can be called on page without Bitrix Framework
10556	*************************************************************/
10557
10558	if (!window.BX)
10559	{
10560		window.BX = {};
10561	}
10562
10563	var BX = window.BX;
10564
10565	BX.Promise = function(fn, ctx) // fn is future-reserved
10566	{
10567		this.state = null;
10568		this.value = null;
10569		this.reason = null;
10570		this.next = null;
10571		this.ctx = ctx || this;
10572
10573		this.onFulfilled = [];
10574		this.onRejected = [];
10575	};
10576	BX.Promise.prototype.fulfill = function(value)
10577	{
10578		this.checkState();
10579
10580		this.value = value;
10581		this.state = true;
10582		this.execute();
10583	};
10584	BX.Promise.prototype.reject = function(reason)
10585	{
10586		this.checkState();
10587
10588		this.reason = reason;
10589		this.state = false;
10590		this.execute();
10591	};
10592	BX.Promise.prototype.then = function(onFulfilled, onRejected)
10593	{
10594		if(typeof (onFulfilled) == "function" || onFulfilled instanceof Function)
10595		{
10596			this.onFulfilled.push(onFulfilled);
10597		}
10598		if(typeof (onRejected) == "function" || onRejected instanceof Function)
10599		{
10600			this.onRejected.push(onRejected);
10601		}
10602
10603		if(this.next === null)
10604		{
10605			this.next = new BX.Promise(null, this.ctx);
10606		}
10607
10608		if(this.state !== null) // if promise was already resolved, execute immediately
10609		{
10610			this.execute();
10611		}
10612
10613		return this.next;
10614	};
10615
10616	BX.Promise.prototype.catch = function(onRejected)
10617	{
10618		if(typeof (onRejected) == "function" || onRejected instanceof Function)
10619		{
10620			this.onRejected.push(onRejected);
10621		}
10622
10623		if(this.next === null)
10624		{
10625			this.next = new BX.Promise(null, this.ctx);
10626		}
10627
10628		if(this.state !== null) // if promise was already resolved, execute immediately
10629		{
10630			this.execute();
10631		}
10632
10633		return this.next;
10634	};
10635
10636	BX.Promise.prototype.setAutoResolve = function(way, ms)
10637	{
10638		this.timer = setTimeout(function(){
10639			if(this.state === null)
10640			{
10641				this[way ? 'fulfill' : 'reject']();
10642			}
10643		}.bind(this), ms || 15);
10644	};
10645	BX.Promise.prototype.cancelAutoResolve = function()
10646	{
10647		clearTimeout(this.timer);
10648	};
10649	/**
10650	 * Resolve function. This function allows promise chaining, like ..then().then()...
10651	 * Typical usage:
10652	 *
10653	 * var p = new Promise();
10654	 *
10655	 * p.then(function(value){
10656	 *  return someValue; // next promise in the chain will be fulfilled with someValue
10657	 * }).then(function(value){
10658	 *
10659	 *  var p1 = new Promise();
10660	 *  *** some async code here, that eventually resolves p1 ***
10661	 *
10662	 *  return p1; // chain will resume when p1 resolved (fulfilled or rejected)
10663	 * }).then(function(value){
10664	 *
10665	 *  // you can also do
10666	 *  var e = new Error();
10667	 *  throw e;
10668	 *  // it will cause next promise to be rejected with e
10669	 *
10670	 *  return someOtherValue;
10671	 * }).then(function(value){
10672	 *  ...
10673	 * }, function(reason){
10674	 *  // promise was rejected with reason
10675	 * })...;
10676	 *
10677	 * p.fulfill('let`s start this chain');
10678	 *
10679	 * @param x
10680	 */
10681	BX.Promise.prototype.resolve = function(x)
10682	{
10683		var this_ = this;
10684
10685		if(this === x)
10686		{
10687			this.reject(new TypeError('Promise cannot fulfill or reject itself')); // avoid recursion
10688		}
10689		// allow "pausing" promise chaining until promise x is fulfilled or rejected
10690		else if(x && x.toString() === "[object BX.Promise]")
10691		{
10692			x.then(function(value){
10693				this_.fulfill(value);
10694			}, function(reason){
10695				this_.reject(reason);
10696			});
10697		}
10698		else // auto-fulfill this promise
10699		{
10700			this.fulfill(x);
10701		}
10702	};
10703
10704	BX.Promise.prototype.toString = function()
10705	{
10706		return "[object BX.Promise]";
10707	};
10708
10709	BX.Promise.prototype.execute = function()
10710	{
10711		if(this.state === null)
10712		{
10713			//then() must not be called before BX.Promise resolve() happens
10714			return;
10715		}
10716
10717		var value = undefined;
10718		var reason = undefined;
10719		var x = undefined;
10720		var k;
10721		if(this.state === true) // promise was fulfill()-ed
10722		{
10723			if(this.onFulfilled.length)
10724			{
10725				try
10726				{
10727					for(k = 0; k < this.onFulfilled.length; k++)
10728					{
10729						x = this.onFulfilled[k].apply(this.ctx, [this.value]);
10730						if(typeof x != 'undefined')
10731						{
10732							value = x;
10733						}
10734					}
10735				}
10736				catch(e)
10737				{
10738					if('console' in window)
10739					{
10740						console.dir(e);
10741					}
10742
10743					if (typeof BX.debug !== 'undefined')
10744					{
10745						BX.debug(e);
10746					}
10747
10748					reason = e; // reject next
10749				}
10750			}
10751			else
10752			{
10753				value = this.value; // resolve next
10754			}
10755		}
10756		else if(this.state === false) // promise was reject()-ed
10757		{
10758			if(this.onRejected.length)
10759			{
10760				try
10761				{
10762					for(k = 0; k < this.onRejected.length; k++)
10763					{
10764						x = this.onRejected[k].apply(this.ctx, [this.reason]);
10765						if(typeof x != 'undefined')
10766						{
10767							value = x;
10768						}
10769					}
10770				}
10771				catch(e)
10772				{
10773					if('console' in window)
10774					{
10775						console.dir(e);
10776					}
10777
10778					if (typeof BX.debug !== 'undefined')
10779					{
10780						BX.debug(e);
10781					}
10782
10783					reason = e; // reject next
10784				}
10785			}
10786			else
10787			{
10788				reason = this.reason; // reject next
10789			}
10790		}
10791
10792		if(this.next !== null)
10793		{
10794			if(typeof reason != 'undefined')
10795			{
10796				this.next.reject(reason);
10797			}
10798			else if(typeof value != 'undefined')
10799			{
10800				this.next.resolve(value);
10801			}
10802		}
10803	};
10804	BX.Promise.prototype.checkState = function()
10805	{
10806		if(this.state !== null)
10807		{
10808			throw new Error('You can not do fulfill() or reject() multiple times');
10809		}
10810	};
10811})(window);
10812
10813
10814
10815
10816;(function(window){
10817
10818if (window.BX.ajax)
10819	return;
10820
10821var
10822	BX = window.BX,
10823
10824	tempDefaultConfig = {},
10825	defaultConfig = {
10826		method: 'GET', // request method: GET|POST
10827		dataType: 'html', // type of data loading: html|json|script
10828		timeout: 0, // request timeout in seconds. 0 for browser-default
10829		async: true, // whether request is asynchronous or not
10830		processData: true, // any data processing is disabled if false, only callback call
10831		scriptsRunFirst: false, // whether to run _all_ found scripts before onsuccess call. script tag can have an attribute "bxrunfirst" to turn  this flag on only for itself
10832		emulateOnload: true,
10833		skipAuthCheck: false, // whether to check authorization failure (SHOUD be set to true for CORS requests)
10834		start: true, // send request immediately (if false, request can be started manually via XMLHttpRequest object returned)
10835		cache: true, // whether NOT to add random addition to URL
10836		preparePost: true, // whether set Content-Type x-www-form-urlencoded in POST
10837		headers: false, // add additional headers, example: [{'name': 'If-Modified-Since', 'value': 'Wed, 15 Aug 2012 08:59:08 GMT'}, {'name': 'If-None-Match', 'value': '0'}]
10838		lsTimeout: 30, //local storage data TTL. useless without lsId.
10839		lsForce: false //wheter to force query instead of using localStorage data. useless without lsId.
10840/*
10841other parameters:
10842	url: url to get/post
10843	data: data to post
10844	onsuccess: successful request callback. BX.proxy may be used.
10845	onfailure: request failure callback. BX.proxy may be used.
10846	onprogress: request progress callback. BX.proxy may be used.
10847
10848	lsId: local storage id - for constantly updating queries which can communicate via localStorage. core_ls.js needed
10849
10850any of the default parameters can be overridden. defaults can be changed by BX.ajax.Setup() - for all further requests!
10851*/
10852	},
10853	loadedScripts = {},
10854	loadedScriptsQueue = [],
10855	r = {
10856		'url_utf': /[^\034-\254]+/g,
10857		'script_self': /\/bitrix\/js\/main\/core\/core(_ajax)*.js$/i,
10858		'script_self_window': /\/bitrix\/js\/main\/core\/core_window.js$/i,
10859		'script_self_admin': /\/bitrix\/js\/main\/core\/core_admin.js$/i,
10860		'script_onload': /window.onload/g
10861	};
10862
10863// low-level method
10864BX.ajax = function(config)
10865{
10866	var status, data;
10867
10868	if (!config || !config.url || !BX.type.isString(config.url))
10869	{
10870		return false;
10871	}
10872
10873	for (var i in tempDefaultConfig)
10874		if (typeof (config[i]) == "undefined") config[i] = tempDefaultConfig[i];
10875
10876	tempDefaultConfig = {};
10877
10878	for (i in defaultConfig)
10879		if (typeof (config[i]) == "undefined") config[i] = defaultConfig[i];
10880
10881	config.method = config.method.toUpperCase();
10882
10883	if (!BX.localStorage)
10884		config.lsId = null;
10885
10886	if (BX.browser.IsIE())
10887	{
10888		var result = r.url_utf.exec(config.url);
10889		if (result)
10890		{
10891			do
10892			{
10893				config.url = config.url.replace(result, BX.util.urlencode(result));
10894				result = r.url_utf.exec(config.url);
10895			} while (result);
10896		}
10897	}
10898
10899	if(config.dataType == 'json')
10900		config.emulateOnload = false;
10901
10902	if (!config.cache && config.method == 'GET')
10903		config.url = BX.ajax._uncache(config.url);
10904
10905	if (config.method == 'POST')
10906	{
10907		if (config.preparePost)
10908		{
10909			config.data = BX.ajax.prepareData(config.data);
10910		}
10911		else if (getLastContentTypeHeader(config.headers) === 'application/json')
10912		{
10913			const isJson = (
10914				BX.Type.isPlainObject(config.data)
10915				|| BX.Type.isString(config.data)
10916				|| BX.Type.isNumber(config.data)
10917				|| BX.Type.isBoolean(config.data)
10918				|| BX.Type.isArray(config.data)
10919			);
10920
10921			if (isJson)
10922			{
10923				config.data = JSON.stringify(config.data);
10924			}
10925		}
10926	}
10927
10928	var bXHR = true;
10929	if (config.lsId && !config.lsForce)
10930	{
10931		var v = BX.localStorage.get('ajax-' + config.lsId);
10932		if (v !== null)
10933		{
10934			bXHR = false;
10935
10936			var lsHandler = function(lsData) {
10937				if (lsData.key == 'ajax-' + config.lsId && lsData.value != 'BXAJAXWAIT')
10938				{
10939					var data = lsData.value,
10940						bRemove = !!lsData.oldValue && data == null;
10941					if (!bRemove)
10942						BX.ajax.__run(config, data);
10943					else if (config.onfailure)
10944						config.onfailure("timeout");
10945
10946					BX.removeCustomEvent('onLocalStorageChange', lsHandler);
10947				}
10948			};
10949
10950			if (v == 'BXAJAXWAIT')
10951			{
10952				BX.addCustomEvent('onLocalStorageChange', lsHandler);
10953			}
10954			else
10955			{
10956				setTimeout(function() {lsHandler({key: 'ajax-' + config.lsId, value: v})}, 10);
10957			}
10958		}
10959	}
10960
10961	if (bXHR)
10962	{
10963		config.xhr = BX.ajax.xhr();
10964		if (!config.xhr) return;
10965
10966		if (config.lsId)
10967		{
10968			BX.localStorage.set('ajax-' + config.lsId, 'BXAJAXWAIT', config.lsTimeout);
10969		}
10970
10971		if (BX.Type.isFunction(config.onprogress))
10972		{
10973			BX.bind(config.xhr, 'progress', config.onprogress);
10974		}
10975
10976		if (BX.Type.isFunction(config.onprogressupload) && config.xhr.upload)
10977		{
10978			BX.bind(config.xhr.upload, 'progress', config.onprogressupload);
10979		}
10980
10981		config.xhr.open(config.method, config.url, config.async);
10982
10983		if (!config.skipBxHeader && !BX.ajax.isCrossDomain(config.url))
10984		{
10985			config.xhr.setRequestHeader('Bx-ajax', 'true');
10986		}
10987
10988		if (config.method == 'POST' && config.preparePost)
10989		{
10990			config.xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
10991		}
10992		if (typeof(config.headers) == "object")
10993		{
10994			for (i = 0; i < config.headers.length; i++)
10995				config.xhr.setRequestHeader(config.headers[i].name, config.headers[i].value);
10996		}
10997
10998		var bRequestCompleted = false;
10999		var onreadystatechange = config.xhr.onreadystatechange = function(additional)
11000		{
11001			if (bRequestCompleted)
11002				return;
11003
11004			if (additional === 'timeout')
11005			{
11006				if (config.onfailure)
11007				{
11008					config.onfailure('timeout', '', config);
11009				}
11010
11011				BX.onCustomEvent(config.xhr, 'onAjaxFailure', ['timeout', '', config]);
11012
11013				config.xhr.onreadystatechange = BX.DoNothing;
11014				config.xhr.abort();
11015
11016				if (config.async)
11017				{
11018					config.xhr = null;
11019				}
11020			}
11021			else
11022			{
11023				if (config.xhr.readyState == 4 || additional == 'run')
11024				{
11025					status = BX.ajax.xhrSuccess(config.xhr) ? "success" : "error";
11026					bRequestCompleted = true;
11027					config.xhr.onreadystatechange = BX.DoNothing;
11028
11029					if (status == 'success')
11030					{
11031						var authHeader = (!!config.skipAuthCheck || BX.ajax.isCrossDomain(config.url))
11032							? false
11033							: config.xhr.getResponseHeader('X-Bitrix-Ajax-Status');
11034
11035						if(!!authHeader && authHeader == 'Authorize')
11036						{
11037							if (config.onfailure)
11038							{
11039								config.onfailure('auth', config.xhr.status, config);
11040							}
11041
11042							BX.onCustomEvent(config.xhr, 'onAjaxFailure', ['auth', config.xhr.status, config]);
11043						}
11044						else
11045						{
11046							var data = config.xhr.responseText;
11047
11048							if (config.lsId)
11049							{
11050								BX.localStorage.set('ajax-' + config.lsId, data, config.lsTimeout);
11051							}
11052
11053							BX.ajax.__run(config, data);
11054						}
11055					}
11056					else
11057					{
11058						if (config.onfailure)
11059						{
11060							config.onfailure('status', config.xhr.status, config);
11061						}
11062
11063						BX.onCustomEvent(config.xhr, 'onAjaxFailure', ['status', config.xhr.status, config]);
11064					}
11065
11066					if (config.async)
11067					{
11068						config.xhr = null;
11069					}
11070				}
11071			}
11072		};
11073
11074		if (config.async && config.timeout > 0)
11075		{
11076			setTimeout(function() {
11077				if (config.xhr && !bRequestCompleted)
11078				{
11079					onreadystatechange("timeout");
11080				}
11081			}, config.timeout * 1000);
11082		}
11083
11084		if (config.start)
11085		{
11086			config.xhr.send(config.data);
11087
11088			if (!config.async)
11089			{
11090				onreadystatechange('run');
11091			}
11092		}
11093
11094		return config.xhr;
11095	}
11096};
11097
11098BX.ajax.xhr = function()
11099{
11100	if (window.XMLHttpRequest)
11101	{
11102		try {return new XMLHttpRequest();} catch(e){}
11103	}
11104	else if (window.ActiveXObject)
11105	{
11106		try { return new window.ActiveXObject("Msxml2.XMLHTTP.6.0"); }
11107			catch(e) {}
11108		try { return new window.ActiveXObject("Msxml2.XMLHTTP.3.0"); }
11109			catch(e) {}
11110		try { return new window.ActiveXObject("Msxml2.XMLHTTP"); }
11111			catch(e) {}
11112		try { return new window.ActiveXObject("Microsoft.XMLHTTP"); }
11113			catch(e) {}
11114		throw new Error("This browser does not support XMLHttpRequest.");
11115	}
11116
11117	return null;
11118};
11119
11120BX.ajax.isCrossDomain = function(url, location)
11121{
11122	location = location || window.location;
11123
11124	//Relative URL gets a current protocol
11125	if (url.indexOf("//") === 0)
11126	{
11127		url = location.protocol + url;
11128	}
11129
11130	//Fast check
11131	if (url.indexOf("http") !== 0)
11132	{
11133		return false;
11134	}
11135
11136	var link = window.document.createElement("a");
11137	link.href = url;
11138
11139	return  link.protocol !== location.protocol ||
11140			link.hostname !== location.hostname ||
11141			BX.ajax.getHostPort(link.protocol, link.host) !== BX.ajax.getHostPort(location.protocol, location.host);
11142};
11143
11144BX.ajax.getHostPort = function(protocol, host)
11145{
11146	var match = /:(\d+)$/.exec(host);
11147	if (match)
11148	{
11149		return match[1];
11150	}
11151	else
11152	{
11153		if (protocol === "http:")
11154		{
11155			return "80";
11156		}
11157		else if (protocol === "https:")
11158		{
11159			return "443";
11160		}
11161	}
11162
11163	return "";
11164};
11165
11166BX.ajax.__prepareOnload = function(scripts, ajax_session)
11167{
11168	if (scripts.length > 0)
11169	{
11170		BX.ajax['onload_' + ajax_session] = null;
11171
11172		for (var i=0,len=scripts.length;i<len;i++)
11173		{
11174			if (scripts[i].isInternal)
11175			{
11176				scripts[i].JS = scripts[i].JS.replace(r.script_onload, 'BX.aja
11176x.onload_' + ajax_session);
11177			}
11178		}
11179	}
11180
11181	BX.CaptureEventsGet();
11182	BX.CaptureEvents(window, 'load');
11183};
11184
11185BX.ajax.__runOnload = function(ajax_session)
11186{
11187	if (null != BX.ajax['onload_' + ajax_session])
11188	{
11189		BX.ajax['onload_' + ajax_session].apply(window);
11190		BX.ajax['onload_' + ajax_session] = null;
11191	}
11192
11193	var h = BX.CaptureEventsGet();
11194
11195	if (h)
11196	{
11197		for (var i=0; i<h.length; i++)
11198			h[i].apply(window);
11199	}
11200};
11201
11202BX.ajax.__run = function(config, data)
11203{
11204	if (!config.processData)
11205	{
11206		if (config.onsuccess)
11207		{
11208			config.onsuccess(data);
11209		}
11210
11211		BX.onCustomEvent(config.xhr, 'onAjaxSuccess', [data, config]);
11212	}
11213	else
11214	{
11215		data = BX.ajax.processRequestData(data, config);
11216	}
11217};
11218
11219
11220BX.ajax._onParseJSONFailure = function(data)
11221{
11222	this.jsonFailure = true;
11223	this.jsonResponse = data;
11224	this.jsonProactive = /^\[WAF\]/.test(data);
11225};
11226
11227BX.ajax.processRequestData = function(data, config)
11228{
11229	var result, scripts = [], styles = [];
11230	switch (config.dataType.toUpperCase())
11231	{
11232		case 'JSON':
11233
11234			var context = config.xhr || {};
11235			BX.addCustomEvent(context, 'onParseJSONFailure', BX.proxy(BX.ajax._onParseJSONFailure, config));
11236			result = BX.parseJSON(data, context);
11237			BX.removeCustomEvent(context, 'onParseJSONFailure', BX.proxy(BX.ajax._onParseJSONFailure, config));
11238
11239			if(!!result && BX.type.isArray(result['bxjs']))
11240			{
11241				for(var i = 0; i < result['bxjs'].length; i++)
11242				{
11243					if(BX.type.isNotEmptyString(result['bxjs'][i]))
11244					{
11245						scripts.push({
11246							"isInternal": false,
11247							"JS": result['bxjs'][i],
11248							"bRunFirst": config.scriptsRunFirst
11249						});
11250					}
11251					else
11252					{
11253						scripts.push(result['bxjs'][i])
11254					}
11255				}
11256			}
11257
11258			if(!!result && BX.type.isArray(result['bxcss']))
11259			{
11260				styles = result['bxcss'];
11261			}
11262
11263		break;
11264		case 'SCRIPT':
11265			scripts.push({"isInternal": true, "JS": data, "bRunFirst": config.scriptsRunFirst});
11266			result = data;
11267		break;
11268
11269		default: // HTML
11270			var ob = BX.processHTML(data, config.scriptsRunFirst);
11271			result = ob.HTML; scripts = ob.SCRIPT; styles = ob.STYLE;
11272		break;
11273	}
11274
11275	if (styles.length > 0)
11276	{
11277		BX.loadCSS(styles);
11278	}
11279
11280	let ajax_session = null;
11281	if (config.emulateOnload)
11282	{
11283		ajax_session = parseInt(Math.random() * 1000000);
11284		BX.ajax.__prepareOnload(scripts, ajax_session);
11285	}
11286
11287	const cb = BX.defer(function()
11288	{
11289		if (config.emulateOnload)
11290		{
11291			BX.ajax.__runOnload(ajax_session);
11292		}
11293
11294		BX.onCustomEvent(config.xhr, 'onAjaxSuccessFinish', [config]);
11295	});
11296
11297	try
11298	{
11299		if (!!config.jsonFailure)
11300		{
11301			throw {type: 'json_failure', data: config.jsonResponse, bProactive: config.jsonProactive};
11302		}
11303
11304		config.scripts = scripts;
11305
11306		BX.ajax.processScripts(config.scripts, true);
11307
11308		if (config.onsuccess)
11309		{
11310			config.onsuccess(result);
11311		}
11312
11313		BX.onCustomEvent(config.xhr, 'onAjaxSuccess', [result, config]);
11314
11315		BX.ajax.processScripts(config.scripts, false, cb);
11316	}
11317	catch (e)
11318	{
11319		if (config.onfailure)
11320			config.onfailure("processing", e);
11321		BX.onCustomEvent(config.xhr, 'onAjaxFailure', ['processing', e, config]);
11322	}
11323};
11324
11325BX.ajax.processScripts = function(scripts, bRunFirst, cb)
11326{
11327	var scriptsExt = [], scriptsInt = '';
11328
11329	cb = cb || BX.DoNothing;
11330
11331	for (var i = 0, length = scripts.length; i < length; i++)
11332	{
11333		if (typeof bRunFirst != 'undefined' && bRunFirst != !!scripts[i].bRunFirst)
11334			continue;
11335
11336		if (scripts[i].isInternal)
11337			scriptsInt += ';' + scripts[i].JS;
11338		else
11339			scriptsExt.push(scripts[i].JS);
11340	}
11341
11342	scriptsExt = BX.util.array_unique(scriptsExt);
11343	var inlineScripts = scriptsInt.length > 0 ? function() { BX.evalGlobal(scriptsInt); } : BX.DoNothing;
11344
11345	if (scriptsExt.length > 0)
11346	{
11347		BX.load(scriptsExt, function() {
11348			inlineScripts();
11349			cb();
11350		});
11351	}
11352	else
11353	{
11354		inlineScripts();
11355		cb();
11356	}
11357};
11358
11359// TODO: extend this function to use with any data objects or forms
11360BX.ajax.prepareData = function(arData, prefix)
11361{
11362	var data = '';
11363	if (BX.type.isString(arData))
11364		data = arData;
11365	else if (null != arData)
11366	{
11367		for(var i in arData)
11368		{
11369			if (arData.hasOwnProperty(i))
11370			{
11371				if (data.length > 0)
11372					data += '&';
11373				var name = BX.util.urlencode(i);
11374				if(prefix)
11375					name = prefix + '[' + name + ']';
11376				if(typeof arData[i] == 'object')
11377					data += BX.ajax.prepareData(arData[i], name);
11378				else
11379					data += name + '=' + BX.util.urlencode(arData[i]);
11380			}
11381		}
11382	}
11383	return data;
11384};
11385
11386BX.ajax.xhrSuccess = function(xhr)
11387{
11388	return (xhr.status >= 200 && xhr.status < 300) || xhr.status === 304 || xhr.status === 1223 || xhr.status === 0;
11389};
11390
11391BX.ajax.Setup = function(config, bTemp)
11392{
11393	bTemp = !!bTemp;
11394
11395	for (var i in config)
11396	{
11397		if (bTemp)
11398			tempDefaultConfig[i] = config[i];
11399		else
11400			defaultConfig[i] = config[i];
11401	}
11402};
11403
11404BX.ajax.replaceLocalStorageValue = function(lsId, data, ttl)
11405{
11406	if (!!BX.localStorage)
11407		BX.localStorage.set('ajax-' + lsId, data, ttl);
11408};
11409
11410
11411BX.ajax._uncache = function(url)
11412{
11413	return url + ((url.indexOf('?') !== -1 ? "&" : "?") + '_=' + (new Date()).getTime());
11414};
11415
11416/* simple interface */
11417BX.ajax.get = function(url, data, callback)
11418{
11419	if (BX.type.isFunction(data))
11420	{
11421		callback = data;
11422		data = '';
11423	}
11424
11425	data = BX.ajax.prepareData(data);
11426
11427	if (data)
11428	{
11429		url += (url.indexOf('?') !== -1 ? "&" : "?") + data;
11430		data = '';
11431	}
11432
11433	return BX.ajax({
11434		'method': 'GET',
11435		'dataType': 'html',
11436		'url': url,
11437		'data':  '',
11438		'onsuccess': callback
11439	});
11440};
11441
11442BX.ajax.getCaptcha = function(callback)
11443{
11444	return BX.ajax.loadJSON('/bitrix/tools/ajax_captcha.php', callback);
11445};
11446
11447BX.ajax.insertToNode = function(url, node)
11448{
11449	node = BX(node);
11450	if (!!node)
11451	{
11452		var eventArgs = { cancel: false };
11453		BX.onCustomEvent('onAjaxInsertToNode', [{ url: url, node: node, eventArgs: eventArgs }]);
11454		if(eventArgs.cancel === true)
11455		{
11456			return;
11457		}
11458
11459		var show = null;
11460		if (!tempDefaultConfig.denyShowWait)
11461		{
11462			show = BX.showWait(node);
11463			delete tempDefaultConfig.denyShowWait;
11464		}
11465
11466		return BX.ajax.get(url, function(data) {
11467			node.innerHTML = data;
11468			BX.closeWait(node, show);
11469		});
11470	}
11471};
11472
11473BX.ajax.post = function(url, data, callback)
11474{
11475	data = BX.ajax.prepareData(data);
11476
11477	return BX.ajax({
11478		'method': 'POST',
11479		'dataType': 'html',
11480		'url': url,
11481		'data':  data,
11482		'onsuccess': callback
11483	});
11484};
11485
11486/**
11487 * BX.ajax with BX.Promise
11488 *
11489 * @param config
11490 * @returns {BX.Promise|false}
11491 */
11492BX.ajax.promise = function(config)
11493{
11494	var result = new BX.Promise();
11495
11496	config.onsuccess = function(data)
11497	{
11498		result.fulfill(data);
11499	};
11500	config.onfailure = function(reason, httpStatus, config)
11501	{
11502		result.reject({
11503			reason: reason,
11504			data: httpStatus,
11505			ajaxConfig: config,
11506			xhr: config.xhr
11507		});
11508	};
11509
11510	var xhr = BX.ajax(config);
11511	if (xhr)
11512	{
11513		if (typeof config.onrequeststart === 'function')
11514		{
11515			config.onrequeststart(xhr);
11516		}
11517	}
11518	else
11519	{
11520		result.reject({
11521			reason: "init",
11522			data: false
11523		});
11524	}
11525
11526	return result;
11527};
11528
11529/* load and execute external file script with onload emulation */
11530BX.ajax.loadScriptAjax = function(script_src, callback, bPreload)
11531{
11532	if (BX.type.isArray(script_src))
11533	{
11534		for (var i=0,len=script_src.length;i<len;i++)
11535		{
11536			BX.ajax.loadScriptAjax(script_src[i], callback, bPreload);
11537		}
11538	}
11539	else
11540	{
11541		var script_src_test = script_src.replace(/\.js\?.*/, '.js');
11542
11543		if (r.script_self.test(script_src_test)) return;
11544		if (r.script_self_window.test(script_src_test) && BX.CWindow) return;
11545		if (r.script_self_admin.test(script_src_test) && BX.admin) return;
11546
11547		if (typeof loadedScripts[script_src_test] == 'undefined')
11548		{
11549			if (!!bPreload)
11550			{
11551				loadedScripts[script_src_test] = '';
11552				return BX.loadScript(script_src);
11553			}
11554			else
11555			{
11556				return BX.ajax({
11557					url: script_src,
11558					method: 'GET',
11559					dataType: 'script',
11560					processData: true,
11561					emulateOnload: false,
11562					scriptsRunFirst: true,
11563					async: false,
11564					start: true,
11565					onsuccess: function(result) {
11566						loadedScripts[script_src_test] = result;
11567						if (callback)
11568							callback(result);
11569					}
11570				});
11571			}
11572		}
11573		else if (callback)
11574		{
11575			callback(loadedScripts[script_src_test]);
11576		}
11577	}
11578};
11579
11580/* non-xhr loadings */
11581BX.ajax.loadJSON = function(url, data, callback, callback_failure)
11582{
11583	if (BX.type.isFunction(data))
11584	{
11585		callback_failure = callback;
11586		callback = data;
11587		data = '';
11588	}
11589
11590	data = BX.ajax.prepareData(data);
11591
11592	if (data)
11593	{
11594		url += (url.indexOf('?') !== -1 ? "&" : "?") + data;
11595		data = '';
11596	}
11597
11598	return BX.ajax({
11599		'method': 'GET',
11600		'dataType': 'json',
11601		'url': url,
11602		'onsuccess': callback,
11603		'onfailure': callback_failure
11604	});
11605};
11606
11607var getLastContentTypeHeader = function (headers) {
11608	if (!BX.Type.isArray(headers))
11609	{
11610		return null;
11611	}
11612	var lastHeader = headers
11613		.filter(function (header) {
11614			return header.name === 'Content-Type';
11615		})
11616		.pop();
11617
11618	return lastHeader ? lastHeader.value : null;
11619};
11620
11621/**
11622 * @see isValidAnalyticsData in ui.analytics
11623* */
11624const isValidAnalyticsData = function (analytics)
11625{
11626	if (!BX.Type.isPlainObject(analytics))
11627	{
11628		console.error('BX.ajax: {analytics} must be an object.');
11629
11630		return false;
11631	}
11632
11633	const requiredFields = ['event', 'tool', 'category'];
11634	for (const field of requiredFields)
11635	{
11636		if (!BX.Type.isStringFilled(analytics[field]))
11637		{
11638			console.error(`BX.ajax: The "${field}" property in the "analytics" object must be a non-empty string.`);
11639
11640			return false;
11641		}
11642	}
11643
11644	const additionalFields = ['p1', 'p2', 'p3', 'p4', 'p5'];
11645	for (const field of additionalFields)
11646	{
11647		const value = analytics[field];
11648		if (!BX.Type.isStringFilled(value))
11649		{
11650			continue;
11651		}
11652
11653		if (value.split('_').length > 2)
11654		{
11655			console.error(`BX.ajax: The "${field}" property (${value}) in the "analytics" object must be a string containing a single underscore.`);
11656
11657			return false;
11658		}
11659	}
11660
11661	return true;
11662};
11663
11664const processAnalyticsDataToGetParameters = function(config)
11665{
11666	const getParameters = {};
11667	if (BX.Type.isStringFilled(config.analyticsLabel) || BX.Type.isPlainObject(config.analyticsLabel))
11668	{
11669		getParameters.analyticsLabel = config.analyticsLabel;
11670	}
11671
11672	if (BX.Type.isPlainObject(config.analytics))
11673	{
11674		if (config.analyticsLabel)
11675		{
11676			delete getParameters.analyticsLabel;
11677			console.error('BX.ajax: Only {analytics} or {analyticsLabel} should be used. If both are present, {analyticsLabel} will be ignored.');
11678		}
11679
11680		if (isValidAnalyticsData(config.analytics))
11681		{
11682			getParameters.st = config.analytics;
11683		}
11684		else
11685		{
11686			console.error('BX.ajax: {analytics} is invalid and is skipped.');
11687		}
11688	}
11689
11690	return getParameters;
11691};
11692
11693const prepareAjaxGetParameters = function(config)
11694{
11695	let getParameters = config.getParameters || {};
11696	getParameters = { ...getParameters, ...processAnalyticsDataToGetParameters(config) };
11697
11698	if (typeof config.mode !== 'undefined')
11699	{
11700		getParameters.mode = config.mode;
11701	}
11702	if (config.navigation)
11703	{
11704		if (config.navigation.page)
11705		{
11706			getParameters.nav = 'page-' + config.navigation.page;
11707		}
11708		if (config.navigation.size)
11709		{
11710			if (getParameters.nav)
11711			{
11712				getParameters.nav += '-';
11713			}
11714			else
11715			{
11716				getParameters.nav = '';
11717			}
11718			getParameters.nav += 'size-' + config.navigation.size;
11719		}
11720	}
11721
11722	return getParameters;
11723};
11724
11725var prepareAjaxConfig = function(config)
11726{
11727	config = BX.type.isPlainObject(config) ? config : {};
11728
11729	config.headers = config.headers || [];
11730	config.headers.push({name: 'X-Bitrix-Csrf-Token', value: BX.bitrix_sessid()});
11731	if (BX.message.SITE_ID)
11732	{
11733		config.headers.push({name: 'X-Bitrix-Site-Id', value: BX.message.SITE_ID});
11734	}
11735
11736	if (typeof config.json !== 'undefined')
11737	{
11738		if (!BX.type.isPlainObject(config.json))
11739		{
11740			throw new Error('Wrong `config.json`, plain object expected.')
11741		}
11742
11743		config.headers.push({name: 'Content-Type', value: 'application/json'});
11744		config.data = config.json;
11745		config.preparePost = false;
11746	}
11747	else if (config.data instanceof FormData)
11748	{
11749		config.preparePost = false;
11750		if (typeof config.signedParameters !== 'undefined')
11751		{
11752			config.data.append('signedParameters', config.signedParameters);
11753		}
11754	}
11755	else if (BX.type.isPlainObject(config.data) || BX.Type.isNil(config.data))
11756	{
11757		config.data = BX.type.isPlainObject(config.data) ? config.data : {};
11758		if (typeof config.signedParameters !== 'undefined')
11759		{
11760			config.data.signedParameters = config.signedParameters;
11761		}
11762	}
11763
11764	if (!config.method)
11765	{
11766		config.method = 'POST'
11767	}
11768
11769	return config;
11770};
11771
11772var buildAjaxPromiseToRestoreCsrf = function(config, withoutRestoringCsrf)
11773{
11774	withoutRestoringCsrf = withoutRestoringCsrf || false;
11775	var originalConfig = BX.clone(config);
11776	var request = null;
11777
11778	var onrequeststart = config.onrequeststart;
11779	config.onrequeststart = function(xhr) {
11780		request = xhr;
11781		if (BX.type.isFunction(onrequeststart))
11782		{
11783			onrequeststart(xhr);
11784		}
11785	};
11786	var onrequeststartOrig = originalConfig.onrequeststart;
11787	originalConfig.onrequeststart = function(xhr) {
11788		request = xhr;
11789		if (BX.type.isFunction(onrequeststartOrig))
11790		{
11791			onrequeststartOrig(xhr);
11792		}
11793	};
11794
11795	var promise = BX.ajax.promise(config);
11796
11797	return promise.then(function(response) {
11798		if (!withoutRestoringCsrf && BX.type.isPlainObject(response) && BX.type.isArray(response.errors))
11799		{
11800			var csrfProblem = false;
11801			response.errors.forEach(function(error) {
11802				if (error.code === 'invalid_csrf' && error.customData.csrf)
11803				{
11804					BX.message({'bitrix_sessid': error.customData.csrf});
11805
11806					originalConfig.headers = originalConfig.headers || [];
11807					originalConfig.headers = originalConfig.headers.filter(function(header) {
11808						return header && header.name !== 'X-Bitrix-Csrf-Token';
11809					});
11810					originalConfig.headers.push({name: 'X-Bitrix-Csrf-Token', value: BX.bitrix_sessid()});
11811
11812					csrfProblem = true;
11813				}
11814			});
11815
11816			if (csrfProblem)
11817			{
11818				return buildAjaxPromiseToRestoreCsrf(originalConfig, true);
11819			}
11820		}
11821
11822		if (!BX.type.isPlainObject(response) || response.status !== 'success')
11823		{
11824			var errorPromise = new BX.Promise();
11825			errorPromise.reject(response);
11826
11827			return errorPromise;
11828		}
11829
11830		return response;
11831	}).catch(function(data) {
11832		var ajaxReject = new BX.Promise();
11833
11834		var originalJsonResponse;
11835		if (BX.type.isPlainObject(data) && data.xhr && data.xhr.responseText)
11836		{
11837			try
11838			{
11839				originalJsonResponse = JSON.parse(data.xhr.responseText);
11840				data = originalJsonResponse;
11841			}
11842			catch (err)
11843			{}
11844		}
11845
11846		if (BX.type.isPlainObject(data) && data.status && data.hasOwnProperty('data'))
11847		{
11848			ajaxReject.reject(data);
11849		}
11850		else
11851		{
11852			ajaxReject.reject({
11853				status: 'error',
11854				data: {
11855					ajaxRejectData: data
11856				},
11857				errors: [
11858					{
11859						code: 'NETWORK_ERROR',
11860						message: 'Network error'
11861					}
11862				]
11863			});
11864		}
11865
11866		return ajaxReject;
11867	}).then(function(response){
11868
11869		var assetsLoaded = new BX.Promise();
11870
11871		var headers = request.getAllResponseHeaders().trim().split(/[\r\n]+/);
11872		var headerMap = {};
11873		headers.forEach(function (line) {
11874			var parts = line.split(': ');
11875			var header = parts.shift().toLowerCase();
11876			headerMap[header] = parts.join(': ');
11877		});
11878
11879		if (!headerMap['x-process-assets'])
11880		{
11881			assetsLoaded.fulfill(response);
11882
11883			return assetsLoaded;
11884		}
11885
11886		var assets = BX.prop.getObject(BX.prop.getObject(response, "data", {}), "assets", {});
11887
11888		var inlineScripts = [];
11889		if (BX.Type.isArrayFilled(assets.string))
11890		{
11891			assets.string
11892				.reduce(function(acc, item) {
11893					if (String(item).length > 0 && !acc.includes(item))
11894					{
11895						acc.push(item);
11896					}
11897
11898					return acc;
11899				}, [])
11900				.forEach(function(item) {
11901					if (String(item).startsWith('<script type="extension/settings"'))
11902					{
11903						BX.html(document.head, item, { useAdjacentHTML: true });
11904					}
11905					else
11906					{
11907						inlineScripts.push(item);
11908					}
11909				});
11910		}
11911
11912		var promise = new Promise(function(resolve, reject) {
11913			var css = BX.prop.getArray(assets, "css", []);
11914			BX.load(css, function(){
11915				BX.loadScript(
11916					BX.prop.getArray(assets, "js", []),
11917					resolve
11918				);
11919			});
11920		});
11921
11922		promise.then(function(){
11923			var stringAsset = inlineScripts.join('\n');
11924			BX.html(document.head, stringAsset, { useAdjacentHTML: true }).then(function(){
11925				assetsLoaded.fulfill(response);
11926			});
11927		});
11928
11929		return assetsLoaded;
11930	});
11931};
11932
11933/**
11934 *
11935 * @param {string} action
11936 * @param {Object} config
11937 * @param {?string|?Object} [config.analyticsLabel]
11938 * @param {?Object} [config.analytics]
11939 * @param {string} [config.analytics.event]
11940 * @param {string} [config.analytics.tool]
11941 * @param {string} [config.analytics.category]
11942 * @param {?string} [config.analytics.c_section]
11943 * @param {?string} [config.analytics.c_sub_section]
11944 * @param {?string} [config.analytics.c_element]
11945 * @param {?string} [config.analytics.type]
11946 * @param {?string} [config.analytics.p1]
11947 * @param {?string} [config.analytics.p2]
11948 * @param {?string} [config.analytics.p3]
11949 * @param {?string} [config.analytics.p4]
11950 * @param {?string} [config.analytics.p5]
11951 * @param {?('success' | 'error' | 'attempt' | 'cancel')} [config.analytics.status]
11952 * @param {string} [config.method='POST']
11953 * @param {Object} [config.data]
11954 * @param {?Object} [config.getParameters]
11955 * @param {?Object} [config.headers]
11956 * @param {?Object} [config.timeout]
11957 * @param {Object} [config.navigation]
11958 * @param {number} [config.navigation.page]
11959 */
11960BX.ajax.runAction = function(action, config)
11961{
11962	config = prepareAjaxConfig(config);
11963	var getParameters = prepareAjaxGetParameters(config);
11964	getParameters.action = action;
11965
11966	var url = '/bitrix/services/main/ajax.php?' + BX.ajax.prepareData(getParameters);
11967	return buildAjaxPromiseToRestoreCsrf({
11968		method: config.method,
11969		dataType: 'json',
11970		url: url,
11971		data: config.data,
11972		timeout: config.timeout,
11973		preparePost: config.preparePost,
11974		headers: config.headers,
11975		onrequeststart: config.onrequeststart,
11976		onprogress: config.onprogress,
11977		onprogressupload: config.onprogressupload
11978	});
11979};
11980
11981/**
11982 *
11983 * @param {string} component
11984 * @param {string} action
11985 * @param {Object} config
11986 * @param {?string|?Object} [config.analyticsLabel]
11987 * @param {?Object} [config.analytics]
11988 * @param {string} [config.analytics.event]
11989 * @param {string} [config.analytics.tool]
11990 * @param {string} [config.analytics.category]
11991 * @param {?string} [config.analytics.c_section]
11992 * @param {?string} [config.analytics.c_sub_section]
11993 * @param {?string} [config.analytics.c_element]
11994 * @param {?string} [config.analytics.type]
11995 * @param {?string} [config.analytics.p1]
11996 * @param {?string} [config.analytics.p2]
11997 * @param {?string} [config.analytics.p3]
11998 * @param {?string} [config.analytics.p4]
11999 * @param {?string} [config.analytics.p5]
12000 * @param {?string} [config.signedParameters]
12001 * @param {string} [config.method='POST']
12002 * @param {string} [config.mode='ajax'] Ajax or class.
12003 * @param {Object} [config.data]
12004 * @param {?Object} [config.getParameters]
12005 * @param {?array} [config.headers]
12006 * @param {?number} [config.timeout]
12007 * @param {Object} [config.navigation]
12008 */
12009BX.ajax.runComponentAction = function (component, action, config)
12010{
12011	config = prepareAjaxConfig(config);
12012	config.mode = config.mode || 'ajax';
12013
12014	var getParameters = prepareAjaxGetParameters(config);
12015	getParameters.c = component;
12016	getParameters.action = action;
12017
12018	var url = '/bitrix/services/main/ajax.php?' + BX.ajax.prepareData(getParameters);
12019
12020	return buildAjaxPromiseToRestoreCsrf({
12021		method: config.method,
12022		dataType: 'json',
12023		url: url,
12024		data: config.data,
12025		timeout: config.timeout,
12026		preparePost: config.preparePost,
12027		headers: config.headers,
12028		onrequeststart: (config.onrequeststart ? config.onrequeststart : null),
12029		onprogress: config.onprogress,
12030		onprogressupload: config.onprogressupload
12031	});
12032};
12033
12034/*
12035arObs = [{
12036	url: url,
12037	type: html|script|json|css,
12038	callback: function
12039}]
12040*/
12041BX.ajax.load = function(arObs, callback)
12042{
12043	if (!BX.type.isArray(arObs))
12044		arObs = [arObs];
12045
12046	var cnt = 0;
12047
12048	if (!BX.type.isFunction(callback))
12049		callback = BX.DoNothing;
12050
12051	var handler = function(data)
12052		{
12053			if (BX.type.isFunction(this.callback))
12054				this.callback(data);
12055
12056			if (++cnt >= len)
12057				callback();
12058		};
12059
12060	for (var i = 0, len = arObs.length; i<len; i++)
12061	{
12062		switch(arObs[i].type.toUpperCase())
12063		{
12064			case 'SCRIPT':
12065				BX.loadScript([arObs[i].url], BX.proxy(handler, arObs[i]));
12066			break;
12067			case 'CSS':
12068				BX.loadCSS([arObs[i].url]);
12069
12070				if (++cnt >= len)
12071					callback();
12072			break;
12073			case 'JSON':
12074				BX.ajax.loadJSON(arObs[i].url, BX.proxy(handler, arObs[i]));
12075			break;
12076
12077			default:
12078				BX.ajax.get(arObs[i].url, '', BX.proxy(handler, arObs[i]));
12079			break;
12080		}
12081	}
12082};
12083
12084/* ajax form sending */
12085BX.ajax.submit = function(obForm, callback)
12086{
12087	if (!obForm.target)
12088	{
12089		if (null == obForm.BXFormTarget)
12090		{
12091			var frame_name = 'formTarget_' + Math.random();
12092			obForm.BXFormTarget = document.body.appendChild(BX.create('IFRAME', {
12093				props: {
12094					name: frame_name,
12095					id: frame_name,
12096					src: 'javascript:void(0)'
12097				},
12098				style: {
12099					display: 'none'
12100				}
12101			}));
12102		}
12103
12104		obForm.target = obForm.BXFormTarget.name;
12105	}
12106
12107	obForm.BXFormCallback = callback;
12108	BX.bind(obForm.BXFormTarget, 'load', BX.proxy(BX.ajax._submit_callback, obForm));
12109
12110	BX.submit(obForm);
12111
12112	return false;
12113};
12114
12115BX.ajax.submitComponentForm = function(obForm, container, bWait)
12116{
12117	if (!obForm.target)
12118	{
12119		if (null == obForm.BXFormTarget)
12120		{
12121			var frame_name = 'formTarget_' + Math.random();
12122			obForm.BXFormTarget = document.body.appendChild(BX.create('IFRAME', {
12123				props: {
12124					name: frame_name,
12125					id: frame_name,
12126					src: 'javascript:void(0)'
12127				},
12128				style: {
12129					display: 'none'
12130				}
12131			}));
12132		}
12133
12134		obForm.target = obForm.BXFormTarget.name;
12135	}
12136
12137	if (!!bWait)
12138		var w = BX.showWait(container);
12139
12140	obForm.BXFormCallback = function(d) {
12141		if (!!bWait)
12142			BX.closeWait(w);
12143
12144		var callOnload = function(){
12145			if(!!window.bxcompajaxframeonload)
12146			{
12147				setTimeout(function(){window.bxcompajaxframeonload();window.bxcompajaxframeonload=null;}, 10);
12148			}
12149		};
12150
12151		BX(container).innerHTML = d;
12152		BX.onCustomEvent('onAjaxSuccess', [null,null,callOnload]);
12153	};
12154
12155	BX.bind(obForm.BXFormTarget, 'load', BX.proxy(BX.ajax._submit_callback, obForm));
12156
12157	return true;
12158};
12159
12160// func will be executed in form context
12161BX.ajax._submit_callback = function()
12162{
12163	//opera and IE8 triggers onload event even on empty iframe
12164	try
12165	{
12166		if(this.BXFormTarget.contentWindow.location.href.indexOf('http') != 0)
12167			return;
12168	} catch (e) {
12169		return;
12170	}
12171
12172	if (this.BXFormCallback)
12173		this.BXFormCallback.apply(this, [this.BXFormTarget.contentWindow.document.body.innerHTML]);
12174
12175	BX.unbindAll(this.BXFormTarget);
12176};
12177
12178BX.ajax.prepareForm = function(obForm, data)
12179{
12180	data = (!!data ? data : {});
12181	var i, ii, el,
12182		_data = [],
12183		n = obForm.elements.length,
12184		files = 0, length = 0;
12185	if(!!obForm)
12186	{
12187		for (i = 0; i < n; i++)
12188		{
12189			el = obForm.elements[i];
12190			if (el.disabled)
12191				continue;
12192
12193			if(!el.type)
12194				continue;
12195
12196			switch(el.type.toLowerCase())
12197			{
12198				case 'text':
12199				case 'textarea':
12200				case 'password':
12201				case 'number':
12202				case 'hidden':
12203				case 'select-one':
12204					_data.push({name: el.name, value: el.value});
12205					length += (el.name.length + el.value.length);
12206					break;
12207				case 'file':
12208					if (!!el.files)
12209					{
12210						for (ii = 0; ii < el.files.length; ii++)
12211						{
12212							files++;
12213							_data.push({name: el.name, value: el.files[ii], file : true});
12214							length += el.files[ii].size;
12215						}
12216					}
12217					break;
12218				case 'radio':
12219				case 'checkbox':
12220					if(el.checked)
12221					{
12222						_data.push({name: el.name, value: el.value});
12223						length += (el.name.length + el.value.length);
12224					}
12225					break;
12226				case 'select-multiple':
12227					for (var j = 0; j < el.options.length; j++)
12228					{
12229						if (el.options[j].selected)
12230						{
12231							_data.push({name : el.name, value : el.options[j].value});
12232							length += (el.name.length + el.options[j].length);
12233						}
12234					}
12235					break;
12236				default:
12237					break;
12238			}
12239		}
12240
12241		i = 0; length = 0;
12242		var current = data, name, rest, pp, tmpKey;
12243
12244		while(i < _data.length)
12245		{
12246			var p = _data[i].name.indexOf('[');
12247			if (tmpKey)
12248			{
12249				current[_data[i].name] = {};
12250				current[_data[i].name][tmpKey.replace(/\[|\]/gi, '')] = _data[i].value;
12251				current = data;
12252				tmpKey = null;
12253				i++;
12254			}
12255			else if (p == -1)
12256			{
12257				current[_data[i].name] = _data[i].value;
12258				current = data;
12259				i++;
12260			}
12261			else
12262			{
12263				name = _data[i].name.substring(0, p);
12264				rest = _data[i].name.substring(p+1);
12265				pp = rest.indexOf(']');
12266
12267				if(pp == -1)
12268				{
12269					if (!current[name])
12270						current[name] = [];
12271					current = data;
12272					i++;
12273				}
12274				else if(pp == 0)
12275				{
12276					if (!current[name])
12277						current[name] = [];
12278					//No index specified - so take the next integer
12279					current = current[name];
12280					_data[i].name = '' + current.length;
12281					if (rest.substring(pp+1).indexOf('[') === 0)
12282						tmpKey = rest.substring(0, pp) + rest.substring(pp+1);
12283				}
12284				else
12285				{
12286					if (!current[name])
12287						current[name] = {};
12288					//Now index name becomes and name and we go deeper into the array
12289					current = current[name];
12290					_data[i].name = rest.substring(0, pp) + rest.substring(pp+1);
12291				}
12292			}
12293		}
12294	}
12295	return {data : data, filesCount : files, roughSize : length};
12296};
12297BX.ajax.submitAjax = function(obForm, config)
12298{
12299	config = (config !== null && typeof config == "object" ? config : {});
12300	config.url = (config["url"] || obForm.getAttribute("action"));
12301
12302	var additionalData = (config["data"] || {});
12303	config.data = BX.ajax.prepareForm(obForm).data;
12304	for (var ii in additionalData)
12305	{
12306		if (additionalData.hasOwnProperty(ii))
12307		{
12308			config.data[ii] = additionalData[ii];
12309		}
12310	}
12311
12312	if (!window["FormData"])
12313	{
12314		BX.ajax(config);
12315	}
12316	else
12317	{
12318		var isFile = function(item)
12319		{
12320			var res = Object.prototype.toString.call(item);
12321			return (res == '[object File]' || res == '[object Blob]');
12322		},
12323		appendToForm = function(fd, key, val)
12324		{
12325			if (!!val && typeof val == "object" && !isFile(val))
12326			{
12327				for (var ii in val)
12328				{
12329					if (val.hasOwnProperty(ii))
12330					{
12331						appendToForm(fd, (key == '' ? ii : key + '[' + ii + ']'), val[ii]);
12332					}
12333				}
12334			}
12335			else
12336				fd.append(key, (!!val ? val : ''));
12337		},
12338		prepareData = function(arData)
12339		{
12340			var data = {};
12341			if (null != arData)
12342			{
12343				if(typeof arData == 'object')
12344				{
12345					for(var i in arData)
12346					{
12347						if (arData.hasOwnProperty(i))
12348						{
12349							var name = BX.util.urlencode(i);
12350							if(typeof arData[i] == 'object' && arData[i]["file"] !== true)
12351								data[name] = prepareData(arData[i]);
12352							else if (arData[i]["file"] === true)
12353								data[name] = arData[i]["value"];
12354							else
12355								data[name] = BX.util.urlencode(arData[i]);
12356						}
12357					}
12358				}
12359				else
12360					data = BX.util.urlencode(arData);
12361			}
12362			return data;
12363		},
12364		fd = new window.FormData();
12365
12366		if (config.method !== 'POST')
12367		{
12368			config.data = BX.ajax.prepareData(config.data);
12369			if (config.data)
12370			{
12371				config.url += (config.url.indexOf('?') !== -1 ? "&" : "?") + config.data;
12372				config.data = '';
12373			}
12374		}
12375		else
12376		{
12377			if (config.preparePost === true)
12378				config.data = prepareData(config.data);
12379			appendToForm(fd, '', config.data);
12380			config.data = fd;
12381		}
12382
12383		config.preparePost = false;
12384		config.start = false;
12385
12386		var xhr = BX.ajax(config);
12387		if (!!config["onprogress"])
12388			xhr.upload.addEventListener(
12389				'progress',
12390				function(e){
12391					var percent = null;
12392					if(e.lengthComputable && (e.total || e["totalSize"])) {
12393						percent = e.loaded * 100 / (e.total || e["totalSize"]);
12394					}
12395					config["onprogress"](e, percent);
12396				}
12397			);
12398		xhr.send(fd);
12399	}
12400};
12401
12402BX.ajax.UpdatePageData = function (arData)
12403{
12404	if (arData.TITLE)
12405		BX.ajax.UpdatePageTitle(arData.TITLE);
12406	if (arData.WINDOW_TITLE || arData.TITLE)
12407		BX.ajax.UpdateWindowTitle(arData.WINDOW_TITLE || arData.TITLE);
12408	if (arData.NAV_CHAIN)
12409		BX.ajax.UpdatePageNavChain(arData.NAV_CHAIN);
12410	if (arData.CSS && arData.CSS.length > 0)
12411		BX.loadCSS(arData.CSS);
12412	if (arData.SCRIPTS && arData.SCRIPTS.length > 0)
12413	{
12414		var f = function(result,config,cb){
12415
12416			if(!!config && BX.type.isArray(config.scripts))
12417			{
12418				for(var i=0,l=arData.SCRIPTS.length;i<l;i++)
12419				{
12420					config.scripts.push({isInternal:false,JS:arData.SCRIPTS[i]});
12421				}
12422			}
12423			else
12424			{
12425				BX.loadScript(arData.SCRIPTS,cb);
12426			}
12427
12428			BX.removeCustomEvent('onAjaxSuccess',f);
12429		};
12430		BX.addCustomEvent('onAjaxSuccess',f);
12431	}
12432	else
12433	{
12434		var f1 = function(result,config,cb){
12435			if(BX.type.isFunction(cb))
12436			{
12437				cb();
12438			}
12439			BX.removeCustomEvent('onAjaxSuccess',f1);
12440		};
12441		BX.addCustomEvent('onAjaxSuccess', f1);
12442	}
12443};
12444
12445BX.ajax.UpdatePageTitle = function(title)
12446{
12447	var obTitle = BX('pagetitle');
12448	if (obTitle)
12449	{
12450		BX.remove(obTitle.firstChild);
12451		if (!obTitle.firstChild)
12452			obTitle.appendChild(document.createTextNode(title));
12453		else
12454			obTitle.insertBefore(document.createTextNode(title), obTitle.firstChild);
12455	}
12456};
12457
12458BX.ajax.UpdateWindowTitle = function(title)
12459{
12460	document.title = title;
12461};
12462
12463BX.ajax.UpdatePageNavChain = function(nav_chain)
12464{
12465	var obNavChain = BX('navigation');
12466	if (obNavChain)
12467	{
12468		obNavChain.innerHTML = nav_chain;
12469	}
12470};
12471
12472/* user options handling */
12473BX.userOptions = {
12474	options: null,
12475	bSend: false,
12476	delay: 5000,
12477	path: '/bitrix/admin/user_options.php?'
12478};
12479
12480BX.userOptions.setAjaxPath = function(url)
12481{
12482	// eslint-disable-next-line no-console
12483	console.warn('BX.userOptions.setAjaxPath is deprecated. There is no way to change ajax path.');
12484};
12485BX.userOptions.save = function(category, name, valueName, value, common)
12486{
12487	if (BX.userOptions.options === null)
12488	{
12489		BX.userOptions.options = {};
12490	}
12491
12492	common = Boolean(common);
12493	BX.userOptions.options[`${category}.${name}.${valueName}`] = [category, name, valueName, value, common];
12494
12495	const stringPackedValue = BX.userOptions.__get();
12496	if (stringPackedValue)
12497	{
12498		document.cookie = `${BX.message('COOKIE_PREFIX')}_LAST_SETTINGS=${encodeURIComponent(stringPackedValue)}&sessid=${BX.bitrix_sessid()}; expires=Thu, 31 Dec ${(new Date()).getFullYear() + 1} 23:59:59 GMT; path=/;`;
12499	}
12500
12501	if (!BX.userOptions.bSend)
12502	{
12503		BX.userOptions.bSend = true;
12504		setTimeout(() => {
12505			BX.userOptions.send(null);
12506		}, BX.userOptions.delay);
12507	}
12508};
12509
12510BX.userOptions.send = function(callback)
12511{
12512	const values = BX.userOptions.__get_values({ backwardCompatibility: true});
12513
12514	BX.userOptions.options = null;
12515	BX.userOptions.bSend = false;
12516
12517	if (values)
12518	{
12519		document.cookie = `${BX.message('COOKIE_PREFIX')}_LAST_SETTINGS=; path=/;`;
12520
12521		BX.ajax.runAction(
12522			'main.userOption.saveOptions',
12523			{
12524				json: {
12525					newValues: values,
12526				},
12527			},
12528		).then((response) => {
12529			if (BX.type.isFunction(callback))
12530			{
12531				callback(response);
12532			}
12533		});
12534	}
12535};
12536
12537BX.userOptions.del = function(category, name, common, callback)
12538{
12539	BX.ajax.runAction(
12540		'main.userOption.deleteOption',
12541		{
12542			json: {
12543				category,
12544				name,
12545				common,
12546			},
12547		},
12548	).then((response) => {
12549		if (BX.type.isFunction(callback))
12550		{
12551			callback(response);
12552		}
12553	});
12554};
12555
12556BX.userOptions.__get_values = function({ backwardCompatibility })
12557{
12558	if (!BX.userOptions || !BX.Type.isPlainObject(BX.userOptions.options))
12559	{
12560		return null;
12561	}
12562
12563	const CATEGORY = 0;
12564	const NAME = 1;
12565	const VALUE_NAME = 2;
12566	const VALUE = 3;
12567	const IS_DEFAULT = 4;
12568
12569	const packedValues = { p: [] };
12570	let currentIndex = -1;
12571	let previousOptionIdentifier = '';
12572
12573	Object.entries(BX.userOptions.options).forEach(([key, userOption]) => {
12574		const category = userOption[CATEGORY];
12575		const name = userOption[NAME];
12576		const currentOptionIdentifier = `${category}.${name}`;
12577
12578		if (previousOptionIdentifier !== currentOptionIdentifier)
12579		{
12580			currentIndex++;
12581			packedValues.p.push({
12582				c: category,
12583				n: name,
12584				v: {},
12585			});
12586			if (userOption[IS_DEFAULT] === true)
12587			{
12588				packedValues.p[currentIndex].d = 'Y';
12589			}
12590			previousOptionIdentifier = currentOptionIdentifier;
12591		}
12592
12593		if (userOption[VALUE_NAME] === null)
12594		{
12595			packedValues.p[currentIndex].v = userOption[VALUE];
12596		}
12597		else
12598		{
12599			let data = userOption[VALUE];
12600			if (backwardCompatibility && Array.isArray(userOption[VALUE]))
12601			{
12602				data = userOption[VALUE].join(',');
12603			}
12604			packedValues.p[currentIndex].v[userOption[VALUE_NAME]] = data;
12605		}
12606	});
12607
12608	return packedValues.p.length > 0 ? packedValues.p : null;
12609};
12610
12611/**
12612 * @deprecated Use instead BX.userOptions.__get_values.
12613 * */
12614BX.userOptions.__get = function()
12615{
12616	if (!BX.userOptions.options) return '';
12617
12618	var sParam = '', n = -1, prevParam = '', aOpt, i;
12619
12620	for (i in BX.userOptions.options)
12621	{
12622		if(BX.userOptions.options.hasOwnProperty(i))
12623		{
12624			aOpt = BX.userOptions.options[i];
12625
12626			if (prevParam != aOpt[0]+'.'+aOpt[1])
12627			{
12628				n++;
12629				sParam += '&p['+n+'][c]='+BX.util.urlencode(aOpt[0]);
12630				sParam += '&p['+n+'][n]='+BX.util.urlencode(aOpt[1]);
12631				if (aOpt[4] == true)
12632					sParam += '&p['+n+'][d]=Y';
12633				prevParam = aOpt[0]+'.'+aOpt[1];
12634			}
12635
12636			var valueName = aOpt[2];
12637			var value = aOpt[3];
12638
12639			if (valueName === null)
12640			{
12641				sParam += '&p['+n+'][v]='+BX.util.urlencode(value);
12642			}
12643			else
12644			{
12645				sParam += '&p['+n+'][v]['+BX.util.urlencode(valueName)+']='+BX.util.urlencode(value);
12646			}
12647		}
12648	}
12649
12650	return sParam.substr(1);
12651};
12652
12653BX.ajax.history = {
12654	expected_hash: '',
12655
12656	obParams: null,
12657
12658	obFrame: null,
12659	obImage: null,
12660
12661	obTimer: null,
12662
12663	bInited: false,
12664	bHashCollision: false,
12665	bPushState: !!(history.pushState && BX.type.isFunction(history.pushState)),
12666
12667	startState: null,
12668
12669	init: function(obParams)
12670	{
12671		if (BX.ajax.history.bInited)
12672			return;
12673
12674		this.obParams = obParams;
12675		var obCurrentState = this.obParams.getState();
12676
12677		if (BX.ajax.history.bPushState)
12678		{
12679			BX.ajax.history.expected_hash = window.location.pathname;
12680			if (window.location.search)
12681				BX.ajax.history.expected_hash += window.location.search;
12682
12683			BX.ajax.history.put(obCurrentState, BX.ajax.history.expected_hash, '', true);
12684			// due to some strange thing, chrome calls popstate event on page start. so we should delay it
12685			setTimeout(function(){BX.bind(window, 'popstate', BX.ajax.history.__hashListener);}, 500);
12686		}
12687		else
12688		{
12689			BX.ajax.history.expected_hash = window.location.hash;
12690
12691			if (!BX.ajax.history.expected_hash || BX.ajax.history.expected_hash == '#')
12692				BX.ajax.history.expected_hash = '__bx_no_hash__';
12693
12694			jsAjaxHistoryContainer.put(BX.ajax.history.expected_hash, obCurrentState);
12695			BX.ajax.history.obTimer = setTimeout(BX.ajax.history.__hashListener, 500);
12696
12697			if (BX.browser.IsIE())
12698			{
12699				BX.ajax.history.obFrame = document.createElement('IFRAME');
12700				BX.hide_object(BX.ajax.history.obFrame);
12701
12702				document.body.appendChild(BX.ajax.history.obFrame);
12703
12704				BX.ajax.history.obFrame.contentWindow.document.open();
12705				BX.ajax.history.obFrame.contentWindow.document.write(BX.ajax.history.expected_hash);
12706				BX.ajax.history.obFrame.contentWindow.document.close();
12707			}
12708			else if (BX.browser.IsOpera())
12709			{
12710				BX.ajax.history.obImage = document.createElement('IMG');
12711				BX.hide_object(BX.ajax.history.obImage);
12712
12713				document.body.appendChild(BX.ajax.history.obImage);
12714
12715				BX.ajax.history.obImage.setAttribute('src', 'javascript:location.href = \'javascript:BX.ajax.history.__hashListener();\';');
12716			}
12717		}
12718
12719		BX.ajax.history.bInited = true;
12720	},
12721
12722	__hashListener: function(e)
12723	{
12724		e = e || window.event || {state:false};
12725
12726		if (BX.ajax.history.bPushState)
12727		{
12728			BX.ajax.history.obParams.setState(e.state||BX.ajax.history.startState);
12729		}
12730		else
12731		{
12732			if (BX.ajax.history.obTimer)
12733			{
12734				window.clearTimeout(BX.ajax.history.obTimer);
12735				BX.ajax.history.obTimer = null;
12736			}
12737
12738			var current_hash;
12739			if (null != BX.ajax.history.obFrame)
12740				current_hash = BX.ajax.history.obFrame.contentWindow.document.body.innerText;
12741			else
12742				current_hash = window.location.hash;
12743
12744			if (!current_hash || current_hash == '#')
12745				current_hash = '__bx_no_hash__';
12746
12747			if (current_hash.indexOf('#') == 0)
12748				current_hash = current_hash.substring(1);
12749
12750			if (current_hash != BX.ajax.history.expected_hash)
12751			{
12752				var state = jsAjaxHistoryContainer.get(current_hash);
12753				if (state)
12754				{
12755					BX.ajax.history.obParams.setState(state);
12756
12757					BX.ajax.history.expected_hash = current_hash;
12758					if (null != BX.ajax.history.obFrame)
12759					{
12760						var __hash = current_hash == '__bx_no_hash__' ? '' : current_hash;
12761						if (window.location.hash != __hash && window.location.hash != '#' + __hash)
12762							window.location.hash = __hash;
12763					}
12764				}
12765			}
12766
12767			BX.ajax.history.obTimer = setTimeout(BX.ajax.history.__hashListener, 500);
12768		}
12769	},
12770
12771	put: function(state, new_hash, new_hash1, bStartState)
12772	{
12773		if (this.bPushState)
12774		{
12775			if(!bStartState)
12776			{
12777				history.pushState(state, '', new_hash);
12778			}
12779			else
12780			{
12781				BX.ajax.history.startState = state;
12782			}
12783		}
12784		else
12785		{
12786			if (typeof new_hash1 != 'undefined')
12787				new_hash = new_hash1;
12788			else
12789				new_hash = 'view' + new_hash;
12790
12791			jsAjaxHistoryContainer.put(new_hash, state);
12792			BX.ajax.history.expected_hash = new_hash;
12793
12794			window.location.hash = BX.util.urlencode(new_hash);
12795
12796			if (null != BX.ajax.history.obFrame)
12797			{
12798				BX.ajax.history.obFrame.contentWindow.document.open();
12799				BX.ajax.history.obFrame.contentWindow.document.write(new_hash);
12800				BX.ajax.history.obFrame.contentWindow.document.close();
12801			}
12802		}
12803	},
12804
12805	checkRedirectStart: function(param_name, param_value)
12806	{
12807		var current_hash = window.location.hash;
12808		if (current_hash.substring(0, 1) == '#') current_hash = current_hash.substring(1);
12809
12810		var test = current_hash.substring(0, 5);
12811		if (test == 'view/' || test == 'view%')
12812		{
12813			BX.ajax.history.bHashCollision = true;
12814			document.write('<' + 'div id="__ajax_hash_collision_' + param_value + '" style="display: none;">');
12815		}
12816	},
12817
12818	checkRedirectFinish: function(param_name, param_value)
12819	{
12820		document.write('</div>');
12821
12822		var current_hash = window.location.hash;
12823		if (current_hash.substring(0, 1) == '#') current_hash = current_hash.substring(1);
12824
12825		BX.ready(function ()
12826		{
12827			var test = current_hash.substring(0, 5);
12828			if (test == 'view/' || test == 'view%')
12829			{
12830				var obColNode = BX('__ajax_hash_collision_' + param_value);
12831				var obNode = obColNode.firstChild;
12832				BX.cleanNode(obNode);
12833				obColNode.style.display = 'block';
12834
12835				// IE, Opera and Chrome automatically modifies hash with urlencode, but FF doesn't ;-(
12836				if (test != 'view%')
12837					current_hash = BX.util.urlencode(current_hash);
12838
12839				current_hash += (current_hash.indexOf('%3F') == -1 ? '%3F' : '%26') + param_name + '=' + param_value;
12840
12841				var url = '/bitrix/tools/ajax_redirector.php?hash=' + current_hash;
12842
12843				BX.ajax.insertToNode(url, obNode);
12844			}
12845		});
12846	}
12847};
12848
12849BX.ajax.component = function(node)
12850{
12851	this.node = node;
12852};
12853
12854BX.ajax.component.prototype.getState = function()
12855{
12856	var state = {
12857		'node': this.node,
12858		'title': window.document.title,
12859		'data': BX(this.node).innerHTML
12860	};
12861
12862	var obNavChain = BX('navigation');
12863	if (null != obNavChain)
12864		state.nav_chain = obNavChain.innerHTML;
12865
12866	BX.onCustomEvent(BX(state.node), "onComponentAjaxHistoryGetState", [state]);
12867
12868	return state;
12869};
12870
12871BX.ajax.component.prototype.setState = function(state)
12872{
12873	BX(state.node).innerHTML = state.data;
12874	BX.ajax.UpdatePageTitle(state.title);
12875
12876	if (state.nav_chain)
12877	{
12878		BX.ajax.UpdatePageNavChain(state.nav_chain);
12879	}
12880
12881	BX.onCustomEvent(BX(state.node), "onComponentAjaxHistorySetState", [state]);
12882};
12883
12884var jsAjaxHistoryContainer = {
12885	arHistory: {},
12886
12887	put: function(hash, state)
12888	{
12889		this.arHistory[hash] = state;
12890	},
12891
12892	get: function(hash)
12893	{
12894		return this.arHistory[hash];
12895	}
12896};
12897
12898
12899BX.ajax.FormData = function()
12900{
12901	this.elements = [];
12902	this.files = [];
12903	this.features = {};
12904	this.isSupported();
12905	this.log('BX FormData init');
12906};
12907
12908BX.ajax.FormData.isSupported = function()
12909{
12910	var f = new BX.ajax.FormData();
12911	var result = f.features.supported;
12912	f = null;
12913	return result;
12914};
12915
12916BX.ajax.FormData.prototype.log = function(o)
12917{
12918	if (false) {
12919		try {
12920			if (BX.browser.IsIE()) o = JSON.stringify(o);
12921			console.log(o);
12922		} catch(e) {}
12923	}
12924};
12925
12926BX.ajax.FormData.prototype.isSupported = function()
12927{
12928	var f = {};
12929	f.fileReader = (window.FileReader && window.FileReader.prototype.readAsBinaryString);
12930	f.readFormData = f.sendFormData = !!(window.FormData);
12931	f.supported = !!(f.readFormData && f.sendFormData);
12932	this.features = f;
12933	this.log('features:');
12934	this.log(f);
12935
12936	return f.supported;
12937};
12938
12939BX.ajax.FormData.prototype.append = function(name, value)
12940{
12941	if (typeof(value) === 'object') { // seems to be files element
12942		this.files.push({'name': name, 'value':value});
12943	} else {
12944		this.elements.push({'name': name, 'value':value});
12945	}
12946};
12947
12948BX.ajax.FormData.prototype.send = function(url, callbackOk, callbackProgress, callbackError)
12949{
12950	this.log('FD send');
12951	this.xhr = BX.ajax({
12952			'method': 'POST',
12953			'dataType': 'html',
12954			'url': url,
12955			'onsuccess': callbackOk,
12956			'onfailure': callbackError,
12957			'start': false,
12958			'preparePost':false
12959		});
12960
12961	if (callbackProgress)
12962	{
12963		this.xhr.upload.addEventListener(
12964			'progress',
12965			function(e) {
12966				if (e.lengthComputable)
12967					callbackProgress(e.loaded / (e.total || e.totalSize));
12968			},
12969			false
12970		);
12971	}
12972
12973	if (this.features.readFormData && this.features.sendFormData)
12974	{
12975		var fd = new FormData();
12976		this.log('use browser formdata');
12977		for (var i in this.elements)
12978		{
12979			if(this.elements.hasOwnProperty(i))
12980				fd.append(this.elements[i].name,this.elements[i].value);
12981		}
12982		for (i in this.files)
12983		{
12984			if(this.files.hasOwnProperty(i))
12985				fd.append(this.files[i].name, this.files[i].value);
12986		}
12987		this.xhr.send(fd);
12988	}
12989
12990	return this.xhr;
12991};
12992
12993BX.addCustomEvent('onAjaxFailure', BX.debug);
12994})(window);
12995
12996
12997
12998(function (exports,main_core) {
12999	'use strict';
13000
13001	var LazyLoad = {
13002		observer: null,
13003		images: {},
13004		imageStatus: {
13005			hidden: -2,
13006			error: -1,
13007			"undefined": 0,
13008			inited: 1,
13009			loaded: 2
13010		},
13011		imageTypes: {
13012			image: 1,
13013			background: 2
13014		},
13015		initObserver: function initObserver() {
13016			this.observer = new IntersectionObserver(this.onIntersection.bind(this), {
13017				rootMargin: '20% 0% 20% 0%',
13018				threshold: 0.10
13019			});
13020		},
13021		onIntersection: function onIntersection(entries) {
13022			entries.forEach(function (entry) {
13023				if (entry.isIntersecting) {
13024					this.showImage(entry.target);
13025				}
13026			}.bind(this));
13027		},
13028		registerImage: function registerImage(id, isImageVisibleCallback, options) {
13029			if (this.observer === null) {
13030				this.initObserver();
13031			}
13032
13033			options = options || {};
13034
13035			if (!main_core.Type.isStringFilled(id)) {
13036				return;
13037			}
13038
13039			if (main_core.Type.isObject(this.images[id])) {
13040				return;
13041			}
13042
13043			var element = document.getElementById(id);
13044
13045			if (!main_core.Type.isDomNode(element)) {
13046				return;
13047			}
13048
13049			this.observer.observe(element);
13050			this.images[id] = {
13051				id: id,
13052				node: null,
13053				src: null,
13054				dataSrcName: options.dataSrcName || 'src',
13055				type: null,
13056				func: main_core.Type.isFunction(isImageVisibleCallback) ? isImageVisibleCallback : null,
13057				status: this.imageStatus.undefined
13058			};
13059		},
13060		registerImages: function registerImages(ids, isImageVisibleCallback, options) {
13061			if (main_core.Type.isArray(ids)) {
13062				for (var i = 0, length = ids.length; i < length; i++) {
13063					this.registerImage(ids[i], isImageVisibleCallback, options);
13064				}
13065			}
13066		},
13067		showImage: function showImage(imageNode) {
13068			var imageNodeId = imageNode.id;
13069
13070			if (!main_core.Type.isStringFilled(imageNodeId)) {
13071				return;
13072			}
13073
13074			var image = this.images[imageNodeId];
13075
13076			if (!main_core.Type.isPlainObject(image)) {
13077				return;
13078			}
13079
13080			if (image.status == this.imageStatus.undefined) {
13081				this.initImage(image);
13082			}
13083
13084			if (image.status !== this.imageStatus.inited) {
13085				return;
13086			}
13087
13088			if (!image.node || !image.node.parentNode) {
13089				image.node = null;
13090				image.status = this.imageStatus.error;
13091				return;
13092			}
13093
13094			if (image.type == this.imageTypes.image) {
13095				image.node.src = image.src;
13096			} else {
13097				image.node.style.backgroundImage = "url('" + image.src + "')";
13098			}
13099
13100			image.node.dataset[image.dataSrcName] = "";
13101			image.status = this.imageStatus.loaded;
13102		},
13103		showImages: function showImages(checkOwnVisibility) {
13104			checkOwnVisibility = checkOwnVisibility !== false;
13105
13106			for (var id in this.images) {
13107				if (!this.images.hasOwnProperty(id)) {
13108					continue;
13109				}
13110
13111				var image = this.images[id];
13112
13113				if (image.status == this.imageStatus.undefined) {
13114					this.initImage(image);
13115				}
13116
13117				if (image.status !== this.imageStatus.inited) {
13118					continue;
13119				}
13120
13121				if (!image.node || !image.node.parentNode) {
13122					image.node = null;
13123					image.status = this.imageStatus.error;
13124					continue;
13125				}
13126
13127				var isImageVisible = true;
13128
13129				if (checkOwnVisibility && main_core.Type.isFunction(image.func)) {
13130					isImageVisible = image.func(image);
13131				}
13132
13133				if (isImageVisible === true && this.isElementVisibleOnScreen(image.node)) {
13134					if (image.type == this.imageTypes.image) {
13135						image.node.src = image.src;
13136					} else {
13137						image.node.style.backgroundImage = "url('" + image.src + "')";
13138					}
13139
13140					image.node.dataset[image.dataSrcName] = "";
13141					image.status = this.imageStatus.loaded;
13142				}
13143			}
13144		},
13145		initImage: function initImage(image) {
13146			image.status = this.imageStatus.error;
13147			var node = document.getElementById(image.id);
13148
13149			if (!main_core.Type.isDomNode(node)) {
13150				return;
13151			}
13152
13153			var src = node.dataset[image.dataSrcName];
13154
13155			if (main_core.Type.isStringFilled(src)) {
13156				image.node = node;
13157				image.src = src;
13158				image.status = this.imageStatus.inited;
13159				image.type = image.node.tagName.toLowerCase() == "img" ? this.imageTypes.image : this.imageTypes.background;
13160			}
13161		},
13162		isElementVisibleOnScreen: function isElementVisibleOnScreen(element) {
13163			var coords = this.getElementCoords(element);
13164			var windowTop = window.pageYOffset || document.documentElement.scrollTop;
13165			var windowBottom = windowTop + document.documentElement.clientHeight;
13166			coords.bottom = coords.top + element.offsetHeight;
13167			return coords.top > windowTop && coords.top < windowBottom || // topVisible
13168			coords.bottom < windowBottom && coords.bottom > windowTop // bottomVisible
13169			;
13170		},
13171		isElementVisibleOn2Screens: function isElementVisibleOn2Screens(element) {
13172			var windowHeight = document.documentElement.clientHeight;
13173			var windowTop = window.pageYOffset || document.documentElement.scrollTop;
13174			var windowBottom = windowTop + windowHeight;
13175			var coords = this.getElementCoords(element);
13176			coords.bottom = coords.top + element.offsetHeight;
13177			windowTop -= windowHeight;
13178			windowBottom += windowHeight;
13179			return coords.top > windowTop && coords.top < windowBottom || // topVisible
13180			coords.bottom < windowBottom && coords.bottom > windowTop // bottomVisible
13181			;
13182		},
13183		getElementCoords: function getElementCoords(element) {
13184			var box = element.getBoundingClientRect();
13185			return {
13186				originTop: box.top,
13187				originLeft: box.left,
13188				top: box.top + window.pageYOffset,
13189				left: box.left + window.pageXOffset
13190			};
13191		},
13192		onScroll: function onScroll() {},
13193		clearImages: function clearImages() {
13194			this.images = [];
13195		}
13196	};
13197
13198	exports.LazyLoad = LazyLoad;
13199
13200}((this.BX = this.BX || {}),BX));
13201
13202
13203
13204(function (exports) {
13205	'use strict';
13206
13207	var ParamBag = /*#__PURE__*/function () {
13208		function ParamBag() {
13209			var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
13210			babelHelpers.classCallCheck(this, ParamBag);
13211
13212			if (!!params && babelHelpers.typeof(params) === 'object') {
13213				this.params = new Map(Object.entries(params));
13214			} else {
13215				this.params = new Map();
13216			}
13217		}
13218
13219		babelHelpers.createClass(ParamBag, [{
13220			key: "getParam",
13221			value: function getParam(key) {
13222				var defaultValue = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
13223
13224				if (this.params.has(key)) {
13225					return this.params.get(key);
13226				}
13227
13228				return defaultValue;
13229			}
13230		}, {
13231			key: "setParam",
13232			value: function setParam(key, value) {
13233				this.params.set(key, value);
13234			}
13235		}, {
13236			key: "clear",
13237			value: function clear() {
13238				this.params.clear();
13239			}
13240		}], [{
13241			key: "create",
13242			value: function create() {
13243				var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
13244				return new ParamBag(params);
13245			}
13246		}]);
13247		return ParamBag;
13248	}();
13249
13250	exports.ParamBag = ParamBag;
13251
13252}((this.BX = this.BX || {})));
13253
13254
13255
13256(function() {
13257	BX.FixFontSize = function(params)
13258	{
13259		var widthNode, computedStyles, width;
13260
13261		this.node = null;
13262		this.prevWindowSize = 0;
13263		this.prevWrapperSize = 0;
13264		this.mainWrapper = null;
13265		this.textWrapper = null;
13266		this.objList = params.objList;
13267		this.minFontSizeList = [];
13268		this.minFontSize = 0;
13269
13270		if (params.onresize)
13271		{
13272			this.prevWindowSize = window.innerWidth || document.documentElement.clientWidth;
13273			BX.bind(window, 'resize', BX.throttle(this.onResize, 350, this));
13274		}
13275
13276		if (params.onAdaptiveResize)
13277		{
13278			widthNode = this.objList[0].scaleBy || this.objList[0].node;
13279			computedStyles = getComputedStyle(widthNode);
13280			this.prevWrapperSize = parseInt(computedStyles["width"]) - parseInt(computedStyles["paddingLeft"]) - parseInt(computedStyles["paddingRight"]);
13281			BX.bind(window, 'resize', BX.throttle(this.onAdaptiveResize, 350, this));
13282		}
13283
13284		this.createTestNodes();
13285		this.decrease();
13286	};
13287
13288	BX.FixFontSize.prototype =
13289		{
13290			createTestNodes: function()
13291			{
13292				this.textWrapper = BX.create('div',{
13293					style : {
13294						display : 'inline-block',
13295						whiteSpace : 'nowrap'
13296					}
13297				});
13298
13299				this.mainWrapper = BX.create('div',{
13300					style : {
13301						height : 0,
13302						overflow : 'hidden'
13303					},
13304					children : [this.textWrapper]
13305				});
13306
13307			},
13308			insertTestNodes: function()
13309			{
13310				document.body.appendChild(this.mainWrapper);
13311			},
13312			removeTestNodes: function()
13313			{
13314				document.body.removeChild(this.mainWrapper);
13315			},
13316			decrease: function()
13317			{
13318				var width,
13319					fontSize,
13320					widthNode,
13321					computedStyles;
13322
13323				this.insertTestNodes();
13324
13325				for(var i=this.objList.length-1; i>=0; i--)
13326				{
13327					widthNode = this.objList[i].scaleBy || this.objList[i].node;
13328					computedStyles = getComputedStyle(widthNode);
13329					width  = parseInt(computedStyles["width"]) - parseInt(computedStyles["paddingLeft"]) - parseInt(computedStyles["paddingRight"]);
13330					fontSize = parseInt(getComputedStyle(this.objList[i].node)["font-size"]);
13331
13332					this.textWrapperSetStyle(this.objList[i].node);
13333
13334					if(this.textWrapperInsertText(this.objList[i].node))
13335					{
13336						while(this.textWrapper.offsetWidth > width && fontSize > 0)
13337						{
13338							this.textWrapper.style.fontSize = --fontSize + 'px';
13339						}
13340
13341						if(this.objList[i].smallestValue)
13342						{
13343							this.minFontSize = this.minFontSize ? Math.min(this.minFontSize, fontSize) : fontSize;
13344
13345							this.minFontSizeList.push(this.objList[i].node)
13346						}
13347						else
13348						{
13349							this.objList[i].node.style.fontSize = fontSize + 'px';
13350						}
13351					}
13352				}
13353
13354				if(this.minFontSizeList.length > 0)
13355					this.setMinFont();
13356
13357				this.removeTestNodes();
13358
13359			},
13360			increase: function()
13361			{
13362				this.insertTestNodes();
13363				var width,
13364					fontSize,
13365					widthNode,
13366					computedStyles;
13367
13368				this.insertTestNodes();
13369
13370				for(var i=this.objList.length-1; i>=0; i--)
13371				{
13372					widthNode = this.objList[i].scaleBy || this.objList[i].node;
13373					computedStyles = getComputedStyle(widthNode);
13374					width  = parseInt(computedStyles["width"]) - parseInt(computedStyles["paddingLeft"]) - parseInt(computedStyles["paddingRight"]);
13375					fontSize = parseInt(getComputedStyle(this.objList[i].node)["font-size"]);
13376
13377					this.textWrapperSetStyle(this.objList[i].node);
13378
13379					if(this.textWrapperInsertText(this.objList[i].node))
13380					{
13381						while(this.textWrapper.offsetWidth < width && fontSize < this.objList[i].maxFontSize)
13382						{
13383							this.textWrapper.style.fontSize = ++fontSize + 'px';
13384						}
13385
13386						fontSize--;
13387
13388						if(this.objList[i].smallestValue)
13389						{
13390							this.minFontSize = this.minFontSize ? Math.min(this.minFontSize, fontSize) : fontSize;
13391
13392							this.minFontSizeList.push(this.objList[i].node)
13393						}
13394						else
13395						{
13396							this.objList[i].node.style.fontSize = fontSize + 'px';
13397						}
13398					}
13399				}
13400
13401				if(this.minFontSizeList.length > 0)
13402					this.setMinFont();
13403
13404				this.removeTestNodes();
13405			},
13406			setMinFont : function()
13407			{
13408				for(var i = this.minFontSizeList.length-1; i>=0; i--)
13409				{
13410					this.minFontSizeList[i].style.fontSize = this.minFontSize + 'px';
13411				}
13412
13413				this.minFontSize = 0;
13414			},
13415			onResize : function()
13416			{
13417				var width = window.innerWidth || document.documentElement.clientWidth;
13418
13419				if(this.prevWindowSize > width)
13420					this.decrease();
13421
13422				else if (this.prevWindowSize < width)
13423					this.increase();
13424
13425				this.prevWindowSize = width;
13426			},
13427			onAdaptiveResize : function()
13428			{
13429				var widthNode = this.objList[0].scaleBy || this.objList[0].node,
13430					computedStyles = getComputedStyle(widthNode),
13431					width = parseInt(computedStyles["width"]) - parseInt(computedStyles["paddingLeft"]) - parseInt(computedStyles["paddingRight"]);
13432
13433				if (this.prevWrapperSize > width)
13434					this.decrease();
13435				else if (this.prevWrapperSize < width)
13436					this.increase();
13437
13438				this.prevWrapperSize = width;
13439			},
13440			textWrapperInsertText : function(node)
13441			{
13442				if(node.textContent){
13443					this.textWrapper.textContent = node.textContent;
13444					return true;
13445				}
13446				else if(node.innerText)
13447				{
13448					this.textWrapper.innerText = node.innerText;
13449					return true;
13450				}
13451				else {
13452					return false;
13453				}
13454			},
13455			textWrapperSetStyle : function(node)
13456			{
13457				this.textWrapper.style.fontFamily = getComputedStyle(node)["font-family"];
13458				this.textWrapper.style.fontSize = getComputedStyle(node)["font-size"];
13459				this.textWrapper.style.fontStyle = getComputedStyle(node)["font-style"];
13460				this.textWrapper.style.fontWeight = getComputedStyle(node)["font-weight"];
13461				this.textWrapper.style.lineHeight = getComputedStyle(node)["line-height"];
13462			}
13463		};
13464
13465	BX.FixFontSize.init = function(params)
13466	{
13467		return new BX.FixFontSize(params);
13468	};
13469})();
13470
13471})();
13472//# sourceMappingURL=core.js.map

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.