PageSourceSearch

https://bonsay.ru/bitrix/cache/js/s1/aspro_max/kernel_main/kernel_main_v1.js?1748269069310329

js bonsay.ru collected 2026-10-02 10:24:21 UTC 310,329 bytes, 11,758 lines download raw bytes

1; /* /bitrix/js/main/core/core_uf.js?174824846118793*/
2; /* /bitrix/js/main/core/core_dd.js?15867829843613*/
3; /* /bitrix/js/main/core/core_tooltip.js?172258261515634*/
4; /* /bitrix/js/main/session.js?16395609593701*/
5; /* /bitrix/js/main/utils.js?161544141129279*/
6; /* /bitrix/js/main/core/core_fx.js?158678298416888*/
7; /* /bitrix/js/main/pageobject/pageobject.js?1589097375864*/
8; /* /bitrix/js/main/core/core_window.js?172258261598766*/
9; /* /bitrix/js/main/date/main.date.js?174824846962683*/
10; /* /bitrix/js/main/core/core_date.js?161544141136080*/
11; /* /bitrix/js/main/core/core_timer.js?16379236876316*/
12; /* /bitrix/js/main/dd.js?169147814014809*/
13
14; /* Start:"a:4:{s:4:"full";s:47:"/bitrix/js/main/core/core_fx.js?158678298416888";s:6:"source";s:31:"/bitrix/js/main/core/core_fx.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
15;(function(window){
16
17var defaultOptions = {
18	time: 1.0,
19	step: 0.05,
20	type: 'linear',
21
22	allowFloat: false
23}
24
25/*
26options: {
27	start: start value or {param: value, param: value}
28	finish: finish value or {param: value, param: value}
29	time: time to transform in seconds
30	type: linear|accelerated|decelerated|custom func name
31	callback,
32	callback_start,
33	callback_complete,
34
35	step: time between steps in seconds
36	allowFloat: false|true
37}
38*/
39BX.fx = function(options)
40{
41	this.options = options;
42
43	if (null != this.options.time)
44		this.options.originalTime = this.options.time;
45	if (null != this.options.step)
46		this.options.originalStep = this.options.step;
47
48	if (!this.__checkOptions())
49		return false;
50
51	this.__go = BX.delegate(this.go, this);
52
53	this.PARAMS = {};
54}
55
56BX.fx.prototype.__checkOptions = function()
57{
58	if (typeof this.options.start != typeof this.options.finish)
59		return false;
60
61	if (null == this.options.time) this.options.time = defaultOptions.time;
62	if (null == this.options.step) this.options.step = defaultOptions.step;
63	if (null == this.options.type) this.options.type = defaultOptions.type;
64	if (null == this.options.allowFloat) this.options.allowFloat = defaultOptions.allowFloat;
65
66	this.options.time *= 1000;
67	this.options.step *= 1000;
68
69	if (typeof this.options.start != 'object')
70	{
71		this.options.start = {_param: this.options.start};
72		this.options.finish = {_param: this.options.finish};
73	}
74
75	var i;
76	for (i in this.options.start)
77	{
78		if (null == this.options.finish[i])
79		{
80			this.options.start[i] = null;
81			delete this.options.start[i];
82		}
83	}
84
85	if (!BX.type.isFunction(this.options.type))
86	{
87		if (BX.type.isFunction(window[this.options.type]))
88			this.options.type = window[this.options.type];
89		else if (BX.type.isFunction(BX.fx.RULES[this.options.type]))
90			this.options.type = BX.fx.RULES[this.options.type];
91		else
92			this.options.type = BX.fx.RULES[defaultOptions.type];
93	}
94
95	return true;
96}
97
98BX.fx.prototype.go = function()
99{
100	var timeCurrent = new Date().valueOf();
101	if (timeCurrent < this.PARAMS.timeFinish)
102	{
103		for (var i in this.PARAMS.current)
104		{
105			this.PARAMS.current[i][0] = this.options.type.apply(this, [{
106				start_value: this.PARAMS.start[i][0],
107				finish_value: this.PARAMS.finish[i][0],
108				current_value: this.PARAMS.current[i][0],
109				current_time: timeCurrent - this.PARAMS.timeStart,
110				total_time: this.options.time
111			}]);
112		}
113
114		this._callback(this.options.callback);
115
116		if (!this.paused)
117			this.PARAMS.timer = setTimeout(this.__go, this.options.step);
118	}
119	else
120	{
121		this.stop();
122	}
123}
124
125BX.fx.prototype._callback = function(cb)
126{
127	var tmp = {};
128
129	cb = cb || this.options.callback;
130
131	for (var i in this.PARAMS.current)
132	{
133		tmp[i] = (this.options.allowFloat ? this.PARAMS.current[i][0] : Math.round(this.PARAMS.current[i][0])) + this.PARAMS.current[i][1];
134	}
135
136	return cb.apply(this, [null != tmp['_param'] ? tmp._param : tmp]);
137}
138
139BX.fx.prototype.start = function()
140{
141	var i,value, unit;
142
143	this.PARAMS.start = {};
144	this.PARAMS.current = {};
145	this.PARAMS.finish = {};
146
147	for (i in this.options.start)
148	{
149		value = +this.options.start[i];
150		unit = (this.options.start[i]+'').substring((value+'').length);
151		this.PARAMS.start[i] = [value, unit];
152		this.PARAMS.current[i] = [value, unit];
153		this.PARAMS.finish[i] = [+this.options.finish[i], unit];
154	}
155
156	this._callback(this.options.callback_start);
157	this._callback(this.options.callback);
158
159	this.PARAMS.timeStart = new Date().valueOf();
160	this.PARAMS.timeFinish = this.PARAMS.timeStart + this.options.time;
161	this.PARAMS.timer = setTimeout(BX.delegate(this.go, this), this.options.step);
162
163	return this;
164}
165
166BX.fx.prototype.pause = function()
167{
168	if (this.paused)
169	{
170		this.PARAMS.timer = setTimeout(this.__go, this.options.step);
171		this.paused = false;
172	}
173	else
174	{
175		clearTimeout(this.PARAMS.timer);
176		this.paused = true;
177	}
178}
179
180BX.fx.prototype.stop = function(silent)
181{
182	silent = !!silent;
183	if (this.PARAMS.timer)
184		clearTimeout(this.PARAMS.timer);
185
186	if (null != this.options.originalTime)
187		this.options.time = this.options.originalTime;
188	if (null != this.options.originalStep)
189		this.options.step = this.options.originalStep;
190
191	this.PARAMS.current = this.PARAMS.finish;
192	if (!silent) {
193		this._callback(this.options.callback);
194		this._callback(this.options.callback_complete);
195	}
196}
197
198/*
199type rules of animation
200 - linear - simple linear animation
201 - accelerated
202 - decelerated
203*/
204
205/*
206	params: {
207		start_value, finish_value, current_time, total_time
208	}
209*/
210BX.fx.RULES =
211{
212	linear: function(params)
213	{
214		return params.start_value + (params.current_time/params.total_time) * (params.finish_value - params.start_value);
215	},
216
217	decelerated: function(params)
218	{
219		return params.start_value + Math.sqrt(params.current_time/params.total_time) * (params.finish_value - params.start_value);
220	},
221
222	accelerated: function(params)
223	{
224		var q = params.current_time/params.total_time;
225		return params.start_value + q * q * (params.finish_value - params.start_value);
226	}
227}
228
229/****************** effects realizaion ************************/
230
231/*
232	type = 'fade' || 'scroll' || 'scale' || 'fold'
233*/
234
235BX.fx.hide = function(el, type, opts)
236{
237	el = BX(el);
238
239	if (typeof type == 'object' && null == opts)
240	{
241		opts = type;
242		type = opts.type
243	}
244
245	if (!opts) opts = {};
246
247	if (!BX.type.isNotEmptyString(type))
248	{
249		el.style.display = 'none';
250		return;
251	}
252
253	var fxOptions = BX.fx.EFFECTS[type](el, opts, 0);
254	fxOptions.callback_complete = function () {
255		if (opts.hide !== false)
256			el.style.display = 'none';
257
258		if (opts.callback_complete)
259			opts.callback_complete.apply(this, arguments);
260	}
261
262	return (new BX.fx(fxOptions)).start();
263}
264
265BX.fx.show = function(el, type, opts)
266{
267	el = BX(el);
268
269	if (typeof type == 'object' && null == opts)
270	{
271		opts = type;
272		type = opts.type
273	}
274
275	if (!opts) opts = {};
276
277	if (!BX.type.isNotEmptyString(type))
278	{
279		el.style.display = 'block';
280		return;
281	}
282
283	var fxOptions = BX.fx.EFFECTS[type](el, opts, 1);
284
285	fxOptions.callback_complete = function () {
286		if (opts.show !== false)
287			el.style.display = 'block';
288
289		if (opts.callback_complete)
290			opts.callback_complete.apply(this, arguments);
291	}
292
293	return (new BX.fx(fxOptions)).start();
294}
295
296BX.fx.EFFECTS = {
297	scroll: function(el, opts, action)
298	{
299		if (!opts.direction) opts.direction = 'vertical';
300
301		var param = opts.direction == 'horizontal' ? 'width' : 'height';
302
303		var val = parseInt(BX.style(el, param));
304		if (isNaN(val))
305		{
306			val = BX.pos(el)[param];
307		}
308
309		if (action == 0)
310			var start = val, finish = opts.min_height ? parseInt(opts.min_height) : 0;
311		else
312			var finish = val, start = opts.min_height ? parseInt(opts.min_height) : 0;
313
314		return {
315			'start': start,
316			'finish': finish,
317			'time': opts.time || defaultOptions.time,
318			'type': 'linear',
319			callback_start: function () {
320				if (BX.style(el, 'position') == 'static')
321					el.style.position = 'relative';
322
323				el.style.overflow = 'hidden';
324				el.style[param] = start + 'px';
325				el.style.display = 'block';
326			},
327			callback: function (val) {el.style[param] = val + 'px';}
328		}
329	},
330
331	fade: function(el, opts, action)
332	{
333		var fadeOpts = {
334			'time': opts.time || defaultOptions.time,
335			'type': action == 0 ? 'decelerated' : 'linear',
336			'start': action == 0 ? 1 : 0,
337			'finish': action == 0 ? 0 : 1,
338			'allowFloat': true
339		};
340
341		if (BX.browser.IsIE() && !BX.browser.IsIE9())
342		{
343			fadeOpts.start *= 100; fadeOpts.finish *= 100; fadeOpts.allowFloat = false;
344
345			fadeOpts.callback_start = function() {
346				el.style.display = 'block';
347				el.style.filter += "progid:DXImageTransform.Microsoft.Alpha(opacity=" + fadeOpts.start + ")";
348			};
349
350			fadeOpts.callback = function (val) {
351				(el.filters['DXImageTransform.Microsoft.alpha']||el.filters.alpha).opacity = val;
352			}
353		}
354		else
355		{
356			fadeOpts.callback_start = function () {
357				el.style.display = 'block';
358			}
359
360			fadeOpts.callback = function (val) {
361				el.style.opacity = el.style.KhtmlOpacity = el.style.MozOpacity = val;
362			};
363		}
364
365		return fadeOpts;
366	},
367
368	fold: function (el, opts, action) // 'fold' is a combination of two consequential 'scroll' hidings.
369	{
370		if (action != 0) return;
371
372		var pos = BX.pos(el);
373		var coef = pos.height / (pos.width + pos.height);
374		var old_opts = {time: opts.time || defaultOptions.time, callback_complete: opts.callback_complete, hide: opts.hide};
375
376		opts.type = 'scroll';
377		opts.direction = 'vertical';
378		opts.min_height = opts.min_height || 10;
379		opts.hide = false;
380		opts.time = coef * old_opts.time;
381		opts.callback_complete = function()
382		{
383			el.style.whiteSpace = 'nowrap';
384
385			opts.direction = 'horizontal';
386			opts.min_height = null;
387
388			opts.time = old_opts.time - opts.time;
389			opts.hide = old_opts.hide;
390			opts.callback_complete = old_opts.callback_complete;
391
392			BX.fx.hide(el, opts);
393		}
394
395		return BX.fx.EFFECTS.scroll(el, opts, action);
396	},
397
398	scale: function (el, opts, action)
399	{
400		var val = {width: parseInt(BX.style(el, 'width')), height: parseInt(BX.style(el, 'height'))};
401		if (isNaN(val.width) || isNaN(val.height))
402		{
403			var pos = BX.pos(el)
404			val = {width: pos.width, height: pos.height};
405		}
406
407		if (action == 0)
408			var start = val, finish = {width: 0, height: 0};
409		else
410			var finish = val, start = {width: 0, height: 0};
411
412		return {
413			'start': start,
414			'finish': finish,
415			'time': opts.time || defaultOptions.time,
416			'type': 'linear',
417			callback_start: function () {
418				el.style.position = 'relative';
419				el.style.overflow = 'hidden';
420				el.style.display = 'block';
421				el.style.height = start.height + 'px';
422				el.style.width = start.width + 'px';
423			},
424			callback: function (val) {
425				el.style.height = val.height + 'px';
426				el.style.width = val.width + 'px';
427			}
428		}
429	}
430}
431
432// Color animation
433//
434// Set animation rule
435// BX.fx.colorAnimate.addRule('animationRule1',"#FFF","#faeeb4", "background-color", 100, 1, true);
436// BX.fx.colorAnimate.addRule('animationRule2',"#fc8282","#ff0000", "color", 100, 1, true);
437// Params: 1 - animation name, 2 - start color, 3 - end color, 4 - count step, 5 - delay each step, 6 - return color on end animation
438//
439// Animate color for element
440// BX.fx.colorAnimate(BX('element'), 'animationRule1,animationRule2');
441
442var defaultOptionsColorAnimation = {
443	arStack: {},
444	arRules: {},
445	globalAnimationId: 0
446}
447
448BX.fx.colorAnimate = function(element, rule, back)
449{
450	if (element == null)
451		return;
452
453	animationId = element.getAttribute('data-animation-id');
454	if (animationId == null)
455	{
456		animationId = defaultOptionsColorAnimation.globalAnimationId;
457		element.setAttribute('data-animation-id', defaultOptionsColorAnimation.globalAnimationId++);
458	}
459	var aRuleList = rule.split(/\s*,\s*/);
460
461	for (var j	= 0; j < aRuleList.length; j++)
462	{
463		rule = aRuleList[j];
464
465		if (!defaultOptionsColorAnimation.arRules[rule]) continue;
466
467		var i=0;
468
469		if (!defaultOptionsColorAnimation.arStack[animationId])
470		{
471			defaultOptionsColorAnimation.arStack[animationId] = {};
472		}
473		else if (defaultOptionsColorAnimation.arStack[animationId][rule])
474		{
475			i = defaultOptionsColorAnimation.arStack[animationId][rule].i;
476			clearInterval(defaultOptionsColorAnimation.arStack[animationId][rule].tId);
477		}
478
479		if ((i==0 && back) || (i==defaultOptionsColorAnimation.arRules[rule][3] && !back)) continue;
480
481		defaultOptionsColorAnimation.arStack[animationId][rule] = {'i':i, 'element': element, 'tId':setInterval('BX.fx.colorAnimate.run("'+animationId+'","'+rule+'")', defaultOptionsColorAnimation.arRules[rule][4]),'back':Boolean(back)};
482	}
483}
484
485BX.fx.colorAnimate.addRule = function (rule, startColor, finishColor, cssProp, step, delay, back)
486{
487	defaultOptionsColorAnimation.arRules[rule] = [
488		BX.util.hex2rgb(startColor),
489		BX.util.hex2rgb(finishColor),
490		cssProp.replace(/\-(.)/g,function(){return arguments[1].toUpperCase();}),
491		step,
492		delay || 1,
493		back || false
494	];
495};
496
497BX.fx.colorAnimate.run = function(animationId, rule)
498{
499	element = defaultOptionsColorAnimation.arStack[animationId][rule].element;
500
501    defaultOptionsColorAnimation.arStack[animationId][rule].i += defaultOptionsColorAnimation.arStack[animationId][rule].back?-1:1;
502 	var finishPercent = defaultOptionsColorAnimation.arStack[animationId][rule].i/defaultOptionsColorAnimation.arRules[rule][3];
503	var startPercent = 1 - finishPercent;
504
505	var aRGBStart = defaultOptionsColorAnimation.arRules[rule][0];
506	var aRGBFinish = defaultOptionsColorAnimation.arRules[rule][1];
507
508	element.style[defaultOptionsColorAnimation.arRules[rule][2]] = 'rgb('+
509	Math.floor( aRGBStart['r'] * startPercent + aRGBFinish['r'] * finishPercent ) + ','+
510	Math.floor( aRGBStart['g'] * startPercent + aRGBFinish['g'] * finishPercent ) + ','+
511	Math.floor( aRGBStart['b'] * startPercent + aRGBFinish['b'] * finishPercent ) +')';
512
513	if ( defaultOptionsColorAnimation.arStack[animationId][rule].i == defaultOptionsColorAnimation.arRules[rule][3] || defaultOptionsColorAnimation.arStack[animationId][rule].i ==0)
514	{
515		clearInterval(defaultOptionsColorAnimation.arStack[animationId][rule].tId);
516		if (defaultOptionsColorAnimation.arRules[rule][5])
517			BX.fx.colorAnimate(defaultOptionsColorAnimation.arStack[animationId][rule].element, rule, true);
518	}
519}
520
521
522/*
523options = {
524	delay: 100,
525	duration : 3000,
526	start : { scroll : document.body.scrollTop, left : 0, opacity :  100 },
527	finish : { scroll : document.body.scrollHeight, left : 500, opacity : 10 },
528	transition : BitrixAnimation.makeEaseOut(BitrixAnimation.transitions.quart),
529
530	step : function(state)
531	{
532		document.body.scrollTop = state.scroll;
533		button.style.left =  state.left + "px";
534		button.style.opacity =  state.opacity / 100;
535	},
536	complete : function()
537	{
538		button.style.background = "green";
539	}
540}
541
542options =
543{
544	delay : 20,
545	duration : 4000,
546	transition : BXAnimation.makeEaseOut(BXAnimation.transitions.quart),
547	progress : function(progress)
548	{
549		document.body.scrollTop = Math.round(topMax * progress);
550		button.style.left =  Math.round(leftMax * progress) + "px";
551		button.style.opacity =  (100 + Math.round((opacityMin - 100) * progress)) / 100;
552
553	},
554	complete : function()
555	{
556		button.style.background = "green";
557	}
558}
559*/
560
561BX.easing = function(options)
562{
563	this.options = options;
564	this.timer = null;
565};
566
567BX.easing.prototype.animate = function()
568{
569	if (!this.options || !this.options.start || !this.options.finish ||
570		typeof(this.options.start) != "object" || typeof(this.options.finish) != "object"
571		)
572		return null;
573
574	for (var propName in this.options.start)
575	{
576		if (typeof(this.options.finish[propName]) == "undefined")
577		{
578			delete this.options.start[propName];
579		}
580	}
581
582	this.options.progress = function(progress) {
583		var state = {};
584		for (var propName in this.start)
585			state[propName] = Math.round(this.start[propName] + (this.finish[propName] - this.start[propName]) * progress);
586
587		if (this.step)
588		{
589			this.step(state);
590		}
591	};
592
593	this.animateProgress();
594};
595
596BX.easing.prototype.stop = function(completed)
597{
598	if (this.timer)
599	{
600		cancelAnimationFrame(this.timer);
601		this.timer = null;
602		if (completed)
603		{
604			this.options.complete && this.options.complete();
605		}
606	}
607};
608
609BX.easing.prototype.animateProgress = function()
610{
611	if (!window.requestAnimationFrame)
612	{
613		//For old browsers we skip animation
614		this.options.progress(1);
615		this.options.complete && this.options.complete();
616		return;
617	}
618
619	var start = null;
620	var delta = this.options.transition || BX.easing.transitions.linear;
621	var duration = this.options.duration || 1000;
622	var animation = BX.proxy(function(time) {
623
624		if (start === null)
625		{
626			start = time;
627		}
628
629		var progress = (time - start) / duration;
630		if (progress > 1)
631		{
632			progress = 1;
633		}
634
635		this.options.progress(delta(progress));
636
637		if (progress == 1)
638		{
639			this.stop(true);
640		}
641		else
642		{
643			this.timer = requestAnimationFrame(animation);
644		}
645
646	}, this);
647
648	this.timer = requestAnimationFrame(animation);
649};
650
651BX.easing.makeEaseInOut = function(delta)
652{
653	return function(progress) {
654		if (progress < 0.5)
655			return delta( 2 * progress ) / 2;
656		else
657			return (2 - delta( 2 * (1-progress) ) ) / 2;
658	}
659};
660
661BX.easing.makeEaseOut = function(delta)
662{
663	return function(progress) {
664		return 1 - delta(1 - progress);
665	};
666};
667
668BX.easing.transitions = {
669
670	linear : function(progress)
671	{
672		return progress;
673	},
674
675	quad : function(progress)
676	{
677		return Math.pow(progress, 2);
678	},
679
680	cubic : function(progress) {
681		return Math.pow(progress, 3);
682	},
683
684	quart : function(progress)
685	{
686		return Math.pow(progress, 4);
687	},
688
689	quint : function(progress)
690	{
691		return Math.pow(progress, 5);
692	},
693
694	circ : function(progress)
695	{
696		return 1 - Math.sin(Math.acos(progress));
697	},
698
699	back : function(progress)
700	{
701		return Math.pow(progress, 2) * ((1.5 + 1) * progress - 1.5);
702	},
703
704	elastic: function(progress)
705	{
706		return Math.pow(2, 10 * (progress-1)) * Math.cos(20 * Math.PI * 1.5/3 * progress);
707	},
708
709	bounce : function(progress)
710	{
711		for(var a = 0, b = 1; 1; a += b, b /= 2) {
712			if (progress >= (7 - 4 * a) / 11) {
713				return -Math.pow((11 - 6 * a - 11 * progress) / 4, 2) + Math.pow(b, 2);
714			}
715		}
716	}};
717
718
719})(window);
720
721
722/* End */
723;
724; /* Start:"a:4:{s:4:"full";s:54:"/bitrix/js/main/pageobject/pageobject.js?1589097375864";s:6:"source";s:40:"/bitrix/js/main/pageobject/pageobject.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
725window.BX = BX || {};
726
727BX.PageObject = {
728	getRootWindow: function()
729	{
730		return BX.PageObject.getTopWindowOfCurrentHost(window);
731	},
732
733	isCrossOriginObject: function(currentWindow)
734	{
735		try
736		{
737			void currentWindow.location.host;
738		}
739		catch (e)
740		{
741			// cross-origin object
742			return true;
743		}
744
745		return false;
746	},
747
748	getTopWindowOfCurrentHost: function(currentWindow)
749	{
750		if (
751			!BX.PageObject.isCrossOriginObject(currentWindow.parent)
752			&& currentWindow.parent !== currentWindow
753			&& currentWindow.parent.location.host === currentWindow.location.host
754		)
755		{
756			return BX.PageObject.getTopWindowOfCurrentHost(currentWindow.parent);
757		}
758
759		return currentWindow;
760	},
761
762	getParentWindowOfCurrentHost: function(currentWindow)
763	{
764		if (BX.PageObject.isCrossOriginObject(currentWindow.parent))
765		{
766			return currentWindow;
767		}
768
769		return currentWindow.parent;
770	}
771};
772/* End */
773;
774; /* Start:"a:4:{s:4:"full";s:51:"/bitrix/js/main/core/core_window.js?172258261598766";s:6:"source";s:35:"/bitrix/js/main/core/core_window.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
775;(function(window) {
776if (BX.WindowManager) return;
777
778/* windows manager */
779BX.WindowManager = {
780	_stack: [],
781	_runtime_resize: {},
782	_delta: 2,
783	_delta_start: 1000,
784	currently_loaded: null,
785
786	settings_category: 'BX.WindowManager.9.5',
787
788	register: function (w)
789	{
790		this.currently_loaded = null;
791
792		w.WM_REG_INDEX = this._stack.length;
793		this._stack.push(w);
794
795		if (this._stack.length < 2)
796		{
797			BX.bind(document, 'keyup', BX.proxy(this.__checkKeyPress, this));
798		}
799	},
800
801	unregister: function (w)
802	{
803		if (null == w.WM_REG_INDEX)
804			return null;
805
806		var _current;
807		if (this._stack.length > 0)
808		{
809			while ((_current = this.__pop_stack()) != w)
810			{
811				if (!_current)
812				{
813					_current = null;
814					break;
815				}
816			}
817
818			if (this._stack.length <= 0)
819			{
820				this.enableKeyCheck();
821			}
822
823			return _current;
824		}
825		else
826		{
827			return null;
828		}
829	},
830
831	__pop_stack: function(clean)
832	{
833		if (this._stack.length > 0)
834		{
835			var _current = this._stack.pop();
836			_current.WM_REG_INDEX = null;
837			BX.onCustomEvent(_current, 'onWindowUnRegister', [clean === true]);
838
839			return _current;
840		}
841		else
842			return null;
843	},
844
845	clean: function()
846	{
847		while (this.__pop_stack(true)){}
848		this._stack = [];
849		this.disableKeyCheck();
850	},
851
852	Get: function()
853	{
854		if (this.currently_loaded)
855			return this.currently_loaded;
856		else if (this._stack.length > 0)
857			return this._stack[this._stack.length-1];
858		else
859			return null;
860	},
861
862	setStartZIndex: function(value)
863	{
864		this._delta_start = value;
865	},
866
867	restoreStartZIndex: function()
868	{
869		this._delta_start = 1000;
870	},
871
872	GetZIndex: function()
873	{
874		var _current;
875		return (null != (_current = this._stack[this._stack.length-1])
876			? parseInt(_current.Get().style.zIndex) + this._delta
877			: this._delta_start
878		);
879	},
880
881	__get_check_url: function(url)
882	{
883		var pos = url.indexOf('?');
884		return pos == -1 ? url : url.substring(0, pos);
885	},
886
887	saveWindowSize: function(url, params)
888	{
889		var check_url = this.__get_check_url(url);
890		if (BX.userOptions)
891		{
892			BX.userOptions.save(this.settings_category, 'size_' + check_url, 'width', params.width);
893			BX.userOptions.save(this.settings_category, 'size_' + check_url, 'height', params.height);
894		}
895
896		this._runtime_resize[check_url] = params;
897	},
898
899	saveWindowOptions: function(wnd_id, opts)
900	{
901		if (BX.userOptions)
902		{
903			for (var i in opts)
904			{
905				if(opts.hasOwnProperty(i))
906				{
907					BX.userOptions.save(this.settings_category, 'options_' + wnd_id, i, opts[i]);
908				}
909			}
910		}
911	},
912
913	getRuntimeWindowSize: function(url)
914	{
915		return this._runtime_resize[this.__get_check_url(url)];
916	},
917
918	disableKeyCheck: function()
919	{
920		BX.unbind(document, 'keyup', BX.proxy(this.__checkKeyPress, this));
921	},
922
923	enableKeyCheck: function()
924	{
925		BX.bind(document, 'keyup', BX.proxy(this.__checkKeyPress, this));
926	},
927
928	__checkKeyPress: function(e)
929	{
930		if (null == e)
931			e = window.event;
932
933		if (e.keyCode == 27)
934		{
935			var wnd = BX.WindowManager.Get();
936			if (wnd && !wnd.unclosable) wnd.Close();
937		}
938	}
939};
940
941BX.garbage(BX.WindowManager.clean, BX.WindowManager);
942
943/* base button class */
944BX.CWindowButton = function(params)
945{
946	if (params.btn)
947	{
948		this.btn = params.btn;
949		this.parentWindow = params.parentWindow;
950
951		if (/save|apply/i.test(this.btn.name))
952		{
953			BX.bind(this.btn, 'click', BX.delegate(this.disableUntilError, this));
954		}
955	}
956	else
957	{
958		this.title = params.title; // html value attr
959		this.hint = params.hint; // html title attr
960		this.id = params.id; // html name and id attrs
961		this.name = params.name; // html name or value attrs when id and title 're absent
962		this.className = params.className; // className for button input
963
964		this.action = params.action;
965		this.onclick = params.onclick;
966
967		// you can override button creation method
968		if (params.Button && BX.type.isFunction(params.Button))
969			this.Button = params.Button;
970
971		this.btn = null;
972	}
973};
974
975BX.CWindowButton.prototype.disable = function()
976{
977	if (this.btn)
978		this.parentWindow.showWait(this.btn);
979};
980BX.CWindowButton.prototype.enable = function(){
981	if (this.btn)
982		this.parentWindow.closeWait(this.btn);
983};
984
985BX.CWindowButton.prototype.emulate = function()
986{
987	if (this.btn && this.btn.disabled)
988		return;
989
990	var act =
991		this.action
992		? BX.delegate(this.action, this)
993		: (
994			this.onclick
995			? this.onclick
996			: (
997				this.btn
998				? this.btn.getAttribute('onclick')
999				: ''
1000			)
1001		);
1002
1003	if (act)
1004	{
1005		setTimeout(act, 50);
1006		if (this.btn && /save|apply/i.test(this.btn.name) && !this.action)
1007		{
1008			this.disableUntilError();
1009		}
1010	}
1011};
1012
1013BX.CWindowButton.prototype.Button = function(parentWindow)
1014{
1015	this.parentWindow = parentWindow;
1016
1017	var btn = {
1018		props: {
1019			'type': 'button',
1020			'name': this.id ? this.id : this.name,
1021			'value': this.title ? this.title : this.name,
1022			'id': this.id
1023		}
1024	};
1025
1026	if (this.hint)
1027		btn.props.title = this.hint;
1028	if (!!this.className)
1029		btn.props.className = this.className;
1030
1031	if (this.action)
1032	{
1033		btn.events = {
1034			'click': BX.delegate(this.action, this)
1035		};
1036	}
1037	else if (this.onclick)
1038	{
1039		if (BX.browser.IsIE())
1040		{
1041			btn.events = {
1042				'click': BX.delegate(function() {eval(this.onclick)}, this)
1043			};
1044		}
1045		else
1046		{
1047			btn.attrs = {
1048				'onclick': this.onclick
1049			};
1050		}
1051	}
1052
1053	this.btn = BX.create('INPUT', btn);
1054
1055	return this.btn;
1056};
1057
1058BX.CWindowButton.prototype.disableUntilError = function() {
1059	this.disable();
1060	if (!this.__window_error_handler_set)
1061	{
1062		BX.addCustomEvent(this.parentWindow, 'onWindowError', BX.delegate(this.enable, this));
1063		this.__window_error_handler_set = true;
1064	}
1065};
1066
1067/* base window class */
1068BX.CWindow = function(div, type)
1069{
1070	this.DIV = div || document.createElement('DIV');
1071
1072	this.SETTINGS = {
1073		resizable: false,
1074		min_height: 0,
1075		min_width: 0,
1076		top: 0,
1077		left: 0,
1078		draggable: false,
1079		drag_restrict: true,
1080		resize_restrict: true
1081	};
1082
1083	this.ELEMENTS = {
1084		draggable: [],
1085		resizer: [],
1086		close: []
1087	};
1088
1089	this.type = type == 'float' ? 'float' : 'dialog';
1090
1091	BX.adjust(this.DIV, {
1092		props: {
1093			className: 'bx-core-window'
1094		},
1095		style: {
1096			'zIndex': 0,
1097			'position': 'absolute',
1098			'display': 'none',
1099			'top': this.SETTINGS.top + 'px',
1100			'left': this.SETTINGS.left + 'px',
1101			'height': '100px',
1102			'width': '100px'
1103		}
1104	});
1105
1106	this.isOpen = false;
1107
1108	BX.addCustomEvent(this, 'onWindowRegister', BX.delegate(this.onRegister, this));
1109	BX.addCustomEvent(this, 'onWindowUnRegister', BX.delegate(this.onUnRegister, this));
1110
1111	this.MOUSEOVER = null;
1112	BX.bind(this.DIV, 'mouseover', BX.delegate(this.__set_msover, this));
1113	BX.bind(this.DIV, 'mouseout', BX.delegate(this.__unset_msover, this));
1114
1115	BX.ready(BX.delegate(function() {
1116		document.body.appendChild(this.DIV);
1117		BX.ZIndexManager.register(this.DIV);
1118	}, this));
1119};
1120
1121BX.CWindow.prototype.Get = function () {return this.DIV};
1122BX.CWindow.prototype.visible = function() {return this.isOpen;};
1123
1124BX.CWindow.prototype.Show = function(bNotRegister)
1125{
1126	this.DIV.style.display = 'block';
1127
1128	if (!bNotRegister)
1129	{
1130		BX.WindowManager.register(this);
1131		BX.onCustomEvent(this, 'onWindowRegister');
1132	}
1133
1134	BX.ZIndexManager.bringToFront(this.DIV);
1135};
1136
1137BX.CWindow.prototype.Hide = function()
1138{
1139	BX.WindowManager.unregister(this);
1140	this.DIV.style.display = 'none';
1141};
1142
1143BX.CWindow.prototype.onRegister = function()
1144{
1145	this.isOpen = true;
1146};
1147
1148BX.CWindow.prototype.onUnRegister = function(clean)
1149{
1150	this.isOpen = false;
1151
1152	if (clean || (this.PARAMS && this.PARAMS.content_url))
1153	{
1154		if (clean) {BX.onCustomEvent(this, 'onWindowClose', [this, true]);}
1155
1156		if (this.DIV.parentNode)
1157			this.DIV.parentNode.removeChild(this.DIV);
1158	}
1159	else
1160	{
1161		this.DIV.style.display = 'none';
1162	}
1163};
1164
1165BX.CWindow.prototype.CloseDialog = // compatibility
1166BX.CWindow.prototype.Close = function(bImmediately)
1167{
1168	BX.onCustomEvent(this, 'onBeforeWindowClose', [this]);
1169	if (bImmediately !== true)
1170	{
1171		if (this.denyClose)
1172			return false;
1173	}
1174
1175	BX.onCustomEvent(this, 'onWindowClose', [this]);
1176
1177	//this crashes vis editor in ie via onWindowResizeExt event handler
1178	//if (this.bExpanded) this.__expand();
1179	// alternative version:
1180	if (this.bExpanded)
1181	{
1182		var pDocElement = BX.GetDocElement();
1183		BX.unbind(window, 'resize', BX.proxy(this.__expand_onresize, this));
1184		pDocElement.style.overflow = this.__expand_settings.overflow;
1185	}
1186
1187	BX.WindowManager.unregister(this);
1188
1189	return true;
1190};
1191
1192BX.CWindow.prototype.SetResize = function(elem)
1193{
1194	elem.style.cursor = 'se-resize';
1195	BX.bind(elem, 'mousedown', BX.proxy(this.__startResize, this));
1196
1197	this.ELEMENTS.resizer.push(elem);
1198	this.SETTINGS.resizable = true;
1199};
1200
1201BX.CWindow.prototype.SetExpand = function(elem, event_name)
1202{
1203	event_name = event_name || 'click';
1204	BX.bind(elem, event_name, BX.proxy(this.__expand, this));
1205};
1206
1207BX.CWindow.prototype.__expand_onresize = function()
1208{
1209	var windowSize = BX.GetWindowInnerSize();
1210	this.DIV.style.width = windowSize.innerWidth + "px";
1211	this.DIV.style.height = windowSize.innerHeight + "px";
1212
1213	BX.onCustomEvent(this, 'onWindowResize');
1214};
1215
1216BX.CWindow.prototype.__expand = function()
1217{
1218	var pDocElement = BX.GetDocElement();
1219
1220	if (!this.bExpanded)
1221	{
1222		var wndScroll = BX.GetWindowScrollPos(),
1223			wndSize = BX.GetWindowInnerSize();
1224
1225		this.__expand_settings = {
1226			resizable: this.SETTINGS.resizable,
1227			draggable: this.SETTINGS.draggable,
1228			width: this.DIV.style.width,
1229			height: this.DIV.style.height,
1230			left: this.DIV.style.left,
1231			top: this.DIV.style.top,
1232			scrollTop: wndScroll.scrollTop,
1233			scrollLeft: wndScroll.scrollLeft,
1234			overflow: BX.style(pDocElement, 'overflow')
1235		};
1236
1237		this.SETTINGS.resizable = false;
1238		this.SETTINGS.draggable = false;
1239
1240		window.scrollTo(0,0);
1241		pDocElement.style.overflow = 'hidden';
1242
1243		this.DIV.style.top = '0px';
1244		this.DIV.style.left = '0px';
1245
1246		this.DIV.style.width = wndSize.innerWidth + 'px';
1247		this.DIV.style.height = wndSize.innerHeight + 'px';
1248
1249		this.bExpanded = true;
1250
1251		BX.onCustomEvent(this, 'onWindowExpand');
1252		BX.onCustomEvent(this, 'onWindowResize');
1253
1254		BX.bind(window, 'resize', BX.proxy(this.__expand_onresize, this));
1255	}
1256	else
1257	{
1258		BX.unbind(window, 'resize', BX.proxy(this.__expand_onresize, this));
1259
1260		this.SETTINGS.resizable = this.__expand_settings.resizable;
1261		this.SETTINGS.draggable = this.__expand_settings.draggable;
1262
1263		pDocElement.style.overflow = this.__expand_settings.overflow;
1264
1265		this.DIV.style.top = this.__expand_settings.top;
1266		this.DIV.style.left = this.__expand_settings.left;
1267		this.DIV.style.width = this.__expand_settings.width;
1268		this.DIV.style.height = this.__expand_settings.height;
1269
1270		window.scrollTo(this.__expand_settings.scrollLeft, this.__expand_settings.scrollTop);
1271
1272		this.bExpanded = false;
1273
1274		BX.onCustomEvent(this, 'onWindowNarrow');
1275		BX.onCustomEvent(this, 'onWindowResize');
1276
1277	}
1278};
1279
1280BX.CWindow.prototype.Resize = function(x, y)
1281{
1282	var new_width = Math.max(x - this.pos.left + this.dx, this.SETTINGS.min_width);
1283	var new_height = Math.max(y - this.pos.top + this.dy, this.SETTINGS.min_height);
1284
1285	if (this.SETTINGS.resize_restrict)
1286	{
1287		var scrollSize = BX.GetWindowScrollSize();
1288
1289		if (this.pos.left + new_width > scrollSize.scrollWidth - this.dw)
1290			new_width = scrollSize.scrollWidth - this.pos.left - this.dw;
1291	}
1292
1293	this.DIV.style.width = new_width + 'px';
1294	this.DIV.style.height = new_height + 'px';
1295
1296	BX.onCustomEvent(this, 'onWindowResize');
1297};
1298
1299BX.CWindow.prototype.__startResize = function(e)
1300{
1301	if (!this.SETTINGS.resizable)
1302		return false;
1303
1304	if(!e) e = window.event;
1305
1306	this.wndSize = BX.GetWindowScrollPos();
1307	this.wndSize.innerWidth = BX.GetWindowInnerSize().innerWidth;
1308
1309	this.pos = BX.pos(this.DIV);
1310
1311	this.x = e.clientX + this.wndSize.scrollLeft;
1312	this.y = e.clientY + this.wndSize.scrollTop;
1313
1314	this.dx = this.pos.left + this.pos.width - this.x;
1315	this.dy = this.pos.top + this.pos.height - this.y;
1316	this.dw = this.pos.width - parseInt(this.DIV.style.width);
1317
1318	BX.bind(document, "mousemove", BX.proxy(this.__moveResize, this));
1319	BX.bind(document, "mouseup", BX.proxy(this.__stopResize, this));
1320
1321	if(document.body.setCapture)
1322		document.body.setCapture();
1323
1324	document.onmousedown = BX.False;
1325
1326	var b = document.body;
1327	b.ondrag = b.onselectstart = BX.False;
1328	b.style.MozUserSelect = this.DIV.style.MozUserSelect = 'none';
1329	b.style.cursor = 'se-resize';
1330
1331	BX.onCustomEvent(this, 'onWindowResizeStart');
1332
1333	return true;
1334};
1335
1336BX.CWindow.prototype.__moveResize = function(e)
1337{
1338	if(!e) e = window.event;
1339
1340	var windowScroll = BX.GetWindowScrollPos();
1341
1342	var x = e.clientX + windowScroll.scrollLeft;
1343	var y = e.clientY + windowScroll.scrollTop;
1344
1345	if(this.x == x && this.y == y)
1346		return;
1347
1348	this.Resize(x, y);
1349
1350	this.x = x;
1351	this.y = y;
1352};
1353
1354BX.CWindow.prototype.__stopResize = function()
1355{
1356	if(document.body.releaseCapture)
1357		document.body.releaseCapture();
1358
1359	BX.unbind(document, "mousemove", BX.proxy(this.__moveResize, this));
1360	BX.unbind(document, "mouseup", BX.proxy(this.__stopResize, this));
1361
1362	document.onmousedown = null;
1363
1364	var b = document.body;
1365	b.ondrag = b.onselectstart = null;
1366	b.style.MozUserSelect = this.DIV.style.MozUserSelect = '';
1367	b.style.cursor = '';
1368
1369	BX.onCustomEvent(this, 'onWindowResizeFinished')
1370};
1371
1372BX.CWindow.prototype.SetClose = function(elem)
1373{
1374	BX.bind(elem, 'click', BX.proxy(this.Close, this));
1375	this.ELEMENTS.close.push(elem);
1376};
1377
1378BX.CWindow.prototype.SetDraggable = function(elem)
1379{
1380	BX.bind(elem, 'mousedown', BX.proxy(this.__startDrag, this));
1381
1382	elem.style.cursor = 'move';
1383
1384	this.ELEMENTS.draggable.push(elem);
1385	this.SETTINGS.draggable = true;
1386};
1387
1388BX.CWindow.prototype.Move = function(x, y)
1389{
1390	var dxShadow = 1; // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1391
1392	var left = parseInt(this.DIV.style.left)+x;
1393	var top = parseInt(this.DIV.style.top)+y;
1394
1395	if (this.SETTINGS.drag_restrict)
1396	{
1397		//Left side
1398		if (left < 0)
1399			left = 0;
1400
1401		//Right side
1402		var scrollSize = BX.GetWindowScrollSize();
1403		var floatWidth = this.DIV.offsetWidth;
1404		var floatHeight = this.DIV.offsetHeight;
1405
1406		if (left > (scrollSize.scrollWidth - floatWidth - dxShadow))
1407			left = scrollSize.scrollWidth - floatWidth - dxShadow;
1408
1409		var scrollHeight = Math.max(
1410			document.body.scrollHeight, document.documentElement.scrollHeight,
1411			document.body.offsetHeight, document.documentElement.offsetHeight,
1412			document.body.clientHeight, document.documentElement.clientHeight,
1413			scrollSize.scrollHeight
1414		);
1415
1416		if (top > (scrollHeight - floatHeight - dxShadow))
1417			top = scrollHeight - floatHeight - dxShadow;
1418
1419		//Top side
1420		if (top < 0)
1421			top = 0;
1422	}
1423
1424	this.DIV.style.left = left+'px';
1425	this.DIV.style.top = top+'px';
1426
1427	//this.AdjustShadow(div);
1428};
1429
1430BX.CWindow.prototype.__startDrag = function(e)
1431{
1432	if (!this.SETTINGS.draggable)
1433		return false;
1434
1435	if(!e) e = window.event;
1436
1437	this.x = e.clientX + document.body.scrollLeft;
1438	this.y = e.clientY + document.body.scrollTop;
1439
1440	this.__bWasDragged = false;
1441	BX.bind(document, "mousemove", BX.proxy(this.__moveDrag, this));
1442	BX.bind(document, "mouseup", BX.proxy(this.__stopDrag, this));
1443
1444	if(document.body.setCapture)
1445		document.body.setCapture();
1446
1447	document.onmousedown = BX.False;
1448
1449	var b = document.body;
1450	b.ondrag = b.onselectstart = BX.False;
1451	b.style.MozUserSelect = this.DIV.style.MozUserSelect = 'none';
1452	b.style.cursor = 'move';
1453	return BX.PreventDefault(e);
1454};
1455
1456BX.CWindow.prototype.__moveDrag = function(e)
1457{
1458	if(!e) e = window.event;
1459
1460	var x = e.clientX + document.body.scrollLeft;
1461	var y = e.clientY + document.body.scrollTop;
1462
1463	if(this.x == x && this.y == y)
1464		return;
1465
1466	this.Move((x - this.x), (y - this.y));
1467	this.x = x;
1468	this.y = y;
1469
1470	if (!this.__bWasDragged)
1471	{
1472		BX.onCustomEvent(this, 'onWindowDragStart');
1473		this.__bWasDragged = true;
1474		BX.bind(BX.proxy_context, "click", BX.PreventDefault);
1475	}
1476
1477	BX.onCustomEvent(this, 'onWindowDrag');
1478};
1479
1480BX.CWindow.prototype.__stopDrag = function(e)
1481{
1482	if(document.body.releaseCapture)
1483		document.body.releaseCapture();
1484
1485	BX.unbind(document, "mousemove", BX.proxy(this.__moveDrag, this));
1486	BX.unbind(document, "mouseup", BX.proxy(this.__stopDrag, this));
1487
1488	document.onmousedown = null;
1489
1490	var b = document.body;
1491	b.ondrag = b.onselectstart = null;
1492	b.style.MozUserSelect = this.DIV.style.MozUserSelect = '';
1493	b.style.cursor = '';
1494
1495	if (this.__bWasDragged)
1496	{
1497		BX.onCustomEvent(this, 'onWindowDragFinished');
1498		var _proxy_context = BX.proxy_context;
1499		setTimeout(function(){BX.unbind(_proxy_context, "click", BX.PreventDefault)}, 100);
1500		this.__bWasDragged = false;
1501	}
1502	return BX.PreventDefault(e);
1503};
1504
1505BX.CWindow.prototype.DenyClose = function()
1506{
1507	this.denyClose = true;
1508};
1509
1510BX.CWindow.prototype.AllowClose = function()
1511{
1512	this.denyClose = false;
1513};
1514
1515BX.CWindow.prototype.ShowError = function(str)
1516{
1517	BX.onCustomEvent(this, 'onWindowError', [str]);
1518
1519	if (this._wait)
1520		BX.closeWait(this._wait);
1521
1522	window.alert(str);
1523};
1524
1525BX.CWindow.prototype.__set_msover = function() {this.MOUSEOVER = true;};
1526BX.CWindow.prototype.__unset_msover = function() {this.MOUSEOVER = false;};
1527
1528/* dialog window class extends window class */
1529BX.CWindowDialog = function() {
1530	var a = arguments;
1531	a[1] = 'dialog';
1532	BX.CWindowDialog.superclass.constructor.apply(this, a);
1533
1534	this.DIV.style.top = '10px';
1535	this.OVERLAY = null;
1536};
1537BX.extend(BX.CWindowDialog, BX.CWindow);
1538
1539BX.CWindowDialog.prototype.__resizeOverlay = function()
1540{
1541	var windowSize = BX.GetWindowScrollSize();
1542	this.OVERLAY.style.width = windowSize.scrollWidth + "px";
1543};
1544
1545BX.CWindowDialog.prototype.CreateOverlay = function(zIndex)
1546{
1547	if (null == this.OVERLAY)
1548	{
1549		var windowSize = BX.GetWindowScrollSize();
1550
1551		// scrollHeight in BX.GetWindowScrollSize may be incorrect
1552		var scrollHeight = Math.max(
1553			document.body.scrollHeight, document.documentElement.scrollHeight,
1554			document.body.offsetHeight, document.documentElement.offsetHeight,
1555			document.body.clientHeight, document.documentElement.clientHeight,
1556			windowSize.scrollHeight
1557		);
1558
1559		this.OVERLAY = document.body.appendChild(BX.create("DIV", {
1560			style: {
1561				position: 'absolute',
1562				top: '0px',
1563				left: '0px',
1564				zIndex: zIndex || (parseInt(this.DIV.style.zIndex)-2),
1565				width: windowSize.scrollWidth + "px",
1566				height: scrollHeight + "px"
1567			}
1568		}));
1569
1570		var component = BX.ZIndexManager.getComponent(this.DIV);
1571		if (component)
1572		{
1573			component.setOverlay(this.OVERLAY);
1574		}
1575	}
1576
1577	return this.OVERLAY;
1578};
1579
1580BX.CWindowDialog.prototype.Show = function()
1581{
1582	BX.CWindowDialog.superclass.Show.apply(this, arguments);
1583
1584	this.CreateOverlay();
1585
1586	this.OVERLAY.style.display = 'block';
1587
1588	BX.unbind(window, 'resize', BX.proxy(this.__resizeOverlay, this));
1589	BX.bind(window, 'resize', BX.proxy(this.__resizeOverlay, this));
1590};
1591
1592BX.CWindowDialog.prototype.onUnRegister = function(clean)
1593{
1594	BX.CWindowDialog.superclass.onUnRegister.apply(this, arguments);
1595
1596	if (this.clean)
1597	{
1598		if (this.OVERLAY.parentNode)
1599			this.OVERLAY.parentNode.removeChild(this.OVERLAY);
1600	}
1601	else
1602	{
1603		this.OVERLAY.style.display = 'none';
1604	}
1605
1606	BX.unbind(window, 'resize', BX.proxy(this.__resizeOverlay, this));
1607};
1608
1609/* standard bitrix dialog extends BX.CWindowDialog */
1610/*
1611	arParams = {
1612		(
1613			title: 'dialog title',
1614			head: 'head block html',
1615			content: 'dialog content',
1616			icon: 'head icon classname or filename',
1617
1618			resize_id: 'some id to save resize information'// useless if resizable = false
1619		)
1620		or
1621		(
1622			content_url: url to content load
1623				loaded content scripts can use BX.WindowManager.Get() to get access to the current window object
1624		)
1625
1626		height: window_height_in_pixels,
1627		width: window_width_in_pixels,
1628
1629		draggable: true|false,
1630		resizable: true|false,
1631
1632		min_height: min_window_height_in_pixels, // useless if resizable = false
1633		min_width: min_window_width_in_pixels, // useless if resizable = false
1634
1635		buttons: [
1636			'html_code',
1637			BX.CDialog.btnSave, BX.CDialog.btnCancel, BX.CDialog.btnClose
1638		]
1639	}
1640*/
1641BX.CDialog = function(arParams)
1642{
1643	BX.CDialog.superclass.constructor.apply(this);
1644
1645	this._sender = 'core_window_cdialog';
1646
1647	this.PARAMS = arParams || {};
1648
1649	for (var i in this.defaultParams)
1650	{
1651		if (typeof this.PARAMS[i] == 'undefined')
1652			this.PARAMS[i] = this.defaultParams[i];
1653	}
1654
1655	this.PARAMS.width = (!isNaN(parseInt(this.PARAMS.width)))
1656		? this.PARAMS.width
1657		: this.defaultParams['width'];
1658	this.PARAMS.height = (!isNaN(parseInt(this.PARAMS.height)))
1659		? this.PARAMS.height
1660		: this.defaultParams['height'];
1661
1662	if (this.PARAMS.resize_id || this.PARAMS.content_url)
1663	{
1664		var arSize = BX.WindowManager.getRuntimeWindowSize(this.PARAMS.resize_id || this.PARAMS.content_url);
1665		if (arSize)
1666		{
1667			this.PARAMS.width = arSize.width;
1668			this.PARAMS.height = arSize.height;
1669		}
1670	}
1671
1672	BX.addClass(this.DIV, 'bx-core-adm-dialog');
1673	this.DIV.id = 'bx-admin-prefix';
1674
1675	this.PARTS = {};
1676
1677	this.DIV.style.height = null;
1678	this.DIV.style.width = null;
1679
1680	this.PARTS.TITLEBAR = this.DIV.appendChild(BX.create('DIV', {props: {
1681			className: 'bx-core-adm-dialog-head'
1682		}
1683	}));
1684
1685	this.PARTS.TITLE_CONTAINER = this.PARTS.TITLEBAR.appendChild(BX.create('SPAN', {
1686		props: {className: 'bx-core-adm-dialog-head-inner'},
1687		text: this.PARAMS.title
1688	}));
1689
1690	this.PARTS.TITLEBAR_ICONS = this.PARTS.TITLEBAR.appendChild(BX.create('DIV', {
1691		props: {
1692			className: 'bx-core-adm-dialog-head-icons'
1693		},
1694		children: (this.PARAMS.resizable ? [
1695			BX.create('SPAN', {props: {className: 'bx-core-adm-icon-expand', title: BX.message('JS_CORE_WINDOW_EXPAND')}}),
1696			BX.create('SPAN', {props: {className: 'bx-core-adm-icon-close', title: BX.message('JS_CORE_WINDOW_CLOSE')}})
1697		] : [
1698			BX.create('SPAN', {props: {className: 'bx-core-adm-icon-close', title: BX.message('JS_CORE_WINDOW_CLOSE')}})
1699		])
1700	}));
1701
1702
1703	this.PARTS.CONTENT = this.DIV.appendChild(BX.create('DIV', {
1704		props: {className: 'bx-core-adm-dialog-content-wrap adm-workarea'}
1705	}));
1706
1707	this.PARTS.CONTENT_DATA = this.PARTS.CONTENT.appendChild(BX.create('DIV', {
1708		props: {className: 'bx-core-adm-dialog-content'},
1709		style: {
1710			height: this.PARAMS.height + 'px',
1711			width: this.PARAMS.width + 'px'
1712		}
1713	}));
1714
1715	this.PARTS.HEAD = this.PARTS.CONTENT_DATA.appendChild(BX.create('DIV', {
1716		props: {
1717			className: 'bx-core-adm-dialog-head-block' + (this.PARAMS.icon ? ' ' + this.PARAMS.icon : '')
1718		}
1719	}));
1720
1721	this.SetHead(this.PARAMS.head);
1722	this.SetContent(this.PARAMS.content);
1723	this.SetTitle(this.PARAMS.title);
1724	this.SetClose(this.PARTS.TITLEBAR_ICONS.lastChild);
1725
1726	if (this.PARAMS.resizable)
1727	{
1728		this.SetExpand(this.PARTS.TITLEBAR_ICONS.firstChild);
1729		this.SetExpand(this.PARTS.TITLEBAR, 'dblclick');
1730
1731		BX.addCustomEvent(this, 'onWindowExpand', BX.proxy(this.__onexpand, this));
1732		BX.addCustomEvent(this, 'onWindowNarrow', BX.proxy(this.__onexpand, this));
1733	}
1734
1735	this.PARTS.FOOT = this.PARTS.BUTTONS_CONTAINER = this.PARTS.CONTENT.appendChild(BX.create('DIV', {
1736			props: {
1737				className: 'bx-core-adm-dialog-buttons'
1738			},
1739			//events: {
1740			//	'click': BX.delegateEvent({property:{type: /button|submit/}}, BX.delegate(function() {this.showWait(BX.proxy_context)}, this))
1741			//},
1742			children: this.ShowButtons()
1743		}
1744	));
1745
1746	if (this.PARAMS.draggable)
1747		this.SetDraggable(this.PARTS.TITLEBAR);
1748
1749	if (this.PARAMS.resizable)
1750	{
1751		this.PARTS.RESIZER = this.DIV.appendChild(BX.create('DIV', {
1752			props: {className: 'bx-core-resizer'}
1753		}));
1754
1755		this.SetResize(this.PARTS.RESIZER);
1756
1757		this.SETTINGS.min_width = this.PARAMS.min_width;
1758		this.SETTINGS.min_height = this.PARAMS.min_height;
1759	}
1760
1761	this.auth_callback = BX.delegate(function(){
1762		this.PARAMS.content = '';
1763		this.hideNotify();
1764		this.Show();
1765	}, this)
1766};
1767BX.extend(BX.CDialog, BX.CWindowDialog);
1768
1769BX.CDialog.prototype.defaultParams = {
1770	width: 700,
1771	height: 400,
1772	min_width: 500,
1773	min_height: 300,
1774
1775	resizable: true,
1776	draggable: true,
1777
1778	title: '',
1779	icon: ''
1780};
1781
1782BX.CDialog.prototype.showWait = function(el)
1783{
1784	if (BX.type.isElementNode(el) && (el.type == 'button' || el.type == 'submit'))
1785	{
1786		BX.defer(function(){el.disabled = true})();
1787
1788		var bSave = (BX.hasClass(el, 'adm-btn-save') || BX.hasClass(el, 'adm-btn-save')),
1789			pos = BX.pos(el, true);
1790
1791		el.bxwaiter = this.PARTS.FOOT.appendChild(BX.create('DIV', {
1792			props: {className: 'adm-btn-load-img' + (bSave ? '-green' : '')},
1793			style: {
1794				top: parseInt((pos.bottom + pos.top)/2 - 10) + 'px',
1795				left: parseInt((pos.right + pos.left)/2 - 10) + 'px'
1796			}
1797		}));
1798
1799		BX.addClass(el, 'adm-btn-load');
1800
1801		this.lastWaitElement = el;
1802
1803		return el.bxwaiter;
1804	}
1805	return null;
1806};
1807
1808BX.CDialog.prototype.closeWait = function(el)
1809{
1810	el = el || this.lastWaitElement;
1811
1812	if (BX.type.isElementNode(el))
1813	{
1814		if (el.bxwaiter)
1815		{
1816			if(el.bxwaiter.parentNode)
1817			{
1818				el.bxwaiter.parentNode.removeChild(el.bxwaiter);
1819			}
1820
1821			el.bxwaiter = null;
1822		}
1823
1824		el.disabled = false;
1825		BX.removeClass(el, 'adm-btn-load');
1826
1827		if (this.lastWaitElement == el)
1828			this.lastWaitElement = null;
1829	}
1830};
1831
1832BX.CDialog.prototype.Authorize = function(arAuthResult)
1833{
1834	this.bSkipReplaceContent = true;
1835	this.ShowError(BX.message('JSADM_AUTH_REQ'));
1836
1837	BX.onCustomEvent(this, 'onWindowError', []);
1838
1839	BX.closeWait();
1840
1841	(new BX.CAuthDialog({
1842		content_url: this.PARAMS.content_url,
1843		auth_result: arAuthResult,
1844		callback: BX.delegate(function(){
1845			if (this.auth_callback)
1846				this.auth_callback()
1847		}, this)
1848	})).Show();
1849};
1850
1851BX.CDialog.prototype.ShowError = function(str)
1852{
1853	BX.onCustomEvent(this, 'onWindowError', [str]);
1854
1855	this.closeWait();
1856
1857	if (this._wait)
1858		BX.closeWait(this._wait);
1859
1860	this.Notify(str, true);
1861};
1862
1863
1864BX.CDialog.prototype.__expandGetSize = function()
1865{
1866	var pDocElement = BX.GetDocElement();
1867	pDocElement.style.overflow = 'hidden';
1868
1869	var wndSize = BX.GetWindowInnerSize();
1870
1871	pDocElement.scrollTop = 0;
1872
1873	this.DIV.style.top = '-' + this.dxShadow + 'px';
1874	this.DIV.style.left = '-' + this.dxShadow + 'px';
1875
1876	return {
1877		width: (wndSize.innerWidth - parseInt(BX.style(this.PARTS.CONTENT, 'padding-right')) - parseInt(BX.style(this.PARTS.CONTENT, 'padding-left'))) + this.dxShadow,
1878		height: (wndSize.innerHeight - this.PARTS.TITLEBAR.offsetHeight - this.PARTS.FOOT.offsetHeight - parseInt(BX.style(this.PARTS.CONTENT, 'padding-top')) - parseInt(BX.style(this.PARTS.CONTENT, 'padding-bottom'))) + this.dxShadow
1879	};
1880};
1881
1882BX.CDialog.prototype.__expand = function()
1883{
1884	var pDocElement = BX.GetDocElement();
1885	this.dxShadow = 2;
1886
1887	if (!this.bExpanded)
1888	{
1889		var wndScroll = BX.GetWindowScrollPos();
1890
1891		this.__expand_settings = {
1892			resizable: this.SETTINGS.resizable,
1893			draggable: this.SETTINGS.draggable,
1894			width: this.PARTS.CONTENT_DATA.style.width,
1895			height: this.PARTS.CONTENT_DATA.style.height,
1896			left: this.DIV.style.left,
1897			top: this.DIV.style.top,
1898			scrollTop: wndScroll.scrollTop,
1899			scrollLeft: wndScroll.scrollLeft,
1900			overflow: BX.style(pDocElement, 'overflow')
1901		};
1902
1903		this.SETTINGS.resizable = false;
1904		this.SETTINGS.draggable = false;
1905
1906		var pos = this.__expandGetSize();
1907
1908		this.PARTS.CONTENT_DATA.style.width = pos.width + 'px';
1909		this.PARTS.CONTENT_DATA.style.height = pos.height + 'px';
1910
1911		window.scrollTo(0,0);
1912		pDocElement.style.overflow = 'hidden';
1913
1914		this.bExpanded = true;
1915
1916		BX.onCustomEvent(this, 'onWindowExpand');
1917		BX.onCustomEvent(this, 'onWindowResize');
1918		BX.onCustomEvent(this, 'onWindowResizeExt', [{'width': pos.width, 'height': pos.height}]);
1919
1920		BX.bind(window, 'resize', BX.proxy(this.__expand_onresize, this));
1921	}
1922	else
1923	{
1924		BX.unbind(window, 'resize', BX.proxy(this.__expand_onresize, this));
1925
1926		this.SETTINGS.resizable = this.__expand_settings.resizable;
1927		this.SETTINGS.draggable = this.__expand_settings.draggable;
1928
1929		pDocElement.style.overflow = this.__expand_settings.overflow;
1930
1931		this.DIV.style.top = this.__expand_settings.top;
1932		this.DIV.style.left = this.__expand_settings.left;
1933		this.PARTS.CONTENT_DATA.style.width = this.__expand_settings.width;
1934		this.PARTS.CONTENT_DATA.style.height = this.__expand_settings.height;
1935		window.scrollTo(this.__expand_settings.scrollLeft, this.__expand_settings.scrollTop);
1936		this.bExpanded = false;
1937
1938		BX.onCustomEvent(this, 'onWindowNarrow');
1939		BX.onCustomEvent(this, 'onWindowResize');
1940		BX.onCustomEvent(this, 'onWindowResizeExt', [{'width': parseInt(this.__expand_settings.width), 'height': parseInt(this.__expand_settings.height)}]);
1941	}
1942};
1943
1944BX.CDialog.prototype.__expand_onresize = function()
1945{
1946	var pos = this.__expandGetSize();
1947
1948	this.PARTS.CONTENT_DATA.style.width = pos.width + 'px';
1949	this.PARTS.CONTENT_DATA.style.height = pos.height + 'px';
1950
1951	BX.onCustomEvent(this, 'onWindowResize');
1952	BX.onCustomEvent(this, 'onWindowResizeExt', [pos]);
1953};
1954
1955BX.CDialog.prototype.__onexpand = function()
1956{
1957	var ob = this.PARTS.TITLEBAR_ICONS.firstChild;
1958	ob.className = BX.toggle(ob.className, ['bx-core-adm-icon-expand', 'bx-core-adm-icon-narrow']);
1959	ob.title = BX.toggle(ob.title, [BX.message('JS_CORE_WINDOW_EXPAND'), BX.message('JS_CORE_WINDOW_NARROW')]);
1960
1961	if (this.PARTS.RESIZER)
1962	{
1963		this.PARTS.RESIZER.style.display = this.bExpanded ? 'none' : 'block';
1964	}
1965};
1966
1967
1968BX.CDialog.prototype.__startResize = function(e)
1969{
1970	if (!this.SETTINGS.resizable)
1971		return false;
1972
1973	if(!e) e = window.event;
1974
1975	this.wndSize = BX.GetWindowScrollPos();
1976	this.wndSize.innerWidth = BX.GetWindowInnerSize().innerWidth;
1977
1978	this.pos = BX.pos(this.PARTS.CONTENT_DATA);
1979
1980	this.x = e.clientX + this.wndSize.scrollLeft;
1981	this.y = e.clientY + this.wndSize.scrollTop;
1982
1983	this.dx = this.pos.left + this.pos.width - this.x;
1984	this.dy = this.pos.top + this.pos.height - this.y;
1985
1986
1987	// TODO: suspicious
1988	this.dw = this.pos.width - parseInt(this.PARTS.CONTENT_DATA.style.width) + parseInt(BX.style(this.PARTS.CONTENT, 'padding-right'));
1989
1990	BX.bind(document, "mousemove", BX.proxy(this.__moveResize, this));
1991	BX.bind(document, "mouseup", BX.proxy(this.__stopResize, this));
1992
1993	if(document.body.setCapture)
1994		document.body.setCapture();
1995
1996	document.onmousedown = BX.False;
1997
1998	var b = document.body;
1999	b.ondrag = b.onselectstart = BX.False;
2000	b.style.MozUserSelect = this.DIV.style.MozUserSelect = 'none';
2001	b.style.cursor = 'se-resize';
2002
2003	BX.onCustomEvent(this, 'onWindowResizeStart');
2004
2005	return true;
2006};
2007
2008BX.CDialog.prototype.Resize = function(x, y)
2009{
2010	var new_width = Math.max(x - this.pos.left + this.dx, this.SETTINGS.min_width);
2011	var new_height = Math.max(y - this.pos.top + this.dy, this.SETTINGS.min_height);
2012
2013	if (this.SETTINGS.resize_restrict)
2014	{
2015		var scrollSize = BX.GetWindowScrollSize();
2016
2017		if (this.pos.left + new_width > scrollSize.scrollWidth - this.dw)
2018			new_width = scrollSize.scrollWidth - this.pos.left - this.dw;
2019	}
2020
2021	this.PARTS.CONTENT_DATA.style.width = new_width + 'px';
2022	this.PARTS.CONTENT_DATA.style.height = new_height + 'px';
2023
2024	BX.onCustomEvent(this, 'onWindowResize');
2025	BX.onCustomEvent(this, 'onWindowResizeExt', [{'height': new_height, 'width': new_width}]);
2026};
2027
2028BX.CDialog.prototype.SetSize = function(obSize)
2029{
2030	this.PARTS.CONTENT_DATA.style.width = obSize.width + 'px';
2031	this.PARTS.CONTENT_DATA.style.height = obSize.height + 'px';
2032
2033	BX.onCustomEvent(this, 'onWindowResize');
2034	BX.onCustomEvent(this, 'onWindowResizeExt', [obSize]);
2035};
2036
2037BX.CDialog.prototype.GetParameters = function(form_name)
2038{
2039	var form = this.GetForm();
2040
2041	if(!form)
2042		return "";
2043
2044	var i, s = "";
2045	var n = form.elements.length;
2046
2047	var delim = '';
2048	for(i=0; i<n; i++)
2049	{
2050		if (s != '') delim = '&';
2051		var el = form.elements[i];
2052		if (el.disabled)
2053			continue;
2054
2055		switch(el.type.toLowerCase())
2056		{
2057			case 'text':
2058			case 'textarea':
2059			case 'password':
2060			case 'hidden':
2061				if (null == form_name && el.name.substr(el.name.length-4) == '_alt' && form.elements[el.name.substr(0, el.name.length-4)])
2062					break;
2063				s += delim + el.name + '=' + BX.util.urlencode(el.value);
2064				break;
2065			case 'radio':
2066				if(el.checked)
2067					s += delim + el.name + '=' + BX.util.urlencode(el.value);
2068				break;
2069			case 'checkbox':
2070				s += delim + el.name + '=' + BX.util.urlencode(el.checked ? 'Y':'N');
2071				break;
2072			case 'select-one':
2073				var val = "";
2074				if (null == form_name && form.elements[el.name + '_alt'] && el.selectedIndex == 0)
2075					val = form.elements[el.name+'_alt'].value;
2076				else
2077					val = el.value;
2078				s += delim + el.name + '=' + BX.util.urlencode(val);
2079				break;
2080			case 'select-multiple':
2081				var j, bAdded = false;
2082				var l = el.options.length;
2083				for (j=0; j<l; j++)
2084				{
2085					if (el.options[j].selected)
2086					{
2087						s += delim + el.name + '=' + BX.util.urlencode(el.options[j].value);
2088						bAdded = true;
2089					}
2090				}
2091				if (!bAdded)
2092					s += delim + el.name + '=';
2093				break;
2094			default:
2095				break;
2096		}
2097	}
2098
2099	return s;
2100};
2101
2102BX.CDialog.prototype.PostParameters = function(params)
2103{
2104	var url = this.PARAMS.content_url;
2105
2106	if (null == params)
2107		params = "";
2108
2109	params += (params == "" ? "" : "&") + "bxsender=" + this._sender;
2110
2111	var index = url.indexOf('?');
2112	if (index == -1)
2113		url += '?' + params;
2114	else
2115		url = url.substring(0, index) + '?' + params + "&" + url.substring(index+1);
2116
2117	BX.showWait();
2118
2119	this.auth_callback = BX.delegate(function(){
2120		this.hideNotify();
2121		this.PostParameters(params);
2122	}, this);
2123
2124	BX.ajax.Setup({skipAuthCheck:true},true);
2125	BX.ajax.post(url, this.GetParameters(), BX.delegate(function(result) {
2126		BX.closeWait();
2127		if (!this.bSkipReplaceContent)
2128		{
2129			this.ClearButtons(); // buttons are appended during form reload, so we should clear footer
2130			this.SetContent(result);
2131			this.Show(true);
2132		}
2133
2134		this.bSkipReplaceContent = false;
2135	}, this));
2136};
2137
2138BX.CDialog.prototype.Submit = function(params, url)
2139{
2140	var FORM = this.GetForm();
2141	if (FORM)
2142	{
2143		FORM.onsubmit = null;
2144
2145		FORM.method = 'POST';
2146		if (!FORM.action || url)
2147		{
2148			url = url || this.PARAMS.content_url;
2149			if (null != params)
2150			{
2151				var index = url.indexOf('?');
2152				if (index == -1)
2153					url += '?' + params;
2154				else
2155					url = url.substring(0, index) + '?' + params + "&" + url.substring(index+1);
2156			}
2157
2158			FORM.action = url;
2159		}
2160
2161		if (!FORM._bxsender)
2162		{
2163			FORM._bxsender = FORM.appendChild(BX.create('INPUT', {
2164				attrs: {
2165					type: 'hidden',
2166					name: 'bxsender',
2167					value: this._sender
2168				}
2169			}));
2170		}
2171
2172		this._wait = BX.showWait();
2173
2174		this.auth_callback = BX.delegate(function(){
2175			this.hideNotify();
2176			this.Submit(params);
2177		}, this);
2178
2179		BX.ajax.submit(FORM, BX.delegate(function(){this.closeWait()}, this));
2180	}
2181	else
2182	{
2183		window.alert('no form registered!');
2184	}
2185};
2186
2187BX.CDialog.prototype.GetForm = function()
2188{
2189	if (null == this.__form)
2190	{
2191		var forms = this.PARTS.CONTENT_DATA.getElementsByTagName('FORM');
2192		this.__form = forms[0] ? forms[0] : null;
2193	}
2194
2195	return this.__form;
2196};
2197
2198BX.CDialog.prototype.GetRealForm = function()
2199{
2200	if (null == this.__rform)
2201	{
2202		var forms = this.PARTS.CONTENT_DATA.getElementsByTagName('FORM');
2203		this.__rform = forms[1] ? forms[1] : (forms[0] ? forms[0] : null);
2204	}
2205
2206	return this.__rform;
2207};
2208
2209BX.CDialog.prototype._checkButton = function(btn)
2210{
2211	var arCustomButtons = ['btnSave', 'btnCancel', 'btnClose'];
2212
2213	for (var i = 0; i < arCustomButtons.length; i++)
2214	{
2215		if (this[arCustomButtons[i]] && (btn == this[arCustomButtons[i]]))
2216			return arCustomButtons[i];
2217	}
2218
2219	return false;
2220};
2221
2222BX.CDialog.prototype.ShowButtons = function()
2223{
2224	var result = [];
2225	if (this.PARAMS.buttons)
2226	{
2227		if (this.PARAMS.buttons.title) this.PARAMS.buttons = [this.PARAMS.buttons];
2228
2229		for (var i=0, len=this.PARAMS.buttons.length; i<len; i++)
2230		{
2231			if (BX.type.isNotEmptyString(this.PARAMS.buttons[i]))
2232			{
2233				result.push(this.PARAMS.buttons[i]);
2234			}
2235			else if (BX.type.isElementNode(this.PARAMS.buttons[i]))
2236			{
2237				result.push(this.PARAMS.buttons[i]);
2238			}
2239			else if (this.PARAMS.buttons[i])
2240			{
2241				//if (!(this.PARAMS.buttons[i] instanceof BX.CWindowButton))
2242				if (!BX.is_subclass_of(this.PARAMS.buttons[i], BX.CWindowButton))
2243				{
2244					var b = this._checkButton(this.PARAMS.buttons[i]); // hack to set links to real CWindowButton object in btnSave etc;
2245					this.PARAMS.buttons[i] = new BX.CWindowButton(this.PARAMS.buttons[i]);
2246					if (b) this[b] = this.PARAMS.buttons[i];
2247				}
2248
2249				result.push(this.PARAMS.buttons[i].Button(this));
2250			}
2251		}
2252	}
2253
2254	return result;
2255};
2256
2257BX.CDialog.prototype.setAutosave = function () {
2258	if (!this.bSetAutosaveDelay)
2259	{
2260		this.bSetAutosaveDelay = true;
2261		setTimeout(BX.proxy(this.setAutosave, this), 10);
2262	}
2263};
2264
2265BX.CDialog.prototype.SetTitle = function(title)
2266{
2267	this.PARAMS.title = title;
2268	BX.cleanNode(this.PARTS.TITLE_CONTAINER).appendChild(document.createTextNode(this.PARAMS.title));
2269};
2270
2271BX.CDialog.prototype.SetHead = function(head)
2272{
2273	this.PARAMS.head = BX.util.trim(head);
2274	this.PARTS.HEAD.innerHTML = this.PARAMS.head || "&nbsp;";
2275	this.PARTS.HEAD.style.display = this.PARAMS.head ? 'block' : 'none';
2276	this.adjustSize();
2277};
2278
2279BX.CDialog.prototype.Notify = function(note, bError, html)
2280{
2281	if (!this.PARTS.NOTIFY)
2282	{
2283		this.PARTS.NOTIFY = this.DIV.insertBefore(BX.create('DIV', {
2284			props: {className: 'adm-warning-block'},
2285			children: [
2286				BX.create('SPAN', {
2287					props: {className: 'adm-warning-text'}
2288				}),
2289				BX.create('SPAN', {
2290					props: {className: 'adm-warning-icon'}
2291				}),
2292				BX.create('SPAN', {
2293					props: {className: 'adm-warning-close'},
2294					events: {click: BX.proxy(this.hideNotify, this)}
2295				})
2296			]
2297		}), this.DIV.firstChild);
2298	}
2299
2300	if (bError)
2301		BX.addClass(this.PARTS.NOTIFY, 'adm-warning-block-red');
2302	else
2303		BX.removeClass(this.PARTS.NOTIFY, 'adm-warning-block-red');
2304
2305	if(html !== true)
2306	{
2307		note = BX.util.htmlspecialchars(note);
2308	}
2309
2310	this.PARTS.NOTIFY.firstChild.innerHTML = note || '&nbsp;';
2311	this.PARTS.NOTIFY.firstChild.style.width = (this.PARAMS.width-50) + 'px';
2312	BX.removeClass(this.PARTS.NOTIFY, 'adm-warning-animate');
2313};
2314
2315BX.CDialog.prototype.hideNotify = function()
2316{
2317	BX.addClass(this.PARTS.NOTIFY, 'adm-warning-animate');
2318};
2319
2320BX.CDialog.prototype.__adjustHeadToIcon = function()
2321{
2322	if (!this.PARTS.HEAD.offsetHeight)
2323	{
2324		setTimeout(BX.delegate(this.__adjustHeadToIcon, this), 50);
2325	}
2326	else
2327	{
2328		if (this.icon_image && this.icon_image.height && this.icon_image.height > this.PARTS.HEAD.offsetHeight - 5)
2329		{
2330			this.PARTS.HEAD.style.height = this.icon_image.height + 5 + 'px';
2331			this.adjustSize();
2332		}
2333
2334		this.icon_image.onload = null;
2335		this.icon_image = null;
2336	}
2337};
2338
2339BX.CDialog.prototype.SetIcon = function(icon_class)
2340{
2341	if (this.PARAMS.icon != icon_class)
2342	{
2343		if (this.PARAMS.icon)
2344			BX.removeClass(this.PARTS.HEAD, this.PARAMS.icon);
2345
2346		this.PARAMS.icon = icon_class;
2347
2348		if (this.PARAMS.icon)
2349		{
2350			BX.addClass(this.PARTS.HEAD, this.PARAMS.icon);
2351
2352			var icon_file = (BX.style(this.PARTS.HEAD, 'background-image') || BX.style(this.PARTS.HEAD, 'backgroundImage'));
2353			if (BX.type.isNotEmptyString(icon_file) && icon_file != 'none')
2354			{
2355				var match = icon_file.match(new RegExp('url\\s*\\(\\s*(\'|"|)(.+?)(\\1)\\s*\\)'));
2356				if(match)
2357				{
2358					icon_file = match[2];
2359					if (BX.type.isNotEmptyString(icon_file))
2360					{
2361						this.icon_image = new Image();
2362						this.icon_image.onload = BX.delegate(this.__adjustHeadToIcon, this);
2363						this.icon_image.src = icon_file;
2364					}
2365				}
2366			}
2367		}
2368	}
2369	this.adjustSize();
2370};
2371
2372BX.CDialog.prototype.SetIconFile = function(icon_file)
2373{
2374	this.icon_image = new Image();
2375	this.icon_image.onload = BX.delegate(this.__adjustHeadToIcon, this);
2376	this.icon_image.src = icon_file;
2377
2378	BX.adjust(this.PARTS.HEAD, {style: {backgroundImage: 'url(' + icon_file + ')', backgroundPosition: 'right 9px'/*'99% center'*/}});
2379	this.adjustSize();
2380};
2381
2382/*
2383BUTTON: {
2384	title: 'title',
2385	'action': function executed in window object context
2386}
2387BX.CDialog.btnSave || BX.CDialog.btnCancel - standard buttons
2388*/
2389
2390BX.CDialog.prototype.SetButtons = function(a)
2391{
2392	if (BX.type.isString(a))
2393	{
2394		if (a.length > 0)
2395		{
2396			this.PARTS.BUTTONS_CONTAINER.innerHTML += a;
2397
2398			var btns = this.PARTS.BUTTONS_CONTAINER.getElementsByTagName('INPUT');
2399			if (btns.length > 0)
2400			{
2401				this.PARAMS.buttons = [];
2402				for (var i = 0; i < btns.length; i++)
2403				{
2404					this.PARAMS.buttons.push(new BX.CWindowButton({btn: btns[i], parentWindow: this}));
2405				}
2406			}
2407		}
2408	}
2409	else
2410	{
2411		this.PARAMS.buttons = a;
2412		BX.adjust(this.PARTS.BUTTONS_CONTAINER, {
2413			children: this.ShowButtons()
2414		});
2415	}
2416	this.adjustSize();
2417};
2418
2419BX.CDialog.prototype.ClearButtons = function()
2420{
2421	BX.cleanNode(this.PARTS.BUTTONS_CONTAINER);
2422	this.adjustSize();
2423};
2424
2425BX.CDialog.prototype.SetContent = function(html)
2426{
2427	this.__form = null;
2428
2429	if (BX.type.isElementNode(html))
2430	{
2431		if (html.parentNode)
2432			html.parentNode.removeChild(html);
2433	}
2434	else if (BX.type.isString(html))
2435	{
2436		html = BX.create('DIV', {html: html});
2437	}
2438
2439	this.PARAMS.content = html;
2440	BX.cleanNode(this.PARTS.CONTENT_DATA);
2441
2442	BX.adjust(this.PARTS.CONTENT_DATA, {
2443		children: [
2444			this.PARTS.HEAD,
2445			BX.create('DIV', {
2446				props: {
2447					className: 'bx-core-adm-dialog-content-wrap-inner'
2448				},
2449				children: [this.PARAMS.content]
2450			})
2451		]
2452	});
2453
2454	if (this.PARAMS.content_url && this.GetForm())
2455	{
2456		this.__form.submitbtn = this.__form.appendChild(BX.create('INPUT', {props:{type:'submit'},style:{display:'none'}}));
2457		this.__form.onsubmit = BX.delegate(this.__submit, this);
2458	}
2459};
2460
2461BX.CDialog.prototype.__submit = function(e)
2462{
2463	for (var i=0,len=this.PARAMS.buttons.length; i<len; i++)
2464	{
2465		if (
2466			this.PARAMS.buttons[i]
2467			&& (
2468				this.PARAMS.buttons[i].name && /save|apply/i.test(this.PARAMS.buttons[i].name)
2469				||
2470				this.PARAMS.buttons[i].btn && this.PARAMS.buttons[i].btn.name && /save|apply/i.test(this.PARAMS.buttons[i].btn.name)
2471			)
2472		)
2473		{
2474			this.PARAMS.buttons[i].emulate();
2475			break;
2476		}
2477	}
2478
2479	return BX.PreventDefault(e);
2480};
2481
2482BX.CDialog.prototype.SwapContent = function(cont)
2483{
2484	cont = BX(cont);
2485
2486	BX.cleanNode(this.PARTS.CONTENT_DATA);
2487	cont.parentNode.removeChild(cont);
2488	this.PARTS.CONTENT_DATA.appendChild(cont);
2489	cont.style.display = 'block';
2490	this.SetContent(cont.innerHTML);
2491};
2492
2493// this method deprecated
2494BX.CDialog.prototype.adjustSize = function()
2495{
2496};
2497
2498// this method deprecated
2499BX.CDialog.prototype.__adjustSize = function()
2500{
2501};
2502
2503BX.CDialog.prototype.adjustSizeEx = function()
2504{
2505	BX.defer(this.__adjustSizeEx, this)();
2506};
2507
2508BX.CDialog.prototype.__adjustSizeEx = function()
2509{
2510	var ob = this.PARTS.CONTENT_DATA.firstChild,
2511		new_height = 0,
2512		marginTop,
2513		marginBottom;
2514
2515	while (ob)
2516	{
2517		if (BX.type.isElementNode(ob))
2518		{
2519			marginTop = parseInt(BX.style(ob, 'margin-top'), 10);
2520			if (isNaN(marginTop))
2521				marginTop = 0;
2522			marginBottom = parseInt(BX.style(ob, 'margin-bottom'), 10);
2523			if (isNaN(marginBottom))
2524				marginBottom = 0;
2525			new_height += ob.offsetHeight + marginTop + marginBottom;
2526		}
2527		ob = BX.nextSibling(ob);
2528	}
2529
2530	if (new_height)
2531		this.PARTS.CONTENT_DATA.style.height = new_height + 'px';
2532};
2533
2534
2535BX.CDialog.prototype.__onResizeFinished = function()
2536{
2537	BX.WindowManager.saveWindowSize(
2538		this.PARAMS.resize_id || this.PARAMS.content_url, {height: parseInt(this.PARTS.CONTENT_DATA.style.height), width: parseInt(this.PARTS.CONTENT_DATA.style.width)}
2539	);
2540};
2541
2542BX.CDialog.prototype.Show = function(bNotRegister)
2543{
2544	if ((!this.PARAMS.content) && this.PARAMS.content_url && BX.ajax && !bNotRegister)
2545	{
2546		var wait = BX.showWait();
2547
2548		BX.WindowManager.currently_loaded = this;
2549
2550		this.CreateOverlay();
2551		this.OVERLAY.style.display = 'block';
2552		this.OVERLAY.className = 'bx-core-dialog-overlay';
2553
2554		var post_data = '', method = 'GET';
2555		if (this.PARAMS.content_post)
2556		{
2557			post_data = this.PARAMS.content_post;
2558			method = 'POST';
2559		}
2560
2561		var url = this.PARAMS.content_url
2562			+ (this.PARAMS.content_url.indexOf('?')<0?'?':'&')+'bxsender=' + this._sender;
2563
2564		this.auth_callback = BX.delegate(function(){
2565			this.PARAMS.content = '';
2566			this.hideNotify();
2567			this.Show();
2568		}, this);
2569
2570		BX.ajax({
2571			method: method,
2572			dataType: 'html',
2573			url: url,
2574			data: post_data,
2575			skipAuthCheck: true,
2576			onsuccess: BX.delegate(function(data) {
2577				BX.closeWait(null, wait);
2578
2579				this.SetContent(data || '&nbsp;');
2580				this.Show();
2581			}, this)
2582		});
2583	}
2584	else
2585	{
2586		BX.WindowManager.currently_loaded = null;
2587		BX.CDialog.superclass.Show.apply(this, arguments);
2588
2589		this.adjustPos();
2590
2591		this.OVERLAY.className = 'bx-core-dialog-overlay';
2592
2593		this.__adjustSize();
2594
2595		BX.removeCustomEvent(this, 'onWindowResize', BX.proxy(this.__adjustSize, this));
2596		BX.addCustomEvent(this, 'onWindowResize', BX.proxy(this.__adjustSize, this));
2597
2598		if (this.PARAMS.resizable && (this.PARAMS.content_url || this.PARAMS.resize_id))
2599		{
2600			BX.removeCustomEvent(this, 'onWindowResizeFinished', BX.proxy(this.__onResizeFinished, this));
2601			BX.addCustomEvent(this, 'onWindowResizeFinished', BX.proxy(this.__onResizeFinished, this));
2602		}
2603	}
2604};
2605
2606BX.CDialog.prototype.GetInnerPos = function()
2607{
2608	return {'width': parseInt(this.PARTS.CONTENT_DATA.style.width), 'height': parseInt(this.PARTS.CONTENT_DATA.style.height)};
2609};
2610
2611BX.CDialog.prototype.adjustPos = function()
2612{
2613	if (!this.bExpanded)
2614	{
2615		var currentWindow = window;
2616		var topWindow = BX.PageObject.getRootWindow();
2617		if (topWindow.BX.SidePanel && topWindow.BX.SidePanel.Instance && topWindow.BX.SidePanel.Instance.getTopSlider())
2618		{
2619			currentWindow = topWindow.BX.SidePanel.Instance.getTopSlider().getWindow();
2620		}
2621		var windowSize = currentWindow.BX.GetWindowInnerSize();
2622		var windowScroll = currentWindow.BX.GetWindowScrollPos();
2623
2624		var style = {
2625			left: parseInt(windowScroll.scrollLeft + windowSize.innerWidth / 2 - parseInt(this.DIV.offsetWidth) / 2) + 'px',
2626			top: Math.max(parseInt(windowScroll.scrollTop + windowSize.innerHe
2626ight / 2 - parseInt(this.DIV.offsetHeight) / 2), 0) + 'px'
2627		};
2628
2629		BX.adjust(this.DIV, {
2630			style: style
2631		});
2632	}
2633};
2634
2635BX.CDialog.prototype.GetContent = function () {return this.PARTS.CONTENT_DATA};
2636
2637BX.CDialog.prototype.btnSave = BX.CDialog.btnSave = {
2638	title: BX.message('JS_CORE_WINDOW_SAVE'),
2639	id: 'savebtn',
2640	name: 'savebtn',
2641	className: BX.browser.IsIE() && BX.browser.IsDoctype() && !BX.browser.IsIE10() ? '' : 'adm-btn-save',
2642	action: function () {
2643		this.disableUntilError();
2644		this.parentWindow.PostParameters();
2645	}
2646};
2647
2648BX.CDialog.prototype.btnCancel = BX.CDialog.btnCancel = {
2649	title: BX.message('JS_CORE_WINDOW_CANCEL'),
2650	id: 'cancel',
2651	name: 'cancel',
2652	action: function () {
2653		this.parentWindow.Close();
2654	}
2655};
2656
2657BX.CDialog.prototype.btnClose = BX.CDialog.btnClose = {
2658	title: BX.message('JS_CORE_WINDOW_CLOSE'),
2659	id: 'close',
2660	name: 'close',
2661	action: function () {
2662		this.parentWindow.Close();
2663	}
2664};
2665
2666/* special child for admin forms loaded into public page */
2667BX.CAdminDialog = function(arParams)
2668{
2669	BX.CAdminDialog.superclass.constructor.apply(this, arguments);
2670
2671	this._sender = 'core_window_cadmindialog';
2672
2673	BX.addClass(this.DIV, 'bx-core-adm-admin-dialog');
2674
2675	this.PARTS.CONTENT.insertBefore(this.PARTS.HEAD, this.PARTS.CONTENT.firstChild);
2676	this.PARTS.HEAD.className = 'bx-core-adm-dialog-tabs';
2677};
2678BX.extend(BX.CAdminDialog, BX.CDialog);
2679
2680BX.CAdminDialog.prototype.SetHead = function()
2681{
2682	BX.CAdminDialog.superclass.SetHead.apply(this, arguments);
2683
2684	if (this.PARTS.HEAD.firstChild && BX.type.isElementNode(this.PARTS.HEAD.firstChild))
2685	{
2686		var ob = this.PARTS.HEAD.firstChild, new_width = 0, marginLeft = 0, marginRight = 0;
2687
2688		while (ob)
2689		{
2690			if (BX.type.isElementNode(ob))
2691			{
2692				marginLeft = parseInt(BX.style(ob, 'margin-left'), 10);
2693				if (isNaN(marginLeft))
2694					marginLeft = 0;
2695				marginRight = parseInt(BX.style(ob, 'margin-right'), 10);
2696				if (isNaN(marginRight))
2697					marginRight = 0;
2698				new_width += ob.offsetWidth + marginLeft + marginRight;
2699			}
2700			ob = BX.nextSibling(ob);
2701		}
2702
2703		this.SETTINGS.min_width = Math.max(new_width, this.SETTINGS.min_width) - 2;
2704		if (this.PARAMS.width < this.SETTINGS.min_width)
2705		{
2706			BX.adjust(this.PARTS.CONTENT_DATA, {
2707				style: {
2708					width: this.SETTINGS.min_width + 'px'
2709				}
2710			});
2711		}
2712	}
2713};
2714
2715BX.CAdminDialog.prototype.SetContent = function(html)
2716{
2717	this.__form = null;
2718
2719	if (BX.type.isElementNode(html))
2720	{
2721		if (html.parentNode)
2722			html.parentNode.removeChild(html);
2723	}
2724
2725	this.PARAMS.content = html;
2726	BX.cleanNode(this.PARTS.CONTENT_DATA);
2727
2728	BX.adjust(this.PARTS.CONTENT_DATA, {
2729		children: [
2730			this.PARAMS.content || '&nbsp;'
2731		]
2732	});
2733
2734	if (this.PARAMS.content_url && this.GetForm())
2735	{
2736		this.__form.appendChild(BX.create('INPUT', {props:{type:'submit'},style:{display:'none'}}));
2737		this.__form.onsubmit = BX.delegate(this.__submit, this);
2738	}
2739};
2740
2741BX.CAdminDialog.prototype.__expandGetSize = function()
2742{
2743	var res = BX.CAdminDialog.superclass.__expandGetSize.apply(this, arguments);
2744
2745	res.width -= parseInt(BX.style(this.PARTS.CONTENT_DATA, 'padding-right')) + parseInt(BX.style(this.PARTS.CONTENT_DATA, 'padding-left'));
2746	res.height -= parseInt(BX.style(this.PARTS.CONTENT_DATA, 'padding-top')) + parseInt(BX.style(this.PARTS.CONTENT_DATA, 'padding-bottom'));
2747
2748	res.height -= this.PARTS.HEAD.offsetHeight;
2749
2750	return res;
2751};
2752
2753BX.CAdminDialog.prototype.Submit = function()
2754{
2755	var FORM = this.GetForm();
2756	if (FORM && !FORM['bxpublic'] && !/bxpublic=/.test(FORM.action))
2757	{
2758		FORM.appendChild(BX.create('INPUT', {
2759			props: {
2760				type: 'hidden',
2761				name: 'bxpublic',
2762				value: 'Y'
2763			}
2764		}));
2765	}
2766
2767	return BX.CAdminDialog.superclass.Submit.apply(this, arguments);
2768};
2769
2770BX.CAdminDialog.prototype.btnSave = BX.CAdminDialog.btnSave = {
2771	title: BX.message('JS_CORE_WINDOW_SAVE'),
2772	id: 'savebtn',
2773	name: 'savebtn',
2774	className: 'adm-btn-save',
2775	action: function () {
2776		this.disableUntilError();
2777		this.parentWindow.Submit();
2778	}
2779};
2780
2781BX.CAdminDialog.btnCancel = BX.CAdminDialog.superclass.btnCancel;
2782BX.CAdminDialog.btnClose = BX.CAdminDialog.superclass.btnClose;
2783
2784BX.CDebugDialog = function(arParams)
2785{
2786	BX.CDebugDialog.superclass.constructor.apply(this, arguments);
2787};
2788BX.extend(BX.CDebugDialog, BX.CDialog);
2789
2790BX.CDebugDialog.prototype.ShowDetails = function(div_id)
2791{
2792	var div = BX(div_id);
2793	if (div)
2794	{
2795		if (this.div_detail_current)
2796			this.div_detail_current.style.display = 'none';
2797
2798		div.style.display = 'block';
2799		this.div_detail_current = div;
2800	}
2801};
2802
2803BX.CDebugDialog.prototype.SetContent = function(html)
2804{
2805	if (!html)
2806		return;
2807
2808	var arHtml = html.split('#DIVIDER#');
2809	if (arHtml.length > 1)
2810	{
2811		this.PARAMS.content = arHtml[1];
2812
2813		this.PARTS.CONTENT_DATA.style.overflow = 'hidden';
2814
2815		BX.CDebugDialog.superclass.SetContent.apply(this, [arHtml[1]]);
2816
2817		this.PARTS.CONTENT_INNER = this.PARTS.CONTENT_DATA.firstChild.nextSibling;
2818		this.PARTS.CONTENT_TOP = this.PARTS.CONTENT_DATA.insertBefore(BX.create('DIV', {
2819			props: {
2820				className: 'bx-debug-content-top'
2821			},
2822			html: arHtml[0]
2823		}), this.PARTS.CONTENT_INNER);
2824		this.PARTS.CONTENT_INNER.style.overflow = 'auto';
2825	}
2826	else
2827	{
2828		BX.CDebugDialog.superclass.SetContent.apply(this, arguments);
2829	}
2830};
2831
2832BX.CDebugDialog.prototype.__adjustSize = function()
2833{
2834	BX.CDebugDialog.superclass.__adjustSize.apply(this, arguments);
2835
2836	if (this.PARTS.CONTENT_TOP)
2837	{
2838		var new_height = this.PARTS.CONTENT_DATA.offsetHeight - this.PARTS.HEAD.offsetHeight - this.PARTS.CONTENT_TOP.offsetHeight - 38;
2839
2840		if (new_height > 0)
2841		{
2842			this.PARTS.CONTENT_INNER.style.height = new_height + 'px';
2843		}
2844	}
2845};
2846
2847
2848/* class for dialog window with editors */
2849
2850BX.CEditorDialog = function(arParams)
2851{
2852	BX.CEditorDialog.superclass.constructor.apply(this, arguments);
2853
2854	BX.removeClass(this.PARTS.CONTENT, 'bx-core-adm-dialog-content-wrap');
2855	BX.removeClass(this.PARTS.CONTENT_DATA, 'bx-core-adm-dialog-content');
2856
2857	BX.removeClass(this.PARTS.CONTENT_DATA.lastChild, 'bx-core-adm-dialog-content-wrap-inner');
2858	BX.removeClass(this.PARTS.BUTTONS_CONTAINER, 'bx-core-adm-dialog-buttons');
2859
2860	BX.addClass(this.PARTS.CONTENT, 'bx-core-editor-dialog-content-wrap');
2861	BX.addClass(this.PARTS.CONTENT_DATA, 'bx-core-editor-dialog-content');
2862	BX.addClass(this.PARTS.BUTTONS_CONTAINER, 'bx-core-editor-dialog-buttons');
2863};
2864BX.extend(BX.CEditorDialog, BX.CDialog);
2865
2866BX.CEditorDialog.prototype.SetContent  = function()
2867{
2868	BX.CEditorDialog.superclass.SetContent.apply(this, arguments);
2869
2870	BX.removeClass(this.PARTS.CONTENT_DATA.lastChild, 'bx-core-adm-dialog-content-wrap-inner');
2871};
2872
2873/* class for wizards in admin section */
2874BX.CWizardDialog = function(arParams)
2875{
2876	BX.CWizardDialog.superclass.constructor.apply(this, arguments);
2877
2878	BX.removeClass(this.PARTS.CONTENT, 'bx-core-adm-dialog-content-wrap');
2879	BX.removeClass(this.PARTS.CONTENT_DATA, 'bx-core-adm-dialog-content');
2880	BX.removeClass(this.PARTS.CONTENT_DATA.lastChild, 'bx-core-adm-dialog-content-wrap-inner');
2881	BX.removeClass(this.PARTS.BUTTONS_CONTAINER, 'bx-core-adm-dialog-buttons');
2882
2883	BX.addClass(this.PARTS.CONTENT, 'bx-core-wizard-dialog-content-wrap');
2884};
2885
2886BX.extend(BX.CWizardDialog, BX.CDialog);
2887
2888/* class for auth dialog */
2889BX.CAuthDialog = function(arParams)
2890{
2891	arParams.resizable = false;
2892	arParams.width = 350;
2893	arParams.height = 200;
2894
2895	arParams.buttons = [this.btnSave];
2896
2897	BX.CAuthDialog.superclass.constructor.apply(this, arguments);
2898	this._sender = 'core_window_cauthdialog';
2899
2900	BX.addClass(this.DIV, 'bx-core-auth-dialog');
2901
2902	BX.AUTHAGENT = this;
2903};
2904BX.extend(BX.CAuthDialog, BX.CDialog);
2905
2906BX.CAuthDialog.prototype.btnSave = BX.CAuthDialog.btnSave = {
2907	title: BX.message('JS_CORE_WINDOW_AUTH'),
2908	id: 'savebtn',
2909	name: 'savebtn',
2910	className: 'adm-btn-save',
2911	action: function () {
2912		this.disableUntilError();
2913		this.parentWindow.Submit('', this.parentWindow.PARAMS.content_url);
2914	}
2915};
2916
2917BX.CAuthDialog.prototype.SetError = function(error)
2918{
2919	BX.closeWait();
2920
2921	if (!!error)
2922		this.ShowError(error.MESSAGE || error);
2923};
2924
2925BX.CAuthDialog.prototype.setAuthResult = function(result)
2926{
2927	BX.closeWait();
2928
2929	if (result === false)
2930	{
2931		this.Close();
2932		if (this.PARAMS.callback)
2933			this.PARAMS.callback();
2934	}
2935	else
2936	{
2937		this.SetError(result);
2938	}
2939};
2940
2941/* MENU CLASSES */
2942
2943BX.CWindowFloat = function(node)
2944{
2945	BX.CWindowFloat.superclass.constructor.apply(this, [node, 'float']);
2946
2947	this.SETTINGS.resizable = false;
2948};
2949BX.extend(BX.CWindowFloat, BX.CWindow);
2950
2951BX.CWindowFloat.prototype.adjustPos = function()
2952{
2953	if (this.PARAMS.parent)
2954		this.adjustToNode();
2955	else if (this.PARAMS.x && this.PARAMS.y)
2956		this.adjustToPos([this.PARAMS.x, this.PARAMS.y]);
2957};
2958
2959BX.CWindowFloat.prototype.adjustToPos = function(pos)
2960{
2961	this.DIV.style.left = parseInt(pos[0]) + 'px';
2962	this.DIV.style.top = parseInt(pos[1]) + 'px';
2963};
2964
2965BX.CWindowFloat.prototype.adjustToNodeGetPos = function()
2966{
2967	return BX.pos(this.PARAMS.parent);
2968};
2969
2970BX.CWindowFloat.prototype.adjustToNode = function(el)
2971{
2972	el = el || this.PARAMS.parent;
2973
2974	this.PARAMS.parent = BX(el);
2975
2976	if (this.PARAMS.parent)
2977	{
2978		var pos = this.adjustToNodeGetPos();
2979
2980		this.DIV.style.top = pos.top + 'px';//(pos.top - 26) + 'px';
2981		this.DIV.style.left = pos.left + 'px';
2982
2983		this.PARAMS.parent.OPENER = this;
2984	}
2985};
2986
2987BX.CWindowFloat.prototype.Show = function()
2988{
2989	this.adjustToPos([-1000, -1000]);
2990	BX.CWindowFloat.superclass.Show.apply(this, arguments);
2991	this.adjustPos();
2992};
2993
2994/* menu opener class */
2995/*
2996{
2997	DOMNode DIV,
2998	BX.CMenu or Array MENU,
2999	TYPE = 'hover' | 'click',
3000	TIMEOUT: 1000
3001	ATTACH_MODE: 'top' | 'right'
3002	ACTIVE_CLASS: className for opener element when menu is opened
3003}
3004*/
3005BX.COpener = function(arParams)
3006{
3007	this.PARAMS = arParams || {};
3008
3009	this.MENU = arParams.MENU || [];
3010
3011	this.DIV = arParams.DIV;
3012	this.ATTACH = arParams.ATTACH || arParams.DIV;
3013	this.ATTACH_MODE = arParams.ATTACH_MODE || 'bottom';
3014
3015	this.ACTIVE_CLASS = arParams.ACTIVE_CLASS || '';
3016	this.PUBLIC_FRAME = arParams.PUBLIC_FRAME || 0;
3017	this.LEVEL = arParams.LEVEL || 0;
3018
3019	this.CLOSE_ON_CLICK = typeof arParams.CLOSE_ON_CLICK != 'undefined' ? !!arParams.CLOSE_ON_CLICK : true;
3020	this.ADJUST_ON_CLICK = typeof arParams.ADJUST_ON_CLICK != 'undefined' ? !!arParams.ADJUST_ON_CLICK : true;
3021
3022	this.TYPE = this.PARAMS.TYPE == 'hover' ? 'hover' : 'click';
3023
3024	this._openTimeout = null;
3025
3026	if (this.PARAMS.TYPE == 'hover' && arParams.TIMEOUT !== 0)
3027		this.TIMEOUT = arParams.TIMEOUT || 1000;
3028	else
3029		this.TIMEOUT = 0;
3030
3031	this.bMenuInit = false;
3032
3033	if (!!this.PARAMS.MENU_URL)
3034	{
3035		this.bMenuLoaded = false;
3036		this.bMenuLoading = false;
3037
3038		this.MENU = [{
3039			TEXT: BX.message('JS_CORE_LOADING'),
3040			CLOSE_ON_CLICK: false
3041		}];
3042
3043		if (this.PARAMS.MENU_PRELOAD)
3044		{
3045			BX.defer(this.Load, this)();
3046		}
3047	}
3048
3049	BX.ready(BX.defer(this.Init, this));
3050};
3051
3052BX.COpener.prototype.Init = function()
3053{
3054	this.DIV = BX(this.DIV);
3055
3056	switch (this.TYPE)
3057	{
3058		case 'hover':
3059			BX.bind(this.DIV, 'mouseover', BX.proxy(this.Open, this));
3060			BX.bind(this.DIV, 'click', BX.proxy(this.Toggle, this));
3061		break;
3062
3063		case 'click':
3064			BX.bind(this.DIV, 'click', BX.proxy(this.Toggle, this));
3065		break;
3066	}
3067
3068	//BX.bind(window, 'scroll', BX.delegate(this.__close_immediately, this));
3069
3070	//this.bMenuInit = false;
3071};
3072
3073BX.COpener.prototype.Load = function()
3074{
3075	if (this.PARAMS.MENU_URL && !this.bMenuLoaded)
3076	{
3077		if (!this.bMenuLoading)
3078		{
3079			var url = this.PARAMS.MENU_URL;
3080			if (url.indexOf('sessid=') <= 0)
3081				url += (url.indexOf('?') > 0 ? '&' : '?') + 'sessid=' + BX.bitrix_sessid();
3082
3083			this.bMenuLoading = true;
3084			BX.ajax.loadJSON(url, BX.proxy(this.SetMenu, this), BX.proxy(this.LoadFailed, this));
3085		}
3086	}
3087};
3088
3089BX.COpener.prototype.SetMenu = function(menu)
3090{
3091	this.bMenuLoaded = true;
3092	this.bMenuLoading = false;
3093	if (this.bMenuInit)
3094	{
3095		this.MENU.setItems(menu);
3096	}
3097	else
3098	{
3099		this.MENU = menu;
3100	}
3101};
3102
3103BX.COpener.prototype.LoadFailed = function(type, error)
3104{
3105	this.bMenuLoading = false;
3106	this.SetMenu([{
3107		TEXT: BX.message('JS_CORE_NO_DATA'),
3108		CLOSE_ON_CLICK: true
3109	}]);
3110	BX.debug(arguments);
3111};
3112
3113BX.COpener.prototype.checkAdminMenu = function()
3114{
3115	if (document.documentElement.id == 'bx-admin-prefix')
3116		return true;
3117
3118	return !!BX.findParent(this.DIV, {property: {id: 'bx-admin-prefix'}});
3119};
3120
3121BX.COpener.prototype.Toggle = function(e)
3122{
3123	this.__clear_timeout();
3124
3125	if (!this.bMenuInit || !this.MENU.visible())
3126	{
3127		var t = this.TIMEOUT;
3128		this.TIMEOUT = 0;
3129		this.Open(e);
3130		this.TIMEOUT = t;
3131	}
3132	else
3133	{
3134		this.MENU.Close();
3135	}
3136
3137	return !!(e||window.event) && BX.PreventDefault(e);
3138};
3139
3140BX.COpener.prototype.GetMenu = function()
3141{
3142	if (!this.bMenuInit)
3143	{
3144		if (BX.type.isArray(this.MENU))
3145		{
3146			this.MENU = new BX.CMenu({
3147				ITEMS: this.MENU,
3148				ATTACH_MODE: this.ATTACH_MODE,
3149				SET_ID: this.checkAdminMenu() ? 'bx-admin-prefix' : '',
3150				CLOSE_ON_CLICK: !!this.CLOSE_ON_CLICK,
3151				ADJUST_ON_CLICK: !!this.ADJUST_ON_CLICK,
3152				PUBLIC_FRAME: !!this.PUBLIC_FRAME,
3153				LEVEL: this.LEVEL,
3154				parent: BX(this.DIV),
3155				parent_attach: BX(this.ATTACH)
3156			});
3157
3158			if (this.LEVEL > 0)
3159			{
3160				BX.bind(this.MENU.DIV, 'mouseover', BX.proxy(this._on_menu_hover, this));
3161				BX.bind(this.MENU.DIV, 'mouseout', BX.proxy(this._on_menu_hout, this));
3162			}
3163		}
3164
3165		BX.addCustomEvent(this.MENU, 'onMenuOpen', BX.proxy(this.handler_onopen, this));
3166		BX.addCustomEvent(this.MENU, 'onMenuClose', BX.proxy(this.handler_onclose, this));
3167
3168		BX.addCustomEvent('onMenuItemHover', BX.proxy(this.handler_onover, this));
3169
3170		this.bMenuInit = true;
3171	}
3172
3173	return this.MENU;
3174};
3175
3176BX.COpener.prototype.Open = function()
3177{
3178	this.GetMenu();
3179
3180	this.bOpen = true;
3181
3182	this.__clear_timeout();
3183
3184	if (this.TIMEOUT > 0)
3185	{
3186		BX.bind(this.DIV, 'mouseout', BX.proxy(this.__clear_timeout, this));
3187		this._openTimeout = setTimeout(BX.proxy(this.__open, this), this.TIMEOUT);
3188	}
3189	else
3190	{
3191		this.__open();
3192	}
3193
3194	if (!!this.PARAMS.MENU_URL && !this.bMenuLoaded)
3195	{
3196		this._loadTimeout = setTimeout(BX.proxy(this.Load, this), parseInt(this.TIMEOUT/2));
3197	}
3198
3199	return true;
3200};
3201
3202BX.COpener.prototype.__clear_timeout = function()
3203{
3204	if (!!this._openTimeout)
3205		clearTimeout(this._openTimeout);
3206	if (!!this._loadTimeout)
3207		clearTimeout(this._loadTimeout);
3208
3209	BX.unbind(this.DIV, 'mouseout', BX.proxy(this.__clear_timeout, this));
3210};
3211
3212BX.COpener.prototype._on_menu_hover = function()
3213{
3214	this.bMenuHover = true;
3215
3216	this.__clear_timeout();
3217
3218	if (this.ACTIVE_CLASS)
3219		BX.addClass(this.DIV, this.ACTIVE_CLASS);
3220
3221};
3222
3223BX.COpener.prototype._on_menu_hout = function()
3224{
3225	this.bMenuHover = false;
3226};
3227
3228BX.COpener.prototype.handler_onover = function(level, opener)
3229{
3230	if (this.bMenuHover)
3231		return;
3232
3233	if (opener != this && level == this.LEVEL-1 && this.ACTIVE_CLASS)
3234	{
3235		BX.removeClass(this.DIV, this.ACTIVE_CLASS);
3236	}
3237
3238	if (this.bMenuInit && level <= this.LEVEL-1 && this.MENU.visible())
3239	{
3240		if (opener != this)
3241		{
3242			this.__clear_timeout();
3243			this._openTimeout = setTimeout(BX.proxy(this.Close, this), this.TIMEOUT);
3244		}
3245	}
3246};
3247
3248BX.COpener.prototype.handler_onopen = function()
3249{
3250	this.bOpen = true;
3251
3252	if (this.ACTIVE_CLASS)
3253		BX.addClass(this.DIV, this.ACTIVE_CLASS);
3254
3255	BX.defer(function() {
3256		BX.onCustomEvent(this, 'onOpenerMenuOpen');
3257	}, this)();
3258};
3259
3260BX.COpener.prototype.handler_onclose = function()
3261{
3262	this.bOpen = false;
3263	BX.onCustomEvent(this, 'onOpenerMenuClose');
3264
3265	if (this.ACTIVE_CLASS)
3266		BX.removeClass(this.DIV, this.ACTIVE_CLASS);
3267};
3268
3269BX.COpener.prototype.Close = function()
3270{
3271	if (!this.bMenuInit)
3272		return;
3273
3274	if (!!this._openTimeout)
3275		clearTimeout(this._openTimeout);
3276
3277	this.bOpen = false;
3278
3279	this.__close();
3280};
3281
3282BX.COpener.prototype.__open = function()
3283{
3284	this.__clear_timeout();
3285
3286	if (this.bMenuInit && this.bOpen && !this.MENU.visible())
3287		this.MENU.Show();
3288};
3289
3290BX.COpener.prototype.__close = function()
3291{
3292	if (this.bMenuInit && !this.bOpen && this.MENU.visible())
3293		this.MENU.Hide();
3294};
3295
3296BX.COpener.prototype.__close_immediately = function() {
3297	this.bOpen = false; this.__close();
3298};
3299
3300BX.COpener.prototype.isMenuVisible = function() {
3301	return null != this.MENU.visible && this.MENU.visible()
3302};
3303
3304/* common menu class */
3305
3306BX.CMenu = function(arParams)
3307{
3308	BX.CMenu.superclass.constructor.apply(this);
3309
3310	this.DIV.style.width = 'auto';//this.DIV.firstChild.offsetWidth + 'px';
3311	this.DIV.style.height = 'auto';//this.DIV.firstChild.offsetHeight + 'px';
3312
3313	this.PARAMS = arParams || {};
3314	this.PARTS = {};
3315
3316	this.PARAMS.ATTACH_MODE = this.PARAMS.ATTACH_MODE || 'bottom';
3317	this.PARAMS.CLOSE_ON_CLICK = typeof this.PARAMS.CLOSE_ON_CLICK == 'undefined' ? true : this.PARAMS.CLOSE_ON_CLICK;
3318	this.PARAMS.ADJUST_ON_CLICK = typeof this.PARAMS.ADJUST_ON_CLICK == 'undefined' ? true : this.PARAMS.ADJUST_ON_CLICK;
3319	this.PARAMS.PUBLIC_FRAME = typeof this.PARAMS.PUBLIC_FRAME == 'undefined' ? false : this.PARAMS.PUBLIC_FRAME;
3320	this.PARAMS.LEVEL = this.PARAMS.LEVEL || 0;
3321
3322	this.DIV.className = 'bx-core-popup-menu bx-core-popup-menu-' + this.PARAMS.ATTACH_MODE + ' bx-core-popup-menu-level' + this.PARAMS.LEVEL + (typeof this.PARAMS.ADDITIONAL_CLASS != 'undefined' ? ' ' + this.PARAMS.ADDITIONAL_CLASS : '');
3323	if (!!this.PARAMS.SET_ID)
3324		this.DIV.id = this.PARAMS.SET_ID;
3325
3326	if (this.PARAMS.LEVEL == 0)
3327	{
3328		this.ARROW = this.DIV.appendChild(BX.create('SPAN', {props: {className: 'bx-core-popup-menu-angle'}, style: {left:'15px'}}));
3329	}
3330
3331	if (!!this.PARAMS.CLASS_NAME)
3332		this.DIV.className += ' ' + this.PARAMS.CLASS_NAME;
3333
3334	BX.bind(this.DIV, 'click', BX.eventCancelBubble);
3335
3336	this.ITEMS = [];
3337
3338	this.setItems(this.PARAMS.ITEMS);
3339
3340	BX.addCustomEvent('onMenuOpen', BX.proxy(this._onMenuOpen, this));
3341	BX.addCustomEvent('onMenuItemSelected', BX.proxy(this.Hide, this));
3342};
3343BX.extend(BX.CMenu, BX.CWindowFloat);
3344
3345BX.CMenu.broadcastCloseEvent = function()
3346{
3347	BX.onCustomEvent("onMenuItemSelected");
3348};
3349
3350BX.CMenu._toggleChecked = function()
3351{
3352	BX.toggleClass(this, 'bx-core-popup-menu-item-checked');
3353};
3354
3355BX.CMenu._itemDblClick = function()
3356{
3357	window.location.href = this.href;
3358};
3359
3360BX.CMenu.prototype.toggleArrow = function(v)
3361{
3362	if (!!this.ARROW)
3363	{
3364		if (typeof v == 'undefined')
3365		{
3366			v = this.ARROW.style.visibility == 'hidden';
3367		}
3368
3369		this.ARROW.style.visibility = !!v ? 'visible' : 'hidden';
3370	}
3371};
3372
3373BX.CMenu.prototype.visible = function()
3374{
3375	return this.DIV.style.display !== 'none';
3376};
3377
3378BX.CMenu.prototype._onMenuOpen = function(menu, menu_level)
3379{
3380	if (this.visible())
3381	{
3382		if (menu_level == this.PARAMS.LEVEL && menu != this)
3383		{
3384			this.Hide();
3385		}
3386	}
3387};
3388
3389BX.CMenu.prototype.onUnRegister = function()
3390{
3391	if (!this.visible())
3392		return;
3393
3394	this.Hide();
3395};
3396
3397BX.CMenu.prototype.setItems = function(items)
3398{
3399	this.PARAMS.ITEMS = items;
3400
3401	BX.cleanNode(this.DIV);
3402
3403	if (!!this.ARROW)
3404		this.DIV.appendChild(this.ARROW);
3405
3406	if (this.PARAMS.ITEMS)
3407	{
3408		this.PARAMS.ITEMS = BX.util.array_values(this.PARAMS.ITEMS);
3409
3410		var bIcons = false;
3411		var cnt = 0;
3412		for (var i = 0, len = this.PARAMS.ITEMS.length; i < len; i++)
3413		{
3414			if ((i == 0 || i == len-1) && this.PARAMS.ITEMS[i].SEPARATOR)
3415				continue;
3416
3417			cnt++;
3418
3419			if (!bIcons)
3420				bIcons = !!this.PARAMS.ITEMS[i].GLOBAL_ICON;
3421
3422			this.addItem(this.PARAMS.ITEMS[i], i);
3423		}
3424
3425		// Occam turning in his grave
3426		if (cnt === 1)
3427			BX.addClass(this.DIV, 'bx-core-popup-menu-single-item');
3428		else
3429			BX.removeClass(this.DIV, 'bx-core-popup-menu-single-item');
3430
3431		if (!bIcons)
3432			BX.addClass(this.DIV, 'bx-core-popup-menu-no-icons');
3433		else
3434			BX.removeClass(this.DIV, 'bx-core-popup-menu-no-icons');
3435
3436	}
3437};
3438
3439BX.CMenu.prototype.addItem = function(item)
3440{
3441	this.ITEMS.push(item);
3442
3443	if (item.SEPARATOR)
3444	{
3445		item.NODE = BX.create(
3446			'DIV', {props: {className: 'bx-core-popup-menu-separator'}}
3447		);
3448	}
3449	else
3450	{
3451		var bHasMenu = (!!item.MENU
3452			&& (
3453				(BX.type.isArray(item.MENU) && item.MENU.length > 0)
3454				|| item.MENU instanceof BX.CMenu
3455			) || !!item.MENU_URL
3456		);
3457
3458		if (item.DISABLED)
3459		{
3460			item.CLOSE_ON_CLICK = false;
3461			item.LINK = null;
3462			item.ONCLICK = null;
3463			item.ACTION = null;
3464		}
3465
3466		var attrs = {};
3467		if (!!item.LINK || BX.browser.IsIE() && !BX.browser.IsDoctype())
3468		{
3469			attrs.href = item.LINK || 'javascript:void(0)';
3470		}
3471		if (this.PARAMS.PUBLIC_FRAME)
3472		{
3473			attrs.target = '_top';
3474		}
3475
3476		item.NODE = BX.create(!!item.LINK || BX.browser.IsIE() && !BX.browser.IsDoctype() ? 'A' : 'SPAN', {
3477			props: {
3478				className: 'bx-core-popup-menu-item'
3479					+ (bHasMenu ? ' bx-core-popup-menu-item-opener' : '')
3480					+ (!!item.DEFAULT ? ' bx-core-popup-menu-item-default' : '')
3481					+ (!!item.DISABLED ? ' bx-core-popup-menu-item-disabled' : '')
3482					+ (!!item.CHECKED ? ' bx-core-popup-menu-item-checked' : ''),
3483					title: !!BX.message['MENU_ENABLE_TOOLTIP'] || !!item.SHOW_TITLE ? item.TITLE || '' : '',
3484				BXMENULEVEL: this.PARAMS.LEVEL
3485			},
3486			attrs: attrs,
3487			events: {
3488				mouseover: function()
3489				{
3490					BX.onCustomEvent('onMenuItemHover', [this.BXMENULEVEL, this.OPENER])
3491				}
3492			},
3493			html: '<span class="bx-core-popup-menu-item-icon' + (item.GLOBAL_ICON ? ' '+item.GLOBAL_ICON : '') + '"></span><span class="bx-core-popup-menu-item-text">'+(item.HTML||(item.TEXT? BX.util.htmlspecialchars(item.TEXT) : ''))+'</span>'
3494		});
3495
3496		if (bHasMenu && !item.DISABLED)
3497		{
3498			item.NODE.OPENER = new BX.COpener({
3499				DIV: item.NODE,
3500				ACTIVE_CLASS: 'bx-core-popup-menu-item-opened',
3501				TYPE: 'hover',
3502				MENU: item.MENU,
3503				MENU_URL: item.MENU_URL,
3504				MENU_PRELOAD: !!item.MENU_PRELOAD,
3505				LEVEL: this.PARAMS.LEVEL + 1,
3506				ATTACH_MODE:'right',
3507				TIMEOUT: 500
3508			});
3509		}
3510		else if (this.PARAMS.CLOSE_ON_CLICK && (typeof item.CLOSE_ON_CLICK == 'undefined' || !!item.CLOSE_ON_CLICK))
3511		{
3512			BX.bind(item.NODE, 'click', BX.CMenu.broadcastCloseEvent);
3513		}
3514		else if (this.PARAMS.ADJUST_ON_CLICK && (typeof item.ADJUST_ON_CLICK == 'undefined' || !!item.ADJUST_ON_CLICK))
3515		{
3516			BX.bind(item.NODE, 'click', BX.defer(this.adjustPos, this));
3517		}
3518
3519		if (bHasMenu && !!item.LINK)
3520		{
3521			BX.bind(item.NODE, 'dblclick', BX.CMenu._itemDblClick);
3522		}
3523
3524		if (typeof item.CHECKED != 'undefined')
3525		{
3526			BX.bind(item.NODE, 'click', BX.CMenu._toggleChecked);
3527		}
3528
3529		item.ONCLICK = item.ACTION || item.ONCLICK;
3530		if (!!item.ONCLICK)
3531		{
3532			if (BX.type.isString(item.ONCLICK))
3533			{
3534				item.ONCLICK = new Function("event", item.ONCLICK);
3535			}
3536
3537			BX.bind(item.NODE, 'click', item.ONCLICK);
3538		}
3539	}
3540
3541	this.DIV.appendChild(item.NODE);
3542};
3543
3544BX.CMenu.prototype._documentClickBind = function()
3545{
3546	this._documentClickUnBind();
3547	BX.bind(document, 'click', BX.proxy(this._documentClick, this));
3548};
3549
3550BX.CMenu.prototype._documentClickUnBind = function()
3551{
3552	BX.unbind(document, 'click', BX.proxy(this._documentClick, this));
3553};
3554
3555BX.CMenu.prototype._documentClick = function(e)
3556{
3557	e = e||window.event;
3558	if(!!e && !(BX.getEventButton(e) & BX.MSLEFT))
3559		return;
3560
3561	this.Close();
3562};
3563
3564BX.CMenu.prototype.Show = function()
3565{
3566	BX.onCustomEvent(this, 'onMenuOpen', [this, this.PARAMS.LEVEL]);
3567	BX.CMenu.superclass.Show.apply(this, []);
3568
3569	this.bCloseEventFired = false;
3570
3571	BX.addCustomEvent(this.PARAMS.parent_attach, 'onChangeNodePosition', BX.proxy(this.adjustToNode, this));
3572
3573	(BX.defer(this._documentClickBind, this))();
3574};
3575
3576BX.CMenu.prototype.Close = // we shouldn't 'Close' window - only hide
3577BX.CMenu.prototype.Hide = function()
3578{
3579	if (!this.visible())
3580		return;
3581
3582	BX.removeCustomEvent(this.PARAMS.parent_attach, 'onChangeNodePosition', BX.proxy(this.adjustToNode, this));
3583
3584	this._documentClickUnBind();
3585
3586	if (!this.bCloseEventFired)
3587	{
3588		BX.onCustomEvent(this, 'onMenuClose', [this, this.PARAMS.LEVEL]);
3589		this.bCloseEventFired = true;
3590	}
3591	BX.CMenu.superclass.Hide.apply(this, arguments);
3592
3593
3594//	this.DIV.onclick = null;
3595	//this.PARAMS.parent.onclick = null;
3596};
3597
3598BX.CMenu.prototype.__adjustMenuToNode = function()
3599{
3600	var pos = BX.pos(this.PARAMS.parent_attach),
3601		bFixed = !!BX.findParent(this.PARAMS.parent_attach, BX.is_fixed);
3602
3603	if (bFixed)
3604		this.DIV.style.position = 'fixed';
3605	else
3606		this.DIV.style.position = 'absolute';
3607
3608	if (!pos.top)
3609	{
3610		this.DIV.style.top = '-1000px';
3611		this.DIV.style.left = '-1000px';
3612	}
3613
3614	if (this.bTimeoutSet) return;
3615
3616	var floatWidth = this.DIV.offsetWidth, floatHeight = this.DIV.offsetHeight;
3617	if (!floatWidth)
3618	{
3619		setTimeout(BX.delegate(function(){
3620			this.bTimeoutSet = false; this.__adjustMenuToNode();
3621		}, this), 100);
3622
3623		this.bTimeoutSet = true;
3624		return;
3625	}
3626
3627	var menu_pos = {},
3628		wndSize = BX.GetWindowSize();
3629
3630/*
3631	if (BX.browser.IsIE() && !BX.browser.IsDoctype())
3632	{
3633		pos.top -= 4; pos.bottom -= 4;
3634		pos.left -= 2; pos.right -= 2;
3635	}
3636*/
3637
3638	switch (this.PARAMS.ATTACH_MODE)
3639	{
3640		case 'bottom':
3641			menu_pos.top = pos.bottom + 9;
3642			menu_pos.left = pos.left;
3643
3644			var arrowPos = 0;
3645			if (!!this.ARROW)
3646			{
3647				if (pos.width > floatWidth)
3648					arrowPos = parseInt(floatWidth/2 - 7);
3649				else
3650					arrowPos = parseInt(Math.min(floatWidth, pos.width)/2 - 7);
3651
3652				if (arrowPos < 7)
3653				{
3654					menu_pos.left -= 15;
3655					arrowPos += 15;
3656				}
3657			}
3658
3659			if (menu_pos.left > wndSize.scrollWidth - floatWidth - 10)
3660			{
3661				var orig_menu_pos = menu_pos.left;
3662				menu_pos.left = wndSize.scrollWidth - floatWidth - 10;
3663
3664				if (!!this.ARROW)
3665					arrowPos += orig_menu_pos - menu_pos.left;
3666			}
3667
3668			if (bFixed)
3669			{
3670				menu_pos.left -= wndSize.scrollLeft;
3671			}
3672
3673			if (!!this.ARROW)
3674				this.ARROW.style.left = arrowPos + 'px';
3675		break;
3676		case 'right':
3677			menu_pos.top = pos.top-1;
3678			menu_pos.left = pos.right;
3679
3680			if (menu_pos.left > wndSize.scrollWidth - floatWidth - 10)
3681			{
3682				menu_pos.left = pos.left - floatWidth - 1;
3683			}
3684		break;
3685	}
3686
3687	if (bFixed)
3688	{
3689		menu_pos.top -= wndSize.scrollTop;
3690	}
3691
3692	if (!!this.ARROW)
3693		this.ARROW.className = 'bx-core-popup-menu-angle';
3694
3695	if((menu_pos.top + floatHeight >
3695 wndSize.scrollTop + wndSize.innerHeight)
3696		|| (menu_pos.top + floatHeight > wndSize.scrollHeight))
3697	{
3698		var new_top = this.PARAMS.ATTACH_MODE == 'bottom'
3699			? pos.top - floatHeight - 9
3700			: pos.bottom - floatHeight + 1;
3701
3702		if((new_top > wndSize.scrollTop)
3703			|| (menu_pos.top + floatHeight > wndSize.scrollHeight))
3704		{
3705			if ((menu_pos.top + floatHeight > wndSize.scrollHeight))
3706			{
3707				menu_pos.top = Math.max(0, wndSize.scrollHeight-floatHeight);
3708				this.toggleArrow(false);
3709			}
3710			else
3711			{
3712				menu_pos.top = new_top;
3713
3714				if (!!this.ARROW)
3715					this.ARROW.className = 'bx-core-popup-menu-angle-bottom';
3716			}
3717		}
3718	}
3719
3720	if (menu_pos.top + menu_pos.left == 0)
3721	{
3722		this.Hide();
3723	}
3724	else
3725	{
3726		this.DIV.style.top = menu_pos.top + 'px';
3727		this.DIV.style.left = menu_pos.left + 'px';
3728	}
3729};
3730
3731BX.CMenu.prototype.adjustToNode = function(el)
3732{
3733	this.PARAMS.parent_attach = BX(el) || this.PARAMS.parent_attach || this.PARAMS.parent;
3734	this.__adjustMenuToNode();
3735};
3736
3737
3738/* components toolbar class */
3739
3740BX.CMenuOpener = function(arParams)
3741{
3742	BX.CMenuOpener.superclass.constructor.apply(this);
3743
3744	this.PARAMS = arParams || {};
3745	this.setParent(this.PARAMS.parent);
3746	this.PARTS = {};
3747
3748	this.SETTINGS.drag_restrict = true;
3749
3750	this.defaultAction = null;
3751
3752	this.timeout = 500;
3753
3754	this.DIV.className = 'bx-component-opener';
3755	this.DIV.ondblclick = BX.PreventDefault;
3756
3757	if (this.PARAMS.component_id)
3758	{
3759		this.PARAMS.transform = !!this.PARAMS.transform;
3760	}
3761
3762	this.OPENERS = [];
3763
3764	this.DIV.appendChild(BX.create('SPAN', {
3765		props: {className: 'bx-context-toolbar' + (this.PARAMS.transform ? ' bx-context-toolbar-vertical-mode' : '')}
3766	}));
3767
3768	//set internal structure and register draggable element
3769	this.PARTS.INNER = this.DIV.firstChild.appendChild(BX.create('SPAN', {
3770		props: {className: 'bx-context-toolbar-inner'},
3771		html: '<span class="bx-context-toolbar-drag-icon"></span><span class="bx-context-toolbar-vertical-line"></span><br>'
3772	}));
3773
3774	this.EXTRA_BUTTONS = {};
3775
3776	var btnCount = 0;
3777	for (var i = 0, len = this.PARAMS.menu.length; i < len; i++)
3778	{
3779		var item = this.addItem(this.PARAMS.menu[i]);
3780		if (null != item)
3781		{
3782			btnCount++;
3783			this.PARTS.INNER.appendChild(item);
3784			this.PARTS.INNER.appendChild(BX.create('BR'));
3785		}
3786	}
3787	var bHasButtons = btnCount > 0;
3788
3789	//menu items will be attached here
3790
3791	this.PARTS.ICONS = this.PARTS.INNER.appendChild(BX.create('SPAN', {
3792		props: {className: 'bx-context-toolbar-icons'}
3793	}));
3794
3795	if (this.PARAMS.component_id)
3796	{
3797		this.PARAMS.pin = !!this.PARAMS.pin;
3798
3799		if (bHasButtons)
3800			this.PARTS.ICONS.appendChild(BX.create('SPAN', {props: {className: 'bx-context-toolbar-separator'}}));
3801
3802		this.PARTS.ICON_PIN = this.PARTS.ICONS.appendChild(BX.create('A', {
3803			attrs: {
3804				href: 'javascript:void(0)'
3805			},
3806			props: {
3807				className: this.PARAMS.pin
3808							? 'bx-context-toolbar-pin-fixed'
3809							: 'bx-context-toolbar-pin'
3810			},
3811			events: {
3812				click: BX.delegate(this.__pin_btn_clicked, this)
3813			}
3814		}));
3815	}
3816
3817
3818	if (this.EXTRA_BUTTONS['components2_props'])
3819	{
3820		var btn = this.EXTRA_BUTTONS['components2_props'] || {URL: 'javascript:void(0)'};
3821		if (null == this.defaultAction)
3822		{
3823			this.defaultAction = btn.ONCLICK;
3824			this.defaultActionTitle = btn.TITLE || btn.TEXT;
3825		}
3826
3827		btn.URL = 'javascript:' + BX.util.urlencode(btn.ONCLICK);
3828
3829		this.ATTACH = this.PARTS.ICONS.appendChild(BX.create('SPAN', {
3830			props: {className: 'bx-context-toolbar-button bx-context-toolbar-button-settings' },
3831			children:
3832			[
3833				BX.create('SPAN',
3834				{
3835					props:{className: 'bx-context-toolbar-button-inner'},
3836					children:
3837					[
3838						BX.create('A', {
3839							attrs: {href: btn.URL},
3840							events: {
3841								mouseover: BX.proxy(this.__msover_text, this),
3842								mouseout: BX.proxy(this.__msout_text, this),
3843								mousedown: BX.proxy(this.__msdown_text, this)
3844							},
3845							html: '<span class="bx-context-toolbar-button-icon bx-context-toolbar-settings-icon"></span>'
3846						}),
3847						BX.create('A', {
3848							attrs: {href: 'javascript: void(0)'},
3849							props: {className: 'bx-context-toolbar-button-arrow'},
3850							events: {
3851								mouseover: BX.proxy(this.__msover_arrow, this),
3852								mouseout: BX.proxy(this.__msout_arrow, this),
3853								mousedown: BX.proxy(this.__msdown_arrow, this)
3854							},
3855							html: '<span class="bx-context-toolbar-button-arrow"></span>'
3856						})
3857					]
3858				})
3859			]
3860		}));
3861
3862		this.OPENER = this.ATTACH.firstChild.lastChild;
3863
3864		var opener = this.attachMenu(this.EXTRA_BUTTONS['components2_submenu']['MENU']);
3865
3866		BX.addCustomEvent(opener, 'onOpenerMenuOpen', BX.proxy(this.__menu_open, this));
3867		BX.addCustomEvent(opener, 'onOpenerMenuClose', BX.proxy(this.__menu_close, this));
3868	}
3869
3870	if (btnCount > 1)
3871	{
3872		this.PARTS.ICONS.appendChild(BX.create('span', { props: {className: 'bx-context-toolbar-separator bx-context-toolbar-separator-switcher'}}));
3873
3874		this.ICON_TRANSFORM = this.PARTS.ICONS.appendChild(BX.create('A', {
3875			attrs: {href: 'javascript: void(0)'},
3876			props: {className: 'bx-context-toolbar-switcher'},
3877			events: {
3878				click: BX.delegate(this.__trf_btn_clicked, this)
3879			}
3880		}));
3881	}
3882
3883	if (this.PARAMS.HINT)
3884	{
3885		this.DIV.BXHINT = this.HINT = new BX.CHint({
3886			parent: this.DIV,
3887			hint:this.PARAMS.HINT.TEXT || '',
3888			title: this.PARAMS.HINT.TITLE || '',
3889			hide_timeout: this.timeout/2,
3890			preventHide: false
3891		});
3892	}
3893
3894	BX.addCustomEvent(this, 'onWindowDragFinished', BX.delegate(this.__onMoveFinished, this));
3895	BX.addCustomEvent('onDynamicModeChange', BX.delegate(this.__onDynamicModeChange, this));
3896	BX.addCustomEvent('onTopPanelCollapse', BX.delegate(this.__onPanelCollapse, this));
3897
3898	BX.addCustomEvent('onMenuOpenerMoved', BX.delegate(this.checkPosition, this));
3899	BX.addCustomEvent('onMenuOpenerUnhide', BX.delegate(this.checkPosition, this));
3900
3901	BX.Event.EventEmitter.incrementMaxListeners('onDynamicModeChange');
3902	BX.Event.EventEmitter.incrementMaxListeners('onTopPanelCollapse');
3903	BX.Event.EventEmitter.incrementMaxListeners('onMenuOpenerMoved');
3904	BX.Event.EventEmitter.incrementMaxListeners('onMenuOpenerUnhide');
3905
3906	if (this.OPENERS)
3907	{
3908		for (i=0,len=this.OPENERS.length; i<len; i++)
3909		{
3910			BX.addCustomEvent(this.OPENERS[i], 'onOpenerMenuOpen', BX.proxy(this.__hide_hint, this));
3911		}
3912	}
3913};
3914BX.extend(BX.CMenuOpener, BX.CWindowFloat);
3915
3916BX.CMenuOpener.prototype.setParent = function(new_parent)
3917{
3918	new_parent = BX(new_parent);
3919
3920	if (!new_parent)
3921	{
3922		return;
3923	}
3924
3925	if(new_parent.OPENER && new_parent.OPENER != this)
3926	{
3927		new_parent.OPENER.Close();
3928		new_parent.OPENER.clearHoverHoutEvents();
3929	}
3930
3931	if(this.PARAMS.parent && this.PARAMS.parent != new_parent)
3932	{
3933		this.clearHoverHoutEvents();
3934		this.PARAMS.parent.OPENER = null;
3935	}
3936
3937	this.PARAMS.parent = new_parent;
3938	this.PARAMS.parent.OPENER = this;
3939};
3940
3941BX.CMenuOpener.prototype.setHoverHoutEvents = function(hover, hout)
3942{
3943	if(!this.__opener_events_set)
3944	{
3945		BX.bind(this.Get(), 'mouseover', hover);
3946		BX.bind(this.Get(), 'mouseout', hout);
3947		this.__opener_events_set = true;
3948	}
3949};
3950
3951BX.CMenuOpener.prototype.clearHoverHoutEvents = function()
3952{
3953	if(this.Get())
3954	{
3955		BX.unbindAll(this.Get());
3956		this.__opener_events_set = false;
3957	}
3958};
3959
3960
3961BX.CMenuOpener.prototype.unclosable = true;
3962
3963BX.CMenuOpener.prototype.__check_intersection = function(pos_self, pos_other)
3964{
3965	return !(pos_other.right <= pos_self.left || pos_other.left >= pos_self.right
3966			|| pos_other.bottom <= pos_self.top || pos_other.top >= pos_self.bottom);
3967};
3968
3969
3970BX.CMenuOpener.prototype.__msover_text = function() {
3971	this.bx_hover = true;
3972	if (!this._menu_open)
3973		BX.addClass(this.ATTACH, 'bx-context-toolbar-button-text-hover');
3974};
3975
3976BX.CMenuOpener.prototype.__msout_text = function() {
3977	this.bx_hover = false;
3978	if (!this._menu_open)
3979		BX.removeClass(this.ATTACH, 'bx-context-toolbar-button-text-hover bx-context-toolbar-button-text-active');
3980};
3981
3982BX.CMenuOpener.prototype.__msover_arrow = function() {
3983	this.bx_hover = true;
3984	if (!this._menu_open)
3985		BX.addClass(this.ATTACH, 'bx-context-toolbar-button-arrow-hover');
3986};
3987
3988BX.CMenuOpener.prototype.__msout_arrow = function() {
3989	this.bx_hover = false;
3990	if (!this._menu_open)
3991		BX.removeClass(this.ATTACH, 'bx-context-toolbar-button-arrow-hover bx-context-toolbar-button-arrow-active');
3992};
3993
3994BX.CMenuOpener.prototype.__msdown_text = function() {
3995	this.bx_active = true;
3996	if (!this._menu_open)
3997		BX.addClass(this.ATTACH, 'bx-context-toolbar-button-text-active');
3998};
3999
4000BX.CMenuOpener.prototype.__msdown_arrow = function() {
4001	this.bx_active = true;
4002	if (!this._menu_open)
4003		BX.addClass(this.ATTACH, 'bx-context-toolbar-button-arrow-active');
4004};
4005
4006BX.CMenuOpener.prototype.__menu_close = function() {
4007	this._menu_open = false;
4008	this.bx_active = false;
4009	BX.removeClass(this.ATTACH, 'bx-context-toolbar-button-active bx-context-toolbar-button-text-active bx-context-toolbar-button-arrow-active');
4010	if (!this.bx_hover)
4011	{
4012		BX.removeClass(this.ATTACH, 'bx-context-toolbar-button-hover bx-context-toolbar-button-text-hover bx-context-toolbar-button-arrow-hover');
4013		this.bx_hover = false;
4014	}
4015};
4016
4017BX.CMenuOpener.prototype.__menu_open = function() {
4018	this._menu_open = true;
4019};
4020
4021BX.CMenuOpener.prototype.checkPosition = function()
4022{
4023	if (this.isMenuVisible() || this.DIV.style.display == 'none'
4024		|| this == BX.proxy_context || BX.proxy_context.zIndex > this.zIndex)
4025		return;
4026
4027	this.correctPosition(BX.proxy_context);
4028};
4029
4030BX.CMenuOpener.prototype.correctPosition = function(opener)
4031{
4032	var pos_self = BX.pos(this.DIV), pos_other = BX.pos(opener.Get());
4033	if (this.__check_intersection(pos_self, pos_other))
4034	{
4035		var new_top = pos_other.top - pos_self.height;
4036		if (new_top < 0)
4037			new_top = pos_other.bottom;
4038
4039		this.DIV.style.top = new_top + 'px';
4040
4041		BX.addCustomEvent(opener, 'onMenuOpenerHide', BX.proxy(this.restorePosition, this));
4042		BX.onCustomEvent(this, 'onMenuOpenerMoved');
4043	}
4044};
4045
4046BX.CMenuOpener.prototype.restorePosition = function()
4047{
4048	if (!this.MOUSEOVER && !this.isMenuVisible())
4049	{
4050		if (this.originalPos)
4051			this.DIV.style.top = this.originalPos.top + 'px';
4052
4053		BX.removeCustomEvent(BX.proxy_context, 'onMenuOpenerHide', BX.proxy(this.restorePosition, this));
4054		if (this.restore_pos_timeout) clearTimeout(this.restore_pos_timeout);
4055	}
4056	else
4057	{
4058		this.restore_pos_timeout = setTimeout(BX.proxy(this.restorePosition, this), this.timeout);
4059	}
4060};
4061
4062
4063BX.CMenuOpener.prototype.Show = function()
4064{
4065	BX.CMenuOpener.superclass.Show.apply(this, arguments);
4066
4067	this.SetDraggable(this.PARTS.INNER.firstChild);
4068
4069	this.DIV.style.width = 'auto';
4070	this.DIV.style.height = 'auto';
4071
4072	if (!this.PARAMS.pin)
4073	{
4074		this.DIV.style.left = '-1000px';
4075		this.DIV.style.top = '-1000px';
4076
4077		this.Hide();
4078	}
4079	else
4080	{
4081		this.bPosAdjusted = true;
4082		this.bMoved = true;
4083
4084		if (this.PARAMS.top) this.DIV.style.top = this.PARAMS.top + 'px';
4085		if (this.PARAMS.left) this.DIV.style.left = this.PARAMS.left + 'px';
4086
4087		this.DIV.style.display = (!BX.admin.dynamic_mode || BX.admin.dynamic_mode_show_borders) ? 'block' : 'none';
4088
4089		if (this.DIV.style.display == 'block')
4090		{
4091			setTimeout(BX.delegate(function() {BX.onCustomEvent(this, 'onMenuOpenerUnhide')}, this), 50);
4092		}
4093	}
4094};
4095
4096BX.CMenuOpener.prototype.executeDefaultAction = function()
4097{
4098	if (this.defaultAction)
4099	{
4100		if (BX.type.isFunction(this.defaultAction))
4101			this.defaultAction();
4102		else if(BX.type.isString(this.defaultAction))
4103			BX.evalGlobal(this.defaultAction);
4104	}
4105};
4106
4107BX.CMenuOpener.prototype.__onDynamicModeChange = function(val)
4108{
4109	this.DIV.style.display = val ? 'block' : 'none';
4110};
4111
4112BX.CMenuOpener.prototype.__onPanelCollapse = function(bCollapsed, dy)
4113{
4114	this.DIV.style.top = (parseInt(this.DIV.style.top) + dy) + 'px';
4115	if (this.PARAMS.pin)
4116	{
4117		this.__savePosition();
4118	}
4119};
4120
4121BX.CMenuOpener.prototype.__onMoveFinished = function()
4122{
4123	BX.onCustomEvent(this, 'onMenuOpenerMoved');
4124
4125	this.bMoved = true;
4126
4127	if (this.PARAMS.pin)
4128		this.__savePosition();
4129};
4130
4131BX.CMenuOpener.prototype.__savePosition = function()
4132{
4133	var arOpts = {};
4134
4135	arOpts.pin = this.PARAMS.pin;
4136	if (!this.PARAMS.pin)
4137	{
4138		arOpts.top = false; arOpts.left = false; arOpts.transform = false;
4139	}
4140	else
4141	{
4142		arOpts.transform = this.PARAMS.transform;
4143		if (this.bMoved)
4144		{
4145			arOpts.left = parseInt(this.DIV.style.left);
4146			arOpts.top = parseInt(this.DIV.style.top);
4147		}
4148	}
4149
4150	BX.WindowManager.saveWindowOptions(this.PARAMS.component_id, arOpts);
4151};
4152
4153BX.CMenuOpener.prototype.__pin_btn_clicked = function() {this.Pin()};
4154BX.CMenuOpener.prototype.Pin = function(val)
4155{
4156	if (null == val)
4157		this.PARAMS.pin = !this.PARAMS.pin;
4158	else
4159		this.PARAMS.pin = !!val;
4160
4161	this.PARTS.ICON_PIN.className = (this.PARAMS.pin ? 'bx-context-toolbar-pin-fixed' : 'bx-context-toolbar-pin');
4162
4163	this.__savePosition();
4164};
4165
4166BX.CMenuOpener.prototype.__trf_btn_clicked = function() {this.Transform()};
4167BX.CMenuOpener.prototype.Transform = function(val)
4168{
4169	var pos = {};
4170
4171	if (null == val)
4172		this.PARAMS.transform = !this.PARAMS.transform;
4173	else
4174		this.PARAMS.transform = !!val;
4175
4176	if (this.bMoved)
4177	{
4178		pos = BX.pos(this.DIV);
4179	}
4180
4181	if (this.PARAMS.transform)
4182		BX.addClass(this.DIV.firstChild, 'bx-context-toolbar-vertical-mode');
4183	else
4184		BX.removeClass(this.DIV.firstChild, 'bx-context-toolbar-vertical-mode');
4185
4186	if (!this.bMoved)
4187	{
4188		this.adjustPos();
4189	}
4190	else
4191	{
4192		this.DIV.style.left = (pos.right - this.DIV.offsetWidth - (BX.browser.IsIE() && !BX.browser.IsDoctype() ? 2 : 0)) + 'px';
4193	}
4194
4195	this.__savePosition();
4196};
4197
4198BX.CMenuOpener.prototype.adjustToNodeGetPos = function()
4199{
4200	var pos = BX.pos(this.PARAMS.parent/*, true*/);
4201
4202	var scrollSize = BX.GetWindowScrollSize();
4203	var floatWidth = this.DIV.offsetWidth;
4204
4205	pos.left -= BX.admin.__border_dx;
4206	pos.top -= BX.admin.__border_dx;
4207
4208	if (true || !this.PARAMS.transform)
4209	{
4210		pos.top -= 45;
4211	}
4212
4213	if (pos.left > scrollSize.scrollWidth - floatWidth)
4214	{
4215		pos.left = scrollSize.scrollWidth - floatWidth;
4216	}
4217
4218	return pos;
4219};
4220
4221BX.CMenuOpener.prototype.addItem = function(item)
4222{
4223	if (item.TYPE)
4224	{
4225		this.EXTRA_BUTTONS[item.TYPE] = item;
4226		return null;
4227	}
4228	else
4229	{
4230		var q = new BX.CMenuOpenerItem(item);
4231		if (null == this.defaultAction)
4232		{
4233			if (q.item.ONCLICK)
4234			{
4235				this.defaultAction = item.ONCLICK;
4236			}
4237			else if (q.item.MENU)
4238			{
4239				this.defaultAction = BX.delegate(function() {this.Open()}, q.item.OPENER);
4240			}
4241
4242			this.defaultActionTitle = item.TITLE || item.TEXT;
4243
4244			BX.addClass(q.Get(), 'bx-content-toolbar-default');
4245		}
4246		if (q.item.OPENER) this.OPENERS[this.OPENERS.length] = q.item.OPENER;
4247		return q.Get();
4248	}
4249};
4250
4251BX.CMenuOpener.prototype.attachMenu = function(menu)
4252{
4253	var opener = new BX.COpener({
4254		'DIV':  this.OPENER,
4255		'ATTACH': this.ATTACH,
4256		'MENU': menu,
4257		'TYPE': 'click'
4258	});
4259
4260	this.OPENERS[this.OPENERS.length] = opener;
4261
4262	return opener;
4263};
4264
4265BX.CMenuOpener.prototype.__hide_hint = function()
4266{
4267	if (this.HINT) this.HINT.__hide_immediately();
4268};
4269
4270BX.CMenuOpener.prototype.isMenuVisible = function()
4271{
4272	for (var i=0,len=this.OPENERS.length; i<len; i++)
4273	{
4274		if (this.OPENERS[i].isMenuVisible())
4275			return true;
4276	}
4277
4278	return false;
4279};
4280
4281BX.CMenuOpener.prototype.Hide = function()
4282{
4283	if (!this.PARAMS.pin)
4284	{
4285		this.DIV.style.display = 'none';
4286		BX.onCustomEvent(this, 'onMenuOpenerHide');
4287	}
4288};
4289BX.CMenuOpener.prototype.UnHide = function()
4290{
4291	this.DIV.style.display = 'block';
4292	if (!this.bPosAdjusted && !this.PARAMS.pin)
4293	{
4294		this.adjustPos();
4295		this.bPosAdjusted = true;
4296	}
4297
4298	if (null == this.originalPos && !this.bMoved)
4299	{
4300		this.originalPos = BX.pos(this.DIV);
4301	}
4302
4303	BX.onCustomEvent(this, 'onMenuOpenerUnhide');
4304};
4305
4306BX.CMenuOpenerItem = function(item)
4307{
4308	this.item = item;
4309
4310	if (this.item.ACTION && !this.item.ONCLICK)
4311	{
4312		this.item.ONCLICK = this.item.ACTION;
4313	}
4314
4315	this.DIV = BX.create('SPAN');
4316	this.DIV.appendChild(BX.create('SPAN', {props: {className: 'bx-context-toolbar-button-underlay'}}));
4317
4318	this.WRAPPER = this.DIV.appendChild(BX.create('SPAN', {
4319		props: {className: 'bx-context-toolbar-button-wrapper'},
4320		children: [
4321			BX.create('SPAN', {
4322				props: {className: 'bx-context-toolbar-button', title: item.TITLE},
4323				children: [
4324					BX.create('SPAN', {
4325						props: {className: 'bx-context-toolbar-button-inner'}
4326					})
4327				]
4328			})
4329		]
4330	}));
4331
4332	var btn_icon = BX.create('SPAN', {
4333		props: {className: 'bx-context-toolbar-button-icon' + (this.item.ICON || this.item.ICONCLASS ? ' ' + (this.item.ICON || this.item.ICONCLASS) : '')},
4334		attrs: (
4335				!(this.item.ICON || this.item.ICONCLASS)
4336				&&
4337				(this.item.SRC || this.item.IMAGE)
4338			)
4339			? {
4340				style: 'background: scroll transparent url(' + (this.item.SRC || this.item.IMAGE) + ') no-repeat center center !important;'
4341			}
4342			: {}
4343	}), btn_text = BX.create('SPAN', {
4344		props: {className: 'bx-context-toolbar-button-text'},
4345		text: this.item.TEXT
4346	});
4347
4348	if (this.item.ACTION && !this.item.ONCLICK)
4349	{
4350		this.item.ONCLICK = this.item.ACTION;
4351	}
4352
4353	this.bHasMenu = !!this.item.MENU;
4354	this.bHasAction = !!this.item.ONCLICK;
4355
4356	if (this.bHasAction)
4357	{
4358		this.LINK = this.WRAPPER.firstChild.firstChild.appendChild(BX.create('A', {
4359			attrs: {
4360				'href': 'javascript: void(0)'
4361			},
4362			events: {
4363				mouseover: this.bHasMenu ? BX.proxy(this.__msover_text, this) : BX.proxy(this.__msover, this),
4364				mouseout: this.bHasMenu ? BX.proxy(this.__msout_text, this) : BX.proxy(this.__msout, this),
4365				mousedown: this.bHasMenu ? BX.proxy(this.__msdown_text, this) : BX.proxy(this.__msdown, this)
4366			},
4367			children: [btn_icon, btn_text]
4368		}));
4369
4370		if (this.bHasMenu)
4371		{
4372			this.LINK_MENU = this.WRAPPER.firstChild.firstChild.appendChild(BX.create('A', {
4373				props: {className: 'bx-context-toolbar-button-arrow'},
4374				attrs: {
4375					'href': 'javascript: void(0)'
4376				},
4377				events: {
4378					mouseover: BX.proxy(this.__msover_arrow, this),
4379					mouseout: BX.proxy(this.__msout_arrow, this),
4380					mousedown: BX.proxy(this.__msdown_arrow, this)
4381				},
4382				children: [
4383					BX.create('SPAN', {props: {className: 'bx-context-toolbar-button-arrow'}})
4384				]
4385			}));
4386		}
4387
4388	}
4389	else if (this.bHasMenu)
4390	{
4391		this.item.ONCLICK = null;
4392
4393		this.LINK = this.LINK_MENU = this.WRAPPER.firstChild.firstChild.appendChild(BX.create('A', {
4394			attrs: {
4395				'href': 'javascript: void(0)'
4396			},
4397			events: {
4398				mouseover: BX.proxy(this.__msover, this),
4399				mouseout: BX.proxy(this.__msout, this),
4400				mousedown: BX.proxy(this.__msdown, this)
4401			},
4402			children: [
4403				btn_icon,
4404				btn_text
4405			]
4406		}));
4407
4408		this.LINK.appendChild(BX.create('SPAN', {props: {className: 'bx-context-toolbar-single-button-arrow'}}));
4409
4410	}
4411
4412	if (this.bHasMenu)
4413	{
4414		this.item.SUBMENU = new BX.CMenu({
4415			ATTACH_MODE:'bottom',
4416			ITEMS:this.item['MENU'],
4417			//PARENT_MENU:this.parentMenu,
4418			parent: this.LINK_MENU,
4419			parent_attach: this.WRAPPER.firstChild
4420		});
4421
4422		this.item.OPENER = new BX.COpener({
4423			DIV: this.LINK_MENU,
4424			TYPE: 'click',
4425			MENU: this.item.SUBMENU
4426		});
4427
4428		BX.addCustomEvent(this.item.OPENER, 'onOpenerMenuOpen', BX.proxy(this.__menu_open, this));
4429		BX.addCustomEvent(this.item.OPENER, 'onOpenerMenuClose', BX.proxy(this.__menu_close, this));
4430	}
4431
4432	if (this.bHasAction)
4433	{
4434		BX.bind(this.LINK, 'click', BX.delegate(this.__click, this));
4435	}
4436};
4437
4438BX.CMenuOpenerItem.prototype.Get = function() {return this.DIV;};
4439BX.CMenuOpenerItem.prototype.__msover = function() {
4440	this.bx_hover = true;
4441	if (!this._menu_open)
4442		BX.addClass(this.LINK.parentNode.parentNode, 'bx-context-toolbar-button-hover');
4443};
4444BX.CMenuOpenerItem.prototype.__msout = function() {
4445	this.bx_hover = false;
4446	if (!this._menu_open)
4447		BX.removeClass(this.LINK.parentNode.parentNode, 'bx-context-toolbar-button-hover bx-context-toolbar-button-active');
4448};
4449BX.CMenuOpenerItem.prototype.__msover_text = function() {
4450	this.bx_hover = true;
4451	if (!this._menu_open)
4452		BX.addClass(this.LINK.parentNode.parentNode, 'bx-context-toolbar-button-text-hover');
4453};
4454BX.CMenuOpenerItem.prototype.__msout_text = function() {
4455	this.bx_hover = false;
4456	if (!this._menu_open)
4457		BX.removeClass(this.LINK.parentNode.parentNode, 'bx-context-toolbar-button-text-hover bx-context-toolbar-button-text-active');
4458};
4459BX.CMenuOpenerItem.prototype.__msover_arrow = function() {
4460	this.bx_hover = true;
4461	if (!this._menu_open)
4462		BX.addClass(this.LINK.parentNode.parentNode, 'bx-context-toolbar-button-arrow-hover');
4463};
4464BX.CMenuOpenerItem.prototype.__msout_arrow = function() {
4465	this.bx_hover = false;
4466	if (!this._menu_open)
4467		BX.removeClass(this.LINK.parentNode.parentNode, 'bx-context-toolbar-button-arrow-hover bx-context-toolbar-button-arrow-active');
4468};
4469BX.CMenuOpenerItem.prototype.__msdown = function() {
4470	this.bx_active = true;
4471	if (!this._menu_open)
4472		BX.addClass(this.LINK.parentNode.parentNode, 'bx-context-toolbar-button-active');
4473};
4474BX.CMenuOpenerItem.prototype.__msdown_text = function() {
4475	this.bx_active = true;
4476	if (!this._menu_open)
4477		BX.addClass(this.LINK.parentNode.parentNode, 'bx-context-toolbar-button-text-active');
4478};
4479BX.CMenuOpenerItem.prototype.__msdown_arrow = function() {
4480	this.bx_active = true;
4481	if (!this._menu_open)
4482		BX.addClass(this.LINK.parentNode.parentNode, 'bx-context-toolbar-button-arrow-active');
4483};
4484BX.CMenuOpenerItem.prototype.__menu_close = function() {
4485
4486	this._menu_open = false;
4487	this.bx_active = false;
4488	BX.removeClass(this.LINK.parentNode.parentNode, 'bx-context-toolbar-button-active bx-context-toolbar-button-text-active bx-context-toolbar-button-arrow-active');
4489	if (!this.bx_hover)
4490	{
4491		BX.removeClass(this.LINK.parentNode.parentNode, 'bx-context-toolbar-button-hover bx-context-toolbar-button-text-hover bx-context-toolbar-button-arrow-hover');
4492		this.bx_hover = false;
4493	}
4494};
4495BX.CMenuOpenerItem.prototype.__menu_open = function() {
4496	this._menu_open = true;
4497};
4498
4499BX.CMenuOpenerItem.prototype.__click = function() {BX.evalGlobal(this.item.ONCLICK)};
4500
4501/* global page opener class */
4502BX.CPageOpener = function(arParams)
4503{
4504	//if (null == arParams.pin) arParams.pin = true;
4505	BX.CPageOpener.superclass.constructor.apply(this, arguments);
4506
4507	this.timeout = 505;
4508
4509	window.PAGE_EDIT_CONTROL = this;
4510};
4511BX.extend(BX.CPageOpener, BX.CMenuOpener);
4512
4513BX.CPageOpener.prototype.checkPosition = function()
4514{
4515	if (/*this.isMenuVisible() || this.DIV.style.display == 'none' || */this == BX.proxy_context)
4516		return;
4517
4518	this.correctPosition(BX.proxy_context);
4519};
4520
4521BX.CPageOpener.prototype.correctPosition = function(opener)
4522{
4523	if (this.bPosCorrected) return;
4524	var pos_self;
4525	if (this.DIV.style.display == 'none')
4526	{
4527		pos_self = this.adjustToNodeGetPos();
4528		pos_self.bottom = pos_self.top + 30;
4529		pos_self.right = pos_self.left + 300;
4530	}
4531	else
4532	{
4533		pos_self = BX.pos(this.DIV);
4534	}
4535
4536	var pos_other = BX.pos(opener.Get());
4537	if (this.__check_intersection(pos_self, pos_other))
4538	{
4539		this.DIV.style.display = 'none';
4540
4541		var handler = BX.proxy(this.restorePosition, this);
4542
4543		BX.removeCustomEvent(opener, 'onMenuOpenerHide', handler);
4544		BX.addCustomEvent(opener, 'onMenuOpenerHide', handler);
4545
4546		this.bPosCorrected = true;
4547	}
4548};
4549
4550BX.CPageOpener.prototype.restorePosition = function()
4551{
4552	if (BX.proxy_context && BX.proxy_context.Get().style.display == 'none')
4553	{
4554		this.bPosCorrected = false;
4555
4556		if (this.PARAMS.parent.bx_over || this.PARAMS.pin)
4557			this.UnHide();
4558
4559		BX.removeCustomEvent('onMenuOpenerHide', BX.proxy(this.restorePosition, this));
4560	}
4561};
4562
4563BX.CPageOpener.prototype.UnHide = function()
4564{
4565	if (!this.bPosCorrected)
4566		BX.CPageOpener.superclass.UnHide.apply(this, arguments);
4567};
4568
4569BX.CPageOpener.prototype.Remove = function()
4570{
4571	BX.admin.removeComponentBorder(this.PARAMS.parent);
4572	BX.userOptions.save('global', 'settings', 'page_edit_control_enable', 'N');
4573	this.DIV.style.display = 'none';
4574};
4575
4576/******* HINT ***************/
4577BX.CHintSimple = function()
4578{
4579	BX.CHintSimple.superclass.constructor.apply(this, arguments);
4580};
4581BX.extend(BX.CHintSimple, BX.CHint);
4582
4583BX.CHintSimple.prototype.Init = function()
4584{
4585	this.DIV = document.body.appendChild(BX.create('DIV', {props: {className: 'bx-tooltip-simple'}, style: {display: 'none'}, children: [(this.CONTENT = BX.create('DIV'))]}));
4586
4587	BX.ZIndexManager.register(this.DIV);
4588
4589	if (this.HINT_TITLE)
4590		this.CONTENT.appendChild(BX.create('B', {text: this.HINT_TITLE}));
4591
4592	if (this.HINT)
4593		this.CONTENT_TEXT = this.CONTENT.appendChild(BX.create('DIV')).appendChild(BX.create('SPAN', {html: this.HINT}));
4594
4595	if (this.PARAMS.preventHide)
4596	{
4597		BX.bind(this.DIV, 'mouseout', BX.proxy(this.Hide, this));
4598		BX.bind(this.DIV, 'mouseover', BX.proxy(this.Show, this));
4599	}
4600
4601	this.bInited = true;
4602};
4603
4604/*************************** admin informer **********************************/
4605BX.adminInformer = {
4606
4607	itemsShow: 3,
4608
4609	Init: function (itemsShow)
4610	{
4611		if(itemsShow)
4612			BX.adminInformer.itemsShow = itemsShow;
4613
4614		var informer = BX("admin-informer");
4615
4616		if(informer)
4617		{
4618			document.body.appendChild(informer);
4619			BX.ZIndexManager.register(informer);
4620		}
4621
4622		BX.addCustomEvent("onTopPanelCollapse", BX.proxy(BX.adminInformer.Close, BX.adminInformer));
4623	},
4624
4625	Toggle: function(notifyBlock)
4626	{
4627		var informer = BX("admin-informer");
4628
4629		if(!informer)
4630			return false;
4631
4632		var pos = BX.pos(notifyBlock);
4633
4634		informer.style.top = (parseInt(pos.top)+parseInt(pos.height)+7)+'px';
4635		informer.style.left = pos.left+'px';
4636
4637		if(!BX.hasClass(informer, "adm-informer-active"))
4638			BX.adminInformer.Show(informer);
4639		else
4640			BX.adminInformer.Hide(informer);
4641
4642		return false;
4643	},
4644
4645	Close: function()
4646	{
4647		BX.adminInformer.Hide(BX("admin-informer"));
4648	},
4649
4650	OnInnerClick: function(event)
4651	{
4652		var target = event.target || event.srcElement;
4653
4654		if(target.nodeName.toLowerCase() != 'a' || BX.hasClass(target,"adm-informer-footer"))
4655		{
4656			return BX.PreventDefault(event);
4657		}
4658
4659		return true;
4660	},
4661
4662	ToggleExtra : function()
4663	{
4664		var footerLink = BX("adm-informer-footer");
4665
4666		if (BX.hasClass(footerLink, "adm-informer-footer-collapsed"))
4667			this.ShowAll();
4668		else
4669			this.HideExtra();
4670
4671		return false;
4672	},
4673
4674	ShowAll: function()
4675	{
4676		var informer = BX("admin-informer");
4677		for(var i=0; i<informer.children.length; i++)
4678
4679			if(BX.hasClass(informer.children[i], "adm-informer-item") && informer.children[i].style.display == "none") {
4680				informer.children[i].style.display = "block";
4681			}
4682
4683		var footerLink = BX("adm-informer-footer");
4684
4685		if(footerLink.textContent !== undefined)
4686			footerLink.textContent = BX.message('JSADM_AI_HIDE_EXTRA');
4687		else
4688			footerLink.innerText = BX.message('JSADM_AI_HIDE_EXTRA');
4689
4690		BX.removeClass(footerLink, "adm-informer-footer-collapsed");
4691
4692		return false;
4693	},
4694
4695	HideExtra: function()
4696	{
4697		var informer = BX("admin-informer");
4698		var hided = 0;
4699
4700		for(var i=BX.adminInformer.itemsShow+1; i<informer.children.length; i++)
4701		{
4702			if (BX.hasClass(informer.children[i], "adm-informer-item") && informer.children[i].style.display == "block") {
4703				informer.children[i].style.display = "none";
4704				hided++;
4705			}
4706		}
4707
4708		var footerLink = BX("adm-informer-footer");
4709
4710		var linkText = BX.message('JSADM_AI_ALL_NOTIF')+" ("+(BX.adminInformer.itemsShow+parseInt(hided))+")";
4711
4712		if(footerLink.textContent !== undefined)
4713			footerLink.textContent = linkText;
4714		else
4715			footerLink.innerText = linkText;
4716
4717		BX.addClass(footerLink, "adm-informer-footer-collapsed");
4718
4719		return false;
4720	},
4721
4722	Show: function(informer)
4723	{
4724		var notifButton = BX("adm-header-notif-block");
4725		if (notifButton)
4726			BX.addClass(notifButton, "adm-header-notif-block-active");
4727
4728		BX.onCustomEvent(informer, 'onBeforeAdminInformerShow');
4729		setTimeout(
4730			BX.proxy(function() {
4731					BX.bind(document, "click", BX.proxy(BX.adminInformer.Close, BX.adminInformer));
4732				},
4733				BX.adminInformer
4734			),0
4735		);
4736		BX.addClass(informer, "adm-informer-active");
4737
4738		BX.ZIndexManager.bringToFront(informer);
4739
4740		setTimeout(function() {BX.addClass(informer, "adm-informer-animate");},0);
4741	},
4742
4743	Hide: function(informer)
4744	{
4745		var notifButton = BX("adm-header-notif-block");
4746		if (notifButton)
4747			BX.removeClass(notifButton, "adm-header-notif-block-active");
4748
4749		BX.unbind(document, "click", BX.proxy(BX.adminInformer.Close, BX.adminInformer));
4750
4751		BX.removeClass(informer, "adm-informer-animate");
4752
4753		if (this.IsAnimationSupported())
4754			setTimeout(function() {BX.removeClass(informer, "adm-informer-active");}, 300);
4755		else
4756			BX.removeClass(informer, "adm-informer-active");
4757
4758		BX.onCustomEvent(informer, 'onAdminInformerHide');
4759		//setTimeout(function() {BX.adminInformer.HideExtra();},500);
4760	},
4761
4762	IsAnimationSupported : function()
4763	{
4764		var d = document.body || document.documentElement;
4765		if (typeof(d.style.transition) == "string")
4766			return true;
4767		else if (typeof(d.style.MozTransition) == "string")
4768			return true;
4769		else if (typeof(d.style.OTransition) == "string")
4770			return true;
4771		else if (typeof(d.style.WebkitTransition) == "string")
4772			return true;
4773		else if (typeof(d.style.msTransition) == "string")
4774			return true;
4775
4776		return false;
4777	},
4778
4779
4780	SetItemHtml: function(itemIdx, html)
4781	{
4782		var itemHtmlDiv = BX("adm-informer-item-html-"+itemIdx);
4783
4784		if(!itemHtmlDiv)
4785			return false;
4786
4787		itemHtmlDiv.innerHTML = html;
4788
4789		return true;
4790	},
4791
4792	SetItemFooter: function(itemIdx, html)
4793	{
4794		var itemFooterDiv = BX("adm-informer-item-footer-"+itemIdx);
4795
4796		if(!itemFooterDiv)
4797			return false;
4798
4799		itemFooterDiv.innerHTML = html;
4800
4801		if(html)
4802			itemFooterDiv.style.display = "block";
4803		else
4804			itemFooterDiv.style.display = "none";
4805
4806		return true;
4807	}
4808
4809};
4810
4811}
4811)(window);
4812
4813
4814/* End */
4815;
4816; /* Start:"a:4:{s:4:"full";s:49:"/bitrix/js/main/date/main.date.js?174824846962683";s:6:"source";s:33:"/bitrix/js/main/date/main.date.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
4817/* eslint-disable */
4818this.BX = this.BX || {};
4819(function (exports,main_core) {
4820	'use strict';
4821
4822	function convertBitrixFormat(format) {
4823	  if (!main_core.Type.isStringFilled(format)) {
4824	    return '';
4825	  }
4826	  return format.replace('YYYY', 'Y') // 1999
4827	  .replace('MMMM', 'F') // January - December
4828	  .replace('MM', 'm') // 01 - 12
4829	  .replace('M', 'M') // Jan - Dec
4830	  .replace('DD', 'd') // 01 - 31
4831	  .replace('G', 'g') //  1 - 12
4832	  .replace(/GG/i, 'G') //  0 - 23
4833	  .replace('H', 'h') // 01 - 12
4834	  .replace(/HH/i, 'H') // 00 - 24
4835	  .replace('MI', 'i') // 00 - 59
4836	  .replace('SS', 's') // 00 - 59
4837	  .replace('TT', 'A') // AM - PM
4838	  .replace('T', 'a'); // am - pm
4839	}
4840
4841	const formatsCache = new main_core.Cache.MemoryCache();
4842
4843	/**
4844	 * Returns culture-specific datetime format by code.
4845	 * The full list with examples can be found in config.php of this extension in ['settings']['formats'].
4846	 * All formats are compatible with this.format() without any additional transformations.
4847	 *
4848	 * @param code
4849	 * @returns {string|null}
4850	 */
4851	function getFormat(code) {
4852	  return formatsCache.remember(`main.date.format.${code}`, () => {
4853	    let format = main_core.Extension.getSettings('main.date').get(`formats.${code}`);
4854	    if (main_core.Type.isStringFilled(format) && (code === 'FORMAT_DATE' || code === 'FORMAT_DATETIME')) {
4855	      format = convertBitrixFormat(format);
4856	    }
4857	    return format;
4858	  });
4859	}
4860
4861	/**
4862	 * @memberOf BX.Main
4863	 * @alias Date
4864	 */
4865	let DateTimeFormat = /*#__PURE__*/function () {
4866	  function DateTimeFormat() {
4867	    babelHelpers.classCallCheck(this, DateTimeFormat);
4868	  }
4869	  babelHelpers.createClass(DateTimeFormat, null, [{
4870	    key: "isAmPmMode",
4871	    value: function isAmPmMode(returnConst) {
4872	      if (returnConst === true) {
4873	        return this._getMessage('AMPM_MODE');
4874	      }
4875	      return this._getMessage('AMPM_MODE') !== false;
4876	    }
4877	  }, {
4878	    key: "convertToUTC",
4879	    value: function convertToUTC(date) {
4880	      if (!main_core.Type.isDate(date)) {
4881	        return null;
4882	      }
4883	      return new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds(), date.getMilliseconds()));
4884	    }
4885	    /**
4886	     * Function creates and returns Javascript Date() object from server timestamp regardless of local browser (system) timezone.
4887	     * For example can be used to convert timestamp from some exact date on server to the JS Date object with the same value.
4888	     *
4889	     * @param timestamp - timestamp in seconds
4890	     * @returns {Date}
4891	     */
4892	  }, {
4893	    key: "getNewDate",
4894	    value: function getNewDate(timestamp) {
4895	      return new Date(this.getBrowserTimestamp(timestamp));
4896	    }
4897	    /**
4898	     * Function transforms server timestamp (in sec) to javascript timestamp (calculated depend on local browser timezone offset). Returns timestamp in milliseconds.
4899	     * Also see BX.Main.Date.getNewDate description.
4900	     *
4901	     * @param timestamp - timestamp in seconds
4902	     * @returns {number}
4903	     */
4904	  }, {
4905	    key: "getBrowserTimestamp",
4906	    value: function getBrowserTimestamp(timestamp) {
4907	      timestamp = parseInt(timestamp, 10);
4908	      const browserOffset = new Date(timestamp * 1000).getTimezoneOffset() * 60;
4909	      return (parseInt(timestamp, 10) + parseInt(this._getMessage('SERVER_TZ_OFFSET')) + browserOffset) * 1000;
4910	    }
4911	    /**
4912	     * Function transforms local browser timestamp (in ms) to server timestamp (calculated depend on local browser timezone offset). Returns timestamp in seconds.
4913	     *
4914	     * @param timestamp - timestamp in milliseconds
4915	     * @returns {number}
4916	     */
4917	  }, {
4918	    key: "getServerTimestamp",
4919	    value: function getServerTimestamp(timestamp) {
4920	      timestamp = parseInt(timestamp, 10);
4921	      const browserOffset = new Date(timestamp).getTimezoneOffset() * 60;
4922	      return Math.round(timestamp / 1000 - (parseInt(this._getMessage('SERVER_TZ_OFFSET'), 10) + parseInt(browserOffset, 10)));
4923	    }
4924	  }, {
4925	    key: "formatLastActivityDate",
4926	    value: function formatLastActivityDate(timestamp, now, utc) {
4927	      const ampm = this.isAmPmMode(true);
4928	      const timeFormat = ampm === this.AM_PM_MODE.LOWER ? 'g:i a' : ampm === this.AM_PM_MODE.UPPER ? 'g:i A' : 'H:i';
4929	      const format = [['tomorrow', '#01#' + timeFormat], ['now', '#02#'], ['todayFuture', '#03#' + timeFormat], ['yesterday', '#04#' + timeFormat], ['-', this.convertBitrixFormat(this._getMessage('FORMAT_DATETIME')).replace(/:s/g, '')], ['
4929s60', 'sago'], ['i60', 'iago'], ['H5', 'Hago'], ['H24', '#03#' + timeFormat], ['d31', 'dago'], ['m12>1', 'mago'], ['m12>0', 'dago'], ['', '#05#']];
4930	      let formattedDate = this.format(format, timestamp, now, utc);
4931	      let match = null;
4932	      if ((match = /^#(\d+)#(.*)/.exec(formattedDate)) != null) {
4933	        switch (match[1]) {
4934	          case '01':
4935	            formattedDate = this._getMessage('FD_LAST_SEEN_TOMORROW').replace('#TIME#', match[2]);
4936	            break;
4937	          case '02':
4938	            formattedDate = this._getMessage('FD_LAST_SEEN_NOW');
4939	            break;
4940	          case '03':
4941	            formattedDate = this._getMessage('FD_LAST_SEEN_TODAY').replace('#TIME#', match[2]);
4942	            break;
4943	          case '04':
4944	            formattedDate = this._getMessage('FD_LAST_SEEN_YESTERDAY').replace('#TIME#', match[2]);
4945	            break;
4946	          case '05':
4947	            formattedDate = this._getMessage('FD_LAST_SEEN_MORE_YEAR');
4948	            break;
4949	          default:
4950	            formattedDate = match[2];
4951	            break;
4952	        }
4953	      }
4954	      return formattedDate;
4955	    }
4956	    /**
4957	     * The method is designed to replace the localization storage on sites without Bitrix Framework.
4958	     * It gets overloaded with custom implementation:
4959	     *
4960	     * const CustomDate = Object.create(BX.Main.Date);
4961	     * CustomDate._getMessage = () => ...new implementation...;
4962	     *
4963	     * This class should get messages only via this method.
4964	     * Otherwise, the class won't work on sites without Bitrix Framework.
4965	     *
4966	     * @param message
4967	     * @returns {*}
4968	     * @private
4969	     */
4970	  }, {
4971	    key: "_getMessage",
4972	    value: function _getMessage(message) {
4973	      return main_core.Loc.getMessage(message);
4974	    }
4975	    /**
4976	     * The method used to parse date from string by given format.
4977	     *
4978	     * @param {string} str - date in given format
4979	     * @param {boolean} isUTC - is date in UTC
4980	     * @param {string} formatDate - format of the date without time
4981	     * @param {string} formatDatetime - format of the date with time
4982	     * @returns {Date|null} - returns Date object if string was parsed or null
4983	     */
4984	  }, {
4985	    key: "parse",
4986	    value: function parse(str, isUTC, formatDate, formatDatetime) {
4987	      if (main_core.Type.isStringFilled(str)) {
4988	        if (!formatDate) {
4989	          formatDate = this._getMessage('FORMAT_DATE');
4990	        }
4991	        if (!formatDatetime) {
4992	          formatDatetime = this._getMessage('FORMAT_DATETIME');
4993	        }
4994	        let regMonths = '';
4995	        for (let i = 1; i <= 12; i++) {
4996	          regMonths = regMonths + '|' + this._getMessage('MON_' + i);
4997	        }
4998	        const expr = new RegExp('([0-9]+|[a-z]+' + regMonths + ')', 'ig');
4999	        const aDate = str.match(expr);
5000	        let aFormat = formatDate.match(/(DD|MI|MMMM|MM|M|YYYY)/ig);
5001	        const aDateArgs = [];
5002	        const aFormatArgs = [];
5003	        const aResult = {};
5004	        if (!aDate) {
5005	          return null;
5006	        }
5007	        if (aDate.length > aFormat.length) {
5008	          aFormat = formatDatetime.match(/(DD|MI|MMMM|MM|M|YYYY|HH|H|SS|TT|T|GG|G)/ig);
5009	        }
5010	        for (let i = 0, cnt = aDate.length; i < cnt; i++) {
5011	          if (aDate[i].trim() !== '') {
5012	            aDateArgs[aDateArgs.length] = aDate[i];
5013	          }
5014	        }
5015	        for (let i = 0, cnt = aFormat.length; i < cnt; i++) {
5016	          if (aFormat[i].trim() !== '') {
5017	            aFormatArgs[aFormatArgs.length] = aFormat[i];
5018	          }
5019	        }
5020	        let m = aFormatArgs.findIndex(item => item === 'MMMM');
5021	        if (m > 0) {
5022	          aDateArgs[m] = this.getMonthIndex(aDateArgs[m]);
5023	          aFormatArgs[m] = 'MM';
5024	        } else {
5025	          m = aFormatArgs.findIndex(item => item === 'M');
5026	          if (m > 0) {
5027	            aDateArgs[m] = this.getMonthIndex(aDateArgs[m]);
5028	            aFormatArgs[m] = 'MM';
5029	          }
5030	        }
5031	        for (let i = 0, cnt = aFormatArgs.length; i < cnt; i++) {
5032	          const k = aFormatArgs[i].toUpperCase();
5033	          aResult[k] = k === 'T' || k === 'TT' ? aDateArgs[i] : parseInt(aDateArgs[i], 10);
5034	        }
5035	        if (aResult['DD'] > 0 && aResult['MM'] > 0 && aResult['YYYY'] > 0) {
5036	          const d = new Date();
5037	          if (isUTC) {
5038	            d.setUTCDate(1);
5039	            d.setUTCFullYear(aResult['YYYY']);
5040	            d.setUTCMonth(aResult['MM'] - 1);
5041	            d.setUTCDate(aResult['DD']);
5042	            d.setUTCHours(0, 0, 0, 0);
5043	          } else {
5044	            d.setDate(1);
5045	            d.setFullYear(aResult['YYYY']);
5046	            d.setMonth(aResult['MM'] - 1);
5047	            d.setDate(aResult['DD']);
5048	            d.setHours(0, 0, 0, 0);
5049	          }
5050	          if ((!isNaN(aResult['HH']) || !isNaN(aResult['GG']) || !isNaN(aResult['H']) || !isNaN(aResult['G'])) && !isNaN(aResult['MI'])) {
5051	            if (!isNaN(aResult['H']) || !isNaN(aResult['G'])) {
5052	              const bPM = (aResult['T'] || aResult['TT'] || 'am').toUpperCase() === 'PM',
5053	                h = parseInt(aResult['H'] || aResult['G'] || 0, 10);
5054	              if (bPM) {
5055	                aResult['HH'] = h + (h === 12 ? 0 : 12);
5056	              } else {
5057	                aResult['HH'] = h < 12 ? h : 0;
5058	              }
5059	            } else {
5060	              aResult['HH'] = parseInt(aResult['HH'] || aResult['GG'] || 0, 10);
5061	            }
5062	            if (isNaN(aResult['SS'])) {
5063	              aResult['SS'] = 0;
5064	            }
5065	            if (isUTC) {
5066	              d.setUTCHours(aResult['HH'], aResult['MI'], aResult['SS']);
5067	            } else {
5068	              d.setHours(aResult['HH'], aResult['MI'], aResult['SS']);
5069	            }
5070	          }
5071	          return d;
5072	        }
5073	      }
5074	      return null;
5075	    }
5076	  }, {
5077	    key: "getMonthIndex",
5078	    value: function getMonthIndex(month) {
5079	      const q = month.toUpperCase();
5080	      const wordMonthCut = ['jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep', 'oct', 'nov', 'dec'];
5081	      const wordMonth = ['january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december'];
5082	      for (let i = 1; i <= 12; i++) {
5083	        if (q === this._getMessage('MON_' + i).toUpperCase() || q === this._getMessage('MONTH_' + i).toUpperCase() || q === this._getMessage('MONTH_' + i + '_S').toUpperCase() || q === wordMonthCut[i - 1].toUpperCase() || q === wordMonth[i - 1].toUpperCase()) {
5084	          return i;
5085	        }
5086	      }
5087	      return month;
5088	    }
5089	  }, {
5090	    key: "format",
5091	    value: function format(_format, timestamp, now, utc) {
5092	      /*
5093	      PHP to Javascript:
5094	      	time() = new Date()
5095	      	mktime(...) = new Date(...)
5096	      	gmmktime(...) = new Date(Date.UTC(...))
5097	      	mktime(0,0,0, 1, 1, 1970) != 0          new Date(1970,0,1).getTime() != 0
5098	      	gmmktime(0,0,0, 1, 1, 1970) == 0        new Date(Date.UTC(1970,0,1)).getTime() == 0
5099	      	date('d.m.Y H:i:s') = BX.Main.Date.format('d.m.Y H:i:s')
5100	      	gmdate('d.m.Y H:i:s') = BX.Main.Date.format('d.m.Y H:i:s', null, null, true);
5101	      */
5102	      const date = main_core.Type.isDate(timestamp) ? new Date(timestamp.getTime()) : main_core.Type.isNumber(timestamp) ? new Date(timestamp * 1000) : new Date();
5103	      const nowDate = main_core.Type.isDate(now) ? new Date(now.getTime()) : main_core.Type.isNumber(now) ? new Date(now * 1000) : new Date();
5104	      const isUTC = !!utc;
5105	      // used in hoisting inner functions, like _formatDateInterval
5106	      const thisDateTimeFormat = this;
5107	      if (main_core.Type.isArray(_format)) {
5108	        return _formatDateInterval(_format, date, nowDate, isUTC);
5109	      } else {
5110	        if (!main_core.Type.isStringFilled(_format)) {
5111	          return '';
5112	        }
5113	      }
5114	      const replaceMap = (_format.match(/{{([^{}]*)}}/g) || []).map(x => {
5115	        return (x.match(/[^{}]+/) || [''])[0];
5116	      });
5117	      if (replaceMap.length > 0) {
5118	        replaceMap.forEach((element, index) => {
5119	          _format = _format.replace('{{' + element + '}}', '{{' + index + '}}');
5120	        });
5121	      }
5122	      const formatRegex = /\\?(sago|iago|isago|Hago|dago|mago|Yago|sdiff|idiff|Hdiff|ddiff|mdiff|Ydiff|sshort|ishort|Hshort|dshort|mshort|Yshort|yesterday|today|tommorow|tomorrow|.)/gi;
5123	      const dateFormats = {
5124	        d: () => {
5125	          // Day of the month 01 to 31
5126	          return getDate(date).toString().padStart(2, '0');
5127	        },
5128	        D: () => {
5129	          //Mon through Sun
5130	          return this._getMessage('DOW_' + getDay(date));
5131	        },
5132	        j: () => {
5133	          //Day of the month 1 to 31
5134	          return getDate(date);
5135	        },
5136	        l: () => {
5137	          //Sunday through Saturday
5138	          return this._getMessage('DAY_OF_WEEK_' + getDay(date));
5139	        },
5140	        N: () => {
5141	          //1 (for Monday) through 7 (for Sunday)
5142	          return getDay(date) || 7;
5143	        },
5144	        S: () => {
5145	          //st, nd, rd or th. Works well with j
5146	          if (getDate(date) % 10 == 1 && getDate(date) != 11) {
5147	            return 'st';
5148	          } else if (getDate(date) % 10 == 2 && getDate(date) != 12) {
5149	            return 'nd';
5150	          } else if (getDate(date) % 10 == 3 && getDate(date) != 13) {
5151	            return 'rd';
5152	          } else {
5153	            return 'th';
5154	          }
5155	        },
5156	        w: () => {
5157	          //0 (for Sunday) through 6 (for Saturday)
5158	          return getDay(date);
5159	        },
5160	        z: () => {
5161	          //0 through 365
5162	          const firstDay = new Date(getFullYear(date), 0, 1);
5163	          const currentDay = new Date(getFullYear(date), getMonth(date), getDate(date));
5164	          return Math.ceil((currentDay - firstDay) / (24 * 3600 * 1000));
5165	        },
5166	        W: () => {
5167	          //ISO-8601 week number of year
5168	          const newDate = new Date(date.getTime());
5169	          const dayNumber = (getDay(date) + 6) % 7;
5170	          setDate(newDate, getDate(newDate) - dayNumber + 3);
5171	          const firstThursday = newDate.getTime();
5172	          setMonth(newDate, 0, 1);
5173	          if (getDay(newDate) != 4) {
5174	            setMonth(newDate, 0, 1 + (4 - getDay(newDate) + 7) % 7);
5175	          }
5176	          const weekNumber = 1 + Math.ceil((firstThursday - newDate) / (7 * 24 * 3600 * 1000));
5177	          return weekNumber.toString().padStart(2, '0');
5178	        },
5179	        F: () => {
5180	          //January through December
5181	          return this._getMessage('MONTH_' + (getMonth(date) + 1) + '_S');
5182	        },
5183	        f: () => {
5184	          //January through December
5185	          return this._getMessage('MONTH_' + (getMonth(date) + 1));
5186	        },
5187	        m: () => {
5188	          //Numeric representation of a month 01 through 12
5189	          return (getMonth(date) + 1).toString().padStart(2, '0');
5190	        },
5191	        M: () => {
5192	          //A short textual representation of a month, three letters Jan through Dec
5193	          return this._getMessage('MON_' + (getMonth(date) + 1));
5194	        },
5195	        n: () => {
5196	          //Numeric representation of a month 1 through 12
5197	          return getMonth(date) + 1;
5198	        },
5199	        t: () => {
5200	          //Number of days in the given month 28 through 31
5201	          const lastMonthDay = isUTC ? new Date(Date.UTC(getFullYear(date), getMonth(date) + 1, 0)) : new Date(getFullYear(date), getMonth(date) + 1, 0);
5202	          return getDate(lastMonthDay);
5203	        },
5204	        L: () => {
5205	          //1 if it is a leap year, 0 otherwise.
5206	          const year = getFullYear(date);
5207	          return year % 4 == 0 && year % 100 != 0 || year % 400 == 0 ? 1 : 0;
5208	        },
5209	        o: () => {
5210	          //ISO-8601 year number
5211	          const correctDate = new Date(date.getTime());
5212	          setDate(correctDate, getDate(correctDate) - (getDay(date) + 6) % 7 + 3);
5213	          return getFullYear(correctDate);
5214	        },
5215	        Y: () => {
5216	          //A full numeric representation of a year, 4 digits
5217	          return getFullYear(date);
5218	        },
5219	        y: () => {
5220	          //A two digit representation of a year
5221	          return getFullYear(date).toString().slice(2);
5222	        },
5223	        a: () => {
5224	          //am or pm
5225	          return getHours(date) > 11 ? 'pm' : 'am';
5226	        },
5227	        A: () => {
5228	          //AM or PM
5229	          return getHours(date) > 11 ? 'PM' : 'AM';
5230	        },
5231	        B: () => {
5232	          //000 through 999
5233	          const swatch = (date.getUTCHours() + 1) % 24 + date.getUTCMinutes() / 60 + date.getUTCSeconds() / 3600;
5234	          return Math.floor(swatch * 1000 / 24).toString().padStart(3, '0');
5235	        },
5236	        g: () => {
5237	          //12-hour format of an hour without leading zeros 1 through 12
5238	          return getHours(date) % 12 || 12;
5239	        },
5240	        G: () => {
5241	          //24-hour format of an hour without leading zeros 0 through 23
5242	          return getHours(date);
5243	        },
5244	        h: () => {
5245	          //12-hour format of an hour with leading zeros 01 through 12
5246	          return (getHours(date) % 12 || 12).toString().padStart(2, '0');
5247	        },
5248	        H: () => {
5249	          //24-hour format of an hour with leading zeros 00 through 23
5250	          return getHours(date).toString().padStart(2, '0');
5251	        },
5252	        i: () => {
5253	          //Minutes with leading zeros 00 to 59
5254	          return getMinutes(date).toString().padStart(2, '0');
5255	        },
5256	        s: () => {
5257	          //Seconds, with leading zeros 00 through 59
5258	          return getSeconds(date).toString().padStart(2, '0');
5259	        },
5260	        u: () => {
5261	          //Microseconds
5262	          return (getMilliseconds(date) * 1000).toString().padStart(6, '0');
5263	        },
5264	        e: () => {
5265	          if (isUTC) {
5266	            return 'UTC';
5267	          }
5268	          return '';
5269	        },
5270	        I: () => {
5271	          if (isUTC) {
5272	            return 0;
5273	          }
5274
5275	          //Whether or not the date is in daylight saving time 1 if Daylight Saving Time, 0 otherwise
5276	          const firstJanuary = new Date(getFullYear(date), 0, 1);
5277	          const firstJanuaryUTC = Date.UTC(getFullYear(date), 0, 1);
5278	          const firstJuly = new Date(getFullYear(date), 6, 0);
5279	          const firstJulyUTC = Date.UTC(getFullYear(date), 6, 0);
5280	          return 0 + (firstJanuary - firstJanuaryUTC !== firstJuly - firstJulyUTC);
5281	        },
5282	        O: () => {
5283	          if (isUTC) {
5284	            return '+0000';
5285	          }
5286
5287	          //Difference to Greenwich time (GMT) in hours +0200
5288	          const timezoneOffset = date.getTimezoneOffset();
5289	          const timezoneOffsetAbs = Math.abs(timezoneOffset);
5290	          return (timezoneOffset > 0 ? '-' : '+') + (Math.floor(timezoneOffsetAbs / 60) * 100 + timezoneOffsetAbs % 60).toString().padStart(4, '0');
5291	        },
5292	        //this method references 'O' method of the same object, arrow function is not suitable here
5293	        P: function () {
5294	          if (isUTC) {
5295	            return '+00:00';
5296	          }
5297
5298	          //Difference to Greenwich time (GMT) with colon between hours and minutes +02:00
5299	          const difference = this.O();
5300	          return difference.substr(0, 3) + ':' + difference.substr(3);
5301	        },
5302	        Z: () => {
5303	          if (isUTC) {
5304	            return 0;
5305	          }
5306	          //Timezone offset in seconds. The offset for timezones west of UTC is always negative,
5307	          //and for those east of UTC is always positive.
5308	          return -date.getTimezoneOffset() * 60;
5309	        },
5310	        c: () => {
5311	          //ISO 8601 date
5312	          return 'Y-m-d\\TH:i:sP'.replace(formatRegex, _replaceDateFormat);
5313	        },
5314	        r: () => {
5315	          //RFC 2822 formatted date
5316	          return 'D, d M Y H:i:s O'.replace(formatRegex, _replaceDateFormat);
5317	        },
5318	        U: () => {
5319	          //Seconds since the Unix Epoch
5320	          return Math.floor(date.getTime() / 1000);
5321	        },
5322	        sago: () => {
5323	          return _formatDateMessage(intval((nowDate - date) / 1000), {
5324	            '0': 'FD_SECOND_AGO_0',
5325	            '1': 'FD_SECOND_AGO_1',
5326	            '10_20': 'FD_SECOND_AGO_10_20',
5327	            'MOD_1': 'FD_SECOND_AGO_MOD_1',
5328	            'MOD_2_4': 'FD_SECOND_AGO_MOD_2_4',
5329	            'MOD_OTHER': 'FD_SECOND_AGO_MOD_OTHER'
5330	          });
5331	        },
5332	        sdiff: () => {
5333	          return _formatDateMessage(intval((nowDate - date) / 1000), {
5334	            '0': 'FD_SECOND_DIFF_0',
5335	            '1': 'FD_SECOND_DIFF_1',
5336	            '10_20': 'FD_SECOND_DIFF_10_20',
5337	            'MOD_1': 'FD_SECOND_DIFF_MOD_1',
5338	            'MOD_2_4': 'FD_SECOND_DIFF_MOD_2_4',
5339	            'MOD_OTHER': 'FD_SECOND_DIFF_MOD_OTHER'
5340	          });
5341	        },
5342	        sshort: () => {
5343	          return this._getMessage('FD_SECOND_SHORT').replace(/#VALUE#/g, intval((nowDate - date) / 1000));
5344	        },
5345	        iago: () => {
5346	          return _formatDateMessage(intval((nowDate - date) / 60 / 1000), {
5347	            '0': 'FD_MINUTE_AGO_0',
5348	            '1': 'FD_MINUTE_AGO_1',
5349	            '10_20': 'FD_MINUTE_AGO_10_20',
5350	            'MOD_1': 'FD_MINUTE_AGO_MOD_1',
5351	            'MOD_2_4': 'FD_MINUTE_AGO_MOD_2_4',
5352	            'MOD_OTHER': 'FD_MINUTE_AGO_MOD_OTHER'
5353	          });
5354	        },
5355	        idiff: () => {
5356	          return _formatDateMessage(intval((nowDate - date) / 60 / 1000), {
5357	            '0': 'FD_MINUTE_DIFF_0',
5358	            '1': 'FD_MINUTE_DIFF_1',
5359	            '10_20': 'FD_MINUTE_DIFF_10_20',
5360	            'MOD_1': 'FD_MINUTE_DIFF_MOD_1',
5361	            'MOD_2_4': 'FD_MINUTE_DIFF_MOD_2_4',
5362	            'MOD_OTHER': 'FD_MINUTE_DIFF_MOD_OTHER'
5363	          });
5364	        },
5365	        isago: () => {
5366	          const minutesAgo = intval((nowDate - date) / 60 / 1000);
5367	          let result = _formatDateMessage(minutesAgo, {
5368	            '0': 'FD_MINUTE_0',
5369	            '1': 'FD_MINUTE_1',
5370	            '10_20': 'FD_MINUTE_10_20',
5371	            'MOD_1': 'FD_MINUTE_MOD_1',
5372	            'MOD_2_4': 'FD_MINUTE_MOD_2_4',
5373	            'MOD_OTHER': 'FD_MINUTE_MOD_OTHER'
5374	          });
5375	          result += ' ';
5376	          const secondsAgo = intval((nowDate - date) / 1000) - minutesAgo * 60;
5377	          result += _formatDateMessage(secondsAgo, {
5378	            '0': 'FD_SECOND_AGO_0',
5379	            '1': 'FD_SECOND_AGO_1',
5380	            '10_20': 'FD_SECOND_AGO_10_20',
5381	            'MOD_1': 'FD_SECOND_AGO_MOD_1',
5382	            'MOD_2_4': 'FD_SECOND_AGO_MOD_2_4',
5383	            'MOD_OTHER': 'FD_SECOND_AGO_MOD_OTHER'
5384	          });
5385	          return result;
5386	        },
5387	        ishort: () => {
5388	          return this._getMessage('FD_MINUTE_SHORT').replace(/#VALUE#/g, intval((nowDate - date) / 60 / 1000));
5389	        },
5390	        Hago: () => {
5391	          return _formatDateMessage(intval((nowDate - date) / 60 / 60 / 1000), {
5392	            '0': 'FD_HOUR_AGO_0',
5393	            '1': 'FD_HOUR_AGO_1',
5394	            '10_20': 'FD_HOUR_AGO_10_20',
5395	            'MOD_1': 'FD_HOUR_AGO_MOD_1',
5396	            'MOD_2_4': 'FD_HOUR_AGO_MOD_2_4',
5397	            'MOD_OTHER': 'FD_HOUR_AGO_MOD_OTHER'
5398	          });
5399	        },
5400	        Hdiff: () => {
5401	          return _formatDateMessage(intval((nowDate - date) / 60 / 60 / 1000), {
5402	            '0': 'FD_HOUR_DIFF_0',
5403	            '1': 'FD_HOUR_DIFF_1',
5404	            '10_20': 'FD_HOUR_DIFF_10_20',
5405	            'MOD_1': 'FD_HOUR_DIFF_MOD_1',
5406	            'MOD_2_4': 'FD_HOUR_DIFF_MOD_2_4',
5407	            'MOD_OTHER': 'FD_HOUR_DIFF_MOD_OTHER'
5408	          });
5409	        },
5410	        Hshort: () => {
5411	          return this._getMessage('FD_HOUR_SHORT').replace(/#VALUE#/g, intval((nowDate - date) / 60 / 60 / 1000));
5412	        },
5413	        yesterday: () => {
5414	          return this._getMessage('FD_YESTERDAY');
5415	        },
5416	        today: () => {
5417	          return this._getMessage('FD_TODAY');
5418	        },
5419	        tommorow: () => {
5420	          return this._getMessage('FD_TOMORROW');
5421	        },
5422	        tomorrow: () => {
5423	          return this._getMessage('FD_TOMORROW');
5424	        },
5425	        dago: () => {
5426	          return _formatDateMessage(intval((nowDate - date) / 60 / 60 / 24 / 1000), {
5427	            '0': 'FD_DAY_AGO_0',
5428	            '1': 'FD_DAY_AGO_1',
5429	            '10_20': 'FD_DAY_AGO_10_20',
5430	            'MOD_1': 'FD_DAY_AGO_MOD_1',
5431	            'MOD_2_4': 'FD_DAY_AGO_MOD_2_4',
5432	            'MOD_OTHER': 'FD_DAY_AGO_MOD_OTHER'
5433	          });
5434	        },
5435	        ddiff: () => {
5436	          return _formatDateMessage(intval((nowDate - date) / 60 / 60 / 24 / 1000), {
5437	            '0': 'FD_DAY_DIFF_0',
5438	            '1': 'FD_DAY_DIFF_1',
5439	            '10_20': 'FD_DAY_DIFF_10_20',
5440	            'MOD_1': 'FD_DAY_DIFF_MOD_1',
5441	            'MOD_2_4': 'FD_DAY_DIFF_MOD_2_4',
5442	            'MOD_OTHER': 'FD_DAY_DIFF_MOD_OTHER'
5443	          });
5444	        },
5445	        dshort: () => {
5446	          return this._getMessage('FD_DAY_SHORT').replace(/#VALUE#/g, intval((nowDate - date) / 60 / 60 / 24 / 1000));
5447	        },
5448	        mago: () => {
5449	          return _formatDateMessage(intval((nowDate - date) / 60 / 60 / 24 / 31 / 1000), {
5450	            '0': 'FD_MONTH_AGO_0',
5451	            '1': 'FD_MONTH_AGO_1',
5452	            '10_20': 'FD_MONTH_AGO_10_20',
5453	            'MOD_1': 'FD_MONTH_AGO_MOD_1',
5454	            'MOD_2_4': 'FD_MONTH_AGO_MOD_2_4',
5455	            'MOD_OTHER': 'FD_MONTH_AGO_MOD_OTHER'
5456	          });
5457	        },
5458	        mdiff: () => {
5459	          return _formatDateMessage(intval((nowDate - date) / 60 / 60 / 24 / 31 / 1000), {
5460	            '0': 'FD_MONTH_DIFF_0',
5461	            '1': 'FD_MONTH_DIFF_1',
5462	            '10_20': 'FD_MONTH_DIFF_10_20',
5463	            'MOD_1': 'FD_MONTH_DIFF_MOD_1',
5464	            'MOD_2_4': 'FD_MONTH_DIFF_MOD_2_4',
5465	            'MOD_OTHER': 'FD_MONTH_DIFF_MOD_OTHER'
5466	          });
5467	        },
5468	        mshort: () => {
5469	          return this._getMessage('FD_MONTH_SHORT').replace(/#VALUE#/g, intval((nowDate - date) / 60 / 60 / 24 / 31 / 1000));
5470	        },
5471	        Yago: () => {
5472	          return _formatDateMessage(intval((nowDate - date) / 60 / 60 / 24 / 365 / 1000), {
5473	            '0': 'FD_YEARS_AGO_0',
5474	            '1': 'FD_YEARS_AGO_1',
5475	            '10_20': 'FD_YEARS_AGO_10_20',
5476	            'MOD_1': 'FD_YEARS_AGO_MOD_1',
5477	            'MOD_2_4': 'FD_YEARS_AGO_MOD_2_4',
5478	            'MOD_OTHER': 'FD_YEARS_AGO_MOD_OTHER'
5479	          });
5480	        },
5481	        Ydiff: () => {
5482	          return _formatDateMessage(intval((nowDate - date) / 60 / 60 / 24 / 365 / 1000), {
5483	            '0': 'FD_YEARS_DIFF_0',
5484	            '1': 'FD_YEARS_DIFF_1',
5485	            '10_20': 'FD_YEARS_DIFF_10_20',
5486	            'MOD_1': 'FD_YEARS_DIFF_MOD_1',
5487	            'MOD_2_4': 'FD_YEARS_DIFF_MOD_2_4',
5488	            'MOD_OTHER': 'FD_YEARS_DIFF_MOD_OTHER'
5489	          });
5490	        },
5491	        Yshort: () => {
5492	          return _formatDateMessage(intval((nowDate - date) / 60 / 60 / 24 / 365 / 1000), {
5493	            '0': 'FD_YEARS_SHORT_0',
5494	            '1': 'FD_YEARS_SHORT_1',
5495	            '10_20': 'FD_YEARS_SHORT_10_20',
5496	            'MOD_1': 'FD_YEARS_SHORT_MOD_1',
5497	            'MOD_2_4': 'FD_YEARS_SHORT_MOD_2_4',
5498	            'MOD_OTHER': 'FD_YEARS_SHORT_MOD_OTHER'
5499	          });
5500	        },
5501	        x: () => {
5502	          const ampm = this.isAmPmMode(true);
5503	          const timeFormat = ampm === this.AM_PM_MODE.LOWER ? 'g:i a' : ampm === this.AM_PM_MODE.UPPER ? 'g:i A' : 'H:i';
5504	          return this.format([['tomorrow', 'tomorrow, ' + timeFormat], ['-', this.convertBitrixFormat(this._getMessage('FORMAT_DATETIME')).replace(/:s/g, '')], ['
5504s', 'sago'], ['i', 'iago'], ['today', 'today, ' + timeFormat], ['yesterday', 'yesterday, ' + timeFormat], ['', this.convertBitrixFormat(this._getMessage('FORMAT_DATETIME')).replace(/:s/g, '')]], date, nowDate, isUTC);
5505	        },
5506	        X: () => {
5507	          const ampm = this.isAmPmMode(true);
5508	          const timeFormat = ampm === this.AM_PM_MODE.LOWER ? 'g:i a' : ampm === this.AM_PM_MODE.UPPER ? 'g:i A' : 'H:i';
5509	          const day = this.format([['tomorrow', 'tomorrow'], ['-', this.convertBitrixFormat(this._getMessage('FORMAT_DATE'))], ['today', 'today'], ['yesterday', 'yesterday'], ['', this.convertBitrixFormat(this._getMessage('FORMAT_DATE'))]], date, nowDate, isUTC);
5510	          const time = this.format([['tomorrow', timeFormat], ['today', timeFormat], ['yesterday', timeFormat], ['', '']], date, nowDate, isUTC);
5511	          if (time.length > 0) {
5512	            return this._getMessage('FD_DAY_AT_TIME').replace(/#DAY#/g, day).replace(/#TIME#/g, time);
5513	          } else {
5514	            return day;
5515	          }
5516	        },
5517	        Q: () => {
5518	          const daysAgo = intval((nowDate - date) / 60 / 60 / 24 / 1000);
5519	          if (daysAgo == 0) {
5520	            return this._getMessage('FD_DAY_DIFF_1').replace(/#VALUE#/g, 1);
5521	          } else {
5522	            return this.format([['d', 'ddiff'], ['m', 'mdiff'], ['', 'Ydiff']], date, nowDate);
5523	          }
5524	        }
5525	      };
5526	      let cutZeroTime = false;
5527	      if (_format[0] && _format[0] == '^') {
5528	        cutZeroTime = true;
5529	        _format = _format.substr(1);
5530	      }
5531	      let result = _format.replace(formatRegex, _replaceDateFormat);
5532	      if (cutZeroTime) {
5533	        /* 	15.04.12 13:00:00 => 15.04.12 13:00
5534	        	00:01:00 => 00:01
5535	        	4 may 00:00:00 => 4 may
5536	        	01-01-12 00:00 => 01-01-12
5537	        */
5538
5539	        result = result.replace(/\s*00:00:00\s*/g, '').replace(/(\d\d:\d\d)(:00)/g, '$1').replace(/(\s*00:00\s*)(?!:)/g, '');
5540	      }
5541	      if (replaceMap.length > 0) {
5542	        replaceMap.forEach(function (element, index) {
5543	          result = result.replace('{{' + index + '}}', element);
5544	        });
5545	      }
5546	      return result;
5547	      function _formatDateInterval(formats, date, nowDate, isUTC) {
5548	        const secondsAgo = intval((nowDate - date) / 1000);
5549	        for (let i = 0; i < formats.length; i++) {
5550	          const formatInterval = formats[i][0];
5551	          const formatValue = formats[i][1];
5552	          let match = null;
5553	          if (formatInterval == 's') {
5554	            if (secondsAgo < 60) {
5555	              return thisDateTimeFormat.format(formatValue, date, nowDate, isUTC);
5556	            }
5557	          } else if ((match = /^s(\d+)\>?(\d+)?/.exec(formatInterval)) != null) {
5558	            if (match[1] && match[2]) {
5559	              if (secondsAgo < match[1] && secondsAgo > match[2]) {
5560	                return thisDateTimeFormat.format(formatValue, date, nowDate, isUTC);
5561	              }
5562	            } else if (secondsAgo < match[1]) {
5563	              return thisDateTimeFormat.format(formatValue, date, nowDate, isUTC);
5564	            }
5565	          } else if (formatInterval == 'i') {
5566	            if (secondsAgo < 60 * 60) {
5567	              return thisDateTimeFormat.format(formatValue, date, nowDate, isUTC);
5568	            }
5569	          } else if ((match = /^i(\d+)\>?(\d+)?/.exec(formatInterval)) != null) {
5570	            if (match[1] && match[2]) {
5571	              if (secondsAgo < match[1] * 60 && secondsAgo > match[2] * 60) {
5572	                return thisDateTimeFormat.format(formatValue, date, nowDate, isUTC);
5573	              }
5574	            } else if (secondsAgo < match[1] * 60) {
5575	              return thisDateTimeFormat.format(formatValue, date, nowDate, isUTC);
5576	            }
5577	          } else if (formatInterval == 'H') {
5578	            if (secondsAgo < 24 * 60 * 60) {
5579	              return thisDateTimeFormat.format(formatValue, date, nowDate, isUTC);
5580	            }
5581	          } else if ((match = /^H(\d+)\>?(\d+)?/.exec(formatInterval)) != null) {
5582	            if (match[1] && match[2]) {
5583	              if (secondsAgo < match[1] * 60 * 60 && secondsAgo > match[2] * 60 * 60) {
5584	                return thisDateTimeFormat.format(formatValue, date, nowDate, isUTC);
5585	              }
5586	            } else if (secondsAgo < match[1] * 60 * 60) {
5587	              return thisDateTimeFormat.format(formatValue, date, nowDate, isUTC);
5588	            }
5589	          } else if (formatInterval == 'd') {
5590	            if (secondsAgo < 31 * 24 * 60 * 60) {
5591	              return thisDateTimeFormat.format(formatValue, date, nowDate, isUTC);
5592	            }
5593	          } else if ((match = /^d(\d+)\>?(\d+)?/.exec(formatInterval)) != null) {
5594	            if (match[1] && match[2]) {
5595	              if (secondsAgo < match[1] * 24 * 60 * 60 && secondsAgo > match[2] * 24 * 60 * 60) {
5596	                return thisDateTimeFormat.format(formatValue, date, nowDate, isUTC);
5597	              }
5598	            } else if (secondsAgo < match[1] * 24 * 60 * 60) {
5599	              return thisDateTimeFormat.format(formatValue, date, nowDate, isUTC);
5600	            }
5601	          } else if (formatInterval == 'm') {
5602	            if (secondsAgo < 365 * 24 * 60 * 60) {
5603	              return thisDateTimeFormat.format(formatValue, date, nowDate, isUTC);
5604	            }
5605	          } else if ((match = /^m(\d+)\>?(\d+)?/.exec(formatInterval)) != null) {
5606	            if (match[1] && match[2]) {
5607	              if (secondsAgo < match[1] * 31 * 24 * 60 * 60 && secondsAgo > match[2] * 31 * 24 * 60 * 60) {
5608	                return thisDateTimeFormat.format(formatValue, date, nowDate, isUTC);
5609	              }
5610	            } else if (secondsAgo < match[1] * 31 * 24 * 60 * 60) {
5611	              return thisDateTimeFormat.format(formatValue, date, nowDate, isUTC);
5612	            }
5613	          } else if (formatInterval == 'now') {
5614	            if (date.getTime() == nowDate.getTime()) {
5615	              return thisDateTimeFormat.format(formatValue, date, nowDate, isUTC);
5616	            }
5617	          } else if (formatInterval == 'today') {
5618	            const year = getFullYear(nowDate);
5619	            const month = getMonth(nowDate);
5620	            const day = getDate(nowDate);
5621	            const todayStart = isUTC ? new Date(Date.UTC(year, month, day, 0, 0, 0, 0)) : new Date(year, month, day, 0, 0, 0, 0);
5622	            const todayEnd = isUTC ? new Date(Date.UTC(year, month, day + 1, 0, 0, 0, 0)) : new Date(year, month, day + 1, 0, 0, 0, 0);
5623	            if (date >= todayStart && date < todayEnd) {
5624	              return thisDateTimeFormat.format(formatValue, date, nowDate, isUTC);
5625	            }
5626	          } else if (formatInterval == 'todayFuture') {
5627	            const year = getFullYear(nowDate);
5628	            const month = getMonth(nowDate);
5629	            const day = getDate(nowDate);
5630	            const todayStart = nowDate.getTime();
5631	            const todayEnd = isUTC ? new Date(Date.UTC(year, month, day + 1, 0, 0, 0, 0)) : new Date(year, month, day + 1, 0, 0, 0, 0);
5632	            if (date >= todayStart && date < todayEnd) {
5633	              return thisDateTimeFormat.format(formatValue, date, nowDate, isUTC);
5634	            }
5635	          } else if (formatInterval == 'yesterday') {
5636	            const year = getFullYear(nowDate);
5637	            const month = getMonth(nowDate);
5638	            const day = getDate(nowDate);
5639	            const yesterdayStart = isUTC ? new Date(Date.UTC(year, month, day - 1, 0, 0, 0, 0)) : new Date(year, month, day - 1, 0, 0, 0, 0);
5640	            const yesterdayEnd = isUTC ? new Date(Date.UTC(year, month, day, 0, 0, 0, 0)) : new Date(year, month, day, 0, 0, 0, 0);
5641	            if (date >= yesterdayStart && date < yesterdayEnd) {
5642	              return thisDateTimeFormat.format(formatValue, date, nowDate, isUTC);
5643	            }
5644	          } else if (formatInterval == 'tommorow' || formatInterval == 'tomorrow') {
5645	            const year = getFullYear(nowDate);
5646	            const month = getMonth(nowDate);
5647	            const day = getDate(nowDate);
5648	            const tomorrowStart = isUTC ? new Date(Date.UTC(year, month, day + 1, 0, 0, 0, 0)) : new Date(year, month, day + 1, 0, 0, 0, 0);
5649	            const tomorrowEnd = isUTC ? new Date(Date.UTC(year, month, day + 2, 0, 0, 0, 0)) : new Date(year, month, day + 2, 0, 0, 0, 0);
5650	            if (date >= tomorrowStart && date < tomorrowEnd) {
5651	              return thisDateTimeFormat.format(formatValue, date, nowDate, isUTC);
5652	            }
5653	          } else if (formatInterval == '-') {
5654	            if (secondsAgo < 0) {
5655	              return thisDateTimeFormat.format(formatValue, date, nowDate, isUTC);
5656	            }
5657	          }
5658	        }
5659
5660	        //return formats.length > 0 ? thisDateTimeFormat.format(formats.pop()[1], date, nowDate, isUTC) : '';
5661	        return formats.length > 0 ? thisDateTimeFormat.format(formats[formats.length - 1][1], date, nowDate, isUTC) : '';
5662	      }
5663	      function getFullYear(date) {
5664	        return isUTC ? date.getUTCFullYear() : date.getFullYear();
5665	      }
5666	      function getDate(date) {
5667	        return isUTC ? date.getUTCDate() : date.getDate();
5668	      }
5669	      function getMonth(date) {
5670	        return isUTC ? date.getUTCMonth() : date.getMonth();
5671	      }
5672	      function getHours(date) {
5673	        return isUTC ? date.getUTCHours() : date.getHours();
5674	      }
5675	      function getMinutes(date) {
5676	        return isUTC ? date.getUTCMinutes() : date.getMinutes();
5677	      }
5678	      function getSeconds(date) {
5679	        return isUTC ? date.getUTCSeconds() : date.getSeconds();
5680	      }
5681	      function getMilliseconds(date) {
5682	        return isUTC ? date.getUTCMilliseconds() : date.getMilliseconds();
5683	      }
5684	      function getDay(date) {
5685	        return isUTC ? date.getUTCDay() : date.getDay();
5686	      }
5687	      function setDate(date, dayValue) {
5688	        return isUTC ? date.setUTCDate(dayValue) : date.setDate(dayValue);
5689	      }
5690	      function setMonth(date, monthValue, dayValue) {
5691	        return isUTC ? date.setUTCMonth(monthValue, dayValue) : date.setMonth(monthValue, dayValue);
5692	      }
5693	      function _formatDateMessage(value, messages) {
5694	        const val = value < 100 ? Math.abs(value) : Math.abs(value % 100);
5695	        const dec = val % 10;
5696	        let message = '';
5697	        if (val == 0) {
5698	          message = thisDateTimeFormat._getMessage(messages['0']);
5699	        } else if (val == 1) {
5700	          message = thisDateTimeFormat._getMessage(messages['1']);
5701	        } else if (val >= 10 && val <= 20) {
5702	          message = thisDateTimeFormat._getMessage(messages['10_20']);
5703	        } else if (dec == 1) {
5704	          message = thisDateTimeFormat._getMessage(messages['MOD_1']);
5705	        } else if (2 <= dec && dec <= 4) {
5706	          message = thisDateTimeFormat._getMessage(messages['MOD_2_4']);
5707	        } else {
5708	          message = thisDateTimeFormat._getMessage(messages['MOD_OTHER']);
5709	        }
5710	        return message.replace(/#VALUE#/g, value);
5711	      }
5712	      function _replaceDateFormat(match, matchFull) {
5713	        if (dateFormats[match]) {
5714	          return dateFormats[match]();
5715	        } else {
5716	          return matchFull;
5717	        }
5718	      }
5719	      function intval(number) {
5720	        return number >= 0 ? Math.floor(number) : Math.ceil(number);
5721	      }
5722	    }
5723	  }]);
5724	  return DateTimeFormat;
5725	}();
5726	babelHelpers.defineProperty(DateTimeFormat, "AM_PM_MODE", {
5727	  UPPER: 1,
5728	  LOWER: 2,
5729	  NONE: false
5730	});
5731	babelHelpers.defineProperty(DateTimeFormat, "convertBitrixFormat", convertBitrixFormat);
5732	babelHelpers.defineProperty(DateTimeFormat, "getFormat", getFormat);
5733
5734	function _classPrivateMethodInitSpec(obj, privateSet) { _checkPrivateRedeclaration(obj, privateSet); privateSet.add(obj); }
5735	function _checkPrivateRedeclaration(obj, privateCollection) { if (privateCollection.has(obj)) { throw new TypeError("Cannot initialize the same private elements twice on an object"); } }
5736	function _classPrivateMethodGet(receiver, privateSet, fn) { if (!privateSet.has(receiver)) { throw new TypeError("attempted to get private field on non-instance"); } return fn; }
5737
5738	/**
5739	 * Available units: `Y` - years, `m` - months, `d` - days, `H` - hours, `i` - minutes, `s` - seconds.
5740	 */
5741
5742	const defaultOptions = {
5743	  format: 'Y m d H i s',
5744	  style: 'long'
5745	};
5746	var _getSeparator = /*#__PURE__*/new WeakSet();
5747	var _getMaxUnit = /*#__PURE__*/new WeakSet();
5748	var _formatUnit = /*#__PURE__*/new WeakSet();
5749	var _getUnitPropertyModByFormat = /*#__PURE__*/new WeakSet();
5750	var _getUnitPropertyByFormat = /*#__PURE__*/new WeakSet();
5751	var _getUnitDuration = /*#__PURE__*/new WeakSet();
5752	let DurationFormat = /*#__PURE__*/function () {
5753	  function DurationFormat(milliseconds) {
5754	    babelHelpers.classCallCheck(this, DurationFormat);
5755	    _classPrivateMethodInitSpec(this, _getUnitDuration);
5756	    _classPrivateMethodInitSpec(this, _getUnitPropertyByFormat);
5757	    _classPrivateMethodInitSpec(this, _getUnitPropertyModByFormat);
5758	    _classPrivateMethodInitSpec(this, _formatUnit);
5759	    _classPrivateMethodInitSpec(this, _getMaxUnit);
5760	    _classPrivateMethodInitSpec(this, _getSeparator);
5761	    this.milliseconds = Math.abs(milliseconds);
5762	  }
5763	  babelHelpers.createClass(DurationFormat, [{
5764	    key: "format",
5765	    /**
5766	     * @example new DurationFormat(5070000).format() // 1 hour, 24 minutes, 30 seconds
5767	     * @example new DurationFormat(5070000).format({ style: 'short' }) // 1 h 24 m 30 s
5768	     * @example new DurationFormat(5070000).format({ format: 'd H i' }) // 1 hour, 24 minutes
5769	     * @example new DurationFormat(5070000).format({ format: 'i s' }) // 84 minutes, 30 seconds
5770	     */
5771	    value: function format(formatOptions = defaultOptions) {
5772	      const options = {
5773	        ...defaultOptions,
5774	        ...formatOptions
5775	      };
5776	      const orderedUnits = main_core.Loc.getMessage('FD_UNIT_ORDER').split(' ');
5777	      const separator = _classPrivateMethodGet(this, _getSeparator, _getSeparator2).
5777call(this, options.style);
5778	      const formatUnits = new Set(options.format.split(' '));
5779	      const maxUnit = _classPrivateMethodGet(this, _getMaxUnit, _getMaxUnit2).call(this, options.format);
5780	      return orderedUnits.filter(unit => formatUnits.has(unit)).map(unit => _classPrivateMethodGet(this, _formatUnit, _formatUnit2).call(this, unit, unit !== maxUnit, options.style)).filter(unit => unit !== '').join(separator);
5781	    }
5782	    /**
5783	     * @example new DurationFormat(5070000).formatClosest() // 1 hour
5784	     * @example new DurationFormat(5070000).formatClosest({ format: 'i s' }) // 84 minutes
5785	     */
5786	  }, {
5787	    key: "formatClosest",
5788	    value: function formatClosest(formatOptions = defaultOptions) {
5789	      const options = {
5790	        ...defaultOptions,
5791	        ...formatOptions
5792	      };
5793	      const maxUnit = _classPrivateMethodGet(this, _getMaxUnit, _getMaxUnit2).call(this, options.format);
5794	      return _classPrivateMethodGet(this, _formatUnit, _formatUnit2).call(this, maxUnit, false, options.style);
5795	    }
5796	  }, {
5797	    key: "seconds",
5798	    get: function () {
5799	      return Math.floor(this.milliseconds / DurationFormat.getUnitDurations().s);
5800	    }
5801	  }, {
5802	    key: "minutes",
5803	    get: function () {
5804	      return Math.floor(this.milliseconds / DurationFormat.getUnitDurations().i);
5805	    }
5806	  }, {
5807	    key: "hours",
5808	    get: function () {
5809	      return Math.floor(this.milliseconds / DurationFormat.getUnitDurations().H);
5810	    }
5811	  }, {
5812	    key: "days",
5813	    get: function () {
5814	      return Math.floor(this.milliseconds / DurationFormat.getUnitDurations().d);
5815	    }
5816	    /**
5817	     * Considering month is 31 days
5818	     */
5819	  }, {
5820	    key: "months",
5821	    get: function () {
5822	      return Math.floor(this.milliseconds / DurationFormat.getUnitDurations().m);
5823	    }
5824	    /**
5825	     * Considering year is 365 days
5826	     */
5827	  }, {
5828	    key: "years",
5829	    get: function () {
5830	      return Math.floor(this.milliseconds / DurationFormat.getUnitDurations().Y);
5831	    }
5832	  }], [{
5833	    key: "createFromSeconds",
5834	    value: function createFromSeconds(seconds) {
5835	      return new DurationFormat(seconds * DurationFormat.getUnitDurations().s);
5836	    }
5837	  }, {
5838	    key: "createFromMinutes",
5839	    value: function createFromMinutes(minutes) {
5840	      return new DurationFormat(minutes * DurationFormat.getUnitDurations().i);
5841	    }
5842	  }, {
5843	    key: "getUnitDurations",
5844	    value: function getUnitDurations() {
5845	      return {
5846	        s: 1000,
5847	        i: 60000,
5848	        H: 3600000,
5849	        d: 86400000,
5850	        m: 2678400000,
5851	        Y: 31536000000
5852	      };
5853	    }
5854	  }]);
5855	  return DurationFormat;
5856	}();
5857	function _getSeparator2(style) {
5858	  if (style === 'short') {
5859	    return main_core.Loc.getMessage('FD_SEPARATOR_SHORT').replaceAll('&#32;', ' ');
5860	  }
5861	  return main_core.Loc.getMessage('FD_SEPARATOR').replaceAll('&#32;', ' ');
5862	}
5863	function _getMaxUnit2(format) {
5864	  const formatUnits = new Set(format.split(' '));
5865	  const units = Object.entries(DurationFormat.getUnitDurations()).filter(([unit]) => formatUnits.has(unit));
5866	  return units.reduce((closestDuration, unitDuration) => {
5867	    const whole = Math.floor(this.milliseconds / unitDuration[1]) >= 1;
5868	    const max = unitDuration[1] > closestDuration[1];
5869	    return whole && max ? unitDuration : closestDuration;
5870	  }, units[0])[0];
5871	}
5872	function _formatUnit2(unitStr, mod, style) {
5873	  const value = mod ? _classPrivateMethodGet(this, _getUnitPropertyModByFormat, _getUnitPropertyModByFormat2).call(this, unitStr) : _classPrivateMethodGet(this, _getUnitPropertyByFormat, _getUnitPropertyByFormat2).call(this, unitStr);
5874	  if (mod && value === 0) {
5875	    return '';
5876	  }
5877	  const now = Date.now() / 1000;
5878	  const unitDuration = value * _classPrivateMethodGet(this, _getUnitDuration, _getUnitDuration2).call(this, unitStr) / 1000;
5879	  const format = style === 'short' ? `${unitStr}short` : `${unitStr}diff`;
5880	  return DateTimeFormat.format(format, now - unitDuration, now);
5881	}
5882	function _getUnitPropertyModByFormat2(unitStr) {
5883	  const propsMod = {
5884	    s: this.seconds % 60,
5885	    i: this.minutes % 60,
5886	    H: this.hours % 24,
5887	    d: this.days % 31,
5888	    m: this.months % 12,
5889	    Y: this.years
5890	  };
5891	  return propsMod[unitStr];
5892	}
5893	function _getUnitPropertyByFormat2(unitStr) {
5894	  const props = {
5895	    s: this.seconds,
5896	    i: this.minutes,
5897	    H: this.hours,
5898	    d: this.days,
5899	    m: this.months,
5900	    Y: this.years
5901	  };
5902	  return props[unitStr];
5903	}
5904	function _getUnitDuration2(unitStr) {
5905	  return DurationFormat.getUnitDurations()[unitStr];
5906	}
5907
5908	const cache = new main_core.Cache.MemoryCache();
5909	/**
5910	 * @memberOf BX.Main.Timezone
5911	 *
5912	 * WARNING! Don't use this class or any classes from Timezone namespace on sites without Bitrix Framework.
5913	 * It is not designed to handle this case and will definitely break.
5914	 */
5915	const Offset = {
5916	  get SERVER_TO_UTC() {
5917	    return cache.remember('SERVER_TO_UTC', () => {
5918	      return main_core.Text.toInteger(main_core.Loc.getMessage('SERVER_TZ_OFFSET'));
5919	    });
5920	  },
5921	  get USER_TO_SERVER() {
5922	    return cache.remember('USER_TO_SERVER', () => {
5923	      return main_core.Text.toInteger(main_core.Loc.getMessage('USER_TZ_OFFSET'));
5924	    });
5925	  },
5926	  // Date returns timezone offset in minutes by default, change it to seconds
5927	  // Also offset is negative in UTC+ timezones and positive in UTC- timezones.
5928	  // By convention Bitrix uses the opposite approach, so change offset sign.
5929	  get BROWSER_TO_UTC() {
5930	    return cache.remember('BROWSER_TO_UTC', () => {
5931	      const offset = main_core.Text.toInteger(new Date().getTimezoneOffset() * 60);
5932	      return -offset;
5933	    });
5934	  }
5935	};
5936	Object.freeze(Offset);
5937
5938	function normalizeTimeValue(timeValue) {
5939	  if (main_core.Type.isDate(timeValue)) {
5940	    return getTimestampFromDate(timeValue);
5941	  }
5942	  return main_core.Text.toInteger(timeValue);
5943	}
5944	function createDateFromTimestamp(timestampInSeconds) {
5945	  return new Date(timestampInSeconds * 1000);
5946	}
5947	function getTimestampFromDate(date) {
5948	  return Math.floor(date.getTime() / 1000);
5949	}
5950
5951	let offset = Offset;
5952	let now = null;
5953	function getOffset() {
5954	  return offset;
5955	}
5956	function getNowTimestamp() {
5957	  var _now;
5958	  return (_now = now) !== null && _now !== void 0 ? _now : getTimestampFromDate(new Date());
5959	}
5960
5961	/**
5962	 * @memberOf BX.Main.Timezone
5963	 *
5964	 * WARNING! Don't use this class or any classes from Timezone namespace on sites without Bitrix Framework.
5965	 * It is not designed to handle this case and will definitely break.
5966	 */
5967	let BrowserTime = /*#__PURE__*/function () {
5968	  function BrowserTime() {
5969	    babelHelpers.classCallCheck(this, BrowserTime);
5970	  }
5971	  babelHelpers.createClass(BrowserTime, null, [{
5972	    key: "getDate",
5973	    /**
5974	     * Returns a Date object with time and date that represent a specific moment in Browser (device) timezone.
5975	     *
5976	     * @param utcTimestamp - normal utc timestamp in seconds. 'now' by default
5977	     * @returns {Date}
5978	     */
5979	    value: function getDate(utcTimestamp = null) {
5980	      const timestamp = main_core.Type.isNumber(utcTimestamp) ? utcTimestamp : this.getTimestamp();
5981	      return createDateFromTimestamp(timestamp);
5982	    }
5983	    /**
5984	     * Transforms a moment in Browser (device) timezone to a moment in User timezone.
5985	     *
5986	     * ATTENTION! Date.getTime() and Date.getTimezoneOffset() will return inaccurate data. Since a native Date object
5987	     * doesn't support timezone other that device timezone, we have to manually change timestamp to shift time value in
5988	     * a Date object.
5989	     *
5990	     * @param browserTime - a moment in Browser (device) timezone. Either a Date object (recommended way). Or timestamp
5991	     * in seconds in Browser timezone (see this.getTimestamp for details).
5992	     * @returns {Date}
5993	     */
5994	  }, {
5995	    key: "toUserDate",
5996	    value: function toUserDate(browserTime) {
5997	      return createDateFromTimestamp(this.toUser(browserTime));
5998	    }
5999	    /**
6000	     * Transforms a moment in Browser (device) timezone to a moment in Server timezone.
6001	     *
6002	     * ATTENTION! Date.getTime() and Date.getTimezoneOffset() will return inaccurate data. Since a native Date object
6003	     * doesn't support timezone other that device timezone, we have to manually change timestamp to shift time value in
6004	     * a Date object.
6005	     *
6006	     * @param browserTime - a moment in Browser (device) timezone. Either a Date object (recommended way). Or timestamp
6007	     * in seconds in Browser timezone (see this.getTimestamp for details).
6008	     * @returns {Date}
6009	     */
6010	  }, {
6011	    key: "toServerDate",
6012	    value: function toServerDate(browserTime) {
6013	      return createDateFromTimestamp(this.toServer(browserTime));
6014	    }
6015	    /**
6016	     * Transforms a moment in Browser (device) timezone to a timestamp in User timezone.
6017	     * It's recommended to use this.toUserDate for more clear code.
6018	     *
6019	     * @param browserTime - a moment in Browser timezone. Either a Date object (recommended way). Or timestamp in seconds
6020	     * in Browser timezone (see this.getTimestamp for details).
6021	     * @returns {number} - timestamp that when passed to 'new Date' will create an object with absolute time matching
6022	     * the time in User timezone
6023	     */
6024	  }, {
6025	    key: "toUser",
6026	    value: function toUser(browserTime) {
6027	      return this.toServer(browserTime) + getOffset().USER_TO_SERVER;
6028	    }
6029	    /**
6030	     * Transforms a moment in Browser (device) timezone to a timestamp in Server timezone.
6031	     * It's recommended to use this.toServerDate for more clear code.
6032	     *
6033	     * @param browserTime - a moment in Browser timezone. Either a Date object (recommended way). Or timestamp in seconds
6034	     * in Browser timezone (see this.getTimestamp for details).
6035	     * @returns {number} - timestamp that when passed to 'new Date' will create an object with absolute time matching
6036	     * the time in Server timezone
6037	     */
6038	  }, {
6039	    key: "toServer",
6040	    value: function toServer(browserTime) {
6041	      return normalizeTimeValue(browserTime) - getOffset().BROWSER_TO_UTC + getOffset().SERVER_TO_UTC;
6042	    }
6043	    /**
6044	     * Returns 'now' timestamp in Browser (device) timezone - when it's passed to a 'new Date', it will create an object
6045	     * with absolute time matching the time as if it was in Browser (device) timezone.
6046	     *
6047	     * @returns {number}
6048	     */
6049	  }, {
6050	    key: "getTimestamp",
6051	    value: function getTimestamp() {
6052	      // since 'Date' class in JS is hardcoded to use device timezone, 'browser timestamp' is just normal UTC timestamp :)
6053
6054	      return getNowTimestamp();
6055	    }
6056	  }]);
6057	  return BrowserTime;
6058	}();
6059
6060	/**
6061	 * @memberOf BX.Main.Timezone
6062	 *
6063	 * WARNING! Don't use this class or any classes from Timezone namespace on sites without Bitrix Framework.
6064	 * It is not designed to handle this case and will definitely break.
6065	 */
6066	let ServerTime = /*#__PURE__*/function () {
6067	  function ServerTime() {
6068	    babelHelpers.classCallCheck(this, ServerTime);
6069	  }
6070	  babelHelpers.createClass(ServerTime, null, [{
6071	    key: "getDate",
6072	    /**
6073	     * Returns a Date object with time and date that represent a specific moment in Server timezone.
6074	     *
6075	     * ATTENTION! Date.getTime() and Date.getTimezoneOffset() will return inaccurate data. Since a native Date object
6076	     * doesn't support timezone other that device timezone, we have to manually change timestamp to shift time value in
6077	     * a Date object.
6078	     *
6079	     * @param utcTimestamp - normal utc timestamp in seconds. 'now' by default
6080	     * @returns {Date}
6081	     */
6082	    value: function getDate(utcTimestamp = null) {
6083	      if (main_core.Type.isNumber(utcTimestamp)) {
6084	        const browserToServerOffset = getOffset().SERVER_TO_UTC - getOffset().BROWSER_TO_UTC;
6085	        return createDateFromTimestamp(utcTimestamp + browserToServerOffset);
6086	      }
6087	      return BrowserTime.toServerDate(BrowserTime.getDate());
6088	    }
6089	    /**
6090	     * Transforms a moment in Server timezone to a moment in User timezone.
6091	     *
6092	     * ATTENTION! Date.getTime() and Date.getTimezoneOffset() will return inaccurate data. Since a native Date object
6093	     * doesn't support timezone other that device timezone, we have to manually change timestamp to shift time value in
6094	     * a Date object.
6095	     *
6096	     * @param serverTime - a moment in Server timezone. Either a Date object (recommended way). Or timestamp in seconds 
6096in
6097	     * Server timezone (see this.getTimestamp for details).
6098	     * @returns {Date}
6099	     */
6100	  }, {
6101	    key: "toUserDate",
6102	    value: function toUserDate(serverTime) {
6103	      return createDateFromTimestamp(this.toUser(serverTime));
6104	    }
6105	    /**
6106	     * Transforms a moment in Server timezone to a moment in Browser (device) timezone.
6107	     *
6108	     * @param serverTime - a moment in Server timezone. Either a Date object (recommended way). Or timestamp in seconds in
6109	     * Server timezone (see this.getTimestamp for details).
6110	     * @returns {Date}
6111	     */
6112	  }, {
6113	    key: "toBrowserDate",
6114	    value: function toBrowserDate(serverTime) {
6115	      return createDateFromTimestamp(this.toBrowser(serverTime));
6116	    }
6117	    /**
6118	     * Transforms a moment in Server timezone to a timestamp in User timezone.
6119	     * It's recommended to use this.toServerDate for more clear code.
6120	     *
6121	     * @param serverTime - a moment in Server timezone. Either a Date object (recommended way). Or timestamp in seconds in
6122	     * Server timezone (see this.getTimestamp for details).
6123	     * @returns {number} - timestamp that when passed to 'new Date' will create an object with absolute time matching
6124	     * the time in User timezone
6125	     */
6126	  }, {
6127	    key: "toUser",
6128	    value: function toUser(serverTime) {
6129	      return normalizeTimeValue(serverTime) + getOffset().USER_TO_SERVER;
6130	    }
6131	    /**
6132	     * Transforms a moment in Server timezone to a timestamp in Browser (device) timezone.
6133	     * It's recommended to use this.toBrowserDate for more clear code.
6134	     *
6135	     * @param serverTime - a moment in Server timezone. Either a Date object (recommended way). Or timestamp in seconds in
6136	     * Server timezone (see this.getTimestamp for details).
6137	     * @returns {number} - timestamp that when passed to 'new Date' will create an object with absolute time matching
6138	     * the time in Browser (device) timezone
6139	     */
6140	  }, {
6141	    key: "toBrowser",
6142	    value: function toBrowser(serverTime) {
6143	      return normalizeTimeValue(serverTime) + getOffset().BROWSER_TO_UTC - getOffset().SERVER_TO_UTC;
6144	    }
6145	    /**
6146	     * Returns 'now' timestamp in Server timezone - when it's passed to a 'new Date', it will create an object with
6147	     * absolute time matching the time as if it was in Server timezone.
6148	     *
6149	     * @returns {number}
6150	     */
6151	  }, {
6152	    key: "getTimestamp",
6153	    value: function getTimestamp() {
6154	      return BrowserTime.toServer(BrowserTime.getTimestamp());
6155	    }
6156	  }]);
6157	  return ServerTime;
6158	}();
6159
6160	function _classStaticPrivateFieldSpecGet(receiver, classConstructor, descriptor) { _classCheckPrivateStaticAccess(receiver, classConstructor); _classCheckPrivateStaticFieldDescriptor(descriptor, "get"); return _classApplyDescriptorGet(receiver, descriptor); }
6161	function _classCheckPrivateStaticFieldDescriptor(descriptor, action) { if (descriptor === undefined) { throw new TypeError("attempted to " + action + " private static field before its declaration"); } }
6162	function _classCheckPrivateStaticAccess(receiver, classConstructor) { if (receiver !== classConstructor) { throw new TypeError("Private static access of wrong provenance"); } }
6163	function _classApplyDescriptorGet(receiver, descriptor) { if (descriptor.get) { return descriptor.get.call(receiver); } return descriptor.value; }
6164
6165	/**
6166	 * @memberOf BX.Main.Timezone
6167	 *
6168	 * WARNING! Don't use this class or any classes from Timezone namespace on sites without Bitrix Framework.
6169	 * It is not designed to handle this case and will definitely break.
6170	 *
6171	 * ATTENTION! In Bitrix user timezone !== browser timezone. Users can change their timezone from their profile settings
6172	 * and the timezone will be different from browser timezone.
6173	 */
6174	let UserTime = /*#__PURE__*/function () {
6175	  function UserTime() {
6176	    babelHelpers.classCallCheck(this, UserTime);
6177	  }
6178	  babelHelpers.createClass(UserTime, null, [{
6179	    key: "getDate",
6180	    /**
6181	     * Returns a Date object with time and date that represent a specific moment in User timezone.
6182	     *
6183	     * ATTENTION! Date.getTime() and Date.getTimezoneOffset() will return inaccurate data. Since a native Date object
6184	     * doesn't support timezone other that device timezone, we have to manually change timestamp to shift time value in
6185	     * a Date object.
6186	     *
6187	     * @param utcTimestamp - normal utc timestamp in seconds. 'now' by default
6188	     * @returns {Date}
6189	     */
6190	    value: function getDate(utcTimestamp = null) {
6191	      if (main_core.Type.isNumber(utcTimestamp)) {
6192	        return createDateFromTimestamp(utcTimestamp + _classStaticPrivateFieldSpecGet(this, UserTime, _userToBrowserOffset));
6193	      }
6194	      return createDateFromTimestamp(this.getTimestamp());
6195	    }
6196	  }, {
6197	    key: "toBrowserDate",
6198	    /**
6199	     * Transforms a moment in User timezone to a moment in Browser (device) timezone.
6200	     *
6201	     * @param userTime - a moment in User timezone. Either a Date object (recommended way). Or timestamp in seconds 
6201in
6202	     * User timezone (see this.getTimestamp for details).
6203	     * @returns {Date}
6204	     */
6205	    value: function toBrowserDate(userTime) {
6206	      return createDateFromTimestamp(this.toBrowser(userTime));
6207	    }
6208	    /**
6209	     * Transforms a moment in User timezone to a moment in Server timezone.
6210	     *
6211	     * ATTENTION! Date.getTime() and Date.getTimezoneOffset() will return inaccurate data. Since a native Date object
6212	     * doesn't support timezone other that device timezone, we have to manually change timestamp to shift time value in
6213	     * a Date object.
6214	     *
6215	     * @param userTime - a moment in User timezone. Either a Date object (recommended way). Or timestamp in seconds in
6216	     * User timezone (see this.getTimestamp for details).
6217	     * @returns {Date}
6218	     */
6219	  }, {
6220	    key: "toServerDate",
6221	    value: function toServerDate(userTime) {
6222	      return createDateFromTimestamp(this.toServer(userTime));
6223	    }
6224	  }, {
6225	    key: "toUTCTimestamp",
6226	    value: function toUTCTimestamp(userTime) {
6227	      return normalizeTimeValue(userTime) - _classStaticPrivateFieldSpecGet(this, UserTime, _userToBrowserOffset);
6228	    }
6229	    /**
6230	     * Transforms a moment in User timezone to a timestamp in Browser timezone.
6231	     * It's recommended to use this.toBrowserDate for more clear code.
6232	     *
6233	     * @param userTime - a moment in User timezone. Either a Date object (recommended way). Or timestamp in seconds in
6234	     * User timezone (see this.getTimestamp for details).
6235	     * @returns {number} - timestamp that when passed to 'new Date' will create an object with absolute time matching
6236	     * the time in Browser (device) timezone
6237	     */
6238	  }, {
6239	    key: "toBrowser",
6240	    value: function toBrowser(userTime) {
6241	      return normalizeTimeValue(userTime) + getOffset().BROWSER_TO_UTC - getOffset().SERVER_TO_UTC - getOffset().USER_TO_SERVER;
6242	    }
6243	    /**
6244	     * Transforms a moment in User timezone to a timestamp in Server timezone.
6245	     * It's recommended to use this.toServerDate for more clear code.
6246	     *
6247	     * @param userTime - a moment in User timezone. Either a Date object (recommended way). Or timestamp in seconds in
6248	     * User timezone (see this.getTimestamp for details).
6249	     * @returns {number} - timestamp that when passed to 'new Date' will create an object with absolute time matching
6250	     * the time in Server timezone
6251	     */
6252	  }, {
6253	    key: "toServer",
6254	    value: function toServer(userTime) {
6255	      return normalizeTimeValue(userTime) - getOffset().USER_TO_SERVER;
6256	    }
6257	    /**
6258	     * Returns 'now' timestamp in User timezone - when it's passed to a 'new Date', it will create an object with absolute
6259	     * time matching the time as if it was in User timezone.
6260	     *
6261	     * @returns {number}
6262	     */
6263	  }, {
6264	    key: "getTimestamp",
6265	    value: function getTimestamp() {
6266	      return BrowserTime.toUser(BrowserTime.getTimestamp());
6267	    }
6268	  }]);
6269	  return UserTime;
6270	}();
6271	function _get_userToBrowserOffset() {
6272	  const userToUTCOffset = getOffset().SERVER_TO_UTC + getOffset().USER_TO_SERVER;
6273	  return userToUTCOffset - getOffset().BROWSER_TO_UTC;
6274	}
6275	var _userToBrowserOffset = {
6276	  get: _get_userToBrowserOffset,
6277	  set: void 0
6278	};
6279
6280	const Timezone = Object.freeze({
6281	  BrowserTime,
6282	  Offset,
6283	  ServerTime,
6284	  UserTime
6285	});
6286
6287	exports.Timezone = Timezone;
6288	exports.Date = DateTimeFormat;
6289	exports.DateTimeFormat = DateTimeFormat;
6290	exports.DurationFormat = DurationFormat;
6291
6292}((this.BX.Main = this.BX.Main || {}),BX));
6293//# sourceMappingURL=main.date.js.map
6294
6295/* End */
6296;
6297; /* Start:"a:4:{s:4:"full";s:49:"/bitrix/js/main/core/core_date.js?161544141136080";s:6:"source";s:33:"/bitrix/js/main/core/core_date.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
6298;(function(){
6299
6300if (BX.date)
6301	return;
6302
6303BX.date = BX.Main.Date;
6304
6305/************************************** calendar class **********************************/
6306
6307var obCalendarSingleton = null;
6308
6309/*
6310params: {
6311	node: bind element || document.body
6312
6313	value - start value in site format (using 'field' param if 'value' does not exist)
6314	callback - date check handler. can return false to prevent calendar closing.
6315	callback_after - another handler, called after date picking
6316
6317	field - field to read/write data
6318
6319	bTime = true - whether to enable time control
6320	bHideTime = false - whether to hide time control by default
6321
6322	currentTime - current UTC time()
6323
6324}
6325*/
6326
6327
6328BX.calendar = function(params)
6329{
6330	return BX.calendar.get().Show(params);
6331};
6332
6333BX.calendar.get = function()
6334{
6335	if (!obCalendarSingleton)
6336		obCalendarSingleton = new BX.JCCalendar();
6337
6338	return obCalendarSingleton;
6339};
6340
6341// simple func for compatibility with the oldies
6342BX.calendar.InsertDaysBack = function(input, days)
6343{
6344	if (days != '')
6345	{
6346		var d = new Date();
6347		if(days > 0)
6348		{
6349			d.setTime(d.valueOf() - days*86400000);
6350		}
6351
6352		input.value = BX.date.format(BX.date.convertBitrixFormat(BX.message('FORMAT_DATE')), d, null);
6353	}
6354	else
6355	{
6356		input.value = '';
6357	}
6358};
6359
6360BX.calendar.ValueToString = function(value, bTime, bUTC)
6361{
6362	return BX.date.format(
6363		BX.date.convertBitrixFormat(BX.message(bTime ? 'FORMAT_DATETIME' : 'FORMAT_DATE')),
6364		value,
6365		null,
6366		!!bUTC
6367	);
6368};
6369
6370BX.calendar.ValueToStringFormat = function(value, bitrixFormat, bUTC)
6371{
6372	return BX.date.format(
6373		BX.date.convertBitrixFormat(bitrixFormat),
6374		value,
6375		null,
6376		!!bUTC
6377	);
6378};
6379
6380
6381BX.CalendarPeriod =
6382{
6383	Init: function(inputFrom, inputTo, selPeriod)
6384	{
6385		if((inputFrom.value != "" || inputTo.value != "") && selPeriod.value == "")
6386			selPeriod.value = "interval";
6387
6388		selPeriod.onchange();
6389	},
6390
6391	ChangeDirectOpts: function(peroidValue, selPParent) // "week" || "others"
6392	{
6393		var selDirect = BX.findChild(selPParent, {'className':'adm-select adm-calendar-direction'}, true);
6394
6395		if(peroidValue == "week")
6396		{
6397			selDirect.options[0].text = BX.message('JSADM_CALEND_PREV_WEEK');
6398			selDirect.options[1].text = BX.message('JSADM_CALEND_CURR_WEEK');
6399			selDirect.options[2].text = BX.message('JSADM_CALEND_NEXT_WEEK');
6400		}
6401		else
6402		{
6403			selDirect.options[0].text = BX.message('JSADM_CALEND_PREV');
6404			selDirect.options[1].text = BX.message('JSADM_CALEND_CURR');
6405			selDirect.options[2].text = BX.message('JSADM_CALEND_NEXT');
6406		}
6407	},
6408
6409	SaveAndClearInput: function(oInput)
6410	{
6411		if(!window.SavedPeriodValues)
6412			window.SavedPeriodValues = {};
6413
6414		window.SavedPeriodValues[oInput.id] = oInput.value;
6415		oInput.value="";
6416	},
6417
6418	RestoreInput: function(oInput)
6419	{
6420		if(!window.SavedPeriodValues || !window.SavedPeriodValues[oInput.id])
6421			return;
6422
6423		oInput.value = window.SavedPeriodValues[oInput.id];
6424		delete(window.SavedPeriodValues[oInput.id]);
6425	},
6426
6427	OnChangeP: function(sel)
6428	{
6429		var selPParent = sel.parentNode.parentNode;
6430		var bShowFrom, bShowTo, bShowDirect, bShowSeparate;
6431		bShowFrom = bShowTo = bShowDirect = bShowSeparate = false;
6432
6433		var inputFromWrap = BX.findChild(selPParent, {'className':'adm-input-wrap adm-calendar-inp adm-calendar-first'});
6434		var inputToWrap = BX.findChild(selPParent, {'className':'adm-input-wrap adm-calendar-second'});
6435		var selDirectWrap = BX.findChild(selPParent, {'className':'adm-select-wrap adm-calendar-direction'});
6436		var separator = BX.findChild(selPParent, {'className':'adm-calendar-separate'});
6437		var inputFrom = BX.findChild(selPParent, {'className':'adm-input adm-calendar-from'},true);
6438		var inputTo = BX.findChild(selPParent, {'className':'adm-input adm-calendar-to'},true);
6439
6440		// define who must be shown
6441		switch (sel.value)
6442		{
6443			case "day":
6444			case "week":
6445			case "month":
6446			case "quarter":
6447			case "year":
6448				bShowDirect=true;
6449				BX.CalendarPeriod.OnChangeD(selDirectWrap.children[0]);
6450				break;
6451
6452			case "before":
6453				bShowTo = true;
6454				break;
6455
6456			case "after":
6457				bShowFrom = true;
6458				break;
6459
6460			case "exact":
6461				bShowFrom= true;
6462				break;
6463
6464			case "interval":
6465				bShowFrom = bShowTo = bShowSeparate = true;
6466				BX.CalendarPeriod.RestoreInput(inputFrom);
6467				BX.CalendarPeriod.RestoreInput(inputTo);
6468
6469				break;
6470
6471			case "":
6472				BX.CalendarPeriod.SaveAndClearInput(inputFrom);
6473				BX.CalendarPeriod.SaveAndClearInput(inputTo);
6474				break;
6475
6476			default:
6477				break;
6478
6479		}
6480
6481		BX.CalendarPeriod.ChangeDirectOpts(sel.value, selPParent);
6482
6483		inputFromWrap.style.display = (bShowFrom? 'inline-block':'none');
6484		inputToWrap.style.display = (bShowTo? 'inline-block':'none');
6485		selDirectWrap.style.display = (bShowDirect? 'inline-block':'none');
6486		separator.style.display = (bShowSeparate? 'inline-block':'none');
6487	},
6488
6489
6490	OnChangeD: function(sel)
6491	{
6492		var selPParent = sel.parentNode.parentNode;
6493		var inputFrom = BX.findChild(selPParent, {'className':'adm-input adm-calendar-from'},true);
6494		var inputTo = BX.findChild(selPParent, {'className':'adm-input adm-calendar-to'},true);
6495		var selPeriod = BX.findChild(selPParent, {'className':'adm-select adm-calendar-period'},true);
6496
6497		var offset=0;
6498
6499		switch (sel.value)
6500		{
6501			case "previous":
6502				offset = -1;
6503				break;
6504
6505			case "next":
6506				offset = 1;
6507				break;
6508
6509			case "current":
6510			default:
6511				break;
6512
6513		}
6514
6515		var from = false;
6516		var to = false;
6517
6518		var today = new Date();
6519		var year = today.getFullYear();
6520		var month = today.getMonth();
6521		var day = today.getDate();
6522		var dayW = today.getDay();
6523
6524		if (dayW == 0)
6525				dayW = 7;
6526
6527		switch (selPeriod.value)
6528		{
6529			case "day":
6530				from = new Date(year, month, day+offset, 0, 0, 0);
6531				to = new Date(year, month, day+offset, 23, 59, 59);
6532				break;
6533
6534			case "week":
6535				from = new Date(year, month, day-dayW+1+offset*7, 0, 0, 0);
6536				to = new Date(year, month, day+(7-dayW)+offset*7, 23, 59, 59);
6537				break;
6538
6539			case "month":
6540				from = new Date(year, month+offset, 1, 0, 0, 0);
6541				to = new Date(year, month+1+offset, 0, 23, 59, 59);
6542				break;
6543
6544			case "quarter":
6545				var quarterNum = Math.floor((month/3))+offset;
6546				from = new Date(year, 3*(quarterNum), 1, 0, 0, 0);
6547				to = new Date(year, 3*(quarterNum+1), 0, 23, 59, 59);
6548				break;
6549
6550			case "year":
6551				from = new Date(year+offset, 0, 1, 0, 0, 0);
6552				to = new Date(year+1+offset, 0, 0, 23, 59, 59);
6553				break;
6554
6555			default:
6556				break;
6557		}
6558
6559		var format = window[inputFrom.name+"_bTime"] ? BX.message('FORMAT_DATETIME') : BX.message('FORMAT_DATE');
6560
6561		if(from)
6562		{
6563			inputFrom.value = BX.formatDate(from, format);
6564			BX.addClass(inputFrom,"adm-calendar-inp-setted");
6565		}
6566
6567		if(to)
6568		{
6569			inputTo.value = BX.formatDate(to, format);
6570			BX.addClass(inputTo,"adm-calendar-inp-setted");
6571		}
6572	}
6573};
6574
6575
6576BX.JCCalendar = function()
6577{
6578	this.params = {};
6579
6580	this.bAmPm = BX.isAmPmMode();
6581
6582	this.popup = null;
6583	this.popup_month = null;
6584	this.popup_year = null;
6585	this.month_popup_classname = '';
6586	this.year_popup_classname = '';
6587	this.value = null;
6588	this._layers = {};
6589	this._current_layer = null;
6590
6591	this.DIV = null;
6592	this.PARTS = {};
6593
6594	this.weekStart = 0;
6595	this.numRows = 6;
6596
6597	this._create = function(params)
6598	{
6599		this.popup = new BX.PopupWindow('calendar_popup_' + Math.random(), params.node, {
6600			closeByEsc: true,
6601			autoHide: false,
6602			content: this._get_content(),
6603			bindOptions: {forceBindPosition: true}
6604		});
6605
6606		BX.bind(this.popup.popupContainer, 'click', function(event) {
6607			event.stopPropagation();
6608		});
6609	};
6610
6611	this._auto_hide_disable = function()
6612	{
6613		BX.unbind(document, 'click', BX.proxy(this._auto_hide, this));
6614	};
6615
6616	this._auto_hide_enable = function()
6617	{
6618		BX.bind(document, 'click', BX.proxy(this._auto_hide, this));
6619	};
6620
6621	this._auto_hide = function(e)
6622	{
6623		this._auto_hide_disable();
6624		this.popup.close();
6625	};
6626
6627	this._get_content = function()
6628	{
6629		var _layer_onclick = BX.delegate(function(e) {
6630			e = e||window.event;
6631			this.SetDate(
6632				new Date(parseInt(BX.proxy_context.getAttribute('data-date'))),
6633				(e.type === 'dblclick' || (this.params.bCompatibility && !this.params.bTimeVisibility))
6634			)
6635		}, this);
6636
6637		this.DIV = BX.create('DIV', {
6638			props: {className: 'bx-calendar'},
6639			children: [
6640				BX.create('DIV', {
6641					props: {
6642						className: 'bx-calendar-header'
6643					},
6644					children: [
6645						BX.create('A', {
6646							attrs: {href: 'javascript:void(0)'},
6647							props: {className: 'bx-calendar-left-arrow'},
6648							events: {click: BX.proxy(this._prev, this)}
6649						}),
6650
6651						BX.create('SPAN', {
6652							props: {className: 'bx-calendar-header-content'},
6653							children: [
6654								(this.PARTS.MONTH = BX.create('A', {
6655									attrs: {href: 'javascript:void(0)'},
6656									props: {className: 'bx-calendar-top-month'},
6657									events: {click: BX.proxy(this._menu_month, this)}
6658								})),
6659
6660								(this.PARTS.YEAR = BX.create('A', {
6661									attrs: {href: 'javascript:void(0)'},
6662									props: {className: 'bx-calendar-top-year'},
6663									events: {click: BX.proxy(this._menu_year, this)}
6664								}))
6665							]
6666						}),
6667
6668						BX.create('A', {
6669							attrs: {href: 'javascript:void(0)'},
6670							props: {className: 'bx-calendar-right-arrow'},
6671							events: {click: BX.proxy(this._next, this)}
6672						})
6673					]
6674				}),
6675
6676				(this.PARTS.WEEK = BX.create('DIV', {
6677					props: {
6678						className: 'bx-calendar-name-day-wrap'
6679					}
6680				})),
6681
6682				(this.PARTS.LAYERS = BX.create('DIV', {
6683					props: {
6684						className: 'bx-calendar-cell-block'
6685					},
6686					events: {
6687						click: BX.delegateEvent({className: 'bx-calendar-cell'}, _layer_onclick),
6688						dblclick: BX.delegateEvent({className: 'bx-calendar-cell'}, _layer_onclick)
6689					}
6690				})),
6691
6692				(this.PARTS.TIME = BX.create('DIV', {
6693					props: {
6694						className: 'bx-calendar-set-time-wrap'
6695					},
6696					events: {
6697						click: BX.delegateEvent(
6698							{attr: 'data-action'},
6699							BX.delegate(this._time_actions, this)
6700						)
6701					},
6702					html: '<a href="javascript:void(0)" data-action="time_show" class="bx-calendar-set-time"><i></i>'+BX.message('CAL_TIME_SET')+'</a><div class="bx-calendar-form-block"><span class="bx-calendar-form-text">'+BX.message('CAL_TIME')+'</span><span class="bx-calendar-form"><input type="text" class="bx-calendar-form-input" maxwidth="2" onkeyup="BX.calendar.get()._check_time()" /><span class="bx-calendar-form-separator"></span><input type="text" class="bx-calendar-form-input" maxwidth="2" onkeyup="BX.calendar.get()._check_time()" />'+(this.bAmPm?'<span class="bx-calendar-AM-PM-block"><span class="bx-calendar-AM-PM-text" data-action="time_ampm"></span><span class="bx-calendar-form-arrow-r"><a href="javascript:void(0)" class="bx-calendar-form-arrow-top" data-action="time_ampm_up"><i></i></a><a href="javascript:void(0)" class="bx-calendar-form-arrow-bottom" data-action="time_ampm_down"><i></i></a></span></span>':'')+'</span><a href="javascript:void(0)" data-action="time_hide" class="bx-calendar-form-close"><i></i></a></div>'
6703				})),
6704
6705				(this.PARTS.BUTTONS = BX.create('DIV', {
6706					props: {className: 'bx-calendar-button-block'},
6707					events: {
6708						click: BX.delegateEvent(
6709							{attr: 'data-action'},
6710							BX.delegate(this._button_actions, this)
6711						)
6712					},
6713					html: '<a href="javascript:void(0)" class="bx-calendar-button bx-calendar-button-select" data-action="submit"><span class="bx-calendar-button-left"></span><span class="bx-calendar-button-text">'+BX.message('CAL_BUTTON')+'</span><span class="bx-calendar-button-right"></span></a><a href="javascript:void(0)" class="bx-calendar-button bx-calendar-button-cancel" data-action="cancel"><span class="bx-calendar-button-left"></span><span class="bx-calendar-button-text">'+BX.message('JS_CORE_WINDOW_CLOSE')+'</span><span class="bx-calendar-button-right"></span></a>'
6714				}))
6715			]
6716		});
6717
6718		this.PARTS.TIME_INPUT_H = BX.findChild(this.PARTS.TIME, {tag: 'INPUT'}, true);
6719		this.PARTS.TIME_INPUT_M = this.PARTS.TIME_INPUT_H.nextSibling.nextSibling;
6720
6721		if (this.bAmPm)
6722			this.PARTS.TIME_AMPM = this.PARTS.TIME_INPUT_M.nextSibling.firstChild;
6723
6724		var spinner = (new BX.JCSpinner({
6725			input: this.PARTS.TIME_INPUT_H,
6726			callback_change: BX.proxy(this._check_time, this),
6727			bSaveValue: false
6728		})).Show();
6729		spinner.className = 'bx-calendar-form-arrow-l';
6730		this.PARTS.TIME_INPUT_H.parentNode.insertBefore(spinner, this.PARTS.TIME_INPUT_H);
6731
6732		spinner = (new BX.JCSpinner({
6733			input: this.PARTS.TIME_INPUT_M,
6734			callback_change: BX.proxy(this._check_time, this),
6735			bSaveValue: true
6736		})).Show();
6737		spinner.className = 'bx-calendar-form-arrow-r';
6738		if (!this.PARTS.TIME_INPUT_M.nextSibling)
6739			this.PARTS.TIME_INPUT_M.parentNode.appendChild(spinner);
6740		else
6741			this.PARTS.TIME_INPUT_M.parentNode.insertBefore(spinner, this.PARTS.TIME_INPUT_M.nextSibling);
6742
6743		for (var i = 0; i < 7; i++)
6744		{
6745			this.PARTS.WEEK.appendChild(BX.create('SPAN', {
6746				props: {
6747					className: 'bx-calendar-name-day'
6748				},
6749				text: BX.message('DOW_' + ((i + this.weekStart) % 7))
6750			}));
6751		}
6752
6753		return this.DIV;
6754	};
6755
6756	this._time_actions = function()
6757	{
6758		switch (BX.proxy_context.getAttribute('data-action'))
6759		{
6760			case 'time_show':
6761				BX.addClass(this.PARTS.TIME, 'bx-calendar-set-time-opened');
6762				if (this.params.bCompatibility)
6763				{
6764					BX.removeClass(this.PARTS.BUTTONS, 'bx-calendar-buttons-disabled');
6765				}
6766				this.popup.adjustPosition();
6767			break;
6768			case 'time_hide':
6769				BX.removeClass(this.PARTS.TIME, 'bx-calendar-set-time-opened');
6770				if (this.params.bCompatibility)
6771				{
6772					this._saveChoice('hide');
6773					BX.addClass(this.PARTS.BUTTONS, 'bx-calendar-buttons-disabled');
6774				}
6775				this.popup.adjustPosition();
6776			break;
6777			case 'time_ampm':
6778				this.PARTS.TIME_AMPM.innerHTML = this.PARTS.TIME_AMPM.innerHTML == 'AM' ? 'PM' : 'AM';
6779			break;
6780			case 'time_ampm_up':
6781				this._check_time({bSaveValue: false}, null, 12);
6782				return;
6783			break;
6784			case 'time_ampm_down':
6785				this._check_time({bSaveValue: false}, null, -12);
6786				return;
6787			break;
6788		}
6789
6790		this._check_time();
6791	};
6792
6793	this._button_actions = function()
6794	{
6795		switch (BX.proxy_context.getAttribute('data-action'))
6796		{
6797			case 'submit':
6798				if (this.params.bCompatibility)
6799				{
6800					this._saveChoice('show');
6801				}
6802				this.SaveValue();
6803			break;
6804			case 'cancel':
6805				this.Close();
6806			break;
6807		}
6808	};
6809
6810	this._saveChoice = function(state)
6811	{
6812		if (this.params.bCategoryTimeVisibilityOption)
6813		{
6814			BX.userOptions.save(
6815				this.params.bCategoryTimeVisibilityOption,
6816				this.params.bNameTimeVisibilityOption,
6817				'visibility',
6818				(state === 'show' ? 'Y' : 'N')
6819			);
6820		}
6821
6822		this._bTimeVisibility = (state === 'show');
6823		this.params.bTimeVisibility = this._bTimeVisibility;
6824	};
6825
6826	this._check_time = function(params, value, direction)
6827	{
6828		var h = parseInt(this.PARTS.TIME_INPUT_H.value.substring(0,5),10)||0,
6829			m = parseInt(this.PARTS.TIME_INPUT_M.value.substring(0,5),10)||0,
6830			bChanged = false;
6831
6832		if (!!params && !params.bSaveValue)
6833		{
6834			this.value.setUTCHours(this.value.getUTCHours() + direction);
6835		}
6836		else if (!isNaN(h))
6837		{
6838			if (this.bAmPm)
6839			{
6840				if (h != 12 && this.PARTS.TIME_AMPM.innerHTML == 'PM')
6841				{
6842					h += 12;
6843				}
6844			}
6845
6846			bChanged = true;
6847			this.value.setUTCHours(h % 24);
6848		}
6849
6850		if (!isNaN(m))
6851		{
6852			bChanged = true;
6853			this.value.setUTCMinutes(m % 60);
6854		}
6855
6856		if (bChanged)
6857		{
6858			this.SetValue(this.value);
6859		}
6860	};
6861
6862	this._set_layer = function()
6863	{
6864		var layerId = parseInt(this.value.getUTCFullYear() + '' + BX.util.str_pad_left(this.value.getUTCMonth()+'', 2, "0"));
6865
6866		if (!this._layers[layerId])
6867		{
6868			this._layers[layerId] = this._create_layer();
6869			this._layers[layerId].BXLAYERID = layerId;
6870		}
6871
6872		if (this._current_layer)
6873		{
6874			var v = new Date(this.value.valueOf());
6875			v.setUTCHours(0); v.setUTCMinutes(0);
6876
6877			var cur_value = BX.findChild(this._layers[layerId], {
6878					tag: 'A',
6879					className: 'bx-calendar-active'
6880				}, true),
6881				new_value = BX.findChild(this._layers[layerId], {
6882					tag: 'A',
6883					attr: {
6884						'data-date' : v.valueOf() + ''
6885					}
6886				}, true);
6887
6888			if (cur_value)
6889			{
6890				BX.removeClass(cur_value, 'bx-calendar-active');
6891			}
6892
6893			if (new_value)
6894			{
6895				BX.addClass(new_value, 'bx-calendar-active');
6896			}
6897
6898			this._replace_layer(this._current_layer, this._layers[layerId]);
6899		}
6900		else
6901		{
6902			this.PARTS.LAYERS.appendChild(this._layers[layerId]);
6903		}
6904
6905		this._current_layer = this._layers[layerId];
6906	};
6907
6908	this._replace_layer = function(old_layer, new_layer)
6909	{
6910		if (old_layer != new_layer)
6911		{
6912			if (!BX.browser.IsIE() || BX.browser.IsDoctype())
6913			{
6914				var dir = old_layer.BXLAYERID > new_layer.BXLAYERID ? 1 : -1;
6915
6916				var old_top = 0;
6917				var new_top = -dir * old_layer.offsetHeight;
6918
6919				old_layer.style.position = 'relative';
6920				old_layer.style.top = "0px";
6921				old_layer.style.zIndex = 5;
6922
6923				new_layer.style.position = 'absolute';
6924				new_layer.style.top = new_top + 'px';
6925				new_layer.style.zIndex = 6;
6926
6927				this.PARTS.LAYERS.appendChild(new_layer);
6928
6929				var delta = 15;
6930
6931				var f;
6932				(f = function() {
6933					new_top += dir * delta;
6934					old_top += dir * delta;
6935
6936					if (dir * new_top < 0)
6937					{
6938						old_layer.style.top = old_top + 'px';
6939						new_layer.style.top = new_top + 'px';
6940						setTimeout(f, 10);
6941					}
6942					else
6943					{
6944						old_layer.parentNode.removeChild(old_layer);
6945
6946						new_layer.style.top = "0px";
6947						new_layer.style.position = 'static';
6948						new_layer.style.zIndex = 0;
6949					}
6950				})();
6951			}
6952			else
6953			{
6954				this.PARTS.LAYERS.replaceChild(new_layer, old_layer);
6955			}
6956		}
6957	};
6958
6959	this._create_layer = function()
6960	{
6961		var l = BX.create('DIV', {
6962			props: {
6963				className: 'bx-calendar-layer'
6964			}
6965		});
6966
6967		var month_start = new Date(this.value);
6968		month_start.setUTCHours(0);
6969		month_start.setUTCMinutes(0);
6970
6971		month_start.setUTCDate(1);
6972
6973		if (month_start.getUTCDay() != this.weekStart)
6974		{
6975			var d = month_start.getUTCDay() - this.weekStart;
6976			d += d < 0 ? 7 : 0;
6977			month_start.setUTCDate(month_start.getUTCDate()-d);
6978		}
6979
6980		var cur_month = this.value.getUTCMonth(),
6981			cur_day = this.value.getUTCDate(),
6982			s = '';
6983		for (var i = 0; i < this.numRows; i++)
6984		{
6985			s += '<div class="bx-calendar-range'
6986				+(i == this.numRows-1 ? ' bx-calendar-range-noline' : '')
6987				+'">';
6988
6989			for (var j = 0; j < 7; j++)
6990			{
6991				d = month_start.getUTCDate();
6992				var wd = month_start.getUTCDay();
6993				var className = 'bx-calendar-cell';
6994
6995				if (cur_month != month_start.getUTCMonth())
6996					className += ' bx-calendar-date-hidden';
6997				else if (cur_day == d)
6998					className += ' bx-calendar-active';
6999
7000
7001				if (wd == 0 || wd == 6)
7002					className += ' bx-calendar-weekend';
7003
7004				s += '<a href="javascript:void(0)" class="'+className+'" data-date="' + month_start.valueOf() + '">' + d + '</a>';
7005
7006				month_start.setUTCDate(month_start.getUTCDate()+1);
7007			}
7008			s += '</div>';
7009		}
7010
7011		l.innerHTML = s;
7012
7013		return l;
7014	};
7015
7016	this._prev = function()
7017	{
7018		this.SetMonth(this.value.getUTCMonth()-1);
7019	};
7020
7021	this._next = function()
7022	{
7023		this.SetMonth(this.value.getUTCMonth()+1);
7024	};
7025
7026	this._menu_month_content = function()
7027	{
7028		var months = '', cur_month = this.value.getMonth(), i;
7029		for (i = 0; i < 12; i++)
7030		{
7031			months += '<span class="bx-calendar-month'+(i == cur_month ? ' bx-calendar-month-active' : '')+'" data-bx-month="' + i + '">' + BX.message('MONTH_' + (i + 1)) + '</span>';
7032		}
7033
7034		return '<div class="bx-calendar-month-popup"><div class="bx-calendar-month-title" data-bx-month="' + this.value.getUTCMonth() + '">' + BX.message('MONTH_' + (this.value.getUTCMonth() + 1)) + '</div><div class="bx-calendar-month-content">' + months + '</div></div>';
7035	};
7036
7037	this._menu_month = function()
7038	{
7039		if (!this.popup_month)
7040		{
7041			this.popup_month = new BX.PopupWindow(
7042				'calendar_popup_month_' + Math.random(), this.PARTS.MONTH,
7043				{
7044					content: this._menu_month_content(),
7045					closeByEsc: true,
7046					autoHide: true,
7047					offsetTop: -29,
7048					offsetLeft: -1,
7049					className: this.month_popup_classname,
7050					events: {
7051						onPopupShow: BX.delegate(function() {
7052							if (this.popup_year)
7053							{
7054								this.popup_year.close();
7055							}
7056						}, this)
7057					}
7058				}
7059			);
7060
7061			BX.bind(this.popup_month.popupContainer, 'click', BX.proxy(this.month_popup_click, this));
7062			this.popup_month.BXMONTH = this.value.getUTCMonth();
7063		}
7064		else if (this.popup_month.BXMONTH != this.value.getUTCMonth())
7065		{
7066			this.popup_month.setContent(this._menu_month_content());
7067			this.popup_month.BXMONTH = this.value.getUTCMonth();
7068		}
7069
7070		this.popup_month.show();
7071	};
7072
7073	this.month_popup_click = function(e)
7074	{
7075		var target = e.target || e.srcElement;
7076		if (target && target.getAttribute && target.getAttribute('data-bx-month'))
7077		{
7078			this.SetMonth(parseInt(target.getAttribute('data-bx-month')));
7079			this.popup_month.close();
7080		}
7081	};
7082
7083	this._menu_year_content = function()
7084	{
7085		var s = '<div class="bx-calendar-year-popup"><div class="bx-calendar-year-title" data-bx-year="' + this.value.getUTCFullYear() + '">' + this.value.getUTCFullYear() + '</div><div class="bx-calendar-year-content" id="bx-calendar-year-content">';
7086
7087		for (var i=-3; i <= 3; i++)
7088		{
7089			s += '<span class="bx-calendar-year-number' + (i == 0?' bx-calendar-year-active' : '') + '" data-bx-year="' + (this.value.getUTCFullYear() - i) + '">' + (this.value.getUTCFullYear() - i)+'</span>';
7090		}
7091
7092		s += '</div><input data-bx-year-input="Y" type="text" class="bx-calendar-year-input" maxlength="4" /></div>';
7093
7094		return s;
7095	};
7096
7097	this._menu_year = function()
7098	{
7099		if (!this.popup_year)
7100		{
7101			this.popup_year = new BX.PopupWindow(
7102				'calendar_popup_year_' + Math.random(), this.PARTS.YEAR,
7103				{
7104					content: this._menu_year_content(),
7105					closeByEsc: true,
7106					autoHide: true,
7107					offsetTop: -29,
7108					offsetLeft: -1,
7109					className: this.year_popup_classname,
7110					events: {
7111						onPopupShow: BX.delegate(function() {
7112							if (this.popup_month)
7113							{
7114								this.popup_month.close();
7115							}
7116						}, this)
7117					}
7118				}
7119			);
7120
7121			BX.bind(this.popup_year.popupContainer, 'click', BX.proxy(this.year_popup_click, this));
7122			BX.bind(this.popup_year.popupContainer, 'keyup', BX.proxy(this.year_popup_keyup, this));
7123			this.popup_year.BXYEAR = this.value.getUTCFullYear();
7124		}
7125		else if (this.popup_year.BXYEAR != this.value.getUTCFullYear())
7126		{
7127			this.popup_year.setContent(this._menu_year_content());
7128			this.popup_year.BXYEAR = this.value.getUTCFullYear();
7129		}
7130
7131		this.popup_year.show();
7132	};
7133
7134	this.year_popup_click = function(e)
7135	{
7136		var target = e.target || e.srcElement;
7137		if (target && target.getAttribute && target.getAttribute('data-bx-year'))
7138		{
7139			this.SetYear(parseInt(target.getAttribute('data-bx-year')));
7140			this.popup_year.close();
7141		}
7142	};
7143	this.year_popup_keyup = function(e)
7144	{
7145		var target = e.target || e.srcElement;
7146		if (target && target.getAttribute && target.getAttribute('data-bx-year-input') == 'Y')
7147		{
7148			var value = parseInt(target.value);
7149			if(value >= 1900 && value <= 2100)
7150			{
7151				this.SetYear(value);
7152				this.popup_year.close();
7153			}
7154		}
7155	};
7156
7157	this._check_date = function(v)
7158	{
7159		var res = v;
7160
7161		if (BX.type.isString(v))
7162		{
7163			res = BX.parseDate(v, true);
7164		}
7165
7166		if (!BX.type.isDate(res) || isNaN(res.valueOf()))
7167		{
7168			res = BX.date.convertToUTC(new Date());
7169			if (this.params.bHideTime)
7170			{
7171				res.setUTCHours(0);
7172				res.setUTCMinutes(0);
7173			}
7174		}
7175
7176		res.setUTCMilliseconds(0);
7177		res.setUTCSeconds(0);
7178
7179		res.BXCHECKED = true;
7180
7181		return res;
7182	};
7183};
7184
7185BX.JCCalendar.prototype.Show = function(params)
7186{
7187	if (!BX.isReady)
7188	{
7189		BX.ready(BX.delegate(function() {this.Show(params)}, this));
7190		return;
7191	}
7192
7193	params.node = params.node||document.body;
7194
7195	if (BX.type.isNotEmptyString(params.node))
7196	{
7197		var n = BX(params.node);
7198		if (!n)
7199		{
7200			n = document.getElementsByName(params.node);
7201			if (n && n.length > 0)
7202			{
7203				n = n[0]
7204			}
7205		}
7206		params.node = n;
7207	}
7208
7209	if (!params.node)
7210		return;
7211
7212	if (!!params.field)
7213	{
7214		if (BX.type.isString(params.field))
7215		{
7216			n = BX(params.field);
7217			if (!!n)
7218			{
7219				params.field = n;
7220			}
7221			else
7222			{
7223				if (params.form)
7224				{
7225					if (BX.type.isString(params.form))
7226					{
7227						params.form = document.forms[params.form];
7228					}
7229				}
7230
7231				if (BX.type.isDomNode(params.form) && !!params.form[params.field])
7232				{
7233					params.field = params.form[params.field];
7234				}
7235				else
7236				{
7237					n = document.getElementsByName(params.field);
7238					if (n && n.length > 0)
7239					{
7240						n = n[0];
7241						params.field = n;
7242					}
7243				}
7244			}
7245
7246			if (BX.type.isString(params.field))
7247			{
7248				params.field = BX(params.field);
7249			}
7250		}
7251	}
7252
7253	var bShow = !this.popup || !this.popup.isShown() || this.params.node != params.node;
7254
7255	this.params = params;
7256
7257	this.params.bCompatibility = (typeof this.params.bCompatibility == 'undefined' ? false : this.params.bCompatibility);
7258	this.params.bTimeVisibility = (typeof this.params.bTimeVisibility == 'undefined' ? !this.params.bCompatibility : this.params.bTimeVisibility);
7259	if (this.params.bCompatibility)
7260	{
7261		this.params.bCategoryTimeVisibilityOption = (
7262			this.params.bCategoryTimeVisibilityOption ? this.params.bCategoryTimeVisibilityOption : ''
7263		);
7264		this.params.bNameTimeVisibilityOption = (
7265			this.params.bNameTimeVisibilityOption ? this.params.bNameTimeVisibilityOption : 'time_visibility'
7266		);
7267
7268		if (typeof this._bTimeVisibility !== 'undefined')
7269		{
7270			this.params.bTimeVisibility = this._bTimeVisibility;
7271		}
7272	}
7273
7274	this.params.bTime = typeof this.params.bTime == 'undefined' ? true : !!this.params.bTime;
7275	this.params.bHideTime = typeof this.params.bHideTime == 'undefined' ? true : !!this.params.bHideTime;
7276	this.params.bUseSecond = typeof this.params.bUseSecond == 'undefined' ? true : !!this.params.bUseSecond;
7277
7278	this.weekStart = parseInt(this.params.weekStart || this.params.weekStart || BX.message('WEEK_START'));
7279	if (isNaN(this.weekStart))
7280		this.weekStart = 1;
7281
7282	if (!this.popup)
7283	{
7284		this._create(this.params);
7285	}
7286	else
7287	{
7288		this.popup.setBindElement(this.params.node);
7289	}
7290
7291	var bHideTime = !!this.params.bHideTime;
7292	if (this.params.value)
7293	{
7294		this.SetValue(this.params.value);
7295		bHideTime = this.value.getUTCHours() <= 0 && this.value.getUTCMinutes() <= 0;
7296	}
7297	else if (this.params.field)
7298	{
7299		this.SetValue(this.params.field.value);
7300		bHideTime = this.value.getUTCHours() <= 0 && this.value.getUTCMinutes() <= 0;
7301	}
7302	else if (!!this.params.currentTime)
7303	{
7304		this.SetValue(this.params.currentTime);
7305	}
7306	else
7307	{
7308		this.SetValue();
7309	}
7310
7311	if (!!this.params.bTime)
7312	{
7313		this.activateTimeStyle(bHideTime);
7314	}
7315	else
7316	{
7317		this.activateDateStyle(bHideTime);
7318	}
7319
7320	if (bShow)
7321	{
7322		this._auto_hide_disable();
7323		this.popup.show();
7324		setTimeout(BX.proxy(this._auto_hide_enable, this), 0);
7325	}
7326
7327	this.params.bSetFocus = typeof this.params.bSetFocus == 'undefined' ? true : !!this.params.bSetFocus;
7328	if(this.params.bSetFocus)
7329	{
7330		params.node.blur();
7331	}
7332	else
7333	{
7334		BX.bind(params.node, 'keyup', BX.defer(function(){
7335			this.SetValue(params.node.value);
7336			if(!!this.params.bTime)
7337			{
7338				if(this.value.getUTCHours() <= 0 && this.value.getUTCMinutes() <= 0)
7339					BX.removeClass(this.PARTS.TIME, 'bx-calendar-set-time-opened');
7340				else
7341					BX.addClass(this.PARTS.TIME, 'bx-calendar-set-time-opened');
7342			}
7343		}, this));
7344	}
7345
7346	return this;
7347};
7348
7349BX.JCCalendar.prototype.activateDateStyle = function(bHideTime)
7350{
7351	BX.addClass(this.DIV, 'bx-calendar-time-disabled');
7352
7353	if (!!bHideTime)
7354		BX.removeClass(this.PARTS.TIME, 'bx-calendar-set-time-opened');
7355	else
7356		BX.addClass(this.PARTS.TIME, 'bx-calendar-set-time-opened');
7357};
7358
7359BX.JCCalendar.prototype.activateTimeStyle = function(bHideTime)
7360{
7361	if (this.params.bCompatibility && !this.params.bTimeVisibility)
7362	{
7363		BX.addClass(this.PARTS.BUTTONS, 'bx-calendar-buttons-disabled');
7364		BX.addClass(this.PARTS.TIME, 'bx-calendar-set-time-wrap-simple');
7365		BX.removeClass(this.PARTS.TIME, 'bx-calendar-set-time-opened');
7366	}
7367	else
7368	{
7369		BX.removeClass(this.DIV, 'bx-calendar-time-disabled');
7370
7371		if (!!bHideTime)
7372			BX.removeClass(this.PARTS.TIME, 'bx-calendar-set-time-opened');
7373		else
7374			BX.addClass(this.PARTS.TIME, 'bx-calendar-set-time-opened');
7375	}
7376};
7377
7378BX.JCCalendar.prototype.SetDay = function(d)
7379{
7380	this.value.setUTCDate(d);
7381	return this.SetValue(this.value);
7382};
7383
7384BX.JCCalendar.prototype.SetMonth = function(m)
7385{
7386	if (this.popup_month)
7387		this.popup_month.close();
7388
7389	this.value.setUTCMonth(m);
7390
7391	if(m < 0)
7392		m += 12;
7393	else if (m >= 12)
7394		m -= 12;
7395
7396	while(this.value.getUTCMonth() > m)
7397	{
7398		this.value.setUTCDate(this.value.getUTCDate()-1);
7399	}
7400
7401	return this.SetValue(this.value);
7402};
7403
7404BX.JCCalendar.prototype.SetYear = function(y)
7405{
7406	if (this.popup_year)
7407		this.popup_year.close();
7408	this.value.setUTCFullYear(y);
7409	return this.SetValue(this.value);
7410};
7411
7412BX.JCCalendar.prototype.SetDate = function(v, bSet)
7413{
7414	v = this._check_date(v);
7415	v.setUTCHours(this.value.getUTCHours());
7416	v.setUTCMinutes(this.value.getUTCMinutes());
7417	v.setUTCSeconds(this.value.getUTCSeconds());
7418
7419	if (this.params.bTime && !bSet)
7420	{
7421		return this.SetValue(v);
7422	}
7423	else
7424	{
7425		this.SetValue(v);
7426		this.SaveValue();
7427	}
7428};
7429
7430BX.JCCalendar.prototype.SetValue = function(v)
7431{
7432	this.value = (v && v.BXCHECKED) ? v : this._check_date(v);
7433
7434	this.PARTS.MONTH.innerHTML = BX.message('MONTH_' + (this.value.getUTCMonth()+1));
7435	this.PARTS.YEAR.innerHTML = this.value.getUTCFullYear();
7436
7437	if (!!this.params.bTime)
7438	{
7439		var h = this.value.getUTCHours();
7440		if (this.bAmPm)
7441		{
7442			if (h >= 12)
7443			{
7444				this.PARTS.TIME_AMPM.innerHTML = 'PM';
7445
7446				if (h != 12)
7447					h -= 12;
7448			}
7449			else
7450			{
7451				this.PARTS.TIME_AMPM.innerHTML = 'AM';
7452
7453				if (h == 0)
7454					h = 12;
7455			}
7456		}
7457
7458		this.PARTS.TIME_INPUT_H.value = BX.util.str_pad_left(h.toString(), 2, "0");
7459		this.PARTS.TIME_INPUT_M.value = BX.util.str_pad_left(this.value.getUTCMinutes().toString(), 2, "0");
7460	}
7461
7462	this._set_layer();
7463
7464	return this;
7465};
7466
7467BX.JCCalendar.prototype.SaveValue = function()
7468{
7469	if (this.popup_month)
7470		this.popup_month.close();
7471	if (this.popup_year)
7472		this.popup_year.close();
7473
7474	var bSetValue = true;
7475	if (!!this.params.callback)
7476	{
7477		var res = this.params.callback.apply(this, [new Date(this.value.valueOf()+this.value.getTimezoneOffset()*60000)]);
7478		if (res === false)
7479			bSetValue = false;
7480	}
7481
7482	if (bSetValue)
7483	{
7484		var bTime = !!this.params.bTime && BX.hasClass(this.PARTS.TIME, 'bx-calendar-set-time-opened');
7485
7486		if (this.params.field)
7487		{
7488			var format = BX.message(bTime ? 'FORMAT_DATETIME' : 'FORMAT_DATE');
7489
7490			if(bTime && !this.params.bUseSecond)
7491			{
7492				format = format.replace(':SS', '');
7493			}
7494
7495			this.params.field.value = BX.calendar.ValueToStringFormat(this.value, format, true);
7496			BX.fireEvent(this.params.field, 'change');
7497		}
7498
7499		this.popup.close();
7500
7501		if (!!this.params.callback_after)
7502		{
7503			this.params.callback_after.apply(this, [new Date(this.value.valueOf()+this.value.getTimezoneOffset()*60000), bTime]);
7504		}
7505	}
7506
7507	return this;
7508};
7509
7510BX.JCCalendar.prototype.Close = function()
7511{
7512	if (!!this.popup)
7513		this.popup.close();
7514
7515	return this;
7516};
7517
7518BX.JCSpinner = function(params)
7519{
7520	params = params || {};
7521	this.params = {
7522		input: params.input || null,
7523
7524		delta: params.delta || 1,
7525
7526		timeout_start: params.timeout_start || 1000,
7527		timeout_cont: params.timeout_cont || 150,
7528
7529		callback_start: params.callback_start || null,
7530		callback_change: params.callback_change || null,
7531		callback_finish: params.callback_finish || null,
7532
7533		bSaveValue: typeof params.bSaveValue == 'undefined' ? !!params.input : !!params.bSaveValue
7534	};
7535
7536	this.mousedown = false;
7537	this.direction = 1;
7538};
7539
7540BX.JCSpinner.prototype.Show = function()
7541{
7542	this.node = BX.create('span', {
7543		events: {
7544			mousedown: BX.delegateEvent(
7545				{attr: 'data-dir'},
7546				BX.delegate(this.Start, this)
7547			)
7548		},
7549		html: '<a href="javascript:void(0)" class="bx-calendar-form-arrow bx-calendar-form-arrow-top" data-dir="1"><i></i></a><a href="javascript:void(0)" class="bx-calendar-form-arrow bx-calendar-form-arrow-bottom" data-dir="-1"><i></i></a>'
7550	});
7551	return this.node;
7552};
7553
7554BX.JCSpinner.prototype.Start = function()
7555{
7556	this.mousedown = true;
7557	this.direction = BX.proxy_context.getAttribute('data-dir') > 0 ? 1 : -1;
7558	BX.bind(document, "mouseup", BX.proxy(this.MouseUp, this));
7559	this.ChangeValue(true);
7560};
7561
7562BX.JCSpinner.prototype.ChangeValue = function(bFirst)
7563{
7564	if(!this.mousedown)
7565		return;
7566
7567	if (this.params.input)
7568	{
7569		var v = parseInt(this.params.input.value, 10) + this.params.delta * this.direction;
7570
7571		if (this.params.bSaveValue)
7572			this.params.input.value = v;
7573
7574		if (!!bFirst && this.params.callback_start)
7575			this.params.callback_start(this.params, v, this.direction);
7576
7577		if (this.params.callback_change)
7578			this.params.callback_change(this.params, v, this.direction);
7579
7580		setTimeout(
7581			BX.proxy(this.ChangeValue, this),
7582			!!bFirst ? this.params.timeout_start : this.params.timeout_cont
7583		);
7584	}
7585};
7586
7587BX.JCSpinner.prototype.MouseUp = function()
7588{
7589	this.mousedown = false;
7590	BX.unbind(document, "mouseup", BX.proxy(this.MouseUp, this));
7591
7592	if (this.params.callback_finish)
7593		this.params.callback_finish(this.params, this.params.input.value);
7594};
7595
7596/**************** compatibility hacks ***************************/
7597
7598window.jsCalendar = {
7599	Show: function(obj, field, fieldFrom, fieldTo, bTime, serverTime, form_name, bHideTimebar)
7600	{
7601		return BX.calendar({
7602			node: obj, field: field, form: form_name, bTime: !!bTime, currentTime: serverTime, bHideTimebar: !!bHideTimebar
7603		});
7604	},
7605
7606	ValueToString: BX.calendar.ValueToString
7607};
7608
7609
7610/************ clock popup transferred from timeman **************/
7611
7612BX.CClockSelector = function(params)
7613{
7614	this.params = params;
7615
7616	this.params.popup_buttons = this.params.popup_buttons || [
7617		new BX.PopupWindowButton({
7618			text : BX.message('CAL_BUTTON'),
7619			className : "popup-window-button-create",
7620			events : {click : BX.proxy(this.setValue, this)}
7621		})
7622	];
7623
7624	this.isReady = false;
7625
7626	this.WND = new BX.PopupWindow(
7627		this.params.popup_id || 'clock_selector_popup',
7628		this.params.node,
7629		this.params.popup_config || {
7630			titleBar: BX.message('CAL_TIME'),
7631			offsetLeft: -45,
7632			offsetTop: -135,
7633			autoHide: true,
7634			closeIcon: true,
7635			closeByEsc: true
7636		}
7637	);
7638
7639	this.SHOW = false;
7640	BX.addCustomEvent(this.WND, "onPopupClose", BX.delegate(this.onPopupClose, this));
7641
7642	this.obClocks = {};
7643	this.CLOCK_ID = this.params.clock_id || 'clock_selector';
7644};
7645
7646BX.CClockSelector.prototype.Show = function()
7647{
7648	if (!this.isReady)
7649	{
7650		//BX.timeman.showWait(this.parent.DIV);
7651
7652		BX.addCustomEvent('onClockRegister', BX.proxy(this.onClockRegister, this));
7653		return BX.ajax.get('/bitrix/tools/clock_selector.php', {start_time: this.params.start_time, clock_id: this.CLOCK_ID, sessid: BX.bitrix_sessid()}, BX.delegate(this.Ready, this));
7654	}
7655
7656	this.WND.setButtons(this.params.popup_buttons);
7657	this.WND.show();
7658
7659	this.SHOW = true;
7660
7661	if (window['bxClock_' + this.obClocks[this.CLOCK_ID]])
7662	{
7663		setTimeout("window['bxClock_" + this.obClocks[this.CLOCK_ID] + "'].CalculateCoordinates()", 40);
7664	}
7665
7666	return true;
7667};
7668
7669BX.CClockSelector.prototype.onClockRegister = function(obClocks)
7670{
7671	if (obClocks[this.CLOCK_ID])
7672	{
7673		this.obClocks[this.CLOCK_ID] = obClocks[this.CLOCK_ID];
7674		BX.removeCustomEvent('onClockRegister', BX.proxy(this.onClockRegister, this));
7675	}
7676};
7677
7678BX.CClockSelector.prototype.Ready = function(data)
7679{
7680	this.content = this.CreateContent(data);
7681	this.WND.setContent(this.content);
7682
7683	this.isReady = true;
7684	//BX.timeman.closeWait();
7685
7686	setTimeout(BX.proxy(this.Show, this), 30);
7687};
7688
7689BX.CClockSelector.prototype.CreateContent = function(data)
7690{
7691	return BX.create('DIV', {
7692		events: {click: BX.PreventDefault},
7693		html:
7694			'<div class="bx-tm-popup-clock">' + data + '</div>'
7695	});
7696};
7697
7698BX.CClockSelector.prototype.setValue = function(e)
7699{
7700	if (this.params.callback)
7701	{
7702		var input = BX.findChild(this.content, {tagName: 'INPUT'}, true);
7703		this.params.callback.apply(this.params.node, [input.value]);
7704	}
7705
7706	return BX.PreventDefault(e);
7707};
7708
7709BX.CClockSelector.prototype.closeWnd = function(e)
7710{
7711	this.WND.close();
7712	return (e || window.event) ? BX.PreventDefault(e) : true;
7713};
7714
7715BX.CClockSelector.prototype.setNode = function(node)
7716{
7717	this.WND.setBindElement(node);
7718};
7719
7720BX.CClockSelector.prototype.setTime = function(timestamp)
7721{
7722	this.params.start_time = timestamp;
7723	if (window['bxClock_' + this.obClocks[this.CLOCK_ID]])
7724	{
7725		window['bxClock_' +  this.obClocks[this.CLOCK_ID]].SetTime(parseInt(timestamp/3600), parseInt((timestamp%3600)/60));
7726	}
7727};
7728
7729BX.CClockSelector.prototype.setCallback = function(cb)
7730{
7731	this.params.callback = cb;
7732};
7733
7734BX.CClockSelector.prototype.onPopupClose = function()
7735{
7736	this.SHOW = false;
7737};
7738
7739})();
7740
7741/* End */
7742;
7743; /* Start:"a:4:{s:4:"full";s:49:"/bitrix/js/main/core/core_timer.js?16379236876316";s:6:"source";s:34:"/bitrix/js/main/core/core_timer.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
7744(function(window){
7745if (window.BX.timer) return;
7746
7747var timers = [],
7748	timeout = 200,
7749	obTimer = null,
7750	last_index = 0;
7751
7752BX.timer = function(container, params)
7753{
7754	params = params || {};
7755	if (BX.type.isString(container) || BX.type.isElementNode(container))
7756		params.container = container;
7757	else if (typeof (container) == "object")
7758		params = container;
7759
7760	if (!params.container)
7761		return false;
7762
7763	var ob = new BX.CTimer(params);
7764	BX.timer.start(ob);
7765
7766	if (null == obTimer)
7767	{
7768		obTimer = setInterval(_RunTimer, timeout);
7769		BX.garbage(BX.timer.clear);
7770	}
7771
7772	return ob;
7773}
7774
7775BX.timer.stop = function(timer)
7776{
7777	timers[timer.TIMER_INDEX] = null;
7778}
7779
7780BX.timer.start = function(timer)
7781{
7782	timer.TIMER_INDEX = last_index;
7783	timers[last_index++] = timer;
7784}
7785
7786BX.timer.clock = function(cont, dt)
7787{
7788	return BX.timer({container: cont, dt: dt});
7789}
7790
7791BX.timer.clear = function()
7792{
7793	clearInterval(obTimer);
7794	timers = null;
7795}
7796
7797BX.timer.registerFormat = function(format_name, format_handler)
7798{
7799	BX.CTimer.prototype.formatValueHandlers[format_name] = format_handler
7800}
7801
7802BX.timer.getHandler = function(format_name)
7803{
7804	return BX.CTimer.prototype.formatValueHandlers[format_name];
7805}
7806
7807BX.CTimer = function(params, index)
7808{
7809	this.container = params.container;
7810	this.from = params.from ? parseInt(params.from.valueOf()) : null;
7811	this.to = params.to ? parseInt(params.to.valueOf()) : null;
7812	this.index = index;
7813
7814	this.dt = parseInt(params.dt);
7815	if (isNaN(this.dt))
7816		this.dt = 0;
7817
7818	this.display = params.display || (BX.isAmPmMode() ? 'clock_am_pm' : 'clock'); // other variants - 'simple', 'worktime'
7819
7820	this.accuracy = params.accuracy || 60; // default timing acccuracy is 1 minute
7821
7822	// if (this.from)
7823		// this.from = new Date(parseInt(this.from.valueOf() / this.accuracy) * this.accuracy);
7824	// if (this.to)
7825		// this.to = new Date(parseInt(this.to.valueOf() / this.accuracy) * this.accuracy);
7826
7827	this.callback = this.from ? this._callback_from : (this.to ? this._callback_to : this._callback);
7828	this.callback_finish = params.callback_finish;
7829
7830	this.formatValue = this.formatValueHandlers.clock;
7831
7832	this.bInited = false;
7833	BX.ready(BX.delegate(this.Init, this));
7834}
7835
7836BX.CTimer.prototype.Init = function()
7837{
7838	if (this.bInited)
7839		return;
7840
7841	this.container = BX(this.container);
7842	this.container_value_fld = this.container.tagName.toUpperCase() == 'INPUT' ? 'value' : 'innerHTML';
7843	if (this.container_value_fld == 'value' && (this.display == 'clock' || this.display == 'clock_am_pm'))
7844	{
7845		if (this.display == 'clock')
7846		{
7847			this.display = 'simple';
7848		}
7849		else if (this.display == 'clock_am_pm')
7850		{
7851			this.display = 'simple_am_pm';
7852		}
7853	}
7854
7855	this.formatValue = this.formatValueHandlers[this.display] ? this.formatValueHandlers[this.display] : this.formatValueHandlers.clock;
7856
7857	this.bInited = true;
7858}
7859
7860BX.CTimer.prototype.setFrom = function(from)
7861{
7862	if (!this.from) return;
7863	this.from = from;
7864}
7865
7866BX.CTimer.prototype.setTo = function(to)
7867{
7868	if (!this.to) return;
7869	this.to = to;
7870}
7871
7872BX.CTimer.prototype._callback = function(date)
7873{
7874	if (this.dt !== 0)
7875		var date = new Date(date.valueOf() + this.dt);
7876
7877	this.setValue(this.formatValue(date.getHours(), date.getMinutes(), date.getSeconds()));
7878}
7879
7880BX.CTimer.prototype._callback_from = function(date)
7881{
7882	var diff = (date.valueOf() - this.from.valueOf() + this.dt)/1000;
7883	this.setValue(
7884		this.formatValue(
7885			parseInt(diff / 3600),
7886			parseInt((diff % 3600) / 60),
7887			parseInt(diff % 60)
7888		)
7889	);
7890}
7891
7892BX.CTimer.prototype._callback_to = function(date)
7893{
7894	var diff = (this.to.valueOf() - date.valueOf())/1000;
7895	if (diff > 0)
7896	{
7897		this.setValue(
7898			this.formatValue(
7899				parseInt(diff / 3600),
7900				parseInt((diff % 3600) / 60),
7901				parseInt(diff % 60)
7902			)
7903		);
7904	}
7905	else
7906	{
7907		this.Finish();
7908	}
7909}
7910
7911BX.CTimer.prototype.formatValueHandlers = {
7912	clock: function(h, m, s)
7913	{
7914		var d = '<span class="bx-timer-semicolon">:</span>';
7915
7916		return BX.util.str_pad(h, 2, '0', 'left')
7917			+ d
7918			+ (this.accuracy >= 3600
7919				? '00'
7920				: BX.util.str_pad(m, 2, '0', 'left'))
7921			+ (this.accuracy >= 60
7922				? ''
7923				:
7924				(d + BX.util.str_pad(s, 2, '0', 'left'))
7925			);
7926	},
7927	clock_am_pm: function(h, m, s)
7928	{
7929		var mt = 'am';
7930		var d = '<span class="bx-timer-semicolon">:</span>';
7931
7932		if (h > 12)
7933		{
7934			h = h - 12;
7935			mt = 'pm';
7936		}
7937		else if (h == 0)
7938		{
7939			h = 12;
7940			mt = 'am';
7941		}
7942		else if (h == 12)
7943		{
7944			mt = 'pm';
7945		}
7946
7947		return h
7948			+ d
7949			+ (this.accuracy >= 3600
7950				? '00'
7951				: BX.util.str_pad(m, 2, '0', 'left'))
7952			+ (this.accuracy >= 60
7953				? ''
7954				:
7955				(d + BX.util.str_pad(s, 2, '0', 'left'))
7956			)
7957			+ ' ' + mt;
7958	},
7959	simple: function(h, m, s)
7960	{
7961		return BX.util.str_pad(h, 2, '0', 'left')
7962			+ ':'
7963			+ (this.accuracy >= 3600
7964				? '00'
7965				: BX.util.str_pad(m, 2, '0', 'left'))
7966
7967			+ (this.accuracy >= 60
7968				? ''
7969				:
7970				(':' + BX.util.str_pad(s, 2, '0', 'left'))
7971			);
7972	},
7973	simple_am_pm: function(h, m, s)
7974	{
7975		var mt = 'am';
7976
7977		if (h > 12)
7978		{
7979			h = h - 12;
7980			mt = 'pm';
7981		}
7982		else if (h == 0)
7983		{
7984			h = 12;
7985			mt = 'am';
7986		}
7987		else if (h == 12)
7988		{
7989			mt = 'pm';
7990		}
7991		return h
7992			+ ':'
7993			+ (this.accuracy >= 3600
7994				? '00'
7995				: BX.util.str_pad(m, 2, '0', 'left'))
7996
7997			+ (this.accuracy >= 60
7998				? ''
7999				:
8000				(':' + BX.util.str_pad(s, 2, '0', 'left'))
8001			) + ' ' + mt;
8002	},
8003	worktime: function(h, m, s)
8004	{
8005		return h + BX.message('JS_CORE_H') + ' '
8006			+ (this.accuracy >= 3600
8007				? ''
8008				: m + BX.message('JS_CORE_M')
8009					+ (this.accuracy >= 60
8010						? ''
8011						: ' ' + s + BX.message('JS_CORE_S')
8012					)
8013				);
8014	},
8015	worktime_short: function(h, m, s)
8016	{
8017		return BX.util.rtrim((h > 0 ? h + BX.message('JS_CORE_H') + ' ' : '')
8018			+ (m > 0 && this.accuracy < 3600 ? m + BX.message('JS_CORE_M') + ' ' : '')
8019			+ (this.accuracy >= 60
8020				? ''
8021				: (s > 0 ? s + BX.message('JS_CORE_S') : '')
8022			));
8023	}
8024}
8025
8026BX.CTimer.prototype.setValue = function(value)
8027{
8028	if (this.bInited)
8029	{
8030		if (value != this._last_value)
8031			this.container[this.container_value_fld] = value;
8032
8033		this._last_value = value;
8034	}
8035}
8036
8037BX.CTimer.prototype.Finish = function()
8038{
8039	BX.timer.stop(this);
8040
8041	if (this.callback_finish)
8042		this.callback_finish.apply(this);
8043
8044	BX.cleanNode(this.container.parentNode);
8045}
8046
8047function _RunTimer()
8048{
8049	var current_moment = new Date();
8050
8051	for (var i=0,len=last_index;i<len;i++)
8052	{
8053		if (timers[i] && timers[i].callback)
8054			timers[i].callback.apply(timers[i], [current_moment]);
8055	}
8056
8057	current_moment = null;
8058}
8059})(window)
8060
8061/* End */
8062;
8063; /* Start:"a:4:{s:4:"full";
8063s:37:"/bitrix/js/main/dd.js?169147814014809";s:6:"source";s:21:"/bitrix/js/main/dd.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
8064;(function(){
8065
8066if (window.jsDD)
8067	return;
8068
8069jsDD = {
8070	arObjects: [],
8071	arDestinations: [],
8072	arDestinationsPriority: [],
8073
8074	arContainers: [],
8075	arContainersPos: [],
8076
8077	current_dest_index: false,
8078	current_node: null,
8079
8080	wndSize: null,
8081
8082	bStarted: false,
8083	bDisable: false,
8084	bDisableDestRefresh: false,
8085
8086	bEscPressed: false,
8087
8088	bScrollWindow: false,
8089	scrollViewTimer: null,
8090	scrollViewConfig: {
8091		checkerTimeout: 30,
8092		scrollZone: 25,
8093		scrollBy: 25,
8094		scrollContainer: null,
8095		bScrollH: true,
8096		bScrollV: true,
8097		pos: null
8098	},
8099
8100	setScrollWindow: function(val)
8101	{
8102		jsDD.bScrollWindow = !!val;
8103		if (BX.type.isDomNode(val))
8104		{
8105			jsDD.scrollViewConfig.scrollContainer = val;
8106			jsDD.scrollViewConfig.pos = BX.pos(val);
8107
8108			var s = BX.style(val, 'overflow') || 'visible',
8109				s1 = BX.style(val, 'overflow-x') || 'visible',
8110				s2 = BX.style(val, 'overflow-y') || 'visible';
8111
8112			jsDD.scrollViewConfig.bScrollH = s != 'visible' || s1 != 'visible';
8113			jsDD.scrollViewConfig.bScrollV = s != 'visible' || s2 != 'visible';
8114		}
8115	},
8116
8117	Reset: function()
8118	{
8119		jsDD.arObjects = [];
8120		jsDD.arDestinations = [];
8121		jsDD.arDestinationsPriority = [];
8122		jsDD.bStarted = false;
8123		jsDD.current_node = null;
8124		jsDD.current_dest_index = false;
8125		jsDD.bDisableDestRefresh = false;
8126		jsDD.bDisable = false;
8127		jsDD.x = null;
8128		jsDD.y = null;
8129		jsDD.start_x = null;
8130		jsDD.start_y = null;
8131		jsDD.wndSize = null;
8132
8133		jsDD.bEscPressed = false;
8134
8135		clearInterval(jsDD.scrollViewTimer)
8136		jsDD.bScrollWindow = false;
8137		jsDD.scrollViewTimer = null;
8138		jsDD.scrollViewConfig.scrollContainer = null;
8139	},
8140
8141	registerObject: function (obNode)
8142	{
8143		BX.bind(obNode, 'mousedown', jsDD.startDrag);
8144		BX.Event.bind(obNode, 'touchstart', jsDD.startDrag, { passive: true });
8145
8146		obNode.__bxddid = jsDD.arObjects.length;
8147
8148		jsDD.arObjects[obNode.__bxddid] = obNode;
8149	},
8150	unregisterObject: function(obNode)
8151	{
8152		if(typeof(obNode["__bxddid"]) === "undefined")
8153		{
8154			return;
8155		}
8156
8157		delete jsDD.arObjects[obNode.__bxddid];
8158		delete obNode.__bxddid;
8159		BX.unbind(obNode, 'mousedown', jsDD.startDrag);
8160		BX.unbind(obNode, 'touchstart', jsDD.startDrag);
8161	},
8162	registerDest: function (obDest, priority)
8163	{
8164		if (!priority)
8165			priority = 100;
8166
8167		obDest.__bxddeid = jsDD.arDestinations.length;
8168		obDest.__bxddpriority = priority;
8169
8170		jsDD.arDestinations[obDest.__bxddeid] = obDest;
8171		if (!jsDD.arDestinationsPriority[priority])
8172			jsDD.arDestinationsPriority[priority] = [obDest.__bxddeid]
8173		else
8174			jsDD.arDestinationsPriority[priority].push(obDest.__bxddeid);
8175
8176		jsDD.refreshDestArea(obDest.__bxddeid);
8177	},
8178	unregisterDest: function(obDest)
8179	{
8180		if(typeof(obDest["__bxddeid"]) === "undefined")
8181		{
8182			return;
8183		}
8184
8185		delete jsDD.arDestinations[obDest.__bxddeid];
8186		delete obDest.__bxddeid;
8187		delete obDest.__bxddpriority;
8188
8189		jsDD.refreshDestArea();
8190	},
8191	disableDest: function(obDest)
8192	{
8193		if (typeof(obDest.__bxddeid) !== "undefined")
8194		{
8195			obDest.__bxdddisabled = true;
8196		}
8197	},
8198
8199	enableDest: function(obDest)
8200	{
8201		if (typeof(obDest.__bxddeid) !== "undefined")
8202		{
8203			obDest.__bxdddisabled = false;
8204		}
8205	},
8206
8207	registerContainer: function (obCont)
8208	{
8209		jsDD.arContainers[jsDD.arContainers.length] = obCont;
8210	},
8211
8212	getContainersScrollPos: function(x, y)
8213	{
8214		var pos = {'left':0, 'top':0};
8215		for(var i=0, n=jsDD.arContainers.length; i<n; i++)
8216		{
8217			if(jsDD.arContainers[i] && x >= jsDD.arContainersPos[i]["left"] && x <= jsDD.arContainersPos[i]["right"] && y >= jsDD.arContainersPos[i]["top"] && y <= jsDD.arContainersPos[i]["bottom"])
8218			{
8219				pos.left = jsDD.arContainers[i].scrollLeft;
8220				pos.top = jsDD.arContainers[i].scrollTop;
8221			}
8222		}
8223		return pos;
8224	},
8225
8226	setContainersPos: function()
8227	{
8228		for(var i=0, n=jsDD.arContainers.length; i<n; i++)
8229		{
8230			if(jsDD.arContainers[i])
8231				jsDD.arContainersPos[i] = BX.pos(jsDD.arContainers[i]);
8232		}
8233	},
8234
8235	refreshDestArea: function(id)
8236	{
8237		if (id && typeof (id) == "object" && typeof (id.__bxddeid) != 'undefined')
8238		{
8239			id = id.__bxddeid;
8240		}
8241
8242		if (typeof id == 'undefined')
8243		{
8244			for (var i = 0, cnt = jsDD.arDestinations.length; i < cnt; i++)
8245			{
8246				jsDD.refreshDestArea(i);
8247			}
8248		}
8249		else
8250		{
8251			if (null == jsDD.arDestinations[id])
8252				return;
8253
8254			var arPos = BX.pos(jsDD.arDestinations[id]);
8255			jsDD.arDestinations[id].__bxpos = [arPos.left, arPos.top, arPos.right, arPos.bottom];
8256		}
8257	},
8258
8259	_checkEsc: function(e)
8260	{
8261		e = e||window.event;
8262		if (jsDD.bStarted && e.keyCode == 27)
8263		{
8264			jsDD.stopCurrentDrag();
8265		}
8266	},
8267
8268	stopCurrentDrag: function()
8269	{
8270		if (jsDD.bStarted)
8271		{
8272			jsDD.bEscPressed = true;
8273			jsDD.stopDrag();
8274		}
8275	},
8276
8277	/* scroll checkers */
8278
8279	_onscroll: function() {
8280		jsDD.wndSize = BX.GetWindowSize();
8281	},
8282
8283	_checkScroll: function()
8284	{
8285		if (jsDD.bScrollWindow)
8286		{
8287			var pseudo_e = {
8288					clientX: jsDD.x - jsDD.wndSize.scrollLeft,
8289					clientY: jsDD.y - jsDD.wndSize.scrollTop
8290				},
8291				bChange = false,
8292				d = jsDD.scrollViewConfig.scrollZone;
8293
8294			// check whether window scroll needed
8295			if (pseudo_e.clientY < d && jsDD.wndSize.scrollTop > 0)
8296			{
8297				window.scrollBy(0, -jsDD.scrollViewConfig.scrollBy);
8298				bChange = true;
8299			}
8300
8301			if (pseudo_e.clientY > jsDD.wndSize.innerHeight - d && jsDD.wndSize.scrollTop < jsDD.wndSize.scrollHeight - jsDD.wndSize.innerHeight)
8302			{
8303				window.scrollBy(0, jsDD.scrollViewConfig.scrollBy);
8304				bChange = true;
8305			}
8306
8307			if (pseudo_e.clientX < d && jsDD.wndSize.scrollLeft > 0)
8308			{
8309				window.scrollBy(-jsDD.scrollViewConfig.scrollBy, 0);
8310				bChange = true;
8311			}
8312
8313			if (pseudo_e.clientX > jsDD.wndSize.innerWidth - d && jsDD.wndSize.scrollLeft < jsDD.wndSize.scrollWidth - jsDD.wndSize.innerWidth)
8314			{
8315				window.scrollBy(jsDD.scrollViewConfig.scrollBy, 0);
8316				bChange = true;
8317			}
8318
8319			// check whether container scroll needed
8320
8321			if (jsDD.scrollViewConfig.scrollContainer)
8322			{
8323				var c = jsDD.scrollViewConfig.scrollContainer;
8324
8325				if (jsDD.scrollViewConfig.bScrollH)
8326				{
8327					if (pseudo_e.clientX + jsDD.wndSize.scrollLeft < jsDD.scrollViewConfig.pos.left + d && c.scrollLeft > 0)
8328					{
8329						c.scrollLeft -= jsDD.scrollViewConfig.scrollBy;
8330						bChange = true;
8331					}
8332
8333					if (pseudo_e.clientX + jsDD.wndSize.scrollLeft > jsDD.scrollViewConfig.pos.right - d
8334						&& c.scrollLeft < c.scrollWidth - c.offsetWidth)
8335					{
8336						c.scrollLeft += jsDD.scrollViewConfig.scrollBy;
8337						bChange = true;
8338					}
8339				}
8340
8341				if (jsDD.scrollViewConfig.bScrollV)
8342				{
8343					if (pseudo_e.clientY + jsDD.wndSize.scrollTop < jsDD.scrollViewConfig.pos.top + d && c.scrollTop > 0)
8344					{
8345						c.scrollTop -= jsDD.scrollViewConfig.scrollBy;
8346						bChange = true;
8347					}
8348
8349					if (pseudo_e.clientY + jsDD.wndSize.scrollTop > jsDD.scrollViewConfig.pos.bottom - d
8350						&& c.scrollTop < c.scrollHeight - c.offsetHeight)
8351					{
8352						c.scrollTop += jsDD.scrollViewConfig.scrollBy;
8353						bChange = true;
8354					}
8355				}
8356			}
8357
8358			if (bChange)
8359			{
8360				jsDD._onscroll();
8361				jsDD.drag(pseudo_e);
8362			}
8363		}
8364	},
8365
8366	/* DD process */
8367
8368	startDrag: function(e)
8369	{
8370		if (jsDD.bDisable)
8371			return true;
8372
8373		e = e || window.event;
8374
8375		if (!(BX.getEventButton(e)&BX.MSLEFT))
8376			return true;
8377
8378		jsDD.current_node = null;
8379		if (e.currentTarget)
8380		{
8381			jsDD.current_node = e.currentTarget;
8382			if (null == jsDD.current_node || null == jsDD.current_node.__bxddid)
8383			{
8384				jsDD.current_node = null;
8385				return;
8386			}
8387		}
8388		else
8389		{
8390			jsDD.current_node = e.srcElement;
8391			if (null == jsDD.current_node)
8392				return;
8393
8394			while (null == jsDD.current_node.__bxddid)
8395			{
8396				jsDD.current_node = jsDD.current_node.parentNode;
8397				if (jsDD.current_node.tagName == 'BODY')
8398					return;
8399			}
8400		}
8401
8402		jsDD.bStarted = false;
8403		jsDD.bPreStarted = true;
8404
8405		jsDD.wndSize = BX.GetWindowSize();
8406
8407		jsDD.start_x = e.clientX + jsDD.wndSize.scrollLeft;
8408		jsDD.start_y = e.clientY + jsDD.wndSize.scrollTop;
8409
8410		BX.bind(document, "mouseup", jsDD.stopDrag);
8411		BX.bind(document, "touchend", jsDD.stopDrag);
8412		BX.bind(document, "mousemove", jsDD.drag);
8413		BX.bind(document, "touchmove", jsDD.drag);
8414		BX.bind(window, 'scroll', jsDD._onscroll);
8415
8416		if(document.body.setCapture)
8417			document.body.setCapture();
8418
8419		if (!jsDD.bDisableDestRefresh)
8420			jsDD.refreshDestArea();
8421
8422		jsDD.setContainersPos();
8423
8424		if(e.type !== "touchstart")
8425		{
8426			jsDD.denySelection();
8427			return BX.PreventDefault(e);
8428		}
8429		else
8430		{
8431			return true;
8432		}
8433	},
8434
8435	start: function()
8436	{
8437		if (jsDD.bDisable)
8438			return true;
8439
8440		document.body.style.cursor = 'move';
8441
8442		if (jsDD.current_node.onbxdragstart)
8443			jsDD.current_node.onbxdragstart();
8444
8445		for (var i = 0, cnt = jsDD.arDestinations.length; i < cnt; i++)
8446		{
8447			if (jsDD.arDestinations[i] && jsDD.arDestinations[i].onbxdestdragstart)
8448				jsDD.arDestinations[i].onbxdestdragstart(jsDD.current_node);
8449		}
8450
8451		jsDD.bStarted = true;
8452		jsDD.bPreStarted = false;
8453
8454		if (jsDD.bScrollWindow)
8455		{
8456			if (jsDD.scrollViewTimer)
8457				clearInterval(jsDD.scrollViewTimer);
8458
8459			jsDD.scrollViewTimer = setInterval(jsDD._checkScroll, jsDD.scrollViewConfig.checkerTimeout);
8460		}
8461
8462		BX.bind(document, 'keypress', this._checkEsc);
8463	},
8464
8465	drag: function(e)
8466	{
8467		if (jsDD.bDisable)
8468			return true;
8469
8470		e = e || window.event;
8471
8472		jsDD.x = e.clientX + jsDD.wndSize.scrollLeft;
8473		jsDD.y = e.clientY + jsDD.wndSize.scrollTop;
8474
8475		if (!jsDD.bStarted)
8476		{
8477			var delta = 5;
8478			if(jsDD.x >= jsDD.start_x-delta && jsDD.x <= jsDD.start_x+delta && jsDD.y >= jsDD.start_y-delta && jsDD.y <= jsDD.start_y+delta)
8479				return true;
8480
8481			jsDD.start();
8482		}
8483
8484		if (jsDD.current_node.onbxdrag)
8485		{
8486			jsDD.current_node.onbxdrag(jsDD.x, jsDD.y, e);
8487		}
8488
8489		var containersScroll = jsDD.getContainersScrollPos(jsDD.x, jsDD.y);
8490		var current_dest_index = jsDD.searchDest(jsDD.x+containersScroll.left, jsDD.y+containersScroll.top);
8491
8492		if (current_dest_index !== jsDD.current_dest_index)
8493		{
8494			if (jsDD.current_dest_index !== false)
8495			{
8496				if (jsDD.current_node.onbxdraghout)
8497					jsDD.current_node.onbxdraghout(jsDD.arDestinations[jsDD.current_dest_index], jsDD.x, jsDD.y);
8498
8499				if (jsDD.arDestinations[jsDD.current_dest_index].onbxdestdraghout)
8500					jsDD.arDestinations[jsDD.current_dest_index].onbxdestdraghout(jsDD.current_node, jsDD.x, jsDD.y);
8501			}
8502
8503			if (current_dest_index !== false)
8504			{
8505				if (jsDD.current_node.onbxdraghover)
8506					jsDD.current_node.onbxdraghover(jsDD.arDestinations[current_dest_index], jsDD.x, jsDD.y);
8507
8508				if (jsDD.arDestinations[current_dest_index].onbxdestdraghover)
8509					jsDD.arDestinations[current_dest_index].onbxdestdraghover(jsDD.current_node, jsDD.x, jsDD.y);
8510			}
8511		}
8512
8513		jsDD.current_dest_index = current_dest_index;
8514	},
8515
8516	stopDrag: function(e)
8517	{
8518		BX.unbind(document, 'keypress', jsDD._checkEsc);
8519
8520		e = e || window.event;
8521
8522		jsDD.bPreStarted = false;
8523
8524		if (jsDD.bStarted)
8525		{
8526			if (!jsDD.bEscPressed)
8527			{
8528				jsDD.x = e.clientX + jsDD.wndSize.scrollLeft;
8529				jsDD.y = e.clientY + jsDD.wndSize.scrollTop;
8530			}
8531
8532			if (null != jsDD.current_node.onbxdragstop)
8533				jsDD.current_node.onbxdragstop(jsDD.x, jsDD.y, e);
8534
8535			var containersScroll = jsDD.getContainersScrollPos(jsDD.x, jsDD.y);
8536			var dest_index = jsDD.searchDest(jsDD.x+containersScroll.left, jsDD.y+containersScroll.top);
8537
8538			if (false !== dest_index)
8539			{
8540				if (jsDD.bEscPressed)
8541				{
8542					if (null != jsDD.arDestinations[dest_index].onbxdestdraghout)
8543					{
8544						if (!jsDD.arDestinations[dest_index].onbxdestdraghout(jsDD.current_node, jsDD.x, jsDD.y))
8545							dest_index = false;
8546						else
8547						{
8548							if (null != jsDD.current_node.onbxdragfinish)
8549								jsDD.current_node.onbxdragfinish(jsDD.arDestinations[dest_index], jsDD.x, jsDD.y);
8550						}
8551					}
8552
8553				}
8554				else
8555				{
8556					if (null != jsDD.arDestinations[dest_index].onbxdestdragfinish)
8557					{
8558						if (!jsDD.arDestinations[dest_index].onbxdestdragfinish(jsDD.current_node, jsDD.x, jsDD.y, e))
8559							dest_index = false;
8560						else
8561						{
8562							if (null != jsDD.current_node.onbxdragfinish)
8563								jsDD.current_node.onbxdragfinish(jsDD.arDestinations[dest_index], jsDD.x, jsDD.y);
8564						}
8565					}
8566				}
8567			}
8568
8569			if (false === dest_index)
8570			{
8571				if (null != jsDD.current_node.onbxdragrelease)
8572					jsDD.current_node.onbxdragrelease(jsDD.x, jsDD.y);
8573			}
8574			else
8575			{
8576				for (var i = 0, cnt = jsDD.arDestinations.length; i < cnt; i++)
8577				{
8578					if (i != dest_index && jsDD.arDestinations[i] && null != jsDD.arDestinations[i].onbxdestdragrelease)
8579						jsDD.arDestinations[i].onbxdestdragrelease(jsDD.current_node, jsDD.x, jsDD.y);
8580				}
8581			}
8582
8583			for (var i = 0, cnt = jsDD.arDestinations.length; i < cnt; i++)
8584			{
8585				if (jsDD.arDestinations[i] && null != jsDD.arDestinations[i].onbxdestdragstop)
8586					jsDD.arDestinations[i].onbxdestdragstop(jsDD.current_node, jsDD.x, jsDD.y);
8587			}
8588		}
8589
8590		if(document.body.releaseCapture)
8591			document.body.releaseCapture();
8592
8593		BX.unbind(window, 'scroll', jsDD._onscroll);
8594		BX.unbind(document, "mousemove", jsDD.drag);
8595		BX.unbind(document, "touchmove", jsDD.drag);
8596		BX.unbind(document, "keypress", jsDD._checkEsc);
8597		BX.unbind(document, "mouseup", jsDD.stopDrag);
8598		BX.unbind(document, "touchend", jsDD.stopDrag);
8599
8600		jsDD.allowSelection();
8601		document.body.style.cursor = '';
8602
8603		jsDD.current_node = null;
8604		jsDD.current_dest_index = false;
8605
8606		if (jsDD.bScrollWindow)
8607		{
8608			if (jsDD.scrollViewTimer)
8609				clearInterval(jsDD.scrollViewTimer);
8610		}
8611
8612		if (jsDD.bStarted && !jsDD.bDisableDestRefresh)
8613			jsDD.refreshDestArea();
8614
8615		jsDD.bStarted = false;
8616		jsDD.bEscPressed = false;
8617	},
8618
8619	searchDest: function(x, y)
8620	{
8621		var p, len, p1, len1, i;
8622		for (p = 0, len = jsDD.arDestinationsPriority.length; p < len; p++)
8623		{
8624			if (jsDD.arDestinationsPriority[p] && BX.type.isArray(jsDD.arDestinationsPriority[p]))
8625			{
8626				for (p1 = 0, len1 = jsDD.arDestinationsPriority[p].length; p1 < len1; p1++)
8627				{
8628					i = jsDD.arDestinationsPriority[p][p1];
8629					if (jsDD.arDestinations[i] && !jsDD.arDestinations[i].__bxdddisabled)
8630					{
8631						if (
8632							jsDD.arDestinations[i].__bxpos[0] <= x &&
8633							jsDD.arDestinations[i].__bxpos[2] >= x &&
8634
8635							jsDD.arDestinations[i].__bxpos[1] <= y &&
8636							jsDD.arDestinations[i].__bxpos[3] >= y
8637							)
8638						{
8639							return i;
8640						}
8641					}
8642				}
8643			}
8644		}
8645
8646		return false;
8647	},
8648
8649	allowSelection: function()
8650	{
8651		document.onmousedown = document.ontouchstart = null;
8652		var b = document.body;
8653		b.ondrag = null;
8654		b.onselectstart = null;
8655		b.style.MozUserSelect = '';
8656
8657		if (jsDD.current_node)
8658		{
8659			jsDD.current_node.ondrag = null;
8660			jsDD.current_node.onselectstart = null;
8661			jsDD.current_node.style.MozUserSelect = '';
8662		}
8663	},
8664
8665	denySelection: function()
8666	{
8667		document.onmousedown = document.ontouchstart = BX.False;
8668		var b = document.body;
8669		b.ondrag = BX.False;
8670		b.onselectstart = BX.False;
8671		b.style.MozUserSelect = 'none';
8672		if (jsDD.current_node)
8673		{
8674			jsDD.current_node.ondrag = BX.False;
8675			jsDD.current_node.onselectstart = BX.False;
8676			jsDD.current_node.style.MozUserSelect = 'none';
8677		}
8678	},
8679
8680	Disable: function() {jsDD.bDisable = true;},
8681	Enable: function() {jsDD.bDisable = false;}
8682}
8683
8684})();
8685
8686/* End */
8687;
8688; /* Start:"a:4:{s:4:"full";s:41:"/bitrix/js/main/session.js?16395609593701";s:6:"source";s:26:"/bitrix/js/main/session.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
8689function CBXSession()
8690{
8691	var _this = this;
8692	this.dateInput = new Date();
8693	this.dateCheck = new Date();
8694	this.dateHit = new Date();
8695	this.notifier = null;
8696	this.checkInterval = 60;
8697	this.checkImmediately = false;
8698
8699	this.Expand = function(key)
8700	{
8701		this.key = key;
8702
8703		BX.ready(function(){
8704			BX.bind(document, "keypress", _this.OnUserInput);
8705			BX.bind(document.body, "mousemove", _this.OnUserInput);
8706			BX.bind(document.body, "click", _this.OnUserInput);
8707
8708			//check the state once in a minute
8709			setInterval(_this.CheckSession, _this.checkInterval*1000);
8710		})
8711	};
8712
8713	this.OnUserInput = function()
8714	{
8715		var currentDate = new Date();
8716		_this.dateInput.setTime(currentDate.valueOf());
8717
8718		if ((currentDate - _this.dateHit)/1000 > (_this.checkInterval + 5) && _this.checkImmediately === false)
8719		{
8720			// last hit was long time ago, need to recheck immediately
8721			_this.checkImmediately = true;
8722			_this.CheckSession();
8723		}
8724	};
8725
8726	this.CheckSession = function()
8727	{
8728		var currentDate = new Date();
8729
8730		if((currentDate - _this.dateCheck)/1000 < (_this.checkInterval - 1) && _this.checkImmediately === false)
8731		{
8732			//storm protection, e.g. after PC wake-up
8733			return;
8734		}
8735
8736		_this.dateCheck.setTime(currentDate.valueOf());
8737
8738		if(_this.dateInput > _this.dateHit)
8739		{
8740			//there was input after the last hit, expand/check the session
8741			var config = {
8742				'method': 'GET',
8743				'headers': [
8744					{'name': 'X-Bitrix-Csrf-Token', 'value': BX.bitrix_sessid()}
8745				],
8746				'dataType': 'html',
8747				'url': '/bitrix/tools/public_session.php?k='+_this.key,
8748				'data':  '',
8749				'onsuccess': function(data){_this.CheckResult(data)},
8750				'lsId': 'sess_expand', //caching the result in the local storage for multiple tabs
8751				'lsTimeout': _this.checkInterval - 5 //some delta for response time
8752			};
8753			BX.ajax(config);
8754		}
8755	};
8756
8757	this.CheckResult = function(data)
8758	{
8759		var currentDate = new Date();
8760		_this.dateHit.setTime(currentDate.valueOf());
8761		_this.checkImmediately = false;
8762
8763		if(data == 'SESSION_EXPIRED')
8764		{
8765			if(BX.message("SessExpired"))
8766			{
8767				if(!_this.notifier)
8768				{
8769					_this.notifier = document.body.appendChild(BX.create('DIV', {
8770						props: {className: 'bx-session-message'},
8771						style: {
8772							top: '0',
8773							backgroundColor: '#FFEB41',
8774							border: '1px solid #EDDA3C',
8775							width: '630px',
8776							fontFamily: 'Arial,Helvetica,sans-serif',
8777							fontSize: '13px',
8778							fontWeight: 'bold',
8779							textAlign: 'center',
8780							color: 'black',
8781							position: 'absolute',
8782							zIndex: '10000',
8783							padding: '10px'
8784						},
8785						html: '<a class="bx-session-message-close" ' +
8786							'style="display:block; width:12px; height:12px; background:url(/bitrix/js/main/core/images/close.gif) center no-repeat; float:right;" ' +
8787							'href="javascript:bxSession.Close()"></a>' +
8788							BX.message("SessExpired")
8789					}));
8790
8791					BX.ZIndexManager.register(_this.notifier);
8792					BX.ZIndexManager.bringToFront(_this.notifier);
8793
8794					var windowScroll = BX.GetWindowScrollPos();
8795					var windowSize = BX.GetWindowInnerSize();
8796
8797					_this.notifier.style.left = parseInt(windowScroll.scrollLeft + (windowSize.innerWidth / 2) - (parseInt(_this.notifier.clientWidth) / 2)) + 'px';
8798
8799					if(BX.browser.IsIE())
8800					{
8801						_this.notifier.style.top = windowScroll.scrollTop + 'px';
8802
8803						BX.bind(window, 'scroll', function()
8804						{
8805							var windowScroll = BX.GetWindowScrollPos();
8806							_this.notifier.style.top = windowScroll.scrollTop + 'px';
8807						});
8808					}
8809					else
8810					{
8811						_this.notifier.style.position='fixed';
8812					}
8813				}
8814
8815				_this.notifier.style.display = '';
8816			}
8817		}
8818	};
8819
8820	this.Close = function()
8821	{
8822		this.notifier.style.display = 'none';
8823	}
8824}
8825
8826var bxSession = new CBXSession();
8827
8828/* End */
8829;
8830; /* Start:"a:4:{s:4:"full";s:40:"/bitrix/js/main/utils.js?161544141129279";s:6:"source";s:24:"/bitrix/js/main/utils.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
8831var phpVars;
8832if(!phpVars)
8833{
8834	phpVars = {
8835		ADMIN_THEME_ID: '.default',
8836		LANGUAGE_ID: 'en',
8837		FORMAT_DATE: 'DD.MM.YYYY',
8838		FORMAT_DATETIME: 'DD.MM.YYYY HH:MI:SS',
8839		opt_context_ctrl: false,
8840		cookiePrefix: 'BITRIX_SM',
8841		titlePrefix: '',
8842		bitrix_sessid: '',
8843		messHideMenu: '',
8844		messShowMenu: '',
8845		messHideButtons: '',
8846		messShowButtons: '',
8847		messFilterInactive: '',
8848		messFilterActive: '',
8849		messFilterLess: '',
8850		messLoading: 'Loading...',
8851		messMenuLoading: '',
8852		messMenuLoadingTitle: '',
8853		messNoData: '',
8854		messExpandTabs: '',
8855		messCollapseTabs: '',
8856		messPanelFixOn: '',
8857		messPanelFixOff: '',
8858		messPanelCollapse: '',
8859		messPanelExpand: ''
8860	};
8861}
8862
8863var jsUtils =
8864{
8865	arEvents: Array(),
8866
8867	addEvent: function(el, evname, func, capture)
8868	{
8869		if(el.attachEvent) // IE
8870			el.attachEvent("on" + evname, func);
8871		else if(el.addEventListener) // Gecko / W3C
8872			el.addEventListener(evname, func, false);
8873		else
8874			el["on" + evname] = func;
8875		this.arEvents[this.arEvents.length] = {'element': el, 'event': evname, 'fn': func};
8876	},
8877
8878	removeEvent: function(el, evname, func)
8879	{
8880		if(el.detachEvent) // IE
8881			el.detachEvent("on" + evname, func);
8882		else if(el.removeEventListener) // Gecko / W3C
8883			el.removeEventListener(evname, func, false);
8884		else
8885			el["on" + evname] = null;
8886	},
8887
8888	removeAllEvents: function(el)
8889	{
8890		var i;
8891		for(i=0; i<this.arEvents.length; i++)
8892		{
8893			if(this.arEvents[i] && (el==false || el==this.arEvents[i].element))
8894			{
8895				jsUtils.removeEvent(this.arEvents[i].element, this.arEvents[i].event, this.arEvents[i].fn);
8896				this.arEvents[i] = null;
8897			}
8898		}
8899		if(el==false)
8900			this.arEvents.length = 0;
8901	},
8902
8903	IsDoctype: function()
8904	{
8905		if (document.compatMode)
8906			return (document.compatMode == "CSS1Compat");
8907
8908		if (document.documentElement && document.documentElement.clientHeight)
8909			return true;
8910
8911		return false;
8912	},
8913
8914	GetRealPos: function(el)
8915	{
8916		if(window.BX)
8917			return BX.pos(el);
8918
8919		if(!el || !el.offsetParent)
8920			return false;
8921
8922		var res = Array();
8923		res["left"] = el.offsetLeft;
8924		res["top"] = el.offsetTop;
8925		var objParent = el.offsetParent;
8926
8927		while(objParent && objParent.tagName != "BODY")
8928		{
8929			res["left"] += objParent.offsetLeft;
8930			res["top"] += objParent.offsetTop;
8931			objParent = objParent.offsetParent;
8932		}
8933		res["right"] = res["left"] + el.offsetWidth;
8934		res["bottom"] = res["top"] + el.offsetHeight;
8935
8936		return res;
8937	},
8938
8939	FindChildObject: function(obj, tag_name, class_name, recursive)
8940	{
8941		if(!obj)
8942			return null;
8943		var tag = tag_name.toUpperCase();
8944		var cl = (class_name? class_name.toLowerCase() : null);
8945		var n = obj.childNodes.length;
8946		for(var j=0; j<n; j++)
8947		{
8948			var child = obj.childNodes[j];
8949			if(child.tagName && child.tagName.toUpperCase() == tag)
8950				if(!class_name || child.className.toLowerCase() == cl)
8951					return child;
8952			if(recursive == true)
8953			{
8954				var deepChild;
8955				if((deepChild = jsUtils.FindChildObject(child, tag_name, class_name, true)))
8956					return deepChild;
8957			}
8958		}
8959		return null;
8960	},
8961
8962	FindParentObject: function(obj, tag_name, class_name)
8963	{
8964		if(!obj)
8965			return null;
8966		var o = obj;
8967		var tag = tag_name.toUpperCase();
8968		var cl = (class_name? class_name.toLowerCase() : null);
8969		while(o.parentNode)
8970		{
8971			var parent = o.parentNode;
8972			if(parent.tagName && parent.tagName.toUpperCase() == tag)
8973				if(!class_name || parent.className.toLowerCase() == cl)
8974					return parent;
8975			o = parent;
8976		}
8977		return null;
8978	},
8979
8980	FindNextSibling: function(obj, tag_name)
8981	{
8982		if(!obj)
8983			return null;
8984		var o = obj;
8985		var tag = tag_name.toUpperCase();
8986		while(o.nextSibling)
8987		{
8988			var sibling = o.nextSibling;
8989			if(sibling.tagName && sibling.tagName.toUpperCase() == tag)
8990				return sibling;
8991			o = sibling;
8992		}
8993		return null;
8994	},
8995
8996	FindPreviousSibling: function(obj, tag_name)
8997	{
8998		if(!obj)
8999			return null;
9000		var o = obj;
9001		var tag = tag_name.toUpperCase();
9002		while(o.previousSibling)
9003		{
9004			var sibling = o.previousSibling;
9005			if(sibling.tagName && sibling.tagName.toUpperCase() == tag)
9006				return sibling;
9007			o = sibling;
9008		}
9009		return null;
9010	},
9011
9012	bOpera : navigator.userAgent.toLowerCase().indexOf('opera') != -1,
9013	bIsIE : document.attachEvent && navigator.userAgent.toLowerCase().indexOf('opera') == -1,
9014
9015	IsIE: function()
9016	{
9017		return this.bIsIE;
9018	},
9019
9020	IsOpera: function()
9021	{
9022		return this.bOpera;
9023	},
9024
9025	IsSafari: function()
9026	{
9027		var userAgent = navigator.userAgent.toLowerCase();
9028		return (/webkit/.test(userAgent));
9029	},
9030
9031	IsEditor: function()
9032	{
9033		var userAgent = navigator.userAgent.toLowerCase();
9034		var version = (userAgent.match( /.+(msie)[\/: ]([\d.]+)/ ) || [])[2];
9035		var safari = /webkit/.test(userAgent);
9036
9037		if (this.IsOpera() || (document.all && !document.compatMode && version < 6) || safari)
9038			return false;
9039
9040		return true;
9041	},
9042
9043	ToggleDiv: function(div)
9044	{
9045		var style = document.getElementById(div).style;
9046		if(style.display!="none")
9047			style.display = "none";
9048		else
9049			style.display = "block";
9050		return (style.display != "none");
9051	},
9052
9053	urlencode: function(s)
9054	{
9055		return escape(s).replace(new RegExp('\\+','g'), '%2B');
9056	},
9057
9058	OpenWindow: function(url, width, height)
9059	{
9060		var w = screen.width, h = screen.height;
9061		if(this.IsOpera())
9062		{
9063			w = document.body.offsetWidth;
9064			h = document.body.offsetHeight;
9065		}
9066		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));
9067	},
9068
9069	SetPageTitle: function(s)
9070	{
9071		document.title = phpVars.titlePrefix+s;
9072		var h1 = document.getElementsByTagName("H1");
9073		if(h1)
9074			h1[0].innerHTML = s;
9075	},
9076
9077	LoadPageToDiv: function(url, div_id)
9078	{
9079		var div = document.getElementById(div_id);
9080		if(!div)
9081			return;
9082		CHttpRequest.Action = function(result)
9083		{
9084			CloseWaitWindow();
9085			document.getElementById(div_id).innerHTML = result;
9086		}
9087		ShowWaitWindow();
9088		CHttpRequest.Send(url);
9089	},
9090
9091	trim: function(s)
9092	{
9093		if (typeof s == 'string' || typeof s == 'object' && s.constructor == String)
9094		{
9095			var r, re;
9096
9097			re = /^[\s\r\n]+/g;
9098			r = s.replace(re, "");
9099			re = /[\s\r\n]+$/g;
9100			r = r.replace(re, "");
9101			return r;
9102		}
9103		else
9104			return s;
9105	},
9106
9107	Redirect: function(args, url)
9108	{
9109		var e = null, bShift = false;
9110		if(args && args.length > 0)
9111			e = args[0];
9112		if(!e)
9113			e = window.event;
9114		if(e)
9115			bShift = e.shiftKey;
9116
9117		if(bShift)
9118			window.open(url);
9119		else
9120		{
9121			window.location.href=url;
9122		}
9123	},
9124
9125	False: function(){return false;},
9126
9127	AlignToPos: function(pos, w, h)
9128	{
9129		var x = pos["left"], y = pos["bottom"];
9130
9131		var scroll = jsUtils.GetWindowScrollPos();
9132		var size = jsUtils.GetWindowInnerSize();
9133
9134		if((size.innerWidth + scroll.scrollLeft) - (pos["left"] + w) < 0)
9135		{
9136			if(pos["right"] - w >= 0 )
9137				x = pos["right"] - w;
9138			else
9139				x = scroll.scrollLeft;
9140		}
9141
9142		if((size.innerHeight + scroll.scrollTop) - (pos["bottom"] + h) < 0)
9143		{
9144			if(pos["top"] - h >= 0)
9145				y = pos["top"] - h;
9146			else
9147				y = scroll.scrollTop;
9148		}
9149
9150		return {'left':x, 'top':y};
9151	},
9152
9153	// evaluate js string in window scope
9154	EvalGlobal: function(script)
9155	{
9156		try {
9157		if (window.execScript)
9158			window.execScript(script, 'javascript');
9159		else if (jsUtils.IsSafari())
9160			window.setTimeout(script, 0);
9161		else
9162			window.eval(script);
9163		} catch (e) {/*alert("Error! jsUtils.EvalGlobal");*/}
9164	},
9165
9166	GetStyleValue: function(el, styleProp)
9167	{
9168		var res;
9169		if(el.currentStyle)
9170			res = el.currentStyle[styleProp];
9171		else if(window.getComputedStyle)
9172			res = document.defaultView.getComputedStyle(el, null).getPropertyValue(styleProp);
9173		if(!res)
9174			res = '';
9175		return res;
9176	},
9177
9178	GetWindowInnerSize: function(pDoc)
9179	{
9180		var width, height;
9181		if (!pDoc)
9182			pDoc = document;
9183
9184		if (self.innerHeight) // all except Explorer
9185		{
9186			width = self.innerWidth;
9187			height = self.innerHeight;
9188		}
9189		else if (pDoc.documentElement && (pDoc.documentElement.clientHeight || pDoc.documentElement.clientWidth)) // Explorer 6 Strict Mode
9190		{
9191			width = pDoc.documentElement.clientWidth;
9192			height = pDoc.documentElement.clientHeight;
9193		}
9194		else if (pDoc.body) // other Explorers
9195		{
9196			width = pDoc.body.clientWidth;
9197			height = pDoc.body.clientHeight;
9198		}
9199		return {innerWidth : width, innerHeight : height};
9200	},
9201
9202	GetWindowScrollPos: function(pDoc)
9203	{
9204		var left, top;
9205		if (!pDoc)
9206			pDoc = document;
9207
9208		if (self.pageYOffset) // all except Explorer
9209		{
9210			left = self.pageXOffset;
9211			top = self.pageYOffset;
9212		}
9213		else if (pDoc.documentElement && (pDoc.documentElement.scrollTop || pDoc.documentElement.scrollLeft)) // Explorer 6 Strict
9214		{
9215			left = document.documentElement.scrollLeft;
9216			top = document.documentElement.scrollTop;
9217		}
9218		else if (pDoc.body) // all other Explorers
9219		{
9220			left = pDoc.body.scrollLeft;
9221			top = pDoc.body.scrollTop;
9222		}
9223		return {scrollLeft : left, scrollTop : top};
9224	},
9225
9226	GetWindowScrollSize: function(pDoc)
9227	{
9228		var width, height;
9229		if (!pDoc)
9230			pDoc = document;
9231
9232		if ( (pDoc.compatMode && pDoc.compatMode == "CSS1Compat"))
9233		{
9234			width = pDoc.documentElement.scrollWidth;
9235			height = pDoc.documentElement.scrollHeight;
9236		}
9237		else
9238		{
9239			if (pDoc.body.scrollHeight > pDoc.body.offsetHeight)
9240				height = pDoc.body.scrollHeight;
9241			else
9242				height = pDoc.body.offsetHeight;
9243
9244			if (pDoc.body.scrollWidth > pDoc.body.offsetWidth ||
9245				(pDoc.compatMode && pDoc.compatMode == "BackCompat") ||
9246				(pDoc.documentElement && !pDoc.documentElement.clientWidth)
9247			)
9248				width = pDoc.body.scrollWidth;
9249			else
9250				width = pDoc.body.offsetWidth;
9251		}
9252		return {scrollWidth : width, scrollHeight : height};
9253	},
9254
9255	GetWindowSize: function()
9256	{
9257		var innerSize = jsUtils.GetWindowInnerSize();
9258		var scrollPos = jsUtils.GetWindowScrollPos();
9259		var scrollSize = jsUtils.GetWindowScrollSize();
9260
9261		return  {
9262			innerWidth : innerSize.innerWidth, innerHeight : innerSize.innerHeight,
9263			scrollLeft : scrollPos.scrollLeft, scrollTop : scrollPos.scrollTop,
9264			scrollWidth : scrollSize.scrollWidth, scrollHeight : scrollSize.scrollHeight
9265		};
9266	},
9267
9268
9269	arCustomEvents: {},
9270
9271	addCustomEvent: function(eventName, eventHandler, arParams, handlerContextObject)
9272	{
9273		if (!this.arCustomEvents[eventName])
9274			this.arCustomEvents[eventName] = [];
9275
9276		if (!arParams)
9277			arParams = [];
9278		if (!handlerContextObject)
9279			handlerContextObject = false;
9280
9281		this.arCustomEvents[eventName].push(
9282			{
9283				handler: eventHandler,
9284				arParams: arParams,
9285				obj: handlerContextObject
9286			}
9287		);
9288	},
9289
9290	removeCustomEvent: function(eventName, eventHandler)
9291	{
9292		if (!this.arCustomEvents[eventName])
9293			return;
9294
9295		var l = this.arCustomEvents[eventName].length;
9296		if (l == 1)
9297		{
9298			delete this.arCustomEvents[eventName];
9299			return;
9300		}
9301
9302		for (var i = 0; i < l; i++)
9303		{
9304			if (!this.arCustomEvents[eventName][i])
9305				continue;
9306			if (this.arCustomEvents[eventName][i].handler == eventHandler)
9307			{
9308				delete this.arCustomEvents[eventName][i];
9309				return;
9310			}
9311		}
9312	},
9313
9314	onCustomEvent: function(eventName, arEventParams)
9315	{
9316		if (!this.arCustomEvents[eventName])
9317			return;
9318
9319		if (!arEventParams)
9320			arEventParams = [];
9321
9322		var h;
9323		for (var i = 0, l = this.arCustomEvents[eventName].length; i < l; i++)
9324		{
9325			h = this.arCustomEvents[eventName][i];
9326			if (!h || !h.handler)
9327				continue;
9328
9329			if (h.obj)
9330				h.handler.call(h.obj, h.arParams, arEventParams);
9331			else
9332				h.handler(h.arParams, arEventParams);
9333		}
9334	},
9335
9336	loadJSFile: function(arJs, oCallBack, pDoc)
9337	{
9338		if (!pDoc)
9339			pDoc = document;
9340		if (typeof arJs == 'string')
9341			arJs = [arJs];
9342		var callback = function()
9343		{
9344			if (!oCallBack)
9345				return;
9346			if (typeof oCallBack == 'function')
9347				return oCallBack();
9348			if (typeof oCallBack != 'object' || !oCallBack.func)
9349				return;
9350			var p = oCallBack.params || {};
9351			if (oCallBack.obj)
9352				oCallBack.func.apply(oCallBack.obj, p);
9353			else
9354				oCallBack.func(p);
9355		};
9356		var load_js = function(ind)
9357		{
9358			if (ind >= arJs.length)
9359				return callback();
9360			var oSript = pDoc.body.appendChild(pDoc.createElement('script'));
9361			oSript.src = arJs[ind];
9362			var bLoaded = false;
9363			oSript.onload = oSript.onreadystatechange = function()
9364			{
9365				if (!bLoaded && (!oSript.readyState || oSript.readyState == "loaded" || oSript.readyState == "complete"))
9366				{
9367					bLoaded = true;
9368					setTimeout(function (){load_js(++ind);}, 50);
9369				}
9370			};
9371		};
9372		load_js(0);
9373	},
9374
9375	loadCSSFile: function(arCSS, pDoc, pWin)
9376	{
9377		if (typeof arCSS == 'string')
9378		{
9379			var bSingle = true;
9380			arCSS = [arCSS];
9381		}
9382		var i, l = arCSS.length, pLnk = [];
9383		if (l == 0)
9384			return;
9385		if (!pDoc)
9386			pDoc = document;
9387		if (!pWin)
9388			pWin = window;
9389		if (!pWin.bxhead)
9390		{
9391			var heads = pDoc.getElementsByTagName('HEAD');
9392			pWin.bxhead = heads[0];
9393		}
9394		if (!pWin.bxhead)
9395			return;
9396		for (i = 0; i < l; i++)
9397		{
9398			var lnk = document.createElement('LINK');
9399			lnk.href = arCSS[i];
9400			lnk.rel = 'stylesheet';
9401			lnk.type = 'text/css';
9402			pWin.bxhead.appendChild(lnk);
9403			pLnk.push(lnk);
9404		}
9405		if (bSingle)
9406			return lnk;
9407		return pLnk;
9408	},
9409
9410	appendBXHint : function(node, html)
9411	{
9412		if (!node || !node.parentNode || !html)
9413			return;
9414		var oBXHint = new BXHint(html);
9415		node.parentNode.insertBefore(oBXHint.oIcon, node);
9416		node.parentNode.removeChild(node);
9417		oBXHint.oIcon.style.marginLeft = "5px";
9418	},
9419
9420	PreventDefault : function(e)
9421	{
9422		if(!e) e = window.event;
9423		if(e.stopPropagation)
9424		{
9425			e.preventDefault();
9426			e.stopPropagation();
9427		}
9428		else
9429		{
9430			e.cancelBubble = true;
9431			e.returnValue = false;
9432		}
9433		return false;
9434	},
9435
9436	CreateElement: function(tag, arAttr, arStyles, pDoc)
9437	{
9438		if (!pDoc)
9439			pDoc = document;
9440		var pEl = pDoc.createElement(tag), p;
9441		if(arAttr)
9442		{
9443			for(p in arAttr)
9444			{
9445				if(p == 'className' || p == 'class')
9446				{
9447					pEl.setAttribute('class', arAttr[p]);
9448					if (jsUtils.IsIE())
9449						pEl.setAttribute('className', arAttr[p]);
9450					continue;
9451				}
9452
9453				if (arAttr[p] != undefined && arAttr[p] != null)
9454					pEl.setAttribute(p, arAttr[p]);
9455			}
9456		}
9457		if(arStyles)
9458		{
9459			for(p in arStyles)
9460				pEl.style[p] = arStyles[p];
9461		}
9462		return pEl;
9463	},
9464
9465	in_array: function(needle, haystack)
9466	{
9467		for(var i=0; i<haystack.length; i++)
9468		{
9469			if(haystack[i] == needle)
9470				return true;
9471		}
9472		return false;
9473	},
9474
9475	htmlspecialchars: function(str)
9476	{
9477		if(!str.replace)
9478			return str;
9479
9480		return str.replace(/&/g, '&amp;').replace(/"/g, '&quot;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
9481	}
9482}
9483
9484/************************************************/
9485
9486function JCFloatDiv()
9487{
9488	var _this = this;
9489	this.floatDiv = null;
9490	this.x = this.y = 0;
9491
9492	this.Create = function(arParams)
9493	{
9494		var div = document.body.appendChild(document.createElement("DIV"));
9495		div.id = arParams.id;
9496		div.style.position = 'absolute';
9497		div.style.left = '-10000px';
9498		div.style.top = '-10000px';
9499		if(arParams.className)
9500			div.className = arParams.className;
9501		if(arParams.zIndex)
9502			div.style.zIndex = arParams.zIndex;
9503		if(arParams.width)
9504			div.style.width = arParams.width+'px';
9505		if(arParams.height)
9506			div.style.height = arParams.height+'px';
9507		return div;
9508	}
9509
9510	this.Show = function(div, left, top, dxShadow, restrictDrag)
9511	{
9512		var component = BX.ZIndexManager.getComponent(div);
9513		if (!component)
9514		{
9515			BX.ZIndexManager.register(div);
9516		}
9517
9518		BX.ZIndexManager.bringToFront(div);
9519
9520		if (left < 0)
9521			left = 0;
9522
9523		if (top < 0)
9524			top = 0;
9525
9526		div.style.left = parseInt(left) + "px";
9527		div.style.top = parseInt(top) + "px";
9528
9529		/*Restrict drag*/
9530		div.restrictDrag = restrictDrag || false;
9531
9532		/*shadow*/
9533		if(isNaN(dxShadow))
9534			dxShadow = 5;
9535
9536		div.dxShadow = dxShadow;
9537	}
9538
9539	this.Close = function(div)
9540	{
9541		if(!div)
9542			return;
9543		var sh = document.getElementById(div.id+"_shadow");
9544		if(sh)
9545			sh.style.visibility = 'hidden';
9546
9547		var frame = document.getElementById(div.id+"_frame");
9548		if(frame)
9549			frame.style.visibility = 'hidden';
9550	}
9551
9552	this.Move = function(div, x, y)
9553	{
9554		if(!div)
9555			return;
9556
9557		var dxShadow = div.dxShadow;
9558		var left = parseInt(div.style.left)+x;
9559		var top = parseInt(div.style.top)+y;
9560
9561		if (div.restrictDrag)
9562		{
9563			//Left side
9564			if (left < 0)
9565				left = 0;
9566
9567			//Right side
9568			if ( (document.compatMode && document.compatMode == "CSS1Compat"))
9569				windowWidth = document.documentElement.scrollWidth;
9570			else
9571			{
9572				if (document.body.scrollWidth > document.body.offsetWidth ||
9573					(document.compatMode && document.compatMode == "BackCompat") ||
9574					(document.documentElement && !document.documentElement.clientWidth)
9575				)
9576					windowWidth = document.body.scrollWidth;
9577				else
9578					windowWidth = document.body.offsetWidth;
9579			}
9580
9581			var floatWidth = div.offsetWidth;
9582			if (left > (windowWidth - floatWidth - dxShadow))
9583				left = windowWidth - floatWidth - dxShadow;
9584
9585			//Top side
9586			if (top < 0)
9587				top = 0;
9588		}
9589
9590		div.style.left = left+'px';
9591		div.style.top = top+'px';
9592
9593		this.AdjustShadow(div);
9594	}
9595
9596	this.HideShadow = function(div)
9597	{
9598		var sh = document.getElementById(div.id + "_shadow");
9599		sh.style.visibility = 'hidden';
9600	}
9601
9602	this.UnhideShadow = function(div)
9603	{
9604		var sh = document.getElementById(div.id + "_shadow");
9605		sh.style.visibility = 'visible';
9606	}
9607
9608	this.AdjustShadow = function(div)
9609	{
9610		var sh = document.getElementById(div.id + "_shadow");
9611		if(sh && sh.style.visibility != 'hidden')
9612		{
9613			var dxShadow = div.dxShadow;
9614
9615			sh.style.width = div.offsetWidth+'px';
9616			sh.style.height = div.offsetHeight+'px';
9617			sh.style.left = parseInt(div.style.left)+dxShadow+'px';
9618			sh.style.top = parseInt(div.style.top)+dxShadow+'px';
9619		}
9620
9621		var frame = document.getElementById(div.id+"_frame");
9622		if(frame)
9623		{
9624			frame.style.width = div.offsetWidth + "px";
9625			frame.style.height = div.offsetHeight + "px";
9626			frame.style.left = div.style.left;
9627			frame.style.top = div.style.top;
9628		}
9629	}
9630
9631	this.StartDrag = function(e, div)
9632	{
9633		if(!e)
9634			e = window.event;
9635		this.x = e.clientX + document.body.scrollLeft;
9636		this.y = e.clientY + document.body.scrollTop;
9637		this.floatDiv = div;
9638
9639		jsUtils.addEvent(document, "mousemove", this.MoveDrag);
9640		document.onmouseup = this.StopDrag;
9641		if(document.body.setCapture)
9642			document.body.setCapture();
9643
9644		document.onmousedown = jsUtils.False;
9645		var b = document.body;
9646		b.ondrag = jsUtils.False;
9647		b.onselectstart = jsUtils.False;
9648		b.style.MozUserSelect = _this.floatDiv.style.MozUserSelect = 'none';
9649		b.style.cursor = 'move';
9650	}
9651
9652	this.StopDrag = function(e)
9653	{
9654		if(document.body.releaseCapture)
9655			document.body.releaseCapture();
9656
9657		jsUtils.removeEvent(document, "mousemove", _this.MoveDrag);
9658		document.onmouseup = null;
9659
9660		this.floatDiv = null;
9661
9662		document.onmousedown = null;
9663		var b = document.body;
9664		b.ondrag = null;
9665		b.onselectstart = null;
9666		b.style.MozUserSelect = _this.floatDiv.style.MozUserSelect = '';
9667		b.style.cursor = '';
9668	}
9669
9670	this.MoveDrag = function(e)
9671	{
9672		var x = e.clientX + document.body.scrollLeft;
9673		var y = e.clientY + document.body.scrollTop;
9674
9675		if(_this.x == x && _this.y == y)
9676			return;
9677
9678		_this.Move(_this.floatDiv, (x - _this.x), (y - _this.y));
9679		_this.x = x;
9680		_this.y = y;
9681	}
9682}
9683var jsFloatDiv = new JCFloatDiv();
9684
9685/************************************************/
9686
9687var BXHint = function(innerHTML, element, addParams)
9688{
9689	this.oDivOver = false;
9690	this.timeOutID = null;
9691	this.oIcon = null;
9692	this.freeze = false;
9693	this.x = 0;
9694	this.y = 0;
9695	this.time = 700;
9696
9697	if (!innerHTML)
9698		innerHTML = "";
9699	this.Create(innerHTML, element, addParams);
9700}
9701
9702BXHint.prototype.Create = function(innerHTML, element, addParams)
9703{
9704	var
9705		_this = this,
9706		width = 0,
9707		height = 0,
9708		className = null,
9709		type = "icon";
9710	this.bWidth = true;
9711
9712	if (addParams)
9713	{
9714		if (addParams.width === false)
9715			this.bWidth = false;
9716		else if (addParams.width)
9717			width = addParams.width;
9718
9719		if (addParams.height)
9720			height = addParams.height;
9721
9722		if (addParams.className)
9723			className = addParams.className;
9724
9725		if (addParams.type && (addParams.type == "link" || addParams.type == "icon"))
9726			type = addParams.type;
9727		if (addParams.time > 0)
9728			this.time = addParams.time;
9729	}
9730
9731	if (element)
9732		type = "element";
9733
9734	if (type == "icon")
9735	{
9736		var element = document.createElement("IMG");
9737		element.src = (addParams && addParams.iconSrc) ? addParams.iconSrc : "/bitrix/themes/"+phpVars.ADMIN_THEME_ID+"/public/popup/hint.gif";
9738		element.ondrag = jsUtils.False;
9739	}
9740	else if (type == "link")
9741	{
9742		var element = document.createElement("A");
9743		element.href = "";
9744		element.onclick = function(e){return false;}
9745		element.innerHTML = "[?]";
9746	}
9747
9748	this.element = element;
9749	if (type == "element")
9750	{
9751		if(addParams && addParams.show_on_click)
9752		{
9753			jsUtils.addEvent(
9754				element,
9755				"click",
9756				function (event)
9757				{
9758					if (!event)
9759						event = window.event;
9760					_this.GetMouseXY(event);
9761					_this.timeOutID = setTimeout(function () {_this.Show(innerHTML,width,height,className) }, 10);
9762				}
9763			);
9764		}
9765		else
9766		{
9767			jsUtils.addEvent(
9768				element,
9769				"mouseover",
9770				function (event)
9771				{
9772					if (!event)
9773						event = window.event;
9774					_this.GetMouseXY(event);
9775					_this.timeOutID = setTimeout(function () {_this.Show(innerHTML,width,height,className) }, 750);
9776				}
9777			);
9778		}
9779
9780		jsUtils.addEvent(
9781			element,
9782			"mouseout",
9783			function(event)
9784			{
9785				if (_this.timeOutID)
9786					clearTimeout(_this.timeOutID);
9787				_this.SmartHide(_this);
9788			}
9789		);
9790	}
9791	else
9792	{
9793		this.oIcon = element;
9794		element.onmouseover = function(event) {if (!event) event = window.event; _this.GetMouseXY(event); _this.Show(innerHTML,width,height,className)};
9795		element.onmouseout = function() {_this.SmartHide(_this);};
9796	}
9797}
9798
9799BXHint.prototype.IsFrozen = function()
9800{
9801	return this.freeze;
9802}
9803
9804BXHint.prototype.Freeze = function()
9805{
9806	this.freeze = true;
9807	this.Hide();
9808}
9809
9810BXHint.prototype.UnFreeze = function()
9811{
9812	this.freeze = false;
9813}
9814
9815BXHint.prototype.GetMouseXY = function(event)
9816{
9817	if (event.pageX || event.pageY)
9818	{
9819		this.x = event.pageX;
9820		this.y = event.pageY;
9821	}
9822	else if (event.clientX || event.clientY)
9823	{
9824		this.x = event.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft) - document.documentElement.clientLeft;
9825		this.y = event.clientY + (document.documentElement.scrollTop || document.body.scrollTop) - document.documentElement.clientTop;
9826	}
9827}
9828
9829BXHint.prototype.Show = function(innerHTML, width, height, className)
9830{
9831	//Delete previous hint
9832	var old = document.getElementById("__BXHint_div");
9833	if (old)
9834		this.Hide();
9835
9836	if (this.freeze)
9837		return;
9838
9839	var _this = this;
9840	var oDiv = document.body.appendChild(document.createElement("DIV"));
9841	oDiv.onmouseover = function(){_this.oDivOver = true};
9842	oDiv.onmouseout = function(){_this.oDivOver = false; _this.SmartHide(_this);}
9843	oDiv.id = "__BXHint_div";
9844	oDiv.className = (className) ? className : "bxhint";
9845	oDiv.style.position = 'absolute';
9846	if (width && this.bWidth)
9847		oDiv.style.width = width + "px";
9848
9849	if (height)
9850		oDiv.style.height = height + "px";
9851	oDiv.innerHTML = innerHTML;
9852
9853	var w = oDiv.offsetWidth;
9854	var h = oDiv.offsetHeight;
9855	if (this.bWidth)
9856	{
9857		if (!width && w>200)
9858			w = Math.round(Math.sqrt(1.618*w*h));
9859		oDiv.style.width = w + "px";
9860		h = oDiv.offsetHeight;
9861	}
9862
9863	var pos = {left : this.x + 10, right : this.x + w, top : this.y, bottom : this.y + h};
9864
9865	pos = this.AlignToPos(pos, w, h);
9866
9867	jsFloatDiv.Show(oDiv, pos.left, pos.top,3);
9868
9869//	oDiv.ondrag = jsUtils.False;
9870//	oDiv.onselectstart = jsUtils.False;
9871//	oDiv.style.MozUserSelect = 'none';
9872	oDiv = null;
9873}
9874
9875BXHint.prototype.AlignToPos = function(pos, w, h)
9876{
9877	var body = document.body;
9878	if((body.clientWidth + body.scrollLeft) < (pos.left + w))
9879		pos.left = (pos.left - w >= 0) ? (pos.left - w) : body.scrollLeft;
9880
9881	if((body.clientHeight + body.scrollTop) - (pos["bottom"]) < 0)
9882		pos.top = (pos.top - h >= 0) ? (pos.top - h) : body.scrollTop;
9883
9884	return pos;
9885}
9886
9887BXHint.prototype.Hide = function()
9888{
9889	var oDiv = document.getElementById("__BXHint_div");
9890
9891	if (!oDiv)
9892		return;
9893
9894	BX.ZIndexManager.unregister(oDiv);
9895
9896	jsFloatDiv.Close(oDiv);
9897	oDiv.parentNode.removeChild(oDiv);
9898	oDiv = null;
9899}
9900
9901BXHint.prototype.SmartHide = function(_this)
9902{
9903	setTimeout(function ()
9904		{
9905			if (!_this.oDivOver)
9906				_this.Hide();
9907		}, 100
9908	);
9909}
9910
9911/************************************************/
9912
9913function WaitOnKeyPress(e)
9914{
9915	if(!e) e = window.event
9916	if(!e) return;
9917	if(e.keyCode == 27)
9918		CloseWaitWindow();
9919}
9920
9921function ShowWaitWindow()
9922{
9923	CloseWaitWindow();
9924
9925	var obWndSize = jsUtils.GetWindowSize();
9926
9927	var div = document.body.appendChild(document.createElement("DIV"));
9928	div.id = "wait_window_div";
9929	div.innerHTML = phpVars.messLoading;
9930	div.className = "waitwindow";
9931	//div.style.left = obWndSize.scrollLeft + (obWndSize.innerWidth - div.offsetWidth) - (jsUtils.IsIE() ? 5 : 20) + "px";
9932	div.style.right = (5 - obWndSize.scrollLeft) + 'px';
9933	div.style.top = obWndSize.scrollTop + 5 + "px";
9934
9935	if(jsUtils.IsIE())
9936	{
9937		var frame = document.createElement("IFRAME");
9938		frame.src = "javascript:''";
9939		frame.id = "wait_window_frame";
9940		frame.className = "waitwindow";
9941		frame.style.width = div.offsetWidth + "px";
9942		frame.style.height = div.offsetHeight + "px";
9943		frame.style.right = div.style.right;
9944		frame.style.top = div.style.top;
9945		document.body.appendChild(frame);
9946	}
9947	jsUtils.addEvent(document, "keypress", WaitOnKeyPress);
9948}
9949
9950function CloseWaitWindow()
9951{
9952	jsUtils.removeEvent(document, "keypress", WaitOnKeyPress);
9953
9954	var frame = document.getElementById("wait_window_frame");
9955	if(frame)
9956		frame.parentNode.removeChild(frame);
9957
9958	var div = document.getElementById("wait_window_div");
9959	if(div)
9960		div.parentNode.removeChild(div);
9961}
9962
9963/************************************************/
9964
9965var jsSelectUtils =
9966{
9967	addNewOption: function(select_id, opt_value, opt_name, do_sort, check_unique)
9968	{
9969		var oSelect = (typeof(select_id) == 'string' || select_id instanceof String? document.getElementById(select_id) : select_id);
9970		if(oSelect)
9971		{
9972			var n = oSelect.length;
9973			if(check_unique !== false)
9974			{
9975				for(var i=0;i<n;i++)
9976					if(oSelect[i].value==opt_value)
9977						return;
9978			}
9979			var newoption = new Option(opt_name, opt_value, false, false);
9980			oSelect.options[n]=newoption;
9981		}
9982		if(do_sort === true)
9983			this.sortSelect(select_id);
9984	},
9985
9986	deleteOption: function(select_id, opt_value)
9987	{
9988		var oSelect = (typeof(select_id) == 'string' || select_id instanceof String? document.getElementById(select_id) : select_id);
9989		if(oSelect)
9990		{
9991			for(var i=0;i<oSelect.length;i++)
9992				if(oSelect[i].value==opt_value)
9993				{
9994					oSelect.remove(i);
9995					break;
9996				}
9997		}
9998	},
9999
10000	deleteSelectedOptions: function(select_id)
10001	{
10002		var oSelect = (typeof(select_id) == 'string' || select_id instanceof String? document.getElementById(select_id) : select_id);
10003		if(oSelect)
10004		{
10005			var i=0;
10006			while(i<oSelect.length)
10007				if(oSelect[i].selected)
10008				{
10009					oSelect[i].selected=false;
10010					oSelect.remove(i);
10011				}
10012				else
10013					i++;
10014		}
10015	},
10016
10017	deleteAllOptions: function(oSelect)
10018	{
10019		if(oSelect)
10020		{
10021			for(var i=oSelect.length-1; i>=0; i--)
10022				oSelect.remove(i);
10023		}
10024	},
10025
10026	optionCompare: function(record1, record2)
10027	{
10028		var value1 = record1.optText.toLowerCase();
10029		var value2 = record2.optText.toLowerCase();
10030		if (value1 > value2) return(1);
10031		if (value1 < value2) return(-1);
10032		return(0);
10033	},
10034
10035	sortSelect: function(select_id)
10036	{
10037		var oSelect = (typeof(select_id) == 'string' || select_id instanceof String? document.getElementById(select_id) : select_id);
10038		if(oSelect)
10039		{
10040			var myOptions = [];
10041			var n = oSelect.options.length;
10042			for (var i=0;i<n;i++)
10043			{
10044				myOptions[i] = {
10045					optText:oSelect[i].text,
10046					optValue:oSelect[i].value
10047				};
10048			}
10049			myOptions.sort(this.optionCompare);
10050			oSelect.length=0;
10051			n = myOptions.length;
10052			for(var i=0;i<n;i++)
10053			{
10054				var newoption = new Option(myOptions[i].optText, myOptions[i].optValue, false, false);
10055				oSelect[i]=newoption;
10056			}
10057		}
10058	},
10059
10060	selectAllOptions: function(select_id)
10061	{
10062		var oSelect = (typeof(select_id) == 'string' || select_id instanceof String? document.getElementById(select_id) : select_id);
10063		if(oSelect)
10064		{
10065			var n = oSelect.length;
10066			for(var i=0;i<n;i++)
10067				oSelect[i].selected=true;
10068		}
10069	},
10070
10071	selectOption: function(select_id, opt_value)
10072	{
10073		var oSelect = (typeof(select_id) == 'string' || select_id instanceof String? document.getElementById(select_id) : select_id);
10074		if(oSelect)
10075		{
10076			var n = oSelect.length;
10077			for(var i=0;i<n;i++)
10078				oSelect[i].selected = (oSelect[i].value == opt_value);
10079		}
10080	},
10081
10082	addSelectedOptions: function(oSelect, to_select_id, check_unique, do_sort)
10083	{
10084		if(!oSelect)
10085			return;
10086		var n = oSelect.length;
10087		for(var i=0; i<n; i++)
10088			if(oSelect[i].selected)
10089				this.addNewOption(to_select_id, oSelect[i].value, oSelect[i].text, do_sort, check_unique);
10090	},
10091
10092	moveOptionsUp: function(oSelect)
10093	{
10094		if(!oSelect)
10095			return;
10096		var n = oSelect.length;
10097		for(var i=0; i<n; i++)
10098		{
10099			if(oSelect[i].selected && i>0 && oSelect[i-1].selected == false)
10100			{
10101				var option1 = new Option(oSelect[i].text, oSelect[i].value);
10102				var option2 = new Option(oSelect[i-1].text, oSelect[i-1].value);
10103				oSelect[i] = option2;
10104				oSelect[i].selected = false;
10105				oSelect[i-1] = option1;
10106				oSelect[i-1].selected = true;
10107			}
10108		}
10109	},
10110
10111	moveOptionsDown: function(oSelect)
10112	{
10113		if(!oSelect)
10114			return;
10115		var n = oSelect.length;
10116		for(var i=n-1; i>=0; i--)
10117		{
10118			if(oSelect[i].selected && i<n-1 && oSelect[i+1].selected == false)
10119			{
10120				var option1 = new Option(oSelect[i].text, oSelect[i].value);
10121				var option2 = new Option(oSelect[i+1].text, oSelect[i+1].value);
10122				oSelect[i] = option2;
10123				oSelect[i].selected = false;
10124				oSelect[i+1] = option1;
10125				oSelect[i+1].selected = true;
10126			}
10127		}
10128	}
10129
10130}
10131
10132/************************************************/
10133
10134/* End */
10135;
10136; /* Start:"a:4:{s:4:"full";s:47:"/bitrix/js/main/core/core_uf.js?174824846118793";s:6:"source";s:31:"/bitrix/js/main/core/core_uf.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
10137;(function ()
10138{
10139	'use strict';
10140
10141	BX.namespace('BX.Main.UF');
10142
10143	if (typeof BX.Main.UF.Manager !== 'undefined')
10144	{
10145		return;
10146	}
10147
10148	var fieldStack = {};
10149
10150	/**
10151	 * Dynamic form manager. Initilized as singleton below
10152	 *
10153	 * @constructor
10154	 */
10155
10156	BX.Main.UF.Manager = function ()
10157	{
10158		this.mode = this.mode || '';
10159		this.ajaxUrl = '/bitrix/tools/uf.php';
10160	};
10161
10162
10163	BX.Main.UF.Manager.getEdit = function (param, callback)
10164	{
10165		return BX.Main.UF.EditManager.get(param, callback);
10166	};
10167
10168	BX.Main.UF.Manager.getView = function (param, callback)
10169	{
10170		return BX.Main.UF.ViewManager.get(param, callback);
10171	};
10172
10173	BX.Main.UF.Manager.prototype.get = function (param, callback)
10174	{
10175		if (!this.mode)
10176		{
10177			this.displayError([
10178				'No mode set. Use BX.UF.EditManager or BX.UF.ViewManager'
10179			]);
10180
10181			return;
10182		}
10183
10184		return this.query(this.mode, {
10185			FIELDS: param.FIELDS,
10186			FORM: param.FORM || '',
10187			CONTEXT: param.CONTEXT || '',
10188			MEDIA_TYPE: param.MEDIA_TYPE || ''
10189		}, callback);
10190	};
10191
10192	BX.Main.UF.Manager.prototype.add = function (param, callback)
10193	{
10194		if (!this.mode)
10195		{
10196			this.displayError([
10197				'No mode set. Use BX.UF.EditManager or BX.UF.ViewManager'
10198			]);
10199
10200			return;
10201		}
10202
10203		return this.query(this.mode, {
10204			action: 'add',
10205			FIELDS: param.FIELDS,
10206			FORM: param.FORM || ''
10207		}, callback);
10208	};
10209
10210	BX.Main.UF.Manager.prototype.update = function (param, callback)
10211	{
10212		if (!this.mode)
10213		{
10214			this.displayError([
10215				'No mode set. Use BX.UF.EditManager or BX.UF.ViewManager'
10216			]);
10217
10218			return;
10219		}
10220
10221		return this.query(this.mode, {
10222			action: 'update',
10223			FIELDS: param.FIELDS,
10224			FORM: param.FORM || ''
10225		}, callback);
10226	};
10227
10228	BX.Main.UF.Manager.prototype.delete = function (param, callback)
10229	{
10230		if (!this.mode)
10231		{
10232			this.displayError([
10233				'No mode set. Use BX.UF.EditManager or BX.UF.ViewManager'
10234			]);
10235
10236			return;
10237		}
10238
10239		return this.query(this.mode, {
10240			action: 'delete',
10241			FIELDS: param.FIELDS,
10242			FORM: param.FORM || ''
10243		}, callback);
10244	};
10245
10246	BX.Main.UF.Manager.prototype.query = function (mode, param, callback)
10247	{
10248		BX.ajax({
10249			dataType: 'json',
10250			url: this.ajaxUrl,
10251			method: 'POST',
10252			data: this.prepareQuery(mode, param),
10253			onsuccess: this.queryCallback(callback)
10254		});
10255	};
10256
10257	BX.Main.UF.Manager.prototype.prepareQuery = function (mode, param)
10258	{
10259		var p = param || {};
10260
10261		p.mode = mode;
10262		p.lang = BX.message('LANGUAGE_ID') || '';
10263		p.tpl = BX.message('UF_SITE_TPL') || '';
10264		p.tpls = BX.message('UF_SITE_TPL_SIGN') || '';
10265		p.sessid = BX.bitrix_sessid();
10266
10267		return p;
10268	};
10269
10270	BX.Main.UF.Manager.prototype.queryCallback = function (callback)
10271	{
10272		var processResult = BX.proxy(this.processResult, this);
10273		return function (result)
10274		{
10275			processResult(result, callback);
10276		}
10277	};
10278
10279	BX.Main.UF.Manager.prototype.processResult = function (result, callback)
10280	{
10281		var asset = '';
10282		if (BX.type.isArray(result.ASSET))
10283		{
10284			asset += result.ASSET.join('\n');
10285		}
10286
10287		if (!!result.ERROR)
10288		{
10289			this.displayError(result.ERROR);
10290		}
10291
10292		return BX.html(null, asset).then(function ()
10293		{
10294			if (!!callback)
10295			{
10296				callback(result.FIELD);
10297			}
10298		});
10299	};
10300
10301	BX.Main.UF.Manager.prototype.displayError = function (errorList)
10302	{
10303		for (var i in errorList)
10304		{
10305			if (errorList.hasOwnProperty(i))
10306			{
10307				console.error(errorList[i]);
10308			}
10309		}
10310	};
10311
10312	BX.Main.UF.Manager.prototype.registerField = function (field, fieldDescription, node)
10313	{
10314		fieldStack[field] = {
10315			FIELD: fieldDescription,
10316			NODE: node
10317		};
10318	};
10319
10320	BX.Main.UF.Manager.prototype.unRegisterField = function (field)
10321	{
10322		if (!!fieldStack[field])
10323		{
10324			delete fieldStack[field];
10325		}
10326	};
10327
10328
10329	BX.Main.UF.ViewManager = function ()
10330	{
10331		BX.Main.UF.ViewManager.superclass.constructor.apply(this, arguments);
10332
10333		this.mode = 'main.view';
10334	};
10335	BX.extend(BX.Main.UF.ViewManager, BX.Main.UF.Manager);
10336
10337	BX.Main.UF.EditManager = function ()
10338	{
10339		BX.Main.UF.EditManager.superclass.constructor.apply(this, arguments);
10340
10341		this.mode = 'main.edit';
10342	};
10343	BX.extend(BX.Main.UF.EditManager, BX.Main.UF.Manager);
10344
10345	BX.Main.UF.EditManager.prototype.validate = function (fieldList, callback)
10346	{
10347		if (fieldList.length > 0)
10348		{
10349			var request = [];
10350			for (var i = 0; i < fieldList.length; i++)
10351			{
10352				var value = BX.Main.UF.Factory.getValue(fieldList[i]);
10353				if (value !== null)
10354				{
10355					request.push({
10356						'ENTITY_ID': fieldStack[fieldList[i]].FIELD.ENTITY_ID,
10357						'FIELD': fieldStack[fieldList[i]].FIELD.FIELD,
10358						'ENTITY_VALUE_ID': fieldStack[fieldList[i]].FIELD.ENTITY_VALUE_ID,
10359						'VALUE': value
10360					});
10361				}
10362			}
10363
10364			return this.query(this.mode, {
10365				action: 'validate',
10366				FIELDS: request
10367			}, callback);
10368		}
10369		else
10370		{
10371			this.queryCallback(callback)({'FIELD': []});
10372		}
10373	};
10374
10375	/**
10376	 * Base type handler class. Will be initialized in Factory.
10377	 *
10378	 * @constructor
10379	 */
10380
10381	BX.Main.UF.BaseType = function ()
10382	{
10383	};
10384
10385	BX.Main.UF.BaseType.prototype.addRow = function (fieldName, thisButton)
10386	{
10387		var element = thisButton.parentNode.getElementsByTagName('span');
10388		if (element && element.length > 0 && element[0])
10389		{
10390			var parentElement = element[0].parentNode; // parent
10391			var newNode = this.getClone(element[element.length - 1], fieldName);
10392
10393			if (parentElement === thisButton.parentNode)
10394			{
10395				parentElement.insertBefore(newNode, thisButton);
10396			}
10397			else
10398			{
10399				parentElement.appendChild(newNode);
10400			}
10401		}
10402	};
10403
10404	/**
10405	 * @deprecated
10406	 * @param fieldName
10407	 * @param thisButton
10408	 */
10409	BX.Main.UF.BaseType.prototype.addMobileRow = function (fieldName, thisButton)
10410	{
10411		var element = thisButton.parentNode.getElementsByTagName('span');
10412		if (element && element.length && element[0])
10413		{
10414			var parentElement = element[0].parentNode; // parent
10415			var newNode = this.getClone(element[element.length - 1], fieldName);
10416			var firstChildren = newNode.firstElementChild;
10417			var name = firstChildren.getAttribute('name');
10418			var re = /\[(\d)]/;
10419			var newName = name.replace(re, function (match, index)
10420			{
10421				index = parseInt(index) + 1;
10422				return '[' + index + ']';
10423			});
10424			var newItemId = false;
10425			var prevItemName = false;
10426			var userFieldTypeName = null;
10427
10428			firstChildren.setAttribute('name', newName);
10429
10430			if (firstChildren.hasChildNodes())
10431			{
10432				firstChildren.childNodes.forEach(
10433					function (item, index, array)
10434					{
10435						if (!prevItemName && item.attributes !== undefined && item.tagName === 'INPUT')
10436						{
10437							item.setAttribute('name', newName);
10438							prevItemName = item.getAttribute('id');
10439							newItemId = prevItemName + '_1';
10440							userFieldTypeName = item.getAttribute('data-user-field-type-name');
10441						}
10442
10443						if (prevItemName && item.attributes !== undefined && item.id !== undefined)
10444						{
10445							var id = item.getAttribute('id');
10446
10447							if (id !== prevItemName)
10448							{
10449								item.setAttribute('id', id.replace(prevItemName, newItemId));
10450							}
10451							else
10452							{
10453								item.setAttribute('id', newItemId);
10454							}
10455						}
10456					}
10457				);
10458			}
10459
10460			if (parentElement === thisButton.parentNode)
10461			{
10462				parentElement.insertBefore(newNode, thisButton);
10463			}
10464			else
10465			{
10466				parentElement.appendChild(newNode);
10467			}
10468
10469			if (newItemId)
10470			{
10471				BX.onCustomEvent(
10472					'onAddMobileUfField',
10473					[newItemId, userFieldTypeName]
10474				);
10475			}
10476
10477		}
10478	};
10479
10480	BX.Main.UF.BaseType.prototype.getClone = function (node, fieldName)
10481	{
10482		var newNode = node.cloneNode(true);
10483
10484		var inputList = this.findInput(newNode, fieldName);
10485		for (var i = 0; i < inputList.length; i++)
10486		{
10487			inputList[i].value = '';
10488		}
10489
10490		return newNode;
10491	};
10492
10493	BX.Main.UF.BaseType.prototype.findInput = function (node, fieldName)
10494	{
10495		return BX.findChildren(node, {
10496			tagName: /INPUT|TEXTAREA|SELECT/i,
10497			attribute: {
10498				name: fieldName
10499			}
10500		}, true);
10501	};
10502
10503	BX.Main.UF.BaseType.prototype.isEmpty = function (field)
10504	{
10505		var node = this.getNode(field),
10506			fieldName = field + (
10507				fieldStack[field].FIELD.MULTIPLE === 'Y'
10508					? '[]'
10509					: ''
10510			);
10511
10512		if (!BX.isNodeInDom(node))
10513		{
10514			console.error('Node for field ' + field + ' is already removed from DOM');
10515		}
10516
10517		var nodeList = this.findInput(node, fieldName);
10518
10519		if (nodeList.length <= 0)
10520		{
10521			console.error('Unable to find field ' + field + ' in the registered node');
10522		}
10523		else
10524		{
10525			for (var i = 0; i < nodeList.length; i++)
10526			{
10527				if (nodeList[i].value !== '')
10528				{
10529					return false;
10530				}
10531			}
10532		}
10533
10534		return true;
10535	};
10536
10537	BX.Main.UF.BaseType.prototype.getValue = function (field)
10538	{
10539		var node = this.getNode(field),
10540			fieldName = field + (
10541				fieldStack[field].FIELD.MULTIPLE === 'Y'
10542					? '[]'
10543					: ''
10544			),
10545			value = fieldStack[field].FIELD.MULTIPLE === 'Y' ? [] : '';
10546
10547		if (!BX.isNodeInDom(node))
10548		{
10549			console.error('Node for field ' + field + ' is already removed from DOM');
10550		}
10551		var nodeList = this.findInput(node, fieldName);
10552
10553		if (nodeList.length <= 0)
10554		{
10555			var nodeChildren = (node.children.length ? node.children[0] : false);
10556			/**
10557			 * @todo remove !BX.util.in_array(fieldStack[field].FIELD.USER_TYPE_ID, ['crm', 'employee'])
10558			 * after deploy new Crm and Employee types
10559			 */
10560			if (
10561				!BX.util.in_array(fieldStack[field].FIELD.USER_TYPE_ID, ['crm', 'employee'])
10562				&&
10563				(
10564					!nodeChildren
10565					||
10566					nodeChildren.getAttribute('data-has-input') !== 'no'
10567				)
10568			)
10569			{
10570				console.error('Unable to find field ' + field + ' in the registered node');
10571			}
10572		}
10573		else
10574		{
10575			for (var i = 0; i < nodeList.length; i++)
10576			{
10577				if (
10578					nodeList[i].tagName === 'INPUT'
10579					&& (nodeList[i].type === 'radio' || nodeList[i].type === 'checkbox')
10580					&& !nodeList[i].checked
10581				)
10582				{
10583					continue;
10584				}
10585
10586				if (!BX.Type.isStringFilled(nodeList[i].value))
10587				{
10588					continue;
10589				}
10590
10591				if (fieldStack[field].FIELD.MULTIPLE === 'Y')
10592				{
10593					value.push(nodeList[i].value);
10594				}
10595				else
10596				{
10597					value = nodeList[i].value;
10598					break;
10599				}
10600			}
10601		}
10602
10603		return value;
10604	};
10605
10606	BX.Main.UF.BaseType.prototype.focus = function (field)
10607	{
10608		var node = this.getNode(field),
10609			fieldName = field + (
10610				fieldStack[field].FIELD.MULTIPLE === 'Y'
10611					? '[]'
10612					: ''
10613			);
10614
10615		if (!BX.isNodeInDom(node))
10616		{
10617			console.error('Node for field ' + field + ' is already removed from DOM');
10618		}
10619		var nodeList = this.findInput(node, fieldName);
10620
10621		if (nodeList.length > 0)
10622		{
10623			BX.focus(nodeList[0]);
10624		}
10625	};
10626
10627	BX.Main.UF.BaseType.prototype.getNode = function (field)
10628	{
10629		return fieldStack[field].NODE;
10630	};
10631
10632	/**
10633	 * Integer type handler class. Will be initialized in Factory.
10634	 *
10635	 * @constructor
10636	 */
10637	BX.Main.UF.TypeBoolean = function ()
10638	{
10639	};
10640	BX.extend(BX.Main.UF.TypeBoolean, BX.Main.UF.BaseType);
10641
10642	BX.Main.UF.TypeBoolean.USER_TYPE_ID = 'boolean';
10643
10644	BX.Main.UF.TypeBoolean.prototype.isEmpty = function (field)
10645	{
10646		return false;
10647	};
10648
10649	/**
10650	 * Integer type handler class. Will be initialized in Factory.
10651	 *
10652	 * @constructor
10653	 */
10654	BX.Main.UF.TypeInteger = function ()
10655	{
10656	};
10657	BX.extend(BX.Main.UF.TypeInteger, BX.Main.UF.BaseType);
10658
10659	BX.Main.UF.TypeInteger.USER_TYPE_ID = 'integer';
10660
10661	/**
10662	 * Double type handler class. Will be initialized in Factory.
10663	 *
10664	 * @constructor
10665	 */
10666	BX.Main.UF.TypeDouble = function ()
10667	{
10668	};
10669	BX.extend(BX.Main.UF.TypeDouble, BX.Main.UF.BaseType);
10670
10671	BX.Main.UF.TypeDouble.USER_TYPE_ID = 'double';
10672
10673	/**
10674	 * String type handler class. Will be initialized in Factory.
10675	 *
10676	 * @constructor
10677	 */
10678	BX.Main.UF.TypeSting = function ()
10679	{
10680	};
10681	BX.extend(BX.Main.UF.TypeSting, BX.Main.UF.BaseType);
10682
10683	BX.Main.UF.TypeSting.USER_TYPE_ID = 'string';
10684
10685	/**
10686	 * URL type handler class. Will be initialized in Factory.
10687	 *
10688	 * @constructor
10689	 */
10690	BX.Main.UF.TypeUrl = function ()
10691	{
10692	};
10693	BX.extend(BX.Main.UF.TypeUrl, BX.Main.UF.BaseType);
10694
10695	BX.Main.UF.TypeUrl.USER_TYPE_ID = 'url';
10696
10697	/**
10698	 * Formatted string type handler class. Will be initialized in Factory.
10699	 *
10700	 * @constructor
10701	 */
10702	BX.Main.UF.TypeStingFormatted = function ()
10703	{
10704	};
10705	BX.extend(BX.Main.UF.TypeStingFormatted, BX.Main.UF.TypeSting);
10706
10707	BX.Main.UF.TypeStingFormatted.USER_TYPE_ID = 'string_formatted';
10708
10709
10710	/**
10711	 * Enumeration type handler class. Will be initialized in Factory.
10712	 *
10713	 * @constructor
10714	 */
10715	BX.Main.UF.TypeEnumeration = function ()
10716	{
10717	};
10718	BX.extend(BX.Main.UF.TypeEnumeration, BX.Main.UF.BaseType);
10719
10720	BX.Main.UF.TypeEnumeration.USER_TYPE_ID = 'enumeration';
10721
10722	BX.Main.UF.TypeEnumeration.prototype.findInput = function (node, fieldName)
10723	{
10724		var inputList = BX.Main.UF.TypeEnumeration.superclass.findInput.apply(this, arguments);
10725
10726		if (inputList.length > 0)
10727		{
10728			for (var i = 0; i < inputList.length; i++)
10729			{
10730				if (inputList[i].tagName === 'INPUT' && inputList[i].type === 'hidden' && inputList.length > 1)
10731				{
10732					delete inputList[i];
10733					break;
10734				}
10735			}
10736		}
10737
10738		return BX.util.array_values(inputList);
10739	};
10740
10741	BX.Main.UF.TypeEnumeration.prototype.focus = function (field)
10742	{
10743		if (fieldStack[field]
10744			&& fieldStack[field].FIELD.SETTINGS.DISPLAY === 'UI'
10745			&& BX.type.isElementNode(fieldStack[field].NODE)
10746		)
10747		{
10748			BX.fireEvent(fieldStack[field].NODE, 'focus');
10749		}
10750		else
10751		{
10752			BX.Main.UF.TypeEnumeration.superclass.focus.apply(this, arguments);
10753		}
10754	};
10755
10756	/**
10757	 * Date type handler class. Will be initialized in Factory.
10758	 *
10759	 * @constructor
10760	 */
10761	BX.Main.UF.TypeDate = function ()
10762	{
10763	};
10764	BX.extend(BX.Main.UF.TypeDate, BX.Main.UF.BaseType);
10765
10766	BX.Main.UF.TypeDate.USER_TYPE_ID = 'date';
10767
10768	BX.Main.UF.TypeDate.prototype.focus = function (field)
10769	{
10770		var fieldName = field + (
10771			fieldStack[field].FIELD.MULTIPLE === 'Y'
10772				? '[]'
10773				: ''
10774		);
10775		var inputList = this.findInput(this.getNode(field), fieldName);
10776
10777		if (inputList.length > 0)
10778		{
10779			BX.fireEvent(inputList[0], 'click');
10780		}
10781
10782		BX.Main.UF.TypeDate.superclass.focus.apply(this, arguments);
10783	};
10784
10785	/**
10786	 * Datetime type handler class. Will be initialized in Factory.
10787	 *
10788	 * @constructor
10789	 */
10790	BX.Main.UF.TypeDateTime = function ()
10791	{
10792	};
10793	BX.extend(BX.Main.UF.TypeDateTime, BX.Main.UF.TypeDate);
10794
10795	BX.Main.UF.TypeDateTime.USER_TYPE_ID = 'datetime';
10796
10797	/**
10798	 * Datetime type handler class. Will be initialized in Factory.
10799	 *
10800	 * @constructor
10801	 */
10802	BX.Main.UF.TypeFile = function ()
10803	{
10804	};
10805	BX.extend(BX.Main.UF.TypeFile, BX.Main.UF.BaseType);
10806
10807	BX.Main.UF.TypeFile.USER_TYPE_ID = 'file';
10808
10809	BX.Main.UF.TypeFile.prototype.findInput = function (node, fieldName)
10810	{
10811		var inputList = BX.Main.UF.TypeFile.superclass.findInput.apply(this, arguments);
10812
10813		if (inputList.length <= 0)
10814		{
10815			inputList = BX.findChildren(node, {
10816				tagName: /INPUT/i,
10817				attribute: {
10818					type: 'file',
10819					name: /^bxu_files/
10820				}
10821			}, true);
10822		}
10823
10824		return inputList;
10825	};
10826
10827	BX.Main.UF.TypeFile.prototype.getValue = function (field)
10828	{
10829		var
10830			baseValue = BX.Main.UF.TypeFile.superclass.getValue.apply(this, arguments),
10831			node = fieldStack[field].NODE,
10832			deletedNodeList = [],
10833			i;
10834
10835		if (fieldStack[field].FIELD.MULTIPLE === 'Y')
10836		{
10837			var deletedFieldName = field + '_del[]';
10838
10839			if (BX.type.isArray(baseValue) && baseValue.length > 0)
10840			{
10841				deletedNodeList = BX.Main.UF.TypeFile.superclass.findInput.apply(this, [node, deletedFieldName]);
10842
10843				for (i = 0; i < deletedNodeList.length; i++)
10844				{
10845					var pos = BX.util.array_search(deletedNodeList[i].value, baseValue);
10846					if (pos >= 0)
10847					{
10848						baseValue[pos] = {'old_id': deletedNodeList[i].value, 'del': 'Y', 'tmp_name': ''};
10849					}
10850				}
10851			}
10852
10853			return BX.util.array_values(baseValue);
10854		}
10855
10856		if (baseValue > 0)
10857		{
10858			var deletedFieldName = field + '_del';
10859
10860			deletedNodeList = BX.Main.UF.TypeFile.superclass.findInput.apply(this, [node, deletedFieldName]);
10861
10862			for (i = 0; i < deletedNodeList.length; i++)
10863			{
10864				if (baseValue == deletedNodeList[i].value)
10865				{
10866					baseValue = {'old_id': baseValue, 'del': 'Y', 'tmp_name': ''};
10867					break;
10868				}
10869			}
10870
10871			return baseValue;
10872		}
10873
10874		return null;
10875	};
10876
10877
10878	/**
10879	 * Type handler Factory singleton. Will be initialized below.
10880	 *
10881	 * @constructor
10882	 */
10883	BX.Main.UF.Factory = function ()
10884	{
10885		this.defaultTypeHandler = BX.Main.UF.BaseType;
10886
10887		this.typeHandlerList = {};
10888		this.objectCollection = {};
10889	};
10890
10891	BX.Main.UF.Factory.prototype.setTypeHandler = function (type, handlerClass)
10892	{
10893		this.typeHandlerList[type] = handlerClass;
10894		if (typeof this.objectCollection[type] !== 'undefined')
10895		{
10896			delete this.objectCollection[type];
10897		}
10898	};
10899
10900	BX.Main.UF.Factory.prototype.get = function (type)
10901	{
10902		if (typeof this.objectCollection[type] === 'undefined')
10903		{
10904			this.objectCollection[type] = this.getObject(type);
10905		}
10906
10907		return this.objectCollection[type];
10908	};
10909
10910	BX.Main.UF.Factory.prototype.getObject = function (type)
10911	{
10912		return new (this.typeHandlerList[type] || this.defaultTypeHandler);
10913	};
10914
10915	BX.Main.UF.Factory.prototype.getFieldObject = function (field)
10916	{
10917		if (typeof fieldStack[field] === 'undefined')
10918		{
10919			console.error('Field ' + field + 'is not registered. Use BX.Main.UF.Factory.registerField to register');
10920
10921			return null;
10922		}
10923
10924		return this.get(fieldStack[field]['FIELD']['USER_TYPE_ID']);
10925	};
10926
10927	BX.Main.UF.Factory.prototype.isEmpty = function (field)
10928	{
10929		if (typeof fieldStack[field] === 'undefined')
10930		{
10931			console.error('Field ' + field + 'is not registered. Use BX.Main.UF.Factory.registerField to register');
10932
10933			return true;
10934		}
10935
10936		return this.get(fieldStack[field]['FIELD']['USER_TYPE_ID']).isEmpty(field);
10937	};
10938
10939	BX.Main.UF.Factory.prototype.getValue = function (field)
10940	{
10941		if (typeof fieldStack[field] === 'undefined')
10942		{
10943			console.error('Field ' + field + 'is not registered. Use BX.Main.UF.Factory.registerField to register');
10944
10945			return null;
10946		}
10947
10948		return this.get(fieldStack[field]['FIELD']['USER_TYPE_ID']).getValue(field);
10949	};
10950
10951	BX.Main.UF.Factory.prototype.focus = function (field)
10952	{
10953		if (typeof fieldStack[field] === 'undefined')
10954		{
10955			console.error('Field ' + field + 'is not registered. Use BX.Main.UF.Factory.registerField to register');
10956		}
10957
10958		return this.get(fieldStack[field]['FIELD']['USER_TYPE_ID']).focus(field);
10959	};
10960
10961	/**
10962	 * Singletons initialization
10963	 */
10964
10965	BX.Main.UF.EditManager = new BX.Main.UF.EditManager();
10966	BX.Main.UF.ViewManager = new BX.Main.UF.ViewManager();
10967	BX.Main.UF.Factory = new BX.Main.UF.Factory();
10968
10969	BX.Main.UF.Factory.setTypeHandler(BX.Main.UF.TypeBoolean.USER_TYPE_ID, BX.Main.UF.TypeBoolean);
10970	BX.Main.UF.Factory.setTypeHandler(BX.Main.UF.TypeInteger.USER_TYPE_ID, BX.Main.UF.TypeInteger);
10971	BX.Main.UF.Factory.setTypeHandler(BX.Main.UF.TypeDouble.USER_TYPE_ID, BX.Main.UF.TypeDouble);
10972	BX.Main.UF.Factory.setTypeHandler(BX.Main.UF.TypeSting.USER_TYPE_ID, BX.Main.UF.TypeSting);
10973	BX.Main.UF.Factory.setTypeHandler(BX.Main.UF.TypeStingFormatted.USER_TYPE_ID, BX.Main.UF.TypeStingFormatted);
10974	BX.Main.UF.Factory.setTypeHandler(BX.Main.UF.TypeEnumeration.USER_TYPE_ID, BX.Main.UF.TypeEnumeration);
10975	BX.Main.UF.Factory.setTypeHandler(BX.Main.UF.TypeFile.USER_TYPE_ID, BX.Main.UF.TypeFile);
10976	BX.Main.UF.Factory.setTypeHandler(BX.Main.UF.TypeDate.USER_TYPE_ID, BX.Main.UF.TypeDate);
10977	BX.Main.UF.Factory.setTypeHandler(BX.Main.UF.TypeDateTime.USER_TYPE_ID, BX.Main.UF.TypeDateTime);
10978})();
10979
10980/* End */
10981;
10982; /* Start:"a:4:{s:4:"full";s:46:"/bitrix/js/main/core/core_dd.js?15867829843613";s:6:"source";s:31:"/bitrix/js/main/core/core_dd.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
10983(function(window){
10984BX.DD = function(params)
10985{
10986	return new BX.DD.dragdrop(params);
10987}
10988
10989BX.DD.allowSelection = function()
10990{
10991	document.onmousedown = null;
10992	var b = document.body;
10993	b.ondrag = null;
10994	b.onselectstart = null;
10995	b.style.MozUserSelect = '';
10996	
10997	// if (jsDD.current_node)
10998	// {
10999		// jsDD.current_node.ondrag = null;
11000		// jsDD.current_node.onselectstart = null;
11001		// jsDD.current_node.style.MozUserSelect = '';
11002	// }
11003}
11004	
11005BX.DD.denySelection = function()
11006{
11007	document.onmousedown = BX.False;
11008	var b = document.body;
11009	b.ondrag = BX.False;
11010	b.onselectstart = BX.False;
11011	b.style.MozUserSelect = 'none';
11012	// if (jsDD.current_node) 
11013	// {
11014		// jsDD.current_node.ondrag = jsUtils.False;
11015		// jsDD.current_node.onselectstart = jsUtils.False;
11016		// jsDD.current_node.style.MozUserSelect = 'none';
11017	// }
11018}
11019
11020BX.DD.dragdrop = function(params)
11021{
11022
11023
11024}
11025
11026/*
11027 * BX.DD.dropFiles - for html5 drag and drop files
11028 *
11029 * example:
11030 *
11031 * BX(function() {
11032 *	  var dropBoxNode = BX('WebDAV23');
11033 *    var dropbox = new BX.DD.dropFiles(dropBoxNode);
11034 *    if (dropbox && dropbox.supported())
11035 *    {
11036 *        BX.addCustomEvent(dropbox, 'dropFiles', function(files) { WDUploadDroppedFiles(files);});
11037 *        BX.addCustomEvent(dropbox, 'dragEnter', function() {BX.addClass( dropBoxNode, 'droptarget');});
11038 *        BX.addCustomEvent(dropbox, 'dragLeave', function() {BX.removeClass( dropBoxNode, 'droptarget');});
11039 *    }
11040 * });
11041 *
11042 * to save files use BX.ajax.FormData
11043 */
11044BX.DD.dropFiles = function(div)
11045{
11046	if (BX.type.isElementNode(div)
11047		&& this.supported())
11048	{
11049		div.setAttribute('dropzone', 'copy f:*/*');
11050		this.DIV = div;
11051		this._timer = null;
11052		this._initEvents();
11053
11054		this._cancelLeave = function()
11055		{
11056			if (this._timer != null)
11057			{
11058				clearTimeout(this._timer);
11059				this._timer = null;
11060			}
11061		}
11062		this._prepareLeave = function()
11063		{
11064			this._cancelLeave();
11065			this._timer = setTimeout( BX.delegate(function() {
11066				BX.onCustomEvent(this, 'dragLeave')
11067			}, this), 100);
11068		}
11069
11070		return this;
11071	}
11072	return false;
11073}
11074
11075BX.DD.dropFiles.prototype._initEvents = function()
11076{
11077	BX.bind(this.DIV, 'dragover', BX.proxy(this._dragOver, this));
11078	BX.bind(this.DIV, 'dragenter', BX.proxy(this._dragEnter, this));
11079	BX.bind(this.DIV, 'dragleave', BX.proxy(this._dragLeave, this));
11080	BX.bind(this.DIV, 'dragexit', BX.proxy(this._dragExit, this));
11081	BX.bind(this.DIV, 'drop', BX.proxy(this._drop, this));
11082}
11083
11084BX.DD.dropFiles.prototype._dragEnter = function(e)
11085{
11086	BX.PreventDefault(e);
11087	this._cancelLeave();
11088	BX.onCustomEvent(this, 'dragEnter', [e]);
11089	return true;
11090}
11091
11092BX.DD.dropFiles.prototype._dragExit = function(e)
11093{
11094	BX.PreventDefault(e);
11095	this._prepareLeave();
11096	return false;
11097}
11098
11099
11100BX.DD.dropFiles.prototype._dragLeave = function(e)
11101{
11102	BX.PreventDefault(e);
11103	this._prepareLeave();
11104	return false;
11105}
11106
11107BX.DD.dropFiles.prototype._dragOver = function(e)
11108{
11109	BX.PreventDefault(e);
11110	this._cancelLeave();
11111	return true;
11112}
11113
11114BX.DD.dropFiles.prototype._drop = function(e)
11115{
11116	BX.PreventDefault(e);
11117	var dt = e.dataTransfer;
11118	var files = dt.files;
11119	BX.onCustomEvent(this, 'dropFiles', [files, e]);
11120	BX.onCustomEvent(this, 'dragLeave')
11121	return false;
11122}
11123
11124BX.DD.dropFiles.prototype.isEventSupported = function(event)
11125{
11126	var div = BX.create('DIV');
11127	var eventName = 'on'+event;
11128	var result = (eventName in div);
11129	
11130	if (!result && div.setAttribute && div.removeAttribute)
11131	{
11132		div.setAttribute(eventName, '');
11133		result = (typeof div[eventName] === 'function');
11134	}
11135
11136	div = null;
11137	return result;
11138}
11139
11140BX.DD.dropFiles.prototype.supported = function()
11141{
11142	return ( (!!window.FileReader) && this.isEventSupported('dragstart') && this.isEventSupported('drop') );
11143}
11144
11145})(window)
11146
11147
11148/* End */
11149;
11150; /* Start:"a:4:{s:4:"full";s:52:"/bitrix/js/main/core/core_tooltip.js?172258261515634";s:6:"source";s:36:"/bitrix/js/main/core/core_tooltip.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
11151(function(window) {
11152if (BX.tooltip) return;
11153
11154var arTooltipIndex = {},
11155	bDisable = false;
11156
11157BX.tooltip = function(user_id, anchor_name, loader, rootClassName, bForceUseLoader, params)
11158{
11159	if (BX.message('TOOLTIP_ENABLED') != "Y")
11160	{
11161		return;
11162	}
11163
11164	if (
11165		BX.browser.IsAndroid()
11166		|| BX.browser.IsIOS()
11167	)
11168	{
11169		return;
11170	}
11171
11172	BX.ready(function() {
11173		var anchor = BX(anchor_name);
11174		if (null == anchor)
11175		{
11176			return;
11177		}
11178
11179		var tooltipId = user_id;
11180		if(bForceUseLoader && BX.type.isNotEmptyString(loader))
11181		{
11182			// prepare tooltip ID from custom loader
11183			var loaderHash = 0;
11184			for(var i = 0, len = loader.length; i < len; i++)
11185			{
11186				loaderHash = (31 * loaderHash + loader.charCodeAt(i)) << 0;
11187			}
11188
11189			tooltipId = loaderHash + user_id;
11190		}
11191
11192		if (null == arTooltipIndex[tooltipId])
11193		{
11194			arTooltipIndex[tooltipId] = new BX.CTooltip(user_id, anchor, loader, rootClassName, bForceUseLoader, params);
11195		}
11196		else
11197		{
11198			arTooltipIndex[tooltipId].ANCHOR = anchor;
11199			arTooltipIndex[tooltipId].rootClassName = rootClassName;
11200			arTooltipIndex[tooltipId].LOADER = (
11201				bForceUseLoader
11202				&& BX.type.isNotEmptyString(loader)
11203					? loader
11204					: '/bitrix/tools/tooltip.php'
11205			);
11206			arTooltipIndex[tooltipId].params = params;
11207			arTooltipIndex[tooltipId].Create();
11208		}
11209	});
11210};
11211
11212BX.tooltip.disable = function(){ bDisable = true; };
11213BX.tooltip.enable = function(){ bDisable = false; };
11214
11215BX.tooltip.hide = function(userId) {
11216	if (BX('user_info_' + userId))
11217	{
11218		BX('user_info_' + userId).style.display = 'none';
11219	}
11220};
11221
11222BX.tooltip.openIM = function(userId) {
11223
11224	const namespace = top.BX.Reflection.namespace('BX.Messenger.Public');
11225	if (namespace)
11226	{
11227		namespace.openChat(userId);
11228		BX.tooltip.hide(userId);
11229	}
11230	else if (BX('MULSonetMessageChatTemplate'))
11231	{
11232		window.open(BX('MULSonetMessageChatTemplate').replace('#user_id#', userId).replace('#USER_ID#', userId).replace('#ID#', userId), '', 'location=yes,status=no,scrollbars=yes,resizable=yes,width=700,height=550,top='+Math.floor((screen.height - 550)/2-14)+',left='+Math.floor((screen.width - 700)/2-5));
11233		BX.tooltip.hide(userId);
11234	}
11235	return false;
11236};
11237
11238
11239BX.tooltip.openCallTo = function(userId) {
11240
11241	const namespace = top.BX.Reflection.namespace('BX.Messenger.Public');
11242	if (namespace)
11243	{
11244		namespace.startVideoCall(userId);
11245	}
11246	return false;
11247};
11248
11249BX.tooltip.checkCallTo = function(nodeId) {
11250};
11251
11252BX.tooltip.openVideoCall = function(userId) {
11253	const namespace = top.BX.Reflection.namespace('BX.Messenger.Public');
11254	if (namespace)
11255	{
11256		namespace.startVideoCall(userId);
11257	}
11258	else if (BX('MULVideoCallTemplate'))
11259	{
11260		window.open(BX('MULVideoCallTemplate').replace('#user_id#', userId).replace('#USER_ID#', userId).replace('#ID#', userId), '', 'location=yes,status=no,scrollbars=yes,resizable=yes,width=1000,height=600,top='+Math.floor((screen.height - 600)/2-14)+',left='+Math.floor((screen.width - 1000)/2-5));
11261		BX.tooltip.hide(userId);
11262	}
11263	return false;
11264};
11265
11266BX.CTooltip = function(user_id, anchor, loader, rootClassName, bForceUseLoader, params)
11267{
11268	this.LOADER = (
11269		bForceUseLoader
11270		&& BX.type.isNotEmptyString(loader)
11271			? loader
11272			: '/bitrix/tools/tooltip.php'
11273	);
11274	this.USER_ID = user_id;
11275	this.ANCHOR = anchor;
11276	this.rootClassName = '';
11277	this.params = (typeof params != 'undefined' ? params : {});
11278
11279	if (
11280		rootClassName != 'undefined'
11281		&& rootClassName != null
11282		&& rootClassName.length > 0
11283	)
11284	{
11285		this.rootClassName = rootClassName;
11286	}
11287
11288	var old = document.getElementById('user_info_' + this.USER_ID);
11289	if (null != old)
11290	{
11291		if (null != old.parentNode)
11292			old.parentNode.removeChild(old);
11293
11294		old = null;
11295	}
11296
11297	var _this = this;
11298
11299	this.INFO = null;
11300
11301	this.width = 393;
11302	this.height = 302;
11303
11304	this.RealAnchor = null;
11305	this.CoordsLeft = 0;
11306	this.CoordsTop = 0;
11307	this.AnchorRight = 0;
11308	this.AnchorBottom = 0;
11309
11310	this.DIV = null;
11311	this.ROOT_DIV = null;
11312
11313	if (BX.browser.IsIE())
11314	{
11315		this.IFRAME = null;
11316	}
11317
11318	this.v_delta = 0;
11319	this.classNameAnim = false;
11320	this.classNameFixed = false;
11321
11322	this.left = 0;
11323	this.top = 0;
11324
11325	this.tracking = false;
11326	this.active = false;
11327	this.showed = false;
11328
11329	this.Create = function()
11330	{
11331		_this.ANCHOR.onmouseover = function() {
11332			if (!bDisable)
11333			{
11334				_this.StartTrackMouse(this);
11335			}
11336		};
11337
11338		_this.ANCHOR.onmouseout = function() {
11339			_this.StopTrackMouse(this);
11340		}
11341	};
11342
11343	this.Create();
11344
11345	this.TrackMouse = function(e)
11346	{
11347		if(!_this.tracking)
11348			return;
11349
11350		var current;
11351		if(e && e.pageX)
11352			current = {x: e.pageX, y: e.pageY};
11353		else
11354			current = {x: e.clientX + document.body.scrollLeft, y: e.clientY + document.body.scrollTop};
11355
11356		if(current.x < 0)
11357			current.x = 0;
11358		if(current.y < 0)
11359			current.y = 0;
11360
11361		current.time = _this.tracking;
11362
11363		if(!_this.active)
11364			_this.active = current;
11365		else
11366		{
11367			if(
11368				_this.active.x >= (current.x - 1) && _this.active.x <= (current.x + 1)
11369				&& _this.active.y >= (current.y - 1) && _this.active.y <= (current.y + 1)
11370			)
11371			{
11372				if((_this.active.time + 20/*2sec*/) <= current.time)
11373					_this.ShowTooltip();
11374			}
11375			else
11376				_this.active = current;
11377		}
11378	};
11379
11380	this.ShowTooltip = function()
11381	{
11382		var old = document.getElementById('user_info_' + _this.USER_ID);
11383		if(bDisable || old && old.style.display == 'block')
11384			return;
11385
11386		var bIE = (BX.browser.IsIE() && !BX.browser.IsIE10());
11387
11388		if (!BX.type.isPlainObject(this.params))
11389		{
11390			this.params = {};
11391		}
11392
11393		if (null == _this.DIV && null == _this.ROOT_DIV)
11394		{
11395			_this.ROOT_DIV = document.body.appendChild(document.createElement('DIV'));
11396			_this.ROOT_DIV.style.position = 'absolute';
11397
11398			BX.ZIndexManager.register(_this.ROOT_DIV);
11399
11400			_this.DIV = _this.ROOT_DIV.appendChild(document.createElement('DIV'));
11401			if (bIE)
11402				_this.DIV.className = 'bx-user-info-shadow-ie';
11403			else
11404				_this.DIV.className = 'bx-user-info-shadow';
11405
11406			_this.DIV.style.width = _this.width + 'px';
11407			_this.DIV.style.height = _this.height + 'px';
11408		}
11409
11410		var left = _this.CoordsLeft;
11411		var top = _this.CoordsTop + 30;
11412		var arScroll = BX.GetWindowScrollPos();
11413		var body = document.body;
11414
11415		var h_mirror = false;
11416		var v_mirror = false;
11417
11418		if((body.clientWidth + arScroll.scrollLeft) < (left + _this.width))
11419		{
11420			left = _this.AnchorRight - _this.width;
11421			h_mirror = true;
11422		}
11423
11424		if((top - arScroll.scrollTop) < 0)
11425		{
11426			top = _this.AnchorBottom - 5;
11427			v_mirror = true;
11428			_this.v_delta = 40;
11429		}
11430		else
11431			_this.v_delta = 0;
11432
11433		_this.ROOT_DIV.style.left = parseInt(left) + "px";
11434		_this.ROOT_DIV.style.top = parseInt(top) + "px";
11435
11436		BX.ZIndexManager.bringToFront(_this.ROOT_DIV);
11437
11438		BX.bind(BX(_this.ROOT_DIV), "click", BX.eventCancelBubble);
11439
11440		if (
11441			this.rootClassName != 'undefined'
11442			&& this.rootClassName != null
11443			&& this.rootClassName.length > 0
11444		)
11445			_this.ROOT_DIV.className = this.rootClassName;
11446
11447		if ('' == _this.DIV.innerHTML)
11448		{
11449			var url = _this.LOADER +
11450				(_this.LOADER.indexOf('?') >= 0 ? '&' : '?') +
11451				'MUL_MODE=INFO&USER_ID=' + _this.USER_ID +
11452				'&site=' + (BX.message('SITE_ID') || '') +
11453				(
11454					typeof _this.params != 'undefined'
11455					&& typeof _this.params.entityType != 'undefined'
11456					&& _this.params.entityType.length > 0
11457						? '&entityType=' + _this.params.entityType
11458						: ''
11459				) +
11460				(
11461					typeof _this.params != 'undefined'
11462					&& typeof _this.params.entityId != 'undefined'
11463					&& parseInt(_this.params.entityId) > 0
11464						? '&entityId=' + parseInt(_this.params.entityId)
11465						: ''
11466				);
11467
11468			BX.ajax.get(url, _this.InsertData);
11469			_this.DIV.id = 'user_info_' + _this.USER_ID;
11470
11471			_this.DIV.innerHTML = '<div class="bx-user-info-wrap">'
11472				+ '<div class="bx-user-info-leftcolumn">'
11473					+ '<div class="bx-user-photo" id="user-info-photo-' + _this.USER_ID + '"><div class="bx-user-info-data-loading">' + BX.message('JS_CORE_LOADING') + '</div></div>'
11474					+ '<div class="bx-user-tb-control bx-user-tb-control-left" id="user-info-toolbar-' + _this.USER_ID + '"></div>'
11475				+ '</div>'
11476				+ '<div class="bx-user-info-data">'
11477					+ '<div id="user-info-data-card-' + _this.USER_ID + '"></div>'
11478					+ '<div class="bx-user-info-data-tools">'
11479						+ '<div class="bx-user-tb-control bx-user-tb-control-right" id="user-info-toolbar2-' + _this.USER_ID + '"></div>'
11480						+ '<div class="bx-user-info-data-clear"></div>'
11481					+ '</div>'
11482				+ '</div>'
11483				+ '</div><div class="bx-user-info-bottomarea"></div>';
11484		}
11485
11486		if (bIE)
11487		{
11488			_this.DIV.className = 'bx-user-info-shadow-ie';
11489			_this.classNameAnim = 'bx-user-info-shadow-anim-ie';
11490			_this.classNameFixed = 'bx-user-info-shadow-ie';
11491		}
11492		else
11493		{
11494			_this.DIV.className = 'bx-user-info-shadow';
11495			_this.classNameAnim = 'bx-user-info-shadow-anim';
11496			_this.classNameFixed = 'bx-user-info-shadow';
11497		}
11498
11499		_this.filterFixed = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='/bitrix/components/bitrix/main.user.link/templates/.default/images/cloud-left-top.png', sizingMethod = 'crop' );";
11500
11501		if (h_mirror && v_mirror)
11502		{
11503			if (BX.browser.IsIE6())
11504			{
11505				_this.DIV.className = 'bx-user-info-shadow-hv-ie6';
11506				_this.classNameAnim = 'bx-user-info-shadow-hv-anim-ie6';
11507				_this.classNameFixed = 'bx-user-info-shadow-hv-ie6';
11508			}
11509			else if (bIE)
11510			{
11511				_this.DIV.className = 'bx-user-info-shadow-hv-ie';
11512				_this.classNameAnim = 'bx-user-info-shadow-hv-anim-ie';
11513				_this.classNameFixed = 'bx-user-info-shadow-hv-ie';
11514			}
11515			else
11516			{
11517				_this.DIV.className = 'bx-user-info-shadow-hv';
11518				_this.classNameAnim = 'bx-user-info-shadow-hv-anim';
11519				_this.classNameFixed = 'bx-user-info-shadow-hv';
11520			}
11521
11522			_this.filterFixed = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='/bitrix/components/bitrix/main.user.link/templates/.default/images/cloud-right-bottom.png', sizingMethod = 'crop' );";
11523		}
11524		else
11525		{
11526			if (h_mirror)
11527			{
11528				if (bIE)
11529				{
11530					_this.DIV.className = 'bx-user-info-shadow-h-ie';
11531					_this.classNameAnim = 'bx-user-info-shadow-h-anim-ie';
11532					_this.classNameFixed = 'bx-user-info-shadow-h-ie';
11533				}
11534				else
11535				{
11536					_this.DIV.className = 'bx-user-info-shadow-h';
11537					_this.classNameAnim = 'bx-user-info-shadow-h-anim';
11538					_this.classNameFixed = 'bx-user-info-shadow-h';
11539				}
11540
11541				_this.filterFixed = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='/bitrix/components/bitrix/main.user.link/templates/.default/images/cloud-right-top.png', sizingMethod = 'crop' );";
11542			}
11543
11544			if (v_mirror)
11545			{
11546				if (BX.browser.IsIE6())
11547				{
11548					_this.DIV.className = 'bx-user-info-shadow-v-ie6';
11549					_this.classNameAnim = 'bx-user-info-shadow-v-anim-ie6';
11550					_this.classNameFixed = 'bx-user-info-shadow-v-ie6';
11551				}
11552				else if (bIE)
11553				{
11554					_this.DIV.className = 'bx-user-info-shadow-v-ie';
11555					_this.classNameAnim = 'bx-user-info-shadow-v-anim-ie';
11556					_this.classNameFixed = 'bx-user-info-shadow-v-ie';
11557				}
11558				else
11559				{
11560					_this.DIV.className = 'bx-user-info-shadow-v';
11561					_this.classNameAnim = 'bx-user-info-shadow-v-anim';
11562					_this.classNameFixed = 'bx-user-info-shadow-v';
11563				}
11564
11565				_this.filterFixed = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='/bitrix/components/bitrix/main.user.link/templates/.default/images/cloud-left-bottom.png', sizingMethod = 'crop' );";
11566			}
11567		}
11568
11569
11570		if (BX.browser.IsIE() && null == _this.IFRAME)
11571		{
11572			_this.IFRAME = document.body.appendChild(document.createElement('IFRAME'));
11573			_this.IFRAME.id = _this.DIV.id + "_frame";
11574			_this.IFRAME.style.position = 'absolute';
11575			_this.IFRAME.style.width = (_this.width - 60) + 'px';
11576			_this.IFRAME.style.height = (_this.height - 100) + 'px';
11577			_this.IFRAME.style.borderStyle = 'solid';
11578			_this.IFRAME.style.borderWidth = '0px';
11579			_this.IFRAME.style.zIndex = 550;
11580			_this.IFRAME.style.display = 'none';
11581		}
11582		if (BX.browser.IsIE())
11583		{
11584			_this.IFRAME.style.left = (parseInt(left) + 25) + "px";
11585			_this.IFRAME.style.top = (parseInt(top) + 30 + _this.v_delta) + "px";
11586		}
11587
11588		_this.DIV.style.display = 'none';
11589		_this.ShowOpacityEffect({func: _this.SetVisible, obj: _this.DIV, arParams: []}
11589, 0);
11590
11591		document.getElementById('user_info_' + _this.USER_ID).onmouseover = function() {
11592			_this.StartTrackMouse(this);
11593		};
11594
11595		document.getElementById('user_info_' + _this.USER_ID).onmouseout = function() {
11596			_this.StopTrackMouse(this);
11597		};
11598
11599		BX.onCustomEvent('onTooltipShow', [this]);
11600	};
11601
11602	this.InsertData = function(data)
11603	{
11604		if (null != data && data.length > 0)
11605		{
11606			eval('_this.INFO = ' + data);
11607
11608			var cardEl = document.getElementById('user-info-data-card-' + _this.USER_ID);
11609			cardEl.innerHTML = _this.INFO.RESULT.Card;
11610
11611			var photoEl = document.getElementById('user-info-photo-' + _this.USER_ID);
11612			photoEl.innerHTML = _this.INFO.RESULT.Photo;
11613
11614			var toolbarEl = document.getElementById('user-info-toolbar-' + _this.USER_ID);
11615			toolbarEl.innerHTML = _this.INFO.RESULT.Toolbar;
11616
11617			var toolbar2El = document.getElementById('user-info-toolbar2-' + _this.USER_ID);
11618			toolbar2El.innerHTML = _this.INFO.RESULT.Toolbar2;
11619
11620			if(BX.type.isArray(_this.INFO.RESULT.Scripts))
11621			{
11622				for(var i = 0; i < _this.INFO.RESULT.Scripts.length; i++)
11623				{
11624					eval(_this.INFO.RESULT.Scripts[i]);
11625				}
11626			}
11627
11628			BX.onCustomEvent('onTooltipInsertData', [_this]);
11629		}
11630	}
11631
11632};
11633BX.CTooltip.prototype.StartTrackMouse = function(ob)
11634{
11635	var _this = this;
11636
11637	if(!this.tracking)
11638	{
11639		var elCoords = BX.pos(ob);
11640		this.RealAnchor = ob;
11641		this.CoordsLeft = elCoords.left + 0;
11642		this.CoordsTop = elCoords.top - 325;
11643		this.AnchorRight = elCoords.right;
11644		this.AnchorBottom = elCoords.bottom;
11645
11646		this.tracking = 1;
11647		BX.bind(document, "mousemove", _this.TrackMouse);
11648
11649		setTimeout(function() {_this.tickTimer()}, 500);
11650	}
11651};
11652
11653BX.CTooltip.prototype.StopTrackMouse = function()
11654{
11655	var _this = this;
11656	if(this.tracking)
11657	{
11658		BX.unbind(document, "mousemove", _this.TrackMouse);
11659		this.active = false;
11660		setTimeout(function() {_this.HideTooltip()}, 500);
11661		this.tracking = false;
11662	}
11663};
11664
11665BX.CTooltip.prototype.tickTimer = function()
11666{
11667	var _this = this;
11668
11669	if(this.tracking)
11670	{
11671		this.tracking++;
11672		if(this.active)
11673		{
11674			if( (this.active.time + 5/*0.5sec*/)  <= this.tracking)
11675				this.ShowTooltip();
11676		}
11677		setTimeout(function() {_this.tickTimer()}, 100);
11678	}
11679};
11680
11681BX.CTooltip.prototype.HideTooltip = function()
11682{
11683	if(!this.tracking)
11684		this.ShowOpacityEffect({func: this.SetInVisible, obj: this.DIV, arParams: []}, 1);
11685};
11686
11687BX.CTooltip.prototype.ShowOpacityEffect = function(oCallback, bFade)
11688{
11689	var steps = 3;
11690	var period = 1;
11691	var delta = 1 / steps;
11692	var i = 0, op, _this = this;
11693
11694	if(BX.browser.IsIE() && _this.DIV)
11695		_this.DIV.className = _this.classNameAnim;
11696
11697	var show = function()
11698	{
11699		i++;
11700		if (i > steps)
11701		{
11702			clearInterval(intId);
11703			if (!oCallback.arParams)
11704				oCallback.arParams = [];
11705			if (oCallback.func && oCallback.obj)
11706				oCallback.func.apply(oCallback.obj, oCallback.arParams);
11707			return;
11708		}
11709		op = bFade ? 1 - i * delta : i * delta;
11710
11711		if (_this.DIV != null)
11712		{
11713			try{
11714				_this.DIV.style.filter = 'progid:DXImageTransform.Microsoft.Alpha(opacity=' + (op * 100) + ')';
11715				_this.DIV.style.opacity = op;
11716				_this.DIV.style.MozOpacity = op;
11717				_this.DIV.style.KhtmlOpacity = op;
11718			}
11719			catch(e){
11720			}
11721			finally{
11722				if (!bFade && i == 1)
11723					_this.DIV.style.display = 'block';
11724
11725				if (bFade && i == steps && _this.DIV)
11726					_this.DIV.style.display = 'none';
11727
11728
11729				if (BX.browser.IsIE() && i == 1 && bFade && _this.IFRAME)
11730					_this.IFRAME.style.display = 'none';
11731
11732
11733				if (BX.browser.IsIE() && i == steps && _this.DIV)
11734				{
11735					if (!bFade)
11736						_this.IFRAME.style.display = 'block';
11737
11738					_this.DIV.style.filter = _this.filterFixed;
11739					_this.DIV.className = _this.classNameFixed;
11740					_this.DIV.innerHTML = ''+_this.DIV.innerHTML;
11741				}
11742
11743				if(bFade)
11744				{
11745					BX.onCustomEvent('onTooltipHide', [_this]);
11746				}
11747			}
11748		}
11749
11750	};
11751	var intId = setInterval(show, period);
11752
11753}
11754
11755})(window);
11756
11757/* End */
11758;

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.