PageSourceSearch

https://mo-yaransk.ru/bitrix/cache/js/s1/modern/kernel_main/kernel_main_v1.js?1745380995250120

js mo-yaransk.ru collected 2026-10-02 07:55:22 UTC 250,120 bytes, 9,460 lines download raw bytes

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

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.