PageSourceSearch

https://regionstal.ru/bitrix/cache/js/s1/rs2023/kernel_main/kernel_main_v1.js?1790326273217273

js regionstal.ru collected 2026-10-07 15:47:13 UTC 217,273 bytes, 8,140 lines download raw bytes

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

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.