PageSourceSearch

https://lkg.ru/bitrix/cache/js/s1/aspro_max/kernel_main/kernel_main_v1.js?1776365449220524

js lkg.ru collected 2026-10-08 03:28:02 UTC 220,524 bytes, 8,797 lines download raw bytes

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

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.